-
-
Notifications
You must be signed in to change notification settings - Fork 53k
Description
GitHub Issue
[Bug]: Subagent completion announce bypasses main LLM since v2026.2.19 (send path regression)
Summary
After upgrading from v2026.2.17 to v2026.2.19, subagent completion announcements from sessions_spawn are delivered directly to the channel via method: "send" instead of being routed through the main session's LLM via method: "agent". This causes raw ✅ Subagent X finished messages to appear in the channel, and the main agent never processes or responds to the completion.
Steps to reproduce
- Configure a multi-agent setup with at least one subagent (e.g.,
reviewer) inopenclaw.json. - From a Discord (or other messaging) channel session, use
sessions_spawnto spawn a subagent task:sessions_spawn(agentId="reviewer", task="Review this text: 'hello world'. Score 1-10.", label="test-review") - Wait for the subagent to complete (~5-30s).
- Observe the announce delivery in the channel and main session transcript.
Expected behavior
The main session's LLM receives the subagent result as a [System Message] (user role), processes it, and responds in its own voice with a natural summary. This is the behavior observed in v2026.2.17.
Main session transcript entry (v2026.2.17, working):
{
"role": "user",
"content": "[System Message] [sessionId: ...] A subagent task \"test-review\" just completed successfully.\n\nResult: ...\n\nA completed subagent task is ready for user delivery. Convert the result above into your normal assistant voice..."
}The main LLM is triggered by this user-role message and responds naturally.
Actual behavior
The completion message is posted directly to the channel as a raw ✅ Subagent X finished message via method: "send". The main session transcript records it as an assistant message with model: "delivery-mirror", and the main LLM is never invoked.
Main session transcript entry (v2026.2.19, broken):
{
"role": "assistant",
"model": "delivery-mirror",
"provider": "openclaw",
"content": [{"type": "text", "text": "✅ Subagent main finished\n\n..."}]
}No main LLM trigger occurs. Raw text appears in the channel.
Note: Cron job announcements are not affected — they continue to use the agent path correctly, because cron does not pass expectsCompletionMessage (defaults to false).
Version
v2026.2.19 (regression from v2026.2.17)
Operating system
Ubuntu 24.04 (WSL2) / Linux 6.6.87.2-microsoft-standard-WSL2
Install method
npm global (Node.js v22.22.0, npm v10.9.2)
Logs, screenshots, and evidence
Verification via downgrade
Downgraded to v2026.2.17 via npm install -g openclaw@2026.2.17 and spawned an identical reviewer subagent. The announce was delivered via agent path — the main LLM received a [System Message] (user role), was triggered, and responded in its own voice. Upgrading back to v2026.2.19 reproduces the send path behavior.
Gateway log comparison
v2026.2.17 (working — main LLM triggered, no send):
2026-02-20T18:04:33.843Z [ws] ⇄ res ✓ agent.wait 4598ms conn=44510f06…5542 id=55d8ae47…2260
v2026.2.19 (broken — send bypasses main LLM):
2026-02-20T17:06:27.850Z [ws] ⇄ res ✓ agent.wait 111243ms conn=31201895…34fc id=39da93d3…a335
2026-02-21T02:06:28.413Z [ws] ⇄ res ✓ send 518ms channel=discord conn=85f68926…a776 id=bc31cf90…b829
Note the send call after agent.wait in v2026.2.19, which directly posts to the channel without triggering the main LLM.
Root cause: introducing commit
Commit: 289f215b3 — fix(agents): make manual subagent completion announce deterministic
Date: 2026-02-18
Files changed: src/agents/subagent-announce.ts (+95/-32), src/agents/subagent-announce.format.e2e.test.ts (+84)
Subsequent related commits in the same release:
e8816c554—Agents: fix subagent completion delivery to origin channel0bf1b38cc—Agents: fix subagent completion thread routing
Source code analysis
v2026.2.17 sendSubagentAnnounceDirectly() in src/agents/subagent-announce.ts:
- Only has
method: "agent"path withdeliver: true - Main LLM is always triggered for announce delivery
- No
completionMessage,completionDirectOrigin, orhasCompletionDirectTargetparameters
v2026.2.19 sendSubagentAnnounceDirectly():
- New
sendpath added by commit289f215b3:if (params.expectsCompletionMessage && hasCompletionDirectTarget && params.completionMessage?.trim()) { await callGateway({ method: "send", params: { channel, to, message: completionMessage, ... } }); // Direct channel post — no LLM trigger }
hasCompletionDirectTargetistruewhenever the requester session has a known channel + to (always true for Discord/Telegram/etc. channel sessions)expectsCompletionMessageis hardcoded totrueinsessions_spawn(both versions — this was not changed)- New
completionMessageuses a simple✅ Subagent X finishedformat (via newbuildCompletionDeliveryMessage()) - The original
agentpath still exists as a fallback but is never reached for channel sessions becausehasCompletionDirectTargetis alwaystrue
Why cron is unaffected
Cron jobs call runSubagentAnnounceFlow without expectsCompletionMessage, so it defaults to false. The send path condition (params.expectsCompletionMessage && ...) is never met, and cron always falls through to the agent path.
Impact and severity
- Affected: All users who spawn subagents via
sessions_spawnfrom channel sessions (Discord, Telegram, Slack, etc.) - Severity: High — breaks the primary subagent orchestration workflow. The main agent can no longer process, summarize, or act on subagent results.
- Frequency: 100% reproducible on v2026.2.19; confirmed working on v2026.2.17 via downgrade.
- Consequence:
- Raw, unprocessed completion messages appear in user channels
- Main agent cannot chain subagent results (e.g., planner → reviewer → worker pipeline)
- Main agent loses context about subagent completions (recorded as
assistant/delivery-mirror, not triggering LLM) - Users must manually ask the main agent to check results
Additional information
- Related issues: Subagent announce leaks internal prompt and stats to user chat #6669 (announce leak), Sub-agent announce fails with gateway timeout when parent session is active #7666 (announce timeout, fixed by fix: context overflow compaction and subagent announce improvements #11664), Feature: per-channel announce suppression for sub-agents #13911 (per-channel announce suppression request), fix(agents): Add retry with exponential backoff for subagent announce delivery #20328 (announce retry, open)
- The
sendpath was likely introduced to improve announce delivery reliability by avoiding gateway timeouts fromagentcalls (Sub-agent announce fails with gateway timeout when parent session is active #7666). However, it removes the ability for the main LLM to process results — a critical capability for multi-agent orchestration workflows. - Possible fixes:
- (a) Make
sendpath opt-in via config (e.g.,agents.defaults.subagents.announceMode: "agent" | "send") - (b) [Recommended] Follow up the
senddelivery with anagentcall to inject the result into the main session and trigger LLM processing — combines reliability ofsend(user sees result immediately) with theagentpath's LLM processing - (c) Add a per-agent or per-spawn option to control announce delivery path
- (a) Make
- There is currently no user-facing configuration to control which path is used.
- Workaround: Downgrade to v2026.2.17. No configuration-level workaround exists on v2026.2.19.