Skip to content

[Feature]: Separate OpenCode reasoning effort and agent (Build/Plan) into distinct composer controls #14210

Description

@aashishsingla567

Area

apps/web, apps/server

Problem / Observed Behavior

When using the OpenCode provider in T3 Code, the reasoning effort (model variant, e.g. Low / Medium / High / Max) and the agent mode (Build / Plan) are bundled into a single compound dropdown trigger in the composer footer (e.g. Max · Build or Medium · Build).

Clicking this trigger opens a single shared popover menu grouping both Reasoning and Agent together:

+-----------------------+
| Reasoning             |
|   Low                 |
|   High                |
|   ✓ Max               |
+-----------------------+
| Agent                 |
|   ✓ Build [Default]   |
|   Plan                |
+-----------------------+

This contrasts with Codex and Claude, where reasoning/effort is exposed as its own dedicated input control separate from interaction/mode controls.

Background

In PR #9287 (fix(opencode): show Reasoning selector for OpenCode models, addressing #2144), the OpenCode variant descriptor was renamed to Reasoning and synthesized into the provider's optionDescriptors. Because TraitsPicker joins all select option descriptors together (labels.join(' · ')), OpenCode's reasoning and agent options ended up rendered as a single joint trigger (Max · Build).

Expected Behavior

Reasoning effort and Agent selection should be distinct, separate controls in the composer:

  1. Dedicated Reasoning Effort picker: A standalone dropdown for reasoning levels (Low, Medium, High, Max / xhigh), matching the UX pattern of Codex and Claude.
  2. Dedicated Agent / Mode control: A separate control for OpenCode agent selection (Build, Plan), aligned with how interaction modes are handled.

Steps to Reproduce

  1. Open T3 Code composer.
  2. Select the OpenCode provider and any model supporting variants (e.g., DeepSeek V4.1 Flash).
  3. Observe the footer toolbar: instead of a dedicated reasoning selector, a single joint pill (Max · Build) is displayed that bundles both Reasoning and Agent options into one menu.

Why this matters

  • Cross-provider consistency: Users switching between Codex, Claude, and OpenCode expect reasoning controls to be in a familiar, dedicated location.
  • Discoverability: Bundling reasoning into the agent/mode dropdown makes reasoning effort hard to discover, leading users to believe effort adjustment is unsupported or fixed to the default.
  • UX Clarity: Reasoning depth and agent mode are orthogonal settings that should not require opening a compound popover to change.

Activity

  1. juliusmarminge commented on Sep 29, 2026

    @juliusmarminge
    Member

    Triage

    This matches the current composer, and it is a UI request rather than a broken control. Reasoning and agent are already stored as separate model options (variant and agent). On web and desktop they are drawn by one shared traits menu, and the button label joins every select with " · ", which is why OpenCode reads Max · Build or Medium · Build.

    Codex, Claude, and Cursor do not put an agent in that menu. Their effort control is the same traits picker, so it usually shows only the effort. Build/Plan is a separate footer toggle, and only while Settings > Legacy features > Plan mode is on (showInteractionModeToggle is true for those drivers). OpenCode sets that flag to false. With legacy plan mode off, the Plan agent is removed, but Build and any custom agents stay, so the effort button still carries the agent name. Mobile already lists Reasoning and Agent as separate rows in thread settings; the gap is the web composer, which the desktop app uses, including the compact overflow menu.

    Turning the legacy Build/Plan toggle on for OpenCode would not cover this. That toggle is only default or plan, and OpenCode sends the agent option, which can be Build, Plan, or a custom primary agent. A split should keep those as two composer controls, and keep Plan hidden unless legacy plan mode is enabled.

    No existing issue tracks this split.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequested improvement or new capability.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions