Add GPT-6 Sol and Luna to the model catalog (#47332)

## What changed

- Add `gpt-6-sol` and `gpt-6-luna` catalog entries and refresh model descriptions.
- Offer migrations from `gpt-5.5`, `gpt-5.6-sol`, and `gpt-5.6-terra` to `gpt-6-sol`, and from `gpt-5.6-luna` to `gpt-6-luna`.
- Retarget retired `gpt-5.4` and `gpt-5.4-mini` selections to GPT-6 Sol and Luna, respectively.
- Recommend `gpt-6-luna` in the rate-limit switch prompt.

## Testing

Extend migration tests to cover the new targets, their default reasoning effort, and prompting again after a previously acknowledged migration to an older target. Update model-picker and rate-limit prompt snapshots.

GitOrigin-RevId: d3a093d18ce44a903383504ab8f5cbbc911d602d
This commit is contained in:
andrewgu-oai
2026-09-22 18:17:39 +00:00
committed by copyberry
parent 0a73d55b80
commit 49e95cc73f
22 changed files with 464 additions and 82 deletions
+1
View File
@@ -81,6 +81,7 @@ async fn daemon_startup(command: &str) -> Result<()> {
suppress_unstable_features_warning = true\nanalytics.enabled = false\n\
windows.sandbox = \"unelevated\"\n\
tui.disable_paste_burst = true\n\
notice.model_migrations.\"gpt-5.6-terra\" = \"gpt-6-sol\"\n\
[projects.{}]\ntrust_level = \"trusted\"\n",
serde_json::to_string(&workspace_path)?,
),
@@ -7,7 +7,7 @@ Scenario: Astra asks who a launch update is for, keeps working, and receives the
## Window 1
-- request 1 (request) --
00:additional_tools/developer (3; hash=6c2ad099cb689791):
00:additional_tools/developer (3; hash=32be5470c6e39932):
- namespace/functions; hash=e7db0a45c4ec3157
- custom/exec
- function/wait
@@ -15,7 +15,7 @@ Scenario: Astra asks who a launch update is for, keeps working, and receives the
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -6,7 +6,7 @@ Scenario: Astra receives host and handler timings on completed and failed code-m
## Window 1
-- request 1 (turn) --
00:additional_tools/developer (3; hash=6c2ad099cb689791):
00:additional_tools/developer (3; hash=32be5470c6e39932):
- namespace/functions; hash=e7db0a45c4ec3157
- custom/exec
- function/wait
@@ -14,7 +14,7 @@ Scenario: Astra receives host and handler timings on completed and failed code-m
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -16,7 +16,7 @@ Settings:
text: {"verbosity":"low"}
tool_choice: "auto"
-- request 1 (request) --
00:additional_tools/developer (3; hash=7931c0eb5da2b494):
00:additional_tools/developer (3; hash=61ac4d92c828cbf9):
- namespace/functions; hash=99a630cff25563aa
- custom/exec
- function/wait
@@ -24,7 +24,7 @@ Settings:
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -16,7 +16,7 @@ Settings:
text: {"verbosity":"low"}
tool_choice: "auto"
-- request 1 (turn) --
00:additional_tools/developer (3; hash=6c2ad099cb689791):
00:additional_tools/developer (3; hash=32be5470c6e39932):
- namespace/functions; hash=e7db0a45c4ec3157
- custom/exec
- function/wait
@@ -24,7 +24,7 @@ Settings:
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -190,7 +190,7 @@ Settings:
## Window 2 (after request 3: input diverged at item 02)
Settings: same as window 1
-- request 4 (turn) --
00:additional_tools/developer (3; hash=6c2ad099cb689791):
00:additional_tools/developer (3; hash=32be5470c6e39932):
- namespace/functions; hash=e7db0a45c4ec3157
- custom/exec
- function/wait
@@ -198,7 +198,7 @@ Settings: same as window 1
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -16,7 +16,7 @@ Settings:
text: {"verbosity":"low"}
tool_choice: "auto"
-- request 1 (turn) --
00:additional_tools/developer (3; hash=6c2ad099cb689791):
00:additional_tools/developer (3; hash=32be5470c6e39932):
- namespace/functions; hash=e7db0a45c4ec3157
- custom/exec
- function/wait
@@ -24,7 +24,7 @@ Settings:
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -113,7 +113,7 @@ Settings:
## Window 2 (after request 2: input diverged at item 00)
Settings: same as window 1
-- request 3 (turn) --
00:additional_tools/developer (3; hash=cc439199c15f983f):
00:additional_tools/developer (3; hash=4327e247f74ba810):
- namespace/functions; hash=8c17932a39355f2d
- custom/exec
- function/wait
@@ -121,7 +121,7 @@ Settings: same as window 1
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -16,7 +16,7 @@ Settings:
text: {"verbosity":"low"}
tool_choice: "auto"
-- request 1 (turn) --
00:additional_tools/developer (3; hash=cc439199c15f983f):
00:additional_tools/developer (3; hash=4327e247f74ba810):
- namespace/functions; hash=8c17932a39355f2d
- custom/exec
- function/wait
@@ -24,7 +24,7 @@ Settings:
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -32,14 +32,14 @@ Settings:
stream: true
text: {"verbosity":"low"}
tool_choice: "auto"
tools (7; hash=459dc91308e98762):
tools (7; hash=884bfb8fc9050f65):
- custom/exec: Catalog exec instructions. Default yield: 1234 ms. `image(imageUrlOrItem: string | { image_url: s...; hash=a49b91fd82908e18
- function/wait: Catalog wait instructions: resume the yielded cell.; args=[cell_id, max_tokens, terminate, yield_time_ms]; hash=67bc0f04da3505b3
- function/request_user_input: Request user input for one to three short questions and wait for the response. This tool is only ...; args=[questions]; hash=64a729b25c424fc6
- function/request_user_input_async: Ask the user one or more questions during ongoing work. Use this tool only to request missing inf...; args=[questions]; hash=d6d74f33db330162
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=46d39bbce8bacc3f
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=fd994b11525da73c
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -16,7 +16,7 @@ Settings:
text: {"verbosity":"low"}
tool_choice: "auto"
-- request 1 (turn) --
00:additional_tools/developer (3; hash=6e5474c6ce389d17):
00:additional_tools/developer (3; hash=48937f38e1083468):
- namespace/functions; hash=e7db0a45c4ec3157
- custom/exec
- function/wait
@@ -24,7 +24,7 @@ Settings:
- function/request_user_input_async
- namespace/clock: Tools for reading and waiting on time.; hash=f402e8c5e9b5e317
- function/sleep
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=8f195b1f18fa3fdb
- namespace/collaboration: Tools for spawning and managing sub-agents.; hash=e7005987945a10f0
- function/followup_task
- function/interrupt_agent
- function/list_agents
@@ -16,7 +16,7 @@ Settings:
stream: true
text: {"verbosity":"low"}
tool_choice: "auto"
tools (11; hash=9b0d0ed0803f6b6e):
tools (11; hash=1974ec5490da160d):
- function/exec_command: Runs a command in a PTY, returning output or a session ID for ongoing interaction.; args=[cmd, justification, login, max_output_tokens, prefix_rule, sandbox_permissions, shell, tty, workdir, yield_time_ms]; hash=c04108e51a8548c5
- function/write_stdin: Writes characters to an existing unified exec session and returns recent output.; args=[chars, max_output_tokens, session_id, yield_time_ms]; hash=7fb62d8a3e2df4e2
- function/list_mcp_resources: Lists resources provided by MCP servers. Resources allow servers to share data that provides cont...; args=[cursor, server]; hash=6792edaff13561bd
@@ -25,7 +25,7 @@ Settings:
- function/request_user_input: Request user input for one to three short questions and wait for the response. This tool is only ...; args=[questions]; hash=64a729b25c424fc6
- custom/apply_patch: The `apply_patch` tool can be used to edit files. This is a FREEFORM tool, so do not wrap the pat...; hash=dea9f12b0111a4ba
- function/view_image: View a local image file from the filesystem when visual inspection is needed. Use this for images...; args=[detail, path]; hash=3b766d5bdec5d50e
- namespace/multi_agent_v1: Tools for spawning and managing sub-agents.; hash=da9d426e1cfa71d0
- namespace/multi_agent_v1: Tools for spawning and managing sub-agents.; hash=b109e235997460a9
- function/close_agent
- function/resume_agent
- function/send_input
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -120,7 +120,7 @@ pub(super) fn model_upgrade_for_migration(
// Saved selections can outlive their catalog entries. Keep only their migration metadata.
let (target_model, current_name, target_name) = match model {
"gpt-5.4-mini" => ("gpt-5.6-luna", "GPT-5.4 Mini", "GPT-5.6 Luna"),
"gpt-5.4-mini" => ("gpt-6-luna", "GPT-5.4 Mini", "GPT-6 Luna"),
_ => return None,
};
Some(ModelUpgrade {
+43 -15
View File
@@ -179,7 +179,7 @@ async fn model_migration_prompt_only_shows_for_deprecated_models() {
));
assert!(should_show_model_migration_prompt(
"gpt-5.4",
"gpt-5.6-terra",
"gpt-6-sol",
&seen,
&presets
));
@@ -369,8 +369,12 @@ async fn accepted_model_migration_persists_target_default_reasoning_effort() ->
let presets = all_model_presets();
let mut migration_copies = Vec::new();
for (model, replacement) in [
("gpt-5.4", "gpt-5.6-terra"),
("gpt-5.4-mini", "gpt-5.6-luna"),
("gpt-5.4", "gpt-6-sol"),
("gpt-5.4-mini", "gpt-6-luna"),
("gpt-5.5", "gpt-6-sol"),
("gpt-5.6-luna", "gpt-6-luna"),
("gpt-5.6-terra", "gpt-6-sol"),
("gpt-5.6-sol", "gpt-6-sol"),
] {
let codex_home = tempdir()?;
std::fs::write(
@@ -383,7 +387,7 @@ async fn accepted_model_migration_persists_target_default_reasoning_effort() ->
.await?;
let current_model = config.model.clone().expect("saved model");
let upgrade = model_upgrade_for_migration(&current_model, &presets)
.expect("retired selection should still migrate");
.expect("catalog selection should have an upgrade");
assert_eq!(upgrade.id, replacement);
assert!(should_show_model_migration_prompt(
&current_model,
@@ -449,11 +453,27 @@ async fn accepted_model_migration_persists_target_default_reasoning_effort() ->
assert_snapshot!(migration_copies.join("\n"), @r"
GPT-5.4 is no longer available
Codex now uses GPT-5.6 Terra in place of GPT-5.4. Switch to GPT-5.6 Terra to continue.
Codex now uses GPT-6 Sol in place of GPT-5.4. Switch to GPT-6 Sol to continue.
GPT-5.4 Mini is no longer available
Codex now uses GPT-5.6 Luna in place of GPT-5.4 Mini. Switch to GPT-5.6 Luna to continue.
Codex now uses GPT-6 Luna in place of GPT-5.4 Mini. Switch to GPT-6 Luna to continue.
Meet GPT-6 Sol
Our latest Sol is more intelligent and more efficient so your usage limits go further. This model is a great daily driver for complex tasks, especially coding.
Meet GPT-6 Luna
Our latest Luna is significantly more efficient, so your usage limits go even further. Reach for it for any job that doesn't require frontier intelligence.
Meet GPT-6 Sol
Our latest Sol is more intelligent and more efficient so your usage limits go further. This model is a great daily driver for complex tasks, especially coding.
Meet GPT-6 Sol
Our latest Sol is more intelligent and more efficient so your usage limits go further. This model is a great daily driver for complex tasks, especially coding.
");
Ok(())
}
@@ -462,16 +482,24 @@ async fn accepted_model_migration_persists_target_default_reasoning_effort() ->
async fn model_migration_prompt_respects_hide_flag_and_self_target() {
let presets = all_model_presets();
let mut seen = BTreeMap::new();
// A previously acknowledged intermediate upgrade must not hide the new target.
seen.insert("gpt-5.4-mini".to_string(), "gpt-5.6-luna".to_string());
assert!(should_show_model_migration_prompt(
"gpt-5.4-mini",
"gpt-6-luna",
&seen,
&presets
));
seen.insert("gpt-5.4-mini".to_string(), "gpt-6-luna".to_string());
assert!(!should_show_model_migration_prompt(
"gpt-5.4-mini",
"gpt-5.6-luna",
"gpt-6-luna",
&seen,
&presets
));
assert!(!should_show_model_migration_prompt(
"gpt-5.6-luna",
"gpt-5.6-luna",
"gpt-6-luna",
"gpt-6-luna",
&seen,
&presets
));
@@ -480,31 +508,31 @@ async fn model_migration_prompt_respects_hide_flag_and_self_target() {
#[tokio::test]
async fn model_migration_prompt_skips_when_target_missing_or_hidden() {
let mut available = all_model_presets();
available.retain(|preset| preset.model != "gpt-5.6-luna");
available.retain(|preset| preset.model != "gpt-6-luna");
assert!(!should_show_model_migration_prompt(
"gpt-5.4-mini",
"gpt-5.6-luna",
"gpt-6-luna",
&BTreeMap::new(),
&available,
));
assert!(target_preset_for_upgrade(&available, "gpt-5.6-luna").is_none());
assert!(target_preset_for_upgrade(&available, "gpt-6-luna").is_none());
let mut with_hidden_target = all_model_presets();
let target = with_hidden_target
.iter_mut()
.find(|preset| preset.model == "gpt-5.6-luna")
.find(|preset| preset.model == "gpt-6-luna")
.expect("target preset present");
target.show_in_picker = false;
assert!(!should_show_model_migration_prompt(
"gpt-5.4-mini",
"gpt-5.6-luna",
"gpt-6-luna",
&BTreeMap::new(),
&with_hidden_target,
));
assert!(target_preset_for_upgrade(&with_hidden_target, "gpt-5.6-luna").is_none());
assert!(target_preset_for_upgrade(&with_hidden_target, "gpt-6-luna").is_none());
}
#[tokio::test]
@@ -6,6 +6,6 @@ Codex just got an upgrade. Introducing GPT-5.5.
We recommend switching from gpt-5.2 to gpt-5.5.
Proven previous-generation model for coding and general work.
Legacy coding model.
You can continue using gpt-5.2 if you prefer.
@@ -1,16 +1,15 @@
---
source: tui/src/chatwidget/tests/bedrock_catalog_tests.rs
assertion_line: 42
expression: "render_bottom_popup(&chat, 100)"
---
Select Model and Effort
› 1. GPT-5.6 Sol (current) Reliable agentic workhorse for everyday tasks.
2. GPT-6-Astra Our most capable model for complex, demanding work.
3. GPT-5.6 Terra Balanced agentic coding model for everyday work.
4. GPT-5.6 Luna Fast and affordable agentic coding model.
5. GPT-5.5 Proven previous-generation model for coding and general work.
› 1. GPT-5.6 Sol (current) Older coding model for complex work.
2. GPT-6-Astra Frontier intelligence for the most demanding work.
3. GPT-5.6 Terra Older balanced model for straightforward work.
4. GPT-5.6 Luna Older fast and efficient model.
5. GPT-5.5 Legacy coding model.
6. GPT-5.4 Strong model for everyday coding.
enter select · esc back
@@ -1,18 +1,17 @@
---
source: tui/src/chatwidget/tests/bedrock_catalog_tests.rs
assertion_line: 42
expression: "render_bottom_popup(&chat, 100)"
---
Select Model and Effort
› 1. GPT-5.6 Sol (Global) (current) Reliable agentic workhorse for everyday tasks.
2. GPT-6-Astra (Global) Our most capable model for complex, demanding work.
3. GPT-5.6 Terra (Global) Balanced agentic coding model for everyday work.
4. GPT-5.6 Luna (Global) Fast and affordable agentic coding model.
5. GPT-5.6 Sol (US cross-region) Reliable agentic workhorse for everyday tasks.
6. GPT-6-Astra (US cross-region) Our most capable model for complex, demanding work.
7. GPT-5.6 Terra (US cross-region) Balanced agentic coding model for everyday work.
8. GPT-5.6 Luna (US cross-region) Fast and affordable agentic coding model.
› 1. GPT-5.6 Sol (Global) (current) Older coding model for complex work.
2. GPT-6-Astra (Global) Frontier intelligence for the most demanding work.
3. GPT-5.6 Terra (Global) Older balanced model for straightforward work.
4. GPT-5.6 Luna (Global) Older fast and efficient model.
5. GPT-5.6 Sol (US cross-region) Older coding model for complex work.
6. GPT-6-Astra (US cross-region) Frontier intelligence for the most demanding work.
7. GPT-5.6 Terra (US cross-region) Older balanced model for straightforward work.
8. GPT-5.6 Luna (US cross-region) Older fast and efficient model.
enter select · esc back
@@ -1,14 +1,12 @@
---
source: tui/src/chatwidget/tests/popups_and_settings.rs
assertion_line: 3466
expression: "render_bottom_popup(&chat, 80)"
---
Select Model and Effort
› 1. Renamed model Balanced agentic coding model for everyday
› 1. Renamed model Older balanced model for straightforward
work.
2. Shared display name (current) Proven previous-generation model for coding
and general work.
2. Shared display name (current) Legacy coding model.
enter select · esc back
@@ -1,16 +1,16 @@
---
source: tui/src/chatwidget/tests/popups_and_settings.rs
assertion_line: 3310
expression: popup
---
Select Model and Effort
1. GPT-6-Astra (default) Our most capable model for complex, demanding work.
2. GPT-5.6-Sol Reliable agentic workhorse for everyday tasks.
3. GPT-5.6-Terra Balanced agentic coding model for everyday work.
4. GPT-5.6-Luna Fast and affordable agentic coding model.
› 5. GPT-5.5 (current) Proven previous-generation model for coding and
general work.
1. GPT-6-Astra (default) Frontier intelligence for the most demanding work.
2. GPT-6-Sol Workhorse model for coding and everyday work.
3. GPT-6-Luna Fast and affordable model for easier tasks.
4. GPT-5.6-Sol Older coding model for complex work.
5. GPT-5.6-Terra Older balanced model for straightforward work.
6. GPT-5.6-Luna Older fast and efficient model.
› 7. GPT-5.5 (current) Legacy coding model.
enter select · esc back
@@ -3,11 +3,11 @@ source: tui/src/chatwidget/tests/status_and_layout.rs
expression: popup
---
Approaching rate limits
Switch to gpt-5.6-luna for lower credit usage?
Switch to gpt-6-luna for lower credit usage?
› 1. Switch to gpt-5.6-luna Fast and affordable agentic coding
model.
› 1. Switch to gpt-6-luna Fast and affordable model for easier
tasks.
2. Keep current model
3. Keep current model (never show again) Hide future rate limit reminders
about switching models
+1 -1
View File
@@ -5,7 +5,7 @@ use codex_protocol::openai_models::ModelPreset;
use std::convert::Infallible;
pub(crate) const LUNA_RESERVE_MODEL: &str = "gpt-reserve";
pub(crate) const LUNA_MODEL: &str = "gpt-5.6-luna";
pub(crate) const LUNA_MODEL: &str = "gpt-6-luna";
pub(crate) fn model_display_name(model: &str) -> &str {
if model.eq_ignore_ascii_case(LUNA_RESERVE_MODEL) {
+2 -1
View File
@@ -535,7 +535,8 @@ pub(super) fn write_test_config(codex_home: &Path, repo_root: &Path) -> Result<(
let config = format!(
"model = \"gpt-5.6-terra\"\nmodel_provider = \"openai\"\n\
suppress_unstable_features_warning = true\nanalytics.enabled = false\n\
features.daemon_auto_start = false\n\n\
features.daemon_auto_start = false\n\
notice.model_migrations.\"gpt-5.6-terra\" = \"gpt-6-sol\"\n\n\
[projects.\"{repo_root}\"]\ntrust_level = \"trusted\"\n"
);
std::fs::write(codex_home.join("config.toml"), config)
+1 -1
View File
@@ -603,7 +603,7 @@ requires_openai_auth = false
supports_websockets = false
[notice.model_migrations]
"gpt-5.4" = "gpt-5.6-terra"
"gpt-5.4" = "gpt-6-sol"
[projects."{repo_root_display}"]
trust_level = "trusted"