fix(tui): Ctrl+T moves to a new effective thinking tier on fixed routes - #6667
Merged
2 commits merged intoSep 28, 2026
Merged
2 commits merged into
2 commits merged into
Conversation
Cause: Ctrl+T could land on a tier the route already treats as the one in effect, so presses looked dead. - Under Auto routing, next_reasoning_effort_for_active_route used cycle_next_for_auto_model, a private 9-rung ladder (minimal, xhigh, ultra...) that disagreed with the /model picker's Auto ladder. - picker_efforts_for_route deduped only identical values, not rungs whose route-normalized tier is identical (DeepSeek medium -> high, K3 off -> low, catalog `thinking: disabled` -> catalog default), and DeepSeek route normalization kept minimal/xhigh/ultra although the wire sends them as low/high/max. Fix: Ctrl+T and the hotbar reasoning.cycle action cycle exactly picker_efforts_for_route (Auto included). That ladder now drops rungs whose route-normalized tier is already offered, preferring the rung that names the tier (Auto is always kept). A persisted alias the ladder dropped enters at the rung it resolves to, so the first press moves on. DeepSeek normalize_for_route now mirrors client::deepseek_effort (minimal -> low, xhigh -> high, ultra -> max). K3's picker no longer lists `off`. cycle_next_for_auto_model is deleted. Tests (cargo test -p codewhale-tui --lib -- <filter>): - ctrl_t: 5 passed; 0 failed (3 of them fail with the fix stashed) - picker: 341 passed; 0 failed - reasoning: 233 passed; 0 failed - cycle: 152 passed; 0 failed; deepseek: 167 passed; 0 failed - kimi: 118 passed; 0 failed; route: 762 passed; 0 failed - receipt: 308 passed; 0 failed; status: 249 passed; 0 failed - hotbar: 82 passed; 0 failed; tui::ui::tests: 824 passed; 0 failed cargo fmt --all -- --check clean. Refs #6650 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Cause: the #6650 ladder dedupe used only normalize_for_route, while the effort status line and Work receipts also apply the route-constrained tier (work_graph::constrained_effective_reasoning_for_route). On Z.ai GLM-5.2 low and medium both resolve to high, so a catalog listing low/medium/high still produced presses that changed nothing. The regression test compared display labels, which under Auto routing are the requested value, so it never proved the effective tier changed and never ran the dedupe path through cycle_effort. Fix: add model_picker::effective_tier_for_route (constrained tier when the route proves one, else normalize_for_route) and use it for both the ladder dedupe and the Ctrl+T anchor for a persisted alias. Routes whose tier is unavailable or untiered keep their rows. Auto model routing is unchanged: it walks the picker's Auto ladder and its tier is settled at dispatch, so the CHANGELOG no longer claims every press changes the tier there. The CHANGELOG now also notes the DeepSeek minimal/xhigh/ultra reporting change and K3 dropping `off`; the stale DeepSeek note in reasoning_preference.rs is corrected. Tests: the Ctrl+T test now compares the effective tier after each press on concrete routes, and a new test injects catalog rows (DeepSeek low/medium/high/xhigh/max, Z.ai GLM-5.2 off/low/medium/high/max) and walks them through cycle_effort. With the dedupe disabled it fails (deepseek press 2 left the tier at High); with only normalize_for_route it fails (GLM-5.2 press 2 left the tier at High). cargo test -p codewhale-tui --lib -- <filter>, CARGO_BUILD_JOBS=4: - ctrl_t: 6 passed; 0 failed - picker: 341 passed; 0 failed - reasoning: 233 passed; 0 failed - effort: 80 passed; 0 failed - zai: 31 passed; 0 failed - hotbar: 82 passed; 0 failed - kimi: 118 passed; 0 failed - deepseek: 167 passed; 0 failed cargo fmt --all -- --check clean. Refs #6650 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Hmbown
force-pushed
the
fix/6650-ctrl-t-effort-cycle
branch
from
September 27, 2026 10:20
fd383c8 to
9226111
Compare
Hmbown
pushed a commit
that referenced
this pull request
Sep 27, 2026
# Conflicts: # CHANGELOG.md # crates/tui/CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #6650
The reporter's case (fixed
deepseek-v4.1-flash, dead presses) was not reproduced, so this PR does not close the issue. See Uncertain.Cause
cycle_next_for_auto_model, a separate 9-rung ladder (minimal,xhigh,ultra, …) that did not match the/modelpicker's Auto ladder.picker_efforts_for_routeremoved only exact duplicate values. It kept rungs that resolve to the same tier on the route: DeepSeekmediumishigh, Z.ai GLM-5.2low/mediumarehigh, K3offislow, and a catalogthinking: disabledvalue becomes the catalog default. DeepSeek route normalization also leftminimal/xhigh/ultraunchanged, but the wire sends them aslow/high/max.Fix
reasoning.cycleaction now cycle exactlypicker_efforts_for_route(…, auto_model).model_picker::effective_tier_for_route, which returns the route-constrained tier when the route proves one (the value the status line and Work receipts report) and otherwisenormalize_for_route. When two rungs collide, the one that names the tier stays.Autois always kept. Routes whose tier is unavailable or untiered keep all their rows.medium) starts from the rung it resolves to, so the first press moves on.normalize_for_routenow matchesclient::deepseek_effort, so/status, receipts and/effort xhighreporthigh, notxhigh. K3's picker no longer listsoff.cycle_next_for_auto_modelis deleted.Not covered
[auto, off, low, medium, high, max]. Its tier is settled when the turn is routed. If the turn goes to DeepSeek,mediumandhighboth sendhigh. The CHANGELOG says so.minimalandlowboth sendlow. This PR does not dedupe them.Evidence
cargo test -p codewhale-tui --lib -- <filter>(CARGO_BUILD_JOBS=4) on head:ctrl_t: 6 passed; 0 failed.every_ctrl_t_press_changes_the_effective_thinking_tierchecks that the effective tier changes on every press, not the label. It covers DeepSeek flash and v4.1, K3 and Grok, over two laps.ctrl_t_skips_catalog_rungs_that_resolve_to_an_offered_tierinjects catalog rows: DeepSeeklow/medium/high/xhigh/maxand GLM-5.2off/low/medium/high/max. It asserts the ladders[auto, low, high, max]and[auto, off, high, max]and checks that every press changes the effective tier.normalize_for_route, it fails with "GLM-5.2: press 2 (Medium) left the effective tier at Tier(High)".picker341/0,reasoning233/0,effort80/0,zai31/0,hotbar82/0,kimi118/0,deepseek167/0.cargo fmt --all -- --checkis clean.cycle152/0,route762/0,receipt308/0,status249/0,tui::ui::tests824/0.Uncertain
With the pinned catalog snapshot, the fixed
deepseek-v4.1-flashladder was already distinct on v0.10.0:[auto, off, low, high, max]. On the old Auto path, each press showed a different requested label. The reporter's visible dead presses may come from a live Models.dev entry for the model that listsmedium/xhigh, and this PR covers that case. The exact live catalog and config were not reproduced, so the issue stays open until the reporter confirms.🤖 Generated with Claude Code