[TUI 0.145.0] Esc-Esc Edit/Resume changes gpt-5.6-sol Ultra to xhigh
What version of Codex CLI is running?
codex-cli 0.145.0
What subscription do you have?
ChatGPT Pro 5x
Which model were you using?
gpt-5.6-sol
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What terminal emulator and version are you using (if applicable)?
Windows Command Prompt
Codex doctor report
Not collected. The issue reproduces deterministically in a short, otherwise normal TUI session.
What issue are you seeing?
After selecting gpt-5.6-sol with Ultra reasoning, using the Esc-Esc
Edit/Resume flow silently changes the reasoning effort back to xhigh.
Ultra remains selected during normal conversation turns. The change occurs
immediately after pressing Enter to confirm a previous prompt, before the
restored prompt is submitted again.
What steps can reproduce the bug?
- Start Codex CLI 0.145.0.
The TUI initially displays gpt-5.6-sol xhigh.
- Run
/model, selectgpt-5.6-sol, and selectUltra.
The TUI now displays gpt-5.6-sol ultra.
- Send
1+1=?.
Codex answers 2, and the TUI still displays gpt-5.6-sol ultra.
- Send
2+2=?.
Codex answers 4, and the TUI still displays gpt-5.6-sol ultra.
- Press Esc twice.
- The previous prompt,
2+2=?, is highlighted. Press Enter to select it
for Edit/Resume.
- Before submitting the restored prompt, observe that the model indicator
has changed to gpt-5.6-sol xhigh.
What is the expected behavior?
The prompt-edit branch should preserve the active conversation's selected
model and reasoning effort, so it should remain gpt-5.6-sol ultra.
The reasoning effort should not silently fall back to the configured
non-Ultra default when creating a branch from an earlier prompt. If this
reset is intentional, the TUI should clearly disclose it before creating
the branch.
Additional information
- The issue reproduces with one Esc-Esc-Enter gesture; repeated or rapid
input is not required.
- No reasoning-effort shortcut keys were used.
- Normal conversation turns preserve
Ultra. - The visible change occurs during prompt-edit branch creation or attachment,
not after a new model response.
- The observed change is confirmed by the TUI model indicator. The next
request payload was not independently inspected.
- A possible cause is that the prompt-edit fork path uses the configured
default effort (xhigh) rather than copying the active conversation's
current effort (Ultra).
Related issues
- #35286 involves the same Esc-Esc-Enter prompt-edit fork path, but reports
buffered input creating multiple chained forks. This issue reproduces with
a single gesture and concerns the selected reasoning effort not being
preserved.
- #35003 involves the same earlier-prompt fork feature in Codex CLI 0.145.0,
but reports copied record timestamps being rewritten. It does not report
a model or reasoning-effort change.
- #11013 and #12042 report reasoning effort changing when entering Plan mode.
This reproduction does not enter Plan mode; it is triggered by confirming
an Esc-Esc Edit/Resume selection.
- #26930 reports reasoning effort changing in Codex Desktop during
delegation or continuation. This report is a deterministic Codex CLI TUI
reproduction involving a prompt-edit branch.
5 Comments
Download this file and run:
git apply prompt-edit-preserve-reasoning-effort.patchprompt-edit-preserve-reasoning-effort.patch
The patch file's content is as below:
Analysis (community)
Residual analysis for #35292 (TUI Esc-Esc Edit/Resume drops
gpt-5.6-solUltra → xhigh) under docs/contributing.md — invitation-only. No unsolicited PR.Root-cause hypothesis
This is not a hardcoded
Ultra → XHighrewrite. Applying advanced Ultra deliberately splits state (live chat = Ultra, durableconfig.model_reasoning_effort= non-Ultra default). Esc-Esc PromptEdit then forks withfresh_session_config()without copying the livecurrent_reasoning_effort(), so the fork override carries the stale non-Ultra value (often the session’s prior xhigh). Ordinary/forkcopies live effort and does not show this bug.Verified at HEAD
4c43465133:1. Ultra apply splits live vs config.
codex-rs/tui/src/app/config_persistence.rson_apply_advanced_reasoning:self.config.model_reasoning_efforttodefault_reasoning_effort_for_conversation_model(model)— which filters out Ultra and prefers a supported configured non-Ultra effort, then model default, then first non-Ultra supported option.Unit coverage at
:1207-1238shows a live Ultra session coexisting with a non-Ultrafresh_session_config().2. PromptEdit path omits live effort (bug pin).
codex-rs/tui/src/app/event_dispatch.rsForkSessionForPromptEdit:refresh_in_memory_config_from_disk_best_effortlet config = self.fresh_session_config();— no assignment ofchat_widget.current_reasoning_effort()fork_thread_at(config, …)Contrast ordinary
/forkin the same file (:175-184): it does setfork_config.model_reasoning_effort = self.chat_widget.current_reasoning_effort()before
fork_thread. The PromptEdit omission is path-specific, not a general fork policy.3. Override is transmitted and applied server-side.
TUI packs
config["model_reasoning_effort"]intoThreadForkParams(app_server_session.rsfork params region; unit test confirms lifecycle params forward overrides).App-server fork path loads overrides via
load_for_cwd(request_overrides, …)(thread_processor.rs~4080–4168) and returnssession_configured.reasoning_effortfrom the new config — it does not re-read the source thread’s Ultra. The TUI then refreshes display from that returned effort (session_flow/ PromptEdit attach).4. Why the issue sees exactly xhigh.
Reporter starts at xhigh, selects Ultra, one Esc-Esc-Enter shows xhigh before resubmit. At HEAD,
gpt-5.6-solsupports both xhigh and Ultra (models-manager/models.json). Becausedefault_reasoning_effort_for_conversation_modelreuses the configured non-Ultra effort when still supported, a prior xhigh config is the deterministic fallback — not a magic Ultra→XHigh table.5. Scope honesty.
/fork.Ranked fix outline (all OSS):
ForkSessionForPromptEdit, afterfresh_session_config(), setconfig.model_reasoning_effort = self.chat_widget.current_reasoning_effort()(mirror
/fork).self.configon advanced apply; keep durable config aligned with live effort when user explicitly chose Ultra.model_reasoning_effort: ultra(today: non-Ultra / xhigh).Fail-first tests already nearby:
conversation_reasoning_uses_compatible_default_for_new_threads,thread_lifecycle_params_forward_config_overrides_and_service_tier— add a PromptEdit-specific case that asserts live Ultra survives.Happy to draft the one-line PromptEdit fix + test if maintainers want it. No unsolicited PR.
I tested CLI 0.147.0. When #37421 occurs, Ultra remains selected only because the backtrack fork fails: the session ID does not change, later turns remain, and the edited prompt is appended to the original thread. Therefore, #37421 masks #35292 but is not a usable workaround.
Thanks @git-longcat — that lines up with the residual pin.
When the Esc-Esc backtrack fork fails (#37421), live Ultra is never rewritten through
ForkSessionForPromptEdit/fresh_session_config(), so the UI can still show Ultra only because the bad fork path did not run. That masks #35292; it is not a fix or usable workaround.Once fork succeeds again, expect the live Ultra → durable non-Ultra (often prior xhigh) drop until PromptEdit copies
current_reasoning_effort()the same way ordinary/forkalready does.Additional reproduction: prompt edit can inherit another session's default model
I confirmed that the same prompt-edit fork path can also replace the active conversation model, not only its reasoning effort.
Reproduction
current-session-modelwithHighreasoning.other-session-default-modelwithLowreasoning toconfig.toml.This is especially surprising because switching models in an unrelated session can update the default configuration and therefore alter a later prompt-edit fork in the original session.
Root cause
ForkSessionForPromptEditrefreshes config from disk and then usesfresh_session_config()without restoring the live chat widget model or reasoning effort. The normal/forkpath already copies both live values.Tested fix
After creating the fresh config, copy both active values before calling the fork path:
The regression test sets one live model/effort, writes different defaults to
config.toml, triggers prompt edit, and asserts that the fork retains the live values while preserving the existing source-history behavior.Patch commit: https://github.com/zzh-www/codex/commit/af773ce736aa2995598bf48d1a63e00547a09830
Local validation:
just fix -p codex-tuipasses.