import type { TSchema } from "typebox"; import type { BranchCondition, ForeachSelector, LoopCondition, MapFn, StepDefinition, WorkflowDefinition } from "./types.ts"; /** Default loop guard: a loop that neither satisfies its condition nor errors within this many iterations crashes. */ export declare const DEFAULT_MAX_ITERATIONS = 100; /** Default concurrency ceiling (spec §3.6): the max steps executing at once across the whole run. */ export declare const DEFAULT_MAX_CONCURRENCY = 4; /** Default foreach concurrency (spec §3.4): sequential unless the author opts in. */ export declare const DEFAULT_FOREACH_CONCURRENCY = 1; /** * Root workflow configuration. The optional TypeBox `input` schema validates initial run data and * infers its author-facing type; `maxConcurrency` defaults to 4. * * @workflowCapability data-flow */ export interface CreateWorkflowOptions { /** Unique workflow name/id — used by `/workflow list` and the run store (spec §1.5, §8.9). */ name: string; description?: string; /** * Optional top-level input schema (spec §3.9). `/workflow run --input` (spec §6.1) validates its * parsed payload against this before a run starts; `/workflow create` (spec §6.6) supplies its own * initial input directly rather than through the command line, since its input is a fixed shape * (the project root) known at every invocation, not something a caller varies per run. */ input?: TInputSchema; /** Default model (`provider/modelId`) for agent steps that declare none (spec §9.5). */ defaultModel?: string; /** * The concurrency ceiling (spec §3.6): bounds the total steps executing at once across every * construct in the run, including nested workflows (which inherit the ROOT run's ceiling). Default * {@link DEFAULT_MAX_CONCURRENCY}. A per-construct `concurrency` above this is rejected at `.commit()`. */ maxConcurrency?: number; } /** Options for a `.map()` construct. @workflowCapability map */ export interface MapOptions { /** Override the auto-generated step name (`map-1`, `map-2`, ...) used in the event log / run context. */ name?: string; } /** Options for a `.branch()` construct. @workflowCapability branch */ export interface BranchOptions { /** Override the auto-generated node name (`branch-1`, ...). */ name?: string; } /** Options shared by `.dowhile()` and `.dountil()`; `maxIterations` defaults to 100. @workflowCapability loop */ export interface LoopOptions { /** Override the auto-generated node name (`loop-1`, ...). */ name?: string; /** Max iterations before the loop crashes (default {@link DEFAULT_MAX_ITERATIONS}). */ maxIterations?: number; } /** * Options for `.foreach()`; `concurrency` defaults to 1. Feedback threads each body's output into the * next item and therefore requires `concurrency: 1`; the current item remains available through * `ctx.scope(foreachName)?.input`. * @workflowCapability foreach */ export interface ForeachOptions { /** Override the auto-generated node name (`foreach-1`, ...). */ name?: string; /** * How many items run at once (spec §3.4). Default {@link DEFAULT_FOREACH_CONCURRENCY} (sequential). * Rejected at `.commit()` if it exceeds the workflow's `maxConcurrency` ceiling (spec §3.6). */ concurrency?: number; /** * Sequential feedback (foreach-feedback spec, Feature 3): item N's body receives item N−1's body * output as its input — item 0 receives the foreach's upstream input — with the same pass-through * rule as a loop (an item producing no output forwards what it received). The ITEM itself is read * from the frame instead: `ctx.scope(foreachName)?.input`. The engine defines delivery, not * aggregation — thread accumulations (e.g. a list of prior summaries) inside the fed value yourself. * Rejected at `.commit()` with `concurrency > 1`: there is no defined order to thread along. */ feedback?: boolean; } /** Options for a `.parallel()` construct. @workflowCapability parallel */ export interface ParallelOptions { /** Override the auto-generated node name (`parallel-1`, ...). */ name?: string; } /** Options for a `.workflow()` nested-workflow construct. @workflowCapability workflow */ export interface NestedWorkflowOptions { /** Override the node name (defaults to the sub-workflow's name). */ name?: string; } /** * One `.branch()` arm: a pure condition paired with the committed sub-workflow to run when it holds. * @workflowCapability branch */ export type BranchArmSpec = readonly [BranchCondition, WorkflowDefinition]; /** * Builder finalized with `.commit()` (Mastra-inspired, spec §1.2/§3). Nodes: `.then()` / `.map()` * (steps), `.branch()` (multi-match), `.dowhile()` / `.dountil()` (loops), `.foreach()`, * `.parallel()` (structural fan-out). Branch arms and loop/foreach bodies are committed sub-workflows * executed recursively by the same engine. */ export interface WorkflowBuilder { /** * Append a step node in sequence. Its input is the previous node's output and is validated against * the step's input schema. * @workflowCapability data-flow */ then(step: StepDefinition): WorkflowBuilder; /** * Insert a pure transform whose result becomes the next node's input via the linear hand-off * (spec §3.7). Reads earlier, non-adjacent outputs via `ctx.getStepResult` / `ctx.getInitData`. * @workflowCapability map */ map(transform: MapFn, options?: MapOptions): WorkflowBuilder; /** * Multi-match branch (spec §3.2): every arm whose condition holds runs sequentially; the node's * output is an object keyed by the executed arm names (each arm name is its body's workflow name). * @workflowCapability branch */ branch(arms: readonly BranchArmSpec[], options?: BranchOptions): WorkflowBuilder; /** * Loop (spec §3.3): run `body`, then repeat while `condition` holds. * * **Feedback** (loop-feedback spec, Feature 2): each iteration's body receives the PREVIOUS * iteration's body output as its input — the first iteration receives the value flowing into the * loop from upstream. It is ordinary, schema-validated step I/O, so the body's input and output * schemas must agree (checked at `.commit()` where both are declared). An iteration that produces * no output (a failed `optional` tail) passes its input through unchanged, and the loop's own * output is the final effective value — readable downstream by the loop's bare name. * * @workflowCapability loop */ dowhile(body: WorkflowDefinition, condition: LoopCondition, options?: LoopOptions): WorkflowBuilder; /** * Run `body`, then repeat until `condition` holds. Feedback follows {@link WorkflowBuilder.dowhile}. * @workflowCapability loop */ dountil(body: WorkflowDefinition, condition: LoopCondition, options?: LoopOptions): WorkflowBuilder; /** * Foreach (spec §3.4): run `body` once per item selected by `selector` (pure), with the item as the * body's input. `options.concurrency` (default 1) bounds how many items run at once. Output is the * array of per-item outputs, in item order — independent of completion order. * * **Author contract (spec §8.3, "non-overlapping side effects"):** at `concurrency > 1`, items run * genuinely concurrently — the engine does not, and cannot, know what a step or its subagent will * touch, so it enforces nothing here. Give each item's body its own files/branches/external * resources; anything shared across items (two agents editing the same file, say) must be sequenced * — either keep `concurrency` at 1, or restructure so the shared resource is touched outside the * fan-out. * * @workflowCapability foreach */ foreach(body: WorkflowDefinition, selector: ForeachSelector, options?: ForeachOptions): WorkflowBuilder; /** * Parallel (spec §3.5): structural fan-out over independent STEPS — every arm runs concurrently * against the same input, bounded only by the workflow ceiling (spec §3.6). Output is an object * keyed by each arm's own step name, independent of completion order. * * **Author contract (spec §8.3, "non-overlapping side effects"):** every arm runs genuinely * concurrently — the same rule as `.foreach`'s doc above applies per arm here: no two arms may touch * the same file, branch, or external resource, since the engine has no way to detect or prevent two * concurrent agents rewriting the same working-tree state. Sequence anything that shares state with * `.then()` instead of putting it in the same `.parallel([...])`. * * @workflowCapability parallel */ parallel(arms: readonly StepDefinition[], options?: ParallelOptions): WorkflowBuilder; /** * Nested workflow (spec §2.3/§11): run a committed sub-workflow's nodes here, transparently folding * into the parent run/log. Output is the sub-workflow's final output. Every step/node name must be * unique across the flattened tree, so nesting the *same* sub-workflow twice is a `commit()` error. * * @workflowCapability workflow */ workflow(subWorkflow: WorkflowDefinition, options?: NestedWorkflowOptions): WorkflowBuilder; /** * Finalize and validate the workflow definition. * @workflowCapability data-flow */ commit(): WorkflowDefinition; } /** * Starts a fluent workflow definition and returns its builder. Append at least one node and call * `.commit()` to obtain a loadable {@link WorkflowDefinition}. * * @remarks * Linear hand-off passes every node's output to the next node. Use `ctx.getStepResult()` for a * non-adjacent result, `ctx.getInitData()` for the root input, and `ctx.scope()` for enclosing * loop/foreach/branch/parallel input. Node names must be unique and cannot contain `/`, `#`, or `@`. * * @example * ```ts * export default createWorkflow({ name: "review", input: requestSchema }) * .then(loadRequest) * .then(reviewRequest) * .commit() * ``` * * @throws If the workflow is empty, names are invalid or duplicated, concurrency exceeds its ceiling, * or incompatible execution options are combined. * * @workflowCapability data-flow */ export declare function createWorkflow(options: CreateWorkflowOptions): WorkflowBuilder; //# sourceMappingURL=create-workflow.d.ts.map