workflows/fan-out

Source: src/workflows/fan-out.ts

fanOut: 1 → N. N subtasks in parallel, with bounded concurrency.

aggregate

function

export function aggregate(results: readonly Result[], wallMs: number): Usage { /* … */ }

Sums the usage of several results over a real elapsed duration.

Exported because a caller that fans out by hand needs the same arithmetic - and because the ratio it produces is the number worth reading.

fanOut

function

export async function fanOut(options: FanOutOptions): Promise<FanOutResult> { /* … */ }

Runs N tasks in parallel.

A branch failing is not a workflow failure: it becomes a Result with ok: false in its slot, and the other branches carry on. Set failFast to opt out of that.

There is no shared mutable state between branches, whatever the lifetime. In "workflow" lifetime each branch gets its own persistent subagent: two branches never merge contexts. Working together means passing Results around, not sharing a memory.

FanOutOptions

type

export type FanOutOptions = WorkflowOptions & {
	/** The agent running every branch, unless {@link FanOutOptions.agents} is given. */
	agent?: Agent;
	/** One agent per task, when branches use different agents. */
	agents?: Agent[];
	/** One task per branch. Their order is the order of the results. */
	tasks: string[];
	/** Maximum number of branches in flight. Defaults to 4. */
	concurrency?: number;
	/** Stop at the first failure instead of letting the other branches finish. */
	failFast?: boolean;
};

The branches, who runs them, and how many may run at once.

FanOutResult

type

export type FanOutResult = WorkflowResult & {
	/** One result per task, **in the order of `tasks`** - not of completion. `steps` is this same list. */
	results: Result[];
};

The branches’ results, and the fan-out read as one.

As a Result: output is every branch’s output labelled by its agent, a failed one marked as such; ok is false when any branch failed and error is the first failure’s; agent and messages are that branch’s, or the last branch’s when none failed. usage.busyMs is the sum of the branches and wallMs the real duration: their ratio is the parallelism actually achieved.