Skip to main content

gproxy_protocol/wire/claude/
models.rs

1use serde::{Deserialize, Serialize};
2
3use crate::Rest;
4
5/// Request/response shapes for `GET /v1/models` and `GET /v1/models/{model_id}`.
6/// `after_id`, `before_id`, and `limit` are query parameters; `anthropic_beta`
7/// is the repeated `anthropic-beta` request header; `model_id` is a path
8/// parameter. Source: `upstream_docs/claude/docs/List Models.md` and
9/// `Get a Model.md`.
10#[derive(
11    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
12)]
13#[serde(rename_all = "snake_case")]
14#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
15#[derive(gproxy_protocol_macros::DeclaredFields)]
16#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
17pub struct ListModelsQuery {
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub after_id: Option<String>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub before_id: Option<String>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub limit: Option<i64>,
24    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
25    pub rest: Rest,
26}
27
28pub type ListModelsRequest = crate::WireRequest<()>;
29pub type GetModelRequest = crate::WireRequest<()>;
30
31#[derive(
32    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
33)]
34#[serde(rename_all = "snake_case")]
35#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
36#[derive(gproxy_protocol_macros::DeclaredFields)]
37#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
38pub struct ListModelsResponseBody {
39    pub data: Vec<ModelInfo>,
40    #[wire(required)]
41    pub first_id: Option<String>,
42    pub has_more: bool,
43    #[wire(required)]
44    pub last_id: Option<String>,
45    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
46    pub rest: Rest,
47}
48
49pub type ListModelsResponse = crate::WireResponse<ListModelsResponseBody>;
50pub type GetModelResponse = crate::WireResponse<ModelInfo>;
51
52#[derive(
53    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
54)]
55#[serde(rename_all = "snake_case")]
56#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
57#[derive(gproxy_protocol_macros::DeclaredFields)]
58#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
59pub struct ModelInfo {
60    pub id: String,
61    #[serde(default)]
62    #[wire(required)]
63    pub allowed_fallback_models: Option<Vec<String>>,
64    #[wire(required)]
65    pub capabilities: Option<ModelCapabilities>,
66    pub created_at: String,
67    pub display_name: String,
68    /// Provider-reported model line; new lines are allowed without inferring from IDs.
69    #[serde(
70        default,
71        deserialize_with = "present_nullable",
72        skip_serializing_if = "Option::is_none"
73    )]
74    pub line: Option<Option<String>>,
75    #[wire(required)]
76    pub max_input_tokens: Option<i64>,
77    #[wire(required)]
78    pub max_tokens: Option<i64>,
79    #[serde(default, skip_serializing_if = "Option::is_none")]
80    pub lifecycle: Option<ModelLifecycle>,
81    #[serde(
82        default,
83        deserialize_with = "present_nullable",
84        skip_serializing_if = "Option::is_none"
85    )]
86    pub deprecated_at: Option<Option<String>>,
87    #[serde(
88        default,
89        deserialize_with = "present_nullable",
90        skip_serializing_if = "Option::is_none"
91    )]
92    pub retires_at: Option<Option<String>>,
93    #[serde(rename = "type")]
94    pub type_: ModelType,
95    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
96    pub rest: Rest,
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
100#[serde(rename_all = "snake_case")]
101#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
102#[derive(gproxy_protocol_macros::DeclaredFields)]
103#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
104pub enum ModelType {
105    Model,
106}
107
108#[derive(
109    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
110)]
111#[serde(rename_all = "snake_case")]
112#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
113#[derive(gproxy_protocol_macros::DeclaredFields)]
114#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
115pub struct ModelCapabilities {
116    pub batch: CapabilitySupport,
117    pub citations: CapabilitySupport,
118    pub code_execution: CapabilitySupport,
119    #[serde(
120        default,
121        deserialize_with = "present_nullable",
122        skip_serializing_if = "Option::is_none"
123    )]
124    pub compaction: Option<Option<CompactionCapability>>,
125    pub context_management: ContextManagementCapability,
126    pub effort: EffortCapability,
127    pub image_input: CapabilitySupport,
128    pub pdf_input: CapabilitySupport,
129    pub structured_outputs: CapabilitySupport,
130    #[serde(default, skip_serializing_if = "Option::is_none")]
131    pub server_tools: Option<ServerToolsCapability>,
132    pub thinking: ThinkingCapability,
133    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
134    pub rest: Rest,
135}
136
137#[derive(
138    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
139)]
140#[serde(rename_all = "snake_case")]
141#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
142#[derive(gproxy_protocol_macros::DeclaredFields)]
143#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
144pub struct CapabilitySupport {
145    pub supported: bool,
146    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
147    pub rest: Rest,
148}
149
150#[derive(
151    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
152)]
153#[serde(rename_all = "snake_case")]
154#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
155#[derive(gproxy_protocol_macros::DeclaredFields)]
156#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
157pub struct ContextManagementCapability {
158    #[wire(required)]
159    pub clear_thinking_20251015: Option<CapabilitySupport>,
160    #[wire(required)]
161    pub clear_tool_uses_20250919: Option<CapabilitySupport>,
162    #[wire(required)]
163    pub compact_20260112: Option<CapabilitySupport>,
164    pub supported: bool,
165    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
166    pub rest: Rest,
167}
168
169#[derive(
170    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
171)]
172#[serde(rename_all = "snake_case")]
173#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
174#[derive(gproxy_protocol_macros::DeclaredFields)]
175#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
176pub struct EffortCapability {
177    pub high: CapabilitySupport,
178    pub low: CapabilitySupport,
179    pub max: CapabilitySupport,
180    pub medium: CapabilitySupport,
181    pub supported: bool,
182    #[wire(required)]
183    pub xhigh: Option<CapabilitySupport>,
184    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
185    pub rest: Rest,
186}
187
188#[derive(
189    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
190)]
191#[serde(rename_all = "snake_case")]
192#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
193#[derive(gproxy_protocol_macros::DeclaredFields)]
194#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
195pub struct ThinkingCapability {
196    pub supported: bool,
197    pub types: ThinkingTypes,
198    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
199    pub rest: Rest,
200}
201
202#[derive(
203    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
204)]
205#[serde(rename_all = "snake_case")]
206#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
207#[derive(gproxy_protocol_macros::DeclaredFields)]
208#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
209pub struct ThinkingTypes {
210    pub adaptive: CapabilitySupport,
211    pub enabled: CapabilitySupport,
212    #[serde(default, skip_serializing_if = "Option::is_none")]
213    pub disabled: Option<CapabilitySupport>,
214    #[serde(default, skip_serializing_if = "Option::is_none")]
215    pub between_tools: Option<CapabilitySupport>,
216    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
217    pub rest: Rest,
218}
219
220/// Server tool availability is separate from programmatic tool calling
221/// (`ModelCapabilities::code_execution`).
222#[derive(
223    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
224)]
225#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
226#[derive(gproxy_protocol_macros::DeclaredFields)]
227#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
228pub struct ServerToolsCapability {
229    pub supported: bool,
230    pub web_search: CapabilitySupport,
231    pub code_execution: CapabilitySupport,
232    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
233    pub rest: Rest,
234}
235
236fn present_nullable<'de, D, T>(d: D) -> Result<Option<Option<T>>, D::Error>
237where
238    D: serde::Deserializer<'de>,
239    T: Deserialize<'de>,
240{
241    Option::<T>::deserialize(d).map(Some)
242}
243
244/// The lifecycle is authoritative; a past scheduled retirement date alone does
245/// not mean that a model has retired.
246#[derive(
247    Debug,
248    Clone,
249    Copy,
250    PartialEq,
251    Eq,
252    Serialize,
253    Deserialize,
254    gproxy_protocol_macros::DeclaredFields,
255)]
256#[serde(rename_all = "snake_case")]
257#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
258#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
259pub enum ModelLifecycle {
260    Active,
261    Deprecated,
262    Retired,
263}
264
265#[derive(
266    Debug,
267    Clone,
268    PartialEq,
269    Eq,
270    Serialize,
271    Deserialize,
272    gproxy_protocol_macros::WireBuilder,
273    gproxy_protocol_macros::DeclaredFields,
274)]
275#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
276#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
277pub struct CompactionCapability {
278    pub supported: bool,
279    pub summarize: CapabilitySupport,
280    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
281    pub rest: Rest,
282}