Skip to main content

gproxy_protocol/protocol/openai/realtime/
session.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4
5use super::super::ResponseToolChoice;
6use super::super::common::*;
7use super::super::generate_content::ResponseTool;
8use super::realtime_string_enum;
9
10realtime_string_enum!(RealtimeSessionType, RealtimeSessionTypeKnown {
11    Realtime => "realtime",
12    Transcription => "transcription",
13});
14
15realtime_string_enum!(RealtimeOutputModality, RealtimeOutputModalityKnown {
16    Text => "text",
17    Audio => "audio",
18});
19
20realtime_string_enum!(NoiseReductionType, NoiseReductionTypeKnown {
21    NearField => "near_field",
22    FarField => "far_field",
23});
24
25realtime_string_enum!(SemanticVadEagerness, SemanticVadEagernessKnown {
26    Low => "low",
27    Medium => "medium",
28    High => "high",
29    Auto => "auto",
30});
31
32#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
33#[non_exhaustive]
34pub struct RealtimeSessionConfig {
35    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
36    pub type_: Option<RealtimeSessionType>,
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub model: Option<OpenAiModelId>,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub output_modalities: Option<Vec<RealtimeOutputModality>>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub instructions: Option<String>,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub audio: Option<RealtimeAudioConfig>,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub include: Option<Vec<String>>,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub tools: Option<Vec<ResponseTool>>,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub tool_choice: Option<ResponseToolChoice>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub max_output_tokens: Option<RealtimeMaxTokens>,
53    #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
54    pub extra: Extra,
55}
56
57#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
58#[serde(untagged)]
59#[non_exhaustive]
60pub enum RealtimeMaxTokens {
61    Count(u64),
62    /// The wire literal `"inf"`.
63    Infinite(String),
64}
65
66#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
67#[non_exhaustive]
68pub struct RealtimeAudioConfig {
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub input: Option<RealtimeAudioInputConfig>,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub output: Option<RealtimeAudioOutputConfig>,
73    #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
74    pub extra: Extra,
75}
76
77#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
78#[non_exhaustive]
79pub struct RealtimeAudioInputConfig {
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub format: Option<RealtimeAudioFormat>,
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub noise_reduction: Option<NoiseReduction>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub transcription: Option<RealtimeTranscriptionConfig>,
86    /// Omitted = server default; `Some(Disabled)` serializes the explicit
87    /// `null` that turns server VAD off.
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub turn_detection: Option<RealtimeTurnDetectionSetting>,
90    #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
91    pub extra: Extra,
92}
93
94#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
95#[non_exhaustive]
96pub struct RealtimeAudioOutputConfig {
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub format: Option<RealtimeAudioFormat>,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub voice: Option<String>,
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub speed: Option<f64>,
103    #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
104    pub extra: Extra,
105}
106
107#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
108#[serde(tag = "type")]
109#[non_exhaustive]
110pub enum RealtimeAudioFormat {
111    #[serde(rename = "audio/pcm")]
112    Pcm {
113        #[serde(skip_serializing_if = "Option::is_none")]
114        rate: Option<u32>,
115        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
116        extra: Extra,
117    },
118    #[serde(rename = "audio/pcmu")]
119    Pcmu {
120        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
121        extra: Extra,
122    },
123    #[serde(rename = "audio/pcma")]
124    Pcma {
125        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
126        extra: Extra,
127    },
128}
129
130#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
131#[non_exhaustive]
132pub struct NoiseReduction {
133    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
134    pub type_: Option<NoiseReductionType>,
135    #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
136    pub extra: Extra,
137}
138
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
140#[non_exhaustive]
141pub struct RealtimeTranscriptionConfig {
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub model: Option<String>,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub language: Option<String>,
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub prompt: Option<String>,
148    #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
149    pub extra: Extra,
150}
151
152#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
153#[serde(untagged)]
154#[non_exhaustive]
155pub enum RealtimeTurnDetectionSetting {
156    /// Serializes as `null`: disables automatic turn detection.
157    Disabled,
158    Vad(RealtimeTurnDetection),
159}
160
161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
162#[serde(tag = "type")]
163#[non_exhaustive]
164pub enum RealtimeTurnDetection {
165    #[serde(rename = "server_vad")]
166    ServerVad {
167        #[serde(skip_serializing_if = "Option::is_none")]
168        threshold: Option<f64>,
169        #[serde(skip_serializing_if = "Option::is_none")]
170        prefix_padding_ms: Option<u32>,
171        #[serde(skip_serializing_if = "Option::is_none")]
172        silence_duration_ms: Option<u32>,
173        #[serde(skip_serializing_if = "Option::is_none")]
174        idle_timeout_ms: Option<u32>,
175        #[serde(skip_serializing_if = "Option::is_none")]
176        create_response: Option<bool>,
177        #[serde(skip_serializing_if = "Option::is_none")]
178        interrupt_response: Option<bool>,
179        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
180        extra: Extra,
181    },
182    #[serde(rename = "semantic_vad")]
183    SemanticVad {
184        #[serde(skip_serializing_if = "Option::is_none")]
185        eagerness: Option<SemanticVadEagerness>,
186        #[serde(skip_serializing_if = "Option::is_none")]
187        create_response: Option<bool>,
188        #[serde(skip_serializing_if = "Option::is_none")]
189        interrupt_response: Option<bool>,
190        #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
191        extra: Extra,
192    },
193}