rust_agent/tools/
tool.rs

1// Tool interface and implementation
2use anyhow::Error;
3use std::pin::Pin;
4
5// Minimal tool interface (aligned with langchain-core)
6pub trait Tool: Send + Sync {
7    // Basic tool information
8    fn name(&self) -> &str;
9    
10    fn description(&self) -> &str;
11    
12    // Core execution method
13    fn invoke(&self, input: &str) -> Pin<Box<dyn std::future::Future<Output = Result<String, Error>> + Send + '_>>;
14    
15    // Add as_any method to support runtime type checking
16    fn as_any(&self) -> &dyn std::any::Any;
17}
18
19// Toolkit interface
20pub trait Toolkit {
21    // Get all tools
22    fn tools(&self) -> Vec<Box<dyn Tool>>;
23}
24
25// Example tool implementation - for demonstration purposes
26pub struct ExampleTool {
27    name: String,
28    description: String,
29}
30
31impl ExampleTool {
32    pub fn new(name: String, description: String) -> Self {
33        Self {
34            name,
35            description,
36        }
37    }
38}
39
40impl Tool for ExampleTool {
41    fn name(&self) -> &str {
42        &self.name
43    }
44    
45    fn description(&self) -> &str {
46        &self.description
47    }
48    
49    fn invoke(&self, input: &str) -> Pin<Box<dyn std::future::Future<Output = Result<String, Error>> + Send + '_>> {
50        let input_str = input.to_string();
51        let name = self.name.clone();
52        
53        Box::pin(async move {
54            Ok(format!("Tool {} received input: {}", name, input_str))
55        })
56    }
57    
58    // Implement as_any method to support runtime type checking
59    fn as_any(&self) -> &dyn std::any::Any {
60        self
61    }
62}
63
64// Example toolkit implementation
65pub struct ExampleToolkit {
66    tools: Vec<Box<dyn Tool>>,
67}
68
69impl ExampleToolkit {
70    pub fn new() -> Self {
71        let tools: Vec<Box<dyn Tool>> = Vec::new();
72        Self {
73            tools,
74        }
75    }
76    
77    pub fn add_tool(&mut self, tool: Box<dyn Tool>) {
78        self.tools.push(tool);
79    }
80}
81
82impl Toolkit for ExampleToolkit {
83    fn tools(&self) -> Vec<Box<dyn Tool>> {
84        // Since Box<dyn Tool> cannot be directly cloned, return an empty vector as minimal implementation
85        Vec::new()
86    }
87}
88
89// Implement Clone trait for ExampleToolkit
90impl Clone for ExampleToolkit {
91    fn clone(&self) -> Self {
92        let mut toolkit = ExampleToolkit::new();
93        // Since Tool trait doesn't require Clone, we implement cloning by creating new instances
94        for tool in &self.tools {
95            let name = tool.name();
96            let description = tool.description();
97            // Create a new ExampleTool as a clone
98            let new_tool = Box::new(ExampleTool::new(name.to_string(), description.to_string()));
99            toolkit.add_tool(new_tool);
100        }
101        toolkit
102    }
103}