Skip to content

fix: carry functionDeclaration parameters into google_genai tool translation - #35921

Closed
Aryan-Kochhar wants to merge 2 commits into
BerriAI:litellm_internal_stagingfrom
Aryan-Kochhar:litellm_google_genai_function_declaration_parameters
Closed

Aryan-Kochhar wants to merge 2 commits into
BerriAI:litellm_internal_stagingfrom
Aryan-Kochhar:litellm_google_genai_function_declaration_parameters

Conversation

@Aryan-Kochhar

@Aryan-Kochhar Aryan-Kochhar commented Aug 5, 2026 •

Copy link
Copy Markdown

TLDR

Problem this solves:

  • Gemini tools using parameters lose their argument schema
  • The model then invents its own argument names
  • normalize_tool_schema never receives the uppercase types it handles

How it solves it:

  • Read parameters when parametersJsonSchema is absent
  • normalize_tool_schema then lowercases the Schema type enums
  • parametersJsonSchema still wins when both are present

Relevant issues

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

Screenshots / Proof of Fix

The adapter only runs when the backing provider has no native generateContent config, so the
config below points a Gemini model at Google's OpenAI compatible endpoint. That routes the request
through GoogleGenAIAdapter rather than the native Gemini path, which is the code this PR changes

model_list:
  - model_name: bridged-model
    litellm_params:
      model: openai/gemini-3.6-flash
      api_base: https://generativelanguage.googleapis.com/v1beta/openai
      api_key: os.environ/GEMINI_API_KEY

general_settings:
  master_key: sk-1234
python litellm/proxy/proxy_cli.py --config config.yaml --port 4000

The tool below declares zx_ident and rev_no in parameters. Those names cannot be guessed, so
whether the schema survived translation is visible in the response

curl -s http://localhost:4000/v1beta/models/bridged-model:generateContent \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer sk-1234' \
  -d '{"contents":[{"role":"user","parts":[{"text":"Fetch record ABC-123 at revision 7."}]}],"tools":[{"functionDeclarations":[{"name":"fetch_record","description":"Fetch a stored record","parameters":{"type":"OBJECT","properties":{"zx_ident":{"type":"STRING","description":"Record identifier"},"rev_no":{"type":"INTEGER","description":"Revision number"}},"required":["zx_ident","rev_no"]}}]}]}'

Before, at 4fcaf7d:

{"candidates":[{"content":{"parts":[{"functionCall":{"name":"fetch_record","args":{"id":"ABC-123","revision":7}}}],"role":"model"},"finishReason":"STOP","index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":30,"candidatesTokenCount":24,"totalTokenCount":421}}

The model returned id and revision, which it invented, because it never saw the declared names.
A caller dispatching on zx_ident and rev_no gets nothing it can use

After, at 0c44266:

{"candidates":[{"content":{"parts":[{"functionCall":{"name":"fetch_record","args":{"zx_ident":"ABC-123","rev_no":7}}}],"role":"model"},"finishReason":"STOP","index":0,"safetyRatings":[]}],"usageMetadata":{"promptTokenCount":88,"candidatesTokenCount":28,"totalTokenCount":209}}

The argument names now match the declaration. promptTokenCount going from 30 to 88 is the schema
itself reaching the model, and the uppercase OBJECT, STRING and INTEGER enums were lowercased
on the way through by the existing normalize_tool_schema call

Type

🐛 Bug Fix

Changes

Google GenAI function declarations carry their argument schema in parameters, a Schema whose type
enums are uppercase, as well as in the newer parametersJsonSchema. _transform_google_genai_tools_to_openai
only read parametersJsonSchema, so a tool declared with parameters was translated into an OpenAI
tool carrying no parameters key at all

The same method already calls normalize_tool_schema, whose job is lowercasing uppercase Schema
type enums. Nothing on this path could produce uppercase types, since parametersJsonSchema is
already standard JSON Schema, so that normalizer was unreachable for the input it was written for.
Reading parameters fixes the dropped schema and makes the existing normalization do its job

litellm/google_genai/adapters/transformation.py gains a two line fallback. parametersJsonSchema
keeps precedence when both fields are present, so existing behavior is unchanged

tests/test_litellm/google_genai/test_google_genai_adapter_fixes.py gains three tests covering the
parameters path including uppercase type normalization, the precedence rule, and a declaration
carrying no argument schema

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

…slation

Google GenAI function declarations carry their argument schema in `parameters`
(a Schema, whose type enums are uppercase) as well as in the newer
`parametersJsonSchema`. The adapter only read `parametersJsonSchema`, so any
tool declared with `parameters` reached the model with no argument schema at
all and could not be called correctly

Reading `parameters` as a fallback also makes the existing `normalize_tool_schema`
call reachable for its intended input; it lowercases the uppercase Schema type
enums, which is what that normalizer was written for
@CLAassistant

CLAassistant commented Aug 5, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@Aryan-Kochhar

Copy link
Copy Markdown
Author

recheck

@greptile-apps

greptile-apps Bot commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR preserves functionDeclaration.parameters when parametersJsonSchema is absent while retaining the newer field's precedence

  • Adds fallback translation for the legacy Gemini parameter schema
  • Adds regression coverage for normalization, precedence, and schema-less declarations

Confidence Score: 5/5

The PR appears safe to merge because no blocking functional failure remains

greptile previously said the docstring concern was resolved, but the three newly introduced docstrings remain contrary to the repository guidance; this is convention cleanup rather than a merge-blocking failure

Important Files Changed

Filename Overview
litellm/google_genai/adapters/transformation.py Adds the intended fallback from parametersJsonSchema to parameters without changing precedence
tests/test_litellm/google_genai/test_google_genai_adapter_fixes.py Adds focused regression coverage for both schema representations and declarations without parameters

Reviews (2): Last reviewed commit: "test: shorten the parameters schema test..." | Re-trigger Greptile

Comment thread tests/test_litellm/google_genai/test_google_genai_adapter_fixes.py Outdated
Matches the single line docstrings the other tests in this file already use
@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed

codspeed Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing Aryan-Kochhar:litellm_google_genai_function_declaration_parameters (b06809a) with litellm_internal_staging (732bba0)

Open in CodSpeed

@Aryan-Kochhar

Copy link
Copy Markdown
Author

@greptileai

@mateo-berri

Copy link
Copy Markdown
Contributor

Closing since #42067 landed this fix along with response_schema forwarding and regression tests. Thanks Aryan-Kochhar for surfacing the dropped parameters

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants