Skip to content

ACP sub-agent completions don't notify the requester channel (Discord/WhatsApp/etc) #40272

Description

@yaseenkadlemakki

Summary

When a task is delegated via sessions_spawn with runtime="acp", the ACP session has no completion notification mechanism — the requester channel (Discord, WhatsApp, etc.) never receives a push notification when the task finishes. Users have to manually ask for status updates.

Even for runtime="subagent", agents will sometimes promise "I'll ping you when done" but the delivery silently fails if the origin resolution can't establish a clear channel+target at announce time.

Root Cause

In src/agents/tools/sessions-spawn-tool.ts, the spawnAcpDirect path does not pass expectsCompletionMessage: true (unlike spawnSubagentDirect):

// runtime === 'acp'
const result = await spawnAcpDirect({ task, label, agentId, ... });
// ^^^^ no expectsCompletionMessage, no completion announce wired up

// runtime === 'subagent'
const result = await spawnSubagentDirect({
  ...
  expectsCompletionMessage: true,  // subagent gets this
});

Additionally, in src/agents/acp-spawn.ts, the only lifecycle hook called is parentRelay?.notifyStarted() — there is no equivalent notifyCompleted() that feeds back into the announce pipeline.

Reproduction

  1. Be in a Discord channel with OpenClaw connected
  2. Ask the agent to do a long-running task (e.g. "implement feature X, full test coverage, push to branch")
  3. Agent spawns an ACP session (runtime="acp")
  4. Task completes ✅ — no message is sent to Discord
  5. User has to manually ask "are you done?"

Expected Behavior

When an ACP (or subagent) session completes, the requester channel should automatically receive a push notification with the result — the same way the runtime="subagent" path works when expectsCompletionMessage: true and the announce pipeline successfully resolves the delivery origin.

Proposed Fix

Option A (minimal): Wire up a completion announce for ACP sessions in acp-spawn.ts, similar to how subagent-registry-runtime.ts triggers runSubagentAnnounceFlow when a subagent run ends.

Option B (explicit hook in sessions_spawn): Add an onComplete parameter to sessions_spawn that lets the calling agent (or system prompt) explicitly declare a delivery target:

sessions_spawn({
  task: "...",
  runtime: "acp",
  onComplete: {
    channel: "discord",
    target: "#general",  // or a session key
    message: "optional override message"
  }
})

This would be stored on the run record and fired by the announce pipeline regardless of runtime type.

Option C (agent-side workaround): Document a reliable pattern for agents to self-schedule a completion check (e.g. a cron job that monitors the ACP session and fires a message when it detects completion). This is fragile and puts the burden on the agent.

Option A is the most conservative fix; Option B gives callers explicit control and works for both runtimes.

Environment

  • OpenClaw v2026.3.2
  • Channel: Discord (ACP thread sessions)
  • Also reproducible with WhatsApp as the requester channel

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions