1use async_trait::async_trait;
2use serde::Serialize;
3use serde_json::Value;
4
5use crate::context::ExecutionContext;
6use crate::error::ToolError;
7use crate::result::{ToolOutput, ToolResult as ToolResultEnum};
8use crate::schema::InputSchema;
9
10pub type ToolResult<T> = Result<T, ToolError>;
12
13#[async_trait]
14pub trait Tool: Send + Sync + 'static {
15 type Output: ToolOutput + Serialize;
17
18 fn name(&self) -> &'static str;
20
21 fn description(&self) -> String;
23
24 fn input_schema(&self) -> &'static InputSchema;
26
27 async fn execute(
36 &self,
37 parameters: Value,
38 context: &ExecutionContext,
39 ) -> ToolResult<Self::Output>;
40
41 fn requires_approval(&self) -> bool {
47 true
48 }
49}
50
51#[async_trait]
52pub trait ExecutableTool: Send + Sync {
53 fn name(&self) -> &'static str;
54 fn description(&self) -> String;
55 fn input_schema(&self) -> &'static InputSchema;
56 async fn run(&self, params: Value, ctx: &ExecutionContext)
57 -> Result<ToolResultEnum, ToolError>;
58 fn requires_approval(&self) -> bool;
59}
60
61#[async_trait]
62impl<T> ExecutableTool for T
63where
64 T: Tool + Send + Sync,
65 T::Output: Into<ToolResultEnum> + Send,
66{
67 fn name(&self) -> &'static str {
68 Tool::name(self)
69 }
70
71 fn description(&self) -> String {
72 Tool::description(self)
73 }
74
75 fn input_schema(&self) -> &'static InputSchema {
76 Tool::input_schema(self)
77 }
78
79 async fn run(&self, p: Value, c: &ExecutionContext) -> Result<ToolResultEnum, ToolError> {
80 Ok(Tool::execute(self, p, c).await?.into())
81 }
82
83 fn requires_approval(&self) -> bool {
84 Tool::requires_approval(self)
85 }
86}