Skip to main content

gproxy_protocol/claude/
types.rs

1use std::collections::BTreeMap;
2
3use http::StatusCode;
4use serde::{Deserialize, Serialize};
5use time::OffsetDateTime;
6
7/// API version for the `anthropic-version` request header.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
9pub enum AnthropicVersion {
10    /// Latest stable API version.
11    #[default]
12    #[serde(rename = "2023-06-01")]
13    V20230601,
14    /// Initial API release version.
15    #[serde(rename = "2023-01-01")]
16    V20230101,
17}
18
19/// HTTP method used by generated request descriptors.
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
21#[serde(rename_all = "UPPERCASE")]
22pub enum HttpMethod {
23    Get,
24    Post,
25    Put,
26    Patch,
27    Delete,
28}
29
30/// Common envelope for HTTP responses from Claude endpoints.
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct ClaudeApiResponse<T> {
33    /// HTTP status code returned by server.
34    #[serde(with = "crate::claude::types::status_code_serde")]
35    pub stats_code: StatusCode,
36    /// Response headers.
37    pub headers: ClaudeResponseHeaders,
38    /// Response body.
39    pub body: T,
40}
41
42/// Common response headers returned by Claude endpoints.
43#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
44pub struct ClaudeResponseHeaders {
45    /// Additional response headers.
46    #[serde(flatten, default, skip_serializing_if = "BTreeMap::is_empty")]
47    pub extra: BTreeMap<String, String>,
48}
49
50/// Serde helpers for `http::StatusCode` as numeric code (e.g. 200, 404, 529).
51pub mod status_code_serde {
52    use http::StatusCode;
53    use serde::de::Error as _;
54    use serde::{Deserialize, Deserializer, Serializer};
55
56    pub fn serialize<S>(value: &StatusCode, serializer: S) -> Result<S::Ok, S::Error>
57    where
58        S: Serializer,
59    {
60        serializer.serialize_u16(value.as_u16())
61    }
62
63    pub fn deserialize<'de, D>(deserializer: D) -> Result<StatusCode, D::Error>
64    where
65        D: Deserializer<'de>,
66    {
67        let code = u16::deserialize(deserializer)?;
68        StatusCode::from_u16(code).map_err(D::Error::custom)
69    }
70}
71
72/// Anthropic beta header value.
73///
74/// The API accepts both known beta tags and arbitrary strings.
75#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
76#[serde(untagged)]
77pub enum AnthropicBeta {
78    Known(AnthropicBetaKnown),
79    Custom(String),
80}
81
82/// Known Anthropic beta tags documented by upstream specs.
83#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
84pub enum AnthropicBetaKnown {
85    #[serde(rename = "message-batches-2024-09-24")]
86    MessageBatches20240924,
87    #[serde(rename = "prompt-caching-2024-07-31")]
88    PromptCaching20240731,
89    #[serde(rename = "computer-use-2024-10-22")]
90    ComputerUse20241022,
91    #[serde(rename = "computer-use-2025-01-24")]
92    ComputerUse20250124,
93    #[serde(rename = "pdfs-2024-09-25")]
94    Pdfs20240925,
95    #[serde(rename = "token-counting-2024-11-01")]
96    TokenCounting20241101,
97    #[serde(rename = "token-efficient-tools-2025-02-19")]
98    TokenEfficientTools20250219,
99    #[serde(rename = "output-128k-2025-02-19")]
100    Output128k20250219,
101    #[serde(rename = "files-api-2025-04-14")]
102    FilesApi20250414,
103    #[serde(rename = "mcp-client-2025-04-04")]
104    McpClient20250404,
105    #[serde(rename = "mcp-client-2025-11-20")]
106    McpClient20251120,
107    #[serde(rename = "dev-full-thinking-2025-05-14")]
108    DevFullThinking20250514,
109    #[serde(rename = "interleaved-thinking-2025-05-14")]
110    InterleavedThinking20250514,
111    #[serde(rename = "code-execution-2025-05-22")]
112    CodeExecution20250522,
113    #[serde(rename = "extended-cache-ttl-2025-04-11")]
114    ExtendedCacheTtl20250411,
115    #[serde(rename = "context-1m-2025-08-07")]
116    Context1m20250807,
117    #[serde(rename = "context-management-2025-06-27")]
118    ContextManagement20250627,
119    #[serde(rename = "model-context-window-exceeded-2025-08-26")]
120    ModelContextWindowExceeded20250826,
121    #[serde(rename = "skills-2025-10-02")]
122    Skills20251002,
123    #[serde(rename = "fast-mode-2026-02-01")]
124    FastMode20260201,
125    #[serde(rename = "compact-2026-01-12")]
126    Compact20260112,
127    #[serde(rename = "task-budgets-2026-03-13")]
128    TaskBudgets20260313,
129}
130
131/// Claude model metadata returned by list/get model endpoints.
132#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
133pub struct BetaModelInfo {
134    /// Unique model identifier.
135    pub id: String,
136    /// RFC 3339 datetime representing model release timestamp.
137    #[serde(with = "time::serde::rfc3339")]
138    pub created_at: OffsetDateTime,
139    /// Human-readable model name.
140    pub display_name: String,
141    /// Maximum input token count.
142    #[serde(default, skip_serializing_if = "Option::is_none")]
143    pub max_input_tokens: Option<u64>,
144    /// Maximum output token count.
145    #[serde(default, skip_serializing_if = "Option::is_none")]
146    pub max_tokens: Option<u64>,
147    /// Model capabilities.
148    #[serde(default, skip_serializing_if = "Option::is_none")]
149    pub capabilities: Option<BetaModelCapabilities>,
150    /// Object type, always "model".
151    #[serde(rename = "type")]
152    pub type_: BetaModelType,
153}
154
155#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
156pub struct BetaModelCapabilities {
157    #[serde(default, skip_serializing_if = "Option::is_none")]
158    pub batch: Option<BetaCapabilitySupport>,
159    #[serde(default, skip_serializing_if = "Option::is_none")]
160    pub citations: Option<BetaCapabilitySupport>,
161    #[serde(default, skip_serializing_if = "Option::is_none")]
162    pub code_execution: Option<BetaCapabilitySupport>,
163    #[serde(default, skip_serializing_if = "Option::is_none")]
164    pub context_management: Option<BetaContextManagementCapability>,
165    #[serde(default, skip_serializing_if = "Option::is_none")]
166    pub effort: Option<BetaEffortCapability>,
167    #[serde(default, skip_serializing_if = "Option::is_none")]
168    pub image_input: Option<BetaCapabilitySupport>,
169    #[serde(default, skip_serializing_if = "Option::is_none")]
170    pub pdf_input: Option<BetaCapabilitySupport>,
171    #[serde(default, skip_serializing_if = "Option::is_none")]
172    pub structured_outputs: Option<BetaCapabilitySupport>,
173    #[serde(default, skip_serializing_if = "Option::is_none")]
174    pub thinking: Option<BetaThinkingCapability>,
175}
176
177#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
178pub struct BetaCapabilitySupport {
179    pub supported: bool,
180}
181
182#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
183pub struct BetaContextManagementCapability {
184    pub supported: bool,
185    #[serde(default, skip_serializing_if = "Option::is_none")]
186    pub clear_thinking_20251015: Option<BetaCapabilitySupport>,
187    #[serde(default, skip_serializing_if = "Option::is_none")]
188    pub clear_tool_uses_20250919: Option<BetaCapabilitySupport>,
189    #[serde(default, skip_serializing_if = "Option::is_none")]
190    pub compact_20260112: Option<BetaCapabilitySupport>,
191}
192
193#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
194pub struct BetaEffortCapability {
195    pub supported: bool,
196    #[serde(default, skip_serializing_if = "Option::is_none")]
197    pub high: Option<BetaCapabilitySupport>,
198    #[serde(default, skip_serializing_if = "Option::is_none")]
199    pub low: Option<BetaCapabilitySupport>,
200    #[serde(default, skip_serializing_if = "Option::is_none")]
201    pub max: Option<BetaCapabilitySupport>,
202    #[serde(default, skip_serializing_if = "Option::is_none")]
203    pub medium: Option<BetaCapabilitySupport>,
204}
205
206#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
207pub struct BetaThinkingCapability {
208    pub supported: bool,
209    #[serde(default, skip_serializing_if = "Option::is_none")]
210    pub types: Option<BetaThinkingTypes>,
211}
212
213#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
214pub struct BetaThinkingTypes {
215    #[serde(default, skip_serializing_if = "Option::is_none")]
216    pub adaptive: Option<BetaCapabilitySupport>,
217    #[serde(default, skip_serializing_if = "Option::is_none")]
218    pub enabled: Option<BetaCapabilitySupport>,
219}
220
221#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
222pub enum BetaModelType {
223    #[serde(rename = "model")]
224    Model,
225}
226
227// ---------------------------------------------------------------------------
228// Files API types (beta)
229// ---------------------------------------------------------------------------
230
231/// Metadata for a file stored via the Files API.
232#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
233pub struct FileMetadata {
234    /// Unique object identifier (format may change over time).
235    pub id: String,
236    /// RFC 3339 datetime representing when the file was created.
237    pub created_at: String,
238    /// Original filename of the uploaded file.
239    pub filename: String,
240    /// MIME type of the file.
241    pub mime_type: String,
242    /// Size of the file in bytes.
243    pub size_bytes: u64,
244    /// Object type — always `"file"`.
245    #[serde(rename = "type")]
246    pub type_: FileObjectType,
247    /// Whether the file can be downloaded.
248    #[serde(default, skip_serializing_if = "Option::is_none")]
249    pub downloadable: Option<bool>,
250}
251
252/// Object type tag for file metadata — always `"file"`.
253#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
254pub enum FileObjectType {
255    #[serde(rename = "file")]
256    File,
257}
258
259/// Response returned when a file is deleted.
260#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
261pub struct DeletedFile {
262    /// ID of the deleted file.
263    pub id: String,
264    /// Deleted object type — always `"file_deleted"`.
265    #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
266    pub type_: Option<DeletedFileType>,
267}
268
269/// Object type tag for deleted file — always `"file_deleted"`.
270#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
271pub enum DeletedFileType {
272    #[serde(rename = "file_deleted")]
273    FileDeleted,
274}
275
276/// Typed beta error codes.
277#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
278pub enum BetaErrorType {
279    /// HTTP 400 (and may be used for other unlisted 4XX errors).
280    #[serde(rename = "invalid_request_error")]
281    InvalidRequestError,
282    /// HTTP 401.
283    #[serde(rename = "authentication_error")]
284    AuthenticationError,
285    /// Billing-related error type; HTTP status is not explicitly defined in `Errors.md`.
286    #[serde(rename = "billing_error")]
287    BillingError,
288    /// HTTP 403.
289    #[serde(rename = "permission_error")]
290    PermissionError,
291    /// HTTP 413.
292    #[serde(rename = "request_too_large")]
293    RequestTooLarge,
294    /// HTTP 404.
295    #[serde(rename = "not_found_error")]
296    NotFoundError,
297    /// HTTP 429.
298    #[serde(rename = "rate_limit_error")]
299    RateLimitError,
300    /// Timeout-related error type; HTTP status is not explicitly defined in `Errors.md`.
301    #[serde(rename = "timeout_error")]
302    TimeoutError,
303    /// HTTP 500.
304    #[serde(rename = "api_error")]
305    ApiError,
306    /// HTTP 529.
307    #[serde(rename = "overloaded_error")]
308    OverloadedError,
309}
310
311#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
312pub struct BetaApiError {
313    pub message: String,
314    #[serde(rename = "type")]
315    pub type_: BetaApiErrorType,
316}
317
318#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
319pub enum BetaApiErrorType {
320    #[serde(rename = "api_error")]
321    ApiError,
322}
323
324#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
325pub struct BetaAuthenticationError {
326    pub message: String,
327    #[serde(rename = "type")]
328    pub type_: BetaAuthenticationErrorType,
329}
330
331#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
332pub enum BetaAuthenticationErrorType {
333    #[serde(rename = "authentication_error")]
334    AuthenticationError,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
338pub struct BetaBillingError {
339    pub message: String,
340    #[serde(rename = "type")]
341    pub type_: BetaBillingErrorType,
342}
343
344#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
345pub enum BetaBillingErrorType {
346    #[serde(rename = "billing_error")]
347    BillingError,
348}
349
350#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
351pub struct BetaGatewayTimeoutError {
352    pub message: String,
353    #[serde(rename = "type")]
354    pub type_: BetaGatewayTimeoutErrorType,
355}
356
357#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
358pub enum BetaGatewayTimeoutErrorType {
359    #[serde(rename = "timeout_error")]
360    TimeoutError,
361}
362
363#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
364pub struct BetaInvalidRequestError {
365    pub message: String,
366    #[serde(rename = "type")]
367    pub type_: BetaInvalidRequestErrorType,
368}
369
370#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
371pub enum BetaInvalidRequestErrorType {
372    #[serde(rename = "invalid_request_error")]
373    InvalidRequestError,
374}
375
376#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
377pub struct BetaNotFoundError {
378    pub message: String,
379    #[serde(rename = "type")]
380    pub type_: BetaNotFoundErrorType,
381}
382
383#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
384pub enum BetaNotFoundErrorType {
385    #[serde(rename = "not_found_error")]
386    NotFoundError,
387}
388
389#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
390pub struct BetaOverloadedError {
391    pub message: String,
392    #[serde(rename = "type")]
393    pub type_: BetaOverloadedErrorType,
394}
395
396#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
397pub enum BetaOverloadedErrorType {
398    #[serde(rename = "overloaded_error")]
399    OverloadedError,
400}
401
402#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
403pub struct BetaPermissionError {
404    pub message: String,
405    #[serde(rename = "type")]
406    pub type_: BetaPermissionErrorType,
407}
408
409#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
410pub enum BetaPermissionErrorType {
411    #[serde(rename = "permission_error")]
412    PermissionError,
413}
414
415#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
416pub struct BetaRateLimitError {
417    pub message: String,
418    #[serde(rename = "type")]
419    pub type_: BetaRateLimitErrorType,
420}
421
422#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
423pub enum BetaRateLimitErrorType {
424    #[serde(rename = "rate_limit_error")]
425    RateLimitError,
426}
427
428/// Error union returned by beta endpoints.
429#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
430#[serde(untagged)]
431pub enum BetaError {
432    InvalidRequest(BetaInvalidRequestError),
433    Authentication(BetaAuthenticationError),
434    Billing(BetaBillingError),
435    Permission(BetaPermissionError),
436    NotFound(BetaNotFoundError),
437    RateLimit(BetaRateLimitError),
438    GatewayTimeout(BetaGatewayTimeoutError),
439    Api(BetaApiError),
440    Overloaded(BetaOverloadedError),
441}
442
443#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
444pub enum BetaErrorResponseType {
445    #[serde(rename = "error")]
446    Error,
447}
448
449/// Top-level beta error response wrapper.
450#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
451pub struct BetaErrorResponse {
452    pub error: BetaError,
453    pub request_id: String,
454    #[serde(rename = "type")]
455    pub type_: BetaErrorResponseType,
456}