1pub use crate::transform::Converted;
2use crate::transform::TransformError;
3use crate::wire::claude::models as claude_models;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct OpenAiModelSupplement {
11 pub owned_by: String,
12 pub created: Option<i64>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18pub struct ClaudeModelSupplement {
19 pub display_name: Option<String>,
20 #[serde(default)]
21 pub line: Option<String>,
22 pub allowed_fallback_models: Vec<String>,
23 pub capabilities: ClaudeCapabilities,
24 pub max_input_tokens: Option<i64>,
25 pub max_tokens: Option<i64>,
26 pub created_at: Option<String>,
27 #[serde(default)]
28 pub lifecycle: Option<claude_models::ModelLifecycle>,
29 #[serde(default)]
30 pub deprecated_at: Option<String>,
31 #[serde(default)]
32 pub retires_at: Option<String>,
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36pub struct ClaudeCapabilities {
37 pub batch: bool,
38 pub citations: bool,
39 pub code_execution: bool,
40 pub context_management: ClaudeContextManagement,
41 pub effort: ClaudeEffort,
42 pub image_input: bool,
43 pub pdf_input: bool,
44 pub structured_outputs: bool,
45 #[serde(default)]
46 pub server_tools: Option<ClaudeServerTools>,
47 #[serde(default)]
48 pub compaction: Option<ClaudeCompaction>,
49 pub thinking: ClaudeThinking,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct ClaudeContextManagement {
54 pub clear_thinking_20251015: bool,
55 pub clear_tool_uses_20250919: bool,
56 pub compact_20260112: bool,
57 pub supported: bool,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
61pub struct ClaudeEffort {
62 pub high: bool,
63 pub low: bool,
64 pub max: bool,
65 pub medium: bool,
66 pub supported: bool,
67 pub xhigh: bool,
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
71pub struct ClaudeThinking {
72 pub supported: bool,
73 pub adaptive: bool,
74 pub enabled: bool,
75 #[serde(default)]
76 pub disabled: Option<bool>,
77 #[serde(default)]
78 pub between_tools: Option<bool>,
79}
80
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
82pub struct ClaudeServerTools {
83 pub supported: bool,
84 pub web_search: bool,
85 pub code_execution: bool,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
89pub struct ClaudeCompaction {
90 pub supported: bool,
91 pub summarize: bool,
92}
93
94impl ClaudeCapabilities {
95 pub(crate) fn into_wire(self) -> claude_models::ModelCapabilities {
96 let support = |supported| claude_models::CapabilitySupport {
97 supported,
98 rest: Default::default(),
99 };
100 claude_models::ModelCapabilities {
101 batch: support(self.batch),
102 citations: support(self.citations),
103 code_execution: support(self.code_execution),
104 compaction: self.compaction.map(|value| {
105 Some(claude_models::CompactionCapability {
106 supported: value.supported,
107 summarize: support(value.summarize),
108 rest: Default::default(),
109 })
110 }),
111 context_management: claude_models::ContextManagementCapability {
112 clear_thinking_20251015: Some(support(
113 self.context_management.clear_thinking_20251015,
114 )),
115 clear_tool_uses_20250919: Some(support(
116 self.context_management.clear_tool_uses_20250919,
117 )),
118 compact_20260112: Some(support(self.context_management.compact_20260112)),
119 supported: self.context_management.supported,
120 rest: Default::default(),
121 },
122 effort: claude_models::EffortCapability {
123 high: support(self.effort.high),
124 low: support(self.effort.low),
125 max: support(self.effort.max),
126 medium: support(self.effort.medium),
127 supported: self.effort.supported,
128 xhigh: Some(support(self.effort.xhigh)),
129 rest: Default::default(),
130 },
131 image_input: support(self.image_input),
132 pdf_input: support(self.pdf_input),
133 structured_outputs: support(self.structured_outputs),
134 server_tools: self
135 .server_tools
136 .map(|tools| claude_models::ServerToolsCapability {
137 supported: tools.supported,
138 web_search: support(tools.web_search),
139 code_execution: support(tools.code_execution),
140 rest: Default::default(),
141 }),
142 thinking: claude_models::ThinkingCapability {
143 supported: self.thinking.supported,
144 types: claude_models::ThinkingTypes {
145 adaptive: support(self.thinking.adaptive),
146 enabled: support(self.thinking.enabled),
147 disabled: self.thinking.disabled.map(support),
148 between_tools: self.thinking.between_tools.map(support),
149 rest: Default::default(),
150 },
151 rest: Default::default(),
152 },
153 rest: Default::default(),
154 }
155 }
156}
157
158#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
160pub struct GeminiModelSupplement {
161 pub base_model_id: String,
162 pub version: String,
163}
164
165#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
170pub struct ListPageFacts {
171 pub complete: bool,
172 pub first_id: Option<String>,
173 pub last_id: Option<String>,
174 pub has_more: Option<bool>,
175 pub next_page_token: Option<String>,
176}
177
178impl ListPageFacts {
179 pub const fn complete() -> Self {
180 Self {
181 complete: true,
182 first_id: None,
183 last_id: None,
184 has_more: Some(false),
185 next_page_token: None,
186 }
187 }
188
189 pub fn explicit(
190 first_id: impl Into<String>,
191 last_id: impl Into<String>,
192 has_more: bool,
193 ) -> Self {
194 Self {
195 complete: false,
196 first_id: Some(first_id.into()),
197 last_id: Some(last_id.into()),
198 has_more: Some(has_more),
199 next_page_token: None,
200 }
201 }
202
203 pub fn with_next_page_token(mut self, token: impl Into<String>) -> Self {
204 self.next_page_token = Some(token.into());
205 self
206 }
207}
208
209pub(crate) fn missing_pagination(detail: &str) -> TransformError {
210 TransformError::new(
211 crate::transform::TransformErrorKind::MissingMetadata,
212 "pagination",
213 detail,
214 )
215}