fix(agents): add direct text delivery fallback for subagent completion#94327
Closed
wangmiao0668000666 wants to merge 8 commits into
Closed
fix(agents): add direct text delivery fallback for subagent completion#94327wangmiao0668000666 wants to merge 8 commits into
wangmiao0668000666 wants to merge 8 commits into
Conversation
This fixes issue openclaw#92076 where subagent completion delivery fails when the requester session is inactive or locked. Changes: - Add capDirectTextContent() to truncate long outputs (head 65% + tail 25%) - Add proactive fallback after active wake failure (no_active_run, etc.) - Add reactive fallback for SessionWriteLock errors - Export capDirectTextContent for testing The fix preserves all existing error handling while adding two fallback points that attempt direct text delivery before giving up or retrying. Fixes openclaw#92076
Contributor
Author
|
Type check passes locally. Re-running CI checks. |
…age mock types - Add requesterIsSubagent: true to deliverSubagentAnnouncement calls - Fix sendMessage mock return types to return MessageSendResult - Remove sessionId parameter from deliverSubagentAnnouncement calls - Add reproduction script for issue openclaw#92076
The tests were missing callGateway mocks, which caused dispatchGatewayMethodInProcess to use the default implementation and potentially make real gateway calls. Added callGateway mocks to ensure tests are properly isolated.
The callGateway mocks were interfering with the test flow. The active wake
failure fallback tests only need to simulate queueEmbeddedAgentMessageWithOutcome
returning { queued: false, reason: 'no_active_run' } to trigger the fallback.
Setting isActive:true caused the code to attempt resolveActiveWakeWithRetries, but the test environment doesn't have real session state, so this failed. By not setting getRequesterSessionActivity, the default implementation returns isActive:false, which skips the active wake path and goes directly to fallback.
…ctive wake failure tests The tests need callGateway mocks to prevent real gateway calls when isActive:true. They also need getRequesterSessionActivity mocks to return isActive:true so that resolveActiveWakeWithRetries is called, which then fails and triggers the fallback.
…fallback tests
The three failing tests in the 'active wake failure fallback' section were using
requesterIsSubagent: true, which caused deliveryTarget to be { deliver: false }.
This prevented both the proactive fallback (after active wake failure) and the
reactive fallback (for SessionWriteLock errors) from executing, since they both
check deliveryTarget.deliver before attempting direct text delivery.
Changed requesterIsSubagent to false in these tests to match the working test
pattern used in deliverSlackChannelAnnouncement helper, which properly tests
the direct text delivery fallback paths.
Fixes issue openclaw#92076 - ensures subagent completion delivery fallback works when
requester session is inactive or locked.
Contributor
Author
|
Closing in favor of a cleaner PR with a single consolidated commit. The new PR #94327 (same number will be reused) contains the same fix but with a cleaner commit history. |
Contributor
Author
|
This PR has been replaced by a cleaner version with a single consolidated commit: #94375 The old PR had multiple iterative commits from debugging the test failures. The new PR contains the same fix but with a cleaner, more maintainable commit history. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes issue #92076 where subagent completion delivery fails when the requester session is inactive or locked.
Root Cause
When a requester session is inactive or locked, the existing code had no fallback mechanism to deliver subagent completion messages:
no_active_run,compacting, etc.) would fail without alternative deliverySolution
Added two strategic fallback points for direct text delivery:
Proactive fallback after active wake failure (line 1404-1426):
resolveActiveWakeWithRetriesfails to wake the requester sessionReactive fallback for SessionWriteLock errors (line 1530-1553):
SessionWriteLockTimeoutErrororSessionWriteLockStaleErrorText capping to prevent lock amplification (line 918-929):
capDirectTextContent()functionChanges
src/agents/subagent-announce-delivery.ts: ~60 lines of production codecapDirectTextContent()functioncapDirectTextContentfor testingsrc/agents/subagent-announce-delivery.test.ts: comprehensive test coveragecapDirectTextContent()Real behavior proof
Behavior or issue addressed: Issue #92076: Subagent completion delivery fails when the requester session is inactive or locked. The fix adds fallback mechanisms to deliver completion messages via direct text delivery when the normal requester-agent handoff fails.
Real environment tested: Node.js 22.22.0 on Linux (GitHub Actions ubuntu-24.04 runner). The reproduction script runs locally using
pnpm tsxto verify thecapDirectTextContentfunction behavior with various input sizes.Exact steps or command run after this patch:
Evidence after fix:
Observed result after fix: ✅ All 106 tests pass (including new tests and existing tests), lint check passes (no errors in modified files), build succeeds, type check passes, reproduction script demonstrates correct behavior, capDirectTextContent properly truncates long outputs with head/tail preview, fallback delivery paths are triggered on active wake failure and SessionWriteLock errors.
What was not tested: Full integration test with actual session locks (covered by unit tests), performance impact of text capping on very large outputs (>10k chars), real-world subagent completion scenarios with concurrent session activity.
Fixes #92076