Skip to main content

gproxy_protocol/openai/audio/
request.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use crate::openai::common::{OpenAiModelId, Rest, VoiceName};
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
7#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
8pub struct SpeechRequest {
9    pub input: String,
10    pub model: OpenAiModelId,
11    pub voice: SpeechVoice,
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub instructions: Option<String>,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub response_format: Option<SpeechResponseFormat>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub speed: Option<f64>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub stream_format: Option<SpeechStreamFormat>,
20    #[serde(default, flatten)]
21    pub rest: Rest,
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25#[serde(untagged)]
26pub enum SpeechVoice {
27    Named(VoiceName),
28    Custom(CustomVoice),
29    Raw(Value),
30}
31
32#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
33#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
34pub struct CustomVoice {
35    pub id: String,
36    #[serde(default, flatten)]
37    pub rest: Rest,
38}
39
40#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
41#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
42pub struct TranscriptionRequest {
43    pub file: String,
44    pub model: OpenAiModelId,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub chunking_strategy: Option<AudioChunkingStrategy>,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub include: Option<Vec<TranscriptionInclude>>,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub keywords: Option<Vec<String>>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub known_speaker_names: Option<Vec<String>>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub known_speaker_references: Option<Vec<String>>,
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub language: Option<String>,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub languages: Option<Vec<String>>,
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub prompt: Option<String>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub response_format: Option<TranscriptionResponseFormat>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub stream: Option<bool>,
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub temperature: Option<f64>,
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub timestamp_granularities: Option<Vec<TimestampGranularity>>,
69    #[serde(default, flatten)]
70    pub rest: Rest,
71}
72
73#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74#[serde(untagged)]
75pub enum AudioChunkingStrategy {
76    Auto(AudioChunkingAuto),
77    ServerVad(ServerVadConfig),
78    Raw(Value),
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
82pub enum AudioChunkingAuto {
83    #[serde(rename = "auto")]
84    Auto,
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
88#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
89pub struct ServerVadConfig {
90    #[serde(rename = "type")]
91    pub type_: ServerVadType,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub prefix_padding_ms: Option<u32>,
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub silence_duration_ms: Option<u32>,
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub threshold: Option<f64>,
98    #[serde(default, flatten)]
99    pub rest: Rest,
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
103pub enum ServerVadType {
104    #[serde(rename = "server_vad")]
105    ServerVad,
106}
107
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
109#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
110pub struct TranslationRequest {
111    pub file: String,
112    pub model: OpenAiModelId,
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub prompt: Option<String>,
115    #[serde(skip_serializing_if = "Option::is_none")]
116    pub response_format: Option<TranslationResponseFormat>,
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub temperature: Option<f64>,
119    #[serde(default, flatten)]
120    pub rest: Rest,
121}
122
123macro_rules! extensible_string {
124    ($name:ident, $known:ident { $($variant:ident => $wire:literal),+ $(,)? }) => {
125        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
126        #[serde(untagged)]
127        pub enum $name {
128            Known($known),
129            Unknown(String),
130        }
131
132        #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
133        pub enum $known {
134            $(#[serde(rename = $wire)] $variant),+
135        }
136    };
137}
138
139extensible_string!(SpeechResponseFormat, KnownSpeechResponseFormat {
140    Mp3 => "mp3", Opus => "opus", Aac => "aac", Flac => "flac", Wav => "wav", Pcm => "pcm",
141});
142extensible_string!(SpeechStreamFormat, KnownSpeechStreamFormat {
143    Sse => "sse", Audio => "audio",
144});
145extensible_string!(TranscriptionResponseFormat, KnownTranscriptionResponseFormat {
146    Json => "json", Text => "text", Srt => "srt", VerboseJson => "verbose_json",
147    Vtt => "vtt", DiarizedJson => "diarized_json",
148});
149extensible_string!(TranslationResponseFormat, KnownTranslationResponseFormat {
150    Json => "json", Text => "text", Srt => "srt", VerboseJson => "verbose_json", Vtt => "vtt",
151});
152extensible_string!(TimestampGranularity, KnownTimestampGranularity {
153    Word => "word", Segment => "segment",
154});
155extensible_string!(TranscriptionInclude, KnownTranscriptionInclude {
156    Logprobs => "logprobs",
157});