vtcode_config/models/model_id/
parse.rs1use std::str::FromStr;
2
3use crate::models::ModelParseError;
4
5use super::ModelId;
6
7impl FromStr for ModelId {
8 type Err = ModelParseError;
9
10 fn from_str(s: &str) -> Result<Self, Self::Err> {
11 use crate::constants::models;
12
13 if s == models::zai::GLM_5 || s == models::zai::GLM_5_LEGACY {
15 return Ok(ModelId::ZaiGlm5);
16 }
17
18 if let Some(model) = Self::parse_openrouter_model(s) {
19 return Ok(model);
20 }
21
22 match s {
23 s if s == models::GEMINI_3_1_PRO_PREVIEW => Ok(ModelId::Gemini31ProPreview),
25 s if s == models::GEMINI_3_1_PRO_PREVIEW_CUSTOMTOOLS => {
26 Ok(ModelId::Gemini31ProPreviewCustomTools)
27 }
28 s if s == models::GEMINI_3_1_FLASH_LITE_PREVIEW => {
29 Ok(ModelId::Gemini31FlashLitePreview)
30 }
31 s if s == models::GEMINI_3_FLASH_PREVIEW => Ok(ModelId::Gemini3FlashPreview),
32 s if s == models::GPT => Ok(ModelId::GPT),
34 s if s == models::GPT_5 => Ok(ModelId::GPT5),
35 s if s == models::GPT_5_2 => Ok(ModelId::GPT52),
36 s if s == models::GPT_5_4 => Ok(ModelId::GPT54),
37 s if s == models::GPT_5_4_PRO => Ok(ModelId::GPT54Pro),
38 s if s == models::GPT_5_MINI => Ok(ModelId::GPT5Mini),
39 s if s == models::GPT_5_NANO => Ok(ModelId::GPT5Nano),
40 s if s == models::openai::GPT_5_3_CODEX => Ok(ModelId::GPT53Codex),
41 s if s == models::openai::GPT_OSS_20B => Ok(ModelId::OpenAIGptOss20b),
42 s if s == models::openai::GPT_OSS_120B => Ok(ModelId::OpenAIGptOss120b),
43 s if s == models::CLAUDE_OPUS_4_6 => Ok(ModelId::ClaudeOpus46),
45 s if s == models::CLAUDE_SONNET_4_6 => Ok(ModelId::ClaudeSonnet46),
46 s if s == models::CLAUDE_HAIKU_4_5 => Ok(ModelId::ClaudeHaiku45),
47 s if s == models::CLAUDE_HAIKU_4_5_20251001 => Ok(ModelId::ClaudeHaiku45),
48 s if s == models::DEEPSEEK_CHAT => Ok(ModelId::DeepSeekChat),
50 s if s == models::DEEPSEEK_REASONER => Ok(ModelId::DeepSeekReasoner),
51 s if s == models::zai::GLM_5 || s == models::zai::GLM_5_LEGACY => Ok(ModelId::ZaiGlm5),
53 s if s == models::moonshot::KIMI_K2_5 => Ok(ModelId::MoonshotKimiK25),
55 s if s == models::ollama::GPT_OSS_20B => Ok(ModelId::OllamaGptOss20b),
56 s if s == models::ollama::GPT_OSS_20B_CLOUD => Ok(ModelId::OllamaGptOss20bCloud),
57 s if s == models::ollama::GPT_OSS_120B_CLOUD => Ok(ModelId::OllamaGptOss120bCloud),
58 s if s == models::ollama::QWEN3_1_7B => Ok(ModelId::OllamaQwen317b),
59 s if s == models::ollama::QWEN3_CODER_NEXT => Ok(ModelId::OllamaQwen3CoderNext),
60 "qwen3-coder-next" => Ok(ModelId::OllamaQwen3CoderNext),
61 s if s == models::ollama::DEEPSEEK_V32_CLOUD => Ok(ModelId::OllamaDeepseekV32Cloud),
62 s if s == models::ollama::QWEN3_NEXT_80B_CLOUD => Ok(ModelId::OllamaQwen3Next80bCloud),
63 s if s == models::ollama::GLM_5_CLOUD => Ok(ModelId::OllamaGlm5Cloud),
64 s if s == models::ollama::GEMINI_3_FLASH_PREVIEW_CLOUD => {
65 Ok(ModelId::OllamaGemini3FlashPreviewCloud)
66 }
67 s if s == models::ollama::MINIMAX_M2_CLOUD => Ok(ModelId::OllamaMinimaxM2Cloud),
68 s if s == models::ollama::MINIMAX_M25_CLOUD => Ok(ModelId::OllamaMinimaxM25Cloud),
69 s if s == models::minimax::MINIMAX_M2_5 => Ok(ModelId::MinimaxM25),
70 s if s == models::huggingface::DEEPSEEK_V32 => Ok(ModelId::HuggingFaceDeepseekV32),
72 s if s == models::huggingface::OPENAI_GPT_OSS_20B => {
73 Ok(ModelId::HuggingFaceOpenAIGptOss20b)
74 }
75 s if s == models::huggingface::OPENAI_GPT_OSS_120B => {
76 Ok(ModelId::HuggingFaceOpenAIGptOss120b)
77 }
78 s if s == models::huggingface::MINIMAX_M2_5_NOVITA => {
79 Ok(ModelId::HuggingFaceMinimaxM25Novita)
80 }
81 s if s == models::huggingface::DEEPSEEK_V32_NOVITA => {
82 Ok(ModelId::HuggingFaceDeepseekV32Novita)
83 }
84 s if s == models::huggingface::XIAOMI_MIMO_V2_FLASH_NOVITA => {
85 Ok(ModelId::HuggingFaceXiaomiMimoV2FlashNovita)
86 }
87 s if s == models::huggingface::ZAI_GLM_5_NOVITA => Ok(ModelId::HuggingFaceGlm5Novita),
88 s if s == models::huggingface::QWEN3_CODER_NEXT_NOVITA => {
89 Ok(ModelId::HuggingFaceQwen3CoderNextNovita)
90 }
91 s if s == models::huggingface::QWEN3_5_397B_A17B_TOGETHER => {
92 Ok(ModelId::HuggingFaceQwen35397BA17BTogether)
93 }
94 s if s == models::huggingface::STEP_3_5_FLASH
95 || s == models::huggingface::STEP_3_5_FLASH_BASE
96 || s == models::huggingface::STEP_3_5_FLASH_LEGACY_FASTEST =>
97 {
98 Ok(ModelId::HuggingFaceStep35Flash)
99 }
100 "minimax/minimax-m2.5" => Ok(ModelId::OpenRouterMinimaxM25),
101 "qwen/qwen3-coder-next" => Ok(ModelId::OpenRouterQwen3CoderNext),
102 _ => {
103 if let Some(model) = Self::parse_openrouter_model(s) {
104 Ok(model)
105 } else {
106 Err(ModelParseError::InvalidModel(s.to_string()))
107 }
108 }
109 }
110 }
111}