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_LUNA,
8 GPT_5_6, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, GPT_5_1_MINI,
13 GPT_OSS_20B,
14 GPT_OSS_120B,
15];
16
17pub const RESPONSES_API_MODELS: &[&str] = &[
19 GPT,
20 GPT_6_ASTRA,
21 GPT_6_SOL,
22 GPT_6_1_SOL,
23 GPT_6_LUNA,
24 GPT_5_6,
25 GPT_5_6_SOL,
26 GPT_5_6_TERRA,
27 GPT_5_6_LUNA,
28 GPT_5_1_MINI,
29];
30
31pub const REASONING_MODELS: &[&str] = &[
33 GPT,
34 GPT_6_ASTRA,
35 GPT_6_SOL,
36 GPT_6_1_SOL,
37 GPT_6_LUNA,
38 GPT_5_6,
39 GPT_5_6_SOL,
40 GPT_5_6_TERRA,
41 GPT_5_6_LUNA,
42];
43
44pub(crate) const SERVICE_TIER_MODELS: &[&str] = RESPONSES_API_MODELS;
46
47pub const TOOL_UNAVAILABLE_MODELS: &[&str] = &[];
49
50pub const HARMONY_MODELS: &[&str] = &[GPT_OSS_20B, GPT_OSS_120B];
52
53pub const STREAMING_REQUIRED_MODELS: &[&str] = &[GPT, GPT_5_6_SOL, GPT_5_6_LUNA];
57
58pub const GPT: &str = "gpt";
60pub const GPT_6_ASTRA: &str = "gpt-6-astra";
61pub const GPT_6_SOL: &str = "gpt-6-sol";
62pub const GPT_6_1_SOL: &str = "gpt-6.1-sol";
63pub const GPT_6_LUNA: &str = "gpt-6-luna";
64pub const GPT_5_6_SOL: &str = "gpt-5.6-sol";
65pub const GPT_5_6_TERRA: &str = "gpt-5.6-terra";
66pub const GPT_5_6_LUNA: &str = "gpt-5.6-luna";
67pub const GPT_5_6: &str = "gpt-5.6";
68pub const GPT_5_1: &str = "gpt-5.1";
69pub const GPT_5_1_MINI: &str = "gpt-5.1-mini";
70pub const GPT_OSS_20B: &str = "gpt-oss-20b";
71pub const GPT_OSS_120B: &str = "gpt-oss-120b";
72
73pub const GPT_5: &str = "gpt-5";
75pub const GPT_5_MINI: &str = "gpt-5-mini";
76pub const GPT_5_NANO: &str = "gpt-5-nano";
77pub const GPT_5_CODEX: &str = "gpt-5-codex";
78pub(crate) const GPT_5_1_CODEX: &str = "gpt-5.1-codex";
79pub(crate) const GPT_5_1_CODEX_MAX: &str = "gpt-5.1-codex-max";
80pub(crate) const GPT_5_1_CODEX_MINI: &str = "gpt-5.1-codex-mini";
81pub const GPT_5_2_CODEX: &str = "gpt-5.2-codex";
82const CODEX_MINI_LATEST: &str = "codex-mini-latest";
83pub const O3: &str = "o3";
84pub const O4_MINI: &str = "o4-mini";
85
86pub(crate) const GPT_5_3_CODEX: &str = "gpt-5.3-codex";
88pub(crate) const GPT_5_4_NANO: &str = "gpt-5.4-nano";
89pub(crate) const GPT_4O: &str = "gpt-4o";
90pub(crate) const GPT_4O_MINI: &str = "gpt-4o-mini";
91pub(crate) const GPT_4_1: &str = "gpt-4.1";
92pub(crate) const GPT_4_1_MINI: &str = "gpt-4.1-mini";
93
94pub const DEPRECATED_MODEL_REPLACEMENTS: &[(&str, &str, &str)] = &[
100 (GPT_5, "gpt-5.6-sol", "GPT-5 is deprecated; use GPT-5.6 Sol for frontier work"),
103 (GPT_5_MINI, "gpt-5.6-terra", "GPT-5 Mini is deprecated; use GPT-5.6 Terra for balanced tasks"),
104 (GPT_5_NANO, "gpt-5.6-luna", "GPT-5 Nano is deprecated; use GPT-5.6 Luna for lightweight tasks"),
105 (O3, "gpt-5.6-sol", "o3 is deprecated; use GPT-5.6 Sol for reasoning tasks"),
106 (O4_MINI, "gpt-5.6-terra", "o4-mini is deprecated; use GPT-5.6 Terra for fast reasoning"),
107 (GPT_5_CODEX, GPT_5_6_SOL, "GPT-5 Codex is deprecated; use GPT-5.3 Codex for agentic coding"),
111 (GPT_5_1_CODEX, GPT_5_6_SOL, "GPT-5.1 Codex is deprecated; use GPT-5.3 Codex for agentic coding"),
112 (
113 GPT_5_1_CODEX_MAX,
114 GPT_5_6_SOL,
115 "GPT-5.1 Codex Max is deprecated; use GPT-5.3 Codex for long-running coding",
116 ),
117 (
118 GPT_5_1_CODEX_MINI,
119 GPT_5_6_SOL,
120 "GPT-5.1 Codex Mini is deprecated; use GPT-5.3 Codex for cost-effective coding",
121 ),
122 (GPT_5_2_CODEX, GPT_5_6_SOL, "GPT-5.2 Codex is deprecated; use GPT-5.3 Codex for agentic coding"),
123 (
124 CODEX_MINI_LATEST,
125 GPT_5_6_SOL,
126 "codex-mini-latest is deprecated; use GPT-5.3 Codex for cost-effective coding",
127 ),
128 (GPT_5_1, "gpt-6-sol", "GPT-5.1 is deprecated and shuts down Apr 1, 2027; use GPT-6 Sol"),
130 (
131 GPT_5_3_CODEX,
132 "gpt-6-sol",
133 "GPT-5.3 Codex is deprecated and shuts down Apr 1, 2027; use GPT-6 Sol for agentic coding",
134 ),
135 (GPT_5_4_NANO, "gpt-6-luna", "GPT-5.4 Nano is deprecated and shuts down Apr 1, 2027; use GPT-6 Luna"),
136 (GPT_4O, "gpt-6-luna", "GPT-4o is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
138 (
139 "gpt-4o-2024-08-06",
140 "gpt-6-luna",
141 "GPT-4o (2024-08-06) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
142 ),
143 (
144 "gpt-4o-2024-11-20",
145 "gpt-6-luna",
146 "GPT-4o (2024-11-20) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
147 ),
148 (GPT_4O_MINI, "gpt-6-luna", "GPT-4o mini is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
149 (
150 "gpt-4o-mini-2024-07-18",
151 "gpt-6-luna",
152 "GPT-4o mini (2024-07-18) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
153 ),
154 (GPT_4_1, "gpt-6-luna", "GPT-4.1 is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
155 (
156 "gpt-4.1-2025-04-14",
157 "gpt-6-luna",
158 "GPT-4.1 (2025-04-14) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
159 ),
160 (GPT_4_1_MINI, "gpt-6-luna", "GPT-4.1 mini is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna"),
161 (
162 "gpt-4.1-mini-2025-04-14",
163 "gpt-6-luna",
164 "GPT-4.1 mini (2025-04-14) is deprecated and shuts down Jan 14, 2027; use GPT-6 Luna",
165 ),
166 (
168 "gpt-5-2025-08-07",
169 "gpt-5.6-sol",
170 "GPT-5 snapshot 2025-08-07 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
171 ),
172 (
173 "gpt-5-mini-2025-08-07",
174 "gpt-5.6-terra",
175 "GPT-5 Mini snapshot 2025-08-07 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Terra",
176 ),
177 (
178 "gpt-5-nano-2025-08-07",
179 "gpt-5.6-luna",
180 "GPT-5 Nano snapshot 2025-08-07 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Luna",
181 ),
182 (
183 "gpt-5-pro-2025-10-06",
184 "gpt-5.6-sol",
185 "GPT-5 Pro snapshot 2025-10-06 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
186 ),
187 (
188 "o3-2025-04-16",
189 "gpt-5.6-sol",
190 "o3 snapshot 2025-04-16 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
191 ),
192 (
193 "o3-pro-2025-06-10",
194 "gpt-5.6-sol",
195 "o3 Pro snapshot 2025-06-10 is deprecated and shuts down Dec 11, 2026; use GPT-5.6 Sol",
196 ),
197 (
199 "gpt-3.5-turbo-0125",
200 "gpt-5.6-terra",
201 "GPT-3.5 Turbo snapshot 0125 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Terra",
202 ),
203 (
204 "gpt-4-0613",
205 "gpt-5.6-sol",
206 "GPT-4 snapshot 0613 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
207 ),
208 (
209 "gpt-4-turbo-2024-04-09",
210 "gpt-5.6-sol",
211 "GPT-4 Turbo snapshot 2024-04-09 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
212 ),
213 (
214 "gpt-4.1-nano-2025-04-14",
215 "gpt-5.6-luna",
216 "GPT-4.1 Nano is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Luna",
217 ),
218 (
219 "gpt-4o-2024-05-13",
220 "gpt-5.6-sol",
221 "GPT-4o snapshot 2024-05-13 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
222 ),
223 ("o1-2024-12-17", "gpt-5.6-sol", "o1 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol"),
224 (
225 "o1-pro-2025-03-19",
226 "gpt-5.6-sol",
227 "o1 Pro is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
228 ),
229 (
230 "o3-mini-2025-01-31",
231 "gpt-5.6-sol",
232 "o3 Mini is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Sol",
233 ),
234 (
235 "o4-mini-2025-04-16",
236 "gpt-5.6-terra",
237 "o4 Mini snapshot 2025-04-16 is deprecated and shuts down Oct 23, 2026; use GPT-5.6 Terra",
238 ),
239 ("gpt-5-chat-latest", "gpt-5.6-sol", "GPT-5 Chat is deprecated; use GPT-5.6 Sol"),
241 ("gpt-5.1-chat-latest", "gpt-5.6-sol", "GPT-5.1 Chat is deprecated; use GPT-5.6 Sol"),
242 (
243 "gpt-5.2-chat-latest",
244 "gpt-5.6-sol",
245 "GPT-5.2 Chat is deprecated and shut down Aug 10, 2026; use GPT-5.6 Sol",
246 ),
247 (
248 "gpt-5.3-chat-latest",
249 "gpt-5.6-sol",
250 "GPT-5.3 Chat is deprecated and shut down Aug 10, 2026; use GPT-5.6 Sol",
251 ),
252];
253
254#[must_use]
259pub fn deprecated_model_replacement(model: &str) -> Option<(&'static str, &'static str)> {
260 DEPRECATED_MODEL_REPLACEMENTS
261 .iter()
262 .find(|(deprecated, _, _)| *deprecated == model)
263 .map(|(_, replacement, reason)| (*replacement, *reason))
264}
265
266#[cfg(test)]
267mod tests {
268 use super::*;
269
270 #[test]
271 fn deprecated_gpt5_maps_to_gpt56_sol() {
272 let (replacement, reason) = deprecated_model_replacement(GPT_5).expect("gpt-5 is deprecated");
273 assert_eq!(replacement, "gpt-5.6-sol");
274 assert!(reason.contains("GPT-5.6 Sol"));
275 }
276
277 #[test]
278 fn deprecated_codex_models_map_to_gpt53_codex() {
279 for (deprecated, expected) in [
280 (GPT_5_CODEX, GPT_5_6_SOL),
281 (GPT_5_1_CODEX, GPT_5_6_SOL),
282 (GPT_5_1_CODEX_MAX, GPT_5_6_SOL),
283 (GPT_5_1_CODEX_MINI, GPT_5_6_SOL),
284 (GPT_5_2_CODEX, GPT_5_6_SOL),
285 (CODEX_MINI_LATEST, GPT_5_6_SOL),
286 ] {
287 let (replacement, _reason) =
288 deprecated_model_replacement(deprecated).unwrap_or_else(|| panic!("{deprecated} should be deprecated"));
289 assert_eq!(replacement, expected, "replacement for {deprecated}");
290 }
291 }
292
293 #[test]
294 fn current_models_have_no_replacement() {
295 assert!(deprecated_model_replacement(GPT_5_6_SOL).is_none());
296 assert!(deprecated_model_replacement(GPT_5_6_SOL).is_none());
297 assert!(deprecated_model_replacement("gpt-5.6-sol").is_none());
298 }
299
300 #[test]
301 fn unknown_models_have_no_replacement() {
302 assert!(deprecated_model_replacement("nonexistent-model").is_none());
303 assert!(deprecated_model_replacement("").is_none());
304 }
305
306 #[test]
307 fn supported_models_excludes_deprecated() {
308 let deprecated_ids: Vec<&str> = DEPRECATED_MODEL_REPLACEMENTS.iter().map(|(id, _, _)| *id).collect();
309 for deprecated in &deprecated_ids {
310 assert!(
311 !SUPPORTED_MODELS.contains(deprecated),
312 "deprecated model {deprecated} should not appear in SUPPORTED_MODELS"
313 );
314 }
315 }
316
317 #[test]
318 fn replacement_targets_are_current_models() {
319 for (_, replacement, _) in DEPRECATED_MODEL_REPLACEMENTS {
321 assert!(
322 SUPPORTED_MODELS.contains(replacement),
323 "replacement target {replacement} must be in SUPPORTED_MODELS"
324 );
325 assert!(
326 deprecated_model_replacement(replacement).is_none(),
327 "replacement target {replacement} must not itself be deprecated"
328 );
329 }
330 }
331
332 #[test]
333 fn capability_lists_have_no_duplicates() {
334 for (list_name, list) in [
337 ("SUPPORTED_MODELS", SUPPORTED_MODELS),
338 ("RESPONSES_API_MODELS", RESPONSES_API_MODELS),
339 ("REASONING_MODELS", REASONING_MODELS),
340 ("STREAMING_REQUIRED_MODELS", STREAMING_REQUIRED_MODELS),
341 ("HARMONY_MODELS", HARMONY_MODELS),
342 ] {
343 let mut seen = std::collections::HashSet::new();
344 for model in list {
345 assert!(seen.insert(*model), "{list_name} lists {model} more than once");
346 }
347 }
348 }
349
350 #[test]
351 fn capability_lists_stay_within_supported_models() {
352 for (list_name, list) in [
354 ("RESPONSES_API_MODELS", RESPONSES_API_MODELS),
355 ("REASONING_MODELS", REASONING_MODELS),
356 ("STREAMING_REQUIRED_MODELS", STREAMING_REQUIRED_MODELS),
357 ("HARMONY_MODELS", HARMONY_MODELS),
358 ] {
359 for model in list {
360 assert!(
361 SUPPORTED_MODELS.contains(model),
362 "{list_name} advertises {model}, which is not in SUPPORTED_MODELS"
363 );
364 }
365 }
366 }
367}