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    pub enabled: bool,
55    pub model: String,
56}
57
58#[derive(Debug, Serialize, Deserialize, Clone)]
59#[serde(tag = "type")]
60pub enum TurnDetection {
61    #[serde(rename = "server_vad")]
62    ServerVAD {
63        threshold: f32,
64        prefix_padding_ms: u32,
65        silence_duration_ms: u32,
66    },
67}
68
69#[derive(Debug, Serialize, Deserialize, Clone)]
70#[serde(tag = "type")]
71pub enum ToolDefinition {
72    #[serde(rename = "function")]
73    Function {
74        name: String,
75        description: String,
76        parameters: serde_json::Value,
77    },
78}
79
80#[derive(Debug, Serialize, Deserialize, Clone)]
81#[serde(rename_all = "lowercase")]
82pub enum ToolChoice {
83    Auto,
84    None,
85    Required,
86    #[serde(untagged)]
87    Function {
88        r#type: FunctionType,
89        name: String,
90    },
91}
92
93#[derive(Debug, Serialize, Deserialize, Clone)]
94#[serde(rename_all = "lowercase")]
95pub enum FunctionType {
96    Function,
97}
98
99#[derive(Debug, Serialize, Deserialize, Clone)]
100#[serde(untagged)]
101pub enum MaxOutputTokens {
102    Num(u16),
103    #[serde(rename = "inf")]
104    Inf,
105}
106
107#[derive(Debug, Serialize, Deserialize, Clone)]
108#[serde(rename_all = "snake_case")]
109pub enum ItemType {
110    Message,
111    FunctionCall,
112    FunctionCallOutput,
113}
114
115#[derive(Debug, Serialize, Deserialize, Clone)]
116#[serde(rename_all = "snake_case")]
117pub enum ItemStatus {
118    Completed,
119    InProgress,
120    Incomplete,
121}
122
123#[derive(Debug, Serialize, Deserialize, Clone)]
124#[serde(rename_all = "lowercase")]
125pub enum ItemRole {
126    User,
127    Assistant,
128    System,
129}
130
131#[derive(Debug, Serialize, Deserialize, Clone)]
132#[serde(rename_all = "snake_case")]
133pub enum ItemContentType {
134    InputText,
135    InputAudio,
136    Text,
137    Audio,
138}
139
140#[derive(Debug, Serialize, Deserialize, Clone)]
141pub struct ItemContent {
142    pub r#type: ItemContentType,
143    #[serde(skip_serializing_if = "Option::is_none")]
144    pub text: Option<String>,
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub audio: Option<String>,
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub transcript: Option<String>,
149}
150
151#[derive(Debug, Serialize, Deserialize, Clone, Default)]
152pub struct Item {
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub id: Option<String>,
155    #[serde(skip_serializing_if = "Option::is_none")]
156    pub r#type: Option<ItemType>,
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub status: Option<ItemStatus>,
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub role: Option<ItemRole>,
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub content: Option<Vec<ItemContent>>,
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub call_id: Option<String>,
165    #[serde(skip_serializing_if = "Option::is_none")]
166    pub name: Option<String>,
167    #[serde(skip_serializing_if = "Option::is_none")]
168    pub arguments: Option<String>,
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub output: Option<String>,
171}
172
173impl TryFrom<serde_json::Value> for Item {
174    type Error = serde_json::Error;
175
176    fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
177        serde_json::from_value(value)
178    }
179}
180
181#[derive(Debug, Serialize, Deserialize, Clone)]
182pub struct APIError {
183    pub r#type: String,
184    pub code: Option<String>,
185    pub message: String,
186    pub param: Option<String>,
187    pub event_id: Option<String>,
188}
189
190#[derive(Debug, Serialize, Deserialize, Clone)]
191pub struct Conversation {
192    pub id: String,
193    pub object: String,
194}
195
196#[derive(Debug, Serialize, Deserialize, Clone)]
197pub struct Response {
198    pub id: String,
199    pub object: String,
200    pub status: ResponseStatus,
201    pub status_details: Option<ResponseStatusDetail>,
202    pub output: Vec<Item>,
203    pub usage: Option<Usage>,
204}
205
206#[derive(Debug, Serialize, Deserialize, Clone)]
207pub struct Usage {
208    pub total_tokens: u32,
209    pub input_tokens: u32,
210    pub output_tokens: u32,
211}
212
213#[derive(Debug, Serialize, Deserialize, Clone)]
214#[serde(rename_all = "snake_case")]
215pub enum ResponseStatus {
216    InProgress,
217    Completed,
218    Cancelled,
219    Failed,
220    Incomplete,
221}
222
223#[derive(Debug, Serialize, Deserialize, Clone)]
224#[serde(tag = "type")]
225pub enum ResponseStatusDetail {
226    #[serde(rename = "cancelled")]
227    Cancelled { reason: CancelledReason },
228    #[serde(rename = "incomplete")]
229    Incomplete { reason: IncompleteReason },
230    #[serde(rename = "failed")]
231    Failed { error: Option<FailedError> },
232}
233
234#[derive(Debug, Serialize, Deserialize, Clone)]
235pub struct FailedError {
236    pub code: String,
237    pub message: String,
238}
239
240#[derive(Debug, Serialize, Deserialize, Clone)]
241#[serde(rename_all = "snake_case")]
242pub enum CancelledReason {
243    TurnDetected,
244    ClientCancelled,
245}
246
247#[derive(Debug, Serialize, Deserialize, Clone)]
248#[serde(rename_all = "snake_case")]
249pub enum IncompleteReason {
250    Interruption,
251    MaxOutputTokens,
252    ContentFilter,
253}
254
255#[derive(Debug, Serialize, Deserialize, Clone)]
256#[serde(tag = "type")]
257pub enum ContentPart {
258    #[serde(rename = "text")]
259    Text { text: String },
260    #[serde(rename = "audio")]
261    Audio {
262        audio: Option<String>,
263        transcript: String,
264    },
265}
266
267#[derive(Debug, Serialize, Deserialize, Clone)]
268pub struct RateLimit {
269    pub name: String,
270    pub limit: u32,
271    pub remaining: u32,
272    pub reset_seconds: f32,
273}