fix: prevent tool_rounds cross-cascade contamination causing hangs

Root cause: proxy.rs eagerly pushed tool rounds via push_tool_round_calls
when intercepting Google's functionCall response. These stale rounds leaked
into LS follow-up requests, producing malformed history that Google timed
out on (60s 'no upstream response').

Changes:
- Remove push_tool_round_calls from proxy.rs response interception
- proxy.rs: use get_tool_rounds (non-destructive) instead of take_tool_rounds
  so accumulated rounds persist across multiple LS requests per cascade
- responses.rs/gemini.rs: build rounds via take+push+set pattern — each
  handler accumulates its own rounds from get_last_function_calls + results
- completions.rs: unchanged (set_tool_rounds replaces from messages)
- clear_tools: also clears tool_rounds to prevent stale data between sessions
- store.rs: add get_tool_rounds (non-destructive clone) method
This commit is contained in:
Nikketryhard
2026-02-16 19:21:03 -06:00
parent 32f02d6456
commit ba96534ead
4 changed files with 31 additions and 14 deletions

View File

@@ -484,6 +484,8 @@ impl MitmStore {
pub async fn clear_tools(&self) {
*self.active_tools.write().await = None;
*self.active_tool_config.write().await = None;
// Also clear accumulated tool rounds to prevent stale data
self.tool_rounds.write().await.clear();
}
/// Set active tool config (Gemini toolConfig format).
@@ -537,6 +539,13 @@ impl MitmStore {
std::mem::take(&mut *self.tool_rounds.write().await)
}
/// Get (non-destructive clone) multi-round tool call history.
/// Used by proxy.rs to read rounds without consuming them, so they
/// persist across multiple LS requests in the same cascade.
pub async fn get_tool_rounds(&self) -> Vec<ToolRound> {
self.tool_rounds.read().await.clone()
}
/// Push a new tool round from Google's response (calls only, results empty).
/// Called by proxy.rs when the MITM intercepts functionCall parts.
pub async fn push_tool_round_calls(&self, calls: Vec<CapturedFunctionCall>) {