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}