Skip to content

feat(subagent): continue parents after subagents - #56

Merged
Pepps233 merged 9 commits into
mainfrom
feat/automatic-parent-continuation
Aug 15, 2026
Merged

Pepps233 merged 9 commits into
mainfrom
feat/automatic-parent-continuation

Conversation

@Pepps233

@Pepps233 Pepps233 commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Keep a parent AgentSession active after it delegates work through spawn_agent.

Wait for the frozen child batch, deliver name-sorted results through hidden context, and continue the parent automatically without another user prompt.

Reasoning

Delegation should remain asynchronous for child startup without allowing the enclosing prompt to settle before its coordinated work is usable.

Freezing each batch and tracking per-run delivery gives exactly-once result consumption, deterministic completion behavior, and a clear boundary for cancellation.

Result-free lifecycle notices keep UI and protocol consumers informed without leaking child output into display events or persisted conversation messages.

Changes

  • Added per-run delivery state, frozen-batch waiting, exactly-once result consumption, and manual handling for direct SDK child spawns.
  • Added automatic hidden result delivery and parent continuation after every child in a batch becomes terminal.
  • Added one coordinated corrective retry per failed child per parent prompt cycle, including partial output and final failure delivery.
  • Added deterministic subagent wait and terminal notice events for SDK, JSON, and RPC consumers.
  • Added a cancellable TUI waiting indicator, assistant-styled notices, and Escape handling that restores queued input and interrupts the frozen batch.
  • Added faux-provider and virtual-terminal regressions for ordering, retries, explicit retrieval, cancellation, context isolation, and direct SDK behavior.
  • Updated SDK, usage, and RPC documentation.

Testing

  • node ../../node_modules/vitest/dist/cli.js --run test/suite/subagent-coordination.test.ts test/interactive-mode-subagent-coordination.test.ts
  • ./test.sh
  • npm run check

@Pepps233 Pepps233 changed the title feat(coding-agent): continue parents after subagents feat(subagent): continue parents after subagents Aug 14, 2026
@Pepps233 Pepps233 self-assigned this Aug 14, 2026
@Pepps233
Pepps233 requested a review from Issacboy123 August 14, 2026 07:48
@Pepps233 Pepps233 added the enhancement New feature or request label Aug 14, 2026
@Pepps233
Pepps233 requested review from Issacboy123 and jefft72 and removed request for Issacboy123 and jefft72 August 14, 2026 07:48
@Pepps233

Copy link
Copy Markdown
Contributor Author

367f296 commited by diffex :)

@Pepps233
Pepps233 marked this pull request as ready for review August 14, 2026 17:21
@Pepps233
Pepps233 force-pushed the feat/automatic-parent-continuation branch from 367f296 to 00943cf Compare August 14, 2026 17:23
- Keeps the originating parent prompt active until coordinated child runs terminate
- Delivers each frozen batch once through hidden name-sorted context
- Keeps cancellation visible and restores queued editor input before interrupting frozen children
- Covers result ordering, retry limits, explicit consumption, and SDK-managed runs
- Restricts coordinated retries to children originally spawned by parent tool calls
- Covers failed direct SDK children woken during a parent model turn
- Describes automatic waiting, hidden delivery, retry limits, and cancellation
- Documents safe subagent lifecycle events for SDK and RPC consumers
@Pepps233
Pepps233 force-pushed the feat/automatic-parent-continuation branch from 00943cf to 50bc888 Compare August 15, 2026 16:40

@Issacboy123 Issacboy123 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This PR directionally looks great. The frozen-batch delivery model and the separation lifecycle notices and hidden result context are good. There are just a couple of edge cases for coordination between parent agents and subagents that should be addressed before merging:

  • There is an issue with an abort timing window, where cancellation can happen before the subagent wait controller exists. This would lead to possible post-run handling to start a new uncancelled wait, and the child would be a hanging process.
  • There are also two state-accounting race conditions around consuming a retry attempt and resetting the retry limit for queued user prompts.

return true;
}

const batch = this._subagentController?.freezeUnconsumedBatch();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If abort() runs after the children spawn but before _waitForSubagentBatch() installs its controller, the parent run is aborted but this code can still freeze the batch and create a fresh, un-aborted wait. A child that never settles would then keep both abort() and the original prompt pending. The cancellation state for the full session run should be preserved, then either initialize this wait as already cancelled or interrupt and skip the pending batch when the parent message was aborted. Aregression where abort lands immediately before post-run handling would help cover the timing window.

return Object.freeze({ timedOut, agents: Object.freeze(agents) });
}

#consumeTerminalQueryResults(result: SubagentQueryResult): void {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This can consume a different attempt from the one represented by result. Since agents and agent_action can execute in parallel, agents may snapshot the failed initial attempt while a concurrent wake replaces record.coordinatedRun with the retry. This method would then mark the new retry consumed, so its eventual result would never be automatically delivered. Include the run ID in the query result and verify it here before changing the delivery state, so only the attempt actually returned by agents is consumed. A regression should run agents({ timeout_ms: 0 }) and the retry action in parallel and verify that the retry result is still delivered.

}

preflightResult?.(true);
this._subagentController?.beginCoordinationCycle();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This advances the coordination cycle for a prompt that starts while idle, but a prompt submitted during streaming takes the queue path without advancing it when delivered. If the previous turn exhausted a child's retry, the queued turn remains in the old cycle and another corrective wake is rejected as a second retry. That conflicts with the documented behavior that a later explicit user prompt starts a fresh cycle. Advance the coordination cycle when each queued explicit user turn is delivered, not only when prompt() begins while idle. Add regression coverage for both queued steering and follow-up input after retry exhaustion.

@Pepps233

Copy link
Copy Markdown
Contributor Author

Resolved by Diffex

Issue: "Parent cancellation could occur after child agents spawned but before the subagent wait controller was installed. The cancellation was then lost, allowing a new uncancelled wait to hang the parent and child."
Resolved by commit db72147: Run-level cancellation is now retained and applied when the batch wait is initialized. A regression aborts at the agent_end boundary and verifies that the pending child is interrupted without another provider call.

Issue: "A terminal agents query could snapshot one coordinated attempt while a parallel wake replaced it with a retry. The stale query then consumed the retry, preventing its eventual result from being delivered automatically."
Resolved by commit 032f09c: Query snapshots now carry an internal coordinated run ID and consume only the matching current attempt, while tool output omits that internal metadata. A parallel query-and-retry regression verifies that the retry batch remains available for delivery.

Issue: "Queued steering and follow-up user messages did not start a fresh coordination cycle when delivered. A retry exhausted by the preceding turn therefore blocked the queued user's corrective retry."
Resolved by commit efb3bf7: Coordination cycles now advance on delivered user messages rather than only on idle prompt submission. Regressions verify fresh retry budgets for both queued steering and follow-up input.

@Pepps233
Pepps233 requested a review from Issacboy123 August 15, 2026 21:30

@Issacboy123 Issacboy123 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@Pepps233
Pepps233 merged commit d1e51bb into main Aug 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants