Skip to content

feat(chat): tabbed model selector with agent segmented control#3437

Closed
tlgimenes wants to merge 12 commits into
mainfrom
tlgimenes/model-selector-redesign
Closed

feat(chat): tabbed model selector with agent segmented control#3437
tlgimenes wants to merge 12 commits into
mainfrom
tlgimenes/model-selector-redesign

Conversation

@tlgimenes
Copy link
Copy Markdown
Contributor

@tlgimenes tlgimenes commented May 22, 2026

What is this contribution about?

Redesigns the chat-input model selector to remove repetition and add explicit agent switching:

  • Agent segmented control (new) — sits to the left of the model pill in the chat input, lets users switch between Decopilot / Claude Code / Codex with one click. Hidden when the active agent has no clonable source (no desktop CLI option) or only one section is eligible. Laptop agents get a small green dot + sr-only "on desktop".
  • Model selector popover — collapsed to a clean 3-row tier picker (Fast / Smart / Thinking) for the active agent. Single-line rows, right-aligned muted descriptions, taller padding, narrower container that hugs the rows (overrides the default w-72 baked into shared PopoverContent).
  • Claude Code labels carry their versions: Haiku 4.5, Sonnet 4.6, Opus 4.7.
  • Side fix: the AI-provider connect dialog used sm:max-w-3xl for every state — its OAuth-pending / provision-pending / provision-error states now use sm:max-w-md so the "Authorize the connection in the popup window…" message no longer floats inside a giant box.

Screenshots/Demonstration

(internal — verified locally in the conductor workspace)

How to Test

  1. Open a chat for an agent with a clonable source (e.g. New Website with a branch). The chat input now shows a segmented control to the left of the model pill — switch between Decopilot / Claude Code / Codex and confirm the model pill icon/label and the popover reflect the choice.
  2. Open the model pill. Confirm a tight 3-row picker (Fast / Smart / Thinking with versioned Claude rows). Click each row and confirm the tier updates.
  3. Open a chat for a non-clonable agent (Decopilot-only). The segmented control is hidden; the model pill still opens the same 3-row picker.
  4. From AI provider settings, trigger an OAuth flow. The "Authorize the connection in the popup window…" dialog is now narrow instead of full-width.

Migration Notes

Not applicable.

Review Checklist

  • PR title is clear and descriptive
  • Changes are tested and working
  • Documentation is updated (if needed)
  • No breaking changes

🤖 Generated with Claude Code


Summary by cubic

Redesigned the chat model selector: agent choice is now a second select pill next to the model pill, and the popover is a compact three-tier picker for the active agent. Also narrowed the provider connect dialog in pending/error states and versioned Claude Code labels.

  • New Features

    • Added a harness select pill (Decopilot / Claude Code / Codex) next to the model pill; hidden when the agent isn’t clonable or there’s only one option. The closed pill shows the active harness; CLI options show a small green dot, and popover rows include an sr-only “on desktop”.
    • The model selector popover shows a single section with three tiers (Fast / Smart / Thinking); no tabs. Right‑aligned descriptions, taller row padding, and w-auto popover with an inner w-72 container. Dropped the redundant “On” tag.
    • Updated Claude Code labels to include versions: Haiku 4.5, Sonnet 4.6, Opus 4.7.
    • Selecting a CLI agent while on a branch now eagerly starts the VM for a faster first response.
  • Bug Fixes

    • Provider connect dialog uses sm:max-w-md for OAuth/provision pending and error states to avoid oversized layouts.

Written for commit 33677e7. Summary will update on new commits. Review in cubic

tlgimenes and others added 11 commits May 21, 2026 22:01
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The dialog used sm:max-w-3xl (768px) for every state. The grid view
needs that width to fit provider cards, but the OAuth/provision
spinner and the error state just show a one-line message — they
looked oversized. Switch to sm:max-w-md (448px) for those states.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Non-clonable agents (no githubRepo metadata) can't route through a
desktop CLI, so showing Claude Code / Codex tabs in the popover was
misleading. Expose isAgentClonable in chat prefs and pass
lockedAgent="decopilot" to the popover when false — that branch
already renders a single section's body with no tab bar.

Also tighten the row style: right-align the muted description
(text-right) and bump py-1.5 to py-2.5 for breathing room.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The selected row's bg-accent highlight already conveys selection;
the trailing "On" text was redundant alongside the new right-aligned
description.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The right-aligned description left an awkward gap inside w-64. Tighter
container reduces the empty space between label and description.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@deco/ui's PopoverContent bakes w-72 into its base className, so my
inner w-56 container left a ~64px empty band of popover background
on the right. Adding w-auto to PopoverContent lets the inner width
own the sizing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e model pill

The chat input now exposes agent selection (Decopilot / Claude Code / Codex)
as an always-visible segmented control to the left of the existing model
pill. The popover loses its tab bar entirely and becomes a clean tier
picker for the active agent.

- New AgentSegmentedControl + AgentSegmentedControlPure components,
  hidden when the agent is not clonable or fewer than two sections are
  eligible.
- AgentModelPopover simplified: no tabs, no lockedAgent prop, always
  renders the active section's three tier rows.
- AgentModelTrigger drops lockedAgent pass-through.
- Tests updated; new tests cover the segmented control surface.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Benchmark

Should we run the Virtual MCP strategy benchmark for this PR?

React with 👍 to run the benchmark.

Reaction Action
👍 Run quick benchmark (10 & 128 tools)

Benchmark will run on the next push after you react.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

Release Options

Suggested: Minor (2.341.0) — based on feat: prefix

React with an emoji to override the release type:

Reaction Type Next Version
👍 Prerelease 2.340.1-alpha.1
🎉 Patch 2.340.1
❤️ Minor 2.341.0
🚀 Major 3.0.0

Current version: 2.340.0

Note: If multiple reactions exist, the smallest bump wins. If no reactions, the suggested bump is used (default: patch).

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

2 issues found across 13 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/mesh/src/web/components/chat/agent-model-popover.tsx">

<violation number="1" location="apps/mesh/src/web/components/chat/agent-model-popover.tsx:34">
P2: Fallback section rendering can lose the selected tier highlight when `activeAgent` is missing. Use `activeTier` for the rendered section so the picker always shows a selected row.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

return <div className="flex flex-col gap-1 w-60" />;
}

const selectedTier = section.kind === activeAgent ? activeTier : null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: Fallback section rendering can lose the selected tier highlight when activeAgent is missing. Use activeTier for the rendered section so the picker always shows a selected row.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/chat/agent-model-popover.tsx, line 34:

<comment>Fallback section rendering can lose the selected tier highlight when `activeAgent` is missing. Use `activeTier` for the rendered section so the picker always shows a selected row.</comment>

<file context>
@@ -9,45 +9,39 @@ interface Props {
+    return <div className="flex flex-col gap-1 w-60" />;
+  }
+
+  const selectedTier = section.kind === activeAgent ? activeTier : null;
 
   return (
</file context>
Suggested change
const selectedTier = section.kind === activeAgent ? activeTier : null;
const selectedTier = activeTier;

Comment thread apps/mesh/src/web/components/chat/agent-segmented-control.tsx Outdated
A second pill next to the model pill makes the harness picker
match the existing model picker UX — closed pill shows the active
harness, click opens a popover with one row per eligible harness.
Visibility rules are unchanged (hidden when the agent is not
clonable or only one section is eligible). The model popover also
widens from w-60 to w-72 to give the description more room.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tlgimenes tlgimenes closed this May 22, 2026
@tlgimenes tlgimenes deleted the tlgimenes/model-selector-redesign branch May 22, 2026 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant