From ef4af8f92415f6f3082a2d373fadb5883f8adee1 Mon Sep 17 00:00:00 2001 From: Om Chillure Date: Sun, 29 Mar 2026 22:01:42 +0530 Subject: [PATCH] Fix/gemini tool schema unsupported keys (#52670) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Summary The Gemini API enforces strict validation on `function_declarations` and rejects requests containing unsupported JSON Schema keywords such as `additionalProperties`, `propertyNames`. This caused Write mode to fail with "failed to stream completion" when tools with complex schemas were used. This PR strips these unsupported keywords from tool schemas before sending them to the Gemini API in `adapt_to_json_schema_subset`. ### How to Review - Check `crates/language_model/src/tool_schema.rs` — the `adapt_to_json_schema_subset` function now removes `additionalProperties` and `propertyNames` from schemas. - Tests are added covering removal of these keys and nested schema handling. - To reproduce the original issue, send a tool schema containing `propertyNames` or `additionalProperties` to the Gemini API — it returns HTTP 400 `INVALID_ARGUMENT` ### How to Test Run the unit tests: ```sh cargo test -p language_model ``` OR manually reproduce this using -> ``` curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=YOUR_KEY" \ -H 'Content-Type: application/json' \ -d '{"contents":[{"parts":[{"text":"test"}]}],"tools":[{"functionDeclarations":[{"name":"test","parameters":{"type":"OBJECT","properties":{"field":{"type":"OBJECT","propertyNames":{"pattern":"^[a-z]+$"},"additionalProperties":{"type":"STRING"}}}}}]}]}' ``` #### Closes #52430 - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Video [Screencast from 2026-03-29 08-32-18.webm](https://github.com/user-attachments/assets/a0069f0e-1f2b-45dc-85bf-f24aacb08599) ### Note : Reopens previous work from closed PR #52644 (fork was deleted) Release Notes: - Fixed an issue where Gemini models would not work when using specific MCP servers --- crates/language_model/src/tool_schema.rs | 29 ++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/crates/language_model/src/tool_schema.rs b/crates/language_model/src/tool_schema.rs index 6fbb3761b43ea04924aaa23373920c41a14c74e3..69afcd1f288064748e3c953a27003361ed5115b0 100644 --- a/crates/language_model/src/tool_schema.rs +++ b/crates/language_model/src/tool_schema.rs @@ -105,9 +105,12 @@ fn adapt_to_json_schema_subset(json: &mut Value) -> Result<()> { ); } - const KEYS_TO_REMOVE: [(&str, fn(&Value) -> bool); 5] = [ + const KEYS_TO_REMOVE: [(&str, fn(&Value) -> bool); 6] = [ ("format", |value| value.is_string()), - ("additionalProperties", |value| value.is_boolean()), + // Gemini doesn't support `additionalProperties` in any form (boolean or schema object) + ("additionalProperties", |_| true), + // Gemini doesn't support `propertyNames` + ("propertyNames", |_| true), ("exclusiveMinimum", |value| value.is_number()), ("exclusiveMaximum", |value| value.is_number()), ("optional", |value| value.is_boolean()), @@ -234,6 +237,28 @@ mod tests { "format": {}, }) ); + + // additionalProperties as an object schema is also unsupported by Gemini + let mut json = json!({ + "type": "object", + "properties": { + "name": { "type": "string" } + }, + "additionalProperties": { "type": "string" }, + "propertyNames": { "pattern": "^[A-Za-z]+$" } + }); + + adapt_to_json_schema_subset(&mut json).unwrap(); + + assert_eq!( + json, + json!({ + "type": "object", + "properties": { + "name": { "type": "string" } + } + }) + ); } #[test]