-
Couldn't load subscription status.
- Fork 93
Implement native JSON mode with schema for Gemini #983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Implement native JSON mode with schema for Gemini #983
Conversation
Enables direct use of Pydantic models for response_schema in Gemini API calls when json_mode=True. Includes updates to warnings for strict mode and relevant unit tests.
|
@willbakst can you please confirm if my recent commits look good? |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #983 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 511 511
Lines 21072 21172 +100
==========================================
+ Hits 21072 21172 +100
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| ] | ||
|
|
||
| if json_mode: | ||
| if json_mode or (response_model and getattr(response_model, "model_config", {}).get("strict", False)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the null check on response_model should guarantee the presence of model_config, so you can do something like this:
if json_mode or (response_model and response_model.model_config.get("strict", False)): ...| messages[-1]["parts"].append( # pyright: ignore [reportTypedDictNotRequiredAccess, reportOptionalMemberAccess, reportArgumentType] | ||
| PartDict(text=_utils.json_mode_content(response_model)) | ||
| ) # pyright: ignore [reportTypedDictNotRequiredAccess, reportOptionalMemberAccess, reportArgumentType] | ||
| config.response_mime_type = "application/json" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was previously inside of the if not tools: ... check because it's possible to set both response_model and tools. We need to make sure that if both are set we don't force the response into application/json since the model may want to respond with a tool call.
| config.response_mime_type = "application/json" | ||
| if response_model: | ||
| config.response_schema = response_model | ||
| elif not tools: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why move this inside of this check for not tools? Previously we've always included this json mode content message.
Implement native JSON mode with schema for Gemini
Closes #472
This pull request enhances the Google Gemini integration within Mirascope to support native, schema-constrained JSON outputs, aligning with the latest capabilities of the Gemini API.
Key Changes & Motivations:
Native Gemini JSON Mode (
response_schema):@llm.call(provider="google", ...)(or the older@google_call) withjson_mode=Trueand a Pydanticresponse_model, Mirascope now directly passes the Pydantic model to thegeneration_config.response_schemaparameter of the Google Gemini API.json_mode=Trueis used without aresponse_model(and no tools are specified), a generic prompt instructing the model to output JSON is still appended to the messages, maintaining existing behavior for that scenario.Updated Warning for Strict Outputs:
BaseTool(triggered whenmodel_config={"strict": True}is used on aresponse_model) has been updated to include"google"in its list of providers that support such strict structured outputs whenjson_mode=True. This reflects the new capability.Unit Tests:
tests/core/google/_utils/test_setup_call.pyto specifically verify the new logic:response_schemais correctly set with the Pydantic model.response_mime_typeis set to"application/json"._utils.json_mode_content) is not invoked whenresponse_schemais active.Minor Docstring Fix:
json_modemtojson_modein the docstring ofgoogle_callinmirascope/core/google/_call.py.How to Test:
Reviewers can test this by:
googleextra (uv pip install -e ".[google]").GOOGLE_API_KEYenvironment variable.@llm.call(provider="google", response_model=MyModel, json_mode=True).MyModel.pytestto ensure the new and existing unit tests pass, particularlytests/core/google/_utils/test_setup_call.py.This change aims to provide a more robust and idiomatic integration with Gemini's evolving features for structured data extraction.