Skip to main content

matrixcode_core/tools/
registry.rs

1//! Tool Registry
2//!
3//! 工具注册中心 - 仅管理代理工具
4
5use super::ToolDefinition;
6use super::toolproxy::{ProxyTool, ProxyMetadata};
7
8/// 工具注册中心 - 仅管理代理工具(内置工具由 Agent 直接管理)
9pub struct ToolRegistry {
10    /// 代理工具(外部注入的工具)
11    proxy_tools: Vec<ProxyTool>,
12}
13
14impl ToolRegistry {
15    /// 创建空的工具注册中心
16    pub fn new() -> Self {
17        Self {
18            proxy_tools: Vec::new(),
19        }
20    }
21    
22    /// 注册代理工具
23    pub fn register(&mut self, tool: ProxyTool) {
24        // 检查工具名称冲突
25        if self.proxy_tools.iter().any(|t| t.definition().name == tool.definition().name) {
26            log::warn!(
27                "Proxy tool '{}' already exists, will be replaced",
28                tool.definition().name
29            );
30            // 移除旧的
31            self.proxy_tools.retain(|t| t.definition().name != tool.definition().name);
32        }
33        
34        self.proxy_tools.push(tool);
35    }
36    
37    /// 批量注册代理工具
38    pub fn register_batch(&mut self, tools: Vec<ProxyTool>) {
39        for tool in tools {
40            self.register(tool);
41        }
42    }
43    
44    /// 获取所有代理工具定义(用于提交给大模型)
45    pub fn proxy_definitions(&self) -> Vec<ToolDefinition> {
46        self.proxy_tools.iter().map(|t| t.definition()).collect()
47    }
48    
49    /// 获取所有代理工具
50    pub fn proxy_tools(&self) -> &[ProxyTool] {
51        &self.proxy_tools
52    }
53    
54    /// 查找代理工具
55    pub fn find_proxy(&self, name: &str) -> Option<&ProxyTool> {
56        self.proxy_tools.iter().find(|t| t.definition().name == name)
57    }
58    
59    /// 获取代理工具数量
60    pub fn count(&self) -> usize {
61        self.proxy_tools.len()
62    }
63    
64    /// 检查是否是代理工具
65    pub fn is_proxy(&self, name: &str) -> bool {
66        self.proxy_tools.iter().any(|t| t.definition().name == name)
67    }
68    
69    /// 获取代理工具元数据
70    pub fn get_metadata(&self, name: &str) -> Option<&ProxyMetadata> {
71        self.proxy_tools
72            .iter()
73            .find(|t| t.definition().name == name)
74            .map(|t| t.metadata())
75    }
76    
77    /// 清空所有代理工具
78    pub fn clear(&mut self) {
79        self.proxy_tools.clear();
80    }
81}
82
83impl Default for ToolRegistry {
84    fn default() -> Self {
85        Self::new()
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92    use serde_json::json;
93    
94    #[test]
95    fn test_registry_creation() {
96        let registry = ToolRegistry::new();
97        assert_eq!(registry.count(), 0);
98    }
99    
100    #[test]
101    fn test_register_proxy_tool() {
102        let mut registry = ToolRegistry::new();
103
104        let proxy_tool = ProxyTool::new(
105            ToolDefinition {
106                name: "custom_search".to_string(),
107                description: "自定义搜索".to_string(),
108                parameters: json!({"type": "object"}),
109                ..Default::default()
110            },
111            ProxyMetadata {
112                tool_type: "search".to_string(),
113                endpoint: None,
114                timeout_ms: 1000,
115                custom: None,
116            },
117        );
118        
119        registry.register(proxy_tool);
120        
121        assert_eq!(registry.count(), 1);
122        assert!(registry.is_proxy("custom_search"));
123        assert!(registry.find_proxy("custom_search").is_some());
124    }
125    
126    #[test]
127    fn test_proxy_definitions() {
128        let mut registry = ToolRegistry::new();
129
130        registry.register(ProxyTool::new(
131            ToolDefinition {
132                name: "test".to_string(),
133                description: "Test".to_string(),
134                parameters: json!({}),
135                ..Default::default()
136            },
137            ProxyMetadata {
138                tool_type: "test".to_string(),
139                endpoint: None,
140                timeout_ms: 1000,
141                custom: None,
142            },
143        ));
144        
145        let definitions = registry.proxy_definitions();
146        assert_eq!(definitions.len(), 1);
147        assert_eq!(definitions[0].name, "test");
148    }
149}