1use serde::{Deserialize, Serialize};
4
5pub use crate::shared::MaxResponseTokens;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
11#[serde(rename_all = "snake_case")]
12#[non_exhaustive]
13pub enum RealtimeAudioFormat {
14 Pcm16,
15 G711Ulaw,
16 G711Alaw,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
21#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
22#[serde(rename_all = "snake_case")]
23#[non_exhaustive]
24pub enum TurnDetectionType {
25 ServerVad,
26 SemanticVad,
27}
28
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
31#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
32#[serde(rename_all = "snake_case")]
33#[non_exhaustive]
34pub enum Eagerness {
35 Low,
36 Medium,
37 High,
38 Auto,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
44#[serde(rename_all = "snake_case")]
45#[non_exhaustive]
46pub enum NoiseReductionType {
47 NearField,
48 FarField,
49}
50
51#[derive(Debug, Clone, Serialize)]
55pub struct SessionCreateRequest {
56 #[serde(skip_serializing_if = "Option::is_none")]
58 pub model: Option<String>,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub voice: Option<String>,
63
64 #[serde(skip_serializing_if = "Option::is_none")]
66 pub instructions: Option<String>,
67
68 #[serde(skip_serializing_if = "Option::is_none")]
70 pub input_audio_format: Option<RealtimeAudioFormat>,
71
72 #[serde(skip_serializing_if = "Option::is_none")]
74 pub output_audio_format: Option<RealtimeAudioFormat>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub modalities: Option<Vec<String>>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
82 pub temperature: Option<f64>,
83
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub max_response_output_tokens: Option<MaxResponseTokens>,
87
88 #[serde(skip_serializing_if = "Option::is_none")]
90 pub tools: Option<Vec<RealtimeTool>>,
91
92 #[serde(skip_serializing_if = "Option::is_none")]
94 pub tool_choice: Option<String>,
95
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub turn_detection: Option<TurnDetection>,
99
100 #[serde(skip_serializing_if = "Option::is_none")]
102 pub input_audio_transcription: Option<InputAudioTranscription>,
103
104 #[serde(skip_serializing_if = "Option::is_none")]
106 pub speed: Option<f64>,
107}
108
109impl SessionCreateRequest {
110 pub fn new() -> Self {
111 Self {
112 model: None,
113 voice: None,
114 instructions: None,
115 input_audio_format: None,
116 output_audio_format: None,
117 modalities: None,
118 temperature: None,
119 max_response_output_tokens: None,
120 tools: None,
121 tool_choice: None,
122 turn_detection: None,
123 input_audio_transcription: None,
124 speed: None,
125 }
126 }
127
128 pub fn model(mut self, model: impl Into<String>) -> Self {
130 self.model = Some(model.into());
131 self
132 }
133
134 pub fn voice(mut self, voice: impl Into<String>) -> Self {
136 self.voice = Some(voice.into());
137 self
138 }
139
140 pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
142 self.instructions = Some(instructions.into());
143 self
144 }
145
146 pub fn modalities(mut self, modalities: Vec<String>) -> Self {
148 self.modalities = Some(modalities);
149 self
150 }
151}
152
153impl Default for SessionCreateRequest {
154 fn default() -> Self {
155 Self::new()
156 }
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct RealtimeTool {
162 #[serde(rename = "type")]
163 pub type_: String,
164 pub name: String,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub description: Option<String>,
167 #[serde(skip_serializing_if = "Option::is_none")]
168 pub parameters: Option<serde_json::Value>,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct TurnDetection {
174 #[serde(rename = "type")]
176 pub type_: TurnDetectionType,
177 #[serde(skip_serializing_if = "Option::is_none")]
179 pub threshold: Option<f64>,
180 #[serde(skip_serializing_if = "Option::is_none")]
182 pub prefix_padding_ms: Option<i64>,
183 #[serde(skip_serializing_if = "Option::is_none")]
185 pub silence_duration_ms: Option<i64>,
186 #[serde(skip_serializing_if = "Option::is_none")]
188 pub create_response: Option<bool>,
189 #[serde(skip_serializing_if = "Option::is_none")]
191 pub interrupt_response: Option<bool>,
192 #[serde(skip_serializing_if = "Option::is_none")]
194 pub eagerness: Option<Eagerness>,
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct InputAudioTranscription {
200 #[serde(skip_serializing_if = "Option::is_none")]
202 pub model: Option<String>,
203 #[serde(skip_serializing_if = "Option::is_none")]
205 pub language: Option<String>,
206 #[serde(skip_serializing_if = "Option::is_none")]
208 pub prompt: Option<String>,
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct InputAudioNoiseReduction {
214 #[serde(rename = "type")]
215 pub type_: NoiseReductionType,
216}
217
218#[derive(Debug, Clone, Deserialize)]
222pub struct ClientSecret {
223 pub value: String,
225 pub expires_at: i64,
227}
228
229#[derive(Debug, Clone, Deserialize)]
231pub struct SessionCreateResponse {
232 pub client_secret: ClientSecret,
234 #[serde(default)]
235 pub model: Option<String>,
236 #[serde(default)]
237 pub voice: Option<String>,
238 #[serde(default)]
239 pub instructions: Option<String>,
240 #[serde(default)]
241 pub modalities: Option<Vec<String>>,
242 #[serde(default)]
243 pub temperature: Option<f64>,
244 #[serde(default)]
245 pub max_response_output_tokens: Option<MaxResponseTokens>,
246 #[serde(default)]
247 pub input_audio_format: Option<RealtimeAudioFormat>,
248 #[serde(default)]
249 pub output_audio_format: Option<RealtimeAudioFormat>,
250 #[serde(default)]
251 pub tools: Option<Vec<RealtimeTool>>,
252 #[serde(default)]
253 pub tool_choice: Option<String>,
254 #[serde(default)]
255 pub turn_detection: Option<TurnDetection>,
256 #[serde(default)]
257 pub speed: Option<f64>,
258}
259
260#[derive(Debug, Clone, Serialize)]
264pub struct ClientSecretConfig {
265 #[serde(skip_serializing_if = "Option::is_none")]
267 pub expires_at: Option<ClientSecretExpiresAt>,
268}
269
270#[derive(Debug, Clone, Serialize)]
272pub struct ClientSecretExpiresAt {
273 pub anchor: String,
275 pub seconds: i64,
277}
278
279#[derive(Debug, Clone, Serialize)]
287pub struct TranscriptionSessionCreateRequest {
288 #[serde(skip_serializing_if = "Option::is_none")]
290 pub client_secret: Option<ClientSecretConfig>,
291
292 #[serde(skip_serializing_if = "Option::is_none")]
294 pub include: Option<Vec<String>>,
295
296 #[serde(skip_serializing_if = "Option::is_none")]
298 pub input_audio_format: Option<RealtimeAudioFormat>,
299
300 #[serde(skip_serializing_if = "Option::is_none")]
302 pub input_audio_noise_reduction: Option<InputAudioNoiseReduction>,
303
304 #[serde(skip_serializing_if = "Option::is_none")]
306 pub input_audio_transcription: Option<InputAudioTranscription>,
307
308 #[serde(skip_serializing_if = "Option::is_none")]
310 pub modalities: Option<Vec<String>>,
311
312 #[serde(skip_serializing_if = "Option::is_none")]
314 pub turn_detection: Option<TurnDetection>,
315}
316
317impl TranscriptionSessionCreateRequest {
318 pub fn new() -> Self {
319 Self {
320 client_secret: None,
321 include: None,
322 input_audio_format: None,
323 input_audio_noise_reduction: None,
324 input_audio_transcription: None,
325 modalities: None,
326 turn_detection: None,
327 }
328 }
329
330 pub fn input_audio_format(mut self, format: RealtimeAudioFormat) -> Self {
331 self.input_audio_format = Some(format);
332 self
333 }
334
335 pub fn transcription(mut self, model: impl Into<String>, language: impl Into<String>) -> Self {
336 self.input_audio_transcription = Some(InputAudioTranscription {
337 model: Some(model.into()),
338 language: Some(language.into()),
339 prompt: None,
340 });
341 self
342 }
343
344 pub fn turn_detection(mut self, td: TurnDetection) -> Self {
345 self.turn_detection = Some(td);
346 self
347 }
348
349 pub fn noise_reduction(mut self, type_: NoiseReductionType) -> Self {
350 self.input_audio_noise_reduction = Some(InputAudioNoiseReduction { type_ });
351 self
352 }
353
354 pub fn include(mut self, items: Vec<String>) -> Self {
355 self.include = Some(items);
356 self
357 }
358
359 pub fn modalities(mut self, modalities: Vec<String>) -> Self {
360 self.modalities = Some(modalities);
361 self
362 }
363
364 pub fn expires_in(mut self, seconds: i64) -> Self {
365 self.client_secret = Some(ClientSecretConfig {
366 expires_at: Some(ClientSecretExpiresAt {
367 anchor: "created_at".into(),
368 seconds,
369 }),
370 });
371 self
372 }
373}
374
375impl Default for TranscriptionSessionCreateRequest {
376 fn default() -> Self {
377 Self::new()
378 }
379}
380
381#[derive(Debug, Clone, Deserialize)]
385pub struct TranscriptionSession {
386 pub client_secret: ClientSecret,
388 #[serde(default)]
390 pub input_audio_format: Option<String>,
391 #[serde(default)]
393 pub input_audio_transcription: Option<InputAudioTranscription>,
394 #[serde(default)]
396 pub modalities: Option<Vec<String>>,
397 #[serde(default)]
399 pub turn_detection: Option<TurnDetection>,
400}