pipeai 0.8.4 → 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 +26 -0
- package/dist/index.cjs +412 -514
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +230 -127
- package/dist/index.d.ts +230 -127
- package/dist/index.js +412 -514
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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/steps/step.ts","../src/steps/transform-step.ts","../src/steps/agent-step.ts","../src/steps/branch-step.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/runtime.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 * @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 * 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 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 ToolSet,\n} from \"ai\";\nimport { type Agent, type GenerateTextResult, type StreamTextResult, type OutputType } from \"./agent\";\nimport { computeStepShapeHash, deepFreeze, warnOnce, 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 } 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\";\n\n// The public type / API surface lives in ./types. Re-export it so existing\n// `from \"./workflow\"` consumers (the step subclasses, index.ts) are unchanged,\n// and import the subset this file references internally.\nexport type * from \"./types\";\nimport type {\n GateSnapshot, CheckpointSnapshot, LegacyGateSnapshotV1, WorkflowSnapshot,\n WorkflowWarning, 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,\n} from \"./types\";\n\n// Runtime plumbing (state construction, observability dispatch, warnings,\n// checkpoint sink) lives in ./runtime. Imported for internal use here, and the\n// subset the `./steps` subclasses + tests reach for is re-exported so their\n// `from \"../workflow\"` imports stay unchanged.\nimport {\n resolveFreezeSnapshots, pendingErrorSourceToStepType, emitCheckpoint,\n __resetStreamOnErrorOnSuspendWarnForTests, pushWarning, fireHook, hasItemHooks,\n demotePendingError, maybeWarnStreamOnErrorOnSuspend, makeRuntimeState,\n} from \"./runtime\";\nexport {\n resolveFreezeSnapshots, pushWarning, fireHook, hasItemHooks,\n __resetStreamOnErrorOnSuspendWarnForTests,\n};\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\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\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\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// ── 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 // catch / finally / gate are `Step` subclasses now; the run loop dispatches\n // them through `execute` like any other node. Only the fields read OUTSIDE\n // execute survive on the union: a gate's `schema` / `merge` (read by\n // `loadState` during resume).\n | { readonly type: \"catch\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void> }\n | { readonly type: \"finally\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void> }\n | { readonly type: \"gate\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void>; readonly schema?: SchemaWithParse; 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\n// Exported at module scope so the extracted `Step` subclasses in `./steps` can\n// type their `execute(state)` bodies. NOT re-exported from `index.ts`, so it\n// 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 below.\nexport type PendingError = {\n error: unknown;\n stepId: string;\n source: \"step\" | \"gate\" | \"finally\" | \"catch\" | \"onCheckpoint\";\n};\n\n// Concurrent foreach/parallel dispatch is inlined in each step\n// (`./steps/foreach-step.ts`, `./steps/parallel-step.ts`) over the `Semaphore`\n// primitive; the shared post-settle warning-merge + abort precedence lives in\n// `./steps/concurrent.ts` (`reconcileUnits`). The per-run state, observability\n// dispatch, warning, and checkpoint helpers live in `./runtime` (imported +\n// selectively re-exported at the top of this file).\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<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 _cachedCheckpointableStepCount?: 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 /**\n * Count of *checkpointable* nodes — `type === \"step\"` only (this includes\n * `branch`/`foreach`/`repeat`/`parallel`/`nested`, all internally `step`).\n * Drives the checkpoint auto-cadence denominator. Distinct from\n * {@link cachedExecutableStepCount}, which also counts `gate` nodes: gates\n * suspend/skip and never reach the checkpoint block, so the runtime\n * `executableStepsSeen` counter never advances on them. Counting gates in\n * the denominator would dilute the \"~4 checkpoints across the run\" target.\n */\n protected get cachedCheckpointableStepCount(): number {\n if (this._cachedCheckpointableStepCount !== undefined) return this._cachedCheckpointableStepCount;\n let n = 0;\n for (const s of this.steps) {\n if (s.type === \"step\") n++;\n }\n this._cachedCheckpointableStepCount = 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 const length = this.cachedExecutableStepCount;\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.cachedCheckpointableStepCount / 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 // Thin delegates to the free `fireHook` / `hasItemHooks` (which take an\n // explicit observability). Kept as methods so the loop's many `this.fireHook`\n // call sites stay unchanged; bare `fireHook` / `hasItemHooks` below resolve to\n // the module-level functions, not these members.\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 fireHook(this.observability, state, name, event);\n }\n\n protected hasItemHooks(): boolean {\n return hasItemHooks(this.observability);\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> {\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> {\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.cachedCheckpointableStepCount / 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 (they don't reach the checkpoint\n // block, so they don't advance this counter — unlike the raw index `i`).\n let executableStepsSeen = 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. 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_STEP_ID,\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 (state.pendingError) demotePendingError(state, state.pendingError);\n state.pendingError = makeAbortError(state.abortSignal);\n } else if (!state.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 state.pendingError = makeAbortError(state.abortSignal);\n }\n }\n\n const node = this.steps[i];\n\n // Run policy per kind — skipped nodes fire NO hooks (preserves the prior\n // per-branch `continue`s). `finally` always runs (cleanup); `catch` runs\n // only on a pending error and never while suspended / after a checkpoint\n // failure; every other kind is skipped while suspended or in error. The\n // step subclasses encode the same policy in their own `shouldSkip`; this\n // mirror is what gates hook-firing, which is the loop's concern.\n const skip =\n node.type === \"finally\" ? false\n : node.type === \"catch\" ? (!!state.suspension || !state.pendingError || !!state.checkpointFailed)\n : (!!state.suspension || !!state.pendingError);\n if (skip) 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 = getObservabilityType(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 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 // 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`; predicate form runs per step. Note: a `when:false`-skipped\n // `type:\"step\"` node returns normally (its body never ran), so it still\n // reaches this block — it advances `executableStepsSeen` and can itself be\n // a checkpoint boundary. This keeps the cadence denominator\n // (cachedCheckpointableStepCount, which counts every `type:\"step\"` node)\n // consistent with the runtime counter.\n if (node.type === \"step\" && !state.pendingError && !state.suspension && opts?.onCheckpoint) {\n executableStepsSeen++;\n const shouldCheckpoint = opts.checkpointWhen\n ? opts.checkpointWhen({ stepIndex: i, stepId: node.id, ctx: state.ctx })\n : executableStepsSeen % 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 state.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.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\n // Abort is sticky and non-recoverable. The in-loop re-promotion at the\n // top of each iteration prevents a `.catch()` from resuming a pipeline\n // mid-flight, but a *terminal* `.catch()` that clears the promoted abort\n // has no subsequent iteration to re-promote it — so without this the run\n // would report `complete` while `.catch().finally()` correctly rejects.\n // Re-promote here so recoverability never depends on catch position.\n // Guarded by `abortPromoted`: only re-promote an abort already observed\n // during this pass (a catch cleared it), not one whose checkpointFailed\n // precedence must win below.\n if (abortPromoted && !state.pendingError && !state.suspension && state.abortSignal?.aborted) {\n state.pendingError = makeAbortError(state.abortSignal);\n }\n\n // Tail — mutually exclusive branches.\n // Precedence: checkpointFailed > original-step error > suspension.\n // (A throwing catch/finally never reaches here — it bubbles straight out of\n // the loop, so there is no finally-aggregation branch.)\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<StepNode> = this.steps;\n for (const idx of nestedPath) {\n const node = steps[idx];\n const child = node?.type === \"step\" ? node.nestedWorkflow : undefined;\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?.type !== \"gate\" || 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 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 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 // 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 * 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<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 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> {\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<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 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> {\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`'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<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 // 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 // `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, 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 = new GateStep(\n id,\n 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 options?.schema as SchemaWithParse | undefined,\n options?.condition\n ? async (state) => options.condition!({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n })\n : undefined,\n options?.merge\n ? (params) => options.merge!(params as { priorOutput: TOutput; response: TResponse })\n : undefined,\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const node = new PredicateBranchStep(explicitId ?? \"branch:predicate\", cases as BranchCase<any, any, any>[]);\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const node = new SelectBranchStep(explicitId ?? \"branch:select\", config 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 foreach<TNextOutput, TG extends Record<string, unknown> = {}>(\n target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | (SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput, TG> & NoGates<TG>),\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 * **Stream-mode + agent-target only.** When the workflow is run via\n * `.stream(...)`, each item's agent runs in stream mode and this hook\n * decides how its stream surfaces to the writer (`itemIndex` = the item\n * index). Without it, agent items run in generate mode (no auto-merge —\n * unlike a single `.step(agent)`, foreach never auto-merges N streams).\n * Not invoked for `SealedWorkflow` targets (which stream transitively via\n * their own steps) nor in generate mode.\n */\n handleStream?: (params: {\n result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;\n writer: UIMessageStreamWriter;\n ctx: Readonly<TContext>;\n input: ElementOf<TOutput>;\n itemIndex: number;\n }) => MaybePromise<void>;\n },\n ): Workflow<TContext, TInput, TNextOutput[], TGates> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const node = new ForeachStep(target 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, ConditionalStepOptions, PendingError } from \"../workflow\";\n\n/**\n * Internal base for a single workflow step node.\n *\n * Background: the run loop in `workflow.ts` consumes a `StepNode` — a\n * structural discriminated union keyed on `type`\n * (`\"step\" | \"gate\" | \"catch\" | \"finally\"`). Historically every combinator on\n * `Workflow` hand-built one of those object literals inline, so the builder\n * class knew the construction details of every step kind. We are migrating that\n * per-kind knowledge into focused `Step` subclasses.\n *\n * ## Execution model (the \"fat step\")\n *\n * The run loop does one thing: call {@link execute}. Everything else is the\n * step's own business — a kind's `execute` decides whether to skip (via\n * {@link shouldSkip} / {@link applyConditionalSkip}), runs its work, and\n * captures any thrown error onto `state.pendingError`, exactly the way it\n * writes its result to `state.output`. Errors accumulate on the state; they do\n * 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. Mirrors `StepNode[\"type\"]`. */\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 // Note: `type: \"step\"` subclasses (agent / transform / nested / branch /\n // foreach / repeat / parallel) also carry a `readonly category` that the run\n // loop reads (`getObservabilityType`) to type observability events. It is not\n // declared on this base — the `StepNode` union in `workflow.ts` redeclares the\n // node shape, so `category` is part of that structural contract rather than\n // this class. Subclasses add it directly.\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 — the only method the run loop invokes. Each kind overrides\n * it to do its work, run its own skip checks, and capture errors onto state.\n * `state.output` is the input on entry and becomes the output on exit;\n * `state.writer` is present in stream mode. The base implementation is a\n * 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: return `true` when this step should be skipped silently\n * (no output change). The default is the \"normal\" policy — skip while the\n * flow is suspended or already in error. Overridden by kinds with inverted\n * policies: `catch` runs only when there's an error, `finally` always runs.\n */\n protected 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, ConditionalStepOptions } from \"../workflow\";\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 runs its\n * own skip checks and captures any thrown error onto `state.pendingError`,\n * mirroring how it writes its 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 if (this.shouldSkip(state)) return;\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, StepOptions, AgentStepHooks, AgentResultParams } from \"../workflow\";\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} runs its\n * own skip checks and captures any thrown error onto `state.pendingError`,\n * mirroring how it writes its result to `state.output`.\n *\n * The raw agent invocation lives in the static {@link runAgent} so it can be\n * shared with the still-literal foreach / parallel / branch combinators (which\n * call it via `Workflow.executeAgent`) until those migrate to `Step` subclasses\n * too. Generics live at the `Workflow.step` API boundary; an `AgentStep`\n * instance 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 if (this.shouldSkip(state)) return;\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","import type { RuntimeState, BranchCase, BranchSelect } from \"../workflow\";\nimport { WorkflowBranchError } from \"../workflow\";\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 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 if (this.shouldSkip(state)) return;\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 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 if (this.shouldSkip(state)) return;\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","/**\n * A counting semaphore for bounding concurrency.\n *\n * `run(fn)` acquires a permit, runs `fn`, and releases the permit afterwards\n * (even if `fn` throws). 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 async run<T>(fn: () => Promise<T>): Promise<T> {\n await this.acquire();\n try {\n return await fn();\n } finally {\n this.release();\n }\n }\n}\n","import type { RuntimeState } from \"../workflow\";\nimport { pushWarning } from \"../workflow\";\n\n/** A unit (foreach item / parallel branch) that rejected. */\nexport type UnitFailure = { key: string | number; index: number; error: unknown };\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 type { MaybePromise } from \"../utils\";\nimport type { Agent } from \"../agent\";\nimport type { RuntimeState, WorkflowObservability, AgentStepHooks } from \"../workflow\";\nimport { SealedWorkflow, Workflow, fireHook, hasItemHooks } from \"../workflow\";\nimport { Step } from \"./step\";\nimport { AgentStep } from \"./agent-step\";\nimport { Semaphore } from \"./semaphore\";\nimport { reconcileUnits, type UnitFailure } 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, with a\n * worker-pool dispatch (default concurrency: unbounded). The dispatch loop is\n * inlined here over a {@link Semaphore}; the post-settle warning-merge + abort\n * precedence is shared with `parallel` via {@link reconcileUnits}. Per-item\n * observability, `onError` recovery (`Workflow.SKIP` to omit), and abort are\n * handled inline. Captures its observability at construction so per-item events\n * fire on the owning workflow's hooks. Self-contained: any thrown error is\n * parked on `state.pendingError`.\n */\nexport class ForeachStep extends Step {\n readonly type = \"step\" as const;\n readonly category = \"foreach\" as const;\n readonly id: string;\n readonly nestedWorkflow?: SealedWorkflow<any, any, any, any>;\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 inheritStreaming: boolean;\n private readonly observability?: WorkflowObservability;\n\n constructor(target: ForeachTarget, options: ForeachOptions | undefined, observability: WorkflowObservability | undefined) {\n super();\n // Validate up front: a positive integer or `Infinity` (full fan-out,\n // clamped by item count). Rejects NaN / 0 / negatives and fractional values.\n if (\n options?.concurrency !== undefined &&\n !((Number.isInteger(options.concurrency) && options.concurrency >= 1) || options.concurrency === Infinity)\n ) {\n throw new Error(`foreach: concurrency must be a positive integer or Infinity, got ${options.concurrency}`);\n }\n this.target = target;\n this.concurrency = options?.concurrency ?? Infinity;\n this.onError = options?.onError;\n this.handleStream = options?.handleStream;\n this.observability = observability;\n this.isWorkflow = target instanceof SealedWorkflow;\n // Agent items inherit the parent's stream mode + writer ONLY when a\n // handleStream is supplied (else generate — foreach never auto-merges N\n // streams). Workflow items always inherit, streaming transitively.\n this.inheritStreaming = this.isWorkflow || this.handleStream !== undefined;\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 if (this.shouldSkip(state)) return;\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 const skipped = new Set<number>();\n const itemStates: (RuntimeState | undefined)[] = new Array(items.length);\n const wantItemHooks = hasItemHooks(this.observability);\n\n const executeItem = async (item: unknown, index: number) => {\n // itemState omits runOptions — per-run config never crosses the foreach\n // boundary; abortSignal IS propagated (cancellation is transitive).\n const itemState: RuntimeState = {\n ctx: state.ctx,\n output: item,\n mode: this.inheritStreaming ? state.mode : \"generate\",\n writer: this.inheritStreaming ? state.writer : undefined,\n abortSignal: state.abortSignal,\n };\n itemStates[index] = itemState;\n const itemStart = wantItemHooks ? performance.now() : 0;\n if (wantItemHooks) {\n await fireHook(this.observability, state, \"onItemStart\", {\n stepId: this.id, type: \"foreach\", itemIndex: index, ctx: state.ctx, input: item,\n });\n }\n try {\n if (this.isWorkflow) {\n await (this.target as SealedWorkflow<any, any, any, any>).executeAsNested(itemState);\n } else {\n await AgentStep.runAgent(\n itemState,\n this.target as Agent<any, any, any>,\n state.ctx,\n this.handleStream ? ({ handleStream: this.handleStream } as AgentStepHooks<any, any, any>) : undefined,\n index,\n );\n }\n results[index] = itemState.output;\n if (wantItemHooks) {\n await fireHook(this.observability, state, \"onItemFinish\", {\n stepId: this.id, type: \"foreach\", itemIndex: index, ctx: state.ctx, output: itemState.output,\n durationMs: performance.now() - itemStart,\n });\n }\n } catch (error) {\n if (wantItemHooks) {\n await fireHook(this.observability, state, \"onItemError\", {\n stepId: this.id, type: \"foreach\", itemIndex: index, ctx: state.ctx, error,\n durationMs: performance.now() - itemStart,\n });\n }\n throw error;\n }\n };\n\n // Bounded dispatch: a Semaphore gates the loop, acquiring a permit BEFORE\n // launching each item 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). foreach's per-item key IS its index.\n const sem = new Semaphore(this.concurrency);\n const failures: UnitFailure[] = [];\n const inflight = new Set<Promise<void>>();\n for (let i = 0; i < items.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 executeItem(items[index], index); }\n catch (error) { failures.push({ key: index, 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 // Reconcile (warning-merge + abort + nested-gate). Throws on abort /\n // nested gate — caught by the outer try below.\n const nonGateFailures = reconcileUnits(state, this.id, failures, items.length, (i) => i, itemStates, state.abortSignal);\n\n // No suspension — run onError per existing semantics in index order.\n for (const { index, error } of nonGateFailures) {\n if (!this.onError) throw error;\n const recovered = await this.onError({ error, item: items[index], index, ctx: state.ctx });\n if (recovered === Workflow.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 type { MaybePromise } from \"../utils\";\nimport type { Agent } from \"../agent\";\nimport type { RuntimeState, WorkflowObservability, AgentStepHooks, ParallelTarget } from \"../workflow\";\nimport { SealedWorkflow, Workflow, fireHook, hasItemHooks } from \"../workflow\";\nimport { Step } from \"./step\";\nimport { AgentStep } from \"./agent-step\";\nimport { Semaphore } from \"./semaphore\";\nimport { reconcileUnits, type UnitFailure } 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> };\n\n/**\n * Parallel step — `Workflow.parallel(branches, options?)`.\n *\n * Feeds the same input to every branch (record or tuple form) with a worker-pool\n * dispatch (default concurrency: unbounded). The dispatch loop is inlined here\n * over a {@link Semaphore}; the post-settle warning-merge + abort precedence is\n * shared with `foreach` via {@link reconcileUnits}. Per-branch observability and\n * `onError` recovery (`Workflow.SKIP` leaves the slot `undefined`) are handled\n * inline. Self-contained: any thrown error is parked on `state.pendingError`.\n */\nexport class ParallelStep extends Step {\n readonly type = \"step\" as const;\n readonly category = \"parallel\" as const;\n readonly id: string;\n\n private readonly entries: Entry[];\n private readonly isTuple: boolean;\n private readonly branchCount: number;\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 this.entries = this.isTuple\n ? (branches as ReadonlyArray<ParallelTarget<any, any>>).map((target, i) => ({ key: i, index: i, target }))\n : Object.entries(branches as Record<string, ParallelTarget<any, any>>).map(([k, t], i) => ({ key: k, index: i, target: t }));\n this.branchCount = this.entries.length;\n\n const requestedConcurrency = options?.concurrency;\n if (\n requestedConcurrency !== undefined &&\n !((Number.isInteger(requestedConcurrency) && requestedConcurrency >= 1) || requestedConcurrency === Infinity)\n ) {\n throw new Error(`parallel: concurrency must be a positive integer or Infinity, got ${requestedConcurrency}`);\n }\n // Default: unbounded (full fan-out, clamped only by branch count).\n this.concurrency = requestedConcurrency ?? Infinity;\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 if (this.shouldSkip(state)) return;\n try {\n const input = state.output;\n const results: Record<string | number, unknown> = (this.isTuple ? new Array(this.branchCount) : {}) as Record<string | number, unknown>;\n const branchStates: (RuntimeState | undefined)[] = new Array(this.branchCount);\n const wantItemHooks = hasItemHooks(this.observability);\n\n const executeBranch = async ({ key, index, target }: Entry) => {\n const isWorkflowBranch = target instanceof SealedWorkflow;\n // Agent branches inherit stream mode + writer only when handleStream is\n // supplied (else generate); workflow branches always inherit.\n const inheritStreaming = isWorkflowBranch || this.handleStream !== undefined;\n const branchState: RuntimeState = {\n ctx: state.ctx,\n output: input,\n mode: inheritStreaming ? state.mode : \"generate\",\n writer: inheritStreaming ? state.writer : undefined,\n abortSignal: state.abortSignal,\n };\n branchStates[index] = branchState;\n const branchStart = wantItemHooks ? performance.now() : 0;\n // itemIndex is the key for record form, numeric index for tuple form.\n const itemIndex: string | number = this.isTuple ? index : (key as string);\n if (wantItemHooks) {\n await fireHook(this.observability, state, \"onItemStart\", {\n stepId: this.id, type: \"parallel\", itemIndex, ctx: state.ctx, input,\n });\n }\n try {\n if (isWorkflowBranch) {\n await (target as SealedWorkflow<any, any, any, any>).executeAsNested(branchState);\n } else {\n await AgentStep.runAgent(\n branchState,\n target as Agent<any, any, any>,\n state.ctx,\n this.handleStream ? ({ handleStream: this.handleStream } as AgentStepHooks<any, any, any>) : undefined,\n itemIndex,\n );\n }\n results[key] = branchState.output;\n if (wantItemHooks) {\n await fireHook(this.observability, state, \"onItemFinish\", {\n stepId: this.id, type: \"parallel\", itemIndex, ctx: state.ctx, output: branchState.output,\n durationMs: performance.now() - branchStart,\n });\n }\n } catch (error) {\n if (wantItemHooks) {\n await fireHook(this.observability, state, \"onItemError\", {\n stepId: this.id, type: \"parallel\", itemIndex, ctx: state.ctx, error,\n durationMs: performance.now() - branchStart,\n });\n }\n throw error;\n }\n };\n\n // Bounded dispatch: a Semaphore gates the loop, acquiring a permit BEFORE\n // launching each branch 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). Per-branch key is the record key / tuple index.\n const keyAt = (i: number) => this.entries[i].key;\n const sem = new Semaphore(this.concurrency);\n const failures: UnitFailure[] = [];\n const inflight = new Set<Promise<void>>();\n for (let i = 0; i < this.branchCount; 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 executeBranch(this.entries[index]); }\n catch (error) { failures.push({ key: keyAt(index), index, error }); }\n finally { sem.release(); }\n })();\n inflight.add(unit);\n void unit.finally(() => inflight.delete(unit));\n }\n\n await Promise.all(inflight);\n failures.sort((a, b) => a.index - b.index);\n\n // Reconcile (warning-merge + abort + nested-gate). Throws on abort /\n // nested gate — caught by the outer try below.\n const nonGateFailures = reconcileUnits(state, this.id, failures, this.branchCount, keyAt, branchStates, state.abortSignal);\n\n // No suspension — handle non-gate failures via onError or rethrow.\n for (const { key, index, error } of nonGateFailures) {\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 if (recovered === Workflow.SKIP) {\n // Both forms: the slot stays `undefined` in place (no index shift).\n results[key] = undefined;\n } else {\n results[key] = recovered;\n }\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 type { RuntimeState, GateSnapshot, SchemaWithParse } from \"../workflow\";\nimport { resolveFreezeSnapshots } from \"../workflow\";\nimport { Step } from \"./step\";\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 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: (state: RuntimeState) => MaybePromise<unknown>;\n private readonly condition?: (state: RuntimeState) => MaybePromise<boolean>;\n\n constructor(\n id: string,\n payload: (state: RuntimeState) => MaybePromise<unknown>,\n schema: SchemaWithParse | undefined,\n condition: ((state: RuntimeState) => MaybePromise<boolean>) | undefined,\n merge: ((params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>) | undefined,\n ) {\n super();\n this.id = id;\n this.payload = payload;\n this.schema = schema;\n this.condition = condition;\n this.merge = merge;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n if (this.shouldSkip(state)) return;\n try {\n // A false condition short-circuits the gate: no suspension, passthrough.\n if (this.condition && !(await this.condition(state))) 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: await this.payload(state),\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 \"../workflow\";\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 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 protected override shouldSkip(state: RuntimeState): boolean {\n return !!state.suspension || !state.pendingError || !!state.checkpointFailed;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n if (this.shouldSkip(state)) return;\n // shouldSkip 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 \"../workflow\";\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 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 protected override shouldSkip(_state: RuntimeState): boolean {\n return false;\n }\n\n override async execute(state: RuntimeState): Promise<void> {\n if (this.shouldSkip(state)) return;\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 type { RuntimeState, ConditionalStepOptions, SealedWorkflow } from \"../workflow\";\nimport { prependNestedPath } 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 skip /\n * `when`-`otherwise` checks and captures any thrown error onto\n * `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 public 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 readonly category = \"nested\" as const;\n readonly id: string;\n readonly nestedWorkflow: SealedWorkflow<any, any, any, any>;\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. Handled before\n // shouldSkip — on resume the parent's pre-gate steps already ran, so this\n // 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 if (this.shouldSkip(state)) return;\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, LoopPredicate, SealedWorkflow } from \"../workflow\";\nimport { WorkflowLoopError } from \"../workflow\";\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 public (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 readonly category = \"repeat\" as const;\n readonly id: string;\n readonly nestedWorkflow?: SealedWorkflow<any, any, any, any>;\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 if (this.shouldSkip(state)) return;\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","// Runtime plumbing for the workflow engine: per-run state construction,\n// observability hook dispatch, warning bookkeeping, pending-error demotion, and\n// the checkpoint sink. These are free functions coupled only to `RuntimeState` /\n// `PendingError` (imported type-only from `./workflow`, so no runtime cycle) plus\n// the public types in `./types`. `workflow.ts` re-exports the subset the `Step`\n// subclasses in `./steps` consume, so their `from \"../workflow\"` imports are\n// unchanged.\n\nimport type { UIMessageStreamWriter } from \"ai\";\nimport { deepFreeze, type MaybePromise } from \"./utils\";\nimport type { RuntimeState, PendingError } from \"./workflow\";\nimport type {\n CheckpointSnapshot,\n RunOptions,\n WorkflowObservability,\n WorkflowResult,\n WorkflowStepType,\n WorkflowWarning,\n} from \"./types\";\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 migrated `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. Free counterpart to `SealedWorkflow#hasItemHooks`.\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","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} 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":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA,QAAAA;AAAA,OAaK;;;AChBP,SAAS,YAAmG;;;ACA5G,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAQ3B,IAAM,gBAAgB,IAAI,kBAAyC;AAE5D,SAAS,cAAiB,QAA+B,IAAgB;AAC9E,SAAO,cAAc,IAAI,QAAQ,EAAE;AACrC;AAqBO,SAAS,kBAAqD;AACnE,SAAO,cAAc,SAAS;AAChC;AAqBO,SAAS,aACd,OACA,KACA,OACsC;AACtC,MAAI,OAAO,UAAU,YAAY;AAC/B,WAAQ,MAAiE,KAAK,KAAK;AAAA,EACrF;AACA,SAAO;AACT;AAeA,eAAsB,cAEpB,QACA,qBAEA,QACkB;AAClB,MAAI,qBAAqB;AACvB,UAAM,SAAS,MAAM,OAAO;AAC5B,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI;AAAA,QACR;AAAA,MAGF;AAAA,IACF;AACA,QAAI,QAAQ;AACV,aAAO,OAAO,MAAM,MAAM;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AACA,SAAO,MAAM,OAAO;AACtB;AAOO,SAAS,WAAc,OAAU,OAAwB,oBAAI,QAAQ,GAAM;AAChF,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,KAAK,IAAI,KAAe,EAAG,QAAO;AAGrF,MAAI,OAAO,SAAS,KAAK,EAAG,QAAO;AACnC,OAAK,IAAI,KAAe;AACxB,SAAO,OAAO,KAAK;AACnB,aAAW,OAAO,QAAQ,QAAQ,KAAe,GAAG;AAElD,eAAY,MAAc,GAAG,GAAG,IAAI;AAAA,EACtC;AACA,SAAO;AACT;AAuCO,SAAS,qBACd,OACA,WACQ;AACR,SAAO,WAAW,QAAQ,EAAE,OAAO,oBAAoB,OAAO,WAAW,oBAAI,QAAQ,CAAC,CAAC,EAAE,OAAO,KAAK;AACvG;AAQA,SAAS,oBACP,OACA,WACA,MACQ;AACR,SAAO,KAAK,UAAU,MAAM,IAAI,CAAC,GAAG,MAAM;AACxC,UAAM,SAA8B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;AACpD,eAAW,SAAS,UAAU,CAAC,GAAG;AAChC,UAAI,KAAK,IAAI,KAAK,GAAG;AACnB,eAAO,KAAK,UAAU,MAAM,MAAM,MAAM,GAAG;AAC3C;AAAA,MACF;AACA,WAAK,IAAI,KAAK;AACd,UAAI;AACF,eAAO,KAAK,oBAAoB,MAAM,qBAAqB,GAAG,WAAW,IAAI,CAAC;AAAA,MAChF,UAAE;AACA,aAAK,OAAO,KAAK;AAAA,MACnB;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC,CAAC;AACJ;AAIA,IAAM,iBAAiB,oBAAI,IAAY;AAChC,SAAS,SAAS,KAAa,SAAwB;AAC5D,MAAI,eAAe,IAAI,GAAG,EAAG;AAC7B,iBAAe,IAAI,GAAG;AAEtB,UAAQ,KAAK,WAAW,GAAG;AAC7B;;;AD1MO,IAAM,sBAAsB,uBAAO,IAAI,6BAA6B;AAqBpE,IAAM,eAAN,MAI8B;AAAA,EACnC,CAAU,mBAAmB,IAAI;AAAA,EAChB;AAAA,EAEjB,YAAY,QAAuD;AACjE,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,WAAW,SAAmC;AAC5C,UAAM,EAAE,SAAS,OAAO,aAAa,GAAG,QAAQ,IAAI,KAAK;AAKzD,WAAO,KAAsB;AAAA,MAC3B,GAAG;AAAA,MACH;AAAA,MACA,SAAS,CAAC,OAAe,YAAkC,QAAQ,OAAO,SAAS,EAAE,GAAG,SAAS,QAAQ,gBAAgB,EAAE,CAAuB;AAAA,IACpJ,CAAqC;AAAA,EACvC;AACF;AAEO,SAAS,aAAuB;AACrC,SAAO,CACL,WAC4C,IAAI,aAAa,MAAM;AACvE;AAEO,SAAS,eAAyB,KAA8C;AACrF,SACE,OAAO,QAAQ,YACf,QAAQ,QACR,uBAAuB;AAE3B;;;ADoEO,IAAM,QAAN,MAIL;AAAA,EACS;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA;AAAA,EACQ;AAAA,EACA;AAAA,EACA,uBAAoD;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAAgD;AAC1D,SAAK,KAAK,OAAO;AACjB,SAAK,cAAc,OAAO,eAAe;AACzC,SAAK,YAAY,OAAO,WAAW;AACnC,SAAK,iBAAiB,OAAO;AAC7B,SAAK,SAAS;AAQd,SAAK,oBAAoB;AAAA,MACvB,OAAO;AAAA,MAAO,OAAO;AAAA,MAAQ,OAAO;AAAA,MACpC,OAAO;AAAA,MAAU,OAAO;AAAA,MAAO,OAAO;AAAA,MACtC,OAAO;AAAA,IACT,EAAE,KAAK,OAAK,OAAO,MAAM,UAAU;AAInC,QAAI,CAAC,KAAK,mBAAmB;AAC3B,YAAM,WAAY,OAAO,SAAgD,CAAC;AAC1E,YAAM,cAAc,OAAO,OAAO,QAAQ,EAAE,KAAK,OAAK,eAAe,CAAC,CAAC;AACvE,UAAI,CAAC,aAAa;AAChB,aAAK,uBAAuB;AAAA,MAC9B;AAAA,IACF;AAIA,UAAM;AAAA,MACJ,IAAI;AAAA,MAAK,aAAa;AAAA,MAAO,OAAO;AAAA,MAAc,QAAQ;AAAA,MAAS,gBAAgB;AAAA,MACnF,OAAO;AAAA,MAAI,QAAQ;AAAA,MAAI,QAAQ;AAAA,MAAI,UAAU;AAAA,MAC7C,OAAO;AAAA,MAAI,aAAa;AAAA,MAAK,YAAY;AAAA,MAAK,UAAU;AAAA,MACxD;AAAA,MAAc;AAAA,MAAU,SAAS;AAAA,MACjC,GAAG;AAAA,IACL,IAAI;AACJ,SAAK,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAM,SACJ,QACG,MAGwD;AAC3D,UAAM,QAAQ,KAAK,CAAC;AACpB,UAAM,cAAc,KAAK,CAAC;AAC1B,WAAO,KAAK,oBAAoB,KAAK,OAAO,eAAe,CAAC,CAAC;AAAA,EAC/D;AAAA,EAEA,MAAM,OACJ,QACG,MAGsD;AACzD,UAAM,QAAQ,KAAK,CAAC;AACpB,UAAM,cAAc,KAAK,CAAC;AAC1B,WAAO,KAAK,kBAAkB,KAAK,OAAO,eAAe,CAAC,CAAC;AAAA,EAC7D;AAAA,EAEA,OAAO,KAAe,SAEb;AACP,WAAO,KAAK,mBAAmB,KAAK,OAAO;AAAA,EAC7C;AAAA,EAEA,eAAe,SAEa;AAC1B,QAAI,CAAC,KAAK,OAAO,OAAO;AACtB,YAAM,IAAI,MAAM,UAAU,KAAK,EAAE,8CAA8C;AAAA,IACjF;AAEA,WAAO;AAAA,MACL,CAAC,mBAAmB,GAAG;AAAA,MACvB,YAAY,CAAC,QAA4B,KAAK,mBAAmB,KAAiB,OAAO;AAAA,IAC3F;AAAA,EACF;AAAA,EAEQ,mBAAmB,KAAe,SAEjC;AACP,QAAI,CAAC,KAAK,OAAO,OAAO;AACtB,YAAM,IAAI,MAAM,UAAU,KAAK,EAAE,sCAAsC;AAAA,IACzE;AAEA,WAAOC,MAAsB;AAAA,MAC3B,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKzB,SAAS,OAAO,WAAmB,gBAAgD;AACjF,cAAM,cAAc,aAAa;AAGjC,cAAM,SAAS,gBAAgB;AAC/B,YAAI,QAAQ;AACV,gBAAMC,UAAS,MAAM,KAAK,kBAAkB,KAAK,WAAW,EAAE,YAAY,CAAC;AAC3E,iBAAO,MAAMA,QAAO,kBAAkB,CAAC;AAWvC,cAAI,SAAS,WAAW;AACtB,kBAAMA,QAAO;AACb,mBAAO,QAAQ,UAAUA,OAAM;AAAA,UACjC;AACA,iBAAO,cAAcA,SAAQ,KAAK,WAAW,KAAK,cAAc;AAAA,QAClE;AACA,cAAM,SAAS,MAAM,KAAK,oBAAoB,KAAK,WAAW,EAAE,YAAY,CAAC;AAC7E,YAAI,SAAS,UAAW,QAAO,QAAQ,UAAU,MAAM;AACvD,eAAO,cAAc,QAAQ,KAAK,WAAW,KAAK,cAAc;AAAA,MAClE;AAAA;AAAA;AAAA,IAGF,CAAqC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAc,cAAc,OAAgB,KAAe,OAA8B;AACvF,QAAI,CAAC,KAAK,OAAO,QAAS;AAC1B,QAAI;AACF,YAAM,KAAK,OAAO,QAAQ,EAAE,OAAO,KAAK,OAAO,QAAQ,gBAAgB,EAAE,CAAC;AAAA,IAC5E,SAAS,cAAc;AAIrB,UAAI,wBAAwB,OAAO;AACjC,YAAI,aAAa,UAAU,QAAW;AACpC,UAAC,aAAqC,QAAQ;AAAA,QAChD;AACA,cAAM;AAAA,MACR;AACA,YAAM,UAAU,IAAI;AAAA,QAClB,UAAU,KAAK,EAAE,+CAA+C,OAAO,YAAY,MAAM,OAAO,YAAY,CAAC;AAAA,MAC/G;AACA,MAAC,QAAgC,QAAQ;AACzC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,oBACZ,KACA,OACA,OAC2D;AAC3D,UAAM,WAAW,MAAM,KAAK,cAAc,KAAK,KAAK;AACpD,UAAM,UAAU,KAAK,iBAAiB,UAAU,KAAK,KAAK;AAC1D,QAAI;AAIF,aAAQ,MAAM,aAAa,EAAE,GAAG,SAAS,GAAG,MAAM,CAAkD;AAAA,IACtG,SAAS,OAAgB;AACvB,YAAM,KAAK,cAAc,OAAO,KAAK,KAAK;AAC1C,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,kBACZ,KACA,OACA,OACyD;AACzD,UAAM,WAAW,MAAM,KAAK,cAAc,KAAK,KAAK;AACpD,UAAM,UAAU,KAAK,iBAAiB,UAAU,KAAK,KAAK;AAC1D,QAAI;AAIF,YAAM,gBAAgB,KAAK,OAAO,UAC9B,EAAE,SAAS,CAAC,EAAE,MAAM,MAA0B,KAAK,cAAc,OAAO,KAAK,KAAK,EAAE,IACpF,CAAC;AACL,aAAO,WAAW;AAAA,QAChB,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,MACL,CAAgD;AAAA,IAClD,SAAS,OAAgB;AAIvB,YAAM,KAAK,cAAc,OAAO,KAAK,KAAK;AAC1C,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,iBAAiB,UAA+B,KAAe,OAAwC;AAC7G,QAAI,SAAS,aAAa,UAAa,SAAS,WAAW,QAAW;AACpE,YAAM,IAAI;AAAA,QACR,UAAU,KAAK,EAAE;AAAA,MAEnB;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG,KAAK;AAAA,MACR,OAAO,SAAS;AAAA,MAChB,OAAO,SAAS;AAAA,MAChB,aAAa,SAAS;AAAA,MACtB,YAAY,SAAS;AAAA,MACrB,UAAU,SAAS;AAAA,MACnB,GAAI,SAAS,aAAa,SACtB,EAAE,UAAU,SAAS,SAAS,IAC9B,EAAE,QAAQ,SAAS,OAAO;AAAA;AAAA;AAAA,MAG9B,GAAI,SAAS,WAAW,SAAY,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;AAAA,MACnE,GAAI,KAAK,OAAO,SAAS,EAAE,QAAQ,KAAK,OAAO,OAAO,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,MAI3D,GAAI,KAAK,gBACL,EAAE,cAAc,CAAC,UAA6B,KAAK,cAAe,EAAE,QAAQ,OAAO,KAAK,OAAO,QAAQ,gBAAgB,EAAE,CAAC,EAAE,IAC5H,CAAC;AAAA,MACL,GAAI,KAAK,YACL,EAAE,UAAU,CAAC,UAAyB,KAAK,UAAW,EAAE,QAAQ,OAAO,KAAK,OAAO,QAAQ,gBAAgB,EAAE,CAAC,EAAE,IAChH,CAAC;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,cAAc,KAAe,OAAmE;AACtG,QAAI,CAAC,KAAK,mBAAmB;AAC3B,aAAO;AAAA,QACL,OAAO,KAAK,OAAO;AAAA,QACnB,QAAQ,KAAK,OAAO;AAAA,QACpB,QAAQ,KAAK,OAAO;AAAA,QACpB,UAAU,KAAK,OAAO;AAAA,QACtB,OAAO,KAAK,wBAAwB,KAAK;AAAA,UACtC,KAAK,OAAO,SAAgD,CAAC;AAAA,UAAG;AAAA,QACnE;AAAA,QACA,aAAa,KAAK,OAAO;AAAA,QACzB,YAAY,KAAK,OAAO;AAAA,QACxB,UAAU,KAAK,OAAO;AAAA,MACxB;AAAA,IACF;AACA,WAAO,KAAK,mBAAmB,KAAK,KAAK;AAAA,EAC3C;AAAA,EAEA,MAAc,mBAAmB,KAAe,OAA6C;AAC3F,UAAM,CAAC,OAAO,QAAQ,QAAQ,UAAU,UAAU,aAAa,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC7F,aAAa,KAAK,OAAO,OAAO,KAAK,KAAK;AAAA,MAC1C,aAAa,KAAK,OAAO,QAAQ,KAAK,KAAK;AAAA,MAC3C,aAAa,KAAK,OAAO,QAAQ,KAAK,KAAK;AAAA,MAC3C,aAAa,KAAK,OAAO,UAAU,KAAK,KAAK;AAAA,MAC7C,aAAa,KAAK,OAAO,OAAO,KAAK,KAAK;AAAA,MAC1C,aAAa,KAAK,OAAO,aAAa,KAAK,KAAK;AAAA,MAChD,aAAa,KAAK,OAAO,YAAY,KAAK,KAAK;AAAA,IACjD,CAAC;AACD,UAAM,QAAQ,KAAK,aAAa,YAAY,CAAC,GAAG,GAAG;AACnD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA,UAAU,KAAK,OAAO;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,aACN,OACA,KACsB;AACtB,UAAM,UAAU,OAAO,QAAQ,KAAK;AACpC,QAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAI,cAAc;AAClB,UAAM,WAAiC,CAAC;AACxC,eAAW,CAAC,KAAK,cAAc,KAAK,SAAS;AAC3C,UAAI,eAAyB,cAAc,GAAG;AAC5C,sBAAc;AACd,iBAAS,GAAG,IAAI,eAAe,WAAW,GAAyB;AAAA,MACrE,OAAO;AACL,iBAAS,GAAG,IAAI;AAAA,MAClB;AAAA,IACF;AACA,WAAO,cAAc,WAAY;AAAA,EACnC;AACF;;;AGrcA;AAAA,EACE;AAAA,OAIK;;;ACoBA,IAAe,OAAf,MAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBN,cAAsC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASzD,MAAM,QAAQ,QAAqC;AAAA,EAEnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQU,WAAW,OAA8B;AACjD,WAAO,CAAC,CAAC,MAAM,cAAc,CAAC,CAAC,MAAM;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAgB,qBACd,OACA,SACkB;AAClB,QAAI,CAAC,SAAS,KAAM,QAAO;AAK3B,UAAM,SAAS,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,OAAO;AACrD,QAAI,MAAM,QAAQ,KAAK,MAAM,EAAG,QAAO;AACvC,QAAI,QAAQ,WAAW;AACrB,YAAM,SAAS,MAAM,QAAQ,UAAU,MAAM;AAAA,IAC/C;AAEA,WAAO;AAAA,EACT;AACF;;;ACnEO,IAAM,gBAAN,cAA4B,KAAK;AAAA,EAC7B,OAAO;AAAA,EACP;AAAA,EACQ;AAAA,EACA;AAAA,EAEjB,YACE,IACA,IACA,SACA;AACA,UAAM;AACN,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AAGF,UAAI,MAAM,KAAK,qBAAqB,OAAO,KAAK,OAAO,EAAG;AAC1D,YAAM,SAAS,MAAM,KAAK,GAAG;AAAA,QAC3B,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA;AAAA;AAAA,QAGb,QAAQ,MAAM;AAAA,MAChB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;ACpCO,IAAM,YAAN,MAAM,mBAAkB,KAAK;AAAA,EACzB,OAAO;AAAA,EACP;AAAA;AAAA,EAEQ;AAAA;AAAA,EAEA;AAAA,EAEjB,YACE,IAEA,OAEA,SACA;AACA,UAAM;AACN,SAAK,KAAK;AACV,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AAGF,UAAI,MAAM,KAAK,qBAAqB,OAAO,KAAK,OAAO,EAAG;AAC1D,YAAM,WAAU,SAAS,OAAO,KAAK,OAAO,MAAM,KAAK,KAAK,OAAO;AAAA,IACrE,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,aAAa,SACX,OAEA,OACA,KAEA,SACA,WACe;AACf,UAAM,QAAQ,MAAM;AACpB,UAAM,sBAAsB,MAAM;AAElC,UAAM,cAAc,MAAM;AAC1B,UAAM,gBAAgB,cAAc,EAAE,YAAY,IAAI;AAEtD,QAAI,MAAM,SAAS,YAAY,MAAM,QAAQ;AAC3C,YAAM,SAAS,MAAM;AAErB,YAAM,cAAc,QAAQ,YAAY;AACtC,cAAM,SAAS,MAAO,MAAM,OAAgJ,KAAK,MAAM,QAAQ,aAAa;AAE5M,YAAI,SAAS,cAAc;AACzB,gBAAM,QAAQ,aAAa,EAAE,QAAQ,QAAQ,KAAK,OAAO,UAAU,CAAC;AAAA,QACtE,OAAO;AACL,iBAAO,MAAM,OAAO,kBAAkB,CAAC;AAAA,QACzC;AAEA,cAAM,aAAa;AAAA,UACjB,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAEF;AAEA,YAAI,SAAS,UAAU;AACrB,gBAAM,QAAQ,SAAS,UAAU;AAAA,QACnC;AAEA,YAAI,SAAS,WAAW;AACtB,gBAAM,SAAS,MAAM,QAAQ,UAAU,UAAU;AAAA,QACnD,OAAO;AACL,gBAAM,SAAS,MAAM,cAAc,QAAQ,qBAAqB,MAAM,cAAc;AAAA,QACtF;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,YAAM,SAAS,MAAO,MAAM,SAAoJ,KAAK,MAAM,QAAQ,aAAa;AAEhN,YAAM,aAAa;AAAA,QACjB,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MAEF;AAEA,UAAI,SAAS,UAAU;AACrB,cAAM,QAAQ,SAAS,UAAU;AAAA,MACnC;AAEA,UAAI,SAAS,WAAW;AACtB,cAAM,SAAS,MAAM,QAAQ,UAAU,UAAU;AAAA,MACnD,OAAO;AACL,cAAM,SAAS,MAAM,cAAc,QAAQ,qBAAqB,MAAM,cAAc;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AACF;;;ACxHO,IAAM,sBAAN,cAAkC,KAAK;AAAA,EACnC,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA;AAAA,EAEQ;AAAA;AAAA,EAGjB,YAAY,IAAY,OAAoC;AAC1D,UAAM;AACN,SAAK,KAAK;AACV,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AAEF,YAAM,MAAM,MAAM;AAElB,YAAM,QAAQ,MAAM;AAEpB,eAAS,YAAY,GAAG,YAAY,KAAK,MAAM,QAAQ,aAAa;AAClE,cAAM,aAAa,KAAK,MAAM,SAAS;AACvC,YAAI,WAAW,MAAM;AACnB,gBAAM,QAAQ,MAAM,WAAW,KAAK,EAAE,KAAK,MAAM,CAAC;AAClD,cAAI,CAAC,MAAO;AAAA,QACd;AAEA,cAAM,UAAU,SAAS,OAAO,WAAW,OAAO,KAAK,YAAY,SAAS;AAC5E;AAAA,MACF;AAKA,UAAI;AACJ,UAAI;AACF,oBAAY,KAAK,UAAU,KAAK;AAChC,YAAI,cAAc,OAAW,aAAY,OAAO,KAAK;AAAA,MACvD,QAAQ;AACN,oBAAY,mBAAmB,OAAO,KAAK;AAAA,MAC7C;AACA,YAAM,IAAI,oBAAoB,aAAa,0FAA0F,SAAS,EAAE;AAAA,IAClJ,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;AAUO,IAAM,mBAAN,cAA+B,KAAK;AAAA,EAChC,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA;AAAA,EAEQ;AAAA;AAAA,EAGjB,YAAY,IAAY,QAA0C;AAChE,UAAM;AACN,SAAK,KAAK;AACV,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AAEF,YAAM,MAAM,MAAM;AAElB,YAAM,QAAQ,MAAM;AACpB,YAAM,SAAS,KAAK;AACpB,YAAM,MAAM,MAAM,OAAO,OAAO,EAAE,KAAK,MAAM,CAAC;AAW9C,YAAM,cAAc,OAAO,UAAU,eAAe,KAAK,OAAO,QAAQ,GAAG;AAC3E,UAAI,eAAgB,OAAO,OAAmC,GAAG,MAAM,QAAW;AAChF,cAAM,IAAI;AAAA,UACR;AAAA,UACA,kBAAkB,GAAG,kIAEF,OAAO,KAAK,OAAO,MAAM,EAAE,KAAK,IAAI,CAAC;AAAA,QAC1D;AAAA,MACF;AACA,UAAI,QAAQ,cAAc,OAAO,OAAO,GAAG,IAAI;AAC/C,UAAI,CAAC,OAAO;AACV,YAAI,OAAO,cAAc;AACvB,iBAAO,aAAa;AAAA,YAClB;AAAA,YACA,eAAe,OAAO,KAAK,OAAO,MAAM;AAAA,YACxC;AAAA,UACF,CAAC;AAAA,QACH;AACA,YAAI,OAAO,UAAU;AACnB,kBAAQ,OAAO;AAAA,QACjB,OAAO;AACL,gBAAM,IAAI,oBAAoB,UAAU,2BAA2B,GAAG,+CAA+C,OAAO,KAAK,OAAO,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,QAC9J;AAAA,MACF;AAGA,YAAM,UAAU,SAAS,OAAO,OAAO,KAAK,QAAQ,GAAG;AAAA,IACzD,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;AChIO,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EACS,UAA6B,CAAC;AAAA,EAE/C,YAAY,SAAiB;AAC3B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,UAAyB;AACvB,QAAI,KAAK,YAAY,GAAG;AACtB,WAAK;AACL,aAAO,QAAQ,QAAQ;AAAA,IACzB;AACA,WAAO,IAAI,QAAc,CAAC,YAAY,KAAK,QAAQ,KAAK,OAAO,CAAC;AAAA,EAClE;AAAA,EAEA,UAAgB;AACd,UAAM,OAAO,KAAK,QAAQ,MAAM;AAChC,QAAI,MAAM;AAGR,WAAK;AAAA,IACP,OAAO;AACL,WAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,MAAM,IAAO,IAAkC;AAC7C,UAAM,KAAK,QAAQ;AACnB,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,UAAE;AACA,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AACF;;;ACvBO,SAAS,eACd,OACA,IACA,UACA,OACA,OACA,YACA,QACe;AAOf,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,KAAK,WAAW,CAAC;AACvB,QAAI,CAAC,GAAI;AACT,QAAI,GAAG,YAAY;AACjB,YAAM,IAAI;AAAA,QACR,mBAAmB,GAAG,WAAW,MAAM,sCAAsC,EAAE,IAAI,MAAM,CAAC,CAAC;AAAA,MAE7F;AAAA,IACF;AACA,QAAI,CAAC,GAAG,SAAU;AAClB,eAAW,KAAK,GAAG,UAAU;AAC3B,kBAAY,OAAO,EAAE,QAAQ,GAAG,EAAE,IAAI,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,KAAK;AAAA,IACxE;AAAA,EACF;AAGA,MAAI,QAAQ,SAAS;AACnB,eAAW,KAAK,UAAU;AACxB,kBAAY,OAAO,mBAAmB,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,KAAK;AAAA,IAClE;AACA,UAAM,OAAO,UAAU,IAAI,MAAM,kBAAkB;AAAA,EACrD;AAGA,SAAO;AACT;;;AC5BO,IAAM,cAAN,cAA0B,KAAK;AAAA,EAC3B,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAAuB,SAAqC,eAAkD;AACxH,UAAM;AAGN,QACE,SAAS,gBAAgB,UACzB,EAAG,OAAO,UAAU,QAAQ,WAAW,KAAK,QAAQ,eAAe,KAAM,QAAQ,gBAAgB,WACjG;AACA,YAAM,IAAI,MAAM,oEAAoE,QAAQ,WAAW,EAAE;AAAA,IAC3G;AACA,SAAK,SAAS;AACd,SAAK,cAAc,SAAS,eAAe;AAC3C,SAAK,UAAU,SAAS;AACxB,SAAK,eAAe,SAAS;AAC7B,SAAK,gBAAgB;AACrB,SAAK,aAAa,kBAAkB;AAIpC,SAAK,mBAAmB,KAAK,cAAc,KAAK,iBAAiB;AACjE,UAAM,YAAY,KAAK,aACjB,OAA8C,MAAM,YACtD,WAAY,OAAgC,EAAE;AAClD,SAAK,KAAK,SAAS,MAAM;AACzB,SAAK,iBAAiB,KAAK,aAAc,SAAgD;AAAA,EAC3F;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AACF,YAAM,QAAQ,MAAM;AACpB,UAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,cAAM,IAAI,MAAM,YAAY,KAAK,EAAE,gCAAgC,OAAO,KAAK,EAAE;AAAA,MACnF;AAEA,YAAM,UAAqB,IAAI,MAAM,MAAM,MAAM;AACjD,YAAM,UAAU,oBAAI,IAAY;AAChC,YAAM,aAA2C,IAAI,MAAM,MAAM,MAAM;AACvE,YAAM,gBAAgB,aAAa,KAAK,aAAa;AAErD,YAAM,cAAc,OAAO,MAAe,UAAkB;AAG1D,cAAM,YAA0B;AAAA,UAC9B,KAAK,MAAM;AAAA,UACX,QAAQ;AAAA,UACR,MAAM,KAAK,mBAAmB,MAAM,OAAO;AAAA,UAC3C,QAAQ,KAAK,mBAAmB,MAAM,SAAS;AAAA,UAC/C,aAAa,MAAM;AAAA,QACrB;AACA,mBAAW,KAAK,IAAI;AACpB,cAAM,YAAY,gBAAgB,YAAY,IAAI,IAAI;AACtD,YAAI,eAAe;AACjB,gBAAM,SAAS,KAAK,eAAe,OAAO,eAAe;AAAA,YACvD,QAAQ,KAAK;AAAA,YAAI,MAAM;AAAA,YAAW,WAAW;AAAA,YAAO,KAAK,MAAM;AAAA,YAAK,OAAO;AAAA,UAC7E,CAAC;AAAA,QACH;AACA,YAAI;AACF,cAAI,KAAK,YAAY;AACnB,kBAAO,KAAK,OAA8C,gBAAgB,SAAS;AAAA,UACrF,OAAO;AACL,kBAAM,UAAU;AAAA,cACd;AAAA,cACA,KAAK;AAAA,cACL,MAAM;AAAA,cACN,KAAK,eAAgB,EAAE,cAAc,KAAK,aAAa,IAAsC;AAAA,cAC7F;AAAA,YACF;AAAA,UACF;AACA,kBAAQ,KAAK,IAAI,UAAU;AAC3B,cAAI,eAAe;AACjB,kBAAM,SAAS,KAAK,eAAe,OAAO,gBAAgB;AAAA,cACxD,QAAQ,KAAK;AAAA,cAAI,MAAM;AAAA,cAAW,WAAW;AAAA,cAAO,KAAK,MAAM;AAAA,cAAK,QAAQ,UAAU;AAAA,cACtF,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AAAA,UACH;AAAA,QACF,SAAS,OAAO;AACd,cAAI,eAAe;AACjB,kBAAM,SAAS,KAAK,eAAe,OAAO,eAAe;AAAA,cACvD,QAAQ,KAAK;AAAA,cAAI,MAAM;AAAA,cAAW,WAAW;AAAA,cAAO,KAAK,MAAM;AAAA,cAAK;AAAA,cACpE,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AAAA,UACH;AACA,gBAAM;AAAA,QACR;AAAA,MACF;AAMA,YAAM,MAAM,IAAI,UAAU,KAAK,WAAW;AAC1C,YAAM,WAA0B,CAAC;AACjC,YAAM,WAAW,oBAAI,IAAmB;AACxC,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAI,MAAM,aAAa,QAAS;AAChC,cAAM,IAAI,QAAQ;AAClB,YAAI,MAAM,aAAa,SAAS;AAAE,cAAI,QAAQ;AAAG;AAAA,QAAO;AACxD,cAAM,QAAQ;AACd,cAAM,QAAQ,YAAY;AACxB,cAAI;AAAE,kBAAM,YAAY,MAAM,KAAK,GAAG,KAAK;AAAA,UAAG,SACvC,OAAO;AAAE,qBAAS,KAAK,EAAE,KAAK,OAAO,OAAO,MAAM,CAAC;AAAA,UAAG,UAC7D;AAAU,gBAAI,QAAQ;AAAA,UAAG;AAAA,QAC3B,GAAG;AACH,iBAAS,IAAI,IAAI;AACjB,aAAK,KAAK,QAAQ,MAAM,SAAS,OAAO,IAAI,CAAC;AAAA,MAC/C;AACA,YAAM,QAAQ,IAAI,QAAQ;AAC1B,eAAS,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAIzC,YAAM,kBAAkB,eAAe,OAAO,KAAK,IAAI,UAAU,MAAM,QAAQ,CAAC,MAAM,GAAG,YAAY,MAAM,WAAW;AAGtH,iBAAW,EAAE,OAAO,MAAM,KAAK,iBAAiB;AAC9C,YAAI,CAAC,KAAK,QAAS,OAAM;AACzB,cAAM,YAAY,MAAM,KAAK,QAAQ,EAAE,OAAO,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,MAAM,IAAI,CAAC;AACzF,YAAI,cAAc,SAAS,MAAM;AAC/B,kBAAQ,IAAI,KAAK;AAAA,QACnB,OAAO;AACL,kBAAQ,KAAK,IAAI;AAAA,QACnB;AAAA,MACF;AAEA,YAAM,SAAS,QAAQ,SAAS,IAC5B,UACA,QAAQ,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;AAAA,IAC9C,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;ACnJO,IAAM,eAAN,cAA2B,KAAK;AAAA,EAC5B,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,UAA4B,SAAmC,eAAkD;AAC3H,UAAM;AACN,SAAK,UAAU,MAAM,QAAQ,QAAQ;AACrC,SAAK,UAAU,KAAK,UACf,SAAqD,IAAI,CAAC,QAAQ,OAAO,EAAE,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE,IACvG,OAAO,QAAQ,QAAoD,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,EAAE,EAAE;AAC7H,SAAK,cAAc,KAAK,QAAQ;AAEhC,UAAM,uBAAuB,SAAS;AACtC,QACE,yBAAyB,UACzB,EAAG,OAAO,UAAU,oBAAoB,KAAK,wBAAwB,KAAM,yBAAyB,WACpG;AACA,YAAM,IAAI,MAAM,qEAAqE,oBAAoB,EAAE;AAAA,IAC7G;AAEA,SAAK,cAAc,wBAAwB;AAC3C,SAAK,UAAU,SAAS;AACxB,SAAK,eAAe,SAAS;AAC7B,SAAK,gBAAgB;AACrB,SAAK,KAAK,SAAS,OAAO,KAAK,UAAU,mBAAmB;AAAA,EAC9D;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AACF,YAAM,QAAQ,MAAM;AACpB,YAAM,UAA6C,KAAK,UAAU,IAAI,MAAM,KAAK,WAAW,IAAI,CAAC;AACjG,YAAM,eAA6C,IAAI,MAAM,KAAK,WAAW;AAC7E,YAAM,gBAAgB,aAAa,KAAK,aAAa;AAErD,YAAM,gBAAgB,OAAO,EAAE,KAAK,OAAO,OAAO,MAAa;AAC7D,cAAM,mBAAmB,kBAAkB;AAG3C,cAAM,mBAAmB,oBAAoB,KAAK,iBAAiB;AACnE,cAAM,cAA4B;AAAA,UAChC,KAAK,MAAM;AAAA,UACX,QAAQ;AAAA,UACR,MAAM,mBAAmB,MAAM,OAAO;AAAA,UACtC,QAAQ,mBAAmB,MAAM,SAAS;AAAA,UAC1C,aAAa,MAAM;AAAA,QACrB;AACA,qBAAa,KAAK,IAAI;AACtB,cAAM,cAAc,gBAAgB,YAAY,IAAI,IAAI;AAExD,cAAM,YAA6B,KAAK,UAAU,QAAS;AAC3D,YAAI,eAAe;AACjB,gBAAM,SAAS,KAAK,eAAe,OAAO,eAAe;AAAA,YACvD,QAAQ,KAAK;AAAA,YAAI,MAAM;AAAA,YAAY;AAAA,YAAW,KAAK,MAAM;AAAA,YAAK;AAAA,UAChE,CAAC;AAAA,QACH;AACA,YAAI;AACF,cAAI,kBAAkB;AACpB,kBAAO,OAA8C,gBAAgB,WAAW;AAAA,UAClF,OAAO;AACL,kBAAM,UAAU;AAAA,cACd;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,KAAK,eAAgB,EAAE,cAAc,KAAK,aAAa,IAAsC;AAAA,cAC7F;AAAA,YACF;AAAA,UACF;AACA,kBAAQ,GAAG,IAAI,YAAY;AAC3B,cAAI,eAAe;AACjB,kBAAM,SAAS,KAAK,eAAe,OAAO,gBAAgB;AAAA,cACxD,QAAQ,KAAK;AAAA,cAAI,MAAM;AAAA,cAAY;AAAA,cAAW,KAAK,MAAM;AAAA,cAAK,QAAQ,YAAY;AAAA,cAClF,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AAAA,UACH;AAAA,QACF,SAAS,OAAO;AACd,cAAI,eAAe;AACjB,kBAAM,SAAS,KAAK,eAAe,OAAO,eAAe;AAAA,cACvD,QAAQ,KAAK;AAAA,cAAI,MAAM;AAAA,cAAY;AAAA,cAAW,KAAK,MAAM;AAAA,cAAK;AAAA,cAC9D,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AAAA,UACH;AACA,gBAAM;AAAA,QACR;AAAA,MACF;AAMA,YAAM,QAAQ,CAAC,MAAc,KAAK,QAAQ,CAAC,EAAE;AAC7C,YAAM,MAAM,IAAI,UAAU,KAAK,WAAW;AAC1C,YAAM,WAA0B,CAAC;AACjC,YAAM,WAAW,oBAAI,IAAmB;AACxC,eAAS,IAAI,GAAG,IAAI,KAAK,aAAa,KAAK;AACzC,YAAI,MAAM,aAAa,QAAS;AAChC,cAAM,IAAI,QAAQ;AAClB,YAAI,MAAM,aAAa,SAAS;AAAE,cAAI,QAAQ;AAAG;AAAA,QAAO;AACxD,cAAM,QAAQ;AACd,cAAM,QAAQ,YAAY;AACxB,cAAI;AAAE,kBAAM,cAAc,KAAK,QAAQ,KAAK,CAAC;AAAA,UAAG,SACzC,OAAO;AAAE,qBAAS,KAAK,EAAE,KAAK,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC;AAAA,UAAG,UACpE;AAAU,gBAAI,QAAQ;AAAA,UAAG;AAAA,QAC3B,GAAG;AACH,iBAAS,IAAI,IAAI;AACjB,aAAK,KAAK,QAAQ,MAAM,SAAS,OAAO,IAAI,CAAC;AAAA,MAC/C;AAEA,YAAM,QAAQ,IAAI,QAAQ;AAC1B,eAAS,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAIzC,YAAM,kBAAkB,eAAe,OAAO,KAAK,IAAI,UAAU,KAAK,aAAa,OAAO,cAAc,MAAM,WAAW;AAGzH,iBAAW,EAAE,KAAK,OAAO,MAAM,KAAK,iBAAiB;AACnD,YAAI,CAAC,KAAK,QAAS,OAAM;AACzB,cAAM,YAAY,MAAM,KAAK,QAAQ;AAAA,UACnC;AAAA,UACA,KAAK,KAAK,UAAU,SAAa;AAAA,UACjC,OAAO,KAAK,UAAU,QAAQ;AAAA,UAC9B,KAAK,MAAM;AAAA,QACb,CAAC;AACD,YAAI,cAAc,SAAS,MAAM;AAE/B,kBAAQ,GAAG,IAAI;AAAA,QACjB,OAAO;AACL,kBAAQ,GAAG,IAAI;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,SAAS;AAAA,IACjB,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;AC5JO,IAAM,WAAN,cAAuB,KAAK;AAAA,EACxB,OAAO;AAAA,EACP;AAAA,EACU,cAAc;AAAA;AAAA,EAGxB;AAAA;AAAA,EAEA;AAAA,EAEQ;AAAA,EACA;AAAA,EAEjB,YACE,IACA,SACA,QACA,WACA,OACA;AACA,UAAM;AACN,SAAK,KAAK;AACV,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,YAAY;AACjB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AAEF,UAAI,KAAK,aAAa,CAAE,MAAM,KAAK,UAAU,KAAK,EAAI;AACtD,YAAM,WAAyB;AAAA,QAC7B,SAAS;AAAA,QACT,MAAM;AAAA,QACN,iBAAiB,MAAM,aAAa;AAAA,QACpC,QAAQ,MAAM;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,aAAa,MAAM,KAAK,QAAQ,KAAK;AAAA,MACvC;AACA,YAAM,aAAa;AACnB,UAAI,uBAAuB,KAAK,EAAG,YAAW,QAAQ;AAAA,IACxD,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;ACjDO,IAAM,YAAN,cAAwB,KAAK;AAAA,EACzB,OAAO;AAAA,EACP;AAAA,EACU,cAAc;AAAA,EAEhB;AAAA,EAEjB,YACE,IACA,SACA;AACA,UAAM;AACN,SAAK,KAAK;AACV,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAGmB,WAAW,OAA8B;AAC1D,WAAO,CAAC,CAAC,MAAM,cAAc,CAAC,MAAM,gBAAgB,CAAC,CAAC,MAAM;AAAA,EAC9D;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAE5B,UAAM,UAAU,MAAM;AAEtB,UAAM,SAAS,MAAM,KAAK,QAAQ;AAAA,MAChC,OAAO,QAAQ;AAAA,MACf,KAAK,MAAM;AAAA,MACX,YAAY,MAAM;AAAA,MAClB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,UAAM,eAAe;AAAA,EACvB;AACF;;;ACnCO,IAAM,cAAN,cAA0B,KAAK;AAAA,EAC3B,OAAO;AAAA,EACP;AAAA,EACU,cAAc;AAAA,EAEhB;AAAA,EAEjB,YAAY,IAAY,IAAgE;AACtF,UAAM;AACN,SAAK,KAAK;AACV,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA,EAGmB,WAAW,QAA+B;AAC3D,WAAO;AAAA,EACT;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAE5B,UAAM,KAAK,GAAG,EAAE,KAAK,MAAM,IAAyB,CAAC;AAAA,EACvD;AACF;;;AChBO,IAAM,qBAAN,cAAiC,KAAK;AAAA,EAClC,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EAEQ;AAAA,EAEjB,YACE,IACA,UACA,SACA;AACA,UAAM;AACN,SAAK,KAAK;AACV,SAAK,iBAAiB;AACtB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAe,QAAQ,OAAoC;AAIzD,UAAM,UAAU,MAAM;AACtB,QAAI,SAAS;AACX,YAAM,gBAAgB;AACtB,YAAM,CAAC,YAAY,GAAG,IAAI,IAAI,QAAQ;AACtC,YAAMC,WAAU,MAAM,aAAa;AACnC,UAAI;AACF,YAAI,KAAK,WAAW,GAAG;AAErB,gBAAM,SAAS,QAAQ;AAAA,QACzB,OAAO;AACL,gBAAM,gBAAgB,EAAE,WAAW,MAAM,YAAY,QAAQ,WAAW;AAAA,QAC1E;AACA,cAAM,KAAK,eAAe,gBAAgB,OAAO,UAAU;AAC3D,YAAI,MAAM,WAAY,OAAM,aAAa,kBAAkB,MAAM,YAAYA,UAAS,KAAK;AAAA,MAC7F,SAAS,OAAO;AACd,cAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,MAC1E;AACA;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,UAAM,UAAU,MAAM,aAAa;AACnC,QAAI;AAGF,UAAI,MAAM,KAAK,qBAAqB,OAAO,KAAK,OAAO,EAAG;AAC1D,YAAM,KAAK,eAAe,gBAAgB,KAAK;AAG/C,UAAI,MAAM,WAAY,OAAM,aAAa,kBAAkB,MAAM,YAAY,SAAS,KAAK;AAAA,IAC7F,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;AC5DO,IAAM,aAAN,cAAyB,KAAK;AAAA,EAC1B,OAAO;AAAA,EACP,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YACE,IACA,QACA,WACA,eACA,YACA;AACA,UAAM;AACN,SAAK,KAAK;AACV,SAAK,SAAS;AACd,SAAK,YAAY;AACjB,SAAK,gBAAgB;AACrB,SAAK,aAAa;AAClB,SAAK,iBAAiB,aAAc,SAAgD;AAAA,EACtF;AAAA,EAEA,MAAe,QAAQ,OAAoC;AACzD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,QAAI;AAGF,YAAM,MAAM,MAAM;AAClB,eAAS,IAAI,GAAG,KAAK,KAAK,eAAe,KAAK;AAI5C,YAAI,MAAM,aAAa,SAAS;AAC9B,gBAAM,MAAM,YAAY,UAAU,IAAI,MAAM,kBAAkB;AAAA,QAChE;AAEA,YAAI,KAAK,YAAY;AACnB,gBAAO,KAAK,OAA8C,gBAAgB,KAAK;AAAA,QACjF,OAAO;AACL,gBAAM,UAAU,SAAS,OAAO,KAAK,QAAgC,GAAG;AAAA,QAC1E;AAEA,cAAM,OAAO,MAAM,KAAK,UAAU,EAAE,QAAQ,MAAM,QAAQ,KAAK,YAAY,EAAE,CAAC;AAC9E,YAAI,KAAM;AAAA,MACZ;AAEA,YAAM,IAAI,kBAAkB,KAAK,eAAe,KAAK,aAAa;AAAA,IACpE,SAAS,OAAO;AACd,YAAM,eAAe,EAAE,OAAO,QAAQ,KAAK,IAAI,QAAQ,KAAK,YAAY;AAAA,IAC1E;AAAA,EACF;AACF;;;ACzDO,SAAS,uBAAuB,OAA8B;AACnE,SAAO,MAAM,YAAY,kBAAkB,OAAO;AACpD;AAQO,SAAS,6BAA6B,QAAkD;AAC7F,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAW,aAAO;AAAA,IACvB,KAAK;AAAS,aAAO;AAAA,IACrB,KAAK;AAAgB,aAAO;AAAA,EAC9B;AACF;AAeA,eAAsB,eACpB,OACA,MACA,iBACA,eACe;AACf,MAAI,CAAC,KAAK,aAAc;AAMxB,QAAM,aAAa,uBAAuB,KAAK;AAC/C,QAAM,OAA2B;AAAA,IAC/B,SAAS;AAAA,IACT,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,aAAa,gBAAgB,MAAM,MAAM,IAAI,MAAM;AAAA,IAC3D;AAAA,EACF;AACA,MAAI,WAAY,YAAW,IAAI;AAE/B,QAAM,KAAK,aAAa,MAAM,EAAE,QAAQ,MAAM,YAAY,CAAC;AAC7D;AAGA,IAAI,+BAA+B;AAe5B,SAAS,YACd,OACA,QACA,QACA,OACM;AACN,GAAC,MAAM,aAAa,CAAC,GAAG,KAAK,EAAE,QAAQ,QAAQ,MAAM,CAAC;AACxD;AAaO,SAAS,SAId,eACA,OACA,MACA,OACuB;AACvB,QAAM,OAAO,gBAAgB,IAAI;AACjC,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,aAAa,OAAO,MAAM,OAAO,IAAI;AAC9C;AAEA,eAAe,aACb,OACA,MACA,OAEA,MACkB;AAClB,MAAI;AACF,UAAM,KAAK,KAAK;AAChB,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,SAAS,eAAe;AAC1B,YAAM,SAAU,MAA6B;AAC7C,kBAAY,OAAO,MAAM,QAAQ,CAAC;AAElC,cAAQ,MAAM,WAAW,IAAI,2BAA2B,MAAM,MAAM,CAAC;AAAA,IACvE;AACA,WAAO;AAAA,EACT;AACF;AAOO,SAAS,aAAa,eAA2D;AACtF,SAAO,CAAC,CAAC,iBAAiB,CAAC,EAAE,cAAc,eAAe,cAAc,gBAAgB,cAAc;AACxG;AAOO,SAAS,mBAAmB,OAAqB,IAAwB;AAC9E,cAAY,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK;AACnD;AAKO,SAAS,gCACd,QACA,SACM;AACN,MAAI,OAAO,WAAW,eAAe,CAAC,SAAS,WAAW,6BAA8B;AACxF,iCAA+B;AAC/B,UAAQ;AAAA,IACN;AAAA,EACF;AACF;AAQO,SAAS,iBACd,KACA,QACA,MACA,MACA,QACc;AACd,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B,YAAY;AAAA,IACZ,aAAa,MAAM;AAAA,EACrB;AACF;;;AdxJO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC7C,YACkB,YAChB,SACA;AACA,UAAM,OAAO;AAHG;AAIhB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YACkB,YACA,eAChB;AACA,UAAM,qCAAqC,aAAa,GAAG;AAH3C;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,qBAAqB;AAQ3B,IAAM,gBAAgB;AAOtB,IAAM,sBAAsB;AAO5B,SAAS,kBAAkB,UAAwB,OAAe,OAAmC;AAC1G,QAAM,OAAqB,EAAE,GAAG,UAAU,YAAY,CAAC,OAAO,GAAI,SAAS,cAAc,CAAC,CAAE,EAAE;AAC9F,MAAI,uBAAuB,KAAK,EAAG,YAAW,IAAI;AAClD,SAAO;AACT;AAOO,SAAS,gBAAgB,QAA4C;AAC1E,MAAI,OAAO,YAAY,GAAG;AACxB,UAAM,IAAI,MAAM,sDAAuD,OAA+B,OAAO,EAAE;AAAA,EACjH;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM;AAAA,IACN,iBAAiB,OAAO;AAAA,IACxB,QAAQ,OAAO;AAAA,IACf,QAAQ,OAAO;AAAA,IACf,aAAa,OAAO;AAAA,EACtB;AACF;AAgCA,SAAS,qBAAqB,MAAkC;AAC9D,MAAI,KAAK,SAAS,OAAQ,QAAO,KAAK;AACtC,SAAQ,KAAK,YAAY;AAC3B;AAOA,SAAS,mBAAmB,MAA+D;AACzF,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AAAQ,aAAO,KAAK,iBAAiB,CAAC,KAAK,cAAc,IAAI,CAAC;AAAA,IACnE,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAW,aAAO,CAAC;AAAA,EAC1B;AACF;AA8EO,IAAM,iBAAN,MAAM,gBAKX;AAAA,EACS;AAAA,EACU;AAAA,EACA;AAAA;AAAA,EAEX,uBAAuB;AAAA;AAAA;AAAA,EAGvB;AAAA,EACA;AAAA,EACA;AAAA,EAEE,YAAY,OAAgC,IAAa,eAAuC;AACxG,SAAK,QAAQ;AACb,SAAK,KAAK;AACV,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,uBAA6B;AACnC,QAAI,KAAK,qBAAsB;AAC/B,UAAM,OAAO,oBAAI,IAAoB;AACrC,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,YAAM,OAAO,KAAK,MAAM,CAAC;AACzB,UAAI,KAAK,GAAG,SAAS,YAAY,GAAG;AAClC,cAAM,IAAI;AAAA,UACR,sBAAsB,KAAK,EAAE,uDAAuD,CAAC;AAAA,QACvF;AAAA,MACF;AACA,YAAM,MAAM,GAAG,KAAK,IAAI,IAAI,KAAK,EAAE;AACnC,YAAM,QAAQ,KAAK,IAAI,GAAG;AAC1B,UAAI,UAAU,QAAW;AACvB,cAAM,IAAI;AAAA,UACR,wBAAwB,KAAK,IAAI,MAAM,KAAK,EAAE,iBAAiB,KAAK,QAAQ,CAAC;AAAA,QAE/E;AAAA,MACF;AACA,WAAK,IAAI,KAAK,CAAC;AAAA,IACjB;AACA,SAAK,uBAAuB;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAc,4BAAoC;AAChD,QAAI,KAAK,+BAA+B,OAAW,QAAO,KAAK;AAC/D,QAAI,IAAI;AACR,eAAW,KAAK,KAAK,OAAO;AAC1B,UAAI,EAAE,SAAS,WAAW,EAAE,SAAS,UAAW;AAAA,IAClD;AACA,SAAK,6BAA6B;AAClC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,IAAc,gCAAwC;AACpD,QAAI,KAAK,mCAAmC,OAAW,QAAO,KAAK;AACnE,QAAI,IAAI;AACR,eAAW,KAAK,KAAK,OAAO;AAC1B,UAAI,EAAE,SAAS,OAAQ;AAAA,IACzB;AACA,SAAK,iCAAiC;AACtC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,uBAAgD;AAC9C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAc,sBAA8B;AAC1C,QAAI,KAAK,yBAAyB,OAAW,QAAO,KAAK;AAEzD,UAAM,YAAY,CAAC,SAAc,mBAAmB,IAAgB;AACpE,SAAK,uBAAuB;AAAA,MAC1B,KAAK;AAAA,MACL;AAAA,IACF;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUU,mBAAmB,MAAoC;AAC/D,QAAI,CAAC,KAAM;AAEX,QAAI,CAAC,KAAK,aAAc;AACxB,QAAI,KAAK,oBAAoB,UAAa,KAAK,mBAAmB,QAAW;AAC3E,YAAM,IAAI,MAAM,uEAAuE;AAAA,IACzF;AACA,QAAI,KAAK,oBAAoB,WAAc,CAAC,OAAO,UAAU,KAAK,eAAe,KAAK,KAAK,kBAAkB,IAAI;AAC/G,YAAM,IAAI,MAAM,+DAA+D,KAAK,eAAe,EAAE;AAAA,IACvG;AACA,UAAM,SAAS,KAAK;AAIpB,UAAM,UAAU,KAAK,mBAAmB,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,gCAAgC,CAAC,CAAC;AACrG,QAAI,KAAK,mBAAmB,KAAK,oBAAoB,+BAA+B,YAAY,KAAK,UAAU,GAAG;AAChH,YAAM,IAAI;AAAA,QACR,0CAA0C,MAAM;AAAA,MAElD;AAAA,IACF;AACA,QAAI,KAAK,mBAAmB,WAAW,GAAG;AACxC;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBU,SAIR,OACA,MACA,OACuB;AACvB,WAAO,SAAS,KAAK,eAAe,OAAO,MAAM,KAAK;AAAA,EACxD;AAAA,EAEU,eAAwB;AAChC,WAAO,aAAa,KAAK,aAAa;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAgB,4BACd,OACA,OACe;AACf,UAAM,WAAW,MAAM,KAAK,SAAS,OAAO,eAAe,KAAK;AAChE,QAAI,aAAa,OAAW;AAC5B,UAAM,IAAI,MAAM;AAChB,QAAI,OAAO,MAAM,YAAY,MAAM,MAAM;AACvC,UAAI;AACF,QAAC,EAA0B,QAAQ;AACnC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,gBAAY,OAAO,eAAe,MAAM,QAAQ,QAAQ;AAAA,EAC1D;AAAA;AAAA,EAIA,MAAM,SACJ,QACG,MAG+B;AAClC,SAAK,qBAAqB;AAC1B,UAAM,QAAQ,KAAK,CAAC;AACpB,UAAM,OAAO,KAAK,CAAC;AACnB,WAAO,KAAK,YAAY,KAAK,GAAG,MAAM,OAAO,EAAE,QAAQ,OAAO,cAAc,KAAK,EAAE;AAAA,EACrF;AAAA,EAEA,OACE,QACG,MAG4B;AAC/B,SAAK,qBAAqB;AAC1B,UAAM,QAAQ,KAAK,CAAC;AACpB,UAAM,UAAU,KAAK,CAAC;AACtB,UAAM,OAAO,KAAK,CAAC;AACnB,WAAO,KAAK,UAAU,KAAK,GAAG,MAAM,SAAS,OAAO,EAAE,QAAQ,OAAO,cAAc,KAAK,EAAE;AAAA,EAC5F;AAAA;AAAA;AAAA,EAIU,YAAY,OAA8C;AAClE,UAAM,WAAW,MAAM,YAAY,CAAC;AAGpC,QAAI,uBAAuB,KAAK,GAAG;AACjC,iBAAW,QAAQ;AAAA,IACrB;AACA,QAAI,MAAM,YAAY;AACpB,aAAO,EAAE,QAAQ,aAAa,UAAU,MAAM,YAAY,SAAS;AAAA,IACrE;AACA,WAAO,EAAE,QAAQ,YAAY,QAAQ,MAAM,QAAmB,SAAS;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAgB,YACd,KACA,YACA,MACA,MACkC;AAClC,SAAK,mBAAmB,IAAI;AAC5B,UAAM,SAAS,MAAM,KAAK;AAC1B,UAAM,QAAQ,iBAAiB,KAAK,OAAO,QAAQ,YAAY,IAAI;AACnE,QAAI,OAAO,cAAe,OAAM,gBAAgB,OAAO;AACvD,UAAM,KAAK,QAAQ,OAAO,YAAY,MAAM,OAAO,YAAY;AAC/D,WAAO,KAAK,YAAY,KAAK;AAAA,EAC/B;AAAA,EAEU,UACR,KACA,YACA,MACA,SACA,MAC+B;AAC/B,SAAK,mBAAmB,IAAI;AAE5B,QAAI;AACJ,QAAI;AACJ,UAAM,gBAAgB,IAAI,QAAiC,CAAC,KAAK,QAAQ;AACvE,sBAAgB;AAChB,qBAAe;AAAA,IACjB,CAAC;AAED,kBAAc,MAAM,MAAM;AAAA,IAAC,CAAC;AAE5B,UAAM,SAAS,sBAAkC;AAAA,MAC/C,SAAS,OAAO,EAAE,OAAO,MAAM;AAK7B,YAAI;AACF,gBAAM,SAAS,MAAM,KAAK;AAC1B,gBAAM,QAAQ,iBAAiB,KAAK,OAAO,QAAQ,UAAU,MAAM,MAAM;AACzE,cAAI,OAAO,cAAe,OAAM,gBAAgB,OAAO;AACvD,gBAAM,KAAK,QAAQ,OAAO,YAAY,MAAM,OAAO,YAAY;AAC/D,gBAAM,SAAS,KAAK,YAAY,KAAK;AACrC,0CAAgC,QAAQ,OAAO;AAC/C,wBAAc,MAAM;AAAA,QACtB,SAAS,OAAO;AACd,uBAAa,KAAK;AAClB,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,GAAI,SAAS,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,MACvD,GAAI,SAAS,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MAC1D,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,QAAQ,iBAAiB,IAAI,CAAC;AAAA,MAClF,GAAI,SAAS,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;AAAA,IAClE,CAAC;AAED,WAAO,EAAE,QAAQ,QAAQ,cAAc;AAAA,EACzC;AAAA;AAAA,EAIA,MAAgB,QACd,OACA,aAAqB,GACrB,MACA,eAAoC,MACrB;AACf,QAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,YAAM,IAAI,MAAM,qFAAqF;AAAA,IACvG;AAGA,QAAI,SAAS,UAAa,MAAM,eAAe,QAAW;AACxD,YAAM,aAAa;AAAA,IACrB;AAIA,UAAM,cAAc,MAAM,gBAAgB,KAAK,mBAAmB,SAC7D,KAAK,mBAAmB,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,gCAAgC,CAAC,CAAC,IACtF;AAMJ,QAAI,sBAAsB;AAQ1B,UAAM,eAAe,gBAAgB;AASrC,QAAI,gBAAgB;AACpB,UAAM,iBAAiB,CAAC,YAAuC;AAAA,MAC7D,OAAO,OAAO,UAAU,IAAI,MAAM,kBAAkB;AAAA,MACpD,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAEA,aAAS,IAAI,YAAY,IAAI,KAAK,MAAM,QAAQ,KAAK;AAInD,UAAI,MAAM,aAAa,SAAS;AAC9B,YAAI,CAAC,eAAe;AAClB,0BAAgB;AAChB,gBAAM,aAAa;AACnB,cAAI,MAAM,aAAc,oBAAmB,OAAO,MAAM,YAAY;AACpE,gBAAM,eAAe,eAAe,MAAM,WAAW;AAAA,QACvD,WAAW,CAAC,MAAM,cAAc;AAI9B,gBAAM,eAAe,eAAe,MAAM,WAAW;AAAA,QACvD;AAAA,MACF;AAEA,YAAM,OAAO,KAAK,MAAM,CAAC;AAQzB,YAAM,OACJ,KAAK,SAAS,YAAY,QACxB,KAAK,SAAS,UAAW,CAAC,CAAC,MAAM,cAAc,CAAC,MAAM,gBAAgB,CAAC,CAAC,MAAM,mBAC7E,CAAC,CAAC,MAAM,cAAc,CAAC,CAAC,MAAM;AACnC,UAAI,KAAM;AAQV,YAAM,UAAU,qBAAqB,IAAI;AACzC,YAAM,SAAS,KAAK;AACpB,YAAM,SAAS,YAAY,IAAI;AAC/B,YAAM,YAAY,MAAM;AAIxB,YAAM,kBAAkB,CAAC,CAAC,MAAM;AAChC,YAAM,YAAY;AAClB,YAAM,KAAK,SAAS,OAAO,eAAe,EAAE,QAAQ,MAAM,SAAS,KAAK,MAAM,KAAK,OAAO,MAAM,OAAO,CAAC;AACxG,UAAI;AACF,cAAM,KAAK,QAAQ,KAAK;AAAA,MAC1B,SAAS,GAAG;AACV,cAAM,KAAK,4BAA4B,OAAO;AAAA,UAC5C;AAAA,UAAQ,MAAM;AAAA,UAAS,KAAK,MAAM;AAAA,UAAK,OAAO;AAAA,UAC9C,YAAY,YAAY,IAAI,IAAI;AAAA,QAClC,CAAC;AACD,cAAM;AAAA,MACR;AAMA,YAAM,WAAW,MAAM,gBAAgB,MAAM,iBAAiB,YAAY,MAAM,eAAe;AAC/F,UAAI,UAAU;AACZ,cAAM,KAAK,4BAA4B,OAAO;AAAA,UAC5C;AAAA,UAAQ,MAAM;AAAA,UAAS,KAAK,MAAM;AAAA,UAAK,OAAO,SAAS;AAAA,UACvD,YAAY,YAAY,IAAI,IAAI;AAAA,QAClC,CAAC;AAAA,MACH,OAAO;AACL,cAAM,KAAK,SAAS,OAAO,gBAAgB;AAAA,UACzC;AAAA,UAAQ,MAAM;AAAA,UAAS,KAAK,MAAM;AAAA,UAAK,QAAQ,MAAM;AAAA,UACrD,YAAY,YAAY,IAAI,IAAI;AAAA,UAAQ,WAAW,CAAC,mBAAmB,CAAC,CAAC,MAAM;AAAA,QACjF,CAAC;AAAA,MACH;AAQA,UAAI,KAAK,SAAS,UAAU,KAAK,aAAa,YAAY,MAAM,YAAY;AAC1E,cAAM,SAAS,MAAM;AACrB,cAAM,aAAa;AACnB,cAAM,IAAI,MAAM,oDAAoD,KAAK,EAAE,YAAY,OAAO,MAAM,KAAK;AAAA,MAC3G;AAYA,UAAI,KAAK,SAAS,UAAU,CAAC,MAAM,gBAAgB,CAAC,MAAM,cAAc,MAAM,cAAc;AAC1F;AACA,cAAM,mBAAmB,KAAK,iBAC1B,KAAK,eAAe,EAAE,WAAW,GAAG,QAAQ,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC,IACrE,sBAAsB,gBAAgB;AAC1C,YAAI,kBAAkB;AACpB,gBAAM,YAAY,YAAY,IAAI;AAClC,cAAI;AACF,kBAAM;AAAA,cACJ;AAAA,cACA;AAAA,cACA,IAAI;AAAA,cACJ,KAAK;AAAA,YACP;AAAA,UACF,SAAS,GAAG;AACV,kBAAM,eAAe,EAAE,OAAO,GAAG,QAAQ,oBAAoB,QAAQ,eAAe;AACpF,kBAAM,mBAAmB;AAGzB,kBAAM,KAAK,4BAA4B,OAAO;AAAA,cAC5C,QAAQ;AAAA,cAAoB,MAAM;AAAA,cAAQ,KAAK,MAAM;AAAA,cAAK,OAAO;AAAA,cACjE,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAWA,QAAI,iBAAiB,CAAC,MAAM,gBAAgB,CAAC,MAAM,cAAc,MAAM,aAAa,SAAS;AAC3F,YAAM,eAAe,eAAe,MAAM,WAAW;AAAA,IACvD;AAMA,QAAI,MAAM,gBAAgB,CAAC,MAAM,YAAY;AAC3C,YAAM,KAAK,MAAM;AACjB,UAAI,MAAM,kBAAkB;AAM1B,cAAM,cAAc,MAAM,YAAY,CAAC;AACvC,cAAM,kBAAkB,GAAG,WAAW,iBAClC,GAAG,QACH,YAAY,KAAK,OAAK,EAAE,WAAW,cAAc,GAAG;AACxD,cAAM,aAAa,YAChB,OAAO,OAAK,EAAE,UAAU,eAAe,EACvC,IAAI,OAAK,EAAE,KAAK;AACnB,YAAI,GAAG,WAAW,kBAAkB,GAAG,UAAU,iBAAiB;AAChE,qBAAW,KAAK,GAAG,KAAK;AAAA,QAC1B;AACA,YAAI,WAAW,SAAS,GAAG;AACzB,kBAAQ;AAAA,YACN,WAAW,WAAW,MAAM;AAAA,YAC5B;AAAA,UACF;AAAA,QACF;AACA,cAAM,mBAAmB,GAAG;AAAA,MAC9B;AACA,YAAM,GAAG;AAAA,IACX,WAAW,MAAM,gBAAgB,MAAM,YAAY;AAEjD,YAAM,KAAK,MAAM;AACjB,yBAAmB,OAAO,EAAE;AAE5B,UAAI;AACF,cAAM,KAAK,eAAe,cAAc;AAAA,UACtC,QAAQ,GAAG;AAAA,UACX,MAAM,6BAA6B,GAAG,MAAM;AAAA,UAC5C,KAAK,MAAM;AAAA,UACX,OAAO,GAAG;AAAA,UACV,YAAY;AAAA,QACd,CAAC;AAAA,MACH,SAAS,UAAU;AACjB,oBAAY,OAAO,eAAe,GAAG,QAAQ,QAAQ;AAAA,MACvD;AACA,YAAM,eAAe;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,gBAAgB,OAAqB,aAAqB,GAAkB;AAChF,UAAM,kBAAkB,MAAM;AAC9B,UAAM,aAAa;AACnB,QAAI;AACF,YAAM,KAAK,QAAQ,OAAO,UAAU;AAAA,IACtC,UAAE;AACA,YAAM,aAAa;AAAA,IACrB;AAAA,EAQF;AAAA;AAAA,EAIA,UACE,QACA,UAC+C;AAE/C,QAAI,SAAS,YAAY,KAAK,SAAS,SAAS,cAAc;AAC5D,YAAM,IAAI,MAAM,8GAA8G;AAAA,IAChI;AACA,UAAM,WAAW;AACjB,QAAI,SAAS,WAAW,QAAQ;AAC9B,YAAM,IAAI;AAAA,QACR,gDAA2C,MAAM,uBAAuB,SAAS,MAAM;AAAA,MACzF;AAAA,IACF;AACA,SAAK,qBAAqB;AAE1B,UAAM,aAAc,SAA0B;AAC9C,QAAI,cAAc,WAAW,SAAS,GAAG;AAIvC,UAAI,QAAiC,KAAK;AAC1C,iBAAW,OAAO,YAAY;AAC5B,cAAM,OAAO,MAAM,GAAG;AACtB,cAAM,QAAQ,MAAM,SAAS,SAAS,KAAK,iBAAiB;AAC5D,YAAI,CAAC,OAAO;AACV,gBAAM,IAAI,MAAM,2BAA2B,MAAM,+BAA0B,GAAG,4BAA4B;AAAA,QAC5G;AACA,gBAAQ,MAAM,qBAAqB;AAAA,MACrC;AACA,YAAM,YAAY,MAAM,SAAS,eAAe;AAChD,UAAI,WAAW,SAAS,UAAU,UAAU,OAAO,QAAQ;AACzD,cAAM,IAAI,MAAM,2BAA2B,MAAM,mCAAmC;AAAA,MACtF;AAGA,YAAM,YAAY,CAAC,GAAG,WAAW,MAAM,CAAC,GAAG,SAAS,kBAAkB,CAAC;AACvE,aAAO,IAAI,gBAA8C,KAAK,OAAO,WAAW,CAAC,GAAG;AAAA,QAClF,MAAM;AAAA,QACN,QAAQ,UAAU;AAAA,QAClB,SAAS,UAAU;AAAA,QACnB,aAAa,SAAS;AAAA,QACtB,UAAU;AAAA,QACV,eAAe,KAAK;AAAA,QACpB,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,UAAM,YAAY,KAAK,cAAc,QAAQ;AAC7C,UAAM,WAAW,KAAK,MAAM,SAAS;AACrC,WAAO,IAAI,gBAA8C,KAAK,OAAO,YAAY,GAAG;AAAA,MAClF,MAAM;AAAA,MACN,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS;AAAA,MAClB,aAAa,SAAS;AAAA,MACtB,UAAU;AAAA,MACV,eAAe,KAAK;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,WACE,UACA,SAC8C;AAE9C,UAAM,SAAU,SAAS,YAAY,KAAK,SAAS,SAAS,UACtD,SAAS,YAAY,KAAM,SAAkC,WAAW;AAC9E,QAAI,QAAQ;AACV,YAAM,IAAI,MAAM,yGAAyG;AAAA,IAC3H;AACA,QAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,YAAM,IAAI,MAAM,sEAAsE;AAAA,IACxF;AACA,UAAM,OAAO;AACb,UAAM,MAAM,KAAK;AACjB,QAAI,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,QAAQ;AAChE,YAAM,IAAI,MAAM,gCAAgC,GAAG,uBAAuB,KAAK,MAAM,MAAM,iBAAiB;AAAA,IAC9G;AACA,QAAI,CAAC,SAAS,gBAAgB;AAC5B,UAAI,CAAC,KAAK,eAAe;AACvB,cAAM,IAAI,MAAM,wEAAwE;AAAA,MAC1F;AACA,WAAK,qBAAqB;AAC1B,UAAI,KAAK,wBAAwB,KAAK,eAAe;AACnD,cAAM,IAAI,MAAM,uGAAuG;AAAA,MACzH;AAAA,IACF,OAAO;AACL,WAAK,qBAAqB;AAAA,IAC5B;AACA,WAAO,IAAI,0BAA6C,KAAK,OAAO,KAAK;AAAA,MACvE,MAAM;AAAA,MACN,aAAa,KAAK;AAAA,MAClB,UAAU;AAAA,MACV,eAAe,KAAK;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QACE,IACA,IACmD;AACnD,UAAM,OAAO,IAAI,YAAY,IAAI,EAAgE;AAEjG,WAAO,IAAI,gBAAkD,CAAC,GAAG,KAAK,OAAO,IAAI,GAAU,KAAK,IAAI,KAAK,aAAa;AAAA,EACxH;AAAA,EAEQ,cAAc,UAAuD;AAG3E,QAAI,SAAS,YAAY,KAAK,SAAS,YAAY,GAAG;AACpD,YAAM,IAAI,MAAM,iCAAkC,SAAiC,OAAO,EAAE;AAAA,IAC9F;AAIA,UAAM,OAAO,SAAS;AACtB,QAAI,OAAO,UAAU,IAAI,KAAK,QAAQ,KAAK,OAAO,KAAK,MAAM,QAAQ;AACnE,YAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,UAAI,KAAK,SAAS,UAAU,KAAK,OAAO,SAAS,QAAQ;AACvD,eAAO;AAAA,MACT;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,YAAM,OAAO,KAAK,MAAM,CAAC;AACzB,UAAI,KAAK,SAAS,UAAU,KAAK,OAAO,SAAS,QAAQ;AACvD,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,IAAI;AAAA,MACR,SAAS,SAAS,MAAM;AAAA,IAC1B;AAAA,EACF;AACF;AAoBO,IAAM,kBAAN,cAIG,eAA6C;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGjB,YACE,OACA,YACA,QACA;AACA,UAAM,OAAO,QAAW,OAAO,aAAa;AAC5C,SAAK,aAAa;AAClB,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO;AACtB,SAAK,cAAc,OAAO;AAC1B,SAAK,kBAAkB,OAAO;AAAA,EAChC;AAAA,EAEQ,iBAAiB,UAAgC;AACvD,QAAI,KAAK,QAAQ;AACf,aAAO,KAAK,OAAO,MAAM,QAAQ;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,iBAAiB,aAA4C;AACzE,QAAI;AACF,YAAM,WAAW,KAAK,iBAAiB,WAAW;AAClD,YAAM,SAAS,KAAK,UAChB,MAAM,KAAK,QAAQ,EAAE,aAAa,KAAK,aAAa,SAAS,CAAC,IAC9D;AACJ,UAAI,KAAK,iBAAiB;AAIxB,eAAO;AAAA,UACL,QAAQ,KAAK;AAAA,UACb,cAAc;AAAA,UACd,eAAe,EAAE,WAAW,KAAK,iBAAiB,YAAY,OAAO;AAAA,QACvE;AAAA,MACF;AACA,aAAO,EAAE,QAAQ,QAAQ,cAAc,KAAK;AAAA,IAC9C,SAAS,OAAO;AACd,aAAO,EAAE,QAAQ,KAAK,aAAa,cAAc,EAAE,OAAO,QAAQ,qBAAqB,QAAQ,OAAO,EAAE;AAAA,IAC1G;AAAA,EACF;AAAA,EAEA,MAAe,SACb,QACG,MAG+B;AAClC,UAAM,cAAc,KAAK,CAAC;AAC1B,UAAM,OAAO,KAAK,CAAC;AACnB,WAAO,KAAK,YAAY,KAAK,KAAK,YAAY,MAAM,MAAM,KAAK,iBAAiB,WAAW,CAAC;AAAA,EAC9F;AAAA,EAES,OACP,QACG,MAG4B;AAC/B,UAAM,cAAc,KAAK,CAAC;AAC1B,UAAM,UAAU,KAAK,CAAC;AACtB,UAAM,OAAO,KAAK,CAAC;AACnB,WAAO,KAAK,UAAU,KAAK,KAAK,YAAY,MAAM,SAAS,MAAM,KAAK,iBAAiB,WAAW,CAAC;AAAA,EACrG;AACF;AAUO,IAAM,4BAAN,cAGG,eAAwC;AAAA,EAC/B;AAAA,EACA;AAAA;AAAA,EAGjB,YACE,OACA,YACA,QACA;AACA,UAAM,OAAO,QAAW,OAAO,aAAa;AAC5C,SAAK,aAAa;AAClB,SAAK,cAAc,OAAO;AAAA,EAC5B;AAAA;AAAA;AAAA,EAIA,MAAe,SACb,QACG,MAC+B;AAClC,UAAM,OAAO,KAAK,CAAC;AACnB,WAAO,KAAK,YAAY,KAAK,KAAK,YAAY,MAAM,OAAO,EAAE,QAAQ,KAAK,aAAa,cAAc,KAAK,EAAE;AAAA,EAC9G;AAAA,EAES,OACP,QACG,MAC4B;AAC/B,UAAM,UAAU,KAAK,CAAC;AACtB,UAAM,OAAO,KAAK,CAAC;AACnB,WAAO,KAAK,UAAU,KAAK,KAAK,YAAY,MAAM,SAAS,OAAO,EAAE,QAAQ,KAAK,aAAa,cAAc,KAAK,EAAE;AAAA,EACrH;AACF;AAIO,IAAM,WAAN,MAAM,kBAKH,eAAkD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1D,OAAgB,OAAsB,uBAAO,qBAAqB;AAAA,EAE1D,YAAY,QAAiC,CAAC,GAAG,IAAa,eAAuC;AAC3G,UAAM,OAAO,IAAI,aAAa;AAAA,EAChC;AAAA,EAEA,OAAO,OACL,SACoC;AAIpC,WAAO,IAAI,UAAmC,CAAC,GAAG,SAAS,IAAI,SAAS,aAAkD;AAAA,EAC5H;AAAA,EAaA,OAAO,KACL,OACA,SAEiC;AAEjC,WAAO,IAAI,UAAgC,CAAC,CAAC,EAAE,KAAK,OAAO,OAAc;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKQ,WACN,MACuC;AAEvC,WAAO,IAAI,UAAsC,CAAC,GAAG,KAAK,OAAO,IAAI,GAAU,KAAK,IAAI,KAAK,aAAa;AAAA,EAC5G;AAAA;AAAA,EA+CA,KACE,QACA,aACA,eAEyC;AAEzC,QAAI,kBAAkB,gBAAgB;AACpC,YAAM,WAAW;AACjB,YAAMC,WAAU;AAChB,YAAMC,QAAO,IAAI;AAAA,QACfD,UAAS,MAAM,SAAS,MAAM;AAAA;AAAA,QAE9B;AAAA,QACAA;AAAA,MACF;AACA,aAAO,KAAK,WAAwBC,KAAI;AAAA,IAC1C;AAGA,QAAI,OAAO,WAAW,UAAU;AAC9B,UAAI,OAAO,gBAAgB,YAAY;AACrC,cAAM,IAAI,MAAM,kBAAkB,MAAM,wCAAwC;AAAA,MAClF;AACA,YAAM,KAAK;AACX,YAAMA,QAAO,IAAI;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,KAAK,WAAwBA,KAAI;AAAA,IAC1C;AAGA,UAAM,QAAQ;AACd,UAAM,UAAU;AAChB,UAAM,OAAO,IAAI;AAAA,MACf,SAAS,MAAM,MAAM;AAAA;AAAA,MAErB;AAAA;AAAA,MAEA;AAAA,IACF;AACA,WAAO,KAAK,WAAwB,IAAI;AAAA,EAC1C;AAAA;AAAA,EAIA,KACE,IACA,SAMuE;AACvE,QAAI,KAAK,MAAM,KAAK,OAAK,EAAE,SAAS,UAAU,EAAE,OAAO,EAAE,GAAG;AAC1D,YAAM,IAAI,MAAM,gCAAgC,EAAE,6CAA6C;AAAA,IACjG;AACA,UAAM,OAAO,IAAI;AAAA,MACf;AAAA,MACA,OAAO,UAAU;AACf,YAAI,SAAS,SAAS;AACpB,iBAAO,QAAQ,QAAQ;AAAA,YACrB,KAAK,MAAM;AAAA,YACX,OAAO,MAAM;AAAA,UACf,CAAC;AAAA,QACH;AACA,eAAO,MAAM;AAAA,MACf;AAAA,MACA,SAAS;AAAA,MACT,SAAS,YACL,OAAO,UAAU,QAAQ,UAAW;AAAA,QAClC,KAAK,MAAM;AAAA,QACX,OAAO,MAAM;AAAA,MACf,CAAC,IACD;AAAA,MACJ,SAAS,QACL,CAAC,WAAW,QAAQ,MAAO,MAAuD,IAClF;AAAA,IACN;AACA,WAAO,KAAK,WAAsD,IAAI;AAAA,EACxE;AAAA;AAAA,EAkBA,OACE,eACA,SACiD;AACjD,QAAI,MAAM,QAAQ,aAAa,GAAG;AAChC,aAAO,KAAK,gBAAgB,eAAe,SAAS,EAAE;AAAA,IACxD;AACA,WAAO,KAAK,aAAa,eAAe,SAAS,EAAE;AAAA,EACrD;AAAA,EAEQ,gBACN,OACA,YACiD;AAEjD,UAAM,OAAO,IAAI,oBAAoB,cAAc,oBAAoB,KAAoC;AAC3G,WAAO,KAAK,WAAwB,IAAI;AAAA,EAC1C;AAAA,EAEQ,aACN,QACA,YACiD;AAEjD,UAAM,OAAO,IAAI,iBAAiB,cAAc,iBAAiB,MAA0C;AAC3G,WAAO,KAAK,WAAwB,IAAI;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,QACE,QACA,SA0BmD;AAEnD,UAAM,OAAO,IAAI,YAAY,QAAe,SAAgB,KAAK,aAAa;AAC9E,WAAO,KAAK,WAA0B,IAAI;AAAA,EAC5C;AAAA;AAAA,EA4CA,SACE,UACA,SAEyC;AAEzC,UAAM,OAAO,IAAI,aAAa,UAAiB,SAAgB,KAAK,aAAa;AAEjF,WAAO,KAAK,WAAgB,IAAI;AAAA,EAClC;AAAA;AAAA,EAIA,OACE,QACA,SAC6C;AAC7C,QAAI,QAAQ,kBAAkB,WAAc,CAAC,OAAO,UAAU,QAAQ,aAAa,KAAK,QAAQ,gBAAgB,IAAI;AAClH,YAAM,IAAI,MAAM,yDAAyD,QAAQ,aAAa,EAAE;AAAA,IAClG;AAIA,QAAK,QAAQ,UAAU,YAAgB,QAAQ,UAAU,SAAY;AACnE,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AACA,UAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,UAAM,aAAa,kBAAkB;AACrC,UAAM,YAAY,aACb,OAAO,MAAM,WACd,UAAW,OAA6C,EAAE;AAC9D,UAAM,KAAK,QAAQ,MAAM;AACzB,UAAM,YAA8C,QAAQ,UACtD,OAAO,MAAM,CAAE,MAAM,QAAQ,MAAO,CAAC;AAE3C,UAAM,OAAO,IAAI;AAAA,MACf;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,KAAK,WAAoB,IAAI;AAAA,EACtC;AAAA;AAAA,EAIA,MACE,IACA,IAC6C;AAG7C,QAAI,CAAC,KAAK,MAAM,KAAK,OAAK,EAAE,SAAS,UAAU,EAAE,SAAS,MAAM,GAAG;AACjE,YAAM,IAAI,MAAM,oBAAoB,EAAE,kDAAkD;AAAA,IAC1F;AACA,UAAM,OAAO,IAAI;AAAA,MACf;AAAA,MACA;AAAA,IACF;AACA,WAAO,KAAK,WAAoB,IAAI;AAAA,EACtC;AAAA;AAAA;AAIF;;;Ae/+CO,IAAM,OAAO,SAAiB;","names":["tool","tool","result","myIndex","options","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"]}
|