Add Structured Output Support for Gemini API #140
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.
Add Structured Output Support for Gemini API
Closes #139
What This Does
Implements structured output support for Google Gemini API to get reliable JSON responses without parsing headaches. Works automatically with Gemini while keeping Ollama working exactly as before.
This uses the latest
google-genaiclient library which has native support for structured outputs, replacing the older approach of parsing JSON from text responses.Why This Matters
The old approach had Gemini sometimes returning malformed JSON that we'd have to parse out of markdown code blocks. Now we get clean, validated JSON directly from the API.
Before:
```json\n{"name": "John"}\n```After:
{"name": "John"}Changes
Core Files
models.py
google-genaiclient integration for structured outputresponse_schemato Gemini API callsllm_utils.py
parse_llm_response()- detects if response is already structuredsupports_structured_output()- checks provider capabilitiespdf.py & evaluator.py
Schema Fixes
Had to remove some Pydantic field constraints that Gemini's API didn't like:
ge=0,gt=0(caused exclusiveMinimum errors)min_length=1,max_items=5(validation conflicts)le=20(maximum value issues)These were nice-to-haves for validation but not critical. The important validation still happens in our code.
Testing
Ran through the smoke tests from CONTRIBUTING.md:
Tested with:
gemini-2.5-flash- structured output working perfectlygemma3:4bvia Ollama - traditional parsing still worksUsage
Nothing changes for users. The code detects your provider and does the right thing: