Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
|
The description now follows the PR template section for section and the compliance check passes:
One note for maintainers on the remaining |
|
I also am wanting this behavior fixed, so thanks for the PR. Just to confirm: the behavior is such that the subagent will now 'block' when it has pending work, and not return to parent until fully done? |
|
Yes, pretty much, the sub agent returns early, it doesn't wait for subagent background task to complete which cause all sort of issues. |
…running Upstream is fixing, for its own runner, a subagent reported to its parent as completed while background work it started is still pending (anomalyco#49305). That fix rests on machinery this fork does not have, so the question was whether our fan-out has the same gap. It does. The test drives three levels through the real loop: the session fans out to a subagent, which starts a nested `task({ background: true })` and ends its turn while that task hangs. The fan-out reports `nested: COMPLETED` and hands the caller the child's last words, the parent's turn finishes, and the nested job is still running — with its result, when it arrives, injected into the child's session, which nobody reads once the fan-out has answered. It takes an experimental flag, a subagent permitted to spawn one, and `subagent_depth: 2` to reach, which is why it is a characterisation test rather than a fix: it records today's behaviour so a change to it is deliberate and visible. Whoever closes the gap should expect these assertions to change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Gr2KVmmJbKQPntkpbsnP9
The test added in the previous commit found the gap it went looking for: a subagent that starts a task with `background: true` and then ends its turn is reported to its caller as simply completed, while that task keeps running and delivers its answer into the subagent's own session — which nobody reads once the caller has its summary. The caller acts on a result that is missing a piece, with nothing to tell it so. Both spawn paths now name what was left behind, and where its answer will go, so a caller can wait for it, read that session, or decide it does not need it. What they do not do is wait: `background: true` is a request to detach, and honouring it by blocking the caller would make the option meaningless. Upstream takes the other road for its own runner in anomalyco#49305, running a subagent to quiescence before reading its answer; that rests on machinery this fork does not have, and it is a change of meaning rather than of wording, so it wants its own decision. The characterisation test becomes a specification: the fan-out still reports the subtask completed, and now has to say what it left running. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Gr2KVmmJbKQPntkpbsnP9
Issue for this PR
Closes #48826
Type of change
What does this PR do?
A subagent that ends a turn while it still has pending background work (
shellor nestedsubagentwithbackground: true) is reported to its parent ascompletedat that first idle. The subagent job settled as soon assessions.resume(child)returned, so the parent received the child's early reply; when the pending work later woke the child and it produced its real result, nothing delivered it.SubagentCompletion.finalTextruns the child to quiescence before reading its response: while the child still owns pending background notifications that will wake it, it waits for their delivery and resumes again.Job.awaitBackground(notificationID)resolves when the notification is admitted (its durable marker clears). Waiting for job settlement alone races that asynchronous delivery.How did you verify your code works?
cd packages/core && bun test test/job.test.ts test/tool-subagent.test.ts— the new regression test (waits for pending child background work before notifying the parent) fails when run against the un-fixed source (Expected "running", Received "completed") and passes with the fix.Reproduced the original failure on v2: the parent was notified with
SHELL_STARTEDwhile the child's background shell was still running, and the child's laterWOKEN_RESULT_COLLECTEDstayed stranded in the child session.Screenshots / recordings
Not a UI change.
Checklist