tools: add Tool registry with handlers
Tool struct wraps ToolDef + async handler function. tools() returns the complete registry — single source of truth for definitions and dispatch. Handler signature: fn(Option<Arc<Mutex<Agent>>>, Value) -> BoxFuture<Result<String>> All tools registered: file ops, bash, web, vision, memory (15 tools), channels (4 tools), control (3 tools). Working stack removed from registry (will be replaced). Old dispatch functions remain for now — next step is to route dispatch through the registry. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
1a13534946
commit
3e6c77e31e
2 changed files with 62 additions and 17 deletions
|
|
@ -235,24 +235,63 @@ pub async fn dispatch_shared(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return all tool definitions (agent-specific + shared + memory).
|
/// Return all registered tools with definitions + handlers.
|
||||||
|
pub fn tools() -> Vec<Tool> {
|
||||||
|
vec![
|
||||||
|
// File tools
|
||||||
|
Tool { def: read::definition(), handler: |_a, v| Box::pin(async move { read::read_file(&v) }) },
|
||||||
|
Tool { def: write::definition(), handler: |_a, v| Box::pin(async move { write::write_file(&v) }) },
|
||||||
|
Tool { def: edit::definition(), handler: |_a, v| Box::pin(async move { edit::edit_file(&v) }) },
|
||||||
|
Tool { def: grep::definition(), handler: |_a, v| Box::pin(async move { grep::grep(&v) }) },
|
||||||
|
Tool { def: glob::definition(), handler: |_a, v| Box::pin(async move { glob::glob_search(&v) }) },
|
||||||
|
|
||||||
|
// Execution tools
|
||||||
|
Tool { def: bash::definition(), handler: |_a, v| Box::pin(async move { bash::run_bash(&v).await }) },
|
||||||
|
Tool { def: web::fetch_definition(), handler: |_a, v| Box::pin(async move { web::web_fetch(&v).await }) },
|
||||||
|
Tool { def: web::search_definition(), handler: |_a, v| Box::pin(async move { web::web_search(&v).await }) },
|
||||||
|
|
||||||
|
// Vision
|
||||||
|
Tool { def: vision::definition(), handler: |_a, v| Box::pin(async move { vision::view_image_text(&v) }) },
|
||||||
|
|
||||||
|
// Memory tools
|
||||||
|
Tool { def: memory::render_def(), handler: |_a, v| Box::pin(async move { memory::render(&v) }) },
|
||||||
|
Tool { def: memory::write_def(), handler: |_a, v| Box::pin(async move { memory::write(&v) }) },
|
||||||
|
Tool { def: memory::search_def(), handler: |_a, v| Box::pin(async move { memory::search(&v) }) },
|
||||||
|
Tool { def: memory::links_def(), handler: |_a, v| Box::pin(async move { memory::links(&v) }) },
|
||||||
|
Tool { def: memory::link_set_def(), handler: |_a, v| Box::pin(async move { memory::link_set(&v) }) },
|
||||||
|
Tool { def: memory::link_add_def(), handler: |_a, v| Box::pin(async move { memory::link_add(&v) }) },
|
||||||
|
Tool { def: memory::used_def(), handler: |_a, v| Box::pin(async move { memory::used(&v) }) },
|
||||||
|
Tool { def: memory::weight_set_def(), handler: |_a, v| Box::pin(async move { memory::weight_set(&v) }) },
|
||||||
|
Tool { def: memory::rename_def(), handler: |_a, v| Box::pin(async move { memory::rename(&v) }) },
|
||||||
|
Tool { def: memory::supersede_def(), handler: |_a, v| Box::pin(async move { memory::supersede(&v) }) },
|
||||||
|
Tool { def: memory::query_def(), handler: |_a, v| Box::pin(async move { memory::query(&v) }) },
|
||||||
|
Tool { def: memory::output_def(), handler: |_a, v| Box::pin(async move { memory::output(&v) }) },
|
||||||
|
|
||||||
|
// Channel tools
|
||||||
|
Tool { def: channels::definitions()[0].clone(), handler: |_a, v| Box::pin(async move { channels::dispatch("channel_list", &v).await }) },
|
||||||
|
Tool { def: channels::definitions()[1].clone(), handler: |_a, v| Box::pin(async move { channels::dispatch("channel_recv", &v).await }) },
|
||||||
|
Tool { def: channels::definitions()[2].clone(), handler: |_a, v| Box::pin(async move { channels::dispatch("channel_send", &v).await }) },
|
||||||
|
Tool { def: channels::definitions()[3].clone(), handler: |_a, v| Box::pin(async move { channels::dispatch("channel_notifications", &v).await }) },
|
||||||
|
|
||||||
|
// Control tools
|
||||||
|
Tool { def: control::definitions()[0].clone(),
|
||||||
|
handler: |_a, _v| Box::pin(async { Ok("Pausing autonomous behavior. Only user input will wake you.".into()) }) },
|
||||||
|
Tool { def: control::definitions()[1].clone(),
|
||||||
|
handler: |_a, v| Box::pin(async move {
|
||||||
|
let model = v.get("model").and_then(|v| v.as_str()).unwrap_or("");
|
||||||
|
Ok(format!("Switching to model: {}", model))
|
||||||
|
}) },
|
||||||
|
Tool { def: control::definitions()[2].clone(),
|
||||||
|
handler: |_a, v| Box::pin(async move {
|
||||||
|
let msg = v.get("message").and_then(|v| v.as_str()).unwrap_or("(yielding to user)");
|
||||||
|
Ok(msg.to_string())
|
||||||
|
}) },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return all tool definitions (extracted from tools()).
|
||||||
pub fn definitions() -> Vec<ToolDef> {
|
pub fn definitions() -> Vec<ToolDef> {
|
||||||
let mut defs = vec![
|
tools().into_iter().map(|t| t.def).collect()
|
||||||
vision::definition(),
|
|
||||||
working_stack::definition(),
|
|
||||||
read::definition(),
|
|
||||||
write::definition(),
|
|
||||||
edit::definition(),
|
|
||||||
bash::definition(),
|
|
||||||
web::fetch_definition(),
|
|
||||||
web::search_definition(),
|
|
||||||
grep::definition(),
|
|
||||||
glob::definition(),
|
|
||||||
];
|
|
||||||
defs.extend(control::definitions());
|
|
||||||
defs.extend(channels::definitions());
|
|
||||||
defs.extend(memory::definitions());
|
|
||||||
defs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return memory + journal tool definitions only.
|
/// Return memory + journal tool definitions only.
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,12 @@ pub(super) fn definition() -> ToolDef {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Text-only version for the Tool registry.
|
||||||
|
pub fn view_image_text(args: &serde_json::Value) -> anyhow::Result<String> {
|
||||||
|
let output = view_image(args)?;
|
||||||
|
Ok(output.text)
|
||||||
|
}
|
||||||
|
|
||||||
/// View an image file or capture a tmux pane.
|
/// View an image file or capture a tmux pane.
|
||||||
pub(super) fn view_image(args: &serde_json::Value) -> Result<ToolOutput> {
|
pub(super) fn view_image(args: &serde_json::Value) -> Result<ToolOutput> {
|
||||||
let a: Args = serde_json::from_value(args.clone())
|
let a: Args = serde_json::from_value(args.clone())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue