Summary
Subagent completion announcements are silently dropped when the parent session has an active but non-consuming embedded Pi run (between turns, idle). The user only sees the result after sending another message that re-triggers the session.
This is a reopen of #75663. The original fix attempt (#75669) was closed because upstream has restructured the subagent completion delivery infrastructure — the agent-mediated completion path was removed and replaced with a sendMessage-based fallback system.
Root Cause (Current Upstream)
In sendSubagentAnnounceDirectly (src/agents/subagent-announce-delivery.ts), when requesterActivity.isActive is true but the embedded Pi run is not consuming messages:
queueEmbeddedPiMessage returns false (run not streaming)
- The code enters the
if (requesterActivity.isActive) block
- The function returns
{ delivered: false } as a dead-end — preventing fallthrough to the callGateway("agent", { expectFinal: true }) path that would start a new run and deliver the message
Proposed Fix
Replace the early-return dead-end with a sendMessage-based fallback attempt, then fall through to the gateway call if the fallback fails. This requires:
- Adding
sendMessage to imports from subagent-announce-delivery.runtime.js
- Adding
sendMessage to SubagentAnnounceDeliveryDeps type and defaults
- Adding
extractThreadCompletionFallbackText, sendCompletionFallback, resolveCompletionFallbackPath helper functions
- Replacing the early return at
if (requesterActivity.isActive) with fallback-then-fallthrough logic
- Updating tests to mock
sendMessage via deps
Environment
- Channel: Telegram (push-based, most affected)
- Less affected: WebChat (polling picks up queued messages)
- Upstream version: v2026.5.7-beta.1
Related
Summary
Subagent completion announcements are silently dropped when the parent session has an active but non-consuming embedded Pi run (between turns, idle). The user only sees the result after sending another message that re-triggers the session.
This is a reopen of #75663. The original fix attempt (#75669) was closed because upstream has restructured the subagent completion delivery infrastructure — the agent-mediated completion path was removed and replaced with a
sendMessage-based fallback system.Root Cause (Current Upstream)
In
sendSubagentAnnounceDirectly(src/agents/subagent-announce-delivery.ts), whenrequesterActivity.isActiveis true but the embedded Pi run is not consuming messages:queueEmbeddedPiMessagereturnsfalse(run not streaming)if (requesterActivity.isActive)block{ delivered: false }as a dead-end — preventing fallthrough to thecallGateway("agent", { expectFinal: true })path that would start a new run and deliver the messageProposed Fix
Replace the early-return dead-end with a
sendMessage-based fallback attempt, then fall through to the gateway call if the fallback fails. This requires:sendMessageto imports fromsubagent-announce-delivery.runtime.jssendMessagetoSubagentAnnounceDeliveryDepstype and defaultsextractThreadCompletionFallbackText,sendCompletionFallback,resolveCompletionFallbackPathhelper functionsif (requesterActivity.isActive)with fallback-then-fallthrough logicsendMessagevia depsEnvironment
Related