Skip to main content

vtcode_config/constants/models/
openai.rs

1pub const DEFAULT_MODEL: &str = "gpt-5.6-sol";
2pub const SUPPORTED_MODELS: &[&str] = &[
3    GPT,
4    GPT_6_ASTRA,
5    GPT_6_SOL,
6    GPT_6_1_SOL,
7    GPT_6_1_TERRA,
8    GPT_6_LUNA,
9    GPT_5_6,       // GPT-5.6 alias (routes to gpt-5.6-sol)
10    GPT_5_6_SOL,   // GPT-5.6 Sol flagship model
11    GPT_5_6_TERRA, // GPT-5.6 Terra balanced model
12    GPT_5_6_LUNA,  // GPT-5.6 Luna efficient model
13    GPT_5_1_MINI,
14    GPT_OSS_20B,
15    GPT_OSS_120B,
16];
17
18/// Models that require the OpenAI Responses API
19pub const RESPONSES_API_MODELS: &[&str] = &[
20    GPT,
21    GPT_6_ASTRA,
22    GPT_6_SOL,
23    GPT_6_1_SOL,
24    GPT_6_1_TERRA,
25    GPT_6_LUNA,
26    GPT_5_6,
27    GPT_5_6_SOL,
28    GPT_5_6_TERRA,
29    GPT_5_6_LUNA,
30    GPT_5_1_MINI,
31];
32
33/// Models that support the OpenAI reasoning parameter payload
34pub const REASONING_MODELS: &[&str] = &[
35    GPT,
36    GPT_6_ASTRA,
37    GPT_6_SOL,
38    GPT_6_1_SOL,
39    GPT_6_1_TERRA,
40    GPT_6_LUNA,
41    GPT_5_6,
42    GPT_5_6_SOL,
43    GPT_5_6_TERRA,
44    GPT_5_6_LUNA,
45];
46
47/// Models that support the native OpenAI `service_tier` request parameter.
48pub(crate) const SERVICE_TIER_MODELS: &[&str] = RESPONSES_API_MODELS;
49
50/// Models that do not expose structured tool calling on the OpenAI platform
51pub const TOOL_UNAVAILABLE_MODELS: &[&str] = &[];
52
53/// GPT-OSS models that use harmony tokenization
54pub const HARMONY_MODELS: &[&str] = &[GPT_OSS_20B, GPT_OSS_120B];
55
56/// Models that reject non-streaming requests on the OpenAI API. The provider
57/// advertises no non-streaming capability for them and coerces generation to
58/// an internally-streamed request (see `OpenAIProvider::requires_streaming_responses`).
59pub const STREAMING_REQUIRED_MODELS: &[&str] = &[GPT, GPT_5_6_SOL, GPT_5_6_LUNA];
60
61// Convenience constants for commonly used models
62pub const GPT: &str = "gpt";
63pub const GPT_6_ASTRA: &str = "gpt-6-astra";
64pub const GPT_6_SOL: &str = "gpt-6-sol";
65pub const GPT_6_1_SOL: &str = "gpt-6.1-sol";
66pub const GPT_6_1_TERRA: &str = "gpt-6.1-terra";
67pub const GPT_6_LUNA: &str = "gpt-6-luna";
68pub const GPT_5_6_SOL: &str = "gpt-5.6-sol";
69pub const GPT_5_6_TERRA: &str = "gpt-5.6-terra";
70pub const GPT_5_6_LUNA: &str = "gpt-5.6-luna";
71pub const GPT_5_6: &str = "gpt-5.6";
72pub const GPT_5_1: &str = "gpt-5.1";
73pub const GPT_5_1_MINI: &str = "gpt-5.1-mini";
74pub const GPT_OSS_20B: &str = "gpt-oss-20b";
75pub const GPT_OSS_120B: &str = "gpt-oss-120b";
76
77// Deprecated constants retained for backward compatibility in tests and internal code
78pub const GPT_5: &str = "gpt-5";
79pub const GPT_5_MINI: &str = "gpt-5-mini";
80pub const GPT_5_NANO: &str = "gpt-5-nano";
81pub const GPT_5_CODEX: &str = "gpt-5-codex";
82pub(crate) const GPT_5_1_CODEX: &str = "gpt-5.1-codex";
83pub(crate) const GPT_5_1_CODEX_MAX: &str = "gpt-5.1-codex-max";
84pub(crate) const GPT_5_1_CODEX_MINI: &str = "gpt-5.1-codex-mini";
85pub const GPT_5_2_CODEX: &str = "gpt-5.2-codex";
86const CODEX_MINI_LATEST: &str = "codex-mini-latest";
87pub const O3: &str = "o3";
88pub const O4_MINI: &str = "o4-mini";
89
90// Oct 2026 deprecation batch (announced 2026-10-01 / 2026-10-14).
91pub(crate) const GPT_5_3_CODEX: &str = "gpt-5.3-codex";
92pub(crate) const GPT_5_4_NANO: &str = "gpt-5.4-nano";
93pub(crate) const GPT_4O: &str = "gpt-4o";
94pub(crate) const GPT_4O_MINI: &str = "gpt-4o-mini";
95pub(crate) const GPT_4_1: &str = "gpt-4.1";
96pub(crate) const GPT_4_1_MINI: &str = "gpt-4.1-mini";
97
98/// Mapping of deprecated OpenAI model IDs to their recommended replacements.
99///
100/// Mappings follow the official OpenAI deprecation table:
101/// <https://developers.openai.com/api/docs/deprecations>.
102/// Replacements are chosen from models currently in `SUPPORTED_MODELS`.
103pub const DEPRECATED_MODEL_REPLACEMENTS: &[(&str, &str, &str)] = &[
104    // (deprecated_id, replacement_id, human-readable reason)
105    // GPT-5 / o3 family — shut down Dec 11, 2026
106    (GPT_5, "gpt-5.6-sol", "GPT-5 is deprecated; use GPT-5.6 Sol for frontier work"),
107    (GPT_5_MINI, "gpt-5.6-terra", "GPT-5 Mini is deprecated; use GPT-5.6 Terra for balanced tasks"),
108    (GPT_5_NANO, "gpt-5.6-luna", "GPT-5 Nano is deprecated; use GPT-5.6 Luna for lightweight tasks"),
109    (O3, "gpt-5.6-sol", "o3 is deprecated; use GPT-5.6 Sol for reasoning tasks"),
110    (O4_MINI, "gpt-5.6-terra", "o4-mini is deprecated; use GPT-5.6 Terra for fast reasoning"),
111    // Codex variants — shut down July 23, 2026 (Apr 1, 2026 for 5.x/5.1.x).
112    // Per OpenAI/GitHub Copilot deprecation notices, the direct successor is
113    // gpt-5.3-codex (the current Codex-optimised model).
114    (GPT_5_CODEX, GPT_5_6_SOL, "GPT-5 Codex is deprecated; use GPT-5.3 Codex for agentic coding"),
115    (GPT_5_1_CODEX, GPT_5_6_SOL, "GPT-5.1 Codex is deprecated; use GPT-5.3 Codex for agentic coding"),
116    (
117        GPT_5_1_CODEX_MAX,
118        GPT_5_6_SOL,
119        "GPT-5.1 Codex Max is deprecated; use GPT-5.3 Codex for long-running coding",
120    ),
121    (
122        GPT_5_1_CODEX_MINI,
123        GPT_5_6_SOL,
124        "GPT-5.1 Codex Mini is deprecated; use GPT-5.3 Codex for cost-effective coding",
125    ),
126    (GPT_5_2_CODEX, GPT_5_6_SOL, "GPT-5.2 Codex is deprecated; use GPT-5.3 Codex for agentic coding"),
127    (
128        CODEX_MINI_LATEST,
129        GPT_5_6_SOL,
130        "codex-mini-latest is deprecated; use GPT-5.3 Codex for cost-effective coding",
131    ),
132    // Oct 1, 2026 batch — shut down Apr 1, 2027.
133    (GPT_5_1, "gpt-6-sol", "GPT-5.1 is deprecated and shuts down Apr 1, 2027; use GPT-6 Sol"),
134    (
135        GPT_5_3_CODEX,
136        "gpt-6-sol",
137        "GPT-5.3 Codex is deprecated and shuts down Apr 1, 2027; use GPT-6 Sol for agentic coding",
138    ),
139    (GPT_5_4_NANO, "gpt-6-luna", "GPT-5.4 Nano is deprecated and shuts down Apr 1, 2027; use GPT-6 Luna"),
140    // Oct 14, 2026 GPT-4 series batch — shut down Jan 14, 2027.
141    (GPT_4O, "gpt-6-luna", "GPT-4o is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
142    (
143        "gpt-4o-2024-08-06",
144        "gpt-6-luna",
145        "GPT-4o (2024-08-06) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
146    ),
147    (
148        "gpt-4o-2024-11-20",
149        "gpt-6-luna",
150        "GPT-4o (2024-11-20) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
151    ),
152    (GPT_4O_MINI, "gpt-6-luna", "GPT-4o mini is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
153    (
154        "gpt-4o-mini-2024-07-18",
155        "gpt-6-luna",
156        "GPT-4o mini (2024-07-18) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
157    ),
158    (GPT_4_1, "gpt-6-luna", "GPT-4.1 is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
159    (
160        "gpt-4.1-2025-04-14",
161        "gpt-6-luna",
162        "GPT-4.1 (2025-04-14) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
163    ),
164    (GPT_4_1_MINI, "gpt-6-luna", "GPT-4.1 mini is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
165    (
166        "gpt-4.1-mini-2025-04-14",
167        "gpt-6-luna",
168        "GPT-4.1 mini (2025-04-14) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
169    ),
170    // Jun 11, 2026 GPT-5/o3 snapshots — shut down Dec 11, 2026.
171    (
172        "gpt-5-2025-08-07",
173        "gpt-5.6-sol",
174        "GPT-5 snapshot 2025-08-07 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
175    ),
176    (
177        "gpt-5-mini-2025-08-07",
178        "gpt-5.6-terra",
179        "GPT-5 Mini snapshot 2025-08-07 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Terra",
180    ),
181    (
182        "gpt-5-nano-2025-08-07",
183        "gpt-5.6-luna",
184        "GPT-5 Nano snapshot 2025-08-07 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Luna",
185    ),
186    (
187        "gpt-5-pro-2025-10-06",
188        "gpt-5.6-sol",
189        "GPT-5 Pro snapshot 2025-10-06 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
190    ),
191    (
192        "o3-2025-04-16",
193        "gpt-5.6-sol",
194        "o3 snapshot 2025-04-16 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
195    ),
196    (
197        "o3-pro-2025-06-10",
198        "gpt-5.6-sol",
199        "o3 Pro snapshot 2025-06-10 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
200    ),
201    // Apr 22, 2026 legacy snapshots — shut down Oct 23, 2026.
202    (
203        "gpt-3.5-turbo-0125",
204        "gpt-5.6-terra",
205        "GPT-3.5 Turbo snapshot 0125 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Terra",
206    ),
207    (
208        "gpt-4-0613",
209        "gpt-5.6-sol",
210        "GPT-4 snapshot 0613 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
211    ),
212    (
213        "gpt-4-turbo-2024-04-09",
214        "gpt-5.6-sol",
215        "GPT-4 Turbo snapshot 2024-04-09 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
216    ),
217    (
218        "gpt-4.1-nano-2025-04-14",
219        "gpt-5.6-luna",
220        "GPT-4.1 Nano is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Luna",
221    ),
222    (
223        "gpt-4o-2024-05-13",
224        "gpt-5.6-sol",
225        "GPT-4o snapshot 2024-05-13 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
226    ),
227    ("o1-2024-12-17", "gpt-5.6-sol", "o1 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol"),
228    (
229        "o1-pro-2025-03-19",
230        "gpt-5.6-sol",
231        "o1 Pro is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
232    ),
233    (
234        "o3-mini-2025-01-31",
235        "gpt-5.6-sol",
236        "o3 Mini is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
237    ),
238    (
239        "o4-mini-2025-04-16",
240        "gpt-5.6-terra",
241        "o4 Mini snapshot 2025-04-16 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Terra",
242    ),
243    // Chat / specialized variants already shut down.
244    ("gpt-5-chat-latest", "gpt-5.6-sol", "GPT-5 Chat is deprecated; use GPT-5.6 Sol"),
245    ("gpt-5.1-chat-latest", "gpt-5.6-sol", "GPT-5.1 Chat is deprecated; use GPT-5.6 Sol"),
246    (
247        "gpt-5.2-chat-latest",
248        "gpt-5.6-sol",
249        "GPT-5.2 Chat is deprecated and shut down Aug 10, 2026; use GPT-5.6 Sol",
250    ),
251    (
252        "gpt-5.3-chat-latest",
253        "gpt-5.6-sol",
254        "GPT-5.3 Chat is deprecated and shut down Aug 10, 2026; use GPT-5.6 Sol",
255    ),
256];
257
258/// Returns the recommended replacement for a deprecated OpenAI model, if known.
259///
260/// Returns `Some((replacement_id, reason))` when the model is a known
261/// deprecated ID, or `None` when it is either current or unrecognized.
262#[must_use]
263pub fn deprecated_model_replacement(model: &str) -> Option<(&'static str, &'static str)> {
264    DEPRECATED_MODEL_REPLACEMENTS
265        .iter()
266        .find(|(deprecated, _, _)| *deprecated == model)
267        .map(|(_, replacement, reason)| (*replacement, *reason))
268}
269
270#[cfg(test)]
271mod tests {
272    use super::*;
273
274    #[test]
275    fn deprecated_gpt5_maps_to_gpt56_sol() {
276        let (replacement, reason) = deprecated_model_replacement(GPT_5).expect("gpt-5 is deprecated");
277        assert_eq!(replacement, "gpt-5.6-sol");
278        assert!(reason.contains("GPT-5.6 Sol"));
279    }
280
281    #[test]
282    fn deprecated_codex_models_map_to_gpt53_codex() {
283        for (deprecated, expected) in [
284            (GPT_5_CODEX, GPT_5_6_SOL),
285            (GPT_5_1_CODEX, GPT_5_6_SOL),
286            (GPT_5_1_CODEX_MAX, GPT_5_6_SOL),
287            (GPT_5_1_CODEX_MINI, GPT_5_6_SOL),
288            (GPT_5_2_CODEX, GPT_5_6_SOL),
289            (CODEX_MINI_LATEST, GPT_5_6_SOL),
290        ] {
291            let (replacement, _reason) =
292                deprecated_model_replacement(deprecated).unwrap_or_else(|| panic!("{deprecated} should be deprecated"));
293            assert_eq!(replacement, expected, "replacement for {deprecated}");
294        }
295    }
296
297    #[test]
298    fn current_models_have_no_replacement() {
299        assert!(deprecated_model_replacement(GPT_5_6_SOL).is_none());
300        assert!(deprecated_model_replacement(GPT_5_6_SOL).is_none());
301        assert!(deprecated_model_replacement("gpt-5.6-sol").is_none());
302    }
303
304    #[test]
305    fn unknown_models_have_no_replacement() {
306        assert!(deprecated_model_replacement("nonexistent-model").is_none());
307        assert!(deprecated_model_replacement("").is_none());
308    }
309
310    #[test]
311    fn supported_models_excludes_deprecated() {
312        let deprecated_ids: Vec<&str> = DEPRECATED_MODEL_REPLACEMENTS.iter().map(|(id, _, _)| *id).collect();
313        for deprecated in &deprecated_ids {
314            assert!(
315                !SUPPORTED_MODELS.contains(deprecated),
316                "deprecated model {deprecated} should not appear in SUPPORTED_MODELS"
317            );
318        }
319    }
320
321    #[test]
322    fn replacement_targets_are_current_models() {
323        // Every replacement must be a currently supported (non-deprecated) model.
324        for (_, replacement, _) in DEPRECATED_MODEL_REPLACEMENTS {
325            assert!(
326                SUPPORTED_MODELS.contains(replacement),
327                "replacement target {replacement} must be in SUPPORTED_MODELS"
328            );
329            assert!(
330                deprecated_model_replacement(replacement).is_none(),
331                "replacement target {replacement} must not itself be deprecated"
332            );
333        }
334    }
335
336    #[test]
337    fn capability_lists_have_no_duplicates() {
338        // `RESPONSES_API_MODELS` is joined into user-facing help text and
339        // `SERVICE_TIER_MODELS` aliases it, so duplicates reach users.
340        for (list_name, list) in [
341            ("SUPPORTED_MODELS", SUPPORTED_MODELS),
342            ("RESPONSES_API_MODELS", RESPONSES_API_MODELS),
343            ("REASONING_MODELS", REASONING_MODELS),
344            ("STREAMING_REQUIRED_MODELS", STREAMING_REQUIRED_MODELS),
345            ("HARMONY_MODELS", HARMONY_MODELS),
346        ] {
347            let mut seen = std::collections::HashSet::new();
348            for model in list {
349                assert!(seen.insert(*model), "{list_name} lists {model} more than once");
350            }
351        }
352    }
353
354    #[test]
355    fn capability_lists_stay_within_supported_models() {
356        // A capability list must never advertise a model the catalog dropped.
357        for (list_name, list) in [
358            ("RESPONSES_API_MODELS", RESPONSES_API_MODELS),
359            ("REASONING_MODELS", REASONING_MODELS),
360            ("STREAMING_REQUIRED_MODELS", STREAMING_REQUIRED_MODELS),
361            ("HARMONY_MODELS", HARMONY_MODELS),
362        ] {
363            for model in list {
364                assert!(
365                    SUPPORTED_MODELS.contains(model),
366                    "{list_name} advertises {model}, which is not in SUPPORTED_MODELS"
367                );
368            }
369        }
370    }
371}