fix(google): gate mixed Gemini tools - #2035
Merged
Merged
Conversation
🦋 Changeset detectedLatest commit: 22e9167 The changes in this PR will be included in the next version bump. This PR includes changesets to release 36 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Keep mocked provider-boundary coverage from replacing credentialed integration clients, and cover tool-choice mapping plus retry-stable configs. Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid replacing caller-supplied function-calling settings when mixed tools only require the server-side invocation flag. Co-authored-by: Cursor <cursoragent@cursor.com>
toubatbrian
approved these changes
Jul 15, 2026
Merged
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
Port livekit/agents#6426 to the JS Google plugin.
toolsandtoolConfiginLLM.chat()instead ofLLMStream.run().tools/toolConfigwhencachedContentis active, including rawextraKwargsvalues.Source diff coverage
Coverage classification
livekit-plugins/livekit-plugins-google/livekit/plugins/google/llm.pyplugins/google/src/llm.tschat(), added tool-choice mapping helper, gated mixed function/provider tools to Gemini 3 Developer API (gemini-3and not Vertex AI), and moved cache-related tool suppression out of stream execution. Adapted naming and target-specificgeminiToolssupport.livekit-plugins/livekit-plugins-google/livekit/plugins/google/utils.pyplugins/google/src/utils.ts(tools, mixed)return shape and warning/drop behavior when mixed tools are not allowed. Adapted to treat bothgeminiToolsandGeminiToolprovider tools as built-in/provider tools in the JS API.livekit-plugins/livekit-plugins-google/livekit/plugins/google/realtime/realtime_api.pyplugins/google/src/realtime/realtime_api.tstoToolsConfig()tuple. No realtime behavior change beyond matching the new helper contract.tests/test_plugin_google_llm.pyplugins/google/src/llm.test.tsGoogleGenAIclient and the targettoolCtxAPI. No extra tests beyond source parity.Verification
pnpm test plugins/googlepasses: 3 files, 15 passed, 2 skipped.pnpm --filter @livekit/agents-plugin-google buildpasses.pnpm --filter @livekit/agents-plugin-google lintexits 0 with existing warnings inplugins/google/src/realtime/realtime_api.ts.pnpm buildpasses.pnpm lintexits 0 with existing warnings across the repo.Infrastructure gaps
None. The target already had Google provider tools, cached content, and request-config testing infrastructure; the required helper contract changes were ported as part of this PR.
Ported from livekit/agents#6426
Original PR description
Follow-up to #6416 (mixed built-in + function tool support). Two things: a correctness fix (Vertex) and a structural cleanup (move request shaping into
chat()).Why
include_server_side_tool_invocationson Vertex too, producing a request Vertex rejects.tool_configconstruction lived inLLMStream._run()even though all its inputs (tools,tool_choice, model,vertexai,cached_content) are known atchat()time. That forced a build-then-mutate pattern, a duplicated mixed-tools predicate, and a build-then-pop()cache dance.What changed
is_gemini_3_api = _is_gemini_3_model(model) and not client.vertexai. On Vertex, mixing falls back to single-type tool use with a warning instead of an unsupported request.tool_configconstruction from_run()intochat(). Builds theToolConfigonce;_run()now owns only what depends on the formatted context (system_instructiondropping) and no longer mutates shared request state on retry.if/elseinchat()(skip building tools when cached) instead of build-then-pop(). Honorscached_contentfrom either the constructor orextra_kwargs.create_tools_configreturns(tools, mixed)and is the single source of truth for whether built-in + function tools are actually combined, so the server-side-invocation flag can't drift from what's sent.Note on
tool_choice="auto"AUTOis passed through as-is alongside the circulation flag (noAUTO→VALIDATEDupgrade). Verified live against the Gemini 3 Developer API:AUTO+ built-in tools is accepted.Tests
New request-capture tests in
test_plugin_google_llm.pycovering: Dev-API mixed path, Vertex fallback, non-Gemini-3 fallback, provider-tools-only,tool_choice="auto"passthrough, and cache-via-extra_kwargssuppression. All 21 google LLM tests pass; ruff clean.🤖 Generated with Claude Code
Cue voice E2E
sid_9f619be36f11at headb79ec082.developerApiMixedTools=true, function toolget_weather, andtoolChoiceMode=AUTO; the spoken turn completed asRequest shape verified.~/.cue-cli/sessions/sid_9f619be36f11/.22e91679custom-function-config fix is covered by a red-green request-boundary regression test; the final focused suite passes 12/12.