xai_openapi/
messages.rs

1//! Anthropic-compatible messages API types for `/v1/messages` endpoint.
2
3use serde::{Deserialize, Serialize};
4
5use crate::prelude::*;
6
7/// Request message for `/v1/messages` endpoint.
8#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
9pub struct MessageRequest {
10    /// Model name for the model to use.
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub model: Option<String>,
13
14    /// Input messages.
15    #[serde(default)]
16    pub messages: Vec<MessageBody>,
17
18    /// The maximum number of tokens to generate before stopping.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub max_tokens: Option<i32>,
21
22    /// System prompt message for the model.
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub system: Option<SystemMessageContent>,
25
26    /// What sampling temperature to use, between 0 and 2.
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub temperature: Option<f32>,
29
30    /// An alternative to sampling with temperature, called nucleus sampling.
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub top_p: Option<f32>,
33
34    /// (Unsupported) When generating next tokens, randomly selecting from k most likely options.
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub top_k: Option<i32>,
37
38    /// If set, partial message deltas will be sent as server-sent events.
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub stream: Option<bool>,
41
42    /// (Not supported by reasoning models) Up to 4 sequences where the API will stop generating.
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub stop_sequences: Option<Vec<String>>,
45
46    /// A list of tools the model may call.
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub tools: Option<Vec<MessageTools>>,
49
50    /// Controls which (if any) tool is called by the model.
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub tool_choice: Option<MessageToolChoice>,
53
54    /// An object describing metadata about the request.
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub metadata: Option<MessageMetadata>,
57}
58
59/// Anthropic compatible message body.
60#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
61pub struct MessageBody {
62    /// The role that the message belongs to: `"system"`, `"user"`, or `"assistant"`.
63    pub role: String,
64
65    /// The content message.
66    pub content: MessageContent,
67}
68
69/// Message content.
70#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
71#[serde(untagged)]
72pub enum MessageContent {
73    /// Text prompt.
74    Text(String),
75    /// An array of message content parts.
76    Parts(Vec<MessageContentPart>),
77}
78
79impl Default for MessageContent {
80    fn default() -> Self {
81        MessageContent::Text(String::new())
82    }
83}
84
85/// Message content part.
86#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
87#[serde(tag = "type", rename_all = "snake_case")]
88pub enum MessageContentPart {
89    /// Text prompt message content part.
90    Text {
91        /// Text prompt.
92        text: String,
93        /// (Unsupported) Cache control.
94        #[serde(skip_serializing_if = "Option::is_none")]
95        cache_control: Option<serde_json::Value>,
96    },
97    /// Image prompt message content part.
98    Image {
99        /// Image source.
100        source: MessageImageContent,
101        /// (Unsupported) Cache control.
102        #[serde(skip_serializing_if = "Option::is_none")]
103        cache_control: Option<serde_json::Value>,
104    },
105    /// Tool call message content part (received from model).
106    ToolUse {
107        /// ID of the tool call.
108        id: String,
109        /// Name of the tool call.
110        name: String,
111        /// Input for tool call.
112        input: serde_json::Value,
113        /// (Unsupported) Cache control.
114        #[serde(skip_serializing_if = "Option::is_none")]
115        cache_control: Option<serde_json::Value>,
116    },
117    /// Tool call result.
118    ToolResult {
119        /// ID of the tool call given by the model.
120        tool_use_id: String,
121        /// Result content of the tool call.
122        content: String,
123        /// Whether the tool call returns an error.
124        #[serde(skip_serializing_if = "Option::is_none")]
125        is_error: Option<bool>,
126        /// (Unsupported) Cache control.
127        #[serde(skip_serializing_if = "Option::is_none")]
128        cache_control: Option<serde_json::Value>,
129    },
130    /// (Redacted) Thinking of the model.
131    RedactedThinking {
132        /// Encrypted data of the redacted thinking.
133        data: String,
134    },
135    /// Thinking of the model.
136    Thinking {
137        /// Thinking.
138        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/// Message image content source.
152#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
153#[serde(tag = "type", rename_all = "lowercase")]
154pub enum MessageImageContent {
155    /// Base64 encoded image.
156    Base64 {
157        /// Base64 encoded image string.
158        data: String,
159        /// Media type of the image source: `image/jpeg`, `image/png`, `image/webp`.
160        media_type: String,
161    },
162    /// URL of the image.
163    Url {
164        /// URL of the image.
165        url: String,
166    },
167}
168
169impl Default for MessageImageContent {
170    fn default() -> Self {
171        MessageImageContent::Url { url: String::new() }
172    }
173}
174
175/// System message content.
176#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
177#[serde(untagged)]
178pub enum SystemMessageContent {
179    /// Text content of system prompt.
180    Text(String),
181    /// An array of system prompt parts.
182    Parts(Vec<SystemMessagePart>),
183}
184
185impl Default for SystemMessageContent {
186    fn default() -> Self {
187        SystemMessageContent::Text(String::new())
188    }
189}
190
191/// System message part.
192#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
193pub struct SystemMessagePart {
194    /// Type of the object. This is always `"text"`.
195    #[serde(rename = "type")]
196    pub part_type: String,
197
198    /// System prompt text.
199    pub text: String,
200
201    /// (Unsupported) Cache control.
202    #[serde(skip_serializing_if = "Option::is_none")]
203    pub cache_control: Option<serde_json::Value>,
204}
205
206/// Response message for `/v1/messages` endpoint.
207#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
208pub struct MessageResponse {
209    /// Unique object identifier.
210    pub id: String,
211
212    /// Object type. This is always `"message"` for message types.
213    #[serde(rename = "type")]
214    pub response_type: String,
215
216    /// Role of the generated message. Always `"assistant"`.
217    pub role: String,
218
219    /// Response message content.
220    pub content: Vec<MessageResponseContent>,
221
222    /// Model name that handled the request.
223    pub model: String,
224
225    /// Token usage information.
226    pub usage: MessageUsage,
227
228    /// Reason to stop: `"stop_sequence"`, `"max_tokens"`, `"end_turn"`, or `"tool_use"`.
229    #[serde(skip_serializing_if = "Option::is_none")]
230    pub stop_reason: Option<String>,
231
232    /// Custom stop sequence used to stop the generation.
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub stop_sequence: Option<String>,
235}
236
237/// Message response content.
238#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
239#[serde(tag = "type", rename_all = "snake_case")]
240pub enum MessageResponseContent {
241    /// Text response from the model.
242    Text {
243        /// Text content.
244        text: String,
245    },
246    /// Thinking response from the model.
247    Thinking {
248        /// Thinking content.
249        thinking: String,
250        /// Signature of the content.
251        signature: String,
252    },
253    /// Redacted thinking response from the model.
254    RedactedThinking {
255        /// Signature of the content.
256        data: String,
257    },
258    /// Request by the model to invoke a tool call.
259    ToolUse {
260        /// Tool call ID.
261        id: String,
262        /// Name of the tool call to be used.
263        name: String,
264        /// Input to the tool call following the `input_schema`.
265        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/// Tool choice option for messages API.
278#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
279#[serde(tag = "type", rename_all = "lowercase")]
280pub enum MessageToolChoice {
281    /// Allows the model to automatically decide whether to call the tool.
282    #[default]
283    Auto,
284    /// Forces the model to use at least one tool, without specifying the tool.
285    Any,
286    /// Forces the model to use the named tool.
287    Tool {
288        /// Name of the tool to use.
289        name: String,
290    },
291}
292
293/// Tool definition for messages API.
294#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
295pub struct MessageTools {
296    /// Name of the tool.
297    pub name: String,
298
299    /// Description of the tool.
300    pub description: String,
301
302    /// Input schema allowed by the tool.
303    pub input_schema: MessageToolInputSchema,
304
305    /// (Unsupported) Cache control.
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub cache_control: Option<serde_json::Value>,
308}
309
310/// Tool input schema for messages API.
311#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
312pub struct MessageToolInputSchema {
313    /// Type of the schema. This is always `"object"`.
314    #[serde(rename = "type")]
315    pub schema_type: String,
316
317    /// JSON-object of the tool input schema.
318    pub properties: serde_json::Value,
319
320    /// Required properties of the tool input schema, if any.
321    #[serde(skip_serializing_if = "Option::is_none")]
322    pub required: Option<Vec<String>>,
323}
324
325/// Metadata for messages API request.
326#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
327pub struct MessageMetadata {
328    /// A unique identifier representing your end-user.
329    #[serde(skip_serializing_if = "Option::is_none")]
330    pub user_id: Option<String>,
331}
332
333/// Token usage information for messages API.
334#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
335pub struct MessageUsage {
336    /// Number of input tokens used.
337    pub input_tokens: i32,
338
339    /// Number of output tokens used.
340    pub output_tokens: i32,
341
342    /// Number of tokens retrieved from the cache for this request.
343    pub cache_read_input_tokens: i32,
344
345    /// (Unsupported) Number of tokens written to the cache when creating a new entry.
346    pub cache_creation_input_tokens: i32,
347}