Skip to content

fix: register ACP run-mode spawns in subagent registry for completion announce#40273

Closed
yaseenkadlemakki wants to merge 1 commit into
openclaw:mainfrom
yaseenkadlemakki:fix/acp-completion-announce
Closed

fix: register ACP run-mode spawns in subagent registry for completion announce#40273
yaseenkadlemakki wants to merge 1 commit into
openclaw:mainfrom
yaseenkadlemakki:fix/acp-completion-announce

Conversation

@yaseenkadlemakki

Copy link
Copy Markdown
Contributor

Problem

Closes #40272

When sessions_spawn is called with runtime="acp" and mode="run", the spawned session had no completion notification mechanism. The requester channel (Discord, WhatsApp, etc.) never received a push notification when the task finished — users had to manually ask for status.

Root Cause

spawnAcpDirect() did not register the run in the subagent registry. The registry's onAgentEvent listener already monitors lifecycle:end events and calls runSubagentAnnounceFlow for all registered runs — but ACP runs were never registered, so the pipeline was never invoked.

Fix

A one-liner conceptually: after a successful ACP run-mode dispatch, call registerSubagentRun() with expectsCompletionMessage: true. The existing announce infrastructure does the rest.

// src/agents/acp-spawn.ts
if (spawnMode === "run" && explicitRequesterKey && requesterInternalKey) {
  registerSubagentRun({
    runId: childRunId,
    childSessionKey: sessionKey,
    requesterSessionKey: requesterInternalKey,
    requesterOrigin,
    expectsCompletionMessage: true,
    spawnMode: "run",
    // ...
  });
}

Scope

Case Registered? Reason
runtime="acp", mode="run" ✅ Yes One-shot task, has a natural end
runtime="acp", mode="session" ❌ No Long-lived thread, no natural completion
No agentSessionKey (standalone/CLI) ❌ No No requester to notify

Safety

  • registerSubagentRun() failure is caught and logged — the spawn still returns "accepted"
  • No new code paths in the announce pipeline (reuses existing subagent announce flow)
  • cleanup: "keep" — ACP sessions are not deleted by the registry on completion

Tests

4 new test cases in src/agents/acp-spawn.test.ts:

  1. ✅ run-mode spawn registers with correct fields (runId, channel, label, task, etc.)
  2. ✅ session-mode spawn is not registered
  3. ✅ spawn without agentSessionKey is not registered
  4. ✅ registration failure does not prevent "accepted" result

All 18 existing acp-spawn.test.ts tests continue to pass.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Mar 8, 2026
@greptile-apps

greptile-apps Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a missing completion notification for ACP run-mode spawns by registering them in the subagent registry immediately after a successful gateway dispatch. The existing onAgentEvent / runSubagentAnnounceFlow pipeline already handles registered runs end-to-end, so this is a targeted one-liner fix that plugs the gap without introducing new code paths.

Key changes:

  • src/agents/acp-spawn.ts: After callGateway returns successfully, a guarded block registers the run via registerSubagentRun() with expectsCompletionMessage: true and cleanup: "keep". Registration is gated on spawnMode === "run" (session-mode skipped) and a non-empty agentSessionKey (standalone/CLI skipped). Registration failures are caught and logged without affecting the spawn result.
  • src/agents/acp-spawn.test.ts: Four new test cases cover the positive registration path, the two negative (session-mode and no-requester) paths, and the error-resilience path. The subagent-registry mock is correctly hoisted before the module under test is imported.

Confidence Score: 4/5

  • Safe to merge; the fix is narrowly scoped, best-effort, and fully covered by new tests.
  • The registration logic is correct, the guard conditions match the stated scope, and all three non-registration paths have dedicated test assertions. The only notable issue is a minor style redundancy where the inner requesterOrigin re-declares and re-computes the same value as an outer variable, which is harmless but could cause maintenance confusion if the two computations ever diverge.
  • No files require special attention.

Last reviewed commit: ce778bc

Comment thread src/agents/acp-spawn.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce778bcf8d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/acp-spawn.ts
Comment thread src/agents/acp-spawn.ts
… announce

Closes openclaw#40272

When sessions_spawn is called with runtime="acp" and mode="run",
the spawned session previously had no completion notification mechanism.
The existing subagent announce pipeline (used by runtime="subagent")
was never invoked, so the requester channel (Discord, WhatsApp, etc.)
never received a push notification when the task finished.

Root cause: spawnAcpDirect() did not register the run in the subagent
registry. The registry's onAgentEvent listener monitors lifecycle:end
events and calls runSubagentAnnounceFlow, which delivers the completion
message back to the requester channel.

Fix: After a successful ACP run-mode dispatch, call registerSubagentRun()
with expectsCompletionMessage=true. The existing registry infrastructure
then handles detection and delivery automatically.

Scope:
- Only applied to mode="run" (one-shot) ACP sessions. Session-mode
  (persistent thread-bound) sessions are long-lived with no natural
  completion event to announce.
- Requires an explicit requester session key (ctx.agentSessionKey) to
  avoid affecting standalone / CLI-triggered ACP spawns.
- registerSubagentRun() failure is caught and logged; the spawn still
  returns "accepted".

Tests: 4 new cases in acp-spawn.test.ts
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 25, 2026
@steipete

Copy link
Copy Markdown
Contributor

Closing this as implemented after Codex review.

Close. Current main already implements ACP requester completion delivery through detached task tracking, so this older PR’s registerSubagentRun() approach is obsolete.

What I checked:

  • ACP spawns now create detached task records with requester delivery context: spawnAcpDirect() records ACP runs via createRunningTaskRun(...) with ownerKey, requesterOrigin, childSessionKey, runId, and pending delivery status. That gives current main a completion-delivery mechanism without registering ACP runs as subagent runs. (src/agents/acp-spawn.ts:1315, f00d65a30496)
  • Task registry listens for lifecycle end/error and triggers terminal delivery: task-registry subscribes to agent lifecycle events, marks ACP/background tasks terminal on end or error, and immediately calls maybeDeliverTaskTerminalUpdate(...) for delivery/fallback. (src/tasks/task-registry.ts:1339, f00d65a30496)
  • Terminal delivery sends to requester channel when origin exists: maybeDeliverTaskTerminalUpdate() sends the formatted completion/failure message to the stored requester origin, or queues a session fallback if direct channel delivery is unavailable. (src/tasks/task-registry.ts:1018, f00d65a30496)
  • Current tests explicitly cover ACP completion delivery to requester channel: Main now has a regression test asserting an ACP task completion emits a requester-channel message and marks delivery as delivered. (src/tasks/task-registry.test.ts:539, f00d65a30496)
  • Current main avoids the PR review concerns by not coupling ACP runs to subagent registry semantics: ACP child-cap accounting now combines true subagent registry runs with separately counted untracked ACP task records, avoiding the exact registerSubagentRun() coupling concerns raised in review about archival/max-children behavior. (src/agents/acp-spawn.ts:240, f00d65a30496)

So I’m closing this as already implemented rather than keeping a duplicate issue open.

Review notes: reviewed against f00d65a30496; fix evidence: commit 724692bb8cf5.

@steipete steipete closed this Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

3 participants