Skip to main content

ai_agents_core/traits/
tool.rs

1//! Tool trait for external capabilities
2
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ToolResult {
10    pub success: bool,
11    pub output: String,
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub metadata: Option<HashMap<String, Value>>,
14}
15
16impl ToolResult {
17    pub fn ok(output: impl Into<String>) -> Self {
18        Self {
19            success: true,
20            output: output.into(),
21            metadata: None,
22        }
23    }
24
25    pub fn ok_with_metadata(output: impl Into<String>, metadata: HashMap<String, Value>) -> Self {
26        Self {
27            success: true,
28            output: output.into(),
29            metadata: Some(metadata),
30        }
31    }
32
33    pub fn error(error: impl Into<String>) -> Self {
34        Self {
35            success: false,
36            output: error.into(),
37            metadata: None,
38        }
39    }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct ToolInfo {
44    pub id: String,
45    pub name: String,
46    pub description: String,
47    pub input_schema: Value,
48}
49
50/// Core tool trait for external capabilities.
51///
52/// Implement this to add custom tools that the agent can invoke during conversation.
53/// Built-in tools use `generate_schema::<T>()` from `ai-agents-tools` with
54/// `schemars::JsonSchema` to derive input schemas automatically.
55#[async_trait]
56pub trait Tool: Send + Sync {
57    /// Unique identifier for this tool (e.g. `"calculator"`).
58    fn id(&self) -> &str;
59    /// Human-readable display name.
60    fn name(&self) -> &str;
61    /// Description shown to the LLM for tool selection.
62    fn description(&self) -> &str;
63    /// JSON Schema describing expected input arguments.
64    fn input_schema(&self) -> Value;
65
66    /// Execute the tool with the given arguments and return a result.
67    async fn execute(&self, args: Value) -> ToolResult;
68
69    /// Returns a [`ToolInfo`] struct from the above methods.
70    fn info(&self) -> ToolInfo {
71        ToolInfo {
72            id: self.id().to_string(),
73            name: self.name().to_string(),
74            description: self.description().to_string(),
75            input_schema: self.input_schema(),
76        }
77    }
78}