From 7e16a7b8925d36a188167218b07072a816213ef1 Mon Sep 17 00:00:00 2001 From: Nikketryhard Date: Sat, 14 Feb 2026 23:10:45 -0600 Subject: [PATCH] fix: clear stale tool state in completions handler to prevent hang Tool definitions stored in MitmStore from /v1/responses requests were persisting and getting injected into /v1/chat/completions requests. This caused Gemini to return functionCalls instead of text, and since the completions handler has no function call handling logic, it would poll forever waiting for text that never came. Fix: clear active_tools, active_tool_config, and has_active_function_call at the start of handle_completions. Also add clear_active_function_call() method to MitmStore. --- src/api/completions.rs | 6 ++++++ src/mitm/store.rs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/api/completions.rs b/src/api/completions.rs index 3f9dde0..d0a4f6c 100644 --- a/src/api/completions.rs +++ b/src/api/completions.rs @@ -78,6 +78,12 @@ pub(crate) async fn handle_completions( } }; + // Clear any stale tool definitions from other endpoints (e.g. /v1/responses) + // to prevent them leaking into completions requests. The completions endpoint + // does not support our custom tool call flow, so tools must never be injected. + state.mitm_store.clear_tools().await; + state.mitm_store.clear_active_function_call(); + let token = state.backend.oauth_token().await; if token.is_empty() { return err_response( diff --git a/src/mitm/store.rs b/src/mitm/store.rs index 8144cb0..f497721 100644 --- a/src/mitm/store.rs +++ b/src/mitm/store.rs @@ -252,6 +252,11 @@ impl MitmStore { self.has_active_function_call.load(Ordering::SeqCst) } + /// Force-clear the active function call flag (used to reset stale state). + pub fn clear_active_function_call(&self) { + self.has_active_function_call.store(false, Ordering::SeqCst); + } + /// Check if there are pending function calls for a cascade. pub async fn has_pending_function_calls(&self, cascade_id: &str) -> bool { let pending = self.pending_function_calls.read().await;