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_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, GPT_5_1_MINI,
14 GPT_OSS_20B,
15 GPT_OSS_120B,
16];
17
18pub 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
33pub 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
47pub(crate) const SERVICE_TIER_MODELS: &[&str] = RESPONSES_API_MODELS;
49
50pub const TOOL_UNAVAILABLE_MODELS: &[&str] = &[];
52
53pub const HARMONY_MODELS: &[&str] = &[GPT_OSS_20B, GPT_OSS_120B];
55
56pub const STREAMING_REQUIRED_MODELS: &[&str] = &[GPT, GPT_5_6_SOL, GPT_5_6_LUNA];
60
61pub 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
77pub 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
90pub(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
98pub const DEPRECATED_MODEL_REPLACEMENTS: &[(&str, &str, &str)] = &[
104 (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 (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 (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 (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 (
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 (
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 ("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#[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 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 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 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}