tools: modernize working_stack, remove special-case dispatch

working_stack now uses the Tool format with an Agent handle —
it locks the agent and modifies the stack directly. The special-case
interception in the turn loop is removed. All tools go through
the unified registry dispatch.

Also passes agent handle to all spawned tool tasks so any tool
that needs Agent access can use it.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-04 16:14:27 -04:00 committed by Kent Overstreet
parent 37fad63ba9
commit e9b26f5d45
3 changed files with 38 additions and 116 deletions

View file

@ -355,8 +355,9 @@ impl Agent {
.unwrap_or(false);
let call_id = call.id.clone();
let call_name = call.function.name.clone();
let agent_handle = agent.clone();
let handle = tokio::spawn(async move {
let output = tools::dispatch(&call.function.name, &args).await;
let output = tools::dispatch_with_agent(&call.function.name, &args, Some(agent_handle)).await;
(call, output)
});
active_tools.lock().unwrap().push(
@ -598,22 +599,11 @@ impl Agent {
args_summary: args_summary.clone(),
});
// working_stack needs &mut Agent — brief lock
if call.function.name == "working_stack" {
let mut me = agent.lock().await;
let result = tools::working_stack::handle(&args, &mut me.context.working_stack);
let output = result.clone();
me.apply_tool_result(call, output, ui_tx, ds);
if !result.starts_with("Error:") {
me.refresh_context_state();
}
return;
}
// Spawn tool, track it
let call_clone = call.clone();
let agent_handle = agent.clone();
let handle = tokio::spawn(async move {
let output = tools::dispatch(&call_clone.function.name, &args).await;
let output = tools::dispatch_with_agent(&call_clone.function.name, &args, Some(agent_handle)).await;
(call_clone, output)
});
active_tools.lock().unwrap().push(