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