Skip to content

fix(vertex): project tool schemas onto the subset Google accepts - #181

Merged
stippi merged 1 commit into
mainfrom
fix/vertex-tool-schema-sanitizing
Aug 16, 2026
Merged

fix(vertex): project tool schemas onto the subset Google accepts#181
stippi merged 1 commit into
mainfrom
fix/vertex-tool-schema-sanitizing

Conversation

@stippi

@stippi stippi commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Problem

Google's Schema parser is strict and rejects the entire request over a single unknown JSON-Schema keyword anywhere in a tool declaration:

400 Invalid JSON payload received. Unknown name "exclusiveMinimum" at
'tools[0].function_declarations[4].parameters.properties[0].value': Cannot find field.

Tool schemas written against full JSON Schema — which Anthropic and OpenAI accept verbatim — therefore made every Gemini request fail. The keywords that show up in practice: exclusiveMinimum, additionalProperties, oneOf.

Fix

sanitize_google_schema projects a schema onto the documented keyword set, recursing through properties, items and anyOf. vertex.rs applies it when building function_declarations.

Dropping a constraint is deliberate and lossy: the tool's description carries the intent for the model and the caller validates arguments anyway. Losing a bound is survivable; losing every request to a 400 is not.

The function is exported because Gemini Live's BidiGenerateContent WebSocket API uses the same Schema type and needs the identical projection — the Tutor app's realtime path consumes it from here rather than keeping a second copy.

Verification

Reproduced and verified against the live API with a real 20-tool set:

  • before400 INVALID_ARGUMENT, three field violations (exclusiveMinimum ×2, additionalProperties)
  • after — request accepted, model answers normally

cargo test -p llm green (3 new tests), clippy clean, cargo fmt applied.

Google's `Schema` parser is strict and rejects the *entire request* over a
single unknown JSON-Schema keyword anywhere in a tool declaration:

    400 Invalid JSON payload received. Unknown name "exclusiveMinimum" at
    'tools[0].function_declarations[4].parameters.properties[0].value'

Tool schemas written against full JSON Schema — which Anthropic and OpenAI
accept verbatim — therefore made every Gemini request fail. `exclusiveMinimum`,
`additionalProperties` and `oneOf` are the ones that show up in practice.

`sanitize_google_schema` projects a schema onto the documented keyword set,
recursing through `properties`, `items` and `anyOf`. Dropping a constraint is
deliberate and lossy: the tool's description carries the intent for the model
and the caller validates arguments anyway — losing a bound is survivable,
losing every request to a 400 is not.

Exported, because Gemini Live's BidiGenerateContent WebSocket API uses the
same `Schema` type and needs the identical projection.
@stippi
stippi merged commit 17806e5 into main Aug 16, 2026
4 of 5 checks passed
@stippi
stippi deleted the fix/vertex-tool-schema-sanitizing branch August 16, 2026 08:02
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.

1 participant