Skip to main content

vtcode_config/models/model_id/
capabilities.rs

1use super::ModelId;
2
3impl ModelId {
4    /// Check if this is a "flash" variant (optimized for speed)
5    pub fn is_flash_variant(&self) -> bool {
6        matches!(
7            self,
8            ModelId::Gemini25FlashPreview
9                | ModelId::Gemini25Flash
10                | ModelId::Gemini25FlashLite
11                | ModelId::ZaiGlm45Flash
12                | ModelId::ZaiGlm46VFlash
13                | ModelId::ZaiGlm46VFlashX
14                | ModelId::MinimaxM21Lightning
15                | ModelId::OllamaGemini3FlashPreviewCloud
16        )
17    }
18
19    /// Check if this is a "pro" variant (optimized for capability)
20    pub fn is_pro_variant(&self) -> bool {
21        matches!(
22            self,
23            ModelId::Gemini25Pro
24                | ModelId::GPT5
25                | ModelId::GPT5Codex
26                | ModelId::ClaudeOpus41
27                | ModelId::DeepSeekReasoner
28                | ModelId::XaiGrok4
29                | ModelId::ZaiGlm4Plus
30                | ModelId::ZaiGlm4PlusDeepThinking
31                | ModelId::ZaiGlm47
32                | ModelId::ZaiGlm47DeepThinking
33                | ModelId::ZaiGlm46
34                | ModelId::ZaiGlm46DeepThinking
35                | ModelId::MinimaxM21
36                | ModelId::OllamaGlm47Cloud
37                | ModelId::OllamaMinimaxM21Cloud
38                | ModelId::MoonshotKimiK25
39        )
40    }
41
42    /// Check if this is an optimized/efficient variant
43    pub fn is_efficient_variant(&self) -> bool {
44        if let Some(meta) = self.openrouter_metadata() {
45            return meta.efficient;
46        }
47        matches!(
48            self,
49            ModelId::Gemini25FlashPreview
50                | ModelId::Gemini25Flash
51                | ModelId::Gemini25FlashLite
52                | ModelId::GPT5Mini
53                | ModelId::GPT5Nano
54                | ModelId::ClaudeHaiku45
55                | ModelId::DeepSeekChat
56                | ModelId::XaiGrok4Code
57                | ModelId::ZaiGlm45Air
58                | ModelId::ZaiGlm45Airx
59                | ModelId::ZaiGlm45Flash
60                | ModelId::ZaiGlm46VFlash
61                | ModelId::ZaiGlm46VFlashX
62        )
63    }
64
65    /// Check if this is a top-tier model
66    pub fn is_top_tier(&self) -> bool {
67        if let Some(meta) = self.openrouter_metadata() {
68            return meta.top_tier;
69        }
70        matches!(
71            self,
72            ModelId::Gemini25Pro
73                | ModelId::GPT5
74                | ModelId::GPT5Codex
75                | ModelId::ClaudeOpus41
76                | ModelId::ClaudeSonnet45
77                | ModelId::ClaudeSonnet4
78                | ModelId::DeepSeekReasoner
79                | ModelId::XaiGrok4
80                | ModelId::XaiGrok4CodeLatest
81                | ModelId::ZaiGlm4Plus
82                | ModelId::ZaiGlm4PlusDeepThinking
83                | ModelId::ZaiGlm47
84                | ModelId::ZaiGlm47DeepThinking
85                | ModelId::ZaiGlm46
86                | ModelId::ZaiGlm46DeepThinking
87                | ModelId::MoonshotKimiK25
88        )
89    }
90
91    /// Determine whether the model is a reasoning-capable variant
92    pub fn is_reasoning_variant(&self) -> bool {
93        if let Some(meta) = self.openrouter_metadata() {
94            return meta.reasoning;
95        }
96        matches!(
97            self,
98            ModelId::ZaiGlm4PlusDeepThinking
99                | ModelId::ZaiGlm47DeepThinking
100                | ModelId::ZaiGlm46DeepThinking
101                | ModelId::ZaiGlm45DeepThinking
102        ) || self.provider().supports_reasoning_effort(self.as_str())
103    }
104
105    /// Determine whether the model supports tool calls/function execution
106    pub fn supports_tool_calls(&self) -> bool {
107        if let Some(meta) = self.openrouter_metadata() {
108            return meta.tool_call;
109        }
110        true
111    }
112
113    /// Get the generation/version string for this model
114    pub fn generation(&self) -> &'static str {
115        if let Some(meta) = self.openrouter_metadata() {
116            return meta.generation;
117        }
118        match self {
119            // Gemini generations
120            ModelId::Gemini25FlashPreview
121            | ModelId::Gemini25Flash
122            | ModelId::Gemini25FlashLite
123            | ModelId::Gemini25Pro => "2.5",
124            ModelId::Gemini3ProPreview => "3",
125            // OpenAI generations
126            ModelId::GPT5
127            | ModelId::GPT5Codex
128            | ModelId::GPT5Mini
129            | ModelId::GPT5Nano
130            | ModelId::CodexMiniLatest => "5",
131            // Anthropic generations
132            ModelId::ClaudeOpus45 | ModelId::ClaudeSonnet45 | ModelId::ClaudeHaiku45 => "4.5",
133            ModelId::ClaudeOpus41 => "4.1",
134            ModelId::ClaudeSonnet4 => "4",
135            // DeepSeek generations
136            ModelId::DeepSeekChat | ModelId::DeepSeekReasoner => "V3.2-Exp",
137            // xAI generations
138            ModelId::XaiGrok4
139            | ModelId::XaiGrok4Mini
140            | ModelId::XaiGrok4Code
141            | ModelId::XaiGrok4CodeLatest
142            | ModelId::XaiGrok4Vision => "4",
143            // Z.AI generations
144            ModelId::ZaiGlm4Plus | ModelId::ZaiGlm4PlusDeepThinking => "4-Plus",
145            ModelId::ZaiGlm47 | ModelId::ZaiGlm47DeepThinking => "4.7",
146            ModelId::ZaiGlm46 | ModelId::ZaiGlm46DeepThinking => "4.6",
147            ModelId::ZaiGlm46V | ModelId::ZaiGlm46VFlash | ModelId::ZaiGlm46VFlashX => "4.6",
148            ModelId::ZaiGlm45
149            | ModelId::ZaiGlm45DeepThinking
150            | ModelId::ZaiGlm45Air
151            | ModelId::ZaiGlm45X
152            | ModelId::ZaiGlm45Airx
153            | ModelId::ZaiGlm45Flash
154            | ModelId::ZaiGlm45V => "4.5",
155            ModelId::ZaiGlm432b0414128k => "4-32B",
156            ModelId::MoonshotKimiK25 => "K2.5",
157            ModelId::OllamaGptOss20b => "oss",
158            ModelId::OllamaGptOss20bCloud => "oss-cloud",
159            ModelId::OllamaGptOss120bCloud => "oss-cloud",
160            ModelId::OllamaQwen317b => "oss",
161            ModelId::OllamaDeepseekV32Cloud => "deepseek-v3.2",
162            ModelId::OllamaQwen3Next80bCloud => "qwen3-next",
163            ModelId::OllamaMistralLarge3675bCloud => "mistral-large-3",
164            ModelId::OllamaKimiK2ThinkingCloud => "kimi-k2-thinking",
165            ModelId::OllamaQwen3Coder480bCloud => "qwen3-coder-cloud",
166            ModelId::OllamaGlm46Cloud => "glm-cloud",
167            ModelId::OllamaMinimaxM2Cloud => "minimax-cloud",
168            ModelId::LmStudioMetaLlama38BInstruct => "meta-llama-3",
169            ModelId::LmStudioMetaLlama318BInstruct => "meta-llama-3.1",
170            ModelId::LmStudioQwen257BInstruct => "qwen2.5",
171            ModelId::LmStudioGemma22BIt => "gemma-2",
172            ModelId::LmStudioGemma29BIt => "gemma-2",
173            ModelId::LmStudioPhi31Mini4kInstruct => "phi-3.1",
174            ModelId::MinimaxM21 | ModelId::MinimaxM21Lightning => "M2.1",
175            ModelId::MinimaxM2 => "M2",
176            ModelId::HuggingFaceDeepseekV32 | ModelId::HuggingFaceDeepseekV32Novita => "v3.2",
177            ModelId::HuggingFaceXiaomiMimoV2FlashNovita => "v2-flash",
178            ModelId::HuggingFaceGlm47 => "4.7",
179            ModelId::HuggingFaceKimiK2Thinking => "k2",
180            ModelId::HuggingFaceKimiK25Novita => "k2.5",
181            ModelId::HuggingFaceMinimaxM21Novita => "m2.1",
182            ModelId::HuggingFaceOpenAIGptOss20b | ModelId::HuggingFaceOpenAIGptOss120b => "oss",
183            _ => unreachable!(),
184        }
185    }
186}