Repository navigation
fix: send output_schema to the Interactions API as response_format - #7871
Open
himanshu096 wants to merge 1 commit into
Open
himanshu096 wants to merge 1 commit into
himanshu096 wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
himanshu096
force-pushed
the
fix/interactions-output-schema
branch
from
October 30, 2026 22:30
a947cfb to
8a07937
Compare
An agent's output_schema is set on config.response_schema, which generate_content_via_interactions never read, so the schema was dropped from every Interactions API request and replies were unconstrained. This hit agents without tools everywhere, and agents with tools on Vertex AI, where the set_model_response fallback is skipped. Send the schema as a JSON text response_format, with the response_mime_type the API requires alongside it. Fixes google#7870
himanshu096
force-pushed
the
fix/interactions-output-schema
branch
from
October 30, 2026 22:57
8a07937 to
85fba8f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
Problem:
An
LlmAgent'soutput_schemais set onllm_request.config.response_schema.generate_content_via_interactionsnever reads that field, so the schema is left out of every Interactions API request (Gemini(use_interactions_api=True)), and replies are unconstrained. This affects agents without tools, and agents with tools on Vertex AI, whereoutput_schema_and_toolsisTrue, so theset_model_responsefallback is skipped.Solution:
_build_response_format()sits next tobuild_generation_config(). It turnsconfig.response_json_schemaorconfig.response_schemainto the Interactions API's JSON text response format:{"type": "text", "mime_type": "application/json", "schema": ...}._schema_utils.schema_to_json_schema(), the converter the Anthropic connector already uses, for pydantic models, generic aliases such aslist[Model], and dicts.types.Schemait usesSchema.json_schema.response_json_schematakes precedence when both fields are set.generate_content_via_interactionssendsresponse_formatandresponse_mime_type="application/json", which google-genai documents as required alongsideresponse_format. It sends them only when a schema is set, so requests without one are unchanged.TextResponseFormatParamand theresponse_format/response_mime_typeparameters ofinteractions.create()exist in google-genai 2.30, ADK's minimum, and in later releases (checked 2.31 and 2.34).Testing Plan
Unit Tests:
New
TestOutputSchemaintests/unittests/models/test_interactions_utils.py, testing throughgenerate_content_via_interactionsand the runner:test_schema_is_sent_as_response_format, parametrized over a pydantic model,list[Model](keeping its$defs),types.Schema, a raw JSON schema dict, andresponse_json_schemataking precedence.test_schema_is_sent_when_streaming.test_no_schema_sends_neither_key: requests without a schema are unchanged.test_agent_output_schema_reaches_the_request: anLlmAgent(output_schema=...)run throughInMemoryRunner, on both the Gemini API and Vertex AI via theenv_variablesfixture.test_agent_with_tools_sends_schema_with_tools_on_vertex: on Vertex AI, a schema agent with a function tool sends both the tool and the response format, with noset_model_response.On
mainwithout the fix, 9 of these 10 tests fail. The tenth,test_no_schema_sends_neither_key, passes either way.The 12 failures are all in
prompt/test_instructions_utils.py. They need the optionaljinja2package, which isn't in my environment, and they fail the same way onmainwithout this change.ruff,isort,pyinkandcodespell(pre-commit versions) pass on both changed files.mypyreports no new errors ininteractions_utils.py.Manual End-to-End (E2E) Tests:
This runs four
LlmAgent(output_schema=...)agents against Vertex AI (global) withGemini(model="gemini-3.6-flash", use_interactions_api=True), and checks whether each final reply validates against its schema. It compares released google-adk 2.13.0 with this branch.The four cases:
no_tools:output_schema=Verdict(ok: bool,reason: str), with the prompt "Tell me a short joke about cats."no_tools_stream: the same agent withStreamingMode.SSE.list_schema:output_schema=list[Verdict]. This confirms the API accepts the$defs/$refthat pydantic generates.with_tool:output_schema=Verdictplus aget_weatherfunction tool on Vertex AI. This confirms the API accepts a response format together with function tools, and the model still calls the tool first.E2E script
Run with
GOOGLE_GENAI_USE_VERTEXAI=1 GOOGLE_CLOUD_PROJECT=<project> GOOGLE_CLOUD_LOCATION=global.Checklist
Additional context
minLength,maxLengthanduniqueItems, without an error. It returns 400 for overly complex schemas. This PR sends the schema unchanged and leaves that behavior to the API.types.Schema: for pydantic models, generateContent convertsresponse_schemainto atypes.Schema, while this path sends pydantic's JSON schema as-is. The live check above shows the API accepts it, including$defs/$ref.🤖 Generated with Claude Code