@yolk-sdk/vercel-workflows 0.1.0-canary.72 → 0.1.0-canary.73

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 CHANGED
@@ -132,10 +132,34 @@ export async function runAgentWorkflow(input: { request: unknown; context: unkno
132
132
  }
133
133
  ```
134
134
 
135
- `runModelStep`, `runToolBatchStep`, `closeStream`, and `writeError` are host-owned
136
- `'use step'` functions. Keep provider calls, tools, persistence, telemetry, and Effect runtimes in
135
+ `runModelStep`, `closeStream`, and `writeError` are host-owned `'use step'` functions.
136
+ `runToolBatchStep` may instead be Workflow orchestration calling concrete per-call steps. Keep provider calls, tools, persistence, telemetry, and Effect runtimes in
137
137
  those steps, not in the `'use workflow'` orchestration body.
138
138
 
139
+ ## Independent children
140
+
141
+ `orchestrateWorkflowToolBatch` runs a full-batch `preflight` before any `execute` callback,
142
+ limits local concurrency, and returns results in original call order. Both callbacks are host
143
+ seams: perform IO in steps, not in the orchestration helper. The host commits exactly one tool
144
+ result per call. Return a pause value from preflight when any HITL request is pending.
145
+ If an execution rejects, the helper stops dispatching new calls, settles already-active siblings,
146
+ and returns their ordered progress plus `failures`. Hosts must propagate those failures while
147
+ retaining completed results and usage; do not treat a partial batch as successful.
148
+
149
+ Start child workflows with Workflow 5 `start(childWorkflow, args)` **from orchestration**, not
150
+ inside the parent tool step. A child wrapper runs its own model/tool steps and returns a typed
151
+ application outcome; platform `completed` alone does not prove application success. Foreground
152
+ hosts await that child outcome; background hosts return an accepted handle and continue.
153
+
154
+ `awaitWorkflowChild({ read, sleep })` polls short durable read steps with a host-provided Workflow
155
+ `sleep` between reads. Do not hold a step open awaiting a long `run.returnValue` poll.
156
+
157
+ Hosts own immutable logical reservations, admission/CAS, ownership checks, storage, bounded
158
+ fanout, safe errors, credentials, and cancellation policy. Parent completion/failure must not
159
+ implicitly cancel independent children. Explicit Stop should persist a durable tombstone before
160
+ sweeping admitted child ids, reject late admission, and expose partial sweep failures for retry.
161
+ Give each independent stream and parallel call its own deterministic event-id namespace.
162
+
139
163
  ## Awaiting input
140
164
 
141
165
  When a tool batch needs HITL input, return `awaitingInput` from `runToolBatchStep`. The package
package/dist/index.d.mts CHANGED
@@ -1,3 +1,4 @@
1
1
  import { SerializableWorkflowState, VercelAgentWorkflowAwaitingInput, VercelAgentWorkflowInput, VercelAgentWorkflowLoopConfig, VercelAgentWorkflowModelStepInput, VercelAgentWorkflowModelStepResult, VercelAgentWorkflowRunResult, VercelAgentWorkflowStepRetryPolicy, VercelAgentWorkflowToolBatchStepInput, VercelAgentWorkflowToolBatchStepResult, WorkflowStepResult, defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
2
2
  import { CommitThenWriteTerminalEventInput, CommitThenWriteTerminalEventResult, DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, WriteDurableAgentEventInput, commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
3
- export { type CommitThenWriteTerminalEventInput, type CommitThenWriteTerminalEventResult, type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
3
+ import { awaitWorkflowChild, orchestrateWorkflowToolBatch } from "./workflow-children.mjs";
4
+ export { type CommitThenWriteTerminalEventInput, type CommitThenWriteTerminalEventResult, type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, awaitWorkflowChild, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, orchestrateWorkflowToolBatch, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
1
  import { defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
2
2
  import { commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
3
- export { commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
3
+ import { awaitWorkflowChild, orchestrateWorkflowToolBatch } from "./workflow-children.mjs";
4
+ export { awaitWorkflowChild, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, orchestrateWorkflowToolBatch, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
@@ -0,0 +1,40 @@
1
+ //#region src/workflow-children.d.ts
2
+ /** Workflow orchestration only. Callbacks must be durable steps (sleep must be Workflow sleep).
3
+ * A read is short-lived; never put a long returnValue poll inside a step.
4
+ */
5
+ declare function awaitWorkflowChild<A>(input: {
6
+ readonly read: () => Promise<{
7
+ readonly done: false;
8
+ } | {
9
+ readonly done: true;
10
+ readonly value: A;
11
+ }>;
12
+ readonly sleep: () => Promise<void>;
13
+ }): Promise<A>;
14
+ /** Preflight fences the entire batch. On rejection, stop dispatching new work, settle already
15
+ * active siblings, and return their ordered progress alongside failures. Hosts must handle failures.
16
+ */
17
+ declare function orchestrateWorkflowToolBatch<Call, Result, Pause>(input: {
18
+ readonly calls: ReadonlyArray<Call>;
19
+ readonly concurrency: number;
20
+ readonly preflight: () => Promise<{
21
+ readonly ready: true;
22
+ } | {
23
+ readonly ready: false;
24
+ readonly value: Pause;
25
+ }>;
26
+ readonly execute: (call: Call, index: number) => Promise<Result>;
27
+ }): Promise<{
28
+ readonly ready: true;
29
+ readonly results: ReadonlyArray<Result>;
30
+ readonly failures?: ReadonlyArray<{
31
+ readonly index: number;
32
+ readonly error: unknown;
33
+ }>;
34
+ } | {
35
+ readonly ready: false;
36
+ readonly value: Pause;
37
+ }>;
38
+ //#endregion
39
+ export { awaitWorkflowChild, orchestrateWorkflowToolBatch };
40
+ //# sourceMappingURL=workflow-children.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-children.d.mts","names":[],"sources":["../src/workflow-children.ts"],"mappings":";;AAGA;;iBAAsB,kBAAA,GAAA,CAAsB,KAAA;EAAA,SACjC,IAAA,QAAY,OAAA;IAAA,SACR,IAAA;EAAA;IAAA,SAA2B,IAAA;IAAA,SAAqB,KAAA,EAAO,CAAA;EAAA;EAAA,SAE3D,KAAA,QAAa,OAAA;AAAA,IACpB,OAAA,CAAQ,CAAA;;;;iBAYU,4BAAA,qBAAA,CAAkD,KAAA;EAAA,SAC7D,KAAA,EAAO,aAAA,CAAc,IAAA;EAAA,SACrB,WAAA;EAAA,SACA,SAAA,QAAiB,OAAA;IAAA,SACb,KAAA;EAAA;IAAA,SAA2B,KAAA;IAAA,SAAuB,KAAA,EAAO,KAAA;EAAA;EAAA,SAE7D,OAAA,GAAU,IAAA,EAAM,IAAA,EAAM,KAAA,aAAkB,OAAA,CAAQ,MAAA;AAAA,IACvD,OAAA;EAAA,SAEW,KAAA;EAAA,SACA,OAAA,EAAS,aAAA,CAAc,MAAA;EAAA,SACvB,QAAA,GAAW,aAAA;IAAA,SAAyB,KAAA;IAAA,SAAwB,KAAA;EAAA;AAAA;EAAA,SAE5D,KAAA;EAAA,SAAuB,KAAA,EAAO,KAAA;AAAA"}
@@ -0,0 +1,51 @@
1
+ //#region src/workflow-children.ts
2
+ /** Workflow orchestration only. Callbacks must be durable steps (sleep must be Workflow sleep).
3
+ * A read is short-lived; never put a long returnValue poll inside a step.
4
+ */
5
+ async function awaitWorkflowChild(input) {
6
+ const { read, sleep } = input;
7
+ for (;;) {
8
+ const state = await read();
9
+ if (state.done) return state.value;
10
+ await sleep();
11
+ }
12
+ }
13
+ /** Preflight fences the entire batch. On rejection, stop dispatching new work, settle already
14
+ * active siblings, and return their ordered progress alongside failures. Hosts must handle failures.
15
+ */
16
+ async function orchestrateWorkflowToolBatch(input) {
17
+ const { calls, concurrency, preflight, execute } = input;
18
+ const prepared = await preflight();
19
+ if (!prepared.ready) return prepared;
20
+ const width = Number.isFinite(concurrency) ? Math.max(1, Math.floor(concurrency)) : 1;
21
+ const entries = calls.map((call, index) => ({
22
+ call,
23
+ index
24
+ }));
25
+ let next = 0;
26
+ const results = /* @__PURE__ */ new Map();
27
+ const failures = [];
28
+ await Promise.all(Array.from({ length: Math.min(width, calls.length) }, async () => {
29
+ while (failures.length === 0) {
30
+ const entry = entries[next++];
31
+ if (entry === void 0) return;
32
+ try {
33
+ results.set(entry.index, await execute(entry.call, entry.index));
34
+ } catch (error) {
35
+ failures.push({
36
+ index: entry.index,
37
+ error
38
+ });
39
+ }
40
+ }
41
+ }));
42
+ return {
43
+ ready: true,
44
+ results: [...results.entries()].sort(([a], [b]) => a - b).map(([, result]) => result),
45
+ ...failures.length === 0 ? {} : { failures: failures.sort((a, b) => a.index - b.index) }
46
+ };
47
+ }
48
+ //#endregion
49
+ export { awaitWorkflowChild, orchestrateWorkflowToolBatch };
50
+
51
+ //# sourceMappingURL=workflow-children.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-children.mjs","names":[],"sources":["../src/workflow-children.ts"],"sourcesContent":["/** Workflow orchestration only. Callbacks must be durable steps (sleep must be Workflow sleep).\n * A read is short-lived; never put a long returnValue poll inside a step.\n */\nexport async function awaitWorkflowChild<A>(input: {\n readonly read: () => Promise<\n { readonly done: false } | { readonly done: true; readonly value: A }\n >\n readonly sleep: () => Promise<void>\n}): Promise<A> {\n const { read, sleep } = input\n for (;;) {\n const state = await read()\n if (state.done) return state.value\n await sleep()\n }\n}\n\n/** Preflight fences the entire batch. On rejection, stop dispatching new work, settle already\n * active siblings, and return their ordered progress alongside failures. Hosts must handle failures.\n */\nexport async function orchestrateWorkflowToolBatch<Call, Result, Pause>(input: {\n readonly calls: ReadonlyArray<Call>\n readonly concurrency: number\n readonly preflight: () => Promise<\n { readonly ready: true } | { readonly ready: false; readonly value: Pause }\n >\n readonly execute: (call: Call, index: number) => Promise<Result>\n}): Promise<\n | {\n readonly ready: true\n readonly results: ReadonlyArray<Result>\n readonly failures?: ReadonlyArray<{ readonly index: number; readonly error: unknown }>\n }\n | { readonly ready: false; readonly value: Pause }\n> {\n const { calls, concurrency, preflight, execute } = input\n const prepared = await preflight()\n if (!prepared.ready) return prepared\n const width = Number.isFinite(concurrency) ? Math.max(1, Math.floor(concurrency)) : 1\n const entries = calls.map((call, index) => ({ call, index }))\n let next = 0\n const results = new Map<number, Result>()\n const failures: Array<{ readonly index: number; readonly error: unknown }> = []\n await Promise.all(\n Array.from({ length: Math.min(width, calls.length) }, async () => {\n while (failures.length === 0) {\n const entry = entries[next++]\n if (entry === undefined) return\n try {\n results.set(entry.index, await execute(entry.call, entry.index))\n } catch (error) {\n failures.push({ index: entry.index, error })\n }\n }\n })\n )\n return {\n ready: true,\n results: [...results.entries()].sort(([a], [b]) => a - b).map(([, result]) => result),\n ...(failures.length === 0 ? {} : { failures: failures.sort((a, b) => a.index - b.index) })\n }\n}\n"],"mappings":";;;;AAGA,eAAsB,mBAAsB,OAK7B;CACb,MAAM,EAAE,MAAM,UAAU;CACxB,SAAS;EACP,MAAM,QAAQ,MAAM,KAAK;EACzB,IAAI,MAAM,MAAM,OAAO,MAAM;EAC7B,MAAM,MAAM;CACd;AACF;;;;AAKA,eAAsB,6BAAkD,OActE;CACA,MAAM,EAAE,OAAO,aAAa,WAAW,YAAY;CACnD,MAAM,WAAW,MAAM,UAAU;CACjC,IAAI,CAAC,SAAS,OAAO,OAAO;CAC5B,MAAM,QAAQ,OAAO,SAAS,WAAW,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,CAAC,IAAI;CACpF,MAAM,UAAU,MAAM,KAAK,MAAM,WAAW;EAAE;EAAM;CAAM,EAAE;CAC5D,IAAI,OAAO;CACX,MAAM,0BAAU,IAAI,IAAoB;CACxC,MAAM,WAAuE,CAAC;CAC9E,MAAM,QAAQ,IACZ,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,OAAO,MAAM,MAAM,EAAE,GAAG,YAAY;EAChE,OAAO,SAAS,WAAW,GAAG;GAC5B,MAAM,QAAQ,QAAQ;GACtB,IAAI,UAAU,KAAA,GAAW;GACzB,IAAI;IACF,QAAQ,IAAI,MAAM,OAAO,MAAM,QAAQ,MAAM,MAAM,MAAM,KAAK,CAAC;GACjE,SAAS,OAAO;IACd,SAAS,KAAK;KAAE,OAAO,MAAM;KAAO;IAAM,CAAC;GAC7C;EACF;CACF,CAAC,CACH;CACA,OAAO;EACL,OAAO;EACP,SAAS,CAAC,GAAG,QAAQ,QAAQ,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,KAAK,GAAG,YAAY,MAAM;EACpF,GAAI,SAAS,WAAW,IAAI,CAAC,IAAI,EAAE,UAAU,SAAS,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CAC1F;AACF"}
@@ -1,3 +1,4 @@
1
1
  import { SerializableWorkflowState, VercelAgentWorkflowAwaitingInput, VercelAgentWorkflowInput, VercelAgentWorkflowLoopConfig, VercelAgentWorkflowModelStepInput, VercelAgentWorkflowModelStepResult, VercelAgentWorkflowRunResult, VercelAgentWorkflowStepRetryPolicy, VercelAgentWorkflowToolBatchStepInput, VercelAgentWorkflowToolBatchStepResult, WorkflowStepResult, defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
2
2
  import { CommitThenWriteTerminalEventInput, CommitThenWriteTerminalEventResult, DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, WriteDurableAgentEventInput, commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
3
- export { type CommitThenWriteTerminalEventInput, type CommitThenWriteTerminalEventResult, type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
3
+ import { awaitWorkflowChild, orchestrateWorkflowToolBatch } from "./workflow-children.mjs";
4
+ export { type CommitThenWriteTerminalEventInput, type CommitThenWriteTerminalEventResult, type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, awaitWorkflowChild, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, orchestrateWorkflowToolBatch, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
package/dist/workflow.mjs CHANGED
@@ -1,3 +1,4 @@
1
1
  import { defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
2
2
  import { commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
3
- export { commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
3
+ import { awaitWorkflowChild, orchestrateWorkflowToolBatch } from "./workflow-children.mjs";
4
+ export { awaitWorkflowChild, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, orchestrateWorkflowToolBatch, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolk-sdk/vercel-workflows",
3
- "version": "0.1.0-canary.72",
3
+ "version": "0.1.0-canary.73",
4
4
  "description": "Vercel Workflow orchestration primitives for Yolk agent loops.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/index.ts CHANGED
@@ -31,3 +31,4 @@ export type {
31
31
  WorkflowStepResult,
32
32
  WriteDurableAgentEventInput
33
33
  } from './workflow.ts'
34
+ export { awaitWorkflowChild, orchestrateWorkflowToolBatch } from './workflow-children.ts'
@@ -0,0 +1,62 @@
1
+ /** Workflow orchestration only. Callbacks must be durable steps (sleep must be Workflow sleep).
2
+ * A read is short-lived; never put a long returnValue poll inside a step.
3
+ */
4
+ export async function awaitWorkflowChild<A>(input: {
5
+ readonly read: () => Promise<
6
+ { readonly done: false } | { readonly done: true; readonly value: A }
7
+ >
8
+ readonly sleep: () => Promise<void>
9
+ }): Promise<A> {
10
+ const { read, sleep } = input
11
+ for (;;) {
12
+ const state = await read()
13
+ if (state.done) return state.value
14
+ await sleep()
15
+ }
16
+ }
17
+
18
+ /** Preflight fences the entire batch. On rejection, stop dispatching new work, settle already
19
+ * active siblings, and return their ordered progress alongside failures. Hosts must handle failures.
20
+ */
21
+ export async function orchestrateWorkflowToolBatch<Call, Result, Pause>(input: {
22
+ readonly calls: ReadonlyArray<Call>
23
+ readonly concurrency: number
24
+ readonly preflight: () => Promise<
25
+ { readonly ready: true } | { readonly ready: false; readonly value: Pause }
26
+ >
27
+ readonly execute: (call: Call, index: number) => Promise<Result>
28
+ }): Promise<
29
+ | {
30
+ readonly ready: true
31
+ readonly results: ReadonlyArray<Result>
32
+ readonly failures?: ReadonlyArray<{ readonly index: number; readonly error: unknown }>
33
+ }
34
+ | { readonly ready: false; readonly value: Pause }
35
+ > {
36
+ const { calls, concurrency, preflight, execute } = input
37
+ const prepared = await preflight()
38
+ if (!prepared.ready) return prepared
39
+ const width = Number.isFinite(concurrency) ? Math.max(1, Math.floor(concurrency)) : 1
40
+ const entries = calls.map((call, index) => ({ call, index }))
41
+ let next = 0
42
+ const results = new Map<number, Result>()
43
+ const failures: Array<{ readonly index: number; readonly error: unknown }> = []
44
+ await Promise.all(
45
+ Array.from({ length: Math.min(width, calls.length) }, async () => {
46
+ while (failures.length === 0) {
47
+ const entry = entries[next++]
48
+ if (entry === undefined) return
49
+ try {
50
+ results.set(entry.index, await execute(entry.call, entry.index))
51
+ } catch (error) {
52
+ failures.push({ index: entry.index, error })
53
+ }
54
+ }
55
+ })
56
+ )
57
+ return {
58
+ ready: true,
59
+ results: [...results.entries()].sort(([a], [b]) => a - b).map(([, result]) => result),
60
+ ...(failures.length === 0 ? {} : { failures: failures.sort((a, b) => a.index - b.index) })
61
+ }
62
+ }
package/src/workflow.ts CHANGED
@@ -35,3 +35,4 @@ export type {
35
35
  SequencedDurableAgentEvent,
36
36
  WriteDurableAgentEventInput
37
37
  } from './workflow-events.ts'
38
+ export { awaitWorkflowChild, orchestrateWorkflowToolBatch } from './workflow-children.ts'