From 1a7c81e5f9b4b266661ed2db857c05fb15dbad16 Mon Sep 17 00:00:00 2001 From: Nikketryhard Date: Sat, 14 Feb 2026 18:53:38 -0600 Subject: [PATCH] feat: strip ALL tools from intercepted requests by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tools are only needed by the Antigravity webview for tool-call UI. Our proxy doesn't need them — the model generates text responses fine without tool definitions. Stripping all 20 tools saves ~15KB per request. --- src/mitm/modify.rs | 62 +++++++++++++--------------------------------- 1 file changed, 17 insertions(+), 45 deletions(-) diff --git a/src/mitm/modify.rs b/src/mitm/modify.rs index 825f881..d32783a 100644 --- a/src/mitm/modify.rs +++ b/src/mitm/modify.rs @@ -7,21 +7,10 @@ use serde_json::Value; use tracing::info; -/// Tools to KEEP — essential coding tools. Everything else gets stripped. -const KEEP_TOOLS: &[&str] = &[ - "view_file", - "write_to_file", - "replace_file_content", - "multi_replace_file_content", - "run_command", - "command_status", - "send_command_input", - "grep_search", - "find_by_name", - "list_dir", - "view_file_outline", - "view_code_item", -]; +/// Whether to strip ALL tool definitions (default: true). +/// The model generates responses fine without them — tools are only +/// needed by the Antigravity webview, not by our proxy. +const STRIP_ALL_TOOLS: bool = true; /// System instruction sections to STRIP (matched by XML tag name). /// These are verbose instructional manuals that add tokens but don't @@ -124,24 +113,17 @@ pub fn modify_request(body: &[u8]) -> Option> { } } - // ── 3. Strip non-essential tools ───────────────────────────────────── - if let Some(tools) = json - .pointer_mut("/request/tools") - .and_then(|v| v.as_array_mut()) - { - let before = tools.len(); - - tools.retain(|tool| { - if let Some(name) = tool["functionDeclarations"][0]["name"].as_str() { - KEEP_TOOLS.contains(&name) - } else { - true // keep unknown structure + // ── 3. Strip tool definitions ──────────────────────────────────────── + if STRIP_ALL_TOOLS { + if let Some(tools) = json + .pointer_mut("/request/tools") + .and_then(|v| v.as_array_mut()) + { + let count = tools.len(); + if count > 0 { + tools.clear(); + changes.push(format!("strip all {count} tools")); } - }); - - let removed = before - tools.len(); - if removed > 0 { - changes.push(format!("strip {removed}/{before} tools (keep {})", KEEP_TOOLS.len())); } } @@ -255,7 +237,7 @@ mod tests { } #[test] - fn test_modify_strips_tools() { + fn test_modify_strips_all_tools() { let body = serde_json::json!({ "project": "test", "requestId": "test/1", @@ -265,7 +247,6 @@ mod tests { {"functionDeclarations": [{"name": "view_file", "description": "view", "parameters": {}}]}, {"functionDeclarations": [{"name": "browser_subagent", "description": "browse", "parameters": {}}]}, {"functionDeclarations": [{"name": "grep_search", "description": "grep", "parameters": {}}]}, - {"functionDeclarations": [{"name": "generate_image", "description": "img", "parameters": {}}]}, ], "generationConfig": {} }, @@ -276,17 +257,8 @@ mod tests { let modified = modify_request(&bytes).unwrap(); let result: Value = serde_json::from_slice(&modified).unwrap(); - let tool_names: Vec<&str> = result["request"]["tools"] - .as_array() - .unwrap() - .iter() - .map(|t| t["functionDeclarations"][0]["name"].as_str().unwrap()) - .collect(); - - assert!(tool_names.contains(&"view_file")); - assert!(tool_names.contains(&"grep_search")); - assert!(!tool_names.contains(&"browser_subagent")); - assert!(!tool_names.contains(&"generate_image")); + let tools = result["request"]["tools"].as_array().unwrap(); + assert!(tools.is_empty(), "all tools should be stripped"); } #[test]