Skip to main content

rs_adk/tool/
simple.rs

1//! Simple function tool that wraps an async closure.
2
3use async_trait::async_trait;
4
5use crate::error::ToolError;
6
7use super::ToolFunction;
8
9/// Simple function tool that wraps an async closure.
10pub 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    /// Create a new simple function tool.
27    ///
28    /// # Examples
29    ///
30    /// ```rust,ignore
31    /// use rs_adk::tool::SimpleTool;
32    /// use serde_json::json;
33    ///
34    /// let tool = SimpleTool::new(
35    ///     "greet",
36    ///     "Greet a user by name",
37    ///     Some(json!({"type": "object", "properties": {"name": {"type": "string"}}, "required": ["name"]})),
38    ///     |args| async move {
39    ///         let name = args["name"].as_str().unwrap_or("World");
40    ///         Ok(json!({"greeting": format!("Hello, {name}!")}))
41    ///     },
42    /// );
43    /// ```
44    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}