import { readCapacitySnapshot, type FanoutConcurrency } from "./capacity.js"; import type { JsonValue, WorkflowCallNode, WorkflowIteration, WorkflowNodeOutput } from "./model.js"; import type { WorkflowChildRunSummary, WorkflowRunDetail } from "./runtime.js"; /** * What a Workflow Call node resolves to before the runner acts on it. * * The node has two shapes and they are exclusive. `items` is fan-out: a width * known up front, every child independent, all of them in flight at once up to * the concurrency ceiling. `iterate` is a loop: a depth discovered as it goes, * one child at a time, each round free to read what the round before it * returned. Both spend the same machinery — a child run per unit of work, keyed * by `itemIndex` — which is why they share a file and a node type. */ /** How many children at once, and over what. `[null]` is the single-call case: * not a special path, just a fan-out of width one. */ export interface FanoutPlan { workflowId: string; concurrency: FanoutConcurrency; items: JsonValue[]; hasItems: boolean; } type CapacityReader = (() => Parameters[0]) | undefined; export declare function fanoutPlan(run: WorkflowRunDetail, node: WorkflowCallNode, capacity: CapacityReader, activeChildren: number): FanoutPlan; export declare function fanoutInput(run: WorkflowRunDetail, node: WorkflowCallNode, plan: FanoutPlan, index: number): Record; export declare function callChildren(run: WorkflowRunDetail, nodeId: string): WorkflowChildRunSummary[]; export declare function childTerminal(child: WorkflowChildRunSummary): boolean; export declare function validateFanoutChildren(node: WorkflowCallNode, plan: FanoutPlan, children: WorkflowChildRunSummary[]): void; /** The node's loop settings, with the bound proved present. Validation refuses * to make a definition with `iterate` executable until it carries one, so a node * reaching the runner without it got here some other way and says so. */ export declare function iterationSettings(node: WorkflowCallNode): Required; export type IterationStep = { kind: "run"; round: number; input: Record; workflowId: string; } | { kind: "settle"; port: "success" | "exhausted"; output: WorkflowNodeOutput; }; /** The whole loop decision, in one place: run the next round, leave through * `success` because nothing asked for another, or leave through `exhausted` * because the bound ran out while something still did. Exhaustion is a route, * not a failure — the run carries on down whatever the author wired there. * * A round that did not complete is neither. `continueWhile` reads the round's * output, and a broken round has none, so letting it fall through would read a * crashed body as a loop that finished cleanly — and asking a body that just * failed for another round is worse. Both stop here, loudly. */ export declare function iterationStep(run: WorkflowRunDetail, node: WorkflowCallNode, children: readonly WorkflowChildRunSummary[]): IterationStep; export {}; //# sourceMappingURL=workflow-call.d.ts.map