1use serde::{Deserialize, Serialize};
7
8use crate::config::constants::models::copilot as copilot_models;
9use crate::config::constants::models::evolink as evolink_models;
10use crate::config::constants::models::llamacpp as llamacpp_models;
11use crate::config::constants::models::mimo as mimo_models;
12use crate::config::constants::models::poolside as poolside_models;
13use crate::config::constants::models::qwen as qwen_models;
14use crate::config::constants::models::stepfun as stepfun_models;
15use crate::config::models::Provider;
16use crate::config::types::ReasoningEffortLevel;
17
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20pub struct ReasoningEffortPreset {
21 pub effort: ReasoningEffortLevel,
23 pub description: String,
25}
26
27#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
29pub struct ModelUpgrade {
30 pub id: String,
32 #[serde(default, skip_serializing_if = "Option::is_none")]
34 pub reasoning_effort_mapping: Option<String>,
35 pub migration_config_key: String,
37 #[serde(default, skip_serializing_if = "Option::is_none")]
39 pub model_link: Option<String>,
40 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub upgrade_copy: Option<String>,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47pub struct ModelInfo {
48 pub slug: String,
50 pub display_name: String,
52 pub description: String,
54 pub provider: Provider,
56 #[serde(default)]
58 pub default_reasoning_level: ReasoningEffortLevel,
59 #[serde(default)]
61 pub supported_reasoning_levels: Vec<ReasoningEffortPreset>,
62 #[serde(default)]
64 pub context_window: Option<i64>,
65 #[serde(default = "default_true")]
67 pub supports_tool_use: bool,
68 #[serde(default = "default_true")]
70 pub supports_streaming: bool,
71 #[serde(default)]
73 pub supports_reasoning: bool,
74 #[serde(default)]
76 pub priority: i32,
77 #[serde(default = "default_visibility")]
79 pub visibility: String,
80 #[serde(default = "default_true")]
82 pub supported_in_api: bool,
83 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub upgrade: Option<ModelUpgrade>,
86}
87
88fn default_true() -> bool {
89 true
90}
91
92fn default_visibility() -> String {
93 "list".to_string()
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
98pub struct ModelPreset {
99 pub id: String,
101 pub model: String,
103 pub display_name: String,
105 pub description: String,
107 pub provider: Provider,
109 pub default_reasoning_effort: ReasoningEffortLevel,
111 pub supported_reasoning_efforts: Vec<ReasoningEffortPreset>,
113 #[serde(default)]
115 pub is_default: bool,
116 #[serde(default, skip_serializing_if = "Option::is_none")]
118 pub upgrade: Option<ModelUpgrade>,
119 #[serde(default = "default_true")]
121 pub show_in_picker: bool,
122 #[serde(default = "default_true")]
124 pub supported_in_api: bool,
125 #[serde(default)]
127 pub context_window: Option<i64>,
128}
129
130impl From<ModelInfo> for ModelPreset {
131 fn from(info: ModelInfo) -> Self {
132 Self {
133 id: info.slug.clone(),
134 model: info.slug,
135 display_name: info.display_name,
136 description: info.description,
137 provider: info.provider,
138 default_reasoning_effort: info.default_reasoning_level,
139 supported_reasoning_efforts: info.supported_reasoning_levels,
140 is_default: false,
141 upgrade: info.upgrade,
142 show_in_picker: info.visibility == "list",
143 supported_in_api: info.supported_in_api,
144 context_window: info.context_window,
145 }
146 }
147}
148
149pub fn builtin_model_presets() -> Vec<ModelPreset> {
151 let mut presets = Vec::new();
152
153 presets.extend(gemini_presets());
155
156 presets.extend(openai_presets());
158
159 presets.extend(anthropic_presets());
161
162 presets.extend(copilot_presets());
164
165 presets.extend(deepseek_presets());
167
168 presets.extend(zai_presets());
170
171 presets.extend(lmstudio_presets());
173
174 presets.extend(llamacpp_presets());
176
177 presets.extend(minimax_presets());
179
180 presets.extend(opencode_zen_presets());
182
183 presets.extend(opencode_go_presets());
185
186 presets.extend(poolside_presets());
188
189 presets.extend(stepfun_presets());
191
192 presets.extend(evolink_presets());
194
195 presets
196}
197
198pub fn presets_for_provider(provider: Provider) -> Vec<ModelPreset> {
200 match provider {
201 Provider::Gemini => gemini_presets(),
202 Provider::OpenAI => openai_presets(),
203 Provider::Anthropic => anthropic_presets(),
204 Provider::Copilot => copilot_presets(),
205 Provider::DeepSeek => deepseek_presets(),
206 Provider::ZAI => zai_presets(),
207 Provider::Minimax => minimax_presets(),
208 Provider::OpenRouter => openrouter_presets(),
209 Provider::Ollama => ollama_presets(),
210 Provider::LmStudio => lmstudio_presets(),
211 Provider::LlamaCpp => llamacpp_presets(),
212 Provider::Moonshot => moonshot_presets(),
213 Provider::Mistral => mistral_presets(),
214 Provider::HuggingFace => huggingface_presets(),
215 Provider::OpenCodeZen => opencode_zen_presets(),
216 Provider::OpenCodeGo => opencode_go_presets(),
217 Provider::MiMo => mimo_presets(),
218 Provider::Qwen => qwen_presets(),
219 Provider::StepFun => stepfun_presets(),
220 Provider::Evolink => evolink_presets(),
221 Provider::Poolside => poolside_presets(),
222 }
223}
224
225fn copilot_presets() -> Vec<ModelPreset> {
226 vec![ModelPreset {
227 id: copilot_models::AUTO.to_string(),
228 model: copilot_models::AUTO.to_string(),
229 display_name: "GitHub Copilot Auto".to_string(),
230 description:
231 "Official GitHub Copilot preview provider via the Copilot CLI with automatic model selection."
232 .to_string(),
233 provider: Provider::Copilot,
234 default_reasoning_effort: ReasoningEffortLevel::Medium,
235 supported_reasoning_efforts: Vec::new(),
236 is_default: true,
237 upgrade: None,
238 show_in_picker: true,
239 supported_in_api: true,
240 context_window: Some(400_000),
241 }]
242}
243
244fn gemini_presets() -> Vec<ModelPreset> {
245 vec![ModelPreset {
246 id: "gemini-3-flash-preview".to_string(),
247 model: "gemini-3-flash-preview".to_string(),
248 display_name: "Gemini 3 Flash Preview".to_string(),
249 description: "Most intelligent model built for speed with superior search and grounding"
250 .to_string(),
251 provider: Provider::Gemini,
252 default_reasoning_effort: ReasoningEffortLevel::Medium,
253 supported_reasoning_efforts: vec![
254 ReasoningEffortPreset {
255 effort: ReasoningEffortLevel::Low,
256 description: "Fast responses".to_string(),
257 },
258 ReasoningEffortPreset {
259 effort: ReasoningEffortLevel::Medium,
260 description: "Balanced reasoning".to_string(),
261 },
262 ReasoningEffortPreset {
263 effort: ReasoningEffortLevel::High,
264 description: "Deep reasoning".to_string(),
265 },
266 ],
267 is_default: true,
268 upgrade: None,
269 show_in_picker: true,
270 supported_in_api: true,
271 context_window: Some(1_048_576),
272 }]
273}
274
275fn reasoning_preset(
276 effort: ReasoningEffortLevel,
277 description: &'static str,
278) -> ReasoningEffortPreset {
279 ReasoningEffortPreset {
280 effort,
281 description: description.to_string(),
282 }
283}
284
285fn openai_reasoning_efforts(include_none: bool, include_xhigh: bool) -> Vec<ReasoningEffortPreset> {
286 let mut efforts = Vec::new();
287 if include_none {
288 efforts.push(reasoning_preset(
289 ReasoningEffortLevel::None,
290 "Lowest latency",
291 ));
292 }
293 efforts.push(reasoning_preset(ReasoningEffortLevel::Low, "Fast"));
294 efforts.push(reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"));
295 efforts.push(reasoning_preset(ReasoningEffortLevel::High, "Deep"));
296 if include_xhigh {
297 efforts.push(reasoning_preset(
298 ReasoningEffortLevel::XHigh,
299 "Maximum reasoning",
300 ));
301 }
302 efforts
303}
304
305fn openai_presets() -> Vec<ModelPreset> {
306 vec![
307 ModelPreset {
308 id: "gpt-5.4".to_string(),
309 model: "gpt-5.4".to_string(),
310 display_name: "GPT-5.4".to_string(),
311 description: "Frontier model for complex professional work".to_string(),
312 provider: Provider::OpenAI,
313 default_reasoning_effort: ReasoningEffortLevel::None,
314 supported_reasoning_efforts: openai_reasoning_efforts(true, true),
315 is_default: true,
316 upgrade: None,
317 show_in_picker: true,
318 supported_in_api: true,
319 context_window: Some(1_050_000),
320 },
321 ModelPreset {
322 id: "gpt-5.4-pro".to_string(),
323 model: "gpt-5.4-pro".to_string(),
324 display_name: "GPT-5.4 Pro".to_string(),
325 description: "Higher-compute GPT-5.4 variant for tougher problems".to_string(),
326 provider: Provider::OpenAI,
327 default_reasoning_effort: ReasoningEffortLevel::Medium,
328 supported_reasoning_efforts: vec![
329 reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"),
330 reasoning_preset(ReasoningEffortLevel::High, "Deep"),
331 reasoning_preset(ReasoningEffortLevel::XHigh, "Maximum reasoning"),
332 ],
333 is_default: false,
334 upgrade: None,
335 show_in_picker: true,
336 supported_in_api: true,
337 context_window: Some(1_050_000),
338 },
339 ModelPreset {
340 id: "gpt-5.3-codex".to_string(),
341 model: "gpt-5.3-codex".to_string(),
342 display_name: "GPT-5.3 Codex".to_string(),
343 description: "GPT-5.3 variant optimized for agentic coding with xhigh reasoning"
344 .to_string(),
345 provider: Provider::OpenAI,
346 default_reasoning_effort: ReasoningEffortLevel::High,
347 supported_reasoning_efforts: openai_reasoning_efforts(true, true),
348 is_default: false,
349 upgrade: None,
350 show_in_picker: true,
351 supported_in_api: true,
352 context_window: Some(272_000),
353 },
354 ModelPreset {
355 id: "gpt-5.2-codex".to_string(),
356 model: "gpt-5.2-codex".to_string(),
357 display_name: "GPT-5.2 Codex".to_string(),
358 description: "GPT-5.2 variant optimized for agentic coding with xhigh reasoning"
359 .to_string(),
360 provider: Provider::OpenAI,
361 default_reasoning_effort: ReasoningEffortLevel::High,
362 supported_reasoning_efforts: openai_reasoning_efforts(true, true),
363 is_default: false,
364 upgrade: None,
365 show_in_picker: true,
366 supported_in_api: true,
367 context_window: Some(272_000),
368 },
369 ModelPreset {
370 id: "gpt-5.1-codex".to_string(),
371 model: "gpt-5.1-codex".to_string(),
372 display_name: "GPT-5.1 Codex".to_string(),
373 description: "GPT-5.1 variant optimized for agentic coding".to_string(),
374 provider: Provider::OpenAI,
375 default_reasoning_effort: ReasoningEffortLevel::High,
376 supported_reasoning_efforts: openai_reasoning_efforts(false, false),
377 is_default: false,
378 upgrade: None,
379 show_in_picker: true,
380 supported_in_api: true,
381 context_window: Some(272_000),
382 },
383 ModelPreset {
384 id: "gpt-5.1-codex-max".to_string(),
385 model: "gpt-5.1-codex-max".to_string(),
386 display_name: "GPT-5.1 Codex Max".to_string(),
387 description:
388 "Higher-compute GPT-5.1 Codex variant for longer-running engineering tasks"
389 .to_string(),
390 provider: Provider::OpenAI,
391 default_reasoning_effort: ReasoningEffortLevel::High,
392 supported_reasoning_efforts: openai_reasoning_efforts(false, false),
393 is_default: false,
394 upgrade: None,
395 show_in_picker: true,
396 supported_in_api: true,
397 context_window: Some(272_000),
398 },
399 ModelPreset {
400 id: "gpt-5-codex".to_string(),
401 model: "gpt-5-codex".to_string(),
402 display_name: "GPT-5 Codex".to_string(),
403 description: "GPT-5 variant optimized for agentic coding".to_string(),
404 provider: Provider::OpenAI,
405 default_reasoning_effort: ReasoningEffortLevel::High,
406 supported_reasoning_efforts: openai_reasoning_efforts(false, false),
407 is_default: false,
408 upgrade: None,
409 show_in_picker: true,
410 supported_in_api: true,
411 context_window: Some(272_000),
412 },
413 ModelPreset {
414 id: "gpt-5.2".to_string(),
415 model: "gpt-5.2".to_string(),
416 display_name: "GPT-5.2".to_string(),
417 description: "Latest frontier model with improved reasoning and coding".to_string(),
418 provider: Provider::OpenAI,
419 default_reasoning_effort: ReasoningEffortLevel::None,
420 supported_reasoning_efforts: openai_reasoning_efforts(true, true),
421 is_default: false,
422 upgrade: None,
423 show_in_picker: true,
424 supported_in_api: true,
425 context_window: Some(272_000),
426 },
427 ModelPreset {
428 id: "gpt-5".to_string(),
429 model: "gpt-5".to_string(),
430 display_name: "GPT-5".to_string(),
431 description: "Latest most capable OpenAI model".to_string(),
432 provider: Provider::OpenAI,
433 default_reasoning_effort: ReasoningEffortLevel::Medium,
434 supported_reasoning_efforts: vec![
435 ReasoningEffortPreset {
436 effort: ReasoningEffortLevel::Low,
437 description: "Fast".to_string(),
438 },
439 ReasoningEffortPreset {
440 effort: ReasoningEffortLevel::Medium,
441 description: "Balanced".to_string(),
442 },
443 ReasoningEffortPreset {
444 effort: ReasoningEffortLevel::High,
445 description: "Deep".to_string(),
446 },
447 ],
448 is_default: false,
449 upgrade: None,
450 show_in_picker: true,
451 supported_in_api: true,
452 context_window: Some(200_000),
453 },
454 ModelPreset {
455 id: "gpt-5-mini".to_string(),
456 model: "gpt-5-mini".to_string(),
457 display_name: "GPT-5 Mini".to_string(),
458 description: "Efficient GPT-5 variant".to_string(),
459 provider: Provider::OpenAI,
460 default_reasoning_effort: ReasoningEffortLevel::Medium,
461 supported_reasoning_efforts: vec![ReasoningEffortPreset {
462 effort: ReasoningEffortLevel::Medium,
463 description: "Balanced".to_string(),
464 }],
465 is_default: false,
466 upgrade: None,
467 show_in_picker: true,
468 supported_in_api: true,
469 context_window: Some(128_000),
470 },
471 ModelPreset {
472 id: "gpt-5-nano".to_string(),
473 model: "gpt-5-nano".to_string(),
474 display_name: "GPT-5 Nano".to_string(),
475 description: "Most cost-effective GPT-5 variant for high-volume tasks".to_string(),
476 provider: Provider::OpenAI,
477 default_reasoning_effort: ReasoningEffortLevel::Medium,
478 supported_reasoning_efforts: vec![ReasoningEffortPreset {
479 effort: ReasoningEffortLevel::Medium,
480 description: "Balanced".to_string(),
481 }],
482 is_default: false,
483 upgrade: None,
484 show_in_picker: true,
485 supported_in_api: true,
486 context_window: Some(200_000),
487 },
488 ModelPreset {
489 id: "o3".to_string(),
490 model: "o3".to_string(),
491 display_name: "o3".to_string(),
492 description: "OpenAI reasoning model for harder multi-step work".to_string(),
493 provider: Provider::OpenAI,
494 default_reasoning_effort: ReasoningEffortLevel::Medium,
495 supported_reasoning_efforts: openai_reasoning_efforts(false, false),
496 is_default: false,
497 upgrade: None,
498 show_in_picker: true,
499 supported_in_api: true,
500 context_window: None,
501 },
502 ModelPreset {
503 id: "o4-mini".to_string(),
504 model: "o4-mini".to_string(),
505 display_name: "o4-mini".to_string(),
506 description: "Smaller OpenAI reasoning model with strong tool use".to_string(),
507 provider: Provider::OpenAI,
508 default_reasoning_effort: ReasoningEffortLevel::Medium,
509 supported_reasoning_efforts: openai_reasoning_efforts(false, false),
510 is_default: false,
511 upgrade: None,
512 show_in_picker: true,
513 supported_in_api: true,
514 context_window: None,
515 },
516 ModelPreset {
517 id: "gpt-oss-20b".to_string(),
518 model: "gpt-oss-20b".to_string(),
519 display_name: "GPT-OSS 20B".to_string(),
520 description: "OpenAI's open-source 20B parameter model".to_string(),
521 provider: Provider::OpenAI,
522 default_reasoning_effort: ReasoningEffortLevel::Medium,
523 supported_reasoning_efforts: vec![
524 ReasoningEffortPreset {
525 effort: ReasoningEffortLevel::Low,
526 description: "Fast".to_string(),
527 },
528 ReasoningEffortPreset {
529 effort: ReasoningEffortLevel::Medium,
530 description: "Balanced".to_string(),
531 },
532 ReasoningEffortPreset {
533 effort: ReasoningEffortLevel::High,
534 description: "Deep".to_string(),
535 },
536 ],
537 is_default: false,
538 upgrade: None,
539 show_in_picker: true,
540 supported_in_api: true,
541 context_window: Some(131_072),
542 },
543 ModelPreset {
544 id: "gpt-oss-120b".to_string(),
545 model: "gpt-oss-120b".to_string(),
546 display_name: "GPT-OSS 120B".to_string(),
547 description: "OpenAI's open-source 120B parameter model with advanced reasoning"
548 .to_string(),
549 provider: Provider::OpenAI,
550 default_reasoning_effort: ReasoningEffortLevel::Medium,
551 supported_reasoning_efforts: vec![
552 ReasoningEffortPreset {
553 effort: ReasoningEffortLevel::Low,
554 description: "Fast".to_string(),
555 },
556 ReasoningEffortPreset {
557 effort: ReasoningEffortLevel::Medium,
558 description: "Balanced".to_string(),
559 },
560 ReasoningEffortPreset {
561 effort: ReasoningEffortLevel::High,
562 description: "Deep".to_string(),
563 },
564 ],
565 is_default: false,
566 upgrade: None,
567 show_in_picker: true,
568 supported_in_api: true,
569 context_window: Some(131_072),
570 },
571 ]
572}
573
574fn anthropic_presets() -> Vec<ModelPreset> {
575 vec![
576 ModelPreset {
577 id: "claude-fable-5".to_string(),
578 model: "claude-fable-5".to_string(),
579 display_name: "Claude Fable 5".to_string(),
580 description:
581 "Anthropic's most capable widely released model with 1M context, 128k output, and always-on adaptive thinking"
582 .to_string(),
583 provider: Provider::Anthropic,
584 default_reasoning_effort: ReasoningEffortLevel::XHigh,
585 supported_reasoning_efforts: vec![
586 ReasoningEffortPreset {
587 effort: ReasoningEffortLevel::Low,
588 description: "Fast adaptive effort".to_string(),
589 },
590 ReasoningEffortPreset {
591 effort: ReasoningEffortLevel::Medium,
592 description: "Balanced adaptive effort".to_string(),
593 },
594 ReasoningEffortPreset {
595 effort: ReasoningEffortLevel::High,
596 description: "Deep adaptive effort".to_string(),
597 },
598 ReasoningEffortPreset {
599 effort: ReasoningEffortLevel::XHigh,
600 description: "Recommended Fable 5 effort for coding and agentic work".to_string(),
601 },
602 ReasoningEffortPreset {
603 effort: ReasoningEffortLevel::Max,
604 description: "Maximum adaptive effort for intelligence-demanding tasks"
605 .to_string(),
606 },
607 ],
608 is_default: true,
609 upgrade: None,
610 show_in_picker: true,
611 supported_in_api: true,
612 context_window: Some(1_000_000),
613 },
614 ModelPreset {
615 id: "claude-opus-4-8".to_string(),
616 model: "claude-opus-4-8".to_string(),
617 display_name: "Claude Opus 4.8".to_string(),
618 description:
619 "Anthropic's most capable model for complex reasoning, long-horizon agentic coding, and high-autonomy work"
620 .to_string(),
621 provider: Provider::Anthropic,
622 default_reasoning_effort: ReasoningEffortLevel::XHigh,
623 supported_reasoning_efforts: vec![
624 ReasoningEffortPreset {
625 effort: ReasoningEffortLevel::Low,
626 description: "Fast adaptive effort".to_string(),
627 },
628 ReasoningEffortPreset {
629 effort: ReasoningEffortLevel::Medium,
630 description: "Balanced adaptive effort".to_string(),
631 },
632 ReasoningEffortPreset {
633 effort: ReasoningEffortLevel::High,
634 description: "Deep adaptive effort".to_string(),
635 },
636 ReasoningEffortPreset {
637 effort: ReasoningEffortLevel::XHigh,
638 description: "Recommended Opus 4.8 effort for coding and agentic work".to_string(),
639 },
640 ReasoningEffortPreset {
641 effort: ReasoningEffortLevel::Max,
642 description: "Maximum adaptive effort for intelligence-demanding tasks"
643 .to_string(),
644 },
645 ],
646 is_default: false,
647 upgrade: None,
648 show_in_picker: true,
649 supported_in_api: true,
650 context_window: Some(1_000_000),
651 },
652 ModelPreset {
653 id: "claude-sonnet-4-6".to_string(),
654 model: "claude-sonnet-4-6".to_string(),
655 display_name: "Claude Sonnet 4.6".to_string(),
656 description:
657 "The best combination of speed and intelligence. Supports extended thinking and adaptive thinking with 1M context."
658 .to_string(),
659 provider: Provider::Anthropic,
660 default_reasoning_effort: ReasoningEffortLevel::High,
661 supported_reasoning_efforts: vec![
662 ReasoningEffortPreset {
663 effort: ReasoningEffortLevel::Low,
664 description: "Fast adaptive effort".to_string(),
665 },
666 ReasoningEffortPreset {
667 effort: ReasoningEffortLevel::Medium,
668 description: "Balanced adaptive effort".to_string(),
669 },
670 ReasoningEffortPreset {
671 effort: ReasoningEffortLevel::High,
672 description: "Default adaptive effort".to_string(),
673 },
674 ReasoningEffortPreset {
675 effort: ReasoningEffortLevel::Max,
676 description: "Maximum adaptive effort".to_string(),
677 },
678 ],
679 is_default: false,
680 upgrade: None,
681 show_in_picker: true,
682 supported_in_api: true,
683 context_window: Some(1_000_000),
684 },
685 ModelPreset {
686 id: "claude-haiku-4-5".to_string(),
687 model: "claude-haiku-4-5".to_string(),
688 display_name: "Claude Haiku 4.5".to_string(),
689 description: "The fastest model with near-frontier intelligence. Supports extended thinking with manual budget."
690 .to_string(),
691 provider: Provider::Anthropic,
692 default_reasoning_effort: ReasoningEffortLevel::Medium,
693 supported_reasoning_efforts: Vec::new(),
694 is_default: false,
695 upgrade: None,
696 show_in_picker: true,
697 supported_in_api: true,
698 context_window: Some(200_000),
699 },
700 ]
701}
702
703fn deepseek_presets() -> Vec<ModelPreset> {
704 vec![
705 ModelPreset {
706 id: "deepseek-v4-pro".to_string(),
707 model: "deepseek-v4-pro".to_string(),
708 display_name: "DeepSeek V4 Pro".to_string(),
709 description: "High-performance reasoning model with advanced thinking capabilities"
710 .to_string(),
711 provider: Provider::DeepSeek,
712 default_reasoning_effort: ReasoningEffortLevel::High,
713 supported_reasoning_efforts: vec![
714 ReasoningEffortPreset {
715 effort: ReasoningEffortLevel::High,
716 description: "Balanced".to_string(),
717 },
718 ReasoningEffortPreset {
719 effort: ReasoningEffortLevel::Max,
720 description: "Maximum thinking".to_string(),
721 },
722 ],
723 is_default: true,
724 upgrade: None,
725 show_in_picker: true,
726 supported_in_api: true,
727 context_window: Some(1_000_000),
728 },
729 ModelPreset {
730 id: "deepseek-v4-flash".to_string(),
731 model: "deepseek-v4-flash".to_string(),
732 display_name: "DeepSeek V4 Flash".to_string(),
733 description: "Fast inference model for cost-effective reasoning tasks".to_string(),
734 provider: Provider::DeepSeek,
735 default_reasoning_effort: ReasoningEffortLevel::High,
736 supported_reasoning_efforts: vec![
737 ReasoningEffortPreset {
738 effort: ReasoningEffortLevel::High,
739 description: "Balanced".to_string(),
740 },
741 ReasoningEffortPreset {
742 effort: ReasoningEffortLevel::Max,
743 description: "Maximum thinking".to_string(),
744 },
745 ],
746 is_default: false,
747 upgrade: None,
748 show_in_picker: true,
749 supported_in_api: true,
750 context_window: Some(1_000_000),
751 },
752 ]
753}
754
755fn zai_presets() -> Vec<ModelPreset> {
756 vec![
757 ModelPreset {
758 id: "glm-5".to_string(),
759 model: "glm-5".to_string(),
760 display_name: "GLM-5".to_string(),
761 description: "Z.ai's flagship open-source foundation model for complex systems"
762 .to_string(),
763 provider: Provider::ZAI,
764 default_reasoning_effort: ReasoningEffortLevel::Medium,
765 supported_reasoning_efforts: vec![
766 ReasoningEffortPreset {
767 effort: ReasoningEffortLevel::Medium,
768 description: "Balanced".to_string(),
769 },
770 ReasoningEffortPreset {
771 effort: ReasoningEffortLevel::High,
772 description: "Deep thinking".to_string(),
773 },
774 ],
775 is_default: false,
776 upgrade: None,
777 show_in_picker: true,
778 supported_in_api: true,
779 context_window: Some(200_000),
780 },
781 ModelPreset {
782 id: "glm-5.1".to_string(),
783 model: "glm-5.1".to_string(),
784 display_name: "GLM-5.1".to_string(),
785 description:
786 "Z.ai's next-gen foundation model with improved reasoning and agent capabilities"
787 .to_string(),
788 provider: Provider::ZAI,
789 default_reasoning_effort: ReasoningEffortLevel::Medium,
790 supported_reasoning_efforts: vec![
791 ReasoningEffortPreset {
792 effort: ReasoningEffortLevel::Medium,
793 description: "Balanced".to_string(),
794 },
795 ReasoningEffortPreset {
796 effort: ReasoningEffortLevel::High,
797 description: "Deep thinking".to_string(),
798 },
799 ],
800 is_default: true,
801 upgrade: None,
802 show_in_picker: true,
803 supported_in_api: true,
804 context_window: Some(200_000),
805 },
806 ]
807}
808
809fn mistral_presets() -> Vec<ModelPreset> {
810 vec![
811 ModelPreset {
812 id: "mistral-large-2512".to_string(),
813 model: "mistral-large-2512".to_string(),
814 display_name: "Mistral Large 3".to_string(),
815 description:
816 "State-of-the-art open-weight general-purpose multimodal model (41B active, 675B total)".to_string(),
817 provider: Provider::Mistral,
818 default_reasoning_effort: ReasoningEffortLevel::Medium,
819 supported_reasoning_efforts: vec![
820 ReasoningEffortPreset {
821 effort: ReasoningEffortLevel::Medium,
822 description: "Balanced".to_string(),
823 },
824 ReasoningEffortPreset {
825 effort: ReasoningEffortLevel::High,
826 description: "Deep".to_string(),
827 },
828 ],
829 is_default: true,
830 upgrade: None,
831 show_in_picker: true,
832 supported_in_api: true,
833 context_window: Some(256_000),
834 },
835 ModelPreset {
836 id: "mistral-medium-3-5".to_string(),
837 model: "mistral-medium-3-5".to_string(),
838 display_name: "Mistral Medium 3.5".to_string(),
839 description:
840 "Frontier-class multimodal model optimized for agentic and coding use cases (256k context)"
841 .to_string(),
842 provider: Provider::Mistral,
843 default_reasoning_effort: ReasoningEffortLevel::Medium,
844 supported_reasoning_efforts: vec![
845 ReasoningEffortPreset {
846 effort: ReasoningEffortLevel::Medium,
847 description: "Balanced".to_string(),
848 },
849 ReasoningEffortPreset {
850 effort: ReasoningEffortLevel::High,
851 description: "Deep".to_string(),
852 },
853 ],
854 is_default: false,
855 upgrade: None,
856 show_in_picker: true,
857 supported_in_api: true,
858 context_window: Some(256_000),
859 },
860 ModelPreset {
861 id: "mistral-small-2603".to_string(),
862 model: "mistral-small-2603".to_string(),
863 display_name: "Mistral Small 4".to_string(),
864 description:
865 "Hybrid model unifying instruct, reasoning, and coding (119B params, 6.5B active)"
866 .to_string(),
867 provider: Provider::Mistral,
868 default_reasoning_effort: ReasoningEffortLevel::Medium,
869 supported_reasoning_efforts: vec![
870 ReasoningEffortPreset {
871 effort: ReasoningEffortLevel::Medium,
872 description: "Balanced".to_string(),
873 },
874 ReasoningEffortPreset {
875 effort: ReasoningEffortLevel::High,
876 description: "Deep".to_string(),
877 },
878 ],
879 is_default: false,
880 upgrade: None,
881 show_in_picker: true,
882 supported_in_api: true,
883 context_window: Some(256_000),
884 },
885 ModelPreset {
886 id: "mistral-medium-2508".to_string(),
887 model: "mistral-medium-2508".to_string(),
888 display_name: "Mistral Medium 3.1".to_string(),
889 description: "Frontier-class multimodal model with 256k context".to_string(),
890 provider: Provider::Mistral,
891 default_reasoning_effort: ReasoningEffortLevel::Medium,
892 supported_reasoning_efforts: vec![ReasoningEffortPreset {
893 effort: ReasoningEffortLevel::Medium,
894 description: "Balanced".to_string(),
895 }],
896 is_default: false,
897 upgrade: None,
898 show_in_picker: true,
899 supported_in_api: true,
900 context_window: Some(256_000),
901 },
902 ModelPreset {
903 id: "codestral-2508".to_string(),
904 model: "codestral-2508".to_string(),
905 display_name: "Codestral".to_string(),
906 description: "Cutting-edge language model for code completion".to_string(),
907 provider: Provider::Mistral,
908 default_reasoning_effort: ReasoningEffortLevel::Medium,
909 supported_reasoning_efforts: Vec::new(),
910 is_default: false,
911 upgrade: None,
912 show_in_picker: true,
913 supported_in_api: true,
914 context_window: Some(256_000),
915 },
916 ]
917}
918
919fn minimax_presets() -> Vec<ModelPreset> {
920 vec![
921 ModelPreset {
922 id: "minimax-m3".to_string(),
923 model: "MiniMax-M3".to_string(),
924 display_name: "MiniMax M3".to_string(),
925 description: "Frontier multimodal coding model with 1M context".to_string(),
926 provider: Provider::Minimax,
927 default_reasoning_effort: ReasoningEffortLevel::Medium,
928 supported_reasoning_efforts: vec![
929 ReasoningEffortPreset {
930 effort: ReasoningEffortLevel::Medium,
931 description: "Balanced".to_string(),
932 },
933 ReasoningEffortPreset {
934 effort: ReasoningEffortLevel::High,
935 description: "Deep".to_string(),
936 },
937 ],
938 is_default: true,
939 upgrade: None,
940 show_in_picker: true,
941 supported_in_api: true,
942 context_window: Some(1_000_000),
943 },
944 ModelPreset {
945 id: "minimax-m2.5".to_string(),
946 model: "MiniMax-M2.5".to_string(),
947 display_name: "MiniMax M2.5".to_string(),
948 description: "Enhanced code understanding and reasoning".to_string(),
949 provider: Provider::Minimax,
950 default_reasoning_effort: ReasoningEffortLevel::Medium,
951 supported_reasoning_efforts: vec![
952 ReasoningEffortPreset {
953 effort: ReasoningEffortLevel::Medium,
954 description: "Balanced".to_string(),
955 },
956 ReasoningEffortPreset {
957 effort: ReasoningEffortLevel::High,
958 description: "Deep".to_string(),
959 },
960 ],
961 is_default: false,
962 upgrade: None,
963 show_in_picker: true,
964 supported_in_api: true,
965 context_window: Some(128_000),
966 },
967 ]
968}
969
970fn openrouter_presets() -> Vec<ModelPreset> {
971 vec![
972 ModelPreset {
973 id: "openrouter/deepseek/deepseek-chat".to_string(),
974 model: "deepseek/deepseek-chat".to_string(),
975 display_name: "DeepSeek V3.2 (OpenRouter)".to_string(),
976 description: "DeepSeek via OpenRouter".to_string(),
977 provider: Provider::OpenRouter,
978 default_reasoning_effort: ReasoningEffortLevel::Medium,
979 supported_reasoning_efforts: vec![ReasoningEffortPreset {
980 effort: ReasoningEffortLevel::Medium,
981 description: "Balanced".to_string(),
982 }],
983 is_default: false,
984 upgrade: None,
985 show_in_picker: true,
986 supported_in_api: true,
987 context_window: Some(128_000),
988 },
989 ModelPreset {
990 id: "openrouter/moonshotai/kimi-k2.6".to_string(),
991 model: "moonshotai/kimi-k2.6".to_string(),
992 display_name: "Kimi K2.6 (OpenRouter)".to_string(),
993 description: "Kimi K2.6 multimodal agentic model via OpenRouter".to_string(),
994 provider: Provider::OpenRouter,
995 default_reasoning_effort: ReasoningEffortLevel::Medium,
996 supported_reasoning_efforts: vec![ReasoningEffortPreset {
997 effort: ReasoningEffortLevel::Medium,
998 description: "Balanced".to_string(),
999 }],
1000 is_default: false,
1001 upgrade: None,
1002 show_in_picker: true,
1003 supported_in_api: true,
1004 context_window: Some(262_144),
1005 },
1006 ModelPreset {
1007 id: "openrouter/qwen/qwen3.7-max".to_string(),
1008 model: "qwen/qwen3.7-max".to_string(),
1009 display_name: "Qwen3.7 Max (OpenRouter)".to_string(),
1010 description: "Qwen3.7 Max flagship model for coding and agentic workloads via OpenRouter".to_string(),
1011 provider: Provider::OpenRouter,
1012 default_reasoning_effort: ReasoningEffortLevel::Medium,
1013 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1014 effort: ReasoningEffortLevel::Medium,
1015 description: "Balanced".to_string(),
1016 }],
1017 is_default: false,
1018 upgrade: None,
1019 show_in_picker: true,
1020 supported_in_api: true,
1021 context_window: Some(1_000_000),
1022 },
1023 ModelPreset {
1024 id: "openrouter/tencent/hy3-preview".to_string(),
1025 model: "tencent/hy3-preview".to_string(),
1026 display_name: "Hy3 Preview (OpenRouter)".to_string(),
1027 description: "Tencent Hy3 high-efficiency MoE model with configurable reasoning via OpenRouter".to_string(),
1028 provider: Provider::OpenRouter,
1029 default_reasoning_effort: ReasoningEffortLevel::Medium,
1030 supported_reasoning_efforts: vec![
1031 ReasoningEffortPreset {
1032 effort: ReasoningEffortLevel::Low,
1033 description: "Fast".to_string(),
1034 },
1035 ReasoningEffortPreset {
1036 effort: ReasoningEffortLevel::Medium,
1037 description: "Balanced".to_string(),
1038 },
1039 ReasoningEffortPreset {
1040 effort: ReasoningEffortLevel::High,
1041 description: "Deep".to_string(),
1042 },
1043 ],
1044 is_default: false,
1045 upgrade: None,
1046 show_in_picker: true,
1047 supported_in_api: true,
1048 context_window: Some(262_144),
1049 },
1050 ModelPreset {
1051 id: "openrouter/x-ai/grok-build-0.1".to_string(),
1052 model: "x-ai/grok-build-0.1".to_string(),
1053 display_name: "Grok Build 0.1 (OpenRouter)".to_string(),
1054 description: "xAI Grok Build 0.1 coding model for agentic software engineering via OpenRouter".to_string(),
1055 provider: Provider::OpenRouter,
1056 default_reasoning_effort: ReasoningEffortLevel::Medium,
1057 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1058 effort: ReasoningEffortLevel::Medium,
1059 description: "Balanced".to_string(),
1060 }],
1061 is_default: false,
1062 upgrade: None,
1063 show_in_picker: true,
1064 supported_in_api: true,
1065 context_window: Some(256_000),
1066 },
1067 ModelPreset {
1068 id: "openrouter/xiaomi/mimo-v2.5".to_string(),
1069 model: "xiaomi/mimo-v2.5".to_string(),
1070 display_name: "MiMo-V2.5 (OpenRouter)".to_string(),
1071 description: "Xiaomi MiMo-V2.5 omnimodal agentic model for complex software engineering via OpenRouter".to_string(),
1072 provider: Provider::OpenRouter,
1073 default_reasoning_effort: ReasoningEffortLevel::Medium,
1074 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1075 effort: ReasoningEffortLevel::Medium,
1076 description: "Balanced".to_string(),
1077 }],
1078 is_default: false,
1079 upgrade: None,
1080 show_in_picker: true,
1081 supported_in_api: true,
1082 context_window: Some(1_000_000),
1083 },
1084 ModelPreset {
1085 id: "openrouter/xiaomi/mimo-v2.5-pro".to_string(),
1086 model: "xiaomi/mimo-v2.5-pro".to_string(),
1087 display_name: "MiMo-V2.5-Pro (OpenRouter)".to_string(),
1088 description: "Xiaomi MiMo-V2.5-Pro flagship agentic model for complex software engineering via OpenRouter".to_string(),
1089 provider: Provider::OpenRouter,
1090 default_reasoning_effort: ReasoningEffortLevel::Medium,
1091 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1092 effort: ReasoningEffortLevel::Medium,
1093 description: "Balanced".to_string(),
1094 }],
1095 is_default: true,
1096 upgrade: None,
1097 show_in_picker: true,
1098 supported_in_api: true,
1099 context_window: Some(1_000_000),
1100 },
1101 ModelPreset {
1102 id: "openrouter/poolside/laguna-m.1:free".to_string(),
1103 model: "poolside/laguna-m.1:free".to_string(),
1104 display_name: "Laguna M.1 free (OpenRouter)".to_string(),
1105 description: "Poolside Laguna M.1 flagship free coding agent model via OpenRouter".to_string(),
1106 provider: Provider::OpenRouter,
1107 default_reasoning_effort: ReasoningEffortLevel::Medium,
1108 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1109 effort: ReasoningEffortLevel::Medium,
1110 description: "Balanced".to_string(),
1111 }],
1112 is_default: false,
1113 upgrade: None,
1114 show_in_picker: true,
1115 supported_in_api: true,
1116 context_window: Some(262_144),
1117 },
1118 ]
1119}
1120
1121fn ollama_presets() -> Vec<ModelPreset> {
1122 vec![
1123 ModelPreset {
1124 id: "ollama/gpt-oss:20b".to_string(),
1125 model: "gpt-oss:20b".to_string(),
1126 display_name: "GPT-OSS 20B (Ollama)".to_string(),
1127 description: "Open-weight GPT-OSS served locally".to_string(),
1128 provider: Provider::Ollama,
1129 default_reasoning_effort: ReasoningEffortLevel::Medium,
1130 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1131 effort: ReasoningEffortLevel::Medium,
1132 description: "Balanced".to_string(),
1133 }],
1134 is_default: true,
1135 upgrade: None,
1136 show_in_picker: true,
1137 supported_in_api: true,
1138 context_window: Some(96_000),
1139 },
1140 ModelPreset {
1141 id: "ollama/deepseek-v4-flash:cloud".to_string(),
1142 model: "deepseek-v4-flash:cloud".to_string(),
1143 display_name: "DeepSeek V4 Flash (Ollama)".to_string(),
1144 description: "Fast inference DeepSeek V4 Flash model via Ollama Cloud".to_string(),
1145 provider: Provider::Ollama,
1146 default_reasoning_effort: ReasoningEffortLevel::Medium,
1147 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1148 effort: ReasoningEffortLevel::Medium,
1149 description: "Balanced".to_string(),
1150 }],
1151 is_default: false,
1152 upgrade: None,
1153 show_in_picker: true,
1154 supported_in_api: true,
1155 context_window: Some(128_000),
1156 },
1157 ModelPreset {
1158 id: "ollama/deepseek-v4-pro:cloud".to_string(),
1159 model: "deepseek-v4-pro:cloud".to_string(),
1160 display_name: "DeepSeek V4 Pro (Ollama)".to_string(),
1161 description: "High-performance DeepSeek V4 Pro model via Ollama Cloud".to_string(),
1162 provider: Provider::Ollama,
1163 default_reasoning_effort: ReasoningEffortLevel::Medium,
1164 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1165 effort: ReasoningEffortLevel::Medium,
1166 description: "Balanced".to_string(),
1167 }],
1168 is_default: false,
1169 upgrade: None,
1170 show_in_picker: true,
1171 supported_in_api: true,
1172 context_window: Some(128_000),
1173 },
1174 ModelPreset {
1175 id: "ollama/nemotron-3-ultra:cloud".to_string(),
1176 model: "nemotron-3-ultra:cloud".to_string(),
1177 display_name: "Nemotron 3 Ultra (Ollama)".to_string(),
1178 description: "NVIDIA Nemotron 3 Ultra 550B for high-throughput reasoning and long-running agent workflows via Ollama Cloud".to_string(),
1179 provider: Provider::Ollama,
1180 default_reasoning_effort: ReasoningEffortLevel::Medium,
1181 supported_reasoning_efforts: vec![
1182 ReasoningEffortPreset {
1183 effort: ReasoningEffortLevel::Medium,
1184 description: "Balanced".to_string(),
1185 },
1186 ReasoningEffortPreset {
1187 effort: ReasoningEffortLevel::High,
1188 description: "Deep".to_string(),
1189 },
1190 ],
1191 is_default: false,
1192 upgrade: None,
1193 show_in_picker: true,
1194 supported_in_api: true,
1195 context_window: Some(256_000),
1196 },
1197 ModelPreset {
1198 id: "ollama/gemma4".to_string(),
1199 model: "gemma4".to_string(),
1200 display_name: "Gemma 4 (Ollama)".to_string(),
1201 description: "Google Gemma 4 for reasoning, agentic workflows, coding, and multimodal understanding".to_string(),
1202 provider: Provider::Ollama,
1203 default_reasoning_effort: ReasoningEffortLevel::Medium,
1204 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1205 effort: ReasoningEffortLevel::Medium,
1206 description: "Balanced".to_string(),
1207 }],
1208 is_default: false,
1209 upgrade: None,
1210 show_in_picker: true,
1211 supported_in_api: true,
1212 context_window: Some(128_000),
1213 },
1214 ModelPreset {
1215 id: "ollama/minimax-m3:cloud".to_string(),
1216 model: "minimax-m3:cloud".to_string(),
1217 display_name: "MiniMax-M3 (Ollama)".to_string(),
1218 description: "Cloud-hosted MiniMax-M3 model via Ollama Cloud".to_string(),
1219 provider: Provider::Ollama,
1220 default_reasoning_effort: ReasoningEffortLevel::Medium,
1221 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1222 effort: ReasoningEffortLevel::Medium,
1223 description: "Balanced".to_string(),
1224 }],
1225 is_default: false,
1226 upgrade: None,
1227 show_in_picker: true,
1228 supported_in_api: true,
1229 context_window: Some(131_072),
1230 },
1231 ]
1232}
1233
1234fn lmstudio_presets() -> Vec<ModelPreset> {
1235 use crate::config::constants::models::lmstudio as lmstudio_models;
1236 vec![
1237 ModelPreset {
1238 id: format!("lmstudio/{}", lmstudio_models::DEEPSEEK_R1_0528_QWEN3_8B),
1239 model: lmstudio_models::DEEPSEEK_R1_0528_QWEN3_8B.to_string(),
1240 display_name: "DeepSeek R1 0528 Qwen3 8B (LM Studio)".to_string(),
1241 description: "DeepSeek R1 distill on Qwen3 8B, reasoning-capable local model"
1242 .to_string(),
1243 provider: Provider::LmStudio,
1244 default_reasoning_effort: ReasoningEffortLevel::Medium,
1245 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1246 effort: ReasoningEffortLevel::Medium,
1247 description: "Balanced".to_string(),
1248 }],
1249 is_default: false,
1250 upgrade: None,
1251 show_in_picker: true,
1252 supported_in_api: true,
1253 context_window: Some(131_072),
1254 },
1255 ModelPreset {
1256 id: format!("lmstudio/{}", lmstudio_models::QWEN3_8B),
1257 model: lmstudio_models::QWEN3_8B.to_string(),
1258 display_name: "Qwen 3 8B (LM Studio)".to_string(),
1259 description: "Qwen 3 8B with thinking mode support for local inference".to_string(),
1260 provider: Provider::LmStudio,
1261 default_reasoning_effort: ReasoningEffortLevel::Medium,
1262 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1263 effort: ReasoningEffortLevel::Medium,
1264 description: "Balanced".to_string(),
1265 }],
1266 is_default: true,
1267 upgrade: None,
1268 show_in_picker: true,
1269 supported_in_api: true,
1270 context_window: Some(131_072),
1271 },
1272 ModelPreset {
1273 id: format!("lmstudio/{}", lmstudio_models::OPENAI_GPT_OSS_20B),
1274 model: lmstudio_models::OPENAI_GPT_OSS_20B.to_string(),
1275 display_name: "GPT-OSS 20B (LM Studio)".to_string(),
1276 description: "OpenAI's open-weight GPT-OSS 20B model served locally via LM Studio"
1277 .to_string(),
1278 provider: Provider::LmStudio,
1279 default_reasoning_effort: ReasoningEffortLevel::Medium,
1280 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1281 effort: ReasoningEffortLevel::Medium,
1282 description: "Balanced".to_string(),
1283 }],
1284 is_default: false,
1285 upgrade: None,
1286 show_in_picker: true,
1287 supported_in_api: true,
1288 context_window: Some(131_072),
1289 },
1290 ModelPreset {
1291 id: format!("lmstudio/{}", lmstudio_models::META_LLAMA_31_8B_INSTRUCT),
1292 model: lmstudio_models::META_LLAMA_31_8B_INSTRUCT.to_string(),
1293 display_name: "Llama 3.1 8B (LM Studio)".to_string(),
1294 description: "Meta Llama 3.1 8B Instruct for general-purpose local inference"
1295 .to_string(),
1296 provider: Provider::LmStudio,
1297 default_reasoning_effort: ReasoningEffortLevel::Medium,
1298 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1299 effort: ReasoningEffortLevel::Medium,
1300 description: "Balanced".to_string(),
1301 }],
1302 is_default: false,
1303 upgrade: None,
1304 show_in_picker: true,
1305 supported_in_api: true,
1306 context_window: Some(131_072),
1307 },
1308 ModelPreset {
1309 id: format!("lmstudio/{}", lmstudio_models::QWEN25_7B_INSTRUCT),
1310 model: lmstudio_models::QWEN25_7B_INSTRUCT.to_string(),
1311 display_name: "Qwen 2.5 7B (LM Studio)".to_string(),
1312 description: "Qwen 2.5 7B Instruct with tool calling support".to_string(),
1313 provider: Provider::LmStudio,
1314 default_reasoning_effort: ReasoningEffortLevel::Medium,
1315 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1316 effort: ReasoningEffortLevel::Medium,
1317 description: "Balanced".to_string(),
1318 }],
1319 is_default: false,
1320 upgrade: None,
1321 show_in_picker: true,
1322 supported_in_api: true,
1323 context_window: Some(32_768),
1324 },
1325 ModelPreset {
1326 id: format!("lmstudio/{}", lmstudio_models::GEMMA_3_12B_IT),
1327 model: lmstudio_models::GEMMA_3_12B_IT.to_string(),
1328 display_name: "Gemma 3 12B (LM Studio)".to_string(),
1329 description: "Google Gemma 3 12B IT for local inference".to_string(),
1330 provider: Provider::LmStudio,
1331 default_reasoning_effort: ReasoningEffortLevel::Medium,
1332 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1333 effort: ReasoningEffortLevel::Medium,
1334 description: "Balanced".to_string(),
1335 }],
1336 is_default: false,
1337 upgrade: None,
1338 show_in_picker: true,
1339 supported_in_api: true,
1340 context_window: Some(32_768),
1341 },
1342 ]
1343}
1344
1345fn llamacpp_presets() -> Vec<ModelPreset> {
1346 vec![
1347 ModelPreset {
1348 id: format!("llamacpp/{}", llamacpp_models::GPT_OSS_20B),
1349 model: llamacpp_models::GPT_OSS_20B.to_string(),
1350 display_name: "GPT-OSS 20B (llama.cpp)".to_string(),
1351 description: "OpenAI's open-weight GPT-OSS 20B model served locally through llama.cpp"
1352 .to_string(),
1353 provider: Provider::LlamaCpp,
1354 default_reasoning_effort: ReasoningEffortLevel::Medium,
1355 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1356 effort: ReasoningEffortLevel::Medium,
1357 description: "Balanced".to_string(),
1358 }],
1359 is_default: true,
1360 upgrade: None,
1361 show_in_picker: true,
1362 supported_in_api: true,
1363 context_window: Some(131_072),
1364 },
1365 ModelPreset {
1366 id: format!("llamacpp/{}", llamacpp_models::QWEN36_27B),
1367 model: llamacpp_models::QWEN36_27B.to_string(),
1368 display_name: "Qwen 3.6 27B (llama.cpp)".to_string(),
1369 description: "Dense Qwen 3.6 local model served through llama.cpp".to_string(),
1370 provider: Provider::LlamaCpp,
1371 default_reasoning_effort: ReasoningEffortLevel::Medium,
1372 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1373 effort: ReasoningEffortLevel::Medium,
1374 description: "Balanced".to_string(),
1375 }],
1376 is_default: false,
1377 upgrade: None,
1378 show_in_picker: true,
1379 supported_in_api: true,
1380 context_window: Some(262_144),
1381 },
1382 ModelPreset {
1383 id: format!("llamacpp/{}", llamacpp_models::QWEN36_35B_A3B),
1384 model: llamacpp_models::QWEN36_35B_A3B.to_string(),
1385 display_name: "Qwen 3.6 35B A3B (llama.cpp)".to_string(),
1386 description: "Qwen 3.6 MoE local model served through llama.cpp".to_string(),
1387 provider: Provider::LlamaCpp,
1388 default_reasoning_effort: ReasoningEffortLevel::Medium,
1389 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1390 effort: ReasoningEffortLevel::Medium,
1391 description: "Balanced".to_string(),
1392 }],
1393 is_default: false,
1394 upgrade: None,
1395 show_in_picker: true,
1396 supported_in_api: true,
1397 context_window: Some(262_144),
1398 },
1399 ModelPreset {
1400 id: format!("llamacpp/{}", llamacpp_models::GEMMA_4_26B_A4B),
1401 model: llamacpp_models::GEMMA_4_26B_A4B.to_string(),
1402 display_name: "Gemma 4 26B A4B (llama.cpp)".to_string(),
1403 description: "Gemma 4 desktop MoE model served through llama.cpp".to_string(),
1404 provider: Provider::LlamaCpp,
1405 default_reasoning_effort: ReasoningEffortLevel::Medium,
1406 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1407 effort: ReasoningEffortLevel::Medium,
1408 description: "Balanced".to_string(),
1409 }],
1410 is_default: false,
1411 upgrade: None,
1412 show_in_picker: true,
1413 supported_in_api: true,
1414 context_window: Some(262_144),
1415 },
1416 ModelPreset {
1417 id: format!("llamacpp/{}", llamacpp_models::GEMMA_4_E4B),
1418 model: llamacpp_models::GEMMA_4_E4B.to_string(),
1419 display_name: "Gemma 4 E4B (llama.cpp)".to_string(),
1420 description: "Tiny-footprint Gemma 4 model served through llama.cpp".to_string(),
1421 provider: Provider::LlamaCpp,
1422 default_reasoning_effort: ReasoningEffortLevel::Low,
1423 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1424 effort: ReasoningEffortLevel::Low,
1425 description: "Fast".to_string(),
1426 }],
1427 is_default: false,
1428 upgrade: None,
1429 show_in_picker: true,
1430 supported_in_api: true,
1431 context_window: Some(131_072),
1432 },
1433 ModelPreset {
1434 id: format!("llamacpp/{}", llamacpp_models::STEP_3_5_FLASH),
1435 model: llamacpp_models::STEP_3_5_FLASH.to_string(),
1436 display_name: "Step 3.5 Flash (llama.cpp)".to_string(),
1437 description: "StepFun's efficient reasoning model served through llama.cpp".to_string(),
1438 provider: Provider::LlamaCpp,
1439 default_reasoning_effort: ReasoningEffortLevel::Medium,
1440 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1441 effort: ReasoningEffortLevel::Medium,
1442 description: "Balanced".to_string(),
1443 }],
1444 is_default: false,
1445 upgrade: None,
1446 show_in_picker: true,
1447 supported_in_api: true,
1448 context_window: Some(262_144),
1449 },
1450 ]
1451}
1452
1453fn opencode_zen_presets() -> Vec<ModelPreset> {
1454 vec![ModelPreset {
1455 id: "opencode/gpt-5.4".to_string(),
1456 model: "gpt-5.4".to_string(),
1457 display_name: "GPT-5.4 (OpenCode Zen)".to_string(),
1458 description: "OpenCode Zen gateway — curated, benchmarked models at cost".to_string(),
1459 provider: Provider::OpenCodeZen,
1460 default_reasoning_effort: ReasoningEffortLevel::Medium,
1461 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1462 effort: ReasoningEffortLevel::Medium,
1463 description: "Balanced".to_string(),
1464 }],
1465 is_default: true,
1466 upgrade: None,
1467 show_in_picker: true,
1468 supported_in_api: true,
1469 context_window: Some(1_050_000),
1470 }]
1471}
1472
1473fn opencode_go_presets() -> Vec<ModelPreset> {
1474 vec![ModelPreset {
1475 id: "opencode-go/kimi-k2.5".to_string(),
1476 model: "kimi-k2.5".to_string(),
1477 display_name: "Kimi K2.5 (OpenCode Go)".to_string(),
1478 description: "OpenCode Go — affordable subscription for open coding models".to_string(),
1479 provider: Provider::OpenCodeGo,
1480 default_reasoning_effort: ReasoningEffortLevel::Medium,
1481 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1482 effort: ReasoningEffortLevel::Medium,
1483 description: "Balanced".to_string(),
1484 }],
1485 is_default: true,
1486 upgrade: None,
1487 show_in_picker: true,
1488 supported_in_api: true,
1489 context_window: Some(256_000),
1490 }]
1491}
1492
1493fn poolside_presets() -> Vec<ModelPreset> {
1494 vec![
1495 ModelPreset {
1496 id: poolside_models::LAGUNA_M1.to_string(),
1497 model: poolside_models::LAGUNA_M1.to_string(),
1498 display_name: "Laguna M.1".to_string(),
1499 description:
1500 "Poolside's flagship MoE coding agent model optimized for multi-step agentic tasks, tool use, and validation (128K context)"
1501 .to_string(),
1502 provider: Provider::Poolside,
1503 default_reasoning_effort: ReasoningEffortLevel::Medium,
1504 supported_reasoning_efforts: Vec::new(),
1505 is_default: true,
1506 upgrade: None,
1507 show_in_picker: true,
1508 supported_in_api: true,
1509 context_window: Some(131_072),
1510 },
1511 ModelPreset {
1512 id: poolside_models::LAGUNA_XS2.to_string(),
1513 model: poolside_models::LAGUNA_XS2.to_string(),
1514 display_name: "Laguna XS.2".to_string(),
1515 description:
1516 "Poolside's efficient MoE coding agent model optimized for fast agentic coding (128K context)"
1517 .to_string(),
1518 provider: Provider::Poolside,
1519 default_reasoning_effort: ReasoningEffortLevel::Medium,
1520 supported_reasoning_efforts: Vec::new(),
1521 is_default: false,
1522 upgrade: None,
1523 show_in_picker: true,
1524 supported_in_api: true,
1525 context_window: Some(131_072),
1526 },
1527 ]
1528}
1529
1530fn mimo_presets() -> Vec<ModelPreset> {
1531 vec![
1532 ModelPreset {
1533 id: mimo_models::MIMO_V2_5_PRO.to_string(),
1534 model: mimo_models::MIMO_V2_5_PRO.to_string(),
1535 display_name: "MiMo V2.5 Pro".to_string(),
1536 description:
1537 "Xiaomi's flagship reasoning model with advanced capabilities (1M context)"
1538 .to_string(),
1539 provider: Provider::MiMo,
1540 default_reasoning_effort: ReasoningEffortLevel::Medium,
1541 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1542 effort: ReasoningEffortLevel::Medium,
1543 description: "Balanced".to_string(),
1544 }],
1545 is_default: true,
1546 upgrade: None,
1547 show_in_picker: true,
1548 supported_in_api: true,
1549 context_window: Some(1_048_576),
1550 },
1551 ModelPreset {
1552 id: mimo_models::MIMO_V2_5.to_string(),
1553 model: mimo_models::MIMO_V2_5.to_string(),
1554 display_name: "MiMo V2.5".to_string(),
1555 description: "Xiaomi's general-purpose model with strong reasoning (1M context)"
1556 .to_string(),
1557 provider: Provider::MiMo,
1558 default_reasoning_effort: ReasoningEffortLevel::Medium,
1559 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1560 effort: ReasoningEffortLevel::Medium,
1561 description: "Balanced".to_string(),
1562 }],
1563 is_default: false,
1564 upgrade: None,
1565 show_in_picker: true,
1566 supported_in_api: true,
1567 context_window: Some(1_048_576),
1568 },
1569 ModelPreset {
1570 id: mimo_models::MIMO_V2_FLASH.to_string(),
1571 model: mimo_models::MIMO_V2_FLASH.to_string(),
1572 display_name: "MiMo V2 Flash".to_string(),
1573 description: "Xiaomi's lightweight fast model for high-throughput tasks (256K context)"
1574 .to_string(),
1575 provider: Provider::MiMo,
1576 default_reasoning_effort: ReasoningEffortLevel::Low,
1577 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1578 effort: ReasoningEffortLevel::Low,
1579 description: "Fast".to_string(),
1580 }],
1581 is_default: false,
1582 upgrade: None,
1583 show_in_picker: true,
1584 supported_in_api: true,
1585 context_window: Some(262_144),
1586 },
1587 ]
1588}
1589
1590fn qwen_presets() -> Vec<ModelPreset> {
1591 vec![
1592 ModelPreset {
1593 id: qwen_models::QWEN3_7_MAX.to_string(),
1594 model: qwen_models::QWEN3_7_MAX.to_string(),
1595 display_name: "Qwen 3.7 Max".to_string(),
1596 description:
1597 "Alibaba Cloud's flagship reasoning model with 131K context and advanced thinking"
1598 .to_string(),
1599 provider: Provider::Qwen,
1600 default_reasoning_effort: ReasoningEffortLevel::Medium,
1601 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1602 effort: ReasoningEffortLevel::Medium,
1603 description: "Balanced".to_string(),
1604 }],
1605 is_default: true,
1606 upgrade: None,
1607 show_in_picker: true,
1608 supported_in_api: true,
1609 context_window: Some(131_072),
1610 },
1611 ModelPreset {
1612 id: qwen_models::QWEN3_6_FLASH.to_string(),
1613 model: qwen_models::QWEN3_6_FLASH.to_string(),
1614 display_name: "Qwen 3.6 Flash".to_string(),
1615 description:
1616 "Alibaba Cloud's fast inference model with 1M context, optimized for speed and cost-efficiency"
1617 .to_string(),
1618 provider: Provider::Qwen,
1619 default_reasoning_effort: ReasoningEffortLevel::Low,
1620 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1621 effort: ReasoningEffortLevel::Low,
1622 description: "Fast".to_string(),
1623 }],
1624 is_default: false,
1625 upgrade: None,
1626 show_in_picker: true,
1627 supported_in_api: true,
1628 context_window: Some(1_048_576),
1629 },
1630 ModelPreset {
1631 id: qwen_models::QWEN3_6_PLUS.to_string(),
1632 model: qwen_models::QWEN3_6_PLUS.to_string(),
1633 display_name: "Qwen 3.6 Plus".to_string(),
1634 description:
1635 "Alibaba Cloud's balanced model with 131K context, strong reasoning and coding performance"
1636 .to_string(),
1637 provider: Provider::Qwen,
1638 default_reasoning_effort: ReasoningEffortLevel::Medium,
1639 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1640 effort: ReasoningEffortLevel::Medium,
1641 description: "Balanced".to_string(),
1642 }],
1643 is_default: false,
1644 upgrade: None,
1645 show_in_picker: true,
1646 supported_in_api: true,
1647 context_window: Some(131_072),
1648 },
1649 ModelPreset {
1650 id: qwen_models::DEEPSEEK_V4_FLASH.to_string(),
1651 model: qwen_models::DEEPSEEK_V4_FLASH.to_string(),
1652 display_name: "DeepSeek V4 Flash (Qwen)".to_string(),
1653 description:
1654 "DeepSeek V4 Flash fast inference model served through Qwen Cloud API (1M context)"
1655 .to_string(),
1656 provider: Provider::Qwen,
1657 default_reasoning_effort: ReasoningEffortLevel::Low,
1658 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1659 effort: ReasoningEffortLevel::Low,
1660 description: "Fast".to_string(),
1661 }],
1662 is_default: false,
1663 upgrade: None,
1664 show_in_picker: true,
1665 supported_in_api: true,
1666 context_window: Some(1_048_576),
1667 },
1668 ModelPreset {
1669 id: qwen_models::DEEPSEEK_V4_PRO.to_string(),
1670 model: qwen_models::DEEPSEEK_V4_PRO.to_string(),
1671 display_name: "DeepSeek V4 Pro (Qwen)".to_string(),
1672 description:
1673 "DeepSeek V4 Pro high-performance reasoning model served through Qwen Cloud API (1M context)"
1674 .to_string(),
1675 provider: Provider::Qwen,
1676 default_reasoning_effort: ReasoningEffortLevel::Medium,
1677 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1678 effort: ReasoningEffortLevel::Medium,
1679 description: "Balanced".to_string(),
1680 }],
1681 is_default: false,
1682 upgrade: None,
1683 show_in_picker: true,
1684 supported_in_api: true,
1685 context_window: Some(1_048_576),
1686 },
1687 ModelPreset {
1688 id: qwen_models::GLM_5_1.to_string(),
1689 model: qwen_models::GLM_5_1.to_string(),
1690 display_name: "GLM-5.1 (Qwen)".to_string(),
1691 description:
1692 "Z.AI GLM-5.1 next-gen foundation model served through Qwen Cloud API"
1693 .to_string(),
1694 provider: Provider::Qwen,
1695 default_reasoning_effort: ReasoningEffortLevel::Medium,
1696 supported_reasoning_efforts: vec![ReasoningEffortPreset {
1697 effort: ReasoningEffortLevel::Medium,
1698 description: "Balanced".to_string(),
1699 }],
1700 is_default: false,
1701 upgrade: None,
1702 show_in_picker: true,
1703 supported_in_api: true,
1704 context_window: Some(131_072),
1705 },
1706 ]
1707}
1708
1709fn stepfun_presets() -> Vec<ModelPreset> {
1710 vec![ModelPreset {
1711 id: stepfun_models::STEP_3_7_FLASH.to_string(),
1712 model: stepfun_models::STEP_3_7_FLASH.to_string(),
1713 display_name: "Step 3.7 Flash".to_string(),
1714 description:
1715 "StepFun's flagship multimodal reasoning model with 256K context and tool calling."
1716 .to_string(),
1717 provider: Provider::StepFun,
1718 default_reasoning_effort: ReasoningEffortLevel::Medium,
1719 supported_reasoning_efforts: vec![
1720 reasoning_preset(ReasoningEffortLevel::Low, "Fast"),
1721 reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"),
1722 reasoning_preset(ReasoningEffortLevel::High, "Deep"),
1723 ],
1724 is_default: true,
1725 upgrade: None,
1726 show_in_picker: true,
1727 supported_in_api: true,
1728 context_window: Some(262_144),
1729 }]
1730}
1731
1732fn evolink_presets() -> Vec<ModelPreset> {
1733 vec![
1734 ModelPreset {
1735 id: "evolink/gpt-5.2".to_string(),
1736 model: evolink_models::GPT_5_2.to_string(),
1737 display_name: "GPT-5.2 (Evolink)".to_string(),
1738 description: "GPT-5.2 served through the Evolink OpenAI-compatible gateway."
1739 .to_string(),
1740 provider: Provider::Evolink,
1741 default_reasoning_effort: ReasoningEffortLevel::Medium,
1742 supported_reasoning_efforts: vec![reasoning_preset(
1743 ReasoningEffortLevel::Medium,
1744 "Balanced",
1745 )],
1746 is_default: true,
1747 upgrade: None,
1748 show_in_picker: true,
1749 supported_in_api: true,
1750 context_window: Some(400_000),
1751 },
1752 ModelPreset {
1753 id: "evolink/gpt-5.5".to_string(),
1754 model: evolink_models::GPT_5_5.to_string(),
1755 display_name: "GPT-5.5 (Evolink)".to_string(),
1756 description: "GPT-5.5 flagship model served through the Evolink gateway.".to_string(),
1757 provider: Provider::Evolink,
1758 default_reasoning_effort: ReasoningEffortLevel::Medium,
1759 supported_reasoning_efforts: vec![reasoning_preset(
1760 ReasoningEffortLevel::Medium,
1761 "Balanced",
1762 )],
1763 is_default: false,
1764 upgrade: None,
1765 show_in_picker: true,
1766 supported_in_api: true,
1767 context_window: Some(400_000),
1768 },
1769 ModelPreset {
1770 id: "evolink/deepseek-v4-pro".to_string(),
1771 model: evolink_models::DEEPSEEK_V4_PRO.to_string(),
1772 display_name: "DeepSeek V4 Pro (Evolink)".to_string(),
1773 description: "DeepSeek V4 Pro reasoning model served through the Evolink gateway."
1774 .to_string(),
1775 provider: Provider::Evolink,
1776 default_reasoning_effort: ReasoningEffortLevel::Medium,
1777 supported_reasoning_efforts: vec![
1778 reasoning_preset(ReasoningEffortLevel::Low, "Fast"),
1779 reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"),
1780 reasoning_preset(ReasoningEffortLevel::High, "Deep"),
1781 ],
1782 is_default: false,
1783 upgrade: None,
1784 show_in_picker: true,
1785 supported_in_api: true,
1786 context_window: Some(163_840),
1787 },
1788 ModelPreset {
1789 id: "evolink/deepseek-v4-flash".to_string(),
1790 model: evolink_models::DEEPSEEK_V4_FLASH.to_string(),
1791 display_name: "DeepSeek V4 Flash (Evolink)".to_string(),
1792 description:
1793 "DeepSeek V4 Flash fast inference model served through the Evolink gateway."
1794 .to_string(),
1795 provider: Provider::Evolink,
1796 default_reasoning_effort: ReasoningEffortLevel::Medium,
1797 supported_reasoning_efforts: vec![
1798 reasoning_preset(ReasoningEffortLevel::Low, "Fast"),
1799 reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"),
1800 reasoning_preset(ReasoningEffortLevel::High, "Deep"),
1801 ],
1802 is_default: false,
1803 upgrade: None,
1804 show_in_picker: true,
1805 supported_in_api: true,
1806 context_window: Some(1_000_000),
1807 },
1808 ModelPreset {
1809 id: "evolink/doubao-seed-2.0-pro".to_string(),
1810 model: evolink_models::DOUBAO_SEED_2_0_PRO.to_string(),
1811 display_name: "Doubao Seed 2.0 Pro (Evolink)".to_string(),
1812 description: "Doubao Seed 2.0 Pro served through the Evolink gateway.".to_string(),
1813 provider: Provider::Evolink,
1814 default_reasoning_effort: ReasoningEffortLevel::Medium,
1815 supported_reasoning_efforts: vec![
1816 reasoning_preset(ReasoningEffortLevel::Low, "Fast"),
1817 reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"),
1818 reasoning_preset(ReasoningEffortLevel::High, "Deep"),
1819 ],
1820 is_default: false,
1821 upgrade: None,
1822 show_in_picker: true,
1823 supported_in_api: true,
1824 context_window: Some(262_144),
1825 },
1826 ModelPreset {
1827 id: "evolink/gemini-3.1-pro-preview".to_string(),
1828 model: evolink_models::GEMINI_3_1_PRO.to_string(),
1829 display_name: "Gemini 3.1 Pro (Evolink)".to_string(),
1830 description: "Gemini 3.1 Pro served through the Evolink gateway via OpenAI SDK format."
1831 .to_string(),
1832 provider: Provider::Evolink,
1833 default_reasoning_effort: ReasoningEffortLevel::Medium,
1834 supported_reasoning_efforts: vec![reasoning_preset(
1835 ReasoningEffortLevel::Medium,
1836 "Balanced",
1837 )],
1838 is_default: false,
1839 upgrade: None,
1840 show_in_picker: true,
1841 supported_in_api: true,
1842 context_window: Some(1_000_000),
1843 },
1844 ModelPreset {
1845 id: "evolink/gemini-3.5-flash".to_string(),
1846 model: evolink_models::GEMINI_3_5_FLASH.to_string(),
1847 display_name: "Gemini 3.5 Flash (Evolink)".to_string(),
1848 description:
1849 "Gemini 3.5 Flash served through the Evolink gateway via OpenAI SDK format."
1850 .to_string(),
1851 provider: Provider::Evolink,
1852 default_reasoning_effort: ReasoningEffortLevel::Medium,
1853 supported_reasoning_efforts: vec![reasoning_preset(
1854 ReasoningEffortLevel::Medium,
1855 "Balanced",
1856 )],
1857 is_default: false,
1858 upgrade: None,
1859 show_in_picker: true,
1860 supported_in_api: true,
1861 context_window: Some(1_000_000),
1862 },
1863 ModelPreset {
1864 id: "evolink/MiniMax-M3".to_string(),
1865 model: evolink_models::MINIMAX_M3.to_string(),
1866 display_name: "MiniMax-M3 (Evolink)".to_string(),
1867 description: "MiniMax-M3 frontier multimodal model served through the Evolink gateway."
1868 .to_string(),
1869 provider: Provider::Evolink,
1870 default_reasoning_effort: ReasoningEffortLevel::Medium,
1871 supported_reasoning_efforts: vec![reasoning_preset(
1872 ReasoningEffortLevel::Medium,
1873 "Balanced",
1874 )],
1875 is_default: false,
1876 upgrade: None,
1877 show_in_picker: true,
1878 supported_in_api: true,
1879 context_window: Some(1_000_000),
1880 },
1881 ModelPreset {
1882 id: "evolink/claude-sonnet-4-6".to_string(),
1883 model: evolink_models::CLAUDE_SONNET_4_6.to_string(),
1884 display_name: "Claude Sonnet 4.6 (Evolink)".to_string(),
1885 description: "Claude Sonnet 4.6 served through Evolink via Anthropic Messages API."
1886 .to_string(),
1887 provider: Provider::Evolink,
1888 default_reasoning_effort: ReasoningEffortLevel::Medium,
1889 supported_reasoning_efforts: vec![reasoning_preset(
1890 ReasoningEffortLevel::Medium,
1891 "Balanced",
1892 )],
1893 is_default: false,
1894 upgrade: None,
1895 show_in_picker: true,
1896 supported_in_api: true,
1897 context_window: Some(200_000),
1898 },
1899 ModelPreset {
1900 id: "evolink/claude-opus-4-8".to_string(),
1901 model: evolink_models::CLAUDE_OPUS_4_8.to_string(),
1902 display_name: "Claude Opus 4.8 (Evolink)".to_string(),
1903 description: "Claude Opus 4.8 served through Evolink via Anthropic Messages API."
1904 .to_string(),
1905 provider: Provider::Evolink,
1906 default_reasoning_effort: ReasoningEffortLevel::High,
1907 supported_reasoning_efforts: vec![
1908 reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"),
1909 reasoning_preset(ReasoningEffortLevel::High, "Deep"),
1910 ],
1911 is_default: false,
1912 upgrade: None,
1913 show_in_picker: true,
1914 supported_in_api: true,
1915 context_window: Some(200_000),
1916 },
1917 ModelPreset {
1918 id: "evolink/claude-haiku-4-5-20251001".to_string(),
1919 model: evolink_models::CLAUDE_HAIKU_4_5.to_string(),
1920 display_name: "Claude Haiku 4.5 (Evolink)".to_string(),
1921 description:
1922 "Claude Haiku 4.5 fast model served through Evolink via Anthropic Messages API."
1923 .to_string(),
1924 provider: Provider::Evolink,
1925 default_reasoning_effort: ReasoningEffortLevel::Low,
1926 supported_reasoning_efforts: vec![
1927 reasoning_preset(ReasoningEffortLevel::Low, "Fast"),
1928 reasoning_preset(ReasoningEffortLevel::Medium, "Balanced"),
1929 ],
1930 is_default: false,
1931 upgrade: None,
1932 show_in_picker: true,
1933 supported_in_api: true,
1934 context_window: Some(200_000),
1935 },
1936 ]
1937}
1938
1939fn moonshot_presets() -> Vec<ModelPreset> {
1940 vec![
1941 ModelPreset {
1942 id: "kimi-k2.6".to_string(),
1943 model: "kimi-k2.6".to_string(),
1944 display_name: "Kimi K2.6 (Moonshot)".to_string(),
1945 description: "Moonshot's latest flagship coding and agent model.".to_string(),
1946 provider: Provider::Moonshot,
1947 default_reasoning_effort: ReasoningEffortLevel::Medium,
1948 supported_reasoning_efforts: vec![reasoning_preset(
1949 ReasoningEffortLevel::Medium,
1950 "Balanced",
1951 )],
1952 is_default: true,
1953 upgrade: None,
1954 show_in_picker: true,
1955 supported_in_api: true,
1956 context_window: Some(256_000),
1957 },
1958 ModelPreset {
1959 id: "kimi-k2.5".to_string(),
1960 model: "kimi-k2.5".to_string(),
1961 display_name: "Kimi K2.5 (Moonshot)".to_string(),
1962 description: "Moonshot's previous flagship model for long-context coding.".to_string(),
1963 provider: Provider::Moonshot,
1964 default_reasoning_effort: ReasoningEffortLevel::Medium,
1965 supported_reasoning_efforts: vec![reasoning_preset(
1966 ReasoningEffortLevel::Medium,
1967 "Balanced",
1968 )],
1969 is_default: false,
1970 upgrade: None,
1971 show_in_picker: true,
1972 supported_in_api: true,
1973 context_window: Some(256_000),
1974 },
1975 ]
1976}
1977
1978fn huggingface_presets() -> Vec<ModelPreset> {
1979 vec![
1980 ModelPreset {
1981 id: "huggingface/deepseek-v4-flash".to_string(),
1982 model: "deepseek-ai/DeepSeek-V4-Flash:novita".to_string(),
1983 display_name: "DeepSeek V4 Flash (HF/Novita)".to_string(),
1984 description:
1985 "Fast inference model for cost-effective reasoning (1M context, 158B params)"
1986 .to_string(),
1987 provider: Provider::HuggingFace,
1988 default_reasoning_effort: ReasoningEffortLevel::High,
1989 supported_reasoning_efforts: vec![
1990 ReasoningEffortPreset {
1991 effort: ReasoningEffortLevel::High,
1992 description: "Balanced".to_string(),
1993 },
1994 ReasoningEffortPreset {
1995 effort: ReasoningEffortLevel::Max,
1996 description: "Maximum thinking".to_string(),
1997 },
1998 ],
1999 is_default: false,
2000 upgrade: None,
2001 show_in_picker: true,
2002 supported_in_api: true,
2003 context_window: Some(1_000_000),
2004 },
2005 ModelPreset {
2006 id: "huggingface/deepseek-v4-pro".to_string(),
2007 model: "deepseek-ai/DeepSeek-V4-Pro:together".to_string(),
2008 display_name: "DeepSeek V4 Pro (HF/Together)".to_string(),
2009 description:
2010 "High-performance reasoning model with advanced thinking capabilities (1M context, 1.6T params)"
2011 .to_string(),
2012 provider: Provider::HuggingFace,
2013 default_reasoning_effort: ReasoningEffortLevel::High,
2014 supported_reasoning_efforts: vec![
2015 ReasoningEffortPreset {
2016 effort: ReasoningEffortLevel::High,
2017 description: "Balanced".to_string(),
2018 },
2019 ReasoningEffortPreset {
2020 effort: ReasoningEffortLevel::Max,
2021 description: "Maximum thinking".to_string(),
2022 },
2023 ],
2024 is_default: false,
2025 upgrade: None,
2026 show_in_picker: true,
2027 supported_in_api: true,
2028 context_window: Some(1_000_000),
2029 },
2030 ModelPreset {
2031 id: "huggingface/nvidia-nemotron-3-ultra".to_string(),
2032 model: "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4:together".to_string(),
2033 display_name: "NVIDIA-Nemotron-3-Ultra-550B (HF/Together)".to_string(),
2034 description:
2035 "NVIDIA Nemotron 3 Ultra 550B-A55B-NVFP4 via Together inference provider"
2036 .to_string(),
2037 provider: Provider::HuggingFace,
2038 default_reasoning_effort: ReasoningEffortLevel::High,
2039 supported_reasoning_efforts: vec![
2040 ReasoningEffortPreset {
2041 effort: ReasoningEffortLevel::High,
2042 description: "Balanced".to_string(),
2043 },
2044 ReasoningEffortPreset {
2045 effort: ReasoningEffortLevel::Max,
2046 description: "Maximum thinking".to_string(),
2047 },
2048 ],
2049 is_default: false,
2050 upgrade: None,
2051 show_in_picker: true,
2052 supported_in_api: true,
2053 context_window: Some(128_000),
2054 },
2055 ]
2056}
2057
2058#[cfg(test)]
2060pub fn all_model_presets() -> Vec<ModelPreset> {
2061 builtin_model_presets()
2062}
2063
2064#[cfg(test)]
2065mod tests {
2066 use super::*;
2067
2068 #[test]
2069 fn only_one_default_per_provider() {
2070 let presets = builtin_model_presets();
2071 let providers: Vec<Provider> = Provider::all_providers();
2072
2073 for provider in providers {
2074 let default_count = presets
2075 .iter()
2076 .filter(|p| p.provider == provider && p.is_default)
2077 .count();
2078 assert!(
2079 default_count <= 1,
2080 "Provider {:?} has {} defaults, expected 0 or 1",
2081 provider,
2082 default_count
2083 );
2084 }
2085 }
2086
2087 #[test]
2088 fn gemini_presets_exist() {
2089 let presets = gemini_presets();
2090 assert!(!presets.is_empty());
2091 assert!(presets.iter().any(|p| p.id.contains("gemini")));
2092 }
2093
2094 #[test]
2095 fn model_info_converts_to_preset() {
2096 let info = ModelInfo {
2097 slug: "test-model".to_string(),
2098 display_name: "Test Model".to_string(),
2099 description: "A test model".to_string(),
2100 provider: Provider::Gemini,
2101 default_reasoning_level: ReasoningEffortLevel::Medium,
2102 supported_reasoning_levels: vec![],
2103 context_window: Some(128_000),
2104 supports_tool_use: true,
2105 supports_streaming: true,
2106 supports_reasoning: false,
2107 priority: 0,
2108 visibility: "list".to_string(),
2109 supported_in_api: true,
2110 upgrade: None,
2111 };
2112
2113 let preset: ModelPreset = info.into();
2114 assert_eq!(preset.id, "test-model");
2115 assert_eq!(preset.model, "test-model");
2116 assert!(preset.show_in_picker);
2117 }
2118
2119 #[test]
2120 fn openai_codex_presets_default_to_high_reasoning() {
2121 let codex = openai_presets()
2122 .into_iter()
2123 .find(|preset| preset.id == "gpt-5.3-codex")
2124 .expect("gpt-5.3-codex preset");
2125
2126 assert_eq!(codex.default_reasoning_effort, ReasoningEffortLevel::High);
2127 }
2128
2129 #[test]
2130 fn moonshot_presets_exist_and_default_to_kimi_k26() {
2131 let presets = moonshot_presets();
2132 assert_eq!(presets.len(), 2);
2133 assert!(presets.iter().any(|preset| preset.id == "kimi-k2.5"));
2134
2135 let default = presets
2136 .iter()
2137 .find(|preset| preset.is_default)
2138 .expect("moonshot default preset");
2139 assert_eq!(default.id, "kimi-k2.6");
2140 assert_eq!(default.provider, Provider::Moonshot);
2141 }
2142}