openai_api_rs/realtime/
types.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Serialize, Deserialize, Clone, Default)]
4pub struct Session {
5    #[serde(skip_serializing_if = "Option::is_none")]
6    pub modalities: Option<Vec<String>>,
7    #[serde(skip_serializing_if = "Option::is_none")]
8    pub instructions: Option<String>,
9    #[serde(skip_serializing_if = "Option::is_none")]
10    pub voice: Option<RealtimeVoice>,
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub input_audio_format: Option<AudioFormat>,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub output_audio_format: Option<AudioFormat>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub input_audio_transcription: Option<AudioTranscription>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub turn_detection: Option<TurnDetection>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub tools: Option<Vec<ToolDefinition>>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub tool_choice: Option<ToolChoice>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub temperature: Option<f32>,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub max_output_tokens: Option<MaxOutputTokens>,
27}
28
29#[derive(Debug, Serialize, Deserialize, Clone)]
30#[serde(rename_all = "lowercase")]
31pub enum RealtimeVoice {
32    Alloy,
33    Ash,
34    Ballad,
35    Coral,
36    Echo,
37    Sage,
38    Shimmer,
39    Verse,
40}
41
42#[derive(Debug, Serialize, Deserialize, Clone)]
43pub enum AudioFormat {
44    #[serde(rename = "pcm16")]
45    PCM16,
46    #[serde(rename = "g711_ulaw")]
47    G711ULAW,
48    #[serde(rename = "g711_alaw")]
49    G711ALAW,
50}
51
52#[derive(Debug, Serialize, Deserialize, Clone)]
53pub struct AudioTranscription {
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub language: Option<String>,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub model: Option<String>,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub prompt: Option<String>,
60}
61
62#[derive(Debug, Serialize, Deserialize, Clone)]
63#[serde(tag = "type")]
64pub enum TurnDetection {
65    #[serde(rename = "server_vad")]
66    ServerVAD {
67        threshold: f32,
68        prefix_padding_ms: u32,
69        silence_duration_ms: u32,
70    },
71}
72
73#[derive(Debug, Serialize, Deserialize, Clone)]
74#[serde(tag = "type")]
75pub enum ToolDefinition {
76    #[serde(rename = "function")]
77    Function {
78        name: String,
79        description: String,
80        parameters: serde_json::Value,
81    },
82}
83
84#[derive(Debug, Serialize, Deserialize, Clone)]
85#[serde(rename_all = "lowercase")]
86pub enum ToolChoice {
87    Auto,
88    None,
89    Required,
90    #[serde(untagged)]
91    Function {
92        r#type: FunctionType,
93        name: String,
94    },
95}
96
97#[derive(Debug, Serialize, Deserialize, Clone)]
98#[serde(rename_all = "lowercase")]
99pub enum FunctionType {
100    Function,
101}
102
103#[derive(Debug, Serialize, Deserialize, Clone)]
104#[serde(untagged)]
105pub enum MaxOutputTokens {
106    Num(u16),
107    #[serde(rename = "inf")]
108    Inf,
109}
110
111#[derive(Debug, Serialize, Deserialize, Clone)]
112#[serde(rename_all = "snake_case")]
113pub enum ItemType {
114    Message,
115    FunctionCall,
116    FunctionCallOutput,
117}
118
119#[derive(Debug, Serialize, Deserialize, Clone)]
120#[serde(rename_all = "snake_case")]
121pub enum ItemStatus {
122    Completed,
123    InProgress,
124    Incomplete,
125}
126
127#[derive(Debug, Serialize, Deserialize, Clone)]
128#[serde(rename_all = "lowercase")]
129pub enum ItemRole {
130    User,
131    Assistant,
132    System,
133}
134
135#[derive(Debug, Serialize, Deserialize, Clone)]
136#[serde(rename_all = "snake_case")]
137pub enum ItemContentType {
138    InputText,
139    InputAudio,
140    InputImage,
141    Text,
142    Audio,
143}
144
145#[derive(Debug, Serialize, Deserialize, Clone)]
146pub struct ItemContent {
147    pub r#type: ItemContentType,
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub text: Option<String>,
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub audio: Option<String>,
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub transcript: Option<String>,
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub image_url: Option<String>,
156}
157
158#[derive(Debug, Serialize, Deserialize, Clone, Default)]
159pub struct Item {
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub id: Option<String>,
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub r#type: Option<ItemType>,
164    #[serde(skip_serializing_if = "Option::is_none")]
165    pub status: Option<ItemStatus>,
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub role: Option<ItemRole>,
168    #[serde(skip_serializing_if = "Option::is_none")]
169    pub content: Option<Vec<ItemContent>>,
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub call_id: Option<String>,
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub name: Option<String>,
174    #[serde(skip_serializing_if = "Option::is_none")]
175    pub arguments: Option<String>,
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub output: Option<String>,
178}
179
180impl TryFrom<serde_json::Value> for Item {
181    type Error = serde_json::Error;
182
183    fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
184        serde_json::from_value(value)
185    }
186}
187
188#[derive(Debug, Serialize, Deserialize, Clone)]
189pub struct APIError {
190    pub r#type: String,
191    pub code: Option<String>,
192    pub message: String,
193    pub param: Option<String>,
194    pub event_id: Option<String>,
195}
196
197#[derive(Debug, Serialize, Deserialize, Clone)]
198pub struct Conversation {
199    pub id: String,
200    pub object: String,
201}
202
203#[derive(Debug, Serialize, Deserialize, Clone)]
204pub struct Response {
205    pub id: String,
206    pub object: String,
207    pub status: ResponseStatus,
208    pub status_details: Option<ResponseStatusDetail>,
209    pub output: Vec<Item>,
210    pub usage: Option<Usage>,
211}
212
213#[derive(Debug, Serialize, Deserialize, Clone)]
214pub struct Usage {
215    pub total_tokens: u32,
216    pub input_tokens: u32,
217    pub output_tokens: u32,
218}
219
220#[derive(Debug, Serialize, Deserialize, Clone)]
221#[serde(rename_all = "snake_case")]
222pub enum ResponseStatus {
223    InProgress,
224    Completed,
225    Cancelled,
226    Failed,
227    Incomplete,
228}
229
230#[derive(Debug, Serialize, Deserialize, Clone)]
231#[serde(tag = "type")]
232pub enum ResponseStatusDetail {
233    #[serde(rename = "cancelled")]
234    Cancelled { reason: CancelledReason },
235    #[serde(rename = "incomplete")]
236    Incomplete { reason: IncompleteReason },
237    #[serde(rename = "failed")]
238    Failed { error: Option<FailedError> },
239}
240
241#[derive(Debug, Serialize, Deserialize, Clone)]
242pub struct FailedError {
243    pub code: Option<String>,
244    pub message: Option<String>,
245    pub r#type: Option<String>,
246}
247
248#[derive(Debug, Serialize, Deserialize, Clone)]
249#[serde(rename_all = "snake_case")]
250pub enum CancelledReason {
251    TurnDetected,
252    ClientCancelled,
253}
254
255#[derive(Debug, Serialize, Deserialize, Clone)]
256#[serde(rename_all = "snake_case")]
257pub enum IncompleteReason {
258    Interruption,
259    MaxOutputTokens,
260    ContentFilter,
261}
262
263#[derive(Debug, Serialize, Deserialize, Clone)]
264#[serde(tag = "type")]
265pub enum ContentPart {
266    #[serde(rename = "text")]
267    Text { text: String },
268    #[serde(rename = "audio")]
269    Audio {
270        audio: Option<String>,
271        transcript: String,
272    },
273}
274
275#[derive(Debug, Serialize, Deserialize, Clone)]
276pub struct RateLimit {
277    pub name: String,
278    pub limit: u32,
279    pub remaining: u32,
280    pub reset_seconds: f32,
281}