1use harness_core::{Action, Tool, ToolError, ToolResult, ToolSchema, World};
4use std::collections::HashMap;
5use std::sync::Arc;
6
7#[derive(Default)]
8pub struct ToolRegistry {
9 tools: HashMap<String, Arc<dyn Tool>>,
10}
11
12impl ToolRegistry {
13 pub fn new() -> Self {
14 Self::default()
15 }
16
17 pub fn insert(&mut self, t: Arc<dyn Tool>) {
18 self.tools.insert(t.name().to_string(), t);
19 }
20
21 pub fn schemas(&self) -> Vec<ToolSchema> {
22 self.tools.values().map(|t| t.schema().clone()).collect()
23 }
24
25 pub async fn dispatch(
26 &self,
27 action: &Action,
28 world: &mut World,
29 ) -> Result<ToolResult, ToolError> {
30 let tool = self
31 .tools
32 .get(&action.tool)
33 .ok_or_else(|| ToolError::NotFound {
34 name: action.tool.clone(),
35 })?
36 .clone();
37 tool.invoke(action.args.clone(), world).await
38 }
39
40 pub fn len(&self) -> usize {
41 self.tools.len()
42 }
43 pub fn is_empty(&self) -> bool {
44 self.tools.is_empty()
45 }
46}