Skip to main content

agentlib_core/
tool.rs

1use crate::types::ToolDefinition;
2use async_trait::async_trait;
3use anyhow::{Result, anyhow};
4use std::collections::HashMap;
5use std::sync::Arc;
6
7#[async_trait]
8pub trait Tool: Send + Sync {
9    fn name(&self) -> &str;
10    fn description(&self) -> Option<&str>;
11    fn parameters(&self) -> serde_json::Value;
12    async fn call(&self, arguments: serde_json::Value) -> Result<serde_json::Value>;
13}
14
15pub struct ToolRegistry {
16    tools: HashMap<String, Arc<dyn Tool>>,
17}
18
19impl ToolRegistry {
20    pub fn new() -> Self {
21        Self {
22            tools: HashMap::new(),
23        }
24    }
25
26    pub fn register(&mut self, tool: Arc<dyn Tool>) {
27        let name = tool.name().to_string();
28        self.tools.insert(name, tool);
29    }
30
31    pub fn get(&self, name: &str) -> Option<&Arc<dyn Tool>> {
32        self.tools.get(name)
33    }
34
35    pub fn list(&self) -> Vec<ToolDefinition> {
36        self.tools.values().map(|t| ToolDefinition {
37            name: t.name().to_string(),
38            description: t.description().map(|s| s.to_string()),
39            parameters: t.parameters(),
40        }).collect()
41    }
42
43    pub async fn call_tool(&self, name: &str, arguments: serde_json::Value) -> Result<serde_json::Value> {
44        let tool = self.get(name).ok_or_else(|| anyhow!("Tool {} not found", name))?;
45        tool.call(arguments).await
46    }
47}