1use anyhow::Error;
3use std::pin::Pin;
4
5pub trait Tool: Send + Sync {
7 fn name(&self) -> &str;
9
10 fn description(&self) -> &str;
11
12 fn invoke(&self, input: &str) -> Pin<Box<dyn std::future::Future<Output = Result<String, Error>> + Send + '_>>;
14
15 fn as_any(&self) -> &dyn std::any::Any;
17}
18
19pub trait Toolkit {
21 fn tools(&self) -> Vec<Box<dyn Tool>>;
23}
24
25pub 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 fn as_any(&self) -> &dyn std::any::Any {
60 self
61 }
62}
63
64pub 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 Vec::new()
86 }
87}
88
89impl Clone for ExampleToolkit {
91 fn clone(&self) -> Self {
92 let mut toolkit = ExampleToolkit::new();
93 for tool in &self.tools {
95 let name = tool.name();
96 let description = tool.description();
97 let new_tool = Box::new(ExampleTool::new(name.to_string(), description.to_string()));
99 toolkit.add_tool(new_tool);
100 }
101 toolkit
102 }
103}