ai_agents_core/traits/
tool.rs1use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use std::collections::HashMap;
7
8use crate::Result;
9use crate::types::{
10 ToolCallClassification, ToolExecutionContext, ToolExecutionRecord, ToolExecutionRequest,
11 ToolPolicyBindings, ToolSafetyMetadata,
12};
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct ToolResult {
16 pub success: bool,
17 pub output: String,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub metadata: Option<HashMap<String, Value>>,
20}
21
22impl ToolResult {
23 pub fn ok(output: impl Into<String>) -> Self {
24 Self {
25 success: true,
26 output: output.into(),
27 metadata: None,
28 }
29 }
30
31 pub fn ok_with_metadata(output: impl Into<String>, metadata: HashMap<String, Value>) -> Self {
32 Self {
33 success: true,
34 output: output.into(),
35 metadata: Some(metadata),
36 }
37 }
38
39 pub fn error(error: impl Into<String>) -> Self {
40 Self {
41 success: false,
42 output: error.into(),
43 metadata: None,
44 }
45 }
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct ToolInfo {
51 pub id: String,
53 pub name: String,
55 pub description: String,
57 pub input_schema: Value,
59 #[serde(default)]
61 pub safety: ToolSafetyMetadata,
62 #[serde(default)]
64 pub policy_bindings: ToolPolicyBindings,
65}
66
67#[async_trait]
73pub trait Tool: Send + Sync {
74 fn id(&self) -> &str;
76 fn name(&self) -> &str;
78 fn description(&self) -> &str;
80 fn input_schema(&self) -> Value;
82
83 async fn execute(&self, args: Value, ctx: ToolExecutionContext) -> ToolResult;
85
86 fn policy_bindings(&self) -> ToolPolicyBindings {
88 ToolPolicyBindings::default()
89 }
90
91 fn safety_metadata(&self) -> ToolSafetyMetadata {
93 ToolSafetyMetadata::conservative_unknown()
94 }
95
96 fn classify_call(&self, _args: &Value) -> ToolCallClassification {
98 ToolCallClassification::from_metadata(&self.safety_metadata())
99 }
100
101 fn info(&self) -> ToolInfo {
103 ToolInfo {
104 id: self.id().to_string(),
105 name: self.name().to_string(),
106 description: self.description().to_string(),
107 input_schema: self.input_schema(),
108 safety: self.safety_metadata(),
109 policy_bindings: self.policy_bindings(),
110 }
111 }
112}
113
114#[async_trait]
116pub trait ToolInvoker: Send + Sync {
117 async fn invoke_tool(&self, request: ToolExecutionRequest) -> Result<ToolExecutionRecord>;
119}