use std::sync::Arc;
use motosan_agent_tool::Tool;
pub mod bash;
pub mod context;
pub mod edit;
pub mod find;
pub mod grep;
pub mod ls;
pub mod read;
pub mod write;
pub use bash::BashTool;
pub use context::{SharedCancelToken, ToolCtx, ToolProgressChunk};
pub use edit::EditTool;
pub use find::FindTool;
pub use grep::GrepTool;
pub use ls::LsTool;
pub use read::ReadTool;
pub use write::WriteTool;
pub fn builtin_tools(ctx: ToolCtx) -> Vec<Arc<dyn Tool>> {
let ctx = Arc::new(ctx);
vec![
Arc::new(ReadTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
Arc::new(BashTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
Arc::new(WriteTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
Arc::new(EditTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
Arc::new(GrepTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
Arc::new(FindTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
Arc::new(LsTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
]
}
#[cfg(test)]
mod tests {
use super::*;
use crate::permissions::NoOpPermissionGate;
use tokio::sync::mpsc;
fn test_ctx() -> ToolCtx {
let (tx, _rx) = mpsc::channel(8);
let cwd = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
ToolCtx::new(cwd, Arc::new(NoOpPermissionGate), tx)
}
#[test]
fn builtin_tools_contains_all_seven() {
let tools = builtin_tools(test_ctx());
let names = tools.iter().map(|tool| tool.def().name).collect::<Vec<_>>();
assert_eq!(tools.len(), 7);
for expected in ["read", "bash", "write", "edit", "grep", "find", "ls"] {
assert!(names.contains(&expected.to_string()), "missing {expected}");
}
}
}