1use async_trait::async_trait;
4
5use crate::Result;
6use crate::llm::ToolDefinition;
7
8use super::tool::{Tool, ToolResult};
9
10pub struct SimpleTool<F>
12where
13 F: Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<String>> + Send>>
14 + Send
15 + Sync,
16{
17 name: String,
18 description: String,
19 func: F,
20}
21
22impl<F> SimpleTool<F>
23where
24 F: Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<String>> + Send>>
25 + Send
26 + Sync,
27{
28 pub fn new(name: impl Into<String>, description: impl Into<String>, func: F) -> Self {
29 Self {
30 name: name.into(),
31 description: description.into(),
32 func,
33 }
34 }
35}
36
37#[async_trait]
38impl<F> Tool for SimpleTool<F>
39where
40 F: Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<String>> + Send>>
41 + Send
42 + Sync,
43{
44 fn name(&self) -> &str {
45 &self.name
46 }
47
48 fn description(&self) -> &str {
49 &self.description
50 }
51
52 fn definition(&self) -> ToolDefinition {
53 ToolDefinition::new(&self.name, &self.description, serde_json::Map::new())
54 }
55
56 async fn execute(&self, _args: serde_json::Value) -> Result<ToolResult> {
57 let content = (self.func)().await?;
58 Ok(ToolResult::new("", content))
59 }
60}