sh_layer3/builtin_tools/
adapter.rs1use crate::builtin_tools::BuiltinTool;
6use async_trait::async_trait;
7use sh_layer2::{Layer2Result, Tool as Layer2Tool, ToolRegistryTrait, ToolResult};
8
9pub struct ToolAdapter {
11 inner: Box<dyn BuiltinTool>,
12}
13
14impl ToolAdapter {
15 pub fn new(tool: Box<dyn BuiltinTool>) -> Self {
16 Self { inner: tool }
17 }
18}
19
20#[async_trait]
21impl Layer2Tool for ToolAdapter {
22 fn name(&self) -> &str {
23 self.inner.name()
24 }
25
26 fn description(&self) -> &str {
27 self.inner.description()
28 }
29
30 fn parameters(&self) -> serde_json::Value {
31 self.inner.parameters_schema()
32 }
33
34 async fn execute(&self, args: &str) -> Layer2Result<ToolResult> {
35 let args_value: serde_json::Value = if args.is_empty() {
37 serde_json::Value::Object(Default::default())
38 } else {
39 serde_json::from_str(args).map_err(|e| {
40 sh_layer2::Layer2Error::AgentError(format!("Parse args error: {}", e))
41 })?
42 };
43
44 let result = self
46 .inner
47 .execute(args_value)
48 .await
49 .map_err(|e| sh_layer2::Layer2Error::AgentError(e.to_string()))?;
50
51 Ok(ToolResult {
53 tool_call_id: String::new(),
54 name: self.inner.name().to_string(),
55 content: result,
56 is_error: false,
57 })
58 }
59}
60
61pub fn register_builtin_tools(registry: &sh_layer2::ToolRegistry) -> anyhow::Result<()> {
63 use super::code::*;
64 use super::file_ops::*;
65 use super::memory_tools::*;
66 use super::search::*;
67 use super::shell::*;
68 use super::workflow_tools::*;
69
70 registry.register(Box::new(ToolAdapter::new(Box::new(ReadFileTool))))?;
72 registry.register(Box::new(ToolAdapter::new(Box::new(WriteFileTool))))?;
73 registry.register(Box::new(ToolAdapter::new(Box::new(EditFileTool))))?;
74 registry.register(Box::new(ToolAdapter::new(Box::new(ListDirectoryTool))))?;
75
76 registry.register(Box::new(ToolAdapter::new(Box::new(GrepTool))))?;
78 registry.register(Box::new(ToolAdapter::new(Box::new(GlobTool))))?;
79
80 registry.register(Box::new(ToolAdapter::new(Box::new(BashTool))))?;
82
83 registry.register(Box::new(ToolAdapter::new(Box::new(GoToDefinitionTool))))?;
85 registry.register(Box::new(ToolAdapter::new(Box::new(FindReferencesTool))))?;
86
87 registry.register(Box::new(ToolAdapter::new(Box::new(SaveMemoryTool::new()))))?;
89 registry.register(Box::new(ToolAdapter::new(Box::new(QueryMemoryTool::new()))))?;
90
91 registry.register(Box::new(ToolAdapter::new(Box::new(
93 CreateCheckpointTool::new(),
94 ))))?;
95 registry.register(Box::new(ToolAdapter::new(Box::new(
96 RestoreCheckpointTool::new(),
97 ))))?;
98
99 Ok(())
100}
101
102#[cfg(test)]
103mod tests {
104 use super::super::file_ops::ReadFileTool;
105 use super::*;
106
107 #[test]
108 fn test_adapter_creation() {
109 let tool = ToolAdapter::new(Box::new(ReadFileTool));
110 assert_eq!(tool.name(), "read_file");
111 }
112}