Skip to main content

gproxy_protocol/wire/openai/
models.rs

1use serde::{Deserialize, Serialize};
2
3use crate::Rest;
4
5/// Query/path request shapes for `GET /models` and `GET /models/{model}`.
6/// Source: `upstream_docs/openai/docs/List models.md` and `Retrieve model.md`.
7/// Extended catalog fields follow `samples/codex/codex-rs/protocol/src/openai_models.rs`.
8pub type ListModelsRequest = crate::WireRequest<()>;
9
10#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(rename_all = "snake_case")]
12#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
13#[derive(gproxy_protocol_macros::DeclaredFields)]
14pub enum ListObject {
15    #[default]
16    List,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(rename_all = "snake_case")]
21#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
22#[derive(gproxy_protocol_macros::DeclaredFields)]
23pub enum ModelObject {
24    Model,
25}
26
27pub type GetModelRequest = crate::WireRequest<()>;
28
29#[derive(
30    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
31)]
32#[serde(rename_all = "snake_case")]
33#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
34#[derive(gproxy_protocol_macros::DeclaredFields)]
35pub struct ListModelsResponseBody {
36    #[serde(default)]
37    pub data: Vec<Model>,
38    #[serde(default)]
39    pub object: ListObject,
40    #[serde(default, skip_serializing_if = "Option::is_none")]
41    pub models: Option<Vec<Model>>,
42    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
43    pub rest: Rest,
44}
45
46pub type ListModelsResponse = crate::WireResponse<ListModelsResponseBody>;
47pub type GetModelResponse = crate::WireResponse<Model>;
48
49#[derive(
50    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
51)]
52#[serde(rename_all = "snake_case")]
53#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
54#[derive(gproxy_protocol_macros::DeclaredFields)]
55pub struct Model {
56    #[serde(default, skip_serializing_if = "String::is_empty")]
57    pub id: String,
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub slug: Option<String>,
60    /// Some compatible catalogs do not report a creation timestamp.
61    #[wire(required)]
62    #[serde(default, skip_serializing_if = "Option::is_none")]
63    pub created: Option<i64>,
64    #[wire(required)]
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub object: Option<ModelObject>,
67    #[wire(required)]
68    #[serde(default, skip_serializing_if = "Option::is_none")]
69    pub owned_by: Option<String>,
70
71    // GPROXY model extensions, matching the v3 OpenAI model contract.
72    #[serde(default, skip_serializing_if = "Option::is_none")]
73    pub display_name: Option<String>,
74    #[serde(default, skip_serializing_if = "Option::is_none")]
75    pub description: Option<String>,
76    #[serde(default, skip_serializing_if = "Option::is_none")]
77    pub instructions: Option<String>,
78    #[serde(default, skip_serializing_if = "Option::is_none")]
79    pub context_window: Option<u64>,
80    #[serde(default, skip_serializing_if = "Option::is_none")]
81    pub max_context_window: Option<u64>,
82    #[serde(default, skip_serializing_if = "Option::is_none")]
83    pub max_output_tokens: Option<u64>,
84    #[serde(default, skip_serializing_if = "Option::is_none")]
85    pub thinking_supported: Option<bool>,
86    #[serde(default, skip_serializing_if = "Option::is_none")]
87    pub input_modalities: Option<Vec<String>>,
88    #[serde(default, skip_serializing_if = "Option::is_none")]
89    pub output_modalities: Option<Vec<String>>,
90    #[serde(default, skip_serializing_if = "Option::is_none")]
91    pub supported_parameters: Option<Vec<String>>,
92    #[serde(
93        default,
94        deserialize_with = "reasoning_levels",
95        skip_serializing_if = "Option::is_none"
96    )]
97    pub supported_reasoning_levels: Option<Vec<ModelReasoningLevel>>,
98    #[serde(default, skip_serializing_if = "Option::is_none")]
99    pub default_reasoning_level: Option<ModelReasoningEffort>,
100    #[serde(default, skip_serializing_if = "Option::is_none")]
101    pub service_tiers: Option<Vec<ModelServiceTier>>,
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub default_service_tier: Option<String>,
104    #[serde(default, skip_serializing_if = "Option::is_none")]
105    pub generation_methods: Option<Vec<String>>,
106    #[serde(default, skip_serializing_if = "Option::is_none")]
107    pub supported_actions: Option<Vec<String>>,
108
109    // Codex model catalog extensions.
110    #[serde(default, skip_serializing_if = "Option::is_none")]
111    pub guardian: Option<GuardianModelPolicy>,
112    #[serde(default, skip_serializing_if = "Option::is_none")]
113    pub shell_type: Option<ConfigShellToolType>,
114    #[serde(default, skip_serializing_if = "Option::is_none")]
115    pub visibility: Option<ModelVisibility>,
116    #[serde(default, skip_serializing_if = "Option::is_none")]
117    pub supported_in_api: Option<bool>,
118    #[serde(default, skip_serializing_if = "Option::is_none")]
119    pub priority: Option<i32>,
120    #[serde(default, skip_serializing_if = "Option::is_none")]
121    pub additional_speed_tiers: Option<Vec<String>>,
122    #[serde(default, skip_serializing_if = "Option::is_none")]
123    pub available_access_programs: Option<ModelAccessPrograms>,
124    #[serde(default, skip_serializing_if = "Option::is_none")]
125    pub availability_nux: Option<ModelAvailabilityNux>,
126    #[serde(default, skip_serializing_if = "Option::is_none")]
127    pub upgrade: Option<ModelInfoUpgrade>,
128    #[serde(default, skip_serializing_if = "Option::is_none")]
129    pub model_messages: Option<ModelMessages>,
130    #[serde(default, skip_serializing_if = "Option::is_none")]
131    pub include_skills_usage_instructions: Option<bool>,
132    #[serde(default, skip_serializing_if = "Option::is_none")]
133    pub include_plugin_usage_instructions: Option<bool>,
134    #[serde(default, skip_serializing_if = "Option::is_none")]
135    pub include_apps_usage_instructions: Option<bool>,
136    #[serde(default, skip_serializing_if = "Option::is_none")]
137    pub supports_reasoning_summary_parameter: Option<bool>,
138    #[serde(default, skip_serializing_if = "Option::is_none")]
139    pub default_reasoning_summary: Option<ModelReasoningSummary>,
140    #[serde(default, skip_serializing_if = "Option::is_none")]
141    pub support_verbosity: Option<bool>,
142    #[serde(default, skip_serializing_if = "Option::is_none")]
143    pub default_verbosity: Option<super::responses::TextVerbosity>,
144    #[serde(default, skip_serializing_if = "Option::is_none")]
145    pub apply_patch_tool_type: Option<ApplyPatchToolType>,
146    #[serde(default, skip_serializing_if = "Option::is_none")]
147    pub web_search_tool_type: Option<WebSearchToolType>,
148    #[serde(default, skip_serializing_if = "Option::is_none")]
149    pub truncation_policy: Option<TruncationPolicyConfig>,
150    #[serde(default, skip_serializing_if = "Option::is_none")]
151    pub supports_image_detail_original: Option<bool>,
152    #[serde(default, skip_serializing_if = "Option::is_none")]
153    pub auto_compact_token_limit: Option<i64>,
154    #[serde(default, skip_serializing_if = "Option::is_none")]
155    pub comp_hash: Option<String>,
156    #[serde(default, skip_serializing_if = "Option::is_none")]
157    pub effective_context_window_percent: Option<i64>,
158    #[serde(default, skip_serializing_if = "Option::is_none")]
159    pub experimental_supported_tools: Option<Vec<String>>,
160    #[serde(default, skip_serializing_if = "Option::is_none")]
161    pub supports_search_tool: Option<bool>,
162    #[serde(default, skip_serializing_if = "Option::is_none")]
163    pub supports_experimental_context: Option<bool>,
164    #[serde(default, skip_serializing_if = "Option::is_none")]
165    pub use_responses_lite: Option<bool>,
166    #[serde(default, skip_serializing_if = "Option::is_none")]
167    pub supports_reasoning_effort_updates: Option<bool>,
168    #[serde(default, skip_serializing_if = "Option::is_none")]
169    pub node_repl_auto_review_required: Option<bool>,
170    #[serde(default, skip_serializing_if = "Option::is_none")]
171    pub node_repl_disabled: Option<bool>,
172    #[serde(default, skip_serializing_if = "Option::is_none")]
173    pub auto_review_model_override: Option<String>,
174    #[serde(default, skip_serializing_if = "Option::is_none")]
175    pub model_specialty: Option<String>,
176    #[serde(
177        default,
178        deserialize_with = "optional_selector",
179        skip_serializing_if = "Option::is_none"
180    )]
181    pub tool_mode: Option<ToolMode>,
182    #[serde(
183        default,
184        deserialize_with = "optional_selector",
185        skip_serializing_if = "Option::is_none"
186    )]
187    pub multi_agent_version: Option<MultiAgentVersion>,
188    #[serde(default, skip_serializing_if = "Option::is_none")]
189    pub multi_agent_reasoning_effort: Option<ModelReasoningEffort>,
190    #[serde(default, skip_serializing_if = "Option::is_none")]
191    pub base_instructions: Option<String>,
192    // Fields also advertised by the bundled Codex catalog.
193    #[serde(default, skip_serializing_if = "Option::is_none")]
194    pub prefer_websockets: Option<bool>,
195    #[serde(default, skip_serializing_if = "Option::is_none")]
196    pub supports_parallel_tool_calls: Option<bool>,
197    #[serde(default, skip_serializing_if = "Option::is_none")]
198    pub supports_reasoning_summaries: Option<bool>,
199    #[serde(default, skip_serializing_if = "Option::is_none")]
200    pub requires_sandboxed_review: Option<bool>,
201    #[serde(default, skip_serializing_if = "Option::is_none")]
202    pub available_in_plans: Option<Vec<String>>,
203    #[serde(default, skip_serializing_if = "Option::is_none")]
204    pub minimal_client_version: Option<ClientVersion>,
205    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
206    pub rest: Rest,
207}
208
209#[derive(
210    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
211)]
212pub struct ModelReasoningLevel {
213    pub effort: ModelReasoningEffort,
214    pub description: String,
215}
216#[derive(
217    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
218)]
219pub struct ModelServiceTier {
220    pub id: String,
221    pub name: String,
222    pub description: String,
223}
224
225fn reasoning_levels<'de, D>(deserializer: D) -> Result<Option<Vec<ModelReasoningLevel>>, D::Error>
226where
227    D: serde::Deserializer<'de>,
228{
229    #[derive(Deserialize)]
230    #[serde(untagged)]
231    enum Level {
232        Preset(ModelReasoningLevel),
233        Effort(ModelReasoningEffort),
234    }
235    Ok(
236        Option::<Vec<Level>>::deserialize(deserializer)?.map(|levels| {
237            levels
238                .into_iter()
239                .map(|level| match level {
240                    Level::Preset(preset) => preset,
241                    Level::Effort(effort) => ModelReasoningLevel {
242                        effort,
243                        description: String::new(),
244                    },
245                })
246                .collect()
247        }),
248    )
249}
250
251#[derive(
252    Debug,
253    Clone,
254    Default,
255    PartialEq,
256    Eq,
257    Serialize,
258    Deserialize,
259    gproxy_protocol_macros::DeclaredFields,
260)]
261pub struct ModelMessages {
262    #[serde(default, skip_serializing_if = "Option::is_none")]
263    pub content_filter_guidance: Option<String>,
264    #[serde(default, skip_serializing_if = "Option::is_none")]
265    pub persistent_instructions: Option<String>,
266    #[serde(default, skip_serializing_if = "Option::is_none")]
267    pub tools: Option<ToolMessages>,
268    #[serde(default, skip_serializing_if = "Option::is_none")]
269    pub instructions_template: Option<String>,
270    #[serde(default, skip_serializing_if = "Option::is_none")]
271    pub instructions_variables: Option<ModelInstructionsVariables>,
272    #[serde(default, skip_serializing_if = "Option::is_none")]
273    pub approvals: Option<ApprovalMessages>,
274    #[serde(default, skip_serializing_if = "Option::is_none")]
275    pub collaboration_modes: Option<CollaborationModeMessages>,
276    #[serde(default, skip_serializing_if = "Option::is_none")]
277    pub auto_review: Option<AutoReviewMessages>,
278    #[serde(default, skip_serializing_if = "Option::is_none")]
279    pub permissions: Option<PermissionMessages>,
280    #[serde(default, skip_serializing_if = "Option::is_none")]
281    pub multi_agent: Option<MultiAgentMessages>,
282    #[serde(default, skip_serializing_if = "Option::is_none")]
283    pub token_budget: Option<ModelTokenBudgetConfig>,
284    #[serde(default, skip_serializing_if = "Option::is_none")]
285    pub guardian_v2: Option<GuardianV2ModelConfig>,
286    #[serde(default, skip_serializing_if = "Option::is_none")]
287    pub confirmation_policies: Option<ConfirmationPolicies>,
288    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
289    pub rest: Rest,
290}
291
292#[derive(
293    Debug,
294    Clone,
295    Default,
296    PartialEq,
297    Eq,
298    Serialize,
299    Deserialize,
300    gproxy_protocol_macros::DeclaredFields,
301)]
302pub struct ConfirmationPolicies {
303    #[serde(default, skip_serializing_if = "Option::is_none")]
304    pub browser_use: Option<String>,
305    #[serde(default, skip_serializing_if = "Option::is_none")]
306    pub computer_use: Option<String>,
307    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
308    pub rest: Rest,
309}
310
311#[derive(
312    Debug,
313    Clone,
314    Default,
315    PartialEq,
316    Eq,
317    Serialize,
318    Deserialize,
319    gproxy_protocol_macros::DeclaredFields,
320)]
321pub struct ToolMessages {
322    #[serde(default, skip_serializing_if = "Option::is_none")]
323    pub indirect_description_prefixes: Option<IndirectDescriptionPrefixes>,
324    #[serde(default, skip_serializing_if = "Option::is_none")]
325    pub send_user_message_async: Option<ToolMessage>,
326    #[serde(default, skip_serializing_if = "Option::is_none")]
327    pub multi_agent: Option<MultiAgentToolMessages>,
328    #[serde(default, skip_serializing_if = "Option::is_none")]
329    pub code_mode: Option<CodeModeToolMessages>,
330    #[serde(default, skip_serializing_if = "Option::is_none")]
331    pub mcp_resources: Option<McpResourceToolMessages>,
332    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
333    pub rest: Rest,
334}
335
336#[derive(
337    Debug,
338    Clone,
339    Default,
340    PartialEq,
341    Eq,
342    Serialize,
343    Deserialize,
344    gproxy_protocol_macros::DeclaredFields,
345)]
346pub struct IndirectDescriptionPrefixes {
347    #[serde(default, skip_serializing_if = "Option::is_none")]
348    pub namespaces: Option<std::collections::BTreeMap<String, String>>,
349    #[serde(default, skip_serializing_if = "Option::is_none")]
350    pub mcp_servers: Option<std::collections::BTreeMap<String, String>>,
351    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
352    pub rest: Rest,
353}
354
355#[derive(
356    Debug,
357    Clone,
358    Default,
359    PartialEq,
360    Eq,
361    Serialize,
362    Deserialize,
363    gproxy_protocol_macros::DeclaredFields,
364)]
365pub struct ToolMessage {
366    #[serde(default, skip_serializing_if = "Option::is_none")]
367    pub description: Option<String>,
368    #[serde(default, skip_serializing_if = "Option::is_none")]
369    pub parameters: Option<String>,
370    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
371    pub rest: Rest,
372}
373
374#[derive(
375    Debug,
376    Clone,
377    Default,
378    PartialEq,
379    Eq,
380    Serialize,
381    Deserialize,
382    gproxy_protocol_macros::DeclaredFields,
383)]
384pub struct MultiAgentToolMessages {
385    #[serde(default, skip_serializing_if = "Option::is_none")]
386    pub spawn_agent: Option<ToolMessage>,
387    #[serde(default, skip_serializing_if = "Option::is_none")]
388    pub send_message: Option<ToolMessage>,
389    #[serde(default, skip_serializing_if = "Option::is_none")]
390    pub followup_task: Option<ToolMessage>,
391    #[serde(default, skip_serializing_if = "Option::is_none")]
392    pub wait_agent: Option<ToolMessage>,
393    #[serde(default, skip_serializing_if = "Option::is_none")]
394    pub interrupt_agent: Option<ToolMessage>,
395    #[serde(default, skip_serializing_if = "Option::is_none")]
396    pub list_agents: Option<ToolMessage>,
397    #[serde(default, skip_serializing_if = "Option::is_none")]
398    pub create_channel: Option<ToolMessage>,
399    #[serde(default, skip_serializing_if = "Option::is_none")]
400    pub get_channels: Option<ToolMessage>,
401    #[serde(default, skip_serializing_if = "Option::is_none")]
402    pub list_threads: Option<ToolMessage>,
403    #[serde(default, skip_serializing_if = "Option::is_none")]
404    pub search_posts: Option<ToolMessage>,
405    #[serde(default, skip_serializing_if = "Option::is_none")]
406    pub read_thread: Option<ToolMessage>,
407    #[serde(default, skip_serializing_if = "Option::is_none")]
408    pub read_post: Option<ToolMessage>,
409    #[serde(default, skip_serializing_if = "Option::is_none")]
410    pub subscribe: Option<ToolMessage>,
411    #[serde(default, skip_serializing_if = "Option::is_none")]
412    pub unsubscribe: Option<ToolMessage>,
413    #[serde(default, skip_serializing_if = "Option::is_none")]
414    pub post: Option<ToolMessage>,
415    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
416    pub rest: Rest,
417}
418
419#[derive(
420    Debug,
421    Clone,
422    Default,
423    PartialEq,
424    Eq,
425    Serialize,
426    Deserialize,
427    gproxy_protocol_macros::DeclaredFields,
428)]
429pub struct McpResourceToolMessages {
430    #[serde(default, skip_serializing_if = "Option::is_none")]
431    pub list_mcp_resources: Option<ToolMessage>,
432    #[serde(default, skip_serializing_if = "Option::is_none")]
433    pub list_mcp_resource_templates: Option<ToolMessage>,
434    #[serde(default, skip_serializing_if = "Option::is_none")]
435    pub read_mcp_resource: Option<ToolMessage>,
436    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
437    pub rest: Rest,
438}
439
440#[derive(
441    Debug,
442    Clone,
443    Default,
444    PartialEq,
445    Eq,
446    Serialize,
447    Deserialize,
448    gproxy_protocol_macros::DeclaredFields,
449)]
450pub struct CodeModeToolMessages {
451    #[serde(default, skip_serializing_if = "Option::is_none")]
452    pub exec: Option<ToolMessage>,
453    #[serde(default, skip_serializing_if = "Option::is_none")]
454    pub wait: Option<ToolMessage>,
455    #[serde(default, skip_serializing_if = "Option::is_none")]
456    pub deferred_nested_tools_guidance: Option<String>,
457    #[serde(default, skip_serializing_if = "Option::is_none")]
458    pub mcp_typescript_preamble: Option<String>,
459    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
460    pub rest: Rest,
461}
462
463#[derive(
464    Debug,
465    Clone,
466    Default,
467    PartialEq,
468    Eq,
469    Serialize,
470    Deserialize,
471    gproxy_protocol_macros::DeclaredFields,
472)]
473pub struct ModelTokenBudgetConfig {
474    #[serde(default)]
475    pub enabled: bool,
476    #[serde(default)]
477    pub use_history_notes_extension: bool,
478    pub reminder_threshold_tokens: i64,
479    pub reminder_message_template: String,
480    pub guidance_message: String,
481    pub auto_compact_fallback_prompt: String,
482    pub auto_compact_fallback_buffer_tokens: i64,
483    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
484    pub rest: Rest,
485}
486
487#[derive(
488    Debug,
489    Clone,
490    Default,
491    PartialEq,
492    Eq,
493    Serialize,
494    Deserialize,
495    gproxy_protocol_macros::DeclaredFields,
496)]
497pub struct ApprovalMessages {
498    #[serde(default, skip_serializing_if = "Option::is_none")]
499    pub on_request: Option<String>,
500    #[serde(default, skip_serializing_if = "Option::is_none")]
501    pub on_request_auto_review: Option<String>,
502    #[serde(default, skip_serializing_if = "Option::is_none")]
503    pub never: Option<String>,
504    #[serde(default, skip_serializing_if = "Option::is_none")]
505    pub unless_trusted: Option<String>,
506    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
507    pub rest: Rest,
508}
509
510#[derive(
511    Debug,
512    Clone,
513    Default,
514    PartialEq,
515    Eq,
516    Serialize,
517    Deserialize,
518    gproxy_protocol_macros::DeclaredFields,
519)]
520pub struct CollaborationModeMessages {
521    #[serde(default, skip_serializing_if = "Option::is_none")]
522    pub default: Option<String>,
523    #[serde(default, skip_serializing_if = "Option::is_none")]
524    pub plan: Option<String>,
525    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
526    pub rest: Rest,
527}
528
529#[derive(
530    Debug,
531    Clone,
532    Default,
533    PartialEq,
534    Eq,
535    Serialize,
536    Deserialize,
537    gproxy_protocol_macros::DeclaredFields,
538)]
539pub struct AutoReviewMessages {
540    #[serde(default, skip_serializing_if = "Option::is_none")]
541    pub policy: Option<String>,
542    #[serde(default, skip_serializing_if = "Option::is_none")]
543    pub policy_template: Option<String>,
544    #[serde(default, skip_serializing_if = "Option::is_none")]
545    pub node_repl_policy: Option<String>,
546    #[serde(default, skip_serializing_if = "Option::is_none")]
547    pub rejection_instructions: Option<String>,
548    #[serde(default, skip_serializing_if = "Option::is_none")]
549    pub timeout_instructions: Option<String>,
550    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
551    pub rest: Rest,
552}
553
554#[derive(
555    Debug,
556    Clone,
557    Default,
558    PartialEq,
559    Eq,
560    Serialize,
561    Deserialize,
562    gproxy_protocol_macros::DeclaredFields,
563)]
564pub struct PermissionMessages {
565    #[serde(default, skip_serializing_if = "Option::is_none")]
566    pub danger_full_access: Option<String>,
567    #[serde(default, skip_serializing_if = "Option::is_none")]
568    pub workspace_write: Option<String>,
569    #[serde(default, skip_serializing_if = "Option::is_none")]
570    pub read_only: Option<String>,
571    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
572    pub rest: Rest,
573}
574
575#[derive(
576    Debug,
577    Clone,
578    Default,
579    PartialEq,
580    Eq,
581    Serialize,
582    Deserialize,
583    gproxy_protocol_macros::DeclaredFields,
584)]
585pub struct MultiAgentMessages {
586    #[serde(default, skip_serializing_if = "Option::is_none")]
587    pub role: Option<MultiAgentRoleMessages>,
588    #[serde(default, skip_serializing_if = "Option::is_none")]
589    pub mode: Option<MultiAgentModeMessages>,
590    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
591    pub rest: Rest,
592}
593
594#[derive(
595    Debug,
596    Clone,
597    Default,
598    PartialEq,
599    Eq,
600    Serialize,
601    Deserialize,
602    gproxy_protocol_macros::DeclaredFields,
603)]
604pub struct MultiAgentRoleMessages {
605    #[serde(default, skip_serializing_if = "Option::is_none")]
606    pub root: Option<String>,
607    #[serde(default, skip_serializing_if = "Option::is_none")]
608    pub subagent: Option<String>,
609    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
610    pub rest: Rest,
611}
612
613#[derive(
614    Debug,
615    Clone,
616    Default,
617    PartialEq,
618    Eq,
619    Serialize,
620    Deserialize,
621    gproxy_protocol_macros::DeclaredFields,
622)]
623pub struct MultiAgentModeMessages {
624    #[serde(default, skip_serializing_if = "Option::is_none")]
625    pub explicit: Option<String>,
626    #[serde(default, skip_serializing_if = "Option::is_none")]
627    pub proactive: Option<String>,
628    #[serde(default, skip_serializing_if = "Option::is_none")]
629    pub hint_text: Option<String>,
630    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
631    pub rest: Rest,
632}
633
634#[derive(
635    Debug,
636    Clone,
637    Default,
638    PartialEq,
639    Eq,
640    Serialize,
641    Deserialize,
642    gproxy_protocol_macros::DeclaredFields,
643)]
644pub struct ModelInstructionsVariables {
645    #[serde(default, skip_serializing_if = "Option::is_none")]
646    pub personality_default: Option<String>,
647    #[serde(default, skip_serializing_if = "Option::is_none")]
648    pub personality_friendly: Option<String>,
649    #[serde(default, skip_serializing_if = "Option::is_none")]
650    pub personality_pragmatic: Option<String>,
651    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
652    pub rest: Rest,
653}
654
655#[derive(
656    Debug,
657    Clone,
658    Default,
659    PartialEq,
660    Eq,
661    Serialize,
662    Deserialize,
663    gproxy_protocol_macros::DeclaredFields,
664)]
665pub struct ModelInfoUpgrade {
666    pub model: String,
667    pub migration_markdown: String,
668    #[serde(default, skip_serializing_if = "Option::is_none")]
669    pub retirement_at: Option<String>,
670    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
671    pub rest: Rest,
672}
673
674#[derive(
675    Debug,
676    Clone,
677    Default,
678    PartialEq,
679    Eq,
680    Serialize,
681    Deserialize,
682    gproxy_protocol_macros::DeclaredFields,
683)]
684pub struct ModelAvailabilityNux {
685    pub message: String,
686    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
687    pub rest: Rest,
688}
689
690#[derive(
691    Debug,
692    Clone,
693    Default,
694    PartialEq,
695    Eq,
696    Serialize,
697    Deserialize,
698    gproxy_protocol_macros::DeclaredFields,
699)]
700pub struct GuardianModelPolicy {
701    #[serde(default, skip_serializing_if = "Option::is_none")]
702    pub computer_use: Option<GuardianReviewMode>,
703    #[serde(default, skip_serializing_if = "Option::is_none")]
704    pub shell: Option<GuardianReviewMode>,
705    #[serde(default, skip_serializing_if = "Option::is_none")]
706    pub file_changes: Option<GuardianReviewMode>,
707    #[serde(default, skip_serializing_if = "Option::is_none")]
708    pub mcp: Option<GuardianReviewMode>,
709    #[serde(default, skip_serializing_if = "Option::is_none")]
710    pub network: Option<GuardianReviewMode>,
711    #[serde(default, skip_serializing_if = "Option::is_none")]
712    pub permissions: Option<GuardianReviewMode>,
713    #[serde(default, skip_serializing_if = "Option::is_none")]
714    pub other_tools: Option<GuardianReviewMode>,
715    #[serde(default, skip_serializing_if = "Option::is_none")]
716    pub unscored_action: Option<GuardianUnscoredAction>,
717    #[serde(default, skip_serializing_if = "Option::is_none")]
718    pub initial_cua_call: Option<bool>,
719    #[serde(default, skip_serializing_if = "Option::is_none")]
720    pub sandboxed_exec_commands: Option<bool>,
721    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
722    pub rest: Rest,
723}
724
725#[derive(
726    Debug,
727    Clone,
728    Default,
729    PartialEq,
730    Eq,
731    Serialize,
732    Deserialize,
733    gproxy_protocol_macros::DeclaredFields,
734)]
735pub struct GuardianV2ModelConfig {
736    #[serde(default, skip_serializing_if = "Option::is_none")]
737    pub async_classifier_mode: Option<AsyncClassifierMode>,
738    #[serde(default, skip_serializing_if = "Option::is_none")]
739    pub async_classifier_conversation_token_limit: Option<usize>,
740    #[serde(default, skip_serializing_if = "Option::is_none")]
741    pub classifier_instructions: Option<String>,
742    #[serde(default, skip_serializing_if = "Option::is_none")]
743    pub review_threshold_basis_points: Option<u16>,
744    #[serde(default, skip_serializing_if = "Option::is_none")]
745    pub max_tool_call_lag: Option<usize>,
746    #[serde(default, skip_serializing_if = "Option::is_none")]
747    pub reasoning_effort: Option<ModelReasoningEffort>,
748    #[serde(default, skip_serializing_if = "Option::is_none")]
749    pub transcript: Option<GuardianV2TranscriptModelConfig>,
750    #[serde(default, skip_serializing_if = "Option::is_none")]
751    pub max_action_tokens: Option<usize>,
752    #[serde(default, skip_serializing_if = "Option::is_none")]
753    pub max_classifier_instruction_tokens: Option<usize>,
754    #[serde(default, skip_serializing_if = "Option::is_none")]
755    pub reuse_parent_compaction: Option<bool>,
756    #[serde(default, skip_serializing_if = "Option::is_none")]
757    pub max_parent_compaction_tokens: Option<usize>,
758    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
759    pub rest: Rest,
760}
761
762#[derive(
763    Debug,
764    Clone,
765    Default,
766    PartialEq,
767    Eq,
768    Serialize,
769    Deserialize,
770    gproxy_protocol_macros::DeclaredFields,
771)]
772pub struct GuardianV2TranscriptModelConfig {
773    #[serde(default, skip_serializing_if = "Option::is_none")]
774    pub sources: Option<Vec<String>>,
775    #[serde(default, skip_serializing_if = "Option::is_none")]
776    pub include_images: Option<bool>,
777    #[serde(default, skip_serializing_if = "Option::is_none")]
778    pub max_message_entry_tokens: Option<usize>,
779    #[serde(default, skip_serializing_if = "Option::is_none")]
780    pub max_tool_entry_tokens: Option<usize>,
781    #[serde(default, skip_serializing_if = "Option::is_none")]
782    pub max_message_transcript_tokens: Option<usize>,
783    #[serde(default, skip_serializing_if = "Option::is_none")]
784    pub max_tool_transcript_tokens: Option<usize>,
785    #[serde(default, skip_serializing_if = "Option::is_none")]
786    pub max_recent_non_user_entries: Option<usize>,
787    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
788    pub rest: Rest,
789}
790
791#[derive(
792    Debug,
793    Clone,
794    Default,
795    PartialEq,
796    Eq,
797    Serialize,
798    Deserialize,
799    gproxy_protocol_macros::DeclaredFields,
800)]
801pub struct ModelAccessPrograms {
802    #[serde(deserialize_with = "known_cyber_programs")]
803    pub cyber: Vec<CyberAccessProgram>,
804    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
805    pub rest: Rest,
806}
807
808#[derive(
809    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
810)]
811#[serde(rename_all = "snake_case")]
812pub enum ModelVisibility {
813    List,
814    Hide,
815    None,
816}
817
818#[derive(
819    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
820)]
821#[serde(rename_all = "snake_case")]
822pub enum ConfigShellToolType {
823    #[serde(alias = "default", alias = "local", alias = "shell_command")]
824    UnifiedExec,
825    Disabled,
826}
827
828#[derive(
829    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
830)]
831#[serde(rename_all = "snake_case")]
832pub enum ApplyPatchToolType {
833    Freeform,
834}
835
836#[derive(
837    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
838)]
839#[serde(rename_all = "snake_case")]
840pub enum WebSearchToolType {
841    Text,
842    TextAndImage,
843}
844
845#[derive(
846    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
847)]
848#[serde(rename_all = "snake_case")]
849pub enum TruncationMode {
850    Bytes,
851    Tokens,
852}
853
854#[derive(
855    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
856)]
857pub struct TruncationPolicyConfig {
858    pub mode: TruncationMode,
859    pub limit: i64,
860    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
861    pub rest: Rest,
862}
863
864#[derive(
865    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
866)]
867#[serde(rename_all = "snake_case")]
868pub enum ToolMode {
869    Direct,
870    CodeMode,
871    CodeModeOnly,
872}
873
874#[derive(
875    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
876)]
877#[serde(rename_all = "snake_case")]
878pub enum MultiAgentVersion {
879    Disabled,
880    V1,
881    V2,
882}
883
884#[derive(
885    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
886)]
887#[serde(rename_all = "snake_case")]
888pub enum CyberAccessProgram {
889    Standard,
890    DaybreakBlue,
891    DaybreakRed,
892}
893
894#[derive(
895    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
896)]
897#[serde(rename_all = "snake_case")]
898pub enum GuardianReviewMode {
899    Disabled,
900    Synchronous,
901    Adaptive,
902    #[serde(untagged)]
903    Unknown(String),
904}
905
906#[derive(
907    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
908)]
909#[serde(rename_all = "snake_case")]
910pub enum GuardianUnscoredAction {
911    Ignore,
912    AgeScore,
913    InvalidateScore,
914    #[serde(untagged)]
915    Unknown(String),
916}
917
918#[derive(
919    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
920)]
921#[serde(rename_all = "snake_case")]
922pub enum AsyncClassifierMode {
923    Snapshot,
924    Conversation,
925}
926
927#[derive(
928    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
929)]
930#[serde(rename_all = "snake_case")]
931pub enum ModelReasoningSummary {
932    Auto,
933    Concise,
934    Detailed,
935    None,
936}
937
938fn optional_selector<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
939where
940    D: serde::Deserializer<'de>,
941    T: serde::de::DeserializeOwned,
942{
943    Ok(Option::<String>::deserialize(deserializer)?
944        .and_then(|value| serde_json::from_value(serde_json::Value::String(value)).ok()))
945}
946
947fn known_cyber_programs<'de, D>(deserializer: D) -> Result<Vec<CyberAccessProgram>, D::Error>
948where
949    D: serde::Deserializer<'de>,
950{
951    Ok(Vec::<String>::deserialize(deserializer)?
952        .into_iter()
953        .filter_map(|value| serde_json::from_value(serde_json::Value::String(value)).ok())
954        .collect())
955}
956
957#[derive(
958    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
959)]
960#[serde(untagged)]
961pub enum ClientVersion {
962    Text(String),
963    Components([u32; 3]),
964}
965
966/// Catalog effort choices include CLI modes such as Ultra and Persistent;
967/// they are distinct from the Responses request's reasoning-effort parameter.
968#[derive(
969    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::DeclaredFields,
970)]
971#[serde(rename_all = "snake_case")]
972pub enum ModelReasoningEffort {
973    None,
974    Minimal,
975    Low,
976    Medium,
977    High,
978    Xhigh,
979    Max,
980    Ultra,
981    Persistent,
982    #[serde(untagged)]
983    Custom(String),
984}