Skip to content

[FEATURE]: Expose delegation metadata (e.g. plugin-assigned category/label) on subagent sessions and message events — plugins cannot surface it anywhere in the runtime UI #44174

Closed as not planned

Description

@edynasty

Description

OpenCode's plugin ecosystem (orchestration plugins like oh-my-openagent, 68k stars) spawns subagent sessions via the SDK with delegation metadata — most importantly a category that selects a category-optimized model profile. That metadata is completely invisible in the UI at runtime, because OpenCode's event stream and session model provide no channel for a plugin to surface it.

This was originally reported from the plugin side as code-yeongyu/oh-my-openagent#6854: "task(category=...) category is invisible in TUI — delegated subagents always labeled 'Sisyphus-Junior', making it look like the orchestrator skipped the category". After digging through both codebases, the root cause is on the OpenCode side, not the plugin side.

The problem in detail

When a plugin orchestrator delegates task(category="quick", ...), OpenCode spawns a child session. The runtime status line and message headers show only:

▣ Sisyphus-Junior · deepseek-v4-flash · 11.4s

The category (quick) — which determined the model, reasoning effort, and agent profile — appears nowhere. This is actively misleading: after plugins migrated category→model mappings to plain model IDs, multiple categories resolve to the same model as the default agent, so a categorized delegation is visually indistinguishable from a category-less one. Users cannot audit which model profile a delegation actually used without opening the SQLite DB and inspecting the parent's task tool-call input.

Why plugins cannot fix this themselves (root cause on OpenCode side)

We traced all three possible injection points; each is closed:

  1. session.create body only accepts parentID + title (SDK types.gen.d.ts). There is no metadata, no agent, no custom display field. A plugin's only channel is the session title, which shows up in session lists/history but not in the runtime status line or message headers.

  2. The runtime status line / agent header is rendered from event info (info.agent, info.modelID, info.variant — e.g. EventMessageUpdated properties). EventMessagePartUpdated properties contain only part + delta; no session title, no category, no delegation metadata. A plugin-side renderer literally has no data to work with.

  3. info.agent originates from the prompt dispatch agent parameter and must exactly match a registered agent name. A plugin cannot pass a display-suffixed name like "Sisyphus-Junior (quick)" — the server rejects unknown agent names (Agent "..." not found), and oh-my-openagent explicitly strips invisible characters from agent names before dispatch (stripInvisibleAgentCharacters) for this reason.

So the only workaround plugins have today is embedding the category into the session title (oh-my-openagent now does "<description> (@<agent> · <category> subagent)" — see code-yeongyu/oh-my-openagent#6854 and the linked PR), which covers the session list but cannot cover the live status line or per-message agent headers, because those never read the title.

Proposed solution (any one of these unblocks the ecosystem)

  • Option A (smallest): Add an optional agentLabel/displayName (or free-form metadata object) to the session.create body, propagated into session.info and included in EventMessageUpdated/EventMessagePartUpdated info. Plugins could then set displayName: "Sisyphus-Junior · quick" at spawn time, and every renderer (TUI, desktop, opencode run CLI) that already prints info.agent could print it alongside.
  • Option B: Include session.title (or the full session info) in the message event payloads, so downstream renderers can correlate a message with its session and derive the label.
  • Option C: Allow the agent field on prompt dispatch to carry a display suffix (e.g. agent: "sisyphus-junior [quick]", bracketed suffix ignored for agent resolution) — this matches how the status line already renders variant in parentheses and requires no schema additions.

Why this matters

  • Auditability: delegation category determines cost and capability (a deep vs quick delegation can differ 6x in token price). Users currently have no way to see it at a glance.
  • Plugin ecosystem parity: Claude Code and Codex-style harnesses surface delegation metadata in their UIs; OpenCode plugins currently cannot, by construction.
  • The plugin side is already done: oh-my-openagent has merged the title-based half of this (session list visibility). The remaining half — live status line / message headers — is blocked purely on OpenCode exposing the data.

Happy to provide reproduction steps, SDK traces, or test a PR branch.

Activity

  1. github-actions commented on Oct 22, 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