1use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5
6use crate::Result;
7use crate::llm::ToolDefinition;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct ToolResult {
12 pub tool_call_id: String,
14 pub content: String,
16 #[serde(default)]
18 pub ephemeral: bool,
19}
20
21impl ToolResult {
22 pub fn new(tool_call_id: impl Into<String>, content: impl Into<String>) -> Self {
23 Self {
24 tool_call_id: tool_call_id.into(),
25 content: content.into(),
26 ephemeral: false,
27 }
28 }
29
30 pub fn with_ephemeral(mut self, ephemeral: bool) -> Self {
31 self.ephemeral = ephemeral;
32 self
33 }
34}
35
36#[async_trait]
38pub trait Tool: Send + Sync {
39 fn name(&self) -> &str;
41
42 fn description(&self) -> &str;
44
45 fn definition(&self) -> ToolDefinition;
47
48 async fn execute(&self, args: serde_json::Value) -> Result<ToolResult>;
50
51 fn ephemeral(&self) -> EphemeralConfig {
53 EphemeralConfig::None
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Default)]
59pub enum EphemeralConfig {
60 #[default]
62 None,
63 Single,
65 Count(usize),
67}