gproxy_protocol/openai/audio/
request.rs1use 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});