gemini: Fix tool schema issues when type field is array (#53834)

Bennet Bo Fenner created

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

Change summary

crates/language_model_core/src/tool_schema.rs | 45 +++++++++++++++++++++
1 file changed, 45 insertions(+)

Detailed changes

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!({