1use serde::{Deserialize, Serialize};
2
3use crate::claude::common::{
4 AssistantRole, Citation, ClaudeModel, Container, ContentBlock, ContextManagementResponse,
5 InputTransformation, MessageObjectType, StopDetails, StopReason, TypedObject, Usage,
6};
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(untagged)]
10#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
11pub enum StreamEvent {
12 Known(Box<KnownStreamEvent>),
13 Unknown(TypedObject),
14}
15
16impl StreamEvent {
17 pub fn event_name(&self) -> Option<&str> {
19 match self {
20 Self::Known(event) => Some(event.event_name()),
21 Self::Unknown(object) => Some(object.type_.as_str()),
22 }
23 }
24}
25
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
27#[serde(tag = "type")]
28#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
29pub enum KnownStreamEvent {
30 #[serde(rename = "message_start")]
31 MessageStart {
32 message: Box<CreateMessageStartBody>,
33 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
34 rest: serde_json::Map<String, serde_json::Value>,
35 },
36 #[serde(rename = "content_block_start")]
37 ContentBlockStart {
38 index: u64,
39 content_block: Box<ContentBlock>,
40 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
41 rest: serde_json::Map<String, serde_json::Value>,
42 },
43 #[serde(rename = "content_block_delta")]
44 ContentBlockDelta {
45 index: u64,
46 delta: Box<EventDelta>,
47 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
48 rest: serde_json::Map<String, serde_json::Value>,
49 },
50 #[serde(rename = "content_block_stop")]
51 ContentBlockStop {
52 index: u64,
53 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
54 rest: serde_json::Map<String, serde_json::Value>,
55 },
56 #[serde(rename = "message_delta")]
57 MessageDelta {
58 #[serde(skip_serializing_if = "Option::is_none")]
59 context_management: Option<Box<ContextManagementResponse>>,
60 delta: Box<MessageDelta>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 input_transformations: Option<Vec<InputTransformation>>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 usage: Option<Box<Usage>>,
65 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
66 rest: serde_json::Map<String, serde_json::Value>,
67 },
68 #[serde(rename = "message_stop")]
69 MessageStop {
70 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
71 rest: serde_json::Map<String, serde_json::Value>,
72 },
73 #[serde(rename = "ping")]
74 Ping {
75 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
76 rest: serde_json::Map<String, serde_json::Value>,
77 },
78 #[serde(rename = "error")]
79 Error {
80 error: StreamError,
81 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
82 rest: serde_json::Map<String, serde_json::Value>,
83 },
84}
85
86impl KnownStreamEvent {
87 pub fn event_name(&self) -> &'static str {
89 match self {
90 Self::MessageStart { .. } => "message_start",
91 Self::ContentBlockStart { .. } => "content_block_start",
92 Self::ContentBlockDelta { .. } => "content_block_delta",
93 Self::ContentBlockStop { .. } => "content_block_stop",
94 Self::MessageDelta { .. } => "message_delta",
95 Self::MessageStop { .. } => "message_stop",
96 Self::Ping { .. } => "ping",
97 Self::Error { .. } => "error",
98 }
99 }
100}
101
102#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
103#[serde(untagged)]
104#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
105pub enum EventDelta {
106 Known(Box<KnownEventDelta>),
107 Unknown(TypedObject),
108}
109
110#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111#[serde(tag = "type")]
112#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
113pub enum KnownEventDelta {
114 #[serde(rename = "text_delta")]
115 Text {
116 text: String,
117 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
118 rest: serde_json::Map<String, serde_json::Value>,
119 },
120 #[serde(rename = "input_json_delta")]
121 InputJson {
122 partial_json: String,
123 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
124 rest: serde_json::Map<String, serde_json::Value>,
125 },
126 #[serde(rename = "citations_delta")]
127 Citations {
128 citation: Box<Citation>,
129 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
130 rest: serde_json::Map<String, serde_json::Value>,
131 },
132 #[serde(rename = "thinking_delta")]
133 Thinking {
134 #[serde(default, skip_serializing_if = "Option::is_none")]
135 estimated_tokens: Option<u64>,
136 thinking: String,
137 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
138 rest: serde_json::Map<String, serde_json::Value>,
139 },
140 #[serde(rename = "signature_delta")]
141 Signature {
142 signature: String,
143 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
144 rest: serde_json::Map<String, serde_json::Value>,
145 },
146 #[serde(rename = "compaction_delta")]
147 Compaction {
148 content: String,
149 encrypted_content: String,
150 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
151 rest: serde_json::Map<String, serde_json::Value>,
152 },
153}
154
155#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
156#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
157pub struct CreateMessageStartBody {
158 pub id: String,
159 #[serde(rename = "type")]
160 pub type_: MessageObjectType,
161 pub role: AssistantRole,
162 pub content: Vec<ContentBlock>,
163 pub model: ClaudeModel,
164 pub stop_reason: Option<StopReason>,
165 pub stop_sequence: Option<String>,
166 #[serde(skip_serializing_if = "Option::is_none")]
167 pub usage: Option<Usage>,
168 #[serde(skip_serializing_if = "Option::is_none")]
169 pub input_transformations: Option<Vec<InputTransformation>>,
170 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
171 pub rest: serde_json::Map<String, serde_json::Value>,
172}
173
174#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
175#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
176pub struct MessageDelta {
177 #[serde(skip_serializing_if = "Option::is_none")]
178 pub container: Option<Container>,
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub stop_reason: Option<StopReason>,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 pub stop_sequence: Option<String>,
183 #[serde(skip_serializing_if = "Option::is_none")]
184 pub stop_details: Option<StopDetails>,
185 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
186 pub rest: serde_json::Map<String, serde_json::Value>,
187}
188
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
190#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
191pub struct StreamError {
192 #[serde(rename = "type")]
193 pub type_: String,
194 pub message: String,
195 #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
196 pub rest: serde_json::Map<String, serde_json::Value>,
197}