Skip to main content

sh_layer3/builtin_tools/
adapter.rs

1//! # Layer 2 Tool Adapter
2//!
3//! 将 Layer 3 builtin_tools 适配为 Layer 2 Tool trait。
4
5use crate::builtin_tools::BuiltinTool;
6use async_trait::async_trait;
7use sh_layer2::{Layer2Result, Tool as Layer2Tool, ToolRegistryTrait, ToolResult};
8
9/// 适配器:将 Layer3 BuiltinTool 适配为 Layer2 Tool
10pub 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        // 解析参数
36        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        // 执行工具
45        let result = self
46            .inner
47            .execute(args_value)
48            .await
49            .map_err(|e| sh_layer2::Layer2Error::AgentError(e.to_string()))?;
50
51        // 返回 ToolResult
52        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
61/// 注册所有内置工具到 Layer 2 ToolRegistry
62pub 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    // 文件操作工具
71    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    // 搜索工具
77    registry.register(Box::new(ToolAdapter::new(Box::new(GrepTool))))?;
78    registry.register(Box::new(ToolAdapter::new(Box::new(GlobTool))))?;
79
80    // Shell 工具
81    registry.register(Box::new(ToolAdapter::new(Box::new(BashTool))))?;
82
83    // 代码分析工具
84    registry.register(Box::new(ToolAdapter::new(Box::new(GoToDefinitionTool))))?;
85    registry.register(Box::new(ToolAdapter::new(Box::new(FindReferencesTool))))?;
86
87    // 记忆工具
88    registry.register(Box::new(ToolAdapter::new(Box::new(SaveMemoryTool::new()))))?;
89    registry.register(Box::new(ToolAdapter::new(Box::new(QueryMemoryTool::new()))))?;
90
91    // 工作流工具
92    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}