Skip to content

fix(subagent): deliver background lane results promptly and in full - #233

Merged
Uking-xxx merged 2 commits into
mainfrom
fix/subagent-lane-no-polling
Oct 10, 2026
Merged

Uking-xxx merged 2 commits into
mainfrom
fix/subagent-lane-no-polling

Conversation

@Uking-xxx

@Uking-xxx Uking-xxx commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Problems

Background subagents (run_in_background: true) had three problems getting results back to the parent agent:

  1. Completions stuck behind progress. With subscribe: "progress", progress notices went into the steering queue, which hands the parent one message per turn. While the parent sat in a long tool call, progress piled up and the lanes' completion notices waited behind it. The parent never learned the lanes were done.
  2. Sleep polling. Told to "wait for the subagents", the parent had no way to know it would be woken, so it waited with sleep loops. Results were handled only after each sleep ended.
  3. Truncated results. The completion notification cut the lane's output at 2,000 characters, and there was no other way to get the rest. Long reports lost their ending, and the parent resorted to parsing the child's session files.

Changes

  1. Progress and restart notices are sent with triggerTurn: false, so they land as context at the turn boundary and stay out of the steering queue. Completion, failure, interrupt, and needs-input notices still wake the parent.
  2. When a lane starts, the tool result tells the parent not to wait with sleep or polling: end the turn or keep working, since it will be woken when the lane finishes, fails, or needs input. The subscribe description says the same, except for "none".
  3. The completion notification carries up to 50,000 characters of output, the same per-task limit a blocking call returns.
  4. The background lane list is ordered by lane creation, as intended in fix(subagent): stop background lanes from flickering and flooding the transcript #229. The previous ordering also made a fix(subagent): stop background lanes from flickering and flooding the transcript #229 test flaky.

Testing

  • New session-level regression test: progress notices plus a completion arriving during a long tool call all reach the next model call. On main, the completion is missing.
  • New test: a long lane report reaches the parent in full.
  • Subagent and session suite tests pass; pnpm run check passes.
  • Manual runs from source: the parent no longer sleep-polls, completions arrive promptly even if the parent is sleeping, and a ~5k-character report arrived intact with its final summary.

Not addressed

Progress notices that accumulate while the parent is idle still all enter its context on the next turn. Coalescing them needs a session-layer change.

xuyunfang added 2 commits October 10, 2026 12:38
Session 01a123da: four progress-subscribed lanes all finished by 03:37,
yet the parent kept running `sleep 180` until past 04:04, convinced the
lanes were still going.

Progress notices were steered. The steering queue drains one message per
turn by default ("one-at-a-time"), and progress arrives every 15s per
lane, so a minutes-long tool call let dozens queue up. The parent read
one stale progress notice per turn, and the lanes' completion notices
sat behind that backlog. Each steered notice also forced one more model
call after the parent meant to stop, which kept the sleep loop going.

- Send progress and restart notices with triggerTurn: false. They land
  as context at the same turn boundary a steer would use, all at once,
  without entering the steering queue or forcing an extra model call.
  Completion, failure, interrupt, and needs-input keep steer +
  triggerTurn.
- Tell the parent, when a lane starts, not to wait with sleep or
  polling: end the turn or carry on, since it is woken when the lane
  finishes, fails, or needs input. The subscribe description says the
  same, except for "none".
- Order the background lane list by creation rather than by which lane
  streamed first, as its comment already claimed.
…ification

The final notification capped the lane output at 2,000 characters. It is
the parent's only copy of the result, since agent_send can reply or stop
but not fetch, so a longer report lost its ending (usually the summary)
and the parent fell back to parsing the child's session file. Raise the
cap to 50,000 characters, the per-task limit a blocking call returns.
@Uking-xxx Uking-xxx changed the title fix(subagent): deliver lane completions promptly while the parent sleeps fix(subagent): deliver background lane results promptly and in full Oct 10, 2026
@Uking-xxx
Uking-xxx merged commit f739208 into main Oct 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant