async_openai/types/realtime/session.rs
1use serde::{Deserialize, Serialize};
2
3use crate::types::{
4 mcp::MCPTool,
5 responses::{Prompt, ToolChoiceFunction, ToolChoiceMCP, ToolChoiceOptions},
6};
7
8/// Controls how long the model waits before emitting transcription text.
9#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
10#[serde(rename_all = "lowercase")]
11pub enum AudioTranscriptionDelay {
12 Minimal,
13 Low,
14 Medium,
15 High,
16 #[serde(rename = "xhigh")]
17 XHigh,
18}
19
20#[derive(Debug, Default, Serialize, Deserialize, Clone)]
21pub struct AudioTranscription {
22 /// The language of the input audio. Supplying the input language in
23 /// [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. `en`) format will improve accuracy and latency.
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub language: Option<String>,
26 /// The model to use for transcription. Current options are `whisper-1`, `gpt-transcribe`, `gpt-live-
27 /// transcribe`, `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-12-15`, `gpt-4o-transcribe`,
28 /// `gpt-4o-transcribe-diarize`, and `gpt-realtime-whisper`. Use `gpt-4o-transcribe-diarize` when you
29 /// need diarization with speaker labels.
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub model: Option<String>,
32 /// An optional text to guide the model's style or continue a previous audio segment.
33 /// For `whisper-1`, the [prompt is a list of keywords](https://platform.openai.com/docs/guides/speech-to-text#prompting). For `gpt-4o-transcribe` models
34 /// (excluding gpt-4o-transcribe-diarize), the prompt is a free text string, for example
35 /// "expect words related to technology".
36 /// Prompt is not supported with `gpt-realtime-whisper` in GA Realtime sessions.
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub prompt: Option<String>,
39 /// Controls how long the model waits before emitting transcription text.
40 /// Higher values can improve transcription accuracy at the cost of latency.
41 /// Only supported with `gpt-realtime-whisper` in GA Realtime sessions.
42 #[serde(skip_serializing_if = "Option::is_none")]
43 pub delay: Option<AudioTranscriptionDelay>,
44 /// Possible languages of the input audio, in
45 /// [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format. Supported by `gpt-
46 /// transcribe` and `gpt-live-transcribe`.
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub languages: Option<Vec<String>>,
49
50 /// Words or phrases to guide transcription of the input audio. Supported by `gpt-transcribe` and `gpt-
51 /// live-transcribe`.
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub keywords: Option<Vec<String>>,
54}
55
56/// Configuration of the transcription model returned by the server.
57#[derive(Debug, Default, Serialize, Deserialize, Clone)]
58pub struct AudioTranscriptionResponse {
59 /// The language of the input audio.
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub language: Option<String>,
62 /// The model used for transcription. Current options are `whisper-1`, `gpt-transcribe`, `gpt-live-
63 /// transcribe`, `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-12-15`, `gpt-4o-transcribe`,
64 /// `gpt-4o-transcribe-diarize`, and `gpt-realtime-whisper`.
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub model: Option<String>,
67 /// The prompt configured for input audio transcription, when present.
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub prompt: Option<String>,
70 /// The possible input audio languages configured for transcription, in
71 /// [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format.
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub languages: Option<Vec<String>>,
74}
75
76#[derive(Debug, Serialize, Deserialize, Clone)]
77#[serde(tag = "type")]
78pub enum RealtimeTurnDetection {
79 /// Server-side voice activity detection (VAD) which flips on when user speech is detected
80 /// and off after a period of silence.
81 #[serde(rename = "server_vad")]
82 ServerVAD {
83 /// Whether or not to automatically generate a response when a VAD stop event occurs. If
84 /// `interrupt_response` is set to `false` this may fail to create a response if the model is
85 /// already responding.
86 ///
87 /// If both `create_response` and `interrupt_response` are set to `false`, the model will
88 /// never respond automatically but VAD events will still be emitted.
89 #[serde(skip_serializing_if = "Option::is_none")]
90 create_response: Option<bool>,
91
92 /// Optional timeout after which a model response will be triggered automatically.
93 /// This is useful for situations in which a long pause from the user is unexpected,
94 /// such as a phone call. The model will effectively prompt the user to continue the
95 /// conversation based on the current context.
96 ///
97 /// The timeout value will be applied after the last model response's audio has finished
98 /// playing, i.e. it's set to the response.done time plus audio playback duration.
99 ///
100 /// An input_audio_buffer.timeout_triggered event (plus events associated with the Response)
101 /// will be emitted when the timeout is reached. Idle timeout is currently only supported
102 /// for server_vad mode.
103 #[serde(skip_serializing_if = "Option::is_none")]
104 idle_timeout_ms: Option<u32>,
105
106 /// Whether or not to automatically interrupt (cancel) any ongoing response with output to the
107 /// default conversation (i.e. `conversation` of `auto`) when a VAD start event occurs. If `true` then
108 /// the response will be cancelled, otherwise it will continue until complete.
109 ///
110 /// If both `create_response` and `interrupt_response` are set to `false`, the model will
111 /// never respond automatically but VAD events will still be emitted.
112 #[serde(skip_serializing_if = "Option::is_none")]
113 interrupt_response: Option<bool>,
114
115 /// Used only for server_vad mode. Amount of audio to include before the VAD detected speech
116 /// (in milliseconds). Defaults to 300ms.
117 prefix_padding_ms: u32,
118 /// Used only for server_vad mode. Duration of silence to detect speech stop
119 /// (in milliseconds). Defaults to 500ms. With shorter values the model will respond
120 /// more quickly, but may jump in on short pauses from the user.
121 silence_duration_ms: u32,
122
123 /// Used only for server_vad mode. Activation threshold for VAD (0.0 to 1.0),
124 /// this defaults to 0.5. A higher threshold will require louder audio to activate
125 /// the model, and thus might perform better in noisy environments.
126 threshold: f32,
127 },
128
129 /// Server-side semantic turn detection which uses a model to determine when the user has
130 /// finished speaking.
131 #[serde(rename = "semantic_vad")]
132 SemanticVAD {
133 /// Whether or not to automatically generate a response when a VAD stop event occurs.
134 #[serde(skip_serializing_if = "Option::is_none", default)]
135 create_response: Option<bool>,
136
137 /// Used only for `semantic_vad` mode. The eagerness of the model to respond.
138 /// `low` will wait longer for the user to continue speaking, `high` will respond more
139 /// quickly. `auto` is the default and is equivalent to `medium`. `low`, `medium`, and `high`
140 /// have max timeouts of 8s, 4s, and 2s respectively.
141 eagerness: String,
142
143 /// Whether or not to automatically interrupt any ongoing response with output to
144 /// the default conversation (i.e. `conversation` of `auto`) when a VAD start event occurs.
145 #[serde(skip_serializing_if = "Option::is_none", default)]
146 interrupt_response: Option<bool>,
147 },
148}
149
150#[derive(Debug, Serialize, Deserialize, Clone)]
151pub enum MaxOutputTokens {
152 #[serde(rename = "inf")]
153 Inf,
154 #[serde(untagged)]
155 Num(u16),
156}
157
158#[derive(Debug, Serialize, Deserialize, Clone)]
159pub struct RealtimeFunctionTool {
160 /// The name of the function.
161 pub name: String,
162 /// The description of the function, including guidance on when and how to call it,
163 /// and guidance about what to tell the user when calling (if anything).
164 pub description: String,
165 /// Parameters of the function in JSON Schema.
166 pub parameters: serde_json::Value,
167}
168
169#[derive(Debug, Serialize, Deserialize, Clone)]
170#[serde(tag = "type")]
171pub enum RealtimeTool {
172 #[serde(rename = "function")]
173 Function(RealtimeFunctionTool),
174 /// Give the model access to additional tools via remote Model Context Protocol (MCP) servers.
175 /// [Learn more about MCP](https://platform.openai.com/docs/guides/tools-remote-mcp).
176 #[serde(rename = "mcp")]
177 MCP(MCPTool),
178}
179
180#[derive(Debug, Serialize, Deserialize, Clone)]
181#[serde(rename_all = "lowercase")]
182pub enum FunctionType {
183 Function,
184}
185
186#[derive(Debug, Serialize, Deserialize, Clone)]
187#[serde(tag = "type", rename_all = "snake_case")]
188pub enum ToolChoice {
189 /// Use this option to force the model to call a specific function.
190 Function(ToolChoiceFunction),
191 /// Use this option to force the model to call a specific tool on a remote MCP server.
192 Mcp(ToolChoiceMCP),
193
194 #[serde(untagged)]
195 Mode(ToolChoiceOptions),
196}
197
198#[derive(Debug, Serialize, Deserialize, Clone)]
199#[serde(rename_all = "lowercase")]
200pub enum RealtimeVoice {
201 Alloy,
202 Ash,
203 Ballad,
204 Coral,
205 Echo,
206 Sage,
207 Shimmer,
208 Verse,
209 Marin,
210 Cedar,
211 #[serde(untagged)]
212 Other(String),
213}
214
215#[derive(Debug, Serialize, Deserialize, Clone)]
216#[serde(tag = "type")]
217pub enum RealtimeAudioFormats {
218 /// The PCM audio format. Only a 24kHz sample rate is supported.
219 #[serde(rename = "audio/pcm")]
220 PCMAudioFormat {
221 /// The sample rate of the audio. Always 24000.
222 rate: u32,
223 },
224 /// The G.711 μ-law format.
225 #[serde(rename = "audio/pcmu")]
226 PCMUAudioFormat,
227 /// The G.711 A-law format.
228 #[serde(rename = "audio/pcma")]
229 PCMAAudioFormat,
230}
231
232#[derive(Debug, Serialize, Deserialize, Clone, Default)]
233pub struct G711ULAWAudioFormat {
234 pub sample_rate: u32,
235 pub channels: u32,
236}
237
238#[derive(Debug, Serialize, Deserialize, Clone)]
239pub struct AudioInput {
240 /// The format of the input audio.
241 pub format: RealtimeAudioFormats,
242 /// Configuration for input audio noise reduction. This can be set to null to turn off.
243 /// Noise reduction filters audio added to the input audio buffer before it is sent to VAD
244 /// and the model. Filtering the audio can improve VAD and turn detection accuracy
245 /// (reducing false positives) and model performance by improving perception of the
246 /// input audio.
247 pub noise_reduction: Option<NoiseReductionType>,
248 /// Configuration for input audio transcription, defaults to off and can be set to `null` to turn off once on.
249 /// Input audio transcription is not native to the model, since the model consumes audio directly.
250 /// Transcription runs asynchronously through [the /audio/transcriptions endpoint](https://platform.openai.com/docs/api-reference/audio/createTranscription)
251 /// and should be treated as guidance of input audio content rather than precisely what the model
252 /// heard. The client can optionally set the language and prompt for transcription,
253 /// these offer additional guidance to the transcription service.
254 pub transcription: Option<AudioTranscription>,
255
256 /// Configuration for turn detection, ether Server VAD or Semantic VAD. This can
257 /// be set to null to turn off, in which case the client must manually trigger model response.
258 ///
259 /// Server VAD means that the model will detect the start and end of speech
260 /// based on audio volume and respond at the end of user speech.
261 ///
262 /// Semantic VAD is more advanced and uses a turn detection model (in conjunction with VAD)
263 /// to semantically estimate whether the user has finished speaking, then dynamically sets
264 /// a timeout based on this probability. For example, if user audio trails off with "uhhm",
265 /// the model will score a low probability of turn end and wait longer for the user to
266 /// continue speaking. This can be useful for more natural conversations, but may have a
267 /// higher latency.
268 pub turn_detection: Option<RealtimeTurnDetection>,
269}
270
271#[derive(Debug, Serialize, Deserialize, Clone)]
272pub struct AudioOutput {
273 /// The format of the output audio.
274 pub format: RealtimeAudioFormats,
275 /// The speed of the model's spoken response as a multiple of the original speed.
276 /// 1.0 is the default speed. 0.25 is the minimum speed. 1.5 is the maximum speed.
277 /// This value can only be changed in between model turns, not while a response
278 /// is in progress.
279 ///
280 /// This parameter is a post-processing adjustment to the audio after it is generated,
281 /// it's also possible to prompt the model to speak faster or slower.
282 pub speed: f32,
283 /// The voice the model uses to respond. Supported built-in voices are `alloy`, `ash`, `ballad`,
284 /// `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. Voice cannot be changed during
285 /// the session once the model has responded with audio at least once. We recommend `marin` and `cedar`
286 /// for best quality.
287 pub voice: RealtimeVoice,
288}
289
290#[derive(Debug, Serialize, Deserialize, Clone)]
291pub struct Audio {
292 pub input: AudioInput,
293 pub output: AudioOutput,
294}
295
296#[derive(Debug, Serialize, Deserialize, Clone)]
297#[serde(rename_all = "lowercase")]
298pub enum Tracing {
299 /// Enables tracing and sets default values for tracing configuration options. Always `auto`.
300 Auto,
301
302 #[serde(untagged)]
303 Configuration(TracingConfiguration),
304}
305
306#[derive(Debug, Serialize, Deserialize, Clone)]
307pub struct TracingConfiguration {
308 /// The group id to attach to this trace to enable filtering and grouping in the Traces Dashboard.
309 pub group_id: String,
310 /// The arbitrary metadata to attach to this trace to enable filtering in the Traces Dashboard.
311 pub metadata: serde_json::Value,
312 /// The name of the workflow to attach to this trace. This is used to name the trace in the Traces Dashboard.
313 pub workflow_name: String,
314}
315
316/// The truncation strategy to use for the session.
317#[derive(Debug, Serialize, Deserialize, Clone)]
318#[serde(rename_all = "lowercase")]
319pub enum RealtimeTruncation {
320 /// `auto` is the default truncation strategy.
321 Auto,
322 /// `disabled` will disable truncation and emit errors when the conversation exceeds the input
323 /// token limit.
324 Disabled,
325
326 /// Retain a fraction of the conversation tokens when the conversation exceeds the input token
327 /// limit. This allows you to amortize truncations across multiple turns, which can help improve
328 /// cached token usage.
329 #[serde(untagged)]
330 RetentionRatio(RetentionRatioTruncation),
331}
332
333#[derive(Debug, Serialize, Deserialize, Clone)]
334pub struct RetentionRatioTruncation {
335 /// Fraction of post-instruction conversation tokens to retain (0.0 - 1.0) when the conversation
336 /// exceeds the input token limit. Setting this to 0.8 means that messages will be dropped
337 /// until 80% of the maximum allowed tokens are used. This helps reduce the frequency of
338 /// truncations and improve cache rates.
339 pub retention_ratio: f32,
340
341 /// Use retention ratio truncation.
342 pub r#type: String,
343
344 /// Optional custom token limits for this truncation strategy. If not provided, the model's
345 /// default token limits will be used.
346 #[serde(skip_serializing_if = "Option::is_none")]
347 pub token_limits: Option<TokenLimits>,
348}
349
350#[derive(Debug, Serialize, Deserialize, Clone)]
351pub struct TokenLimits {
352 /// Maximum tokens allowed in the conversation after instructions (which including tool
353 /// definitions). For example, setting this to 5,000 would mean that truncation would occur
354 /// when the conversation exceeds 5,000 tokens after instructions. This cannot be higher
355 /// than the model's context window size minus the maximum output tokens.
356 pub post_instructions: u32,
357}
358
359#[derive(Debug, Serialize, Deserialize, Clone)]
360#[serde(tag = "type")]
361pub enum Session {
362 // Boxed as per clippy suggestion:
363 // https://rust-lang.github.io/rust -clippy/rust-1.91.0/index.html#large_enum_variant
364 // the largest variant contains at least 600 bytes, the second-largest variant contains at least 144 bytes
365 /// The type of session to create. Always `realtime` for the Realtime API.
366 #[serde(rename = "realtime")]
367 RealtimeSession(Box<RealtimeSession>),
368 /// The type of session to create. Always `transcription` for transcription sessions.
369 #[serde(rename = "transcription")]
370 RealtimeTranscriptionSession(Box<RealtimeTranscriptionSession>),
371}
372
373#[derive(Debug, Serialize, Deserialize, Clone)]
374#[serde(tag = "type")]
375pub enum RealtimeSessionConfiguration {
376 Realtime(RealtimeSession),
377}
378
379impl Default for RealtimeSessionConfiguration {
380 fn default() -> Self {
381 Self::Realtime(RealtimeSession::default())
382 }
383}
384
385/// Constrains effort on reasoning for reasoning-capable Realtime models such as `gpt-realtime-2`.
386#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Default)]
387#[serde(rename_all = "lowercase")]
388pub enum RealtimeReasoningEffort {
389 Minimal,
390 #[default]
391 Low,
392 Medium,
393 High,
394 #[serde(rename = "xhigh")]
395 XHigh,
396}
397
398/// Configuration for reasoning-capable Realtime models such as `gpt-realtime-2`.
399#[derive(Debug, Default, Serialize, Deserialize, Clone)]
400pub struct RealtimeReasoning {
401 #[serde(skip_serializing_if = "Option::is_none")]
402 pub effort: Option<RealtimeReasoningEffort>,
403}
404
405/// Realtime session object configuration.
406/// openapi spec type: RealtimeSessionCreateRequestGA
407#[derive(Debug, Serialize, Deserialize, Clone, Default)]
408pub struct RealtimeSession {
409 #[serde(skip_serializing_if = "Option::is_none")]
410 pub id: Option<String>,
411 #[serde(skip_serializing_if = "Option::is_none")]
412 pub expires_at: Option<u64>,
413 #[serde(skip_serializing_if = "Option::is_none")]
414 pub audio: Option<Audio>,
415
416 /// Additional fields to include in server outputs.
417 ///
418 /// `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription.
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub include: Option<Vec<String>>,
421
422 /// The default system instructions (i.e. system message) prepended to model calls.
423 /// This field allows the client to guide the model on desired responses.
424 /// The model can be instructed on response content and format,
425 /// (e.g. "be extremely succinct", "act friendly", "here are examples of good responses")
426 /// and on audio behavior (e.g. "talk quickly", "inject emotion into your voice",
427 /// "laugh frequently"). The instructions are not guaranteed to be followed by the model, but
428 /// they provide guidance to the model on the desired behavior.
429 ///
430 /// Note that the server sets default instructions which will be used if this field is not set
431 /// and are visible in the `session.created` event at the start of the session.
432 #[serde(skip_serializing_if = "Option::is_none")]
433 pub instructions: Option<String>,
434
435 /// Maximum number of output tokens for a single assistant response,
436 /// inclusive of tool calls. Provide an integer between 1 and 4096 to limit output tokens,
437 /// or `inf` for the maximum available tokens for a given model. Defaults to `inf`.
438 #[serde(skip_serializing_if = "Option::is_none")]
439 pub max_output_tokens: Option<MaxOutputTokens>,
440
441 /// The Realtime model used for this session.
442 #[serde(skip_serializing_if = "Option::is_none")]
443 pub model: Option<String>,
444
445 /// The set of modalities the model can respond with. It defaults to
446 /// `["audio"]`, indicating that the model will respond with audio plus a transcript. `["text"]`
447 /// can be used to make the model respond with text only. It is not possible to request both
448 /// `text` and `audio` at the same time.
449 #[serde(skip_serializing_if = "Option::is_none")]
450 pub output_modalities: Option<Vec<String>>,
451
452 /// Reference to a prompt template and its variables.
453 /// [Learn more](https://platform.openai.com/docs/guides/text?api-mode=responses#reusable-prompts).
454 #[serde(skip_serializing_if = "Option::is_none")]
455 pub prompt: Option<Prompt>,
456
457 /// How the model chooses tools. Provide one of the string modes or force a specific
458 /// function/MCP tool.
459 #[serde(skip_serializing_if = "Option::is_none")]
460 pub tool_choice: Option<ToolChoice>,
461
462 /// Tools available to the model.
463 #[serde(skip_serializing_if = "Option::is_none")]
464 pub tools: Option<Vec<RealtimeTool>>,
465
466 /// Realtime API can write session traces to the [Traces Dashboard](https://platform.openai.com/logs?api=traces).
467 /// Set to null to disable tracing. Once tracing is enabled for a session, the configuration cannot be modified.
468 ///
469 /// `auto` will create a trace for the session with default values for the workflow name,
470 /// group id, and metadata.
471 #[serde(skip_serializing_if = "Option::is_none")]
472 pub tracing: Option<Tracing>,
473
474 /// When the number of tokens in a conversation exceeds the model's input token limit,
475 /// the conversation be truncated, meaning messages (starting from the oldest) will not be
476 /// included in the model's context. A 32k context model with 4,096 max output tokens can
477 /// only include 28,224 tokens in the context before truncation occurs. Clients can configure
478 /// truncation behavior to truncate with a lower max token limit, which is an effective way to
479 /// control token usage and cost. Truncation will reduce the number of cached tokens on the next
480 /// turn (busting the cache), since messages are dropped from the beginning of the context.
481 /// However, clients can also configure truncation to retain messages up to a fraction of the
482 /// maximum context size, which will reduce the need for future truncations and thus improve
483 /// the cache rate. Truncation can be disabled entirely, which means the server will never
484 /// truncate but would instead return an error if the conversation exceeds the model's input
485 /// token limit.
486 #[serde(skip_serializing_if = "Option::is_none")]
487 pub truncation: Option<RealtimeTruncation>,
488
489 /// Whether the model may call multiple tools in parallel.
490 #[serde(skip_serializing_if = "Option::is_none")]
491 pub parallel_tool_calls: Option<bool>,
492
493 /// Configuration for reasoning-capable Realtime models such as `gpt-realtime-2`.
494 #[serde(skip_serializing_if = "Option::is_none")]
495 pub reasoning: Option<RealtimeReasoning>,
496}
497
498/// Type of noise reduction. `near_field` is for close-talking microphones such as
499/// headphones, `far_field` is for far-field microphones such as laptop or conference
500/// room microphones.
501#[derive(Debug, Serialize, Deserialize, Clone)]
502#[serde(tag = "type", rename_all = "snake_case")]
503pub enum NoiseReductionType {
504 NearField,
505 FarField,
506}
507
508#[derive(Debug, Serialize, Deserialize, Clone)]
509pub struct TranscriptionAudio {
510 pub input: AudioInput,
511}
512
513/// Realtime transcription session object configuration.
514/// openapi spec type: RealtimeTranscriptionSessionCreateRequestGA
515#[derive(Debug, Serialize, Deserialize, Clone)]
516pub struct RealtimeTranscriptionSession {
517 #[serde(skip_serializing_if = "Option::is_none")]
518 pub id: Option<String>,
519 #[serde(skip_serializing_if = "Option::is_none")]
520 pub expires_at: Option<u64>,
521 /// Configuration for input and output audio.
522 pub audio: TranscriptionAudio,
523
524 /// Additional fields to include in server outputs.
525 ///
526 /// `item.input_audio_transcription.logprobs`: Include logprobs for input audio transcription.
527 #[serde(skip_serializing_if = "Option::is_none")]
528 pub include: Option<Vec<String>>,
529}