Skip to main content

gproxy_protocol/wire/gemini/
voices.rs

1//! Gemini Voices API (`/v1beta/voices`), audited 2026-10-01.
2//! Source: upstream_docs/gemini/docs/Voices.md and the official Interactions OpenAPI.
3//! Bodies and query parameters use snake_case. Voice IDs stay in the URL path.
4//! These wire types do not provision voices or implement gateway routing.
5use crate::{Rest, WireRequest, WireResponse};
6use serde::{Deserialize, Serialize};
7
8pub type CreateVoiceRequest = WireRequest<CreateVoiceRequestBody>;
9pub type CreateVoiceResponse = WireResponse<Voice>;
10pub type ListVoicesRequest = WireRequest<()>;
11pub type ListVoicesResponse = WireResponse<ListVoicesResponseBody>;
12pub type GetVoiceRequest = WireRequest<()>;
13pub type GetVoiceResponse = WireResponse<Voice>;
14pub type DeleteVoiceRequest = WireRequest<()>;
15pub type DeleteVoiceResponse = WireResponse<DeleteVoiceResponseBody>;
16
17#[derive(
18    Debug,
19    Clone,
20    PartialEq,
21    Serialize,
22    Deserialize,
23    gproxy_protocol_macros::WireBuilder,
24    gproxy_protocol_macros::DeclaredFields,
25)]
26#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
27#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
28pub struct CreateVoiceRequestBody {
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub store: Option<bool>,
31    pub voice: Voice,
32    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
33    pub rest: Rest,
34}
35
36#[derive(
37    Debug,
38    Clone,
39    PartialEq,
40    Serialize,
41    Deserialize,
42    gproxy_protocol_macros::WireBuilder,
43    gproxy_protocol_macros::DeclaredFields,
44)]
45#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
46#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
47pub struct ListVoicesResponseBody {
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub next_page_token: Option<String>,
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub voices: Option<Vec<Voice>>,
52    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
53    pub rest: Rest,
54}
55
56#[derive(
57    Debug,
58    Clone,
59    PartialEq,
60    Serialize,
61    Deserialize,
62    gproxy_protocol_macros::WireBuilder,
63    gproxy_protocol_macros::DeclaredFields,
64)]
65#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
66#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
67pub struct DeleteVoiceResponseBody {
68    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
69    pub rest: Rest,
70}
71
72#[derive(
73    Debug,
74    Clone,
75    PartialEq,
76    Serialize,
77    Deserialize,
78    gproxy_protocol_macros::WireBuilder,
79    gproxy_protocol_macros::DeclaredFields,
80)]
81#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
82#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
83pub struct Voice {
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub accent: Option<String>,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub context: Option<String>,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub description: Option<String>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub display_name: Option<String>,
92    /// Output only.
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub expire_time: Option<String>,
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub gender: Option<String>,
97    /// Output only.
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub id: Option<String>,
100    /// Output only.
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub key: Option<String>,
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub language_code: Option<String>,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub model: Option<String>,
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub persona: Option<String>,
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub pitch: Option<Pitch>,
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub prompted: Option<PromptedVoice>,
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub region_code: Option<String>,
115    /// Input only; the server does not return consent or reference recordings.
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub replicated: Option<ReplicatedVoice>,
118    /// Output only.
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub sample_audio: Option<AudioData>,
121    #[serde(rename = "type")]
122    pub type_: VoiceType,
123    /// Output only.
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub usage: Option<Usage>,
126    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
127    pub rest: Rest,
128}
129
130#[derive(
131    Debug,
132    Clone,
133    Copy,
134    PartialEq,
135    Eq,
136    Serialize,
137    Deserialize,
138    gproxy_protocol_macros::DeclaredFields,
139)]
140#[serde(rename_all = "snake_case")]
141#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
142#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
143pub enum Pitch {
144    Low,
145    Medium,
146    High,
147}
148
149#[derive(
150    Debug,
151    Clone,
152    PartialEq,
153    Serialize,
154    Deserialize,
155    gproxy_protocol_macros::WireBuilder,
156    gproxy_protocol_macros::DeclaredFields,
157)]
158#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
159#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
160pub struct PromptedVoice {
161    pub input: String,
162    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
163    pub rest: Rest,
164}
165
166#[derive(
167    Debug,
168    Clone,
169    PartialEq,
170    Serialize,
171    Deserialize,
172    gproxy_protocol_macros::WireBuilder,
173    gproxy_protocol_macros::DeclaredFields,
174)]
175#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
176#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
177pub struct ReplicatedVoice {
178    pub consent_audio: AudioData,
179    pub source_audio: AudioData,
180    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
181    pub rest: Rest,
182}
183
184#[derive(
185    Debug,
186    Clone,
187    PartialEq,
188    Serialize,
189    Deserialize,
190    gproxy_protocol_macros::WireBuilder,
191    gproxy_protocol_macros::DeclaredFields,
192)]
193#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
194#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
195pub struct AudioData {
196    pub data: String,
197    pub mime_type: String,
198    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
199    pub rest: Rest,
200}
201
202#[derive(
203    Debug,
204    Clone,
205    Copy,
206    PartialEq,
207    Eq,
208    Serialize,
209    Deserialize,
210    gproxy_protocol_macros::DeclaredFields,
211)]
212#[serde(rename_all = "snake_case")]
213#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
214#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
215pub enum VoiceType {
216    Replicated,
217    Prompted,
218    Prebuilt,
219}
220
221#[derive(
222    Debug,
223    Clone,
224    PartialEq,
225    Serialize,
226    Deserialize,
227    gproxy_protocol_macros::WireBuilder,
228    gproxy_protocol_macros::DeclaredFields,
229)]
230#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
231#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
232pub struct Usage {
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub cached_tokens_by_modality: Option<Vec<ModalityTokens>>,
235    #[serde(skip_serializing_if = "Option::is_none")]
236    pub grounding_tool_count: Option<Vec<GroundingToolCount>>,
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub input_tokens_by_modality: Option<Vec<ModalityTokens>>,
239    #[serde(skip_serializing_if = "Option::is_none")]
240    pub output_tokens_by_modality: Option<Vec<ModalityTokens>>,
241    #[serde(skip_serializing_if = "Option::is_none")]
242    pub tool_use_tokens_by_modality: Option<Vec<ModalityTokens>>,
243    #[serde(skip_serializing_if = "Option::is_none")]
244    pub total_cached_tokens: Option<i64>,
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub total_input_tokens: Option<i64>,
247    #[serde(skip_serializing_if = "Option::is_none")]
248    pub total_output_tokens: Option<i64>,
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub total_thought_tokens: Option<i64>,
251    #[serde(skip_serializing_if = "Option::is_none")]
252    pub total_tokens: Option<i64>,
253    #[serde(skip_serializing_if = "Option::is_none")]
254    pub total_tool_use_tokens: Option<i64>,
255    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
256    pub rest: Rest,
257}
258
259#[derive(
260    Debug,
261    Clone,
262    PartialEq,
263    Serialize,
264    Deserialize,
265    gproxy_protocol_macros::WireBuilder,
266    gproxy_protocol_macros::DeclaredFields,
267)]
268#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
269#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
270pub struct ModalityTokens {
271    #[serde(skip_serializing_if = "Option::is_none")]
272    pub modality: Option<ResponseModality>,
273    #[serde(skip_serializing_if = "Option::is_none")]
274    pub tokens: Option<i64>,
275    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
276    pub rest: Rest,
277}
278
279#[derive(
280    Debug,
281    Clone,
282    PartialEq,
283    Serialize,
284    Deserialize,
285    gproxy_protocol_macros::WireBuilder,
286    gproxy_protocol_macros::DeclaredFields,
287)]
288#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
289#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
290pub struct GroundingToolCount {
291    #[serde(skip_serializing_if = "Option::is_none")]
292    pub count: Option<i64>,
293    #[serde(skip_serializing_if = "Option::is_none")]
294    #[serde(rename = "type")]
295    pub type_: Option<GroundingToolType>,
296    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
297    pub rest: Rest,
298}
299
300#[derive(
301    Debug,
302    Clone,
303    Copy,
304    PartialEq,
305    Eq,
306    Serialize,
307    Deserialize,
308    gproxy_protocol_macros::DeclaredFields,
309)]
310#[serde(rename_all = "snake_case")]
311#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
312#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
313pub enum ResponseModality {
314    Text,
315    Image,
316    Audio,
317    Video,
318    Document,
319}
320
321#[derive(
322    Debug,
323    Clone,
324    Copy,
325    PartialEq,
326    Eq,
327    Serialize,
328    Deserialize,
329    gproxy_protocol_macros::DeclaredFields,
330)]
331#[serde(rename_all = "snake_case")]
332#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
333#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
334pub enum GroundingToolType {
335    GoogleSearch,
336    GoogleMaps,
337    Retrieval,
338}
339
340#[derive(
341    Debug,
342    Clone,
343    PartialEq,
344    Serialize,
345    Deserialize,
346    gproxy_protocol_macros::WireBuilder,
347    gproxy_protocol_macros::DeclaredFields,
348)]
349#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
350#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
351pub struct ListVoicesQuery {
352    #[serde(skip_serializing_if = "Option::is_none")]
353    pub accent: Option<Vec<String>>,
354    #[serde(skip_serializing_if = "Option::is_none")]
355    pub context: Option<Vec<String>>,
356    #[serde(skip_serializing_if = "Option::is_none")]
357    pub gender: Option<Vec<String>>,
358    #[serde(skip_serializing_if = "Option::is_none")]
359    pub language_code: Option<Vec<String>>,
360    #[serde(skip_serializing_if = "Option::is_none")]
361    pub page_size: Option<i64>,
362    #[serde(skip_serializing_if = "Option::is_none")]
363    pub page_token: Option<String>,
364    #[serde(skip_serializing_if = "Option::is_none")]
365    pub persona: Option<Vec<String>>,
366    #[serde(skip_serializing_if = "Option::is_none")]
367    pub pitch: Option<Vec<String>>,
368    #[serde(skip_serializing_if = "Option::is_none")]
369    pub region_code: Option<Vec<String>>,
370    #[serde(skip_serializing_if = "Option::is_none")]
371    pub search: Option<String>,
372    #[serde(skip_serializing_if = "Option::is_none")]
373    #[serde(rename = "type")]
374    pub type_: Option<Vec<String>>,
375    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
376    pub rest: Rest,
377}