1use std::sync::Arc;
2
3use motosan_agent_tool::Tool;
4
5pub mod bash;
6pub mod context;
7pub mod edit;
8pub mod find;
9pub mod grep;
10pub mod ls;
11pub mod read;
12pub mod write;
13
14pub use bash::BashTool;
15pub use context::{SharedCancelToken, ToolCtx, ToolProgressChunk};
16pub use edit::EditTool;
17pub use find::FindTool;
18pub use grep::GrepTool;
19pub use ls::LsTool;
20pub use read::ReadTool;
21pub use write::WriteTool;
22
23pub fn builtin_tools(ctx: ToolCtx) -> Vec<Arc<dyn Tool>> {
24 let ctx = Arc::new(ctx);
25 vec![
26 Arc::new(ReadTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
27 Arc::new(BashTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
28 Arc::new(WriteTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
29 Arc::new(EditTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
30 Arc::new(GrepTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
31 Arc::new(FindTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
32 Arc::new(LsTool::new(Arc::clone(&ctx))) as Arc<dyn Tool>,
33 ]
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use crate::permissions::NoOpPermissionGate;
40 use tokio::sync::mpsc;
41
42 fn test_ctx() -> ToolCtx {
43 let (tx, _rx) = mpsc::channel(8);
44 let cwd = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
45 ToolCtx::new(cwd, Arc::new(NoOpPermissionGate), tx)
46 }
47
48 #[test]
49 fn builtin_tools_contains_all_seven() {
50 let tools = builtin_tools(test_ctx());
51 let names = tools.iter().map(|tool| tool.def().name).collect::<Vec<_>>();
52 assert_eq!(tools.len(), 7);
53 for expected in ["read", "bash", "write", "edit", "grep", "find", "ls"] {
54 assert!(names.contains(&expected.to_string()), "missing {expected}");
55 }
56 }
57}