1use serde::{Deserialize, Serialize};
4
5use crate::prelude::*;
6
7#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
9pub struct MessageRequest {
10 #[serde(skip_serializing_if = "Option::is_none")]
12 pub model: Option<String>,
13
14 #[serde(default)]
16 pub messages: Vec<MessageBody>,
17
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub max_tokens: Option<i32>,
21
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub system: Option<SystemMessageContent>,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
28 pub temperature: Option<f32>,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub top_p: Option<f32>,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub top_k: Option<i32>,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub stream: Option<bool>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub stop_sequences: Option<Vec<String>>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub tools: Option<Vec<MessageTools>>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub tool_choice: Option<MessageToolChoice>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub metadata: Option<MessageMetadata>,
57}
58
59#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
61pub struct MessageBody {
62 pub role: String,
64
65 pub content: MessageContent,
67}
68
69#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
71#[serde(untagged)]
72pub enum MessageContent {
73 Text(String),
75 Parts(Vec<MessageContentPart>),
77}
78
79impl Default for MessageContent {
80 fn default() -> Self {
81 MessageContent::Text(String::new())
82 }
83}
84
85#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
87#[serde(tag = "type", rename_all = "snake_case")]
88pub enum MessageContentPart {
89 Text {
91 text: String,
93 #[serde(skip_serializing_if = "Option::is_none")]
95 cache_control: Option<serde_json::Value>,
96 },
97 Image {
99 source: MessageImageContent,
101 #[serde(skip_serializing_if = "Option::is_none")]
103 cache_control: Option<serde_json::Value>,
104 },
105 ToolUse {
107 id: String,
109 name: String,
111 input: serde_json::Value,
113 #[serde(skip_serializing_if = "Option::is_none")]
115 cache_control: Option<serde_json::Value>,
116 },
117 ToolResult {
119 tool_use_id: String,
121 content: String,
123 #[serde(skip_serializing_if = "Option::is_none")]
125 is_error: Option<bool>,
126 #[serde(skip_serializing_if = "Option::is_none")]
128 cache_control: Option<serde_json::Value>,
129 },
130 RedactedThinking {
132 data: String,
134 },
135 Thinking {
137 thinking: String,
139 },
140}
141
142impl Default for MessageContentPart {
143 fn default() -> Self {
144 MessageContentPart::Text {
145 text: String::new(),
146 cache_control: None,
147 }
148 }
149}
150
151#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
153#[serde(tag = "type", rename_all = "lowercase")]
154pub enum MessageImageContent {
155 Base64 {
157 data: String,
159 media_type: String,
161 },
162 Url {
164 url: String,
166 },
167}
168
169impl Default for MessageImageContent {
170 fn default() -> Self {
171 MessageImageContent::Url { url: String::new() }
172 }
173}
174
175#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
177#[serde(untagged)]
178pub enum SystemMessageContent {
179 Text(String),
181 Parts(Vec<SystemMessagePart>),
183}
184
185impl Default for SystemMessageContent {
186 fn default() -> Self {
187 SystemMessageContent::Text(String::new())
188 }
189}
190
191#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
193pub struct SystemMessagePart {
194 #[serde(rename = "type")]
196 pub part_type: String,
197
198 pub text: String,
200
201 #[serde(skip_serializing_if = "Option::is_none")]
203 pub cache_control: Option<serde_json::Value>,
204}
205
206#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
208pub struct MessageResponse {
209 pub id: String,
211
212 #[serde(rename = "type")]
214 pub response_type: String,
215
216 pub role: String,
218
219 pub content: Vec<MessageResponseContent>,
221
222 pub model: String,
224
225 pub usage: MessageUsage,
227
228 #[serde(skip_serializing_if = "Option::is_none")]
230 pub stop_reason: Option<String>,
231
232 #[serde(skip_serializing_if = "Option::is_none")]
234 pub stop_sequence: Option<String>,
235}
236
237#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
239#[serde(tag = "type", rename_all = "snake_case")]
240pub enum MessageResponseContent {
241 Text {
243 text: String,
245 },
246 Thinking {
248 thinking: String,
250 signature: String,
252 },
253 RedactedThinking {
255 data: String,
257 },
258 ToolUse {
260 id: String,
262 name: String,
264 input: serde_json::Value,
266 },
267}
268
269impl Default for MessageResponseContent {
270 fn default() -> Self {
271 MessageResponseContent::Text {
272 text: String::new(),
273 }
274 }
275}
276
277#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
279#[serde(tag = "type", rename_all = "lowercase")]
280pub enum MessageToolChoice {
281 #[default]
283 Auto,
284 Any,
286 Tool {
288 name: String,
290 },
291}
292
293#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
295pub struct MessageTools {
296 pub name: String,
298
299 pub description: String,
301
302 pub input_schema: MessageToolInputSchema,
304
305 #[serde(skip_serializing_if = "Option::is_none")]
307 pub cache_control: Option<serde_json::Value>,
308}
309
310#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
312pub struct MessageToolInputSchema {
313 #[serde(rename = "type")]
315 pub schema_type: String,
316
317 pub properties: serde_json::Value,
319
320 #[serde(skip_serializing_if = "Option::is_none")]
322 pub required: Option<Vec<String>>,
323}
324
325#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
327pub struct MessageMetadata {
328 #[serde(skip_serializing_if = "Option::is_none")]
330 pub user_id: Option<String>,
331}
332
333#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
335pub struct MessageUsage {
336 pub input_tokens: i32,
338
339 pub output_tokens: i32,
341
342 pub cache_read_input_tokens: i32,
344
345 pub cache_creation_input_tokens: i32,
347}