anomalyco / anomalyco/opencode

[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

Open
#44,174 0 comments 0 reactions 1 assignee View on GitHub

@rekram1-node is already working on this.

Since Aug 22, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.