1use crate::RunState;
2use futures::future::BoxFuture;
3use llm_sdk::{JSONSchema, Part, Tool};
4use serde_json::Value;
5use std::{error::Error, fmt::Debug};
6
7pub trait AgentTool<TCtx>: Send + Sync {
12    fn name(&self) -> String;
14    fn description(&self) -> String;
16    fn parameters(&self) -> JSONSchema;
19    fn execute<'a>(
26        &'a self,
27        args: Value,
28        context: &'a TCtx,
29        state: &'a RunState,
30    ) -> BoxFuture<'a, Result<AgentToolResult, Box<dyn Error + Send + Sync>>>;
31}
32
33impl<TCtx> Debug for dyn AgentTool<TCtx> {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        f.debug_struct("AgentTool")
36            .field("name", &self.name())
37            .field("description", &self.description())
38            .field("parameters", &self.parameters())
39            .field("execute", &"Function")
40            .finish()
41    }
42}
43
44#[derive(Clone)]
45pub struct AgentToolResult {
46    pub content: Vec<Part>,
47    pub is_error: bool,
48}
49
50impl<TCtx> From<&dyn AgentTool<TCtx>> for Tool {
51    fn from(agent_tool: &dyn AgentTool<TCtx>) -> Self {
52        Self {
53            name: agent_tool.name(),
54            description: agent_tool.description(),
55            parameters: agent_tool.parameters(),
56        }
57    }
58}