use super::ToolDefinition;
use super::toolproxy::{ProxyTool, ProxyMetadata};
pub struct ToolRegistry {
proxy_tools: Vec<ProxyTool>,
}
impl ToolRegistry {
pub fn new() -> Self {
Self {
proxy_tools: Vec::new(),
}
}
pub fn register(&mut self, tool: ProxyTool) {
if self.proxy_tools.iter().any(|t| t.definition().name == tool.definition().name) {
log::warn!(
"Proxy tool '{}' already exists, will be replaced",
tool.definition().name
);
self.proxy_tools.retain(|t| t.definition().name != tool.definition().name);
}
self.proxy_tools.push(tool);
}
pub fn register_batch(&mut self, tools: Vec<ProxyTool>) {
for tool in tools {
self.register(tool);
}
}
pub fn proxy_definitions(&self) -> Vec<ToolDefinition> {
self.proxy_tools.iter().map(|t| t.definition()).collect()
}
pub fn proxy_tools(&self) -> &[ProxyTool] {
&self.proxy_tools
}
pub fn find_proxy(&self, name: &str) -> Option<&ProxyTool> {
self.proxy_tools.iter().find(|t| t.definition().name == name)
}
pub fn count(&self) -> usize {
self.proxy_tools.len()
}
pub fn is_proxy(&self, name: &str) -> bool {
self.proxy_tools.iter().any(|t| t.definition().name == name)
}
pub fn get_metadata(&self, name: &str) -> Option<&ProxyMetadata> {
self.proxy_tools
.iter()
.find(|t| t.definition().name == name)
.map(|t| t.metadata())
}
pub fn clear(&mut self) {
self.proxy_tools.clear();
}
}
impl Default for ToolRegistry {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn test_registry_creation() {
let registry = ToolRegistry::new();
assert_eq!(registry.count(), 0);
}
#[test]
fn test_register_proxy_tool() {
let mut registry = ToolRegistry::new();
let proxy_tool = ProxyTool::new(
ToolDefinition {
name: "custom_search".to_string(),
description: "自定义搜索".to_string(),
parameters: json!({"type": "object"}),
..Default::default()
},
ProxyMetadata {
tool_type: "search".to_string(),
endpoint: None,
timeout_ms: 1000,
custom: None,
},
);
registry.register(proxy_tool);
assert_eq!(registry.count(), 1);
assert!(registry.is_proxy("custom_search"));
assert!(registry.find_proxy("custom_search").is_some());
}
#[test]
fn test_proxy_definitions() {
let mut registry = ToolRegistry::new();
registry.register(ProxyTool::new(
ToolDefinition {
name: "test".to_string(),
description: "Test".to_string(),
parameters: json!({}),
..Default::default()
},
ProxyMetadata {
tool_type: "test".to_string(),
endpoint: None,
timeout_ms: 1000,
custom: None,
},
));
let definitions = registry.proxy_definitions();
assert_eq!(definitions.len(), 1);
assert_eq!(definitions[0].name, "test");
}
}