From 40c6379ca1f98a98c5ea1bb1369719b869cb869c Mon Sep 17 00:00:00 2001 From: Nikketryhard Date: Sun, 15 Feb 2026 00:18:32 -0600 Subject: [PATCH] fix: strip $schema and unsupported JSON Schema fields from tool params MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Google's Gemini API rejects $schema, additionalProperties, $ref, $defs, default, examples, and title in tool parameter schemas. OpenCode/MCP tools include these standard JSON Schema fields. Now recursively stripped during OpenAI→Gemini tool conversion. --- src/mitm/modify.rs | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/mitm/modify.rs b/src/mitm/modify.rs index 0462dec..20b4e36 100644 --- a/src/mitm/modify.rs +++ b/src/mitm/modify.rs @@ -474,7 +474,8 @@ pub fn openai_tools_to_gemini(tools: &[Value]) -> Vec { "description": func["description"], }); if let Some(params) = func.get("parameters") { - decl["parameters"] = uppercase_types(params.clone()); + let cleaned = clean_schema_for_gemini(uppercase_types(params.clone())); + decl["parameters"] = cleaned; } Some(decl) }) @@ -487,6 +488,41 @@ pub fn openai_tools_to_gemini(tools: &[Value]) -> Vec { vec![serde_json::json!({"functionDeclarations": declarations})] } +/// Recursively strip JSON Schema fields that Google's Gemini API doesn't accept. +/// Known unsupported: $schema, additionalProperties, $ref, $defs, default, examples +fn clean_schema_for_gemini(mut val: Value) -> Value { + const STRIP_KEYS: &[&str] = &[ + "$schema", + "additionalProperties", + "$ref", + "$defs", + "default", + "examples", + "title", + ]; + + match &mut val { + Value::Object(map) => { + for key in STRIP_KEYS { + map.remove(*key); + } + let keys: Vec = map.keys().cloned().collect(); + for key in keys { + if let Some(v) = map.remove(&key) { + map.insert(key, clean_schema_for_gemini(v)); + } + } + } + Value::Array(arr) => { + for v in arr.iter_mut() { + *v = clean_schema_for_gemini(std::mem::take(v)); + } + } + _ => {} + } + val +} + /// Convert OpenAI tool_choice to Gemini toolConfig format. /// /// OpenAI: "auto" | "required" | "none" | {"type":"function","function":{"name":"X"}}