tools: Tool is Copy, clean dispatch without Arc clone

Tool derives Copy (all fields are Copy: &'static str + fn pointer).
dispatch_with_agent copies the Tool out of the agent lock guard,
drops the guard, then calls the handler. No Arc cloning needed.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-04 16:25:42 -04:00 committed by Kent Overstreet
parent d9e1c2c59f
commit d195160b1e

View file

@ -37,6 +37,7 @@ pub type ToolHandler = fn(
/// A tool with its definition and handler — single source of truth. /// A tool with its definition and handler — single source of truth.
/// Strings are static — the tool list JSON can be built without /// Strings are static — the tool list JSON can be built without
/// serialization by interpolating these directly. /// serialization by interpolating these directly.
#[derive(Clone, Copy)]
pub struct Tool { pub struct Tool {
pub name: &'static str, pub name: &'static str,
pub description: &'static str, pub description: &'static str,
@ -173,27 +174,18 @@ pub async fn dispatch_with_agent(
agent: Option<std::sync::Arc<tokio::sync::Mutex<super::Agent>>>, agent: Option<std::sync::Arc<tokio::sync::Mutex<super::Agent>>>,
) -> String { ) -> String {
// Look up in agent's tools if available, otherwise global // Look up in agent's tools if available, otherwise global
if let Some(ref agent) = agent { let tool = if let Some(ref a) = agent {
let agent_guard = agent.lock().await; let guard = a.lock().await;
if let Some(tool) = agent_guard.tools.iter().find(|t| t.name == name) { guard.tools.iter().find(|t| t.name == name).copied()
let handler = tool.handler; } else {
drop(agent_guard); None
return match handler(Some(agent.clone()), args.clone()).await { };
Ok(s) => s, let tool = tool.or_else(|| tools().into_iter().find(|t| t.name == name));
Err(e) => format!("Error: {}", e), match tool {
}; Some(t) => (t.handler)(agent, args.clone()).await
} .unwrap_or_else(|e| format!("Error: {}", e)),
None => format!("Error: Unknown tool: {}", name),
} }
// Fallback to global registry
for tool in tools() {
if tool.name == name {
return match (tool.handler)(agent, args.clone()).await {
Ok(s) => s,
Err(e) => format!("Error: {}", e),
};
}
}
format!("Error: Unknown tool: {}", name)
} }
/// Dispatch shared tools — used by subconscious agents. /// Dispatch shared tools — used by subconscious agents.