Repository navigation
fix(lite_llm): honor capability for schema and tools - #6955
JimmyWang0417 wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Thanks for picking this up. Confirming it fixes the issue: tested against a live provider, since that was the gap noted in the PR description. Reporter of #6954. Setup: branch Baseline on released With this branch, default Two function calls per turn, which is the minimum: The conservative default looks right. LiteLLM cannot answer this question even in principle, since it reports the two capabilities independently and has no API for the combination: litellm.supports_response_schema(model="openrouter/google/gemini-3.1-flash-lite") # True
litellm.supports_function_calling(model="openrouter/google/gemini-3.1-flash-lite") # TrueBoth True while the combination still loops, so opt-in is the only correct direction. LGTM from my side. |
|
Heads up that Worth doing soon: #5057 fixed the equivalent problem on the native Gemini path and went stale partly for this reason. |
|
Thank you for taking the time to test this with a live provider and for the careful review. Your detailed comparison of the tool-call counts was very helpful and made the regression much clearer. You were also right to point out that the Google CLA had not been signed. I overlooked it before opening the PR, and I’m sorry that this delayed the review. The CLA is now signed and the check is passing. Your test confirms the fix for Thanks again for catching the issue and for the thorough, responsible review. |
LiteLlm cannot infer whether every provider supports combining an output schema with tools, so report the capability conservatively by default and allow explicit opt-in for known-compatible models. Keep the capability-only option out of LiteLLM completion arguments. Fixes google#6954
4333de9 to
ced2d36
Compare
|
Following up on my previous reply, I reran the same two-turn reproducer on the current PR head and its base using OpenRouter. Environment: Python 3.13.9,
A turn reaching the 8-call safety limit is counted as not completing normally; this reproduces the reported repeated-tool-call issue. The PR head completed all six turns with the expected call sequence: I also checked The focused unit-test suite also passes: The wall-time values are included only as observations from this capped reproducer, not as a general performance benchmark. These results validate the reported OpenRouter/model path and are not intended to generalize to every LiteLLM provider or model. |
Resolve LiteLlm capabilities per model via litellm.supports_response_schema with provider-level fallbacks and explicit Gemini and Claude model family gating. Providers with native schema support (e.g. OpenAI, Azure OpenAI) continue to pair schemas directly with tools, even when using custom deployment names missing from litellm's static model map. Models that cannot combine structured outputs with function calling (such as Claude models across direct Anthropic or third-party aggregator routes and Gemini models accessed via LiteLLM/OpenRouter) and any unmapped providers not affirmed by litellm's static map conservatively default to output_schema_and_tools=False, falling back to SetModelResponseTool instead of looping. Users with custom routing requirements can subclass LiteLlm and override capabilities. Merge #6955 Closes #6954 PiperOrigin-RevId: 985404522
|
Thank you @JimmyWang0417 for your contribution! 🎉 Your changes have been successfully imported and merged via Copybara in commit e37af14. Closing this PR as the changes are now in the main branch. |
What's going on
LiteLlm.capabilitiesreportedoutput_schema_and_tools=Truefor everyprovider and model it wrapped. For providers that cannot combine an output
schema with tools, ADK therefore skipped the
SetModelResponseToolfallbackand could repeatedly call tools instead of returning structured output.
The fix
False) by default.output_schema_and_toolsconstructor argument so callerscan opt in for a known-compatible provider/model combination.
LiteLlmandGemma3Ollama.Closes #6954
Testing Plan
Unit Tests
completion-argument filtering.
pytest -q tests/unittests/models/test_capabilities.py tests/unittests/models/test_litellm.py tests/unittests/models/test_gemma_llm.py tests/unittests/utils/test_output_schema_utils.py tests/unittests/flows/llm_flows/test_basic_processor.py tests/unittests/flows/llm_flows/test_output_schema_processor.py(514 passed)ruff checkandpyink --checkon all changed Python files.python -m compileallandgit diff --check.Manual End-to-End (E2E) Tests
base using the same two-turn script, one deterministic tool, one Pydantic
output schema, and one session.
Environment and method:
86b2e5baaa487558b10fc9f2b48fe0d4ceefb755ced2d36f601224ef867daf0da4505caf082b3f3d3.13.9; source checkout reportsgoogle-adk 2.8.0litellm 1.98.0,google-genai 2.22.0,pydantic 2.13.5openrouter/<model-id>route for the Gemini models; credentials and endpointare intentionally omitted.
was bounded with
RunConfig(max_llm_calls=8)to prevent an unbounded baselineloop from consuming credits.
Primary reproduction (
gemini-3.1-flash-lite, three independent runs, twoturns per run):
86b2e5bTrue1, 8, 8, 8, 8, 8ced2d36False2, 2, 2, 2, 2, 2On the PR head every turn followed
get_current_time -> set_model_response, returned a validCityTimeobject, and terminated. On thebase, five of six turns reached the eight-call safety limit while repeatedly
calling
get_current_time; the remaining turn returned structured outputwithout the fallback tool. This is the same failure mode described in #6954.
*Wall time is the observed wall time of this bounded gateway run, not a
benchmark. Base runs that hit the call limit are not successful completions, so
the primary evidence is the call sequence, termination, and structured-output
validity. The independent live OpenRouter validation in the issue reporter's
PR comment
also measured 4/12/18/19 baseline calls versus exactly 2 calls per turn on the
fix, and is limited to
openrouter/google/gemini-3.1-flash-lite.Checklist
environment and results above).