Python: fix(gemini): forward response_format as response_schema (#5888)#5892
Open
Protocol-zero-0 wants to merge 1 commit into
Open
Conversation
…osoft#5888) When the cross-client `response_format` option is set on `GeminiChatClient` without an explicit `response_schema`, the client switched into JSON mode (`response_mime_type=application/json`) but dropped the schema, so the model produced arbitrary JSON. This surfaced via the declarative loader: `AgentFactory` translates a PromptAgent's `outputSchema` into `chat_options["response_format"]`, which then reaches the Gemini client as a plain dict. The schema is now also forwarded to Gemini's native `response_schema` when no explicit `response_schema` was supplied, for both dict (raw JSON schema) and Pydantic `BaseModel` response formats. An explicit `response_schema` continues to take precedence. Adds three regression tests covering dict and BaseModel response_format forwarding and the precedence ordering. Fixes microsoft#5888
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a bug where the Gemini chat client dropped response_format schemas (used by declarative agents' outputSchema), leaving the model in JSON mode without a schema. The fix forwards response_format to Gemini's native response_schema field when the explicit response_schema option is not set.
Changes:
- In
_prepare_config, fall back toresponse_formatwhenresponse_schemais unset; supports both raw JSON schema dicts and PydanticBaseModelsubclasses. - Explicit
response_schemacontinues to take precedence. - Added three regression tests covering dict, Pydantic, and precedence cases.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| python/packages/gemini/agent_framework_gemini/_chat_client.py | Forward response_format to Gemini's response_schema when no explicit schema is set. |
| python/packages/gemini/tests/test_gemini_client.py | Regression tests for dict/Pydantic forwarding and explicit-schema precedence. |
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.
Summary
Fixes #5888 — when a declarative agent's `outputSchema` reaches the Gemini chat client, the schema was dropped and the model returned arbitrary JSON instead of conforming to the schema.
Root cause
The Gemini chat client only forwarded the schema to the underlying Google GenAI `response_schema` field when the user used Gemini's own `response_schema` option. The cross-client `response_format` option (which is what `AgentFactory` from `agent_framework_declarative` populates from `outputSchema`) only triggered `response_mime_type=application/json` but left `response_schema` unset, so Gemini received JSON mode with no schema.
`python/packages/gemini/agent_framework_gemini/_chat_client.py` previously:
```python
if options.get("response_format") or options.get("response_schema"):
kwargs["response_mime_type"] = "application/json"
if schema := options.get("response_schema"):
kwargs["response_schema"] = schema
```
Fix
When `response_schema` is not explicitly set, fall back to `response_format` and forward it. Handles both raw JSON schema dicts (what the declarative loader produces) and Pydantic `BaseModel` classes. Explicit `response_schema` continues to take precedence.
Tests
Added three regression tests in `packages/gemini/tests/test_gemini_client.py`:
```
99 passed, 8 skipped
```
`ruff check` and `ruff format --check` clean on the touched files.
Scope
Surgical change inside `_build_generate_content_config`. No public API surface change; existing tests untouched.
Fixes #5888