From dec1a2a3b855fe004a47596cb236beaf4ed256a5 Mon Sep 17 00:00:00 2001 From: Bennet Bo Fenner Date: Wed, 15 Apr 2026 10:11:44 +0200 Subject: [PATCH] gemini: Fix tool schema issues when type field is array (#53834) Closes #53919 Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] 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 Release Notes: - gemini: Fixed an issue with MCP servers specifying tools with specific schemas --- crates/language_model_core/src/tool_schema.rs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/crates/language_model_core/src/tool_schema.rs b/crates/language_model_core/src/tool_schema.rs index 0e82b2f41081469c6c04d16765e8336eb903fd94..86e6d6d137e469dc3b743a40eeb1f2f50348395b 100644 --- a/crates/language_model_core/src/tool_schema.rs +++ b/crates/language_model_core/src/tool_schema.rs @@ -118,6 +118,15 @@ fn adapt_to_json_schema_subset(json: &mut Value) -> Result<()> { } } + // Ensure that the type field is not an array. This can happen with MCP tool + // schemas that use multiple types (e.g. `["string", "number"]` or `["string", "null"]`). + if let Some(type_value) = obj.get_mut("type") + && let Some(types) = type_value.as_array() + && let Some(first_type) = types.first().cloned() + { + *type_value = first_type; + } + if matches!(obj.get("description"), Some(Value::String(_))) && !obj.contains_key("type") && !(obj.contains_key("anyOf") @@ -307,6 +316,42 @@ mod tests { ); } + #[test] + fn test_transform_array_type_to_single_type() { + let mut json = json!({ + "type": "object", + "properties": { + "projectSlugOrId": { + "type": ["string", "number"], + "description": "Project slug or numeric ID" + }, + "optionalName": { + "type": ["string", "null"], + "description": "An optional name" + } + } + }); + + adapt_to_json_schema_subset(&mut json).unwrap(); + + assert_eq!( + json, + json!({ + "type": "object", + "properties": { + "projectSlugOrId": { + "type": "string", + "description": "Project slug or numeric ID" + }, + "optionalName": { + "type": "string", + "description": "An optional name" + } + } + }) + ); + } + #[test] fn test_transform_fails_if_unsupported_keys_exist() { let mut json = json!({