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    Text,
141    Audio,
142}
143
144#[derive(Debug, Serialize, Deserialize, Clone)]
145pub struct ItemContent {
146    pub r#type: ItemContentType,
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub text: Option<String>,
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub audio: Option<String>,
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub transcript: Option<String>,
153}
154
155#[derive(Debug, Serialize, Deserialize, Clone, Default)]
156pub struct Item {
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub id: Option<String>,
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub r#type: Option<ItemType>,
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub status: Option<ItemStatus>,
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub role: Option<ItemRole>,
165    #[serde(skip_serializing_if = "Option::is_none")]
166    pub content: Option<Vec<ItemContent>>,
167    #[serde(skip_serializing_if = "Option::is_none")]
168    pub call_id: Option<String>,
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub name: Option<String>,
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub arguments: Option<String>,
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub output: Option<String>,
175}
176
177impl TryFrom<serde_json::Value> for Item {
178    type Error = serde_json::Error;
179
180    fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
181        serde_json::from_value(value)
182    }
183}
184
185#[derive(Debug, Serialize, Deserialize, Clone)]
186pub struct APIError {
187    pub r#type: String,
188    pub code: Option<String>,
189    pub message: String,
190    pub param: Option<String>,
191    pub event_id: Option<String>,
192}
193
194#[derive(Debug, Serialize, Deserialize, Clone)]
195pub struct Conversation {
196    pub id: String,
197    pub object: String,
198}
199
200#[derive(Debug, Serialize, Deserialize, Clone)]
201pub struct Response {
202    pub id: String,
203    pub object: String,
204    pub status: ResponseStatus,
205    pub status_details: Option<ResponseStatusDetail>,
206    pub output: Vec<Item>,
207    pub usage: Option<Usage>,
208}
209
210#[derive(Debug, Serialize, Deserialize, Clone)]
211pub struct Usage {
212    pub total_tokens: u32,
213    pub input_tokens: u32,
214    pub output_tokens: u32,
215}
216
217#[derive(Debug, Serialize, Deserialize, Clone)]
218#[serde(rename_all = "snake_case")]
219pub enum ResponseStatus {
220    InProgress,
221    Completed,
222    Cancelled,
223    Failed,
224    Incomplete,
225}
226
227#[derive(Debug, Serialize, Deserialize, Clone)]
228#[serde(tag = "type")]
229pub enum ResponseStatusDetail {
230    #[serde(rename = "cancelled")]
231    Cancelled { reason: CancelledReason },
232    #[serde(rename = "incomplete")]
233    Incomplete { reason: IncompleteReason },
234    #[serde(rename = "failed")]
235    Failed { error: Option<FailedError> },
236}
237
238#[derive(Debug, Serialize, Deserialize, Clone)]
239pub struct FailedError {
240    pub code: Option<String>,
241    pub message: Option<String>,
242    pub r#type: Option<String>,
243}
244
245#[derive(Debug, Serialize, Deserialize, Clone)]
246#[serde(rename_all = "snake_case")]
247pub enum CancelledReason {
248    TurnDetected,
249    ClientCancelled,
250}
251
252#[derive(Debug, Serialize, Deserialize, Clone)]
253#[serde(rename_all = "snake_case")]
254pub enum IncompleteReason {
255    Interruption,
256    MaxOutputTokens,
257    ContentFilter,
258}
259
260#[derive(Debug, Serialize, Deserialize, Clone)]
261#[serde(tag = "type")]
262pub enum ContentPart {
263    #[serde(rename = "text")]
264    Text { text: String },
265    #[serde(rename = "audio")]
266    Audio {
267        audio: Option<String>,
268        transcript: String,
269    },
270}
271
272#[derive(Debug, Serialize, Deserialize, Clone)]
273pub struct RateLimit {
274    pub name: String,
275    pub limit: u32,
276    pub remaining: u32,
277    pub reset_seconds: f32,
278}