gproxy_protocol/protocol/claude/common/blocks/
content.rs1use serde::{Deserialize, Serialize};
2
3use super::super::server_tools::*;
4use super::super::{JsonObject, MessageRole, StringOrArray, TypedObject};
5use super::*;
6use crate::protocol::extensible::type_tag_union_deserialize;
7
8pub type MessageContent = StringOrArray<ContentBlockParam>;
9pub type SystemPrompt = StringOrArray<TextBlock>;
10pub type ContentBlock = ResponseContentBlock;
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct MessageParam {
14 pub role: MessageRole,
15 pub content: MessageContent,
16 #[serde(default, flatten, skip_serializing_if = "JsonObject::is_empty")]
17 pub extra: JsonObject,
18}
19
20#[derive(Debug, Clone, PartialEq, Serialize)]
24#[serde(untagged)]
25pub enum ContentBlockParam {
26 Text(TextBlock),
27 Image(ImageBlock),
28 Document(DocumentBlock),
29 SearchResult(SearchResultBlock),
30 Thinking(ThinkingBlock),
31 RedactedThinking(RedactedThinkingBlock),
32 ToolUse(ToolUseBlock),
33 ToolResult(ToolResultBlock),
34 ServerToolUse(ServerToolUseBlock),
35 WebSearchToolResult(WebSearchToolResultBlock),
36 WebFetchToolResult(WebFetchToolResultBlock),
37 AdvisorToolResult(AdvisorToolResultBlock),
38 CodeExecutionToolResult(CodeExecutionToolResultBlock),
39 BashCodeExecutionToolResult(BashCodeExecutionToolResultBlock),
40 TextEditorCodeExecutionToolResult(TextEditorCodeExecutionToolResultBlock),
41 ToolSearchToolResult(ToolSearchToolResultBlock),
42 McpToolUse(McpToolUseBlock),
43 McpToolResult(McpToolResultBlock),
44 ContainerUpload(ContainerUploadBlock),
45 Compaction(CompactionBlock),
46 MidConversationSystem(MidConversationSystemBlock),
47 ToolAddition(ToolAdditionBlock),
48 ToolRemoval(ToolRemovalBlock),
49 Fallback(FallbackBlock),
50 Raw(TypedObject),
51}
52
53type_tag_union_deserialize!(ContentBlockParam {
54 "text" => Text,
55 "image" => Image,
56 "document" => Document,
57 "search_result" => SearchResult,
58 "thinking" => Thinking,
59 "redacted_thinking" => RedactedThinking,
60 "tool_use" => ToolUse,
61 "tool_result" => ToolResult,
62 "server_tool_use" => ServerToolUse,
63 "web_search_tool_result" => WebSearchToolResult,
64 "web_fetch_tool_result" => WebFetchToolResult,
65 "advisor_tool_result" => AdvisorToolResult,
66 "code_execution_tool_result" => CodeExecutionToolResult,
67 "bash_code_execution_tool_result" => BashCodeExecutionToolResult,
68 "text_editor_code_execution_tool_result" => TextEditorCodeExecutionToolResult,
69 "tool_search_tool_result" => ToolSearchToolResult,
70 "mcp_tool_use" => McpToolUse,
71 "mcp_tool_result" => McpToolResult,
72 "container_upload" => ContainerUpload,
73 "compaction" => Compaction,
74 "mid_conv_system" => MidConversationSystem,
75 "tool_addition" => ToolAddition,
76 "tool_removal" => ToolRemoval,
77 "fallback" => Fallback,
78});
79
80#[derive(Debug, Clone, PartialEq, Serialize)]
81#[serde(untagged)]
82pub enum ResponseContentBlock {
83 Text(ResponseTextBlock),
84 Thinking(ThinkingBlock),
85 RedactedThinking(RedactedThinkingBlock),
86 ToolUse(ResponseToolUseBlock),
87 ServerToolUse(ResponseServerToolUseBlock),
88 WebSearchToolResult(ResponseWebSearchToolResultBlock),
89 WebFetchToolResult(ResponseWebFetchToolResultBlock),
90 AdvisorToolResult(ResponseAdvisorToolResultBlock),
91 CodeExecutionToolResult(ResponseCodeExecutionToolResultBlock),
92 BashCodeExecutionToolResult(ResponseBashCodeExecutionToolResultBlock),
93 TextEditorCodeExecutionToolResult(ResponseTextEditorCodeExecutionToolResultBlock),
94 ToolSearchToolResult(ResponseToolSearchToolResultBlock),
95 McpToolUse(ResponseMcpToolUseBlock),
96 McpToolResult(ResponseMcpToolResultBlock),
97 ContainerUpload(ResponseContainerUploadBlock),
98 Compaction(ResponseCompactionBlock),
99 Fallback(FallbackBlock),
100 Raw(TypedObject),
101}
102
103type_tag_union_deserialize!(ResponseContentBlock {
104 "text" => Text,
105 "thinking" => Thinking,
106 "redacted_thinking" => RedactedThinking,
107 "tool_use" => ToolUse,
108 "server_tool_use" => ServerToolUse,
109 "web_search_tool_result" => WebSearchToolResult,
110 "web_fetch_tool_result" => WebFetchToolResult,
111 "advisor_tool_result" => AdvisorToolResult,
112 "code_execution_tool_result" => CodeExecutionToolResult,
113 "bash_code_execution_tool_result" => BashCodeExecutionToolResult,
114 "text_editor_code_execution_tool_result" => TextEditorCodeExecutionToolResult,
115 "tool_search_tool_result" => ToolSearchToolResult,
116 "mcp_tool_use" => McpToolUse,
117 "mcp_tool_result" => McpToolResult,
118 "container_upload" => ContainerUpload,
119 "compaction" => Compaction,
120 "fallback" => Fallback,
121});
122
123#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
124#[serde(untagged)]
125pub enum ToolResultContent {
126 Text(String),
127 Blocks(Vec<ToolResultContentBlock>),
128 Raw(serde_json::Value),
129}
130
131#[derive(Debug, Clone, PartialEq, Serialize)]
132#[serde(untagged)]
133pub enum ToolResultContentBlock {
134 Text(TextBlock),
135 Image(ImageBlock),
136 SearchResult(SearchResultBlock),
137 Document(DocumentBlock),
138 ToolReference(ToolReferenceBlock),
139 Raw(TypedObject),
140}
141
142type_tag_union_deserialize!(ToolResultContentBlock {
143 "text" => Text,
144 "image" => Image,
145 "search_result" => SearchResult,
146 "document" => Document,
147 "tool_reference" => ToolReference,
148});
149
150pub type McpToolResultContent = StringOrArray<TextBlock>;
151
152#[cfg(test)]
153mod tests {
154 use serde_json::json;
155
156 use super::*;
157
158 #[test]
159 fn tag_dispatch_falls_back_to_raw() {
160 let wire = json!({"type": "hologram", "payload": {"x": 1}});
162 let block: ContentBlockParam = serde_json::from_value(wire.clone()).unwrap();
163 assert!(matches!(block, ContentBlockParam::Raw(_)));
164 assert_eq!(serde_json::to_value(&block).unwrap(), wire);
165
166 let wire = json!({"type": "tool_use", "id": 42});
169 let block: ContentBlockParam = serde_json::from_value(wire.clone()).unwrap();
170 assert!(matches!(block, ContentBlockParam::Raw(_)));
171 assert_eq!(serde_json::to_value(&block).unwrap(), wire);
172 }
173}