feat(session): real fan-out — parallel subtasks, background subagents on by default, per-session cap - #145
Merged
Merged
Conversation
filipeforattini
force-pushed
the
feat/goal-fanout
branch
from
September 5, 2026 20:06
d07ce97 to
b2736df
Compare
filipeforattini
force-pushed
the
feat/goal-subagents
branch
from
September 5, 2026 20:06
ab635fa to
1590060
Compare
filipeforattini
force-pushed
the
feat/goal-fanout
branch
from
September 5, 2026 23:41
b2736df to
19dea55
Compare
filipeforattini
force-pushed
the
feat/goal-subagents
branch
2 times, most recently
from
September 5, 2026 23:58
2682b85 to
b203e9b
Compare
filipeforattini
force-pushed
the
feat/goal-fanout
branch
2 times, most recently
from
September 6, 2026 00:38
2a6819c to
5c9fbe5
Compare
filipeforattini
force-pushed
the
feat/goal-subagents
branch
2 times, most recently
from
September 6, 2026 01:08
80691c7 to
e0e42b0
Compare
filipeforattini
force-pushed
the
feat/goal-fanout
branch
from
September 6, 2026 01:08
5c9fbe5 to
edf09c3
Compare
…bagents on by default, capped A user message with several subtask parts ran exactly one of them. handleSubtask writes an assistant message with finish "tool-calls"; on the next iteration that message is the turn's last finished one and MessageV2.latest() drops every part before it — the other subtasks vanished without a trace. The loop now drains the whole pending batch with Effect.forEach at experimental.subtask_concurrency (default 4). Each subtask still gets its own assistant message and tool part, created in submission order, so the transcript keeps that order however the children finish; the "summarize the output above" nudge is written once for the batch. Background subagents come out from behind REDCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS: the goal loop parks on WAIT while one runs and the task tool now caps them, so the guard the experiment stood behind is built in. The cap is per session — experimental.background_subagents_max, default 4 — and past it the tool fails with "wait for one to report, or run this task in the foreground", which is the answer the model needs rather than a silent queue. Foreground tasks are not capped: they are the caller's own turn waiting. Claude-Session: https://claude.ai/code/session_014XwJPDhq1ahcm3rd454WzQ
filipeforattini
force-pushed
the
feat/goal-fanout
branch
from
September 6, 2026 01:25
edf09c3 to
4ffd360
Compare
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.
Increment 3 of the
/goalplan, stacked on #144.What the harness allowed before
SubtaskPartper iteration; the assistant message it wrote became the turn's last finished message, andMessageV2.latest()dropped every part before it — so a message with three subtasks ran the last one and lost the other two.task(background: true)failed unlessREDCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true.SessionRunState.cancelwalksparentSessionIdand cancels owned background jobs.What it allows now
experimental.subtask_concurrencyat a time (default 4). Each keeps its own assistant message and tool part; they are created in submission order so the transcript reads in that order whatever the finish order. One "summarize the output above" nudge per batch.REDCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=falseturns them off. The TUI/app capability flag follows the server, nothing to change there.experimental.background_subagents_max(default 4). Past it the task tool fails with "N already running (limit M). Wait for one to report, or run this task in the foreground." Foreground tasks are not capped./goal-dropand Ctrl+C cancel the fan-out through the existing cascade (covered by the existingcancelling the parent run cancels running background tasksand the recursive-descendants tests).Still missing
Tests
prompt.test.ts: three subtasks on one message are all running at once (three running jobs under the parent), finish in reverse order, and their outputs land as alpha, beta, gamma; the turn makes exactly four provider calls.task.test.ts: the cap refuses the second background subagent with the limit in the message, and a foreground task still runs; the flag-off refusal moved to a layer that turns the flag off.registry.test.ts: the background parameter is exposed by default and hidden when the flag is off.runtime-flags.test.ts: on by default, off with the env set to false.--timeout 30000(what CI runs); redcode and core typecheck clean.https://claude.ai/code/session_014XwJPDhq1ahcm3rd454WzQ
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.