diff --git a/src/agent/tools/mod.rs b/src/agent/tools/mod.rs index 560a42c..cb0b65b 100644 --- a/src/agent/tools/mod.rs +++ b/src/agent/tools/mod.rs @@ -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 { + 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 { - let mut defs = vec![ - 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 + tools().into_iter().map(|t| t.def).collect() } /// Return memory + journal tool definitions only. diff --git a/src/agent/tools/vision.rs b/src/agent/tools/vision.rs index 03dc763..02bdcfa 100644 --- a/src/agent/tools/vision.rs +++ b/src/agent/tools/vision.rs @@ -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 { + let output = view_image(args)?; + Ok(output.text) +} + /// View an image file or capture a tmux pane. pub(super) fn view_image(args: &serde_json::Value) -> Result { let a: Args = serde_json::from_value(args.clone())