Skip to main content

apiari_claude_sdk/
tools.rs

1//! Tool use request/result protocol types.
2//!
3//! These are convenience wrappers around the raw [`ContentBlock::ToolUse`] and
4//! [`ContentBlock::ToolResult`] variants, providing a more ergonomic API for
5//! the common case of extracting tool calls from assistant messages and
6//! constructing tool results to send back.
7
8use serde::{Deserialize, Serialize};
9
10/// A tool-use request extracted from an assistant message.
11///
12/// This is a flattened view of a [`ContentBlock::ToolUse`](crate::types::ContentBlock::ToolUse)
13/// block, convenient for pattern-matching in application code.
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct ToolUse {
16    /// Unique identifier for this tool invocation (assigned by the model).
17    pub id: String,
18    /// The tool name (e.g. `"Bash"`, `"Edit"`, `"Read"`, or an MCP tool).
19    pub name: String,
20    /// The tool input parameters as a JSON value.
21    pub input: serde_json::Value,
22}
23
24/// A tool result to send back to the model.
25///
26/// Constructed by application code after executing the requested tool.
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct ToolResult {
29    /// The `id` from the corresponding [`ToolUse`].
30    pub tool_use_id: String,
31    /// The result output (text content).
32    pub output: String,
33    /// Whether the tool execution failed.
34    pub is_error: bool,
35}
36
37impl ToolUse {
38    /// Extract all tool-use requests from an assistant message's content blocks.
39    pub fn extract_from_content(content: &[crate::types::ContentBlock]) -> Vec<Self> {
40        content
41            .iter()
42            .filter_map(|block| match block {
43                crate::types::ContentBlock::ToolUse { id, name, input } => Some(ToolUse {
44                    id: id.clone(),
45                    name: name.clone(),
46                    input: input.clone(),
47                }),
48                _ => None,
49            })
50            .collect()
51    }
52}
53
54impl ToolResult {
55    /// Create a successful tool result.
56    pub fn success(tool_use_id: impl Into<String>, output: impl Into<String>) -> Self {
57        Self {
58            tool_use_id: tool_use_id.into(),
59            output: output.into(),
60            is_error: false,
61        }
62    }
63
64    /// Create an error tool result.
65    pub fn error(tool_use_id: impl Into<String>, message: impl Into<String>) -> Self {
66        Self {
67            tool_use_id: tool_use_id.into(),
68            output: message.into(),
69            is_error: true,
70        }
71    }
72
73    /// Convert this tool result into an [`InputMessage`](crate::types::InputMessage)
74    /// suitable for writing to the CLI's stdin.
75    pub fn into_input_message(self) -> crate::types::InputMessage {
76        crate::types::InputMessage::tool_result(self.tool_use_id, self.output, self.is_error)
77    }
78}