Skip to main content

claude_rust_tools/application/
registry.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3
4use claude_rust_types::Tool;
5use serde_json::{Value, json};
6
7pub struct ToolRegistry {
8    tools: HashMap<String, Arc<dyn Tool>>,
9}
10
11impl ToolRegistry {
12    pub fn new() -> Self {
13        Self {
14            tools: HashMap::new(),
15        }
16    }
17
18    pub fn register(&mut self, tool: Arc<dyn Tool>) {
19        self.tools.insert(tool.name().to_string(), tool);
20    }
21
22    pub fn get(&self, name: &str) -> Option<&Arc<dyn Tool>> {
23        self.tools.get(name)
24    }
25
26    /// Look up a tool by its primary name or any of its aliases.
27    pub fn get_by_name_or_alias(&self, name: &str) -> Option<&Arc<dyn Tool>> {
28        if let Some(tool) = self.tools.get(name) {
29            return Some(tool);
30        }
31        self.tools.values().find(|t| t.aliases().contains(&name))
32    }
33
34    fn make_tool_def(t: &dyn Tool) -> Value {
35        let mut def = json!({
36            "name": t.name(),
37            "description": t.description(),
38            "input_schema": t.input_schema(),
39        });
40        if t.strict() {
41            def.as_object_mut().unwrap().insert("strict".to_string(), json!(true));
42        }
43        def
44    }
45
46    pub fn tool_definitions(&self) -> Vec<Value> {
47        self.tools
48            .values()
49            .filter(|t| !t.should_defer())
50            .map(|t| Self::make_tool_def(t.as_ref()))
51            .collect()
52    }
53
54    /// Return minimal definitions for deferred tools (name + description only).
55    pub fn deferred_tool_definitions(&self) -> Vec<Value> {
56        self.tools
57            .values()
58            .filter(|t| t.should_defer())
59            .map(|t| {
60                json!({
61                    "name": t.name(),
62                    "description": t.description(),
63                })
64            })
65            .collect()
66    }
67
68    /// Return tool definitions filtered by a predicate on the tool trait.
69    pub fn tool_definitions_filtered<F>(&self, predicate: F) -> Vec<Value>
70    where
71        F: Fn(&dyn Tool) -> bool,
72    {
73        self.tools
74            .values()
75            .filter(|t| predicate(t.as_ref()))
76            .map(|t| Self::make_tool_def(t.as_ref()))
77            .collect()
78    }
79
80    pub fn tool_names(&self) -> Vec<String> {
81        let mut names: Vec<String> = self.tools.keys().cloned().collect();
82        names.sort();
83        names
84    }
85
86    pub fn clone_excluding(&self, exclude: &[&str]) -> Self {
87        let tools = self
88            .tools
89            .iter()
90            .filter(|(name, _)| !exclude.contains(&name.as_str()))
91            .map(|(k, v)| (k.clone(), v.clone()))
92            .collect();
93        Self { tools }
94    }
95}
96
97impl Default for ToolRegistry {
98    fn default() -> Self {
99        Self::new()
100    }
101}