Repository navigation
cmux NEXT model menu: every row names its effort, each agent tab lists current versions with older ones under Legacy - #30054
Conversation
…sions in harness menus Every quick-menu row with effort levels names its level at rest (the chat's own tab too), the running row is emphasized, and a harness menu that lists older versions of a declared catalog family folds them under Legacy models so Codex and Claude tabs group the same way. Fixes #29915 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…running model (#29915) Review findings on #29915: a vendor-wide family (Vercel AI Gateway's OpenAI, Google) must not fold one product line under another, the chat's running model keeps its row, and a dated snapshot never folds its plain alias. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the running model Fold key is the declared family plus the version-stripped id, version comparison ignores snapshot dates, and quickSections / retryModelSections pass the running model so it is never moved to Legacy models. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arness menu Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Correctness review (review subagent, correctness first)Round 1 reviewed fa2da85..fef693f.
The effort-at-rest logic and the CSS selector were found correct: no-recommended, no-levels and undefined current effort all behave as before. Round 2 reviewed fef693f..256941b and found no blocking findings.
The head ba65507 adds only formatting, and the removal of an unneeded Set spread. |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Gallery before/after for
States
Pick other states with a red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 55361f1; does not block Tour of Shipped in:
|
There was a problem hiding this comment.
3 issues found across 7 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="webviews/src/agent-session/acpmux/relevantModels.ts">
<violation number="1" location="webviews/src/agent-session/acpmux/relevantModels.ts:61">
P2: `olderVersion` takes version digits from the raw id, so `[1m]` tags and hyphenated snapshot dates count as version parts when the name has no version. Strip bracket tags and date suffixes before parsing so context variants stay with their base model and aliases are not folded under dated snapshots.</violation>
<violation number="2" location="webviews/src/agent-session/acpmux/relevantModels.ts:100">
P2: A versionless model that shares a product line with versioned models can become the line's `newest` and block folding. `olderVersion` returns false whenever either side lacks a version, so the newest-tracking loop never replaces a versionless first entry. Skip versionless models here so only versioned models seed `newest`.</violation>
</file>
<file name="webviews/src/agent-session/acpmux/QuickModelMenu.tsx">
<violation number="1" location="webviews/src/agent-session/acpmux/QuickModelMenu.tsx:605">
P2: Effort-capable models without `defaultEffort` still have no recommended choice, so `shown` stays undefined and the effort trigger remains hidden at rest. Derive and display the actual landing level for these rows so every supported model names its effort.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| * whose name and id carry no version (a bare alias). A snapshot date is no version part, so | ||
| * `claude-opus-4-5` is not older than its dated snapshot `claude-opus-4-5-20251101`. */ | ||
| function olderVersion(a: Model, b: Model): boolean { | ||
| const release = (model: Model) => version(model).filter((part) => part < 100_000); |
There was a problem hiding this comment.
P2: olderVersion takes version digits from the raw id, so [1m] tags and hyphenated snapshot dates count as version parts when the name has no version. Strip bracket tags and date suffixes before parsing so context variants stay with their base model and aliases are not folded under dated snapshots.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/relevantModels.ts, line 61:
<comment>`olderVersion` takes version digits from the raw id, so `[1m]` tags and hyphenated snapshot dates count as version parts when the name has no version. Strip bracket tags and date suffixes before parsing so context variants stay with their base model and aliases are not folded under dated snapshots.</comment>
<file context>
@@ -54,9 +54,29 @@ function newer(a: Model, b: Model): boolean {
+ * whose name and id carry no version (a bare alias). A snapshot date is no version part, so
+ * `claude-opus-4-5` is not older than its dated snapshot `claude-opus-4-5-20251101`. */
+function olderVersion(a: Model, b: Model): boolean {
+ const release = (model: Model) => version(model).filter((part) => part < 100_000);
+ const left = release(a);
+ const right = release(b);
</file context>
| !!running && (model.offers ?? [model]).some((offer) => offer.id === running || offer.release === running); | ||
| const newest = new Map<string, T>(); | ||
| for (const model of chosen) { | ||
| if (!model.family) continue; |
There was a problem hiding this comment.
P2: A versionless model that shares a product line with versioned models can become the line's newest and block folding. olderVersion returns false whenever either side lacks a version, so the newest-tracking loop never replaces a versionless first entry. Skip versionless models here so only versioned models seed newest.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/relevantModels.ts, line 100:
<comment>A versionless model that shares a product line with versioned models can become the line's `newest` and block folding. `olderVersion` returns false whenever either side lacks a version, so the newest-tracking loop never replaces a versionless first entry. Skip versionless models here so only versioned models seed `newest`.</comment>
<file context>
@@ -67,6 +87,25 @@ export function relevantModelSections<T extends Model>(
+ !!running && (model.offers ?? [model]).some((offer) => offer.id === running || offer.release === running);
+ const newest = new Map<string, T>();
+ for (const model of chosen) {
+ if (!model.family) continue;
+ const key = lineKey(model);
+ const previous = newest.get(key);
</file context>
| if (!model.family) continue; | |
| if (!model.family || !version(model).some((part) => part < 100_000)) continue; |
| : held | ||
| ? choices.find((choice) => choice.recommended) | ||
| : undefined; | ||
| : choices.find((choice) => choice.recommended); |
There was a problem hiding this comment.
P2: Effort-capable models without defaultEffort still have no recommended choice, so shown stays undefined and the effort trigger remains hidden at rest. Derive and display the actual landing level for these rows so every supported model names its effort.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/QuickModelMenu.tsx, line 605:
<comment>Effort-capable models without `defaultEffort` still have no recommended choice, so `shown` stays undefined and the effort trigger remains hidden at rest. Derive and display the actual landing level for these rows so every supported model names its effort.</comment>
<file context>
@@ -597,14 +597,13 @@ export function QuickModelMenu({
- : held
- ? choices.find((choice) => choice.recommended)
- : undefined;
+ : choices.find((choice) => choice.recommended);
+ const held = !running && !!shown;
// The row stays one line: the model, then its effort item at the trailing edge (the running
</file context>
|
Found 9 test failures on Blacksmith runners: Failures
|
Visual review (visual-review subagent) at ba65507Verdict: FIX (advisory). The only fix finding is about evidence and rests on Linux renders, so it does not block the merge. Source: CI gallery-advisory https://github.com/manaflow-ai/cmux/actions/runs/41267686432. All 32 states are Linux Chromium with fallback fonts. The
|
Non-green checks at ba65507None of these failures come from this PR. It changes only seven webviews model-menu files.
Own verdict: the diff, the tests (167 pass), the review findings and the advisory visual review are all resolved at this head. Labeling |
|
Review (claude-review-subagent): SHIP at ba65507 No blocking correctness defect found. I read the diff What I checked
Non-blocking notes
|
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Fixes #29915
Summary
The issue reported three problems with the cmux NEXT agent chat quick model menu.
QuickModelMenu.tsxwithEffort,modelPicker.css).relevantModelSections). Each tab shows its lines' current versions and keeps the same Legacy fold. A product line is the declared catalog family plus the version-stripped id, so a gateway whose families are whole vendors ("OpenAI", "Google") never folds Astra under Sol.quickSectionsandretryModelSectionspass it in.title/aria-labeltooltip. The rail stays marks-only, per the picker design rule, so I added no visible tab text.Tests
The regression tests are committed before the fix.
bun test test/relevant-models.test.ts src/agent-session/acpmux/QuickModelMenu.test.tsxgave 39 pass and 2 fail. The failures are exactly the new tests: "a harness menu that lists older versions of a catalog family folds them, keeping variants" and "every model row with levels names one at rest, on the chat's own tab too".bun test test/relevant-models.test.tsgave 7 pass and 2 fail. The failures are "a vendor-wide family folds within one product line only" and "the running model keeps its row and a dated snapshot never folds its alias".retry-model-sections,retry-model,model-menu-compact,model-menu-providers,model-menu-short-list,model-picker-effort-provenance,model-picker-inline-effort-focus,current-model-familiesandmodel-button-default-effortgave 167 pass and 0 fail.model-menu-compact/model-menu-providerswere already there: 8 on base and 8 on head.bun run check: type check passed (3613 files). Lint and fmt are clean on every changed file. The remaining reds are on base files this PR does not touch:check:popup-hover-revealsfails onconversation/conversation.css:2448.vp fmtflagsnewtab/NewTabDots.gallery.ts,newtab/tabDots.ts,test/composer-plus-geometry.test.tsandtest/model-menu-compact.test.tsx.python3 scripts/cmux-next/prepush-gate.py: no new violations.CMUX_WEB_LINT_SKIP_REASONbecause the pre-push web lint refused only on those base reds. Every flagged file is byte-identical to base f06d9bd.Review
A correctness-first review subagent found two blocking issues in the first fix:
.shown-only list.It also found a should-fix: a dated snapshot id folded its alias. All three are fixed in 4840703 (tests) and 7e2491a (fix), along with two nits (a redundant
data-heldcondition and a stale doc comment). The re-review found no blocking findings. One accepted nit remains: an id dated with dashes (-2025-11-01) and a name with no digits could still fold its alias, and no catalog row has that shape.Observed / Not run
Changelog
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Fixes #29915: the cmux NEXT quick model menu now names an effort level on every model row, and each agent tab shows current model versions with older ones folded under Legacy models.
Written for commit ba65507. Summary will update on new commits.