Skip to main content

gproxy_protocol/wire/openai/chat/
response.rs

1use super::content::{FunctionCall, MessageToolCall};
2use super::content::{present_nullable, required_nullable};
3use crate::{Rest, WireResponse};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
7#[serde(rename_all = "snake_case")]
8#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
9#[derive(gproxy_protocol_macros::DeclaredFields)]
10#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
11pub struct GenerateContentResponseBody {
12    pub id: String,
13    pub choices: Vec<Choice>,
14    pub created: i64,
15    pub model: String,
16    pub object: CompletionObject,
17    #[serde(
18        default,
19        deserialize_with = "present_nullable",
20        skip_serializing_if = "Option::is_none"
21    )]
22    pub service_tier: Option<Option<ResponseServiceTier>>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub system_fingerprint: Option<String>,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub usage: Option<Usage>,
27    #[serde(
28        default,
29        deserialize_with = "present_nullable",
30        skip_serializing_if = "Option::is_none"
31    )]
32    pub moderation: Option<Option<ModerationResponse>>,
33    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
34    pub rest: Rest,
35}
36pub type GenerateContentResponse = WireResponse<GenerateContentResponseBody>;
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
38#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
39#[derive(gproxy_protocol_macros::DeclaredFields)]
40#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
41pub enum CompletionObject {
42    #[serde(rename = "chat.completion")]
43    ChatCompletion,
44}
45#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
46#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
47#[derive(gproxy_protocol_macros::DeclaredFields)]
48#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
49pub enum ResponseServiceTier {
50    #[serde(rename = "auto")]
51    Auto,
52    #[serde(rename = "default")]
53    Default,
54    #[serde(rename = "flex")]
55    Flex,
56    #[serde(rename = "scale")]
57    Scale,
58    #[serde(rename = "priority")]
59    Priority,
60    #[serde(rename = "fast")]
61    Fast,
62    #[serde(rename = "ultrafast")]
63    Ultrafast,
64}
65#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
66#[serde(rename_all = "snake_case")]
67#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
68#[derive(gproxy_protocol_macros::DeclaredFields)]
69#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
70pub struct Choice {
71    pub finish_reason: FinishReason,
72    pub index: i64,
73    #[wire(required)]
74    #[cfg_attr(feature = "schema", schemars(extend("x-gproxy-required" = true)))]
75    #[serde(default, deserialize_with = "required_nullable")]
76    pub logprobs: Option<Logprobs>,
77    pub message: ResponseMessage,
78    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
79    pub rest: Rest,
80}
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
82#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
83#[derive(gproxy_protocol_macros::DeclaredFields)]
84#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
85pub enum FinishReason {
86    #[serde(rename = "stop")]
87    Stop,
88    #[serde(rename = "length")]
89    Length,
90    #[serde(rename = "tool_calls")]
91    ToolCalls,
92    #[serde(rename = "content_filter")]
93    ContentFilter,
94    #[serde(rename = "function_call")]
95    FunctionCall,
96}
97#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
98#[serde(rename_all = "snake_case")]
99#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
100#[derive(gproxy_protocol_macros::DeclaredFields)]
101#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
102pub struct ResponseMessage {
103    #[serde(
104        default,
105        deserialize_with = "present_nullable",
106        skip_serializing_if = "Option::is_none"
107    )]
108    pub reasoning_details: Option<Option<Vec<super::reasoning::ReasoningDetail>>>,
109    /// Plain-text reasoning returned by compatible providers (for example DeepSeek).
110    #[serde(
111        default,
112        deserialize_with = "present_nullable",
113        skip_serializing_if = "Option::is_none"
114    )]
115    pub reasoning_content: Option<Option<String>>,
116    /// Alternative compatible-provider spelling. Kept separately on the wire.
117    #[serde(
118        default,
119        deserialize_with = "present_nullable",
120        skip_serializing_if = "Option::is_none"
121    )]
122    pub reasoning: Option<Option<String>>,
123    #[wire(required)]
124    #[cfg_attr(feature = "schema", schemars(extend("x-gproxy-required" = true)))]
125    #[serde(default, deserialize_with = "required_nullable")]
126    pub content: Option<String>,
127    #[wire(required)]
128    #[cfg_attr(feature = "schema", schemars(extend("x-gproxy-required" = true)))]
129    #[serde(default, deserialize_with = "required_nullable")]
130    pub refusal: Option<String>,
131    pub role: ResponseRole,
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub annotations: Option<Vec<Annotation>>,
134    #[serde(
135        default,
136        deserialize_with = "present_nullable",
137        skip_serializing_if = "Option::is_none"
138    )]
139    pub audio: Option<Option<ResponseAudio>>,
140    #[serde(skip_serializing_if = "Option::is_none")]
141    pub function_call: Option<FunctionCall>,
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub tool_calls: Option<Vec<MessageToolCall>>,
144    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
145    pub rest: Rest,
146}
147#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
148#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
149#[derive(gproxy_protocol_macros::DeclaredFields)]
150#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
151pub enum ResponseRole {
152    #[serde(rename = "assistant")]
153    Assistant,
154}
155#[derive(
156    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
157)]
158#[serde(rename_all = "snake_case")]
159#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
160#[derive(gproxy_protocol_macros::DeclaredFields)]
161#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
162pub struct ResponseAudio {
163    pub id: String,
164    pub data: String,
165    pub expires_at: i64,
166    pub transcript: String,
167    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
168    pub rest: Rest,
169}
170#[derive(
171    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
172)]
173#[serde(rename_all = "snake_case")]
174#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
175#[derive(gproxy_protocol_macros::DeclaredFields)]
176#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
177pub struct Annotation {
178    #[serde(rename = "type")]
179    pub type_: AnnotationType,
180    pub url_citation: UrlCitation,
181    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
182    pub rest: Rest,
183}
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
185#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
186#[derive(gproxy_protocol_macros::DeclaredFields)]
187#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
188pub enum AnnotationType {
189    #[serde(rename = "url_citation")]
190    UrlCitation,
191}
192#[derive(
193    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
194)]
195#[serde(rename_all = "snake_case")]
196#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
197#[derive(gproxy_protocol_macros::DeclaredFields)]
198#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
199pub struct UrlCitation {
200    pub end_index: i64,
201    pub start_index: i64,
202    pub title: String,
203    pub url: String,
204    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
205    pub rest: Rest,
206}
207#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
208#[serde(rename_all = "snake_case")]
209#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
210#[derive(gproxy_protocol_macros::DeclaredFields)]
211#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
212pub struct Logprobs {
213    #[wire(required)]
214    #[cfg_attr(feature = "schema", schemars(extend("x-gproxy-required" = true)))]
215    #[serde(deserialize_with = "required_nullable")]
216    pub content: Option<Vec<TokenLogprob>>,
217    #[wire(required)]
218    #[cfg_attr(feature = "schema", schemars(extend("x-gproxy-required" = true)))]
219    #[serde(deserialize_with = "required_nullable")]
220    pub refusal: Option<Vec<TokenLogprob>>,
221    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
222    pub rest: Rest,
223}
224#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
225#[serde(rename_all = "snake_case")]
226#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
227#[derive(gproxy_protocol_macros::DeclaredFields)]
228#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
229pub struct TokenLogprob {
230    pub token: String,
231    #[wire(required)]
232    #[cfg_attr(feature = "schema", schemars(extend("x-gproxy-required" = true)))]
233    #[serde(deserialize_with = "required_nullable")]
234    pub bytes: Option<Vec<i64>>,
235    pub logprob: f64,
236    pub top_logprobs: Vec<TokenLogprobTop>,
237    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
238    pub rest: Rest,
239}
240#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
241#[serde(rename_all = "snake_case")]
242#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
243#[derive(gproxy_protocol_macros::DeclaredFields)]
244#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
245pub struct TokenLogprobTop {
246    pub token: String,
247    #[wire(required)]
248    #[cfg_attr(feature = "schema", schemars(extend("x-gproxy-required" = true)))]
249    #[serde(deserialize_with = "required_nullable")]
250    pub bytes: Option<Vec<i64>>,
251    pub logprob: f64,
252    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
253    pub rest: Rest,
254}
255#[derive(
256    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
257)]
258#[serde(rename_all = "snake_case")]
259#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
260#[derive(gproxy_protocol_macros::DeclaredFields)]
261#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
262pub struct Usage {
263    pub prompt_tokens: i64,
264    pub completion_tokens: i64,
265    pub total_tokens: i64,
266    #[serde(skip_serializing_if = "Option::is_none")]
267    pub prompt_tokens_details: Option<PromptTokensDetails>,
268    #[serde(skip_serializing_if = "Option::is_none")]
269    pub completion_tokens_details: Option<CompletionTokensDetails>,
270    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
271    pub rest: Rest,
272}
273#[derive(
274    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
275)]
276#[serde(rename_all = "snake_case")]
277#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
278#[derive(gproxy_protocol_macros::DeclaredFields)]
279#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
280pub struct PromptTokensDetails {
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub text_tokens: Option<i64>,
283    #[serde(skip_serializing_if = "Option::is_none")]
284    pub image_tokens: Option<i64>,
285    #[serde(skip_serializing_if = "Option::is_none")]
286    pub cache_write_tokens: Option<i64>,
287
288    #[serde(skip_serializing_if = "Option::is_none")]
289    pub cached_tokens: Option<i64>,
290    #[serde(skip_serializing_if = "Option::is_none")]
291    pub audio_tokens: Option<i64>,
292    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
293    pub rest: Rest,
294}
295#[derive(
296    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
297)]
298#[serde(rename_all = "snake_case")]
299#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
300#[derive(gproxy_protocol_macros::DeclaredFields)]
301#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
302pub struct CompletionTokensDetails {
303    #[serde(skip_serializing_if = "Option::is_none")]
304    pub text_tokens: Option<i64>,
305    #[serde(skip_serializing_if = "Option::is_none")]
306    pub accepted_prediction_tokens: Option<i64>,
307    #[serde(skip_serializing_if = "Option::is_none")]
308    pub rejected_prediction_tokens: Option<i64>,
309
310    #[serde(skip_serializing_if = "Option::is_none")]
311    pub reasoning_tokens: Option<i64>,
312    #[serde(skip_serializing_if = "Option::is_none")]
313    pub audio_tokens: Option<i64>,
314    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
315    pub rest: Rest,
316}
317#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
318#[serde(rename_all = "snake_case")]
319#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
320#[derive(gproxy_protocol_macros::DeclaredFields)]
321#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
322pub struct ModerationResponse {
323    pub input: ModerationResultOrError,
324    pub output: ModerationResultOrError,
325    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
326    pub rest: Rest,
327}
328#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
329#[serde(untagged)]
330#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
331#[derive(gproxy_protocol_macros::DeclaredFields)]
332#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
333pub enum ModerationResultOrError {
334    Result(ModerationResult),
335    Error(ModerationError),
336}
337#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
338#[serde(rename_all = "snake_case")]
339#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
340#[derive(gproxy_protocol_macros::DeclaredFields)]
341#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
342pub struct ModerationResult {
343    pub model: String,
344    pub results: Vec<ModerationResultItem>,
345    #[serde(rename = "type")]
346    pub type_: ModerationResultType,
347    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
348    pub rest: Rest,
349}
350#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
351#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
352#[derive(gproxy_protocol_macros::DeclaredFields)]
353#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
354pub enum ModerationResultType {
355    #[serde(rename = "moderation_results")]
356    ModerationResults,
357}
358#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
359#[serde(rename_all = "snake_case")]
360#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
361#[derive(gproxy_protocol_macros::DeclaredFields)]
362#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
363pub struct ModerationResultItem {
364    pub categories: std::collections::BTreeMap<String, bool>,
365    pub category_applied_input_types: std::collections::BTreeMap<String, Vec<ModerationInputType>>,
366    pub category_scores: std::collections::BTreeMap<String, f64>,
367    pub flagged: bool,
368    pub model: String,
369    #[serde(rename = "type")]
370    pub type_: ModerationItemType,
371    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
372    pub rest: Rest,
373}
374#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
375#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
376#[derive(gproxy_protocol_macros::DeclaredFields)]
377#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
378pub enum ModerationInputType {
379    #[serde(rename = "text")]
380    Text,
381    #[serde(rename = "image")]
382    Image,
383}
384#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
385#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
386#[derive(gproxy_protocol_macros::DeclaredFields)]
387#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
388pub enum ModerationItemType {
389    #[serde(rename = "moderation_result")]
390    ModerationResult,
391}
392#[derive(
393    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
394)]
395#[serde(rename_all = "snake_case")]
396#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
397#[derive(gproxy_protocol_macros::DeclaredFields)]
398#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
399pub struct ModerationError {
400    pub code: String,
401    pub message: String,
402    #[serde(rename = "type")]
403    pub type_: ModerationErrorType,
404    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
405    pub rest: Rest,
406}
407#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
408#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
409#[derive(gproxy_protocol_macros::DeclaredFields)]
410#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
411pub enum ModerationErrorType {
412    #[serde(rename = "error")]
413    Error,
414}