1use async_trait::async_trait;
4
5use crate::error::ToolError;
6
7use super::ToolFunction;
8
9pub struct SimpleTool {
11 name: String,
12 description: String,
13 parameters: Option<serde_json::Value>,
14 #[allow(clippy::type_complexity)]
15 handler: Box<
16 dyn Fn(
17 serde_json::Value,
18 ) -> std::pin::Pin<
19 Box<dyn std::future::Future<Output = Result<serde_json::Value, ToolError>> + Send>,
20 > + Send
21 + Sync,
22 >,
23}
24
25impl SimpleTool {
26 pub fn new<F, Fut>(
45 name: impl Into<String>,
46 description: impl Into<String>,
47 parameters: Option<serde_json::Value>,
48 handler: F,
49 ) -> Self
50 where
51 F: Fn(serde_json::Value) -> Fut + Send + Sync + 'static,
52 Fut: std::future::Future<Output = Result<serde_json::Value, ToolError>> + Send + 'static,
53 {
54 Self {
55 name: name.into(),
56 description: description.into(),
57 parameters,
58 handler: Box::new(move |args| Box::pin(handler(args))),
59 }
60 }
61}
62
63#[async_trait]
64impl ToolFunction for SimpleTool {
65 fn name(&self) -> &str {
66 &self.name
67 }
68 fn description(&self) -> &str {
69 &self.description
70 }
71 fn parameters(&self) -> Option<serde_json::Value> {
72 self.parameters.clone()
73 }
74 async fn call(&self, args: serde_json::Value) -> Result<serde_json::Value, ToolError> {
75 (self.handler)(args).await
76 }
77}