pipeai 0.3.0 → 0.8.1

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/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Tool, ToolExecutionOptions, UIMessageStreamWriter, FlexibleSchema, streamText, generateText, Output, LanguageModel, ModelMessage, ToolChoice, ToolSet, StopCondition, OnStepFinishEvent, OnFinishEvent, GenerateTextResult as GenerateTextResult$1, StreamTextResult as StreamTextResult$1 } from 'ai';
1
+ import { Tool, ToolExecutionOptions, UIMessageStreamWriter, FlexibleSchema, streamText, generateText, Output, LanguageModel, ModelMessage, ToolChoice, ToolSet, StopCondition, OnStepFinishEvent, OnFinishEvent, GenerateTextResult as GenerateTextResult$1, StreamTextResult as StreamTextResult$1, UIMessage, UIMessageStreamOnFinishCallback, IdGenerator } from 'ai';
2
2
  import { ZodType } from 'zod';
3
3
 
4
4
  declare const TOOL_PROVIDER_BRAND: unique symbol;
@@ -24,7 +24,38 @@ declare class ToolProvider<TContext, TInput = unknown, TOutput = unknown> implem
24
24
  createTool(context: Readonly<TContext>): Tool;
25
25
  }
26
26
  declare function defineTool<TContext>(): <TInput, TOutput>(config: ToolProviderConfig<TContext, TInput, TOutput>) => ToolProvider<TContext, TInput, TOutput>;
27
+ declare function isToolProvider<TContext>(obj: unknown): obj is IToolProvider<TContext>;
27
28
 
29
+ /**
30
+ * Returns the active `UIMessageStreamWriter` if the current async context is
31
+ * running inside a streaming workflow, or `undefined` otherwise.
32
+ *
33
+ * Use from inside a custom `IToolProvider`'s returned `Tool.execute` callback
34
+ * to forward incremental output to the workflow's UI message stream:
35
+ *
36
+ * ```ts
37
+ * import { getActiveWriter, type IToolProvider, TOOL_PROVIDER_BRAND } from "pipeai";
38
+ *
39
+ * const myProvider: IToolProvider<MyCtx> = {
40
+ * [TOOL_PROVIDER_BRAND]: true,
41
+ * createTool(ctx) {
42
+ * return tool({
43
+ * execute: async (input) => {
44
+ * const writer = getActiveWriter();
45
+ * // ...stream incremental progress to writer if present...
46
+ * return result;
47
+ * },
48
+ * });
49
+ * },
50
+ * };
51
+ * ```
52
+ *
53
+ * **Important timing note:** call this from *inside* the `Tool.execute`
54
+ * callback, not from inside `createTool` itself. `createTool` runs during
55
+ * agent setup (before the workflow has set the writer); `Tool.execute` runs
56
+ * during tool invocation (when the writer is live).
57
+ */
58
+ declare function getActiveWriter(): UIMessageStreamWriter | undefined;
28
59
  type MaybePromise<T> = T | Promise<T>;
29
60
  /**
30
61
  * A value that can be static or derived from context and input.
@@ -39,6 +70,16 @@ type OutputType<T = any> = ReturnType<typeof Output.object<T>>;
39
70
  type AgentToolSet<TContext> = Record<string, Tool | IToolProvider<TContext>>;
40
71
  type GenerateTextResult<TOOLS extends ToolSet = ToolSet, OUTPUT extends OutputType = OutputType> = GenerateTextResult$1<TOOLS, OUTPUT>;
41
72
  type StreamTextResult<TOOLS extends ToolSet = ToolSet, OUTPUT extends OutputType = OutputType> = StreamTextResult$1<TOOLS, OUTPUT>;
73
+ /**
74
+ * The result passed to `asTool` / `asToolProvider`'s `mapOutput`.
75
+ *
76
+ * The same agent may be invoked as a tool from a generate-mode parent
77
+ * (returns `GenerateTextResult`, sync `.text`/`.output`) or from a
78
+ * stream-mode parent (returns `StreamTextResult`, async `.text`/`.output`).
79
+ * The callsite cannot statically tell which mode it is in, so `mapOutput`
80
+ * receives the union and must `await` the relevant fields to support both.
81
+ */
82
+ type AsToolMapOutput<TOutput> = (result: GenerateTextResult<ToolSet, OutputType<TOutput>> | StreamTextResult<ToolSet, OutputType<TOutput>>) => MaybePromise<TOutput>;
42
83
  type StreamTextOptions = Parameters<typeof streamText>[0];
43
84
  type GenerateTextOptions = Parameters<typeof generateText>[0];
44
85
  type ManagedKeys = 'model' | 'system' | 'prompt' | 'messages' | 'tools' | 'activeTools' | 'toolChoice' | 'stopWhen' | 'output' | 'onFinish' | 'onStepFinish' | 'onError';
@@ -48,6 +89,13 @@ interface AgentConfig<TContext, TInput = void, TOutput = void> extends AIPassthr
48
89
  description?: string;
49
90
  input?: ZodType<TInput>;
50
91
  output?: OutputType<TOutput>;
92
+ /**
93
+ * Zod schema used to validate `output` after the AI SDK returns. Distinct
94
+ * from `tool.outputSchema` (AI SDK's tool-execution output schema): this
95
+ * runs **after** the SDK has parsed structured output, as a runtime guard
96
+ * against parse drift. If omitted, the parsed output is trusted as-is.
97
+ */
98
+ validateOutput?: ZodType<TOutput>;
51
99
  model: Resolvable<TContext, TInput, LanguageModel>;
52
100
  system?: Resolvable<TContext, TInput, string>;
53
101
  prompt?: Resolvable<TContext, TInput, string>;
@@ -55,7 +103,17 @@ interface AgentConfig<TContext, TInput = void, TOutput = void> extends AIPassthr
55
103
  tools?: Resolvable<TContext, TInput, AgentToolSet<TContext>>;
56
104
  activeTools?: Resolvable<TContext, TInput, string[]>;
57
105
  toolChoice?: Resolvable<TContext, TInput, ToolChoice<ToolSet>>;
58
- stopWhen?: Resolvable<TContext, TInput, StopCondition<ToolSet> | Array<StopCondition<ToolSet>>>;
106
+ /**
107
+ * Stop condition(s) for the tool loop. Pass either a single AI-SDK
108
+ * `StopCondition` (which is itself a function) or an array of them.
109
+ *
110
+ * **Not a `Resolvable`.** A `StopCondition` and a `(ctx, input) => StopCondition`
111
+ * resolver are both functions and cannot be safely distinguished at
112
+ * runtime, so this field intentionally does NOT accept the resolver
113
+ * form. If you need per-call dynamic stop conditions, build the agent
114
+ * inside your handler instead of using a static instance.
115
+ */
116
+ stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;
59
117
  onStepFinish?: (params: {
60
118
  result: OnStepFinishEvent;
61
119
  ctx: Readonly<TContext>;
@@ -79,6 +137,14 @@ declare class Agent<TContext, TInput = void, TOutput = void> {
79
137
  readonly id: string;
80
138
  readonly description: string;
81
139
  readonly hasOutput: boolean;
140
+ /**
141
+ * Zod schema used to validate the agent's structured `output` after the AI
142
+ * SDK returns. Distinct from `tool.outputSchema` (which validates tool
143
+ * execution output). Exposed (readonly) so external runners — notably the
144
+ * workflow runtime — can pass it through to `extractOutput` without
145
+ * re-plumbing it.
146
+ */
147
+ readonly validateOutput: ZodType<TOutput> | undefined;
82
148
  private readonly config;
83
149
  private readonly _hasDynamicConfig;
84
150
  private readonly _resolvedStaticTools;
@@ -86,15 +152,26 @@ declare class Agent<TContext, TInput = void, TOutput = void> {
86
152
  private readonly _onStepFinish;
87
153
  private readonly _onFinish;
88
154
  constructor(config: AgentConfig<TContext, TInput, TOutput>);
89
- generate(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<GenerateTextResult<ToolSet, OutputType<TOutput>>>;
90
- stream(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<StreamTextResult<ToolSet, OutputType<TOutput>>>;
155
+ generate(ctx: TContext, ...args: TInput extends void ? [input?: TInput, options?: {
156
+ abortSignal?: AbortSignal;
157
+ }] : [input: TInput, options?: {
158
+ abortSignal?: AbortSignal;
159
+ }]): Promise<GenerateTextResult<ToolSet, OutputType<TOutput>>>;
160
+ stream(ctx: TContext, ...args: TInput extends void ? [input?: TInput, options?: {
161
+ abortSignal?: AbortSignal;
162
+ }] : [input: TInput, options?: {
163
+ abortSignal?: AbortSignal;
164
+ }]): Promise<StreamTextResult<ToolSet, OutputType<TOutput>>>;
91
165
  asTool(ctx: TContext, options?: {
92
- mapOutput?: (result: GenerateTextResult<ToolSet, OutputType<TOutput>>) => MaybePromise<TOutput>;
166
+ mapOutput?: AsToolMapOutput<TOutput>;
93
167
  }): Tool;
94
168
  asToolProvider(options?: {
95
- mapOutput?: (result: GenerateTextResult<ToolSet, OutputType<TOutput>>) => MaybePromise<TOutput>;
169
+ mapOutput?: AsToolMapOutput<TOutput>;
96
170
  }): IToolProvider<TContext>;
97
171
  private createToolInstance;
172
+ private invokeOnError;
173
+ private generateWithOptions;
174
+ private streamWithOptions;
98
175
  private buildCallOptions;
99
176
  private resolveConfig;
100
177
  private resolveConfigAsync;
@@ -110,45 +187,271 @@ declare class WorkflowLoopError extends Error {
110
187
  readonly maxIterations: number;
111
188
  constructor(iterations: number, maxIterations: number);
112
189
  }
113
- interface WorkflowSnapshot {
190
+ declare class NestedGateUnsupportedError extends Error {
191
+ readonly gateId: string;
192
+ readonly workflowId: string | undefined;
193
+ readonly siblingErrors: readonly unknown[];
194
+ readonly siblingSuspensions: readonly {
195
+ index: number;
196
+ gateId: string;
197
+ }[];
198
+ constructor(gateId: string, workflowId: string | undefined, siblingErrors?: readonly unknown[], siblingSuspensions?: readonly {
199
+ index: number;
200
+ gateId: string;
201
+ }[]);
202
+ }
203
+ /**
204
+ * v2 gate snapshot. The `kind` discriminant differentiates it from
205
+ * checkpoint snapshots. The legacy v1 form is still accepted by `loadState`.
206
+ */
207
+ interface GateSnapshot {
208
+ readonly version: 2;
209
+ readonly kind: "gate";
210
+ readonly resumeFromIndex: number;
211
+ readonly output: unknown;
212
+ readonly gateId: string;
213
+ readonly gatePayload: unknown;
214
+ }
215
+ /**
216
+ * v2 checkpoint snapshot. Carries a step-shape hash; resume verifies the
217
+ * workflow definition hasn't drifted before continuing.
218
+ */
219
+ interface CheckpointSnapshot {
220
+ readonly version: 2;
221
+ readonly kind: "checkpoint";
222
+ readonly resumeFromIndex: number;
223
+ readonly output: unknown;
224
+ readonly stepShapeHash: string;
225
+ }
226
+ /**
227
+ * Legacy v0.4.0 gate-only snapshot. Accepted by `loadState` for one release
228
+ * via the shim path. `kind?: undefined` makes runtime narrowing on
229
+ * `kind === undefined` reachable — JSON round-trips strip the property.
230
+ * Migrate via `migrateSnapshot()` before v0.8.0+.
231
+ */
232
+ interface LegacyGateSnapshotV1 {
114
233
  readonly version: 1;
234
+ readonly kind?: undefined;
115
235
  readonly resumeFromIndex: number;
116
236
  readonly output: unknown;
117
237
  readonly gateId: string;
118
238
  readonly gatePayload: unknown;
119
239
  }
120
- declare class WorkflowSuspended extends Error {
121
- readonly snapshot: WorkflowSnapshot;
122
- constructor(snapshot: WorkflowSnapshot);
240
+ type WorkflowSnapshot = GateSnapshot | CheckpointSnapshot | LegacyGateSnapshotV1;
241
+ interface WorkflowWarning {
242
+ readonly source: "step" | "finally" | "catch" | "onCheckpoint" | "onStepStart" | "onStepFinish" | "onStepError" | "foreach-sibling";
243
+ readonly stepId: string;
244
+ readonly error: unknown;
123
245
  }
124
- interface AgentStepHooks<TContext, TOutput, TNextOutput> {
125
- mapGenerateResult?: (params: {
126
- result: GenerateTextResult<ToolSet, OutputType<TNextOutput>>;
127
- ctx: Readonly<TContext>;
128
- input: TOutput;
129
- }) => MaybePromise<TNextOutput>;
130
- mapStreamResult?: (params: {
131
- result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;
132
- ctx: Readonly<TContext>;
133
- input: TOutput;
134
- }) => MaybePromise<TNextOutput>;
135
- onGenerateResult?: (params: {
136
- result: GenerateTextResult<ToolSet, OutputType<TNextOutput>>;
137
- ctx: Readonly<TContext>;
138
- input: TOutput;
246
+ type WorkflowStepType = "step" | "nested" | "gate" | "catch" | "finally" | "branch" | "foreach" | "repeat" | "parallel";
247
+ /**
248
+ * Workflow observability hooks. All optional. Errors thrown inside hooks
249
+ * are captured into `result.warnings` with a matching `source` tag, except
250
+ * `onStepError`, which causes the run to throw the ORIGINAL step error with
251
+ * `error.cause = obsError` (preserving `instanceof` on the original).
252
+ *
253
+ * Per-node firing rules (where "step-like" = step / nested / branch /
254
+ * foreach / parallel / repeat):
255
+ * - step-like / gate (cond-true → suspends): onStepStart always; onStepFinish
256
+ * when body returns (suspended: true for gate, false otherwise); onStepError
257
+ * on body throw.
258
+ * - gate (cond false → skip): onStepStart, onStepFinish({ suspended: false }).
259
+ * - catch: onStepStart only when pendingError set; onStepFinish when catchFn
260
+ * returns; onStepError when catchFn throws.
261
+ * - finally: onStepStart always (runs even after suspension); onStepFinish
262
+ * always; onStepError when body throws.
263
+ * - foreach / parallel: emit ALSO per-item events (onItemStart/Finish/Error).
264
+ * - repeat: emit ONLY combinator-level events (no per-iteration events —
265
+ * iteration count is data-dependent and per-item would be misleading).
266
+ *
267
+ * Skip-checked nodes (`state.suspension || pendingError` already set on entry)
268
+ * emit nothing — `.finally()` is the exception.
269
+ */
270
+ interface WorkflowObservability {
271
+ onStepStart?: (event: {
272
+ stepId: string;
273
+ type: WorkflowStepType;
274
+ ctx: unknown;
275
+ input: unknown;
139
276
  }) => MaybePromise<void>;
140
- onStreamResult?: (params: {
141
- result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;
142
- ctx: Readonly<TContext>;
143
- input: TOutput;
277
+ onStepFinish?: (event: {
278
+ stepId: string;
279
+ type: WorkflowStepType;
280
+ ctx: unknown;
281
+ output: unknown;
282
+ durationMs: number;
283
+ suspended: boolean;
284
+ }) => MaybePromise<void>;
285
+ onStepError?: (event: {
286
+ stepId: string;
287
+ type: WorkflowStepType;
288
+ ctx: unknown;
289
+ error: unknown;
290
+ durationMs: number;
144
291
  }) => MaybePromise<void>;
292
+ onItemStart?: (event: {
293
+ stepId: string;
294
+ type: "foreach" | "parallel";
295
+ itemIndex: number | string;
296
+ ctx: unknown;
297
+ input: unknown;
298
+ }) => MaybePromise<void>;
299
+ onItemFinish?: (event: {
300
+ stepId: string;
301
+ type: "foreach" | "parallel";
302
+ itemIndex: number | string;
303
+ ctx: unknown;
304
+ output: unknown;
305
+ durationMs: number;
306
+ }) => MaybePromise<void>;
307
+ onItemError?: (event: {
308
+ stepId: string;
309
+ type: "foreach" | "parallel";
310
+ itemIndex: number | string;
311
+ ctx: unknown;
312
+ error: unknown;
313
+ durationMs: number;
314
+ }) => MaybePromise<void>;
315
+ }
316
+ interface RunOptions {
317
+ /**
318
+ * Step-level checkpoint sink. Called after each successful step body when
319
+ * `checkpointEvery` cadence or `checkpointWhen` predicate fires. Receives a
320
+ * v2 `CheckpointSnapshot` and an `AbortSignal` that aborts on
321
+ * `checkpointTimeout` expiration. Throwing here propagates to the caller
322
+ * as an error — workflow `.catch()` is bypassed for checkpoint failures.
323
+ */
324
+ readonly onCheckpoint?: (snapshot: CheckpointSnapshot, opts: {
325
+ signal: AbortSignal;
326
+ }) => MaybePromise<void>;
327
+ /**
328
+ * Fire `onCheckpoint` every N executable steps. Mutually exclusive with
329
+ * `checkpointWhen`. Default: `max(1, ceil(executableCount / 4))` —
330
+ * 4 checkpoints across the run, with a floor of every step on tiny pipelines.
331
+ */
332
+ readonly checkpointEvery?: number;
333
+ /**
334
+ * Predicate variant — fire `onCheckpoint` exactly when this returns true.
335
+ * Mutually exclusive with `checkpointEvery`.
336
+ */
337
+ readonly checkpointWhen?: (params: {
338
+ stepIndex: number;
339
+ stepId: string;
340
+ ctx: unknown;
341
+ }) => boolean;
342
+ /**
343
+ * When truthy, deeply freeze the gate / checkpoint snapshot and the
344
+ * `result.warnings` array. Default false. Pass `"iAcceptThePerformanceCost"`
345
+ * to bypass `validateRunOptions`' catastrophic-combo guard
346
+ * (freezeSnapshots: true + checkpointEvery: 1 + steps.length >= 8).
347
+ */
348
+ readonly freezeSnapshots?: boolean | "iAcceptThePerformanceCost";
349
+ /**
350
+ * Cooperative cancellation signal. Checked at every step boundary inside
351
+ * `execute()` and forwarded to agent calls in `executeAgent`, foreach
352
+ * workers, and nested workflows. When the signal aborts, the workflow
353
+ * tears down to `signal.reason` via the same pending-error path as any
354
+ * other step failure, so `.catch()` handlers still get a chance to
355
+ * observe (or recover from) the abort. `.finally()` bodies still run
356
+ * on the abort path. Unlike `freezeSnapshots`, this option DOES
357
+ * propagate into nested workflows, foreach items, and repeat loops —
358
+ * cancellation should be transitive.
359
+ */
360
+ readonly abortSignal?: AbortSignal;
361
+ /**
362
+ * Maximum ms `onCheckpoint` is allowed to run before its AbortSignal fires.
363
+ * On timeout, a `CheckpointTimeoutError` is raised on the run (catch is
364
+ * bypassed; original error reaches the caller). Default: no timeout.
365
+ */
366
+ readonly checkpointTimeout?: number;
367
+ }
368
+ /**
369
+ * Synthetic step id reported when `onCheckpoint` itself throws. Reserved
370
+ * via the construction-time `(type, id)` walk — user step ids may not
371
+ * contain the `::pipeai::` namespace.
372
+ */
373
+ declare const CHECKPOINT_STEP_ID: "::pipeai::onCheckpoint";
374
+ /**
375
+ * Thrown internally when `onCheckpoint` exceeds `RunOptions.checkpointTimeout`.
376
+ * Surfaces to the caller as the rejection error.
377
+ */
378
+ declare class CheckpointTimeoutError extends Error {
379
+ readonly timeoutMs: number;
380
+ constructor(timeoutMs: number);
381
+ }
382
+ /**
383
+ * Convert a legacy v1 gate snapshot to a v2 gate snapshot. Long-lived
384
+ * storage (Redis-without-TTL, S3, Postgres) should re-serialize via this
385
+ * helper before v0.8.0+ drops v1 acceptance.
386
+ */
387
+ declare function migrateSnapshot(legacy: LegacyGateSnapshotV1): GateSnapshot;
388
+ /**
389
+ * Discriminated union describing one agent invocation's result.
390
+ *
391
+ * - `mode: "generate"` — `result` is a `GenerateTextResult`; `.text`, `.output`,
392
+ * `.usage` etc. are synchronous (already-resolved).
393
+ * - `mode: "stream"` — `result` is a `StreamTextResult`; the same fields are
394
+ * `Promise`s that you must `await` before reading.
395
+ *
396
+ * The shared field set (`ctx`, `input`) is identical across both modes;
397
+ * narrowing on `mode` is only necessary when you need to touch a
398
+ * mode-specific shape.
399
+ */
400
+ type AgentResultParams<TContext, TOutput, TNextOutput> = {
401
+ readonly mode: "generate";
402
+ readonly result: GenerateTextResult<ToolSet, OutputType<TNextOutput>>;
403
+ readonly ctx: Readonly<TContext>;
404
+ readonly input: TOutput;
405
+ } | {
406
+ readonly mode: "stream";
407
+ readonly result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;
408
+ readonly ctx: Readonly<TContext>;
409
+ readonly input: TOutput;
410
+ };
411
+ interface AgentStepHooks<TContext, TOutput, TNextOutput> {
412
+ /**
413
+ * Transform the agent's result into the next step's input. Fires once per
414
+ * step regardless of generate-vs-stream mode; discriminate on `mode` if you
415
+ * need a mode-specific field. Returning the agent's `result.text` works
416
+ * for both modes (string vs Promise<string>) because `MaybePromise` accepts
417
+ * either.
418
+ *
419
+ * If omitted, the workflow's default extraction is used:
420
+ * - With `agent.output` declared → `extractOutput(result, agent.validateOutput)`
421
+ * - Without `agent.output` → `result.text` (awaited if stream)
422
+ */
423
+ mapResult?: (params: AgentResultParams<TContext, TOutput, TNextOutput>) => MaybePromise<TNextOutput>;
424
+ /**
425
+ * Observe the agent's result without changing the step's downstream value.
426
+ * Fires once per step regardless of mode. Use for logging, telemetry,
427
+ * usage accounting, side-effects that should not affect pipeline data
428
+ * flow.
429
+ */
430
+ onResult?: (params: AgentResultParams<TContext, TOutput, TNextOutput>) => MaybePromise<void>;
431
+ /**
432
+ * **Stream-mode only.** Override the workflow's default
433
+ * `writer.merge(result.toUIMessageStream())` call so YOU control how the
434
+ * agent's stream reaches the outer workflow's UI message stream. Useful
435
+ * for buffering, transforming, fan-out to multiple writers, or injecting
436
+ * custom UI messages around the agent's output.
437
+ *
438
+ * Has no generate-mode analog because in generate mode there is no stream
439
+ * to merge. If both `handleStream` and `mapResult`/`onResult` are
440
+ * configured, `handleStream` runs first.
441
+ */
145
442
  handleStream?: (params: {
146
443
  result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;
147
444
  writer: UIMessageStreamWriter;
148
445
  ctx: Readonly<TContext>;
446
+ input: TOutput;
149
447
  }) => MaybePromise<void>;
150
448
  }
151
- type StepOptions<TContext, TOutput, TNextOutput> = AgentStepHooks<TContext, TOutput, TNextOutput>;
449
+ type StepOptions<TContext, TOutput, TNextOutput> = AgentStepHooks<TContext, TOutput, TNextOutput> & {
450
+ /** Override the default step id (`agent.id`). Required when reusing the same
451
+ * agent across multiple steps in one workflow — the construction-time
452
+ * `(type, id)` walk rejects duplicates. */
453
+ id?: string;
454
+ };
152
455
  interface BranchCase<TContext, TOutput, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {
153
456
  when?: (params: {
154
457
  ctx: Readonly<TContext>;
@@ -161,19 +464,77 @@ interface BranchSelect<TContext, TOutput, TKeys extends string, TNextOutput> ext
161
464
  ctx: Readonly<TContext>;
162
465
  input: TOutput;
163
466
  }) => MaybePromise<TKeys>;
164
- agents: Record<TKeys, Agent<TContext, any, TNextOutput>>;
165
- fallback?: Agent<TContext, any, TNextOutput>;
166
- }
167
- interface WorkflowResult<TOutput> {
168
- output: TOutput;
467
+ agents: Record<TKeys, Agent<TContext, TOutput, TNextOutput>>;
468
+ fallback?: Agent<TContext, TOutput, TNextOutput>;
469
+ /**
470
+ * Diagnostic hook invoked when `select` returns a key that has no matching
471
+ * entry in `agents`. Fires BEFORE `fallback` is applied or
472
+ * `WorkflowBranchError` is thrown, regardless of whether a `fallback` is
473
+ * configured. Useful for logging typos / unexpected classifier output.
474
+ */
475
+ onUnknownKey?: (params: {
476
+ key: string;
477
+ availableKeys: TKeys[];
478
+ ctx: Readonly<TContext>;
479
+ }) => void;
169
480
  }
481
+ type WorkflowResult<TOutput> = {
482
+ readonly status: "complete";
483
+ readonly output: TOutput;
484
+ readonly warnings: readonly WorkflowWarning[];
485
+ } | {
486
+ readonly status: "suspended";
487
+ readonly snapshot: GateSnapshot;
488
+ readonly warnings: readonly WorkflowWarning[];
489
+ };
170
490
  interface WorkflowStreamResult<TOutput> {
171
491
  stream: ReadableStream;
172
- output: Promise<TOutput>;
492
+ output: Promise<WorkflowResult<TOutput>>;
173
493
  }
174
- interface WorkflowStreamOptions {
494
+ /**
495
+ * Options for `Workflow.stream` / `ResumedWorkflow.stream` /
496
+ * `CheckpointResumedWorkflow.stream`. Forwarded verbatim to the AI SDK's
497
+ * `createUIMessageStream`.
498
+ *
499
+ * Generic over the UI message shape so consumers with a custom
500
+ * `UIMessage<METADATA, DATA_PARTS, TOOLS>` get their narrowed type in
501
+ * `onFinish` / `originalMessages` instead of the unparameterized default.
502
+ *
503
+ * Note: AI SDK's `createUIMessageStream` ALSO accepts an `onStepFinish`
504
+ * (per-token-step) callback. We intentionally do NOT expose it here — there
505
+ * are already two clearer step-finish callbacks at different granularities:
506
+ * - `Agent.onStepFinish` for per-model-call observation, and
507
+ * - `WorkflowObservability.onStepFinish` for per-workflow-step observation.
508
+ * Adding a third one named the same thing on `WorkflowStreamOptions` would
509
+ * be confusing. Reach for one of the two above instead.
510
+ */
511
+ interface WorkflowStreamOptions<UI_MESSAGE extends UIMessage = UIMessage> {
512
+ /**
513
+ * Map an unknown error into a user-visible string. Forwarded as-is to
514
+ * `createUIMessageStream`'s `onError`. Returning `string` is required by
515
+ * the AI SDK — the string is what the stream emits to clients.
516
+ */
175
517
  onError?: (error: unknown) => string;
176
- onFinish?: () => MaybePromise<void>;
518
+ /**
519
+ * Prior `UIMessage`s the stream should continue from. When provided, the
520
+ * AI SDK assumes persistence mode and assigns a response-message id.
521
+ * Used for chat resumption / continuation flows.
522
+ */
523
+ originalMessages?: UI_MESSAGE[];
524
+ /**
525
+ * Fires once the stream finishes, with the full payload the AI SDK
526
+ * delivers: the updated `messages` array, the freshly-emitted
527
+ * `responseMessage`, `isAborted` / `isContinuation` flags, and the
528
+ * `finishReason`. Use this for persistence, analytics, or downstream
529
+ * notification.
530
+ */
531
+ onFinish?: UIMessageStreamOnFinishCallback<UI_MESSAGE>;
532
+ /**
533
+ * Override the response message-id generator. Forwarded to
534
+ * `createUIMessageStream`'s `generateId` option. Useful for deterministic
535
+ * IDs in tests or coordinating with a server-side ID space.
536
+ */
537
+ generateId?: IdGenerator;
177
538
  }
178
539
  type LoopPredicate<TContext, TOutput> = (params: {
179
540
  output: TOutput;
@@ -190,13 +551,58 @@ type RepeatOptions<TContext, TOutput> = {
190
551
  maxIterations?: number;
191
552
  };
192
553
  type ElementOf<T> = T extends readonly (infer E)[] ? E : never;
554
+ /** A target for a `parallel()` branch — agent or sealed workflow. */
555
+ type ParallelTarget<TContext, TInput> = Agent<TContext, TInput, any> | SealedWorkflow<TContext, TInput, any>;
556
+ /** Extract the output type of a single parallel branch target. */
557
+ type BranchOutput<T> = T extends Agent<any, any, infer O> ? O : T extends SealedWorkflow<any, any, infer O> ? O : never;
558
+ /** Output shape for the record form: `{ [K]: BranchOutput<T[K]> }`. */
559
+ type ParallelOutputRecord<T extends Record<string, unknown>> = {
560
+ [K in keyof T]: BranchOutput<T[K]>;
561
+ };
562
+ /** Output shape for the tuple form: `[O1, O2, ...]`. */
563
+ type ParallelOutputTuple<T extends ReadonlyArray<unknown>> = {
564
+ [K in keyof T]: BranchOutput<T[K]>;
565
+ };
566
+ interface ParallelOptions<TContext> {
567
+ /** Override the default step id. Default: `parallel:record` or `parallel:tuple`. */
568
+ id?: string;
569
+ /**
570
+ * Max branches in flight at any moment. Default: `min(branches.length, 5)`.
571
+ * Pass `Infinity` (or `branches.length`) for full fan-out on >5-branch calls
572
+ * — the default caps at 5 to protect against rate limits and emits a
573
+ * one-time warn when the cap kicks in.
574
+ */
575
+ concurrency?: number;
576
+ /**
577
+ * Per-branch error handler. On the no-suspension path, called once per
578
+ * rejected branch in index order after all settle. Return a value to
579
+ * substitute, return `Workflow.SKIP` to leave the slot undefined (record
580
+ * form only — tuple SKIP would shift indices), or rethrow to abort the
581
+ * parallel.
582
+ *
583
+ * **Bypassed entirely on the suspension path** (any branch hit a nested
584
+ * gate). See README's "Suspension under `parallel()`" section.
585
+ */
586
+ onError?: (params: {
587
+ error: unknown;
588
+ /** Branch key in the record form; `undefined` in the tuple form. */
589
+ key?: string;
590
+ /** Branch index in the tuple form; `undefined` in the record form. */
591
+ index?: number;
592
+ ctx: Readonly<TContext>;
593
+ }) => unknown | typeof Workflow.SKIP | Promise<unknown | typeof Workflow.SKIP>;
594
+ }
193
595
  interface SchemaWithParse<T = unknown> {
194
596
  parse(data: unknown): T;
195
597
  }
598
+ type StepCategory = "step" | "nested" | "branch" | "foreach" | "repeat" | "parallel";
196
599
  type StepNode = {
197
600
  readonly type: "step";
198
601
  readonly id: string;
199
602
  readonly execute: (state: RuntimeState) => MaybePromise<void>;
603
+ readonly nestedWorkflow?: SealedWorkflow<any, any, any, any>;
604
+ /** Disambiguates observability events. Default `"step"`. */
605
+ readonly category?: StepCategory;
200
606
  } | {
201
607
  readonly type: "catch";
202
608
  readonly id: string;
@@ -226,32 +632,129 @@ interface RuntimeState {
226
632
  output: unknown;
227
633
  mode: "generate" | "stream";
228
634
  writer?: UIMessageStreamWriter;
635
+ suspension?: GateSnapshot;
636
+ warnings?: WorkflowWarning[];
637
+ checkpointFailed?: boolean;
638
+ runOptions?: RunOptions;
639
+ abortSignal?: AbortSignal;
229
640
  }
641
+ type PendingError = {
642
+ error: unknown;
643
+ stepId: string;
644
+ source: "step" | "finally" | "catch" | "onCheckpoint";
645
+ };
230
646
  declare class SealedWorkflow<TContext, TInput = void, TOutput = void, TGates extends Record<string, unknown> = {}> {
231
647
  readonly id?: string;
232
648
  protected readonly steps: ReadonlyArray<StepNode>;
233
- protected constructor(steps: ReadonlyArray<StepNode>, id?: string);
234
- generate(ctx: TContext, ...args: TInput extends void ? [input?: TInput] : [input: TInput]): Promise<WorkflowResult<TOutput>>;
235
- stream(ctx: TContext, ...args: TInput extends void ? [input?: TInput, options?: WorkflowStreamOptions] : [input: TInput, options?: WorkflowStreamOptions]): WorkflowStreamResult<TOutput>;
236
- protected execute(state: RuntimeState, startIndex?: number): Promise<void>;
649
+ protected readonly observability?: WorkflowObservability;
650
+ private duplicateCheckPassed;
651
+ private _cachedExecutableStepCount?;
652
+ private _cachedStepShapeHash?;
653
+ protected constructor(steps: ReadonlyArray<StepNode>, id?: string, observability?: WorkflowObservability);
654
+ /**
655
+ * Walk the step list once per terminal instance. Rejects:
656
+ * - Duplicate `(type, id)` pairs.
657
+ * - User step ids containing the reserved `::pipeai::` namespace
658
+ * (CHECKPOINT_STEP_ID lives there).
659
+ */
660
+ private ensureDuplicateCheck;
661
+ /**
662
+ * Count of executable nodes — i.e. NOT `catch` or `finally`. Drives
663
+ * checkpoint auto-cadence so adding cleanup steps doesn't surprise users
664
+ * with extra fires. `branch`/`foreach`/`repeat`/`parallel`/`nested` are all
665
+ * `type: "step"` internally and count as executable.
666
+ */
667
+ protected get cachedExecutableStepCount(): number;
668
+ /** @internal — used by `computeStepShapeHash` to descend nested workflows. */
669
+ getStepsForShapeHash(): ReadonlyArray<StepNode>;
670
+ protected get cachedStepShapeHash(): string;
671
+ /**
672
+ * Validate user-provided RunOptions before a run begins. Throws on
673
+ * outright errors and on the loud-disaster combo (`freezeSnapshots: true
674
+ * + checkpointEvery: 1` on a workflow of 8+ steps). Warns once on the
675
+ * merely-suspicious combo (`freezeSnapshots: true + cadence <= 2`).
676
+ * Plan-of-record: catastrophic combo escape via the
677
+ * `"iAcceptThePerformanceCost"` literal.
678
+ */
679
+ protected validateRunOptions(opts: RunOptions | undefined): void;
680
+ /**
681
+ * Fire an observability hook safely. Returns `undefined` synchronously when
682
+ * no hook is registered — avoiding the promise wrapper + microtask that an
683
+ * async function would unconditionally allocate on every step boundary.
684
+ *
685
+ * On hook throw:
686
+ * - non-`onStepError` hooks: warning pushed + console.error.
687
+ * - `onStepError`: throw is propagated as a return value; the run loop
688
+ * attaches it as `cause` on the original step error.
689
+ *
690
+ * Returns the hook's thrown error if any; undefined otherwise. Callers
691
+ * `await` the result — `await undefined` is sync, so the no-hook path
692
+ * stays allocation-free.
693
+ */
694
+ protected fireHook<K extends keyof WorkflowObservability, E extends Parameters<NonNullable<WorkflowObservability[K]>>[0]>(state: RuntimeState, name: K, event: E): MaybePromise<unknown>;
695
+ private fireHookSlow;
696
+ generate(ctx: TContext, ...args: TInput extends void ? [input?: TInput, opts?: RunOptions] : [input: TInput, opts?: RunOptions]): Promise<WorkflowResult<TOutput>>;
697
+ stream<UI_MESSAGE extends UIMessage = UIMessage>(ctx: TContext, ...args: TInput extends void ? [input?: TInput, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions] : [input: TInput, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]): WorkflowStreamResult<TOutput>;
698
+ protected buildResult(state: RuntimeState): WorkflowResult<TOutput>;
699
+ protected execute(state: RuntimeState, startIndex?: number, opts?: RunOptions, initialError?: PendingError | null): Promise<void>;
237
700
  protected executeNestedWorkflow(state: RuntimeState, workflow: SealedWorkflow<TContext, unknown, unknown, any>): Promise<void>;
238
701
  protected executeAgent<TAgentInput, TNextOutput>(state: RuntimeState, agent: Agent<TContext, any, TNextOutput>, ctx: TContext, options?: AgentStepHooks<TContext, any, TNextOutput>): Promise<void>;
239
702
  loadState<K extends string & keyof TGates>(gateId: K, snapshot: WorkflowSnapshot): ResumedWorkflow<TContext, TGates[K], TOutput>;
703
+ /**
704
+ * Resume from a checkpoint snapshot. Validates the step-shape hash unless
705
+ * `{ skipShapeCheck: true }` is passed. Throws on:
706
+ * - gate snapshots (use `loadState` instead)
707
+ * - missing/corrupted `stepShapeHash`
708
+ * - shape mismatch (unless skipped)
709
+ * - out-of-bounds `resumeFromIndex`
710
+ * - 0-step workflow (structural invariant)
711
+ *
712
+ * Returns a `CheckpointResumedWorkflow` whose `generate(ctx, opts?)` takes
713
+ * NO response arg — the state is seeded from the snapshot's output. The
714
+ * matching gate-resume path (`loadState`) keeps the `response` arg.
715
+ */
716
+ resumeFrom(snapshot: WorkflowSnapshot, options?: {
717
+ skipShapeCheck?: boolean;
718
+ }): CheckpointResumedWorkflow<TContext, TOutput>;
719
+ /**
720
+ * Append a `.finally()` body to a sealed workflow, returning another sealed
721
+ * workflow. Allows multi-finally chains (`.finally().finally()`). A throwing
722
+ * `.finally` body does NOT abort subsequent ones — they all run.
723
+ */
724
+ finally(id: string, fn: (params: {
725
+ ctx: Readonly<TContext>;
726
+ }) => MaybePromise<void>): SealedWorkflow<TContext, TInput, TOutput, TGates>;
240
727
  private findGateIndex;
241
728
  }
729
+ interface ResumedWorkflowConfig {
730
+ readonly mode: "gate" | "checkpoint";
731
+ readonly schema?: SchemaWithParse<unknown>;
732
+ readonly mergeFn?: (params: {
733
+ priorOutput: unknown;
734
+ response: unknown;
735
+ }) => MaybePromise<unknown>;
736
+ readonly priorOutput?: unknown;
737
+ readonly snapshot?: WorkflowSnapshot;
738
+ readonly observability?: WorkflowObservability;
739
+ }
242
740
  declare class ResumedWorkflow<TContext, TResponse = unknown, TOutput = void> extends SealedWorkflow<TContext, TResponse, TOutput> {
243
741
  private readonly startIndex;
244
742
  private readonly schema?;
245
743
  private readonly mergeFn?;
246
744
  private readonly priorOutput;
247
745
  /** @internal */
248
- constructor(steps: ReadonlyArray<StepNode>, startIndex: number, schema?: SchemaWithParse<TResponse>, mergeFn?: (params: {
249
- priorOutput: unknown;
250
- response: unknown;
251
- }) => MaybePromise<unknown>, priorOutput?: unknown);
746
+ constructor(steps: ReadonlyArray<StepNode>, startIndex: number, config: ResumedWorkflowConfig);
252
747
  private validateResponse;
253
- generate(ctx: TContext, ...args: TResponse extends void ? [response?: TResponse] : [response: TResponse]): Promise<WorkflowResult<TOutput>>;
254
- stream(ctx: TContext, ...args: TResponse extends void ? [response?: TResponse, options?: WorkflowStreamOptions] : [response: TResponse, options?: WorkflowStreamOptions]): WorkflowStreamResult<TOutput>;
748
+ generate(ctx: TContext, ...args: TResponse extends void ? [response?: TResponse, opts?: RunOptions] : [response: TResponse, opts?: RunOptions]): Promise<WorkflowResult<TOutput>>;
749
+ stream<UI_MESSAGE extends UIMessage = UIMessage>(ctx: TContext, ...args: TResponse extends void ? [response?: TResponse, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions] : [response: TResponse, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]): WorkflowStreamResult<TOutput>;
750
+ }
751
+ declare class CheckpointResumedWorkflow<TContext, TOutput = void> extends SealedWorkflow<TContext, void, TOutput> {
752
+ private readonly startIndex;
753
+ private readonly priorOutput;
754
+ /** @internal */
755
+ constructor(steps: ReadonlyArray<StepNode>, startIndex: number, config: ResumedWorkflowConfig);
756
+ generate(ctx: TContext, ...args: [input?: void, opts?: RunOptions]): Promise<WorkflowResult<TOutput>>;
757
+ stream<UI_MESSAGE extends UIMessage = UIMessage>(ctx: TContext, ...args: [input?: void, options?: WorkflowStreamOptions<UI_MESSAGE>, opts?: RunOptions]): WorkflowStreamResult<TOutput>;
255
758
  }
256
759
  declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends Record<string, unknown> = {}> extends SealedWorkflow<TContext, TInput, TOutput, TGates> {
257
760
  /**
@@ -263,8 +766,10 @@ declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends R
263
766
  private constructor();
264
767
  static create<TContext, TInput = void>(options?: {
265
768
  id?: string;
769
+ observability?: WorkflowObservability;
266
770
  }): Workflow<TContext, TInput, TInput>;
267
771
  static from<TContext, TInput, TOutput>(agent: Agent<TContext, TInput, TOutput>, options?: StepOptions<TContext, TInput, TOutput>): Workflow<TContext, TInput, TOutput>;
772
+ private appendStep;
268
773
  step<TNextOutput>(agent: Agent<TContext, TOutput, TNextOutput>, options?: StepOptions<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates>;
269
774
  step<TNextOutput>(workflow: SealedWorkflow<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates>;
270
775
  step<TNextOutput>(id: string, fn: (params: {
@@ -286,26 +791,32 @@ declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends R
286
791
  response: TResponse;
287
792
  }) => MaybePromise<TResponse>;
288
793
  }): Workflow<TContext, TInput, TResponse, TGates & Record<Id, TResponse>>;
289
- branch<TNextOutput>(cases: BranchCase<TContext, TOutput, TNextOutput>[]): Workflow<TContext, TInput, TNextOutput, TGates>;
290
- branch<TKeys extends string, TNextOutput>(config: BranchSelect<TContext, TOutput, TKeys, TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates>;
794
+ branch<TNextOutput>(cases: BranchCase<TContext, TOutput, TNextOutput>[], options?: {
795
+ id?: string;
796
+ }): Workflow<TContext, TInput, TNextOutput, TGates>;
797
+ branch<TKeys extends string, TNextOutput>(config: BranchSelect<TContext, TOutput, TKeys, TNextOutput>, options?: {
798
+ id?: string;
799
+ }): Workflow<TContext, TInput, TNextOutput, TGates>;
291
800
  private branchPredicate;
292
801
  private branchSelect;
293
802
  /**
294
803
  * Map each item of an array through an agent or sub-workflow.
295
804
  *
296
805
  * @param target Agent or `SealedWorkflow` invoked once per item.
806
+ * @param options.id Override the default step id (`foreach:<agentId>` or
807
+ * the workflow's id). Required when chaining multiple foreach over the same
808
+ * target — the construction-time `(type, id)` walk rejects duplicates.
297
809
  * @param options.concurrency Max items in flight at any moment (default 1).
298
810
  * Backed by a semaphore: as soon as one item completes, the next launches —
299
811
  * no lockstep batching.
300
- * @param options.onError Per-iteration error handler. When provided, a single
301
- * item's failure no longer aborts the foreach. Return a `TNextOutput` value
302
- * to substitute for the failed item, return `Workflow.SKIP` to omit the
303
- * index (shortening the output array), or throw / return a rejected promise
304
- * to abort the foreach step (the thrown error is caught by any downstream
305
- * `.catch()`). When omitted, the existing fail-fast behavior is preserved.
306
- * `onError` is invoked sequentially in index order after all items settle.
812
+ * @param options.onError Per-iteration error handler. **Bypassed entirely on
813
+ * the suspension path** (when any item hits a nested gate) — see the
814
+ * foreach concurrency hazards in the README. Otherwise: return a
815
+ * `TNextOutput` value to substitute, return `Workflow.SKIP` to omit, throw
816
+ * to abort. Invoked sequentially in index order after all items settle.
307
817
  */
308
818
  foreach<TNextOutput>(target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput>, options?: {
819
+ id?: string;
309
820
  concurrency?: number;
310
821
  onError?: (params: {
311
822
  error: unknown;
@@ -314,16 +825,21 @@ declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends R
314
825
  ctx: Readonly<TContext>;
315
826
  }) => MaybePromise<TNextOutput | typeof Workflow.SKIP>;
316
827
  }): Workflow<TContext, TInput, TNextOutput[], TGates>;
317
- repeat(target: Agent<TContext, TOutput, TOutput> | SealedWorkflow<TContext, TOutput, TOutput>, options: RepeatOptions<TContext, TOutput>): Workflow<TContext, TInput, TOutput, TGates>;
828
+ /** Record-form overload. Returns `{ [K]: BranchOutput<T[K]> }`. */
829
+ parallel<TBranches extends Record<string, ParallelTarget<TContext, TOutput>>>(branches: TBranches, options?: ParallelOptions<TContext>): Workflow<TContext, TInput, ParallelOutputRecord<TBranches>, TGates>;
830
+ /** Tuple-form overload. Returns `[O1, O2, ...]`. Use `as const`. */
831
+ parallel<TBranches extends ReadonlyArray<ParallelTarget<TContext, TOutput>>>(branches: TBranches, options?: ParallelOptions<TContext>): Workflow<TContext, TInput, ParallelOutputTuple<TBranches>, TGates>;
832
+ repeat(target: Agent<TContext, TOutput, TOutput> | SealedWorkflow<TContext, TOutput, TOutput>, options: RepeatOptions<TContext, TOutput> & {
833
+ id?: string;
834
+ }): Workflow<TContext, TInput, TOutput, TGates>;
318
835
  catch(id: string, fn: (params: {
319
836
  error: unknown;
320
837
  ctx: Readonly<TContext>;
321
838
  lastOutput: TOutput;
322
839
  stepId: string;
323
840
  }) => MaybePromise<TOutput>): Workflow<TContext, TInput, TOutput, TGates>;
324
- finally(id: string, fn: (params: {
325
- ctx: Readonly<TContext>;
326
- }) => MaybePromise<void>): SealedWorkflow<TContext, TInput, TOutput, TGates>;
327
841
  }
328
842
 
329
- export { Agent, type AgentConfig, type AgentStepHooks, type BranchCase, type BranchSelect, type GenerateTextResult, type IToolProvider, type MaybePromise, type OutputType, type RepeatOptions, type Resolvable, ResumedWorkflow, SealedWorkflow, type StepOptions, type StreamTextResult, type ToolExecuteOptions, type ToolProviderConfig, Workflow, WorkflowBranchError, WorkflowLoopError, type WorkflowResult, type WorkflowSnapshot, type WorkflowStreamOptions, type WorkflowStreamResult, WorkflowSuspended, defineTool };
843
+ declare const SKIP: symbol;
844
+
845
+ export { Agent, type AgentConfig, type AgentResultParams, type AgentStepHooks, type AsToolMapOutput, type BranchCase, type BranchSelect, CHECKPOINT_STEP_ID, CheckpointResumedWorkflow, type CheckpointSnapshot, CheckpointTimeoutError, type GateSnapshot, type GenerateTextResult, type IToolProvider, type LegacyGateSnapshotV1, type MaybePromise, NestedGateUnsupportedError, type OutputType, type ParallelOptions, type ParallelOutputRecord, type ParallelOutputTuple, type ParallelTarget, type RepeatOptions, type Resolvable, ResumedWorkflow, type RunOptions, SKIP, SealedWorkflow, type StepOptions, type StreamTextResult, TOOL_PROVIDER_BRAND, type ToolExecuteOptions, ToolProvider, type ToolProviderConfig, Workflow, WorkflowBranchError, WorkflowLoopError, type WorkflowObservability, type WorkflowResult, type WorkflowSnapshot, type WorkflowStepType, type WorkflowStreamOptions, type WorkflowStreamResult, type WorkflowWarning, defineTool, getActiveWriter, isToolProvider, migrateSnapshot };