pipeai 0.8.2 → 0.8.4
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 +75 -12
- package/dist/index.cjs +1154 -937
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +337 -131
- package/dist/index.d.ts +337 -131
- package/dist/index.js +1152 -934
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -26,36 +26,6 @@ declare class ToolProvider<TContext, TInput = unknown, TOutput = unknown> implem
|
|
|
26
26
|
declare function defineTool<TContext>(): <TInput, TOutput>(config: ToolProviderConfig<TContext, TInput, TOutput>) => ToolProvider<TContext, TInput, TOutput>;
|
|
27
27
|
declare function isToolProvider<TContext>(obj: unknown): obj is IToolProvider<TContext>;
|
|
28
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;
|
|
59
29
|
type MaybePromise<T> = T | Promise<T>;
|
|
60
30
|
/**
|
|
61
31
|
* A value that can be static or derived from context and input.
|
|
@@ -178,28 +148,7 @@ declare class Agent<TContext, TInput = void, TOutput = void> {
|
|
|
178
148
|
private resolveTools;
|
|
179
149
|
}
|
|
180
150
|
|
|
181
|
-
|
|
182
|
-
readonly branchType: "predicate" | "select";
|
|
183
|
-
constructor(branchType: "predicate" | "select", message: string);
|
|
184
|
-
}
|
|
185
|
-
declare class WorkflowLoopError extends Error {
|
|
186
|
-
readonly iterations: number;
|
|
187
|
-
readonly maxIterations: number;
|
|
188
|
-
constructor(iterations: number, maxIterations: number);
|
|
189
|
-
}
|
|
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
|
-
}
|
|
151
|
+
type SkipSentinel = typeof Workflow.SKIP;
|
|
203
152
|
/**
|
|
204
153
|
* v2 gate snapshot. The `kind` discriminant differentiates it from
|
|
205
154
|
* checkpoint snapshots. The legacy v1 form is still accepted by `loadState`.
|
|
@@ -211,6 +160,15 @@ interface GateSnapshot {
|
|
|
211
160
|
readonly output: unknown;
|
|
212
161
|
readonly gateId: string;
|
|
213
162
|
readonly gatePayload: unknown;
|
|
163
|
+
/**
|
|
164
|
+
* Path of nested-workflow step indices from the ROOT workflow down to the
|
|
165
|
+
* workflow that owns the gate, outermost-first. Absent/empty for a top-level
|
|
166
|
+
* gate. Each `.step(workflow)` the suspension bubbles through prepends its own
|
|
167
|
+
* step index, so {@link SealedWorkflow.loadState} can descend back to the
|
|
168
|
+
* gate on resume. (`resumeFromIndex` is the gate's index within that
|
|
169
|
+
* innermost workflow; `gateId` is the innermost gate's id.)
|
|
170
|
+
*/
|
|
171
|
+
readonly nestedPath?: readonly number[];
|
|
214
172
|
}
|
|
215
173
|
/**
|
|
216
174
|
* v2 checkpoint snapshot. Carries a step-shape hash; resume verifies the
|
|
@@ -239,7 +197,7 @@ interface LegacyGateSnapshotV1 {
|
|
|
239
197
|
}
|
|
240
198
|
type WorkflowSnapshot = GateSnapshot | CheckpointSnapshot | LegacyGateSnapshotV1;
|
|
241
199
|
interface WorkflowWarning {
|
|
242
|
-
readonly source: "step" | "finally" | "catch" | "onCheckpoint" | "onStepStart" | "onStepFinish" | "onStepError" | "foreach-sibling";
|
|
200
|
+
readonly source: "step" | "gate" | "finally" | "catch" | "onCheckpoint" | "onStepStart" | "onStepFinish" | "onStepError" | "onItemStart" | "onItemFinish" | "onItemError" | "foreach-sibling";
|
|
243
201
|
readonly stepId: string;
|
|
244
202
|
readonly error: unknown;
|
|
245
203
|
}
|
|
@@ -255,6 +213,9 @@ type WorkflowStepType = "step" | "nested" | "gate" | "catch" | "finally" | "bran
|
|
|
255
213
|
* - step-like / gate (cond-true → suspends): onStepStart always; onStepFinish
|
|
256
214
|
* when body returns (suspended: true for gate, false otherwise); onStepError
|
|
257
215
|
* on body throw.
|
|
216
|
+
* - step-like (`when` → false → skip): onStepStart, onStepFinish({ suspended:
|
|
217
|
+
* false }) with the passthrough/`otherwise` value as `output`. A skipped
|
|
218
|
+
* step's body never runs, but it is still bracketed by start/finish.
|
|
258
219
|
* - gate (cond false → skip): onStepStart, onStepFinish({ suspended: false }).
|
|
259
220
|
* - catch: onStepStart only when pendingError set; onStepFinish when catchFn
|
|
260
221
|
* returns; onStepError when catchFn throws.
|
|
@@ -267,17 +228,17 @@ type WorkflowStepType = "step" | "nested" | "gate" | "catch" | "finally" | "bran
|
|
|
267
228
|
* Skip-checked nodes (`state.suspension || pendingError` already set on entry)
|
|
268
229
|
* emit nothing — `.finally()` is the exception.
|
|
269
230
|
*/
|
|
270
|
-
interface WorkflowObservability {
|
|
231
|
+
interface WorkflowObservability<TContext = unknown> {
|
|
271
232
|
onStepStart?: (event: {
|
|
272
233
|
stepId: string;
|
|
273
234
|
type: WorkflowStepType;
|
|
274
|
-
ctx:
|
|
235
|
+
ctx: TContext;
|
|
275
236
|
input: unknown;
|
|
276
237
|
}) => MaybePromise<void>;
|
|
277
238
|
onStepFinish?: (event: {
|
|
278
239
|
stepId: string;
|
|
279
240
|
type: WorkflowStepType;
|
|
280
|
-
ctx:
|
|
241
|
+
ctx: TContext;
|
|
281
242
|
output: unknown;
|
|
282
243
|
durationMs: number;
|
|
283
244
|
suspended: boolean;
|
|
@@ -285,7 +246,7 @@ interface WorkflowObservability {
|
|
|
285
246
|
onStepError?: (event: {
|
|
286
247
|
stepId: string;
|
|
287
248
|
type: WorkflowStepType;
|
|
288
|
-
ctx:
|
|
249
|
+
ctx: TContext;
|
|
289
250
|
error: unknown;
|
|
290
251
|
durationMs: number;
|
|
291
252
|
}) => MaybePromise<void>;
|
|
@@ -293,14 +254,14 @@ interface WorkflowObservability {
|
|
|
293
254
|
stepId: string;
|
|
294
255
|
type: "foreach" | "parallel";
|
|
295
256
|
itemIndex: number | string;
|
|
296
|
-
ctx:
|
|
257
|
+
ctx: TContext;
|
|
297
258
|
input: unknown;
|
|
298
259
|
}) => MaybePromise<void>;
|
|
299
260
|
onItemFinish?: (event: {
|
|
300
261
|
stepId: string;
|
|
301
262
|
type: "foreach" | "parallel";
|
|
302
263
|
itemIndex: number | string;
|
|
303
|
-
ctx:
|
|
264
|
+
ctx: TContext;
|
|
304
265
|
output: unknown;
|
|
305
266
|
durationMs: number;
|
|
306
267
|
}) => MaybePromise<void>;
|
|
@@ -308,7 +269,7 @@ interface WorkflowObservability {
|
|
|
308
269
|
stepId: string;
|
|
309
270
|
type: "foreach" | "parallel";
|
|
310
271
|
itemIndex: number | string;
|
|
311
|
-
ctx:
|
|
272
|
+
ctx: TContext;
|
|
312
273
|
error: unknown;
|
|
313
274
|
durationMs: number;
|
|
314
275
|
}) => MaybePromise<void>;
|
|
@@ -317,12 +278,15 @@ interface RunOptions {
|
|
|
317
278
|
/**
|
|
318
279
|
* Step-level checkpoint sink. Called after each successful step body when
|
|
319
280
|
* `checkpointEvery` cadence or `checkpointWhen` predicate fires. Receives a
|
|
320
|
-
* v2 `CheckpointSnapshot` and
|
|
321
|
-
*
|
|
281
|
+
* v2 `CheckpointSnapshot` and the run's `abortSignal` (or `undefined` when
|
|
282
|
+
* the run wasn't given one), so a cancelled run can tear down an in-flight
|
|
283
|
+
* write if the callback honors it. Throwing here propagates to the caller
|
|
322
284
|
* as an error — workflow `.catch()` is bypassed for checkpoint failures.
|
|
285
|
+
* There is no framework-imposed timeout; bound the write yourself by racing
|
|
286
|
+
* the passed `signal` against your own timer if you need one.
|
|
323
287
|
*/
|
|
324
288
|
readonly onCheckpoint?: (snapshot: CheckpointSnapshot, opts: {
|
|
325
|
-
signal: AbortSignal;
|
|
289
|
+
signal: AbortSignal | undefined;
|
|
326
290
|
}) => MaybePromise<void>;
|
|
327
291
|
/**
|
|
328
292
|
* Fire `onCheckpoint` every N executable steps. Mutually exclusive with
|
|
@@ -349,42 +313,20 @@ interface RunOptions {
|
|
|
349
313
|
/**
|
|
350
314
|
* Cooperative cancellation signal. Checked at every step boundary inside
|
|
351
315
|
* `execute()` and forwarded to agent calls in `executeAgent`, foreach
|
|
352
|
-
* workers,
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
316
|
+
* workers, parallel branches, nested workflows, and the `onCheckpoint`
|
|
317
|
+
* callback's `signal` (so a cancelled run can tear down an in-flight
|
|
318
|
+
* checkpoint write, if the callback honors it). When the signal aborts,
|
|
319
|
+
* the workflow tears down to `signal.reason` via the same pending-error path
|
|
320
|
+
* as any other step failure, so `.catch()` handlers still get a chance to
|
|
321
|
+
* observe the abort (e.g. for logging/cleanup) — but an abort is sticky and
|
|
322
|
+
* non-recoverable: even a terminal `.catch()` that returns a value cannot
|
|
323
|
+
* make the run complete; it still rejects with `signal.reason`. `.finally()`
|
|
324
|
+
* bodies still run on the abort path. Unlike `freezeSnapshots`, this option DOES
|
|
325
|
+
* propagate into nested workflows, foreach items, parallel branches, and
|
|
326
|
+
* repeat loops — cancellation should be transitive.
|
|
359
327
|
*/
|
|
360
328
|
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
329
|
}
|
|
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
330
|
/**
|
|
389
331
|
* Discriminated union describing one agent invocation's result.
|
|
390
332
|
*
|
|
@@ -438,20 +380,70 @@ interface AgentStepHooks<TContext, TOutput, TNextOutput> {
|
|
|
438
380
|
* Has no generate-mode analog because in generate mode there is no stream
|
|
439
381
|
* to merge. If both `handleStream` and `mapResult`/`onResult` are
|
|
440
382
|
* configured, `handleStream` runs first.
|
|
383
|
+
*
|
|
384
|
+
* `itemIndex` identifies the execution when this hook runs inside a
|
|
385
|
+
* multi-execution combinator: the numeric index for `foreach` and tuple
|
|
386
|
+
* `parallel`, the key for record `parallel`, and the matched key / case
|
|
387
|
+
* index for `branch`. It is `undefined` for a plain single `.step(agent)`.
|
|
441
388
|
*/
|
|
442
389
|
handleStream?: (params: {
|
|
443
390
|
result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;
|
|
444
391
|
writer: UIMessageStreamWriter;
|
|
445
392
|
ctx: Readonly<TContext>;
|
|
446
393
|
input: TOutput;
|
|
394
|
+
itemIndex?: number | string;
|
|
447
395
|
}) => MaybePromise<void>;
|
|
448
396
|
}
|
|
449
|
-
|
|
397
|
+
/**
|
|
398
|
+
* Predicate gating whether a step runs. Receives the step's input. When it
|
|
399
|
+
* returns false the step is skipped — its body (agent / fn / sub-workflow) is
|
|
400
|
+
* never invoked.
|
|
401
|
+
*/
|
|
402
|
+
type StepWhen<TContext, TOutput> = (params: {
|
|
403
|
+
ctx: Readonly<TContext>;
|
|
404
|
+
input: TOutput;
|
|
405
|
+
}) => MaybePromise<boolean>;
|
|
406
|
+
/**
|
|
407
|
+
* Produces the step's output when `when` returns false. With it, a skipped
|
|
408
|
+
* step's output is `otherwise(...)` (typed `TNextOutput`, so the step's output
|
|
409
|
+
* type stays `TNextOutput`). Without it, a skipped step passes its input
|
|
410
|
+
* through unchanged (output type widens to `TOutput | TNextOutput`).
|
|
411
|
+
*/
|
|
412
|
+
type StepOtherwise<TContext, TOutput, TNextOutput> = (params: {
|
|
413
|
+
ctx: Readonly<TContext>;
|
|
414
|
+
input: TOutput;
|
|
415
|
+
}) => MaybePromise<TNextOutput>;
|
|
416
|
+
/** Conditional-skip options shared by all `step` forms. */
|
|
417
|
+
interface ConditionalStepOptions<TContext, TOutput, TNextOutput> {
|
|
418
|
+
/** Run the step only when this returns true. Omit to always run. */
|
|
419
|
+
when?: StepWhen<TContext, TOutput>;
|
|
420
|
+
/**
|
|
421
|
+
* Skip value when `when` is false. Omit for passthrough (input unchanged).
|
|
422
|
+
* Has no effect without `when` — a lone `otherwise` is never invoked.
|
|
423
|
+
*/
|
|
424
|
+
otherwise?: StepOtherwise<TContext, TOutput, TNextOutput>;
|
|
425
|
+
}
|
|
426
|
+
type StepOptions<TContext, TOutput, TNextOutput> = AgentStepHooks<TContext, TOutput, TNextOutput> & ConditionalStepOptions<TContext, TOutput, TNextOutput> & {
|
|
450
427
|
/** Override the default step id (`agent.id`). Required when reusing the same
|
|
451
428
|
* agent across multiple steps in one workflow — the construction-time
|
|
452
429
|
* `(type, id)` walk rejects duplicates. */
|
|
453
430
|
id?: string;
|
|
454
431
|
};
|
|
432
|
+
/** Options for the inline `step(id, fn, options?)` form — conditional skip only. */
|
|
433
|
+
type InlineStepOptions<TContext, TOutput, TNextOutput> = ConditionalStepOptions<TContext, TOutput, TNextOutput>;
|
|
434
|
+
/** Options for the nested `step(workflow, options?)` form — conditional skip + id override. */
|
|
435
|
+
type NestedStepOptions<TContext, TOutput, TNextOutput> = ConditionalStepOptions<TContext, TOutput, TNextOutput> & {
|
|
436
|
+
id?: string;
|
|
437
|
+
};
|
|
438
|
+
/**
|
|
439
|
+
* A step that supplies `when` without `otherwise` may skip to passthrough, so
|
|
440
|
+
* its output widens to `TOutput | TNextOutput`. Supplying `otherwise` (which
|
|
441
|
+
* returns `TNextOutput`) — or omitting `when` — keeps the output `TNextOutput`.
|
|
442
|
+
*/
|
|
443
|
+
type SkipPassthrough<TContext, TOutput, TNextOutput> = ConditionalStepOptions<TContext, TOutput, TNextOutput> & {
|
|
444
|
+
when: StepWhen<TContext, TOutput>;
|
|
445
|
+
otherwise?: undefined;
|
|
446
|
+
};
|
|
455
447
|
interface BranchCase<TContext, TOutput, TNextOutput> extends AgentStepHooks<TContext, TOutput, TNextOutput> {
|
|
456
448
|
when?: (params: {
|
|
457
449
|
ctx: Readonly<TContext>;
|
|
@@ -541,6 +533,14 @@ type LoopPredicate<TContext, TOutput> = (params: {
|
|
|
541
533
|
ctx: Readonly<TContext>;
|
|
542
534
|
iterations: number;
|
|
543
535
|
}) => MaybePromise<boolean>;
|
|
536
|
+
/**
|
|
537
|
+
* Loop control for `repeat`. Exactly one of `until` / `while` — never both.
|
|
538
|
+
*
|
|
539
|
+
* Both forms are **do-while**: the body always runs at least once, then the
|
|
540
|
+
* predicate is checked. This is intentional — the predicate receives the
|
|
541
|
+
* body's `output`, which doesn't exist until the body has run — but it means
|
|
542
|
+
* `while: () => false` still executes the body once (it is not a pre-check).
|
|
543
|
+
*/
|
|
544
544
|
type RepeatOptions<TContext, TOutput> = {
|
|
545
545
|
until: LoopPredicate<TContext, TOutput>;
|
|
546
546
|
while?: never;
|
|
@@ -551,6 +551,20 @@ type RepeatOptions<TContext, TOutput> = {
|
|
|
551
551
|
maxIterations?: number;
|
|
552
552
|
};
|
|
553
553
|
type ElementOf<T> = T extends readonly (infer E)[] ? E : never;
|
|
554
|
+
/**
|
|
555
|
+
* Brand that makes a *gated* workflow unassignable where gates are forbidden —
|
|
556
|
+
* `foreach` / `parallel` / `repeat` targets. A nested gate can't suspend one
|
|
557
|
+
* branch of a concurrent fan-out or one iteration of a loop, so it's rejected
|
|
558
|
+
* at build time. Since `.step(workflow)` folds child gates into `TGates`, this
|
|
559
|
+
* catches gates at ANY nesting depth, not just direct ones.
|
|
560
|
+
*/
|
|
561
|
+
type GatesForbidden = {
|
|
562
|
+
readonly __agent_workflow_error__: "a workflow with gate(s) cannot be a foreach / parallel / repeat target";
|
|
563
|
+
};
|
|
564
|
+
/** `unknown` when `TG` has no gate keys (no-op intersection), else the {@link GatesForbidden} brand. */
|
|
565
|
+
type NoGates<TG extends Record<string, unknown>> = [keyof TG] extends [never] ? unknown : GatesForbidden;
|
|
566
|
+
/** A `parallel` branch with its gates checked: gated workflows resolve to the {@link GatesForbidden} brand. */
|
|
567
|
+
type GatelessBranch<T> = T extends SealedWorkflow<any, any, any, infer G> ? ([keyof G] extends [never] ? T : GatesForbidden) : T;
|
|
554
568
|
/** A target for a `parallel()` branch — agent or sealed workflow. */
|
|
555
569
|
type ParallelTarget<TContext, TInput> = Agent<TContext, TInput, any> | SealedWorkflow<TContext, TInput, any>;
|
|
556
570
|
/** Extract the output type of a single parallel branch target. */
|
|
@@ -563,25 +577,40 @@ type ParallelOutputRecord<T extends Record<string, unknown>> = {
|
|
|
563
577
|
type ParallelOutputTuple<T extends ReadonlyArray<unknown>> = {
|
|
564
578
|
[K in keyof T]: BranchOutput<T[K]>;
|
|
565
579
|
};
|
|
566
|
-
|
|
580
|
+
/**
|
|
581
|
+
* Record output when `onError` is supplied: any branch may be `SKIP`ped,
|
|
582
|
+
* leaving its slot `undefined`, so every value is widened to `| undefined`.
|
|
583
|
+
*/
|
|
584
|
+
type ParallelOutputRecordPartial<T extends Record<string, unknown>> = {
|
|
585
|
+
[K in keyof T]: BranchOutput<T[K]> | undefined;
|
|
586
|
+
};
|
|
587
|
+
/** Tuple counterpart of `ParallelOutputRecordPartial` — each slot `| undefined`. */
|
|
588
|
+
type ParallelOutputTuplePartial<T extends ReadonlyArray<unknown>> = {
|
|
589
|
+
[K in keyof T]: BranchOutput<T[K]> | undefined;
|
|
590
|
+
};
|
|
591
|
+
interface ParallelOptions<TContext, TOutput = unknown> {
|
|
567
592
|
/** Override the default step id. Default: `parallel:record` or `parallel:tuple`. */
|
|
568
593
|
id?: string;
|
|
569
594
|
/**
|
|
570
|
-
* Max branches in flight at any moment. Default: `
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
* one-time warn when the cap kicks in.
|
|
595
|
+
* Max branches in flight at any moment. **Default: unbounded** (`Infinity` —
|
|
596
|
+
* all branches run concurrently, clamped only by branch count). Pass an
|
|
597
|
+
* integer to throttle against provider rate limits.
|
|
574
598
|
*/
|
|
575
599
|
concurrency?: number;
|
|
576
600
|
/**
|
|
577
601
|
* Per-branch error handler. On the no-suspension path, called once per
|
|
578
602
|
* rejected branch in index order after all settle. Return a value to
|
|
579
|
-
* substitute, return `Workflow.SKIP` to leave the slot undefined
|
|
580
|
-
*
|
|
581
|
-
*
|
|
603
|
+
* substitute, return `Workflow.SKIP` to leave the slot `undefined`, or
|
|
604
|
+
* rethrow to abort the parallel. A throw (or rethrow) aborts immediately:
|
|
605
|
+
* rejected branches at indices AFTER the throwing one are neither recovered
|
|
606
|
+
* nor surfaced as warnings. SKIP works in both the record and tuple
|
|
607
|
+
* forms (the slot stays `undefined` in place — it does not shift indices);
|
|
608
|
+
* supplying `onError` widens the output values to `BranchOutput | undefined`
|
|
609
|
+
* to reflect that a slot may be skipped.
|
|
582
610
|
*
|
|
583
611
|
* **Bypassed entirely on the suspension path** (any branch hit a nested
|
|
584
|
-
* gate)
|
|
612
|
+
* gate) and on the cancellation path (the run was aborted). See README's
|
|
613
|
+
* "Suspension under `parallel()`" section.
|
|
585
614
|
*/
|
|
586
615
|
onError?: (params: {
|
|
587
616
|
error: unknown;
|
|
@@ -590,11 +619,61 @@ interface ParallelOptions<TContext> {
|
|
|
590
619
|
/** Branch index in the tuple form; `undefined` in the record form. */
|
|
591
620
|
index?: number;
|
|
592
621
|
ctx: Readonly<TContext>;
|
|
593
|
-
}) => unknown |
|
|
622
|
+
}) => unknown | SkipSentinel | Promise<unknown | SkipSentinel>;
|
|
623
|
+
/**
|
|
624
|
+
* **Stream-mode + agent-branch only.** When the workflow is run via
|
|
625
|
+
* `.stream(...)`, each agent branch runs in stream mode and this hook decides
|
|
626
|
+
* how its stream surfaces to the writer (`itemIndex` = the record key or the
|
|
627
|
+
* tuple index). Without it, agent branches run in generate mode (no
|
|
628
|
+
* auto-merge). Not invoked for `SealedWorkflow` branches (which stream
|
|
629
|
+
* transitively via their own steps) nor in generate mode.
|
|
630
|
+
*/
|
|
631
|
+
handleStream?: (params: {
|
|
632
|
+
result: StreamTextResult<ToolSet, any>;
|
|
633
|
+
writer: UIMessageStreamWriter;
|
|
634
|
+
ctx: Readonly<TContext>;
|
|
635
|
+
input: TOutput;
|
|
636
|
+
itemIndex: number | string;
|
|
637
|
+
}) => MaybePromise<void>;
|
|
594
638
|
}
|
|
595
639
|
interface SchemaWithParse<T = unknown> {
|
|
596
640
|
parse(data: unknown): T;
|
|
597
641
|
}
|
|
642
|
+
|
|
643
|
+
declare class WorkflowBranchError extends Error {
|
|
644
|
+
readonly branchType: "predicate" | "select";
|
|
645
|
+
constructor(branchType: "predicate" | "select", message: string);
|
|
646
|
+
}
|
|
647
|
+
declare class WorkflowLoopError extends Error {
|
|
648
|
+
readonly iterations: number;
|
|
649
|
+
readonly maxIterations: number;
|
|
650
|
+
constructor(iterations: number, maxIterations: number);
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Synthetic step id reported when `onCheckpoint` itself throws. Reserved
|
|
654
|
+
* via the construction-time `(type, id)` walk — user step ids may not
|
|
655
|
+
* contain the `::pipeai::` namespace.
|
|
656
|
+
*/
|
|
657
|
+
declare const CHECKPOINT_STEP_ID: "::pipeai::onCheckpoint";
|
|
658
|
+
/**
|
|
659
|
+
* Synthetic step id carried by the pending-error a cancellation promotes
|
|
660
|
+
* (surfaced to `.catch()` / observability). Lives in the reserved
|
|
661
|
+
* `::pipeai::` namespace so it can't be confused with a user step literally
|
|
662
|
+
* named "abort".
|
|
663
|
+
*/
|
|
664
|
+
declare const ABORT_STEP_ID: "::pipeai::abort";
|
|
665
|
+
/**
|
|
666
|
+
* Synthetic step id used when a gate-resume's response validation / merge
|
|
667
|
+
* throws before the pipeline re-enters `execute()`. Reserved-namespaced for
|
|
668
|
+
* the same reason as {@link ABORT_STEP_ID}.
|
|
669
|
+
*/
|
|
670
|
+
declare const GATE_RESUME_STEP_ID: "::pipeai::gate:resume";
|
|
671
|
+
/**
|
|
672
|
+
* Convert a legacy v1 gate snapshot to a v2 gate snapshot. Long-lived
|
|
673
|
+
* storage (Redis-without-TTL, S3, Postgres) should re-serialize via this
|
|
674
|
+
* helper before v0.8.0+ drops v1 acceptance.
|
|
675
|
+
*/
|
|
676
|
+
declare function migrateSnapshot(legacy: LegacyGateSnapshotV1): GateSnapshot;
|
|
598
677
|
type StepCategory = "step" | "nested" | "branch" | "foreach" | "repeat" | "parallel";
|
|
599
678
|
type StepNode = {
|
|
600
679
|
readonly type: "step";
|
|
@@ -606,12 +685,7 @@ type StepNode = {
|
|
|
606
685
|
} | {
|
|
607
686
|
readonly type: "catch";
|
|
608
687
|
readonly id: string;
|
|
609
|
-
readonly
|
|
610
|
-
error: unknown;
|
|
611
|
-
ctx: unknown;
|
|
612
|
-
lastOutput: unknown;
|
|
613
|
-
stepId: string;
|
|
614
|
-
}) => MaybePromise<unknown>;
|
|
688
|
+
readonly execute: (state: RuntimeState) => MaybePromise<void>;
|
|
615
689
|
} | {
|
|
616
690
|
readonly type: "finally";
|
|
617
691
|
readonly id: string;
|
|
@@ -619,9 +693,8 @@ type StepNode = {
|
|
|
619
693
|
} | {
|
|
620
694
|
readonly type: "gate";
|
|
621
695
|
readonly id: string;
|
|
622
|
-
readonly
|
|
696
|
+
readonly execute: (state: RuntimeState) => MaybePromise<void>;
|
|
623
697
|
readonly schema?: SchemaWithParse;
|
|
624
|
-
readonly condition?: (state: RuntimeState) => MaybePromise<boolean>;
|
|
625
698
|
readonly merge?: (params: {
|
|
626
699
|
priorOutput: unknown;
|
|
627
700
|
response: unknown;
|
|
@@ -635,13 +708,39 @@ interface RuntimeState {
|
|
|
635
708
|
suspension?: GateSnapshot;
|
|
636
709
|
warnings?: WorkflowWarning[];
|
|
637
710
|
checkpointFailed?: boolean;
|
|
711
|
+
pendingError?: PendingError;
|
|
638
712
|
runOptions?: RunOptions;
|
|
639
713
|
abortSignal?: AbortSignal;
|
|
714
|
+
stepIndex?: number;
|
|
715
|
+
resumeDescent?: ResumeDescent;
|
|
640
716
|
}
|
|
717
|
+
/**
|
|
718
|
+
* Drives resume re-entry for a gate that suspended inside nested workflows.
|
|
719
|
+
* `remaining` is the list of child start-indices to descend through, one per
|
|
720
|
+
* nesting level, ending with the innermost gate's `resumeFromIndex + 1`. When a
|
|
721
|
+
* `NestedWorkflowStep` consumes the LAST entry it first seeds `state.output`
|
|
722
|
+
* with `seedOutput` (the merged gate response) before running the innermost
|
|
723
|
+
* child from that index.
|
|
724
|
+
*/
|
|
725
|
+
type ResumeDescent = {
|
|
726
|
+
readonly remaining: readonly number[];
|
|
727
|
+
readonly seedOutput: unknown;
|
|
728
|
+
};
|
|
641
729
|
type PendingError = {
|
|
642
730
|
error: unknown;
|
|
643
731
|
stepId: string;
|
|
644
|
-
source: "step" | "finally" | "catch" | "onCheckpoint";
|
|
732
|
+
source: "step" | "gate" | "finally" | "catch" | "onCheckpoint";
|
|
733
|
+
};
|
|
734
|
+
/**
|
|
735
|
+
* Seed for a run: the initial pipeline `output` plus an optional pre-execute
|
|
736
|
+
* `initialError`. The resume entry points compute these differently (gate
|
|
737
|
+
* schema-parse + merge vs. plain snapshot output), but every entry point then
|
|
738
|
+
* funnels through the same `runGenerate` / `runStream` machinery.
|
|
739
|
+
*/
|
|
740
|
+
type StateSeed = {
|
|
741
|
+
output: unknown;
|
|
742
|
+
initialError: PendingError | null;
|
|
743
|
+
resumeDescent?: ResumeDescent;
|
|
645
744
|
};
|
|
646
745
|
declare class SealedWorkflow<TContext, TInput = void, TOutput = void, TGates extends Record<string, unknown> = {}> {
|
|
647
746
|
readonly id?: string;
|
|
@@ -649,6 +748,7 @@ declare class SealedWorkflow<TContext, TInput = void, TOutput = void, TGates ext
|
|
|
649
748
|
protected readonly observability?: WorkflowObservability;
|
|
650
749
|
private duplicateCheckPassed;
|
|
651
750
|
private _cachedExecutableStepCount?;
|
|
751
|
+
private _cachedCheckpointableStepCount?;
|
|
652
752
|
private _cachedStepShapeHash?;
|
|
653
753
|
protected constructor(steps: ReadonlyArray<StepNode>, id?: string, observability?: WorkflowObservability);
|
|
654
754
|
/**
|
|
@@ -665,6 +765,16 @@ declare class SealedWorkflow<TContext, TInput = void, TOutput = void, TGates ext
|
|
|
665
765
|
* `type: "step"` internally and count as executable.
|
|
666
766
|
*/
|
|
667
767
|
protected get cachedExecutableStepCount(): number;
|
|
768
|
+
/**
|
|
769
|
+
* Count of *checkpointable* nodes — `type === "step"` only (this includes
|
|
770
|
+
* `branch`/`foreach`/`repeat`/`parallel`/`nested`, all internally `step`).
|
|
771
|
+
* Drives the checkpoint auto-cadence denominator. Distinct from
|
|
772
|
+
* {@link cachedExecutableStepCount}, which also counts `gate` nodes: gates
|
|
773
|
+
* suspend/skip and never reach the checkpoint block, so the runtime
|
|
774
|
+
* `executableStepsSeen` counter never advances on them. Counting gates in
|
|
775
|
+
* the denominator would dilute the "~4 checkpoints across the run" target.
|
|
776
|
+
*/
|
|
777
|
+
protected get cachedCheckpointableStepCount(): number;
|
|
668
778
|
/** @internal — used by `computeStepShapeHash` to descend nested workflows. */
|
|
669
779
|
getStepsForShapeHash(): ReadonlyArray<StepNode>;
|
|
670
780
|
protected get cachedStepShapeHash(): string;
|
|
@@ -692,13 +802,44 @@ declare class SealedWorkflow<TContext, TInput = void, TOutput = void, TGates ext
|
|
|
692
802
|
* stays allocation-free.
|
|
693
803
|
*/
|
|
694
804
|
protected fireHook<K extends keyof WorkflowObservability, E extends Parameters<NonNullable<WorkflowObservability[K]>>[0]>(state: RuntimeState, name: K, event: E): MaybePromise<unknown>;
|
|
695
|
-
|
|
805
|
+
protected hasItemHooks(): boolean;
|
|
806
|
+
/**
|
|
807
|
+
* Fire `onStepError` for a step-body failure and honor the documented
|
|
808
|
+
* cause-attachment contract uniformly across every firing path (step, gate,
|
|
809
|
+
* catch, finally, checkpoint). When the hook itself throws, its error is
|
|
810
|
+
* attached as `cause` on the ORIGINAL error so the original still reaches the
|
|
811
|
+
* caller with the failure trail attached. If the original error is frozen /
|
|
812
|
+
* non-extensible (cause assignment throws) or is not an object, the hook
|
|
813
|
+
* error is recorded as a warning instead — so an `onStepError` throw is never
|
|
814
|
+
* silently lost. (The suspension-wins tail fires `onStepError` separately, on
|
|
815
|
+
* its own demotion path.)
|
|
816
|
+
*/
|
|
817
|
+
protected fireStepErrorAndAttachCause(state: RuntimeState, event: {
|
|
818
|
+
stepId: string;
|
|
819
|
+
type: WorkflowStepType;
|
|
820
|
+
ctx: unknown;
|
|
821
|
+
error: unknown;
|
|
822
|
+
durationMs: number;
|
|
823
|
+
}): Promise<void>;
|
|
696
824
|
generate(ctx: TContext, ...args: TInput extends void ? [input?: TInput, opts?: RunOptions] : [input: TInput, opts?: RunOptions]): Promise<WorkflowResult<TOutput>>;
|
|
697
825
|
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
826
|
protected buildResult(state: RuntimeState): WorkflowResult<TOutput>;
|
|
827
|
+
protected runGenerate(ctx: unknown, startIndex: number, opts: RunOptions | undefined, seed: () => MaybePromise<StateSeed>): Promise<WorkflowResult<TOutput>>;
|
|
828
|
+
protected runStream<UI_MESSAGE extends UIMessage = UIMessage>(ctx: unknown, startIndex: number, opts: RunOptions | undefined, options: WorkflowStreamOptions<UI_MESSAGE> | undefined, seed: () => MaybePromise<StateSeed>): WorkflowStreamResult<TOutput>;
|
|
699
829
|
protected execute(state: RuntimeState, startIndex?: number, opts?: RunOptions, initialError?: PendingError | null): Promise<void>;
|
|
700
|
-
|
|
701
|
-
|
|
830
|
+
/**
|
|
831
|
+
* Run THIS sealed workflow as a nested step on the caller's run `state`.
|
|
832
|
+
* Public (internal; not re-exported from index) so `Step` subclasses —
|
|
833
|
+
* `nested` / `repeat` / `foreach` / `parallel` with `SealedWorkflow` targets
|
|
834
|
+
* — can run a sub-workflow without reaching the protected `execute`.
|
|
835
|
+
*
|
|
836
|
+
* Contract: RunOptions is run-scoped, so the child never inherits the
|
|
837
|
+
* parent's (`state.warnings` IS propagated — telemetry > config). A gate
|
|
838
|
+
* inside the child leaves `state.suspension` set so it propagates up (only a
|
|
839
|
+
* `.step(workflow)` ever does this — concurrent/looped combinators forbid
|
|
840
|
+
* gated targets at build time).
|
|
841
|
+
*/
|
|
842
|
+
executeAsNested(state: RuntimeState, startIndex?: number): Promise<void>;
|
|
702
843
|
loadState<K extends string & keyof TGates>(gateId: K, snapshot: WorkflowSnapshot): ResumedWorkflow<TContext, TGates[K], TOutput>;
|
|
703
844
|
/**
|
|
704
845
|
* Resume from a checkpoint snapshot. Validates the step-shape hash unless
|
|
@@ -719,7 +860,9 @@ declare class SealedWorkflow<TContext, TInput = void, TOutput = void, TGates ext
|
|
|
719
860
|
/**
|
|
720
861
|
* Append a `.finally()` body to a sealed workflow, returning another sealed
|
|
721
862
|
* workflow. Allows multi-finally chains (`.finally().finally()`). A throwing
|
|
722
|
-
* `.finally` body
|
|
863
|
+
* `.finally` body bubbles straight out of the run: it is non-recoverable, does
|
|
864
|
+
* NOT aggregate with a prior error, and subsequent `.finally()` bodies do not
|
|
865
|
+
* run. (See {@link FinallyStep} for the full contract.)
|
|
723
866
|
*/
|
|
724
867
|
finally(id: string, fn: (params: {
|
|
725
868
|
ctx: Readonly<TContext>;
|
|
@@ -736,15 +879,31 @@ interface ResumedWorkflowConfig {
|
|
|
736
879
|
readonly priorOutput?: unknown;
|
|
737
880
|
readonly snapshot?: WorkflowSnapshot;
|
|
738
881
|
readonly observability?: WorkflowObservability;
|
|
882
|
+
/**
|
|
883
|
+
* Set only for a NESTED gate resume: the descent (child start-indices per
|
|
884
|
+
* level, innermost-last) the merged gate response rides down to the suspended
|
|
885
|
+
* child. When present, `startIndex` is the ROOT's nested-step index and the
|
|
886
|
+
* seed sets `state.resumeDescent` instead of the root `output`.
|
|
887
|
+
*/
|
|
888
|
+
readonly nestedRemaining?: readonly number[];
|
|
739
889
|
}
|
|
740
890
|
declare class ResumedWorkflow<TContext, TResponse = unknown, TOutput = void> extends SealedWorkflow<TContext, TResponse, TOutput> {
|
|
741
891
|
private readonly startIndex;
|
|
742
892
|
private readonly schema?;
|
|
743
893
|
private readonly mergeFn?;
|
|
744
894
|
private readonly priorOutput;
|
|
895
|
+
private readonly nestedRemaining?;
|
|
745
896
|
/** @internal */
|
|
746
897
|
constructor(steps: ReadonlyArray<StepNode>, startIndex: number, config: ResumedWorkflowConfig);
|
|
747
898
|
private validateResponse;
|
|
899
|
+
/**
|
|
900
|
+
* Seed the run by validating the gate response and merging it with the
|
|
901
|
+
* suspended output. Runs schema.parse + mergeFn inside a try so a failure
|
|
902
|
+
* becomes a pre-execute `initialError` (routed through `.catch()`) rather
|
|
903
|
+
* than escaping the run synchronously. On error the output falls back to the
|
|
904
|
+
* prior (pre-gate) output.
|
|
905
|
+
*/
|
|
906
|
+
private seedFromResponse;
|
|
748
907
|
generate(ctx: TContext, ...args: TResponse extends void ? [response?: TResponse, opts?: RunOptions] : [response: TResponse, opts?: RunOptions]): Promise<WorkflowResult<TOutput>>;
|
|
749
908
|
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
909
|
}
|
|
@@ -766,17 +925,25 @@ declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends R
|
|
|
766
925
|
private constructor();
|
|
767
926
|
static create<TContext, TInput = void>(options?: {
|
|
768
927
|
id?: string;
|
|
769
|
-
observability?: WorkflowObservability
|
|
928
|
+
observability?: WorkflowObservability<TContext>;
|
|
770
929
|
}): Workflow<TContext, TInput, TInput>;
|
|
930
|
+
static from<TContext, TInput, TOutput>(agent: Agent<TContext, TInput, TOutput>, options: StepOptions<TContext, TInput, TOutput> & SkipPassthrough<TContext, TInput, TOutput>): Workflow<TContext, TInput, TInput | TOutput>;
|
|
771
931
|
static from<TContext, TInput, TOutput>(agent: Agent<TContext, TInput, TOutput>, options?: StepOptions<TContext, TInput, TOutput>): Workflow<TContext, TInput, TOutput>;
|
|
772
932
|
private appendStep;
|
|
933
|
+
step<TNextOutput>(agent: Agent<TContext, TOutput, TNextOutput>, options: StepOptions<TContext, TOutput, TNextOutput> & SkipPassthrough<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TOutput | TNextOutput, TGates>;
|
|
773
934
|
step<TNextOutput>(agent: Agent<TContext, TOutput, TNextOutput>, options?: StepOptions<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates>;
|
|
774
|
-
step<TNextOutput>(workflow: SealedWorkflow<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates>;
|
|
935
|
+
step<TNextOutput, TChildGates extends Record<string, unknown> = {}>(workflow: SealedWorkflow<TContext, TOutput, TNextOutput, TChildGates>, options: NestedStepOptions<TContext, TOutput, TNextOutput> & SkipPassthrough<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TOutput | TNextOutput, TGates & TChildGates>;
|
|
936
|
+
step<TNextOutput, TChildGates extends Record<string, unknown> = {}>(workflow: SealedWorkflow<TContext, TOutput, TNextOutput, TChildGates>, options?: NestedStepOptions<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates & TChildGates>;
|
|
937
|
+
step<TNextOutput>(id: string, fn: (params: {
|
|
938
|
+
ctx: Readonly<TContext>;
|
|
939
|
+
input: TOutput;
|
|
940
|
+
writer?: UIMessageStreamWriter;
|
|
941
|
+
}) => MaybePromise<TNextOutput>, options: InlineStepOptions<TContext, TOutput, TNextOutput> & SkipPassthrough<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TOutput | TNextOutput, TGates>;
|
|
775
942
|
step<TNextOutput>(id: string, fn: (params: {
|
|
776
943
|
ctx: Readonly<TContext>;
|
|
777
944
|
input: TOutput;
|
|
778
945
|
writer?: UIMessageStreamWriter;
|
|
779
|
-
}) => MaybePromise<TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates>;
|
|
946
|
+
}) => MaybePromise<TNextOutput>, options?: InlineStepOptions<TContext, TOutput, TNextOutput>): Workflow<TContext, TInput, TNextOutput, TGates>;
|
|
780
947
|
gate<TResponse = TOutput, Id extends string = string>(id: Id & (Id extends keyof TGates ? never : Id), options?: {
|
|
781
948
|
payload?: (params: {
|
|
782
949
|
ctx: Readonly<TContext>;
|
|
@@ -807,16 +974,23 @@ declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends R
|
|
|
807
974
|
* @param options.id Override the default step id (`foreach:<agentId>` or
|
|
808
975
|
* the workflow's id). Required when chaining multiple foreach over the same
|
|
809
976
|
* target — the construction-time `(type, id)` walk rejects duplicates.
|
|
810
|
-
* @param options.concurrency Max items in flight at any moment
|
|
811
|
-
*
|
|
977
|
+
* @param options.concurrency Max items in flight at any moment. **Default:
|
|
978
|
+
* unbounded** (`Infinity` — every item runs concurrently, clamped only by
|
|
979
|
+
* item count). Pass an integer to throttle against provider rate limits.
|
|
980
|
+
* Backed by a worker pool: as soon as one item completes, the next launches —
|
|
812
981
|
* no lockstep batching.
|
|
813
982
|
* @param options.onError Per-iteration error handler. **Bypassed entirely on
|
|
814
|
-
* the suspension path** (when any item hits a nested gate)
|
|
983
|
+
* the suspension path** (when any item hits a nested gate) **and on the
|
|
984
|
+
* cancellation path** (the run was aborted — pre-abort failures become
|
|
985
|
+
* `foreach-sibling` warnings and the abort reason rethrows) — see the
|
|
815
986
|
* foreach concurrency hazards in the README. Otherwise: return a
|
|
816
987
|
* `TNextOutput` value to substitute, return `Workflow.SKIP` to omit, throw
|
|
817
988
|
* to abort. Invoked sequentially in index order after all items settle.
|
|
989
|
+
* A throw (or rethrow) from `onError` aborts the foreach immediately:
|
|
990
|
+
* failures at indices AFTER the throwing one are neither recovered nor
|
|
991
|
+
* surfaced as warnings.
|
|
818
992
|
*/
|
|
819
|
-
foreach<TNextOutput>(target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput
|
|
993
|
+
foreach<TNextOutput, TG extends Record<string, unknown> = {}>(target: Agent<TContext, ElementOf<TOutput>, TNextOutput> | (SealedWorkflow<TContext, ElementOf<TOutput>, TNextOutput, TG> & NoGates<TG>), options?: {
|
|
820
994
|
id?: string;
|
|
821
995
|
concurrency?: number;
|
|
822
996
|
onError?: (params: {
|
|
@@ -825,12 +999,44 @@ declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends R
|
|
|
825
999
|
index: number;
|
|
826
1000
|
ctx: Readonly<TContext>;
|
|
827
1001
|
}) => MaybePromise<TNextOutput | typeof Workflow.SKIP>;
|
|
1002
|
+
/**
|
|
1003
|
+
* **Stream-mode + agent-target only.** When the workflow is run via
|
|
1004
|
+
* `.stream(...)`, each item's agent runs in stream mode and this hook
|
|
1005
|
+
* decides how its stream surfaces to the writer (`itemIndex` = the item
|
|
1006
|
+
* index). Without it, agent items run in generate mode (no auto-merge —
|
|
1007
|
+
* unlike a single `.step(agent)`, foreach never auto-merges N streams).
|
|
1008
|
+
* Not invoked for `SealedWorkflow` targets (which stream transitively via
|
|
1009
|
+
* their own steps) nor in generate mode.
|
|
1010
|
+
*/
|
|
1011
|
+
handleStream?: (params: {
|
|
1012
|
+
result: StreamTextResult<ToolSet, OutputType<TNextOutput>>;
|
|
1013
|
+
writer: UIMessageStreamWriter;
|
|
1014
|
+
ctx: Readonly<TContext>;
|
|
1015
|
+
input: ElementOf<TOutput>;
|
|
1016
|
+
itemIndex: number;
|
|
1017
|
+
}) => MaybePromise<void>;
|
|
828
1018
|
}): Workflow<TContext, TInput, TNextOutput[], TGates>;
|
|
1019
|
+
/** Record-form + `onError`. Values are `BranchOutput | undefined` (SKIP-able). */
|
|
1020
|
+
parallel<TBranches extends Record<string, ParallelTarget<TContext, TOutput>>>(branches: TBranches & {
|
|
1021
|
+
[K in keyof TBranches]: GatelessBranch<TBranches[K]>;
|
|
1022
|
+
}, options: ParallelOptions<TContext, TOutput> & {
|
|
1023
|
+
onError: NonNullable<ParallelOptions<TContext, TOutput>["onError"]>;
|
|
1024
|
+
}): Workflow<TContext, TInput, ParallelOutputRecordPartial<TBranches>, TGates>;
|
|
829
1025
|
/** Record-form overload. Returns `{ [K]: BranchOutput<T[K]> }`. */
|
|
830
|
-
parallel<TBranches extends Record<string, ParallelTarget<TContext, TOutput>>>(branches: TBranches
|
|
1026
|
+
parallel<TBranches extends Record<string, ParallelTarget<TContext, TOutput>>>(branches: TBranches & {
|
|
1027
|
+
[K in keyof TBranches]: GatelessBranch<TBranches[K]>;
|
|
1028
|
+
}, options?: ParallelOptions<TContext, TOutput>): Workflow<TContext, TInput, ParallelOutputRecord<TBranches>, TGates>;
|
|
1029
|
+
/** Tuple-form + `onError`. Each slot is `BranchOutput | undefined` (SKIP-able). */
|
|
1030
|
+
parallel<TBranches extends ReadonlyArray<ParallelTarget<TContext, TOutput>>>(branches: TBranches & {
|
|
1031
|
+
[K in keyof TBranches]: GatelessBranch<TBranches[K]>;
|
|
1032
|
+
}, options: ParallelOptions<TContext, TOutput> & {
|
|
1033
|
+
onError: NonNullable<ParallelOptions<TContext, TOutput>["onError"]>;
|
|
1034
|
+
}): Workflow<TContext, TInput, ParallelOutputTuplePartial<TBranches>, TGates>;
|
|
831
1035
|
/** Tuple-form overload. Returns `[O1, O2, ...]`. Use `as const`. */
|
|
832
|
-
parallel<TBranches extends ReadonlyArray<ParallelTarget<TContext, TOutput>>>(branches: TBranches
|
|
833
|
-
|
|
1036
|
+
parallel<TBranches extends ReadonlyArray<ParallelTarget<TContext, TOutput>>>(branches: TBranches & {
|
|
1037
|
+
[K in keyof TBranches]: GatelessBranch<TBranches[K]>;
|
|
1038
|
+
}, options?: ParallelOptions<TContext, TOutput>): Workflow<TContext, TInput, ParallelOutputTuple<TBranches>, TGates>;
|
|
1039
|
+
repeat<TG extends Record<string, unknown> = {}>(target: Agent<TContext, TOutput, TOutput> | (SealedWorkflow<TContext, TOutput, TOutput, TG> & NoGates<TG>), options: RepeatOptions<TContext, TOutput> & {
|
|
834
1040
|
id?: string;
|
|
835
1041
|
}): Workflow<TContext, TInput, TOutput, TGates>;
|
|
836
1042
|
catch(id: string, fn: (params: {
|
|
@@ -843,4 +1049,4 @@ declare class Workflow<TContext, TInput = void, TOutput = void, TGates extends R
|
|
|
843
1049
|
|
|
844
1050
|
declare const SKIP: symbol;
|
|
845
1051
|
|
|
846
|
-
export { Agent, type AgentConfig, type AgentResultParams, type AgentStepHooks, type AsToolMapOutput, type BranchCase, type BranchSelect, CHECKPOINT_STEP_ID, CheckpointResumedWorkflow, type CheckpointSnapshot,
|
|
1052
|
+
export { ABORT_STEP_ID, Agent, type AgentConfig, type AgentResultParams, type AgentStepHooks, type AsToolMapOutput, type BranchCase, type BranchSelect, CHECKPOINT_STEP_ID, CheckpointResumedWorkflow, type CheckpointSnapshot, GATE_RESUME_STEP_ID, type GateSnapshot, type GenerateTextResult, type IToolProvider, type LegacyGateSnapshotV1, type MaybePromise, 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, isToolProvider, migrateSnapshot };
|