Repository navigation
fix(ai): send Gemini tool schemas as parametersJsonSchema - #51009
Merged
Merged
Conversation
The Gemini protocol projected tool schemas into Google's legacy OpenAPI
subset for the `parameters` field. The projection dropped $ref, $defs,
and additionalProperties, stringified enum values, and still produced
schemas Gemini rejects: Vertex (and the Zen gateway, which reaches Gemini
through Vertex) requires a type on every node, and the API rejects
properties on non-object types. Most of Vercel's MCP tools failed, and
accepted calls came back with wrong argument types ("3" for an integer
enum, JSON strings for referenced objects).
Send tool schemas in `parametersJsonSchema`, which accepts standard JSON
Schema, and rewrite only the shapes it still rejects: `required` entries
without a declared property, draft-04 boolean exclusive bounds, draft-07
tuple items, and recursive $ref loops that do not pass through an
optional property or potentially empty array items.
This was referenced Sep 24, 2026
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.
Problem
The Gemini protocol (Google AI Studio, Vertex Gemini, and Gemini on the Zen gateway) sent tool schemas in the legacy
parametersfield. That field only accepts Google's OpenAPI-subset schema, soGeminiToolSchema.convertprojected every tool schema into it. The projection was lossy and still produced schemas Gemini rejects:typeon every node, so anyconst, untyped enum, or untyped field fails with "didn't specify the schema type field". The API also rejectspropertieson non-object types. Tuples,prefixItems, anditems: truefail everywhere. Vercel's MCP toolset (169 tools, sent in 5 chunks) failed in 4 of 5 chunks on Vertex and Zen, and 3 of 5 on the API.$ref/$defs,additionalProperties, andoneOfdetail are dropped and enum values are stringified, so Gemini fills arguments with the wrong types. In forced tool calls: integer enums came back as"3", referenced objects andoneOfunions came back as JSON strings, andadditionalPropertiesmaps came back empty (0/3 correct in each scenario).Change
gemini.ts: tool declarations useparametersJsonSchema, which accepts standard JSON Schema.utils/gemini-json-schema.ts: rewrites only the shapesparametersJsonSchemastill rejects, each verified live:requiredentries with no declared property are removed.exclusiveMinimum/exclusiveMaximumbecome the numeric form (seen in a real Vercel tool).items: [...](+additionalItems) becomeprefixItems(+items).$refloop that passes through an optional property or potentially empty arrayitems. Other self-references become{}. The main real-world case is Zod's JSON-value schema, whose loop goes throughadditionalProperties. Wrapping the ref as nullable does not satisfy Gemini (tested).const,default,enum,examples, anddependentRequiredis never rewritten.GeminiToolSchemastays for the separatetoolSchema: "gemini"compatibility mode on OpenAI-compatible routes, which this PR does not touch.Verification
Live through the V2 client on Gemini API, Vertex, and Zen (
gemini-3.8-flash). The corpus has 45 schemas, including a regression case for every past Gemini schema fix, plus Vercel's full MCP toolset:The only remaining rejections are synthetic schemas nested 24+ levels deep.
parametersJsonSchemaallows about 15 nestedpropertieslevels, versus about 31 forparameters. No real schema tested comes close; Vercel's deepest is 13.Known limitation, unchanged by this PR: Gemini cannot reliably fill a free-form "any JSON value" parameter with either field.
Tests:
gemini.test.tscovers the normalizer rules and sending standard JSON Schema unchanged. The three cassettes whose request bodies contain tool declarations (google-vertex/calls-a-tool,google-vertex/continues-after-a-tool-result,pdf/gemini-tool-result) were re-recorded.bun testinpackages/ai: 1505 pass.bun run check: 35/35.