pipeai 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -12
- package/dist/index.cjs +1108 -993
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +503 -194
- package/dist/index.d.ts +503 -194
- package/dist/index.js +1106 -990
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent.ts","../src/tool-provider.ts","../src/utils.ts","../src/workflow.ts","../src/index.ts"],"sourcesContent":["import {\n generateText,\n streamText,\n tool,\n Output,\n type GenerateTextResult as AIGenerateTextResult,\n type StreamTextResult as AIStreamTextResult,\n type UIMessageStreamWriter,\n type ModelMessage,\n type LanguageModel,\n type Tool,\n type ToolSet,\n type StopCondition,\n type ToolChoice,\n type OnStepFinishEvent,\n type OnFinishEvent,\n} from \"ai\";\n\n// Extract the Output interface type from the Output.object return type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type OutputType<T = any> = ReturnType<typeof Output.object<T>>;\nimport type { ZodType } from \"zod\";\nimport { isToolProvider, TOOL_PROVIDER_BRAND, type IToolProvider } from \"./tool-provider\";\nimport { extractOutput, getActiveWriter, resolveValue, type MaybePromise, type Resolvable } from \"./utils\";\n\n// Tools config accepts both AI SDK tools and context-aware ToolProviders\ntype AgentToolSet<TContext> = Record<string, Tool | IToolProvider<TContext>>;\n\n// ── Result type aliases ─────────────────────────────────────────────\n\nexport type GenerateTextResult<TOOLS extends ToolSet = ToolSet, OUTPUT extends OutputType = OutputType> = AIGenerateTextResult<TOOLS, OUTPUT>;\nexport type StreamTextResult<TOOLS extends ToolSet = ToolSet, OUTPUT extends OutputType = OutputType> = AIStreamTextResult<TOOLS, OUTPUT>;\n\n/**\n * The result passed to `asTool` / `asToolProvider`'s `mapOutput`.\n *\n * The same agent may be invoked as a tool from a generate-mode parent\n * (returns `GenerateTextResult`, sync `.text`/`.output`) or from a\n * stream-mode parent (returns `StreamTextResult`, async `.text`/`.output`).\n * The callsite cannot statically tell which mode it is in, so `mapOutput`\n * receives the union and must `await` the relevant fields to support both.\n */\nexport type AsToolMapOutput<TOutput> = (\n result:\n | GenerateTextResult<ToolSet, OutputType<TOutput>>\n | StreamTextResult<ToolSet, OutputType<TOutput>>,\n) => MaybePromise<TOutput>;\n\n// ── AI SDK passthrough types ────────────────────────────────────────\n\n// Extract options types from both AI SDK entry points\ntype StreamTextOptions = Parameters<typeof streamText>[0];\ntype GenerateTextOptions = Parameters<typeof generateText>[0];\n\n// Keys we replace with resolvable or context-enriched versions\ntype ManagedKeys =\n | 'model' | 'system' | 'prompt' | 'messages'\n | 'tools' | 'activeTools' | 'toolChoice' | 'stopWhen'\n | 'output' | 'onFinish' | 'onStepFinish' | 'onError';\n\n// Combine options from both streamText and generateText.\n// Each side contributes its unique props; shared props merge naturally.\n// Stream-only props (onChunk, onAbort) are ignored by generateText.\n// Generate-only props (experimental_include.responseBody) are ignored by streamText.\ntype AIPassthroughOptions =\n Omit<StreamTextOptions, ManagedKeys> &\n Omit<GenerateTextOptions, ManagedKeys>;\n\n// ── Resolved config (output of resolveConfig / resolveConfigAsync) ──\n\ninterface ResolvedAgentConfig {\n model: LanguageModel;\n prompt: string | undefined;\n system: string | undefined;\n messages: ModelMessage[] | undefined;\n tools: Record<string, Tool>;\n activeTools: string[] | undefined;\n toolChoice: ToolChoice<ToolSet> | undefined;\n stopWhen: StopCondition<ToolSet> | Array<StopCondition<ToolSet>> | undefined;\n}\n\n// ── Agent Configuration ─────────────────────────────────────────────\n\nexport interface AgentConfig<\n TContext,\n TInput = void,\n TOutput = void,\n> extends AIPassthroughOptions {\n // ── Custom (not in AI SDK) ──\n id: string;\n description?: string;\n input?: ZodType<TInput>;\n output?: OutputType<TOutput>;\n /**\n * Zod schema used to validate `output` after the AI SDK returns. Distinct\n * from `tool.outputSchema` (AI SDK's tool-execution output schema): this\n * runs **after** the SDK has parsed structured output, as a runtime guard\n * against parse drift. If omitted, the parsed output is trusted as-is.\n */\n validateOutput?: ZodType<TOutput>;\n\n // ── Resolvable (our versions of AI SDK properties) ──\n model: Resolvable<TContext, TInput, LanguageModel>;\n system?: Resolvable<TContext, TInput, string>;\n prompt?: Resolvable<TContext, TInput, string>;\n messages?: Resolvable<TContext, TInput, ModelMessage[]>;\n tools?: Resolvable<TContext, TInput, AgentToolSet<TContext>>;\n activeTools?: Resolvable<TContext, TInput, string[]>;\n toolChoice?: Resolvable<TContext, TInput, ToolChoice<ToolSet>>;\n /**\n * Stop condition(s) for the tool loop. Pass either a single AI-SDK\n * `StopCondition` (which is itself a function) or an array of them.\n *\n * **Not a `Resolvable`.** A `StopCondition` and a `(ctx, input) => StopCondition`\n * resolver are both functions and cannot be safely distinguished at\n * runtime, so this field intentionally does NOT accept the resolver\n * form. If you need per-call dynamic stop conditions, build the agent\n * inside your handler instead of using a static instance.\n */\n stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;\n\n // ── Context-enriched callbacks (replace AI SDK versions) ──\n // `writer` is available when the agent runs inside a streaming workflow.\n onStepFinish?: (params: { result: OnStepFinishEvent; ctx: Readonly<TContext>; input: TInput; writer?: UIMessageStreamWriter }) => MaybePromise<void>;\n onFinish?: (params: { result: OnFinishEvent; ctx: Readonly<TContext>; input: TInput; writer?: UIMessageStreamWriter }) => MaybePromise<void>;\n onError?: (params: { error: unknown; ctx: Readonly<TContext>; input: TInput; writer?: UIMessageStreamWriter }) => MaybePromise<void>;\n}\n\n// ── Agent ───────────────────────────────────────────────────────────\n\nexport class Agent<\n TContext,\n TInput = void,\n TOutput = void,\n> {\n readonly id: string;\n readonly description: string;\n readonly hasOutput: boolean;\n /**\n * Zod schema used to validate the agent's structured `output` after the AI\n * SDK returns. Distinct from `tool.outputSchema` (which validates tool\n * execution output). Exposed (readonly) so external runners — notably the\n * workflow runtime — can pass it through to `extractOutput` without\n * re-plumbing it.\n */\n readonly validateOutput: ZodType<TOutput> | undefined;\n private readonly config: AgentConfig<TContext, TInput, TOutput>;\n private readonly _hasDynamicConfig: boolean;\n private readonly _resolvedStaticTools: Record<string, Tool> | null = null;\n private readonly _passthrough: Record<string, unknown>;\n private readonly _onStepFinish: AgentConfig<TContext, TInput, TOutput>['onStepFinish'];\n private readonly _onFinish: AgentConfig<TContext, TInput, TOutput>['onFinish'];\n\n constructor(config: AgentConfig<TContext, TInput, TOutput>) {\n this.id = config.id;\n this.description = config.description ?? \"\";\n this.hasOutput = config.output !== undefined;\n this.validateOutput = config.validateOutput;\n this.config = config;\n // NOTE: `stopWhen` is intentionally excluded. A bare `StopCondition` is\n // itself a function (`({ steps }) => boolean`), so the typeof-function\n // resolver heuristic in `resolveValue` would misidentify it as a\n // `(ctx, input) => ...` Resolvable and call it with the wrong shape.\n // For `stopWhen` we always treat a function value as a static\n // StopCondition; dynamic stopWhen must return an array\n // (`(ctx, input) => [stepCountIs(5)]`), which is the unambiguous form.\n this._hasDynamicConfig = [\n config.model, config.system, config.prompt,\n config.messages, config.tools, config.activeTools,\n config.toolChoice,\n ].some(v => typeof v === \"function\");\n\n // Cache tools when config is static and contains no ToolProviders.\n // Avoids re-iterating the tools map on every generate()/stream() call.\n if (!this._hasDynamicConfig) {\n const rawTools = (config.tools as AgentToolSet<TContext> | undefined) ?? {};\n const hasProvider = Object.values(rawTools).some(v => isToolProvider(v));\n if (!hasProvider) {\n this._resolvedStaticTools = rawTools as Record<string, Tool>;\n }\n }\n\n // Pre-compute the passthrough (AI SDK options we don't manage) once,\n // rather than destructuring on every generate()/stream() call.\n const {\n id: _id, description: _desc, input: _inputSchema, output: _output, validateOutput: _validateOutput,\n model: _m, system: _s, prompt: _p, messages: _msg,\n tools: _t, activeTools: _at, toolChoice: _tc, stopWhen: _sw,\n onStepFinish, onFinish, onError: _onError,\n ...passthrough\n } = config;\n this._passthrough = passthrough;\n this._onStepFinish = onStepFinish;\n this._onFinish = onFinish;\n }\n\n async generate(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: { abortSignal?: AbortSignal }]\n : [input: TInput, options?: { abortSignal?: AbortSignal }]\n ): Promise<GenerateTextResult<ToolSet, OutputType<TOutput>>> {\n const input = args[0] as TInput;\n const callOptions = args[1] as { abortSignal?: AbortSignal } | undefined;\n return this.generateWithOptions(ctx, input, callOptions ?? {});\n }\n\n async stream(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: { abortSignal?: AbortSignal }]\n : [input: TInput, options?: { abortSignal?: AbortSignal }]\n ): Promise<StreamTextResult<ToolSet, OutputType<TOutput>>> {\n const input = args[0] as TInput;\n const callOptions = args[1] as { abortSignal?: AbortSignal } | undefined;\n return this.streamWithOptions(ctx, input, callOptions ?? {});\n }\n\n asTool(ctx: TContext, options?: {\n mapOutput?: AsToolMapOutput<TOutput>;\n }): Tool {\n return this.createToolInstance(ctx, options);\n }\n\n asToolProvider(options?: {\n mapOutput?: AsToolMapOutput<TOutput>;\n }): IToolProvider<TContext> {\n if (!this.config.input) {\n throw new Error(`Agent \"${this.id}\": asToolProvider() requires an input schema`);\n }\n\n return {\n [TOOL_PROVIDER_BRAND]: true as const,\n createTool: (ctx: Readonly<TContext>) => this.createToolInstance(ctx as TContext, options),\n };\n }\n\n private createToolInstance(ctx: TContext, options?: {\n mapOutput?: AsToolMapOutput<TOutput>;\n }): Tool {\n if (!this.config.input) {\n throw new Error(`Agent \"${this.id}\": asTool() requires an input schema`);\n }\n\n return tool<TInput, TOutput>({\n description: this.description,\n inputSchema: this.config.input,\n // The AI SDK passes a `ToolExecutionOptions` argument that carries\n // `abortSignal`, `toolCallId`, `messages`, etc. Forward `abortSignal` so\n // a parent agent's abort cancels in-flight sub-agent calls instead of\n // leaving them running and producing detached output.\n execute: async (toolInput: TInput, execOptions?: { abortSignal?: AbortSignal }) => {\n const abortSignal = execOptions?.abortSignal;\n // When inside a streaming workflow, automatically use stream() and merge to the active writer.\n // Otherwise fall back to generate().\n const writer = getActiveWriter();\n if (writer) {\n const result = await this.streamWithOptions(ctx, toolInput, { abortSignal });\n writer.merge(result.toUIMessageStream());\n // Drain the text side to release the StreamTextResult anchor — the\n // writer.merge above only consumes the UI-message side, leaving\n // `result.text` pending until awaited.\n //\n // When mapOutput is provided, we explicitly do NOT call extractOutput\n // here: extractOutput throws if `hasOutput` is true but the model\n // returned no structured value, which would block any mapOutput that\n // wanted to recover from missing/malformed structured output by\n // reading `result.text`. mapOutput becomes the user's chance to do\n // their own extraction.\n if (options?.mapOutput) {\n await result.text;\n return options.mapOutput(result);\n }\n return extractOutput(result, this.hasOutput, this.validateOutput);\n }\n const result = await this.generateWithOptions(ctx, toolInput, { abortSignal });\n if (options?.mapOutput) return options.mapOutput(result);\n return extractOutput(result, this.hasOutput, this.validateOutput);\n },\n // TS cannot simplify the SDK's `NeverOptional<TOutput, ...>` conditional in a\n // generic context, so we cast through `unknown` instead of `any`.\n } as unknown as Tool<TInput, TOutput>);\n }\n\n // ── Internal: shared call helpers ─────────────────────────────\n // `generate()` / `stream()` and the `asTool()` wrapper all funnel through\n // these so the abortSignal-forwarding and onError-wrapping logic stays in\n // one place. `extra` carries per-call overrides (currently `abortSignal`).\n\n // If the user-supplied onError callback itself throws, attach the original\n // model error as `.cause` on the new error and rethrow the wrapper. Without\n // this, the original error is silently shadowed.\n private async invokeOnError(error: unknown, ctx: TContext, input: TInput): Promise<void> {\n if (!this.config.onError) return;\n try {\n await this.config.onError({ error, ctx, input, writer: getActiveWriter() });\n } catch (handlerError) {\n // Promote non-Error throws (`throw \"boom\"`, `throw 42`, etc.) so we\n // can chain the original error onto a real Error and keep diagnostics\n // intact. Re-throwing the raw non-Error value would drop the chain.\n if (handlerError instanceof Error) {\n if (handlerError.cause === undefined) {\n (handlerError as { cause?: unknown }).cause = error;\n }\n throw handlerError;\n }\n const wrapped = new Error(\n `Agent \"${this.id}\": onError handler threw a non-Error value (${typeof handlerError}): ${String(handlerError)}`,\n );\n (wrapped as { cause?: unknown }).cause = error;\n throw wrapped;\n }\n }\n\n private async generateWithOptions(\n ctx: TContext,\n input: TInput,\n extra: { abortSignal?: AbortSignal },\n ): Promise<GenerateTextResult<ToolSet, OutputType<TOutput>>> {\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n try {\n // The SDK's `Output.object<T>` return type doesn't simplify generically\n // — cast through `unknown` rather than `any` so we keep the boundary\n // narrow without forcing the call site to know SDK option internals.\n return (await generateText({ ...options, ...extra } as unknown as Parameters<typeof generateText>[0])) as GenerateTextResult<ToolSet, OutputType<TOutput>>;\n } catch (error: unknown) {\n await this.invokeOnError(error, ctx, input);\n throw error;\n }\n }\n\n private async streamWithOptions(\n ctx: TContext,\n input: TInput,\n extra: { abortSignal?: AbortSignal },\n ): Promise<StreamTextResult<ToolSet, OutputType<TOutput>>> {\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n try {\n // Only attach `onError` when the user supplied one. Setting it to\n // `undefined` explicitly suppresses some SDK versions' default\n // rethrow-on-partial-stream-error, silently swallowing stream failures.\n const onErrorOption = this.config.onError\n ? { onError: ({ error }: { error: unknown }) => this.invokeOnError(error, ctx, input) }\n : {};\n return streamText({\n ...options,\n ...extra,\n ...onErrorOption,\n } as unknown as Parameters<typeof streamText>[0]) as StreamTextResult<ToolSet, OutputType<TOutput>>;\n } catch (error: unknown) {\n // streamText typically defers errors to the returned stream, but a\n // synchronous throw (e.g., invalid options) would otherwise bypass\n // onError entirely.\n await this.invokeOnError(error, ctx, input);\n throw error;\n }\n }\n\n private buildCallOptions(resolved: ResolvedAgentConfig, ctx: TContext, input: TInput): Record<string, unknown> {\n if (resolved.messages === undefined && resolved.prompt === undefined) {\n throw new Error(\n `Agent \"${this.id}\": neither \\`prompt\\` nor \\`messages\\` was provided. ` +\n `Configure one of them, or supply a Resolvable that returns one based on input.`,\n );\n }\n return {\n ...this._passthrough,\n model: resolved.model,\n tools: resolved.tools,\n activeTools: resolved.activeTools,\n toolChoice: resolved.toolChoice,\n stopWhen: resolved.stopWhen,\n ...(resolved.messages !== undefined\n ? { messages: resolved.messages }\n : { prompt: resolved.prompt }),\n // Use `!== undefined` rather than truthy so an intentional empty\n // `system: \"\"` survives instead of being silently dropped.\n ...(resolved.system !== undefined ? { system: resolved.system } : {}),\n ...(this.config.output ? { output: this.config.output } : {}),\n // Only attach the callback when the user supplied one. Passing\n // `undefined` explicitly can suppress default SDK rethrow behavior in\n // some versions.\n ...(this._onStepFinish\n ? { onStepFinish: (event: OnStepFinishEvent) => this._onStepFinish!({ result: event, ctx, input, writer: getActiveWriter() }) }\n : {}),\n ...(this._onFinish\n ? { onFinish: (event: OnFinishEvent) => this._onFinish!({ result: event, ctx, input, writer: getActiveWriter() }) }\n : {}),\n };\n }\n\n private resolveConfig(ctx: TContext, input: TInput): ResolvedAgentConfig | Promise<ResolvedAgentConfig> {\n if (!this._hasDynamicConfig) {\n return {\n model: this.config.model as LanguageModel,\n prompt: this.config.prompt as string | undefined,\n system: this.config.system as string | undefined,\n messages: this.config.messages as ModelMessage[] | undefined,\n tools: this._resolvedStaticTools ?? this.resolveTools(\n (this.config.tools as AgentToolSet<TContext> | undefined) ?? {}, ctx\n ),\n activeTools: this.config.activeTools as string[] | undefined,\n toolChoice: this.config.toolChoice as ToolChoice<ToolSet> | undefined,\n stopWhen: this.config.stopWhen as StopCondition<ToolSet> | Array<StopCondition<ToolSet>> | undefined,\n };\n }\n return this.resolveConfigAsync(ctx, input);\n }\n\n private async resolveConfigAsync(ctx: TContext, input: TInput): Promise<ResolvedAgentConfig> {\n const [model, prompt, system, messages, rawTools, activeTools, toolChoice] = await Promise.all([\n resolveValue(this.config.model, ctx, input),\n resolveValue(this.config.prompt, ctx, input),\n resolveValue(this.config.system, ctx, input),\n resolveValue(this.config.messages, ctx, input),\n resolveValue(this.config.tools, ctx, input),\n resolveValue(this.config.activeTools, ctx, input),\n resolveValue(this.config.toolChoice, ctx, input),\n ]);\n const tools = this.resolveTools(rawTools ?? {}, ctx);\n return {\n model,\n prompt,\n system,\n messages,\n tools,\n activeTools,\n toolChoice,\n // `stopWhen` is always static — see field declaration for why.\n stopWhen: this.config.stopWhen,\n };\n }\n\n private resolveTools(\n tools: AgentToolSet<TContext>,\n ctx: TContext\n ): Record<string, Tool> {\n const entries = Object.entries(tools);\n if (entries.length === 0) return tools as Record<string, Tool>;\n let hasProvider = false;\n const resolved: Record<string, Tool> = {};\n for (const [key, toolOrProvider] of entries) {\n if (isToolProvider<TContext>(toolOrProvider)) {\n hasProvider = true;\n resolved[key] = toolOrProvider.createTool(ctx as Readonly<TContext>);\n } else {\n resolved[key] = toolOrProvider as Tool;\n }\n }\n return hasProvider ? resolved : (tools as Record<string, Tool>);\n }\n}\n","import { tool, type Tool, type ToolExecutionOptions, type FlexibleSchema, type UIMessageStreamWriter } from \"ai\";\nimport { getActiveWriter } from \"./utils\";\n\nexport const TOOL_PROVIDER_BRAND = Symbol.for(\"agent-workflow.ToolProvider\");\n\nexport type ToolExecuteOptions = ToolExecutionOptions & {\n writer?: UIMessageStreamWriter;\n};\n\ntype ToolProviderOptions = NonNullable<Tool[\"providerOptions\"]>;\n\nexport type ToolProviderConfig<TContext, TInput, TOutput> = {\n description?: string;\n input: FlexibleSchema<TInput>;\n outputSchema?: FlexibleSchema<TOutput>;\n providerOptions?: ToolProviderOptions;\n execute: (input: TInput, ctx: Readonly<TContext>, options: ToolExecuteOptions) => Promise<TOutput>;\n};\n\nexport interface IToolProvider<TContext> {\n readonly [TOOL_PROVIDER_BRAND]: true;\n createTool(context: Readonly<TContext>): Tool;\n}\n\nexport class ToolProvider<\n TContext,\n TInput = unknown,\n TOutput = unknown,\n> implements IToolProvider<TContext> {\n readonly [TOOL_PROVIDER_BRAND] = true as const;\n private readonly config: ToolProviderConfig<TContext, TInput, TOutput>;\n\n constructor(config: ToolProviderConfig<TContext, TInput, TOutput>) {\n this.config = config;\n }\n\n createTool(context: Readonly<TContext>): Tool {\n const { execute, input: inputSchema, ...toolDef } = this.config;\n // The shape matches `Tool<TInput, TOutput>`, but TS cannot simplify the SDK's\n // `NeverOptional<TOutput, ...>` conditional in a generic context, so the literal\n // is not assignable directly. Cast through `unknown` rather than `any` so the\n // return type and call sites still get type-checked.\n return tool<TInput, TOutput>({\n ...toolDef,\n inputSchema,\n execute: (input: TInput, options: ToolExecutionOptions) => execute(input, context, { ...options, writer: getActiveWriter() } as ToolExecuteOptions),\n } as unknown as Tool<TInput, TOutput>);\n }\n}\n\nexport function defineTool<TContext>() {\n return <TInput, TOutput>(\n config: ToolProviderConfig<TContext, TInput, TOutput>\n ): ToolProvider<TContext, TInput, TOutput> => new ToolProvider(config);\n}\n\nexport function isToolProvider<TContext>(obj: unknown): obj is IToolProvider<TContext> {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n TOOL_PROVIDER_BRAND in obj\n );\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\nimport type { UIMessageStreamWriter } from \"ai\";\nimport type { ZodType } from \"zod\";\n\n// ── Stream writer context ────────────────────────────────────────────\n// Invisible to the user. The workflow sets the writer before agent execution;\n// tools and sub-agents read it automatically via getActiveWriter().\n\nconst writerStorage = new AsyncLocalStorage<UIMessageStreamWriter>();\n\nexport function runWithWriter<T>(writer: UIMessageStreamWriter, fn: () => T): T {\n return writerStorage.run(writer, fn);\n}\n\n/**\n * Returns the active `UIMessageStreamWriter` if the current async context is\n * running inside a streaming workflow, or `undefined` otherwise.\n *\n * Use from inside a custom `IToolProvider`'s returned `Tool.execute` callback\n * to forward incremental output to the workflow's UI message stream:\n *\n * ```ts\n * import { getActiveWriter, type IToolProvider, TOOL_PROVIDER_BRAND } from \"pipeai\";\n *\n * const myProvider: IToolProvider<MyCtx> = {\n * [TOOL_PROVIDER_BRAND]: true,\n * createTool(ctx) {\n * return tool({\n * execute: async (input) => {\n * const writer = getActiveWriter();\n * // ...stream incremental progress to writer if present...\n * return result;\n * },\n * });\n * },\n * };\n * ```\n *\n * **Important timing note:** call this from *inside* the `Tool.execute`\n * callback, not from inside `createTool` itself. `createTool` runs during\n * agent setup (before the workflow has set the writer); `Tool.execute` runs\n * during tool invocation (when the writer is live).\n */\nexport function getActiveWriter(): UIMessageStreamWriter | undefined {\n return writerStorage.getStore();\n}\n\n// ── Common types ─────────────────────────────────────────────────────\n\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * A value that can be static or derived from context and input.\n * Used for agent config fields that may need runtime resolution.\n *\n * Functions may return a Promise for async resolution; static values are always sync.\n */\nexport type Resolvable<TCtx, TInput, TValue> =\n | TValue\n | ((ctx: Readonly<TCtx>, input: TInput) => TValue | Promise<TValue>);\n\nexport function resolveValue<TCtx, TInput, TValue>(\n value: Resolvable<TCtx, TInput, TValue>,\n ctx: TCtx,\n input: TInput\n): TValue | Promise<TValue>;\nexport function resolveValue<TCtx, TInput, TValue>(\n value: Resolvable<TCtx, TInput, TValue> | undefined,\n ctx: TCtx,\n input: TInput\n): TValue | Promise<TValue> | undefined {\n if (typeof value === \"function\") {\n return (value as (ctx: TCtx, input: TInput) => TValue | Promise<TValue>)(ctx, input);\n }\n return value;\n}\n\n/**\n * Minimal counting semaphore. Up to `permits` callers can hold a permit\n * concurrently; further `acquire()` calls queue FIFO until one is released.\n */\nexport class Semaphore {\n private available: number;\n private waiters: Array<() => void> = [];\n\n constructor(permits: number) {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new Error(`Semaphore: permits must be a positive integer, got ${permits}`);\n }\n this.available = permits;\n }\n\n async acquire(): Promise<void> {\n if (this.available > 0) {\n this.available--;\n return;\n }\n await new Promise<void>(resolve => this.waiters.push(resolve));\n }\n\n release(): void {\n const next = this.waiters.shift();\n if (next) next();\n else this.available++;\n }\n}\n\n/**\n * Extract structured output from an AI SDK result.\n *\n * - When `hasStructuredOutput` is `true`, awaits `result.output`. If the SDK\n * did not produce a structured value, this throws — silent fall-back to raw\n * text would mask schema mismatches at the call site.\n * - When `schema` is provided, the awaited output is validated through the\n * Zod schema before being returned, catching SDK-side parse drift.\n * - When `hasStructuredOutput` is `false`, returns `result.text`.\n *\n * Works for both generate (sync .output/.text) and stream (async .output/.text) results.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function extractOutput(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result: any,\n hasStructuredOutput: boolean,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema?: ZodType<any>,\n): Promise<unknown> {\n if (hasStructuredOutput) {\n const output = await result.output;\n if (output === undefined) {\n throw new Error(\n \"Agent: structured output was declared but the model returned none. \" +\n \"This usually means the model produced text that did not match the declared schema, \" +\n \"or the underlying SDK did not parse the structured output.\",\n );\n }\n if (schema) {\n return schema.parse(output);\n }\n return output;\n }\n return await result.text;\n}\n\n/**\n * Recursively freeze an object graph. Cycles are tracked via a WeakSet so we\n * never recurse into the same node twice. Maps/Sets stay structurally frozen\n * but `.set()`/`.add()` still mutate them — Object.freeze doesn't cover those.\n */\nexport function deepFreeze<T>(value: T, seen: WeakSet<object> = new WeakSet()): T {\n if (value === null || typeof value !== \"object\" || seen.has(value as object)) return value;\n // Already-frozen subtree (e.g. user-passed frozen ctx) — its children are\n // either also frozen or intentionally mutable, either way we should not recurse.\n if (Object.isFrozen(value)) return value;\n seen.add(value as object);\n Object.freeze(value);\n for (const key of Reflect.ownKeys(value as object)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deepFreeze((value as any)[key], seen);\n }\n return value;\n}\n\n// ── stepShapeHash (F1) ───────────────────────────────────────────────\n//\n// Recursive SHA-256 of the workflow's structural shape (index, type, id,\n// nested workflow shapes). Used by checkpoint resume to detect drift —\n// when the user inserts/removes/reorders a step, the hash changes and\n// resume refuses to continue unless explicitly told to via\n// `{ skipShapeCheck: true }`.\n//\n// **Agent identity is NOT in the hash.** Two checkpoints from runs that\n// used different agent configs (same id) hash identically. Version agents\n// by content if resume-trust matters.\n\n/**\n * The minimal shape interface this util needs from a `SealedWorkflow`.\n * Importing the workflow class here would create a circular dependency\n * (utils.ts ← workflow.ts and workflow.ts ← utils.ts); so we accept any\n * object exposing `id` and `getStepsForShapeHash()`.\n */\nexport interface WorkflowShapeHashable {\n readonly id?: string;\n // Returns the StepNode[] for this workflow. Structurally typed to avoid\n // a circular import — the real type is `ReadonlyArray<StepNode>`.\n getStepsForShapeHash(): ReadonlyArray<StepNodeShape>;\n}\n\n/**\n * Structural typing for a StepNode as seen by the shape hasher. Mirrors\n * the actual `StepNode` union without importing it. Adding fields to\n * StepNode without updating this contract won't fail compilation; the\n * dispatch map in workflow.ts (typed via `Record<StepNode[\"type\"], ...>`)\n * is the load-bearing exhaustiveness guard.\n */\nexport interface StepNodeShape {\n readonly type: string;\n readonly id: string;\n}\n\nexport function computeStepShapeHash(\n steps: ReadonlyArray<StepNodeShape>,\n getNested: (node: StepNodeShape) => readonly WorkflowShapeHashable[],\n): string {\n return createHash(\"sha256\").update(canonicalDescriptor(steps, getNested, new WeakSet())).digest(\"hex\");\n}\n\n/**\n * `path` tracks the current DFS stack only — added on entry, removed on exit.\n * Sibling re-visits of the same SealedWorkflow are NOT cycles (shared\n * subgraphs hash identically to two structurally-equivalent distinct\n * instances). Only ancestor re-visits (true cycles) emit the cycle marker.\n */\nfunction canonicalDescriptor(\n steps: ReadonlyArray<StepNodeShape>,\n getNested: (node: StepNodeShape) => readonly WorkflowShapeHashable[],\n path: WeakSet<WorkflowShapeHashable>,\n): string {\n return JSON.stringify(steps.map((s, i) => {\n const triple: (number | string)[] = [i, s.type, s.id];\n for (const inner of getNested(s)) {\n if (path.has(inner)) {\n triple.push(`<cycle:${inner.id ?? \"anon\"}>`);\n continue;\n }\n path.add(inner);\n try {\n triple.push(canonicalDescriptor(inner.getStepsForShapeHash(), getNested, path));\n } finally {\n path.delete(inner);\n }\n }\n return triple;\n }));\n}\n\n// ── warnOnce (F1) — module-level dedup helper ────────────────────────\n\nconst warnedOnceKeys = new Set<string>();\nexport function warnOnce(key: string, message?: string): void {\n if (warnedOnceKeys.has(key)) return;\n warnedOnceKeys.add(key);\n // eslint-disable-next-line no-console\n console.warn(message ?? key);\n}\n\n/**\n * @internal — test-only reset of the warnOnce dedup. Same shape as\n * workflow.ts's `__resetStreamOnErrorOnSuspendWarnForTests`.\n */\nexport function __resetWarnOnceForTests(): void {\n warnedOnceKeys.clear();\n}\n","import {\n createUIMessageStream,\n type UIMessage,\n type UIMessageStreamWriter,\n type UIMessageStreamOnFinishCallback,\n type IdGenerator,\n type ToolSet,\n} from \"ai\";\nimport { type Agent, type GenerateTextResult, type StreamTextResult, type OutputType } from \"./agent\";\nimport { computeStepShapeHash, deepFreeze, extractOutput, runWithWriter, warnOnce, type MaybePromise } from \"./utils\";\n\n// ── Error Types ─────────────────────────────────────────────────────\n\nexport class WorkflowBranchError extends Error {\n constructor(\n public readonly branchType: \"predicate\" | \"select\",\n message: string,\n ) {\n super(message);\n this.name = \"WorkflowBranchError\";\n }\n}\n\nexport class WorkflowLoopError extends Error {\n constructor(\n public readonly iterations: number,\n public readonly maxIterations: number,\n ) {\n super(`Loop exceeded maximum iterations (${maxIterations})`);\n this.name = \"WorkflowLoopError\";\n }\n}\n\nexport class NestedGateUnsupportedError extends Error {\n readonly gateId: string;\n readonly workflowId: string | undefined;\n // Always present; non-gate rejections from concurrent foreach.\n readonly siblingErrors: readonly unknown[];\n // Always present; OTHER suspending items in concurrent foreach.\n readonly siblingSuspensions: readonly { index: number; gateId: string }[];\n\n constructor(\n gateId: string,\n workflowId: string | undefined,\n siblingErrors: readonly unknown[] = [],\n siblingSuspensions: readonly { index: number; gateId: string }[] = [],\n ) {\n super(`Gate \"${gateId}\" hit inside nested workflow \"${workflowId ?? \"(anonymous)\"}\". Nested gates are not yet supported.`);\n this.name = \"NestedGateUnsupportedError\";\n this.gateId = gateId;\n this.workflowId = workflowId;\n this.siblingErrors = siblingErrors;\n this.siblingSuspensions = siblingSuspensions;\n }\n}\n\n// ── Snapshot / Warnings / Run options ────────────────────────────────\n\n/**\n * v2 gate snapshot. The `kind` discriminant differentiates it from\n * checkpoint snapshots. The legacy v1 form is still accepted by `loadState`.\n */\nexport interface GateSnapshot {\n readonly version: 2;\n readonly kind: \"gate\";\n readonly resumeFromIndex: number;\n readonly output: unknown;\n readonly gateId: string;\n readonly gatePayload: unknown;\n}\n\n/**\n * v2 checkpoint snapshot. Carries a step-shape hash; resume verifies the\n * workflow definition hasn't drifted before continuing.\n */\nexport interface CheckpointSnapshot {\n readonly version: 2;\n readonly kind: \"checkpoint\";\n readonly resumeFromIndex: number; // index of the NEXT step to run\n readonly output: unknown;\n readonly stepShapeHash: string; // SHA-256 hex of canonical recursive shape\n}\n\n/**\n * Legacy v0.4.0 gate-only snapshot. Accepted by `loadState` for one release\n * via the shim path. `kind?: undefined` makes runtime narrowing on\n * `kind === undefined` reachable — JSON round-trips strip the property.\n * Migrate via `migrateSnapshot()` before v0.8.0+.\n */\nexport interface LegacyGateSnapshotV1 {\n readonly version: 1;\n readonly kind?: undefined;\n readonly resumeFromIndex: number;\n readonly output: unknown;\n readonly gateId: string;\n readonly gatePayload: unknown;\n}\n\nexport type WorkflowSnapshot = GateSnapshot | CheckpointSnapshot | LegacyGateSnapshotV1;\n\nexport interface WorkflowWarning {\n readonly source:\n | \"step\"\n | \"finally\"\n | \"catch\"\n | \"onCheckpoint\"\n | \"onStepStart\"\n | \"onStepFinish\"\n | \"onStepError\"\n | \"foreach-sibling\";\n readonly stepId: string;\n readonly error: unknown;\n}\n\nexport type WorkflowStepType =\n | \"step\"\n | \"nested\"\n | \"gate\"\n | \"catch\"\n | \"finally\"\n | \"branch\"\n | \"foreach\"\n | \"repeat\"\n | \"parallel\";\n\n/**\n * Workflow observability hooks. All optional. Errors thrown inside hooks\n * are captured into `result.warnings` with a matching `source` tag, except\n * `onStepError`, which causes the run to throw the ORIGINAL step error with\n * `error.cause = obsError` (preserving `instanceof` on the original).\n *\n * Per-node firing rules (where \"step-like\" = step / nested / branch /\n * foreach / parallel / repeat):\n * - step-like / gate (cond-true → suspends): onStepStart always; onStepFinish\n * when body returns (suspended: true for gate, false otherwise); onStepError\n * on body throw.\n * - gate (cond false → skip): onStepStart, onStepFinish({ suspended: false }).\n * - catch: onStepStart only when pendingError set; onStepFinish when catchFn\n * returns; onStepError when catchFn throws.\n * - finally: onStepStart always (runs even after suspension); onStepFinish\n * always; onStepError when body throws.\n * - foreach / parallel: emit ALSO per-item events (onItemStart/Finish/Error).\n * - repeat: emit ONLY combinator-level events (no per-iteration events —\n * iteration count is data-dependent and per-item would be misleading).\n *\n * Skip-checked nodes (`state.suspension || pendingError` already set on entry)\n * emit nothing — `.finally()` is the exception.\n */\nexport interface WorkflowObservability {\n onStepStart?: (event: {\n stepId: string;\n type: WorkflowStepType;\n ctx: unknown;\n input: unknown;\n }) => MaybePromise<void>;\n onStepFinish?: (event: {\n stepId: string;\n type: WorkflowStepType;\n ctx: unknown;\n output: unknown;\n durationMs: number;\n suspended: boolean;\n }) => MaybePromise<void>;\n onStepError?: (event: {\n stepId: string;\n type: WorkflowStepType;\n ctx: unknown;\n error: unknown;\n durationMs: number;\n }) => MaybePromise<void>;\n onItemStart?: (event: {\n stepId: string;\n type: \"foreach\" | \"parallel\";\n itemIndex: number | string;\n ctx: unknown;\n input: unknown;\n }) => MaybePromise<void>;\n onItemFinish?: (event: {\n stepId: string;\n type: \"foreach\" | \"parallel\";\n itemIndex: number | string;\n ctx: unknown;\n output: unknown;\n durationMs: number;\n }) => MaybePromise<void>;\n onItemError?: (event: {\n stepId: string;\n type: \"foreach\" | \"parallel\";\n itemIndex: number | string;\n ctx: unknown;\n error: unknown;\n durationMs: number;\n }) => MaybePromise<void>;\n}\n\nexport interface RunOptions {\n /**\n * Step-level checkpoint sink. Called after each successful step body when\n * `checkpointEvery` cadence or `checkpointWhen` predicate fires. Receives a\n * v2 `CheckpointSnapshot` and an `AbortSignal` that aborts on\n * `checkpointTimeout` expiration. Throwing here propagates to the caller\n * as an error — workflow `.catch()` is bypassed for checkpoint failures.\n */\n readonly onCheckpoint?: (snapshot: CheckpointSnapshot, opts: { signal: AbortSignal }) => MaybePromise<void>;\n /**\n * Fire `onCheckpoint` every N executable steps. Mutually exclusive with\n * `checkpointWhen`. Default: `max(1, ceil(executableCount / 4))` —\n * 4 checkpoints across the run, with a floor of every step on tiny pipelines.\n */\n readonly checkpointEvery?: number;\n /**\n * Predicate variant — fire `onCheckpoint` exactly when this returns true.\n * Mutually exclusive with `checkpointEvery`.\n */\n readonly checkpointWhen?: (params: { stepIndex: number; stepId: string; ctx: unknown }) => boolean;\n /**\n * When truthy, deeply freeze the gate / checkpoint snapshot and the\n * `result.warnings` array. Default false. Pass `\"iAcceptThePerformanceCost\"`\n * to bypass `validateRunOptions`' catastrophic-combo guard\n * (freezeSnapshots: true + checkpointEvery: 1 + steps.length >= 8).\n */\n readonly freezeSnapshots?: boolean | \"iAcceptThePerformanceCost\";\n /**\n * Cooperative cancellation signal. Checked at every step boundary inside\n * `execute()` and forwarded to agent calls in `executeAgent`, foreach\n * workers, and nested workflows. When the signal aborts, the workflow\n * tears down to `signal.reason` via the same pending-error path as any\n * other step failure, so `.catch()` handlers still get a chance to\n * observe (or recover from) the abort. `.finally()` bodies still run\n * on the abort path. Unlike `freezeSnapshots`, this option DOES\n * propagate into nested workflows, foreach items, and repeat loops —\n * cancellation should be transitive.\n */\n readonly abortSignal?: AbortSignal;\n /**\n * Maximum ms `onCheckpoint` is allowed to run before its AbortSignal fires.\n * On timeout, a `CheckpointTimeoutError` is raised on the run (catch is\n * bypassed; original error reaches the caller). Default: no timeout.\n */\n readonly checkpointTimeout?: number;\n}\n\n/**\n * Synthetic step id reported when `onCheckpoint` itself throws. Reserved\n * via the construction-time `(type, id)` walk — user step ids may not\n * contain the `::pipeai::` namespace.\n */\nexport const CHECKPOINT_STEP_ID = \"::pipeai::onCheckpoint\" as const;\n\n/**\n * Thrown internally when `onCheckpoint` exceeds `RunOptions.checkpointTimeout`.\n * Surfaces to the caller as the rejection error.\n */\nexport class CheckpointTimeoutError extends Error {\n readonly timeoutMs: number;\n constructor(timeoutMs: number) {\n super(`onCheckpoint exceeded ${timeoutMs}ms timeout`);\n this.name = \"CheckpointTimeoutError\";\n this.timeoutMs = timeoutMs;\n }\n}\n\nfunction resolveFreezeSnapshots(state: RuntimeState): boolean {\n return state.runOptions?.freezeSnapshots ? true : false;\n}\n\n/**\n * Convert a legacy v1 gate snapshot to a v2 gate snapshot. Long-lived\n * storage (Redis-without-TTL, S3, Postgres) should re-serialize via this\n * helper before v0.8.0+ drops v1 acceptance.\n */\nexport function migrateSnapshot(legacy: LegacyGateSnapshotV1): GateSnapshot {\n if (legacy.version !== 1) {\n throw new Error(`migrateSnapshot: expected v1 snapshot, got version ${(legacy as { version: number }).version}`);\n }\n return {\n version: 2,\n kind: \"gate\",\n resumeFromIndex: legacy.resumeFromIndex,\n output: legacy.output,\n gateId: legacy.gateId,\n gatePayload: legacy.gatePayload,\n };\n}\n\n// ── Shared Agent Step Hooks ─────────────────────────────────────────\n\n/**\n * Discriminated union describing one agent invocation's result.\n *\n * - `mode: \"generate\"` — `result` is a `GenerateTextResult`; `.text`, `.output`,\n * `.usage` etc. are synchronous (already-resolved).\n * - `mode: \"stream\"` — `result` is a `StreamTextResult`; the same fields are\n * `Promise`s that you must `await` before reading.\n *\n * The shared field set (`ctx`, `input`) is identical across both modes;\n * narrowing on `mode` is only necessary when you need to touch a\n * mode-specific shape.\n */\nexport type AgentResultParams<TContext, TOutput, TNextOutput> =\n | {\n readonly mode: \"generate\";\n readonly result: GenerateTextResult<ToolSet, OutputType<TNextOutput>>;\n readonly ctx: Readonly<TContext>;\n readonly input: TOutput;\n }\n | {\n readonly mode: \"stream\";\n readonly result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;\n readonly ctx: Readonly<TContext>;\n readonly input: TOutput;\n };\n\nexport interface AgentStepHooks<TContext, TOutput, TNextOutput> {\n /**\n * Transform the agent's result into the next step's input. Fires once per\n * step regardless of generate-vs-stream mode; discriminate on `mode` if you\n * need a mode-specific field. Returning the agent's `result.text` works\n * for both modes (string vs Promise<string>) because `MaybePromise` accepts\n * either.\n *\n * If omitted, the workflow's default extraction is used:\n * - With `agent.output` declared → `extractOutput(result, agent.validateOutput)`\n * - Without `agent.output` → `result.text` (awaited if stream)\n */\n mapResult?: (params: AgentResultParams<TContext, TOutput, TNextOutput>) => MaybePromise<TNextOutput>;\n\n /**\n * Observe the agent's result without changing the step's downstream value.\n * Fires once per step regardless of mode. Use for logging, telemetry,\n * usage accounting, side-effects that should not affect pipeline data\n * flow.\n */\n onResult?: (params: AgentResultParams<TContext, TOutput, TNextOutput>) => MaybePromise<void>;\n\n /**\n * **Stream-mode only.** Override the workflow's default\n * `writer.merge(result.toUIMessageStream())` call so YOU control how the\n * agent's stream reaches the outer workflow's UI message stream. Useful\n * for buffering, transforming, fan-out to multiple writers, or injecting\n * custom UI messages around the agent's output.\n *\n * Has no generate-mode analog because in generate mode there is no stream\n * to merge. If both `handleStream` and `mapResult`/`onResult` are\n * configured, `handleStream` runs first.\n */\n handleStream?: (params: {\n result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;\n writer: UIMessageStreamWriter;\n ctx: Readonly<TContext>;\n input: TOutput;\n }) => MaybePromise<void>;\n}\n\n// ── Step Options ────────────────────────────────────────────────────\n\nexport type StepOptions<TContext, TOutput, TNextOutput> = AgentStepHooks<TContext, TOutput, TNextOutput> & {\n /** Override the default step id (`agent.id`). Required when reusing the same\n * agent across multiple steps in one workflow — the construction-time\n * `(type, id)` walk rejects duplicates. */\n id?: string;\n};\n\n// ── Branch Types ────────────────────────────────────────────────────\n\nexport interface BranchCase<TContext, TOutput, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {\n when?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<boolean>;\n agent: Agent<TContext, TOutput, TNextOutput>;\n}\n\nexport interface BranchSelect<TContext, TOutput, TKeys extends string, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {\n select: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TKeys>;\n agents: Record<TKeys, Agent<TContext, TOutput, TNextOutput>>;\n fallback?: Agent<TContext, TOutput, TNextOutput>;\n /**\n * Diagnostic hook invoked when `select` returns a key that has no matching\n * entry in `agents`. Fires BEFORE `fallback` is applied or\n * `WorkflowBranchError` is thrown, regardless of whether a `fallback` is\n * configured. Useful for logging typos / unexpected classifier output.\n */\n onUnknownKey?: (params: { key: string; availableKeys: TKeys[]; ctx: Readonly<TContext> }) => void;\n}\n\n// ── Result Types ────────────────────────────────────────────────────\n\nexport type WorkflowResult<TOutput> =\n | { readonly status: \"complete\"; readonly output: TOutput; readonly warnings: readonly WorkflowWarning[] }\n | { readonly status: \"suspended\"; readonly snapshot: GateSnapshot; readonly warnings: readonly WorkflowWarning[] };\n\nexport interface WorkflowStreamResult<TOutput> {\n stream: ReadableStream;\n output: Promise<WorkflowResult<TOutput>>; // never rejects on suspension; rejects on real errors\n}\n\n/**\n * Options for `Workflow.stream` / `ResumedWorkflow.stream` /\n * `CheckpointResumedWorkflow.stream`. Forwarded verbatim to the AI SDK's\n * `createUIMessageStream`.\n *\n * Generic over the UI message shape so consumers with a custom\n * `UIMessage<METADATA, DATA_PARTS, TOOLS>` get their narrowed type in\n * `onFinish` / `originalMessages` instead of the unparameterized default.\n *\n * Note: AI SDK's `createUIMessageStream` ALSO accepts an `onStepFinish`\n * (per-token-step) callback. We intentionally do NOT expose it here — there\n * are already two clearer step-finish callbacks at different granularities:\n * - `Agent.onStepFinish` for per-model-call observation, and\n * - `WorkflowObservability.onStepFinish` for per-workflow-step observation.\n * Adding a third one named the same thing on `WorkflowStreamOptions` would\n * be confusing. Reach for one of the two above instead.\n */\nexport interface WorkflowStreamOptions<UI_MESSAGE extends UIMessage = UIMessage> {\n /**\n * Map an unknown error into a user-visible string. Forwarded as-is to\n * `createUIMessageStream`'s `onError`. Returning `string` is required by\n * the AI SDK — the string is what the stream emits to clients.\n */\n onError?: (error: unknown) => string;\n /**\n * Prior `UIMessage`s the stream should continue from. When provided, the\n * AI SDK assumes persistence mode and assigns a response-message id.\n * Used for chat resumption / continuation flows.\n */\n originalMessages?: UI_MESSAGE[];\n /**\n * Fires once the stream finishes, with the full payload the AI SDK\n * delivers: the updated `messages` array, the freshly-emitted\n * `responseMessage`, `isAborted` / `isContinuation` flags, and the\n * `finishReason`. Use this for persistence, analytics, or downstream\n * notification.\n */\n onFinish?: UIMessageStreamOnFinishCallback<UI_MESSAGE>;\n /**\n * Override the response message-id generator. Forwarded to\n * `createUIMessageStream`'s `generateId` option. Useful for deterministic\n * IDs in tests or coordinating with a server-side ID space.\n */\n generateId?: IdGenerator;\n}\n\n// ── Loop Types ──────────────────────────────────────────────────────\n\ntype LoopPredicate<TContext, TOutput> = (params: {\n output: TOutput;\n ctx: Readonly<TContext>;\n iterations: number;\n}) => MaybePromise<boolean>;\n\n// Exactly one of `until` or `while` — never both.\nexport type RepeatOptions<TContext, TOutput> =\n | { until: LoopPredicate<TContext, TOutput>; while?: never; maxIterations?: number }\n | { while: LoopPredicate<TContext, TOutput>; until?: never; maxIterations?: number };\n\n// Extracts the element type from an array type. Resolves to `never` for non-arrays,\n// making foreach uncallable at compile time when the previous step doesn't produce an array.\ntype ElementOf<T> = T extends readonly (infer E)[] ? E : never;\n\n// ── parallel() supporting types ─────────────────────────────────────\n\n/** A target for a `parallel()` branch — agent or sealed workflow. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ParallelTarget<TContext, TInput> =\n | Agent<TContext, TInput, any>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | SealedWorkflow<TContext, TInput, any>;\n\n/** Extract the output type of a single parallel branch target. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype BranchOutput<T> = T extends Agent<any, any, infer O>\n ? O\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : T extends SealedWorkflow<any, any, infer O>\n ? O\n : never;\n\n/** Output shape for the record form: `{ [K]: BranchOutput<T[K]> }`. */\nexport type ParallelOutputRecord<T extends Record<string, unknown>> = {\n [K in keyof T]: BranchOutput<T[K]>;\n};\n\n/** Output shape for the tuple form: `[O1, O2, ...]`. */\nexport type ParallelOutputTuple<T extends ReadonlyArray<unknown>> = {\n [K in keyof T]: BranchOutput<T[K]>;\n};\n\nexport interface ParallelOptions<TContext> {\n /** Override the default step id. Default: `parallel:record` or `parallel:tuple`. */\n id?: string;\n /**\n * Max branches in flight at any moment. Default: `min(branches.length, 5)`.\n * Pass `Infinity` (or `branches.length`) for full fan-out on >5-branch calls\n * — the default caps at 5 to protect against rate limits and emits a\n * one-time warn when the cap kicks in.\n */\n concurrency?: number;\n /**\n * Per-branch error handler. On the no-suspension path, called once per\n * rejected branch in index order after all settle. Return a value to\n * substitute, return `Workflow.SKIP` to leave the slot undefined (record\n * form only — tuple SKIP would shift indices), or rethrow to abort the\n * parallel.\n *\n * **Bypassed entirely on the suspension path** (any branch hit a nested\n * gate). See README's \"Suspension under `parallel()`\" section.\n */\n onError?: (params: {\n error: unknown;\n /** Branch key in the record form; `undefined` in the tuple form. */\n key?: string;\n /** Branch index in the tuple form; `undefined` in the record form. */\n index?: number;\n ctx: Readonly<TContext>;\n }) => unknown | typeof Workflow.SKIP | Promise<unknown | typeof Workflow.SKIP>;\n}\n\n// ── Schema type (structural — works with Zod, Valibot, ArkType, etc.) ──\n\ninterface SchemaWithParse<T = unknown> {\n parse(data: unknown): T;\n}\n\n// ── Step Node ───────────────────────────────────────────────────────\n\n// `nestedWorkflow` is consumed by the recursive `stepShapeHash` walk; runtime\n// execution goes through the `execute` closure. `category` drives\n// observability event typing — keeps a single `type: \"step\"` variant rather\n// than splitting branch/foreach/repeat/parallel/nested into their own unions.\ntype StepCategory = \"step\" | \"nested\" | \"branch\" | \"foreach\" | \"repeat\" | \"parallel\";\n\ntype StepNode =\n | {\n readonly type: \"step\";\n readonly id: string;\n readonly execute: (state: RuntimeState) => MaybePromise<void>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly nestedWorkflow?: SealedWorkflow<any, any, any, any>;\n /** Disambiguates observability events. Default `\"step\"`. */\n readonly category?: StepCategory;\n }\n | { readonly type: \"catch\"; readonly id: string; readonly catchFn: (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown> }\n | { readonly type: \"finally\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void> }\n | { readonly type: \"gate\"; readonly id: string; readonly payload: (state: RuntimeState) => MaybePromise<unknown>; readonly schema?: SchemaWithParse; readonly condition?: (state: RuntimeState) => MaybePromise<boolean>; readonly merge?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown> };\n\n/**\n * Maps a step node's category (or non-step type) to the observability event\n * `type` field. Drives `WorkflowStepType` reporting.\n */\nfunction getObservabilityType(node: StepNode): WorkflowStepType {\n if (node.type !== \"step\") return node.type;\n return (node.category ?? \"step\") as WorkflowStepType;\n}\n\n/**\n * Returns the nested workflow(s) attached to a step node. The exhaustive\n * switch (no `default`) makes adding a new StepNode variant a TS error.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getNestedWorkflows(node: StepNode): readonly SealedWorkflow<any, any, any, any>[] {\n switch (node.type) {\n case \"step\": return node.nestedWorkflow ? [node.nestedWorkflow] : [];\n case \"gate\":\n case \"catch\":\n case \"finally\": return [];\n }\n}\n\ninterface RuntimeState {\n ctx: unknown;\n output: unknown;\n mode: \"generate\" | \"stream\";\n writer?: UIMessageStreamWriter;\n // Only gates set `suspension`.\n suspension?: GateSnapshot;\n warnings?: WorkflowWarning[];\n checkpointFailed?: boolean;\n // Same RunOptions seen by execute(); reset to undefined inside nested\n // workflows and omitted from foreach itemState so per-run config doesn't\n // leak into nested execution.\n runOptions?: RunOptions;\n // Cooperative cancellation. Held on state separately from runOptions\n // because — unlike freezeSnapshots — abortSignal SHOULD propagate into\n // nested workflows and foreach items.\n abortSignal?: AbortSignal;\n}\n\n// Pending error tracked through a single execute() pass. The `source`\n// discriminant drives the precedence tail\n// (checkpointFailed > finally-wrap > step > suspension) and the onStepError\n// type mapping below.\ntype PendingError = {\n error: unknown;\n stepId: string;\n source: \"step\" | \"finally\" | \"catch\" | \"onCheckpoint\";\n};\n\n/**\n * Map `PendingError.source` to the `WorkflowStepType` value that\n * `onStepError` should report. `onCheckpoint` is mapped to `\"step\"`,\n * consistent with the `{ stepId: CHECKPOINT_STEP_ID, type: \"step\" }` contract.\n * Exhaustive switch — adding a new `source` variant is a compile error.\n */\nfunction pendingErrorSourceToStepType(source: PendingError[\"source\"]): WorkflowStepType {\n switch (source) {\n case \"step\": return \"step\";\n case \"finally\": return \"finally\";\n case \"catch\": return \"catch\";\n case \"onCheckpoint\": return \"step\";\n }\n}\n\n/**\n * Invoke `opts.onCheckpoint(snapshot, { signal })` with optional timeout via\n * AbortSignal. Throws on onCheckpoint failure or timeout\n * (CheckpointTimeoutError). The run loop catches and sets\n * `state.checkpointFailed`, which routes through the precedence tail\n * (checkpointFailed > finally-wrap > original-step > suspension).\n */\nasync function emitCheckpoint(\n state: RuntimeState,\n opts: RunOptions,\n resumeFromIndex: number,\n stepShapeHash: string,\n): Promise<void> {\n if (!opts.onCheckpoint) return;\n const snap: CheckpointSnapshot = {\n version: 2,\n kind: \"checkpoint\",\n resumeFromIndex,\n output: state.output,\n stepShapeHash,\n };\n if (resolveFreezeSnapshots(state)) deepFreeze(snap);\n\n const controller = new AbortController();\n if (opts.checkpointTimeout !== undefined) {\n const timeoutMs = opts.checkpointTimeout;\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const callPromise = Promise.resolve(opts.onCheckpoint(snap, { signal: controller.signal }));\n const timeoutPromise = new Promise<never>((_, reject) => {\n controller.signal.addEventListener(\n \"abort\",\n () => reject(new CheckpointTimeoutError(timeoutMs)),\n { once: true },\n );\n });\n // Swallow loser to avoid unhandled rejection on the race.\n callPromise.catch(() => {});\n timeoutPromise.catch(() => {});\n await Promise.race([callPromise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId);\n }\n } else {\n await opts.onCheckpoint(snap, { signal: controller.signal });\n }\n}\n\n// One-time stream-mode warning when a gate fires with options.onError set.\nlet warnedStreamOnErrorOnSuspend = false;\n\n/**\n * @internal — test-only reset of the one-time stream-mode warn dedup.\n */\nexport function __resetStreamOnErrorOnSuspendWarnForTests(): void {\n warnedStreamOnErrorOnSuspend = false;\n}\n\n/**\n * Push an entry onto state.warnings, allocating the array lazily on first use.\n * Centralizes the `(state.warnings ??= []).push({source, stepId, error})` idiom.\n */\nfunction pushWarning(\n state: RuntimeState,\n source: WorkflowWarning[\"source\"],\n stepId: string,\n error: unknown,\n): void {\n (state.warnings ??= []).push({ source, stepId, error });\n}\n\n/**\n * Demote a pendingError into a warning. Used everywhere a new pendingError is\n * about to overwrite the prior one (finally/catch errors after a step error,\n * abort promoted over an in-flight error, suspension-wins tail).\n */\nfunction demotePendingError(state: RuntimeState, pe: PendingError): void {\n pushWarning(state, pe.source, pe.stepId, pe.error);\n}\n\n/**\n * Emit the one-shot stream-onError-on-suspend warning if applicable.\n */\nfunction maybeWarnStreamOnErrorOnSuspend(\n result: WorkflowResult<unknown>,\n options: { onError?: (error: unknown) => string } | undefined,\n): void {\n if (result.status !== \"suspended\" || !options?.onError || warnedStreamOnErrorOnSuspend) return;\n warnedStreamOnErrorOnSuspend = true;\n console.warn(\n \"pipeai: stream() with options.onError suspended at a gate — onError will NOT be invoked for suspension. Discriminate via the resolved output Promise.\"\n );\n}\n\n// ── Sealed Workflow (returned by finally — execution only) ───────────\n\nexport class SealedWorkflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> {\n readonly id?: string;\n protected readonly steps: ReadonlyArray<StepNode>;\n protected readonly observability?: WorkflowObservability;\n // Memoized — see ensureDuplicateCheck().\n private duplicateCheckPassed = false;\n // Memoized lazily per terminal instance — build pipelines once at module\n // load and re-run via generate() to amortize.\n private _cachedExecutableStepCount?: number;\n private _cachedStepShapeHash?: string;\n\n protected constructor(steps: ReadonlyArray<StepNode>, id?: string, observability?: WorkflowObservability) {\n this.steps = steps;\n this.id = id;\n this.observability = observability;\n }\n\n // ── Construction-time validation (memoized per terminal instance) ────\n\n /**\n * Walk the step list once per terminal instance. Rejects:\n * - Duplicate `(type, id)` pairs.\n * - User step ids containing the reserved `::pipeai::` namespace\n * (CHECKPOINT_STEP_ID lives there).\n */\n private ensureDuplicateCheck(): void {\n if (this.duplicateCheckPassed) return;\n const seen = new Map<string, number>();\n for (let i = 0; i < this.steps.length; i++) {\n const node = this.steps[i];\n if (node.id.includes(\"::pipeai::\")) {\n throw new Error(\n `Workflow: step id \"${node.id}\" uses the reserved \"::pipeai::\" namespace at index ${i}.`\n );\n }\n const key = `${node.type}:${node.id}`;\n const prior = seen.get(key);\n if (prior !== undefined) {\n throw new Error(\n `Workflow: duplicate (${node.type}, \"${node.id}\") at indices ${prior} and ${i}. ` +\n `Pass an explicit \\`{ id }\\` (e.g. for back-to-back \\`branch(...)\\` or \\`foreach(agentX).foreach(agentX)\\`) to disambiguate.`\n );\n }\n seen.set(key, i);\n }\n this.duplicateCheckPassed = true;\n }\n\n // ── shape-hash + RunOptions validation ────────────────────────\n\n /**\n * Count of executable nodes — i.e. NOT `catch` or `finally`. Drives\n * checkpoint auto-cadence so adding cleanup steps doesn't surprise users\n * with extra fires. `branch`/`foreach`/`repeat`/`parallel`/`nested` are all\n * `type: \"step\"` internally and count as executable.\n */\n protected get cachedExecutableStepCount(): number {\n if (this._cachedExecutableStepCount !== undefined) return this._cachedExecutableStepCount;\n let n = 0;\n for (const s of this.steps) {\n if (s.type !== \"catch\" && s.type !== \"finally\") n++;\n }\n this._cachedExecutableStepCount = n;\n return n;\n }\n\n /** @internal — used by `computeStepShapeHash` to descend nested workflows. */\n getStepsForShapeHash(): ReadonlyArray<StepNode> {\n return this.steps;\n }\n\n protected get cachedStepShapeHash(): string {\n if (this._cachedStepShapeHash !== undefined) return this._cachedStepShapeHash;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const getNested = (node: any) => getNestedWorkflows(node as StepNode) as unknown as readonly { id?: string; getStepsForShapeHash(): ReadonlyArray<{ type: string; id: string }> }[];\n this._cachedStepShapeHash = computeStepShapeHash(\n this.steps as unknown as ReadonlyArray<{ type: string; id: string }>,\n getNested,\n );\n return this._cachedStepShapeHash;\n }\n\n /**\n * Validate user-provided RunOptions before a run begins. Throws on\n * outright errors and on the loud-disaster combo (`freezeSnapshots: true\n * + checkpointEvery: 1` on a workflow of 8+ steps). Warns once on the\n * merely-suspicious combo (`freezeSnapshots: true + cadence <= 2`).\n * Plan-of-record: catastrophic combo escape via the\n * `\"iAcceptThePerformanceCost\"` literal.\n */\n protected validateRunOptions(opts: RunOptions | undefined): void {\n if (!opts) return;\n // checkpoint-specific validation only applies when onCheckpoint is set.\n if (!opts.onCheckpoint) return;\n if (opts.checkpointEvery !== undefined && opts.checkpointWhen !== undefined) {\n throw new Error(\"RunOptions: checkpointEvery and checkpointWhen are mutually exclusive\");\n }\n if (opts.checkpointEvery !== undefined && (!Number.isInteger(opts.checkpointEvery) || opts.checkpointEvery < 1)) {\n throw new Error(`RunOptions: checkpointEvery must be a positive integer, got ${opts.checkpointEvery}`);\n }\n if (opts.checkpointTimeout !== undefined && (!Number.isFinite(opts.checkpointTimeout) || opts.checkpointTimeout < 1)) {\n throw new Error(`RunOptions: checkpointTimeout must be a finite positive number (ms), got ${opts.checkpointTimeout}`);\n }\n const length = this.cachedExecutableStepCount;\n const cadence = opts.checkpointEvery ?? Math.max(1, Math.ceil(length / 4));\n if (opts.freezeSnapshots && opts.freezeSnapshots !== \"iAcceptThePerformanceCost\" && cadence === 1 && length >= 8) {\n throw new Error(\n `freezeSnapshots+checkpointEvery:1 on a ${length}-step workflow is reliably catastrophic. ` +\n `Set checkpointEvery >= 5, freezeSnapshots: false, or pass \"iAcceptThePerformanceCost\".`\n );\n }\n if (opts.freezeSnapshots && cadence <= 2) {\n warnOnce(\n \"pipeai:freezeSnapshots-low-cadence\",\n \"pipeai: freezeSnapshots+checkpointEvery<=2 compounds graph-walk cost.\",\n );\n }\n }\n\n // ── Observability helpers ─────────────────────────────────────\n\n /**\n * Fire an observability hook safely. Returns `undefined` synchronously when\n * no hook is registered — avoiding the promise wrapper + microtask that an\n * async function would unconditionally allocate on every step boundary.\n *\n * On hook throw:\n * - non-`onStepError` hooks: warning pushed + console.error.\n * - `onStepError`: throw is propagated as a return value; the run loop\n * attaches it as `cause` on the original step error.\n *\n * Returns the hook's thrown error if any; undefined otherwise. Callers\n * `await` the result — `await undefined` is sync, so the no-hook path\n * stays allocation-free.\n */\n protected fireHook<\n K extends keyof WorkflowObservability,\n E extends Parameters<NonNullable<WorkflowObservability[K]>>[0],\n >(\n state: RuntimeState,\n name: K,\n event: E,\n ): MaybePromise<unknown> {\n const hook = this.observability?.[name];\n if (!hook) return undefined;\n return this.fireHookSlow(state, name, event, hook);\n }\n\n private async fireHookSlow<K extends keyof WorkflowObservability>(\n state: RuntimeState,\n name: K,\n event: unknown,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n hook: any,\n ): Promise<unknown> {\n try {\n await hook(event);\n return undefined;\n } catch (e) {\n if (name !== \"onStepError\") {\n const stepId = (event as { stepId: string }).stepId;\n pushWarning(state, name as WorkflowWarning[\"source\"], stepId, e);\n // eslint-disable-next-line no-console\n console.error(`pipeai: ${name} hook threw for stepId \"${stepId}\":`, e);\n }\n return e;\n }\n }\n\n // ── Execution ─────────────────────────────────────────────────\n\n async generate(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, opts?: RunOptions]\n : [input: TInput, opts?: RunOptions]\n ): Promise<WorkflowResult<TOutput>> {\n this.ensureDuplicateCheck();\n const input = args[0];\n const opts = args[1] as RunOptions | undefined;\n this.validateRunOptions(opts);\n const state: RuntimeState = {\n ctx,\n output: input,\n mode: \"generate\",\n runOptions: opts,\n abortSignal: opts?.abortSignal,\n };\n\n await this.execute(state, 0, opts);\n\n return this.buildResult(state);\n }\n\n stream<UI_MESSAGE extends UIMessage = UIMessage>(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n : [input: TInput, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n ): WorkflowStreamResult<TOutput> {\n this.ensureDuplicateCheck();\n const input = args[0];\n const options = args[1] as WorkflowStreamOptions<UI_MESSAGE> | undefined;\n const opts = args[2] as RunOptions | undefined;\n this.validateRunOptions(opts);\n const abortSignal = opts?.abortSignal;\n\n let resolveOutput!: (value: WorkflowResult<TOutput>) => void;\n let rejectOutput!: (error: unknown) => void;\n const outputPromise = new Promise<WorkflowResult<TOutput>>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n\n // Prevent unhandled rejection warning if the consumer never awaits `output`.\n outputPromise.catch(() => {});\n\n const stream = createUIMessageStream<UI_MESSAGE>({\n execute: async ({ writer }) => {\n const state: RuntimeState = {\n ctx,\n output: input,\n mode: \"stream\",\n writer,\n runOptions: opts,\n abortSignal,\n };\n\n try {\n await this.execute(state, 0, opts);\n const result = this.buildResult(state);\n maybeWarnStreamOnErrorOnSuspend(result, options);\n resolveOutput(result);\n } catch (error) {\n rejectOutput(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n ...(options?.originalMessages ? { originalMessages: options.originalMessages } : {}),\n ...(options?.generateId ? { generateId: options.generateId } : {}),\n });\n\n return {\n stream,\n output: outputPromise,\n };\n }\n\n // Helper — converts terminal RuntimeState into a WorkflowResult; freezes\n // snapshot + warnings if requested via runOptions.\n protected buildResult(state: RuntimeState): WorkflowResult<TOutput> {\n const warnings = state.warnings ?? [];\n if (state.suspension && resolveFreezeSnapshots(state)) {\n deepFreeze(warnings);\n }\n if (state.suspension) {\n return { status: \"suspended\", snapshot: state.suspension, warnings };\n }\n return { status: \"complete\", output: state.output as TOutput, warnings };\n }\n\n // ── Internal: execute pipeline ────────────────────────────────\n\n protected async execute(\n state: RuntimeState,\n startIndex: number = 0,\n opts?: RunOptions,\n initialError: PendingError | null = null,\n ): Promise<void> {\n if (this.steps.length === 0) {\n throw new Error(\"Workflow has no steps. Add at least one step before calling generate() or stream().\");\n }\n\n // Make sure runOptions is plumbed even if the caller didn't initialize state.\n if (opts !== undefined && state.runOptions === undefined) {\n state.runOptions = opts;\n }\n\n // Hoisted once per run — the numeric cadence form has no per-step input,\n // so recomputing it per iteration was pure overhead.\n const ckptCadence = opts?.onCheckpoint && opts.checkpointWhen === undefined\n ? (opts.checkpointEvery ?? Math.max(1, Math.ceil(this.cachedExecutableStepCount / 4)))\n : 0;\n\n // `initialError` lets callers (e.g. ResumedWorkflow.stream) seed the\n // pipeline already-in-error so a pre-execute failure (schema.parse,\n // merge throw) flows through downstream `.catch()` like any other step\n // failure instead of escaping synchronously.\n let pendingError: PendingError | null = initialError;\n\n // Tracks whether the abort signal has already been promoted into\n // pendingError in this execute() pass. On first observation we discard\n // any in-progress suspension (caller asked to stop) and preserve any\n // prior step error as a warning. Subsequent iterations only re-promote\n // if a downstream catch cleared pendingError — the platform semantics\n // of AbortSignal.aborted (sticky once true) say the workflow shouldn't\n // resume mid-pipeline just because a catch swallowed one observation.\n let abortPromoted = false;\n const makeAbortError = (signal: AbortSignal): PendingError => ({\n error: signal.reason ?? new Error(\"Workflow aborted\"),\n stepId: \"abort\",\n source: \"step\",\n });\n\n for (let i = startIndex; i < this.steps.length; i++) {\n // Abort checkpoint — runs at every iteration boundary, before any\n // node dispatch, so finally/catch nodes that come AFTER the abort\n // still get to run (cleanup + recovery contract).\n if (state.abortSignal?.aborted) {\n if (!abortPromoted) {\n abortPromoted = true;\n state.suspension = undefined;\n if (pendingError) demotePendingError(state, pendingError);\n pendingError = makeAbortError(state.abortSignal);\n } else if (!pendingError) {\n // A catch handler swallowed the abort. Re-promote so downstream\n // steps still see the signal as the \"stop\" condition the caller\n // requested.\n pendingError = makeAbortError(state.abortSignal);\n }\n }\n\n const node = this.steps[i];\n\n if (node.type === \"finally\") {\n const stepId = node.id;\n const finStart = performance.now();\n await this.fireHook(state, \"onStepStart\", { stepId, type: \"finally\", ctx: state.ctx, input: state.output });\n try {\n await node.execute(state);\n await this.fireHook(state, \"onStepFinish\", {\n stepId, type: \"finally\", ctx: state.ctx, output: state.output,\n durationMs: performance.now() - finStart, suspended: false,\n });\n } catch (e) {\n await this.fireHook(state, \"onStepError\", {\n stepId, type: \"finally\", ctx: state.ctx, error: e,\n durationMs: performance.now() - finStart,\n });\n // Multi-error preservation: never silently overwrite a prior pendingError —\n // push it to warnings before promoting this finally error.\n if (pendingError) demotePendingError(state, pendingError);\n pendingError = { error: e, stepId, source: \"finally\" };\n }\n continue;\n }\n\n if (node.type === \"catch\") {\n // .catch() bypassed on suspension AND on checkpoint failure (checkpoint failure propagates to caller).\n if (state.suspension || !pendingError || state.checkpointFailed) continue;\n const stepId = node.id;\n const cStart = performance.now();\n await this.fireHook(state, \"onStepStart\", { stepId, type: \"catch\", ctx: state.ctx, input: state.output });\n try {\n state.output = await node.catchFn({\n error: pendingError.error,\n ctx: state.ctx,\n lastOutput: state.output,\n stepId: pendingError.stepId,\n });\n pendingError = null;\n await this.fireHook(state, \"onStepFinish\", {\n stepId, type: \"catch\", ctx: state.ctx, output: state.output,\n durationMs: performance.now() - cStart, suspended: false,\n });\n } catch (e) {\n await this.fireHook(state, \"onStepError\", {\n stepId, type: \"catch\", ctx: state.ctx, error: e,\n durationMs: performance.now() - cStart,\n });\n if (pendingError) demotePendingError(state, pendingError);\n pendingError = { error: e, stepId, source: \"catch\" };\n }\n continue;\n }\n\n // Skip remaining non-finally/non-catch nodes when suspended or in error state.\n if (state.suspension || pendingError) continue;\n\n if (node.type === \"gate\") {\n // Capture errors from condition/payload callbacks into pendingError so\n // they route through the workflow's .catch() pipeline like any other\n // step error. Without this, a throwing gate callback escapes execute()\n // entirely and bypasses all downstream catch nodes.\n const stepId = node.id;\n const gStart = performance.now();\n await this.fireHook(state, \"onStepStart\", { stepId, type: \"gate\", ctx: state.ctx, input: state.output });\n try {\n if (node.condition && !(await node.condition(state))) {\n // Cond returned false — skip the gate. Fire onStepFinish({ suspended: false }).\n await this.fireHook(state, \"onStepFinish\", {\n stepId, type: \"gate\", ctx: state.ctx, output: state.output,\n durationMs: performance.now() - gStart, suspended: false,\n });\n continue;\n }\n const snapshot: GateSnapshot = {\n version: 2,\n kind: \"gate\",\n resumeFromIndex: i,\n output: state.output,\n gateId: node.id,\n gatePayload: await node.payload(state),\n };\n state.suspension = snapshot;\n if (resolveFreezeSnapshots(state)) deepFreeze(snapshot);\n await this.fireHook(state, \"onStepFinish\", {\n stepId, type: \"gate\", ctx: state.ctx, output: state.output,\n durationMs: performance.now() - gStart, suspended: true,\n });\n } catch (e) {\n pendingError = { error: e, stepId: node.id, source: \"step\" };\n }\n continue;\n }\n\n // type === \"step\" — driven by `category` for observability type reporting.\n const obsType = getObservabilityType(node);\n const stepId = node.id;\n const sStart = performance.now();\n const stepInput = state.output;\n await this.fireHook(state, \"onStepStart\", { stepId, type: obsType, ctx: state.ctx, input: stepInput });\n try {\n await node.execute(state);\n await this.fireHook(state, \"onStepFinish\", {\n stepId, type: obsType, ctx: state.ctx, output: state.output,\n durationMs: performance.now() - sStart, suspended: false,\n });\n } catch (e) {\n pendingError = { error: e, stepId: node.id, source: \"step\" };\n // onStepError special-cases: if the hook throws, attach the obsError as\n // `cause` on the original step error so the original reaches the caller\n // with the failure trail attached. Other hooks' throws become warnings.\n const obsError = await this.fireHook(state, \"onStepError\", {\n stepId, type: obsType, ctx: state.ctx, error: e,\n durationMs: performance.now() - sStart,\n });\n if (obsError !== undefined && typeof e === \"object\" && e !== null) {\n try {\n (e as { cause?: unknown }).cause = obsError;\n } catch {\n // Some objects are frozen / non-extensible — ignore.\n }\n }\n }\n\n // Defensive invariant: only gate nodes set state.suspension, and\n // executeNestedWorkflow/foreach clear inner suspension before rethrowing.\n // A non-undefined value here means a coding bug bypassed that contract.\n // The cast is needed because TS narrowed suspension to undefined at the\n // top-of-loop falsy check and doesn't know the await may have mutated it.\n const leaked = (state as { suspension?: GateSnapshot }).suspension;\n if (leaked) {\n state.suspension = undefined;\n throw new Error(`internal: suspension bubbled from non-gate step \"${node.id}\" (gate \"${leaked.gateId}\").`);\n }\n\n // Emit a checkpoint after a successful step body. Skipped on pendingError\n // (the step threw — no clean state to snapshot) or on suspension (gate\n // already won). Numeric `checkpointEvery` (default: max(1, ceil(count/4)))\n // uses the loop-hoisted `ckptCadence`; predicate form runs per step.\n if (!pendingError && !state.suspension && opts?.onCheckpoint) {\n const shouldCheckpoint = opts.checkpointWhen\n ? opts.checkpointWhen({ stepIndex: i, stepId: node.id, ctx: state.ctx })\n : (i + 1) % ckptCadence === 0;\n if (shouldCheckpoint) {\n const ckptStart = performance.now();\n try {\n await emitCheckpoint(\n state,\n opts,\n i + 1,\n this.cachedStepShapeHash,\n );\n } catch (e) {\n pendingError = { error: e, stepId: CHECKPOINT_STEP_ID, source: \"onCheckpoint\" };\n state.checkpointFailed = true;\n // Route through onStepError with the synthetic CHECKPOINT_STEP_ID\n // and type: \"step\" (matches pendingErrorSourceToStepType(\"onCheckpoint\")).\n await this.fireHook(state, \"onStepError\", {\n stepId: CHECKPOINT_STEP_ID, type: \"step\", ctx: state.ctx, error: e,\n durationMs: performance.now() - ckptStart,\n });\n }\n }\n }\n }\n\n // Tail — mutually exclusive branches.\n // Precedence: checkpointFailed > finally-wrap > original-step > suspension.\n if (pendingError && !state.suspension) {\n if (state.checkpointFailed) {\n // Checkpoint error reaches caller bare; finally errors get console.warn\n // because the rejection path can't carry warnings.\n const warningsArr = state.warnings ?? [];\n const checkpointError = pendingError.source === \"onCheckpoint\"\n ? pendingError.error\n : warningsArr.find(w => w.source === \"onCheckpoint\")?.error;\n const finallyErrors = warningsArr.filter(w => w.source === \"finally\").map(w => w.error);\n const all = pendingError.source === \"finally\"\n ? [...finallyErrors, pendingError.error]\n : finallyErrors;\n if (all.length > 0) {\n console.warn(\n `pipeai: ${all.length} .finally() error(s) suppressed by checkpoint-failure precedence:`,\n all,\n );\n }\n throw checkpointError ?? pendingError.error;\n }\n const isFinallyPath = pendingError.source === \"finally\"\n || (state.warnings?.some(w => w.source === \"finally\") ?? false);\n if (isFinallyPath) {\n // Source order: warnings were pushed in the order errors occurred (step\n // before finally, earlier finally before later finally), so this preserves\n // the chronological sequence the plan specifies. Single-error case included\n // — once any finally is in the picture, the contract is AggregateError.\n const all = [...(state.warnings ?? []).map(w => w.error), pendingError.error];\n throw new AggregateError(all, `Workflow failed with ${all.length} error(s) from .finally() bodies`);\n }\n throw pendingError.error;\n } else if (pendingError && state.suspension) {\n // Suspension wins; preserve the step error as a warning.\n demotePendingError(state, pendingError);\n // Also emit onStepError so observers can see the loss.\n try {\n await this.observability?.onStepError?.({\n stepId: pendingError.stepId,\n type: pendingErrorSourceToStepType(pendingError.source),\n ctx: state.ctx,\n error: pendingError.error,\n durationMs: 0,\n });\n } catch (obsError) {\n pushWarning(state, \"onStepError\", pendingError.stepId, obsError);\n }\n pendingError = null;\n }\n }\n\n // ── Internal: execute a nested workflow within a step/loop ─────\n // Defined on SealedWorkflow (not Workflow) because TypeScript's protected\n // access rules only allow calling workflow.execute() from the same class.\n //\n // Contract: clears any inner suspension before re-throwing as\n // NestedGateUnsupportedError. The outer execute() therefore never observes\n // a leaked `state.suspension` from non-gate nodes (defensive invariant).\n\n protected async executeNestedWorkflow(\n state: RuntimeState,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n workflow: SealedWorkflow<TContext, unknown, unknown, any>,\n ): Promise<void> {\n // RunOptions is run-scoped — child never inherits parent's runOptions.\n // state.warnings IS propagated (asymmetric on purpose: telemetry > config).\n const savedRunOptions = state.runOptions;\n state.runOptions = undefined;\n try {\n await workflow.execute(state);\n } finally {\n state.runOptions = savedRunOptions;\n }\n if (state.suspension) {\n const gateId = state.suspension.gateId;\n state.suspension = undefined; // clear before throw (load-bearing invariant 1)\n throw new NestedGateUnsupportedError(gateId, workflow.id);\n }\n }\n\n // ── Internal: execute an agent within a step/branch ───────────\n // In stream mode, output extraction awaits the full stream before returning.\n // Streaming benefits the client (incremental output), not pipeline throughput —\n // each step still runs sequentially.\n\n protected async executeAgent<TAgentInput, TNextOutput>(\n state: RuntimeState,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agent: Agent<TContext, any, TNextOutput>,\n ctx: TContext,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: AgentStepHooks<TContext, any, TNextOutput>,\n ): Promise<void> {\n const input = state.output as TAgentInput;\n const hasStructuredOutput = agent.hasOutput;\n\n const abortSignal = state.abortSignal;\n const agentCallOpts = abortSignal ? { abortSignal } : undefined;\n\n if (state.mode === \"stream\" && state.writer) {\n const writer = state.writer;\n // Run inside writer context so tools accessed via getActiveWriter() pick it up.\n await runWithWriter(writer, async () => {\n const result = await (agent.stream as (ctx: TContext, input: unknown, opts?: { abortSignal?: AbortSignal }) => Promise<StreamTextResult<ToolSet, OutputType<TNextOutput>>>)(ctx, state.output, agentCallOpts);\n\n if (options?.handleStream) {\n await options.handleStream({ result, writer, ctx, input });\n } else {\n writer.merge(result.toUIMessageStream());\n }\n\n const hookParams = {\n mode: \"stream\",\n result,\n ctx: ctx as Readonly<TContext>,\n input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as AgentResultParams<TContext, any, TNextOutput>;\n\n if (options?.onResult) {\n await options.onResult(hookParams);\n }\n\n if (options?.mapResult) {\n state.output = await options.mapResult(hookParams);\n } else {\n state.output = await extractOutput(result, hasStructuredOutput, agent.validateOutput);\n }\n });\n } else {\n const result = await (agent.generate as (ctx: TContext, input: unknown, opts?: { abortSignal?: AbortSignal }) => Promise<GenerateTextResult<ToolSet, OutputType<TNextOutput>>>)(ctx, state.output, agentCallOpts);\n\n const hookParams = {\n mode: \"generate\",\n result,\n ctx: ctx as Readonly<TContext>,\n input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as AgentResultParams<TContext, any, TNextOutput>;\n\n if (options?.onResult) {\n await options.onResult(hookParams);\n }\n\n if (options?.mapResult) {\n state.output = await options.mapResult(hookParams);\n } else {\n state.output = await extractOutput(result, hasStructuredOutput, agent.validateOutput);\n }\n }\n }\n\n // ── Gate: load persisted state for resumption ──────────────────\n\n loadState<K extends string & keyof TGates>(\n gateId: K,\n snapshot: WorkflowSnapshot,\n ): ResumedWorkflow<TContext, TGates[K], TOutput> {\n // Reject checkpoint snapshots — they belong to resumeFrom(), not loadState().\n if (snapshot.version === 2 && snapshot.kind === \"checkpoint\") {\n throw new Error(`loadState: received a checkpoint snapshot. Use resumeFrom() for checkpoint resume; loadState() is for gates.`);\n }\n const gateLike = snapshot as GateSnapshot | LegacyGateSnapshotV1;\n if (gateLike.gateId !== gateId) {\n throw new Error(\n `loadState: gate ID mismatch — expected \"${gateId}\" but snapshot has \"${gateLike.gateId}\".`\n );\n }\n this.ensureDuplicateCheck();\n const gateIndex = this.findGateIndex(gateLike);\n const gateNode = this.steps[gateIndex] as Extract<StepNode, { type: \"gate\" }>;\n return new ResumedWorkflow<TContext, TGates[K], TOutput>(this.steps, gateIndex + 1, {\n mode: \"gate\",\n schema: gateNode.schema as SchemaWithParse<TGates[K]> | undefined,\n mergeFn: gateNode.merge,\n priorOutput: gateLike.output,\n snapshot: gateLike,\n observability: this.observability,\n });\n }\n\n // ── Checkpoint resume ──────────────────────────────────────────\n\n /**\n * Resume from a checkpoint snapshot. Validates the step-shape hash unless\n * `{ skipShapeCheck: true }` is passed. Throws on:\n * - gate snapshots (use `loadState` instead)\n * - missing/corrupted `stepShapeHash`\n * - shape mismatch (unless skipped)\n * - out-of-bounds `resumeFromIndex`\n * - 0-step workflow (structural invariant)\n *\n * Returns a `CheckpointResumedWorkflow` whose `generate(ctx, opts?)` takes\n * NO response arg — the state is seeded from the snapshot's output. The\n * matching gate-resume path (`loadState`) keeps the `response` arg.\n */\n resumeFrom(\n snapshot: WorkflowSnapshot,\n options?: { skipShapeCheck?: boolean },\n ): CheckpointResumedWorkflow<TContext, TOutput> {\n // Detect gate snapshots (v2 with kind=\"gate\" OR legacy v1 with gateId).\n const isGate = (snapshot.version === 2 && snapshot.kind === \"gate\")\n || (snapshot.version === 1 && (snapshot as LegacyGateSnapshotV1).gateId !== undefined);\n if (isGate) {\n throw new Error(`resumeFrom: received a gate snapshot. Use loadState() for gate resume; resumeFrom() is for checkpoints.`);\n }\n if (this.steps.length === 0) {\n throw new Error(\"resumeFrom: workflow has no steps; snapshot is structurally invalid.\");\n }\n const ckpt = snapshot as CheckpointSnapshot;\n const idx = ckpt.resumeFromIndex;\n if (!Number.isInteger(idx) || idx < 0 || idx > this.steps.length) {\n throw new Error(`resumeFrom: resumeFromIndex (${idx}) out of bounds for ${this.steps.length}-step workflow.`);\n }\n if (!options?.skipShapeCheck) {\n if (!ckpt.stepShapeHash) {\n throw new Error(\"resumeFrom: snapshot missing stepShapeHash; corrupted or hand-crafted.\");\n }\n this.ensureDuplicateCheck();\n if (this.cachedStepShapeHash !== ckpt.stepShapeHash) {\n throw new Error(\"resumeFrom: workflow shape mismatch; cannot safely resume. Pass { skipShapeCheck: true } to override.\");\n }\n } else {\n this.ensureDuplicateCheck();\n }\n return new CheckpointResumedWorkflow<TContext, TOutput>(this.steps, idx, {\n mode: \"checkpoint\",\n priorOutput: ckpt.output,\n snapshot: ckpt,\n observability: this.observability,\n });\n }\n\n /**\n * Append a `.finally()` body to a sealed workflow, returning another sealed\n * workflow. Allows multi-finally chains (`.finally().finally()`). A throwing\n * `.finally` body does NOT abort subsequent ones — they all run.\n */\n finally(\n id: string,\n fn: (params: { ctx: Readonly<TContext> }) => MaybePromise<void>,\n ): SealedWorkflow<TContext, TInput, TOutput, TGates> {\n const node: StepNode = {\n type: \"finally\",\n id,\n execute: async (state) => {\n await fn({ ctx: state.ctx as Readonly<TContext> });\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new SealedWorkflow<TContext, TInput, TOutput, TGates>([...this.steps, node] as any, this.id, this.observability);\n }\n\n private findGateIndex(snapshot: GateSnapshot | LegacyGateSnapshotV1): number {\n // Accepted: v1 (legacy gate-only) and v2 (gate or checkpoint). Gate-flavor\n // v2 is discriminated by kind === \"gate\"; legacy v1 has no `kind`.\n if (snapshot.version !== 1 && snapshot.version !== 2) {\n throw new Error(`Unsupported snapshot version: ${(snapshot as { version: number }).version}`);\n }\n\n // Fast path — only when the hint is a sane integer in range AND points at the right gate.\n // Rejects -1, NaN, Infinity, 999999, fractional indices.\n const hint = snapshot.resumeFromIndex;\n if (Number.isInteger(hint) && hint >= 0 && hint < this.steps.length) {\n const node = this.steps[hint];\n if (node.type === \"gate\" && node.id === snapshot.gateId) {\n return hint;\n }\n }\n\n // Fallback — scan all steps by gate id (reorder-tolerant).\n for (let i = 0; i < this.steps.length; i++) {\n const node = this.steps[i];\n if (node.type === \"gate\" && node.id === snapshot.gateId) {\n return i;\n }\n }\n\n throw new Error(\n `Gate \"${snapshot.gateId}\" not found in workflow. The workflow definition may have changed since the snapshot was created.`\n );\n }\n}\n\n// ── Resumed Workflow ──────────────────────────────────────────────────\n\ninterface ResumedWorkflowConfig {\n readonly mode: \"gate\" | \"checkpoint\";\n readonly schema?: SchemaWithParse<unknown>;\n readonly mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n readonly priorOutput?: unknown;\n readonly snapshot?: WorkflowSnapshot;\n readonly observability?: WorkflowObservability;\n}\n\nexport class ResumedWorkflow<\n TContext,\n TResponse = unknown,\n TOutput = void,\n> extends SealedWorkflow<TContext, TResponse, TOutput> {\n private readonly startIndex: number;\n private readonly schema?: SchemaWithParse<TResponse>;\n private readonly mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n private readonly priorOutput: unknown;\n\n /** @internal */\n constructor(\n steps: ReadonlyArray<StepNode>,\n startIndex: number,\n config: ResumedWorkflowConfig,\n ) {\n super(steps, undefined, config.observability);\n this.startIndex = startIndex;\n this.schema = config.schema as SchemaWithParse<TResponse> | undefined;\n this.mergeFn = config.mergeFn;\n this.priorOutput = config.priorOutput;\n }\n\n private validateResponse(response: TResponse): TResponse {\n if (this.schema) {\n return this.schema.parse(response) as TResponse;\n }\n return response;\n }\n\n override async generate(\n ctx: TContext,\n ...args: TResponse extends void\n ? [response?: TResponse, opts?: RunOptions]\n : [response: TResponse, opts?: RunOptions]\n ): Promise<WorkflowResult<TOutput>> {\n const rawResponse = args[0] as TResponse;\n const opts = args[1] as RunOptions | undefined;\n // Run prep (schema.parse + mergeFn) inside the workflow's error pipeline\n // so a downstream `.catch()` can observe failures here. Without this,\n // a schema/merge throw would reject the promise raw, bypassing catch.\n let output: unknown = this.priorOutput;\n let initialError: PendingError | null = null;\n try {\n const response = this.validateResponse(rawResponse);\n output = this.mergeFn\n ? await this.mergeFn({ priorOutput: this.priorOutput, response })\n : response;\n } catch (error) {\n initialError = { error, stepId: \"gate:resume\", source: \"step\" };\n }\n const state: RuntimeState = {\n ctx,\n output,\n mode: \"generate\",\n runOptions: opts,\n abortSignal: opts?.abortSignal,\n };\n await this.execute(state, this.startIndex, opts, initialError);\n return this.buildResult(state);\n }\n\n override stream<UI_MESSAGE extends UIMessage = UIMessage>(\n ctx: TContext,\n ...args: TResponse extends void\n ? [response?: TResponse, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n : [response: TResponse, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n ): WorkflowStreamResult<TOutput> {\n const rawResponse = args[0] as TResponse;\n const options = args[1] as WorkflowStreamOptions<UI_MESSAGE> | undefined;\n const opts = args[2] as RunOptions | undefined;\n const abortSignal = opts?.abortSignal;\n\n let resolveOutput!: (value: WorkflowResult<TOutput>) => void;\n let rejectOutput!: (error: unknown) => void;\n const outputPromise = new Promise<WorkflowResult<TOutput>>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n outputPromise.catch(() => {});\n\n const mergeFn = this.mergeFn;\n const priorOutput = this.priorOutput;\n const startIndex = this.startIndex;\n\n const stream = createUIMessageStream<UI_MESSAGE>({\n execute: async ({ writer }) => {\n // Run prep (schema.parse + mergeFn) inside the error pipeline (same as\n // generate()). Without this, a schema parse throw escapes synchronously\n // from .stream(...) and bypasses any downstream .catch().\n let output: unknown = priorOutput;\n let initialError: PendingError | null = null;\n try {\n const response = this.validateResponse(rawResponse);\n output = mergeFn\n ? await mergeFn({ priorOutput, response })\n : response;\n } catch (error) {\n initialError = { error, stepId: \"gate:resume\", source: \"step\" };\n }\n const state: RuntimeState = {\n ctx,\n output,\n mode: \"stream\",\n writer,\n runOptions: opts,\n abortSignal,\n };\n\n try {\n await this.execute(state, startIndex, opts, initialError);\n const result = this.buildResult(state);\n maybeWarnStreamOnErrorOnSuspend(result, options);\n resolveOutput(result);\n } catch (error) {\n rejectOutput(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n ...(options?.originalMessages ? { originalMessages: options.originalMessages } : {}),\n ...(options?.generateId ? { generateId: options.generateId } : {}),\n });\n\n return { stream, output: outputPromise };\n }\n}\n\n// ── Checkpoint-Resumed Workflow ──────────────────────────────────────\n//\n// Used by `resumeFrom()`. Same step list, different entry index — no\n// gate-merge logic (no response argument) because the state is seeded\n// from the checkpoint snapshot's `output`. To keep gate-resume's\n// `loadState` form ergonomic, this is a separate class instead of\n// overloading ResumedWorkflow's generate().\n\nexport class CheckpointResumedWorkflow<\n TContext,\n TOutput = void,\n> extends SealedWorkflow<TContext, void, TOutput> {\n private readonly startIndex: number;\n private readonly priorOutput: unknown;\n\n /** @internal */\n constructor(\n steps: ReadonlyArray<StepNode>,\n startIndex: number,\n config: ResumedWorkflowConfig,\n ) {\n super(steps, undefined, config.observability);\n this.startIndex = startIndex;\n this.priorOutput = config.priorOutput;\n }\n\n // Override with widened arg list compatible with parent's `[input?, opts?]`.\n // Inputs are ignored — state is seeded from the snapshot's `output` field.\n override async generate(\n ctx: TContext,\n ...args: [input?: void, opts?: RunOptions]\n ): Promise<WorkflowResult<TOutput>> {\n const opts = args[1];\n this.validateRunOptions(opts);\n const state: RuntimeState = {\n ctx,\n output: this.priorOutput,\n mode: \"generate\",\n runOptions: opts,\n };\n await this.execute(state, this.startIndex, opts);\n return this.buildResult(state);\n }\n\n override stream<UI_MESSAGE extends UIMessage = UIMessage>(\n ctx: TContext,\n ...args: [input?: void, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n ): WorkflowStreamResult<TOutput> {\n const options = args[1];\n const opts = args[2];\n this.validateRunOptions(opts);\n\n let resolveOutput!: (value: WorkflowResult<TOutput>) => void;\n let rejectOutput!: (error: unknown) => void;\n const outputPromise = new Promise<WorkflowResult<TOutput>>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n outputPromise.catch(() => {});\n\n const priorOutput = this.priorOutput;\n const startIndex = this.startIndex;\n\n const stream = createUIMessageStream<UI_MESSAGE>({\n execute: async ({ writer }) => {\n const state: RuntimeState = {\n ctx,\n output: priorOutput,\n mode: \"stream\",\n writer,\n runOptions: opts,\n };\n try {\n await this.execute(state, startIndex, opts);\n const result = this.buildResult(state);\n maybeWarnStreamOnErrorOnSuspend(result, options);\n resolveOutput(result);\n } catch (error) {\n rejectOutput(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n ...(options?.originalMessages ? { originalMessages: options.originalMessages } : {}),\n ...(options?.generateId ? { generateId: options.generateId } : {}),\n });\n\n return { stream, output: outputPromise };\n }\n}\n\n// ── Workflow ────────────────────────────────────────────────────────\n\nexport class Workflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> extends SealedWorkflow<TContext, TInput, TOutput, TGates> {\n\n /**\n * Sentinel value for `foreach`'s `onError` handler. Returning `Workflow.SKIP`\n * from `onError` omits the failed item's index from the output array,\n * shortening it relative to the input array.\n */\n static readonly SKIP: unique symbol = Symbol(\"pipeai.foreach.skip\");\n\n private constructor(steps: ReadonlyArray<StepNode> = [], id?: string, observability?: WorkflowObservability) {\n super(steps, id, observability);\n }\n\n static create<TContext, TInput = void>(\n options?: { id?: string; observability?: WorkflowObservability },\n ): Workflow<TContext, TInput, TInput> {\n return new Workflow<TContext, TInput, TInput>([], options?.id, options?.observability);\n }\n\n static from<TContext, TInput, TOutput>(\n agent: Agent<TContext, TInput, TOutput>,\n options?: StepOptions<TContext, TInput, TOutput>\n ): Workflow<TContext, TInput, TOutput> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, any>([]).step(agent, options);\n }\n\n // Builder helper — append a step and return a re-typed Workflow.\n // Centralizes the `[...steps, node] as any` + new Workflow + observability/id\n // forwarding pattern used by every combinator method.\n private appendStep<TNext, TG extends Record<string, unknown> = TGates>(\n node: StepNode,\n ): Workflow<TContext, TInput, TNext, TG> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNext, TG>([...this.steps, node] as any, this.id, this.observability);\n }\n\n // ── step: agent overload ──────────────────────────────────────\n\n step<TNextOutput>(\n agent: Agent<TContext, TOutput, TNextOutput>,\n options?: StepOptions<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: nested workflow overload ─────────────────────────────\n\n step<TNextOutput>(\n workflow: SealedWorkflow<TContext, TOutput, TNextOutput>,\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: transform overload (replaces map + tap) ─────────────\n\n step<TNextOutput>(\n id: string,\n fn: (params: { ctx: Readonly<TContext>; input: TOutput; writer?: UIMessageStreamWriter }) => MaybePromise<TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: implementation ──────────────────────────────────────\n\n step<TNextOutput>(\n target: Agent<TContext, TOutput, TNextOutput> | SealedWorkflow<TContext, TOutput, TNextOutput> | string,\n optionsOrFn?: StepOptions<TContext, TOutput, TNextOutput> | ((params: { ctx: Readonly<TContext>; input: TOutput; writer?: UIMessageStreamWriter }) => MaybePromise<TNextOutput>)\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n // Nested workflow overload: step(workflow)\n if (target instanceof SealedWorkflow) {\n const workflow = target;\n const node: StepNode = {\n type: \"step\",\n id: workflow.id ?? \"nested-workflow\",\n nestedWorkflow: workflow, // Feeds the recursive stepShapeHash walk.\n category: \"nested\", // Observability event type.\n execute: async (state) => {\n await this.executeNestedWorkflow(state, workflow as SealedWorkflow<TContext, unknown, unknown, any>);\n },\n };\n return this.appendStep<TNextOutput>(node);\n }\n\n // Transform overload: step(id, fn)\n if (typeof target === \"string\") {\n if (typeof optionsOrFn !== \"function\") {\n throw new Error(`Workflow step(\"${target}\"): second argument must be a function`);\n }\n const fn = optionsOrFn as (params: { ctx: Readonly<TContext>; input: TOutput; writer?: UIMessageStreamWriter }) => MaybePromise<TNextOutput>;\n const node: StepNode = {\n type: \"step\",\n id: target,\n execute: async (state) => {\n state.output = await fn({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n // Present in stream mode (undefined in generate mode), letting the\n // inline step emit UIMessageChunk parts onto the workflow's stream.\n writer: state.writer,\n });\n },\n };\n return this.appendStep<TNextOutput>(node);\n }\n\n // Agent overload: step(agent, options?)\n const agent = target;\n const options = optionsOrFn as StepOptions<TContext, TOutput, TNextOutput> | undefined;\n const node: StepNode = {\n type: \"step\",\n id: options?.id ?? agent.id,\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n await this.executeAgent(state, agent, ctx, options);\n },\n };\n return this.appendStep<TNextOutput>(node);\n }\n\n // ── gate: human-in-the-loop suspension point ────────────────\n\n gate<TResponse = TOutput, Id extends string = string>(\n id: Id & (Id extends keyof TGates ? never : Id),\n options?: {\n payload?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<unknown>;\n schema?: SchemaWithParse<TResponse>;\n condition?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<boolean>;\n merge?: (params: { priorOutput: TOutput; response: TResponse }) => MaybePromise<TResponse>;\n }\n ): Workflow<TContext, TInput, TResponse, TGates & Record<Id, TResponse>> {\n if (this.steps.some(s => s.type === \"gate\" && s.id === id)) {\n throw new Error(`Workflow: duplicate gate ID \"${id}\". Each gate must have a unique identifier.`);\n }\n const node: StepNode = {\n type: \"gate\",\n id,\n schema: options?.schema,\n condition: options?.condition\n ? async (state) => options.condition!({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n })\n : undefined,\n merge: options?.merge\n ? (params) => options.merge!(params as { priorOutput: TOutput; response: TResponse })\n : undefined,\n payload: async (state) => {\n if (options?.payload) {\n return options.payload({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n });\n }\n return state.output;\n },\n };\n return this.appendStep<TResponse, TGates & Record<Id, TResponse>>(node);\n }\n\n // ── branch: predicate routing (array) ─────────────────────────\n\n branch<TNextOutput>(\n cases: BranchCase<TContext, TOutput, TNextOutput>[],\n options?: { id?: string },\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── branch: key routing (select) ──────────────────────────────\n\n branch<TKeys extends string, TNextOutput>(\n config: BranchSelect<TContext, TOutput, TKeys, TNextOutput>,\n options?: { id?: string },\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── branch: implementation ────────────────────────────────────\n\n branch<TKeys extends string, TNextOutput>(\n casesOrConfig: BranchCase<TContext, TOutput, TNextOutput>[] | BranchSelect<TContext, TOutput, TKeys, TNextOutput>,\n options?: { id?: string },\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n if (Array.isArray(casesOrConfig)) {\n return this.branchPredicate(casesOrConfig, options?.id);\n }\n return this.branchSelect(casesOrConfig, options?.id);\n }\n\n private branchPredicate<TNextOutput>(\n cases: BranchCase<TContext, TOutput, TNextOutput>[],\n explicitId?: string,\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n const node: StepNode = {\n type: \"step\",\n id: explicitId ?? \"branch:predicate\",\n category: \"branch\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n const input = state.output as TOutput;\n\n for (const branchCase of cases) {\n if (branchCase.when) {\n const match = await branchCase.when({ ctx, input });\n if (!match) continue;\n }\n\n // Matched (or no `when` = default)\n await this.executeAgent(state, branchCase.agent, ctx, branchCase);\n return;\n }\n\n // Render the input defensively — JSON.stringify throws on cyclic /\n // BigInt / function-valued inputs, which would mask the real branch\n // mismatch with a serialization error.\n let inputRepr: string;\n try {\n inputRepr = JSON.stringify(input);\n if (inputRepr === undefined) inputRepr = String(input);\n } catch {\n inputRepr = `[unserializable ${typeof input}]`;\n }\n throw new WorkflowBranchError(\"predicate\", `No branch matched and no default branch (a case without \\`when\\`) was provided. Input: ${inputRepr}`);\n },\n };\n return this.appendStep<TNextOutput>(node);\n }\n\n private branchSelect<TKeys extends string, TNextOutput>(\n config: BranchSelect<TContext, TOutput, TKeys, TNextOutput>,\n explicitId?: string,\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n const node: StepNode = {\n type: \"step\",\n id: explicitId ?? \"branch:select\",\n category: \"branch\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n const input = state.output as TOutput;\n const key = await config.select({ ctx, input });\n\n // Distinguish \"key not declared at all\" from \"key present but value\n // is `undefined`\" (e.g. `agents: { bug: cond ? agentA : undefined }`).\n // The latter is a user-side bug — fail loud rather than silently\n // falling back, since the fallback obscures the misconfiguration.\n //\n // Use Object.prototype.hasOwnProperty.call (not `in`) so untrusted\n // classifier output like \"toString\"/\"constructor\"/\"__proto__\" doesn't\n // resolve to a Object.prototype method and crash executeAgent with an\n // opaque \"agent.generate is not a function\".\n const keyDeclared = Object.prototype.hasOwnProperty.call(config.agents, key);\n if (keyDeclared && (config.agents as Record<string, unknown>)[key] === undefined) {\n throw new WorkflowBranchError(\n \"select\",\n `Agent for key \"${key}\" was declared but the value is undefined. ` +\n `This usually means a conditional spread set the value to undefined. ` +\n `Available keys: ${Object.keys(config.agents).join(\", \")}`,\n );\n }\n let agent = keyDeclared ? config.agents[key] : undefined;\n if (!agent) {\n if (config.onUnknownKey) {\n config.onUnknownKey({\n key,\n availableKeys: Object.keys(config.agents) as TKeys[],\n ctx: ctx as Readonly<TContext>,\n });\n }\n if (config.fallback) {\n agent = config.fallback;\n } else {\n throw new WorkflowBranchError(\"select\", `No agent found for key \"${key}\" and no fallback provided. Available keys: ${Object.keys(config.agents).join(\", \")}`);\n }\n }\n\n await this.executeAgent(state, agent, ctx, config);\n },\n };\n return this.appendStep<TNextOutput>(node);\n }\n\n // ── foreach: array iteration ─────────────────────────────────\n\n /**\n * Map each item of an array through an agent or sub-workflow.\n *\n * @param target Agent or `SealedWorkflow` invoked once per item.\n * @param options.id Override the default step id (`foreach:<agentId>` or\n * the workflow's id). Required when chaining multiple foreach over the same\n * target — the construction-time `(type, id)` walk rejects duplicates.\n * @param options.concurrency Max items in flight at any moment (default 1).\n * Backed by a semaphore: as soon as one item completes, the next launches —\n * no lockstep batching.\n * @param options.onError Per-iteration error handler. **Bypassed entirely on\n * the suspension path** (when any item hits a nested gate) — see the\n * foreach concurrency hazards in the README. Otherwise: return a\n * `TNextOutput` value to substitute, return `Workflow.SKIP` to omit, throw\n * to abort. Invoked sequentially in index order after all items settle.\n */\n foreach<TNextOutput>(\n target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput>,\n options?: {\n id?: string;\n concurrency?: number;\n onError?: (params: {\n error: unknown;\n item: ElementOf<TOutput>;\n index: number;\n ctx: Readonly<TContext>;\n }) => MaybePromise<TNextOutput | typeof Workflow.SKIP>;\n },\n ): Workflow<TContext, TInput, TNextOutput[], TGates> {\n const concurrency = options?.concurrency ?? 1;\n const onError = options?.onError;\n const isWorkflow = target instanceof SealedWorkflow;\n const defaultId = isWorkflow\n ? (target.id ?? \"foreach\")\n : `foreach:${(target as Agent<TContext, ElementOf<TOutput>, TNextOutput>).id}`;\n const id = options?.id ?? defaultId;\n\n const node: StepNode = {\n type: \"step\",\n id,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n nestedWorkflow: isWorkflow ? (target as SealedWorkflow<any, any, any, any>) : undefined,\n category: \"foreach\",\n execute: async (state) => {\n const items = state.output;\n if (!Array.isArray(items)) {\n throw new Error(`foreach \"${id}\": expected array input, got ${typeof items}`);\n }\n\n const ctx = state.ctx as TContext;\n const results: unknown[] = new Array(items.length);\n const skipped = new Set<number>();\n const itemStates: (RuntimeState | undefined)[] = new Array(items.length);\n\n const executeItem = async (item: unknown, index: number) => {\n // itemState explicitly omits runOptions — per-run config never crosses\n // the foreach boundary. abortSignal IS propagated though, since\n // cancellation must be transitive across the foreach barrier.\n const itemState: RuntimeState = {\n ctx: state.ctx,\n output: item,\n mode: \"generate\",\n abortSignal: state.abortSignal,\n };\n itemStates[index] = itemState;\n const itemStart = performance.now();\n await this.fireHook(state, \"onItemStart\", {\n stepId: id, type: \"foreach\", itemIndex: index, ctx: state.ctx, input: item,\n });\n try {\n if (isWorkflow) {\n await this.executeNestedWorkflow(itemState, target as SealedWorkflow<TContext, unknown, unknown, any>);\n } else {\n await this.executeAgent(itemState, target as Agent<TContext, unknown, TNextOutput>, ctx);\n }\n results[index] = itemState.output;\n await this.fireHook(state, \"onItemFinish\", {\n stepId: id, type: \"foreach\", itemIndex: index, ctx: state.ctx, output: itemState.output,\n durationMs: performance.now() - itemStart,\n });\n } catch (error) {\n await this.fireHook(state, \"onItemError\", {\n stepId: id, type: \"foreach\", itemIndex: index, ctx: state.ctx, error,\n durationMs: performance.now() - itemStart,\n });\n throw error;\n }\n };\n\n // Merge per-item warnings into the parent state, namespaced.\n // Runs on EVERY exit path (success, suspension, or onError throw).\n const mergeItemWarnings = () => {\n for (let idx = 0; idx < items.length; idx++) {\n const its = itemStates[idx];\n if (!its?.warnings) continue;\n for (const w of its.warnings) {\n pushWarning(state, w.source, `${id}[${idx}]:${w.stepId}`, w.error);\n }\n }\n };\n\n const handleRejection = async (error: unknown, item: unknown, index: number) => {\n if (!onError) throw error;\n const recovered = await onError({\n error,\n item: item as ElementOf<TOutput>,\n index,\n ctx: state.ctx as Readonly<TContext>,\n });\n if (recovered === Workflow.SKIP) {\n skipped.add(index);\n } else {\n results[index] = recovered;\n }\n };\n\n // Collect rejections, then partition + branch.\n type Failure = { index: number; error: unknown };\n const failures: Failure[] = [];\n\n // Cooperative cancellation: bail before launching each item so a\n // large foreach doesn't fire off all items just because the parent's\n // abortSignal triggered mid-iteration. In-flight items already running\n // can't be yanked back, but their executeAgent call forwarded the\n // signal so the SDK side will tear them down.\n const signal = state.abortSignal;\n\n if (concurrency <= 1) {\n for (let i = 0; i < items.length; i++) {\n if (signal?.aborted) {\n failures.push({ index: i, error: signal.reason ?? new Error(\"Workflow aborted\") });\n continue;\n }\n try {\n await executeItem(items[i], i);\n } catch (error) {\n failures.push({ index: i, error });\n }\n }\n } else {\n // Worker pool: O(concurrency) async closures share a counter rather\n // than O(N) closures all queuing on a semaphore. The shared\n // `nextIndex++` is safe because JS is single-threaded — the\n // read+increment is synchronous and the following `await` yields\n // AFTER the index is captured.\n let nextIndex = 0;\n const worker = async () => {\n while (true) {\n const i = nextIndex++;\n if (i >= items.length) return;\n if (signal?.aborted) {\n failures.push({ index: i, error: signal.reason ?? new Error(\"Workflow aborted\") });\n continue;\n }\n try {\n await executeItem(items[i], i);\n } catch (error) {\n failures.push({ index: i, error });\n }\n }\n };\n const workers = Array.from(\n { length: Math.min(concurrency, items.length) },\n () => worker(),\n );\n await Promise.all(workers);\n }\n\n failures.sort((a, b) => a.index - b.index);\n\n // Partition into gate vs non-gate rejections.\n const gateFailures: { index: number; error: NestedGateUnsupportedError }[] = [];\n const nonGateFailures: Failure[] = [];\n for (const f of failures) {\n if (f.error instanceof NestedGateUnsupportedError) {\n gateFailures.push({ index: f.index, error: f.error });\n } else {\n nonGateFailures.push(f);\n }\n }\n\n // Always merge per-item warnings before deciding which path to take.\n mergeItemWarnings();\n\n if (gateFailures.length > 0) {\n // Suspension path — onError is bypassed entirely. Non-gate rejections\n // become foreach-sibling warnings. Lowest-index marker wins.\n for (const nr of nonGateFailures) {\n pushWarning(state, \"foreach-sibling\", `${id}[${nr.index}]`, nr.error);\n }\n const lowest = gateFailures[0];\n const otherSuspensions = gateFailures.slice(1).map(g => ({\n index: g.index,\n gateId: g.error.gateId,\n }));\n const siblingErrors = nonGateFailures.map(nr => nr.error);\n throw new NestedGateUnsupportedError(\n lowest.error.gateId,\n lowest.error.workflowId,\n siblingErrors,\n otherSuspensions,\n );\n }\n\n // No suspension — run onError per existing semantics in index order.\n for (const { index, error } of nonGateFailures) {\n await handleRejection(error, items[index], index);\n }\n\n state.output = skipped.size === 0\n ? results\n : results.filter((_, i) => !skipped.has(i));\n },\n };\n return this.appendStep<TNextOutput[]>(node);\n }\n\n // ── parallel: fan-out combinator ────────────────────────────────\n //\n // Same input fed to each branch. Generate mode only — writer is NOT threaded\n // through (interleaving multiple agent streams into one writer is not\n // supported). For SealedWorkflow branches, a nested gate throws\n // NestedGateUnsupportedError (same machinery as foreach concurrent).\n //\n // Default concurrency: `min(branches.length, 5)` — most users want fan-out,\n // not lockstep batching. Warn-once when branch count exceeds the 5 cap so\n // users notice unexpected rate-limit pressure.\n\n /** Record-form overload. Returns `{ [K]: BranchOutput<T[K]> }`. */\n parallel<TBranches extends Record<string, ParallelTarget<TContext, TOutput>>>(\n branches: TBranches,\n options?: ParallelOptions<TContext>,\n ): Workflow<TContext, TInput, ParallelOutputRecord<TBranches>, TGates>;\n\n /** Tuple-form overload. Returns `[O1, O2, ...]`. Use `as const`. */\n parallel<TBranches extends ReadonlyArray<ParallelTarget<TContext, TOutput>>>(\n branches: TBranches,\n options?: ParallelOptions<TContext>,\n ): Workflow<TContext, TInput, ParallelOutputTuple<TBranches>, TGates>;\n\n // Implementation\n parallel(\n branches: Record<string, ParallelTarget<TContext, TOutput>> | ReadonlyArray<ParallelTarget<TContext, TOutput>>,\n options?: ParallelOptions<TContext>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Workflow<TContext, TInput, any, TGates> {\n const isTuple = Array.isArray(branches);\n const entries: Array<{ key: string | number; index: number; target: ParallelTarget<TContext, TOutput> }> = isTuple\n ? (branches as ReadonlyArray<ParallelTarget<TContext, TOutput>>).map((target, i) => ({ key: i, index: i, target }))\n : Object.entries(branches as Record<string, ParallelTarget<TContext, TOutput>>).map(([k, t], i) => ({ key: k, index: i, target: t }));\n const branchCount = entries.length;\n const requestedConcurrency = options?.concurrency;\n let effectiveConcurrency: number;\n if (requestedConcurrency === undefined) {\n effectiveConcurrency = Math.min(branchCount, 5);\n } else {\n effectiveConcurrency = requestedConcurrency;\n }\n // Warn-once when >5 branches without explicit concurrency override.\n if (requestedConcurrency === undefined && branchCount > 5) {\n warnOnce(\n \"pipeai:parallel-cap\",\n `pipeai: parallel() with ${branchCount} branches capped at concurrency 5 by default. Pass { concurrency: ${branchCount} } (or Infinity) to opt in, or set { concurrency: N } if you want fewer.`,\n );\n }\n const onError = options?.onError;\n const id = options?.id ?? (isTuple ? \"parallel:tuple\" : \"parallel:record\");\n\n const node: StepNode = {\n type: \"step\",\n id,\n category: \"parallel\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n const input = state.output;\n const results: Record<string | number, unknown> = (isTuple ? new Array(branchCount) : {}) as Record<string | number, unknown>;\n const branchStates: (RuntimeState | undefined)[] = new Array(branchCount);\n\n const executeBranch = async ({ key, index, target }: { key: string | number; index: number; target: ParallelTarget<TContext, TOutput> }) => {\n // Per-branch itemState — same isolation as foreach (no runOptions).\n const branchState: RuntimeState = { ctx: state.ctx, output: input, mode: \"generate\" };\n branchStates[index] = branchState;\n const branchStart = performance.now();\n // itemIndex is the key for record form, numeric index for tuple form.\n const itemIndex: string | number = isTuple ? index : (key as string);\n await this.fireHook(state, \"onItemStart\", {\n stepId: id, type: \"parallel\", itemIndex, ctx: state.ctx, input,\n });\n try {\n if (target instanceof SealedWorkflow) {\n await this.executeNestedWorkflow(branchState, target as SealedWorkflow<TContext, unknown, unknown, any>);\n } else {\n await this.executeAgent(branchState, target as Agent<TContext, unknown, unknown>, ctx);\n }\n results[key] = branchState.output;\n await this.fireHook(state, \"onItemFinish\", {\n stepId: id, type: \"parallel\", itemIndex, ctx: state.ctx, output: branchState.output,\n durationMs: performance.now() - branchStart,\n });\n } catch (error) {\n await this.fireHook(state, \"onItemError\", {\n stepId: id, type: \"parallel\", itemIndex, ctx: state.ctx, error,\n durationMs: performance.now() - branchStart,\n });\n throw error;\n }\n };\n\n // Same partition + suspension contract as foreach concurrent.\n type Failure = { key: string | number; index: number; error: unknown };\n const failures: Failure[] = [];\n\n const eff = Number.isFinite(effectiveConcurrency) ? Math.max(1, effectiveConcurrency) : branchCount;\n if (eff <= 1) {\n for (const e of entries) {\n try {\n await executeBranch(e);\n } catch (error) {\n failures.push({ key: e.key, index: e.index, error });\n }\n }\n } else {\n // Worker pool (same shape as foreach): K closures share a counter\n // instead of N closures queuing on a semaphore.\n let nextIndex = 0;\n const worker = async () => {\n while (true) {\n const i = nextIndex++;\n if (i >= branchCount) return;\n const e = entries[i];\n try {\n await executeBranch(e);\n } catch (error) {\n failures.push({ key: e.key, index: e.index, error });\n }\n }\n };\n const workers = Array.from(\n { length: Math.min(eff, branchCount) },\n () => worker(),\n );\n await Promise.all(workers);\n }\n\n // Always merge per-branch warnings into the parent, namespaced.\n for (let idx = 0; idx < branchCount; idx++) {\n const bs = branchStates[idx];\n if (!bs?.warnings) continue;\n for (const w of bs.warnings) {\n pushWarning(state, w.source, `${id}[${entries[idx].key}]:${w.stepId}`, w.error);\n }\n }\n\n // Partition rejections into gate vs non-gate.\n const gateFailures: { key: string | number; index: number; error: NestedGateUnsupportedError }[] = [];\n const nonGateFailures: Failure[] = [];\n for (const f of failures) {\n if (f.error instanceof NestedGateUnsupportedError) gateFailures.push({ key: f.key, index: f.index, error: f.error });\n else nonGateFailures.push(f);\n }\n gateFailures.sort((a, b) => a.index - b.index);\n nonGateFailures.sort((a, b) => a.index - b.index);\n\n if (gateFailures.length > 0) {\n // Suspension path — onError bypassed; non-gate rejections become warnings.\n for (const nr of nonGateFailures) {\n pushWarning(state, \"foreach-sibling\", `${id}[${nr.key}]`, nr.error);\n }\n const lowest = gateFailures[0];\n const otherSuspensions = gateFailures.slice(1).map(g => ({ index: g.index, gateId: g.error.gateId }));\n const siblingErrors = nonGateFailures.map(nr => nr.error);\n throw new NestedGateUnsupportedError(\n lowest.error.gateId,\n lowest.error.workflowId,\n siblingErrors,\n otherSuspensions,\n );\n }\n\n // No suspension — handle non-gate failures via onError or rethrow.\n for (const { key, index, error } of nonGateFailures) {\n if (!onError) throw error;\n const recovered = await onError({\n error,\n key: isTuple ? undefined : (key as string),\n index: isTuple ? (index) : undefined,\n ctx: state.ctx as Readonly<TContext>,\n });\n if (recovered === Workflow.SKIP) {\n // Record form: leave the key as `undefined`. Tuple form: same — the\n // slot stays `undefined`. The output type accepts SKIP only on the\n // record form at compile time.\n results[key] = undefined;\n } else {\n results[key] = recovered;\n }\n }\n\n state.output = results;\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return this.appendStep<any>(node);\n }\n\n // ── repeat: conditional loop ─────────────────────────────────\n\n repeat(\n target: Agent<TContext, TOutput, TOutput> | SealedWorkflow<TContext, TOutput, TOutput>,\n options: RepeatOptions<TContext, TOutput> & { id?: string },\n ): Workflow<TContext, TInput, TOutput, TGates> {\n const maxIterations = options.maxIterations ?? 10;\n const isWorkflow = target instanceof SealedWorkflow;\n const defaultId = isWorkflow\n ? (target.id ?? \"repeat\")\n : `repeat:${(target as Agent<TContext, TOutput, TOutput>).id}`;\n const id = options.id ?? defaultId;\n const predicate: LoopPredicate<TContext, TOutput> = options.until\n ?? (async (p) => !(await options.while!(p)));\n\n const node: StepNode = {\n type: \"step\",\n id,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n nestedWorkflow: isWorkflow ? (target as SealedWorkflow<any, any, any, any>) : undefined,\n category: \"repeat\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n\n for (let i = 1; i <= maxIterations; i++) {\n // Cancellation checkpoint between iterations. The body's executeAgent\n // already forwards the signal so an in-flight call cancels too, but\n // the explicit check here covers SealedWorkflow bodies and transform-\n // only loops where the signal wouldn't otherwise propagate.\n if (state.abortSignal?.aborted) {\n throw state.abortSignal.reason ?? new Error(\"Workflow aborted\");\n }\n\n if (isWorkflow) {\n await this.executeNestedWorkflow(state, target as SealedWorkflow<TContext, unknown, unknown, any>);\n } else {\n await this.executeAgent(state, target as Agent<TContext, TOutput, TOutput>, ctx);\n }\n\n const done = await predicate({\n output: state.output as TOutput,\n ctx: ctx as Readonly<TContext>,\n iterations: i,\n });\n if (done) return;\n }\n\n throw new WorkflowLoopError(maxIterations, maxIterations);\n },\n };\n return this.appendStep<TOutput>(node);\n }\n\n // ── catch ─────────────────────────────────────────────────────\n\n catch(\n id: string,\n fn: (params: { error: unknown; ctx: Readonly<TContext>; lastOutput: TOutput; stepId: string }) => MaybePromise<TOutput>\n ): Workflow<TContext, TInput, TOutput, TGates> {\n if (!this.steps.some(s => s.type === \"step\")) {\n throw new Error(`Workflow: catch(\"${id}\") requires at least one preceding step.`);\n }\n const node: StepNode = {\n type: \"catch\",\n id,\n catchFn: fn as (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown>,\n };\n return this.appendStep<TOutput>(node);\n }\n\n // `.finally()` is inherited from SealedWorkflow now (it lives there so\n // multi-finally chains are possible — `.finally().finally()`).\n}\n","export { Agent } from \"./agent\";\nexport type {\n AgentConfig,\n GenerateTextResult,\n StreamTextResult,\n OutputType,\n AsToolMapOutput,\n} from \"./agent\";\n\nexport {\n Workflow,\n WorkflowBranchError,\n WorkflowLoopError,\n NestedGateUnsupportedError,\n CheckpointTimeoutError,\n CHECKPOINT_STEP_ID,\n migrateSnapshot,\n} from \"./workflow\";\n\n// `SKIP` is a unique-symbol sentinel returned from `foreach`'s `onError` to\n// omit an item from the output array. It mirrors `Workflow.SKIP` and is\n// re-exported here so consumers who only `import type { SealedWorkflow }` can\n// still reach the runtime value without importing the full `Workflow` class.\nimport { Workflow as _WorkflowForSkip } from \"./workflow\";\nexport const SKIP = _WorkflowForSkip.SKIP;\nexport type { SealedWorkflow, ResumedWorkflow, CheckpointResumedWorkflow } from \"./workflow\";\nexport type {\n AgentStepHooks,\n AgentResultParams,\n StepOptions,\n BranchCase,\n BranchSelect,\n RepeatOptions,\n WorkflowResult,\n WorkflowStreamResult,\n WorkflowStreamOptions,\n WorkflowSnapshot,\n GateSnapshot,\n CheckpointSnapshot,\n LegacyGateSnapshotV1,\n WorkflowWarning,\n WorkflowStepType,\n WorkflowObservability,\n RunOptions,\n ParallelTarget,\n ParallelOutputRecord,\n ParallelOutputTuple,\n ParallelOptions,\n} from \"./workflow\";\n\nexport { defineTool, ToolProvider, isToolProvider, TOOL_PROVIDER_BRAND } from \"./tool-provider\";\nexport type { ToolProviderConfig, ToolExecuteOptions, IToolProvider } from \"./tool-provider\";\n\nexport { getActiveWriter } from \"./utils\";\nexport type { MaybePromise, Resolvable } from \"./utils\";\n"],"mappings":"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","names":["tool","tool","result","stepId","node"]}
|
|
1
|
+
{"version":3,"sources":["../src/agent.ts","../src/tool-provider.ts","../src/utils.ts","../src/workflow.ts","../src/steps/step.ts","../src/steps/transform-step.ts","../src/steps/agent-step.ts","../src/errors.ts","../src/steps/branch-step.ts","../src/runtime.ts","../src/steps/semaphore.ts","../src/steps/concurrent.ts","../src/steps/foreach-step.ts","../src/steps/parallel-step.ts","../src/steps/gate-step.ts","../src/steps/catch-step.ts","../src/steps/finally-step.ts","../src/steps/nested-workflow-step.ts","../src/steps/repeat-step.ts","../src/index.ts"],"sourcesContent":["import {\n generateText,\n streamText,\n tool,\n Output,\n type GenerateTextResult as AIGenerateTextResult,\n type StreamTextResult as AIStreamTextResult,\n type UIMessageStreamWriter,\n type ModelMessage,\n type LanguageModel,\n type Tool,\n type ToolSet,\n type StopCondition,\n type ToolChoice,\n type OnStepFinishEvent,\n type OnFinishEvent,\n} from \"ai\";\n\n// Extract the Output interface type from the Output.object return type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type OutputType<T = any> = ReturnType<typeof Output.object<T>>;\nimport type { ZodType } from \"zod\";\nimport { isToolProvider, TOOL_PROVIDER_BRAND, type IToolProvider } from \"./tool-provider\";\nimport { extractOutput, getActiveWriter, resolveValue, type MaybePromise, type Resolvable } from \"./utils\";\n\n// Tools config accepts both AI SDK tools and context-aware ToolProviders\ntype AgentToolSet<TContext> = Record<string, Tool | IToolProvider<TContext>>;\n\n// ── Result type aliases ─────────────────────────────────────────────\n\nexport type GenerateTextResult<TOOLS extends ToolSet = ToolSet, OUTPUT extends OutputType = OutputType> = AIGenerateTextResult<TOOLS, OUTPUT>;\nexport type StreamTextResult<TOOLS extends ToolSet = ToolSet, OUTPUT extends OutputType = OutputType> = AIStreamTextResult<TOOLS, OUTPUT>;\n\n/**\n * The result passed to `asTool` / `asToolProvider`'s `mapOutput`.\n *\n * The same agent may be invoked as a tool from a generate-mode parent\n * (returns `GenerateTextResult`, sync `.text`/`.output`) or from a\n * stream-mode parent (returns `StreamTextResult`, async `.text`/`.output`).\n * The callsite cannot statically tell which mode it is in, so `mapOutput`\n * receives the union and must `await` the relevant fields to support both.\n */\nexport type AsToolMapOutput<TOutput> = (\n result:\n | GenerateTextResult<ToolSet, OutputType<TOutput>>\n | StreamTextResult<ToolSet, OutputType<TOutput>>,\n) => MaybePromise<TOutput>;\n\n// ── AI SDK passthrough types ────────────────────────────────────────\n\n// Extract options types from both AI SDK entry points\ntype StreamTextOptions = Parameters<typeof streamText>[0];\ntype GenerateTextOptions = Parameters<typeof generateText>[0];\n\n// Keys we replace with resolvable or context-enriched versions\ntype ManagedKeys =\n | 'model' | 'system' | 'prompt' | 'messages'\n | 'tools' | 'activeTools' | 'toolChoice' | 'stopWhen'\n | 'output' | 'onFinish' | 'onStepFinish' | 'onError';\n\n// Combine options from both streamText and generateText.\n// Each side contributes its unique props; shared props merge naturally.\n// Stream-only props (onChunk, onAbort) are ignored by generateText.\n// Generate-only props (experimental_include.responseBody) are ignored by streamText.\ntype AIPassthroughOptions =\n Omit<StreamTextOptions, ManagedKeys> &\n Omit<GenerateTextOptions, ManagedKeys>;\n\n// ── Resolved config (output of resolveConfig / resolveConfigAsync) ──\n\ninterface ResolvedAgentConfig {\n model: LanguageModel;\n prompt: string | undefined;\n system: string | undefined;\n messages: ModelMessage[] | undefined;\n tools: Record<string, Tool>;\n activeTools: string[] | undefined;\n toolChoice: ToolChoice<ToolSet> | undefined;\n stopWhen: StopCondition<ToolSet> | Array<StopCondition<ToolSet>> | undefined;\n}\n\n// ── Agent Configuration ─────────────────────────────────────────────\n\nexport interface AgentConfig<\n TContext,\n TInput = void,\n TOutput = void,\n> extends AIPassthroughOptions {\n // ── Custom (not in AI SDK) ──\n id: string;\n description?: string;\n input?: ZodType<TInput>;\n output?: OutputType<TOutput>;\n /**\n * Zod schema used to validate `output` after the AI SDK returns. Distinct\n * from `tool.outputSchema` (AI SDK's tool-execution output schema): this\n * runs **after** the SDK has parsed structured output, as a runtime guard\n * against parse drift. If omitted, the parsed output is trusted as-is.\n */\n validateOutput?: ZodType<TOutput>;\n\n // ── Resolvable (our versions of AI SDK properties) ──\n model: Resolvable<TContext, TInput, LanguageModel>;\n system?: Resolvable<TContext, TInput, string>;\n prompt?: Resolvable<TContext, TInput, string>;\n messages?: Resolvable<TContext, TInput, ModelMessage[]>;\n tools?: Resolvable<TContext, TInput, AgentToolSet<TContext>>;\n activeTools?: Resolvable<TContext, TInput, string[]>;\n toolChoice?: Resolvable<TContext, TInput, ToolChoice<ToolSet>>;\n /**\n * Stop condition(s) for the tool loop. Pass either a single AI-SDK\n * `StopCondition` (which is itself a function) or an array of them.\n *\n * **Not a `Resolvable`.** A `StopCondition` and a `(ctx, input) => StopCondition`\n * resolver are both functions and cannot be safely distinguished at\n * runtime, so this field intentionally does NOT accept the resolver\n * form. If you need per-call dynamic stop conditions, build the agent\n * inside your handler instead of using a static instance.\n */\n stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;\n\n // ── Context-enriched callbacks (replace AI SDK versions) ──\n // `writer` is available when the agent runs inside a streaming workflow.\n onStepFinish?: (params: { result: OnStepFinishEvent; ctx: Readonly<TContext>; input: TInput; writer?: UIMessageStreamWriter }) => MaybePromise<void>;\n onFinish?: (params: { result: OnFinishEvent; ctx: Readonly<TContext>; input: TInput; writer?: UIMessageStreamWriter }) => MaybePromise<void>;\n onError?: (params: { error: unknown; ctx: Readonly<TContext>; input: TInput; writer?: UIMessageStreamWriter }) => MaybePromise<void>;\n}\n\n// ── Agent ───────────────────────────────────────────────────────────\n\nexport class Agent<\n TContext,\n TInput = void,\n TOutput = void,\n> {\n readonly id: string;\n readonly description: string;\n readonly hasOutput: boolean;\n /**\n * Zod schema used to validate the agent's structured `output` after the AI\n * SDK returns. Distinct from `tool.outputSchema` (which validates tool\n * execution output). Exposed (readonly) so external runners — notably the\n * workflow runtime — can pass it through to `extractOutput` without\n * re-plumbing it.\n */\n readonly validateOutput: ZodType<TOutput> | undefined;\n private readonly config: AgentConfig<TContext, TInput, TOutput>;\n private readonly _hasDynamicConfig: boolean;\n private readonly _resolvedStaticTools: Record<string, Tool> | null = null;\n private readonly _passthrough: Record<string, unknown>;\n private readonly _onStepFinish: AgentConfig<TContext, TInput, TOutput>['onStepFinish'];\n private readonly _onFinish: AgentConfig<TContext, TInput, TOutput>['onFinish'];\n\n constructor(config: AgentConfig<TContext, TInput, TOutput>) {\n this.id = config.id;\n this.description = config.description ?? \"\";\n this.hasOutput = config.output !== undefined;\n this.validateOutput = config.validateOutput;\n this.config = config;\n // NOTE: `stopWhen` is intentionally excluded. A bare `StopCondition` is\n // itself a function (`({ steps }) => boolean`), so the typeof-function\n // resolver heuristic in `resolveValue` would misidentify it as a\n // `(ctx, input) => ...` Resolvable and call it with the wrong shape.\n // For `stopWhen` we always treat a function value as a static\n // StopCondition; dynamic stopWhen must return an array\n // (`(ctx, input) => [stepCountIs(5)]`), which is the unambiguous form.\n this._hasDynamicConfig = [\n config.model, config.system, config.prompt,\n config.messages, config.tools, config.activeTools,\n config.toolChoice,\n ].some(v => typeof v === \"function\");\n\n // Cache tools when config is static and contains no ToolProviders.\n // Avoids re-iterating the tools map on every generate()/stream() call.\n if (!this._hasDynamicConfig) {\n const rawTools = (config.tools as AgentToolSet<TContext> | undefined) ?? {};\n const hasProvider = Object.values(rawTools).some(v => isToolProvider(v));\n if (!hasProvider) {\n this._resolvedStaticTools = rawTools as Record<string, Tool>;\n }\n }\n\n // Pre-compute the passthrough (AI SDK options we don't manage) once,\n // rather than destructuring on every generate()/stream() call.\n const {\n id: _id, description: _desc, input: _inputSchema, output: _output, validateOutput: _validateOutput,\n model: _m, system: _s, prompt: _p, messages: _msg,\n tools: _t, activeTools: _at, toolChoice: _tc, stopWhen: _sw,\n onStepFinish, onFinish, onError: _onError,\n ...passthrough\n } = config;\n this._passthrough = passthrough;\n this._onStepFinish = onStepFinish;\n this._onFinish = onFinish;\n }\n\n async generate(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: { abortSignal?: AbortSignal }]\n : [input: TInput, options?: { abortSignal?: AbortSignal }]\n ): Promise<GenerateTextResult<ToolSet, OutputType<TOutput>>> {\n const input = args[0] as TInput;\n const callOptions = args[1] as { abortSignal?: AbortSignal } | undefined;\n return this.generateWithOptions(ctx, input, callOptions ?? {});\n }\n\n async stream(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: { abortSignal?: AbortSignal }]\n : [input: TInput, options?: { abortSignal?: AbortSignal }]\n ): Promise<StreamTextResult<ToolSet, OutputType<TOutput>>> {\n const input = args[0] as TInput;\n const callOptions = args[1] as { abortSignal?: AbortSignal } | undefined;\n return this.streamWithOptions(ctx, input, callOptions ?? {});\n }\n\n asTool(ctx: TContext, options?: {\n mapOutput?: AsToolMapOutput<TOutput>;\n }): Tool {\n return this.createToolInstance(ctx, options);\n }\n\n asToolProvider(options?: {\n mapOutput?: AsToolMapOutput<TOutput>;\n }): IToolProvider<TContext> {\n if (!this.config.input) {\n throw new Error(`Agent \"${this.id}\": asToolProvider() requires an input schema`);\n }\n\n return {\n [TOOL_PROVIDER_BRAND]: true as const,\n createTool: (ctx: Readonly<TContext>) => this.createToolInstance(ctx as TContext, options),\n };\n }\n\n private createToolInstance(ctx: TContext, options?: {\n mapOutput?: AsToolMapOutput<TOutput>;\n }): Tool {\n if (!this.config.input) {\n throw new Error(`Agent \"${this.id}\": asTool() requires an input schema`);\n }\n\n return tool<TInput, TOutput>({\n description: this.description,\n inputSchema: this.config.input,\n // The AI SDK passes a `ToolExecutionOptions` argument that carries\n // `abortSignal`, `toolCallId`, `messages`, etc. Forward `abortSignal` so\n // a parent agent's abort cancels in-flight sub-agent calls instead of\n // leaving them running and producing detached output.\n execute: async (toolInput: TInput, execOptions?: { abortSignal?: AbortSignal }) => {\n const abortSignal = execOptions?.abortSignal;\n // When inside a streaming workflow, automatically use stream() and merge to the active writer.\n // Otherwise fall back to generate().\n const writer = getActiveWriter();\n if (writer) {\n const result = await this.streamWithOptions(ctx, toolInput, { abortSignal });\n writer.merge(result.toUIMessageStream());\n // Drain the text side to release the StreamTextResult anchor — the\n // writer.merge above only consumes the UI-message side, leaving\n // `result.text` pending until awaited.\n //\n // When mapOutput is provided, we explicitly do NOT call extractOutput\n // here: extractOutput throws if `hasOutput` is true but the model\n // returned no structured value, which would block any mapOutput that\n // wanted to recover from missing/malformed structured output by\n // reading `result.text`. mapOutput becomes the user's chance to do\n // their own extraction.\n if (options?.mapOutput) {\n await result.text;\n return options.mapOutput(result);\n }\n return extractOutput(result, this.hasOutput, this.validateOutput);\n }\n const result = await this.generateWithOptions(ctx, toolInput, { abortSignal });\n if (options?.mapOutput) return options.mapOutput(result);\n return extractOutput(result, this.hasOutput, this.validateOutput);\n },\n // TS cannot simplify the SDK's `NeverOptional<TOutput, ...>` conditional in a\n // generic context, so we cast through `unknown` instead of `any`.\n } as unknown as Tool<TInput, TOutput>);\n }\n\n // ── Internal: shared call helpers ─────────────────────────────\n // `generate()` / `stream()` and the `asTool()` wrapper all funnel through\n // these so the abortSignal-forwarding and onError-wrapping logic stays in\n // one place. `extra` carries per-call overrides (currently `abortSignal`).\n\n // If the user-supplied onError callback itself throws, attach the original\n // model error as `.cause` on the new error and rethrow the wrapper. Without\n // this, the original error is silently shadowed.\n private async invokeOnError(error: unknown, ctx: TContext, input: TInput): Promise<void> {\n if (!this.config.onError) return;\n try {\n await this.config.onError({ error, ctx, input, writer: getActiveWriter() });\n } catch (handlerError) {\n // Promote non-Error throws (`throw \"boom\"`, `throw 42`, etc.) so we\n // can chain the original error onto a real Error and keep diagnostics\n // intact. Re-throwing the raw non-Error value would drop the chain.\n if (handlerError instanceof Error) {\n if (handlerError.cause === undefined) {\n (handlerError as { cause?: unknown }).cause = error;\n }\n throw handlerError;\n }\n const wrapped = new Error(\n `Agent \"${this.id}\": onError handler threw a non-Error value (${typeof handlerError}): ${String(handlerError)}`,\n );\n (wrapped as { cause?: unknown }).cause = error;\n throw wrapped;\n }\n }\n\n private async generateWithOptions(\n ctx: TContext,\n input: TInput,\n extra: { abortSignal?: AbortSignal },\n ): Promise<GenerateTextResult<ToolSet, OutputType<TOutput>>> {\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n try {\n // The SDK's `Output.object<T>` return type doesn't simplify generically\n // — cast through `unknown` rather than `any` so we keep the boundary\n // narrow without forcing the call site to know SDK option internals.\n return (await generateText({ ...options, ...extra } as unknown as Parameters<typeof generateText>[0])) as GenerateTextResult<ToolSet, OutputType<TOutput>>;\n } catch (error: unknown) {\n await this.invokeOnError(error, ctx, input);\n throw error;\n }\n }\n\n private async streamWithOptions(\n ctx: TContext,\n input: TInput,\n extra: { abortSignal?: AbortSignal },\n ): Promise<StreamTextResult<ToolSet, OutputType<TOutput>>> {\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n try {\n // Only attach `onError` when the user supplied one. Setting it to\n // `undefined` explicitly suppresses some SDK versions' default\n // rethrow-on-partial-stream-error, silently swallowing stream failures.\n const onErrorOption = this.config.onError\n ? {\n onError: async ({ error }: { error: unknown }) => {\n // `invokeOnError` rethrows when the user's handler throws, to\n // preserve diagnostics. On the generate path that rethrow is\n // caught by the caller; here it would reject inside the SDK's\n // stream `onError` callback, which has no error channel and can\n // surface as an unhandled rejection. Catch it and surface the\n // failure (original chained as `cause`) so the intent isn't lost.\n try {\n await this.invokeOnError(error, ctx, input);\n } catch (handlerError) {\n // eslint-disable-next-line no-console\n console.error(`Agent \"${this.id}\": onError handler threw on the stream path:`, handlerError);\n }\n },\n }\n : {};\n return streamText({\n ...options,\n ...extra,\n ...onErrorOption,\n } as unknown as Parameters<typeof streamText>[0]) as StreamTextResult<ToolSet, OutputType<TOutput>>;\n } catch (error: unknown) {\n // streamText typically defers errors to the returned stream, but a\n // synchronous throw (e.g., invalid options) would otherwise bypass\n // onError entirely.\n await this.invokeOnError(error, ctx, input);\n throw error;\n }\n }\n\n private buildCallOptions(resolved: ResolvedAgentConfig, ctx: TContext, input: TInput): Record<string, unknown> {\n if (resolved.messages === undefined && resolved.prompt === undefined) {\n throw new Error(\n `Agent \"${this.id}\": neither \\`prompt\\` nor \\`messages\\` was provided. ` +\n `Configure one of them, or supply a Resolvable that returns one based on input.`,\n );\n }\n return {\n ...this._passthrough,\n model: resolved.model,\n tools: resolved.tools,\n activeTools: resolved.activeTools,\n toolChoice: resolved.toolChoice,\n stopWhen: resolved.stopWhen,\n ...(resolved.messages !== undefined\n ? { messages: resolved.messages }\n : { prompt: resolved.prompt }),\n // Use `!== undefined` rather than truthy so an intentional empty\n // `system: \"\"` survives instead of being silently dropped.\n ...(resolved.system !== undefined ? { system: resolved.system } : {}),\n ...(this.config.output ? { output: this.config.output } : {}),\n // Only attach the callback when the user supplied one. Passing\n // `undefined` explicitly can suppress default SDK rethrow behavior in\n // some versions.\n ...(this._onStepFinish\n ? { onStepFinish: (event: OnStepFinishEvent) => this._onStepFinish!({ result: event, ctx, input, writer: getActiveWriter() }) }\n : {}),\n ...(this._onFinish\n ? { onFinish: (event: OnFinishEvent) => this._onFinish!({ result: event, ctx, input, writer: getActiveWriter() }) }\n : {}),\n };\n }\n\n private resolveConfig(ctx: TContext, input: TInput): ResolvedAgentConfig | Promise<ResolvedAgentConfig> {\n if (!this._hasDynamicConfig) {\n return {\n model: this.config.model as LanguageModel,\n prompt: this.config.prompt as string | undefined,\n system: this.config.system as string | undefined,\n messages: this.config.messages as ModelMessage[] | undefined,\n tools: this._resolvedStaticTools ?? this.resolveTools(\n (this.config.tools as AgentToolSet<TContext> | undefined) ?? {}, ctx\n ),\n activeTools: this.config.activeTools as string[] | undefined,\n toolChoice: this.config.toolChoice as ToolChoice<ToolSet> | undefined,\n stopWhen: this.config.stopWhen as StopCondition<ToolSet> | Array<StopCondition<ToolSet>> | undefined,\n };\n }\n return this.resolveConfigAsync(ctx, input);\n }\n\n private async resolveConfigAsync(ctx: TContext, input: TInput): Promise<ResolvedAgentConfig> {\n const [model, prompt, system, messages, rawTools, activeTools, toolChoice] = await Promise.all([\n resolveValue(this.config.model, ctx, input),\n resolveValue(this.config.prompt, ctx, input),\n resolveValue(this.config.system, ctx, input),\n resolveValue(this.config.messages, ctx, input),\n resolveValue(this.config.tools, ctx, input),\n resolveValue(this.config.activeTools, ctx, input),\n resolveValue(this.config.toolChoice, ctx, input),\n ]);\n const tools = this.resolveTools(rawTools ?? {}, ctx);\n return {\n model,\n prompt,\n system,\n messages,\n tools,\n activeTools,\n toolChoice,\n // `stopWhen` is always static — see field declaration for why.\n stopWhen: this.config.stopWhen,\n };\n }\n\n private resolveTools(\n tools: AgentToolSet<TContext>,\n ctx: TContext\n ): Record<string, Tool> {\n const entries = Object.entries(tools);\n if (entries.length === 0) return tools as Record<string, Tool>;\n let hasProvider = false;\n const resolved: Record<string, Tool> = {};\n for (const [key, toolOrProvider] of entries) {\n if (isToolProvider<TContext>(toolOrProvider)) {\n hasProvider = true;\n resolved[key] = toolOrProvider.createTool(ctx as Readonly<TContext>);\n } else {\n resolved[key] = toolOrProvider as Tool;\n }\n }\n return hasProvider ? resolved : (tools as Record<string, Tool>);\n }\n}\n","import { tool, type Tool, type ToolExecutionOptions, type FlexibleSchema, type UIMessageStreamWriter } from \"ai\";\nimport { getActiveWriter } from \"./utils\";\n\nexport const TOOL_PROVIDER_BRAND = Symbol.for(\"agent-workflow.ToolProvider\");\n\nexport type ToolExecuteOptions = ToolExecutionOptions & {\n writer?: UIMessageStreamWriter;\n};\n\ntype ToolProviderOptions = NonNullable<Tool[\"providerOptions\"]>;\n\nexport type ToolProviderConfig<TContext, TInput, TOutput> = {\n description?: string;\n input: FlexibleSchema<TInput>;\n outputSchema?: FlexibleSchema<TOutput>;\n providerOptions?: ToolProviderOptions;\n execute: (input: TInput, ctx: Readonly<TContext>, options: ToolExecuteOptions) => Promise<TOutput>;\n};\n\nexport interface IToolProvider<TContext> {\n readonly [TOOL_PROVIDER_BRAND]: true;\n createTool(context: Readonly<TContext>): Tool;\n}\n\nexport class ToolProvider<\n TContext,\n TInput = unknown,\n TOutput = unknown,\n> implements IToolProvider<TContext> {\n readonly [TOOL_PROVIDER_BRAND] = true as const;\n private readonly config: ToolProviderConfig<TContext, TInput, TOutput>;\n\n constructor(config: ToolProviderConfig<TContext, TInput, TOutput>) {\n this.config = config;\n }\n\n createTool(context: Readonly<TContext>): Tool {\n const { execute, input: inputSchema, ...toolDef } = this.config;\n // The shape matches `Tool<TInput, TOutput>`, but TS cannot simplify the SDK's\n // `NeverOptional<TOutput, ...>` conditional in a generic context, so the literal\n // is not assignable directly. Cast through `unknown` rather than `any` so the\n // return type and call sites still get type-checked.\n return tool<TInput, TOutput>({\n ...toolDef,\n inputSchema,\n execute: (input: TInput, options: ToolExecutionOptions) => execute(input, context, { ...options, writer: getActiveWriter() } as ToolExecuteOptions),\n } as unknown as Tool<TInput, TOutput>);\n }\n}\n\nexport function defineTool<TContext>() {\n return <TInput, TOutput>(\n config: ToolProviderConfig<TContext, TInput, TOutput>\n ): ToolProvider<TContext, TInput, TOutput> => new ToolProvider(config);\n}\n\nexport function isToolProvider<TContext>(obj: unknown): obj is IToolProvider<TContext> {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n TOOL_PROVIDER_BRAND in obj\n );\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\nimport type { UIMessageStreamWriter } from \"ai\";\nimport type { ZodType } from \"zod\";\n\n// ── Stream writer context ────────────────────────────────────────────\n// Invisible to the user. The workflow sets the writer before agent execution;\n// tools and sub-agents read it automatically via getActiveWriter().\n\nconst writerStorage = new AsyncLocalStorage<UIMessageStreamWriter>();\n\nexport function runWithWriter<T>(writer: UIMessageStreamWriter, fn: () => T): T {\n return writerStorage.run(writer, fn);\n}\n\n/**\n * @internal — NOT part of the public API. Do not export from `index.ts`.\n *\n * Returns the active `UIMessageStreamWriter` if the current async context is\n * running inside a streaming workflow, or `undefined` otherwise.\n *\n * This is the internal mechanism that powers the writer hand-off to user code.\n * Consumers should reach the writer through the supported, explicit paths\n * instead of calling this directly:\n * - `defineTool` / `ToolProvider` inject `writer` into the `execute(input,\n * ctx, { writer })` options.\n * - Agent `onStepFinish` / `onFinish` / `onError` callbacks receive `writer`.\n * - Inline `Workflow.step(id, fn)` handlers receive `writer` in their params.\n *\n * **Timing note (for internal callers):** must be read from *inside* the live\n * execution callback (e.g. `Tool.execute`), not at construction/`createTool`\n * time — the writer is only set on the async context while an agent stream\n * call is in flight.\n */\nexport function getActiveWriter(): UIMessageStreamWriter | undefined {\n return writerStorage.getStore();\n}\n\n// ── Common types ─────────────────────────────────────────────────────\n\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * Sentinel returned from `foreach` / `parallel`'s `onError` handler to omit\n * the failed item (foreach: shortens the output array; parallel: leaves the\n * slot `undefined`). Lives here — a leaf module — so the step subclasses can\n * reach it without a value-level cycle through ./workflow. `Workflow.SKIP`\n * and the package-level `SKIP` export both alias this symbol.\n */\nexport const SKIP: unique symbol = Symbol(\"pipeai.foreach.skip\");\n\n/**\n * A value that can be static or derived from context and input.\n * Used for agent config fields that may need runtime resolution.\n *\n * Functions may return a Promise for async resolution; static values are always sync.\n */\nexport type Resolvable<TCtx, TInput, TValue> =\n | TValue\n | ((ctx: Readonly<TCtx>, input: TInput) => TValue | Promise<TValue>);\n\nexport function resolveValue<TCtx, TInput, TValue>(\n value: Resolvable<TCtx, TInput, TValue>,\n ctx: TCtx,\n input: TInput\n): TValue | Promise<TValue>;\nexport function resolveValue<TCtx, TInput, TValue>(\n value: Resolvable<TCtx, TInput, TValue> | undefined,\n ctx: TCtx,\n input: TInput\n): TValue | Promise<TValue> | undefined {\n if (typeof value === \"function\") {\n return (value as (ctx: TCtx, input: TInput) => TValue | Promise<TValue>)(ctx, input);\n }\n return value;\n}\n\n/**\n * Extract structured output from an AI SDK result.\n *\n * - When `hasStructuredOutput` is `true`, awaits `result.output`. If the SDK\n * did not produce a structured value, this throws — silent fall-back to raw\n * text would mask schema mismatches at the call site.\n * - When `schema` is provided, the awaited output is validated through the\n * Zod schema before being returned, catching SDK-side parse drift.\n * - When `hasStructuredOutput` is `false`, returns `result.text`.\n *\n * Works for both generate (sync .output/.text) and stream (async .output/.text) results.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function extractOutput(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n result: any,\n hasStructuredOutput: boolean,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n schema?: ZodType<any>,\n): Promise<unknown> {\n if (hasStructuredOutput) {\n const output = await result.output;\n if (output === undefined) {\n throw new Error(\n \"Agent: structured output was declared but the model returned none. \" +\n \"This usually means the model produced text that did not match the declared schema, \" +\n \"or the underlying SDK did not parse the structured output.\",\n );\n }\n if (schema) {\n return schema.parse(output);\n }\n return output;\n }\n return await result.text;\n}\n\n/**\n * Recursively freeze an object graph. Cycles are tracked via a WeakSet so we\n * never recurse into the same node twice. Maps/Sets stay structurally frozen\n * but `.set()`/`.add()` still mutate them — Object.freeze doesn't cover those.\n */\nexport function deepFreeze<T>(value: T, seen: WeakSet<object> = new WeakSet()): T {\n if (value === null || typeof value !== \"object\" || seen.has(value as object)) return value;\n // Already-frozen subtree (e.g. user-passed frozen ctx) — its children are\n // either also frozen or intentionally mutable, either way we should not recurse.\n if (Object.isFrozen(value)) return value;\n seen.add(value as object);\n Object.freeze(value);\n for (const key of Reflect.ownKeys(value as object)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deepFreeze((value as any)[key], seen);\n }\n return value;\n}\n\n// ── stepShapeHash (F1) ───────────────────────────────────────────────\n//\n// Recursive SHA-256 of the workflow's structural shape (index, type, id,\n// nested workflow shapes). Used by checkpoint resume to detect drift —\n// when the user inserts/removes/reorders a step, the hash changes and\n// resume refuses to continue unless explicitly told to via\n// `{ skipShapeCheck: true }`.\n//\n// **Agent identity is NOT in the hash.** Two checkpoints from runs that\n// used different agent configs (same id) hash identically. Version agents\n// by content if resume-trust matters.\n\n/**\n * The minimal shape interface this util needs from a `SealedWorkflow`.\n * Importing the workflow class here would create a circular dependency\n * (utils.ts ← workflow.ts and workflow.ts ← utils.ts); so we accept any\n * object exposing `id` and `getStepsForShapeHash()`.\n */\nexport interface WorkflowShapeHashable {\n readonly id?: string;\n // Returns the step nodes for this workflow. Structurally typed to avoid a\n // circular import — the real type is `ReadonlyArray<Step>` (from ./steps/step).\n getStepsForShapeHash(): ReadonlyArray<StepNodeShape>;\n}\n\n/**\n * Structural typing for a step node as seen by the shape hasher. Mirrors the\n * `type` / `id` the run loop dispatches on, without importing the `Step` class.\n * Only these two fields feed the hash; the run loop itself (workflow.ts) is the\n * load-bearing consumer of the full `Step` shape.\n */\nexport interface StepNodeShape {\n readonly type: string;\n readonly id: string;\n}\n\nexport function computeStepShapeHash(\n steps: ReadonlyArray<StepNodeShape>,\n getNested: (node: StepNodeShape) => readonly WorkflowShapeHashable[],\n): string {\n return createHash(\"sha256\").update(canonicalDescriptor(steps, getNested, new WeakSet())).digest(\"hex\");\n}\n\n/**\n * `path` tracks the current DFS stack only — added on entry, removed on exit.\n * Sibling re-visits of the same SealedWorkflow are NOT cycles (shared\n * subgraphs hash identically to two structurally-equivalent distinct\n * instances). Only ancestor re-visits (true cycles) emit the cycle marker.\n */\nfunction canonicalDescriptor(\n steps: ReadonlyArray<StepNodeShape>,\n getNested: (node: StepNodeShape) => readonly WorkflowShapeHashable[],\n path: WeakSet<WorkflowShapeHashable>,\n): string {\n return JSON.stringify(steps.map((s, i) => {\n const triple: (number | string)[] = [i, s.type, s.id];\n for (const inner of getNested(s)) {\n if (path.has(inner)) {\n triple.push(`<cycle:${inner.id ?? \"anon\"}>`);\n continue;\n }\n path.add(inner);\n try {\n triple.push(canonicalDescriptor(inner.getStepsForShapeHash(), getNested, path));\n } finally {\n path.delete(inner);\n }\n }\n return triple;\n }));\n}\n\n// ── warnOnce (F1) — module-level dedup helper ────────────────────────\n\nconst warnedOnceKeys = new Set<string>();\nexport function warnOnce(key: string, message?: string): void {\n if (warnedOnceKeys.has(key)) return;\n warnedOnceKeys.add(key);\n // eslint-disable-next-line no-console\n console.warn(message ?? key);\n}\n\n/**\n * @internal — test-only reset of the warnOnce dedup. Same shape as\n * workflow.ts's `__resetStreamOnErrorOnSuspendWarnForTests`.\n */\nexport function __resetWarnOnceForTests(): void {\n warnedOnceKeys.clear();\n}\n","import {\n createUIMessageStream,\n type UIMessage,\n type UIMessageStreamWriter,\n} from \"ai\";\nimport { type Agent } from \"./agent\";\nimport { computeStepShapeHash, deepFreeze, warnOnce, SKIP, type MaybePromise } from \"./utils\";\nimport { TransformStep } from \"./steps/transform-step\";\nimport { AgentStep } from \"./steps/agent-step\";\nimport { PredicateBranchStep, SelectBranchStep } from \"./steps/branch-step\";\nimport { ForeachStep } from \"./steps/foreach-step\";\nimport { ParallelStep } from \"./steps/parallel-step\";\nimport { GateStep, type GateStepOptions } from \"./steps/gate-step\";\nimport { CatchStep } from \"./steps/catch-step\";\nimport { FinallyStep } from \"./steps/finally-step\";\nimport { NestedWorkflowStep } from \"./steps/nested-workflow-step\";\nimport { RepeatStep } from \"./steps/repeat-step\";\nimport { Step } from \"./steps/step\";\n\n// The public type / API surface lives in ./types. Re-export it so existing\n// `from \"./workflow\"` consumers (index.ts, tests) are unchanged, and import the\n// subset this file references internally.\nexport type * from \"./types\";\nimport type {\n GateSnapshot, CheckpointSnapshot, LegacyGateSnapshotV1, WorkflowSnapshot,\n WorkflowStepType, WorkflowObservability, RunOptions,\n StepOptions, InlineStepOptions, ConditionalStepOptions, NestedStepOptions,\n BranchCase, BranchSelect, WorkflowResult, WorkflowStreamResult,\n WorkflowStreamOptions, LoopPredicate, RepeatOptions, ParallelTarget,\n ParallelOptions, ParallelOutputRecord, ParallelOutputTuple,\n ParallelOutputRecordPartial, ParallelOutputTuplePartial, SchemaWithParse,\n SkipPassthrough, ElementOf, NoGates, GatelessBranch, ForeachOptions,\n} from \"./types\";\n\n// Error classes + reserved synthetic step ids live in the leaf `./errors`\n// module (no internal imports, so steps can reach them without a value cycle).\n// Re-exported here so `from \"./workflow\"` consumers (index.ts, tests) are\n// unchanged.\nimport {\n WorkflowBranchError, WorkflowLoopError,\n CHECKPOINT_STEP_ID, ABORT_STEP_ID, GATE_RESUME_STEP_ID,\n} from \"./errors\";\nexport { WorkflowBranchError, WorkflowLoopError, CHECKPOINT_STEP_ID, ABORT_STEP_ID, GATE_RESUME_STEP_ID };\n\n// Runtime plumbing (per-run state, observability dispatch, warnings, checkpoint\n// sink, pending-error demotion) lives in ./runtime. The `RuntimeState` /\n// `PendingError` / `ResumeDescent` types live there too.\nimport {\n resolveFreezeSnapshots, pendingErrorSourceToStepType, emitCheckpoint,\n __resetStreamOnErrorOnSuspendWarnForTests, pushWarning, demotePendingError,\n maybeWarnStreamOnErrorOnSuspend, makeRuntimeState, makeAbortError,\n fireHook as fireHookFree,\n} from \"./runtime\";\nimport type { RuntimeState, PendingError, ResumeDescent } from \"./runtime\";\nexport type { RuntimeState, PendingError, ResumeDescent } from \"./runtime\";\n// Tests reach for this one-shot warn reset via `from \"../workflow\"`.\nexport { __resetStreamOnErrorOnSuspendWarnForTests };\n\n/**\n * Convert a legacy v1 gate snapshot to a v2 gate snapshot. Long-lived\n * storage (Redis-without-TTL, S3, Postgres) should re-serialize via this\n * helper before v0.8.0+ drops v1 acceptance.\n */\nexport function migrateSnapshot(legacy: LegacyGateSnapshotV1): GateSnapshot {\n if (legacy.version !== 1) {\n throw new Error(`migrateSnapshot: expected v1 snapshot, got version ${(legacy as { version: number }).version}`);\n }\n return {\n version: 2,\n kind: \"gate\",\n resumeFromIndex: legacy.resumeFromIndex,\n output: legacy.output,\n gateId: legacy.gateId,\n gatePayload: legacy.gatePayload,\n };\n}\n\n/**\n * Seed for a run: the initial pipeline `output` plus an optional pre-execute\n * `initialError`. The resume entry points compute these differently (gate\n * schema-parse + merge vs. plain snapshot output), but every entry point then\n * funnels through the same `runGenerate` / `runStream` machinery.\n */\ntype StateSeed = { output: unknown; initialError: PendingError | null; resumeDescent?: ResumeDescent };\n\n// ── Sealed Workflow (returned by finally — execution only) ───────────\n\nexport class SealedWorkflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> {\n readonly id?: string;\n protected readonly steps: ReadonlyArray<Step>;\n protected readonly observability?: WorkflowObservability;\n // Memoized — see ensureDuplicateCheck().\n private duplicateCheckPassed = false;\n // Memoized lazily per terminal instance: the executable / checkpointable step\n // counts (one walk) and the recursive shape hash (separate — it's expensive).\n private _stepCounts?: { executable: number; checkpointable: number };\n private _cachedStepShapeHash?: string;\n\n protected constructor(steps: ReadonlyArray<Step>, id?: string, observability?: WorkflowObservability) {\n this.steps = steps;\n this.id = id;\n this.observability = observability;\n }\n\n // ── Construction-time validation (memoized per terminal instance) ────\n\n /**\n * Walk the step list once per terminal instance. Rejects:\n * - Duplicate `(type, id)` pairs.\n * - User step ids containing the reserved `::pipeai::` namespace\n * (CHECKPOINT_STEP_ID lives there).\n */\n private ensureDuplicateCheck(): void {\n if (this.duplicateCheckPassed) return;\n const seen = new Map<string, number>();\n for (let i = 0; i < this.steps.length; i++) {\n const node = this.steps[i];\n if (node.id.includes(\"::pipeai::\")) {\n throw new Error(\n `Workflow: step id \"${node.id}\" uses the reserved \"::pipeai::\" namespace at index ${i}.`\n );\n }\n const key = `${node.type}:${node.id}`;\n const prior = seen.get(key);\n if (prior !== undefined) {\n throw new Error(\n `Workflow: duplicate (${node.type}, \"${node.id}\") at indices ${prior} and ${i}. ` +\n `Pass an explicit \\`{ id }\\` (e.g. for back-to-back \\`branch(...)\\` or \\`foreach(agentX).foreach(agentX)\\`) to disambiguate.`\n );\n }\n seen.set(key, i);\n }\n this.duplicateCheckPassed = true;\n }\n\n // ── step counts + shape-hash (memoized) ────────────────────────────\n\n /**\n * Two cadence inputs from a single walk:\n * - `executable` — nodes that aren't `catch` / `finally`. A graph-size\n * proxy for the catastrophe threshold in {@link validateRunOptions}.\n * - `checkpointable` — `type === \"step\"` nodes only (this includes\n * branch / foreach / repeat / parallel / nested). Drives the checkpoint\n * auto-cadence denominator: gates suspend/skip and never reach the\n * checkpoint block, so counting them would dilute the \"~4 checkpoints\n * across the run\" target.\n */\n protected get stepCounts(): { executable: number; checkpointable: number } {\n if (this._stepCounts) return this._stepCounts;\n let executable = 0;\n let checkpointable = 0;\n for (const s of this.steps) {\n if (s.type !== \"catch\" && s.type !== \"finally\") executable++;\n if (s.type === \"step\") checkpointable++;\n }\n return (this._stepCounts = { executable, checkpointable });\n }\n\n /** @internal — used by `computeStepShapeHash` to descend nested workflows. */\n getStepsForShapeHash(): ReadonlyArray<Step> {\n return this.steps;\n }\n\n protected get cachedStepShapeHash(): string {\n if (this._cachedStepShapeHash !== undefined) return this._cachedStepShapeHash;\n const getNested = (node: { nestedWorkflow?: SealedWorkflow<unknown, unknown, unknown> }) =>\n node.nestedWorkflow ? [node.nestedWorkflow] : [];\n this._cachedStepShapeHash = computeStepShapeHash(\n this.steps as unknown as ReadonlyArray<{ type: string; id: string }>,\n getNested as unknown as (node: { type: string; id: string }) => readonly { id?: string; getStepsForShapeHash(): ReadonlyArray<{ type: string; id: string }> }[],\n );\n return this._cachedStepShapeHash;\n }\n\n /**\n * Validate user-provided RunOptions before a run begins. Throws on\n * outright errors and on the loud-disaster combo (`freezeSnapshots: true\n * + checkpointEvery: 1` on a workflow of 8+ steps). Warns once on the\n * merely-suspicious combo (`freezeSnapshots: true + cadence <= 2`), and on\n * checkpoint-cadence options set without an `onCheckpoint` sink (a no-op\n * that usually signals a forgotten sink).\n */\n protected validateRunOptions(opts: RunOptions | undefined): void {\n if (!opts) return;\n if (opts.checkpointEvery !== undefined && opts.checkpointWhen !== undefined) {\n throw new Error(\"RunOptions: checkpointEvery and checkpointWhen are mutually exclusive\");\n }\n if (opts.checkpointEvery !== undefined && (!Number.isInteger(opts.checkpointEvery) || opts.checkpointEvery < 1)) {\n throw new Error(`RunOptions: checkpointEvery must be a positive integer, got ${opts.checkpointEvery}`);\n }\n // Cadence options without a sink do nothing — likely a forgotten sink.\n if (!opts.onCheckpoint) {\n if (opts.checkpointEvery !== undefined || opts.checkpointWhen !== undefined) {\n warnOnce(\n \"pipeai:checkpoint-without-sink\",\n \"pipeai: checkpointEvery/checkpointWhen set without onCheckpoint — no checkpoints will fire. Did you forget the onCheckpoint sink?\",\n );\n }\n return;\n }\n const length = this.stepCounts.executable;\n // Cadence is computed from the checkpointable-step count (gates excluded)\n // so this guard predicts the actual runtime cadence; `length` stays the\n // executable-node count as a graph-size proxy for the catastrophe threshold.\n const cadence = opts.checkpointEvery ?? Math.max(1, Math.ceil(this.stepCounts.checkpointable / 4));\n if (opts.freezeSnapshots && opts.freezeSnapshots !== \"iAcceptThePerformanceCost\" && cadence === 1 && length >= 8) {\n throw new Error(\n `freezeSnapshots+checkpointEvery:1 on a ${length}-step workflow is reliably catastrophic. ` +\n `Set checkpointEvery >= 5, freezeSnapshots: false, or pass \"iAcceptThePerformanceCost\".`\n );\n }\n if (opts.freezeSnapshots && cadence <= 2) {\n warnOnce(\n \"pipeai:freezeSnapshots-low-cadence\",\n \"pipeai: freezeSnapshots+checkpointEvery<=2 compounds graph-walk cost.\",\n );\n }\n }\n\n // ── Observability helpers ─────────────────────────────────────\n\n /** Observability event `type` for a node: a `type: \"step\"` node reports its\n * `category` (agent / transform default to `\"step\"`); every other node's\n * `type` IS the event type. */\n private obsEventType(node: Step): WorkflowStepType {\n if (node.type !== \"step\") return node.type;\n return node.category ?? \"step\";\n }\n\n /**\n * Fire an observability hook safely. Returns `undefined` synchronously when\n * no hook is registered — avoiding the promise wrapper + microtask that an\n * async function would unconditionally allocate on every step boundary.\n *\n * On hook throw:\n * - non-`onStepError` hooks: warning pushed + console.error.\n * - `onStepError`: throw is propagated as a return value; the run loop\n * attaches it as `cause` on the original step error.\n *\n * Returns the hook's thrown error if any; undefined otherwise. Callers\n * `await` the result — `await undefined` is sync, so the no-hook path\n * stays allocation-free.\n *\n * Thin delegate to the free `fireHook` (which takes an explicit\n * observability), kept as a method so the loop's many `this.fireHook` call\n * sites stay unchanged.\n */\n protected fireHook<\n K extends keyof WorkflowObservability,\n E extends Parameters<NonNullable<WorkflowObservability[K]>>[0],\n >(\n state: RuntimeState,\n name: K,\n event: E,\n ): MaybePromise<unknown> {\n return fireHookFree(this.observability, state, name, event);\n }\n\n /**\n * Fire `onStepError` for a step-body failure and honor the documented\n * cause-attachment contract uniformly across every firing path (step, gate,\n * catch, finally, checkpoint). When the hook itself throws, its error is\n * attached as `cause` on the ORIGINAL error so the original still reaches the\n * caller with the failure trail attached. If the original error is frozen /\n * non-extensible (cause assignment throws) or is not an object, the hook\n * error is recorded as a warning instead — so an `onStepError` throw is never\n * silently lost. (The suspension-wins tail fires `onStepError` separately, on\n * its own demotion path.)\n */\n protected async fireStepErrorAndAttachCause(\n state: RuntimeState,\n event: { stepId: string; type: WorkflowStepType; ctx: unknown; error: unknown; durationMs: number },\n ): Promise<void> {\n const obsError = await this.fireHook(state, \"onStepError\", event);\n if (obsError === undefined) return;\n const e = event.error;\n if (typeof e === \"object\" && e !== null) {\n try {\n (e as { cause?: unknown }).cause = obsError;\n return;\n } catch {\n // Original error frozen / non-extensible — fall through to the warning.\n }\n }\n pushWarning(state, \"onStepError\", event.stepId, obsError);\n }\n\n // ── Execution ─────────────────────────────────────────────────\n\n async generate(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, opts?: RunOptions]\n : [input: TInput, opts?: RunOptions]\n ): Promise<WorkflowResult<TOutput>> {\n this.ensureDuplicateCheck();\n const input = args[0];\n const opts = args[1] as RunOptions | undefined;\n return this.runGenerate(ctx, 0, opts, () => ({ output: input, initialError: null }));\n }\n\n stream<UI_MESSAGE extends UIMessage = UIMessage>(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n : [input: TInput, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n ): WorkflowStreamResult<TOutput, UI_MESSAGE> {\n this.ensureDuplicateCheck();\n const input = args[0];\n const options = args[1] as WorkflowStreamOptions<UI_MESSAGE> | undefined;\n const opts = args[2] as RunOptions | undefined;\n return this.runStream(ctx, 0, opts, options, () => ({ output: input, initialError: null }));\n }\n\n // Helper — converts terminal RuntimeState into a WorkflowResult; freezes\n // snapshot + warnings if requested via runOptions.\n protected buildResult(state: RuntimeState): WorkflowResult<TOutput> {\n const warnings = state.warnings ?? [];\n // freezeSnapshots freezes the warnings array on BOTH terminal paths\n // (complete and suspended), per the documented contract.\n if (resolveFreezeSnapshots(state)) {\n deepFreeze(warnings);\n }\n if (state.suspension) {\n return { status: \"suspended\", snapshot: state.suspension, warnings };\n }\n return { status: \"complete\", output: state.output as TOutput, warnings };\n }\n\n // ── Shared run drivers (generate / stream) ────────────────────\n // Every public entry point — base generate/stream plus gate- and\n // checkpoint-resume — differs only in (a) how it seeds the initial output /\n // pre-execute error and (b) the start index. Both drivers take a `seed`\n // thunk for (a) and a `startIndex` for (b); the rest (validation, state\n // construction, execute, result building, stream plumbing) is identical.\n\n protected async runGenerate(\n ctx: unknown,\n startIndex: number,\n opts: RunOptions | undefined,\n seed: () => MaybePromise<StateSeed>,\n ): Promise<WorkflowResult<TOutput>> {\n this.validateRunOptions(opts);\n const seeded = await seed();\n const state = makeRuntimeState(ctx, seeded.output, \"generate\", opts);\n if (seeded.resumeDescent) state.resumeDescent = seeded.resumeDescent;\n await this.execute(state, startIndex, opts, seeded.initialError);\n return this.buildResult(state);\n }\n\n protected runStream<UI_MESSAGE extends UIMessage = UIMessage>(\n ctx: unknown,\n startIndex: number,\n opts: RunOptions | undefined,\n options: WorkflowStreamOptions<UI_MESSAGE> | undefined,\n seed: () => MaybePromise<StateSeed>,\n ): WorkflowStreamResult<TOutput, UI_MESSAGE> {\n this.validateRunOptions(opts);\n\n let resolveOutput!: (value: WorkflowResult<TOutput>) => void;\n let rejectOutput!: (error: unknown) => void;\n const outputPromise = new Promise<WorkflowResult<TOutput>>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n // Prevent unhandled rejection warning if the consumer never awaits `output`.\n outputPromise.catch(() => {});\n\n const stream = createUIMessageStream<UI_MESSAGE>({\n execute: async ({ writer }) => {\n // Seeding (gate schema-parse + merge) runs here, inside the stream's\n // error pipeline — a throw must surface as a rejected `output`/stream,\n // not escape synchronously from `.stream(...)`. The resume seeds catch\n // their own errors into `initialError` so `.catch()` can observe them.\n try {\n const seeded = await seed();\n const state = makeRuntimeState(ctx, seeded.output, \"stream\", opts, writer);\n if (seeded.resumeDescent) state.resumeDescent = seeded.resumeDescent;\n await this.execute(state, startIndex, opts, seeded.initialError);\n const result = this.buildResult(state);\n maybeWarnStreamOnErrorOnSuspend(result, options);\n resolveOutput(result);\n } catch (error) {\n rejectOutput(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n ...(options?.originalMessages ? { originalMessages: options.originalMessages } : {}),\n ...(options?.generateId ? { generateId: options.generateId } : {}),\n });\n\n return { stream, output: outputPromise };\n }\n\n // ── Internal: execute pipeline ────────────────────────────────\n\n protected async execute(\n state: RuntimeState,\n startIndex: number = 0,\n opts?: RunOptions,\n initialError: PendingError | null = null,\n ): Promise<void> {\n if (this.steps.length === 0) {\n throw new Error(\"Workflow has no steps. Add at least one step before calling generate() or stream().\");\n }\n\n // Make sure runOptions is plumbed even if the caller didn't initialize state.\n if (opts !== undefined && state.runOptions === undefined) {\n state.runOptions = opts;\n }\n\n // Hoisted once per run — the numeric cadence form has no per-step input,\n // so recomputing it per iteration was pure overhead.\n const ckptCadence = opts?.onCheckpoint && opts.checkpointWhen === undefined\n ? (opts.checkpointEvery ?? Math.max(1, Math.ceil(this.stepCounts.checkpointable / 4)))\n : 0;\n\n // Counts completed executable step bodies (not raw loop indices), so the\n // numeric `checkpointEvery` cadence means \"every N executable steps\" even\n // when catch/finally nodes are interleaved. Boxed so `maybeCheckpoint` can\n // advance it.\n const ckptCounter = { seen: 0 };\n\n // `state.pendingError` is the single source of truth for the in-flight\n // error — steps park their captured throws there, and `catch`/`finally`\n // steps read/clear it. `initialError` lets callers (e.g.\n // ResumedWorkflow.stream) seed the pipeline already-in-error so a\n // pre-execute failure (schema.parse, merge throw) flows through downstream\n // `.catch()` like any other step failure instead of escaping synchronously.\n state.pendingError = initialError ?? undefined;\n\n // Tracks whether the abort signal has already been promoted into\n // pendingError in this execute() pass (see `promoteAbort`).\n const abortState = { promoted: false };\n\n for (let i = startIndex; i < this.steps.length; i++) {\n // Abort checkpoint — runs at every iteration boundary, before any\n // node dispatch, so finally/catch nodes that come AFTER the abort\n // still get to run (cleanup + recovery contract).\n this.promoteAbort(state, abortState);\n\n const node = this.steps[i];\n\n // Run policy is the node's own business: `finally` always runs, `catch`\n // runs only on a pending error (and never while suspended / after a\n // checkpoint failure), every other kind is skipped while suspended or in\n // error. Skipped nodes fire NO hooks.\n if (node.shouldSkip(state)) continue;\n\n // Uniform dispatch: every node is a `Step`. A normal step runs its body\n // and parks any error on `state.pendingError` (recoverable by `.catch()`).\n // The error-handling layer is different: a `catch`/`finally` body that\n // throws does NOT park — it bubbles out of `execute`. We surface it to\n // observers via onStepError, then re-throw so it leaves the run (no\n // `.catch()`, no aggregation). Observability type comes from the category.\n const obsType = this.obsEventType(node);\n const stepId = node.id;\n const sStart = performance.now();\n const errBefore = state.pendingError;\n // A `finally` runs while a gate's suspension is still parked; only the\n // gate that NEWLY parks one reports `suspended: true`. Capture the prior\n // state so the finish hook attributes suspension to the right node.\n const suspendedBefore = !!state.suspension;\n state.stepIndex = i; // consumed by GateStep for `resumeFromIndex`.\n await this.fireHook(state, \"onStepStart\", { stepId, type: obsType, ctx: state.ctx, input: state.output });\n try {\n await node.execute(state);\n } catch (e) {\n await this.fireStepErrorAndAttachCause(state, {\n stepId, type: obsType, ctx: state.ctx, error: e,\n durationMs: performance.now() - sStart,\n });\n throw e;\n }\n\n // Reconcile observability against what the step did. A newly-parked error\n // (distinct from the one we entered with) routes to onStepError, typed by\n // the node's category and honoring the cause-attachment contract;\n // otherwise the step finished — `suspended` reflects a gate parking.\n const newError = state.pendingError && state.pendingError !== errBefore ? state.pendingError : null;\n // An abort that a nested workflow / concurrent unit already rethrew lands\n // here parked under the CHILD step's id. It's a cancellation, not a\n // step-logic failure — emit no step-level event (promoteAbort re-parks it,\n // settleRun throws it). Without this the child step reports a phantom\n // failure that duplicates the abort the caller already gets.\n const isAbort = !!newError && state.abortSignal?.aborted === true && newError.error === state.abortSignal.reason;\n if (isAbort) {\n // Cancellation owns the error; no onStepStart/Finish/Error pairing.\n } else if (newError) {\n await this.fireStepErrorAndAttachCause(state, {\n stepId, type: obsType, ctx: state.ctx, error: newError.error,\n durationMs: performance.now() - sStart,\n });\n } else {\n await this.fireHook(state, \"onStepFinish\", {\n stepId, type: obsType, ctx: state.ctx, output: state.output,\n durationMs: performance.now() - sStart, suspended: !suspendedBefore && !!state.suspension,\n });\n }\n\n // Defensive invariant: only a gate — or a `nested` step propagating a\n // child gate's suspension up — may park a suspension. A `type:\"step\"` node\n // is skipped while suspended (above), so a suspension present after any\n // OTHER category's body leaked from a coding bug. (foreach/parallel run\n // branches on separate item states, so they never set the parent's\n // suspension; repeat forbids gated targets at build time.)\n if (node.type === \"step\" && node.category !== \"nested\" && state.suspension) {\n const leaked = state.suspension;\n state.suspension = undefined;\n throw new Error(`internal: suspension bubbled from non-gate step \"${node.id}\" (gate \"${leaked.gateId}\").`);\n }\n\n await this.maybeCheckpoint(state, opts, node, i, ckptCadence, ckptCounter);\n }\n\n await this.settleRun(state, abortState.promoted);\n }\n\n /**\n * Promote a fired abort signal into `state.pendingError` at an iteration\n * boundary. First observation discards any in-progress suspension (the caller\n * asked to stop) and preserves a genuinely-different prior step error as a\n * warning — but NOT one that is itself the abort reason (a nested workflow /\n * concurrent unit that already rethrew it), which would surface a phantom\n * step-failure warning. Subsequent iterations only re-promote if a downstream\n * catch cleared pendingError — `AbortSignal.aborted` is sticky, so the\n * workflow must not resume mid-pipeline just because a catch swallowed one\n * observation.\n */\n private promoteAbort(state: RuntimeState, abortState: { promoted: boolean }): void {\n const signal = state.abortSignal;\n if (!signal?.aborted) return;\n if (!abortState.promoted) {\n abortState.promoted = true;\n state.suspension = undefined;\n const prior = state.pendingError;\n // Skip demotion when the in-flight error IS the abort reason — it already\n // represents this abort, so re-recording it as a warning is noise.\n if (prior && prior.error !== signal.reason) demotePendingError(state, prior);\n state.pendingError = makeAbortError(signal);\n } else if (!state.pendingError) {\n // A catch handler swallowed the abort. Re-promote so downstream steps\n // still see the signal as the \"stop\" condition the caller requested.\n state.pendingError = makeAbortError(signal);\n }\n }\n\n /**\n * Emit a checkpoint after a successful `type:\"step\"` body. Skipped on\n * pendingError (no clean state to snapshot), on suspension (gate already\n * won), and for catch/finally/gate nodes (not checkpointable). Numeric\n * `checkpointEvery` (default: `max(1, ceil(count/4))`) uses the loop-hoisted\n * `ckptCadence`; the predicate form runs per step. A `when:false`-skipped\n * `type:\"step\"` node returns normally (its body never ran) and still reaches\n * here — it advances the counter and can itself be a checkpoint boundary,\n * keeping the cadence denominator (`stepCounts.checkpointable`) consistent\n * with the runtime counter.\n */\n private async maybeCheckpoint(\n state: RuntimeState,\n opts: RunOptions | undefined,\n node: Step,\n index: number,\n ckptCadence: number,\n counter: { seen: number },\n ): Promise<void> {\n if (node.type !== \"step\" || state.pendingError || state.suspension || !opts?.onCheckpoint) return;\n counter.seen++;\n const shouldCheckpoint = opts.checkpointWhen\n ? opts.checkpointWhen({ stepIndex: index, stepId: node.id, ctx: state.ctx })\n : counter.seen % ckptCadence === 0;\n if (!shouldCheckpoint) return;\n const ckptStart = performance.now();\n try {\n await emitCheckpoint(state, opts, index + 1, this.cachedStepShapeHash);\n } catch (e) {\n state.pendingError = { error: e, stepId: CHECKPOINT_STEP_ID, source: \"onCheckpoint\" };\n state.checkpointFailed = true;\n // Route through onStepError with the synthetic CHECKPOINT_STEP_ID and\n // type: \"step\" (matches pendingErrorSourceToStepType(\"onCheckpoint\")).\n await this.fireStepErrorAndAttachCause(state, {\n stepId: CHECKPOINT_STEP_ID, type: \"step\", ctx: state.ctx, error: e,\n durationMs: performance.now() - ckptStart,\n });\n }\n }\n\n /**\n * Terminal reconciliation after the loop. Re-promotes a swallowed abort\n * (recoverability must not depend on catch position), then resolves the\n * mutually-exclusive precedence tail: checkpointFailed > original-step error\n * > suspension. (A throwing catch/finally never reaches here — it bubbles\n * straight out of the loop, so there is no finally-aggregation branch.)\n */\n private async settleRun(state: RuntimeState, abortPromoted: boolean): Promise<void> {\n // Abort is sticky and non-recoverable. The in-loop re-promotion prevents a\n // `.catch()` from resuming a pipeline mid-flight, but a *terminal* `.catch()`\n // that clears the promoted abort has no subsequent iteration to re-promote\n // it — so without this the run would report `complete` while\n // `.catch().finally()` correctly rejects. Guarded by `abortPromoted`: only\n // re-promote an abort already observed this pass (a catch cleared it), not\n // one whose checkpointFailed precedence must win below.\n if (abortPromoted && !state.pendingError && !state.suspension && state.abortSignal?.aborted) {\n state.pendingError = makeAbortError(state.abortSignal);\n }\n\n if (state.pendingError && !state.suspension) {\n const pe = state.pendingError;\n if (state.checkpointFailed) {\n // The checkpoint error reaches the caller bare. Every OTHER error\n // accumulated this run — step/gate errors demoted to warnings (e.g. by\n // abort promotion) — cannot ride the rejection (it carries a single\n // error, not the warnings array), so surface them via console.warn\n // rather than dropping them silently.\n const warningsArr = state.warnings ?? [];\n const checkpointError = pe.source === \"onCheckpoint\"\n ? pe.error\n : warningsArr.find(w => w.source === \"onCheckpoint\")?.error;\n const suppressed = warningsArr\n .filter(w => w.error !== checkpointError)\n .map(w => w.error);\n if (pe.source !== \"onCheckpoint\" && pe.error !== checkpointError) {\n suppressed.push(pe.error);\n }\n if (suppressed.length > 0) {\n console.warn(\n `pipeai: ${suppressed.length} error(s) suppressed by checkpoint-failure precedence:`,\n suppressed,\n );\n }\n throw checkpointError ?? pe.error;\n }\n throw pe.error;\n } else if (state.pendingError && state.suspension) {\n // Suspension wins; preserve the step error as a warning.\n const pe = state.pendingError;\n demotePendingError(state, pe);\n // Also emit onStepError so observers can see the loss.\n try {\n await this.observability?.onStepError?.({\n stepId: pe.stepId,\n type: pendingErrorSourceToStepType(pe.source),\n ctx: state.ctx,\n error: pe.error,\n durationMs: 0,\n });\n } catch (obsError) {\n pushWarning(state, \"onStepError\", pe.stepId, obsError);\n }\n state.pendingError = undefined;\n }\n }\n\n /**\n * Run THIS sealed workflow as a nested step on the caller's run `state`.\n * Public (internal; not re-exported from index) so `Step` subclasses —\n * `nested` / `repeat` / `foreach` / `parallel` with `SealedWorkflow` targets\n * — can run a sub-workflow without reaching the protected `execute`.\n *\n * Contract: RunOptions is run-scoped, so the child never inherits the\n * parent's (`state.warnings` IS propagated — telemetry > config). A gate\n * inside the child leaves `state.suspension` set so it propagates up (only a\n * `.step(workflow)` ever does this — concurrent/looped combinators forbid\n * gated targets at build time).\n */\n async executeAsNested(state: RuntimeState, startIndex: number = 0): Promise<void> {\n const savedRunOptions = state.runOptions;\n state.runOptions = undefined;\n try {\n await this.execute(state, startIndex);\n } finally {\n state.runOptions = savedRunOptions;\n }\n // A gate inside this nested workflow leaves `state.suspension` set; it\n // propagates up as a first-class suspension (NOT an error). The calling\n // `NestedWorkflowStep` prepends its own step index to the snapshot path so\n // resume can descend back here, and the run loop relaxes its\n // leaked-suspension invariant for `nested` nodes. (Concurrent/looped\n // combinators — foreach / parallel / repeat — forbid gated targets at build\n // time, so they never observe a propagated suspension.)\n }\n\n // ── Gate: load persisted state for resumption ──────────────────\n\n loadState<K extends string & keyof TGates>(\n gateId: K,\n snapshot: WorkflowSnapshot,\n ): ResumedWorkflow<TContext, TGates[K], TOutput> {\n // Reject checkpoint snapshots — they belong to resumeFrom(), not loadState().\n if (snapshot.version === 2 && snapshot.kind === \"checkpoint\") {\n throw new Error(`loadState: received a checkpoint snapshot. Use resumeFrom() for checkpoint resume; loadState() is for gates.`);\n }\n const gateLike = snapshot as GateSnapshot | LegacyGateSnapshotV1;\n if (gateLike.gateId !== gateId) {\n throw new Error(\n `loadState: gate ID mismatch — expected \"${gateId}\" but snapshot has \"${gateLike.gateId}\".`\n );\n }\n this.ensureDuplicateCheck();\n\n const nestedPath = (gateLike as GateSnapshot).nestedPath;\n if (nestedPath && nestedPath.length > 0) {\n // Nested gate: walk the path to the innermost workflow that owns the gate\n // (for its schema/merge), then resume the ROOT at the first nested step\n // and descend back down (see `ResumeDescent`).\n let steps: ReadonlyArray<Step> = this.steps;\n for (const idx of nestedPath) {\n const child = steps[idx]?.nestedWorkflow;\n if (!child) {\n throw new Error(`loadState: nested gate \"${gateId}\" path is stale — step ${idx} is not a nested workflow.`);\n }\n steps = child.getStepsForShapeHash();\n }\n const innerGate = steps[gateLike.resumeFromIndex];\n if (!(innerGate instanceof GateStep) || innerGate.id !== gateId) {\n throw new Error(`loadState: nested gate \"${gateId}\" not found at the recorded path.`);\n }\n // Descent: root resumes from nestedPath[0]; each nested step descends the\n // next path index; the innermost runs from gate+1 with the merged response.\n const remaining = [...nestedPath.slice(1), gateLike.resumeFromIndex + 1];\n return new ResumedWorkflow<TContext, TGates[K], TOutput>(this.steps, nestedPath[0], {\n mode: \"gate\",\n schema: innerGate.schema as SchemaWithParse<TGates[K]> | undefined,\n mergeFn: innerGate.merge,\n priorOutput: gateLike.output,\n snapshot: gateLike,\n observability: this.observability,\n nestedRemaining: remaining,\n });\n }\n\n const gateIndex = this.findGateIndex(gateLike);\n // findGateIndex guarantees a GateStep at this index.\n const gateNode = this.steps[gateIndex] as GateStep;\n return new ResumedWorkflow<TContext, TGates[K], TOutput>(this.steps, gateIndex + 1, {\n mode: \"gate\",\n schema: gateNode.schema as SchemaWithParse<TGates[K]> | undefined,\n mergeFn: gateNode.merge,\n priorOutput: gateLike.output,\n snapshot: gateLike,\n observability: this.observability,\n });\n }\n\n // ── Checkpoint resume ──────────────────────────────────────────\n\n /**\n * Resume from a checkpoint snapshot. Validates the step-shape hash unless\n * `{ skipShapeCheck: true }` is passed. Throws on:\n * - gate snapshots (use `loadState` instead)\n * - missing/corrupted `stepShapeHash`\n * - shape mismatch (unless skipped)\n * - out-of-bounds `resumeFromIndex`\n * - 0-step workflow (structural invariant)\n *\n * Returns a `CheckpointResumedWorkflow` whose `generate(ctx, opts?)` takes\n * NO response arg — the state is seeded from the snapshot's output. The\n * matching gate-resume path (`loadState`) keeps the `response` arg.\n */\n resumeFrom(\n snapshot: WorkflowSnapshot,\n options?: { skipShapeCheck?: boolean },\n ): CheckpointResumedWorkflow<TContext, TOutput> {\n // Detect gate snapshots (v2 with kind=\"gate\" OR legacy v1 with gateId).\n const isGate = (snapshot.version === 2 && snapshot.kind === \"gate\")\n || (snapshot.version === 1 && (snapshot as LegacyGateSnapshotV1).gateId !== undefined);\n if (isGate) {\n throw new Error(`resumeFrom: received a gate snapshot. Use loadState() for gate resume; resumeFrom() is for checkpoints.`);\n }\n if (this.steps.length === 0) {\n throw new Error(\"resumeFrom: workflow has no steps; snapshot is structurally invalid.\");\n }\n const ckpt = snapshot as CheckpointSnapshot;\n const idx = ckpt.resumeFromIndex;\n if (!Number.isInteger(idx) || idx < 0 || idx > this.steps.length) {\n throw new Error(`resumeFrom: resumeFromIndex (${idx}) out of bounds for ${this.steps.length}-step workflow.`);\n }\n if (!options?.skipShapeCheck) {\n if (!ckpt.stepShapeHash) {\n throw new Error(\"resumeFrom: snapshot missing stepShapeHash; corrupted or hand-crafted.\");\n }\n this.ensureDuplicateCheck();\n if (this.cachedStepShapeHash !== ckpt.stepShapeHash) {\n throw new Error(\"resumeFrom: workflow shape mismatch; cannot safely resume. Pass { skipShapeCheck: true } to override.\");\n }\n } else {\n this.ensureDuplicateCheck();\n }\n return new CheckpointResumedWorkflow<TContext, TOutput>(this.steps, idx, {\n priorOutput: ckpt.output,\n observability: this.observability,\n });\n }\n\n /**\n * Append a `.finally()` body to a sealed workflow, returning another sealed\n * workflow. Allows multi-finally chains (`.finally().finally()`). A throwing\n * `.finally` body bubbles straight out of the run: it is non-recoverable, does\n * NOT aggregate with a prior error, and subsequent `.finally()` bodies do not\n * run. (See {@link FinallyStep} for the full contract.)\n */\n finally(\n id: string,\n fn: (params: { ctx: Readonly<TContext> }) => MaybePromise<void>,\n ): SealedWorkflow<TContext, TInput, TOutput, TGates> {\n const node = new FinallyStep(id, fn as (params: { ctx: Readonly<unknown> }) => MaybePromise<void>);\n return new SealedWorkflow<TContext, TInput, TOutput, TGates>([...this.steps, node], this.id, this.observability);\n }\n\n private findGateIndex(snapshot: GateSnapshot | LegacyGateSnapshotV1): number {\n // Accepted: v1 (legacy gate-only) and v2 (gate or checkpoint). Gate-flavor\n // v2 is discriminated by kind === \"gate\"; legacy v1 has no `kind`.\n if (snapshot.version !== 1 && snapshot.version !== 2) {\n throw new Error(`Unsupported snapshot version: ${(snapshot as { version: number }).version}`);\n }\n\n // Fast path — only when the hint is a sane integer in range AND points at the right gate.\n // Rejects -1, NaN, Infinity, 999999, fractional indices.\n const hint = snapshot.resumeFromIndex;\n if (Number.isInteger(hint) && hint >= 0 && hint < this.steps.length) {\n const node = this.steps[hint];\n if (node.type === \"gate\" && node.id === snapshot.gateId) {\n return hint;\n }\n }\n\n // Fallback — scan all steps by gate id (reorder-tolerant).\n for (let i = 0; i < this.steps.length; i++) {\n const node = this.steps[i];\n if (node.type === \"gate\" && node.id === snapshot.gateId) {\n return i;\n }\n }\n\n throw new Error(\n `Gate \"${snapshot.gateId}\" not found in workflow. The workflow definition may have changed since the snapshot was created.`\n );\n }\n}\n\n// ── Resumed Workflow ──────────────────────────────────────────────────\n\ninterface ResumedWorkflowConfig {\n readonly mode: \"gate\";\n readonly schema?: SchemaWithParse<unknown>;\n readonly mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n readonly priorOutput?: unknown;\n readonly snapshot?: WorkflowSnapshot;\n readonly observability?: WorkflowObservability;\n /**\n * Set only for a NESTED gate resume: the descent (child start-indices per\n * level, innermost-last) the merged gate response rides down to the suspended\n * child. When present, `startIndex` is the ROOT's nested-step index and the\n * seed sets `state.resumeDescent` instead of the root `output`.\n */\n readonly nestedRemaining?: readonly number[];\n}\n\nexport class ResumedWorkflow<\n TContext,\n TResponse = unknown,\n TOutput = void,\n> extends SealedWorkflow<TContext, TResponse, TOutput> {\n private readonly startIndex: number;\n private readonly schema?: SchemaWithParse<TResponse>;\n private readonly mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n private readonly priorOutput: unknown;\n private readonly nestedRemaining?: readonly number[];\n\n /** @internal */\n constructor(\n steps: ReadonlyArray<Step>,\n startIndex: number,\n config: ResumedWorkflowConfig,\n ) {\n super(steps, undefined, config.observability);\n this.startIndex = startIndex;\n this.schema = config.schema as SchemaWithParse<TResponse> | undefined;\n this.mergeFn = config.mergeFn;\n this.priorOutput = config.priorOutput;\n this.nestedRemaining = config.nestedRemaining;\n }\n\n private validateResponse(response: TResponse): TResponse {\n if (this.schema) {\n return this.schema.parse(response) as TResponse;\n }\n return response;\n }\n\n /**\n * Seed the run by validating the gate response and merging it with the\n * suspended output. Runs schema.parse + mergeFn inside a try so a failure\n * becomes a pre-execute `initialError` (routed through `.catch()`) rather\n * than escaping the run synchronously. On error the output falls back to the\n * prior (pre-gate) output.\n */\n private async seedFromResponse(rawResponse: TResponse): Promise<StateSeed> {\n try {\n const response = this.validateResponse(rawResponse);\n const merged = this.mergeFn\n ? await this.mergeFn({ priorOutput: this.priorOutput, response })\n : response;\n if (this.nestedRemaining) {\n // Nested gate: the merged response rides the descent down to the\n // suspended child. The root output is unused (the first node executed is\n // the descent's nested step), so park `priorOutput` there.\n return {\n output: this.priorOutput,\n initialError: null,\n resumeDescent: { remaining: this.nestedRemaining, seedOutput: merged },\n };\n }\n return { output: merged, initialError: null };\n } catch (error) {\n return { output: this.priorOutput, initialError: { error, stepId: GATE_RESUME_STEP_ID, source: \"step\" } };\n }\n }\n\n override async generate(\n ctx: TContext,\n ...args: TResponse extends void\n ? [response?: TResponse, opts?: RunOptions]\n : [response: TResponse, opts?: RunOptions]\n ): Promise<WorkflowResult<TOutput>> {\n const rawResponse = args[0] as TResponse;\n const opts = args[1] as RunOptions | undefined;\n return this.runGenerate(ctx, this.startIndex, opts, () => this.seedFromResponse(rawResponse));\n }\n\n override stream<UI_MESSAGE extends UIMessage = UIMessage>(\n ctx: TContext,\n ...args: TResponse extends void\n ? [response?: TResponse, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n : [response: TResponse, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n ): WorkflowStreamResult<TOutput, UI_MESSAGE> {\n const rawResponse = args[0] as TResponse;\n const options = args[1] as WorkflowStreamOptions<UI_MESSAGE> | undefined;\n const opts = args[2] as RunOptions | undefined;\n return this.runStream(ctx, this.startIndex, opts, options, () => this.seedFromResponse(rawResponse));\n }\n}\n\n// ── Checkpoint-Resumed Workflow ──────────────────────────────────────\n//\n// Used by `resumeFrom()`. Same step list, different entry index — no\n// gate-merge logic (no response argument) because the state is seeded\n// from the checkpoint snapshot's `output`. To keep gate-resume's\n// `loadState` form ergonomic, this is a separate class instead of\n// overloading ResumedWorkflow's generate().\n\nexport class CheckpointResumedWorkflow<\n TContext,\n TOutput = void,\n> extends SealedWorkflow<TContext, void, TOutput> {\n private readonly startIndex: number;\n private readonly priorOutput: unknown;\n\n /** @internal */\n constructor(\n steps: ReadonlyArray<Step>,\n startIndex: number,\n config: { priorOutput?: unknown; observability?: WorkflowObservability },\n ) {\n super(steps, undefined, config.observability);\n this.startIndex = startIndex;\n this.priorOutput = config.priorOutput;\n }\n\n // Override with widened arg list compatible with parent's `[input?, opts?]`.\n // Inputs are ignored — state is seeded from the snapshot's `output` field.\n override async generate(\n ctx: TContext,\n ...args: [input?: void, opts?: RunOptions]\n ): Promise<WorkflowResult<TOutput>> {\n const opts = args[1];\n return this.runGenerate(ctx, this.startIndex, opts, () => ({ output: this.priorOutput, initialError: null }));\n }\n\n override stream<UI_MESSAGE extends UIMessage = UIMessage>(\n ctx: TContext,\n ...args: [input?: void, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]\n ): WorkflowStreamResult<TOutput, UI_MESSAGE> {\n const options = args[1];\n const opts = args[2];\n return this.runStream(ctx, this.startIndex, opts, options, () => ({ output: this.priorOutput, initialError: null }));\n }\n}\n\n// ── Workflow ────────────────────────────────────────────────────────\n\nexport class Workflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> extends SealedWorkflow<TContext, TInput, TOutput, TGates> {\n\n /**\n * Sentinel value for `foreach`/`parallel`'s `onError` handler. Returning\n * `Workflow.SKIP` omits the failed item (foreach: shortens the output array;\n * parallel: leaves the slot `undefined`). Aliases the leaf-module `SKIP` so\n * the step subclasses can compare against it without importing this class.\n */\n static readonly SKIP = SKIP;\n\n private constructor(steps: ReadonlyArray<Step> = [], id?: string, observability?: WorkflowObservability) {\n super(steps, id, observability);\n }\n\n static create<TContext, TInput = void>(\n options?: { id?: string; observability?: WorkflowObservability<TContext> },\n ): Workflow<TContext, TInput, TInput> {\n // The internal representation threads `ctx` as `unknown`; the public\n // option is narrowed to WorkflowObservability<TContext> so user callbacks\n // see their real context type. The cast bridges the contravariant gap.\n return new Workflow<TContext, TInput, TInput>([], options?.id, options?.observability as WorkflowObservability | undefined);\n }\n\n // `when` without `otherwise` can passthrough the first step → output widens\n // to `TInput | TOutput`, mirroring the `step` overloads. Declared first so it\n // wins when `otherwise` is absent.\n static from<TContext, TInput, TOutput>(\n agent: Agent<TContext, TInput, TOutput>,\n options: StepOptions<TContext, TInput, TOutput> & SkipPassthrough<TContext, TInput, TOutput>\n ): Workflow<TContext, TInput, TInput | TOutput>;\n static from<TContext, TInput, TOutput>(\n agent: Agent<TContext, TInput, TOutput>,\n options?: StepOptions<TContext, TInput, TOutput>\n ): Workflow<TContext, TInput, TOutput>;\n static from<TContext, TInput, TOutput>(\n agent: Agent<TContext, TInput, TOutput>,\n options?: StepOptions<TContext, TInput, TOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Workflow<TContext, TInput, any> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, any>([]).step(agent, options as any);\n }\n\n // Builder helper — append a step and return a re-typed Workflow.\n private appendStep<TNext, TG extends Record<string, unknown> = TGates>(\n node: Step,\n ): Workflow<TContext, TInput, TNext, TG> {\n return new Workflow<TContext, TInput, TNext, TG>([...this.steps, node], this.id, this.observability);\n }\n\n // ── step: agent overload ──────────────────────────────────────\n // `when` without `otherwise` may skip to passthrough → output widens to\n // `TOutput | TNextOutput`. The fallback (no `when`, or `when` + `otherwise`)\n // keeps `TNextOutput`. The passthrough overload is declared first so it wins\n // when `otherwise` is absent.\n\n step<TNextOutput>(\n agent: Agent<TContext, TOutput, TNextOutput>,\n options: StepOptions<TContext, TOutput, TNextOutput> & SkipPassthrough<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TOutput | TNextOutput, TGates>;\n step<TNextOutput>(\n agent: Agent<TContext, TOutput, TNextOutput>,\n options?: StepOptions<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: nested workflow overload ─────────────────────────────\n // The child's gates fold into the parent's `TGates` (`TGates & TChildGates`),\n // so a nested gate is resumable by id via `loadState` AND surfaces to the\n // build-time guard on `foreach`/`parallel`/`repeat` (which forbid gated\n // targets at any nesting depth).\n\n step<TNextOutput, TChildGates extends Record<string, unknown> = {}>(\n workflow: SealedWorkflow<TContext, TOutput, TNextOutput, TChildGates>,\n options: NestedStepOptions<TContext, TOutput, TNextOutput> & SkipPassthrough<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TOutput | TNextOutput, TGates & TChildGates>;\n step<TNextOutput, TChildGates extends Record<string, unknown> = {}>(\n workflow: SealedWorkflow<TContext, TOutput, TNextOutput, TChildGates>,\n options?: NestedStepOptions<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates & TChildGates>;\n\n // ── step: transform overload (replaces map + tap) ─────────────\n\n step<TNextOutput>(\n id: string,\n fn: (params: { ctx: Readonly<TContext>; input: TOutput; writer?: UIMessageStreamWriter }) => MaybePromise<TNextOutput>,\n options: InlineStepOptions<TContext, TOutput, TNextOutput> & SkipPassthrough<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TOutput | TNextOutput, TGates>;\n step<TNextOutput>(\n id: string,\n fn: (params: { ctx: Readonly<TContext>; input: TOutput; writer?: UIMessageStreamWriter }) => MaybePromise<TNextOutput>,\n options?: InlineStepOptions<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: implementation ──────────────────────────────────────\n\n step<TNextOutput>(\n target: Agent<TContext, TOutput, TNextOutput> | SealedWorkflow<TContext, TOutput, TNextOutput> | string,\n optionsOrFn?: StepOptions<TContext, TOutput, TNextOutput> | NestedStepOptions<TContext, TOutput, TNextOutput> | ((params: { ctx: Readonly<TContext>; input: TOutput; writer?: UIMessageStreamWriter }) => MaybePromise<TNextOutput>),\n inlineOptions?: InlineStepOptions<TContext, TOutput, TNextOutput>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Workflow<TContext, TInput, any, TGates> {\n // Nested workflow overload: step(workflow, options?)\n if (target instanceof SealedWorkflow) {\n const workflow = target;\n const options = optionsOrFn as NestedStepOptions<TContext, TOutput, TNextOutput> | undefined;\n const node = new NestedWorkflowStep(\n options?.id ?? workflow.id ?? \"nested-workflow\",\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n workflow as SealedWorkflow<any, any, any, any>,\n options as ConditionalStepOptions<unknown, unknown, unknown> | undefined,\n );\n return this.appendStep<TNextOutput>(node);\n }\n\n // Transform overload: step(id, fn, options?)\n if (typeof target === \"string\") {\n if (typeof optionsOrFn !== \"function\") {\n throw new Error(`Workflow step(\"${target}\"): second argument must be a function`);\n }\n const fn = optionsOrFn as (params: { ctx: Readonly<TContext>; input: TOutput; writer?: UIMessageStreamWriter }) => MaybePromise<TNextOutput>;\n const node = new TransformStep(\n target,\n fn as (params: { ctx: unknown; input: unknown; writer?: UIMessageStreamWriter }) => MaybePromise<unknown>,\n inlineOptions as ConditionalStepOptions<unknown, unknown, unknown> | undefined,\n );\n return this.appendStep<TNextOutput>(node);\n }\n\n // Agent overload: step(agent, options?)\n const agent = target;\n const options = optionsOrFn as StepOptions<TContext, TOutput, TNextOutput> | undefined;\n const node = new AgentStep(\n options?.id ?? agent.id,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agent as Agent<any, any, any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options as StepOptions<any, any, any> | undefined,\n );\n return this.appendStep<TNextOutput>(node);\n }\n\n // ── gate: human-in-the-loop suspension point ────────────────\n\n gate<TResponse = TOutput, TMerged = TResponse, Id extends string = string>(\n id: Id & (Id extends keyof TGates ? never : Id),\n options?: {\n payload?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<unknown>;\n schema?: SchemaWithParse<TResponse>;\n condition?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<boolean>;\n // `merge` may produce a value of a different type than the validated\n // `response` — `TMerged` (defaults to `TResponse`) becomes the gate's\n // downstream output, while `TGates[Id]` stays `TResponse` (what\n // `loadState` validates as the resume response).\n merge?: (params: { priorOutput: TOutput; response: TResponse }) => MaybePromise<TMerged>;\n }\n ): Workflow<TContext, TInput, TMerged, TGates & Record<Id, TResponse>> {\n if (this.steps.some(s => s.type === \"gate\" && s.id === id)) {\n throw new Error(`Workflow: duplicate gate ID \"${id}\". Each gate must have a unique identifier.`);\n }\n // The builder just forwards user options; GateStep wraps `{ctx, input}` and\n // applies the payload default. Function param contravariance forces the cast.\n const node = new GateStep(id, options as unknown as GateStepOptions | undefined);\n return this.appendStep<TMerged, TGates & Record<Id, TResponse>>(node);\n }\n\n // ── branch: predicate routing (array) ─────────────────────────\n\n branch<TNextOutput>(\n cases: BranchCase<TContext, TOutput, TNextOutput>[],\n options?: { id?: string },\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── branch: key routing (select) ──────────────────────────────\n\n branch<TKeys extends string, TNextOutput>(\n config: BranchSelect<TContext, TOutput, TKeys, TNextOutput>,\n options?: { id?: string },\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── branch: implementation ────────────────────────────────────\n\n branch<TKeys extends string, TNextOutput>(\n casesOrConfig: BranchCase<TContext, TOutput, TNextOutput>[] | BranchSelect<TContext, TOutput, TKeys, TNextOutput>,\n options?: { id?: string },\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n const node = Array.isArray(casesOrConfig)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ? new PredicateBranchStep(options?.id ?? \"branch:predicate\", casesOrConfig as BranchCase<any, any, any>[])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : new SelectBranchStep(options?.id ?? \"branch:select\", casesOrConfig as BranchSelect<any, any, any, any>);\n return this.appendStep<TNextOutput>(node);\n }\n\n // ── foreach: array iteration ─────────────────────────────────\n\n /**\n * Map each item of an array through an agent or sub-workflow.\n *\n * @param target Agent or `SealedWorkflow` invoked once per item.\n * @param options.id Override the default step id (`foreach:<agentId>` or\n * the workflow's id). Required when chaining multiple foreach over the same\n * target — the construction-time `(type, id)` walk rejects duplicates.\n * @param options.concurrency Max items in flight at any moment. **Default:\n * unbounded** (`Infinity` — every item runs concurrently, clamped only by\n * item count). Pass an integer to throttle against provider rate limits.\n * Backed by a worker pool: as soon as one item completes, the next launches —\n * no lockstep batching.\n * @param options.onError Per-iteration error handler. **Bypassed entirely on\n * the suspension path** (when any item hits a nested gate) **and on the\n * cancellation path** (the run was aborted — pre-abort failures become\n * `foreach-sibling` warnings and the abort reason rethrows) — see the\n * foreach concurrency hazards in the README. Otherwise: return a\n * `TNextOutput` value to substitute, return `Workflow.SKIP` to omit, throw\n * to abort. Invoked sequentially in index order after all items settle.\n * A throw (or rethrow) from `onError` aborts the foreach immediately:\n * failures at indices AFTER the throwing one are neither recovered nor\n * surfaced as warnings.\n */\n // Agent / sub-workflow target form.\n foreach<TNextOutput, TG extends Record<string, unknown> = {}>(\n target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | (SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput, TG> & NoGates<TG>),\n options?: ForeachOptions<TContext, TOutput, TNextOutput>,\n ): Workflow<TContext, TInput, TNextOutput[], TGates>;\n\n // Per-item path-builder form: `foreach(path => path.step(a).step(b), opts)`.\n // The callback receives a sub-builder seeded with the array's element type and\n // returns the built per-item path. Each item runs that whole chain as one\n // concurrent unit (item 0 can be at the last step while item 1 is at the\n // first) — the only barrier is collecting the `TNextOutput[]` at the end. Pure\n // sugar over passing a pre-built `SealedWorkflow`: same behavior, but the\n // element type is inferred so you skip the `Workflow.create<Ctx, Item>()`\n // boilerplate. A gate in the per-item path is forbidden, same as any foreach\n // body (`NoGates`).\n foreach<TNextOutput, TG extends Record<string, unknown> = {}>(\n build: (path: Workflow<TContext, ElementOf<TOutput>, ElementOf<TOutput>>) => (SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput, TG> & NoGates<TG>),\n options?: ForeachOptions<TContext, TOutput, TNextOutput>,\n ): Workflow<TContext, TInput, TNextOutput[], TGates>;\n\n // Implementation\n foreach<TNextOutput>(\n target:\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Agent<TContext, any, TNextOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | SealedWorkflow<TContext, any, TNextOutput, any>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | ((path: Workflow<TContext, any, any>) => SealedWorkflow<TContext, any, TNextOutput, any>),\n options?: ForeachOptions<TContext, TOutput, TNextOutput>,\n ): Workflow<TContext, TInput, TNextOutput[], TGates> {\n // Callback form: build the per-item path from a fresh element-typed builder.\n // The parent's observability is forwarded so steps INSIDE the per-item path\n // fire onStepStart/Finish/Error (the callback form otherwise gives the user\n // no way to attach them). (Agents / SealedWorkflows are objects, never\n // functions, so `typeof` cleanly discriminates the builder callback.)\n const body = typeof target === \"function\"\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ? target(Workflow.create<TContext, any>({ observability: this.observability as WorkflowObservability<TContext> | undefined }))\n : target;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const node = new ForeachStep(body as any, options as any, this.observability);\n return this.appendStep<TNextOutput[]>(node);\n }\n\n // ── parallel: fan-out combinator ────────────────────────────────\n //\n // Same input fed to each branch. Streaming: agent branches stream only when a\n // `handleStream` is supplied (otherwise they run generate — N agent streams\n // are never auto-merged into one writer); `SealedWorkflow` branches always\n // inherit and stream transitively via their own steps. A `SealedWorkflow`\n // branch containing a gate is rejected at build time (a gate can't suspend one\n // branch of a fan-out).\n //\n // Default concurrency: **unbounded** (`Infinity` — every branch runs\n // concurrently, clamped only by branch count). No rate-limit cap by default;\n // pass an explicit `concurrency` to throttle against provider limits.\n\n // With `onError`, any branch may be SKIPped → output values widen to\n // `BranchOutput | undefined`. The with-onError overloads are declared first\n // so they win when `onError` is present.\n\n /** Record-form + `onError`. Values are `BranchOutput | undefined` (SKIP-able). */\n parallel<TBranches extends Record<string, ParallelTarget<TContext, TOutput>>>(\n branches: TBranches & { [K in keyof TBranches]: GatelessBranch<TBranches[K]> },\n options: ParallelOptions<TContext, TOutput> & { onError: NonNullable<ParallelOptions<TContext, TOutput>[\"onError\"]> },\n ): Workflow<TContext, TInput, ParallelOutputRecordPartial<TBranches>, TGates>;\n\n /** Record-form overload. Returns `{ [K]: BranchOutput<T[K]> }`. */\n parallel<TBranches extends Record<string, ParallelTarget<TContext, TOutput>>>(\n branches: TBranches & { [K in keyof TBranches]: GatelessBranch<TBranches[K]> },\n options?: ParallelOptions<TContext, TOutput>,\n ): Workflow<TContext, TInput, ParallelOutputRecord<TBranches>, TGates>;\n\n /** Tuple-form + `onError`. Each slot is `BranchOutput | undefined` (SKIP-able). */\n parallel<TBranches extends ReadonlyArray<ParallelTarget<TContext, TOutput>>>(\n branches: TBranches & { [K in keyof TBranches]: GatelessBranch<TBranches[K]> },\n options: ParallelOptions<TContext, TOutput> & { onError: NonNullable<ParallelOptions<TContext, TOutput>[\"onError\"]> },\n ): Workflow<TContext, TInput, ParallelOutputTuplePartial<TBranches>, TGates>;\n\n /** Tuple-form overload. Returns `[O1, O2, ...]`. Use `as const`. */\n parallel<TBranches extends ReadonlyArray<ParallelTarget<TContext, TOutput>>>(\n branches: TBranches & { [K in keyof TBranches]: GatelessBranch<TBranches[K]> },\n options?: ParallelOptions<TContext, TOutput>,\n ): Workflow<TContext, TInput, ParallelOutputTuple<TBranches>, TGates>;\n\n // Implementation\n parallel(\n branches: Record<string, ParallelTarget<TContext, TOutput>> | ReadonlyArray<ParallelTarget<TContext, TOutput>>,\n options?: ParallelOptions<TContext, TOutput>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Workflow<TContext, TInput, any, TGates> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const node = new ParallelStep(branches as any, options as any, this.observability);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return this.appendStep<any>(node);\n }\n\n // ── repeat: conditional loop ─────────────────────────────────\n\n repeat<TG extends Record<string, unknown> = {}>(\n target: Agent<TContext, TOutput, TOutput> | (SealedWorkflow<TContext, TOutput, TOutput, TG> & NoGates<TG>),\n options: RepeatOptions<TContext, TOutput> & { id?: string },\n ): Workflow<TContext, TInput, TOutput, TGates> {\n if (options.maxIterations !== undefined && (!Number.isInteger(options.maxIterations) || options.maxIterations < 1)) {\n throw new Error(`repeat: maxIterations must be a positive integer, got ${options.maxIterations}`);\n }\n // The type union already enforces exactly-one; this guards a type-bypassed\n // caller (`{}` or both) from a confusing `options.while is not a function`\n // TypeError deep inside the loop body.\n if ((options.until === undefined) === (options.while === undefined)) {\n throw new Error(\"repeat: requires exactly one of `until` or `while`\");\n }\n const maxIterations = options.maxIterations ?? 10;\n const isWorkflow = target instanceof SealedWorkflow;\n const defaultId = isWorkflow\n ? (target.id ?? \"repeat\")\n : `repeat:${(target as Agent<TContext, TOutput, TOutput>).id}`;\n const id = options.id ?? defaultId;\n const predicate: LoopPredicate<TContext, TOutput> = options.until\n ?? (async (p) => !(await options.while!(p)));\n\n const node = new RepeatStep(\n id,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n target as Agent<any, any, any> | SealedWorkflow<any, any, any, any>,\n predicate,\n maxIterations,\n isWorkflow,\n );\n return this.appendStep<TOutput>(node);\n }\n\n // ── catch ─────────────────────────────────────────────────────\n\n catch(\n id: string,\n fn: (params: { error: unknown; ctx: Readonly<TContext>; lastOutput: TOutput; stepId: string }) => MaybePromise<TOutput>\n ): Workflow<TContext, TInput, TOutput, TGates> {\n // A preceding `gate` also qualifies — a throwing gate condition/payload is\n // routed as a `source: \"step\"` pendingError that `.catch()` is meant to handle.\n if (!this.steps.some(s => s.type === \"step\" || s.type === \"gate\")) {\n throw new Error(`Workflow: catch(\"${id}\") requires at least one preceding step or gate.`);\n }\n const node = new CatchStep(\n id,\n fn as (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown>,\n );\n return this.appendStep<TOutput>(node);\n }\n\n // `.finally()` is inherited from SealedWorkflow now (it lives there so\n // multi-finally chains are possible — `.finally().finally()`).\n}\n","import type { RuntimeState, PendingError } from \"../runtime\";\nimport type { ConditionalStepOptions } from \"../types\";\nimport type { SealedWorkflow } from \"../workflow\";\n\n/**\n * Disambiguates observability events for `type: \"step\"` nodes. Keeps a single\n * `type: \"step\"` node kind rather than splitting branch/foreach/repeat/\n * parallel/nested into their own run-loop variants.\n */\nexport type StepCategory = \"step\" | \"nested\" | \"branch\" | \"foreach\" | \"repeat\" | \"parallel\";\n\n/**\n * Base class for a single workflow step node. The run loop in `workflow.ts`\n * consumes `ReadonlyArray<Step>` directly — every combinator on `Workflow`\n * constructs one of the subclasses in this directory.\n *\n * ## Execution model (the \"fat step\")\n *\n * The run loop does two things: ask {@link shouldSkip} whether the node runs\n * at all (skipped nodes fire no observability hooks), then call\n * {@link execute}. Everything else is the step's own business — a kind's\n * `execute` runs its work (applying the body-level `when` / `otherwise`\n * decision via {@link applyConditionalSkip}) and captures any thrown error\n * onto `state.pendingError`, exactly the way it writes its result to\n * `state.output`. Errors accumulate on the state; they do not escape.\n *\n * The base {@link execute} is a no-op so kinds with no body of their own need\n * not override it. {@link errorSource} tags which precedence bucket a captured\n * error lands in.\n */\nexport abstract class Step {\n /** Run-loop dispatch discriminant. */\n abstract readonly type: \"step\" | \"gate\" | \"catch\" | \"finally\";\n /** Identifier, unique per `type`; surfaced in observability and snapshots. */\n abstract readonly id: string;\n\n /**\n * Observability event subtype for `type: \"step\"` nodes (agent / transform =\n * `\"step\"`; nested / branch / foreach / repeat / parallel override).\n * `undefined` on gate / catch / finally nodes, whose `type` IS the event type.\n */\n readonly category?: StepCategory;\n\n /**\n * The sealed sub-workflow attached to this node, when it has one (`nested`,\n * and workflow-target `foreach` / `repeat`). Consumed by the recursive\n * `stepShapeHash` walk and the resume path-walk in `loadState`.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly nestedWorkflow?: SealedWorkflow<any, any, any, any>;\n\n /**\n * Precedence source tag a kind writes to `state.pendingError` when it\n * captures a thrown body error. Defaults to `\"step\"`; kinds with a distinct\n * error-precedence bucket (e.g. `finally`, `catch`, `gate`) override it.\n */\n protected readonly errorSource: PendingError[\"source\"] = \"step\";\n\n /**\n * The step's body, invoked by the run loop only after {@link shouldSkip}\n * returned `false`. Each kind overrides it to do its work and capture errors\n * onto state. `state.output` is the input on entry and becomes the output on\n * exit; `state.writer` is present in stream mode. The base implementation is\n * a no-op so kinds that carry no body of their own need not override it.\n */\n async execute(_state: RuntimeState): Promise<void> {\n // No-op default; subclasses override.\n }\n\n /**\n * Run-policy gate, called by the run loop before {@link execute}: return\n * `true` when this step should be skipped silently (no hooks, no output\n * change). The default is the \"normal\" policy — skip while the flow is\n * suspended or already in error. Overridden by kinds with inverted policies:\n * `catch` runs only when there's an error, `finally` always runs.\n */\n shouldSkip(state: RuntimeState): boolean {\n return !!state.suspension || !!state.pendingError;\n }\n\n /**\n * Apply `when` / `otherwise` conditional-skip options. Returns `true` when\n * the body should be skipped — i.e. `when` returned false. On skip,\n * `otherwise` (if present) produces the output; without it the input passes\n * through unchanged. Distinct from {@link shouldSkip}: this is the body-level\n * `when` / `otherwise` decision a kind applies after the policy gate passes.\n */\n protected async applyConditionalSkip(\n state: RuntimeState,\n options: ConditionalStepOptions<unknown, unknown, unknown> | undefined,\n ): Promise<boolean> {\n if (!options?.when) return false;\n // `when` / `otherwise` expect `{ ctx: Readonly<unknown>; input: unknown }`;\n // `Readonly<unknown>` resolves to `{}`, which raw `unknown` is not\n // assignable to — so build the params once with an assertion. The values\n // are the live ctx/output; only the static type is coerced.\n const params = { ctx: state.ctx, input: state.output } as { ctx: Readonly<unknown>; input: unknown };\n if (await options.when(params)) return false;\n if (options.otherwise) {\n state.output = await options.otherwise(params);\n }\n // No `otherwise` → passthrough: leave state.output unchanged.\n return true;\n }\n}\n","import type { UIMessageStreamWriter } from \"ai\";\nimport type { MaybePromise } from \"../utils\";\nimport type { RuntimeState } from \"../runtime\";\nimport type { ConditionalStepOptions } from \"../types\";\nimport { Step } from \"./step\";\n\n/** The inline transform body produced by `Workflow.step(id, fn, options?)`. */\ntype TransformFn = (params: {\n ctx: unknown;\n input: unknown;\n writer?: UIMessageStreamWriter;\n}) => MaybePromise<unknown>;\n\n/**\n * Inline transform step — `Workflow.step(id, fn, options?)`.\n *\n * Runs `fn` with the current `ctx` / `input` (and the stream `writer` in stream\n * mode), assigning its result to `state.output`. Self-contained: it captures\n * any thrown error onto `state.pendingError`, mirroring how it writes its\n * result to `state.output`.\n *\n * Generics live at the `Workflow.step` API boundary; internally the body and\n * options are erased to `unknown` (the run loop only sees `RuntimeState`).\n */\nexport class TransformStep extends Step {\n readonly type = \"step\" as const;\n readonly id: string;\n private readonly fn: TransformFn;\n private readonly options?: ConditionalStepOptions<unknown, unknown, unknown>;\n\n constructor(\n id: string,\n fn: TransformFn,\n options?: ConditionalStepOptions<unknown, unknown, unknown>,\n ) {\n super();\n this.id = id;\n this.fn = fn;\n this.options = options;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n // Inside the try so a throwing `when` / `otherwise` routes through\n // `.catch()` like any other body failure.\n if (await this.applyConditionalSkip(state, this.options)) return;\n state.output = await this.fn({\n ctx: state.ctx,\n input: state.output,\n // Present in stream mode (undefined in generate mode), letting the\n // inline step emit UIMessageChunk parts onto the workflow's stream.\n writer: state.writer,\n });\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n","import type { ToolSet } from \"ai\";\nimport type { Agent, GenerateTextResult, StreamTextResult, OutputType } from \"../agent\";\nimport { extractOutput, runWithWriter } from \"../utils\";\nimport type { RuntimeState } from \"../runtime\";\nimport type { StepOptions, AgentStepHooks, AgentResultParams } from \"../types\";\nimport { Step } from \"./step\";\n\n/**\n * Agent step — `Workflow.step(agent, options?)`.\n *\n * Runs `agent` against the current input, applying the `mapResult` /\n * `onResult` / `handleStream` hooks. Self-contained: {@link execute} captures\n * any thrown error onto `state.pendingError`, mirroring how it writes its\n * result to `state.output`.\n *\n * The raw agent invocation lives in the static {@link runAgent} so the\n * concurrent dispatch (`./concurrent`) and the branch steps can share it.\n * Generics live at the `Workflow.step` API boundary; an `AgentStep` instance\n * erases the agent and options to `any` (the run loop only sees\n * `RuntimeState`).\n */\nexport class AgentStep extends Step {\n readonly type = \"step\" as const;\n readonly id: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly agent: Agent<any, any, any>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly options?: StepOptions<any, any, any>;\n\n constructor(\n id: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agent: Agent<any, any, any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: StepOptions<any, any, any>,\n ) {\n super();\n this.id = id;\n this.agent = agent;\n this.options = options;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n // Inside the try so a throwing `when` / `otherwise` routes through\n // `.catch()` like any other body failure.\n if (await this.applyConditionalSkip(state, this.options)) return;\n await AgentStep.runAgent(state, this.agent, state.ctx, this.options);\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n\n /**\n * Run an agent against the current state, writing its result to\n * `state.output`. In stream mode, output extraction awaits the full stream\n * before returning — streaming benefits the client (incremental output), not\n * pipeline throughput, since each step still runs sequentially.\n *\n * Static (does not touch instance state) so the still-literal foreach /\n * parallel / branch combinators can share it. `itemIndex` identifies the\n * execution to `handleStream` inside a multi-execution combinator (numeric\n * index, record key, or matched case); `undefined` for a plain single\n * `.step(agent)`.\n */\n static async runAgent<TContext, TNextOutput>(\n state: RuntimeState,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agent: Agent<TContext, any, TNextOutput>,\n ctx: TContext,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: AgentStepHooks<TContext, any, TNextOutput>,\n itemIndex?: number | string,\n ): Promise<void> {\n const input = state.output;\n const hasStructuredOutput = agent.hasOutput;\n\n const abortSignal = state.abortSignal;\n const agentCallOpts = abortSignal ? { abortSignal } : undefined;\n\n if (state.mode === \"stream\" && state.writer) {\n const writer = state.writer;\n // Run inside writer context so tools accessed via getActiveWriter() pick it up.\n await runWithWriter(writer, async () => {\n const result = await (agent.stream as (ctx: TContext, input: unknown, opts?: { abortSignal?: AbortSignal }) => Promise<StreamTextResult<ToolSet, OutputType<TNextOutput>>>)(ctx, state.output, agentCallOpts);\n\n if (options?.handleStream) {\n await options.handleStream({ result, writer, ctx, input, itemIndex });\n } else {\n writer.merge(result.toUIMessageStream());\n }\n\n const hookParams = {\n mode: \"stream\",\n result,\n ctx: ctx as Readonly<TContext>,\n input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as AgentResultParams<TContext, any, TNextOutput>;\n\n if (options?.onResult) {\n await options.onResult(hookParams);\n }\n\n if (options?.mapResult) {\n state.output = await options.mapResult(hookParams);\n } else {\n state.output = await extractOutput(result, hasStructuredOutput, agent.validateOutput);\n }\n });\n } else {\n const result = await (agent.generate as (ctx: TContext, input: unknown, opts?: { abortSignal?: AbortSignal }) => Promise<GenerateTextResult<ToolSet, OutputType<TNextOutput>>>)(ctx, state.output, agentCallOpts);\n\n const hookParams = {\n mode: \"generate\",\n result,\n ctx: ctx as Readonly<TContext>,\n input,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as AgentResultParams<TContext, any, TNextOutput>;\n\n if (options?.onResult) {\n await options.onResult(hookParams);\n }\n\n if (options?.mapResult) {\n state.output = await options.mapResult(hookParams);\n } else {\n state.output = await extractOutput(result, hasStructuredOutput, agent.validateOutput);\n }\n }\n }\n}\n","// Workflow error classes and reserved synthetic step ids. A leaf module (no\n// internal imports) so step subclasses and the runtime can reach these without\n// a value-level cycle through ./workflow.\n\nexport class WorkflowBranchError extends Error {\n constructor(\n public readonly branchType: \"predicate\" | \"select\",\n message: string,\n ) {\n super(message);\n this.name = \"WorkflowBranchError\";\n }\n}\n\nexport class WorkflowLoopError extends Error {\n constructor(\n public readonly iterations: number,\n public readonly maxIterations: number,\n ) {\n super(`Loop exceeded maximum iterations (${maxIterations})`);\n this.name = \"WorkflowLoopError\";\n }\n}\n\n/**\n * Synthetic step id reported when `onCheckpoint` itself throws. Reserved\n * via the construction-time `(type, id)` walk — user step ids may not\n * contain the `::pipeai::` namespace.\n */\nexport const CHECKPOINT_STEP_ID = \"::pipeai::onCheckpoint\" as const;\n\n/**\n * Synthetic step id carried by the pending-error a cancellation promotes\n * (surfaced to `.catch()` / observability). Lives in the reserved\n * `::pipeai::` namespace so it can't be confused with a user step literally\n * named \"abort\".\n */\nexport const ABORT_STEP_ID = \"::pipeai::abort\" as const;\n\n/**\n * Synthetic step id used when a gate-resume's response validation / merge\n * throws before the pipeline re-enters `execute()`. Reserved-namespaced for\n * the same reason as {@link ABORT_STEP_ID}.\n */\nexport const GATE_RESUME_STEP_ID = \"::pipeai::gate:resume\" as const;\n","import type { RuntimeState } from \"../runtime\";\nimport type { BranchCase, BranchSelect } from \"../types\";\nimport { WorkflowBranchError } from \"../errors\";\nimport { Step } from \"./step\";\nimport { AgentStep } from \"./agent-step\";\n\n/**\n * Predicate branch — `Workflow.branch(cases)`.\n *\n * Walks the cases in order, routing to the first whose `when` matches (a case\n * without `when` is the default). Throws `WorkflowBranchError` when nothing\n * matches and there is no default. Self-contained: captures any thrown error\n * (no-match, predicate throw, or the routed agent) onto `state.pendingError`.\n */\nexport class PredicateBranchStep extends Step {\n readonly type = \"step\" as const;\n override readonly category = \"branch\" as const;\n readonly id: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly cases: BranchCase<any, any, any>[];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(id: string, cases: BranchCase<any, any, any>[]) {\n super();\n this.id = id;\n this.cases = cases;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctx = state.ctx as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const input = state.output as any;\n\n for (let caseIndex = 0; caseIndex < this.cases.length; caseIndex++) {\n const branchCase = this.cases[caseIndex];\n if (branchCase.when) {\n const match = await branchCase.when({ ctx, input });\n if (!match) continue;\n }\n // Matched (or no `when` = default). itemIndex = matched case index.\n await AgentStep.runAgent(state, branchCase.agent, ctx, branchCase, caseIndex);\n return;\n }\n\n // Render the input defensively — JSON.stringify throws on cyclic /\n // BigInt / function-valued inputs, which would mask the real branch\n // mismatch with a serialization error.\n let inputRepr: string;\n try {\n inputRepr = JSON.stringify(input);\n if (inputRepr === undefined) inputRepr = String(input);\n } catch {\n inputRepr = `[unserializable ${typeof input}]`;\n }\n throw new WorkflowBranchError(\"predicate\", `No branch matched and no default branch (a case without \\`when\\`) was provided. Input: ${inputRepr}`);\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n\n/**\n * Select branch — `Workflow.branch({ select, agents, fallback?, onUnknownKey? })`.\n *\n * Routes to `agents[select(...)]`. A declared-but-`undefined` agent fails loud\n * (a misconfiguration, not an unknown key); a genuinely unknown key fires\n * `onUnknownKey`, then falls back to `fallback` or throws `WorkflowBranchError`.\n * Self-contained: captures any thrown error onto `state.pendingError`.\n */\nexport class SelectBranchStep extends Step {\n readonly type = \"step\" as const;\n override readonly category = \"branch\" as const;\n readonly id: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly config: BranchSelect<any, any, any, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(id: string, config: BranchSelect<any, any, any, any>) {\n super();\n this.id = id;\n this.config = config;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctx = state.ctx as any;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const input = state.output as any;\n const config = this.config;\n const key = await config.select({ ctx, input });\n\n // Distinguish \"key not declared at all\" from \"key present but value\n // is `undefined`\" (e.g. `agents: { bug: cond ? agentA : undefined }`).\n // The latter is a user-side bug — fail loud rather than silently\n // falling back, since the fallback obscures the misconfiguration.\n //\n // Use Object.prototype.hasOwnProperty.call (not `in`) so untrusted\n // classifier output like \"toString\"/\"constructor\"/\"__proto__\" doesn't\n // resolve to an Object.prototype method and crash runAgent with an\n // opaque \"agent.generate is not a function\".\n const keyDeclared = Object.prototype.hasOwnProperty.call(config.agents, key);\n if (keyDeclared && (config.agents as Record<string, unknown>)[key] === undefined) {\n throw new WorkflowBranchError(\n \"select\",\n `Agent for key \"${key}\" was declared but the value is undefined. ` +\n `This usually means a conditional spread set the value to undefined. ` +\n `Available keys: ${Object.keys(config.agents).join(\", \")}`,\n );\n }\n let agent = keyDeclared ? config.agents[key] : undefined;\n if (!agent) {\n if (config.onUnknownKey) {\n config.onUnknownKey({\n key,\n availableKeys: Object.keys(config.agents),\n ctx,\n });\n }\n if (config.fallback) {\n agent = config.fallback;\n } else {\n throw new WorkflowBranchError(\"select\", `No agent found for key \"${key}\" and no fallback provided. Available keys: ${Object.keys(config.agents).join(\", \")}`);\n }\n }\n\n // itemIndex = the selected key.\n await AgentStep.runAgent(state, agent, ctx, config, key);\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n","// Runtime plumbing for the workflow engine: the per-run `RuntimeState` (and\n// its construction), observability hook dispatch, warning bookkeeping,\n// pending-error demotion, and the checkpoint sink. Coupled only to the public\n// types in `./types` and the leaf `./errors` module — no value-level cycle\n// through `./workflow` — so the `Step` subclasses in `./steps` import from\n// here directly.\n\nimport type { UIMessageStreamWriter } from \"ai\";\nimport { deepFreeze, type MaybePromise } from \"./utils\";\nimport { ABORT_STEP_ID } from \"./errors\";\nimport type {\n CheckpointSnapshot,\n GateSnapshot,\n RunOptions,\n WorkflowObservability,\n WorkflowResult,\n WorkflowStepType,\n WorkflowWarning,\n} from \"./types\";\n\n// ── Per-run state ────────────────────────────────────────────────────\n\n// Consumed by the run loop in ./workflow and every `Step` subclass. NOT\n// re-exported from index.ts, so it stays out of the public package API.\nexport interface RuntimeState {\n ctx: unknown;\n output: unknown;\n mode: \"generate\" | \"stream\";\n writer?: UIMessageStreamWriter;\n // Only gates set `suspension`.\n suspension?: GateSnapshot;\n warnings?: WorkflowWarning[];\n checkpointFailed?: boolean;\n // Error channel for the fat-step model and the single source of truth for the\n // in-flight error: a `Step#execute` body parks its thrown error here instead\n // of letting it escape, and the run loop + `catch`/`finally` steps read and\n // clear it. (`catch`/`finally` bodies are the exception — their throws bubble\n // straight out of `execute` rather than parking here.)\n pendingError?: PendingError;\n // Same RunOptions seen by execute(); reset to undefined inside nested\n // workflows and omitted from foreach itemState so per-run config doesn't\n // leak into nested execution.\n runOptions?: RunOptions;\n // Cooperative cancellation. Held on state separately from runOptions\n // because — unlike freezeSnapshots — abortSignal SHOULD propagate into\n // nested workflows and foreach items.\n abortSignal?: AbortSignal;\n // Index of the node the run loop is currently executing. Set per iteration\n // so a `GateStep` can stamp `resumeFromIndex` into its suspension snapshot\n // without the loop reaching into the node.\n stepIndex?: number;\n // Set only when resuming a NESTED gate: the descent a `NestedWorkflowStep`\n // follows back down to the suspended child. Consumed (and cleared) one\n // nesting level at a time. See `ResumeDescent`.\n resumeDescent?: ResumeDescent;\n}\n\n/**\n * Drives resume re-entry for a gate that suspended inside nested workflows.\n * `remaining` is the list of child start-indices to descend through, one per\n * nesting level, ending with the innermost gate's `resumeFromIndex + 1`. When a\n * `NestedWorkflowStep` consumes the LAST entry it first seeds `state.output`\n * with `seedOutput` (the merged gate response) before running the innermost\n * child from that index.\n */\nexport type ResumeDescent = {\n readonly remaining: readonly number[];\n readonly seedOutput: unknown;\n};\n\n// Pending error tracked through a single execute() pass. The `source`\n// discriminant drives the precedence tail\n// (checkpointFailed > finally-wrap > step > suspension) and the onStepError\n// type mapping in `pendingErrorSourceToStepType`.\nexport type PendingError = {\n error: unknown;\n stepId: string;\n source: \"step\" | \"gate\" | \"finally\" | \"catch\" | \"onCheckpoint\";\n};\n\n/**\n * The pending-error a cancellation promotes: the signal's reason under the\n * reserved {@link ABORT_STEP_ID}, recoverable-looking to `.catch()` but sticky\n * (the run loop re-promotes it).\n */\nexport function makeAbortError(signal: AbortSignal): PendingError {\n return {\n error: signal.reason ?? new Error(\"Workflow aborted\"),\n stepId: ABORT_STEP_ID,\n source: \"step\",\n };\n}\n\n/**\n * Prepend a nested-workflow step index to a propagating gate suspension so\n * resume can descend back to the gate. Returns a fresh snapshot (re-frozen when\n * `freezeSnapshots` is on) since the original may be frozen.\n */\nexport function prependNestedPath(snapshot: GateSnapshot, index: number, state: RuntimeState): GateSnapshot {\n const next: GateSnapshot = { ...snapshot, nestedPath: [index, ...(snapshot.nestedPath ?? [])] };\n if (resolveFreezeSnapshots(state)) deepFreeze(next);\n return next;\n}\n\nexport function resolveFreezeSnapshots(state: RuntimeState): boolean {\n return state.runOptions?.freezeSnapshots ? true : false;\n}\n\n/**\n * Map `PendingError.source` to the `WorkflowStepType` value that\n * `onStepError` should report. `onCheckpoint` is mapped to `\"step\"`,\n * consistent with the `{ stepId: CHECKPOINT_STEP_ID, type: \"step\" }` contract.\n * Exhaustive switch — adding a new `source` variant is a compile error.\n */\nexport function pendingErrorSourceToStepType(source: PendingError[\"source\"]): WorkflowStepType {\n switch (source) {\n case \"step\": return \"step\";\n case \"gate\": return \"gate\";\n case \"finally\": return \"finally\";\n case \"catch\": return \"catch\";\n case \"onCheckpoint\": return \"step\";\n }\n}\n\n/**\n * Invoke `opts.onCheckpoint(snapshot, { signal })`, forwarding the run-level\n * abort signal so a cancelled run can tear down an in-flight checkpoint write\n * (provided the callback honors the signal — JS can't force-cancel a promise).\n * Throws on onCheckpoint failure; the run loop catches and sets\n * `state.pendingError` (source `\"onCheckpoint\"`), which routes through the\n * precedence tail (checkpointFailed > original-step > suspension).\n *\n * There is no framework-imposed timeout: every awaited callback (agent calls,\n * transforms, gates, lifecycle hooks) can equally hang, and the uniform way to\n * bound any of them is the run's `abortSignal` — race it against your own timer\n * if you need one, rather than have the engine special-case this one callback.\n */\nexport async function emitCheckpoint(\n state: RuntimeState,\n opts: RunOptions,\n resumeFromIndex: number,\n stepShapeHash: string,\n): Promise<void> {\n if (!opts.onCheckpoint) return;\n // When freezing, the checkpoint path keeps executing — so deep-freezing\n // `state.output` directly would hand the next step a frozen input. Snapshot\n // an independent clone instead, leaving the live value mutable. (Snapshots\n // are meant to be serializable for Redis/S3/Postgres persistence, so a\n // structured clone is sound here.) Without freeze we alias as before.\n const willFreeze = resolveFreezeSnapshots(state);\n const snap: CheckpointSnapshot = {\n version: 2,\n kind: \"checkpoint\",\n resumeFromIndex,\n output: willFreeze ? structuredClone(state.output) : state.output,\n stepShapeHash,\n };\n if (willFreeze) deepFreeze(snap);\n\n await opts.onCheckpoint(snap, { signal: state.abortSignal });\n}\n\n// One-time stream-mode warning when a gate fires with options.onError set.\nlet warnedStreamOnErrorOnSuspend = false;\n\n/**\n * @internal — test-only reset of the one-time stream-mode warn dedup.\n */\nexport function __resetStreamOnErrorOnSuspendWarnForTests(): void {\n warnedStreamOnErrorOnSuspend = false;\n}\n\n/**\n * Push an entry onto state.warnings, allocating the array lazily on first use.\n * Centralizes the `(state.warnings ??= []).push({source, stepId, error})` idiom.\n * Exported (module-internal; not re-exported from index) so migrated `Step`\n * subclasses can record warnings the same way.\n */\nexport function pushWarning(\n state: RuntimeState,\n source: WorkflowWarning[\"source\"],\n stepId: string,\n error: unknown,\n): void {\n (state.warnings ??= []).push({ source, stepId, error });\n}\n\n/**\n * Fire an observability hook safely against an explicit `observability` object.\n * Returns `undefined` synchronously when no hook is registered (allocation-free\n * no-hook path). On throw: non-`onStepError` hooks push a warning + console.error\n * and the error is returned; `onStepError` throws are returned for the caller to\n * attach as `cause`.\n *\n * Free function (not a method) so the `Step` subclasses — `foreach` /\n * `parallel`, which fire per-item events — can use their captured observability.\n * `SealedWorkflow#fireHook` delegates here with `this.observability`.\n */\nexport function fireHook<\n K extends keyof WorkflowObservability,\n E extends Parameters<NonNullable<WorkflowObservability[K]>>[0],\n>(\n observability: WorkflowObservability | undefined,\n state: RuntimeState,\n name: K,\n event: E,\n): MaybePromise<unknown> {\n const hook = observability?.[name];\n if (!hook) return undefined;\n return fireHookSlow(state, name, event, hook);\n}\n\nasync function fireHookSlow<K extends keyof WorkflowObservability>(\n state: RuntimeState,\n name: K,\n event: unknown,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n hook: any,\n): Promise<unknown> {\n try {\n await hook(event);\n return undefined;\n } catch (e) {\n if (name !== \"onStepError\") {\n const stepId = (event as { stepId: string }).stepId;\n pushWarning(state, name, stepId, e);\n // eslint-disable-next-line no-console\n console.error(`pipeai: ${name} hook threw for stepId \"${stepId}\":`, e);\n }\n return e;\n }\n}\n\n/**\n * True when any per-item observability hook is registered on `observability`.\n * Lets `foreach` / `parallel` skip per-item timing + event allocation on\n * hook-less runs.\n */\nexport function hasItemHooks(observability: WorkflowObservability | undefined): boolean {\n return !!observability && !!(observability.onItemStart || observability.onItemFinish || observability.onItemError);\n}\n\n/**\n * Demote a pendingError into a warning. Used everywhere a new pendingError is\n * about to overwrite the prior one (finally/catch errors after a step error,\n * abort promoted over an in-flight error, suspension-wins tail).\n */\nexport function demotePendingError(state: RuntimeState, pe: PendingError): void {\n pushWarning(state, pe.source, pe.stepId, pe.error);\n}\n\n/**\n * Emit the one-shot stream-onError-on-suspend warning if applicable.\n */\nexport function maybeWarnStreamOnErrorOnSuspend(\n result: WorkflowResult<unknown>,\n options: { onError?: (error: unknown) => string } | undefined,\n): void {\n if (result.status !== \"suspended\" || !options?.onError || warnedStreamOnErrorOnSuspend) return;\n warnedStreamOnErrorOnSuspend = true;\n console.warn(\n \"pipeai: stream() with options.onError suspended at a gate — onError will NOT be invoked for suspension. Discriminate via the resolved output Promise.\"\n );\n}\n\n/**\n * Build the per-run `RuntimeState`. Centralizes the shape every entry point\n * (generate/stream + gate/checkpoint resume) used to hand-construct. `abortSignal`\n * is always sourced from `opts` so cancellation is honored uniformly — the\n * checkpoint-resume path previously omitted it.\n */\nexport function makeRuntimeState(\n ctx: unknown,\n output: unknown,\n mode: \"generate\" | \"stream\",\n opts: RunOptions | undefined,\n writer?: UIMessageStreamWriter,\n): RuntimeState {\n return {\n ctx,\n output,\n mode,\n ...(writer ? { writer } : {}),\n runOptions: opts,\n abortSignal: opts?.abortSignal,\n };\n}\n","/**\n * A counting semaphore for bounding concurrency. `acquire()` resolves when a\n * permit is available; `release()` hands the permit to the next waiter (or\n * returns it to the pool). Constructing with `Infinity` permits makes it an\n * always-open gate (full fan-out — `acquire` never blocks).\n */\nexport class Semaphore {\n private available: number;\n private readonly waiters: Array<() => void> = [];\n\n constructor(permits: number) {\n this.available = permits;\n }\n\n acquire(): Promise<void> {\n if (this.available > 0) {\n this.available--;\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => this.waiters.push(resolve));\n }\n\n release(): void {\n const next = this.waiters.shift();\n if (next) {\n // Hand the permit straight to the next waiter — net permit count is\n // unchanged, so no decrement/increment dance.\n next();\n } else {\n this.available++;\n }\n }\n}\n","import type { UIMessageStreamWriter } from \"ai\";\nimport type { MaybePromise } from \"../utils\";\nimport type { Agent } from \"../agent\";\nimport { fireHook, hasItemHooks, pushWarning, type RuntimeState } from \"../runtime\";\nimport type { AgentStepHooks, WorkflowObservability } from \"../types\";\nimport type { SealedWorkflow } from \"../workflow\";\nimport { AgentStep } from \"./agent-step\";\nimport { Semaphore } from \"./semaphore\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/** A unit (foreach item / parallel branch) that rejected. */\nexport type UnitFailure = { key: string | number; index: number; error: unknown };\n\n/**\n * One dispatchable unit of concurrent work: a foreach item or a parallel\n * branch. `key` is the unit's identity everywhere it surfaces — hook\n * `itemIndex`, warning namespace, `UnitFailure.key` (foreach: the item index;\n * parallel: the record key / tuple index). `isWorkflow` is computed by the\n * owning step (it already discriminates the target at construction) so this\n * module never needs a value-level `instanceof SealedWorkflow`.\n */\nexport type ConcurrentUnit = {\n readonly key: string | number;\n readonly input: unknown;\n readonly target: Agent<any, any, any> | SealedWorkflow<any, any, any, any>;\n readonly isWorkflow: boolean;\n};\n\n/**\n * Validate a `foreach` / `parallel` `concurrency` option: a positive integer\n * or `Infinity` (full fan-out, clamped by unit count). Rejects NaN / 0 /\n * negatives and fractional values. Returns the effective value — **default:\n * unbounded**.\n */\nexport function validateConcurrency(kind: \"foreach\" | \"parallel\", value: number | undefined): number {\n if (\n value !== undefined &&\n !((Number.isInteger(value) && value >= 1) || value === Infinity)\n ) {\n throw new Error(`${kind}: concurrency must be a positive integer or Infinity, got ${value}`);\n }\n return value ?? Infinity;\n}\n\n/**\n * The dispatch loop shared by `foreach` and `parallel`: run every unit through\n * a worker pool, fire per-item observability, then reconcile (warning-merge +\n * abort precedence via {@link reconcileUnits}).\n *\n * Per unit: a fresh `RuntimeState` is built — `runOptions` is omitted (per-run\n * config never crosses the concurrency boundary) while `abortSignal` IS\n * propagated (cancellation is transitive). Agent units inherit the parent's\n * stream mode + writer ONLY when a `handleStream` is supplied (else they run\n * generate — N agent streams are never auto-merged into one writer); workflow\n * units always inherit, streaming transitively via their own steps.\n *\n * Returns the non-gate failures, sorted by unit index, for the calling step's\n * `onError` semantics. Throws on abort — the calling step's `execute` captures\n * the throw onto `state.pendingError`.\n */\nexport async function dispatchUnits(params: {\n state: RuntimeState;\n stepId: string;\n kind: \"foreach\" | \"parallel\";\n units: ReadonlyArray<ConcurrentUnit>;\n concurrency: number;\n observability: WorkflowObservability | undefined;\n handleStream?: (params: {\n result: any;\n writer: UIMessageStreamWriter;\n ctx: any;\n input: any;\n itemIndex: any;\n }) => MaybePromise<void>;\n /** Write the unit's output into the caller's result shape (array / record). */\n onUnitSuccess: (index: number, output: unknown) => void;\n}): Promise<UnitFailure[]> {\n const { state, stepId, kind, units, observability, handleStream, onUnitSuccess } = params;\n const unitStates: (RuntimeState | undefined)[] = new Array(units.length);\n const wantItemHooks = hasItemHooks(observability);\n\n const executeUnit = async (unit: ConcurrentUnit, index: number) => {\n const inheritStreaming = unit.isWorkflow || handleStream !== undefined;\n const unitState: RuntimeState = {\n ctx: state.ctx,\n output: unit.input,\n mode: inheritStreaming ? state.mode : \"generate\",\n writer: inheritStreaming ? state.writer : undefined,\n abortSignal: state.abortSignal,\n };\n unitStates[index] = unitState;\n const unitStart = wantItemHooks ? performance.now() : 0;\n if (wantItemHooks) {\n await fireHook(observability, state, \"onItemStart\", {\n stepId, type: kind, itemIndex: unit.key, ctx: state.ctx, input: unit.input,\n });\n }\n try {\n if (unit.isWorkflow) {\n await (unit.target as SealedWorkflow<any, any, any, any>).executeAsNested(unitState);\n } else {\n await AgentStep.runAgent(\n unitState,\n unit.target as Agent<any, any, any>,\n state.ctx,\n handleStream ? ({ handleStream } as AgentStepHooks<any, any, any>) : undefined,\n unit.key,\n );\n }\n onUnitSuccess(index, unitState.output);\n if (wantItemHooks) {\n await fireHook(observability, state, \"onItemFinish\", {\n stepId, type: kind, itemIndex: unit.key, ctx: state.ctx, output: unitState.output,\n durationMs: performance.now() - unitStart,\n });\n }\n } catch (error) {\n if (wantItemHooks) {\n await fireHook(observability, state, \"onItemError\", {\n stepId, type: kind, itemIndex: unit.key, ctx: state.ctx, error,\n durationMs: performance.now() - unitStart,\n });\n }\n throw error;\n }\n };\n\n // Bounded dispatch: a Semaphore gates the loop, acquiring a permit BEFORE\n // launching each unit so only K are ever in flight (`Infinity` → full\n // fan-out). Units self-evict from `inflight` on settle, so the set retains\n // O(K) promises, not O(N).\n const sem = new Semaphore(params.concurrency);\n const failures: UnitFailure[] = [];\n const inflight = new Set<Promise<void>>();\n for (let i = 0; i < units.length; i++) {\n if (state.abortSignal?.aborted) break;\n await sem.acquire();\n if (state.abortSignal?.aborted) { sem.release(); break; }\n const index = i;\n const unit = (async () => {\n try { await executeUnit(units[index], index); }\n catch (error) { failures.push({ key: units[index].key, index, error }); }\n finally { sem.release(); }\n })();\n inflight.add(unit);\n void unit.finally(() => inflight.delete(unit));\n }\n await Promise.all(inflight);\n failures.sort((a, b) => a.index - b.index);\n\n return reconcileUnits(state, stepId, failures, units.length, (i) => units[i].key, unitStates, state.abortSignal);\n}\n\n/**\n * Post-dispatch policy shared by `foreach` and `parallel`. Merges each unit's\n * warnings into the parent (namespaced `id[key]:stepId`), then applies\n * precedence:\n *\n * - **abort wins** → surface pre-abort failures as `foreach-sibling` warnings\n * and rethrow the abort reason;\n * - otherwise → return the failures for the caller's `onError`.\n *\n * (Nested gates can't suspend a concurrent branch — gated targets are forbidden\n * at build time — so there is no nested-gate case here.) Throws on abort; the\n * caller (a step's `execute`) captures the throw onto `state.pendingError`.\n */\nexport function reconcileUnits(\n state: RuntimeState,\n id: string,\n failures: UnitFailure[],\n count: number,\n keyAt: (index: number) => string | number,\n unitStates: ReadonlyArray<RuntimeState | undefined>,\n signal: AbortSignal | undefined,\n): UnitFailure[] {\n // Merge per-unit warnings into the parent (every exit path, once). Also assert\n // the no-gate-in-a-concurrent-unit invariant: gated targets are forbidden at\n // build time (the `NoGates` / `GatelessBranch` type brands), but that guard is\n // purely type-level. If a cast bypassed it and a unit suspended, its\n // suspension would otherwise be silently dropped (only `unitState.output` is\n // read) — so fail loud instead.\n for (let i = 0; i < count; i++) {\n const us = unitStates[i];\n if (!us) continue;\n if (us.suspension) {\n throw new Error(\n `internal: gate \"${us.suspension.gateId}\" suspended inside concurrent unit ${id}[${keyAt(i)}]. ` +\n `Gates are forbidden in foreach / parallel targets — a cast must have bypassed the build-time guard.`\n );\n }\n if (!us.warnings) continue;\n for (const w of us.warnings) {\n pushWarning(state, w.source, `${id}[${keyAt(i)}]:${w.stepId}`, w.error);\n }\n }\n\n // Cooperative cancellation wins over onError and suspension.\n if (signal?.aborted) {\n for (const f of failures) {\n pushWarning(state, \"foreach-sibling\", `${id}[${f.key}]`, f.error);\n }\n throw signal.reason ?? new Error(\"Workflow aborted\");\n }\n\n // Hand the failures back for the caller's `onError` handling.\n return failures;\n}\n","import type { UIMessageStreamWriter } from \"ai\";\nimport { SKIP, type MaybePromise } from \"../utils\";\nimport type { Agent } from \"../agent\";\nimport type { RuntimeState } from \"../runtime\";\nimport type { WorkflowObservability } from \"../types\";\nimport { SealedWorkflow } from \"../workflow\";\nimport { Step } from \"./step\";\nimport { dispatchUnits, validateConcurrency } from \"./concurrent\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype ForeachTarget = Agent<any, any, any> | SealedWorkflow<any, any, any, any>;\ntype ForeachOptions = {\n id?: string;\n concurrency?: number;\n onError?: (params: { error: unknown; item: any; index: number; ctx: any }) => MaybePromise<any>;\n handleStream?: (params: { result: any; writer: UIMessageStreamWriter; ctx: any; input: any; itemIndex: number }) => MaybePromise<void>;\n};\n\n/**\n * Foreach step — `Workflow.foreach(target, options?)`.\n *\n * Maps each item of the array input through an agent or sub-workflow via the\n * shared worker-pool dispatch ({@link dispatchUnits} — default concurrency:\n * unbounded), which also handles per-item observability and the post-settle\n * warning-merge + abort precedence. This step owns only what is foreach-shaped:\n * array validation, `onError` recovery (`Workflow.SKIP` omits the item,\n * shortening the output array), and result assembly. Captures its observability\n * at construction so per-item events fire on the owning workflow's hooks.\n * Self-contained: any thrown error is parked on `state.pendingError`.\n */\nexport class ForeachStep extends Step {\n readonly type = \"step\" as const;\n override readonly category = \"foreach\" as const;\n override readonly nestedWorkflow?: SealedWorkflow<any, any, any, any>;\n readonly id: string;\n\n private readonly target: ForeachTarget;\n private readonly concurrency: number;\n private readonly onError?: ForeachOptions[\"onError\"];\n private readonly handleStream?: ForeachOptions[\"handleStream\"];\n private readonly isWorkflow: boolean;\n private readonly observability?: WorkflowObservability;\n\n constructor(target: ForeachTarget, options: ForeachOptions | undefined, observability: WorkflowObservability | undefined) {\n super();\n this.target = target;\n this.concurrency = validateConcurrency(\"foreach\", options?.concurrency);\n this.onError = options?.onError;\n this.handleStream = options?.handleStream;\n this.observability = observability;\n this.isWorkflow = target instanceof SealedWorkflow;\n const defaultId = this.isWorkflow\n ? ((target as SealedWorkflow<any, any, any, any>).id ?? \"foreach\")\n : `foreach:${(target as Agent<any, any, any>).id}`;\n this.id = options?.id ?? defaultId;\n this.nestedWorkflow = this.isWorkflow ? (target as SealedWorkflow<any, any, any, any>) : undefined;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n const items = state.output;\n if (!Array.isArray(items)) {\n throw new Error(`foreach \"${this.id}\": expected array input, got ${typeof items}`);\n }\n\n const results: unknown[] = new Array(items.length);\n // foreach's per-unit key IS its index. Throws on abort — caught below.\n const failures = await dispatchUnits({\n state,\n stepId: this.id,\n kind: \"foreach\",\n units: items.map((item, i) => ({ key: i, input: item, target: this.target, isWorkflow: this.isWorkflow })),\n concurrency: this.concurrency,\n observability: this.observability,\n handleStream: this.handleStream,\n onUnitSuccess: (index, output) => { results[index] = output; },\n });\n\n // No suspension — run onError per existing semantics in index order.\n const skipped = new Set<number>();\n for (const { index, error } of failures) {\n if (!this.onError) throw error;\n const recovered = await this.onError({ error, item: items[index], index, ctx: state.ctx });\n if (recovered === SKIP) {\n skipped.add(index);\n } else {\n results[index] = recovered;\n }\n }\n\n state.output = skipped.size === 0\n ? results\n : results.filter((_, i) => !skipped.has(i));\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n","import type { UIMessageStreamWriter } from \"ai\";\nimport { SKIP, type MaybePromise } from \"../utils\";\nimport type { RuntimeState } from \"../runtime\";\nimport type { ParallelTarget, WorkflowObservability } from \"../types\";\nimport { SealedWorkflow } from \"../workflow\";\nimport { Step } from \"./step\";\nimport { dispatchUnits, validateConcurrency } from \"./concurrent\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype ParallelBranches = Record<string, ParallelTarget<any, any>> | ReadonlyArray<ParallelTarget<any, any>>;\ntype ParallelOpts = {\n id?: string;\n concurrency?: number;\n onError?: (params: { error: unknown; key?: string; index?: number; ctx: any }) => unknown | Promise<unknown>;\n handleStream?: (params: { result: any; writer: UIMessageStreamWriter; ctx: any; input: any; itemIndex: number | string }) => MaybePromise<void>;\n};\ntype Entry = { key: string | number; index: number; target: ParallelTarget<any, any>; isWorkflow: boolean };\n\n/**\n * Parallel step — `Workflow.parallel(branches, options?)`.\n *\n * Feeds the same input to every branch (record or tuple form) via the shared\n * worker-pool dispatch ({@link dispatchUnits} — default concurrency:\n * unbounded), which also handles per-branch observability and the post-settle\n * warning-merge + abort precedence. This step owns only what is\n * parallel-shaped: the record/tuple entry mapping, `onError` recovery\n * (`Workflow.SKIP` leaves the slot `undefined`), and result assembly.\n * Self-contained: any thrown error is parked on `state.pendingError`.\n */\nexport class ParallelStep extends Step {\n readonly type = \"step\" as const;\n override readonly category = \"parallel\" as const;\n readonly id: string;\n\n private readonly entries: Entry[];\n private readonly isTuple: boolean;\n private readonly concurrency: number;\n private readonly onError?: ParallelOpts[\"onError\"];\n private readonly handleStream?: ParallelOpts[\"handleStream\"];\n private readonly observability?: WorkflowObservability;\n\n constructor(branches: ParallelBranches, options: ParallelOpts | undefined, observability: WorkflowObservability | undefined) {\n super();\n this.isTuple = Array.isArray(branches);\n // The unit key is the record key / tuple index — it identifies the branch\n // in hook `itemIndex`, warning namespaces, and the result slot.\n this.entries = this.isTuple\n ? (branches as ReadonlyArray<ParallelTarget<any, any>>).map((target, i) => ({ key: i, index: i, target, isWorkflow: target instanceof SealedWorkflow }))\n : Object.entries(branches as Record<string, ParallelTarget<any, any>>).map(([k, t], i) => ({ key: k, index: i, target: t, isWorkflow: t instanceof SealedWorkflow }));\n this.concurrency = validateConcurrency(\"parallel\", options?.concurrency);\n this.onError = options?.onError;\n this.handleStream = options?.handleStream;\n this.observability = observability;\n this.id = options?.id ?? (this.isTuple ? \"parallel:tuple\" : \"parallel:record\");\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n const input = state.output;\n const results: Record<string | number, unknown> = (this.isTuple ? new Array(this.entries.length) : {}) as Record<string | number, unknown>;\n\n // Throws on abort — caught below.\n const failures = await dispatchUnits({\n state,\n stepId: this.id,\n kind: \"parallel\",\n units: this.entries.map((e) => ({ key: e.key, input, target: e.target, isWorkflow: e.isWorkflow })),\n concurrency: this.concurrency,\n observability: this.observability,\n handleStream: this.handleStream,\n onUnitSuccess: (index, output) => { results[this.entries[index].key] = output; },\n });\n\n // No suspension — handle non-gate failures via onError or rethrow.\n for (const { key, index, error } of failures) {\n if (!this.onError) throw error;\n const recovered = await this.onError({\n error,\n key: this.isTuple ? undefined : (key as string),\n index: this.isTuple ? index : undefined,\n ctx: state.ctx,\n });\n // SKIP: both forms leave the slot `undefined` in place (no index shift).\n results[key] = recovered === SKIP ? undefined : recovered;\n }\n\n state.output = results;\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n","import { deepFreeze, type MaybePromise } from \"../utils\";\nimport { resolveFreezeSnapshots, type RuntimeState } from \"../runtime\";\nimport type { GateSnapshot, SchemaWithParse } from \"../types\";\nimport { Step } from \"./step\";\n\n/**\n * User-facing gate options as accepted by `Workflow.gate(id, options?)`.\n * Generics live at that API boundary; here `ctx` / `input` are erased.\n */\nexport interface GateStepOptions {\n payload?: (params: { ctx: Readonly<unknown>; input: unknown }) => MaybePromise<unknown>;\n schema?: SchemaWithParse;\n condition?: (params: { ctx: Readonly<unknown>; input: unknown }) => MaybePromise<boolean>;\n merge?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n}\n\n/**\n * Gate step — `Workflow.gate(id, options?)`.\n *\n * Human-in-the-loop suspension point. With the standard run policy\n * ({@link shouldSkip}) it runs only when neither suspended nor in error. An\n * optional `condition` can short-circuit the gate (returns false → no\n * suspension, passthrough). Otherwise it snapshots the run — `resumeFromIndex`\n * comes from `state.stepIndex`, set by the run loop — parks it on\n * `state.suspension`, and (when freezing) deep-freezes the snapshot. A throwing\n * `condition`/`payload` is captured onto `state.pendingError` (`source: \"gate\"`)\n * so it routes through `.catch()` like any other step error.\n *\n * `schema` / `merge` are public because `SealedWorkflow.loadState` reads them\n * off the node during gate resume (response validation + merge).\n */\nexport class GateStep extends Step {\n readonly type = \"gate\" as const;\n readonly id: string;\n protected override readonly errorSource = \"gate\" as const;\n\n /** Read by `loadState` to validate the resumed gate response. */\n readonly schema?: SchemaWithParse;\n /** Read by `loadState` to merge the response with the suspended output. */\n readonly merge?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n\n private readonly payload?: GateStepOptions[\"payload\"];\n private readonly condition?: GateStepOptions[\"condition\"];\n\n constructor(id: string, options: GateStepOptions | undefined) {\n super();\n this.id = id;\n this.payload = options?.payload;\n this.schema = options?.schema;\n this.condition = options?.condition;\n this.merge = options?.merge;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n const params = { ctx: state.ctx, input: state.output } as { ctx: Readonly<unknown>; input: unknown };\n // A false condition short-circuits the gate: no suspension, passthrough.\n if (this.condition && !(await this.condition(params))) return;\n const snapshot: GateSnapshot = {\n version: 2,\n kind: \"gate\",\n resumeFromIndex: state.stepIndex ?? -1,\n output: state.output,\n gateId: this.id,\n gatePayload: this.payload ? await this.payload(params) : state.output,\n };\n state.suspension = snapshot;\n if (resolveFreezeSnapshots(state)) deepFreeze(snapshot);\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n","import type { MaybePromise } from \"../utils\";\nimport type { RuntimeState } from \"../runtime\";\nimport { Step } from \"./step\";\n\n/**\n * Catch step — `Workflow.catch(id, fn)`.\n *\n * The pipeline's recovery handler. Inverted run policy ({@link shouldSkip}): it\n * runs ONLY when there is a `state.pendingError` to handle, and is bypassed on\n * suspension and on checkpoint failure (which propagates to the caller bare).\n * On success the handler's return becomes the new output and the pending error\n * is cleared.\n *\n * If the handler itself throws, the error is NOT captured — it bubbles straight\n * out of the run. A throwing recovery handler is non-recoverable: it does not\n * chain to a later `.catch()`, and it is not aggregated. (Contrast a regular\n * step, whose error is parked on `state.pendingError` for `.catch()` to handle.)\n */\nexport class CatchStep extends Step {\n readonly type = \"catch\" as const;\n readonly id: string;\n protected override readonly errorSource = \"catch\" as const;\n\n private readonly catchFn: (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown>;\n\n constructor(\n id: string,\n catchFn: (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown>,\n ) {\n super();\n this.id = id;\n this.catchFn = catchFn;\n }\n\n // Runs only on a pending error; skipped on suspension and checkpoint failure.\n override shouldSkip(state: RuntimeState): boolean {\n return !!state.suspension || !state.pendingError || !!state.checkpointFailed;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n // The run loop's shouldSkip gate guarantees pendingError is set here.\n const handled = state.pendingError!;\n // A throw here is intentionally NOT caught — it bubbles out of the run.\n state.output = await this.catchFn({\n error: handled.error,\n ctx: state.ctx,\n lastOutput: state.output,\n stepId: handled.stepId,\n });\n state.pendingError = undefined;\n }\n}\n","import type { MaybePromise } from \"../utils\";\nimport type { RuntimeState } from \"../runtime\";\nimport { Step } from \"./step\";\n\n/**\n * Finally step — `Workflow.finally(id, fn)`.\n *\n * Cleanup body that runs on every non-bubbled exit path: after success, after a\n * step error, and after suspension. {@link shouldSkip} is therefore always\n * `false`.\n *\n * A throwing body is NOT captured — it bubbles straight out of the run. This\n * means a throwing `finally` is non-recoverable: it does not aggregate with a\n * prior error, subsequent `.finally()` bodies do not run, and on suspension it\n * rejects rather than returning the snapshot. (Contrast a regular step, whose\n * error is parked on `state.pendingError` for `.catch()` to handle.)\n */\nexport class FinallyStep extends Step {\n readonly type = \"finally\" as const;\n readonly id: string;\n protected override readonly errorSource = \"finally\" as const;\n\n private readonly fn: (params: { ctx: Readonly<unknown> }) => MaybePromise<void>;\n\n constructor(id: string, fn: (params: { ctx: Readonly<unknown> }) => MaybePromise<void>) {\n super();\n this.id = id;\n this.fn = fn;\n }\n\n // Always runs — cleanup must fire regardless of suspension / error state.\n override shouldSkip(_state: RuntimeState): boolean {\n return false;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n // A throw here is intentionally NOT caught — it bubbles out of the run.\n await this.fn({ ctx: state.ctx as Readonly<unknown> });\n }\n}\n","import { prependNestedPath, type RuntimeState } from \"../runtime\";\nimport type { ConditionalStepOptions } from \"../types\";\nimport type { SealedWorkflow } from \"../workflow\";\nimport { Step } from \"./step\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Nested-workflow step — `Workflow.step(workflow, options?)`.\n *\n * Runs a sealed sub-workflow against the current input via\n * {@link SealedWorkflow.executeAsNested}. A gate inside the child leaves\n * `state.suspension` set; this step propagates it up — prepending its own step\n * index to the snapshot's `nestedPath` so resume can descend back here — rather\n * than treating it as an error. Self-contained: runs its own `when`-`otherwise`\n * checks and captures any thrown error onto `state.pendingError`.\n *\n * On resume (`state.resumeDescent` set), it re-enters the child at the recorded\n * index instead of running it fresh; at the innermost level it seeds the merged\n * gate response before resuming the child from `resumeFromIndex + 1`.\n *\n * `nestedWorkflow` is set so the recursive `stepShapeHash` walk (and the\n * resume path-walk in `loadState`) can descend into the sub-workflow.\n */\nexport class NestedWorkflowStep extends Step {\n readonly type = \"step\" as const;\n override readonly category = \"nested\" as const;\n override readonly nestedWorkflow: SealedWorkflow<any, any, any, any>;\n readonly id: string;\n\n private readonly options?: ConditionalStepOptions<unknown, unknown, unknown>;\n\n constructor(\n id: string,\n workflow: SealedWorkflow<any, any, any, any>,\n options: ConditionalStepOptions<unknown, unknown, unknown> | undefined,\n ) {\n super();\n this.id = id;\n this.nestedWorkflow = workflow;\n this.options = options;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n // Resume descent: re-enter the child at the recorded index. Skips the\n // `when` / `otherwise` check — on resume the parent's pre-gate steps\n // already ran, so this step is the descent target, not a fresh run.\n const descent = state.resumeDescent;\n if (descent) {\n state.resumeDescent = undefined; // consume this level\n const [childStart, ...rest] = descent.remaining;\n const myIndex = state.stepIndex ?? -1;\n try {\n if (rest.length === 0) {\n // Innermost level: seed the merged gate response, resume from gate+1.\n state.output = descent.seedOutput;\n } else {\n state.resumeDescent = { remaining: rest, seedOutput: descent.seedOutput };\n }\n await this.nestedWorkflow.executeAsNested(state, childStart);\n if (state.suspension) state.suspension = prependNestedPath(state.suspension, myIndex, state);\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n return;\n }\n\n const myIndex = state.stepIndex ?? -1; // capture before the child overwrites stepIndex\n try {\n // Inside the try so a throwing `when` / `otherwise` routes through\n // `.catch()` like any other body failure.\n if (await this.applyConditionalSkip(state, this.options)) return;\n await this.nestedWorkflow.executeAsNested(state);\n // A gate inside the child suspended: propagate up, recording our index so\n // resume can descend back to the gate.\n if (state.suspension) state.suspension = prependNestedPath(state.suspension, myIndex, state);\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n","import type { Agent } from \"../agent\";\nimport type { RuntimeState } from \"../runtime\";\nimport type { LoopPredicate } from \"../types\";\nimport type { SealedWorkflow } from \"../workflow\";\nimport { WorkflowLoopError } from \"../errors\";\nimport { AgentStep } from \"./agent-step\";\nimport { Step } from \"./step\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Repeat step — `Workflow.repeat(target, options)`.\n *\n * Do-while loop: runs `target` (agent or sub-workflow) against the current\n * output, then evaluates the resolved `predicate` (from `until` / `while`).\n * Stops when the predicate is satisfied or `maxIterations` is hit (the latter\n * throws `WorkflowLoopError`). Cooperative cancellation is checked between\n * iterations. Self-contained: any thrown error — loop-limit, abort, or a body\n * failure — is captured onto `state.pendingError`.\n *\n * `nestedWorkflow` is set (for workflow targets) so the recursive\n * `stepShapeHash` walk can descend into the body's shape.\n */\nexport class RepeatStep extends Step {\n readonly type = \"step\" as const;\n override readonly category = \"repeat\" as const;\n override readonly nestedWorkflow?: SealedWorkflow<any, any, any, any>;\n readonly id: string;\n\n private readonly target: Agent<any, any, any> | SealedWorkflow<any, any, any, any>;\n private readonly predicate: LoopPredicate<any, any>;\n private readonly maxIterations: number;\n private readonly isWorkflow: boolean;\n\n constructor(\n id: string,\n target: Agent<any, any, any> | SealedWorkflow<any, any, any, any>,\n predicate: LoopPredicate<any, any>,\n maxIterations: number,\n isWorkflow: boolean,\n ) {\n super();\n this.id = id;\n this.target = target;\n this.predicate = predicate;\n this.maxIterations = maxIterations;\n this.isWorkflow = isWorkflow;\n this.nestedWorkflow = isWorkflow ? (target as SealedWorkflow<any, any, any, any>) : undefined;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n try {\n // Predicate/runAgent params are erased to `any` at this boundary; the\n // generics live at the `Workflow.repeat` API surface.\n const ctx = state.ctx as any;\n for (let i = 1; i <= this.maxIterations; i++) {\n // Cancellation checkpoint between iterations. The agent body's runAgent\n // forwards the signal so an in-flight call cancels too, but this covers\n // sub-workflow bodies where the signal wouldn't otherwise propagate.\n if (state.abortSignal?.aborted) {\n throw state.abortSignal.reason ?? new Error(\"Workflow aborted\");\n }\n\n if (this.isWorkflow) {\n await (this.target as SealedWorkflow<any, any, any, any>).executeAsNested(state);\n } else {\n await AgentStep.runAgent(state, this.target as Agent<any, any, any>, ctx);\n }\n\n const done = await this.predicate({ output: state.output, ctx, iterations: i });\n if (done) return;\n }\n\n throw new WorkflowLoopError(this.maxIterations, this.maxIterations);\n } catch (error) {\n state.pendingError = { error, stepId: this.id, source: this.errorSource };\n }\n }\n}\n","export { Agent } from \"./agent\";\nexport type {\n AgentConfig,\n GenerateTextResult,\n StreamTextResult,\n OutputType,\n AsToolMapOutput,\n} from \"./agent\";\n\nexport {\n Workflow,\n WorkflowBranchError,\n WorkflowLoopError,\n CHECKPOINT_STEP_ID,\n ABORT_STEP_ID,\n GATE_RESUME_STEP_ID,\n migrateSnapshot,\n} from \"./workflow\";\n\n// `SKIP` is a unique-symbol sentinel returned from `foreach`'s `onError` to\n// omit an item from the output array. It mirrors `Workflow.SKIP` and is\n// re-exported here so consumers who only `import type { SealedWorkflow }` can\n// still reach the runtime value without importing the full `Workflow` class.\nimport { Workflow as _WorkflowForSkip } from \"./workflow\";\nexport const SKIP = _WorkflowForSkip.SKIP;\nexport type { SealedWorkflow, ResumedWorkflow, CheckpointResumedWorkflow } from \"./workflow\";\nexport type {\n AgentStepHooks,\n AgentResultParams,\n StepOptions,\n BranchCase,\n BranchSelect,\n RepeatOptions,\n WorkflowResult,\n WorkflowStreamResult,\n WorkflowStreamOptions,\n WorkflowSnapshot,\n GateSnapshot,\n CheckpointSnapshot,\n LegacyGateSnapshotV1,\n WorkflowWarning,\n WorkflowStepType,\n WorkflowObservability,\n RunOptions,\n ParallelTarget,\n ParallelOutputRecord,\n ParallelOutputTuple,\n ParallelOptions,\n ForeachOptions,\n} from \"./workflow\";\n\nexport { defineTool, ToolProvider, isToolProvider, TOOL_PROVIDER_BRAND } from \"./tool-provider\";\nexport type { ToolProviderConfig, ToolExecuteOptions, IToolProvider } from \"./tool-provider\";\n\nexport type { MaybePromise, Resolvable } from \"./utils\";\n"],"mappings":"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","names":["tool","tool","result","myIndex","options","node","SKIP"]}
|