1pub mod async_tool;
2pub use async_tool::AsyncTool;
3
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::sync::Arc;
7
8use crate::TypeError;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct AgentToolDefinition {
12 pub name: String,
13 pub description: String,
14 pub parameters: serde_json::Value, }
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct ToolCall {
19 pub tool_name: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub call_id: Option<String>,
23 pub arguments: serde_json::Value,
24}
25
26#[derive(Debug)]
27pub struct ToolRegistry {
28 tools: HashMap<String, Box<dyn Tool + Send + Sync>>,
29 async_tools: HashMap<String, Arc<dyn AsyncTool>>,
30}
31
32pub trait Tool: Send + Sync + std::fmt::Debug {
33 fn name(&self) -> &str;
34 fn description(&self) -> &str;
35 fn parameter_schema(&self) -> serde_json::Value;
36 fn execute(&self, args: serde_json::Value) -> Result<serde_json::Value, TypeError>;
37}
38
39impl ToolRegistry {
40 pub fn new() -> Self {
41 Self {
42 tools: HashMap::new(),
43 async_tools: HashMap::new(),
44 }
45 }
46
47 pub fn register_tool(&mut self, tool: Box<dyn Tool + Send + Sync>) {
48 self.tools.insert(tool.name().to_string(), tool);
49 }
50
51 pub fn register_async_tool(&mut self, tool: Arc<dyn AsyncTool>) {
52 self.async_tools.insert(tool.name().to_string(), tool);
53 }
54
55 pub fn execute(&self, call: &ToolCall) -> Result<serde_json::Value, TypeError> {
56 self.tools
57 .get(&call.tool_name)
58 .ok_or_else(|| TypeError::Error(format!("Tool {} not found", call.tool_name)))?
59 .execute(call.arguments.clone())
60 }
61
62 pub fn get_definitions(&self) -> Vec<AgentToolDefinition> {
63 self.tools
64 .values()
65 .map(|tool| AgentToolDefinition {
66 name: tool.name().to_string(),
67 description: tool.description().to_string(),
68 parameters: tool.parameter_schema(),
69 })
70 .collect()
71 }
72
73 pub fn get_all_definitions(&self) -> Vec<AgentToolDefinition> {
75 let mut defs: Vec<AgentToolDefinition> = self
76 .tools
77 .values()
78 .map(|tool| AgentToolDefinition {
79 name: tool.name().to_string(),
80 description: tool.description().to_string(),
81 parameters: tool.parameter_schema(),
82 })
83 .collect();
84
85 for tool in self.async_tools.values() {
86 defs.push(AgentToolDefinition {
87 name: tool.name().to_string(),
88 description: tool.description().to_string(),
89 parameters: tool.parameter_schema(),
90 });
91 }
92
93 defs
94 }
95
96 pub fn get_async_tool(&self, name: &str) -> Option<Arc<dyn AsyncTool>> {
99 self.async_tools.get(name).cloned()
100 }
101
102 pub fn has_sync_tool(&self, name: &str) -> bool {
104 self.tools.contains_key(name)
105 }
106
107 pub fn len(&self) -> usize {
109 self.tools.len() + self.async_tools.len()
110 }
111
112 pub fn is_empty(&self) -> bool {
114 self.tools.is_empty() && self.async_tools.is_empty()
115 }
116}
117
118impl Default for ToolRegistry {
119 fn default() -> Self {
120 Self::new()
121 }
122}
123
124#[derive(Debug)]
125pub struct ToolCallInfo {
126 pub name: String,
127 pub arguments: serde_json::Value,
128 pub call_id: Option<String>,
129 pub result: Option<serde_json::Value>,
130}