Skip to content

cmux NEXT model menu: every row names its effort, each agent tab lists current versions with older ones under Legacy - #30054

Merged
lawrencecchen merged 6 commits into
feat-cmux-nextfrom
feat-cmux-next-29915-model-picker
Nov 1, 2026
Merged

lawrencecchen merged 6 commits into
feat-cmux-nextfrom
feat-cmux-next-29915-model-picker

Conversation

@austinywang

@austinywang austinywang commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #29915

Summary

The issue reported three problems with the cmux NEXT agent chat quick model menu.

  1. Effort was easy to miss. Effort showed as "Medium >" only on the selected row. Now every model row with effort levels names its level at rest. The running row shows the chat's current effort and other rows show their default. On the chat's own tab, other rows used to hide this until hover. The running row's effort is in the stronger text color so it reads as the live choice (QuickModelMenu.tsx withEffort, modelPicker.css).
  2. Tabs listed models inconsistently. Codex reports its whole live list as its menu, so its tab listed every GPT generation flat. Claude Code reports a short menu, so its older versions sat under Legacy models. Now, when a harness menu lists an older version of one product line alongside a newer one, the older one moves to Legacy models (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.
    • Context variants of one version (Opus 5.5 and Opus 5.5 · 1M) both stay.
    • Versionless aliases, models without a declared family, and an alias beside its dated snapshot never fold.
    • The chat's running model always keeps its row. quickSections and retryModelSections pass it in.
  3. Harness icons looked identical. Duplicate marks such as claude vs claude-sr2 were already merged into one tab per family by cmux NEXT model picker: one tab per model family; transports and logins are Account routes #29770, which landed after the reported build. Each rail mark already carries its harness name as a title / aria-label tooltip. 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.

  • Red, round 1 (fix files at base, tests from fa2da85): bun test test/relevant-models.test.ts src/agent-session/acpmux/QuickModelMenu.test.tsx gave 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".
  • Red, round 2 (review findings, tests from 4840703 against the round-1 fix fef693f): bun test test/relevant-models.test.ts gave 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".
  • Green (head, rebased on f06d9bd): those files plus 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-families and model-button-default-effort gave 167 pass and 0 fail.
  • The duplicate-key React warnings in model-menu-compact / model-menu-providers were 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-reveals fails on conversation/conversation.css:2448.
    • vp fmt flags newtab/NewTabDots.gallery.ts, newtab/tabDots.ts, test/composer-plus-geometry.test.ts and test/model-menu-compact.test.tsx.
  • python3 scripts/cmux-next/prepush-gate.py: no new violations.
  • Pushed with CMUX_WEB_LINT_SKIP_REASON because 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:

  1. Vendor-wide gateway families folded unrelated product lines.
  2. The running model could be folded into Legacy, and it disappeared from the .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-held condition 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

  • Observed: the focused bun tests above, run locally.
  • Not run: a tagged dev build, and the full webview suite (CI runs it).
  • Visual: the gallery compare (merge-base vs head) is posted as a PR comment.

Changelog

  • Fixed: the cmux NEXT model menu shows every model's effort level, and each agent tab lists only current model versions, with older ones under Legacy models.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with 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.

  • Every row with effort levels names its level at rest (previously only the selected row showed it as "Medium >"); the running row's level is emphasized.
  • 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.
  • Context variants of one version stay together; the running model always keeps its row; vendor-wide families like a gateway's "OpenAI" fold within one product line only, and dated snapshot ids don't fold their aliases.

Written for commit ba65507. Summary will update on new commits.

View guided diff Turn on auto-fix

austinywang and others added 6 commits October 31, 2026 19:41
…29915)

Regression tests for #29915.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…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>
@austinywang austinywang added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@austinywang austinywang added the media-tour Run the cmux-next UI tour (cmux-next-media.yml) on every push label Nov 1, 2026
@austinywang

Copy link
Copy Markdown
Contributor Author

Correctness review (review subagent, correctness first)

Round 1 reviewed fa2da85..fef693f.

  1. Blocking, fixed. relevantModels.ts: a harness whose catalog families are whole vendors (Vercel AI Gateway: OpenAI, Google, Anthropic, Z.AI) would fold every model below that vendor's newest version, for example GPT-6 Astra under GPT-6.1 Sol. The fold key is now the declared family plus the version-stripped id (lineKey). Test: "a vendor-wide family folds within one product line only".
  2. Blocking, fixed. The chat's running model could fold into Legacy models, and it vanished from the .shown-only list at ModelPicker.tsx:1293. relevantModelSections now takes the running model, and quickSections and retryModelSections pass it in, so it is never folded. Test: "the running model keeps its row and a dated snapshot never folds its alias".
  3. Should-fix, fixed. A dated snapshot id (claude-opus-4-5-20251101) folded its plain alias. Version comparison now ignores date-sized parts. The same test covers it.
  4. Nit, fixed. The redundant held && shown in data-held.
  5. Nit, addressed. Test gaps for 1 and 2. The new tests above fail against fef693f (7 pass, 2 fail) and pass on the head.

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.

  • Nit, fixed in 256941b. The retryModelSections doc comment was stale.
  • Nit, accepted. A dash-separated date id (-2025-11-01) on a model whose name has no digits could still fold its alias. No catalog row has that shape.

The head ba65507 adds only formatting, and the removal of an unneeded Set spread.

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review ba65507: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr30054 -f ref=feat-cmux-next-29915-model-picker -f platform=macos -f backend_mode=local

Gallery before/after for ba65507: 16 states rendered, 16 images differ, 1671 more touched states not rendered. Images are in the run's artifact, not on this public PR; the independent review of this head reads them on its own, so the PR needs no hand-made screenshots of these states.

gh run download 41267686432 -R manaflow-ai/cmux -n gallery-advisory-30054-ba65507032adfbc552bb343fb1ca00cca600ae98 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.composer-pickers/closed Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/closed Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/pill-rail Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/pill-rail Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-menu Apple System Colors changed 0.127% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-menu Apple System Colors Light changed 0.123% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-more Apple System Colors Light changed 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-more Apple System Colors changed 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-focus Apple System Colors Light changed 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-focus Apple System Colors changed 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-press-drag-release Apple System Colors Light changed 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/model-press-drag-release Apple System Colors changed 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/effort-menu Apple System Colors changed 0.127% own QuickModelMenu.tsx
agent-pane.composer-pickers/effort-menu Apple System Colors Light changed 0.124% own QuickModelMenu.tsx
agent-pane.composer-pickers/effort-focus Apple System Colors Light changed 0% own QuickModelMenu.tsx
agent-pane.composer-pickers/effort-focus Apple System Colors changed 0% own QuickModelMenu.tsx
agent-pane.composer-row/claude-auto Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/claude-auto Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/grid-running Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/grid-running Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/grid-draft Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/grid-draft Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/long-model Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/long-model Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/leo-report Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/leo-report Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/granted Apple System Colors Light unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/granted Apple System Colors unchanged 0% own QuickModelMenu.tsx
agent-pane.composer-row/fast-off Apple System Colors changed 0.424% own QuickModelMenu.tsx
agent-pane.composer-row/fast-off Apple System Colors Light changed 0.422% own QuickModelMenu.tsx
agent-pane.composer-row/fast-on Apple System Colors changed 0.424% own QuickModelMenu.tsx
agent-pane.composer-row/fast-on Apple System Colors Light changed 0.422% own QuickModelMenu.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 55361f1; does not block

Tour of ba65507032 (run): no media. The tour did not run: only webview code changed (7 path(s)), which the gallery advisory run checks in Linux Chromium on the pull request (its artifact holds any captures); add the media-tour-mac label, then re-add media-tour, to tour it on a Mac.

Shipped in:

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

@blacksmith-sh

blacksmith-sh Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Found 9 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpptmnzhy2/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmption6gbm/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)/
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)
View Logs
test_no_runner_picker_returns_a_hosted_mac (main.NoHostedMacInNightlies.test_no_run
ner_picker_returns_a_hosted_mac)/
test_no_runner_picker_returns_a_hosted_mac (main.NoHostedMacInNightlies.test_no_run
ner_picker_returns_a_hosted_mac)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@austinywang

Copy link
Copy Markdown
Contributor Author

Visual review (visual-review subagent) at ba65507

Verdict: 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 media-tour run https://github.com/manaflow-ai/cmux/actions/runs/41267702009 produced no capture of the model menu.

  1. fix (evidence, advisory). No real-app capture of the open model menu. Confirm it on a DEV build of this head, light and dark, in the system font.
  2. intent. In composer-row/fast-off and fast-on (the 0.42% diff), Sonnet, Haiku and Fable now show "Medium >" muted at rest, and the running Opus row shows "Medium >" in text color. The columns line up, and nothing overlaps the checkmark or ⌘2–⌘4.
  3. intended. With the side dropdown open, the highlighted running-row trigger now uses text color instead of muted. That is the running-row emphasis. The dropdown itself is unchanged.
  4. intent. In model-menu, GPT-6 Astra shows no level at rest. Its fixture has no recommended level, so it stays hover-only as before.
  5. coverage. No gallery state shows the harness rail or the Legacy fold. Unit tests in this PR cover the fold.
  6. pre-existing, not this PR. The fast-off and fast-on story names look swapped relative to the toggle they show.
  7. taste → Leo. Four repeated "Medium >" labels make the menu denser. Does it still read as calm? This is the trade-off cmux NEXT: model picker shows duplicate Claude/Codex harness icons and hides effort #29915 asks for: effort obvious on every row.

@austinywang

Copy link
Copy Markdown
Contributor Author

Non-green checks at ba65507

None 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 ready-to-land.

@austinywang austinywang added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Nov 1, 2026
@lawrencecchen

Copy link
Copy Markdown
Contributor

Review (claude-review-subagent): SHIP at ba65507

No blocking correctness defect found. I read the diff f06d9bd0736c..ba65507032ad and did not build or run tests locally (fleet/CI only).

What I checked

  • relevantModels.ts fold:
    • The fold runs only when the harness reports top, only on models already in chosen, and only on models with a declared family. It only removes rows. It never adds one, so a model that is not in the report stays under More models.
    • lineKey is the declared family plus the version-stripped id (release ?? id). Vendor-wide families ("OpenAI") stay split by product line (gpt-sol, gpt-astra, gpt-mini).
    • olderVersion drops parts >= 100000. So claude-opus-4-5-20251101 and claude-opus-4-5 compare equal and do not fold. Same-version context variants (opus[1m] / opus) do not fold. Rows with no version never fold.
    • The running model is matched on offer.id or offer.release and is never removed.
  • Callers (git grep in webviews/):
    • ModelPicker.quickSections passes props.model only for the chat's own harness (line 938), so other tabs fold their own old versions.
    • retryModelSections passes current.
    • The tests in test/current-model-families.test.ts and test/retry-model-sections.test.ts that call it with no running still pass in CI (react-apps-check (2)).
  • Tests fail without the fix, traced by hand:
    • Test 1 expects 7 shown rows. Before the fix all 9 were shown.
    • Test 2 fails if the key is the family alone, because all the openai/* rows would fold.
    • Test 3 fails without the snapshot-date filter, and also without the running guard.
    • In QuickModelMenu.test.tsx, the Sonnet row on the chat's own tab had no data-held and an empty level before the fix.
    • All four test files ran and passed in web / react-apps-check on this head.
  • QuickModelMenu.tsx: a row that is not running now shows its recommended level on every tab. held = !running && !!shown, so a row with no recommended level still hides its item until pointed at.
  • CSS: SubmenuTrigger renders as a direct child of .acpmux-quick-model-effort with ui-menu-item ... acpmux-quick-effort-trigger, so the new [data-running] > .ui-menu-item.acpmux-quick-effort-trigger selector matches. It overrides the base --agent-muted. The highlight rules set only the background, so nothing else is overridden.
  • Non-green checks are base findings, not caused by this PR:
    • cmux-next checks: the only red is "Checks job structure". The same red is on base commit 699e330, together with other job-structure reds.
    • release-notary: the red is test_no_runner_picker_returns_a_hosted_mac, a workflow runner test. It is red on several recent feat-cmux-next tip commits (78d3b7e, 699e330, f818cf7).
    • Guard status only wraps release-notary.
    • This PR touches only webviews/.

Non-blocking notes

  • retryModelSections.ts doc comment: "With a report the running model keeps its row" is true only when the running model is in the report. A running older model that is not in the report still goes under More models. The existing test "a running older model stays folded" depends on that behavior. Consider: "With a report, a running model the report lists keeps its row."
  • The newest scan depends on order when a line mixes a row with no version and a row with a version: if the row with no version comes first, nothing in that line folds. This is unlikely, because an alias with no digits usually has a different inferred line. It fails safe (no fold).
  • version() reads the first number in the name, else every number in the id. In a vendor-wide family, two sizes of one generation can share a line key (for example "Llama 3.1 8B" and "Llama 3.3 70B" both map to llama-b-instruct). Then the older one folds under More models. It stays reachable, so this is not a defect.
  • This is a change people will notice. Consider a highlight file in release-notes/next/ per WRITING.md.

@lawrencecchen
lawrencecchen merged commit 085a965 into feat-cmux-next Nov 1, 2026
279 of 305 checks passed
@lawrencecchen
lawrencecchen deleted the feat-cmux-next-29915-model-picker branch November 1, 2026 07:11

This branch was previously deployed

1 inactive deployment
ci-routing-agent — ba655070 Deployed Nov 1, 2026 by austinywang via wait for same-key tree publisher #93304
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

media-tour Run the cmux-next UI tour (cmux-next-media.yml) on every push ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants