Skip to content

fix(core): align Gemini placeholder user turns with ADK Python - #1629

Open
innoprej wants to merge 1 commit into
google:mainfrom
innoprej:fix/gemini-placeholder-parity
Open

innoprej wants to merge 1 commit into
google:mainfrom
innoprej:fix/gemini-placeholder-parity

Conversation

@innoprej

@innoprej innoprej commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

2. Or, if no issue exists, describe the change:

Problem:

GeminiUtil.ensureModelResponse appends a user turn when a request has no contents or does not end with a user turn. In Java this turn is "Continue output. DO NOT look at this line. ONLY look at the content before this line and system instruction." — an instruction-override style sentence that ADK Python, TypeScript and Go do not use. With Vertex AI and Model Armor prompt injection and jailbreak detection enabled, requests whose only user-role content is this sentence are blocked (piAndJailbreakFilterResult MATCH_FOUND, confidence HIGH), so agents driven only by their instruction cannot run.

Solution:

Use the same wording as ADK Python's BaseLlm._maybe_append_user_content and ADK TypeScript's maybeAppendUserContent:

  • no contents: HANDLE_SYSTEM_INSTRUCTION_MESSAGE = "Handle the requests as specified in the System Instruction."
  • last turn not from the user: CONTINUE_OUTPUT_MESSAGE = "Continue processing previous requests as instructed. Exit or provide a summary if no more outputs are needed." (same as Go)

CONTINUE_OUTPUT_MESSAGE keeps its name, so existing references still compile; only its text changes. The condition for appending a turn is unchanged.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

./mvnw -pl core test -Dtest=GeminiUtilTest — 32 tests, 0 failures (Microsoft Build of OpenJDK 17.0.19). The expected texts are now string literals that match ADK Python; the four placeholder tests fail on main (they receive the old sentence) and pass with this change. Full ./mvnw -pl core test on Windows 11: 2120 run, 0 failures (24 skipped).

Manual End-to-End (E2E) Tests:

Observed in an application on Vertex AI with Model Armor floor settings: agents that run on their instruction alone were blocked on the first model call while the old sentence was appended. In the same project and settings, the old sentence typed as a plain user message in a new chat session was also blocked by Model Armor, while the new empty-contents sentence ("Handle the requests as specified in the System Instruction.") was not. The patched library itself has not yet been run end-to-end under Model Armor.

Checklist

  • I have read the CONTRIBUTING.md document.
  • My pull request contains a single commit.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

GeminiUtil.ensureModelResponse appends a user turn when a request has no
contents or does not end with a user turn. In Java this turn is
"Continue output. DO NOT look at this line. ONLY look at the content
before this line and system instruction." ADK Python, TypeScript and Go
use different, neutral wording, and the Java sentence reads like an
instruction-override prompt. A request whose only user-role content was
this sentence was flagged by Model Armor prompt injection and jailbreak
detection (confidence HIGH), which blocks agents that are driven only by
their system instruction.

Use the same wording as ADK Python and ADK TypeScript:
- no contents: "Handle the requests as specified in the System
  Instruction."
- last turn not from the user: "Continue processing previous requests as
  instructed. Exit or provide a summary if no more outputs are needed."
@hemasekhar-p hemasekhar-p self-assigned this Oct 8, 2026
@hemasekhar-p

Copy link
Copy Markdown
Contributor

Hi @innoprej, Thank you for your contribution and for taking the time to submit this pull request. Our team is currently reviewing your changes and we will reach out if we need any further information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GeminiUtil placeholder user turn ("Continue output. DO NOT look at this line ...") is flagged by prompt injection filters

2 participants