fix: tool call race conditions and missing completions tool result extraction

- store.rs: record_function_call now falls back to active_cascade_id
  (matching record_usage behavior) instead of blind _latest fallback
- store.rs: add cascade-aware take_function_calls(cascade_id) method
  with priority: exact match → active cascade → _latest → any key
- completions.rs: extract tool_calls from assistant messages and tool
  results from tool messages, storing them for MITM injection. This was
  the ROOT CAUSE — the completions handler stored tool definitions but
  never extracted tool results, so modify_request couldn't rewrite the
  LS conversation history with proper functionCall/functionResponse
- responses.rs: use cascade-aware take_function_calls for consistency
This commit is contained in:
Nikketryhard
2026-02-16 18:43:16 -06:00
parent 38b4130c55
commit 6bda2ecafa
3 changed files with 153 additions and 7 deletions

View File

@@ -599,7 +599,7 @@ async fn handle_responses_sync(
let start = std::time::Instant::now();
while start.elapsed().as_secs() < timeout {
// Check for function calls
let captured = state.mitm_store.take_any_function_calls().await;
let captured = state.mitm_store.take_function_calls(&cascade_id).await;
if let Some(ref raw_calls) = captured {
let calls: Vec<_> = if let Some(max) = params.max_tool_calls {
raw_calls.iter().take(max as usize).collect()
@@ -715,7 +715,7 @@ async fn handle_responses_sync(
let msg_id = format!("msg_{}", uuid::Uuid::new_v4().to_string().replace('-', ""));
// Check for captured function calls from MITM (clears the active flag)
let captured_tool_calls = state.mitm_store.take_any_function_calls().await;
let captured_tool_calls = state.mitm_store.take_function_calls(&cascade_id).await;
// Enforce max_tool_calls limit
let captured_tool_calls = captured_tool_calls.map(|mut calls| {
@@ -909,7 +909,7 @@ async fn handle_responses_stream(
}
// Check for function calls first
let captured = state.mitm_store.take_any_function_calls().await;
let captured = state.mitm_store.take_function_calls(&cascade_id).await;
if let Some(ref raw_calls) = captured {
let calls: Vec<_> = if let Some(max) = params.max_tool_calls {
raw_calls.iter().take(max as usize).collect()