pipeai 0.2.0 → 0.3.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 +28 -4
- package/dist/index.cjs +84 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -12
- package/dist/index.d.ts +40 -12
- package/dist/index.js +84 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -238,7 +238,7 @@ This is useful when the agent is defined at module scope but the context isn't a
|
|
|
238
238
|
|
|
239
239
|
## defineTool — Context-Aware Tools
|
|
240
240
|
|
|
241
|
-
`defineTool` wraps a tool definition so the agent's runtime context is injected into every `execute` call. The `input` field maps to AI SDK's `
|
|
241
|
+
`defineTool` wraps a tool definition so the agent's runtime context is injected into every `execute` call. The `input` field maps to AI SDK's `inputSchema`. When running inside a streaming workflow, the `writer` is automatically available in the third parameter for streaming metadata or progress updates to the client:
|
|
242
242
|
|
|
243
243
|
```ts
|
|
244
244
|
import { defineTool } from "pipeai";
|
|
@@ -484,13 +484,15 @@ const pipeline = Workflow.create<Ctx>()
|
|
|
484
484
|
.step("combine", ({ input }) => input.join("\n\n"));
|
|
485
485
|
```
|
|
486
486
|
|
|
487
|
-
Concurrent processing with
|
|
487
|
+
Concurrent processing with bounded parallelism:
|
|
488
488
|
|
|
489
489
|
```ts
|
|
490
|
-
//
|
|
490
|
+
// Up to 3 items run simultaneously; the next launches as soon as one finishes.
|
|
491
491
|
.foreach(summarizer, { concurrency: 3 })
|
|
492
492
|
```
|
|
493
493
|
|
|
494
|
+
`concurrency` is the **maximum number of items in flight at any moment** — backed by a semaphore. There's no lockstep batching: a slow item never blocks a finished slot from picking up the next pending one.
|
|
495
|
+
|
|
494
496
|
Works with nested workflows too:
|
|
495
497
|
|
|
496
498
|
```ts
|
|
@@ -503,6 +505,28 @@ const pipeline = Workflow.create<Ctx>()
|
|
|
503
505
|
.foreach(processItem, { concurrency: 5 });
|
|
504
506
|
```
|
|
505
507
|
|
|
508
|
+
#### Per-item error recovery via `onError`
|
|
509
|
+
|
|
510
|
+
By default a single item's failure aborts the whole `foreach`. Pass an `onError` handler to recover individual items — return a substitute value, return `Workflow.SKIP` to drop the failed index from the output array, or rethrow to abort the step (the throw is catchable by a downstream `.catch()`):
|
|
511
|
+
|
|
512
|
+
```ts
|
|
513
|
+
import { Workflow } from "pipeai";
|
|
514
|
+
|
|
515
|
+
const pipeline = Workflow.create<Ctx>()
|
|
516
|
+
.step("fetch", async ({ ctx }) => ctx.db.urls.getAll())
|
|
517
|
+
.foreach(scraper, {
|
|
518
|
+
concurrency: 5,
|
|
519
|
+
onError: ({ error, item, index }) => {
|
|
520
|
+
// Substitute a placeholder
|
|
521
|
+
if (isTransient(error)) return { url: item, body: "" };
|
|
522
|
+
// Or drop the item entirely (output array is shortened)
|
|
523
|
+
return Workflow.SKIP;
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
`onError` is invoked sequentially in **index order** after all items settle, so its observable order is deterministic regardless of completion timing. In-flight siblings are never cancelled by another item's failure.
|
|
529
|
+
|
|
506
530
|
**Type safety:** `foreach()` uses `ElementOf<TOutput>` to extract the array element type. If the previous step doesn't produce an array, the call is rejected at compile time.
|
|
507
531
|
|
|
508
532
|
### Conditional loops via `repeat()`
|
|
@@ -594,7 +618,7 @@ const { stream, output } = pipeline.stream(ctx, initialInput, {
|
|
|
594
618
|
| `.step(id, fn)` | Transform the output. `fn` receives `{ ctx, input }` and returns the new output. |
|
|
595
619
|
| `.branch([...cases])` | Predicate routing. First `when` match wins; case without `when` is default. |
|
|
596
620
|
| `.branch({ select, agents })` | Key routing. `select` returns a key, runs the matching agent. |
|
|
597
|
-
| `.foreach(target, opts?)` | Map each array element through an agent or workflow. `opts.concurrency`
|
|
621
|
+
| `.foreach(target, opts?)` | Map each array element through an agent or workflow. `opts.concurrency` is the max items in flight (default: 1). `opts.onError` recovers per-item failures; return `Workflow.SKIP` to drop an index. |
|
|
598
622
|
| `.repeat(target, opts)` | Loop an agent or workflow. Use `{ until }` or `{ while }` (mutually exclusive). `maxIterations` defaults to 10. |
|
|
599
623
|
| `.gate(id, opts?)` | Human-in-the-loop suspension point. Throws `WorkflowSuspended` with a serializable snapshot. Resume via `loadState(gateId, snapshot)`. |
|
|
600
624
|
| `.catch(id, fn)` | Handle errors. `fn` receives `{ error, ctx, lastOutput, stepId }` and returns a recovery value. |
|
package/dist/index.cjs
CHANGED
|
@@ -50,6 +50,28 @@ function resolveValue(value, ctx, input) {
|
|
|
50
50
|
}
|
|
51
51
|
return value;
|
|
52
52
|
}
|
|
53
|
+
var Semaphore = class {
|
|
54
|
+
available;
|
|
55
|
+
waiters = [];
|
|
56
|
+
constructor(permits) {
|
|
57
|
+
if (!Number.isInteger(permits) || permits < 1) {
|
|
58
|
+
throw new Error(`Semaphore: permits must be a positive integer, got ${permits}`);
|
|
59
|
+
}
|
|
60
|
+
this.available = permits;
|
|
61
|
+
}
|
|
62
|
+
async acquire() {
|
|
63
|
+
if (this.available > 0) {
|
|
64
|
+
this.available--;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
await new Promise((resolve) => this.waiters.push(resolve));
|
|
68
|
+
}
|
|
69
|
+
release() {
|
|
70
|
+
const next = this.waiters.shift();
|
|
71
|
+
if (next) next();
|
|
72
|
+
else this.available++;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
53
75
|
async function extractOutput(result, hasStructuredOutput) {
|
|
54
76
|
if (hasStructuredOutput) {
|
|
55
77
|
const output = await result.output;
|
|
@@ -70,9 +92,8 @@ var ToolProvider = class {
|
|
|
70
92
|
const { execute, input: inputSchema, ...toolDef } = this.config;
|
|
71
93
|
return (0, import_ai.tool)({
|
|
72
94
|
...toolDef,
|
|
73
|
-
|
|
95
|
+
inputSchema,
|
|
74
96
|
execute: (input, options) => execute(input, context, { ...options, writer: getActiveWriter() })
|
|
75
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
97
|
});
|
|
77
98
|
}
|
|
78
99
|
};
|
|
@@ -179,7 +200,7 @@ var Agent = class {
|
|
|
179
200
|
}
|
|
180
201
|
return (0, import_ai2.tool)({
|
|
181
202
|
description: this.description,
|
|
182
|
-
|
|
203
|
+
inputSchema: this.config.input,
|
|
183
204
|
execute: async (toolInput) => {
|
|
184
205
|
const writer = getActiveWriter();
|
|
185
206
|
if (writer) {
|
|
@@ -192,7 +213,8 @@ var Agent = class {
|
|
|
192
213
|
if (options?.mapOutput) return options.mapOutput(result);
|
|
193
214
|
return extractOutput(result, this.hasOutput);
|
|
194
215
|
}
|
|
195
|
-
//
|
|
216
|
+
// TS cannot simplify the SDK's `NeverOptional<TOutput, ...>` conditional in a
|
|
217
|
+
// generic context, so we cast through `unknown` instead of `any`.
|
|
196
218
|
});
|
|
197
219
|
}
|
|
198
220
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -546,6 +568,12 @@ var ResumedWorkflow = class extends SealedWorkflow {
|
|
|
546
568
|
}
|
|
547
569
|
};
|
|
548
570
|
var Workflow = class _Workflow extends SealedWorkflow {
|
|
571
|
+
/**
|
|
572
|
+
* Sentinel value for `foreach`'s `onError` handler. Returning `Workflow.SKIP`
|
|
573
|
+
* from `onError` omits the failed item's index from the output array,
|
|
574
|
+
* shortening it relative to the input array.
|
|
575
|
+
*/
|
|
576
|
+
static SKIP = /* @__PURE__ */ Symbol("pipeai.foreach.skip");
|
|
549
577
|
constructor(steps = [], id) {
|
|
550
578
|
super(steps, id);
|
|
551
579
|
}
|
|
@@ -672,8 +700,24 @@ var Workflow = class _Workflow extends SealedWorkflow {
|
|
|
672
700
|
return new _Workflow([...this.steps, node], this.id);
|
|
673
701
|
}
|
|
674
702
|
// ── foreach: array iteration ─────────────────────────────────
|
|
703
|
+
/**
|
|
704
|
+
* Map each item of an array through an agent or sub-workflow.
|
|
705
|
+
*
|
|
706
|
+
* @param target Agent or `SealedWorkflow` invoked once per item.
|
|
707
|
+
* @param options.concurrency Max items in flight at any moment (default 1).
|
|
708
|
+
* Backed by a semaphore: as soon as one item completes, the next launches —
|
|
709
|
+
* no lockstep batching.
|
|
710
|
+
* @param options.onError Per-iteration error handler. When provided, a single
|
|
711
|
+
* item's failure no longer aborts the foreach. Return a `TNextOutput` value
|
|
712
|
+
* to substitute for the failed item, return `Workflow.SKIP` to omit the
|
|
713
|
+
* index (shortening the output array), or throw / return a rejected promise
|
|
714
|
+
* to abort the foreach step (the thrown error is caught by any downstream
|
|
715
|
+
* `.catch()`). When omitted, the existing fail-fast behavior is preserved.
|
|
716
|
+
* `onError` is invoked sequentially in index order after all items settle.
|
|
717
|
+
*/
|
|
675
718
|
foreach(target, options) {
|
|
676
719
|
const concurrency = options?.concurrency ?? 1;
|
|
720
|
+
const onError = options?.onError;
|
|
677
721
|
const isWorkflow = target instanceof SealedWorkflow;
|
|
678
722
|
const id = isWorkflow ? target.id ?? "foreach" : `foreach:${target.id}`;
|
|
679
723
|
const node = {
|
|
@@ -686,6 +730,7 @@ var Workflow = class _Workflow extends SealedWorkflow {
|
|
|
686
730
|
}
|
|
687
731
|
const ctx = state.ctx;
|
|
688
732
|
const results = new Array(items.length);
|
|
733
|
+
const skipped = /* @__PURE__ */ new Set();
|
|
689
734
|
const executeItem = async (item, index) => {
|
|
690
735
|
const itemState = { ctx: state.ctx, output: item, mode: "generate" };
|
|
691
736
|
if (isWorkflow) {
|
|
@@ -695,17 +740,47 @@ var Workflow = class _Workflow extends SealedWorkflow {
|
|
|
695
740
|
}
|
|
696
741
|
results[index] = itemState.output;
|
|
697
742
|
};
|
|
743
|
+
const handleRejection = async (error, item, index) => {
|
|
744
|
+
if (!onError) throw error;
|
|
745
|
+
const recovered = await onError({
|
|
746
|
+
error,
|
|
747
|
+
item,
|
|
748
|
+
index,
|
|
749
|
+
ctx: state.ctx
|
|
750
|
+
});
|
|
751
|
+
if (recovered === _Workflow.SKIP) {
|
|
752
|
+
skipped.add(index);
|
|
753
|
+
} else {
|
|
754
|
+
results[index] = recovered;
|
|
755
|
+
}
|
|
756
|
+
};
|
|
698
757
|
if (concurrency <= 1) {
|
|
699
758
|
for (let i = 0; i < items.length; i++) {
|
|
700
|
-
|
|
759
|
+
try {
|
|
760
|
+
await executeItem(items[i], i);
|
|
761
|
+
} catch (error) {
|
|
762
|
+
await handleRejection(error, items[i], i);
|
|
763
|
+
}
|
|
701
764
|
}
|
|
702
765
|
} else {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
766
|
+
const sem = new Semaphore(concurrency);
|
|
767
|
+
const failures = [];
|
|
768
|
+
await Promise.all(items.map(async (item, i) => {
|
|
769
|
+
await sem.acquire();
|
|
770
|
+
try {
|
|
771
|
+
await executeItem(item, i);
|
|
772
|
+
} catch (error) {
|
|
773
|
+
failures.push({ index: i, error });
|
|
774
|
+
} finally {
|
|
775
|
+
sem.release();
|
|
776
|
+
}
|
|
777
|
+
}));
|
|
778
|
+
failures.sort((a, b) => a.index - b.index);
|
|
779
|
+
for (const { index, error } of failures) {
|
|
780
|
+
await handleRejection(error, items[index], index);
|
|
706
781
|
}
|
|
707
782
|
}
|
|
708
|
-
state.output = results;
|
|
783
|
+
state.output = skipped.size === 0 ? results : results.filter((_, i) => !skipped.has(i));
|
|
709
784
|
}
|
|
710
785
|
};
|
|
711
786
|
return new _Workflow([...this.steps, node], this.id);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/tool-provider.ts","../src/utils.ts","../src/workflow.ts"],"sourcesContent":["export { Agent } from \"./agent\";\nexport type {\n AgentConfig,\n GenerateTextResult,\n StreamTextResult,\n} from \"./agent\";\n\nexport { Workflow, WorkflowBranchError, WorkflowLoopError, WorkflowSuspended } from \"./workflow\";\nexport type { SealedWorkflow, ResumedWorkflow } from \"./workflow\";\nexport type {\n AgentStepHooks,\n StepOptions,\n BranchCase,\n BranchSelect,\n RepeatOptions,\n WorkflowResult,\n WorkflowStreamResult,\n WorkflowStreamOptions,\n WorkflowSnapshot,\n} from \"./workflow\";\n\nexport { defineTool } from \"./tool-provider\";\nexport type { ToolProviderConfig, ToolExecuteOptions, IToolProvider } from \"./tool-provider\";\n\nexport type { MaybePromise, Resolvable } from \"./utils\";\n","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\ntype 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// ── 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 // ── 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 stopWhen?: Resolvable<TContext, TInput, 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 private readonly config: AgentConfig<TContext, TInput, TOutput>;\n private readonly _hasDynamicConfig: boolean;\n private readonly _resolvedStaticTools: Record<string, Tool> | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _passthrough: Record<string, any>;\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.config = config;\n this._hasDynamicConfig = [\n config.model, config.system, config.prompt,\n config.messages, config.tools, config.activeTools,\n config.toolChoice, config.stopWhen,\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,\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(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<GenerateTextResult> {\n const input = args[0] as TInput;\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return await generateText(options as any);\n } catch (error: unknown) {\n if (this.config.onError) {\n await this.config.onError({ error, ctx, input, writer: getActiveWriter() });\n }\n throw error;\n }\n }\n\n async stream(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<StreamTextResult> {\n const input = args[0] as TInput;\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return streamText({\n ...options,\n onError: this.config.onError\n ? ({ error }: { error: unknown }) => this.config.onError!({ error, ctx, input, writer: getActiveWriter() })\n : undefined,\n } as any);\n }\n\n asTool(ctx: TContext, options?: {\n mapOutput?: (result: GenerateTextResult) => MaybePromise<TOutput>;\n }): Tool {\n return this.createToolInstance(ctx, options);\n }\n\n asToolProvider(options?: {\n mapOutput?: (result: GenerateTextResult) => MaybePromise<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?: (result: GenerateTextResult) => MaybePromise<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({\n description: this.description,\n parameters: this.config.input,\n execute: async (toolInput: TInput) => {\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.stream as (ctx: TContext, input: TInput) => Promise<StreamTextResult>)(ctx, toolInput);\n writer.merge(result.toUIMessageStream());\n if (options?.mapOutput) return options.mapOutput(result as unknown as GenerateTextResult);\n return extractOutput(result, this.hasOutput);\n }\n const result = await (this.generate as (ctx: TContext, input: TInput) => Promise<GenerateTextResult>)(ctx, toolInput);\n if (options?.mapOutput) return options.mapOutput(result);\n return extractOutput(result, this.hasOutput);\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private buildCallOptions(resolved: ResolvedAgentConfig, ctx: TContext, input: TInput): Record<string, any> {\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\n ? { messages: resolved.messages }\n : { prompt: resolved.prompt ?? \"\" }),\n ...(resolved.system ? { system: resolved.system } : {}),\n ...(this.config.output ? { output: this.config.output } : {}),\n onStepFinish: this._onStepFinish\n ? (event: OnStepFinishEvent) => this._onStepFinish!({ result: event, ctx, input, writer: getActiveWriter() })\n : undefined,\n onFinish: this._onFinish\n ? (event: OnFinishEvent) => this._onFinish!({ result: event, ctx, input, writer: getActiveWriter() })\n : undefined,\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, stopWhen] = 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 resolveValue(this.config.stopWhen, ctx, input),\n ]);\n const tools = this.resolveTools(rawTools ?? {}, ctx);\n return { model, prompt, system, messages, tools, activeTools, toolChoice, stopWhen };\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\nexport type ToolProviderConfig<TContext, TInput, TOutput> = {\n description?: string;\n input: FlexibleSchema<TInput>;\n output?: FlexibleSchema<unknown>;\n providerOptions?: unknown;\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 return tool({\n ...toolDef,\n parameters: inputSchema,\n execute: (input: TInput, options?: ToolExecutionOptions) => execute(input, context, { ...options, writer: getActiveWriter() } as ToolExecuteOptions),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any);\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 type { UIMessageStreamWriter } from \"ai\";\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\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, falling back to text.\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(result: any, hasStructuredOutput: boolean): Promise<unknown> {\n if (hasStructuredOutput) {\n const output = await result.output;\n if (output !== undefined) return output;\n }\n return await result.text;\n}\n","import {\n createUIMessageStream,\n type UIMessageStreamWriter,\n} from \"ai\";\nimport { type Agent, type GenerateTextResult, type StreamTextResult } from \"./agent\";\nimport { extractOutput, runWithWriter, type MaybePromise } from \"./utils\";\n\n// ── Error Types ─────────────────────────────────────────────────────\n\nexport class WorkflowBranchError extends Error {\n constructor(\n public readonly branchType: \"predicate\" | \"select\",\n message: string,\n ) {\n super(message);\n this.name = \"WorkflowBranchError\";\n }\n}\n\nexport class WorkflowLoopError extends Error {\n constructor(\n public readonly iterations: number,\n public readonly maxIterations: number,\n ) {\n super(`Loop exceeded maximum iterations (${maxIterations})`);\n this.name = \"WorkflowLoopError\";\n }\n}\n\n// ── Gate / Snapshot Types ─────────────────────────────────────────────\n\nexport interface WorkflowSnapshot {\n readonly version: 1;\n readonly resumeFromIndex: number;\n readonly output: unknown;\n readonly gateId: string;\n readonly gatePayload: unknown;\n}\n\nexport class WorkflowSuspended extends Error {\n readonly snapshot: WorkflowSnapshot;\n constructor(snapshot: WorkflowSnapshot) {\n super(`Workflow suspended at gate \"${snapshot.gateId}\"`);\n this.name = \"WorkflowSuspended\";\n this.snapshot = snapshot;\n }\n}\n\n// ── Shared Agent Step Hooks ─────────────────────────────────────────\n\nexport interface AgentStepHooks<TContext, TOutput, TNextOutput> {\n mapGenerateResult?: (params: { result: GenerateTextResult; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>;\n mapStreamResult?: (params: { result: StreamTextResult; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>;\n onGenerateResult?: (params: { result: GenerateTextResult; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<void>;\n onStreamResult?: (params: { result: StreamTextResult; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<void>;\n handleStream?: (params: {\n result: StreamTextResult;\n writer: UIMessageStreamWriter;\n ctx: Readonly<TContext>;\n }) => MaybePromise<void>;\n}\n\n// ── Step Options ────────────────────────────────────────────────────\n\nexport type StepOptions<TContext, TOutput, TNextOutput> = AgentStepHooks<TContext, TOutput, TNextOutput>;\n\n// ── Branch Types ────────────────────────────────────────────────────\n\nexport interface BranchCase<TContext, TOutput, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {\n when?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<boolean>;\n agent: Agent<TContext, TOutput, TNextOutput>;\n}\n\nexport interface BranchSelect<TContext, TOutput, TKeys extends string, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {\n select: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TKeys>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agents: Record<TKeys, Agent<TContext, any, TNextOutput>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fallback?: Agent<TContext, any, TNextOutput>;\n}\n\n// ── Result Types ────────────────────────────────────────────────────\n\nexport interface WorkflowResult<TOutput> {\n output: TOutput;\n}\n\nexport interface WorkflowStreamResult<TOutput> {\n stream: ReadableStream;\n output: Promise<TOutput>;\n}\n\nexport interface WorkflowStreamOptions {\n onError?: (error: unknown) => string;\n onFinish?: () => MaybePromise<void>;\n}\n\n// ── Loop Types ──────────────────────────────────────────────────────\n\ntype LoopPredicate<TContext, TOutput> = (params: {\n output: TOutput;\n ctx: Readonly<TContext>;\n iterations: number;\n}) => MaybePromise<boolean>;\n\n// Exactly one of `until` or `while` — never both.\nexport type RepeatOptions<TContext, TOutput> =\n | { until: LoopPredicate<TContext, TOutput>; while?: never; maxIterations?: number }\n | { while: LoopPredicate<TContext, TOutput>; until?: never; maxIterations?: number };\n\n// Extracts the element type from an array type. Resolves to `never` for non-arrays,\n// making foreach uncallable at compile time when the previous step doesn't produce an array.\ntype ElementOf<T> = T extends readonly (infer E)[] ? E : never;\n\n// ── Schema type (structural — works with Zod, Valibot, ArkType, etc.) ──\n\ninterface SchemaWithParse<T = unknown> {\n parse(data: unknown): T;\n}\n\n// ── Step Node ───────────────────────────────────────────────────────\n\ntype StepNode =\n | { readonly type: \"step\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void> }\n | { readonly type: \"catch\"; readonly id: string; readonly catchFn: (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown> }\n | { readonly type: \"finally\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void> }\n | { readonly type: \"gate\"; readonly id: string; readonly payload: (state: RuntimeState) => MaybePromise<unknown>; readonly schema?: SchemaWithParse; readonly condition?: (state: RuntimeState) => MaybePromise<boolean>; readonly merge?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown> };\n\ninterface RuntimeState {\n ctx: unknown;\n output: unknown;\n mode: \"generate\" | \"stream\";\n writer?: UIMessageStreamWriter;\n}\n\n// ── Sealed Workflow (returned by finally — execution only) ───────────\n\nexport class SealedWorkflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> {\n readonly id?: string;\n protected readonly steps: ReadonlyArray<StepNode>;\n\n protected constructor(steps: ReadonlyArray<StepNode>, id?: string) {\n this.steps = steps;\n this.id = id;\n }\n\n // ── Execution ─────────────────────────────────────────────────\n\n async generate(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<WorkflowResult<TOutput>> {\n const input = args[0];\n const state: RuntimeState = {\n ctx,\n output: input,\n mode: \"generate\",\n };\n\n await this.execute(state);\n\n return {\n output: state.output as TOutput,\n };\n }\n\n stream(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: WorkflowStreamOptions]\n : [input: TInput, options?: WorkflowStreamOptions]\n ): WorkflowStreamResult<TOutput> {\n const input = args[0];\n const options = args[1] as WorkflowStreamOptions | undefined;\n\n let resolveOutput: (value: TOutput) => void;\n let rejectOutput: (error: unknown) => void;\n const outputPromise = new Promise<TOutput>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n\n // Prevent unhandled rejection warning if the consumer never awaits `output`.\n // The original promise still rejects normally when awaited.\n outputPromise.catch(() => {});\n\n const stream = createUIMessageStream({\n execute: async ({ writer }) => {\n const state: RuntimeState = {\n ctx,\n output: input,\n mode: \"stream\",\n writer,\n };\n\n try {\n await this.execute(state);\n resolveOutput(state.output as TOutput);\n } catch (error) {\n rejectOutput!(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n });\n\n return {\n stream,\n output: outputPromise,\n };\n }\n\n // ── Internal: execute pipeline ────────────────────────────────\n\n protected async execute(state: RuntimeState, startIndex: number = 0): 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 let pendingError: { error: unknown; stepId: string } | null = null;\n\n for (let i = startIndex; i < this.steps.length; i++) {\n const node = this.steps[i];\n\n if (node.type === \"finally\") {\n await node.execute(state);\n continue;\n }\n\n if (node.type === \"catch\") {\n if (!pendingError) continue;\n try {\n state.output = await node.catchFn({\n error: pendingError.error,\n ctx: state.ctx,\n lastOutput: state.output,\n stepId: pendingError.stepId,\n });\n pendingError = null;\n } catch (catchError) {\n pendingError = { error: catchError, stepId: node.id };\n }\n continue;\n }\n\n if (node.type === \"gate\") {\n if (pendingError) continue; // skip gates while in error state\n // Conditional gate: if condition returns false, skip (passthrough)\n if (node.condition) {\n const shouldSuspend = await node.condition(state);\n if (!shouldSuspend) continue;\n }\n const gatePayload = await node.payload(state);\n throw new WorkflowSuspended({\n version: 1,\n resumeFromIndex: i,\n output: state.output,\n gateId: node.id,\n gatePayload,\n });\n }\n\n // type === \"step\" — skip while in error state\n if (pendingError) continue;\n\n try {\n await node.execute(state);\n } catch (error) {\n if (error instanceof WorkflowSuspended) throw error; // propagate, don't capture\n pendingError = { error, stepId: node.id };\n }\n }\n\n if (pendingError) throw pendingError.error;\n }\n\n // ── Internal: execute a nested workflow within a step/loop ─────\n // Defined on SealedWorkflow (not Workflow) because TypeScript's protected\n // access rules only allow calling workflow.execute() from the same class.\n\n protected async executeNestedWorkflow(\n state: RuntimeState,\n workflow: SealedWorkflow<TContext, unknown, unknown, any>,\n ): Promise<void> {\n try {\n await workflow.execute(state);\n } catch (error) {\n if (error instanceof WorkflowSuspended) {\n throw new Error(\n `Gates inside nested workflows are not yet supported. ` +\n `Gate \"${error.snapshot.gateId}\" was hit inside nested workflow \"${workflow.id ?? \"(anonymous)\"}\". ` +\n `Consider using a conditional gate with \\`condition\\` to skip when criteria are met, ` +\n `or restructure the workflow to use gates at the top level only.`\n );\n }\n throw error;\n }\n }\n\n // ── Internal: execute an agent within a step/branch ───────────\n // In stream mode, output extraction awaits the full stream before returning.\n // Streaming benefits the client (incremental output), not pipeline throughput —\n // each step still runs sequentially.\n\n protected async executeAgent<TAgentInput, TNextOutput>(\n state: RuntimeState,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agent: Agent<TContext, any, TNextOutput>,\n ctx: TContext,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: AgentStepHooks<TContext, any, TNextOutput>,\n ): Promise<void> {\n const input = state.output as TAgentInput;\n const hasStructuredOutput = agent.hasOutput;\n\n if (state.mode === \"stream\" && state.writer) {\n const writer = state.writer;\n // Run inside writer context so tools (asTool, defineTool) can access the writer automatically\n await runWithWriter(writer, async () => {\n const result = await (agent.stream as (ctx: TContext, input: unknown) => Promise<StreamTextResult>)(ctx, state.output);\n\n if (options?.handleStream) {\n await options.handleStream({ result, writer, ctx });\n } else {\n writer.merge(result.toUIMessageStream());\n }\n\n if (options?.onStreamResult) {\n await options.onStreamResult({ result, ctx, input });\n }\n\n if (options?.mapStreamResult) {\n state.output = await options.mapStreamResult({ result, ctx, input });\n } else {\n state.output = await extractOutput(result, hasStructuredOutput);\n }\n });\n } else {\n const result = await (agent.generate as (ctx: TContext, input: unknown) => Promise<GenerateTextResult>)(ctx, state.output);\n\n if (options?.onGenerateResult) {\n await options.onGenerateResult({ result, ctx, input });\n }\n\n if (options?.mapGenerateResult) {\n state.output = await options.mapGenerateResult({ result, ctx, input });\n } else {\n state.output = await extractOutput(result, hasStructuredOutput);\n }\n }\n }\n\n // ── Gate: load persisted state for resumption ──────────────────\n\n loadState<K extends string & keyof TGates>(\n gateId: K,\n snapshot: WorkflowSnapshot,\n ): ResumedWorkflow<TContext, TGates[K], TOutput> {\n if (snapshot.gateId !== gateId) {\n throw new Error(\n `loadState: gate ID mismatch — expected \"${gateId}\" but snapshot has \"${snapshot.gateId}\".`\n );\n }\n const gateIndex = this.findGateIndex(snapshot);\n const gateNode = this.steps[gateIndex] as Extract<StepNode, { type: \"gate\" }>;\n return new ResumedWorkflow<TContext, TGates[K], TOutput>(\n this.steps,\n gateIndex + 1,\n gateNode.schema as SchemaWithParse<TGates[K]> | undefined,\n gateNode.merge,\n snapshot.output,\n );\n }\n\n private findGateIndex(snapshot: WorkflowSnapshot): number {\n if (snapshot.version !== 1) {\n throw new Error(`Unsupported snapshot version: ${snapshot.version}`);\n }\n\n // Fast path: check the hint index first (backward compat + O(1))\n const hint = snapshot.resumeFromIndex;\n if (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\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\nexport class ResumedWorkflow<\n TContext,\n TResponse = unknown,\n TOutput = void,\n> extends SealedWorkflow<TContext, TResponse, TOutput> {\n private readonly startIndex: number;\n private readonly schema?: SchemaWithParse<TResponse>;\n private readonly mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n private readonly priorOutput: unknown;\n\n /** @internal */\n constructor(\n steps: ReadonlyArray<StepNode>,\n startIndex: number,\n schema?: SchemaWithParse<TResponse>,\n mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>,\n priorOutput?: unknown,\n ) {\n super(steps);\n this.startIndex = startIndex;\n this.schema = schema;\n this.mergeFn = mergeFn;\n this.priorOutput = priorOutput;\n }\n\n private validateResponse(response: TResponse): TResponse {\n if (this.schema) {\n return this.schema.parse(response);\n }\n return response;\n }\n\n override async generate(\n ctx: TContext,\n ...args: TResponse extends void ? [response?: TResponse] : [response: TResponse]\n ): Promise<WorkflowResult<TOutput>> {\n const response = this.validateResponse(args[0] as TResponse);\n const output = this.mergeFn\n ? await this.mergeFn({ priorOutput: this.priorOutput, response })\n : response;\n const state: RuntimeState = { ctx, output, mode: \"generate\" };\n await this.execute(state, this.startIndex);\n return { output: state.output as TOutput };\n }\n\n override stream(\n ctx: TContext,\n ...args: TResponse extends void\n ? [response?: TResponse, options?: WorkflowStreamOptions]\n : [response: TResponse, options?: WorkflowStreamOptions]\n ): WorkflowStreamResult<TOutput> {\n const response = this.validateResponse(args[0] as TResponse);\n const options = args[1] as WorkflowStreamOptions | undefined;\n\n let resolveOutput: (value: TOutput) => void;\n let rejectOutput: (error: unknown) => void;\n const outputPromise = new Promise<TOutput>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n outputPromise.catch(() => {});\n\n const mergeFn = this.mergeFn;\n const priorOutput = this.priorOutput;\n\n const stream = createUIMessageStream({\n execute: async ({ writer }) => {\n const output = mergeFn\n ? await mergeFn({ priorOutput, response })\n : response;\n const state: RuntimeState = {\n ctx,\n output,\n mode: \"stream\",\n writer,\n };\n\n try {\n await this.execute(state, this.startIndex);\n resolveOutput(state.output as TOutput);\n } catch (error) {\n rejectOutput!(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n });\n\n return { stream, output: outputPromise };\n }\n}\n\n// ── Workflow ────────────────────────────────────────────────────────\n\nexport class Workflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> extends SealedWorkflow<TContext, TInput, TOutput, TGates> {\n\n private constructor(steps: ReadonlyArray<StepNode> = [], id?: string) {\n super(steps, id);\n }\n\n static create<TContext, TInput = void>(options?: { id?: string }): Workflow<TContext, TInput, TInput> {\n return new Workflow<TContext, TInput, TInput>([], options?.id);\n }\n\n static from<TContext, TInput, TOutput>(\n agent: Agent<TContext, TInput, TOutput>,\n options?: StepOptions<TContext, TInput, TOutput>\n ): Workflow<TContext, TInput, TOutput> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, any>([]).step(agent, options);\n }\n\n // ── step: agent overload ──────────────────────────────────────\n\n step<TNextOutput>(\n agent: Agent<TContext, TOutput, TNextOutput>,\n options?: StepOptions<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: nested workflow overload ─────────────────────────────\n\n step<TNextOutput>(\n workflow: SealedWorkflow<TContext, TOutput, TNextOutput>,\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: transform overload (replaces map + tap) ─────────────\n\n step<TNextOutput>(\n id: string,\n fn: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: implementation ──────────────────────────────────────\n\n step<TNextOutput>(\n target: Agent<TContext, TOutput, TNextOutput> | SealedWorkflow<TContext, TOutput, TNextOutput> | string,\n optionsOrFn?: StepOptions<TContext, TOutput, TNextOutput> | ((params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>)\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n // Nested workflow overload: step(workflow)\n if (target instanceof SealedWorkflow) {\n const workflow = target;\n const node: StepNode = {\n type: \"step\",\n id: workflow.id ?? \"nested-workflow\",\n execute: async (state) => {\n await this.executeNestedWorkflow(state, workflow as SealedWorkflow<TContext, unknown, unknown, any>);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // Transform overload: step(id, fn)\n if (typeof target === \"string\") {\n if (typeof optionsOrFn !== \"function\") {\n throw new Error(`Workflow step(\"${target}\"): second argument must be a function`);\n }\n const fn = optionsOrFn as (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>;\n const node: StepNode = {\n type: \"step\",\n id: target,\n execute: async (state) => {\n state.output = await fn({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n });\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // Agent overload: step(agent, options?)\n const agent = target;\n const options = optionsOrFn as StepOptions<TContext, TOutput, TNextOutput> | undefined;\n const node: StepNode = {\n type: \"step\",\n id: agent.id,\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n await this.executeAgent(state, agent, ctx, options);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── gate: human-in-the-loop suspension point ────────────────\n\n gate<TResponse = TOutput, Id extends string = string>(\n id: Id & (Id extends keyof TGates ? never : Id),\n options?: {\n payload?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<unknown>;\n schema?: SchemaWithParse<TResponse>;\n condition?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<boolean>;\n merge?: (params: { priorOutput: TOutput; response: TResponse }) => MaybePromise<TResponse>;\n }\n ): Workflow<TContext, TInput, TResponse, TGates & Record<Id, TResponse>> {\n if (this.steps.some(s => s.type === \"gate\" && s.id === id)) {\n throw new Error(`Workflow: duplicate gate ID \"${id}\". Each gate must have a unique identifier.`);\n }\n const node: StepNode = {\n type: \"gate\",\n id,\n schema: options?.schema,\n condition: options?.condition\n ? async (state) => options.condition!({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n })\n : undefined,\n merge: options?.merge\n ? (params) => options.merge!(params as { priorOutput: TOutput; response: TResponse })\n : undefined,\n payload: async (state) => {\n if (options?.payload) {\n return options.payload({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n });\n }\n return state.output;\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TResponse, TGates & Record<Id, TResponse>>([...this.steps, node] as any, this.id);\n }\n\n // ── branch: predicate routing (array) ─────────────────────────\n\n branch<TNextOutput>(\n cases: BranchCase<TContext, TOutput, TNextOutput>[]\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 ): 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 ): Workflow<TContext, TInput, TNextOutput, TGates> {\n if (Array.isArray(casesOrConfig)) {\n return this.branchPredicate(casesOrConfig);\n }\n return this.branchSelect(casesOrConfig);\n }\n\n private branchPredicate<TNextOutput>(\n cases: BranchCase<TContext, TOutput, TNextOutput>[]\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n const node: StepNode = {\n type: \"step\",\n id: \"branch:predicate\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n const input = state.output as TOutput;\n\n for (const branchCase of cases) {\n if (branchCase.when) {\n const match = await branchCase.when({ ctx, input });\n if (!match) continue;\n }\n\n // Matched (or no `when` = default)\n await this.executeAgent(state, branchCase.agent, ctx, branchCase);\n return;\n }\n\n throw new WorkflowBranchError(\"predicate\", `No branch matched and no default branch (a case without \\`when\\`) was provided. Input: ${JSON.stringify(input)}`);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n private branchSelect<TKeys extends string, TNextOutput>(\n config: BranchSelect<TContext, TOutput, TKeys, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n const node: StepNode = {\n type: \"step\",\n id: \"branch:select\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n const input = state.output as TOutput;\n const key = await config.select({ ctx, input });\n\n let agent = config.agents[key];\n if (!agent) {\n if (config.fallback) {\n agent = config.fallback;\n } else {\n throw new WorkflowBranchError(\"select\", `No agent found for key \"${key}\" and no fallback provided. Available keys: ${Object.keys(config.agents).join(\", \")}`);\n }\n }\n\n await this.executeAgent(state, agent, ctx, config);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── foreach: array iteration ─────────────────────────────────\n\n foreach<TNextOutput>(\n target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput>,\n options?: { concurrency?: number },\n ): Workflow<TContext, TInput, TNextOutput[], TGates> {\n const concurrency = options?.concurrency ?? 1;\n const isWorkflow = target instanceof SealedWorkflow;\n const id = isWorkflow ? (target.id ?? \"foreach\") : `foreach:${(target as Agent<TContext, ElementOf<TOutput>, TNextOutput>).id}`;\n\n const node: StepNode = {\n type: \"step\",\n id,\n execute: async (state) => {\n const items = state.output;\n if (!Array.isArray(items)) {\n throw new Error(`foreach \"${id}\": expected array input, got ${typeof items}`);\n }\n\n const ctx = state.ctx as TContext;\n const results: unknown[] = new Array(items.length);\n\n // Streaming is intentionally not propagated to foreach items —\n // each item runs in generate mode because merging interleaved\n // streams from parallel items into a single writer is not supported.\n const executeItem = async (item: unknown, index: number) => {\n const itemState: RuntimeState = { ctx: state.ctx, output: item, mode: \"generate\" };\n if (isWorkflow) {\n await this.executeNestedWorkflow(itemState, target as SealedWorkflow<TContext, unknown, unknown, any>);\n } else {\n await this.executeAgent(itemState, target as Agent<TContext, unknown, TNextOutput>, ctx);\n }\n results[index] = itemState.output;\n };\n\n if (concurrency <= 1) {\n for (let i = 0; i < items.length; i++) {\n await executeItem(items[i], i);\n }\n } else {\n for (let i = 0; i < items.length; i += concurrency) {\n const batch = items.slice(i, i + concurrency);\n await Promise.all(batch.map((item, j) => executeItem(item, i + j)));\n }\n }\n\n state.output = results;\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput[], TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── repeat: conditional loop ─────────────────────────────────\n\n repeat(\n target: Agent<TContext, TOutput, TOutput> | SealedWorkflow<TContext, TOutput, TOutput>,\n options: RepeatOptions<TContext, TOutput>,\n ): Workflow<TContext, TInput, TOutput, TGates> {\n const maxIterations = options.maxIterations ?? 10;\n const isWorkflow = target instanceof SealedWorkflow;\n const id = isWorkflow ? (target.id ?? \"repeat\") : `repeat:${(target as Agent<TContext, TOutput, TOutput>).id}`;\n const predicate: LoopPredicate<TContext, TOutput> = options.until\n ?? (async (p) => !(await options.while!(p)));\n\n const node: StepNode = {\n type: \"step\",\n id,\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n\n for (let i = 1; i <= maxIterations; i++) {\n if (isWorkflow) {\n await this.executeNestedWorkflow(state, target as SealedWorkflow<TContext, unknown, unknown, any>);\n } else {\n await this.executeAgent(state, target as Agent<TContext, TOutput, TOutput>, ctx);\n }\n\n const done = await predicate({\n output: state.output as TOutput,\n ctx: ctx as Readonly<TContext>,\n iterations: i,\n });\n if (done) return;\n }\n\n throw new WorkflowLoopError(maxIterations, maxIterations);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── catch ─────────────────────────────────────────────────────\n\n catch(\n id: string,\n fn: (params: { error: unknown; ctx: Readonly<TContext>; lastOutput: TOutput; stepId: string }) => MaybePromise<TOutput>\n ): Workflow<TContext, TInput, TOutput, TGates> {\n if (!this.steps.some(s => s.type === \"step\")) {\n throw new Error(`Workflow: catch(\"${id}\") requires at least one preceding step.`);\n }\n const node: StepNode = {\n type: \"catch\",\n id,\n catchFn: fn as (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown>,\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── finally (terminal — returns sealed workflow) ──────────────\n\n finally(\n id: string,\n fn: (params: { ctx: Readonly<TContext> }) => MaybePromise<void>\n ): SealedWorkflow<TContext, TInput, TOutput, TGates> {\n const node: StepNode = {\n type: \"finally\",\n id,\n execute: async (state) => {\n await fn({ ctx: state.ctx as Readonly<TContext> });\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new SealedWorkflow<TContext, TInput, TOutput, TGates>([...this.steps, node] as any, this.id);\n }\n}\n\n"],"mappings":"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","names":["import_ai","result","import_ai","node"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/agent.ts","../src/tool-provider.ts","../src/utils.ts","../src/workflow.ts"],"sourcesContent":["export { Agent } from \"./agent\";\nexport type {\n AgentConfig,\n GenerateTextResult,\n StreamTextResult,\n OutputType,\n} from \"./agent\";\n\nexport { Workflow, WorkflowBranchError, WorkflowLoopError, WorkflowSuspended } from \"./workflow\";\nexport type { SealedWorkflow, ResumedWorkflow } from \"./workflow\";\nexport type {\n AgentStepHooks,\n StepOptions,\n BranchCase,\n BranchSelect,\n RepeatOptions,\n WorkflowResult,\n WorkflowStreamResult,\n WorkflowStreamOptions,\n WorkflowSnapshot,\n} from \"./workflow\";\n\nexport { defineTool } from \"./tool-provider\";\nexport type { ToolProviderConfig, ToolExecuteOptions, IToolProvider } from \"./tool-provider\";\n\nexport type { MaybePromise, Resolvable } from \"./utils\";\n","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// ── 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 // ── 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 stopWhen?: Resolvable<TContext, TInput, 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 private readonly config: AgentConfig<TContext, TInput, TOutput>;\n private readonly _hasDynamicConfig: boolean;\n private readonly _resolvedStaticTools: Record<string, Tool> | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private readonly _passthrough: Record<string, any>;\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.config = config;\n this._hasDynamicConfig = [\n config.model, config.system, config.prompt,\n config.messages, config.tools, config.activeTools,\n config.toolChoice, config.stopWhen,\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,\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(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<GenerateTextResult<ToolSet, OutputType<TOutput>>> {\n const input = args[0] as TInput;\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return await generateText(options as any);\n } catch (error: unknown) {\n if (this.config.onError) {\n await this.config.onError({ error, ctx, input, writer: getActiveWriter() });\n }\n throw error;\n }\n }\n\n async stream(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<StreamTextResult<ToolSet, OutputType<TOutput>>> {\n const input = args[0] as TInput;\n const resolved = await this.resolveConfig(ctx, input);\n const options = this.buildCallOptions(resolved, ctx, input);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return streamText({\n ...options,\n onError: this.config.onError\n ? ({ error }: { error: unknown }) => this.config.onError!({ error, ctx, input, writer: getActiveWriter() })\n : undefined,\n } as any);\n }\n\n asTool(ctx: TContext, options?: {\n mapOutput?: (result: GenerateTextResult<ToolSet, OutputType<TOutput>>) => MaybePromise<TOutput>;\n }): Tool {\n return this.createToolInstance(ctx, options);\n }\n\n asToolProvider(options?: {\n mapOutput?: (result: GenerateTextResult<ToolSet, OutputType<TOutput>>) => MaybePromise<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?: (result: GenerateTextResult<ToolSet, OutputType<TOutput>>) => MaybePromise<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 execute: async (toolInput: TInput) => {\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.stream as (ctx: TContext, input: TInput) => Promise<StreamTextResult>)(ctx, toolInput);\n writer.merge(result.toUIMessageStream());\n if (options?.mapOutput) return options.mapOutput(result as unknown as GenerateTextResult);\n return extractOutput(result, this.hasOutput);\n }\n const result = await (this.generate as (ctx: TContext, input: TInput) => Promise<GenerateTextResult>)(ctx, toolInput);\n if (options?.mapOutput) return options.mapOutput(result);\n return extractOutput(result, this.hasOutput);\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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private buildCallOptions(resolved: ResolvedAgentConfig, ctx: TContext, input: TInput): Record<string, any> {\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\n ? { messages: resolved.messages }\n : { prompt: resolved.prompt ?? \"\" }),\n ...(resolved.system ? { system: resolved.system } : {}),\n ...(this.config.output ? { output: this.config.output } : {}),\n onStepFinish: this._onStepFinish\n ? (event: OnStepFinishEvent) => this._onStepFinish!({ result: event, ctx, input, writer: getActiveWriter() })\n : undefined,\n onFinish: this._onFinish\n ? (event: OnFinishEvent) => this._onFinish!({ result: event, ctx, input, writer: getActiveWriter() })\n : undefined,\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, stopWhen] = 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 resolveValue(this.config.stopWhen, ctx, input),\n ]);\n const tools = this.resolveTools(rawTools ?? {}, ctx);\n return { model, prompt, system, messages, tools, activeTools, toolChoice, stopWhen };\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 type { UIMessageStreamWriter } from \"ai\";\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\nexport function getActiveWriter(): UIMessageStreamWriter | undefined {\n return writerStorage.getStore();\n}\n\n// ── Common types ─────────────────────────────────────────────────────\n\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * A value that can be static or derived from context and input.\n * Used for agent config fields that may need runtime resolution.\n *\n * Functions may return a Promise for async resolution; static values are always sync.\n */\nexport type Resolvable<TCtx, TInput, TValue> =\n | TValue\n | ((ctx: Readonly<TCtx>, input: TInput) => TValue | Promise<TValue>);\n\nexport function resolveValue<TCtx, TInput, TValue>(\n value: Resolvable<TCtx, TInput, TValue>,\n ctx: TCtx,\n input: TInput\n): TValue | Promise<TValue>;\nexport function resolveValue<TCtx, TInput, TValue>(\n value: Resolvable<TCtx, TInput, TValue> | undefined,\n ctx: TCtx,\n input: TInput\n): TValue | Promise<TValue> | undefined {\n if (typeof value === \"function\") {\n return (value as (ctx: TCtx, input: TInput) => TValue | Promise<TValue>)(ctx, input);\n }\n return value;\n}\n\n/**\n * Minimal counting semaphore. Up to `permits` callers can hold a permit\n * concurrently; further `acquire()` calls queue FIFO until one is released.\n */\nexport class Semaphore {\n private available: number;\n private waiters: Array<() => void> = [];\n\n constructor(permits: number) {\n if (!Number.isInteger(permits) || permits < 1) {\n throw new Error(`Semaphore: permits must be a positive integer, got ${permits}`);\n }\n this.available = permits;\n }\n\n async acquire(): Promise<void> {\n if (this.available > 0) {\n this.available--;\n return;\n }\n await new Promise<void>(resolve => this.waiters.push(resolve));\n }\n\n release(): void {\n const next = this.waiters.shift();\n if (next) next();\n else this.available++;\n }\n}\n\n/**\n * Extract structured output from an AI SDK result, falling back to text.\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(result: any, hasStructuredOutput: boolean): Promise<unknown> {\n if (hasStructuredOutput) {\n const output = await result.output;\n if (output !== undefined) return output;\n }\n return await result.text;\n}\n","import {\n createUIMessageStream,\n type UIMessageStreamWriter,\n type ToolSet,\n} from \"ai\";\nimport { type Agent, type GenerateTextResult, type StreamTextResult, type OutputType } from \"./agent\";\nimport { extractOutput, runWithWriter, Semaphore, type MaybePromise } from \"./utils\";\n\n// ── Error Types ─────────────────────────────────────────────────────\n\nexport class WorkflowBranchError extends Error {\n constructor(\n public readonly branchType: \"predicate\" | \"select\",\n message: string,\n ) {\n super(message);\n this.name = \"WorkflowBranchError\";\n }\n}\n\nexport class WorkflowLoopError extends Error {\n constructor(\n public readonly iterations: number,\n public readonly maxIterations: number,\n ) {\n super(`Loop exceeded maximum iterations (${maxIterations})`);\n this.name = \"WorkflowLoopError\";\n }\n}\n\n// ── Gate / Snapshot Types ─────────────────────────────────────────────\n\nexport interface WorkflowSnapshot {\n readonly version: 1;\n readonly resumeFromIndex: number;\n readonly output: unknown;\n readonly gateId: string;\n readonly gatePayload: unknown;\n}\n\nexport class WorkflowSuspended extends Error {\n readonly snapshot: WorkflowSnapshot;\n constructor(snapshot: WorkflowSnapshot) {\n super(`Workflow suspended at gate \"${snapshot.gateId}\"`);\n this.name = \"WorkflowSuspended\";\n this.snapshot = snapshot;\n }\n}\n\n// ── Shared Agent Step Hooks ─────────────────────────────────────────\n\nexport interface AgentStepHooks<TContext, TOutput, TNextOutput> {\n mapGenerateResult?: (params: { result: GenerateTextResult<ToolSet, OutputType<TNextOutput>>; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>;\n mapStreamResult?: (params: { result: StreamTextResult<ToolSet, OutputType<TNextOutput>>; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>;\n onGenerateResult?: (params: { result: GenerateTextResult<ToolSet, OutputType<TNextOutput>>; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<void>;\n onStreamResult?: (params: { result: StreamTextResult<ToolSet, OutputType<TNextOutput>>; ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<void>;\n handleStream?: (params: {\n result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;\n writer: UIMessageStreamWriter;\n ctx: Readonly<TContext>;\n }) => MaybePromise<void>;\n}\n\n// ── Step Options ────────────────────────────────────────────────────\n\nexport type StepOptions<TContext, TOutput, TNextOutput> = AgentStepHooks<TContext, TOutput, TNextOutput>;\n\n// ── Branch Types ────────────────────────────────────────────────────\n\nexport interface BranchCase<TContext, TOutput, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {\n when?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<boolean>;\n agent: Agent<TContext, TOutput, TNextOutput>;\n}\n\nexport interface BranchSelect<TContext, TOutput, TKeys extends string, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {\n select: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TKeys>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agents: Record<TKeys, Agent<TContext, any, TNextOutput>>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fallback?: Agent<TContext, any, TNextOutput>;\n}\n\n// ── Result Types ────────────────────────────────────────────────────\n\nexport interface WorkflowResult<TOutput> {\n output: TOutput;\n}\n\nexport interface WorkflowStreamResult<TOutput> {\n stream: ReadableStream;\n output: Promise<TOutput>;\n}\n\nexport interface WorkflowStreamOptions {\n onError?: (error: unknown) => string;\n onFinish?: () => MaybePromise<void>;\n}\n\n// ── Loop Types ──────────────────────────────────────────────────────\n\ntype LoopPredicate<TContext, TOutput> = (params: {\n output: TOutput;\n ctx: Readonly<TContext>;\n iterations: number;\n}) => MaybePromise<boolean>;\n\n// Exactly one of `until` or `while` — never both.\nexport type RepeatOptions<TContext, TOutput> =\n | { until: LoopPredicate<TContext, TOutput>; while?: never; maxIterations?: number }\n | { while: LoopPredicate<TContext, TOutput>; until?: never; maxIterations?: number };\n\n// Extracts the element type from an array type. Resolves to `never` for non-arrays,\n// making foreach uncallable at compile time when the previous step doesn't produce an array.\ntype ElementOf<T> = T extends readonly (infer E)[] ? E : never;\n\n// ── Schema type (structural — works with Zod, Valibot, ArkType, etc.) ──\n\ninterface SchemaWithParse<T = unknown> {\n parse(data: unknown): T;\n}\n\n// ── Step Node ───────────────────────────────────────────────────────\n\ntype StepNode =\n | { readonly type: \"step\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void> }\n | { readonly type: \"catch\"; readonly id: string; readonly catchFn: (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown> }\n | { readonly type: \"finally\"; readonly id: string; readonly execute: (state: RuntimeState) => MaybePromise<void> }\n | { readonly type: \"gate\"; readonly id: string; readonly payload: (state: RuntimeState) => MaybePromise<unknown>; readonly schema?: SchemaWithParse; readonly condition?: (state: RuntimeState) => MaybePromise<boolean>; readonly merge?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown> };\n\ninterface RuntimeState {\n ctx: unknown;\n output: unknown;\n mode: \"generate\" | \"stream\";\n writer?: UIMessageStreamWriter;\n}\n\n// ── Sealed Workflow (returned by finally — execution only) ───────────\n\nexport class SealedWorkflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> {\n readonly id?: string;\n protected readonly steps: ReadonlyArray<StepNode>;\n\n protected constructor(steps: ReadonlyArray<StepNode>, id?: string) {\n this.steps = steps;\n this.id = id;\n }\n\n // ── Execution ─────────────────────────────────────────────────\n\n async generate(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<WorkflowResult<TOutput>> {\n const input = args[0];\n const state: RuntimeState = {\n ctx,\n output: input,\n mode: \"generate\",\n };\n\n await this.execute(state);\n\n return {\n output: state.output as TOutput,\n };\n }\n\n stream(\n ctx: TContext,\n ...args: TInput extends void\n ? [input?: TInput, options?: WorkflowStreamOptions]\n : [input: TInput, options?: WorkflowStreamOptions]\n ): WorkflowStreamResult<TOutput> {\n const input = args[0];\n const options = args[1] as WorkflowStreamOptions | undefined;\n\n let resolveOutput: (value: TOutput) => void;\n let rejectOutput: (error: unknown) => void;\n const outputPromise = new Promise<TOutput>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n\n // Prevent unhandled rejection warning if the consumer never awaits `output`.\n // The original promise still rejects normally when awaited.\n outputPromise.catch(() => {});\n\n const stream = createUIMessageStream({\n execute: async ({ writer }) => {\n const state: RuntimeState = {\n ctx,\n output: input,\n mode: \"stream\",\n writer,\n };\n\n try {\n await this.execute(state);\n resolveOutput(state.output as TOutput);\n } catch (error) {\n rejectOutput!(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n });\n\n return {\n stream,\n output: outputPromise,\n };\n }\n\n // ── Internal: execute pipeline ────────────────────────────────\n\n protected async execute(state: RuntimeState, startIndex: number = 0): 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 let pendingError: { error: unknown; stepId: string } | null = null;\n\n for (let i = startIndex; i < this.steps.length; i++) {\n const node = this.steps[i];\n\n if (node.type === \"finally\") {\n await node.execute(state);\n continue;\n }\n\n if (node.type === \"catch\") {\n if (!pendingError) continue;\n try {\n state.output = await node.catchFn({\n error: pendingError.error,\n ctx: state.ctx,\n lastOutput: state.output,\n stepId: pendingError.stepId,\n });\n pendingError = null;\n } catch (catchError) {\n pendingError = { error: catchError, stepId: node.id };\n }\n continue;\n }\n\n if (node.type === \"gate\") {\n if (pendingError) continue; // skip gates while in error state\n // Conditional gate: if condition returns false, skip (passthrough)\n if (node.condition) {\n const shouldSuspend = await node.condition(state);\n if (!shouldSuspend) continue;\n }\n const gatePayload = await node.payload(state);\n throw new WorkflowSuspended({\n version: 1,\n resumeFromIndex: i,\n output: state.output,\n gateId: node.id,\n gatePayload,\n });\n }\n\n // type === \"step\" — skip while in error state\n if (pendingError) continue;\n\n try {\n await node.execute(state);\n } catch (error) {\n if (error instanceof WorkflowSuspended) throw error; // propagate, don't capture\n pendingError = { error, stepId: node.id };\n }\n }\n\n if (pendingError) throw pendingError.error;\n }\n\n // ── Internal: execute a nested workflow within a step/loop ─────\n // Defined on SealedWorkflow (not Workflow) because TypeScript's protected\n // access rules only allow calling workflow.execute() from the same class.\n\n protected async executeNestedWorkflow(\n state: RuntimeState,\n workflow: SealedWorkflow<TContext, unknown, unknown, any>,\n ): Promise<void> {\n try {\n await workflow.execute(state);\n } catch (error) {\n if (error instanceof WorkflowSuspended) {\n throw new Error(\n `Gates inside nested workflows are not yet supported. ` +\n `Gate \"${error.snapshot.gateId}\" was hit inside nested workflow \"${workflow.id ?? \"(anonymous)\"}\". ` +\n `Consider using a conditional gate with \\`condition\\` to skip when criteria are met, ` +\n `or restructure the workflow to use gates at the top level only.`\n );\n }\n throw error;\n }\n }\n\n // ── Internal: execute an agent within a step/branch ───────────\n // In stream mode, output extraction awaits the full stream before returning.\n // Streaming benefits the client (incremental output), not pipeline throughput —\n // each step still runs sequentially.\n\n protected async executeAgent<TAgentInput, TNextOutput>(\n state: RuntimeState,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agent: Agent<TContext, any, TNextOutput>,\n ctx: TContext,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options?: AgentStepHooks<TContext, any, TNextOutput>,\n ): Promise<void> {\n const input = state.output as TAgentInput;\n const hasStructuredOutput = agent.hasOutput;\n\n if (state.mode === \"stream\" && state.writer) {\n const writer = state.writer;\n // Run inside writer context so tools (asTool, defineTool) can access the writer automatically\n await runWithWriter(writer, async () => {\n const result = await (agent.stream as (ctx: TContext, input: unknown) => Promise<StreamTextResult<ToolSet, OutputType<TNextOutput>>>)(ctx, state.output);\n\n if (options?.handleStream) {\n await options.handleStream({ result, writer, ctx });\n } else {\n writer.merge(result.toUIMessageStream());\n }\n\n if (options?.onStreamResult) {\n await options.onStreamResult({ result, ctx, input });\n }\n\n if (options?.mapStreamResult) {\n state.output = await options.mapStreamResult({ result, ctx, input });\n } else {\n state.output = await extractOutput(result, hasStructuredOutput);\n }\n });\n } else {\n const result = await (agent.generate as (ctx: TContext, input: unknown) => Promise<GenerateTextResult<ToolSet, OutputType<TNextOutput>>>)(ctx, state.output);\n\n if (options?.onGenerateResult) {\n await options.onGenerateResult({ result, ctx, input });\n }\n\n if (options?.mapGenerateResult) {\n state.output = await options.mapGenerateResult({ result, ctx, input });\n } else {\n state.output = await extractOutput(result, hasStructuredOutput);\n }\n }\n }\n\n // ── Gate: load persisted state for resumption ──────────────────\n\n loadState<K extends string & keyof TGates>(\n gateId: K,\n snapshot: WorkflowSnapshot,\n ): ResumedWorkflow<TContext, TGates[K], TOutput> {\n if (snapshot.gateId !== gateId) {\n throw new Error(\n `loadState: gate ID mismatch — expected \"${gateId}\" but snapshot has \"${snapshot.gateId}\".`\n );\n }\n const gateIndex = this.findGateIndex(snapshot);\n const gateNode = this.steps[gateIndex] as Extract<StepNode, { type: \"gate\" }>;\n return new ResumedWorkflow<TContext, TGates[K], TOutput>(\n this.steps,\n gateIndex + 1,\n gateNode.schema as SchemaWithParse<TGates[K]> | undefined,\n gateNode.merge,\n snapshot.output,\n );\n }\n\n private findGateIndex(snapshot: WorkflowSnapshot): number {\n if (snapshot.version !== 1) {\n throw new Error(`Unsupported snapshot version: ${snapshot.version}`);\n }\n\n // Fast path: check the hint index first (backward compat + O(1))\n const hint = snapshot.resumeFromIndex;\n if (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\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\nexport class ResumedWorkflow<\n TContext,\n TResponse = unknown,\n TOutput = void,\n> extends SealedWorkflow<TContext, TResponse, TOutput> {\n private readonly startIndex: number;\n private readonly schema?: SchemaWithParse<TResponse>;\n private readonly mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>;\n private readonly priorOutput: unknown;\n\n /** @internal */\n constructor(\n steps: ReadonlyArray<StepNode>,\n startIndex: number,\n schema?: SchemaWithParse<TResponse>,\n mergeFn?: (params: { priorOutput: unknown; response: unknown }) => MaybePromise<unknown>,\n priorOutput?: unknown,\n ) {\n super(steps);\n this.startIndex = startIndex;\n this.schema = schema;\n this.mergeFn = mergeFn;\n this.priorOutput = priorOutput;\n }\n\n private validateResponse(response: TResponse): TResponse {\n if (this.schema) {\n return this.schema.parse(response);\n }\n return response;\n }\n\n override async generate(\n ctx: TContext,\n ...args: TResponse extends void ? [response?: TResponse] : [response: TResponse]\n ): Promise<WorkflowResult<TOutput>> {\n const response = this.validateResponse(args[0] as TResponse);\n const output = this.mergeFn\n ? await this.mergeFn({ priorOutput: this.priorOutput, response })\n : response;\n const state: RuntimeState = { ctx, output, mode: \"generate\" };\n await this.execute(state, this.startIndex);\n return { output: state.output as TOutput };\n }\n\n override stream(\n ctx: TContext,\n ...args: TResponse extends void\n ? [response?: TResponse, options?: WorkflowStreamOptions]\n : [response: TResponse, options?: WorkflowStreamOptions]\n ): WorkflowStreamResult<TOutput> {\n const response = this.validateResponse(args[0] as TResponse);\n const options = args[1] as WorkflowStreamOptions | undefined;\n\n let resolveOutput: (value: TOutput) => void;\n let rejectOutput: (error: unknown) => void;\n const outputPromise = new Promise<TOutput>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n outputPromise.catch(() => {});\n\n const mergeFn = this.mergeFn;\n const priorOutput = this.priorOutput;\n\n const stream = createUIMessageStream({\n execute: async ({ writer }) => {\n const output = mergeFn\n ? await mergeFn({ priorOutput, response })\n : response;\n const state: RuntimeState = {\n ctx,\n output,\n mode: \"stream\",\n writer,\n };\n\n try {\n await this.execute(state, this.startIndex);\n resolveOutput(state.output as TOutput);\n } catch (error) {\n rejectOutput!(error);\n throw error;\n }\n },\n ...(options?.onError ? { onError: options.onError } : {}),\n ...(options?.onFinish ? { onFinish: options.onFinish } : {}),\n });\n\n return { stream, output: outputPromise };\n }\n}\n\n// ── Workflow ────────────────────────────────────────────────────────\n\nexport class Workflow<\n TContext,\n TInput = void,\n TOutput = void,\n TGates extends Record<string, unknown> = {},\n> extends SealedWorkflow<TContext, TInput, TOutput, TGates> {\n\n /**\n * Sentinel value for `foreach`'s `onError` handler. Returning `Workflow.SKIP`\n * from `onError` omits the failed item's index from the output array,\n * shortening it relative to the input array.\n */\n static readonly SKIP: unique symbol = Symbol(\"pipeai.foreach.skip\");\n\n private constructor(steps: ReadonlyArray<StepNode> = [], id?: string) {\n super(steps, id);\n }\n\n static create<TContext, TInput = void>(options?: { id?: string }): Workflow<TContext, TInput, TInput> {\n return new Workflow<TContext, TInput, TInput>([], options?.id);\n }\n\n static from<TContext, TInput, TOutput>(\n agent: Agent<TContext, TInput, TOutput>,\n options?: StepOptions<TContext, TInput, TOutput>\n ): Workflow<TContext, TInput, TOutput> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, any>([]).step(agent, options);\n }\n\n // ── step: agent overload ──────────────────────────────────────\n\n step<TNextOutput>(\n agent: Agent<TContext, TOutput, TNextOutput>,\n options?: StepOptions<TContext, TOutput, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: nested workflow overload ─────────────────────────────\n\n step<TNextOutput>(\n workflow: SealedWorkflow<TContext, TOutput, TNextOutput>,\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: transform overload (replaces map + tap) ─────────────\n\n step<TNextOutput>(\n id: string,\n fn: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates>;\n\n // ── step: implementation ──────────────────────────────────────\n\n step<TNextOutput>(\n target: Agent<TContext, TOutput, TNextOutput> | SealedWorkflow<TContext, TOutput, TNextOutput> | string,\n optionsOrFn?: StepOptions<TContext, TOutput, TNextOutput> | ((params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>)\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n // Nested workflow overload: step(workflow)\n if (target instanceof SealedWorkflow) {\n const workflow = target;\n const node: StepNode = {\n type: \"step\",\n id: workflow.id ?? \"nested-workflow\",\n execute: async (state) => {\n await this.executeNestedWorkflow(state, workflow as SealedWorkflow<TContext, unknown, unknown, any>);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // Transform overload: step(id, fn)\n if (typeof target === \"string\") {\n if (typeof optionsOrFn !== \"function\") {\n throw new Error(`Workflow step(\"${target}\"): second argument must be a function`);\n }\n const fn = optionsOrFn as (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<TNextOutput>;\n const node: StepNode = {\n type: \"step\",\n id: target,\n execute: async (state) => {\n state.output = await fn({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n });\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // Agent overload: step(agent, options?)\n const agent = target;\n const options = optionsOrFn as StepOptions<TContext, TOutput, TNextOutput> | undefined;\n const node: StepNode = {\n type: \"step\",\n id: agent.id,\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n await this.executeAgent(state, agent, ctx, options);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── gate: human-in-the-loop suspension point ────────────────\n\n gate<TResponse = TOutput, Id extends string = string>(\n id: Id & (Id extends keyof TGates ? never : Id),\n options?: {\n payload?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<unknown>;\n schema?: SchemaWithParse<TResponse>;\n condition?: (params: { ctx: Readonly<TContext>; input: TOutput }) => MaybePromise<boolean>;\n merge?: (params: { priorOutput: TOutput; response: TResponse }) => MaybePromise<TResponse>;\n }\n ): Workflow<TContext, TInput, TResponse, TGates & Record<Id, TResponse>> {\n if (this.steps.some(s => s.type === \"gate\" && s.id === id)) {\n throw new Error(`Workflow: duplicate gate ID \"${id}\". Each gate must have a unique identifier.`);\n }\n const node: StepNode = {\n type: \"gate\",\n id,\n schema: options?.schema,\n condition: options?.condition\n ? async (state) => options.condition!({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n })\n : undefined,\n merge: options?.merge\n ? (params) => options.merge!(params as { priorOutput: TOutput; response: TResponse })\n : undefined,\n payload: async (state) => {\n if (options?.payload) {\n return options.payload({\n ctx: state.ctx as Readonly<TContext>,\n input: state.output as TOutput,\n });\n }\n return state.output;\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TResponse, TGates & Record<Id, TResponse>>([...this.steps, node] as any, this.id);\n }\n\n // ── branch: predicate routing (array) ─────────────────────────\n\n branch<TNextOutput>(\n cases: BranchCase<TContext, TOutput, TNextOutput>[]\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 ): 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 ): Workflow<TContext, TInput, TNextOutput, TGates> {\n if (Array.isArray(casesOrConfig)) {\n return this.branchPredicate(casesOrConfig);\n }\n return this.branchSelect(casesOrConfig);\n }\n\n private branchPredicate<TNextOutput>(\n cases: BranchCase<TContext, TOutput, TNextOutput>[]\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n const node: StepNode = {\n type: \"step\",\n id: \"branch:predicate\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n const input = state.output as TOutput;\n\n for (const branchCase of cases) {\n if (branchCase.when) {\n const match = await branchCase.when({ ctx, input });\n if (!match) continue;\n }\n\n // Matched (or no `when` = default)\n await this.executeAgent(state, branchCase.agent, ctx, branchCase);\n return;\n }\n\n throw new WorkflowBranchError(\"predicate\", `No branch matched and no default branch (a case without \\`when\\`) was provided. Input: ${JSON.stringify(input)}`);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n private branchSelect<TKeys extends string, TNextOutput>(\n config: BranchSelect<TContext, TOutput, TKeys, TNextOutput>\n ): Workflow<TContext, TInput, TNextOutput, TGates> {\n const node: StepNode = {\n type: \"step\",\n id: \"branch:select\",\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n const input = state.output as TOutput;\n const key = await config.select({ ctx, input });\n\n let agent = config.agents[key];\n if (!agent) {\n if (config.fallback) {\n agent = config.fallback;\n } else {\n throw new WorkflowBranchError(\"select\", `No agent found for key \"${key}\" and no fallback provided. Available keys: ${Object.keys(config.agents).join(\", \")}`);\n }\n }\n\n await this.executeAgent(state, agent, ctx, config);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput, TGates>([...this.steps, node] as any, this.id);\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.concurrency Max items in flight at any moment (default 1).\n * Backed by a semaphore: as soon as one item completes, the next launches —\n * no lockstep batching.\n * @param options.onError Per-iteration error handler. When provided, a single\n * item's failure no longer aborts the foreach. Return a `TNextOutput` value\n * to substitute for the failed item, return `Workflow.SKIP` to omit the\n * index (shortening the output array), or throw / return a rejected promise\n * to abort the foreach step (the thrown error is caught by any downstream\n * `.catch()`). When omitted, the existing fail-fast behavior is preserved.\n * `onError` is invoked sequentially in index order after all items settle.\n */\n foreach<TNextOutput>(\n target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput>,\n options?: {\n concurrency?: number;\n onError?: (params: {\n error: unknown;\n item: ElementOf<TOutput>;\n index: number;\n ctx: Readonly<TContext>;\n }) => MaybePromise<TNextOutput | typeof Workflow.SKIP>;\n },\n ): Workflow<TContext, TInput, TNextOutput[], TGates> {\n const concurrency = options?.concurrency ?? 1;\n const onError = options?.onError;\n const isWorkflow = target instanceof SealedWorkflow;\n const id = isWorkflow ? (target.id ?? \"foreach\") : `foreach:${(target as Agent<TContext, ElementOf<TOutput>, TNextOutput>).id}`;\n\n const node: StepNode = {\n type: \"step\",\n id,\n execute: async (state) => {\n const items = state.output;\n if (!Array.isArray(items)) {\n throw new Error(`foreach \"${id}\": expected array input, got ${typeof items}`);\n }\n\n const ctx = state.ctx as TContext;\n const results: unknown[] = new Array(items.length);\n const skipped = new Set<number>();\n\n // Streaming is intentionally not propagated to foreach items —\n // each item runs in generate mode because merging interleaved\n // streams from parallel items into a single writer is not supported.\n const executeItem = async (item: unknown, index: number) => {\n const itemState: RuntimeState = { ctx: state.ctx, output: item, mode: \"generate\" };\n if (isWorkflow) {\n await this.executeNestedWorkflow(itemState, target as SealedWorkflow<TContext, unknown, unknown, any>);\n } else {\n await this.executeAgent(itemState, target as Agent<TContext, unknown, TNextOutput>, ctx);\n }\n results[index] = itemState.output;\n };\n\n const handleRejection = async (error: unknown, item: unknown, index: number) => {\n if (!onError) throw error;\n const recovered = await onError({\n error,\n item: item as ElementOf<TOutput>,\n index,\n ctx: state.ctx as Readonly<TContext>,\n });\n if (recovered === Workflow.SKIP) {\n skipped.add(index);\n } else {\n results[index] = recovered;\n }\n };\n\n if (concurrency <= 1) {\n for (let i = 0; i < items.length; i++) {\n try {\n await executeItem(items[i], i);\n } catch (error) {\n await handleRejection(error, items[i], i);\n }\n }\n } else {\n // Bounded concurrency via semaphore: at most `concurrency` items run\n // simultaneously; the next one starts as soon as one releases.\n // Failures are buffered and processed in index order AFTER all items\n // settle so onError invocations remain deterministic.\n const sem = new Semaphore(concurrency);\n const failures: Array<{ index: number; error: unknown }> = [];\n\n await Promise.all(items.map(async (item, i) => {\n await sem.acquire();\n try {\n await executeItem(item, i);\n } catch (error) {\n failures.push({ index: i, error });\n } finally {\n sem.release();\n }\n }));\n\n failures.sort((a, b) => a.index - b.index);\n for (const { index, error } of failures) {\n await handleRejection(error, items[index], index);\n }\n }\n\n state.output = skipped.size === 0\n ? results\n : results.filter((_, i) => !skipped.has(i));\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TNextOutput[], TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── repeat: conditional loop ─────────────────────────────────\n\n repeat(\n target: Agent<TContext, TOutput, TOutput> | SealedWorkflow<TContext, TOutput, TOutput>,\n options: RepeatOptions<TContext, TOutput>,\n ): Workflow<TContext, TInput, TOutput, TGates> {\n const maxIterations = options.maxIterations ?? 10;\n const isWorkflow = target instanceof SealedWorkflow;\n const id = isWorkflow ? (target.id ?? \"repeat\") : `repeat:${(target as Agent<TContext, TOutput, TOutput>).id}`;\n const predicate: LoopPredicate<TContext, TOutput> = options.until\n ?? (async (p) => !(await options.while!(p)));\n\n const node: StepNode = {\n type: \"step\",\n id,\n execute: async (state) => {\n const ctx = state.ctx as TContext;\n\n for (let i = 1; i <= maxIterations; i++) {\n if (isWorkflow) {\n await this.executeNestedWorkflow(state, target as SealedWorkflow<TContext, unknown, unknown, any>);\n } else {\n await this.executeAgent(state, target as Agent<TContext, TOutput, TOutput>, ctx);\n }\n\n const done = await predicate({\n output: state.output as TOutput,\n ctx: ctx as Readonly<TContext>,\n iterations: i,\n });\n if (done) return;\n }\n\n throw new WorkflowLoopError(maxIterations, maxIterations);\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── catch ─────────────────────────────────────────────────────\n\n catch(\n id: string,\n fn: (params: { error: unknown; ctx: Readonly<TContext>; lastOutput: TOutput; stepId: string }) => MaybePromise<TOutput>\n ): Workflow<TContext, TInput, TOutput, TGates> {\n if (!this.steps.some(s => s.type === \"step\")) {\n throw new Error(`Workflow: catch(\"${id}\") requires at least one preceding step.`);\n }\n const node: StepNode = {\n type: \"catch\",\n id,\n catchFn: fn as (params: { error: unknown; ctx: unknown; lastOutput: unknown; stepId: string }) => MaybePromise<unknown>,\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new Workflow<TContext, TInput, TOutput, TGates>([...this.steps, node] as any, this.id);\n }\n\n // ── finally (terminal — returns sealed workflow) ──────────────\n\n finally(\n id: string,\n fn: (params: { ctx: Readonly<TContext> }) => MaybePromise<void>\n ): SealedWorkflow<TContext, TInput, TOutput, TGates> {\n const node: StepNode = {\n type: \"finally\",\n id,\n execute: async (state) => {\n await fn({ ctx: state.ctx as Readonly<TContext> });\n },\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new SealedWorkflow<TContext, TInput, TOutput, TGates>([...this.steps, node] as any, this.id);\n }\n}\n\n"],"mappings":"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","names":["import_ai","result","import_ai","node"]}
|