Skip to main content

litellm_rust/
types.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::borrow::Cow;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(untagged)]
7pub enum ChatMessageContent {
8    Text(String),
9    Parts(Vec<ChatContentPart>),
10}
11
12impl ChatMessageContent {
13    pub fn text(text: impl Into<String>) -> Self {
14        Self::Text(text.into())
15    }
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(untagged)]
20pub enum ChatContentPart {
21    Text(ChatContentPartText),
22    ImageUrl(ChatContentPartImageUrl),
23    InputAudio(ChatContentPartInputAudio),
24    File(ChatContentPartFile),
25    Other(Value),
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct ChatContentPartText {
30    #[serde(rename = "type")]
31    pub kind: Cow<'static, str>,
32    pub text: String,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct ChatContentPartImageUrl {
37    #[serde(rename = "type")]
38    pub kind: Cow<'static, str>,
39    pub image_url: ChatImageUrl,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43#[serde(untagged)]
44pub enum ChatImageUrl {
45    Url(String),
46    Object(ChatImageUrlObject),
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct ChatImageUrlObject {
51    pub url: String,
52    pub detail: Option<String>,
53    pub format: Option<String>,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct ChatContentPartInputAudio {
58    #[serde(rename = "type")]
59    pub kind: Cow<'static, str>,
60    pub input_audio: ChatInputAudio,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct ChatInputAudio {
65    pub data: String,
66    pub format: String,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct ChatContentPartFile {
71    #[serde(rename = "type")]
72    pub kind: Cow<'static, str>,
73    pub file: ChatFile,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct ChatFile {
78    pub file_id: Option<String>,
79    pub file_data: Option<String>,
80    pub format: Option<String>,
81    pub detail: Option<String>,
82    pub video_metadata: Option<Value>,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct ChatMessage {
87    pub role: String,
88    pub content: ChatMessageContent,
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub name: Option<String>,
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub tool_call_id: Option<String>,
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub tool_calls: Option<Value>,
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub function_call: Option<Value>,
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub provider_specific_fields: Option<Value>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct ChatRequest {
103    pub model: String,
104    pub messages: Vec<ChatMessage>,
105    pub temperature: Option<f32>,
106    pub max_tokens: Option<u32>,
107    pub response_format: Option<Value>,
108    pub max_completion_tokens: Option<u32>,
109    pub tools: Option<Value>,
110    pub tool_choice: Option<Value>,
111    pub parallel_tool_calls: Option<bool>,
112    pub stop: Option<Value>,
113    pub top_p: Option<f32>,
114    pub presence_penalty: Option<f32>,
115    pub frequency_penalty: Option<f32>,
116    pub seed: Option<u64>,
117    pub user: Option<String>,
118    pub metadata: Option<Value>,
119    pub reasoning_effort: Option<Value>,
120    pub thinking: Option<Value>,
121}
122
123impl ChatRequest {
124    pub fn new(model: impl Into<String>) -> Self {
125        Self {
126            model: model.into(),
127            messages: Vec::new(),
128            temperature: None,
129            max_tokens: None,
130            response_format: None,
131            max_completion_tokens: None,
132            tools: None,
133            tool_choice: None,
134            parallel_tool_calls: None,
135            stop: None,
136            top_p: None,
137            presence_penalty: None,
138            frequency_penalty: None,
139            seed: None,
140            user: None,
141            metadata: None,
142            reasoning_effort: None,
143            thinking: None,
144        }
145    }
146
147    pub fn message(mut self, role: impl Into<String>, content: impl Into<String>) -> Self {
148        self.messages.push(ChatMessage {
149            role: role.into(),
150            content: ChatMessageContent::Text(content.into()),
151            name: None,
152            tool_call_id: None,
153            tool_calls: None,
154            function_call: None,
155            provider_specific_fields: None,
156        });
157        self
158    }
159
160    pub fn message_with_content(
161        mut self,
162        role: impl Into<String>,
163        content: ChatMessageContent,
164    ) -> Self {
165        self.messages.push(ChatMessage {
166            role: role.into(),
167            content,
168            name: None,
169            tool_call_id: None,
170            tool_calls: None,
171            function_call: None,
172            provider_specific_fields: None,
173        });
174        self
175    }
176
177    pub fn temperature(mut self, temperature: f32) -> Self {
178        self.temperature = Some(temperature);
179        self
180    }
181
182    pub fn max_tokens(mut self, max_tokens: u32) -> Self {
183        self.max_tokens = Some(max_tokens);
184        self
185    }
186
187    pub fn response_format(mut self, format: Value) -> Self {
188        self.response_format = Some(format);
189        self
190    }
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct ChatResponse {
195    pub content: String,
196    pub usage: Usage,
197    pub response_id: Option<String>,
198    pub header_cost: Option<f64>,
199    pub raw: Option<Value>,
200}
201
202/// Token usage statistics from an LLM API response.
203///
204/// Uses `u64` for token counts to handle large values consistently
205/// across different platforms and avoid truncation.
206#[derive(Debug, Clone, Serialize, Deserialize, Default)]
207pub struct Usage {
208    pub prompt_tokens: Option<u64>,
209    pub completion_tokens: Option<u64>,
210    pub thoughts_tokens: Option<u64>,
211    pub total_tokens: Option<u64>,
212    pub cost_usd: Option<f64>,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
216pub struct EmbeddingRequest {
217    pub model: String,
218    pub input: Value,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct EmbeddingResponse {
223    pub vectors: Vec<Vec<f32>>,
224    pub usage: Usage,
225    pub raw: Option<Value>,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize)]
229pub struct ImageRequest {
230    pub model: String,
231    pub prompt: String,
232    pub n: Option<u32>,
233    pub size: Option<String>,
234    pub quality: Option<String>,
235    pub background: Option<String>,
236}
237
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct ImageData {
240    pub b64_json: Option<String>,
241    pub url: Option<String>,
242    pub revised_prompt: Option<String>,
243    pub mime_type: Option<String>,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct ImageEditRequest {
248    pub model: String,
249    pub prompt: String,
250    pub images: Vec<ImageInputData>,
251    pub n: Option<u32>,
252    pub size: Option<String>,
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct ImageInputData {
257    pub b64_json: Option<String>,
258    pub url: Option<String>,
259    pub mime_type: Option<String>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
263pub struct ImageResponse {
264    pub images: Vec<ImageData>,
265    pub usage: Usage,
266    pub raw: Option<Value>,
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize)]
270pub struct VideoRequest {
271    pub model: String,
272    pub prompt: String,
273    pub seconds: Option<u32>,
274    pub size: Option<String>,
275}
276
277#[derive(Debug, Clone, Serialize, Deserialize)]
278pub struct VideoResponse {
279    pub video_url: Option<String>,
280    pub raw: Option<Value>,
281}