Skip to main content

vtcode_config/models/model_id/
parse.rs

1use 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        if let Some(model) = Self::parse_openrouter_model(s) {
12            return Ok(model);
13        }
14
15        use crate::constants::models;
16        match s {
17            // Gemini models
18            s if s == models::GEMINI_2_5_FLASH_PREVIEW => Ok(ModelId::Gemini25FlashPreview),
19            s if s == models::GEMINI_2_5_FLASH => Ok(ModelId::Gemini25Flash),
20            s if s == models::GEMINI_2_5_FLASH_LITE => Ok(ModelId::Gemini25FlashLite),
21            s if s == models::GEMINI_2_5_PRO => Ok(ModelId::Gemini25Pro),
22            s if s == models::GEMINI_3_PRO_PREVIEW => Ok(ModelId::Gemini3ProPreview),
23            // OpenAI models
24            s if s == models::GPT_5 => Ok(ModelId::GPT5),
25            s if s == models::GPT_5_CODEX => Ok(ModelId::GPT5Codex),
26            s if s == models::GPT_5_MINI => Ok(ModelId::GPT5Mini),
27            s if s == models::GPT_5_NANO => Ok(ModelId::GPT5Nano),
28            s if s == models::CODEX_MINI_LATEST => Ok(ModelId::CodexMiniLatest),
29            s if s == models::openai::GPT_OSS_20B => Ok(ModelId::OpenAIGptOss20b),
30            s if s == models::openai::GPT_OSS_120B => Ok(ModelId::OpenAIGptOss120b),
31            // Anthropic models
32            s if s == models::CLAUDE_OPUS_4_5 => Ok(ModelId::ClaudeOpus45),
33            s if s == models::CLAUDE_OPUS_4_1 => Ok(ModelId::ClaudeOpus41),
34            s if s == models::CLAUDE_SONNET_4_5 => Ok(ModelId::ClaudeSonnet45),
35            s if s == models::CLAUDE_HAIKU_4_5 => Ok(ModelId::ClaudeHaiku45),
36            s if s == models::CLAUDE_SONNET_4_5_20250929 => Ok(ModelId::ClaudeSonnet4),
37            // DeepSeek models
38            s if s == models::DEEPSEEK_CHAT => Ok(ModelId::DeepSeekChat),
39            s if s == models::DEEPSEEK_REASONER => Ok(ModelId::DeepSeekReasoner),
40            // xAI models
41            s if s == models::xai::GROK_4 => Ok(ModelId::XaiGrok4),
42            s if s == models::xai::GROK_4_MINI => Ok(ModelId::XaiGrok4Mini),
43            s if s == models::xai::GROK_4_CODE => Ok(ModelId::XaiGrok4Code),
44            s if s == models::xai::GROK_4_CODE_LATEST => Ok(ModelId::XaiGrok4CodeLatest),
45            s if s == models::xai::GROK_4_VISION => Ok(ModelId::XaiGrok4Vision),
46            // Z.AI models
47            s if s == models::zai::GLM_4_PLUS => Ok(ModelId::ZaiGlm4Plus),
48            s if s == models::zai::GLM_4_PLUS_DEEP_THINKING => Ok(ModelId::ZaiGlm4PlusDeepThinking),
49            s if s == models::zai::GLM_4_7 => Ok(ModelId::ZaiGlm47),
50            s if s == models::zai::GLM_4_7_DEEP_THINKING => Ok(ModelId::ZaiGlm47DeepThinking),
51            s if s == models::zai::GLM_4_6 => Ok(ModelId::ZaiGlm46),
52            s if s == models::zai::GLM_4_6_DEEP_THINKING => Ok(ModelId::ZaiGlm46DeepThinking),
53            s if s == models::zai::GLM_4_6V => Ok(ModelId::ZaiGlm46V),
54            s if s == models::zai::GLM_4_6V_FLASH => Ok(ModelId::ZaiGlm46VFlash),
55            s if s == models::zai::GLM_4_6V_FLASHX => Ok(ModelId::ZaiGlm46VFlashX),
56            s if s == models::zai::GLM_4_5 => Ok(ModelId::ZaiGlm45),
57            s if s == models::zai::GLM_4_5_DEEP_THINKING => Ok(ModelId::ZaiGlm45DeepThinking),
58            s if s == models::zai::GLM_4_5_AIR => Ok(ModelId::ZaiGlm45Air),
59            s if s == models::zai::GLM_4_5_X => Ok(ModelId::ZaiGlm45X),
60            s if s == models::zai::GLM_4_5_AIRX => Ok(ModelId::ZaiGlm45Airx),
61            s if s == models::zai::GLM_4_5_FLASH => Ok(ModelId::ZaiGlm45Flash),
62            s if s == models::zai::GLM_4_5V => Ok(ModelId::ZaiGlm45V),
63            s if s == models::zai::GLM_4_32B_0414_128K => Ok(ModelId::ZaiGlm432b0414128k),
64            // Moonshot models
65            s if s == models::moonshot::KIMI_K2_5 => Ok(ModelId::MoonshotKimiK25),
66            s if s == models::ollama::GPT_OSS_20B => Ok(ModelId::OllamaGptOss20b),
67            s if s == models::ollama::GPT_OSS_20B_CLOUD => Ok(ModelId::OllamaGptOss20bCloud),
68            s if s == models::ollama::GPT_OSS_120B_CLOUD => Ok(ModelId::OllamaGptOss120bCloud),
69            s if s == models::ollama::QWEN3_1_7B => Ok(ModelId::OllamaQwen317b),
70            s if s == models::ollama::DEEPSEEK_V32_CLOUD => Ok(ModelId::OllamaDeepseekV32Cloud),
71            s if s == models::ollama::QWEN3_NEXT_80B_CLOUD => Ok(ModelId::OllamaQwen3Next80bCloud),
72            s if s == models::ollama::MISTRAL_LARGE_3_675B_CLOUD => {
73                Ok(ModelId::OllamaMistralLarge3675bCloud)
74            }
75            s if s == models::ollama::KIMI_K2_THINKING_CLOUD => {
76                Ok(ModelId::OllamaKimiK2ThinkingCloud)
77            }
78            s if s == models::ollama::QWEN3_CODER_480B_CLOUD => {
79                Ok(ModelId::OllamaQwen3Coder480bCloud)
80            }
81            s if s == models::ollama::GLM_46_CLOUD => Ok(ModelId::OllamaGlm46Cloud),
82            s if s == models::ollama::GLM_47_CLOUD => Ok(ModelId::OllamaGlm47Cloud),
83            s if s == models::ollama::GEMINI_3_PRO_PREVIEW_LATEST_CLOUD => {
84                Ok(ModelId::OllamaGemini3ProPreviewLatestCloud)
85            }
86            s if s == models::ollama::GEMINI_3_FLASH_PREVIEW_CLOUD => {
87                Ok(ModelId::OllamaGemini3FlashPreviewCloud)
88            }
89            s if s == models::ollama::MINIMAX_M2_CLOUD => Ok(ModelId::OllamaMinimaxM2Cloud),
90            s if s == models::ollama::MINIMAX_M21_CLOUD => Ok(ModelId::OllamaMinimaxM21Cloud),
91            s if s == models::ollama::DEVSTRAL_2_123B_CLOUD => {
92                Ok(ModelId::OllamaDevstral2123bCloud)
93            }
94            s if s == models::ollama::NEMOTRON_3_NANO_30B_CLOUD => {
95                Ok(ModelId::OllamaNemotron3Nano30bCloud)
96            }
97            s if s == models::lmstudio::META_LLAMA_3_8B_INSTRUCT => {
98                Ok(ModelId::LmStudioMetaLlama38BInstruct)
99            }
100            s if s == models::lmstudio::META_LLAMA_31_8B_INSTRUCT => {
101                Ok(ModelId::LmStudioMetaLlama318BInstruct)
102            }
103            s if s == models::lmstudio::QWEN25_7B_INSTRUCT => Ok(ModelId::LmStudioQwen257BInstruct),
104            s if s == models::lmstudio::GEMMA_2_2B_IT => Ok(ModelId::LmStudioGemma22BIt),
105            s if s == models::lmstudio::GEMMA_2_9B_IT => Ok(ModelId::LmStudioGemma29BIt),
106            s if s == models::lmstudio::PHI_31_MINI_4K_INSTRUCT => {
107                Ok(ModelId::LmStudioPhi31Mini4kInstruct)
108            }
109            s if s == models::minimax::MINIMAX_M2_1 => Ok(ModelId::MinimaxM21),
110            s if s == models::minimax::MINIMAX_M2_1_LIGHTNING => Ok(ModelId::MinimaxM21Lightning),
111            s if s == models::minimax::MINIMAX_M2 => Ok(ModelId::MinimaxM2),
112            // Hugging Face models
113            s if s == models::huggingface::DEEPSEEK_V32 => Ok(ModelId::HuggingFaceDeepseekV32),
114            s if s == models::huggingface::OPENAI_GPT_OSS_20B => {
115                Ok(ModelId::HuggingFaceOpenAIGptOss20b)
116            }
117            s if s == models::huggingface::OPENAI_GPT_OSS_120B => {
118                Ok(ModelId::HuggingFaceOpenAIGptOss120b)
119            }
120            s if s == models::huggingface::ZAI_GLM_47 => Ok(ModelId::HuggingFaceGlm47),
121            s if s == models::huggingface::MOONSHOT_KIMI_K2_THINKING => {
122                Ok(ModelId::HuggingFaceKimiK2Thinking)
123            }
124            s if s == models::huggingface::MOONSHOT_KIMI_K2_5_NOVITA => {
125                Ok(ModelId::HuggingFaceKimiK25Novita)
126            }
127            s if s == models::huggingface::MINIMAX_M2_1_NOVITA => {
128                Ok(ModelId::HuggingFaceMinimaxM21Novita)
129            }
130            s if s == models::huggingface::DEEPSEEK_V32_NOVITA => {
131                Ok(ModelId::HuggingFaceDeepseekV32Novita)
132            }
133            s if s == models::huggingface::XIAOMI_MIMO_V2_FLASH_NOVITA => {
134                Ok(ModelId::HuggingFaceXiaomiMimoV2FlashNovita)
135            }
136            _ => Err(ModelParseError::InvalidModel(s.to_string())),
137        }
138    }
139}