Skip to content

fix: preserve requester route for subagent completion delivery#72806

Merged
steipete merged 2 commits into
openclaw:mainfrom
sfuminya:fix/subagent-completion-routing-requester-origin-main
Apr 27, 2026
Merged

fix: preserve requester route for subagent completion delivery#72806
steipete merged 2 commits into
openclaw:mainfrom
sfuminya:fix/subagent-completion-routing-requester-origin-main

Conversation

@sfuminya

Copy link
Copy Markdown
Contributor

Summary

Fix subagent completion delivery so completion announcements route back to the original requester session/conversation instead of leaking into the child agent's bound external window/account.

Problem

We hit a real Telegram routing bug in cross-agent subagent runs:

  • main/default spawned a subagent targeting another agent (for example novel-agent)
  • the child session correctly rebound to the target agent's own delivery context/window
  • but the later completion announcement sometimes followed that child-bound route
  • result: the completion marker appeared in the project bot window instead of the original main/default chat

This was reproduced in real Telegram live validation, not just tests.

Root cause

There were two routing mistakes that compounded:

  1. In src/agents/subagent-spawn.ts, the registry stored requesterOrigin from the child-side delivery context (childSessionOrigin) instead of preserving the original requester route.

    • That meant completion delivery later reused a target-agent/project-bot account as if it were the requester return path.
  2. In src/agents/subagent-announce-delivery.ts, completion delivery routing resolved bound destinations using params.childSessionKey and allowed non-fail-closed fallback.

    • That let completion delivery prefer the child session's external binding, or a stray single bound destination, instead of the requester/orchestrator session.

Fix

src/agents/subagent-spawn.ts

  • preserve requesterOrigin from the incoming requester context
  • compute childSessionOrigin separately via resolveRequesterOriginForChild(...)
  • keep thread-binding / child agent delivery on childSessionOrigin
  • register subagent runs with the original requesterOrigin
  • merge thread binding delivery back into childSessionOrigin, not requesterOrigin

src/agents/subagent-announce-delivery.ts

  • resolve completion delivery bindings against params.requesterSessionKey
  • set failClosed: true for completion delivery routing

src/agents/subagent-spawn.thread-binding.test.ts

  • update expectations to match the corrected split:
    • child delivery uses the child/target-agent route
    • registry requester origin stays on the original requester route

Validation

Automated

Ran targeted agent tests:

npx vitest --config test/vitest/vitest.agents.config.ts run \
  src/agents/subagent-spawn.thread-binding.test.ts \
  src/agents/subagent-spawn.test.ts

Observed passing results on the final minimal patch.

Live verification

We also validated with real Telegram routing using a novel-agent subagent completion marker flow:

  • spawn subagent from main/default
  • child replies with a unique marker line only
  • observe where the completion marker actually lands in Telegram

The final minimal patch correctly delivered the completion back to the original main/default conversation instead of the Novel bot window.

Why this change is minimal

This PR intentionally keeps only the production fixes plus the single necessary thread-binding expectation update. Extra helper changes and regression-only scaffolding used during investigation were removed before preparing the PR.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS labels Apr 27, 2026
@greptile-apps

greptile-apps Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a Telegram routing bug where subagent completion announcements were incorrectly delivered to the child agent's external window/account instead of the original requester session. Two targeted fixes are made: subagent-spawn.ts now correctly separates requesterOrigin (from the incoming caller context) and childSessionOrigin (resolved for the target agent), and subagent-announce-delivery.ts routes completion-delivery bindings against params.requesterSessionKey with failClosed: true to prevent fallback to the wrong destination.

Confidence Score: 5/5

Safe to merge — minimal, well-targeted fix with a coherent test update confirming the corrected routing split.

All three changed locations are self-consistent: the origin split in spawn, the session-key fix in announce-delivery, and the updated test expectations all align. No regressions introduced, no edge cases left unhandled.

No files require special attention.

Reviews (1): Last reviewed commit: "fix: preserve requester route for subage..." | Re-trigger Greptile

@sfuminya

Copy link
Copy Markdown
Contributor Author

Quick follow-up on the current red CI:

I checked the failing jobs for this PR.

  • checks-node-core is only the aggregate failure.
  • The underlying failing shard is checks-node-core-runtime-infra.
  • The actual failing test there is:
    • src/config/schema.base.generated.test.ts
    • matches the computed base config schema payload

That failure appears to be in generated/base config schema baseline coverage (the diff mentions schema/help entries such as hooks.mappings[].transform.module), which looks unrelated to the routing-only changes in this PR.

This PR intentionally only changes:

  • src/agents/subagent-spawn.ts
  • src/agents/subagent-announce-delivery.ts
  • src/agents/subagent-spawn.thread-binding.test.ts

Local validation I ran for the final minimal patch:

npx vitest --config test/vitest/vitest.agents.config.ts run \
  src/agents/subagent-spawn.thread-binding.test.ts \
  src/agents/subagent-spawn.test.ts

Those targeted agent tests passed locally.

I also did live Telegram validation for the exact bug this PR fixes:

  • spawn a cross-agent subagent from main/default
  • let the child reply with a unique completion marker only
  • verify where the completion actually lands

With the final minimal patch, the completion correctly returned to the original requester conversation instead of the child agent / project-bot window.

So at the moment the PR appears to be blocked by an unrelated schema/generated baseline failure rather than by the subagent routing fix itself.

If maintainers want, I can also split this further or rebase onto a greener mainline once that schema failure is resolved.

@steipete steipete force-pushed the fix/subagent-completion-routing-requester-origin-main branch from 4e9471d to b8fbd24 Compare April 27, 2026 13:11
@steipete steipete merged commit 2c57d70 into openclaw:main Apr 27, 2026
66 of 67 checks passed
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…law#72806)

* fix: preserve requester route for subagent completion delivery

* fix(agents): preserve requester subagent completion routes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…law#72806)

* fix: preserve requester route for subagent completion delivery

* fix(agents): preserve requester subagent completion routes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
globalcaos pushed a commit to globalcaos/tinkerclaw that referenced this pull request May 13, 2026
…law#72806)

* fix: preserve requester route for subagent completion delivery

* fix(agents): preserve requester subagent completion routes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…law#72806)

* fix: preserve requester route for subagent completion delivery

* fix(agents): preserve requester subagent completion routes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
…law#72806)

* fix: preserve requester route for subagent completion delivery

* fix(agents): preserve requester subagent completion routes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
…law#72806)

* fix: preserve requester route for subagent completion delivery

* fix(agents): preserve requester subagent completion routes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants