Fix GoogleModelSettings.google_cached_content so request omits system_instruction, tools, and tool_config#5681
Merged
dsfaccini merged 10 commits intoJun 2, 2026
Conversation
…google_cached_content` is set Vertex AI and the Gemini API reject requests that combine `cached_content` with `system_instruction`, `tools`, or `tool_config` (`400 INVALID_ARGUMENT`: "Tool config, tools and system instruction should not be set in the request when using cached content."). The cache resource itself owns those fields. Before this change, `GoogleModelSettings.google_cached_content` was unusable in any realistic agent: as soon as the agent had a tool registered or produced a non-`None` `system_instruction`, every request would 400. Also tightens the docstring on `GoogleModelSettings.google_cached_content` to spell out the omission semantics, and adds three regression tests in `tests/models/test_google.py` covering the cache-set, cache-unset, and trivial paths via `mocker.patch.object(model.client.aio.models, 'generate_content', ...)`. Closes pydantic#5671
…ing case Collapses the three near-identical mocker-based tests for the `google_cached_content` omission fix into one parametrized test (3 cases × 2 `stream` values). The new `stream=True` axis exercises `generate_content_stream`, which shares `_build_content_and_config` with the non-streaming path — previously untested. Addresses review-tests item (a) on PR pydantic#5681.
…r tools Adds a `UserWarning` from `_build_content_and_config` whenever `google_cached_content` is set and either `system_instruction` or `tools` (and thus `tool_config`) would otherwise have been sent — the cache resource owns those fields, so they're stripped silently otherwise. The parametrized cache-content test gains an `expect_warning` axis covering all three cases. Also documents the setting and the silent-ignore caveat in `docs/models/google.md`. Addresses review items (b) and (d) on PR pydantic#5681. A VCR cassette exercising a real `cachedContents` resource (item c) is skipped — needs provisioning of a real cache via `client.caches.create()` with ≥4096 input tokens and a TTL, which is beyond simple cassette recording.
…rning Matches the formatting of neighbouring warnings in the file (`_get_deprecated_google_service_tier` etc.) — produces e.g. ``system_instruction`, `tools`, `tool_config`` instead of a bare Python list repr. Addresses auto-review thread on PR pydantic#5681.
…ls in `PromptedOutput` mode
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
When
GoogleModelSettings.google_cached_contentis set, the outgoingGenerateContentConfigno longer includessystem_instruction,tools,or
tool_config. The cache resource owns those fields; both the GeminiAPI and Vertex AI reject requests that supply them alongside
cached_contentwith400 INVALID_ARGUMENT:Before this change,
GoogleModelSettings.google_cached_contentwasunusable in any realistic agent: as soon as the agent had a tool
registered or produced a non-
Nonesystem_instruction, every requestwould 400.
Changes
pydantic_ai_slim/pydantic_ai/models/google.py::_build_content_and_config:set
system_instruction,tools, andtool_configtoNonewhengoogle_cached_contentis set; keep the existing shape otherwise.Tightened the docstring on
GoogleModelSettings.google_cached_contentto spell out the omission semantics.
Added regression tests in
tests/models/test_google.pycovering thecache-set, cache-unset, and trivial paths via
mocker.patch.object(model.client.aio.models, 'generate_content', ...),mirroring the existing
test_google_top_k_propagationpattern.Closes
GoogleModelSettings.google_cached_contentunusable: request still includessystem_instruction/tools, Vertex 400s #5671Checklist