Skip to content

[FEATURE]: allow plugins to switch active primary agent (custom primary agent handoff) #14528

Closed as not planned

Description

@zeakd

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

What I’m trying to do

HI. I’m defining my own primary agent (e.g. ideation) and I want to ship a plugin that provides an ideation_exit tool.
When the tool hands off to another primary agent (usually build), I want the TUI to update its active agent selector too.
Server-side handoff is already possible by injecting a synthetic user message with agent: "build", but the TUI selector doesn’t follow.
So the UI can show the wrong active agent and the next user input may be sent with the wrong agent.

Current behavior

TUI currently auto-switches local.agent only for plan_enter / plan_exit (hardcoded).
Plugin-defined handoff tools (like ideation_exit) can’t trigger the same UI update.

Proposal

Add a first-class TUI event/intent to set the active primary agent:

  • Event: tui.agent.set
  • Payload: { name: string }
  • Expose it through the same plumbing as other TUI events (so plugins can emit it)
  • TUI handles it by calling local.agent.set(name)
    This would let plugins keep the agent selector in sync after a custom primary-agent handoff.

References

  • Hardcoded mapping today: packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
  • Existing TUI event plumbing: packages/opencode/src/cli/cmd/tui/event.ts, packages/opencode/src/server/routes/tui.ts
  • plan_enter/exit pattern: packages/opencode/src/tool/plan.ts

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    needs:complianceThis means the issue will auto-close after 2 hours.
    on Feb 21, 2026
  2. changed the title [-]plugin/tui: allow plugins to switch active primary agent (custom primary agent handoff)[/-] [+][FEATURE]: allow plugins to switch active primary agent (custom primary agent handoff)[/+] on Feb 21, 2026
  3. github-actions commented on Feb 21, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now follows the contributing guidelines and looks great. We appreciate the clear description and references to the relevant code.

  4. github-actions commented on Feb 21, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now follows our contributing guidelines. Your feature request is clear and well-structured. We appreciate the detailed context and the code references.

  5. wilmoore commented on Mar 5, 2026

    @wilmoore

    +1 — this unlocks a big safety/UX workflow for me even with built-in agents.

    Use case: “auto-return to Plan” safety rail

    I use plan as my default to avoid unintended edits, but I switch to build temporarily to execute changes. The problem is I often forget I’m still in build and send the next prompt assuming plan, which can immediately start editing/running commands.

    This prevents accidental edits/commands by making Plan the “sticky default” after any Build interaction.

    Today I can almost solve this with a plugin, but it’s brittle:

    • on a user message sent under build, immediately switch the active agent back to plan for the next prompt
      …but the missing primitive is exactly what this issue proposes: a deterministic, first-class way for plugins to set the active primary agent in the TUI.

    Request

    Please add a plugin-accessible, deterministic “set active agent by name” mechanism (your tui.agent.set { name } proposal is perfect).

    This should:

    • update the TUI agent selector (so the next user input is actually sent as that agent)
    • work for both built-in and custom primary agents

    Bonus (makes plugins more robust)

    Bonus: emit tui.agent.updated { name } (or expose a currentAgent() API) so plugins can avoid redundant toggles and verify state.

    This would let safety plugins implement “Plan-by-default” reliably without relying on agent.cycle ordering.

  6. assigned and unassigned on Apr 26, 2026
  7. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  8. github-actions commented on Jul 4, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions