gproxy_protocol/protocol/claude/message/
stream.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::protocol::claude::common::{
6 AssistantRole, Citation, ClaudeModel, Container, ContentBlock, ContextManagementResponse,
7 JsonObject, MessageObjectType, StopDetails, StopReason, TypedObject, Usage,
8};
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11#[serde(untagged)]
12pub enum StreamEvent {
13 Known(Box<KnownStreamEvent>),
14 Unknown(TypedObject),
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18#[serde(tag = "type")]
19pub enum KnownStreamEvent {
20 #[serde(rename = "message_start")]
21 MessageStart {
22 message: Box<CreateMessageStartBody>,
23 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
24 extra: JsonObject,
25 },
26 #[serde(rename = "content_block_start")]
27 ContentBlockStart {
28 index: u64,
29 content_block: Box<ContentBlock>,
30 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
31 extra: JsonObject,
32 },
33 #[serde(rename = "content_block_delta")]
34 ContentBlockDelta {
35 index: u64,
36 delta: Box<EventDelta>,
37 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
38 extra: JsonObject,
39 },
40 #[serde(rename = "content_block_stop")]
41 ContentBlockStop {
42 index: u64,
43 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
44 extra: JsonObject,
45 },
46 #[serde(rename = "message_delta")]
47 MessageDelta {
48 #[serde(skip_serializing_if = "Option::is_none")]
49 context_management: Option<Box<ContextManagementResponse>>,
50 delta: Box<MessageDelta>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 usage: Option<Box<Usage>>,
53 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
54 extra: JsonObject,
55 },
56 #[serde(rename = "message_stop")]
57 MessageStop {
58 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
59 extra: JsonObject,
60 },
61 #[serde(rename = "ping")]
62 Ping {
63 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
64 extra: JsonObject,
65 },
66 #[serde(rename = "error")]
67 Error {
68 error: StreamError,
69 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
70 extra: JsonObject,
71 },
72}
73
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
75#[serde(untagged)]
76pub enum EventDelta {
77 Known(Box<KnownEventDelta>),
78 Unknown(TypedObject),
79}
80
81#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
82#[serde(tag = "type")]
83pub enum KnownEventDelta {
84 #[serde(rename = "text_delta")]
85 Text {
86 text: String,
87 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
88 extra: JsonObject,
89 },
90 #[serde(rename = "input_json_delta")]
91 InputJson {
92 partial_json: String,
93 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
94 extra: JsonObject,
95 },
96 #[serde(rename = "citations_delta")]
97 Citations {
98 citation: Box<Citation>,
99 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
100 extra: JsonObject,
101 },
102 #[serde(rename = "thinking_delta")]
103 Thinking {
104 #[serde(default, skip_serializing_if = "Option::is_none")]
105 estimated_tokens: Option<u64>,
106 thinking: String,
107 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
108 extra: JsonObject,
109 },
110 #[serde(rename = "signature_delta")]
111 Signature {
112 signature: String,
113 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
114 extra: JsonObject,
115 },
116 #[serde(rename = "compaction_delta")]
117 Compaction {
118 content: String,
119 encrypted_content: String,
120 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
121 extra: JsonObject,
122 },
123}
124
125#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
126pub struct CreateMessageStartBody {
127 pub id: String,
128 #[serde(rename = "type")]
129 pub type_: MessageObjectType,
130 pub role: AssistantRole,
131 pub content: Vec<ContentBlock>,
132 pub model: ClaudeModel,
133 pub stop_reason: Option<StopReason>,
134 pub stop_sequence: Option<String>,
135 pub usage: Usage,
136 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
137 pub extra: JsonObject,
138}
139
140#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
141pub struct MessageDelta {
142 #[serde(skip_serializing_if = "Option::is_none")]
143 pub container: Option<Container>,
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub stop_reason: Option<StopReason>,
146 #[serde(skip_serializing_if = "Option::is_none")]
147 pub stop_sequence: Option<String>,
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub stop_details: Option<StopDetails>,
150 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
151 pub extra: JsonObject,
152}
153
154#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155pub struct StreamError {
156 #[serde(rename = "type")]
157 pub type_: String,
158 pub message: String,
159 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
160 pub extra: JsonObject,
161}