1use std::borrow::Cow;
5use std::sync::LazyLock;
6use crate::ReasoningEffort;
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum AnthropicModel {
9 Claude35Haiku20241022,
10 Claude35Sonnet20240620,
11 Claude35Sonnet20241022,
12 Claude37Sonnet20250219,
13 Claude3Haiku20240307,
14 Claude3Opus20240229,
15 Claude3Sonnet20240229,
16 ClaudeHaiku45,
17 ClaudeHaiku4520251001,
18 ClaudeOpus40,
19 ClaudeOpus41,
20 ClaudeOpus4120250805,
21 ClaudeOpus420250514,
22 ClaudeOpus45,
23 ClaudeOpus4520251101,
24 ClaudeOpus46,
25 ClaudeOpus47,
26 ClaudeSonnet40,
27 ClaudeSonnet420250514,
28 ClaudeSonnet45,
29 ClaudeSonnet4520250929,
30 ClaudeSonnet46,
31}
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub enum CodexModel {
34 Gpt5,
35 Gpt5Codex,
36 Gpt51,
37 Gpt51Codex,
38 Gpt51CodexMax,
39 Gpt51CodexMini,
40 Gpt52,
41 Gpt52Codex,
42 Gpt52Pro,
43 Gpt53Codex,
44 Gpt53CodexSpark,
45 Gpt54,
46 Gpt54Mini,
47 Gpt54Nano,
48 Gpt54Pro,
49 Gpt55,
50 Gpt55Pro,
51}
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53pub enum DeepSeekModel {
54 DeepseekChat,
55 DeepseekReasoner,
56 DeepseekV4Flash,
57 DeepseekV4Pro,
58}
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
60pub enum GeminiModel {
61 Gemini15Flash,
62 Gemini15Flash8b,
63 Gemini15Pro,
64 Gemini20Flash,
65 Gemini20FlashLite,
66 Gemini25Flash,
67 Gemini25FlashLite,
68 Gemini25FlashLitePreview0617,
69 Gemini25FlashLitePreview092025,
70 Gemini25FlashPreview0417,
71 Gemini25FlashPreview0520,
72 Gemini25FlashPreview092025,
73 Gemini25Pro,
74 Gemini25ProPreview0506,
75 Gemini25ProPreview0605,
76 Gemini3FlashPreview,
77 Gemini3ProPreview,
78 Gemini31FlashLite,
79 Gemini31FlashLitePreview,
80 Gemini31ProPreview,
81 Gemini31ProPreviewCustomtools,
82 GeminiLive25Flash,
83 GeminiLive25FlashPreviewNativeAudio,
84 Gemma327bIt,
85 Gemma426bA4bIt,
86 Gemma431bIt,
87}
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
89pub enum MoonshotModel {
90 KimiK20711Preview,
91 KimiK20905Preview,
92 KimiK2Thinking,
93 KimiK2ThinkingTurbo,
94 KimiK2TurboPreview,
95 KimiK25,
96 KimiK26,
97}
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
99pub enum OpenaiModel {
100 Gpt4,
101 Gpt4Turbo,
102 Gpt41,
103 Gpt41Mini,
104 Gpt41Nano,
105 Gpt4o,
106 Gpt4o20240513,
107 Gpt4o20240806,
108 Gpt4o20241120,
109 Gpt4oMini,
110 Gpt5,
111 Gpt5Codex,
112 Gpt5Mini,
113 Gpt5Nano,
114 Gpt5Pro,
115 Gpt51,
116 Gpt51Codex,
117 Gpt51CodexMax,
118 Gpt51CodexMini,
119 Gpt52,
120 Gpt52Codex,
121 Gpt52Pro,
122 Gpt53Codex,
123 Gpt53CodexSpark,
124 Gpt54,
125 Gpt54Mini,
126 Gpt54Nano,
127 Gpt54Pro,
128 Gpt55,
129 Gpt55Pro,
130 O1,
131 O1Pro,
132 O3,
133 O3DeepResearch,
134 O3Mini,
135 O3Pro,
136 O4Mini,
137 O4MiniDeepResearch,
138}
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
140pub enum OpenRouterModel {
141 AnthropicClaude35Haiku,
142 AnthropicClaude37Sonnet,
143 AnthropicClaudeHaiku45,
144 AnthropicClaudeOpus4,
145 AnthropicClaudeOpus41,
146 AnthropicClaudeOpus45,
147 AnthropicClaudeOpus46,
148 AnthropicClaudeOpus47,
149 AnthropicClaudeSonnet4,
150 AnthropicClaudeSonnet45,
151 AnthropicClaudeSonnet46,
152 ArceeAiTrinityLargePreviewFree,
153 ArceeAiTrinityLargeThinking,
154 DeepseekDeepseekChatV31,
155 DeepseekDeepseekR1,
156 DeepseekDeepseekV31Terminus,
157 DeepseekDeepseekV31TerminusExacto,
158 DeepseekDeepseekV32,
159 DeepseekDeepseekV32Speciale,
160 DeepseekDeepseekV4Flash,
161 DeepseekDeepseekV4Pro,
162 GoogleGemini20Flash001,
163 GoogleGemini25Flash,
164 GoogleGemini25FlashLite,
165 GoogleGemini25FlashLitePreview092025,
166 GoogleGemini25FlashPreview092025,
167 GoogleGemini25Pro,
168 GoogleGemini25ProPreview0506,
169 GoogleGemini25ProPreview0605,
170 GoogleGemini3FlashPreview,
171 GoogleGemini3ProPreview,
172 GoogleGemini31FlashLitePreview,
173 GoogleGemini31ProPreview,
174 GoogleGemini31ProPreviewCustomtools,
175 GoogleGemma327bIt,
176 GoogleGemma327bItFree,
177 GoogleGemma426bA4bIt,
178 GoogleGemma426bA4bItFree,
179 GoogleGemma431bIt,
180 GoogleGemma431bItFree,
181 InceptionMercury2,
182 MetaLlamaLlama3370bInstructFree,
183 MinimaxMinimax01,
184 MinimaxMinimaxM1,
185 MinimaxMinimaxM2,
186 MinimaxMinimaxM21,
187 MinimaxMinimaxM25,
188 MinimaxMinimaxM25Free,
189 MinimaxMinimaxM27,
190 MistralaiCodestral2508,
191 MistralaiDevstral2512,
192 MistralaiDevstralMedium2507,
193 MistralaiDevstralSmall2505,
194 MistralaiDevstralSmall2507,
195 MistralaiMistralMedium3,
196 MistralaiMistralMedium31,
197 MistralaiMistralSmall2603,
198 MistralaiMistralSmall3124bInstruct,
199 MistralaiMistralSmall3224bInstruct,
200 MoonshotaiKimiK2,
201 MoonshotaiKimiK20905,
202 MoonshotaiKimiK20905Exacto,
203 MoonshotaiKimiK2Thinking,
204 MoonshotaiKimiK25,
205 MoonshotaiKimiK26,
206 NousresearchHermes4405b,
207 NousresearchHermes470b,
208 NvidiaNemotron3Nano30bA3bFree,
209 NvidiaNemotron3NanoOmni30bA3bReasoningFree,
210 NvidiaNemotron3Super120bA12b,
211 NvidiaNemotron3Super120bA12bFree,
212 NvidiaNemotronNano12bV2VlFree,
213 NvidiaNemotronNano9bV2,
214 NvidiaNemotronNano9bV2Free,
215 OpenaiGpt41,
216 OpenaiGpt41Mini,
217 OpenaiGpt4oMini,
218 OpenaiGpt5,
219 OpenaiGpt5Codex,
220 OpenaiGpt5Image,
221 OpenaiGpt5Mini,
222 OpenaiGpt5Nano,
223 OpenaiGpt5Pro,
224 OpenaiGpt51,
225 OpenaiGpt51Chat,
226 OpenaiGpt51Codex,
227 OpenaiGpt51CodexMax,
228 OpenaiGpt51CodexMini,
229 OpenaiGpt52,
230 OpenaiGpt52Chat,
231 OpenaiGpt52Codex,
232 OpenaiGpt52Pro,
233 OpenaiGpt53Codex,
234 OpenaiGpt54,
235 OpenaiGpt54Mini,
236 OpenaiGpt54Nano,
237 OpenaiGpt54Pro,
238 OpenaiGpt55,
239 OpenaiGpt55Pro,
240 OpenaiGptOss120b,
241 OpenaiGptOss120bExacto,
242 OpenaiGptOss120bFree,
243 OpenaiGptOss20b,
244 OpenaiGptOss20bFree,
245 OpenaiGptOssSafeguard20b,
246 OpenaiO4Mini,
247 OpenrouterElephantAlpha,
248 OpenrouterFree,
249 OpenrouterOwlAlpha,
250 OpenrouterParetoCode,
251 PoolsideLagunaM1Free,
252 PoolsideLagunaXs2Free,
253 PrimeIntellectIntellect3,
254 QwenQwen3627b,
255 QwenQwenPlus,
256 QwenQwen3235bA22b0725,
257 QwenQwen3235bA22bThinking2507,
258 QwenQwen330bA3bInstruct2507,
259 QwenQwen330bA3bThinking2507,
260 QwenQwen3Coder,
261 QwenQwen3Coder30bA3bInstruct,
262 QwenQwen3CoderFlash,
263 QwenQwen3CoderPlus,
264 QwenQwen3CoderExacto,
265 QwenQwen3Max,
266 QwenQwen3Next80bA3bInstruct,
267 QwenQwen3Next80bA3bThinking,
268 QwenQwen35397bA17b,
269 QwenQwen35Flash0223,
270 QwenQwen35Plus0215,
271 QwenQwen36Plus,
272 StepfunStep35Flash,
273 TencentHy3Preview,
274 XAiGrok3,
275 XAiGrok3Beta,
276 XAiGrok3Mini,
277 XAiGrok3MiniBeta,
278 XAiGrok4,
279 XAiGrok4Fast,
280 XAiGrok41Fast,
281 XAiGrok420Beta,
282 XAiGrok43,
283 XAiGrokCodeFast1,
284 XiaomiMimoV2Flash,
285 XiaomiMimoV2Omni,
286 XiaomiMimoV2Pro,
287 XiaomiMimoV25,
288 XiaomiMimoV25Pro,
289 ZAiGlm45,
290 ZAiGlm45Air,
291 ZAiGlm45v,
292 ZAiGlm46,
293 ZAiGlm46Exacto,
294 ZAiGlm47,
295 ZAiGlm47Flash,
296 ZAiGlm5,
297 ZAiGlm5Turbo,
298 ZAiGlm51,
299}
300#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
301pub enum ZAiModel {
302 Glm45,
303 Glm45Air,
304 Glm45Flash,
305 Glm45v,
306 Glm46,
307 Glm46v,
308 Glm47,
309 Glm47Flash,
310 Glm47Flashx,
311 Glm5,
312 Glm5Turbo,
313 Glm51,
314 Glm5vTurbo,
315}
316#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
317pub enum BedrockFoundationModel {
318 AmazonNova2LiteV10,
319 AmazonNovaLiteV10,
320 AmazonNovaMicroV10,
321 AmazonNovaProV10,
322 AnthropicClaudeHaiku4520251001V10,
323 AnthropicClaudeOpus4120250805V10,
324 AnthropicClaudeOpus4520251101V10,
325 AnthropicClaudeOpus46V1,
326 AnthropicClaudeOpus47,
327 AnthropicClaudeSonnet4520250929V10,
328 AnthropicClaudeSonnet46,
329 AuAnthropicClaudeHaiku4520251001V10,
330 AuAnthropicClaudeOpus46V1,
331 AuAnthropicClaudeSonnet4520250929V10,
332 AuAnthropicClaudeSonnet46,
333 DeepseekR1V10,
334 DeepseekV3V10,
335 DeepseekV32,
336 EuAnthropicClaudeHaiku4520251001V10,
337 EuAnthropicClaudeOpus4520251101V10,
338 EuAnthropicClaudeOpus46V1,
339 EuAnthropicClaudeOpus47,
340 EuAnthropicClaudeSonnet4520250929V10,
341 EuAnthropicClaudeSonnet46,
342 GlobalAnthropicClaudeHaiku4520251001V10,
343 GlobalAnthropicClaudeOpus4520251101V10,
344 GlobalAnthropicClaudeOpus46V1,
345 GlobalAnthropicClaudeOpus47,
346 GlobalAnthropicClaudeSonnet4520250929V10,
347 GlobalAnthropicClaudeSonnet46,
348 GoogleGemma327bIt,
349 GoogleGemma34bIt,
350 JpAnthropicClaudeOpus47,
351 JpAnthropicClaudeSonnet4520250929V10,
352 JpAnthropicClaudeSonnet46,
353 MetaLlama3170bInstructV10,
354 MetaLlama318bInstructV10,
355 MetaLlama3370bInstructV10,
356 MetaLlama4Maverick17bInstructV10,
357 MetaLlama4Scout17bInstructV10,
358 MinimaxMinimaxM2,
359 MinimaxMinimaxM21,
360 MinimaxMinimaxM25,
361 MistralDevstral2123b,
362 MistralMagistralSmall2509,
363 MistralMinistral314bInstruct,
364 MistralMinistral33bInstruct,
365 MistralMinistral38bInstruct,
366 MistralMistralLarge3675bInstruct,
367 MistralPixtralLarge2502V10,
368 MistralVoxtralMini3b2507,
369 MistralVoxtralSmall24b2507,
370 MoonshotKimiK2Thinking,
371 MoonshotaiKimiK25,
372 NvidiaNemotronNano12bV2,
373 NvidiaNemotronNano330b,
374 NvidiaNemotronNano9bV2,
375 NvidiaNemotronSuper3120b,
376 OpenaiGptOss120b10,
377 OpenaiGptOss20b10,
378 OpenaiGptOssSafeguard120b,
379 OpenaiGptOssSafeguard20b,
380 QwenQwen3235bA22b2507V10,
381 QwenQwen332bV10,
382 QwenQwen3Coder30bA3bV10,
383 QwenQwen3Coder480bA35bV10,
384 QwenQwen3CoderNext,
385 QwenQwen3Next80bA3b,
386 QwenQwen3Vl235bA22b,
387 UsAnthropicClaudeHaiku4520251001V10,
388 UsAnthropicClaudeOpus4120250805V10,
389 UsAnthropicClaudeOpus4520251101V10,
390 UsAnthropicClaudeOpus46V1,
391 UsAnthropicClaudeOpus47,
392 UsAnthropicClaudeSonnet4520250929V10,
393 UsAnthropicClaudeSonnet46,
394 UsDeepseekR1V10,
395 UsMetaLlama4Maverick17bInstructV10,
396 UsMetaLlama4Scout17bInstructV10,
397 WriterPalmyraX4V10,
398 WriterPalmyraX5V10,
399 ZaiGlm47,
400 ZaiGlm47Flash,
401 ZaiGlm5,
402}
403impl AnthropicModel {
404 #[allow(clippy::too_many_lines)]
405 fn model_id(self) -> &'static str {
406 match self {
407 Self::Claude35Haiku20241022 => "claude-3-5-haiku-20241022",
408 Self::Claude35Sonnet20240620 => "claude-3-5-sonnet-20240620",
409 Self::Claude35Sonnet20241022 => "claude-3-5-sonnet-20241022",
410 Self::Claude37Sonnet20250219 => "claude-3-7-sonnet-20250219",
411 Self::Claude3Haiku20240307 => "claude-3-haiku-20240307",
412 Self::Claude3Opus20240229 => "claude-3-opus-20240229",
413 Self::Claude3Sonnet20240229 => "claude-3-sonnet-20240229",
414 Self::ClaudeHaiku45 => "claude-haiku-4-5",
415 Self::ClaudeHaiku4520251001 => "claude-haiku-4-5-20251001",
416 Self::ClaudeOpus40 => "claude-opus-4-0",
417 Self::ClaudeOpus41 => "claude-opus-4-1",
418 Self::ClaudeOpus4120250805 => "claude-opus-4-1-20250805",
419 Self::ClaudeOpus420250514 => "claude-opus-4-20250514",
420 Self::ClaudeOpus45 => "claude-opus-4-5",
421 Self::ClaudeOpus4520251101 => "claude-opus-4-5-20251101",
422 Self::ClaudeOpus46 => "claude-opus-4-6",
423 Self::ClaudeOpus47 => "claude-opus-4-7",
424 Self::ClaudeSonnet40 => "claude-sonnet-4-0",
425 Self::ClaudeSonnet420250514 => "claude-sonnet-4-20250514",
426 Self::ClaudeSonnet45 => "claude-sonnet-4-5",
427 Self::ClaudeSonnet4520250929 => "claude-sonnet-4-5-20250929",
428 Self::ClaudeSonnet46 => "claude-sonnet-4-6",
429 }
430 }
431 #[allow(clippy::too_many_lines)]
432 fn display_name(self) -> &'static str {
433 match self {
434 Self::Claude3Haiku20240307 => "Claude Haiku 3",
435 Self::Claude35Haiku20241022 => "Claude Haiku 3.5",
436 Self::ClaudeHaiku4520251001 => "Claude Haiku 4.5",
437 Self::ClaudeHaiku45 => "Claude Haiku 4.5 (latest)",
438 Self::Claude3Opus20240229 => "Claude Opus 3",
439 Self::ClaudeOpus420250514 => "Claude Opus 4",
440 Self::ClaudeOpus40 => "Claude Opus 4 (latest)",
441 Self::ClaudeOpus4120250805 => "Claude Opus 4.1",
442 Self::ClaudeOpus41 => "Claude Opus 4.1 (latest)",
443 Self::ClaudeOpus4520251101 => "Claude Opus 4.5",
444 Self::ClaudeOpus45 => "Claude Opus 4.5 (latest)",
445 Self::ClaudeOpus46 => "Claude Opus 4.6",
446 Self::ClaudeOpus47 => "Claude Opus 4.7",
447 Self::Claude3Sonnet20240229 => "Claude Sonnet 3",
448 Self::Claude35Sonnet20240620 => "Claude Sonnet 3.5",
449 Self::Claude35Sonnet20241022 => "Claude Sonnet 3.5 v2",
450 Self::Claude37Sonnet20250219 => "Claude Sonnet 3.7",
451 Self::ClaudeSonnet420250514 => "Claude Sonnet 4",
452 Self::ClaudeSonnet40 => "Claude Sonnet 4 (latest)",
453 Self::ClaudeSonnet4520250929 => "Claude Sonnet 4.5",
454 Self::ClaudeSonnet45 => "Claude Sonnet 4.5 (latest)",
455 Self::ClaudeSonnet46 => "Claude Sonnet 4.6",
456 }
457 }
458 #[allow(clippy::too_many_lines)]
459 fn context_window(self) -> u32 {
460 match self {
461 Self::Claude35Haiku20241022
462 | Self::Claude35Sonnet20240620
463 | Self::Claude35Sonnet20241022
464 | Self::Claude37Sonnet20250219
465 | Self::Claude3Haiku20240307
466 | Self::Claude3Opus20240229
467 | Self::Claude3Sonnet20240229
468 | Self::ClaudeHaiku45
469 | Self::ClaudeHaiku4520251001
470 | Self::ClaudeOpus40
471 | Self::ClaudeOpus41
472 | Self::ClaudeOpus4120250805
473 | Self::ClaudeOpus420250514
474 | Self::ClaudeOpus45
475 | Self::ClaudeOpus4520251101
476 | Self::ClaudeSonnet40
477 | Self::ClaudeSonnet420250514
478 | Self::ClaudeSonnet45
479 | Self::ClaudeSonnet4520250929 => 200_000,
480 Self::ClaudeOpus46 | Self::ClaudeOpus47 | Self::ClaudeSonnet46 => 1_000_000,
481 }
482 }
483 #[allow(clippy::too_many_lines)]
484 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
485 match self {
486 Self::Claude35Haiku20241022
487 | Self::Claude35Sonnet20240620
488 | Self::Claude35Sonnet20241022
489 | Self::Claude3Haiku20240307
490 | Self::Claude3Opus20240229
491 | Self::Claude3Sonnet20240229 => &[],
492 Self::Claude37Sonnet20250219
493 | Self::ClaudeHaiku45
494 | Self::ClaudeHaiku4520251001
495 | Self::ClaudeOpus40
496 | Self::ClaudeOpus41
497 | Self::ClaudeOpus4120250805
498 | Self::ClaudeOpus420250514
499 | Self::ClaudeOpus45
500 | Self::ClaudeOpus4520251101
501 | Self::ClaudeOpus46
502 | Self::ClaudeOpus47
503 | Self::ClaudeSonnet40
504 | Self::ClaudeSonnet420250514
505 | Self::ClaudeSonnet45
506 | Self::ClaudeSonnet4520250929
507 | Self::ClaudeSonnet46 => {
508 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
509 }
510 }
511 }
512 pub fn supports_reasoning(self) -> bool {
513 !self.reasoning_levels().is_empty()
514 }
515 #[allow(clippy::too_many_lines)]
516 pub fn supports_prompt_caching(self) -> bool {
517 match self {
518 Self::Claude35Haiku20241022
519 | Self::Claude35Sonnet20240620
520 | Self::Claude35Sonnet20241022
521 | Self::Claude37Sonnet20250219
522 | Self::Claude3Haiku20240307
523 | Self::Claude3Opus20240229
524 | Self::Claude3Sonnet20240229
525 | Self::ClaudeHaiku45
526 | Self::ClaudeHaiku4520251001
527 | Self::ClaudeOpus40
528 | Self::ClaudeOpus41
529 | Self::ClaudeOpus4120250805
530 | Self::ClaudeOpus420250514
531 | Self::ClaudeOpus45
532 | Self::ClaudeOpus4520251101
533 | Self::ClaudeOpus46
534 | Self::ClaudeOpus47
535 | Self::ClaudeSonnet40
536 | Self::ClaudeSonnet420250514
537 | Self::ClaudeSonnet45
538 | Self::ClaudeSonnet4520250929
539 | Self::ClaudeSonnet46 => true,
540 }
541 }
542 #[allow(clippy::too_many_lines)]
543 pub fn supports_image(self) -> bool {
544 match self {
545 Self::Claude35Haiku20241022
546 | Self::Claude35Sonnet20240620
547 | Self::Claude35Sonnet20241022
548 | Self::Claude37Sonnet20250219
549 | Self::Claude3Haiku20240307
550 | Self::Claude3Opus20240229
551 | Self::Claude3Sonnet20240229
552 | Self::ClaudeHaiku45
553 | Self::ClaudeHaiku4520251001
554 | Self::ClaudeOpus40
555 | Self::ClaudeOpus41
556 | Self::ClaudeOpus4120250805
557 | Self::ClaudeOpus420250514
558 | Self::ClaudeOpus45
559 | Self::ClaudeOpus4520251101
560 | Self::ClaudeOpus46
561 | Self::ClaudeOpus47
562 | Self::ClaudeSonnet40
563 | Self::ClaudeSonnet420250514
564 | Self::ClaudeSonnet45
565 | Self::ClaudeSonnet4520250929
566 | Self::ClaudeSonnet46 => true,
567 }
568 }
569 #[allow(clippy::too_many_lines)]
570 pub fn supports_audio(self) -> bool {
571 match self {
572 Self::Claude35Haiku20241022
573 | Self::Claude35Sonnet20240620
574 | Self::Claude35Sonnet20241022
575 | Self::Claude37Sonnet20250219
576 | Self::Claude3Haiku20240307
577 | Self::Claude3Opus20240229
578 | Self::Claude3Sonnet20240229
579 | Self::ClaudeHaiku45
580 | Self::ClaudeHaiku4520251001
581 | Self::ClaudeOpus40
582 | Self::ClaudeOpus41
583 | Self::ClaudeOpus4120250805
584 | Self::ClaudeOpus420250514
585 | Self::ClaudeOpus45
586 | Self::ClaudeOpus4520251101
587 | Self::ClaudeOpus46
588 | Self::ClaudeOpus47
589 | Self::ClaudeSonnet40
590 | Self::ClaudeSonnet420250514
591 | Self::ClaudeSonnet45
592 | Self::ClaudeSonnet4520250929
593 | Self::ClaudeSonnet46 => false,
594 }
595 }
596 const ALL: &[AnthropicModel] = &[
597 Self::Claude35Haiku20241022,
598 Self::Claude35Sonnet20240620,
599 Self::Claude35Sonnet20241022,
600 Self::Claude37Sonnet20250219,
601 Self::Claude3Haiku20240307,
602 Self::Claude3Opus20240229,
603 Self::Claude3Sonnet20240229,
604 Self::ClaudeHaiku45,
605 Self::ClaudeHaiku4520251001,
606 Self::ClaudeOpus40,
607 Self::ClaudeOpus41,
608 Self::ClaudeOpus4120250805,
609 Self::ClaudeOpus420250514,
610 Self::ClaudeOpus45,
611 Self::ClaudeOpus4520251101,
612 Self::ClaudeOpus46,
613 Self::ClaudeOpus47,
614 Self::ClaudeSonnet40,
615 Self::ClaudeSonnet420250514,
616 Self::ClaudeSonnet45,
617 Self::ClaudeSonnet4520250929,
618 Self::ClaudeSonnet46,
619 ];
620}
621impl std::str::FromStr for AnthropicModel {
622 type Err = String;
623 #[allow(clippy::too_many_lines)]
624 fn from_str(s: &str) -> Result<Self, Self::Err> {
625 match s {
626 "claude-3-5-haiku-20241022" => Ok(Self::Claude35Haiku20241022),
627 "claude-3-5-sonnet-20240620" => Ok(Self::Claude35Sonnet20240620),
628 "claude-3-5-sonnet-20241022" => Ok(Self::Claude35Sonnet20241022),
629 "claude-3-7-sonnet-20250219" => Ok(Self::Claude37Sonnet20250219),
630 "claude-3-haiku-20240307" => Ok(Self::Claude3Haiku20240307),
631 "claude-3-opus-20240229" => Ok(Self::Claude3Opus20240229),
632 "claude-3-sonnet-20240229" => Ok(Self::Claude3Sonnet20240229),
633 "claude-haiku-4-5" => Ok(Self::ClaudeHaiku45),
634 "claude-haiku-4-5-20251001" => Ok(Self::ClaudeHaiku4520251001),
635 "claude-opus-4-0" => Ok(Self::ClaudeOpus40),
636 "claude-opus-4-1" => Ok(Self::ClaudeOpus41),
637 "claude-opus-4-1-20250805" => Ok(Self::ClaudeOpus4120250805),
638 "claude-opus-4-20250514" => Ok(Self::ClaudeOpus420250514),
639 "claude-opus-4-5" => Ok(Self::ClaudeOpus45),
640 "claude-opus-4-5-20251101" => Ok(Self::ClaudeOpus4520251101),
641 "claude-opus-4-6" => Ok(Self::ClaudeOpus46),
642 "claude-opus-4-7" => Ok(Self::ClaudeOpus47),
643 "claude-sonnet-4-0" => Ok(Self::ClaudeSonnet40),
644 "claude-sonnet-4-20250514" => Ok(Self::ClaudeSonnet420250514),
645 "claude-sonnet-4-5" => Ok(Self::ClaudeSonnet45),
646 "claude-sonnet-4-5-20250929" => Ok(Self::ClaudeSonnet4520250929),
647 "claude-sonnet-4-6" => Ok(Self::ClaudeSonnet46),
648 _ => Err(format!("Unknown anthropic model: '{s}'")),
649 }
650 }
651}
652impl CodexModel {
653 #[allow(clippy::too_many_lines)]
654 fn model_id(self) -> &'static str {
655 match self {
656 Self::Gpt5 => "gpt-5",
657 Self::Gpt5Codex => "gpt-5-codex",
658 Self::Gpt51 => "gpt-5.1",
659 Self::Gpt51Codex => "gpt-5.1-codex",
660 Self::Gpt51CodexMax => "gpt-5.1-codex-max",
661 Self::Gpt51CodexMini => "gpt-5.1-codex-mini",
662 Self::Gpt52 => "gpt-5.2",
663 Self::Gpt52Codex => "gpt-5.2-codex",
664 Self::Gpt52Pro => "gpt-5.2-pro",
665 Self::Gpt53Codex => "gpt-5.3-codex",
666 Self::Gpt53CodexSpark => "gpt-5.3-codex-spark",
667 Self::Gpt54 => "gpt-5.4",
668 Self::Gpt54Mini => "gpt-5.4-mini",
669 Self::Gpt54Nano => "gpt-5.4-nano",
670 Self::Gpt54Pro => "gpt-5.4-pro",
671 Self::Gpt55 => "gpt-5.5",
672 Self::Gpt55Pro => "gpt-5.5-pro",
673 }
674 }
675 #[allow(clippy::too_many_lines)]
676 fn display_name(self) -> &'static str {
677 match self {
678 Self::Gpt5 => "GPT-5",
679 Self::Gpt5Codex => "GPT-5-Codex",
680 Self::Gpt51 => "GPT-5.1",
681 Self::Gpt51Codex => "GPT-5.1 Codex",
682 Self::Gpt51CodexMax => "GPT-5.1 Codex Max",
683 Self::Gpt51CodexMini => "GPT-5.1 Codex mini",
684 Self::Gpt52 => "GPT-5.2",
685 Self::Gpt52Codex => "GPT-5.2 Codex",
686 Self::Gpt52Pro => "GPT-5.2 Pro",
687 Self::Gpt53Codex => "GPT-5.3 Codex",
688 Self::Gpt53CodexSpark => "GPT-5.3 Codex Spark",
689 Self::Gpt54 => "GPT-5.4",
690 Self::Gpt54Pro => "GPT-5.4 Pro",
691 Self::Gpt54Mini => "GPT-5.4 mini",
692 Self::Gpt54Nano => "GPT-5.4 nano",
693 Self::Gpt55 => "GPT-5.5",
694 Self::Gpt55Pro => "GPT-5.5 Pro",
695 }
696 }
697 #[allow(clippy::too_many_lines)]
698 fn context_window(self) -> u32 {
699 match self {
700 Self::Gpt53CodexSpark => 128_000,
701 Self::Gpt52
702 | Self::Gpt53Codex
703 | Self::Gpt54
704 | Self::Gpt54Mini
705 | Self::Gpt55 => 272_000,
706 Self::Gpt5
707 | Self::Gpt5Codex
708 | Self::Gpt51
709 | Self::Gpt51Codex
710 | Self::Gpt51CodexMax
711 | Self::Gpt51CodexMini
712 | Self::Gpt52Codex
713 | Self::Gpt52Pro
714 | Self::Gpt54Nano => 400_000,
715 Self::Gpt54Pro | Self::Gpt55Pro => 1_050_000,
716 }
717 }
718 #[allow(clippy::too_many_lines)]
719 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
720 match self {
721 Self::Gpt5
722 | Self::Gpt5Codex
723 | Self::Gpt51
724 | Self::Gpt51Codex
725 | Self::Gpt51CodexMax
726 | Self::Gpt51CodexMini
727 | Self::Gpt52
728 | Self::Gpt52Codex
729 | Self::Gpt52Pro
730 | Self::Gpt53Codex
731 | Self::Gpt53CodexSpark
732 | Self::Gpt54
733 | Self::Gpt54Mini
734 | Self::Gpt54Nano
735 | Self::Gpt54Pro
736 | Self::Gpt55
737 | Self::Gpt55Pro => {
738 &[
739 ReasoningEffort::Low,
740 ReasoningEffort::Medium,
741 ReasoningEffort::High,
742 ReasoningEffort::Xhigh,
743 ]
744 }
745 }
746 }
747 pub fn supports_reasoning(self) -> bool {
748 !self.reasoning_levels().is_empty()
749 }
750 #[allow(clippy::too_many_lines)]
751 pub fn supports_prompt_caching(self) -> bool {
752 match self {
753 Self::Gpt52Pro | Self::Gpt54Pro | Self::Gpt55Pro => false,
754 Self::Gpt5
755 | Self::Gpt5Codex
756 | Self::Gpt51
757 | Self::Gpt51Codex
758 | Self::Gpt51CodexMax
759 | Self::Gpt51CodexMini
760 | Self::Gpt52
761 | Self::Gpt52Codex
762 | Self::Gpt53Codex
763 | Self::Gpt53CodexSpark
764 | Self::Gpt54
765 | Self::Gpt54Mini
766 | Self::Gpt54Nano
767 | Self::Gpt55 => true,
768 }
769 }
770 #[allow(clippy::too_many_lines)]
771 pub fn supports_image(self) -> bool {
772 match self {
773 Self::Gpt5
774 | Self::Gpt5Codex
775 | Self::Gpt51
776 | Self::Gpt51Codex
777 | Self::Gpt51CodexMax
778 | Self::Gpt51CodexMini
779 | Self::Gpt52
780 | Self::Gpt52Codex
781 | Self::Gpt52Pro
782 | Self::Gpt53Codex
783 | Self::Gpt53CodexSpark
784 | Self::Gpt54
785 | Self::Gpt54Mini
786 | Self::Gpt54Nano
787 | Self::Gpt54Pro
788 | Self::Gpt55
789 | Self::Gpt55Pro => true,
790 }
791 }
792 #[allow(clippy::too_many_lines)]
793 pub fn supports_audio(self) -> bool {
794 match self {
795 Self::Gpt5
796 | Self::Gpt5Codex
797 | Self::Gpt51
798 | Self::Gpt51Codex
799 | Self::Gpt51CodexMax
800 | Self::Gpt51CodexMini
801 | Self::Gpt52
802 | Self::Gpt52Codex
803 | Self::Gpt52Pro
804 | Self::Gpt53Codex
805 | Self::Gpt53CodexSpark
806 | Self::Gpt54
807 | Self::Gpt54Mini
808 | Self::Gpt54Nano
809 | Self::Gpt54Pro
810 | Self::Gpt55
811 | Self::Gpt55Pro => false,
812 }
813 }
814 const ALL: &[CodexModel] = &[
815 Self::Gpt5,
816 Self::Gpt5Codex,
817 Self::Gpt51,
818 Self::Gpt51Codex,
819 Self::Gpt51CodexMax,
820 Self::Gpt51CodexMini,
821 Self::Gpt52,
822 Self::Gpt52Codex,
823 Self::Gpt52Pro,
824 Self::Gpt53Codex,
825 Self::Gpt53CodexSpark,
826 Self::Gpt54,
827 Self::Gpt54Mini,
828 Self::Gpt54Nano,
829 Self::Gpt54Pro,
830 Self::Gpt55,
831 Self::Gpt55Pro,
832 ];
833}
834impl std::str::FromStr for CodexModel {
835 type Err = String;
836 #[allow(clippy::too_many_lines)]
837 fn from_str(s: &str) -> Result<Self, Self::Err> {
838 match s {
839 "gpt-5" => Ok(Self::Gpt5),
840 "gpt-5-codex" => Ok(Self::Gpt5Codex),
841 "gpt-5.1" => Ok(Self::Gpt51),
842 "gpt-5.1-codex" => Ok(Self::Gpt51Codex),
843 "gpt-5.1-codex-max" => Ok(Self::Gpt51CodexMax),
844 "gpt-5.1-codex-mini" => Ok(Self::Gpt51CodexMini),
845 "gpt-5.2" => Ok(Self::Gpt52),
846 "gpt-5.2-codex" => Ok(Self::Gpt52Codex),
847 "gpt-5.2-pro" => Ok(Self::Gpt52Pro),
848 "gpt-5.3-codex" => Ok(Self::Gpt53Codex),
849 "gpt-5.3-codex-spark" => Ok(Self::Gpt53CodexSpark),
850 "gpt-5.4" => Ok(Self::Gpt54),
851 "gpt-5.4-mini" => Ok(Self::Gpt54Mini),
852 "gpt-5.4-nano" => Ok(Self::Gpt54Nano),
853 "gpt-5.4-pro" => Ok(Self::Gpt54Pro),
854 "gpt-5.5" => Ok(Self::Gpt55),
855 "gpt-5.5-pro" => Ok(Self::Gpt55Pro),
856 _ => Err(format!("Unknown codex model: '{s}'")),
857 }
858 }
859}
860impl DeepSeekModel {
861 #[allow(clippy::too_many_lines)]
862 fn model_id(self) -> &'static str {
863 match self {
864 Self::DeepseekChat => "deepseek-chat",
865 Self::DeepseekReasoner => "deepseek-reasoner",
866 Self::DeepseekV4Flash => "deepseek-v4-flash",
867 Self::DeepseekV4Pro => "deepseek-v4-pro",
868 }
869 }
870 #[allow(clippy::too_many_lines)]
871 fn display_name(self) -> &'static str {
872 match self {
873 Self::DeepseekChat => "DeepSeek Chat",
874 Self::DeepseekReasoner => "DeepSeek Reasoner",
875 Self::DeepseekV4Flash => "DeepSeek V4 Flash",
876 Self::DeepseekV4Pro => "DeepSeek V4 Pro",
877 }
878 }
879 #[allow(clippy::too_many_lines)]
880 fn context_window(self) -> u32 {
881 match self {
882 Self::DeepseekChat
883 | Self::DeepseekReasoner
884 | Self::DeepseekV4Flash
885 | Self::DeepseekV4Pro => 1_000_000,
886 }
887 }
888 #[allow(clippy::too_many_lines)]
889 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
890 match self {
891 Self::DeepseekChat => &[],
892 Self::DeepseekReasoner | Self::DeepseekV4Flash | Self::DeepseekV4Pro => {
893 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
894 }
895 }
896 }
897 pub fn supports_reasoning(self) -> bool {
898 !self.reasoning_levels().is_empty()
899 }
900 #[allow(clippy::too_many_lines)]
901 pub fn supports_prompt_caching(self) -> bool {
902 match self {
903 Self::DeepseekChat
904 | Self::DeepseekReasoner
905 | Self::DeepseekV4Flash
906 | Self::DeepseekV4Pro => true,
907 }
908 }
909 #[allow(clippy::too_many_lines)]
910 pub fn supports_image(self) -> bool {
911 match self {
912 Self::DeepseekChat
913 | Self::DeepseekReasoner
914 | Self::DeepseekV4Flash
915 | Self::DeepseekV4Pro => false,
916 }
917 }
918 #[allow(clippy::too_many_lines)]
919 pub fn supports_audio(self) -> bool {
920 match self {
921 Self::DeepseekChat
922 | Self::DeepseekReasoner
923 | Self::DeepseekV4Flash
924 | Self::DeepseekV4Pro => false,
925 }
926 }
927 const ALL: &[DeepSeekModel] = &[
928 Self::DeepseekChat,
929 Self::DeepseekReasoner,
930 Self::DeepseekV4Flash,
931 Self::DeepseekV4Pro,
932 ];
933}
934impl std::str::FromStr for DeepSeekModel {
935 type Err = String;
936 #[allow(clippy::too_many_lines)]
937 fn from_str(s: &str) -> Result<Self, Self::Err> {
938 match s {
939 "deepseek-chat" => Ok(Self::DeepseekChat),
940 "deepseek-reasoner" => Ok(Self::DeepseekReasoner),
941 "deepseek-v4-flash" => Ok(Self::DeepseekV4Flash),
942 "deepseek-v4-pro" => Ok(Self::DeepseekV4Pro),
943 _ => Err(format!("Unknown deepseek model: '{s}'")),
944 }
945 }
946}
947impl GeminiModel {
948 #[allow(clippy::too_many_lines)]
949 fn model_id(self) -> &'static str {
950 match self {
951 Self::Gemini15Flash => "gemini-1.5-flash",
952 Self::Gemini15Flash8b => "gemini-1.5-flash-8b",
953 Self::Gemini15Pro => "gemini-1.5-pro",
954 Self::Gemini20Flash => "gemini-2.0-flash",
955 Self::Gemini20FlashLite => "gemini-2.0-flash-lite",
956 Self::Gemini25Flash => "gemini-2.5-flash",
957 Self::Gemini25FlashLite => "gemini-2.5-flash-lite",
958 Self::Gemini25FlashLitePreview0617 => "gemini-2.5-flash-lite-preview-06-17",
959 Self::Gemini25FlashLitePreview092025 => {
960 "gemini-2.5-flash-lite-preview-09-2025"
961 }
962 Self::Gemini25FlashPreview0417 => "gemini-2.5-flash-preview-04-17",
963 Self::Gemini25FlashPreview0520 => "gemini-2.5-flash-preview-05-20",
964 Self::Gemini25FlashPreview092025 => "gemini-2.5-flash-preview-09-2025",
965 Self::Gemini25Pro => "gemini-2.5-pro",
966 Self::Gemini25ProPreview0506 => "gemini-2.5-pro-preview-05-06",
967 Self::Gemini25ProPreview0605 => "gemini-2.5-pro-preview-06-05",
968 Self::Gemini3FlashPreview => "gemini-3-flash-preview",
969 Self::Gemini3ProPreview => "gemini-3-pro-preview",
970 Self::Gemini31FlashLite => "gemini-3.1-flash-lite",
971 Self::Gemini31FlashLitePreview => "gemini-3.1-flash-lite-preview",
972 Self::Gemini31ProPreview => "gemini-3.1-pro-preview",
973 Self::Gemini31ProPreviewCustomtools => "gemini-3.1-pro-preview-customtools",
974 Self::GeminiLive25Flash => "gemini-live-2.5-flash",
975 Self::GeminiLive25FlashPreviewNativeAudio => {
976 "gemini-live-2.5-flash-preview-native-audio"
977 }
978 Self::Gemma327bIt => "gemma-3-27b-it",
979 Self::Gemma426bA4bIt => "gemma-4-26b-a4b-it",
980 Self::Gemma431bIt => "gemma-4-31b-it",
981 }
982 }
983 #[allow(clippy::too_many_lines)]
984 fn display_name(self) -> &'static str {
985 match self {
986 Self::Gemini15Flash => "Gemini 1.5 Flash",
987 Self::Gemini15Flash8b => "Gemini 1.5 Flash-8B",
988 Self::Gemini15Pro => "Gemini 1.5 Pro",
989 Self::Gemini20Flash => "Gemini 2.0 Flash",
990 Self::Gemini20FlashLite => "Gemini 2.0 Flash Lite",
991 Self::Gemini25Flash => "Gemini 2.5 Flash",
992 Self::Gemini25FlashLite => "Gemini 2.5 Flash Lite",
993 Self::Gemini25FlashLitePreview0617 => "Gemini 2.5 Flash Lite Preview 06-17",
994 Self::Gemini25FlashLitePreview092025 => "Gemini 2.5 Flash Lite Preview 09-25",
995 Self::Gemini25FlashPreview0417 => "Gemini 2.5 Flash Preview 04-17",
996 Self::Gemini25FlashPreview0520 => "Gemini 2.5 Flash Preview 05-20",
997 Self::Gemini25FlashPreview092025 => "Gemini 2.5 Flash Preview 09-25",
998 Self::Gemini25Pro => "Gemini 2.5 Pro",
999 Self::Gemini25ProPreview0506 => "Gemini 2.5 Pro Preview 05-06",
1000 Self::Gemini25ProPreview0605 => "Gemini 2.5 Pro Preview 06-05",
1001 Self::Gemini3FlashPreview => "Gemini 3 Flash Preview",
1002 Self::Gemini3ProPreview => "Gemini 3 Pro Preview",
1003 Self::Gemini31FlashLite => "Gemini 3.1 Flash Lite",
1004 Self::Gemini31FlashLitePreview => "Gemini 3.1 Flash Lite Preview",
1005 Self::Gemini31ProPreview => "Gemini 3.1 Pro Preview",
1006 Self::Gemini31ProPreviewCustomtools => "Gemini 3.1 Pro Preview Custom Tools",
1007 Self::GeminiLive25Flash => "Gemini Live 2.5 Flash",
1008 Self::GeminiLive25FlashPreviewNativeAudio => {
1009 "Gemini Live 2.5 Flash Preview Native Audio"
1010 }
1011 Self::Gemma327bIt => "Gemma 3 27B",
1012 Self::Gemma426bA4bIt => "Gemma 4 26B",
1013 Self::Gemma431bIt => "Gemma 4 31B",
1014 }
1015 }
1016 #[allow(clippy::too_many_lines)]
1017 fn context_window(self) -> u32 {
1018 match self {
1019 Self::GeminiLive25Flash => 128_000,
1020 Self::GeminiLive25FlashPreviewNativeAudio | Self::Gemma327bIt => 131_072,
1021 Self::Gemma426bA4bIt | Self::Gemma431bIt => 256_000,
1022 Self::Gemini15Flash
1023 | Self::Gemini15Flash8b
1024 | Self::Gemini15Pro
1025 | Self::Gemini3ProPreview => 1_000_000,
1026 Self::Gemini20Flash
1027 | Self::Gemini20FlashLite
1028 | Self::Gemini25Flash
1029 | Self::Gemini25FlashLite
1030 | Self::Gemini25FlashLitePreview0617
1031 | Self::Gemini25FlashLitePreview092025
1032 | Self::Gemini25FlashPreview0417
1033 | Self::Gemini25FlashPreview0520
1034 | Self::Gemini25FlashPreview092025
1035 | Self::Gemini25Pro
1036 | Self::Gemini25ProPreview0506
1037 | Self::Gemini25ProPreview0605
1038 | Self::Gemini3FlashPreview
1039 | Self::Gemini31FlashLite
1040 | Self::Gemini31FlashLitePreview
1041 | Self::Gemini31ProPreview
1042 | Self::Gemini31ProPreviewCustomtools => 1_048_576,
1043 }
1044 }
1045 #[allow(clippy::too_many_lines)]
1046 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
1047 match self {
1048 Self::Gemini15Flash
1049 | Self::Gemini15Flash8b
1050 | Self::Gemini15Pro
1051 | Self::Gemini20Flash
1052 | Self::Gemini20FlashLite
1053 | Self::Gemma327bIt => &[],
1054 Self::Gemini25Flash
1055 | Self::Gemini25FlashLite
1056 | Self::Gemini25FlashLitePreview0617
1057 | Self::Gemini25FlashLitePreview092025
1058 | Self::Gemini25FlashPreview0417
1059 | Self::Gemini25FlashPreview0520
1060 | Self::Gemini25FlashPreview092025
1061 | Self::Gemini25Pro
1062 | Self::Gemini25ProPreview0506
1063 | Self::Gemini25ProPreview0605
1064 | Self::Gemini3FlashPreview
1065 | Self::Gemini3ProPreview
1066 | Self::Gemini31FlashLite
1067 | Self::Gemini31FlashLitePreview
1068 | Self::Gemini31ProPreview
1069 | Self::Gemini31ProPreviewCustomtools
1070 | Self::GeminiLive25Flash
1071 | Self::GeminiLive25FlashPreviewNativeAudio
1072 | Self::Gemma426bA4bIt
1073 | Self::Gemma431bIt => {
1074 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
1075 }
1076 }
1077 }
1078 pub fn supports_reasoning(self) -> bool {
1079 !self.reasoning_levels().is_empty()
1080 }
1081 #[allow(clippy::too_many_lines)]
1082 pub fn supports_prompt_caching(self) -> bool {
1083 match self {
1084 Self::Gemini20FlashLite
1085 | Self::GeminiLive25Flash
1086 | Self::GeminiLive25FlashPreviewNativeAudio
1087 | Self::Gemma327bIt
1088 | Self::Gemma426bA4bIt
1089 | Self::Gemma431bIt => false,
1090 Self::Gemini15Flash
1091 | Self::Gemini15Flash8b
1092 | Self::Gemini15Pro
1093 | Self::Gemini20Flash
1094 | Self::Gemini25Flash
1095 | Self::Gemini25FlashLite
1096 | Self::Gemini25FlashLitePreview0617
1097 | Self::Gemini25FlashLitePreview092025
1098 | Self::Gemini25FlashPreview0417
1099 | Self::Gemini25FlashPreview0520
1100 | Self::Gemini25FlashPreview092025
1101 | Self::Gemini25Pro
1102 | Self::Gemini25ProPreview0506
1103 | Self::Gemini25ProPreview0605
1104 | Self::Gemini3FlashPreview
1105 | Self::Gemini3ProPreview
1106 | Self::Gemini31FlashLite
1107 | Self::Gemini31FlashLitePreview
1108 | Self::Gemini31ProPreview
1109 | Self::Gemini31ProPreviewCustomtools => true,
1110 }
1111 }
1112 #[allow(clippy::too_many_lines)]
1113 pub fn supports_image(self) -> bool {
1114 match self {
1115 Self::GeminiLive25FlashPreviewNativeAudio => false,
1116 Self::Gemini15Flash
1117 | Self::Gemini15Flash8b
1118 | Self::Gemini15Pro
1119 | Self::Gemini20Flash
1120 | Self::Gemini20FlashLite
1121 | Self::Gemini25Flash
1122 | Self::Gemini25FlashLite
1123 | Self::Gemini25FlashLitePreview0617
1124 | Self::Gemini25FlashLitePreview092025
1125 | Self::Gemini25FlashPreview0417
1126 | Self::Gemini25FlashPreview0520
1127 | Self::Gemini25FlashPreview092025
1128 | Self::Gemini25Pro
1129 | Self::Gemini25ProPreview0506
1130 | Self::Gemini25ProPreview0605
1131 | Self::Gemini3FlashPreview
1132 | Self::Gemini3ProPreview
1133 | Self::Gemini31FlashLite
1134 | Self::Gemini31FlashLitePreview
1135 | Self::Gemini31ProPreview
1136 | Self::Gemini31ProPreviewCustomtools
1137 | Self::GeminiLive25Flash
1138 | Self::Gemma327bIt
1139 | Self::Gemma426bA4bIt
1140 | Self::Gemma431bIt => true,
1141 }
1142 }
1143 #[allow(clippy::too_many_lines)]
1144 pub fn supports_audio(self) -> bool {
1145 match self {
1146 Self::Gemma327bIt | Self::Gemma426bA4bIt | Self::Gemma431bIt => false,
1147 Self::Gemini15Flash
1148 | Self::Gemini15Flash8b
1149 | Self::Gemini15Pro
1150 | Self::Gemini20Flash
1151 | Self::Gemini20FlashLite
1152 | Self::Gemini25Flash
1153 | Self::Gemini25FlashLite
1154 | Self::Gemini25FlashLitePreview0617
1155 | Self::Gemini25FlashLitePreview092025
1156 | Self::Gemini25FlashPreview0417
1157 | Self::Gemini25FlashPreview0520
1158 | Self::Gemini25FlashPreview092025
1159 | Self::Gemini25Pro
1160 | Self::Gemini25ProPreview0506
1161 | Self::Gemini25ProPreview0605
1162 | Self::Gemini3FlashPreview
1163 | Self::Gemini3ProPreview
1164 | Self::Gemini31FlashLite
1165 | Self::Gemini31FlashLitePreview
1166 | Self::Gemini31ProPreview
1167 | Self::Gemini31ProPreviewCustomtools
1168 | Self::GeminiLive25Flash
1169 | Self::GeminiLive25FlashPreviewNativeAudio => true,
1170 }
1171 }
1172 const ALL: &[GeminiModel] = &[
1173 Self::Gemini15Flash,
1174 Self::Gemini15Flash8b,
1175 Self::Gemini15Pro,
1176 Self::Gemini20Flash,
1177 Self::Gemini20FlashLite,
1178 Self::Gemini25Flash,
1179 Self::Gemini25FlashLite,
1180 Self::Gemini25FlashLitePreview0617,
1181 Self::Gemini25FlashLitePreview092025,
1182 Self::Gemini25FlashPreview0417,
1183 Self::Gemini25FlashPreview0520,
1184 Self::Gemini25FlashPreview092025,
1185 Self::Gemini25Pro,
1186 Self::Gemini25ProPreview0506,
1187 Self::Gemini25ProPreview0605,
1188 Self::Gemini3FlashPreview,
1189 Self::Gemini3ProPreview,
1190 Self::Gemini31FlashLite,
1191 Self::Gemini31FlashLitePreview,
1192 Self::Gemini31ProPreview,
1193 Self::Gemini31ProPreviewCustomtools,
1194 Self::GeminiLive25Flash,
1195 Self::GeminiLive25FlashPreviewNativeAudio,
1196 Self::Gemma327bIt,
1197 Self::Gemma426bA4bIt,
1198 Self::Gemma431bIt,
1199 ];
1200}
1201impl std::str::FromStr for GeminiModel {
1202 type Err = String;
1203 #[allow(clippy::too_many_lines)]
1204 fn from_str(s: &str) -> Result<Self, Self::Err> {
1205 match s {
1206 "gemini-1.5-flash" => Ok(Self::Gemini15Flash),
1207 "gemini-1.5-flash-8b" => Ok(Self::Gemini15Flash8b),
1208 "gemini-1.5-pro" => Ok(Self::Gemini15Pro),
1209 "gemini-2.0-flash" => Ok(Self::Gemini20Flash),
1210 "gemini-2.0-flash-lite" => Ok(Self::Gemini20FlashLite),
1211 "gemini-2.5-flash" => Ok(Self::Gemini25Flash),
1212 "gemini-2.5-flash-lite" => Ok(Self::Gemini25FlashLite),
1213 "gemini-2.5-flash-lite-preview-06-17" => {
1214 Ok(Self::Gemini25FlashLitePreview0617)
1215 }
1216 "gemini-2.5-flash-lite-preview-09-2025" => {
1217 Ok(Self::Gemini25FlashLitePreview092025)
1218 }
1219 "gemini-2.5-flash-preview-04-17" => Ok(Self::Gemini25FlashPreview0417),
1220 "gemini-2.5-flash-preview-05-20" => Ok(Self::Gemini25FlashPreview0520),
1221 "gemini-2.5-flash-preview-09-2025" => Ok(Self::Gemini25FlashPreview092025),
1222 "gemini-2.5-pro" => Ok(Self::Gemini25Pro),
1223 "gemini-2.5-pro-preview-05-06" => Ok(Self::Gemini25ProPreview0506),
1224 "gemini-2.5-pro-preview-06-05" => Ok(Self::Gemini25ProPreview0605),
1225 "gemini-3-flash-preview" => Ok(Self::Gemini3FlashPreview),
1226 "gemini-3-pro-preview" => Ok(Self::Gemini3ProPreview),
1227 "gemini-3.1-flash-lite" => Ok(Self::Gemini31FlashLite),
1228 "gemini-3.1-flash-lite-preview" => Ok(Self::Gemini31FlashLitePreview),
1229 "gemini-3.1-pro-preview" => Ok(Self::Gemini31ProPreview),
1230 "gemini-3.1-pro-preview-customtools" => {
1231 Ok(Self::Gemini31ProPreviewCustomtools)
1232 }
1233 "gemini-live-2.5-flash" => Ok(Self::GeminiLive25Flash),
1234 "gemini-live-2.5-flash-preview-native-audio" => {
1235 Ok(Self::GeminiLive25FlashPreviewNativeAudio)
1236 }
1237 "gemma-3-27b-it" => Ok(Self::Gemma327bIt),
1238 "gemma-4-26b-a4b-it" => Ok(Self::Gemma426bA4bIt),
1239 "gemma-4-31b-it" => Ok(Self::Gemma431bIt),
1240 _ => Err(format!("Unknown gemini model: '{s}'")),
1241 }
1242 }
1243}
1244impl MoonshotModel {
1245 #[allow(clippy::too_many_lines)]
1246 fn model_id(self) -> &'static str {
1247 match self {
1248 Self::KimiK20711Preview => "kimi-k2-0711-preview",
1249 Self::KimiK20905Preview => "kimi-k2-0905-preview",
1250 Self::KimiK2Thinking => "kimi-k2-thinking",
1251 Self::KimiK2ThinkingTurbo => "kimi-k2-thinking-turbo",
1252 Self::KimiK2TurboPreview => "kimi-k2-turbo-preview",
1253 Self::KimiK25 => "kimi-k2.5",
1254 Self::KimiK26 => "kimi-k2.6",
1255 }
1256 }
1257 #[allow(clippy::too_many_lines)]
1258 fn display_name(self) -> &'static str {
1259 match self {
1260 Self::KimiK20711Preview => "Kimi K2 0711",
1261 Self::KimiK20905Preview => "Kimi K2 0905",
1262 Self::KimiK2Thinking => "Kimi K2 Thinking",
1263 Self::KimiK2ThinkingTurbo => "Kimi K2 Thinking Turbo",
1264 Self::KimiK2TurboPreview => "Kimi K2 Turbo",
1265 Self::KimiK25 => "Kimi K2.5",
1266 Self::KimiK26 => "Kimi K2.6",
1267 }
1268 }
1269 #[allow(clippy::too_many_lines)]
1270 fn context_window(self) -> u32 {
1271 match self {
1272 Self::KimiK20711Preview => 131_072,
1273 Self::KimiK20905Preview
1274 | Self::KimiK2Thinking
1275 | Self::KimiK2ThinkingTurbo
1276 | Self::KimiK2TurboPreview
1277 | Self::KimiK25
1278 | Self::KimiK26 => 262_144,
1279 }
1280 }
1281 #[allow(clippy::too_many_lines)]
1282 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
1283 match self {
1284 Self::KimiK20711Preview
1285 | Self::KimiK20905Preview
1286 | Self::KimiK2TurboPreview => &[],
1287 Self::KimiK2Thinking
1288 | Self::KimiK2ThinkingTurbo
1289 | Self::KimiK25
1290 | Self::KimiK26 => {
1291 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
1292 }
1293 }
1294 }
1295 pub fn supports_reasoning(self) -> bool {
1296 !self.reasoning_levels().is_empty()
1297 }
1298 #[allow(clippy::too_many_lines)]
1299 pub fn supports_prompt_caching(self) -> bool {
1300 match self {
1301 Self::KimiK20711Preview
1302 | Self::KimiK20905Preview
1303 | Self::KimiK2Thinking
1304 | Self::KimiK2ThinkingTurbo
1305 | Self::KimiK2TurboPreview
1306 | Self::KimiK25
1307 | Self::KimiK26 => true,
1308 }
1309 }
1310 #[allow(clippy::too_many_lines)]
1311 pub fn supports_image(self) -> bool {
1312 match self {
1313 Self::KimiK20711Preview
1314 | Self::KimiK20905Preview
1315 | Self::KimiK2Thinking
1316 | Self::KimiK2ThinkingTurbo
1317 | Self::KimiK2TurboPreview => false,
1318 Self::KimiK25 | Self::KimiK26 => true,
1319 }
1320 }
1321 #[allow(clippy::too_many_lines)]
1322 pub fn supports_audio(self) -> bool {
1323 match self {
1324 Self::KimiK20711Preview
1325 | Self::KimiK20905Preview
1326 | Self::KimiK2Thinking
1327 | Self::KimiK2ThinkingTurbo
1328 | Self::KimiK2TurboPreview
1329 | Self::KimiK25
1330 | Self::KimiK26 => false,
1331 }
1332 }
1333 const ALL: &[MoonshotModel] = &[
1334 Self::KimiK20711Preview,
1335 Self::KimiK20905Preview,
1336 Self::KimiK2Thinking,
1337 Self::KimiK2ThinkingTurbo,
1338 Self::KimiK2TurboPreview,
1339 Self::KimiK25,
1340 Self::KimiK26,
1341 ];
1342}
1343impl std::str::FromStr for MoonshotModel {
1344 type Err = String;
1345 #[allow(clippy::too_many_lines)]
1346 fn from_str(s: &str) -> Result<Self, Self::Err> {
1347 match s {
1348 "kimi-k2-0711-preview" => Ok(Self::KimiK20711Preview),
1349 "kimi-k2-0905-preview" => Ok(Self::KimiK20905Preview),
1350 "kimi-k2-thinking" => Ok(Self::KimiK2Thinking),
1351 "kimi-k2-thinking-turbo" => Ok(Self::KimiK2ThinkingTurbo),
1352 "kimi-k2-turbo-preview" => Ok(Self::KimiK2TurboPreview),
1353 "kimi-k2.5" => Ok(Self::KimiK25),
1354 "kimi-k2.6" => Ok(Self::KimiK26),
1355 _ => Err(format!("Unknown moonshot model: '{s}'")),
1356 }
1357 }
1358}
1359impl OpenaiModel {
1360 #[allow(clippy::too_many_lines)]
1361 fn model_id(self) -> &'static str {
1362 match self {
1363 Self::Gpt4 => "gpt-4",
1364 Self::Gpt4Turbo => "gpt-4-turbo",
1365 Self::Gpt41 => "gpt-4.1",
1366 Self::Gpt41Mini => "gpt-4.1-mini",
1367 Self::Gpt41Nano => "gpt-4.1-nano",
1368 Self::Gpt4o => "gpt-4o",
1369 Self::Gpt4o20240513 => "gpt-4o-2024-05-13",
1370 Self::Gpt4o20240806 => "gpt-4o-2024-08-06",
1371 Self::Gpt4o20241120 => "gpt-4o-2024-11-20",
1372 Self::Gpt4oMini => "gpt-4o-mini",
1373 Self::Gpt5 => "gpt-5",
1374 Self::Gpt5Codex => "gpt-5-codex",
1375 Self::Gpt5Mini => "gpt-5-mini",
1376 Self::Gpt5Nano => "gpt-5-nano",
1377 Self::Gpt5Pro => "gpt-5-pro",
1378 Self::Gpt51 => "gpt-5.1",
1379 Self::Gpt51Codex => "gpt-5.1-codex",
1380 Self::Gpt51CodexMax => "gpt-5.1-codex-max",
1381 Self::Gpt51CodexMini => "gpt-5.1-codex-mini",
1382 Self::Gpt52 => "gpt-5.2",
1383 Self::Gpt52Codex => "gpt-5.2-codex",
1384 Self::Gpt52Pro => "gpt-5.2-pro",
1385 Self::Gpt53Codex => "gpt-5.3-codex",
1386 Self::Gpt53CodexSpark => "gpt-5.3-codex-spark",
1387 Self::Gpt54 => "gpt-5.4",
1388 Self::Gpt54Mini => "gpt-5.4-mini",
1389 Self::Gpt54Nano => "gpt-5.4-nano",
1390 Self::Gpt54Pro => "gpt-5.4-pro",
1391 Self::Gpt55 => "gpt-5.5",
1392 Self::Gpt55Pro => "gpt-5.5-pro",
1393 Self::O1 => "o1",
1394 Self::O1Pro => "o1-pro",
1395 Self::O3 => "o3",
1396 Self::O3DeepResearch => "o3-deep-research",
1397 Self::O3Mini => "o3-mini",
1398 Self::O3Pro => "o3-pro",
1399 Self::O4Mini => "o4-mini",
1400 Self::O4MiniDeepResearch => "o4-mini-deep-research",
1401 }
1402 }
1403 #[allow(clippy::too_many_lines)]
1404 fn display_name(self) -> &'static str {
1405 match self {
1406 Self::Gpt4 => "GPT-4",
1407 Self::Gpt4Turbo => "GPT-4 Turbo",
1408 Self::Gpt41 => "GPT-4.1",
1409 Self::Gpt41Mini => "GPT-4.1 mini",
1410 Self::Gpt41Nano => "GPT-4.1 nano",
1411 Self::Gpt4o => "GPT-4o",
1412 Self::Gpt4o20240513 => "GPT-4o (2024-05-13)",
1413 Self::Gpt4o20240806 => "GPT-4o (2024-08-06)",
1414 Self::Gpt4o20241120 => "GPT-4o (2024-11-20)",
1415 Self::Gpt4oMini => "GPT-4o mini",
1416 Self::Gpt5 => "GPT-5",
1417 Self::Gpt5Mini => "GPT-5 Mini",
1418 Self::Gpt5Nano => "GPT-5 Nano",
1419 Self::Gpt5Pro => "GPT-5 Pro",
1420 Self::Gpt5Codex => "GPT-5-Codex",
1421 Self::Gpt51 => "GPT-5.1",
1422 Self::Gpt51Codex => "GPT-5.1 Codex",
1423 Self::Gpt51CodexMax => "GPT-5.1 Codex Max",
1424 Self::Gpt51CodexMini => "GPT-5.1 Codex mini",
1425 Self::Gpt52 => "GPT-5.2",
1426 Self::Gpt52Codex => "GPT-5.2 Codex",
1427 Self::Gpt52Pro => "GPT-5.2 Pro",
1428 Self::Gpt53Codex => "GPT-5.3 Codex",
1429 Self::Gpt53CodexSpark => "GPT-5.3 Codex Spark",
1430 Self::Gpt54 => "GPT-5.4",
1431 Self::Gpt54Pro => "GPT-5.4 Pro",
1432 Self::Gpt54Mini => "GPT-5.4 mini",
1433 Self::Gpt54Nano => "GPT-5.4 nano",
1434 Self::Gpt55 => "GPT-5.5",
1435 Self::Gpt55Pro => "GPT-5.5 Pro",
1436 Self::O1 => "o1",
1437 Self::O1Pro => "o1-pro",
1438 Self::O3 => "o3",
1439 Self::O3DeepResearch => "o3-deep-research",
1440 Self::O3Mini => "o3-mini",
1441 Self::O3Pro => "o3-pro",
1442 Self::O4Mini => "o4-mini",
1443 Self::O4MiniDeepResearch => "o4-mini-deep-research",
1444 }
1445 }
1446 #[allow(clippy::too_many_lines)]
1447 fn context_window(self) -> u32 {
1448 match self {
1449 Self::Gpt4 => 8192,
1450 Self::Gpt4Turbo
1451 | Self::Gpt4o
1452 | Self::Gpt4o20240513
1453 | Self::Gpt4o20240806
1454 | Self::Gpt4o20241120
1455 | Self::Gpt4oMini
1456 | Self::Gpt53CodexSpark => 128_000,
1457 Self::O1
1458 | Self::O1Pro
1459 | Self::O3
1460 | Self::O3DeepResearch
1461 | Self::O3Mini
1462 | Self::O3Pro
1463 | Self::O4Mini
1464 | Self::O4MiniDeepResearch => 200_000,
1465 Self::Gpt5
1466 | Self::Gpt5Codex
1467 | Self::Gpt5Mini
1468 | Self::Gpt5Nano
1469 | Self::Gpt5Pro
1470 | Self::Gpt51
1471 | Self::Gpt51Codex
1472 | Self::Gpt51CodexMax
1473 | Self::Gpt51CodexMini
1474 | Self::Gpt52
1475 | Self::Gpt52Codex
1476 | Self::Gpt52Pro
1477 | Self::Gpt53Codex
1478 | Self::Gpt54Mini
1479 | Self::Gpt54Nano => 400_000,
1480 Self::Gpt41 | Self::Gpt41Mini | Self::Gpt41Nano => 1_047_576,
1481 Self::Gpt54 | Self::Gpt54Pro | Self::Gpt55 | Self::Gpt55Pro => 1_050_000,
1482 }
1483 }
1484 #[allow(clippy::too_many_lines)]
1485 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
1486 match self {
1487 Self::Gpt4
1488 | Self::Gpt4Turbo
1489 | Self::Gpt41
1490 | Self::Gpt41Mini
1491 | Self::Gpt41Nano
1492 | Self::Gpt4o
1493 | Self::Gpt4o20240513
1494 | Self::Gpt4o20240806
1495 | Self::Gpt4o20241120
1496 | Self::Gpt4oMini => &[],
1497 Self::Gpt5
1498 | Self::Gpt5Codex
1499 | Self::Gpt5Mini
1500 | Self::Gpt5Nano
1501 | Self::Gpt5Pro
1502 | Self::Gpt51
1503 | Self::Gpt51Codex
1504 | Self::Gpt51CodexMax
1505 | Self::Gpt51CodexMini
1506 | Self::Gpt52
1507 | Self::Gpt52Codex
1508 | Self::Gpt52Pro
1509 | Self::Gpt53Codex
1510 | Self::Gpt53CodexSpark
1511 | Self::Gpt54
1512 | Self::Gpt54Mini
1513 | Self::Gpt54Nano
1514 | Self::Gpt54Pro
1515 | Self::Gpt55
1516 | Self::Gpt55Pro
1517 | Self::O1
1518 | Self::O1Pro
1519 | Self::O3
1520 | Self::O3DeepResearch
1521 | Self::O3Mini
1522 | Self::O3Pro
1523 | Self::O4Mini
1524 | Self::O4MiniDeepResearch => {
1525 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
1526 }
1527 }
1528 }
1529 pub fn supports_reasoning(self) -> bool {
1530 !self.reasoning_levels().is_empty()
1531 }
1532 #[allow(clippy::too_many_lines)]
1533 pub fn supports_prompt_caching(self) -> bool {
1534 match self {
1535 Self::Gpt4
1536 | Self::Gpt4Turbo
1537 | Self::Gpt4o20240513
1538 | Self::Gpt5Pro
1539 | Self::Gpt52Pro
1540 | Self::Gpt54Pro
1541 | Self::Gpt55Pro
1542 | Self::O1Pro
1543 | Self::O3Pro => false,
1544 Self::Gpt41
1545 | Self::Gpt41Mini
1546 | Self::Gpt41Nano
1547 | Self::Gpt4o
1548 | Self::Gpt4o20240806
1549 | Self::Gpt4o20241120
1550 | Self::Gpt4oMini
1551 | Self::Gpt5
1552 | Self::Gpt5Codex
1553 | Self::Gpt5Mini
1554 | Self::Gpt5Nano
1555 | Self::Gpt51
1556 | Self::Gpt51Codex
1557 | Self::Gpt51CodexMax
1558 | Self::Gpt51CodexMini
1559 | Self::Gpt52
1560 | Self::Gpt52Codex
1561 | Self::Gpt53Codex
1562 | Self::Gpt53CodexSpark
1563 | Self::Gpt54
1564 | Self::Gpt54Mini
1565 | Self::Gpt54Nano
1566 | Self::Gpt55
1567 | Self::O1
1568 | Self::O3
1569 | Self::O3DeepResearch
1570 | Self::O3Mini
1571 | Self::O4Mini
1572 | Self::O4MiniDeepResearch => true,
1573 }
1574 }
1575 #[allow(clippy::too_many_lines)]
1576 pub fn supports_image(self) -> bool {
1577 match self {
1578 Self::Gpt4 | Self::O3Mini => false,
1579 Self::Gpt4Turbo
1580 | Self::Gpt41
1581 | Self::Gpt41Mini
1582 | Self::Gpt41Nano
1583 | Self::Gpt4o
1584 | Self::Gpt4o20240513
1585 | Self::Gpt4o20240806
1586 | Self::Gpt4o20241120
1587 | Self::Gpt4oMini
1588 | Self::Gpt5
1589 | Self::Gpt5Codex
1590 | Self::Gpt5Mini
1591 | Self::Gpt5Nano
1592 | Self::Gpt5Pro
1593 | Self::Gpt51
1594 | Self::Gpt51Codex
1595 | Self::Gpt51CodexMax
1596 | Self::Gpt51CodexMini
1597 | Self::Gpt52
1598 | Self::Gpt52Codex
1599 | Self::Gpt52Pro
1600 | Self::Gpt53Codex
1601 | Self::Gpt53CodexSpark
1602 | Self::Gpt54
1603 | Self::Gpt54Mini
1604 | Self::Gpt54Nano
1605 | Self::Gpt54Pro
1606 | Self::Gpt55
1607 | Self::Gpt55Pro
1608 | Self::O1
1609 | Self::O1Pro
1610 | Self::O3
1611 | Self::O3DeepResearch
1612 | Self::O3Pro
1613 | Self::O4Mini
1614 | Self::O4MiniDeepResearch => true,
1615 }
1616 }
1617 #[allow(clippy::too_many_lines)]
1618 pub fn supports_audio(self) -> bool {
1619 match self {
1620 Self::Gpt4
1621 | Self::Gpt4Turbo
1622 | Self::Gpt41
1623 | Self::Gpt41Mini
1624 | Self::Gpt41Nano
1625 | Self::Gpt4o
1626 | Self::Gpt4o20240513
1627 | Self::Gpt4o20240806
1628 | Self::Gpt4o20241120
1629 | Self::Gpt4oMini
1630 | Self::Gpt5
1631 | Self::Gpt5Codex
1632 | Self::Gpt5Mini
1633 | Self::Gpt5Nano
1634 | Self::Gpt5Pro
1635 | Self::Gpt51
1636 | Self::Gpt51Codex
1637 | Self::Gpt51CodexMax
1638 | Self::Gpt51CodexMini
1639 | Self::Gpt52
1640 | Self::Gpt52Codex
1641 | Self::Gpt52Pro
1642 | Self::Gpt53Codex
1643 | Self::Gpt53CodexSpark
1644 | Self::Gpt54
1645 | Self::Gpt54Mini
1646 | Self::Gpt54Nano
1647 | Self::Gpt54Pro
1648 | Self::Gpt55
1649 | Self::Gpt55Pro
1650 | Self::O1
1651 | Self::O1Pro
1652 | Self::O3
1653 | Self::O3DeepResearch
1654 | Self::O3Mini
1655 | Self::O3Pro
1656 | Self::O4Mini
1657 | Self::O4MiniDeepResearch => false,
1658 }
1659 }
1660 const ALL: &[OpenaiModel] = &[
1661 Self::Gpt4,
1662 Self::Gpt4Turbo,
1663 Self::Gpt41,
1664 Self::Gpt41Mini,
1665 Self::Gpt41Nano,
1666 Self::Gpt4o,
1667 Self::Gpt4o20240513,
1668 Self::Gpt4o20240806,
1669 Self::Gpt4o20241120,
1670 Self::Gpt4oMini,
1671 Self::Gpt5,
1672 Self::Gpt5Codex,
1673 Self::Gpt5Mini,
1674 Self::Gpt5Nano,
1675 Self::Gpt5Pro,
1676 Self::Gpt51,
1677 Self::Gpt51Codex,
1678 Self::Gpt51CodexMax,
1679 Self::Gpt51CodexMini,
1680 Self::Gpt52,
1681 Self::Gpt52Codex,
1682 Self::Gpt52Pro,
1683 Self::Gpt53Codex,
1684 Self::Gpt53CodexSpark,
1685 Self::Gpt54,
1686 Self::Gpt54Mini,
1687 Self::Gpt54Nano,
1688 Self::Gpt54Pro,
1689 Self::Gpt55,
1690 Self::Gpt55Pro,
1691 Self::O1,
1692 Self::O1Pro,
1693 Self::O3,
1694 Self::O3DeepResearch,
1695 Self::O3Mini,
1696 Self::O3Pro,
1697 Self::O4Mini,
1698 Self::O4MiniDeepResearch,
1699 ];
1700}
1701impl std::str::FromStr for OpenaiModel {
1702 type Err = String;
1703 #[allow(clippy::too_many_lines)]
1704 fn from_str(s: &str) -> Result<Self, Self::Err> {
1705 match s {
1706 "gpt-4" => Ok(Self::Gpt4),
1707 "gpt-4-turbo" => Ok(Self::Gpt4Turbo),
1708 "gpt-4.1" => Ok(Self::Gpt41),
1709 "gpt-4.1-mini" => Ok(Self::Gpt41Mini),
1710 "gpt-4.1-nano" => Ok(Self::Gpt41Nano),
1711 "gpt-4o" => Ok(Self::Gpt4o),
1712 "gpt-4o-2024-05-13" => Ok(Self::Gpt4o20240513),
1713 "gpt-4o-2024-08-06" => Ok(Self::Gpt4o20240806),
1714 "gpt-4o-2024-11-20" => Ok(Self::Gpt4o20241120),
1715 "gpt-4o-mini" => Ok(Self::Gpt4oMini),
1716 "gpt-5" => Ok(Self::Gpt5),
1717 "gpt-5-codex" => Ok(Self::Gpt5Codex),
1718 "gpt-5-mini" => Ok(Self::Gpt5Mini),
1719 "gpt-5-nano" => Ok(Self::Gpt5Nano),
1720 "gpt-5-pro" => Ok(Self::Gpt5Pro),
1721 "gpt-5.1" => Ok(Self::Gpt51),
1722 "gpt-5.1-codex" => Ok(Self::Gpt51Codex),
1723 "gpt-5.1-codex-max" => Ok(Self::Gpt51CodexMax),
1724 "gpt-5.1-codex-mini" => Ok(Self::Gpt51CodexMini),
1725 "gpt-5.2" => Ok(Self::Gpt52),
1726 "gpt-5.2-codex" => Ok(Self::Gpt52Codex),
1727 "gpt-5.2-pro" => Ok(Self::Gpt52Pro),
1728 "gpt-5.3-codex" => Ok(Self::Gpt53Codex),
1729 "gpt-5.3-codex-spark" => Ok(Self::Gpt53CodexSpark),
1730 "gpt-5.4" => Ok(Self::Gpt54),
1731 "gpt-5.4-mini" => Ok(Self::Gpt54Mini),
1732 "gpt-5.4-nano" => Ok(Self::Gpt54Nano),
1733 "gpt-5.4-pro" => Ok(Self::Gpt54Pro),
1734 "gpt-5.5" => Ok(Self::Gpt55),
1735 "gpt-5.5-pro" => Ok(Self::Gpt55Pro),
1736 "o1" => Ok(Self::O1),
1737 "o1-pro" => Ok(Self::O1Pro),
1738 "o3" => Ok(Self::O3),
1739 "o3-deep-research" => Ok(Self::O3DeepResearch),
1740 "o3-mini" => Ok(Self::O3Mini),
1741 "o3-pro" => Ok(Self::O3Pro),
1742 "o4-mini" => Ok(Self::O4Mini),
1743 "o4-mini-deep-research" => Ok(Self::O4MiniDeepResearch),
1744 _ => Err(format!("Unknown openai model: '{s}'")),
1745 }
1746 }
1747}
1748impl OpenRouterModel {
1749 #[allow(clippy::too_many_lines)]
1750 fn model_id(self) -> &'static str {
1751 match self {
1752 Self::AnthropicClaude35Haiku => "anthropic/claude-3.5-haiku",
1753 Self::AnthropicClaude37Sonnet => "anthropic/claude-3.7-sonnet",
1754 Self::AnthropicClaudeHaiku45 => "anthropic/claude-haiku-4.5",
1755 Self::AnthropicClaudeOpus4 => "anthropic/claude-opus-4",
1756 Self::AnthropicClaudeOpus41 => "anthropic/claude-opus-4.1",
1757 Self::AnthropicClaudeOpus45 => "anthropic/claude-opus-4.5",
1758 Self::AnthropicClaudeOpus46 => "anthropic/claude-opus-4.6",
1759 Self::AnthropicClaudeOpus47 => "anthropic/claude-opus-4.7",
1760 Self::AnthropicClaudeSonnet4 => "anthropic/claude-sonnet-4",
1761 Self::AnthropicClaudeSonnet45 => "anthropic/claude-sonnet-4.5",
1762 Self::AnthropicClaudeSonnet46 => "anthropic/claude-sonnet-4.6",
1763 Self::ArceeAiTrinityLargePreviewFree => "arcee-ai/trinity-large-preview:free",
1764 Self::ArceeAiTrinityLargeThinking => "arcee-ai/trinity-large-thinking",
1765 Self::DeepseekDeepseekChatV31 => "deepseek/deepseek-chat-v3.1",
1766 Self::DeepseekDeepseekR1 => "deepseek/deepseek-r1",
1767 Self::DeepseekDeepseekV31Terminus => "deepseek/deepseek-v3.1-terminus",
1768 Self::DeepseekDeepseekV31TerminusExacto => {
1769 "deepseek/deepseek-v3.1-terminus:exacto"
1770 }
1771 Self::DeepseekDeepseekV32 => "deepseek/deepseek-v3.2",
1772 Self::DeepseekDeepseekV32Speciale => "deepseek/deepseek-v3.2-speciale",
1773 Self::DeepseekDeepseekV4Flash => "deepseek/deepseek-v4-flash",
1774 Self::DeepseekDeepseekV4Pro => "deepseek/deepseek-v4-pro",
1775 Self::GoogleGemini20Flash001 => "google/gemini-2.0-flash-001",
1776 Self::GoogleGemini25Flash => "google/gemini-2.5-flash",
1777 Self::GoogleGemini25FlashLite => "google/gemini-2.5-flash-lite",
1778 Self::GoogleGemini25FlashLitePreview092025 => {
1779 "google/gemini-2.5-flash-lite-preview-09-2025"
1780 }
1781 Self::GoogleGemini25FlashPreview092025 => {
1782 "google/gemini-2.5-flash-preview-09-2025"
1783 }
1784 Self::GoogleGemini25Pro => "google/gemini-2.5-pro",
1785 Self::GoogleGemini25ProPreview0506 => "google/gemini-2.5-pro-preview-05-06",
1786 Self::GoogleGemini25ProPreview0605 => "google/gemini-2.5-pro-preview-06-05",
1787 Self::GoogleGemini3FlashPreview => "google/gemini-3-flash-preview",
1788 Self::GoogleGemini3ProPreview => "google/gemini-3-pro-preview",
1789 Self::GoogleGemini31FlashLitePreview => {
1790 "google/gemini-3.1-flash-lite-preview"
1791 }
1792 Self::GoogleGemini31ProPreview => "google/gemini-3.1-pro-preview",
1793 Self::GoogleGemini31ProPreviewCustomtools => {
1794 "google/gemini-3.1-pro-preview-customtools"
1795 }
1796 Self::GoogleGemma327bIt => "google/gemma-3-27b-it",
1797 Self::GoogleGemma327bItFree => "google/gemma-3-27b-it:free",
1798 Self::GoogleGemma426bA4bIt => "google/gemma-4-26b-a4b-it",
1799 Self::GoogleGemma426bA4bItFree => "google/gemma-4-26b-a4b-it:free",
1800 Self::GoogleGemma431bIt => "google/gemma-4-31b-it",
1801 Self::GoogleGemma431bItFree => "google/gemma-4-31b-it:free",
1802 Self::InceptionMercury2 => "inception/mercury-2",
1803 Self::MetaLlamaLlama3370bInstructFree => {
1804 "meta-llama/llama-3.3-70b-instruct:free"
1805 }
1806 Self::MinimaxMinimax01 => "minimax/minimax-01",
1807 Self::MinimaxMinimaxM1 => "minimax/minimax-m1",
1808 Self::MinimaxMinimaxM2 => "minimax/minimax-m2",
1809 Self::MinimaxMinimaxM21 => "minimax/minimax-m2.1",
1810 Self::MinimaxMinimaxM25 => "minimax/minimax-m2.5",
1811 Self::MinimaxMinimaxM25Free => "minimax/minimax-m2.5:free",
1812 Self::MinimaxMinimaxM27 => "minimax/minimax-m2.7",
1813 Self::MistralaiCodestral2508 => "mistralai/codestral-2508",
1814 Self::MistralaiDevstral2512 => "mistralai/devstral-2512",
1815 Self::MistralaiDevstralMedium2507 => "mistralai/devstral-medium-2507",
1816 Self::MistralaiDevstralSmall2505 => "mistralai/devstral-small-2505",
1817 Self::MistralaiDevstralSmall2507 => "mistralai/devstral-small-2507",
1818 Self::MistralaiMistralMedium3 => "mistralai/mistral-medium-3",
1819 Self::MistralaiMistralMedium31 => "mistralai/mistral-medium-3.1",
1820 Self::MistralaiMistralSmall2603 => "mistralai/mistral-small-2603",
1821 Self::MistralaiMistralSmall3124bInstruct => {
1822 "mistralai/mistral-small-3.1-24b-instruct"
1823 }
1824 Self::MistralaiMistralSmall3224bInstruct => {
1825 "mistralai/mistral-small-3.2-24b-instruct"
1826 }
1827 Self::MoonshotaiKimiK2 => "moonshotai/kimi-k2",
1828 Self::MoonshotaiKimiK20905 => "moonshotai/kimi-k2-0905",
1829 Self::MoonshotaiKimiK20905Exacto => "moonshotai/kimi-k2-0905:exacto",
1830 Self::MoonshotaiKimiK2Thinking => "moonshotai/kimi-k2-thinking",
1831 Self::MoonshotaiKimiK25 => "moonshotai/kimi-k2.5",
1832 Self::MoonshotaiKimiK26 => "moonshotai/kimi-k2.6",
1833 Self::NousresearchHermes4405b => "nousresearch/hermes-4-405b",
1834 Self::NousresearchHermes470b => "nousresearch/hermes-4-70b",
1835 Self::NvidiaNemotron3Nano30bA3bFree => "nvidia/nemotron-3-nano-30b-a3b:free",
1836 Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree => {
1837 "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free"
1838 }
1839 Self::NvidiaNemotron3Super120bA12b => "nvidia/nemotron-3-super-120b-a12b",
1840 Self::NvidiaNemotron3Super120bA12bFree => {
1841 "nvidia/nemotron-3-super-120b-a12b:free"
1842 }
1843 Self::NvidiaNemotronNano12bV2VlFree => "nvidia/nemotron-nano-12b-v2-vl:free",
1844 Self::NvidiaNemotronNano9bV2 => "nvidia/nemotron-nano-9b-v2",
1845 Self::NvidiaNemotronNano9bV2Free => "nvidia/nemotron-nano-9b-v2:free",
1846 Self::OpenaiGpt41 => "openai/gpt-4.1",
1847 Self::OpenaiGpt41Mini => "openai/gpt-4.1-mini",
1848 Self::OpenaiGpt4oMini => "openai/gpt-4o-mini",
1849 Self::OpenaiGpt5 => "openai/gpt-5",
1850 Self::OpenaiGpt5Codex => "openai/gpt-5-codex",
1851 Self::OpenaiGpt5Image => "openai/gpt-5-image",
1852 Self::OpenaiGpt5Mini => "openai/gpt-5-mini",
1853 Self::OpenaiGpt5Nano => "openai/gpt-5-nano",
1854 Self::OpenaiGpt5Pro => "openai/gpt-5-pro",
1855 Self::OpenaiGpt51 => "openai/gpt-5.1",
1856 Self::OpenaiGpt51Chat => "openai/gpt-5.1-chat",
1857 Self::OpenaiGpt51Codex => "openai/gpt-5.1-codex",
1858 Self::OpenaiGpt51CodexMax => "openai/gpt-5.1-codex-max",
1859 Self::OpenaiGpt51CodexMini => "openai/gpt-5.1-codex-mini",
1860 Self::OpenaiGpt52 => "openai/gpt-5.2",
1861 Self::OpenaiGpt52Chat => "openai/gpt-5.2-chat",
1862 Self::OpenaiGpt52Codex => "openai/gpt-5.2-codex",
1863 Self::OpenaiGpt52Pro => "openai/gpt-5.2-pro",
1864 Self::OpenaiGpt53Codex => "openai/gpt-5.3-codex",
1865 Self::OpenaiGpt54 => "openai/gpt-5.4",
1866 Self::OpenaiGpt54Mini => "openai/gpt-5.4-mini",
1867 Self::OpenaiGpt54Nano => "openai/gpt-5.4-nano",
1868 Self::OpenaiGpt54Pro => "openai/gpt-5.4-pro",
1869 Self::OpenaiGpt55 => "openai/gpt-5.5",
1870 Self::OpenaiGpt55Pro => "openai/gpt-5.5-pro",
1871 Self::OpenaiGptOss120b => "openai/gpt-oss-120b",
1872 Self::OpenaiGptOss120bExacto => "openai/gpt-oss-120b:exacto",
1873 Self::OpenaiGptOss120bFree => "openai/gpt-oss-120b:free",
1874 Self::OpenaiGptOss20b => "openai/gpt-oss-20b",
1875 Self::OpenaiGptOss20bFree => "openai/gpt-oss-20b:free",
1876 Self::OpenaiGptOssSafeguard20b => "openai/gpt-oss-safeguard-20b",
1877 Self::OpenaiO4Mini => "openai/o4-mini",
1878 Self::OpenrouterElephantAlpha => "openrouter/elephant-alpha",
1879 Self::OpenrouterFree => "openrouter/free",
1880 Self::OpenrouterOwlAlpha => "openrouter/owl-alpha",
1881 Self::OpenrouterParetoCode => "openrouter/pareto-code",
1882 Self::PoolsideLagunaM1Free => "poolside/laguna-m.1:free",
1883 Self::PoolsideLagunaXs2Free => "poolside/laguna-xs.2:free",
1884 Self::PrimeIntellectIntellect3 => "prime-intellect/intellect-3",
1885 Self::QwenQwen3627b => "qwen/qwen-3.6-27b",
1886 Self::QwenQwenPlus => "qwen/qwen-plus",
1887 Self::QwenQwen3235bA22b0725 => "qwen/qwen3-235b-a22b-07-25",
1888 Self::QwenQwen3235bA22bThinking2507 => "qwen/qwen3-235b-a22b-thinking-2507",
1889 Self::QwenQwen330bA3bInstruct2507 => "qwen/qwen3-30b-a3b-instruct-2507",
1890 Self::QwenQwen330bA3bThinking2507 => "qwen/qwen3-30b-a3b-thinking-2507",
1891 Self::QwenQwen3Coder => "qwen/qwen3-coder",
1892 Self::QwenQwen3Coder30bA3bInstruct => "qwen/qwen3-coder-30b-a3b-instruct",
1893 Self::QwenQwen3CoderFlash => "qwen/qwen3-coder-flash",
1894 Self::QwenQwen3CoderPlus => "qwen/qwen3-coder-plus",
1895 Self::QwenQwen3CoderExacto => "qwen/qwen3-coder:exacto",
1896 Self::QwenQwen3Max => "qwen/qwen3-max",
1897 Self::QwenQwen3Next80bA3bInstruct => "qwen/qwen3-next-80b-a3b-instruct",
1898 Self::QwenQwen3Next80bA3bThinking => "qwen/qwen3-next-80b-a3b-thinking",
1899 Self::QwenQwen35397bA17b => "qwen/qwen3.5-397b-a17b",
1900 Self::QwenQwen35Flash0223 => "qwen/qwen3.5-flash-02-23",
1901 Self::QwenQwen35Plus0215 => "qwen/qwen3.5-plus-02-15",
1902 Self::QwenQwen36Plus => "qwen/qwen3.6-plus",
1903 Self::StepfunStep35Flash => "stepfun/step-3.5-flash",
1904 Self::TencentHy3Preview => "tencent/hy3-preview",
1905 Self::XAiGrok3 => "x-ai/grok-3",
1906 Self::XAiGrok3Beta => "x-ai/grok-3-beta",
1907 Self::XAiGrok3Mini => "x-ai/grok-3-mini",
1908 Self::XAiGrok3MiniBeta => "x-ai/grok-3-mini-beta",
1909 Self::XAiGrok4 => "x-ai/grok-4",
1910 Self::XAiGrok4Fast => "x-ai/grok-4-fast",
1911 Self::XAiGrok41Fast => "x-ai/grok-4.1-fast",
1912 Self::XAiGrok420Beta => "x-ai/grok-4.20-beta",
1913 Self::XAiGrok43 => "x-ai/grok-4.3",
1914 Self::XAiGrokCodeFast1 => "x-ai/grok-code-fast-1",
1915 Self::XiaomiMimoV2Flash => "xiaomi/mimo-v2-flash",
1916 Self::XiaomiMimoV2Omni => "xiaomi/mimo-v2-omni",
1917 Self::XiaomiMimoV2Pro => "xiaomi/mimo-v2-pro",
1918 Self::XiaomiMimoV25 => "xiaomi/mimo-v2.5",
1919 Self::XiaomiMimoV25Pro => "xiaomi/mimo-v2.5-pro",
1920 Self::ZAiGlm45 => "z-ai/glm-4.5",
1921 Self::ZAiGlm45Air => "z-ai/glm-4.5-air",
1922 Self::ZAiGlm45v => "z-ai/glm-4.5v",
1923 Self::ZAiGlm46 => "z-ai/glm-4.6",
1924 Self::ZAiGlm46Exacto => "z-ai/glm-4.6:exacto",
1925 Self::ZAiGlm47 => "z-ai/glm-4.7",
1926 Self::ZAiGlm47Flash => "z-ai/glm-4.7-flash",
1927 Self::ZAiGlm5 => "z-ai/glm-5",
1928 Self::ZAiGlm5Turbo => "z-ai/glm-5-turbo",
1929 Self::ZAiGlm51 => "z-ai/glm-5.1",
1930 }
1931 }
1932 #[allow(clippy::too_many_lines)]
1933 fn display_name(self) -> &'static str {
1934 match self {
1935 Self::AnthropicClaude35Haiku => "Claude Haiku 3.5",
1936 Self::AnthropicClaudeHaiku45 => "Claude Haiku 4.5",
1937 Self::AnthropicClaudeOpus4 => "Claude Opus 4",
1938 Self::AnthropicClaudeOpus41 => "Claude Opus 4.1",
1939 Self::AnthropicClaudeOpus45 => "Claude Opus 4.5",
1940 Self::AnthropicClaudeOpus46 => "Claude Opus 4.6",
1941 Self::AnthropicClaudeOpus47 => "Claude Opus 4.7",
1942 Self::AnthropicClaude37Sonnet => "Claude Sonnet 3.7",
1943 Self::AnthropicClaudeSonnet4 => "Claude Sonnet 4",
1944 Self::AnthropicClaudeSonnet45 => "Claude Sonnet 4.5",
1945 Self::AnthropicClaudeSonnet46 => "Claude Sonnet 4.6",
1946 Self::MistralaiCodestral2508 => "Codestral 2508",
1947 Self::DeepseekDeepseekV31Terminus => "DeepSeek V3.1 Terminus",
1948 Self::DeepseekDeepseekV31TerminusExacto => "DeepSeek V3.1 Terminus (exacto)",
1949 Self::DeepseekDeepseekV32 => "DeepSeek V3.2",
1950 Self::DeepseekDeepseekV32Speciale => "DeepSeek V3.2 Speciale",
1951 Self::DeepseekDeepseekV4Flash => "DeepSeek V4 Flash",
1952 Self::DeepseekDeepseekV4Pro => "DeepSeek V4 Pro",
1953 Self::DeepseekDeepseekChatV31 => "DeepSeek-V3.1",
1954 Self::DeepseekDeepseekR1 => "DeepSeek: R1",
1955 Self::MistralaiDevstral2512 => "Devstral 2 2512",
1956 Self::MistralaiDevstralMedium2507 => "Devstral Medium",
1957 Self::MistralaiDevstralSmall2505 => "Devstral Small",
1958 Self::MistralaiDevstralSmall2507 => "Devstral Small 1.1",
1959 Self::OpenrouterElephantAlpha => "Elephant (free)",
1960 Self::OpenrouterFree => "Free Models Router",
1961 Self::ZAiGlm45 => "GLM 4.5",
1962 Self::ZAiGlm45Air => "GLM 4.5 Air",
1963 Self::ZAiGlm45v => "GLM 4.5V",
1964 Self::ZAiGlm46 => "GLM 4.6",
1965 Self::ZAiGlm46Exacto => "GLM 4.6 (exacto)",
1966 Self::ZAiGlm47 => "GLM-4.7",
1967 Self::ZAiGlm47Flash => "GLM-4.7-Flash",
1968 Self::ZAiGlm5 => "GLM-5",
1969 Self::ZAiGlm5Turbo => "GLM-5-Turbo",
1970 Self::ZAiGlm51 => "GLM-5.1",
1971 Self::OpenaiGptOss120b => "GPT OSS 120B",
1972 Self::OpenaiGptOss120bExacto => "GPT OSS 120B (exacto)",
1973 Self::OpenaiGptOss20b => "GPT OSS 20B",
1974 Self::OpenaiGptOssSafeguard20b => "GPT OSS Safeguard 20B",
1975 Self::OpenaiGpt41 => "GPT-4.1",
1976 Self::OpenaiGpt41Mini => "GPT-4.1 Mini",
1977 Self::OpenaiGpt4oMini => "GPT-4o-mini",
1978 Self::OpenaiGpt5 => "GPT-5",
1979 Self::OpenaiGpt5Codex => "GPT-5 Codex",
1980 Self::OpenaiGpt5Image => "GPT-5 Image",
1981 Self::OpenaiGpt5Mini => "GPT-5 Mini",
1982 Self::OpenaiGpt5Nano => "GPT-5 Nano",
1983 Self::OpenaiGpt5Pro => "GPT-5 Pro",
1984 Self::OpenaiGpt51 => "GPT-5.1",
1985 Self::OpenaiGpt51Chat => "GPT-5.1 Chat",
1986 Self::OpenaiGpt51Codex => "GPT-5.1-Codex",
1987 Self::OpenaiGpt51CodexMax => "GPT-5.1-Codex-Max",
1988 Self::OpenaiGpt51CodexMini => "GPT-5.1-Codex-Mini",
1989 Self::OpenaiGpt52 => "GPT-5.2",
1990 Self::OpenaiGpt52Chat => "GPT-5.2 Chat",
1991 Self::OpenaiGpt52Pro => "GPT-5.2 Pro",
1992 Self::OpenaiGpt52Codex => "GPT-5.2-Codex",
1993 Self::OpenaiGpt53Codex => "GPT-5.3-Codex",
1994 Self::OpenaiGpt54 => "GPT-5.4",
1995 Self::OpenaiGpt54Mini => "GPT-5.4 Mini",
1996 Self::OpenaiGpt54Nano => "GPT-5.4 Nano",
1997 Self::OpenaiGpt54Pro => "GPT-5.4 Pro",
1998 Self::OpenaiGpt55 => "GPT-5.5",
1999 Self::OpenaiGpt55Pro => "GPT-5.5 Pro",
2000 Self::GoogleGemini20Flash001 => "Gemini 2.0 Flash",
2001 Self::GoogleGemini25Flash => "Gemini 2.5 Flash",
2002 Self::GoogleGemini25FlashLite => "Gemini 2.5 Flash Lite",
2003 Self::GoogleGemini25FlashLitePreview092025 => {
2004 "Gemini 2.5 Flash Lite Preview 09-25"
2005 }
2006 Self::GoogleGemini25FlashPreview092025 => "Gemini 2.5 Flash Preview 09-25",
2007 Self::GoogleGemini25Pro => "Gemini 2.5 Pro",
2008 Self::GoogleGemini25ProPreview0506 => "Gemini 2.5 Pro Preview 05-06",
2009 Self::GoogleGemini25ProPreview0605 => "Gemini 2.5 Pro Preview 06-05",
2010 Self::GoogleGemini3FlashPreview => "Gemini 3 Flash Preview",
2011 Self::GoogleGemini3ProPreview => "Gemini 3 Pro Preview",
2012 Self::GoogleGemini31FlashLitePreview => "Gemini 3.1 Flash Lite Preview",
2013 Self::GoogleGemini31ProPreview => "Gemini 3.1 Pro Preview",
2014 Self::GoogleGemini31ProPreviewCustomtools => {
2015 "Gemini 3.1 Pro Preview Custom Tools"
2016 }
2017 Self::GoogleGemma327bIt => "Gemma 3 27B",
2018 Self::GoogleGemma327bItFree => "Gemma 3 27B (free)",
2019 Self::GoogleGemma426bA4bIt => "Gemma 4 26B A4B",
2020 Self::GoogleGemma426bA4bItFree => "Gemma 4 26B A4B (free)",
2021 Self::GoogleGemma431bIt => "Gemma 4 31B",
2022 Self::GoogleGemma431bItFree => "Gemma 4 31B (free)",
2023 Self::XAiGrok3 => "Grok 3",
2024 Self::XAiGrok3Beta => "Grok 3 Beta",
2025 Self::XAiGrok3Mini => "Grok 3 Mini",
2026 Self::XAiGrok3MiniBeta => "Grok 3 Mini Beta",
2027 Self::XAiGrok4 => "Grok 4",
2028 Self::XAiGrok4Fast => "Grok 4 Fast",
2029 Self::XAiGrok41Fast => "Grok 4.1 Fast",
2030 Self::XAiGrok420Beta => "Grok 4.20 Beta",
2031 Self::XAiGrok43 => "Grok 4.3",
2032 Self::XAiGrokCodeFast1 => "Grok Code Fast 1",
2033 Self::NousresearchHermes4405b => "Hermes 4 405B",
2034 Self::NousresearchHermes470b => "Hermes 4 70B",
2035 Self::TencentHy3Preview => "Hy3 preview",
2036 Self::PrimeIntellectIntellect3 => "Intellect 3",
2037 Self::MoonshotaiKimiK2 => "Kimi K2",
2038 Self::MoonshotaiKimiK20905 => "Kimi K2 Instruct 0905",
2039 Self::MoonshotaiKimiK20905Exacto => "Kimi K2 Instruct 0905 (exacto)",
2040 Self::MoonshotaiKimiK2Thinking => "Kimi K2 Thinking",
2041 Self::MoonshotaiKimiK25 => "Kimi K2.5",
2042 Self::MoonshotaiKimiK26 => "Kimi K2.6",
2043 Self::PoolsideLagunaM1Free => "Laguna M.1",
2044 Self::PoolsideLagunaXs2Free => "Laguna XS.2",
2045 Self::MetaLlamaLlama3370bInstructFree => "Llama 3.3 70B Instruct (free)",
2046 Self::InceptionMercury2 => "Mercury 2",
2047 Self::MinimaxMinimaxM1 => "MiniMax M1",
2048 Self::MinimaxMinimaxM2 => "MiniMax M2",
2049 Self::MinimaxMinimaxM21 => "MiniMax M2.1",
2050 Self::MinimaxMinimaxM25 => "MiniMax M2.5",
2051 Self::MinimaxMinimaxM25Free => "MiniMax M2.5 (free)",
2052 Self::MinimaxMinimaxM27 => "MiniMax M2.7",
2053 Self::MinimaxMinimax01 => "MiniMax-01",
2054 Self::MistralaiMistralMedium3 => "Mistral Medium 3",
2055 Self::MistralaiMistralMedium31 => "Mistral Medium 3.1",
2056 Self::MistralaiMistralSmall3124bInstruct => "Mistral Small 3.1 24B Instruct",
2057 Self::MistralaiMistralSmall3224bInstruct => "Mistral Small 3.2 24B Instruct",
2058 Self::MistralaiMistralSmall2603 => "Mistral Small 4",
2059 Self::NvidiaNemotron3Nano30bA3bFree => "Nemotron 3 Nano 30B A3B (free)",
2060 Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree => {
2061 "Nemotron 3 Nano Omni (free)"
2062 }
2063 Self::NvidiaNemotron3Super120bA12b => "Nemotron 3 Super",
2064 Self::NvidiaNemotron3Super120bA12bFree => "Nemotron 3 Super (free)",
2065 Self::NvidiaNemotronNano12bV2VlFree => "Nemotron Nano 12B 2 VL (free)",
2066 Self::NvidiaNemotronNano9bV2Free => "Nemotron Nano 9B V2 (free)",
2067 Self::OpenrouterOwlAlpha => "Owl Alpha",
2068 Self::OpenrouterParetoCode => "Pareto Code Router",
2069 Self::QwenQwen3235bA22b0725 => "Qwen3 235B A22B Instruct 2507",
2070 Self::QwenQwen3235bA22bThinking2507 => "Qwen3 235B A22B Thinking 2507",
2071 Self::QwenQwen330bA3bInstruct2507 => "Qwen3 30B A3B Instruct 2507",
2072 Self::QwenQwen330bA3bThinking2507 => "Qwen3 30B A3B Thinking 2507",
2073 Self::QwenQwen3Coder => "Qwen3 Coder",
2074 Self::QwenQwen3CoderExacto => "Qwen3 Coder (exacto)",
2075 Self::QwenQwen3Coder30bA3bInstruct => "Qwen3 Coder 30B A3B Instruct",
2076 Self::QwenQwen3CoderFlash => "Qwen3 Coder Flash",
2077 Self::QwenQwen3CoderPlus => "Qwen3 Coder Plus",
2078 Self::QwenQwen3Max => "Qwen3 Max",
2079 Self::QwenQwen3Next80bA3bInstruct => "Qwen3 Next 80B A3B Instruct",
2080 Self::QwenQwen3Next80bA3bThinking => "Qwen3 Next 80B A3B Thinking",
2081 Self::QwenQwen35397bA17b => "Qwen3.5 397B A17B",
2082 Self::QwenQwen35Plus0215 => "Qwen3.5 Plus 2026-02-15",
2083 Self::QwenQwen3627b => "Qwen3.6 27B",
2084 Self::QwenQwen36Plus => "Qwen3.6 Plus",
2085 Self::QwenQwenPlus => "Qwen: Qwen-Plus",
2086 Self::QwenQwen35Flash0223 => "Qwen: Qwen3.5-Flash",
2087 Self::StepfunStep35Flash => "Step 3.5 Flash",
2088 Self::ArceeAiTrinityLargePreviewFree => "Trinity Large Preview",
2089 Self::ArceeAiTrinityLargeThinking => "Trinity Large Thinking",
2090 Self::XiaomiMimoV2Flash => "Xiaomi: MiMo-V2-Flash",
2091 Self::XiaomiMimoV2Omni => "Xiaomi: MiMo-V2-Omni",
2092 Self::XiaomiMimoV2Pro => "Xiaomi: MiMo-V2-Pro",
2093 Self::XiaomiMimoV25 => "Xiaomi: MiMo-V2.5",
2094 Self::XiaomiMimoV25Pro => "Xiaomi: MiMo-V2.5-Pro",
2095 Self::OpenaiGptOss120bFree => "gpt-oss-120b (free)",
2096 Self::OpenaiGptOss20bFree => "gpt-oss-20b (free)",
2097 Self::NvidiaNemotronNano9bV2 => "nvidia-nemotron-nano-9b-v2",
2098 Self::OpenaiO4Mini => "o4 Mini",
2099 }
2100 }
2101 #[allow(clippy::too_many_lines)]
2102 fn context_window(self) -> u32 {
2103 match self {
2104 Self::DeepseekDeepseekR1 | Self::ZAiGlm45v => 64_000,
2105 Self::GoogleGemma327bIt | Self::MistralaiMistralSmall3224bInstruct => 96_000,
2106 Self::InceptionMercury2
2107 | Self::MistralaiDevstralSmall2505
2108 | Self::MistralaiMistralSmall3124bInstruct
2109 | Self::NvidiaNemotronNano12bV2VlFree
2110 | Self::NvidiaNemotronNano9bV2Free
2111 | Self::OpenaiGpt4oMini
2112 | Self::OpenaiGpt51Chat
2113 | Self::OpenaiGpt52Chat
2114 | Self::QwenQwen3CoderFlash
2115 | Self::ZAiGlm45
2116 | Self::ZAiGlm45Air => 128_000,
2117 Self::ArceeAiTrinityLargePreviewFree
2118 | Self::DeepseekDeepseekV31Terminus
2119 | Self::DeepseekDeepseekV31TerminusExacto
2120 | Self::GoogleGemma327bItFree
2121 | Self::MetaLlamaLlama3370bInstructFree
2122 | Self::MistralaiDevstralMedium2507
2123 | Self::MistralaiDevstralSmall2507
2124 | Self::MistralaiMistralMedium3
2125 | Self::MoonshotaiKimiK2
2126 | Self::NousresearchHermes4405b
2127 | Self::NousresearchHermes470b
2128 | Self::NvidiaNemotronNano9bV2
2129 | Self::OpenaiGptOss120b
2130 | Self::OpenaiGptOss120bExacto
2131 | Self::OpenaiGptOss120bFree
2132 | Self::OpenaiGptOss20b
2133 | Self::OpenaiGptOss20bFree
2134 | Self::OpenaiGptOssSafeguard20b
2135 | Self::PoolsideLagunaM1Free
2136 | Self::PoolsideLagunaXs2Free
2137 | Self::PrimeIntellectIntellect3
2138 | Self::QwenQwen3CoderExacto
2139 | Self::XAiGrok3
2140 | Self::XAiGrok3Beta
2141 | Self::XAiGrok3Mini
2142 | Self::XAiGrok3MiniBeta => 131_072,
2143 Self::QwenQwen3Coder30bA3bInstruct => 160_000,
2144 Self::DeepseekDeepseekChatV31
2145 | Self::DeepseekDeepseekV32
2146 | Self::DeepseekDeepseekV32Speciale => 163_840,
2147 Self::MinimaxMinimaxM2 => 196_600,
2148 Self::AnthropicClaude35Haiku
2149 | Self::AnthropicClaude37Sonnet
2150 | Self::AnthropicClaudeHaiku45
2151 | Self::AnthropicClaudeOpus4
2152 | Self::AnthropicClaudeOpus41
2153 | Self::AnthropicClaudeOpus45
2154 | Self::AnthropicClaudeSonnet4
2155 | Self::OpenaiO4Mini
2156 | Self::OpenrouterFree
2157 | Self::OpenrouterParetoCode
2158 | Self::ZAiGlm46
2159 | Self::ZAiGlm46Exacto
2160 | Self::ZAiGlm47Flash => 200_000,
2161 Self::ZAiGlm5 | Self::ZAiGlm5Turbo | Self::ZAiGlm51 => 202_752,
2162 Self::MinimaxMinimaxM21
2163 | Self::MinimaxMinimaxM25
2164 | Self::MinimaxMinimaxM25Free
2165 | Self::MinimaxMinimaxM27
2166 | Self::ZAiGlm47 => 204_800,
2167 Self::MistralaiCodestral2508
2168 | Self::NvidiaNemotron3Nano30bA3bFree
2169 | Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree
2170 | Self::StepfunStep35Flash
2171 | Self::TencentHy3Preview
2172 | Self::XAiGrok4
2173 | Self::XAiGrokCodeFast1 => 256_000,
2174 Self::QwenQwen330bA3bInstruct2507 | Self::QwenQwen330bA3bThinking2507 => {
2175 262_000
2176 }
2177 Self::ArceeAiTrinityLargeThinking
2178 | Self::GoogleGemma426bA4bIt
2179 | Self::GoogleGemma426bA4bItFree
2180 | Self::GoogleGemma431bIt
2181 | Self::GoogleGemma431bItFree
2182 | Self::MistralaiDevstral2512
2183 | Self::MistralaiMistralMedium31
2184 | Self::MistralaiMistralSmall2603
2185 | Self::MoonshotaiKimiK20905
2186 | Self::MoonshotaiKimiK20905Exacto
2187 | Self::MoonshotaiKimiK2Thinking
2188 | Self::MoonshotaiKimiK25
2189 | Self::MoonshotaiKimiK26
2190 | Self::NvidiaNemotron3Super120bA12b
2191 | Self::NvidiaNemotron3Super120bA12bFree
2192 | Self::OpenrouterElephantAlpha
2193 | Self::QwenQwen3627b
2194 | Self::QwenQwen3235bA22b0725
2195 | Self::QwenQwen3235bA22bThinking2507
2196 | Self::QwenQwen3Coder
2197 | Self::QwenQwen3Max
2198 | Self::QwenQwen3Next80bA3bInstruct
2199 | Self::QwenQwen3Next80bA3bThinking
2200 | Self::QwenQwen35397bA17b
2201 | Self::XiaomiMimoV2Flash
2202 | Self::XiaomiMimoV2Omni => 262_144,
2203 Self::OpenaiGpt5
2204 | Self::OpenaiGpt5Codex
2205 | Self::OpenaiGpt5Image
2206 | Self::OpenaiGpt5Mini
2207 | Self::OpenaiGpt5Nano
2208 | Self::OpenaiGpt5Pro
2209 | Self::OpenaiGpt51
2210 | Self::OpenaiGpt51Codex
2211 | Self::OpenaiGpt51CodexMax
2212 | Self::OpenaiGpt51CodexMini
2213 | Self::OpenaiGpt52
2214 | Self::OpenaiGpt52Codex
2215 | Self::OpenaiGpt52Pro
2216 | Self::OpenaiGpt53Codex
2217 | Self::OpenaiGpt54Mini
2218 | Self::OpenaiGpt54Nano => 400_000,
2219 Self::AnthropicClaudeOpus46
2220 | Self::AnthropicClaudeOpus47
2221 | Self::AnthropicClaudeSonnet45
2222 | Self::AnthropicClaudeSonnet46
2223 | Self::MinimaxMinimax01
2224 | Self::MinimaxMinimaxM1
2225 | Self::QwenQwenPlus
2226 | Self::QwenQwen3CoderPlus
2227 | Self::QwenQwen35Flash0223
2228 | Self::QwenQwen35Plus0215
2229 | Self::QwenQwen36Plus
2230 | Self::XAiGrok43 => 1_000_000,
2231 Self::OpenaiGpt41 | Self::OpenaiGpt41Mini => 1_047_576,
2232 Self::DeepseekDeepseekV4Flash
2233 | Self::DeepseekDeepseekV4Pro
2234 | Self::GoogleGemini20Flash001
2235 | Self::GoogleGemini25Flash
2236 | Self::GoogleGemini25FlashLite
2237 | Self::GoogleGemini25FlashLitePreview092025
2238 | Self::GoogleGemini25FlashPreview092025
2239 | Self::GoogleGemini25Pro
2240 | Self::GoogleGemini25ProPreview0506
2241 | Self::GoogleGemini25ProPreview0605
2242 | Self::GoogleGemini3FlashPreview
2243 | Self::GoogleGemini31FlashLitePreview
2244 | Self::GoogleGemini31ProPreview
2245 | Self::GoogleGemini31ProPreviewCustomtools
2246 | Self::XiaomiMimoV2Pro
2247 | Self::XiaomiMimoV25
2248 | Self::XiaomiMimoV25Pro => 1_048_576,
2249 Self::OpenrouterOwlAlpha => 1_048_756,
2250 Self::GoogleGemini3ProPreview
2251 | Self::OpenaiGpt54
2252 | Self::OpenaiGpt54Pro
2253 | Self::OpenaiGpt55
2254 | Self::OpenaiGpt55Pro => 1_050_000,
2255 Self::XAiGrok4Fast | Self::XAiGrok41Fast | Self::XAiGrok420Beta => 2_000_000,
2256 }
2257 }
2258 #[allow(clippy::too_many_lines)]
2259 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
2260 match self {
2261 Self::AnthropicClaude35Haiku
2262 | Self::ArceeAiTrinityLargePreviewFree
2263 | Self::GoogleGemini20Flash001
2264 | Self::GoogleGemma327bIt
2265 | Self::GoogleGemma327bItFree
2266 | Self::MetaLlamaLlama3370bInstructFree
2267 | Self::MistralaiCodestral2508
2268 | Self::MistralaiDevstral2512
2269 | Self::MistralaiDevstralMedium2507
2270 | Self::MistralaiDevstralSmall2505
2271 | Self::MistralaiDevstralSmall2507
2272 | Self::MistralaiMistralMedium3
2273 | Self::MistralaiMistralMedium31
2274 | Self::MistralaiMistralSmall3124bInstruct
2275 | Self::MistralaiMistralSmall3224bInstruct
2276 | Self::MoonshotaiKimiK2
2277 | Self::MoonshotaiKimiK20905
2278 | Self::MoonshotaiKimiK20905Exacto
2279 | Self::OpenaiGpt41
2280 | Self::OpenaiGpt41Mini
2281 | Self::OpenaiGpt4oMini
2282 | Self::OpenaiGpt54Nano
2283 | Self::QwenQwen3627b
2284 | Self::QwenQwenPlus
2285 | Self::QwenQwen3235bA22b0725
2286 | Self::QwenQwen330bA3bInstruct2507
2287 | Self::QwenQwen3Coder
2288 | Self::QwenQwen3Coder30bA3bInstruct
2289 | Self::QwenQwen3CoderFlash
2290 | Self::QwenQwen3CoderPlus
2291 | Self::QwenQwen3CoderExacto
2292 | Self::QwenQwen3Next80bA3bInstruct
2293 | Self::XAiGrok3
2294 | Self::XAiGrok3Beta => &[],
2295 Self::AnthropicClaude37Sonnet
2296 | Self::AnthropicClaudeHaiku45
2297 | Self::AnthropicClaudeOpus4
2298 | Self::AnthropicClaudeOpus41
2299 | Self::AnthropicClaudeOpus45
2300 | Self::AnthropicClaudeOpus46
2301 | Self::AnthropicClaudeOpus47
2302 | Self::AnthropicClaudeSonnet4
2303 | Self::AnthropicClaudeSonnet45
2304 | Self::AnthropicClaudeSonnet46
2305 | Self::ArceeAiTrinityLargeThinking
2306 | Self::DeepseekDeepseekChatV31
2307 | Self::DeepseekDeepseekR1
2308 | Self::DeepseekDeepseekV31Terminus
2309 | Self::DeepseekDeepseekV31TerminusExacto
2310 | Self::DeepseekDeepseekV32
2311 | Self::DeepseekDeepseekV32Speciale
2312 | Self::DeepseekDeepseekV4Flash
2313 | Self::DeepseekDeepseekV4Pro
2314 | Self::GoogleGemini25Flash
2315 | Self::GoogleGemini25FlashLite
2316 | Self::GoogleGemini25FlashLitePreview092025
2317 | Self::GoogleGemini25FlashPreview092025
2318 | Self::GoogleGemini25Pro
2319 | Self::GoogleGemini25ProPreview0506
2320 | Self::GoogleGemini25ProPreview0605
2321 | Self::GoogleGemini3FlashPreview
2322 | Self::GoogleGemini3ProPreview
2323 | Self::GoogleGemini31FlashLitePreview
2324 | Self::GoogleGemini31ProPreview
2325 | Self::GoogleGemini31ProPreviewCustomtools
2326 | Self::GoogleGemma426bA4bIt
2327 | Self::GoogleGemma426bA4bItFree
2328 | Self::GoogleGemma431bIt
2329 | Self::GoogleGemma431bItFree
2330 | Self::InceptionMercury2
2331 | Self::MinimaxMinimax01
2332 | Self::MinimaxMinimaxM1
2333 | Self::MinimaxMinimaxM2
2334 | Self::MinimaxMinimaxM21
2335 | Self::MinimaxMinimaxM25
2336 | Self::MinimaxMinimaxM25Free
2337 | Self::MinimaxMinimaxM27
2338 | Self::MistralaiMistralSmall2603
2339 | Self::MoonshotaiKimiK2Thinking
2340 | Self::MoonshotaiKimiK25
2341 | Self::MoonshotaiKimiK26
2342 | Self::NousresearchHermes4405b
2343 | Self::NousresearchHermes470b
2344 | Self::NvidiaNemotron3Nano30bA3bFree
2345 | Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree
2346 | Self::NvidiaNemotron3Super120bA12b
2347 | Self::NvidiaNemotron3Super120bA12bFree
2348 | Self::NvidiaNemotronNano12bV2VlFree
2349 | Self::NvidiaNemotronNano9bV2
2350 | Self::NvidiaNemotronNano9bV2Free
2351 | Self::OpenaiGpt5
2352 | Self::OpenaiGpt5Codex
2353 | Self::OpenaiGpt5Image
2354 | Self::OpenaiGpt5Mini
2355 | Self::OpenaiGpt5Nano
2356 | Self::OpenaiGpt5Pro
2357 | Self::OpenaiGpt51
2358 | Self::OpenaiGpt51Chat
2359 | Self::OpenaiGpt51Codex
2360 | Self::OpenaiGpt51CodexMax
2361 | Self::OpenaiGpt51CodexMini
2362 | Self::OpenaiGpt52
2363 | Self::OpenaiGpt52Chat
2364 | Self::OpenaiGpt52Codex
2365 | Self::OpenaiGpt52Pro
2366 | Self::OpenaiGpt53Codex
2367 | Self::OpenaiGpt54
2368 | Self::OpenaiGpt54Mini
2369 | Self::OpenaiGpt54Pro
2370 | Self::OpenaiGpt55
2371 | Self::OpenaiGpt55Pro
2372 | Self::OpenaiGptOss120b
2373 | Self::OpenaiGptOss120bExacto
2374 | Self::OpenaiGptOss120bFree
2375 | Self::OpenaiGptOss20b
2376 | Self::OpenaiGptOss20bFree
2377 | Self::OpenaiGptOssSafeguard20b
2378 | Self::OpenaiO4Mini
2379 | Self::OpenrouterElephantAlpha
2380 | Self::OpenrouterFree
2381 | Self::OpenrouterOwlAlpha
2382 | Self::OpenrouterParetoCode
2383 | Self::PoolsideLagunaM1Free
2384 | Self::PoolsideLagunaXs2Free
2385 | Self::PrimeIntellectIntellect3
2386 | Self::QwenQwen3235bA22bThinking2507
2387 | Self::QwenQwen330bA3bThinking2507
2388 | Self::QwenQwen3Max
2389 | Self::QwenQwen3Next80bA3bThinking
2390 | Self::QwenQwen35397bA17b
2391 | Self::QwenQwen35Flash0223
2392 | Self::QwenQwen35Plus0215
2393 | Self::QwenQwen36Plus
2394 | Self::StepfunStep35Flash
2395 | Self::TencentHy3Preview
2396 | Self::XAiGrok3Mini
2397 | Self::XAiGrok3MiniBeta
2398 | Self::XAiGrok4
2399 | Self::XAiGrok4Fast
2400 | Self::XAiGrok41Fast
2401 | Self::XAiGrok420Beta
2402 | Self::XAiGrok43
2403 | Self::XAiGrokCodeFast1
2404 | Self::XiaomiMimoV2Flash
2405 | Self::XiaomiMimoV2Omni
2406 | Self::XiaomiMimoV2Pro
2407 | Self::XiaomiMimoV25
2408 | Self::XiaomiMimoV25Pro
2409 | Self::ZAiGlm45
2410 | Self::ZAiGlm45Air
2411 | Self::ZAiGlm45v
2412 | Self::ZAiGlm46
2413 | Self::ZAiGlm46Exacto
2414 | Self::ZAiGlm47
2415 | Self::ZAiGlm47Flash
2416 | Self::ZAiGlm5
2417 | Self::ZAiGlm5Turbo
2418 | Self::ZAiGlm51 => {
2419 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
2420 }
2421 }
2422 }
2423 pub fn supports_reasoning(self) -> bool {
2424 !self.reasoning_levels().is_empty()
2425 }
2426 #[allow(clippy::too_many_lines)]
2427 pub fn supports_prompt_caching(self) -> bool {
2428 match self {
2429 Self::ArceeAiTrinityLargePreviewFree
2430 | Self::ArceeAiTrinityLargeThinking
2431 | Self::DeepseekDeepseekChatV31
2432 | Self::DeepseekDeepseekR1
2433 | Self::DeepseekDeepseekV31Terminus
2434 | Self::DeepseekDeepseekV31TerminusExacto
2435 | Self::DeepseekDeepseekV32
2436 | Self::DeepseekDeepseekV32Speciale
2437 | Self::GoogleGemini3ProPreview
2438 | Self::GoogleGemini31ProPreview
2439 | Self::GoogleGemini31ProPreviewCustomtools
2440 | Self::GoogleGemma327bIt
2441 | Self::GoogleGemma327bItFree
2442 | Self::GoogleGemma426bA4bIt
2443 | Self::GoogleGemma426bA4bItFree
2444 | Self::GoogleGemma431bIt
2445 | Self::GoogleGemma431bItFree
2446 | Self::MetaLlamaLlama3370bInstructFree
2447 | Self::MinimaxMinimax01
2448 | Self::MinimaxMinimaxM1
2449 | Self::MinimaxMinimaxM21
2450 | Self::MinimaxMinimaxM25Free
2451 | Self::MistralaiCodestral2508
2452 | Self::MistralaiDevstral2512
2453 | Self::MistralaiDevstralMedium2507
2454 | Self::MistralaiDevstralSmall2505
2455 | Self::MistralaiDevstralSmall2507
2456 | Self::MistralaiMistralMedium3
2457 | Self::MistralaiMistralMedium31
2458 | Self::MistralaiMistralSmall2603
2459 | Self::MistralaiMistralSmall3124bInstruct
2460 | Self::MistralaiMistralSmall3224bInstruct
2461 | Self::MoonshotaiKimiK2
2462 | Self::MoonshotaiKimiK20905
2463 | Self::MoonshotaiKimiK20905Exacto
2464 | Self::NousresearchHermes4405b
2465 | Self::NousresearchHermes470b
2466 | Self::NvidiaNemotron3Nano30bA3bFree
2467 | Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree
2468 | Self::NvidiaNemotron3Super120bA12b
2469 | Self::NvidiaNemotron3Super120bA12bFree
2470 | Self::NvidiaNemotronNano12bV2VlFree
2471 | Self::NvidiaNemotronNano9bV2
2472 | Self::NvidiaNemotronNano9bV2Free
2473 | Self::OpenaiGpt5
2474 | Self::OpenaiGpt5Mini
2475 | Self::OpenaiGpt5Nano
2476 | Self::OpenaiGpt5Pro
2477 | Self::OpenaiGpt52Pro
2478 | Self::OpenaiGpt55Pro
2479 | Self::OpenaiGptOss120b
2480 | Self::OpenaiGptOss120bExacto
2481 | Self::OpenaiGptOss120bFree
2482 | Self::OpenaiGptOss20b
2483 | Self::OpenaiGptOss20bFree
2484 | Self::OpenaiGptOssSafeguard20b
2485 | Self::OpenrouterElephantAlpha
2486 | Self::OpenrouterFree
2487 | Self::OpenrouterOwlAlpha
2488 | Self::OpenrouterParetoCode
2489 | Self::PrimeIntellectIntellect3
2490 | Self::QwenQwen3627b
2491 | Self::QwenQwen3235bA22b0725
2492 | Self::QwenQwen3235bA22bThinking2507
2493 | Self::QwenQwen330bA3bInstruct2507
2494 | Self::QwenQwen330bA3bThinking2507
2495 | Self::QwenQwen3Coder
2496 | Self::QwenQwen3Coder30bA3bInstruct
2497 | Self::QwenQwen3CoderExacto
2498 | Self::QwenQwen3Next80bA3bInstruct
2499 | Self::QwenQwen3Next80bA3bThinking
2500 | Self::QwenQwen35397bA17b
2501 | Self::QwenQwen35Flash0223
2502 | Self::QwenQwen35Plus0215
2503 | Self::ZAiGlm45
2504 | Self::ZAiGlm45Air
2505 | Self::ZAiGlm45v
2506 | Self::ZAiGlm47Flash => false,
2507 Self::AnthropicClaude35Haiku
2508 | Self::AnthropicClaude37Sonnet
2509 | Self::AnthropicClaudeHaiku45
2510 | Self::AnthropicClaudeOpus4
2511 | Self::AnthropicClaudeOpus41
2512 | Self::AnthropicClaudeOpus45
2513 | Self::AnthropicClaudeOpus46
2514 | Self::AnthropicClaudeOpus47
2515 | Self::AnthropicClaudeSonnet4
2516 | Self::AnthropicClaudeSonnet45
2517 | Self::AnthropicClaudeSonnet46
2518 | Self::DeepseekDeepseekV4Flash
2519 | Self::DeepseekDeepseekV4Pro
2520 | Self::GoogleGemini20Flash001
2521 | Self::GoogleGemini25Flash
2522 | Self::GoogleGemini25FlashLite
2523 | Self::GoogleGemini25FlashLitePreview092025
2524 | Self::GoogleGemini25FlashPreview092025
2525 | Self::GoogleGemini25Pro
2526 | Self::GoogleGemini25ProPreview0506
2527 | Self::GoogleGemini25ProPreview0605
2528 | Self::GoogleGemini3FlashPreview
2529 | Self::GoogleGemini31FlashLitePreview
2530 | Self::InceptionMercury2
2531 | Self::MinimaxMinimaxM2
2532 | Self::MinimaxMinimaxM25
2533 | Self::MinimaxMinimaxM27
2534 | Self::MoonshotaiKimiK2Thinking
2535 | Self::MoonshotaiKimiK25
2536 | Self::MoonshotaiKimiK26
2537 | Self::OpenaiGpt41
2538 | Self::OpenaiGpt41Mini
2539 | Self::OpenaiGpt4oMini
2540 | Self::OpenaiGpt5Codex
2541 | Self::OpenaiGpt5Image
2542 | Self::OpenaiGpt51
2543 | Self::OpenaiGpt51Chat
2544 | Self::OpenaiGpt51Codex
2545 | Self::OpenaiGpt51CodexMax
2546 | Self::OpenaiGpt51CodexMini
2547 | Self::OpenaiGpt52
2548 | Self::OpenaiGpt52Chat
2549 | Self::OpenaiGpt52Codex
2550 | Self::OpenaiGpt53Codex
2551 | Self::OpenaiGpt54
2552 | Self::OpenaiGpt54Mini
2553 | Self::OpenaiGpt54Nano
2554 | Self::OpenaiGpt54Pro
2555 | Self::OpenaiGpt55
2556 | Self::OpenaiO4Mini
2557 | Self::PoolsideLagunaM1Free
2558 | Self::PoolsideLagunaXs2Free
2559 | Self::QwenQwenPlus
2560 | Self::QwenQwen3CoderFlash
2561 | Self::QwenQwen3CoderPlus
2562 | Self::QwenQwen3Max
2563 | Self::QwenQwen36Plus
2564 | Self::StepfunStep35Flash
2565 | Self::TencentHy3Preview
2566 | Self::XAiGrok3
2567 | Self::XAiGrok3Beta
2568 | Self::XAiGrok3Mini
2569 | Self::XAiGrok3MiniBeta
2570 | Self::XAiGrok4
2571 | Self::XAiGrok4Fast
2572 | Self::XAiGrok41Fast
2573 | Self::XAiGrok420Beta
2574 | Self::XAiGrok43
2575 | Self::XAiGrokCodeFast1
2576 | Self::XiaomiMimoV2Flash
2577 | Self::XiaomiMimoV2Omni
2578 | Self::XiaomiMimoV2Pro
2579 | Self::XiaomiMimoV25
2580 | Self::XiaomiMimoV25Pro
2581 | Self::ZAiGlm46
2582 | Self::ZAiGlm46Exacto
2583 | Self::ZAiGlm47
2584 | Self::ZAiGlm5
2585 | Self::ZAiGlm5Turbo
2586 | Self::ZAiGlm51 => true,
2587 }
2588 }
2589 #[allow(clippy::too_many_lines)]
2590 pub fn supports_image(self) -> bool {
2591 match self {
2592 Self::ArceeAiTrinityLargePreviewFree
2593 | Self::ArceeAiTrinityLargeThinking
2594 | Self::DeepseekDeepseekChatV31
2595 | Self::DeepseekDeepseekR1
2596 | Self::DeepseekDeepseekV31Terminus
2597 | Self::DeepseekDeepseekV31TerminusExacto
2598 | Self::DeepseekDeepseekV32
2599 | Self::DeepseekDeepseekV32Speciale
2600 | Self::DeepseekDeepseekV4Flash
2601 | Self::DeepseekDeepseekV4Pro
2602 | Self::InceptionMercury2
2603 | Self::MetaLlamaLlama3370bInstructFree
2604 | Self::MinimaxMinimaxM1
2605 | Self::MinimaxMinimaxM2
2606 | Self::MinimaxMinimaxM21
2607 | Self::MinimaxMinimaxM25
2608 | Self::MinimaxMinimaxM25Free
2609 | Self::MinimaxMinimaxM27
2610 | Self::MistralaiCodestral2508
2611 | Self::MistralaiDevstral2512
2612 | Self::MistralaiDevstralMedium2507
2613 | Self::MistralaiDevstralSmall2505
2614 | Self::MistralaiDevstralSmall2507
2615 | Self::MoonshotaiKimiK2
2616 | Self::MoonshotaiKimiK20905
2617 | Self::MoonshotaiKimiK20905Exacto
2618 | Self::MoonshotaiKimiK2Thinking
2619 | Self::NousresearchHermes4405b
2620 | Self::NousresearchHermes470b
2621 | Self::NvidiaNemotron3Nano30bA3bFree
2622 | Self::NvidiaNemotron3Super120bA12b
2623 | Self::NvidiaNemotron3Super120bA12bFree
2624 | Self::NvidiaNemotronNano9bV2
2625 | Self::NvidiaNemotronNano9bV2Free
2626 | Self::OpenaiGptOss120b
2627 | Self::OpenaiGptOss120bExacto
2628 | Self::OpenaiGptOss120bFree
2629 | Self::OpenaiGptOss20b
2630 | Self::OpenaiGptOss20bFree
2631 | Self::OpenaiGptOssSafeguard20b
2632 | Self::OpenrouterElephantAlpha
2633 | Self::OpenrouterOwlAlpha
2634 | Self::OpenrouterParetoCode
2635 | Self::PoolsideLagunaM1Free
2636 | Self::PoolsideLagunaXs2Free
2637 | Self::PrimeIntellectIntellect3
2638 | Self::QwenQwenPlus
2639 | Self::QwenQwen3235bA22b0725
2640 | Self::QwenQwen3235bA22bThinking2507
2641 | Self::QwenQwen330bA3bInstruct2507
2642 | Self::QwenQwen330bA3bThinking2507
2643 | Self::QwenQwen3Coder
2644 | Self::QwenQwen3Coder30bA3bInstruct
2645 | Self::QwenQwen3CoderFlash
2646 | Self::QwenQwen3CoderPlus
2647 | Self::QwenQwen3CoderExacto
2648 | Self::QwenQwen3Max
2649 | Self::QwenQwen3Next80bA3bInstruct
2650 | Self::QwenQwen3Next80bA3bThinking
2651 | Self::StepfunStep35Flash
2652 | Self::TencentHy3Preview
2653 | Self::XAiGrok3
2654 | Self::XAiGrok3Beta
2655 | Self::XAiGrok3Mini
2656 | Self::XAiGrok3MiniBeta
2657 | Self::XAiGrok4
2658 | Self::XAiGrokCodeFast1
2659 | Self::XiaomiMimoV2Flash
2660 | Self::XiaomiMimoV2Pro
2661 | Self::XiaomiMimoV25Pro
2662 | Self::ZAiGlm45
2663 | Self::ZAiGlm45Air
2664 | Self::ZAiGlm46
2665 | Self::ZAiGlm46Exacto
2666 | Self::ZAiGlm47
2667 | Self::ZAiGlm47Flash
2668 | Self::ZAiGlm5
2669 | Self::ZAiGlm5Turbo
2670 | Self::ZAiGlm51 => false,
2671 Self::AnthropicClaude35Haiku
2672 | Self::AnthropicClaude37Sonnet
2673 | Self::AnthropicClaudeHaiku45
2674 | Self::AnthropicClaudeOpus4
2675 | Self::AnthropicClaudeOpus41
2676 | Self::AnthropicClaudeOpus45
2677 | Self::AnthropicClaudeOpus46
2678 | Self::AnthropicClaudeOpus47
2679 | Self::AnthropicClaudeSonnet4
2680 | Self::AnthropicClaudeSonnet45
2681 | Self::AnthropicClaudeSonnet46
2682 | Self::GoogleGemini20Flash001
2683 | Self::GoogleGemini25Flash
2684 | Self::GoogleGemini25FlashLite
2685 | Self::GoogleGemini25FlashLitePreview092025
2686 | Self::GoogleGemini25FlashPreview092025
2687 | Self::GoogleGemini25Pro
2688 | Self::GoogleGemini25ProPreview0506
2689 | Self::GoogleGemini25ProPreview0605
2690 | Self::GoogleGemini3FlashPreview
2691 | Self::GoogleGemini3ProPreview
2692 | Self::GoogleGemini31FlashLitePreview
2693 | Self::GoogleGemini31ProPreview
2694 | Self::GoogleGemini31ProPreviewCustomtools
2695 | Self::GoogleGemma327bIt
2696 | Self::GoogleGemma327bItFree
2697 | Self::GoogleGemma426bA4bIt
2698 | Self::GoogleGemma426bA4bItFree
2699 | Self::GoogleGemma431bIt
2700 | Self::GoogleGemma431bItFree
2701 | Self::MinimaxMinimax01
2702 | Self::MistralaiMistralMedium3
2703 | Self::MistralaiMistralMedium31
2704 | Self::MistralaiMistralSmall2603
2705 | Self::MistralaiMistralSmall3124bInstruct
2706 | Self::MistralaiMistralSmall3224bInstruct
2707 | Self::MoonshotaiKimiK25
2708 | Self::MoonshotaiKimiK26
2709 | Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree
2710 | Self::NvidiaNemotronNano12bV2VlFree
2711 | Self::OpenaiGpt41
2712 | Self::OpenaiGpt41Mini
2713 | Self::OpenaiGpt4oMini
2714 | Self::OpenaiGpt5
2715 | Self::OpenaiGpt5Codex
2716 | Self::OpenaiGpt5Image
2717 | Self::OpenaiGpt5Mini
2718 | Self::OpenaiGpt5Nano
2719 | Self::OpenaiGpt5Pro
2720 | Self::OpenaiGpt51
2721 | Self::OpenaiGpt51Chat
2722 | Self::OpenaiGpt51Codex
2723 | Self::OpenaiGpt51CodexMax
2724 | Self::OpenaiGpt51CodexMini
2725 | Self::OpenaiGpt52
2726 | Self::OpenaiGpt52Chat
2727 | Self::OpenaiGpt52Codex
2728 | Self::OpenaiGpt52Pro
2729 | Self::OpenaiGpt53Codex
2730 | Self::OpenaiGpt54
2731 | Self::OpenaiGpt54Mini
2732 | Self::OpenaiGpt54Nano
2733 | Self::OpenaiGpt54Pro
2734 | Self::OpenaiGpt55
2735 | Self::OpenaiGpt55Pro
2736 | Self::OpenaiO4Mini
2737 | Self::OpenrouterFree
2738 | Self::QwenQwen3627b
2739 | Self::QwenQwen35397bA17b
2740 | Self::QwenQwen35Flash0223
2741 | Self::QwenQwen35Plus0215
2742 | Self::QwenQwen36Plus
2743 | Self::XAiGrok4Fast
2744 | Self::XAiGrok41Fast
2745 | Self::XAiGrok420Beta
2746 | Self::XAiGrok43
2747 | Self::XiaomiMimoV2Omni
2748 | Self::XiaomiMimoV25
2749 | Self::ZAiGlm45v => true,
2750 }
2751 }
2752 #[allow(clippy::too_many_lines)]
2753 pub fn supports_audio(self) -> bool {
2754 match self {
2755 Self::AnthropicClaude35Haiku
2756 | Self::AnthropicClaude37Sonnet
2757 | Self::AnthropicClaudeHaiku45
2758 | Self::AnthropicClaudeOpus4
2759 | Self::AnthropicClaudeOpus41
2760 | Self::AnthropicClaudeOpus45
2761 | Self::AnthropicClaudeOpus46
2762 | Self::AnthropicClaudeOpus47
2763 | Self::AnthropicClaudeSonnet4
2764 | Self::AnthropicClaudeSonnet45
2765 | Self::AnthropicClaudeSonnet46
2766 | Self::ArceeAiTrinityLargePreviewFree
2767 | Self::ArceeAiTrinityLargeThinking
2768 | Self::DeepseekDeepseekChatV31
2769 | Self::DeepseekDeepseekR1
2770 | Self::DeepseekDeepseekV31Terminus
2771 | Self::DeepseekDeepseekV31TerminusExacto
2772 | Self::DeepseekDeepseekV32
2773 | Self::DeepseekDeepseekV32Speciale
2774 | Self::DeepseekDeepseekV4Flash
2775 | Self::DeepseekDeepseekV4Pro
2776 | Self::GoogleGemma327bIt
2777 | Self::GoogleGemma327bItFree
2778 | Self::GoogleGemma426bA4bIt
2779 | Self::GoogleGemma426bA4bItFree
2780 | Self::GoogleGemma431bIt
2781 | Self::GoogleGemma431bItFree
2782 | Self::InceptionMercury2
2783 | Self::MetaLlamaLlama3370bInstructFree
2784 | Self::MinimaxMinimax01
2785 | Self::MinimaxMinimaxM1
2786 | Self::MinimaxMinimaxM2
2787 | Self::MinimaxMinimaxM21
2788 | Self::MinimaxMinimaxM25
2789 | Self::MinimaxMinimaxM25Free
2790 | Self::MinimaxMinimaxM27
2791 | Self::MistralaiCodestral2508
2792 | Self::MistralaiDevstral2512
2793 | Self::MistralaiDevstralMedium2507
2794 | Self::MistralaiDevstralSmall2505
2795 | Self::MistralaiDevstralSmall2507
2796 | Self::MistralaiMistralMedium3
2797 | Self::MistralaiMistralMedium31
2798 | Self::MistralaiMistralSmall2603
2799 | Self::MistralaiMistralSmall3124bInstruct
2800 | Self::MistralaiMistralSmall3224bInstruct
2801 | Self::MoonshotaiKimiK2
2802 | Self::MoonshotaiKimiK20905
2803 | Self::MoonshotaiKimiK20905Exacto
2804 | Self::MoonshotaiKimiK2Thinking
2805 | Self::MoonshotaiKimiK25
2806 | Self::MoonshotaiKimiK26
2807 | Self::NousresearchHermes4405b
2808 | Self::NousresearchHermes470b
2809 | Self::NvidiaNemotron3Nano30bA3bFree
2810 | Self::NvidiaNemotron3Super120bA12b
2811 | Self::NvidiaNemotron3Super120bA12bFree
2812 | Self::NvidiaNemotronNano12bV2VlFree
2813 | Self::NvidiaNemotronNano9bV2
2814 | Self::NvidiaNemotronNano9bV2Free
2815 | Self::OpenaiGpt41
2816 | Self::OpenaiGpt41Mini
2817 | Self::OpenaiGpt4oMini
2818 | Self::OpenaiGpt5
2819 | Self::OpenaiGpt5Codex
2820 | Self::OpenaiGpt5Image
2821 | Self::OpenaiGpt5Mini
2822 | Self::OpenaiGpt5Nano
2823 | Self::OpenaiGpt5Pro
2824 | Self::OpenaiGpt51
2825 | Self::OpenaiGpt51Chat
2826 | Self::OpenaiGpt51Codex
2827 | Self::OpenaiGpt51CodexMax
2828 | Self::OpenaiGpt51CodexMini
2829 | Self::OpenaiGpt52
2830 | Self::OpenaiGpt52Chat
2831 | Self::OpenaiGpt52Codex
2832 | Self::OpenaiGpt52Pro
2833 | Self::OpenaiGpt53Codex
2834 | Self::OpenaiGpt54
2835 | Self::OpenaiGpt54Mini
2836 | Self::OpenaiGpt54Nano
2837 | Self::OpenaiGpt54Pro
2838 | Self::OpenaiGpt55
2839 | Self::OpenaiGpt55Pro
2840 | Self::OpenaiGptOss120b
2841 | Self::OpenaiGptOss120bExacto
2842 | Self::OpenaiGptOss120bFree
2843 | Self::OpenaiGptOss20b
2844 | Self::OpenaiGptOss20bFree
2845 | Self::OpenaiGptOssSafeguard20b
2846 | Self::OpenaiO4Mini
2847 | Self::OpenrouterElephantAlpha
2848 | Self::OpenrouterFree
2849 | Self::OpenrouterOwlAlpha
2850 | Self::OpenrouterParetoCode
2851 | Self::PoolsideLagunaM1Free
2852 | Self::PoolsideLagunaXs2Free
2853 | Self::PrimeIntellectIntellect3
2854 | Self::QwenQwen3627b
2855 | Self::QwenQwenPlus
2856 | Self::QwenQwen3235bA22b0725
2857 | Self::QwenQwen3235bA22bThinking2507
2858 | Self::QwenQwen330bA3bInstruct2507
2859 | Self::QwenQwen330bA3bThinking2507
2860 | Self::QwenQwen3Coder
2861 | Self::QwenQwen3Coder30bA3bInstruct
2862 | Self::QwenQwen3CoderFlash
2863 | Self::QwenQwen3CoderPlus
2864 | Self::QwenQwen3CoderExacto
2865 | Self::QwenQwen3Max
2866 | Self::QwenQwen3Next80bA3bInstruct
2867 | Self::QwenQwen3Next80bA3bThinking
2868 | Self::QwenQwen35397bA17b
2869 | Self::QwenQwen35Flash0223
2870 | Self::QwenQwen35Plus0215
2871 | Self::QwenQwen36Plus
2872 | Self::StepfunStep35Flash
2873 | Self::TencentHy3Preview
2874 | Self::XAiGrok3
2875 | Self::XAiGrok3Beta
2876 | Self::XAiGrok3Mini
2877 | Self::XAiGrok3MiniBeta
2878 | Self::XAiGrok4
2879 | Self::XAiGrok4Fast
2880 | Self::XAiGrok41Fast
2881 | Self::XAiGrok420Beta
2882 | Self::XAiGrok43
2883 | Self::XAiGrokCodeFast1
2884 | Self::XiaomiMimoV2Flash
2885 | Self::XiaomiMimoV2Pro
2886 | Self::XiaomiMimoV25Pro
2887 | Self::ZAiGlm45
2888 | Self::ZAiGlm45Air
2889 | Self::ZAiGlm45v
2890 | Self::ZAiGlm46
2891 | Self::ZAiGlm46Exacto
2892 | Self::ZAiGlm47
2893 | Self::ZAiGlm47Flash
2894 | Self::ZAiGlm5
2895 | Self::ZAiGlm5Turbo
2896 | Self::ZAiGlm51 => false,
2897 Self::GoogleGemini20Flash001
2898 | Self::GoogleGemini25Flash
2899 | Self::GoogleGemini25FlashLite
2900 | Self::GoogleGemini25FlashLitePreview092025
2901 | Self::GoogleGemini25FlashPreview092025
2902 | Self::GoogleGemini25Pro
2903 | Self::GoogleGemini25ProPreview0506
2904 | Self::GoogleGemini25ProPreview0605
2905 | Self::GoogleGemini3FlashPreview
2906 | Self::GoogleGemini3ProPreview
2907 | Self::GoogleGemini31FlashLitePreview
2908 | Self::GoogleGemini31ProPreview
2909 | Self::GoogleGemini31ProPreviewCustomtools
2910 | Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree
2911 | Self::XiaomiMimoV2Omni
2912 | Self::XiaomiMimoV25 => true,
2913 }
2914 }
2915 const ALL: &[OpenRouterModel] = &[
2916 Self::AnthropicClaude35Haiku,
2917 Self::AnthropicClaude37Sonnet,
2918 Self::AnthropicClaudeHaiku45,
2919 Self::AnthropicClaudeOpus4,
2920 Self::AnthropicClaudeOpus41,
2921 Self::AnthropicClaudeOpus45,
2922 Self::AnthropicClaudeOpus46,
2923 Self::AnthropicClaudeOpus47,
2924 Self::AnthropicClaudeSonnet4,
2925 Self::AnthropicClaudeSonnet45,
2926 Self::AnthropicClaudeSonnet46,
2927 Self::ArceeAiTrinityLargePreviewFree,
2928 Self::ArceeAiTrinityLargeThinking,
2929 Self::DeepseekDeepseekChatV31,
2930 Self::DeepseekDeepseekR1,
2931 Self::DeepseekDeepseekV31Terminus,
2932 Self::DeepseekDeepseekV31TerminusExacto,
2933 Self::DeepseekDeepseekV32,
2934 Self::DeepseekDeepseekV32Speciale,
2935 Self::DeepseekDeepseekV4Flash,
2936 Self::DeepseekDeepseekV4Pro,
2937 Self::GoogleGemini20Flash001,
2938 Self::GoogleGemini25Flash,
2939 Self::GoogleGemini25FlashLite,
2940 Self::GoogleGemini25FlashLitePreview092025,
2941 Self::GoogleGemini25FlashPreview092025,
2942 Self::GoogleGemini25Pro,
2943 Self::GoogleGemini25ProPreview0506,
2944 Self::GoogleGemini25ProPreview0605,
2945 Self::GoogleGemini3FlashPreview,
2946 Self::GoogleGemini3ProPreview,
2947 Self::GoogleGemini31FlashLitePreview,
2948 Self::GoogleGemini31ProPreview,
2949 Self::GoogleGemini31ProPreviewCustomtools,
2950 Self::GoogleGemma327bIt,
2951 Self::GoogleGemma327bItFree,
2952 Self::GoogleGemma426bA4bIt,
2953 Self::GoogleGemma426bA4bItFree,
2954 Self::GoogleGemma431bIt,
2955 Self::GoogleGemma431bItFree,
2956 Self::InceptionMercury2,
2957 Self::MetaLlamaLlama3370bInstructFree,
2958 Self::MinimaxMinimax01,
2959 Self::MinimaxMinimaxM1,
2960 Self::MinimaxMinimaxM2,
2961 Self::MinimaxMinimaxM21,
2962 Self::MinimaxMinimaxM25,
2963 Self::MinimaxMinimaxM25Free,
2964 Self::MinimaxMinimaxM27,
2965 Self::MistralaiCodestral2508,
2966 Self::MistralaiDevstral2512,
2967 Self::MistralaiDevstralMedium2507,
2968 Self::MistralaiDevstralSmall2505,
2969 Self::MistralaiDevstralSmall2507,
2970 Self::MistralaiMistralMedium3,
2971 Self::MistralaiMistralMedium31,
2972 Self::MistralaiMistralSmall2603,
2973 Self::MistralaiMistralSmall3124bInstruct,
2974 Self::MistralaiMistralSmall3224bInstruct,
2975 Self::MoonshotaiKimiK2,
2976 Self::MoonshotaiKimiK20905,
2977 Self::MoonshotaiKimiK20905Exacto,
2978 Self::MoonshotaiKimiK2Thinking,
2979 Self::MoonshotaiKimiK25,
2980 Self::MoonshotaiKimiK26,
2981 Self::NousresearchHermes4405b,
2982 Self::NousresearchHermes470b,
2983 Self::NvidiaNemotron3Nano30bA3bFree,
2984 Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree,
2985 Self::NvidiaNemotron3Super120bA12b,
2986 Self::NvidiaNemotron3Super120bA12bFree,
2987 Self::NvidiaNemotronNano12bV2VlFree,
2988 Self::NvidiaNemotronNano9bV2,
2989 Self::NvidiaNemotronNano9bV2Free,
2990 Self::OpenaiGpt41,
2991 Self::OpenaiGpt41Mini,
2992 Self::OpenaiGpt4oMini,
2993 Self::OpenaiGpt5,
2994 Self::OpenaiGpt5Codex,
2995 Self::OpenaiGpt5Image,
2996 Self::OpenaiGpt5Mini,
2997 Self::OpenaiGpt5Nano,
2998 Self::OpenaiGpt5Pro,
2999 Self::OpenaiGpt51,
3000 Self::OpenaiGpt51Chat,
3001 Self::OpenaiGpt51Codex,
3002 Self::OpenaiGpt51CodexMax,
3003 Self::OpenaiGpt51CodexMini,
3004 Self::OpenaiGpt52,
3005 Self::OpenaiGpt52Chat,
3006 Self::OpenaiGpt52Codex,
3007 Self::OpenaiGpt52Pro,
3008 Self::OpenaiGpt53Codex,
3009 Self::OpenaiGpt54,
3010 Self::OpenaiGpt54Mini,
3011 Self::OpenaiGpt54Nano,
3012 Self::OpenaiGpt54Pro,
3013 Self::OpenaiGpt55,
3014 Self::OpenaiGpt55Pro,
3015 Self::OpenaiGptOss120b,
3016 Self::OpenaiGptOss120bExacto,
3017 Self::OpenaiGptOss120bFree,
3018 Self::OpenaiGptOss20b,
3019 Self::OpenaiGptOss20bFree,
3020 Self::OpenaiGptOssSafeguard20b,
3021 Self::OpenaiO4Mini,
3022 Self::OpenrouterElephantAlpha,
3023 Self::OpenrouterFree,
3024 Self::OpenrouterOwlAlpha,
3025 Self::OpenrouterParetoCode,
3026 Self::PoolsideLagunaM1Free,
3027 Self::PoolsideLagunaXs2Free,
3028 Self::PrimeIntellectIntellect3,
3029 Self::QwenQwen3627b,
3030 Self::QwenQwenPlus,
3031 Self::QwenQwen3235bA22b0725,
3032 Self::QwenQwen3235bA22bThinking2507,
3033 Self::QwenQwen330bA3bInstruct2507,
3034 Self::QwenQwen330bA3bThinking2507,
3035 Self::QwenQwen3Coder,
3036 Self::QwenQwen3Coder30bA3bInstruct,
3037 Self::QwenQwen3CoderFlash,
3038 Self::QwenQwen3CoderPlus,
3039 Self::QwenQwen3CoderExacto,
3040 Self::QwenQwen3Max,
3041 Self::QwenQwen3Next80bA3bInstruct,
3042 Self::QwenQwen3Next80bA3bThinking,
3043 Self::QwenQwen35397bA17b,
3044 Self::QwenQwen35Flash0223,
3045 Self::QwenQwen35Plus0215,
3046 Self::QwenQwen36Plus,
3047 Self::StepfunStep35Flash,
3048 Self::TencentHy3Preview,
3049 Self::XAiGrok3,
3050 Self::XAiGrok3Beta,
3051 Self::XAiGrok3Mini,
3052 Self::XAiGrok3MiniBeta,
3053 Self::XAiGrok4,
3054 Self::XAiGrok4Fast,
3055 Self::XAiGrok41Fast,
3056 Self::XAiGrok420Beta,
3057 Self::XAiGrok43,
3058 Self::XAiGrokCodeFast1,
3059 Self::XiaomiMimoV2Flash,
3060 Self::XiaomiMimoV2Omni,
3061 Self::XiaomiMimoV2Pro,
3062 Self::XiaomiMimoV25,
3063 Self::XiaomiMimoV25Pro,
3064 Self::ZAiGlm45,
3065 Self::ZAiGlm45Air,
3066 Self::ZAiGlm45v,
3067 Self::ZAiGlm46,
3068 Self::ZAiGlm46Exacto,
3069 Self::ZAiGlm47,
3070 Self::ZAiGlm47Flash,
3071 Self::ZAiGlm5,
3072 Self::ZAiGlm5Turbo,
3073 Self::ZAiGlm51,
3074 ];
3075}
3076impl std::str::FromStr for OpenRouterModel {
3077 type Err = String;
3078 #[allow(clippy::too_many_lines)]
3079 fn from_str(s: &str) -> Result<Self, Self::Err> {
3080 match s {
3081 "anthropic/claude-3.5-haiku" => Ok(Self::AnthropicClaude35Haiku),
3082 "anthropic/claude-3.7-sonnet" => Ok(Self::AnthropicClaude37Sonnet),
3083 "anthropic/claude-haiku-4.5" => Ok(Self::AnthropicClaudeHaiku45),
3084 "anthropic/claude-opus-4" => Ok(Self::AnthropicClaudeOpus4),
3085 "anthropic/claude-opus-4.1" => Ok(Self::AnthropicClaudeOpus41),
3086 "anthropic/claude-opus-4.5" => Ok(Self::AnthropicClaudeOpus45),
3087 "anthropic/claude-opus-4.6" => Ok(Self::AnthropicClaudeOpus46),
3088 "anthropic/claude-opus-4.7" => Ok(Self::AnthropicClaudeOpus47),
3089 "anthropic/claude-sonnet-4" => Ok(Self::AnthropicClaudeSonnet4),
3090 "anthropic/claude-sonnet-4.5" => Ok(Self::AnthropicClaudeSonnet45),
3091 "anthropic/claude-sonnet-4.6" => Ok(Self::AnthropicClaudeSonnet46),
3092 "arcee-ai/trinity-large-preview:free" => {
3093 Ok(Self::ArceeAiTrinityLargePreviewFree)
3094 }
3095 "arcee-ai/trinity-large-thinking" => Ok(Self::ArceeAiTrinityLargeThinking),
3096 "deepseek/deepseek-chat-v3.1" => Ok(Self::DeepseekDeepseekChatV31),
3097 "deepseek/deepseek-r1" => Ok(Self::DeepseekDeepseekR1),
3098 "deepseek/deepseek-v3.1-terminus" => Ok(Self::DeepseekDeepseekV31Terminus),
3099 "deepseek/deepseek-v3.1-terminus:exacto" => {
3100 Ok(Self::DeepseekDeepseekV31TerminusExacto)
3101 }
3102 "deepseek/deepseek-v3.2" => Ok(Self::DeepseekDeepseekV32),
3103 "deepseek/deepseek-v3.2-speciale" => Ok(Self::DeepseekDeepseekV32Speciale),
3104 "deepseek/deepseek-v4-flash" => Ok(Self::DeepseekDeepseekV4Flash),
3105 "deepseek/deepseek-v4-pro" => Ok(Self::DeepseekDeepseekV4Pro),
3106 "google/gemini-2.0-flash-001" => Ok(Self::GoogleGemini20Flash001),
3107 "google/gemini-2.5-flash" => Ok(Self::GoogleGemini25Flash),
3108 "google/gemini-2.5-flash-lite" => Ok(Self::GoogleGemini25FlashLite),
3109 "google/gemini-2.5-flash-lite-preview-09-2025" => {
3110 Ok(Self::GoogleGemini25FlashLitePreview092025)
3111 }
3112 "google/gemini-2.5-flash-preview-09-2025" => {
3113 Ok(Self::GoogleGemini25FlashPreview092025)
3114 }
3115 "google/gemini-2.5-pro" => Ok(Self::GoogleGemini25Pro),
3116 "google/gemini-2.5-pro-preview-05-06" => {
3117 Ok(Self::GoogleGemini25ProPreview0506)
3118 }
3119 "google/gemini-2.5-pro-preview-06-05" => {
3120 Ok(Self::GoogleGemini25ProPreview0605)
3121 }
3122 "google/gemini-3-flash-preview" => Ok(Self::GoogleGemini3FlashPreview),
3123 "google/gemini-3-pro-preview" => Ok(Self::GoogleGemini3ProPreview),
3124 "google/gemini-3.1-flash-lite-preview" => {
3125 Ok(Self::GoogleGemini31FlashLitePreview)
3126 }
3127 "google/gemini-3.1-pro-preview" => Ok(Self::GoogleGemini31ProPreview),
3128 "google/gemini-3.1-pro-preview-customtools" => {
3129 Ok(Self::GoogleGemini31ProPreviewCustomtools)
3130 }
3131 "google/gemma-3-27b-it" => Ok(Self::GoogleGemma327bIt),
3132 "google/gemma-3-27b-it:free" => Ok(Self::GoogleGemma327bItFree),
3133 "google/gemma-4-26b-a4b-it" => Ok(Self::GoogleGemma426bA4bIt),
3134 "google/gemma-4-26b-a4b-it:free" => Ok(Self::GoogleGemma426bA4bItFree),
3135 "google/gemma-4-31b-it" => Ok(Self::GoogleGemma431bIt),
3136 "google/gemma-4-31b-it:free" => Ok(Self::GoogleGemma431bItFree),
3137 "inception/mercury-2" => Ok(Self::InceptionMercury2),
3138 "meta-llama/llama-3.3-70b-instruct:free" => {
3139 Ok(Self::MetaLlamaLlama3370bInstructFree)
3140 }
3141 "minimax/minimax-01" => Ok(Self::MinimaxMinimax01),
3142 "minimax/minimax-m1" => Ok(Self::MinimaxMinimaxM1),
3143 "minimax/minimax-m2" => Ok(Self::MinimaxMinimaxM2),
3144 "minimax/minimax-m2.1" => Ok(Self::MinimaxMinimaxM21),
3145 "minimax/minimax-m2.5" => Ok(Self::MinimaxMinimaxM25),
3146 "minimax/minimax-m2.5:free" => Ok(Self::MinimaxMinimaxM25Free),
3147 "minimax/minimax-m2.7" => Ok(Self::MinimaxMinimaxM27),
3148 "mistralai/codestral-2508" => Ok(Self::MistralaiCodestral2508),
3149 "mistralai/devstral-2512" => Ok(Self::MistralaiDevstral2512),
3150 "mistralai/devstral-medium-2507" => Ok(Self::MistralaiDevstralMedium2507),
3151 "mistralai/devstral-small-2505" => Ok(Self::MistralaiDevstralSmall2505),
3152 "mistralai/devstral-small-2507" => Ok(Self::MistralaiDevstralSmall2507),
3153 "mistralai/mistral-medium-3" => Ok(Self::MistralaiMistralMedium3),
3154 "mistralai/mistral-medium-3.1" => Ok(Self::MistralaiMistralMedium31),
3155 "mistralai/mistral-small-2603" => Ok(Self::MistralaiMistralSmall2603),
3156 "mistralai/mistral-small-3.1-24b-instruct" => {
3157 Ok(Self::MistralaiMistralSmall3124bInstruct)
3158 }
3159 "mistralai/mistral-small-3.2-24b-instruct" => {
3160 Ok(Self::MistralaiMistralSmall3224bInstruct)
3161 }
3162 "moonshotai/kimi-k2" => Ok(Self::MoonshotaiKimiK2),
3163 "moonshotai/kimi-k2-0905" => Ok(Self::MoonshotaiKimiK20905),
3164 "moonshotai/kimi-k2-0905:exacto" => Ok(Self::MoonshotaiKimiK20905Exacto),
3165 "moonshotai/kimi-k2-thinking" => Ok(Self::MoonshotaiKimiK2Thinking),
3166 "moonshotai/kimi-k2.5" => Ok(Self::MoonshotaiKimiK25),
3167 "moonshotai/kimi-k2.6" => Ok(Self::MoonshotaiKimiK26),
3168 "nousresearch/hermes-4-405b" => Ok(Self::NousresearchHermes4405b),
3169 "nousresearch/hermes-4-70b" => Ok(Self::NousresearchHermes470b),
3170 "nvidia/nemotron-3-nano-30b-a3b:free" => {
3171 Ok(Self::NvidiaNemotron3Nano30bA3bFree)
3172 }
3173 "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free" => {
3174 Ok(Self::NvidiaNemotron3NanoOmni30bA3bReasoningFree)
3175 }
3176 "nvidia/nemotron-3-super-120b-a12b" => Ok(Self::NvidiaNemotron3Super120bA12b),
3177 "nvidia/nemotron-3-super-120b-a12b:free" => {
3178 Ok(Self::NvidiaNemotron3Super120bA12bFree)
3179 }
3180 "nvidia/nemotron-nano-12b-v2-vl:free" => {
3181 Ok(Self::NvidiaNemotronNano12bV2VlFree)
3182 }
3183 "nvidia/nemotron-nano-9b-v2" => Ok(Self::NvidiaNemotronNano9bV2),
3184 "nvidia/nemotron-nano-9b-v2:free" => Ok(Self::NvidiaNemotronNano9bV2Free),
3185 "openai/gpt-4.1" => Ok(Self::OpenaiGpt41),
3186 "openai/gpt-4.1-mini" => Ok(Self::OpenaiGpt41Mini),
3187 "openai/gpt-4o-mini" => Ok(Self::OpenaiGpt4oMini),
3188 "openai/gpt-5" => Ok(Self::OpenaiGpt5),
3189 "openai/gpt-5-codex" => Ok(Self::OpenaiGpt5Codex),
3190 "openai/gpt-5-image" => Ok(Self::OpenaiGpt5Image),
3191 "openai/gpt-5-mini" => Ok(Self::OpenaiGpt5Mini),
3192 "openai/gpt-5-nano" => Ok(Self::OpenaiGpt5Nano),
3193 "openai/gpt-5-pro" => Ok(Self::OpenaiGpt5Pro),
3194 "openai/gpt-5.1" => Ok(Self::OpenaiGpt51),
3195 "openai/gpt-5.1-chat" => Ok(Self::OpenaiGpt51Chat),
3196 "openai/gpt-5.1-codex" => Ok(Self::OpenaiGpt51Codex),
3197 "openai/gpt-5.1-codex-max" => Ok(Self::OpenaiGpt51CodexMax),
3198 "openai/gpt-5.1-codex-mini" => Ok(Self::OpenaiGpt51CodexMini),
3199 "openai/gpt-5.2" => Ok(Self::OpenaiGpt52),
3200 "openai/gpt-5.2-chat" => Ok(Self::OpenaiGpt52Chat),
3201 "openai/gpt-5.2-codex" => Ok(Self::OpenaiGpt52Codex),
3202 "openai/gpt-5.2-pro" => Ok(Self::OpenaiGpt52Pro),
3203 "openai/gpt-5.3-codex" => Ok(Self::OpenaiGpt53Codex),
3204 "openai/gpt-5.4" => Ok(Self::OpenaiGpt54),
3205 "openai/gpt-5.4-mini" => Ok(Self::OpenaiGpt54Mini),
3206 "openai/gpt-5.4-nano" => Ok(Self::OpenaiGpt54Nano),
3207 "openai/gpt-5.4-pro" => Ok(Self::OpenaiGpt54Pro),
3208 "openai/gpt-5.5" => Ok(Self::OpenaiGpt55),
3209 "openai/gpt-5.5-pro" => Ok(Self::OpenaiGpt55Pro),
3210 "openai/gpt-oss-120b" => Ok(Self::OpenaiGptOss120b),
3211 "openai/gpt-oss-120b:exacto" => Ok(Self::OpenaiGptOss120bExacto),
3212 "openai/gpt-oss-120b:free" => Ok(Self::OpenaiGptOss120bFree),
3213 "openai/gpt-oss-20b" => Ok(Self::OpenaiGptOss20b),
3214 "openai/gpt-oss-20b:free" => Ok(Self::OpenaiGptOss20bFree),
3215 "openai/gpt-oss-safeguard-20b" => Ok(Self::OpenaiGptOssSafeguard20b),
3216 "openai/o4-mini" => Ok(Self::OpenaiO4Mini),
3217 "openrouter/elephant-alpha" => Ok(Self::OpenrouterElephantAlpha),
3218 "openrouter/free" => Ok(Self::OpenrouterFree),
3219 "openrouter/owl-alpha" => Ok(Self::OpenrouterOwlAlpha),
3220 "openrouter/pareto-code" => Ok(Self::OpenrouterParetoCode),
3221 "poolside/laguna-m.1:free" => Ok(Self::PoolsideLagunaM1Free),
3222 "poolside/laguna-xs.2:free" => Ok(Self::PoolsideLagunaXs2Free),
3223 "prime-intellect/intellect-3" => Ok(Self::PrimeIntellectIntellect3),
3224 "qwen/qwen-3.6-27b" => Ok(Self::QwenQwen3627b),
3225 "qwen/qwen-plus" => Ok(Self::QwenQwenPlus),
3226 "qwen/qwen3-235b-a22b-07-25" => Ok(Self::QwenQwen3235bA22b0725),
3227 "qwen/qwen3-235b-a22b-thinking-2507" => {
3228 Ok(Self::QwenQwen3235bA22bThinking2507)
3229 }
3230 "qwen/qwen3-30b-a3b-instruct-2507" => Ok(Self::QwenQwen330bA3bInstruct2507),
3231 "qwen/qwen3-30b-a3b-thinking-2507" => Ok(Self::QwenQwen330bA3bThinking2507),
3232 "qwen/qwen3-coder" => Ok(Self::QwenQwen3Coder),
3233 "qwen/qwen3-coder-30b-a3b-instruct" => Ok(Self::QwenQwen3Coder30bA3bInstruct),
3234 "qwen/qwen3-coder-flash" => Ok(Self::QwenQwen3CoderFlash),
3235 "qwen/qwen3-coder-plus" => Ok(Self::QwenQwen3CoderPlus),
3236 "qwen/qwen3-coder:exacto" => Ok(Self::QwenQwen3CoderExacto),
3237 "qwen/qwen3-max" => Ok(Self::QwenQwen3Max),
3238 "qwen/qwen3-next-80b-a3b-instruct" => Ok(Self::QwenQwen3Next80bA3bInstruct),
3239 "qwen/qwen3-next-80b-a3b-thinking" => Ok(Self::QwenQwen3Next80bA3bThinking),
3240 "qwen/qwen3.5-397b-a17b" => Ok(Self::QwenQwen35397bA17b),
3241 "qwen/qwen3.5-flash-02-23" => Ok(Self::QwenQwen35Flash0223),
3242 "qwen/qwen3.5-plus-02-15" => Ok(Self::QwenQwen35Plus0215),
3243 "qwen/qwen3.6-plus" => Ok(Self::QwenQwen36Plus),
3244 "stepfun/step-3.5-flash" => Ok(Self::StepfunStep35Flash),
3245 "tencent/hy3-preview" => Ok(Self::TencentHy3Preview),
3246 "x-ai/grok-3" => Ok(Self::XAiGrok3),
3247 "x-ai/grok-3-beta" => Ok(Self::XAiGrok3Beta),
3248 "x-ai/grok-3-mini" => Ok(Self::XAiGrok3Mini),
3249 "x-ai/grok-3-mini-beta" => Ok(Self::XAiGrok3MiniBeta),
3250 "x-ai/grok-4" => Ok(Self::XAiGrok4),
3251 "x-ai/grok-4-fast" => Ok(Self::XAiGrok4Fast),
3252 "x-ai/grok-4.1-fast" => Ok(Self::XAiGrok41Fast),
3253 "x-ai/grok-4.20-beta" => Ok(Self::XAiGrok420Beta),
3254 "x-ai/grok-4.3" => Ok(Self::XAiGrok43),
3255 "x-ai/grok-code-fast-1" => Ok(Self::XAiGrokCodeFast1),
3256 "xiaomi/mimo-v2-flash" => Ok(Self::XiaomiMimoV2Flash),
3257 "xiaomi/mimo-v2-omni" => Ok(Self::XiaomiMimoV2Omni),
3258 "xiaomi/mimo-v2-pro" => Ok(Self::XiaomiMimoV2Pro),
3259 "xiaomi/mimo-v2.5" => Ok(Self::XiaomiMimoV25),
3260 "xiaomi/mimo-v2.5-pro" => Ok(Self::XiaomiMimoV25Pro),
3261 "z-ai/glm-4.5" => Ok(Self::ZAiGlm45),
3262 "z-ai/glm-4.5-air" => Ok(Self::ZAiGlm45Air),
3263 "z-ai/glm-4.5v" => Ok(Self::ZAiGlm45v),
3264 "z-ai/glm-4.6" => Ok(Self::ZAiGlm46),
3265 "z-ai/glm-4.6:exacto" => Ok(Self::ZAiGlm46Exacto),
3266 "z-ai/glm-4.7" => Ok(Self::ZAiGlm47),
3267 "z-ai/glm-4.7-flash" => Ok(Self::ZAiGlm47Flash),
3268 "z-ai/glm-5" => Ok(Self::ZAiGlm5),
3269 "z-ai/glm-5-turbo" => Ok(Self::ZAiGlm5Turbo),
3270 "z-ai/glm-5.1" => Ok(Self::ZAiGlm51),
3271 _ => Err(format!("Unknown openrouter model: '{s}'")),
3272 }
3273 }
3274}
3275impl ZAiModel {
3276 #[allow(clippy::too_many_lines)]
3277 fn model_id(self) -> &'static str {
3278 match self {
3279 Self::Glm45 => "glm-4.5",
3280 Self::Glm45Air => "glm-4.5-air",
3281 Self::Glm45Flash => "glm-4.5-flash",
3282 Self::Glm45v => "glm-4.5v",
3283 Self::Glm46 => "glm-4.6",
3284 Self::Glm46v => "glm-4.6v",
3285 Self::Glm47 => "glm-4.7",
3286 Self::Glm47Flash => "glm-4.7-flash",
3287 Self::Glm47Flashx => "glm-4.7-flashx",
3288 Self::Glm5 => "glm-5",
3289 Self::Glm5Turbo => "glm-5-turbo",
3290 Self::Glm51 => "glm-5.1",
3291 Self::Glm5vTurbo => "glm-5v-turbo",
3292 }
3293 }
3294 #[allow(clippy::too_many_lines)]
3295 fn display_name(self) -> &'static str {
3296 match self {
3297 Self::Glm45 => "GLM-4.5",
3298 Self::Glm45Air => "GLM-4.5-Air",
3299 Self::Glm45Flash => "GLM-4.5-Flash",
3300 Self::Glm45v => "GLM-4.5V",
3301 Self::Glm46 => "GLM-4.6",
3302 Self::Glm46v => "GLM-4.6V",
3303 Self::Glm47 => "GLM-4.7",
3304 Self::Glm47Flash => "GLM-4.7-Flash",
3305 Self::Glm47Flashx => "GLM-4.7-FlashX",
3306 Self::Glm5 => "GLM-5",
3307 Self::Glm5Turbo => "GLM-5-Turbo",
3308 Self::Glm51 => "GLM-5.1",
3309 Self::Glm5vTurbo => "GLM-5V-Turbo",
3310 }
3311 }
3312 #[allow(clippy::too_many_lines)]
3313 fn context_window(self) -> u32 {
3314 match self {
3315 Self::Glm45v => 64_000,
3316 Self::Glm46v => 128_000,
3317 Self::Glm45 | Self::Glm45Air | Self::Glm45Flash => 131_072,
3318 Self::Glm47Flash
3319 | Self::Glm47Flashx
3320 | Self::Glm5Turbo
3321 | Self::Glm51
3322 | Self::Glm5vTurbo => 200_000,
3323 Self::Glm46 | Self::Glm47 | Self::Glm5 => 204_800,
3324 }
3325 }
3326 #[allow(clippy::too_many_lines)]
3327 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
3328 match self {
3329 Self::Glm45
3330 | Self::Glm45Air
3331 | Self::Glm45Flash
3332 | Self::Glm45v
3333 | Self::Glm46
3334 | Self::Glm46v
3335 | Self::Glm47
3336 | Self::Glm47Flash
3337 | Self::Glm47Flashx
3338 | Self::Glm5
3339 | Self::Glm5Turbo
3340 | Self::Glm51
3341 | Self::Glm5vTurbo => {
3342 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
3343 }
3344 }
3345 }
3346 pub fn supports_reasoning(self) -> bool {
3347 !self.reasoning_levels().is_empty()
3348 }
3349 #[allow(clippy::too_many_lines)]
3350 pub fn supports_prompt_caching(self) -> bool {
3351 match self {
3352 Self::Glm45v | Self::Glm46v => false,
3353 Self::Glm45
3354 | Self::Glm45Air
3355 | Self::Glm45Flash
3356 | Self::Glm46
3357 | Self::Glm47
3358 | Self::Glm47Flash
3359 | Self::Glm47Flashx
3360 | Self::Glm5
3361 | Self::Glm5Turbo
3362 | Self::Glm51
3363 | Self::Glm5vTurbo => true,
3364 }
3365 }
3366 #[allow(clippy::too_many_lines)]
3367 pub fn supports_image(self) -> bool {
3368 match self {
3369 Self::Glm45
3370 | Self::Glm45Air
3371 | Self::Glm45Flash
3372 | Self::Glm46
3373 | Self::Glm47
3374 | Self::Glm47Flash
3375 | Self::Glm47Flashx
3376 | Self::Glm5
3377 | Self::Glm5Turbo
3378 | Self::Glm51 => false,
3379 Self::Glm45v | Self::Glm46v | Self::Glm5vTurbo => true,
3380 }
3381 }
3382 #[allow(clippy::too_many_lines)]
3383 pub fn supports_audio(self) -> bool {
3384 match self {
3385 Self::Glm45
3386 | Self::Glm45Air
3387 | Self::Glm45Flash
3388 | Self::Glm45v
3389 | Self::Glm46
3390 | Self::Glm46v
3391 | Self::Glm47
3392 | Self::Glm47Flash
3393 | Self::Glm47Flashx
3394 | Self::Glm5
3395 | Self::Glm5Turbo
3396 | Self::Glm51
3397 | Self::Glm5vTurbo => false,
3398 }
3399 }
3400 const ALL: &[ZAiModel] = &[
3401 Self::Glm45,
3402 Self::Glm45Air,
3403 Self::Glm45Flash,
3404 Self::Glm45v,
3405 Self::Glm46,
3406 Self::Glm46v,
3407 Self::Glm47,
3408 Self::Glm47Flash,
3409 Self::Glm47Flashx,
3410 Self::Glm5,
3411 Self::Glm5Turbo,
3412 Self::Glm51,
3413 Self::Glm5vTurbo,
3414 ];
3415}
3416impl std::str::FromStr for ZAiModel {
3417 type Err = String;
3418 #[allow(clippy::too_many_lines)]
3419 fn from_str(s: &str) -> Result<Self, Self::Err> {
3420 match s {
3421 "glm-4.5" => Ok(Self::Glm45),
3422 "glm-4.5-air" => Ok(Self::Glm45Air),
3423 "glm-4.5-flash" => Ok(Self::Glm45Flash),
3424 "glm-4.5v" => Ok(Self::Glm45v),
3425 "glm-4.6" => Ok(Self::Glm46),
3426 "glm-4.6v" => Ok(Self::Glm46v),
3427 "glm-4.7" => Ok(Self::Glm47),
3428 "glm-4.7-flash" => Ok(Self::Glm47Flash),
3429 "glm-4.7-flashx" => Ok(Self::Glm47Flashx),
3430 "glm-5" => Ok(Self::Glm5),
3431 "glm-5-turbo" => Ok(Self::Glm5Turbo),
3432 "glm-5.1" => Ok(Self::Glm51),
3433 "glm-5v-turbo" => Ok(Self::Glm5vTurbo),
3434 _ => Err(format!("Unknown zai model: '{s}'")),
3435 }
3436 }
3437}
3438impl BedrockFoundationModel {
3439 #[allow(clippy::too_many_lines)]
3440 fn model_id(self) -> &'static str {
3441 match self {
3442 Self::AmazonNova2LiteV10 => "amazon.nova-2-lite-v1:0",
3443 Self::AmazonNovaLiteV10 => "amazon.nova-lite-v1:0",
3444 Self::AmazonNovaMicroV10 => "amazon.nova-micro-v1:0",
3445 Self::AmazonNovaProV10 => "amazon.nova-pro-v1:0",
3446 Self::AnthropicClaudeHaiku4520251001V10 => {
3447 "anthropic.claude-haiku-4-5-20251001-v1:0"
3448 }
3449 Self::AnthropicClaudeOpus4120250805V10 => {
3450 "anthropic.claude-opus-4-1-20250805-v1:0"
3451 }
3452 Self::AnthropicClaudeOpus4520251101V10 => {
3453 "anthropic.claude-opus-4-5-20251101-v1:0"
3454 }
3455 Self::AnthropicClaudeOpus46V1 => "anthropic.claude-opus-4-6-v1",
3456 Self::AnthropicClaudeOpus47 => "anthropic.claude-opus-4-7",
3457 Self::AnthropicClaudeSonnet4520250929V10 => {
3458 "anthropic.claude-sonnet-4-5-20250929-v1:0"
3459 }
3460 Self::AnthropicClaudeSonnet46 => "anthropic.claude-sonnet-4-6",
3461 Self::AuAnthropicClaudeHaiku4520251001V10 => {
3462 "au.anthropic.claude-haiku-4-5-20251001-v1:0"
3463 }
3464 Self::AuAnthropicClaudeOpus46V1 => "au.anthropic.claude-opus-4-6-v1",
3465 Self::AuAnthropicClaudeSonnet4520250929V10 => {
3466 "au.anthropic.claude-sonnet-4-5-20250929-v1:0"
3467 }
3468 Self::AuAnthropicClaudeSonnet46 => "au.anthropic.claude-sonnet-4-6",
3469 Self::DeepseekR1V10 => "deepseek.r1-v1:0",
3470 Self::DeepseekV3V10 => "deepseek.v3-v1:0",
3471 Self::DeepseekV32 => "deepseek.v3.2",
3472 Self::EuAnthropicClaudeHaiku4520251001V10 => {
3473 "eu.anthropic.claude-haiku-4-5-20251001-v1:0"
3474 }
3475 Self::EuAnthropicClaudeOpus4520251101V10 => {
3476 "eu.anthropic.claude-opus-4-5-20251101-v1:0"
3477 }
3478 Self::EuAnthropicClaudeOpus46V1 => "eu.anthropic.claude-opus-4-6-v1",
3479 Self::EuAnthropicClaudeOpus47 => "eu.anthropic.claude-opus-4-7",
3480 Self::EuAnthropicClaudeSonnet4520250929V10 => {
3481 "eu.anthropic.claude-sonnet-4-5-20250929-v1:0"
3482 }
3483 Self::EuAnthropicClaudeSonnet46 => "eu.anthropic.claude-sonnet-4-6",
3484 Self::GlobalAnthropicClaudeHaiku4520251001V10 => {
3485 "global.anthropic.claude-haiku-4-5-20251001-v1:0"
3486 }
3487 Self::GlobalAnthropicClaudeOpus4520251101V10 => {
3488 "global.anthropic.claude-opus-4-5-20251101-v1:0"
3489 }
3490 Self::GlobalAnthropicClaudeOpus46V1 => "global.anthropic.claude-opus-4-6-v1",
3491 Self::GlobalAnthropicClaudeOpus47 => "global.anthropic.claude-opus-4-7",
3492 Self::GlobalAnthropicClaudeSonnet4520250929V10 => {
3493 "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
3494 }
3495 Self::GlobalAnthropicClaudeSonnet46 => "global.anthropic.claude-sonnet-4-6",
3496 Self::GoogleGemma327bIt => "google.gemma-3-27b-it",
3497 Self::GoogleGemma34bIt => "google.gemma-3-4b-it",
3498 Self::JpAnthropicClaudeOpus47 => "jp.anthropic.claude-opus-4-7",
3499 Self::JpAnthropicClaudeSonnet4520250929V10 => {
3500 "jp.anthropic.claude-sonnet-4-5-20250929-v1:0"
3501 }
3502 Self::JpAnthropicClaudeSonnet46 => "jp.anthropic.claude-sonnet-4-6",
3503 Self::MetaLlama3170bInstructV10 => "meta.llama3-1-70b-instruct-v1:0",
3504 Self::MetaLlama318bInstructV10 => "meta.llama3-1-8b-instruct-v1:0",
3505 Self::MetaLlama3370bInstructV10 => "meta.llama3-3-70b-instruct-v1:0",
3506 Self::MetaLlama4Maverick17bInstructV10 => {
3507 "meta.llama4-maverick-17b-instruct-v1:0"
3508 }
3509 Self::MetaLlama4Scout17bInstructV10 => "meta.llama4-scout-17b-instruct-v1:0",
3510 Self::MinimaxMinimaxM2 => "minimax.minimax-m2",
3511 Self::MinimaxMinimaxM21 => "minimax.minimax-m2.1",
3512 Self::MinimaxMinimaxM25 => "minimax.minimax-m2.5",
3513 Self::MistralDevstral2123b => "mistral.devstral-2-123b",
3514 Self::MistralMagistralSmall2509 => "mistral.magistral-small-2509",
3515 Self::MistralMinistral314bInstruct => "mistral.ministral-3-14b-instruct",
3516 Self::MistralMinistral33bInstruct => "mistral.ministral-3-3b-instruct",
3517 Self::MistralMinistral38bInstruct => "mistral.ministral-3-8b-instruct",
3518 Self::MistralMistralLarge3675bInstruct => {
3519 "mistral.mistral-large-3-675b-instruct"
3520 }
3521 Self::MistralPixtralLarge2502V10 => "mistral.pixtral-large-2502-v1:0",
3522 Self::MistralVoxtralMini3b2507 => "mistral.voxtral-mini-3b-2507",
3523 Self::MistralVoxtralSmall24b2507 => "mistral.voxtral-small-24b-2507",
3524 Self::MoonshotKimiK2Thinking => "moonshot.kimi-k2-thinking",
3525 Self::MoonshotaiKimiK25 => "moonshotai.kimi-k2.5",
3526 Self::NvidiaNemotronNano12bV2 => "nvidia.nemotron-nano-12b-v2",
3527 Self::NvidiaNemotronNano330b => "nvidia.nemotron-nano-3-30b",
3528 Self::NvidiaNemotronNano9bV2 => "nvidia.nemotron-nano-9b-v2",
3529 Self::NvidiaNemotronSuper3120b => "nvidia.nemotron-super-3-120b",
3530 Self::OpenaiGptOss120b10 => "openai.gpt-oss-120b-1:0",
3531 Self::OpenaiGptOss20b10 => "openai.gpt-oss-20b-1:0",
3532 Self::OpenaiGptOssSafeguard120b => "openai.gpt-oss-safeguard-120b",
3533 Self::OpenaiGptOssSafeguard20b => "openai.gpt-oss-safeguard-20b",
3534 Self::QwenQwen3235bA22b2507V10 => "qwen.qwen3-235b-a22b-2507-v1:0",
3535 Self::QwenQwen332bV10 => "qwen.qwen3-32b-v1:0",
3536 Self::QwenQwen3Coder30bA3bV10 => "qwen.qwen3-coder-30b-a3b-v1:0",
3537 Self::QwenQwen3Coder480bA35bV10 => "qwen.qwen3-coder-480b-a35b-v1:0",
3538 Self::QwenQwen3CoderNext => "qwen.qwen3-coder-next",
3539 Self::QwenQwen3Next80bA3b => "qwen.qwen3-next-80b-a3b",
3540 Self::QwenQwen3Vl235bA22b => "qwen.qwen3-vl-235b-a22b",
3541 Self::UsAnthropicClaudeHaiku4520251001V10 => {
3542 "us.anthropic.claude-haiku-4-5-20251001-v1:0"
3543 }
3544 Self::UsAnthropicClaudeOpus4120250805V10 => {
3545 "us.anthropic.claude-opus-4-1-20250805-v1:0"
3546 }
3547 Self::UsAnthropicClaudeOpus4520251101V10 => {
3548 "us.anthropic.claude-opus-4-5-20251101-v1:0"
3549 }
3550 Self::UsAnthropicClaudeOpus46V1 => "us.anthropic.claude-opus-4-6-v1",
3551 Self::UsAnthropicClaudeOpus47 => "us.anthropic.claude-opus-4-7",
3552 Self::UsAnthropicClaudeSonnet4520250929V10 => {
3553 "us.anthropic.claude-sonnet-4-5-20250929-v1:0"
3554 }
3555 Self::UsAnthropicClaudeSonnet46 => "us.anthropic.claude-sonnet-4-6",
3556 Self::UsDeepseekR1V10 => "us.deepseek.r1-v1:0",
3557 Self::UsMetaLlama4Maverick17bInstructV10 => {
3558 "us.meta.llama4-maverick-17b-instruct-v1:0"
3559 }
3560 Self::UsMetaLlama4Scout17bInstructV10 => {
3561 "us.meta.llama4-scout-17b-instruct-v1:0"
3562 }
3563 Self::WriterPalmyraX4V10 => "writer.palmyra-x4-v1:0",
3564 Self::WriterPalmyraX5V10 => "writer.palmyra-x5-v1:0",
3565 Self::ZaiGlm47 => "zai.glm-4.7",
3566 Self::ZaiGlm47Flash => "zai.glm-4.7-flash",
3567 Self::ZaiGlm5 => "zai.glm-5",
3568 }
3569 }
3570 #[allow(clippy::too_many_lines)]
3571 fn display_name(self) -> &'static str {
3572 match self {
3573 Self::AuAnthropicClaudeOpus46V1 => "AU Anthropic Claude Opus 4.6",
3574 Self::AuAnthropicClaudeSonnet46 => "AU Anthropic Claude Sonnet 4.6",
3575 Self::AnthropicClaudeHaiku4520251001V10 => "Claude Haiku 4.5",
3576 Self::AuAnthropicClaudeHaiku4520251001V10 => "Claude Haiku 4.5 (AU)",
3577 Self::EuAnthropicClaudeHaiku4520251001V10 => "Claude Haiku 4.5 (EU)",
3578 Self::GlobalAnthropicClaudeHaiku4520251001V10 => "Claude Haiku 4.5 (Global)",
3579 Self::UsAnthropicClaudeHaiku4520251001V10 => "Claude Haiku 4.5 (US)",
3580 Self::AnthropicClaudeOpus4120250805V10 => "Claude Opus 4.1",
3581 Self::UsAnthropicClaudeOpus4120250805V10 => "Claude Opus 4.1 (US)",
3582 Self::AnthropicClaudeOpus4520251101V10 => "Claude Opus 4.5",
3583 Self::EuAnthropicClaudeOpus4520251101V10 => "Claude Opus 4.5 (EU)",
3584 Self::GlobalAnthropicClaudeOpus4520251101V10 => "Claude Opus 4.5 (Global)",
3585 Self::UsAnthropicClaudeOpus4520251101V10 => "Claude Opus 4.5 (US)",
3586 Self::AnthropicClaudeOpus46V1 => "Claude Opus 4.6",
3587 Self::EuAnthropicClaudeOpus46V1 => "Claude Opus 4.6 (EU)",
3588 Self::GlobalAnthropicClaudeOpus46V1 => "Claude Opus 4.6 (Global)",
3589 Self::UsAnthropicClaudeOpus46V1 => "Claude Opus 4.6 (US)",
3590 Self::AnthropicClaudeOpus47 => "Claude Opus 4.7",
3591 Self::EuAnthropicClaudeOpus47 => "Claude Opus 4.7 (EU)",
3592 Self::GlobalAnthropicClaudeOpus47 => "Claude Opus 4.7 (Global)",
3593 Self::JpAnthropicClaudeOpus47 => "Claude Opus 4.7 (JP)",
3594 Self::UsAnthropicClaudeOpus47 => "Claude Opus 4.7 (US)",
3595 Self::AnthropicClaudeSonnet4520250929V10 => "Claude Sonnet 4.5",
3596 Self::AuAnthropicClaudeSonnet4520250929V10 => "Claude Sonnet 4.5 (AU)",
3597 Self::EuAnthropicClaudeSonnet4520250929V10 => "Claude Sonnet 4.5 (EU)",
3598 Self::GlobalAnthropicClaudeSonnet4520250929V10 => {
3599 "Claude Sonnet 4.5 (Global)"
3600 }
3601 Self::JpAnthropicClaudeSonnet4520250929V10 => "Claude Sonnet 4.5 (JP)",
3602 Self::UsAnthropicClaudeSonnet4520250929V10 => "Claude Sonnet 4.5 (US)",
3603 Self::AnthropicClaudeSonnet46 => "Claude Sonnet 4.6",
3604 Self::EuAnthropicClaudeSonnet46 => "Claude Sonnet 4.6 (EU)",
3605 Self::GlobalAnthropicClaudeSonnet46 => "Claude Sonnet 4.6 (Global)",
3606 Self::JpAnthropicClaudeSonnet46 => "Claude Sonnet 4.6 (JP)",
3607 Self::UsAnthropicClaudeSonnet46 => "Claude Sonnet 4.6 (US)",
3608 Self::DeepseekR1V10 => "DeepSeek-R1",
3609 Self::UsDeepseekR1V10 => "DeepSeek-R1 (US)",
3610 Self::DeepseekV3V10 => "DeepSeek-V3.1",
3611 Self::DeepseekV32 => "DeepSeek-V3.2",
3612 Self::MistralDevstral2123b => "Devstral 2 123B",
3613 Self::ZaiGlm47 => "GLM-4.7",
3614 Self::ZaiGlm47Flash => "GLM-4.7-Flash",
3615 Self::ZaiGlm5 => "GLM-5",
3616 Self::OpenaiGptOssSafeguard120b => "GPT OSS Safeguard 120B",
3617 Self::OpenaiGptOssSafeguard20b => "GPT OSS Safeguard 20B",
3618 Self::GoogleGemma34bIt => "Gemma 3 4B IT",
3619 Self::GoogleGemma327bIt => "Google Gemma 3 27B Instruct",
3620 Self::MoonshotKimiK2Thinking => "Kimi K2 Thinking",
3621 Self::MoonshotaiKimiK25 => "Kimi K2.5",
3622 Self::MetaLlama3170bInstructV10 => "Llama 3.1 70B Instruct",
3623 Self::MetaLlama318bInstructV10 => "Llama 3.1 8B Instruct",
3624 Self::MetaLlama3370bInstructV10 => "Llama 3.3 70B Instruct",
3625 Self::MetaLlama4Maverick17bInstructV10 => "Llama 4 Maverick 17B Instruct",
3626 Self::UsMetaLlama4Maverick17bInstructV10 => {
3627 "Llama 4 Maverick 17B Instruct (US)"
3628 }
3629 Self::MetaLlama4Scout17bInstructV10 => "Llama 4 Scout 17B Instruct",
3630 Self::UsMetaLlama4Scout17bInstructV10 => "Llama 4 Scout 17B Instruct (US)",
3631 Self::MistralMagistralSmall2509 => "Magistral Small 1.2",
3632 Self::MinimaxMinimaxM2 => "MiniMax M2",
3633 Self::MinimaxMinimaxM21 => "MiniMax M2.1",
3634 Self::MinimaxMinimaxM25 => "MiniMax M2.5",
3635 Self::MistralMinistral314bInstruct => "Ministral 14B 3.0",
3636 Self::MistralMinistral33bInstruct => "Ministral 3 3B",
3637 Self::MistralMinistral38bInstruct => "Ministral 3 8B",
3638 Self::MistralMistralLarge3675bInstruct => "Mistral Large 3",
3639 Self::NvidiaNemotronSuper3120b => "NVIDIA Nemotron 3 Super 120B A12B",
3640 Self::NvidiaNemotronNano12bV2 => "NVIDIA Nemotron Nano 12B v2 VL BF16",
3641 Self::NvidiaNemotronNano330b => "NVIDIA Nemotron Nano 3 30B",
3642 Self::NvidiaNemotronNano9bV2 => "NVIDIA Nemotron Nano 9B v2",
3643 Self::AmazonNova2LiteV10 => "Nova 2 Lite",
3644 Self::AmazonNovaLiteV10 => "Nova Lite",
3645 Self::AmazonNovaMicroV10 => "Nova Micro",
3646 Self::AmazonNovaProV10 => "Nova Pro",
3647 Self::WriterPalmyraX4V10 => "Palmyra X4",
3648 Self::WriterPalmyraX5V10 => "Palmyra X5",
3649 Self::MistralPixtralLarge2502V10 => "Pixtral Large (25.02)",
3650 Self::QwenQwen3Next80bA3b => "Qwen/Qwen3-Next-80B-A3B-Instruct",
3651 Self::QwenQwen3Vl235bA22b => "Qwen/Qwen3-VL-235B-A22B-Instruct",
3652 Self::QwenQwen3235bA22b2507V10 => "Qwen3 235B A22B 2507",
3653 Self::QwenQwen332bV10 => "Qwen3 32B (dense)",
3654 Self::QwenQwen3Coder30bA3bV10 => "Qwen3 Coder 30B A3B Instruct",
3655 Self::QwenQwen3Coder480bA35bV10 => "Qwen3 Coder 480B A35B Instruct",
3656 Self::QwenQwen3CoderNext => "Qwen3 Coder Next",
3657 Self::MistralVoxtralMini3b2507 => "Voxtral Mini 3B 2507",
3658 Self::MistralVoxtralSmall24b2507 => "Voxtral Small 24B 2507",
3659 Self::OpenaiGptOss120b10 => "gpt-oss-120b",
3660 Self::OpenaiGptOss20b10 => "gpt-oss-20b",
3661 }
3662 }
3663 #[allow(clippy::too_many_lines)]
3664 fn context_window(self) -> u32 {
3665 match self {
3666 Self::QwenQwen332bV10 => 16_384,
3667 Self::MistralVoxtralSmall24b2507 => 32_000,
3668 Self::WriterPalmyraX4V10 => 122_880,
3669 Self::AmazonNova2LiteV10
3670 | Self::AmazonNovaMicroV10
3671 | Self::DeepseekR1V10
3672 | Self::GoogleGemma34bIt
3673 | Self::MetaLlama3170bInstructV10
3674 | Self::MetaLlama318bInstructV10
3675 | Self::MetaLlama3370bInstructV10
3676 | Self::MistralMagistralSmall2509
3677 | Self::MistralMinistral314bInstruct
3678 | Self::MistralMinistral38bInstruct
3679 | Self::MistralPixtralLarge2502V10
3680 | Self::MistralVoxtralMini3b2507
3681 | Self::NvidiaNemotronNano12bV2
3682 | Self::NvidiaNemotronNano330b
3683 | Self::NvidiaNemotronNano9bV2
3684 | Self::OpenaiGptOss120b10
3685 | Self::OpenaiGptOss20b10
3686 | Self::OpenaiGptOssSafeguard120b
3687 | Self::OpenaiGptOssSafeguard20b
3688 | Self::UsDeepseekR1V10 => 128_000,
3689 Self::QwenQwen3Coder480bA35bV10 | Self::QwenQwen3CoderNext => 131_072,
3690 Self::DeepseekV3V10 | Self::DeepseekV32 => 163_840,
3691 Self::MinimaxMinimaxM25 => 196_608,
3692 Self::AnthropicClaudeHaiku4520251001V10
3693 | Self::AnthropicClaudeOpus4120250805V10
3694 | Self::AnthropicClaudeOpus4520251101V10
3695 | Self::AnthropicClaudeSonnet4520250929V10
3696 | Self::AuAnthropicClaudeHaiku4520251001V10
3697 | Self::AuAnthropicClaudeSonnet4520250929V10
3698 | Self::EuAnthropicClaudeHaiku4520251001V10
3699 | Self::EuAnthropicClaudeOpus4520251101V10
3700 | Self::EuAnthropicClaudeSonnet4520250929V10
3701 | Self::GlobalAnthropicClaudeHaiku4520251001V10
3702 | Self::GlobalAnthropicClaudeOpus4520251101V10
3703 | Self::GlobalAnthropicClaudeSonnet4520250929V10
3704 | Self::JpAnthropicClaudeSonnet4520250929V10
3705 | Self::UsAnthropicClaudeHaiku4520251001V10
3706 | Self::UsAnthropicClaudeOpus4120250805V10
3707 | Self::UsAnthropicClaudeOpus4520251101V10
3708 | Self::UsAnthropicClaudeSonnet4520250929V10
3709 | Self::ZaiGlm47Flash => 200_000,
3710 Self::GoogleGemma327bIt | Self::ZaiGlm5 => 202_752,
3711 Self::MinimaxMinimaxM2 => 204_608,
3712 Self::MinimaxMinimaxM21 | Self::ZaiGlm47 => 204_800,
3713 Self::MistralDevstral2123b
3714 | Self::MistralMinistral33bInstruct
3715 | Self::MistralMistralLarge3675bInstruct
3716 | Self::MoonshotKimiK2Thinking
3717 | Self::MoonshotaiKimiK25 => 256_000,
3718 Self::QwenQwen3Next80bA3b | Self::QwenQwen3Vl235bA22b => 262_000,
3719 Self::NvidiaNemotronSuper3120b
3720 | Self::QwenQwen3235bA22b2507V10
3721 | Self::QwenQwen3Coder30bA3bV10 => 262_144,
3722 Self::AmazonNovaLiteV10 | Self::AmazonNovaProV10 => 300_000,
3723 Self::AnthropicClaudeOpus46V1
3724 | Self::AnthropicClaudeOpus47
3725 | Self::AnthropicClaudeSonnet46
3726 | Self::AuAnthropicClaudeOpus46V1
3727 | Self::AuAnthropicClaudeSonnet46
3728 | Self::EuAnthropicClaudeOpus46V1
3729 | Self::EuAnthropicClaudeOpus47
3730 | Self::EuAnthropicClaudeSonnet46
3731 | Self::GlobalAnthropicClaudeOpus46V1
3732 | Self::GlobalAnthropicClaudeOpus47
3733 | Self::GlobalAnthropicClaudeSonnet46
3734 | Self::JpAnthropicClaudeOpus47
3735 | Self::JpAnthropicClaudeSonnet46
3736 | Self::MetaLlama4Maverick17bInstructV10
3737 | Self::UsAnthropicClaudeOpus46V1
3738 | Self::UsAnthropicClaudeOpus47
3739 | Self::UsAnthropicClaudeSonnet46
3740 | Self::UsMetaLlama4Maverick17bInstructV10 => 1_000_000,
3741 Self::WriterPalmyraX5V10 => 1_040_000,
3742 Self::MetaLlama4Scout17bInstructV10
3743 | Self::UsMetaLlama4Scout17bInstructV10 => 3_500_000,
3744 }
3745 }
3746 #[allow(clippy::too_many_lines)]
3747 pub fn reasoning_levels(self) -> &'static [ReasoningEffort] {
3748 match self {
3749 Self::AmazonNova2LiteV10
3750 | Self::AmazonNovaLiteV10
3751 | Self::AmazonNovaMicroV10
3752 | Self::AmazonNovaProV10
3753 | Self::GoogleGemma327bIt
3754 | Self::GoogleGemma34bIt
3755 | Self::MetaLlama3170bInstructV10
3756 | Self::MetaLlama318bInstructV10
3757 | Self::MetaLlama3370bInstructV10
3758 | Self::MetaLlama4Maverick17bInstructV10
3759 | Self::MetaLlama4Scout17bInstructV10
3760 | Self::MistralDevstral2123b
3761 | Self::MistralMinistral314bInstruct
3762 | Self::MistralMinistral33bInstruct
3763 | Self::MistralMinistral38bInstruct
3764 | Self::MistralMistralLarge3675bInstruct
3765 | Self::MistralPixtralLarge2502V10
3766 | Self::MistralVoxtralMini3b2507
3767 | Self::MistralVoxtralSmall24b2507
3768 | Self::NvidiaNemotronNano12bV2
3769 | Self::NvidiaNemotronNano9bV2
3770 | Self::OpenaiGptOss120b10
3771 | Self::OpenaiGptOss20b10
3772 | Self::OpenaiGptOssSafeguard120b
3773 | Self::OpenaiGptOssSafeguard20b
3774 | Self::QwenQwen3235bA22b2507V10
3775 | Self::QwenQwen3Coder30bA3bV10
3776 | Self::QwenQwen3Coder480bA35bV10
3777 | Self::QwenQwen3Next80bA3b
3778 | Self::QwenQwen3Vl235bA22b
3779 | Self::UsMetaLlama4Maverick17bInstructV10
3780 | Self::UsMetaLlama4Scout17bInstructV10 => &[],
3781 Self::AnthropicClaudeHaiku4520251001V10
3782 | Self::AnthropicClaudeOpus4120250805V10
3783 | Self::AnthropicClaudeOpus4520251101V10
3784 | Self::AnthropicClaudeOpus46V1
3785 | Self::AnthropicClaudeOpus47
3786 | Self::AnthropicClaudeSonnet4520250929V10
3787 | Self::AnthropicClaudeSonnet46
3788 | Self::AuAnthropicClaudeHaiku4520251001V10
3789 | Self::AuAnthropicClaudeOpus46V1
3790 | Self::AuAnthropicClaudeSonnet4520250929V10
3791 | Self::AuAnthropicClaudeSonnet46
3792 | Self::DeepseekR1V10
3793 | Self::DeepseekV3V10
3794 | Self::DeepseekV32
3795 | Self::EuAnthropicClaudeHaiku4520251001V10
3796 | Self::EuAnthropicClaudeOpus4520251101V10
3797 | Self::EuAnthropicClaudeOpus46V1
3798 | Self::EuAnthropicClaudeOpus47
3799 | Self::EuAnthropicClaudeSonnet4520250929V10
3800 | Self::EuAnthropicClaudeSonnet46
3801 | Self::GlobalAnthropicClaudeHaiku4520251001V10
3802 | Self::GlobalAnthropicClaudeOpus4520251101V10
3803 | Self::GlobalAnthropicClaudeOpus46V1
3804 | Self::GlobalAnthropicClaudeOpus47
3805 | Self::GlobalAnthropicClaudeSonnet4520250929V10
3806 | Self::GlobalAnthropicClaudeSonnet46
3807 | Self::JpAnthropicClaudeOpus47
3808 | Self::JpAnthropicClaudeSonnet4520250929V10
3809 | Self::JpAnthropicClaudeSonnet46
3810 | Self::MinimaxMinimaxM2
3811 | Self::MinimaxMinimaxM21
3812 | Self::MinimaxMinimaxM25
3813 | Self::MistralMagistralSmall2509
3814 | Self::MoonshotKimiK2Thinking
3815 | Self::MoonshotaiKimiK25
3816 | Self::NvidiaNemotronNano330b
3817 | Self::NvidiaNemotronSuper3120b
3818 | Self::QwenQwen332bV10
3819 | Self::QwenQwen3CoderNext
3820 | Self::UsAnthropicClaudeHaiku4520251001V10
3821 | Self::UsAnthropicClaudeOpus4120250805V10
3822 | Self::UsAnthropicClaudeOpus4520251101V10
3823 | Self::UsAnthropicClaudeOpus46V1
3824 | Self::UsAnthropicClaudeOpus47
3825 | Self::UsAnthropicClaudeSonnet4520250929V10
3826 | Self::UsAnthropicClaudeSonnet46
3827 | Self::UsDeepseekR1V10
3828 | Self::WriterPalmyraX4V10
3829 | Self::WriterPalmyraX5V10
3830 | Self::ZaiGlm47
3831 | Self::ZaiGlm47Flash
3832 | Self::ZaiGlm5 => {
3833 &[ReasoningEffort::Low, ReasoningEffort::Medium, ReasoningEffort::High]
3834 }
3835 }
3836 }
3837 pub fn supports_reasoning(self) -> bool {
3838 !self.reasoning_levels().is_empty()
3839 }
3840 #[allow(clippy::too_many_lines)]
3841 pub fn supports_prompt_caching(self) -> bool {
3842 match self {
3843 Self::AmazonNova2LiteV10
3844 | Self::DeepseekR1V10
3845 | Self::DeepseekV3V10
3846 | Self::DeepseekV32
3847 | Self::GoogleGemma327bIt
3848 | Self::GoogleGemma34bIt
3849 | Self::MetaLlama3170bInstructV10
3850 | Self::MetaLlama318bInstructV10
3851 | Self::MetaLlama3370bInstructV10
3852 | Self::MetaLlama4Maverick17bInstructV10
3853 | Self::MetaLlama4Scout17bInstructV10
3854 | Self::MinimaxMinimaxM2
3855 | Self::MinimaxMinimaxM21
3856 | Self::MinimaxMinimaxM25
3857 | Self::MistralDevstral2123b
3858 | Self::MistralMagistralSmall2509
3859 | Self::MistralMinistral314bInstruct
3860 | Self::MistralMinistral33bInstruct
3861 | Self::MistralMinistral38bInstruct
3862 | Self::MistralMistralLarge3675bInstruct
3863 | Self::MistralPixtralLarge2502V10
3864 | Self::MistralVoxtralMini3b2507
3865 | Self::MistralVoxtralSmall24b2507
3866 | Self::MoonshotKimiK2Thinking
3867 | Self::MoonshotaiKimiK25
3868 | Self::NvidiaNemotronNano12bV2
3869 | Self::NvidiaNemotronNano330b
3870 | Self::NvidiaNemotronNano9bV2
3871 | Self::NvidiaNemotronSuper3120b
3872 | Self::OpenaiGptOss120b10
3873 | Self::OpenaiGptOss20b10
3874 | Self::OpenaiGptOssSafeguard120b
3875 | Self::OpenaiGptOssSafeguard20b
3876 | Self::QwenQwen3235bA22b2507V10
3877 | Self::QwenQwen332bV10
3878 | Self::QwenQwen3Coder30bA3bV10
3879 | Self::QwenQwen3Coder480bA35bV10
3880 | Self::QwenQwen3CoderNext
3881 | Self::QwenQwen3Next80bA3b
3882 | Self::QwenQwen3Vl235bA22b
3883 | Self::UsDeepseekR1V10
3884 | Self::UsMetaLlama4Maverick17bInstructV10
3885 | Self::UsMetaLlama4Scout17bInstructV10
3886 | Self::WriterPalmyraX4V10
3887 | Self::WriterPalmyraX5V10
3888 | Self::ZaiGlm47
3889 | Self::ZaiGlm47Flash
3890 | Self::ZaiGlm5 => false,
3891 Self::AmazonNovaLiteV10
3892 | Self::AmazonNovaMicroV10
3893 | Self::AmazonNovaProV10
3894 | Self::AnthropicClaudeHaiku4520251001V10
3895 | Self::AnthropicClaudeOpus4120250805V10
3896 | Self::AnthropicClaudeOpus4520251101V10
3897 | Self::AnthropicClaudeOpus46V1
3898 | Self::AnthropicClaudeOpus47
3899 | Self::AnthropicClaudeSonnet4520250929V10
3900 | Self::AnthropicClaudeSonnet46
3901 | Self::AuAnthropicClaudeHaiku4520251001V10
3902 | Self::AuAnthropicClaudeOpus46V1
3903 | Self::AuAnthropicClaudeSonnet4520250929V10
3904 | Self::AuAnthropicClaudeSonnet46
3905 | Self::EuAnthropicClaudeHaiku4520251001V10
3906 | Self::EuAnthropicClaudeOpus4520251101V10
3907 | Self::EuAnthropicClaudeOpus46V1
3908 | Self::EuAnthropicClaudeOpus47
3909 | Self::EuAnthropicClaudeSonnet4520250929V10
3910 | Self::EuAnthropicClaudeSonnet46
3911 | Self::GlobalAnthropicClaudeHaiku4520251001V10
3912 | Self::GlobalAnthropicClaudeOpus4520251101V10
3913 | Self::GlobalAnthropicClaudeOpus46V1
3914 | Self::GlobalAnthropicClaudeOpus47
3915 | Self::GlobalAnthropicClaudeSonnet4520250929V10
3916 | Self::GlobalAnthropicClaudeSonnet46
3917 | Self::JpAnthropicClaudeOpus47
3918 | Self::JpAnthropicClaudeSonnet4520250929V10
3919 | Self::JpAnthropicClaudeSonnet46
3920 | Self::UsAnthropicClaudeHaiku4520251001V10
3921 | Self::UsAnthropicClaudeOpus4120250805V10
3922 | Self::UsAnthropicClaudeOpus4520251101V10
3923 | Self::UsAnthropicClaudeOpus46V1
3924 | Self::UsAnthropicClaudeOpus47
3925 | Self::UsAnthropicClaudeSonnet4520250929V10
3926 | Self::UsAnthropicClaudeSonnet46 => true,
3927 }
3928 }
3929 #[allow(clippy::too_many_lines)]
3930 pub fn supports_image(self) -> bool {
3931 match self {
3932 Self::AmazonNovaMicroV10
3933 | Self::DeepseekR1V10
3934 | Self::DeepseekV3V10
3935 | Self::DeepseekV32
3936 | Self::MetaLlama3170bInstructV10
3937 | Self::MetaLlama318bInstructV10
3938 | Self::MetaLlama3370bInstructV10
3939 | Self::MinimaxMinimaxM2
3940 | Self::MinimaxMinimaxM21
3941 | Self::MinimaxMinimaxM25
3942 | Self::MistralDevstral2123b
3943 | Self::MistralMinistral314bInstruct
3944 | Self::MistralMinistral38bInstruct
3945 | Self::MistralVoxtralMini3b2507
3946 | Self::MistralVoxtralSmall24b2507
3947 | Self::MoonshotKimiK2Thinking
3948 | Self::NvidiaNemotronNano330b
3949 | Self::NvidiaNemotronNano9bV2
3950 | Self::NvidiaNemotronSuper3120b
3951 | Self::OpenaiGptOss120b10
3952 | Self::OpenaiGptOss20b10
3953 | Self::OpenaiGptOssSafeguard120b
3954 | Self::OpenaiGptOssSafeguard20b
3955 | Self::QwenQwen3235bA22b2507V10
3956 | Self::QwenQwen332bV10
3957 | Self::QwenQwen3Coder30bA3bV10
3958 | Self::QwenQwen3Coder480bA35bV10
3959 | Self::QwenQwen3CoderNext
3960 | Self::QwenQwen3Next80bA3b
3961 | Self::UsDeepseekR1V10
3962 | Self::WriterPalmyraX4V10
3963 | Self::WriterPalmyraX5V10
3964 | Self::ZaiGlm47
3965 | Self::ZaiGlm47Flash
3966 | Self::ZaiGlm5 => false,
3967 Self::AmazonNova2LiteV10
3968 | Self::AmazonNovaLiteV10
3969 | Self::AmazonNovaProV10
3970 | Self::AnthropicClaudeHaiku4520251001V10
3971 | Self::AnthropicClaudeOpus4120250805V10
3972 | Self::AnthropicClaudeOpus4520251101V10
3973 | Self::AnthropicClaudeOpus46V1
3974 | Self::AnthropicClaudeOpus47
3975 | Self::AnthropicClaudeSonnet4520250929V10
3976 | Self::AnthropicClaudeSonnet46
3977 | Self::AuAnthropicClaudeHaiku4520251001V10
3978 | Self::AuAnthropicClaudeOpus46V1
3979 | Self::AuAnthropicClaudeSonnet4520250929V10
3980 | Self::AuAnthropicClaudeSonnet46
3981 | Self::EuAnthropicClaudeHaiku4520251001V10
3982 | Self::EuAnthropicClaudeOpus4520251101V10
3983 | Self::EuAnthropicClaudeOpus46V1
3984 | Self::EuAnthropicClaudeOpus47
3985 | Self::EuAnthropicClaudeSonnet4520250929V10
3986 | Self::EuAnthropicClaudeSonnet46
3987 | Self::GlobalAnthropicClaudeHaiku4520251001V10
3988 | Self::GlobalAnthropicClaudeOpus4520251101V10
3989 | Self::GlobalAnthropicClaudeOpus46V1
3990 | Self::GlobalAnthropicClaudeOpus47
3991 | Self::GlobalAnthropicClaudeSonnet4520250929V10
3992 | Self::GlobalAnthropicClaudeSonnet46
3993 | Self::GoogleGemma327bIt
3994 | Self::GoogleGemma34bIt
3995 | Self::JpAnthropicClaudeOpus47
3996 | Self::JpAnthropicClaudeSonnet4520250929V10
3997 | Self::JpAnthropicClaudeSonnet46
3998 | Self::MetaLlama4Maverick17bInstructV10
3999 | Self::MetaLlama4Scout17bInstructV10
4000 | Self::MistralMagistralSmall2509
4001 | Self::MistralMinistral33bInstruct
4002 | Self::MistralMistralLarge3675bInstruct
4003 | Self::MistralPixtralLarge2502V10
4004 | Self::MoonshotaiKimiK25
4005 | Self::NvidiaNemotronNano12bV2
4006 | Self::QwenQwen3Vl235bA22b
4007 | Self::UsAnthropicClaudeHaiku4520251001V10
4008 | Self::UsAnthropicClaudeOpus4120250805V10
4009 | Self::UsAnthropicClaudeOpus4520251101V10
4010 | Self::UsAnthropicClaudeOpus46V1
4011 | Self::UsAnthropicClaudeOpus47
4012 | Self::UsAnthropicClaudeSonnet4520250929V10
4013 | Self::UsAnthropicClaudeSonnet46
4014 | Self::UsMetaLlama4Maverick17bInstructV10
4015 | Self::UsMetaLlama4Scout17bInstructV10 => true,
4016 }
4017 }
4018 #[allow(clippy::too_many_lines)]
4019 pub fn supports_audio(self) -> bool {
4020 match self {
4021 Self::AmazonNova2LiteV10
4022 | Self::AmazonNovaLiteV10
4023 | Self::AmazonNovaMicroV10
4024 | Self::AmazonNovaProV10
4025 | Self::AnthropicClaudeHaiku4520251001V10
4026 | Self::AnthropicClaudeOpus4120250805V10
4027 | Self::AnthropicClaudeOpus4520251101V10
4028 | Self::AnthropicClaudeOpus46V1
4029 | Self::AnthropicClaudeOpus47
4030 | Self::AnthropicClaudeSonnet4520250929V10
4031 | Self::AnthropicClaudeSonnet46
4032 | Self::AuAnthropicClaudeHaiku4520251001V10
4033 | Self::AuAnthropicClaudeOpus46V1
4034 | Self::AuAnthropicClaudeSonnet4520250929V10
4035 | Self::AuAnthropicClaudeSonnet46
4036 | Self::DeepseekR1V10
4037 | Self::DeepseekV3V10
4038 | Self::DeepseekV32
4039 | Self::EuAnthropicClaudeHaiku4520251001V10
4040 | Self::EuAnthropicClaudeOpus4520251101V10
4041 | Self::EuAnthropicClaudeOpus46V1
4042 | Self::EuAnthropicClaudeOpus47
4043 | Self::EuAnthropicClaudeSonnet4520250929V10
4044 | Self::EuAnthropicClaudeSonnet46
4045 | Self::GlobalAnthropicClaudeHaiku4520251001V10
4046 | Self::GlobalAnthropicClaudeOpus4520251101V10
4047 | Self::GlobalAnthropicClaudeOpus46V1
4048 | Self::GlobalAnthropicClaudeOpus47
4049 | Self::GlobalAnthropicClaudeSonnet4520250929V10
4050 | Self::GlobalAnthropicClaudeSonnet46
4051 | Self::GoogleGemma327bIt
4052 | Self::GoogleGemma34bIt
4053 | Self::JpAnthropicClaudeOpus47
4054 | Self::JpAnthropicClaudeSonnet4520250929V10
4055 | Self::JpAnthropicClaudeSonnet46
4056 | Self::MetaLlama3170bInstructV10
4057 | Self::MetaLlama318bInstructV10
4058 | Self::MetaLlama3370bInstructV10
4059 | Self::MetaLlama4Maverick17bInstructV10
4060 | Self::MetaLlama4Scout17bInstructV10
4061 | Self::MinimaxMinimaxM2
4062 | Self::MinimaxMinimaxM21
4063 | Self::MinimaxMinimaxM25
4064 | Self::MistralDevstral2123b
4065 | Self::MistralMagistralSmall2509
4066 | Self::MistralMinistral314bInstruct
4067 | Self::MistralMinistral33bInstruct
4068 | Self::MistralMinistral38bInstruct
4069 | Self::MistralMistralLarge3675bInstruct
4070 | Self::MistralPixtralLarge2502V10
4071 | Self::MoonshotKimiK2Thinking
4072 | Self::MoonshotaiKimiK25
4073 | Self::NvidiaNemotronNano12bV2
4074 | Self::NvidiaNemotronNano330b
4075 | Self::NvidiaNemotronNano9bV2
4076 | Self::NvidiaNemotronSuper3120b
4077 | Self::OpenaiGptOss120b10
4078 | Self::OpenaiGptOss20b10
4079 | Self::OpenaiGptOssSafeguard120b
4080 | Self::OpenaiGptOssSafeguard20b
4081 | Self::QwenQwen3235bA22b2507V10
4082 | Self::QwenQwen332bV10
4083 | Self::QwenQwen3Coder30bA3bV10
4084 | Self::QwenQwen3Coder480bA35bV10
4085 | Self::QwenQwen3CoderNext
4086 | Self::QwenQwen3Next80bA3b
4087 | Self::QwenQwen3Vl235bA22b
4088 | Self::UsAnthropicClaudeHaiku4520251001V10
4089 | Self::UsAnthropicClaudeOpus4120250805V10
4090 | Self::UsAnthropicClaudeOpus4520251101V10
4091 | Self::UsAnthropicClaudeOpus46V1
4092 | Self::UsAnthropicClaudeOpus47
4093 | Self::UsAnthropicClaudeSonnet4520250929V10
4094 | Self::UsAnthropicClaudeSonnet46
4095 | Self::UsDeepseekR1V10
4096 | Self::UsMetaLlama4Maverick17bInstructV10
4097 | Self::UsMetaLlama4Scout17bInstructV10
4098 | Self::WriterPalmyraX4V10
4099 | Self::WriterPalmyraX5V10
4100 | Self::ZaiGlm47
4101 | Self::ZaiGlm47Flash
4102 | Self::ZaiGlm5 => false,
4103 Self::MistralVoxtralMini3b2507 | Self::MistralVoxtralSmall24b2507 => true,
4104 }
4105 }
4106 const ALL: &[BedrockFoundationModel] = &[
4107 Self::AmazonNova2LiteV10,
4108 Self::AmazonNovaLiteV10,
4109 Self::AmazonNovaMicroV10,
4110 Self::AmazonNovaProV10,
4111 Self::AnthropicClaudeHaiku4520251001V10,
4112 Self::AnthropicClaudeOpus4120250805V10,
4113 Self::AnthropicClaudeOpus4520251101V10,
4114 Self::AnthropicClaudeOpus46V1,
4115 Self::AnthropicClaudeOpus47,
4116 Self::AnthropicClaudeSonnet4520250929V10,
4117 Self::AnthropicClaudeSonnet46,
4118 Self::AuAnthropicClaudeHaiku4520251001V10,
4119 Self::AuAnthropicClaudeOpus46V1,
4120 Self::AuAnthropicClaudeSonnet4520250929V10,
4121 Self::AuAnthropicClaudeSonnet46,
4122 Self::DeepseekR1V10,
4123 Self::DeepseekV3V10,
4124 Self::DeepseekV32,
4125 Self::EuAnthropicClaudeHaiku4520251001V10,
4126 Self::EuAnthropicClaudeOpus4520251101V10,
4127 Self::EuAnthropicClaudeOpus46V1,
4128 Self::EuAnthropicClaudeOpus47,
4129 Self::EuAnthropicClaudeSonnet4520250929V10,
4130 Self::EuAnthropicClaudeSonnet46,
4131 Self::GlobalAnthropicClaudeHaiku4520251001V10,
4132 Self::GlobalAnthropicClaudeOpus4520251101V10,
4133 Self::GlobalAnthropicClaudeOpus46V1,
4134 Self::GlobalAnthropicClaudeOpus47,
4135 Self::GlobalAnthropicClaudeSonnet4520250929V10,
4136 Self::GlobalAnthropicClaudeSonnet46,
4137 Self::GoogleGemma327bIt,
4138 Self::GoogleGemma34bIt,
4139 Self::JpAnthropicClaudeOpus47,
4140 Self::JpAnthropicClaudeSonnet4520250929V10,
4141 Self::JpAnthropicClaudeSonnet46,
4142 Self::MetaLlama3170bInstructV10,
4143 Self::MetaLlama318bInstructV10,
4144 Self::MetaLlama3370bInstructV10,
4145 Self::MetaLlama4Maverick17bInstructV10,
4146 Self::MetaLlama4Scout17bInstructV10,
4147 Self::MinimaxMinimaxM2,
4148 Self::MinimaxMinimaxM21,
4149 Self::MinimaxMinimaxM25,
4150 Self::MistralDevstral2123b,
4151 Self::MistralMagistralSmall2509,
4152 Self::MistralMinistral314bInstruct,
4153 Self::MistralMinistral33bInstruct,
4154 Self::MistralMinistral38bInstruct,
4155 Self::MistralMistralLarge3675bInstruct,
4156 Self::MistralPixtralLarge2502V10,
4157 Self::MistralVoxtralMini3b2507,
4158 Self::MistralVoxtralSmall24b2507,
4159 Self::MoonshotKimiK2Thinking,
4160 Self::MoonshotaiKimiK25,
4161 Self::NvidiaNemotronNano12bV2,
4162 Self::NvidiaNemotronNano330b,
4163 Self::NvidiaNemotronNano9bV2,
4164 Self::NvidiaNemotronSuper3120b,
4165 Self::OpenaiGptOss120b10,
4166 Self::OpenaiGptOss20b10,
4167 Self::OpenaiGptOssSafeguard120b,
4168 Self::OpenaiGptOssSafeguard20b,
4169 Self::QwenQwen3235bA22b2507V10,
4170 Self::QwenQwen332bV10,
4171 Self::QwenQwen3Coder30bA3bV10,
4172 Self::QwenQwen3Coder480bA35bV10,
4173 Self::QwenQwen3CoderNext,
4174 Self::QwenQwen3Next80bA3b,
4175 Self::QwenQwen3Vl235bA22b,
4176 Self::UsAnthropicClaudeHaiku4520251001V10,
4177 Self::UsAnthropicClaudeOpus4120250805V10,
4178 Self::UsAnthropicClaudeOpus4520251101V10,
4179 Self::UsAnthropicClaudeOpus46V1,
4180 Self::UsAnthropicClaudeOpus47,
4181 Self::UsAnthropicClaudeSonnet4520250929V10,
4182 Self::UsAnthropicClaudeSonnet46,
4183 Self::UsDeepseekR1V10,
4184 Self::UsMetaLlama4Maverick17bInstructV10,
4185 Self::UsMetaLlama4Scout17bInstructV10,
4186 Self::WriterPalmyraX4V10,
4187 Self::WriterPalmyraX5V10,
4188 Self::ZaiGlm47,
4189 Self::ZaiGlm47Flash,
4190 Self::ZaiGlm5,
4191 ];
4192}
4193impl std::str::FromStr for BedrockFoundationModel {
4194 type Err = String;
4195 #[allow(clippy::too_many_lines)]
4196 fn from_str(s: &str) -> Result<Self, Self::Err> {
4197 match s {
4198 "amazon.nova-2-lite-v1:0" => Ok(Self::AmazonNova2LiteV10),
4199 "amazon.nova-lite-v1:0" => Ok(Self::AmazonNovaLiteV10),
4200 "amazon.nova-micro-v1:0" => Ok(Self::AmazonNovaMicroV10),
4201 "amazon.nova-pro-v1:0" => Ok(Self::AmazonNovaProV10),
4202 "anthropic.claude-haiku-4-5-20251001-v1:0" => {
4203 Ok(Self::AnthropicClaudeHaiku4520251001V10)
4204 }
4205 "anthropic.claude-opus-4-1-20250805-v1:0" => {
4206 Ok(Self::AnthropicClaudeOpus4120250805V10)
4207 }
4208 "anthropic.claude-opus-4-5-20251101-v1:0" => {
4209 Ok(Self::AnthropicClaudeOpus4520251101V10)
4210 }
4211 "anthropic.claude-opus-4-6-v1" => Ok(Self::AnthropicClaudeOpus46V1),
4212 "anthropic.claude-opus-4-7" => Ok(Self::AnthropicClaudeOpus47),
4213 "anthropic.claude-sonnet-4-5-20250929-v1:0" => {
4214 Ok(Self::AnthropicClaudeSonnet4520250929V10)
4215 }
4216 "anthropic.claude-sonnet-4-6" => Ok(Self::AnthropicClaudeSonnet46),
4217 "au.anthropic.claude-haiku-4-5-20251001-v1:0" => {
4218 Ok(Self::AuAnthropicClaudeHaiku4520251001V10)
4219 }
4220 "au.anthropic.claude-opus-4-6-v1" => Ok(Self::AuAnthropicClaudeOpus46V1),
4221 "au.anthropic.claude-sonnet-4-5-20250929-v1:0" => {
4222 Ok(Self::AuAnthropicClaudeSonnet4520250929V10)
4223 }
4224 "au.anthropic.claude-sonnet-4-6" => Ok(Self::AuAnthropicClaudeSonnet46),
4225 "deepseek.r1-v1:0" => Ok(Self::DeepseekR1V10),
4226 "deepseek.v3-v1:0" => Ok(Self::DeepseekV3V10),
4227 "deepseek.v3.2" => Ok(Self::DeepseekV32),
4228 "eu.anthropic.claude-haiku-4-5-20251001-v1:0" => {
4229 Ok(Self::EuAnthropicClaudeHaiku4520251001V10)
4230 }
4231 "eu.anthropic.claude-opus-4-5-20251101-v1:0" => {
4232 Ok(Self::EuAnthropicClaudeOpus4520251101V10)
4233 }
4234 "eu.anthropic.claude-opus-4-6-v1" => Ok(Self::EuAnthropicClaudeOpus46V1),
4235 "eu.anthropic.claude-opus-4-7" => Ok(Self::EuAnthropicClaudeOpus47),
4236 "eu.anthropic.claude-sonnet-4-5-20250929-v1:0" => {
4237 Ok(Self::EuAnthropicClaudeSonnet4520250929V10)
4238 }
4239 "eu.anthropic.claude-sonnet-4-6" => Ok(Self::EuAnthropicClaudeSonnet46),
4240 "global.anthropic.claude-haiku-4-5-20251001-v1:0" => {
4241 Ok(Self::GlobalAnthropicClaudeHaiku4520251001V10)
4242 }
4243 "global.anthropic.claude-opus-4-5-20251101-v1:0" => {
4244 Ok(Self::GlobalAnthropicClaudeOpus4520251101V10)
4245 }
4246 "global.anthropic.claude-opus-4-6-v1" => {
4247 Ok(Self::GlobalAnthropicClaudeOpus46V1)
4248 }
4249 "global.anthropic.claude-opus-4-7" => Ok(Self::GlobalAnthropicClaudeOpus47),
4250 "global.anthropic.claude-sonnet-4-5-20250929-v1:0" => {
4251 Ok(Self::GlobalAnthropicClaudeSonnet4520250929V10)
4252 }
4253 "global.anthropic.claude-sonnet-4-6" => {
4254 Ok(Self::GlobalAnthropicClaudeSonnet46)
4255 }
4256 "google.gemma-3-27b-it" => Ok(Self::GoogleGemma327bIt),
4257 "google.gemma-3-4b-it" => Ok(Self::GoogleGemma34bIt),
4258 "jp.anthropic.claude-opus-4-7" => Ok(Self::JpAnthropicClaudeOpus47),
4259 "jp.anthropic.claude-sonnet-4-5-20250929-v1:0" => {
4260 Ok(Self::JpAnthropicClaudeSonnet4520250929V10)
4261 }
4262 "jp.anthropic.claude-sonnet-4-6" => Ok(Self::JpAnthropicClaudeSonnet46),
4263 "meta.llama3-1-70b-instruct-v1:0" => Ok(Self::MetaLlama3170bInstructV10),
4264 "meta.llama3-1-8b-instruct-v1:0" => Ok(Self::MetaLlama318bInstructV10),
4265 "meta.llama3-3-70b-instruct-v1:0" => Ok(Self::MetaLlama3370bInstructV10),
4266 "meta.llama4-maverick-17b-instruct-v1:0" => {
4267 Ok(Self::MetaLlama4Maverick17bInstructV10)
4268 }
4269 "meta.llama4-scout-17b-instruct-v1:0" => {
4270 Ok(Self::MetaLlama4Scout17bInstructV10)
4271 }
4272 "minimax.minimax-m2" => Ok(Self::MinimaxMinimaxM2),
4273 "minimax.minimax-m2.1" => Ok(Self::MinimaxMinimaxM21),
4274 "minimax.minimax-m2.5" => Ok(Self::MinimaxMinimaxM25),
4275 "mistral.devstral-2-123b" => Ok(Self::MistralDevstral2123b),
4276 "mistral.magistral-small-2509" => Ok(Self::MistralMagistralSmall2509),
4277 "mistral.ministral-3-14b-instruct" => Ok(Self::MistralMinistral314bInstruct),
4278 "mistral.ministral-3-3b-instruct" => Ok(Self::MistralMinistral33bInstruct),
4279 "mistral.ministral-3-8b-instruct" => Ok(Self::MistralMinistral38bInstruct),
4280 "mistral.mistral-large-3-675b-instruct" => {
4281 Ok(Self::MistralMistralLarge3675bInstruct)
4282 }
4283 "mistral.pixtral-large-2502-v1:0" => Ok(Self::MistralPixtralLarge2502V10),
4284 "mistral.voxtral-mini-3b-2507" => Ok(Self::MistralVoxtralMini3b2507),
4285 "mistral.voxtral-small-24b-2507" => Ok(Self::MistralVoxtralSmall24b2507),
4286 "moonshot.kimi-k2-thinking" => Ok(Self::MoonshotKimiK2Thinking),
4287 "moonshotai.kimi-k2.5" => Ok(Self::MoonshotaiKimiK25),
4288 "nvidia.nemotron-nano-12b-v2" => Ok(Self::NvidiaNemotronNano12bV2),
4289 "nvidia.nemotron-nano-3-30b" => Ok(Self::NvidiaNemotronNano330b),
4290 "nvidia.nemotron-nano-9b-v2" => Ok(Self::NvidiaNemotronNano9bV2),
4291 "nvidia.nemotron-super-3-120b" => Ok(Self::NvidiaNemotronSuper3120b),
4292 "openai.gpt-oss-120b-1:0" => Ok(Self::OpenaiGptOss120b10),
4293 "openai.gpt-oss-20b-1:0" => Ok(Self::OpenaiGptOss20b10),
4294 "openai.gpt-oss-safeguard-120b" => Ok(Self::OpenaiGptOssSafeguard120b),
4295 "openai.gpt-oss-safeguard-20b" => Ok(Self::OpenaiGptOssSafeguard20b),
4296 "qwen.qwen3-235b-a22b-2507-v1:0" => Ok(Self::QwenQwen3235bA22b2507V10),
4297 "qwen.qwen3-32b-v1:0" => Ok(Self::QwenQwen332bV10),
4298 "qwen.qwen3-coder-30b-a3b-v1:0" => Ok(Self::QwenQwen3Coder30bA3bV10),
4299 "qwen.qwen3-coder-480b-a35b-v1:0" => Ok(Self::QwenQwen3Coder480bA35bV10),
4300 "qwen.qwen3-coder-next" => Ok(Self::QwenQwen3CoderNext),
4301 "qwen.qwen3-next-80b-a3b" => Ok(Self::QwenQwen3Next80bA3b),
4302 "qwen.qwen3-vl-235b-a22b" => Ok(Self::QwenQwen3Vl235bA22b),
4303 "us.anthropic.claude-haiku-4-5-20251001-v1:0" => {
4304 Ok(Self::UsAnthropicClaudeHaiku4520251001V10)
4305 }
4306 "us.anthropic.claude-opus-4-1-20250805-v1:0" => {
4307 Ok(Self::UsAnthropicClaudeOpus4120250805V10)
4308 }
4309 "us.anthropic.claude-opus-4-5-20251101-v1:0" => {
4310 Ok(Self::UsAnthropicClaudeOpus4520251101V10)
4311 }
4312 "us.anthropic.claude-opus-4-6-v1" => Ok(Self::UsAnthropicClaudeOpus46V1),
4313 "us.anthropic.claude-opus-4-7" => Ok(Self::UsAnthropicClaudeOpus47),
4314 "us.anthropic.claude-sonnet-4-5-20250929-v1:0" => {
4315 Ok(Self::UsAnthropicClaudeSonnet4520250929V10)
4316 }
4317 "us.anthropic.claude-sonnet-4-6" => Ok(Self::UsAnthropicClaudeSonnet46),
4318 "us.deepseek.r1-v1:0" => Ok(Self::UsDeepseekR1V10),
4319 "us.meta.llama4-maverick-17b-instruct-v1:0" => {
4320 Ok(Self::UsMetaLlama4Maverick17bInstructV10)
4321 }
4322 "us.meta.llama4-scout-17b-instruct-v1:0" => {
4323 Ok(Self::UsMetaLlama4Scout17bInstructV10)
4324 }
4325 "writer.palmyra-x4-v1:0" => Ok(Self::WriterPalmyraX4V10),
4326 "writer.palmyra-x5-v1:0" => Ok(Self::WriterPalmyraX5V10),
4327 "zai.glm-4.7" => Ok(Self::ZaiGlm47),
4328 "zai.glm-4.7-flash" => Ok(Self::ZaiGlm47Flash),
4329 "zai.glm-5" => Ok(Self::ZaiGlm5),
4330 _ => Err(format!("Unknown bedrock model: '{s}'")),
4331 }
4332 }
4333}
4334#[derive(Debug, Clone, PartialEq, Eq, Hash)]
4336pub enum LlmModel {
4337 Anthropic(AnthropicModel),
4338 Codex(CodexModel),
4339 DeepSeek(DeepSeekModel),
4340 Gemini(GeminiModel),
4341 Moonshot(MoonshotModel),
4342 Openai(OpenaiModel),
4343 OpenRouter(OpenRouterModel),
4344 ZAi(ZAiModel),
4345 Bedrock(BedrockModel),
4346 Ollama(String),
4347 LlamaCpp(String),
4348}
4349impl From<AnthropicModel> for LlmModel {
4350 fn from(m: AnthropicModel) -> Self {
4351 LlmModel::Anthropic(m)
4352 }
4353}
4354impl From<CodexModel> for LlmModel {
4355 fn from(m: CodexModel) -> Self {
4356 LlmModel::Codex(m)
4357 }
4358}
4359impl From<DeepSeekModel> for LlmModel {
4360 fn from(m: DeepSeekModel) -> Self {
4361 LlmModel::DeepSeek(m)
4362 }
4363}
4364impl From<GeminiModel> for LlmModel {
4365 fn from(m: GeminiModel) -> Self {
4366 LlmModel::Gemini(m)
4367 }
4368}
4369impl From<MoonshotModel> for LlmModel {
4370 fn from(m: MoonshotModel) -> Self {
4371 LlmModel::Moonshot(m)
4372 }
4373}
4374impl From<OpenaiModel> for LlmModel {
4375 fn from(m: OpenaiModel) -> Self {
4376 LlmModel::Openai(m)
4377 }
4378}
4379impl From<OpenRouterModel> for LlmModel {
4380 fn from(m: OpenRouterModel) -> Self {
4381 LlmModel::OpenRouter(m)
4382 }
4383}
4384impl From<ZAiModel> for LlmModel {
4385 fn from(m: ZAiModel) -> Self {
4386 LlmModel::ZAi(m)
4387 }
4388}
4389impl From<BedrockModel> for LlmModel {
4390 fn from(m: BedrockModel) -> Self {
4391 LlmModel::Bedrock(m)
4392 }
4393}
4394impl LlmModel {
4395 pub fn model_id(&self) -> Cow<'static, str> {
4397 match self {
4398 Self::Anthropic(m) => Cow::Borrowed(m.model_id()),
4399 Self::Codex(m) => Cow::Borrowed(m.model_id()),
4400 Self::DeepSeek(m) => Cow::Borrowed(m.model_id()),
4401 Self::Gemini(m) => Cow::Borrowed(m.model_id()),
4402 Self::Moonshot(m) => Cow::Borrowed(m.model_id()),
4403 Self::Openai(m) => Cow::Borrowed(m.model_id()),
4404 Self::OpenRouter(m) => Cow::Borrowed(m.model_id()),
4405 Self::ZAi(m) => Cow::Borrowed(m.model_id()),
4406 Self::Bedrock(m) => m.model_id(),
4407 Self::Ollama(s) | Self::LlamaCpp(s) => Cow::Owned(s.clone()),
4408 }
4409 }
4410 pub fn display_name(&self) -> Cow<'static, str> {
4412 match self {
4413 Self::Anthropic(m) => Cow::Borrowed(m.display_name()),
4414 Self::Codex(m) => Cow::Borrowed(m.display_name()),
4415 Self::DeepSeek(m) => Cow::Borrowed(m.display_name()),
4416 Self::Gemini(m) => Cow::Borrowed(m.display_name()),
4417 Self::Moonshot(m) => Cow::Borrowed(m.display_name()),
4418 Self::Openai(m) => Cow::Borrowed(m.display_name()),
4419 Self::OpenRouter(m) => Cow::Borrowed(m.display_name()),
4420 Self::ZAi(m) => Cow::Borrowed(m.display_name()),
4421 Self::Bedrock(m) => m.display_name(),
4422 Self::Ollama(s) => Cow::Owned(format!("Ollama {s}")),
4423 Self::LlamaCpp(s) => Cow::Owned(format!("LlamaCpp {s}")),
4424 }
4425 }
4426 pub fn provider(&self) -> &'static str {
4428 match self {
4429 Self::Anthropic(_) => "anthropic",
4430 Self::Codex(_) => "codex",
4431 Self::DeepSeek(_) => "deepseek",
4432 Self::Gemini(_) => "gemini",
4433 Self::Moonshot(_) => "moonshot",
4434 Self::Openai(_) => "openai",
4435 Self::OpenRouter(_) => "openrouter",
4436 Self::ZAi(_) => "zai",
4437 Self::Bedrock(_) => "bedrock",
4438 Self::Ollama(_) => "ollama",
4439 Self::LlamaCpp(_) => "llamacpp",
4440 }
4441 }
4442 pub fn provider_display_name(&self) -> &'static str {
4444 match self {
4445 Self::Anthropic(_) => "Anthropic",
4446 Self::Codex(_) => "Codex",
4447 Self::DeepSeek(_) => "DeepSeek",
4448 Self::Gemini(_) => "Gemini",
4449 Self::Moonshot(_) => "Moonshot",
4450 Self::Openai(_) => "OpenAI",
4451 Self::OpenRouter(_) => "OpenRouter",
4452 Self::ZAi(_) => "ZAI",
4453 Self::Bedrock(_) => "AWS Bedrock",
4454 Self::Ollama(_) => "Ollama",
4455 Self::LlamaCpp(_) => "LlamaCpp",
4456 }
4457 }
4458 pub fn context_window(&self) -> Option<u32> {
4460 match self {
4461 Self::Anthropic(m) => Some(m.context_window()),
4462 Self::Codex(m) => Some(m.context_window()),
4463 Self::DeepSeek(m) => Some(m.context_window()),
4464 Self::Gemini(m) => Some(m.context_window()),
4465 Self::Moonshot(m) => Some(m.context_window()),
4466 Self::Openai(m) => Some(m.context_window()),
4467 Self::OpenRouter(m) => Some(m.context_window()),
4468 Self::ZAi(m) => Some(m.context_window()),
4469 Self::Bedrock(m) => m.context_window(),
4470 Self::Ollama(_) | Self::LlamaCpp(_) => None,
4471 }
4472 }
4473 pub fn required_env_var(&self) -> Option<&'static str> {
4475 match self {
4476 Self::Anthropic(_) => Some("ANTHROPIC_API_KEY"),
4477 Self::DeepSeek(_) => Some("DEEPSEEK_API_KEY"),
4478 Self::Gemini(_) => Some("GEMINI_API_KEY"),
4479 Self::Moonshot(_) => Some("MOONSHOT_API_KEY"),
4480 Self::Openai(_) => Some("OPENAI_API_KEY"),
4481 Self::OpenRouter(_) => Some("OPENROUTER_API_KEY"),
4482 Self::ZAi(_) => Some("ZAI_API_KEY"),
4483 Self::Codex(_) | Self::Bedrock(_) | Self::Ollama(_) | Self::LlamaCpp(_) => {
4484 None
4485 }
4486 }
4487 }
4488 pub const ALL_REQUIRED_ENV_VARS: &[&str] = &[
4490 "ANTHROPIC_API_KEY",
4491 "DEEPSEEK_API_KEY",
4492 "GEMINI_API_KEY",
4493 "MOONSHOT_API_KEY",
4494 "OPENAI_API_KEY",
4495 "OPENROUTER_API_KEY",
4496 "ZAI_API_KEY",
4497 ];
4498 pub fn oauth_provider_id(&self) -> Option<&'static str> {
4500 match self {
4501 Self::Codex(_) => Some("codex"),
4502 Self::Anthropic(_)
4503 | Self::DeepSeek(_)
4504 | Self::Gemini(_)
4505 | Self::Moonshot(_)
4506 | Self::Openai(_)
4507 | Self::OpenRouter(_)
4508 | Self::ZAi(_)
4509 | Self::Bedrock(_)
4510 | Self::Ollama(_)
4511 | Self::LlamaCpp(_) => None,
4512 }
4513 }
4514 pub fn reasoning_levels(&self) -> &'static [ReasoningEffort] {
4516 match self {
4517 Self::Anthropic(m) => m.reasoning_levels(),
4518 Self::Codex(m) => m.reasoning_levels(),
4519 Self::DeepSeek(m) => m.reasoning_levels(),
4520 Self::Gemini(m) => m.reasoning_levels(),
4521 Self::Moonshot(m) => m.reasoning_levels(),
4522 Self::Openai(m) => m.reasoning_levels(),
4523 Self::OpenRouter(m) => m.reasoning_levels(),
4524 Self::ZAi(m) => m.reasoning_levels(),
4525 Self::Bedrock(m) => m.reasoning_levels(),
4526 Self::Ollama(_) | Self::LlamaCpp(_) => &[],
4527 }
4528 }
4529 pub fn supports_reasoning(&self) -> bool {
4531 !self.reasoning_levels().is_empty()
4532 }
4533 pub fn supports_prompt_caching(&self) -> bool {
4535 match self {
4536 Self::Anthropic(m) => m.supports_prompt_caching(),
4537 Self::Codex(m) => m.supports_prompt_caching(),
4538 Self::DeepSeek(m) => m.supports_prompt_caching(),
4539 Self::Gemini(m) => m.supports_prompt_caching(),
4540 Self::Moonshot(m) => m.supports_prompt_caching(),
4541 Self::Openai(m) => m.supports_prompt_caching(),
4542 Self::OpenRouter(m) => m.supports_prompt_caching(),
4543 Self::ZAi(m) => m.supports_prompt_caching(),
4544 Self::Bedrock(m) => m.supports_prompt_caching(),
4545 Self::Ollama(_) | Self::LlamaCpp(_) => false,
4546 }
4547 }
4548 pub fn supports_image(&self) -> bool {
4550 match self {
4551 Self::Anthropic(m) => m.supports_image(),
4552 Self::Codex(m) => m.supports_image(),
4553 Self::DeepSeek(m) => m.supports_image(),
4554 Self::Gemini(m) => m.supports_image(),
4555 Self::Moonshot(m) => m.supports_image(),
4556 Self::Openai(m) => m.supports_image(),
4557 Self::OpenRouter(m) => m.supports_image(),
4558 Self::ZAi(m) => m.supports_image(),
4559 Self::Bedrock(m) => m.supports_image(),
4560 Self::Ollama(_) | Self::LlamaCpp(_) => false,
4561 }
4562 }
4563 pub fn supports_audio(&self) -> bool {
4565 match self {
4566 Self::Anthropic(m) => m.supports_audio(),
4567 Self::Codex(m) => m.supports_audio(),
4568 Self::DeepSeek(m) => m.supports_audio(),
4569 Self::Gemini(m) => m.supports_audio(),
4570 Self::Moonshot(m) => m.supports_audio(),
4571 Self::Openai(m) => m.supports_audio(),
4572 Self::OpenRouter(m) => m.supports_audio(),
4573 Self::ZAi(m) => m.supports_audio(),
4574 Self::Bedrock(m) => m.supports_audio(),
4575 Self::Ollama(_) | Self::LlamaCpp(_) => false,
4576 }
4577 }
4578 pub fn all() -> &'static [LlmModel] {
4580 static ALL: LazyLock<Vec<LlmModel>> = LazyLock::new(|| {
4581 let mut v = Vec::new();
4582 v.extend(AnthropicModel::ALL.iter().copied().map(LlmModel::Anthropic));
4583 v.extend(CodexModel::ALL.iter().copied().map(LlmModel::Codex));
4584 v.extend(DeepSeekModel::ALL.iter().copied().map(LlmModel::DeepSeek));
4585 v.extend(GeminiModel::ALL.iter().copied().map(LlmModel::Gemini));
4586 v.extend(MoonshotModel::ALL.iter().copied().map(LlmModel::Moonshot));
4587 v.extend(OpenaiModel::ALL.iter().copied().map(LlmModel::Openai));
4588 v.extend(OpenRouterModel::ALL.iter().copied().map(LlmModel::OpenRouter));
4589 v.extend(ZAiModel::ALL.iter().copied().map(LlmModel::ZAi));
4590 v.extend(
4591 BedrockFoundationModel::ALL
4592 .iter()
4593 .copied()
4594 .map(BedrockModel::Foundation)
4595 .map(LlmModel::Bedrock),
4596 );
4597 v
4598 });
4599 &ALL
4600 }
4601}
4602impl std::fmt::Display for LlmModel {
4603 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4604 write!(f, "{}:{}", self.provider(), self.model_id())
4605 }
4606}
4607impl std::str::FromStr for LlmModel {
4608 type Err = String;
4609 fn from_str(s: &str) -> Result<Self, Self::Err> {
4611 let (provider_str, model_str) = s.split_once(':').unwrap_or((s, ""));
4612 match provider_str {
4613 "anthropic" => model_str.parse::<AnthropicModel>().map(Self::Anthropic),
4614 "codex" => model_str.parse::<CodexModel>().map(Self::Codex),
4615 "deepseek" => model_str.parse::<DeepSeekModel>().map(Self::DeepSeek),
4616 "gemini" => model_str.parse::<GeminiModel>().map(Self::Gemini),
4617 "moonshot" => model_str.parse::<MoonshotModel>().map(Self::Moonshot),
4618 "openai" => model_str.parse::<OpenaiModel>().map(Self::Openai),
4619 "openrouter" => model_str.parse::<OpenRouterModel>().map(Self::OpenRouter),
4620 "zai" => model_str.parse::<ZAiModel>().map(Self::ZAi),
4621 "bedrock" => model_str.parse::<BedrockModel>().map(Self::Bedrock),
4622 "ollama" => Ok(Self::Ollama(model_str.to_string())),
4623 "llamacpp" => Ok(Self::LlamaCpp(model_str.to_string())),
4624 _ => Err(format!("Unknown provider: '{provider_str}'")),
4625 }
4626 }
4627}