-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[FEATURE]: SendUserMessage / Brief tool for proactive async notifications from sub-agents #20482
Description
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
-
SendUserMessagetool is registered withReadOnlypermission (no filesystem write needed) -
proactivemessages appear in the TUI/web UI immediately without a parent LLM turn -
proactivemessages 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
Agenttool
Related / cross-reference
- claw-code reference: https://github.com/instructkr/claw-code/tree/main/rust (
SendUserMessage/Brieftool) - Background task result batching (cost angle): [FEATURE]: Silent result collection for background tasks to avoid consuming LLM turns #20460
- Sub-agent tool isolation: [FEATURE]: Add hidden field to skill frontmatter to exclude skills from agent selection #20474
- Orchestrator-executor topology: [FEATURE]: Coordinator shell + fork mode #20368
- Learnings from claude-code source: Lessons from claude-code-main? #20475