Skip to content

[FEATURE]: SendUserMessage / Brief tool for proactive async notifications from sub-agents #20482

@borealBytes

Description

@borealBytes

Feature hasn't been suggested before.

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

Note: This is related to but distinct from #20460 (which addresses LLM turn cost for background task result collection). This issue is about the tool primitive itself — a dedicated, lightweight message channel that sub-agents can use to push status updates to the user without triggering a parent LLM turn at all.


Describe the enhancement you want to request

Problem

Background agents in OpenCode currently have no way to proactively surface a message to the user. Their only communication channel is via tool results returned to the parent agent, which requires the parent to wake up, consume an LLM turn, and relay the message. This is both expensive (see #20460) and slow.

claw-code implements a SendUserMessage tool (also aliased as Brief) with a status: "normal" | "proactive" field. proactive status sends directly to the user's UI without waiting for the parent agent to wake.

Proposed solution

// packages/opencode/src/tool/send-user-message.ts

export const SendUserMessageTool = Tool.define({
  name: "SendUserMessage",
  description: "Send a status message or attachment directly to the user without consuming a parent LLM turn.",
  parameters: z.object({
    message: z.string(),
    attachments: z.array(z.string()).optional(), // file paths
    status: z.enum(["normal", "proactive"])
  }),
  execute: async ({ message, attachments, status }) => {
    // "proactive" bypasses parent agent and writes directly to session event stream
    // "normal" queues as a tool result for the parent to relay
    await Bus.publish("assistant.message", { message, attachments, status })
    return { message, sentAt: new Date().toISOString() }
  }
})

Behavior

status Behavior
"normal" Message is queued as a tool result; parent agent relays it on next turn
"proactive" Message is written directly to the session event stream / UI immediately, bypassing the parent LLM turn entirely

Why this matters

  • Background research agents can report "Found 3 relevant files, continuing..." without waking the orchestrator
  • Long-running build agents can push incremental progress updates
  • Error conditions in sub-agents can be surfaced to the user immediately, not after the orchestrator's next poll cycle
  • Eliminates the N+1 LLM turn problem for parallel agent status reporting (directly addresses the cost issue in [FEATURE]: Silent result collection for background tasks to avoid consuming LLM turns #20460)

Acceptance criteria

  • SendUserMessage tool is registered with ReadOnly permission (no filesystem write needed)
  • proactive messages appear in the TUI/web UI immediately without a parent LLM turn
  • proactive messages are visually distinct from normal assistant messages (e.g., labelled with the sub-agent's name)
  • File attachments resolve relative to the workspace root and are validated before sending
  • Tool is available to sub-agents spawned via the Agent tool

Related / cross-reference

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions