Skip to content

Subagents: restore announce chain + fix nested retry/drop regressions#22223

Merged
tyler6204 merged 2 commits intomainfrom
fix/cron-subagent-regressions
Feb 20, 2026
Merged

Subagents: restore announce chain + fix nested retry/drop regressions#22223
tyler6204 merged 2 commits intomainfrom
fix/cron-subagent-regressions

Conversation

@tyler6204
Copy link
Member

@tyler6204 tyler6204 commented Feb 20, 2026

Summary

This PR restores subagent orchestration behavior to the pre-regression model and fixes the remaining nested announce delivery issue observed in live depth tests.

1) Restore subagent announce to agent-only path

  • Reverts the direct send completion delivery pattern.
  • Keeps completion delivery on the agent path only (system-message injection into requester session).
  • Removes direct-channel completion framing behavior so parent LLM always owns user-facing voice.

2) Fix nested/sub-subagent announce completion timing

  • Defers announce when a finished run still has active descendants.
  • Detects placeholder parent replies like "waiting for nested result" and waits for the parent's follow-up synthesized reply.
  • Prevents announcing stale placeholder text.

3) Fix announce drop under deep nesting

Live failures showed top-level runs hitting retry limit before descendants finished, dropping final announces.

  • In finalizeSubagentCleanup, deferrals caused by active descendants no longer consume retry budget.
  • Retry budget is still enforced for real repeated failures; expiry guard is preserved.

4) Cron isolated session behavior

  • Restores fresh-session-per-run behavior for isolated cron/webhook runs.
  • Keeps valid override-preservation behavior while rolling session IDs.

5) Default max spawn depth

  • Introduces shared default DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH = 2.
  • Wires all depth checks/prompt policy fallbacks to the shared default.
  • Updates config defaults and tests/docs accordingly.

Validation

  • pnpm exec vitest run src/cron/isolated-agent/session.test.ts src/config/config.agent-concurrency-defaults.test.ts src/config/config.identity-defaults.test.ts src/agents/openclaw-tools.subagents.sessions-spawn-depth-limits.test.ts src/agents/subagent-registry.announce-loop-guard.test.ts src/agents/subagent-registry.nested.test.ts
  • pnpm exec vitest run --config vitest.e2e.config.ts src/agents/system-prompt.e2e.test.ts src/agents/subagent-announce.format.e2e.test.ts src/agents/openclaw-tools.subagents.sessions-spawn.lifecycle.e2e.test.ts src/agents/pi-tools.policy.e2e.test.ts src/agents/subagent-registry.persistence.e2e.test.ts

Notes

  • Addresses the reported cases where depth-3 chains completed internally but final announces were missing at the top-level requester session.

Greptile Summary

This PR restores subagent orchestration to a reliable announce-chain model and fixes nested completion delivery regressions observed in deep nesting scenarios.

Key Changes:

  • Restored subagent completions to agent-only delivery path (system message injection) instead of direct send calls, ensuring parent LLM owns user-facing voice
  • Fixed nested announce timing by detecting active descendants and deferring announce until descendant runs complete and parent synthesizes final reply
  • Fixed announce drop regression under deep nesting by separating normal deferrals (active descendants) from retry budget consumption, preventing premature give-up before descendants finish
  • Introduced shared DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH = 2 constant wired through all depth checks and policy fallbacks for consistency
  • Restored cron isolated session behavior to always create fresh session per run while preserving per-session override settings
  • Added placeholder detection logic (isLikelyWaitingForDescendantResult) to defer announcing stale intermediate replies and wait for synthesized follow-ups

Architecture:

The PR addresses a critical timing issue where top-level runs would exhaust retry limits before descendants finished, causing final announces to be dropped. The fix introduces descendant-aware deferral logic in finalizeSubagentCleanup that doesn't consume retry budget when waiting for active descendants, while still enforcing limits for actual repeated failures.

Confidence Score: 4/5

  • This PR is safe to merge with low risk given comprehensive test coverage and targeted fixes
  • Score reflects well-structured logic changes with clear intent, comprehensive test updates, and no obvious security concerns. The PR addresses real production issues with depth-3 chains. Deducted one point because the retry/deferral logic in finalizeSubagentCleanup is complex with multiple conditional paths that could benefit from additional integration testing under high-concurrency scenarios.
  • Pay close attention to src/agents/subagent-registry.ts lines 324-377 (finalizeSubagentCleanup retry logic) and src/agents/subagent-announce.ts lines 518-564 (descendant detection and placeholder handling)

Last reviewed commit: 241b86e

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: XL maintainer Maintainer-authored PR labels Feb 20, 2026
@tyler6204 tyler6204 self-assigned this Feb 20, 2026
Copy link

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

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: 241b86e8cd

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +677 to +679
if (!requesterIsSubagent && !directOrigin) {
const { entry } = loadRequesterSessionEntry(targetRequesterSessionKey);
directOrigin = resolveAnnounceOrigin(entry, targetRequesterOrigin);
directOrigin = deliveryContextFromSession(entry);

Choose a reason for hiding this comment

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

P1 Badge Merge direct announce origin with stored delivery context

This branch now uses targetRequesterOrigin as-is whenever it is present, so if a run was spawned from a non-deliverable/internal channel hint (for example webchat) the direct announce call keeps that channel and never falls back to the persisted lastChannel/lastTo route. In that case agent delivery is forced to non-delivery and the completion update is not sent to the user even though the requester session has a valid outbound target; this used to be avoided by always resolving origin against the session entry.

Useful? React with 👍 / 👎.

// actually on and must take priority over the session entry, which may carry
// stale lastChannel / lastTo values from a previous channel interaction.
return mergeDeliveryContext(normalizedRequester, normalizedEntry);
return mergeDeliveryContext(requesterOrigin, deliveryContextFromSession(entry));

Choose a reason for hiding this comment

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

P1 Badge Ignore internal channel hints when resolving queued announce origin

resolveAnnounceOrigin now directly prioritizes requesterOrigin without filtering non-deliverable channels, so a queued announce can inherit webchat/internal channel hints and overwrite a valid persisted delivery route from the requester session. When that queued item is sent, the gateway treats the channel as internal and does not deliver outward, causing queued subagent completions to be dropped while the requester run is active.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle bot added the docs Improvements or additions to documentation label Feb 20, 2026
@tyler6204 tyler6204 merged commit fe57bea into main Feb 20, 2026
22 of 25 checks passed
@tyler6204 tyler6204 deleted the fix/cron-subagent-regressions branch February 20, 2026 23:39
@tyler6204
Copy link
Member Author

Merged via squash.

Kansodata pushed a commit to Kansodata/openclaw that referenced this pull request Feb 21, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)
Hansen1018 added a commit to Hansen1018/openclaw that referenced this pull request Feb 21, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)
vincentkoc pushed a commit that referenced this pull request Feb 21, 2026
…#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (#22223) (thanks @tyler6204)
dgarson pushed a commit to dgarson/clawdbot that referenced this pull request Feb 21, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)
mmyyfirstb pushed a commit to mmyyfirstb/openclaw that referenced this pull request Feb 21, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)
mcinteerj pushed a commit to mcinteerj/openclaw that referenced this pull request Feb 21, 2026
…2223

Commit f555835 ("Channels: add thread-aware model overrides") inadvertently
reverted the `resolveAnnounceOrigin` channel guard introduced in fe57bea
(openclaw#22223). The revert changed `isInternalMessageChannel` back to
`!isDeliverableMessageChannel`, which strips non-standard channel hints
(anything not in the built-in deliverable list) from the requester origin.

When the stripped origin falls back to the session entry's persisted
`lastChannel`/`lastTo`, stale values from a previous interaction (e.g.
WhatsApp with no valid E.164 target) cause delivery failures:

    Error: Delivering to WhatsApp requires target <E.164|group JID>
    [warn] Subagent announce give up (retry-limit)

The fix narrows the guard back to `isInternalMessageChannel` so only the
webchat channel is stripped — matching the intent of openclaw#22223.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mcinteerj pushed a commit to mcinteerj/openclaw that referenced this pull request Feb 21, 2026
Two issues caused subagent completion announces to silently fail for
plugin channels like Gmail:

1. `resolveAnnounceOrigin` used `!isDeliverableMessageChannel()` to
   strip non-standard channels, inadvertently reverting the narrower
   `isInternalMessageChannel()` guard from openclaw#22223 (fe57bea). Restored
   the original guard so only webchat is stripped.

2. `sendSubagentAnnounceDirectly` and `sendAnnounce` passed the origin
   channel/to verbatim to `callGateway()`, even when the channel was
   not in the deliverable list. Plugin channels whose adapter ID differs
   from their registered plugin ID (e.g. "gmail" vs "openclaw-gmail")
   were unroutable, causing the gateway to time out (15s x 3 retries)
   and then fall back to stale session routes (typically WhatsApp with
   no valid E.164 target).

   Fix: check `isDeliverableMessageChannel()` before passing channel
   hints. When the channel is unroutable, omit channel/to/accountId so
   the gateway resolves delivery from connected clients or session state.

Symptoms observed:
  Subagent completion direct announce failed: gateway timeout after 15000ms
  [warn] Subagent announce give up (retry-limit) retries=3
  Error: Delivering to WhatsApp requires target <E.164|group JID>

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mcinteerj pushed a commit to mcinteerj/openclaw that referenced this pull request Feb 22, 2026
Two issues caused subagent completion announces to silently fail for
plugin channels like Gmail:

1. `resolveAnnounceOrigin` used `!isDeliverableMessageChannel()` to
   strip non-standard channels, inadvertently reverting the narrower
   `isInternalMessageChannel()` guard from openclaw#22223 (fe57bea). Restored
   the original guard so only webchat is stripped.

2. `sendSubagentAnnounceDirectly` and `sendAnnounce` passed the origin
   channel/to verbatim to `callGateway()`, even when the channel was
   not in the deliverable list. Plugin channels whose adapter ID differs
   from their registered plugin ID (e.g. "gmail" vs "openclaw-gmail")
   were unroutable, causing the gateway to time out (15s x 3 retries)
   and then fall back to stale session routes (typically WhatsApp with
   no valid E.164 target).

   Fix: check `isDeliverableMessageChannel()` before passing channel
   hints. When the channel is unroutable, omit channel/to/accountId so
   the gateway resolves delivery from connected clients or session state.

Symptoms observed:
  Subagent completion direct announce failed: gateway timeout after 15000ms
  [warn] Subagent announce give up (retry-limit) retries=3
  Error: Delivering to WhatsApp requires target <E.164|group JID>

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mcinteerj pushed a commit to mcinteerj/openclaw that referenced this pull request Feb 22, 2026
Two issues caused subagent completion announces to silently fail for
plugin channels like Gmail:

1. `resolveAnnounceOrigin` used `!isDeliverableMessageChannel()` to
   strip non-standard channels, inadvertently reverting the narrower
   `isInternalMessageChannel()` guard from openclaw#22223 (fe57bea). Restored
   the original guard so only webchat is stripped.

2. `sendSubagentAnnounceDirectly` and `sendAnnounce` passed the origin
   channel/to verbatim to `callGateway()`, even when the channel was
   not in the deliverable list. Plugin channels whose adapter ID differs
   from their registered plugin ID (e.g. "gmail" vs "openclaw-gmail")
   were unroutable, causing the gateway to time out (15s x 3 retries)
   and then fall back to stale session routes (typically WhatsApp with
   no valid E.164 target).

   Fix: check `isDeliverableMessageChannel()` before passing channel
   hints. When the channel is unroutable, omit channel/to/accountId so
   the gateway resolves delivery from connected clients or session state.

Symptoms observed:
  Subagent completion direct announce failed: gateway timeout after 15000ms
  [warn] Subagent announce give up (retry-limit) retries=3
  Error: Delivering to WhatsApp requires target <E.164|group JID>

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mcinteerj pushed a commit to mcinteerj/openclaw that referenced this pull request Feb 22, 2026
Two issues caused subagent completion announces to silently fail for
plugin channels like Gmail:

1. `resolveAnnounceOrigin` used `!isDeliverableMessageChannel()` to
   strip non-standard channels, inadvertently reverting the narrower
   `isInternalMessageChannel()` guard from openclaw#22223 (fe57bea). Restored
   the original guard so only webchat is stripped.

2. `sendSubagentAnnounceDirectly` and `sendAnnounce` passed the origin
   channel/to verbatim to `callGateway()`, even when the channel was
   not in the deliverable list. Plugin channels whose adapter ID differs
   from their registered plugin ID (e.g. "gmail" vs "openclaw-gmail")
   were unroutable, causing the gateway to time out (15s x 3 retries)
   and then fall back to stale session routes (typically WhatsApp with
   no valid E.164 target).

   Fix: check `isDeliverableMessageChannel()` before passing channel
   hints. When the channel is unroutable, omit channel/to/accountId so
   the gateway resolves delivery from connected clients or session state.

Symptoms observed:
  Subagent completion direct announce failed: gateway timeout after 15000ms
  [warn] Subagent announce give up (retry-limit) retries=3
  Error: Delivering to WhatsApp requires target <E.164|group JID>

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mcinteerj pushed a commit to mcinteerj/openclaw that referenced this pull request Feb 22, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
obviyus pushed a commit to guirguispierre/openclaw that referenced this pull request Feb 22, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)
mreedr pushed a commit to mreedr/openclaw-custom that referenced this pull request Feb 24, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)
steipete pushed a commit that referenced this pull request Feb 24, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR #22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: #22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
steipete pushed a commit that referenced this pull request Feb 24, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR #22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: #22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Prithvirajbilla pushed a commit to Prithvirajbilla/openclaw that referenced this pull request Feb 24, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
plgs2005 pushed a commit to plgs2005/openclaw that referenced this pull request Feb 24, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
margulans pushed a commit to margulans/Neiron-AI-assistant that referenced this pull request Feb 25, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
brianleach pushed a commit to brianleach/openclaw that referenced this pull request Feb 26, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
mylukin pushed a commit to mylukin/openclaw that referenced this pull request Feb 26, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 1, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)

(cherry picked from commit fe57bea)

# Conflicts:
#	CHANGELOG.md
#	docs/concepts/session-tool.md
#	docs/tools/subagents.md
#	src/agents/openclaw-tools.subagents.sessions-spawn-depth-limits.test.ts
#	src/agents/openclaw-tools.subagents.sessions-spawn.lifecycle.e2e.test.ts
#	src/agents/pi-tools.policy.ts
#	src/agents/subagent-announce.format.e2e.test.ts
#	src/agents/subagent-announce.ts
#	src/agents/subagent-registry.announce-loop-guard.test.ts
#	src/agents/subagent-registry.ts
#	src/agents/system-prompt.test.ts
#	src/agents/tools/subagents-tool.ts
#	src/config/config.identity-defaults.test.ts
#	src/config/types.agent-defaults.ts
#	src/config/zod-schema.agent-defaults.ts
#	src/cron/isolated-agent/session.test.ts
#	src/cron/isolated-agent/session.ts
hughdidit pushed a commit to hughdidit/DAISy-Agency that referenced this pull request Mar 3, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)

(cherry picked from commit fe57bea)

# Conflicts:
#	CHANGELOG.md
#	docs/concepts/session-tool.md
#	docs/tools/subagents.md
#	src/agents/openclaw-tools.subagents.sessions-spawn-depth-limits.test.ts
#	src/agents/openclaw-tools.subagents.sessions-spawn.lifecycle.e2e.test.ts
#	src/agents/pi-tools.policy.ts
#	src/agents/subagent-announce.ts
#	src/agents/subagent-registry.announce-loop-guard.test.ts
#	src/agents/subagent-registry.ts
#	src/agents/system-prompt.test.ts
#	src/agents/tools/subagents-tool.ts
#	src/config/config.identity-defaults.test.ts
#	src/config/defaults.ts
#	src/config/types.agent-defaults.ts
#	src/config/zod-schema.agent-defaults.ts
#	src/cron/isolated-agent/session.test.ts
#	src/cron/isolated-agent/session.ts
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…openclaw#22223)

* Subagents: restore announce flow and fix nested delivery retries

* fix: prep subagent announce + docs alignment (openclaw#22223) (thanks @tyler6204)
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…unceOrigin

Restores the narrower internal-channel guard from PR openclaw#22223 (fe57bea) that was
inadvertently reverted by f555835.

The original !isDeliverableMessageChannel() check strips the requester's channel
whenever it is not in the registered deliverable set. This causes delivery
failures for plugin channels whose adapter ID differs from their plugin ID (e.g.
"gmail" vs "openclaw-gmail"): the requester origin is discarded and the announce
falls back to stale session routes — typically WhatsApp — resulting in a timeout
followed by an E.164 format error.

Replacing with isInternalMessageChannel() limits stripping to explicitly internal
channels (webchat), preserving the requester origin for all external channels
regardless of whether they are currently in the deliverable list.

Fixes: openclaw#22223 regression introduced in f555835
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling docs Improvements or additions to documentation maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant