agent-framework-js 0.1.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/AGENT_USAGE.md +207 -0
- package/LICENSE +21 -0
- package/README.md +99 -0
- package/dist/agents/index.cjs +35 -0
- package/dist/agents/index.cjs.map +1 -0
- package/dist/agents/index.d.cts +8 -0
- package/dist/agents/index.d.ts +8 -0
- package/dist/agents/index.js +10 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/chunk-5M6ER4ZX.cjs +4 -0
- package/dist/chunk-5M6ER4ZX.cjs.map +1 -0
- package/dist/chunk-5PDJOBTD.js +38 -0
- package/dist/chunk-5PDJOBTD.js.map +1 -0
- package/dist/chunk-7ZXUIHLH.js +18 -0
- package/dist/chunk-7ZXUIHLH.js.map +1 -0
- package/dist/chunk-ACBIHS5H.js +30 -0
- package/dist/chunk-ACBIHS5H.js.map +1 -0
- package/dist/chunk-DEABART4.js +54 -0
- package/dist/chunk-DEABART4.js.map +1 -0
- package/dist/chunk-FOTCUNP5.cjs +34 -0
- package/dist/chunk-FOTCUNP5.cjs.map +1 -0
- package/dist/chunk-FSDMBWQV.cjs +20 -0
- package/dist/chunk-FSDMBWQV.cjs.map +1 -0
- package/dist/chunk-GYDY3KX5.cjs +72 -0
- package/dist/chunk-GYDY3KX5.cjs.map +1 -0
- package/dist/chunk-HGEPXJDG.js +129 -0
- package/dist/chunk-HGEPXJDG.js.map +1 -0
- package/dist/chunk-IJASUMIQ.cjs +57 -0
- package/dist/chunk-IJASUMIQ.cjs.map +1 -0
- package/dist/chunk-IU3LS5FC.cjs +10 -0
- package/dist/chunk-IU3LS5FC.cjs.map +1 -0
- package/dist/chunk-IUKD54F7.js +8 -0
- package/dist/chunk-IUKD54F7.js.map +1 -0
- package/dist/chunk-IXV4UIF5.js +79 -0
- package/dist/chunk-IXV4UIF5.js.map +1 -0
- package/dist/chunk-KEI3EALJ.cjs +10 -0
- package/dist/chunk-KEI3EALJ.cjs.map +1 -0
- package/dist/chunk-LMN75W3W.cjs +87 -0
- package/dist/chunk-LMN75W3W.cjs.map +1 -0
- package/dist/chunk-MCLVWCOB.js +3 -0
- package/dist/chunk-MCLVWCOB.js.map +1 -0
- package/dist/chunk-MQ2XTH3S.cjs +87 -0
- package/dist/chunk-MQ2XTH3S.cjs.map +1 -0
- package/dist/chunk-QJ5XHA6S.cjs +95 -0
- package/dist/chunk-QJ5XHA6S.cjs.map +1 -0
- package/dist/chunk-RD5YUB2E.js +190 -0
- package/dist/chunk-RD5YUB2E.js.map +1 -0
- package/dist/chunk-RZ43WNHR.js +8 -0
- package/dist/chunk-RZ43WNHR.js.map +1 -0
- package/dist/chunk-RZP2ZUUX.cjs +252 -0
- package/dist/chunk-RZP2ZUUX.cjs.map +1 -0
- package/dist/chunk-T2GHJ5R4.js +241 -0
- package/dist/chunk-T2GHJ5R4.js.map +1 -0
- package/dist/chunk-TAMJ5HSR.cjs +137 -0
- package/dist/chunk-TAMJ5HSR.cjs.map +1 -0
- package/dist/chunk-TLACSVEZ.cjs +201 -0
- package/dist/chunk-TLACSVEZ.cjs.map +1 -0
- package/dist/chunk-UVWQWOLO.js +196 -0
- package/dist/chunk-UVWQWOLO.js.map +1 -0
- package/dist/chunk-V472N2PK.js +91 -0
- package/dist/chunk-V472N2PK.js.map +1 -0
- package/dist/chunk-V6O6SYAN.cjs +43 -0
- package/dist/chunk-V6O6SYAN.cjs.map +1 -0
- package/dist/chunk-VLSVL5N2.js +48 -0
- package/dist/chunk-VLSVL5N2.js.map +1 -0
- package/dist/chunk-WSMYH2IN.cjs +86 -0
- package/dist/chunk-WSMYH2IN.cjs.map +1 -0
- package/dist/chunk-XPXTXOYQ.js +81 -0
- package/dist/chunk-XPXTXOYQ.js.map +1 -0
- package/dist/chunk-YBFLWRO5.cjs +194 -0
- package/dist/chunk-YBFLWRO5.cjs.map +1 -0
- package/dist/chunk-YCBDEEAV.js +82 -0
- package/dist/chunk-YCBDEEAV.js.map +1 -0
- package/dist/chunk-YH5746OF.js +69 -0
- package/dist/chunk-YH5746OF.js.map +1 -0
- package/dist/chunk-YKZJRE32.cjs +50 -0
- package/dist/chunk-YKZJRE32.cjs.map +1 -0
- package/dist/declarative/index.cjs +19 -0
- package/dist/declarative/index.cjs.map +1 -0
- package/dist/declarative/index.d.cts +60 -0
- package/dist/declarative/index.d.ts +60 -0
- package/dist/declarative/index.js +10 -0
- package/dist/declarative/index.js.map +1 -0
- package/dist/errors-CjVz4W_5.d.cts +68 -0
- package/dist/errors-CjVz4W_5.d.ts +68 -0
- package/dist/index-C2vzfbBz.d.cts +57 -0
- package/dist/index-C2vzfbBz.d.ts +57 -0
- package/dist/index-D7-znzrc.d.ts +153 -0
- package/dist/index-DdYZeNIu.d.cts +153 -0
- package/dist/index.cjs +236 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +51 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.cjs +19 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +72 -0
- package/dist/mcp/index.d.ts +72 -0
- package/dist/mcp/index.js +6 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/middleware/index.cjs +17 -0
- package/dist/middleware/index.cjs.map +1 -0
- package/dist/middleware/index.d.cts +29 -0
- package/dist/middleware/index.d.ts +29 -0
- package/dist/middleware/index.js +4 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/observability/index.cjs +29 -0
- package/dist/observability/index.cjs.map +1 -0
- package/dist/observability/index.d.cts +1 -0
- package/dist/observability/index.d.ts +1 -0
- package/dist/observability/index.js +4 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/persistence/index.cjs +24 -0
- package/dist/persistence/index.cjs.map +1 -0
- package/dist/persistence/index.d.cts +51 -0
- package/dist/persistence/index.d.ts +51 -0
- package/dist/persistence/index.js +7 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/provider-CMAymr1b.d.cts +82 -0
- package/dist/provider-osAtfZ7x.d.ts +82 -0
- package/dist/providers/index.cjs +26 -0
- package/dist/providers/index.cjs.map +1 -0
- package/dist/providers/index.d.cts +107 -0
- package/dist/providers/index.d.ts +107 -0
- package/dist/providers/index.js +5 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/registry-CpO0yH5v.d.ts +57 -0
- package/dist/registry-D4fThGiN.d.cts +57 -0
- package/dist/skill-DfNChtJN.d.cts +45 -0
- package/dist/skill-DfNChtJN.d.ts +45 -0
- package/dist/skills/index.cjs +20 -0
- package/dist/skills/index.cjs.map +1 -0
- package/dist/skills/index.d.cts +30 -0
- package/dist/skills/index.d.ts +30 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/thread-CWVzTyti.d.ts +51 -0
- package/dist/thread-Dfo9LLf7.d.cts +51 -0
- package/dist/tool-BZg_znMZ.d.cts +50 -0
- package/dist/tool-CSCC87OD.d.ts +50 -0
- package/dist/tools/index.cjs +27 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +21 -0
- package/dist/tools/index.d.ts +21 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types-Cn1g9Tg4.d.cts +63 -0
- package/dist/types-Cn1g9Tg4.d.ts +63 -0
- package/dist/workflows/index.cjs +50 -0
- package/dist/workflows/index.cjs.map +1 -0
- package/dist/workflows/index.d.cts +182 -0
- package/dist/workflows/index.d.ts +182 -0
- package/dist/workflows/index.js +5 -0
- package/dist/workflows/index.js.map +1 -0
- package/package.json +145 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkMQ2XTH3S_cjs = require('./chunk-MQ2XTH3S.cjs');
|
|
4
|
+
|
|
5
|
+
// src/workflows/concurrency.ts
|
|
6
|
+
async function runBounded(tasks, maxConcurrency, policy) {
|
|
7
|
+
const limit = maxConcurrency === -1 ? tasks.length : Math.max(1, maxConcurrency);
|
|
8
|
+
const results = new Array(tasks.length);
|
|
9
|
+
let next = 0;
|
|
10
|
+
let failed;
|
|
11
|
+
async function worker() {
|
|
12
|
+
for (; ; ) {
|
|
13
|
+
if (policy === "fail-fast" && failed) return;
|
|
14
|
+
const i = next++;
|
|
15
|
+
if (i >= tasks.length) return;
|
|
16
|
+
try {
|
|
17
|
+
results[i] = { index: i, value: await tasks[i]() };
|
|
18
|
+
} catch (e) {
|
|
19
|
+
const err = e;
|
|
20
|
+
results[i] = { index: i, error: err };
|
|
21
|
+
if (policy === "fail-fast") {
|
|
22
|
+
failed = err;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const workers = Array.from({ length: Math.min(limit, tasks.length) }, () => worker());
|
|
29
|
+
await Promise.all(workers);
|
|
30
|
+
if (policy === "fail-fast" && failed) throw failed;
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/workflows/patterns.ts
|
|
35
|
+
async function invoke(agent, input, ctx) {
|
|
36
|
+
const res = await agent.run(input);
|
|
37
|
+
if (res.error || res.status === "failed") {
|
|
38
|
+
ctx.errors[agent.name] = res.error?.message ?? "failed";
|
|
39
|
+
throw res.error ?? new Error(`Agent ${agent.name} failed`);
|
|
40
|
+
}
|
|
41
|
+
ctx.outputs[agent.name] = res.output;
|
|
42
|
+
return res.output;
|
|
43
|
+
}
|
|
44
|
+
async function stepSequential(agents, ctx, input, hooks) {
|
|
45
|
+
const agent = agents[ctx.cursor];
|
|
46
|
+
if (!agent) return { complete: true };
|
|
47
|
+
const feed = ctx.cursor === 0 ? input : ctx.output;
|
|
48
|
+
ctx.output = await invoke(agent, feed, ctx);
|
|
49
|
+
ctx.cursor++;
|
|
50
|
+
const done = ctx.cursor >= agents.length || !!hooks.isComplete?.(ctx.output, ctx);
|
|
51
|
+
return { complete: done };
|
|
52
|
+
}
|
|
53
|
+
async function stepConcurrent(agents, ctx, input, hooks) {
|
|
54
|
+
const results = await runBounded(
|
|
55
|
+
agents.map((a) => () => invoke(a, input, ctx)),
|
|
56
|
+
hooks.maxConcurrency ?? 4,
|
|
57
|
+
hooks.failurePolicy ?? "fail-soft"
|
|
58
|
+
);
|
|
59
|
+
const outputs = results.filter((r) => r.value !== void 0).map((r) => r.value);
|
|
60
|
+
ctx.output = outputs.join("\n\n");
|
|
61
|
+
return { complete: true };
|
|
62
|
+
}
|
|
63
|
+
async function stepHandoff(agents, ctx, input, hooks) {
|
|
64
|
+
const agent = agents[ctx.cursor];
|
|
65
|
+
if (!agent) return { complete: true };
|
|
66
|
+
const feed = ctx.round === 0 ? input : ctx.output;
|
|
67
|
+
ctx.output = await invoke(agent, feed, ctx);
|
|
68
|
+
if (hooks.isComplete?.(ctx.output, ctx)) return { complete: true };
|
|
69
|
+
const nextName = hooks.selectNext?.(ctx.output, ctx) ?? null;
|
|
70
|
+
if (!nextName) return { complete: true };
|
|
71
|
+
const idx = agents.findIndex((a) => a.name === nextName);
|
|
72
|
+
if (idx < 0) return { complete: true };
|
|
73
|
+
ctx.cursor = idx;
|
|
74
|
+
return { complete: false };
|
|
75
|
+
}
|
|
76
|
+
async function stepGroup(agents, ctx, input, hooks) {
|
|
77
|
+
let combined = ctx.round === 0 ? input : ctx.output;
|
|
78
|
+
for (const agent of agents) {
|
|
79
|
+
combined = await invoke(agent, combined, ctx);
|
|
80
|
+
if (hooks.isComplete?.(combined, ctx)) {
|
|
81
|
+
ctx.output = combined;
|
|
82
|
+
return { complete: true };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
ctx.output = combined;
|
|
86
|
+
return { complete: false };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/workflows/checkpoint.ts
|
|
90
|
+
var CHECKPOINT_VERSION = "1";
|
|
91
|
+
function createCheckpoint(id, state) {
|
|
92
|
+
return { version: CHECKPOINT_VERSION, id, state };
|
|
93
|
+
}
|
|
94
|
+
function serializeCheckpoint(cp) {
|
|
95
|
+
return JSON.stringify(cp);
|
|
96
|
+
}
|
|
97
|
+
function restoreCheckpoint(input) {
|
|
98
|
+
let cp;
|
|
99
|
+
if (typeof input === "string") {
|
|
100
|
+
try {
|
|
101
|
+
cp = JSON.parse(input);
|
|
102
|
+
} catch {
|
|
103
|
+
throw new chunkMQ2XTH3S_cjs.CheckpointError("Checkpoint data is not valid JSON", "corrupt");
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
cp = input;
|
|
107
|
+
}
|
|
108
|
+
if (!cp || typeof cp !== "object" || typeof cp.id !== "string" || typeof cp.state !== "object") {
|
|
109
|
+
throw new chunkMQ2XTH3S_cjs.CheckpointError("Checkpoint is missing required fields", "corrupt");
|
|
110
|
+
}
|
|
111
|
+
if (cp.version !== CHECKPOINT_VERSION) {
|
|
112
|
+
throw new chunkMQ2XTH3S_cjs.CheckpointError(
|
|
113
|
+
`Checkpoint version ${cp.version} does not match ${CHECKPOINT_VERSION}`,
|
|
114
|
+
"version-mismatch"
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return cp;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/workflows/workflow.ts
|
|
121
|
+
function freshContext(input) {
|
|
122
|
+
return { output: input, outputs: {}, round: 0, cursor: 0, errors: {} };
|
|
123
|
+
}
|
|
124
|
+
function contextFromCheckpoint(cp) {
|
|
125
|
+
const s = cp.state;
|
|
126
|
+
return {
|
|
127
|
+
output: s.output ?? "",
|
|
128
|
+
outputs: s.outputs ?? {},
|
|
129
|
+
round: s.round ?? 0,
|
|
130
|
+
cursor: s.cursor ?? 0,
|
|
131
|
+
errors: s.errors ?? {}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function createWorkflow(config) {
|
|
135
|
+
const maxRounds = config.maxRounds ?? 16;
|
|
136
|
+
const id = `wf-${Math.random().toString(36).slice(2)}`;
|
|
137
|
+
let currentStatus = "running";
|
|
138
|
+
const hooks = {
|
|
139
|
+
isComplete: config.isComplete,
|
|
140
|
+
selectNext: config.selectNext,
|
|
141
|
+
maxConcurrency: config.maxConcurrency,
|
|
142
|
+
failurePolicy: config.failurePolicy
|
|
143
|
+
};
|
|
144
|
+
async function stepOnce(ctx, input) {
|
|
145
|
+
switch (config.pattern) {
|
|
146
|
+
case "sequential":
|
|
147
|
+
return (await stepSequential(config.agents, ctx, input, hooks)).complete;
|
|
148
|
+
case "concurrent":
|
|
149
|
+
return (await stepConcurrent(config.agents, ctx, input, hooks)).complete;
|
|
150
|
+
case "handoff":
|
|
151
|
+
return (await stepHandoff(config.agents, ctx, input, hooks)).complete;
|
|
152
|
+
case "group":
|
|
153
|
+
return (await stepGroup(config.agents, ctx, input, hooks)).complete;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function snapshot(ctx) {
|
|
157
|
+
return createCheckpoint(id, { ...ctx });
|
|
158
|
+
}
|
|
159
|
+
async function drive(ctx, input) {
|
|
160
|
+
try {
|
|
161
|
+
for (; ; ) {
|
|
162
|
+
const prompt = config.humanInputGate?.(ctx);
|
|
163
|
+
if (prompt) {
|
|
164
|
+
currentStatus = "awaiting-input";
|
|
165
|
+
return { status: currentStatus, output: ctx.output, awaiting: { prompt }, checkpoint: snapshot(ctx) };
|
|
166
|
+
}
|
|
167
|
+
const complete = await stepOnce(ctx, input);
|
|
168
|
+
ctx.round++;
|
|
169
|
+
if (complete) {
|
|
170
|
+
currentStatus = "completed";
|
|
171
|
+
return { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };
|
|
172
|
+
}
|
|
173
|
+
if (maxRounds !== -1 && ctx.round >= maxRounds) {
|
|
174
|
+
currentStatus = "completed";
|
|
175
|
+
return { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} catch (e) {
|
|
179
|
+
currentStatus = "failed";
|
|
180
|
+
return {
|
|
181
|
+
status: currentStatus,
|
|
182
|
+
output: ctx.output,
|
|
183
|
+
error: e.message,
|
|
184
|
+
checkpoint: snapshot(ctx)
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async function run(input) {
|
|
189
|
+
currentStatus = "running";
|
|
190
|
+
return drive(freshContext(input), input);
|
|
191
|
+
}
|
|
192
|
+
async function* runStream(input) {
|
|
193
|
+
currentStatus = "running";
|
|
194
|
+
const ctx = freshContext(input);
|
|
195
|
+
for (; ; ) {
|
|
196
|
+
const prompt = config.humanInputGate?.(ctx);
|
|
197
|
+
if (prompt) {
|
|
198
|
+
currentStatus = "awaiting-input";
|
|
199
|
+
const state = {
|
|
200
|
+
status: currentStatus,
|
|
201
|
+
output: ctx.output,
|
|
202
|
+
awaiting: { prompt },
|
|
203
|
+
checkpoint: snapshot(ctx)
|
|
204
|
+
};
|
|
205
|
+
yield { type: "awaiting-input", prompt, state };
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
let complete;
|
|
209
|
+
try {
|
|
210
|
+
complete = await stepOnce(ctx, input);
|
|
211
|
+
} catch (e) {
|
|
212
|
+
currentStatus = "failed";
|
|
213
|
+
yield {
|
|
214
|
+
type: "done",
|
|
215
|
+
state: { status: "failed", output: ctx.output, error: e.message, checkpoint: snapshot(ctx) }
|
|
216
|
+
};
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
ctx.round++;
|
|
220
|
+
yield { type: "round", round: ctx.round, output: ctx.output };
|
|
221
|
+
if (complete || maxRounds !== -1 && ctx.round >= maxRounds) {
|
|
222
|
+
currentStatus = "completed";
|
|
223
|
+
yield { type: "done", state: { status: "completed", output: ctx.output, checkpoint: snapshot(ctx) } };
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function resume(state, humanInput) {
|
|
229
|
+
const cp = restoreCheckpoint(state.checkpoint);
|
|
230
|
+
const ctx = contextFromCheckpoint(cp);
|
|
231
|
+
if (humanInput !== void 0) {
|
|
232
|
+
ctx.output = humanInput;
|
|
233
|
+
ctx.outputs["__human__"] = humanInput;
|
|
234
|
+
}
|
|
235
|
+
currentStatus = "running";
|
|
236
|
+
return drive(ctx, ctx.output);
|
|
237
|
+
}
|
|
238
|
+
return { run, runStream, resume, status: () => currentStatus };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
exports.CHECKPOINT_VERSION = CHECKPOINT_VERSION;
|
|
242
|
+
exports.createCheckpoint = createCheckpoint;
|
|
243
|
+
exports.createWorkflow = createWorkflow;
|
|
244
|
+
exports.restoreCheckpoint = restoreCheckpoint;
|
|
245
|
+
exports.runBounded = runBounded;
|
|
246
|
+
exports.serializeCheckpoint = serializeCheckpoint;
|
|
247
|
+
exports.stepConcurrent = stepConcurrent;
|
|
248
|
+
exports.stepGroup = stepGroup;
|
|
249
|
+
exports.stepHandoff = stepHandoff;
|
|
250
|
+
exports.stepSequential = stepSequential;
|
|
251
|
+
//# sourceMappingURL=chunk-RZP2ZUUX.cjs.map
|
|
252
|
+
//# sourceMappingURL=chunk-RZP2ZUUX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/workflows/concurrency.ts","../src/workflows/patterns.ts","../src/workflows/checkpoint.ts","../src/workflows/workflow.ts"],"names":["CheckpointError"],"mappings":"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","file":"chunk-RZP2ZUUX.cjs","sourcesContent":["/**\n * Bounded-concurrency execution with a configurable failure policy for concurrent\n * workflows. Fail-soft (default) aggregates partial results; fail-fast cancels\n * remaining work on the first failure. (FR-019b, FR-019c)\n *\n * @packageDocumentation\n */\n\n/** How concurrent branches react to a failure. */\nexport type FailurePolicy = \"fail-soft\" | \"fail-fast\";\n\n/** Per-branch outcome under fail-soft. */\nexport interface BranchResult<T> {\n\tindex: number;\n\tvalue?: T;\n\terror?: Error;\n}\n\n/**\n * Run `tasks` with at most `maxConcurrency` in flight (-1 = unlimited).\n *\n * - `fail-soft`: every branch runs; failures are captured per-branch.\n * - `fail-fast`: the first failure rejects and remaining branches are abandoned.\n *\n * @returns Per-branch results (always, including under fail-fast where the failing\n * branch carries the error). Under fail-fast this throws on first failure.\n */\nexport async function runBounded<T>(\n\ttasks: Array<() => Promise<T>>,\n\tmaxConcurrency: number,\n\tpolicy: FailurePolicy,\n): Promise<Array<BranchResult<T>>> {\n\tconst limit = maxConcurrency === -1 ? tasks.length : Math.max(1, maxConcurrency);\n\tconst results: Array<BranchResult<T>> = new Array(tasks.length);\n\tlet next = 0;\n\tlet failed: Error | undefined;\n\n\tasync function worker(): Promise<void> {\n\t\tfor (; ;) {\n\t\t\tif (policy === \"fail-fast\" && failed) return;\n\t\t\tconst i = next++;\n\t\t\tif (i >= tasks.length) return;\n\t\t\ttry {\n\t\t\t\tresults[i] = { index: i, value: await tasks[i]!() };\n\t\t\t} catch (e) {\n\t\t\t\tconst err = e as Error;\n\t\t\t\tresults[i] = { index: i, error: err };\n\t\t\t\tif (policy === \"fail-fast\") {\n\t\t\t\t\tfailed = err;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst workers = Array.from({ length: Math.min(limit, tasks.length) }, () => worker());\n\tawait Promise.all(workers);\n\n\tif (policy === \"fail-fast\" && failed) throw failed;\n\treturn results;\n}\n","/**\n * Orchestration patterns: sequential, concurrent, handoff, and group collaboration.\n * Each pattern advances a {@link WorkflowContext} by one round and reports whether\n * the workflow is complete. (FR-019)\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"../agents/agent.js\";\nimport { runBounded, type FailurePolicy } from \"./concurrency.js\";\n\n/** Supported orchestration patterns. */\nexport type WorkflowPattern = \"sequential\" | \"concurrent\" | \"handoff\" | \"group\";\n\n/** Mutable state threaded through pattern execution. */\nexport interface WorkflowContext {\n\t/** Latest combined output. */\n\toutput: string;\n\t/** Per-agent latest outputs (by agent name). */\n\toutputs: Record<string, string>;\n\t/** Current round (0-based). */\n\tround: number;\n\t/** Index of the next agent (handoff/sequential). */\n\tcursor: number;\n\t/** Names of agents that errored this run (fail-soft). */\n\terrors: Record<string, string>;\n}\n\n/** Hooks customizing pattern behavior. */\nexport interface PatternHooks {\n\t/** Returns true when an output signals the workflow is complete. (FR-019a) */\n\tisComplete?: (output: string, ctx: WorkflowContext) => boolean;\n\t/** For handoff: choose the next agent name from the latest output (or null to stop). */\n\tselectNext?: (output: string, ctx: WorkflowContext) => string | null;\n\tmaxConcurrency?: number;\n\tfailurePolicy?: FailurePolicy;\n}\n\n/** One step's result. */\nexport interface StepResult {\n\tcomplete: boolean;\n}\n\nasync function invoke(agent: Agent, input: string, ctx: WorkflowContext): Promise<string> {\n\tconst res = await agent.run(input);\n\tif (res.error || res.status === \"failed\") {\n\t\tctx.errors[agent.name] = res.error?.message ?? \"failed\";\n\t\tthrow res.error ?? new Error(`Agent ${agent.name} failed`);\n\t}\n\tctx.outputs[agent.name] = res.output;\n\treturn res.output;\n}\n\n/** Advance a sequential workflow by one agent. */\nexport async function stepSequential(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tconst agent = agents[ctx.cursor];\n\tif (!agent) return { complete: true };\n\tconst feed = ctx.cursor === 0 ? input : ctx.output;\n\tctx.output = await invoke(agent, feed, ctx);\n\tctx.cursor++;\n\tconst done = ctx.cursor >= agents.length || !!hooks.isComplete?.(ctx.output, ctx);\n\treturn { complete: done };\n}\n\n/** Run all agents concurrently on the same input and aggregate outputs. */\nexport async function stepConcurrent(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tconst results = await runBounded(\n\t\tagents.map((a) => () => invoke(a, input, ctx)),\n\t\thooks.maxConcurrency ?? 4,\n\t\thooks.failurePolicy ?? \"fail-soft\",\n\t);\n\tconst outputs = results.filter((r) => r.value !== undefined).map((r) => r.value as string);\n\tctx.output = outputs.join(\"\\n\\n\");\n\treturn { complete: true };\n}\n\n/** Advance a handoff workflow: the current agent may delegate to another. */\nexport async function stepHandoff(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tconst agent = agents[ctx.cursor];\n\tif (!agent) return { complete: true };\n\tconst feed = ctx.round === 0 ? input : ctx.output;\n\tctx.output = await invoke(agent, feed, ctx);\n\n\tif (hooks.isComplete?.(ctx.output, ctx)) return { complete: true };\n\tconst nextName = hooks.selectNext?.(ctx.output, ctx) ?? null;\n\tif (!nextName) return { complete: true };\n\tconst idx = agents.findIndex((a) => a.name === nextName);\n\tif (idx < 0) return { complete: true };\n\tctx.cursor = idx;\n\treturn { complete: false };\n}\n\n/** Group collaboration: every agent contributes each round until complete. */\nexport async function stepGroup(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tlet combined = ctx.round === 0 ? input : ctx.output;\n\tfor (const agent of agents) {\n\t\tcombined = await invoke(agent, combined, ctx);\n\t\tif (hooks.isComplete?.(combined, ctx)) {\n\t\t\tctx.output = combined;\n\t\t\treturn { complete: true };\n\t\t}\n\t}\n\tctx.output = combined;\n\treturn { complete: false };\n}\n","/**\n * Workflow checkpointing. A checkpoint is a serializable snapshot enabling resume.\n * Restore fails closed: corrupt or version-mismatched data yields a typed\n * {@link CheckpointError} with no partial restore. (FR-022, FR-022a)\n *\n * @packageDocumentation\n */\n\nimport { CheckpointError } from \"../core/errors.js\";\n\n/** Current checkpoint schema version. */\nexport const CHECKPOINT_VERSION = \"1\";\n\n/** A serializable workflow snapshot. */\nexport interface Checkpoint {\n\tversion: string;\n\tid: string;\n\t/** Opaque workflow state (round, messages, pending node, etc.). */\n\tstate: Record<string, unknown>;\n}\n\n/** Create a checkpoint with the current schema version. */\nexport function createCheckpoint(id: string, state: Record<string, unknown>): Checkpoint {\n\treturn { version: CHECKPOINT_VERSION, id, state };\n}\n\n/** Serialize a checkpoint to a string. */\nexport function serializeCheckpoint(cp: Checkpoint): string {\n\treturn JSON.stringify(cp);\n}\n\n/**\n * Restore a checkpoint from its serialized form or object. Fails closed.\n *\n * @throws {CheckpointError} `corrupt` if the data cannot be parsed/validated.\n * @throws {CheckpointError} `version-mismatch` if the schema version differs.\n */\nexport function restoreCheckpoint(input: string | Checkpoint): Checkpoint {\n\tlet cp: Checkpoint;\n\tif (typeof input === \"string\") {\n\t\ttry {\n\t\t\tcp = JSON.parse(input) as Checkpoint;\n\t\t} catch {\n\t\t\tthrow new CheckpointError(\"Checkpoint data is not valid JSON\", \"corrupt\");\n\t\t}\n\t} else {\n\t\tcp = input;\n\t}\n\n\tif (!cp || typeof cp !== \"object\" || typeof cp.id !== \"string\" || typeof cp.state !== \"object\") {\n\t\tthrow new CheckpointError(\"Checkpoint is missing required fields\", \"corrupt\");\n\t}\n\tif (cp.version !== CHECKPOINT_VERSION) {\n\t\tthrow new CheckpointError(\n\t\t\t`Checkpoint version ${cp.version} does not match ${CHECKPOINT_VERSION}`,\n\t\t\t\"version-mismatch\",\n\t\t);\n\t}\n\treturn cp;\n}\n","/**\n * The workflow engine: composes agents under an orchestration pattern with a\n * completion signal and a configurable max-rounds safety cap, bounded concurrency,\n * a failure policy, streaming, human-in-the-loop yield/resume, and checkpointing.\n * (FR-018, FR-019, FR-019a, FR-019b, FR-019c, FR-020, FR-021, FR-021a, FR-021b, FR-022)\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"../agents/agent.js\";\nimport type { FailurePolicy } from \"./concurrency.js\";\nimport {\n\tstepSequential,\n\tstepConcurrent,\n\tstepHandoff,\n\tstepGroup,\n\ttype WorkflowPattern,\n\ttype WorkflowContext,\n\ttype PatternHooks,\n} from \"./patterns.js\";\nimport { createCheckpoint, restoreCheckpoint, type Checkpoint } from \"./checkpoint.js\";\n\n/** Lifecycle status of a workflow run, observable by the host. (FR-021b) */\nexport type WorkflowStatus = \"running\" | \"awaiting-input\" | \"completed\" | \"failed\";\n\n/** Configuration for {@link createWorkflow}. */\nexport interface WorkflowConfig {\n\tpattern: WorkflowPattern;\n\tagents: Agent[];\n\t/** Max rounds; -1 = unlimited. Default 16. (FR-019a) */\n\tmaxRounds?: number;\n\t/** Concurrent failure policy. Default fail-soft. (FR-019b) */\n\tfailurePolicy?: FailurePolicy;\n\t/** Max parallel agent calls; -1 = unlimited. Default 4. (FR-019c) */\n\tmaxConcurrency?: number;\n\t/** Completion signal: end the workflow when this returns true. (FR-019a) */\n\tisComplete?: (output: string, ctx: WorkflowContext) => boolean;\n\t/** Handoff target selector. */\n\tselectNext?: (output: string, ctx: WorkflowContext) => string | null;\n\t/** Human-in-the-loop gate: when it returns a prompt, the workflow yields. (FR-021) */\n\thumanInputGate?: (ctx: WorkflowContext) => string | null;\n}\n\n/** Serializable result/handle of a workflow run. (FR-021a, FR-022) */\nexport interface WorkflowState {\n\tstatus: WorkflowStatus;\n\toutput: string;\n\t/** Present when status is `awaiting-input`. */\n\tawaiting?: { prompt: string };\n\t/** Error message when status is `failed`. */\n\terror?: string;\n\t/** Snapshot enabling resume. */\n\tcheckpoint: Checkpoint;\n}\n\n/** Streamed workflow event. (FR-020) */\nexport type WorkflowEvent =\n\t| { type: \"round\"; round: number; output: string }\n\t| { type: \"awaiting-input\"; prompt: string; state: WorkflowState }\n\t| { type: \"done\"; state: WorkflowState };\n\n/** A runnable multi-agent workflow. */\nexport interface Workflow {\n\trun(input: string): Promise<WorkflowState>;\n\trunStream(input: string): AsyncIterable<WorkflowEvent>;\n\tresume(state: WorkflowState, humanInput?: string): Promise<WorkflowState>;\n\tstatus(): WorkflowStatus;\n}\n\nfunction freshContext(input: string): WorkflowContext {\n\treturn { output: input, outputs: {}, round: 0, cursor: 0, errors: {} };\n}\n\nfunction contextFromCheckpoint(cp: Checkpoint): WorkflowContext {\n\tconst s = cp.state as Partial<WorkflowContext>;\n\treturn {\n\t\toutput: s.output ?? \"\",\n\t\toutputs: s.outputs ?? {},\n\t\tround: s.round ?? 0,\n\t\tcursor: s.cursor ?? 0,\n\t\terrors: s.errors ?? {},\n\t};\n}\n\n/**\n * Create a workflow.\n *\n * @example\n * ```ts\n * const wf = createWorkflow({ pattern: \"sequential\", agents: [researcher, summarizer] });\n * let state = await wf.run(\"Summarize the notes.\");\n * if (state.status === \"awaiting-input\") state = await wf.resume(state, \"approved\");\n * ```\n */\nexport function createWorkflow(config: WorkflowConfig): Workflow {\n\tconst maxRounds = config.maxRounds ?? 16;\n\tconst id = `wf-${Math.random().toString(36).slice(2)}`;\n\tlet currentStatus: WorkflowStatus = \"running\";\n\n\tconst hooks: PatternHooks = {\n\t\tisComplete: config.isComplete,\n\t\tselectNext: config.selectNext,\n\t\tmaxConcurrency: config.maxConcurrency,\n\t\tfailurePolicy: config.failurePolicy,\n\t};\n\n\tasync function stepOnce(ctx: WorkflowContext, input: string): Promise<boolean> {\n\t\tswitch (config.pattern) {\n\t\t\tcase \"sequential\":\n\t\t\t\treturn (await stepSequential(config.agents, ctx, input, hooks)).complete;\n\t\t\tcase \"concurrent\":\n\t\t\t\treturn (await stepConcurrent(config.agents, ctx, input, hooks)).complete;\n\t\t\tcase \"handoff\":\n\t\t\t\treturn (await stepHandoff(config.agents, ctx, input, hooks)).complete;\n\t\t\tcase \"group\":\n\t\t\t\treturn (await stepGroup(config.agents, ctx, input, hooks)).complete;\n\t\t}\n\t}\n\n\tfunction snapshot(ctx: WorkflowContext): Checkpoint {\n\t\treturn createCheckpoint(id, { ...ctx });\n\t}\n\n\tasync function drive(ctx: WorkflowContext, input: string): Promise<WorkflowState> {\n\t\ttry {\n\t\t\tfor (; ;) {\n\t\t\t\t// Human-in-the-loop: yield a serializable awaiting-input state. (FR-021a)\n\t\t\t\tconst prompt = config.humanInputGate?.(ctx);\n\t\t\t\tif (prompt) {\n\t\t\t\t\tcurrentStatus = \"awaiting-input\";\n\t\t\t\t\treturn { status: currentStatus, output: ctx.output, awaiting: { prompt }, checkpoint: snapshot(ctx) };\n\t\t\t\t}\n\n\t\t\t\tconst complete = await stepOnce(ctx, input);\n\t\t\t\tctx.round++;\n\n\t\t\t\tif (complete) {\n\t\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\t\treturn { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };\n\t\t\t\t}\n\t\t\t\tif (maxRounds !== -1 && ctx.round >= maxRounds) {\n\t\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\t\treturn { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tcurrentStatus = \"failed\";\n\t\t\treturn {\n\t\t\t\tstatus: currentStatus,\n\t\t\t\toutput: ctx.output,\n\t\t\t\terror: (e as Error).message,\n\t\t\t\tcheckpoint: snapshot(ctx),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync function run(input: string): Promise<WorkflowState> {\n\t\tcurrentStatus = \"running\";\n\t\treturn drive(freshContext(input), input);\n\t}\n\n\tasync function* runStream(input: string): AsyncIterable<WorkflowEvent> {\n\t\tcurrentStatus = \"running\";\n\t\tconst ctx = freshContext(input);\n\t\tfor (; ;) {\n\t\t\tconst prompt = config.humanInputGate?.(ctx);\n\t\t\tif (prompt) {\n\t\t\t\tcurrentStatus = \"awaiting-input\";\n\t\t\t\tconst state: WorkflowState = {\n\t\t\t\t\tstatus: currentStatus,\n\t\t\t\t\toutput: ctx.output,\n\t\t\t\t\tawaiting: { prompt },\n\t\t\t\t\tcheckpoint: snapshot(ctx),\n\t\t\t\t};\n\t\t\t\tyield { type: \"awaiting-input\", prompt, state };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet complete: boolean;\n\t\t\ttry {\n\t\t\t\tcomplete = await stepOnce(ctx, input);\n\t\t\t} catch (e) {\n\t\t\t\tcurrentStatus = \"failed\";\n\t\t\t\tyield {\n\t\t\t\t\ttype: \"done\",\n\t\t\t\t\tstate: { status: \"failed\", output: ctx.output, error: (e as Error).message, checkpoint: snapshot(ctx) },\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.round++;\n\t\t\tyield { type: \"round\", round: ctx.round, output: ctx.output };\n\t\t\tif (complete || (maxRounds !== -1 && ctx.round >= maxRounds)) {\n\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\tyield { type: \"done\", state: { status: \"completed\", output: ctx.output, checkpoint: snapshot(ctx) } };\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function resume(state: WorkflowState, humanInput?: string): Promise<WorkflowState> {\n\t\t// Fail-closed restore of the checkpoint. (FR-022a)\n\t\tconst cp = restoreCheckpoint(state.checkpoint);\n\t\tconst ctx = contextFromCheckpoint(cp);\n\t\tif (humanInput !== undefined) {\n\t\t\tctx.output = humanInput;\n\t\t\tctx.outputs[\"__human__\"] = humanInput;\n\t\t}\n\t\tcurrentStatus = \"running\";\n\t\treturn drive(ctx, ctx.output);\n\t}\n\n\treturn { run, runStream, resume, status: () => currentStatus };\n}\n"]}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { CheckpointError } from './chunk-IXV4UIF5.js';
|
|
2
|
+
|
|
3
|
+
// src/workflows/concurrency.ts
|
|
4
|
+
async function runBounded(tasks, maxConcurrency, policy) {
|
|
5
|
+
const limit = maxConcurrency === -1 ? tasks.length : Math.max(1, maxConcurrency);
|
|
6
|
+
const results = new Array(tasks.length);
|
|
7
|
+
let next = 0;
|
|
8
|
+
let failed;
|
|
9
|
+
async function worker() {
|
|
10
|
+
for (; ; ) {
|
|
11
|
+
if (policy === "fail-fast" && failed) return;
|
|
12
|
+
const i = next++;
|
|
13
|
+
if (i >= tasks.length) return;
|
|
14
|
+
try {
|
|
15
|
+
results[i] = { index: i, value: await tasks[i]() };
|
|
16
|
+
} catch (e) {
|
|
17
|
+
const err = e;
|
|
18
|
+
results[i] = { index: i, error: err };
|
|
19
|
+
if (policy === "fail-fast") {
|
|
20
|
+
failed = err;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const workers = Array.from({ length: Math.min(limit, tasks.length) }, () => worker());
|
|
27
|
+
await Promise.all(workers);
|
|
28
|
+
if (policy === "fail-fast" && failed) throw failed;
|
|
29
|
+
return results;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/workflows/patterns.ts
|
|
33
|
+
async function invoke(agent, input, ctx) {
|
|
34
|
+
const res = await agent.run(input);
|
|
35
|
+
if (res.error || res.status === "failed") {
|
|
36
|
+
ctx.errors[agent.name] = res.error?.message ?? "failed";
|
|
37
|
+
throw res.error ?? new Error(`Agent ${agent.name} failed`);
|
|
38
|
+
}
|
|
39
|
+
ctx.outputs[agent.name] = res.output;
|
|
40
|
+
return res.output;
|
|
41
|
+
}
|
|
42
|
+
async function stepSequential(agents, ctx, input, hooks) {
|
|
43
|
+
const agent = agents[ctx.cursor];
|
|
44
|
+
if (!agent) return { complete: true };
|
|
45
|
+
const feed = ctx.cursor === 0 ? input : ctx.output;
|
|
46
|
+
ctx.output = await invoke(agent, feed, ctx);
|
|
47
|
+
ctx.cursor++;
|
|
48
|
+
const done = ctx.cursor >= agents.length || !!hooks.isComplete?.(ctx.output, ctx);
|
|
49
|
+
return { complete: done };
|
|
50
|
+
}
|
|
51
|
+
async function stepConcurrent(agents, ctx, input, hooks) {
|
|
52
|
+
const results = await runBounded(
|
|
53
|
+
agents.map((a) => () => invoke(a, input, ctx)),
|
|
54
|
+
hooks.maxConcurrency ?? 4,
|
|
55
|
+
hooks.failurePolicy ?? "fail-soft"
|
|
56
|
+
);
|
|
57
|
+
const outputs = results.filter((r) => r.value !== void 0).map((r) => r.value);
|
|
58
|
+
ctx.output = outputs.join("\n\n");
|
|
59
|
+
return { complete: true };
|
|
60
|
+
}
|
|
61
|
+
async function stepHandoff(agents, ctx, input, hooks) {
|
|
62
|
+
const agent = agents[ctx.cursor];
|
|
63
|
+
if (!agent) return { complete: true };
|
|
64
|
+
const feed = ctx.round === 0 ? input : ctx.output;
|
|
65
|
+
ctx.output = await invoke(agent, feed, ctx);
|
|
66
|
+
if (hooks.isComplete?.(ctx.output, ctx)) return { complete: true };
|
|
67
|
+
const nextName = hooks.selectNext?.(ctx.output, ctx) ?? null;
|
|
68
|
+
if (!nextName) return { complete: true };
|
|
69
|
+
const idx = agents.findIndex((a) => a.name === nextName);
|
|
70
|
+
if (idx < 0) return { complete: true };
|
|
71
|
+
ctx.cursor = idx;
|
|
72
|
+
return { complete: false };
|
|
73
|
+
}
|
|
74
|
+
async function stepGroup(agents, ctx, input, hooks) {
|
|
75
|
+
let combined = ctx.round === 0 ? input : ctx.output;
|
|
76
|
+
for (const agent of agents) {
|
|
77
|
+
combined = await invoke(agent, combined, ctx);
|
|
78
|
+
if (hooks.isComplete?.(combined, ctx)) {
|
|
79
|
+
ctx.output = combined;
|
|
80
|
+
return { complete: true };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
ctx.output = combined;
|
|
84
|
+
return { complete: false };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/workflows/checkpoint.ts
|
|
88
|
+
var CHECKPOINT_VERSION = "1";
|
|
89
|
+
function createCheckpoint(id, state) {
|
|
90
|
+
return { version: CHECKPOINT_VERSION, id, state };
|
|
91
|
+
}
|
|
92
|
+
function serializeCheckpoint(cp) {
|
|
93
|
+
return JSON.stringify(cp);
|
|
94
|
+
}
|
|
95
|
+
function restoreCheckpoint(input) {
|
|
96
|
+
let cp;
|
|
97
|
+
if (typeof input === "string") {
|
|
98
|
+
try {
|
|
99
|
+
cp = JSON.parse(input);
|
|
100
|
+
} catch {
|
|
101
|
+
throw new CheckpointError("Checkpoint data is not valid JSON", "corrupt");
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
cp = input;
|
|
105
|
+
}
|
|
106
|
+
if (!cp || typeof cp !== "object" || typeof cp.id !== "string" || typeof cp.state !== "object") {
|
|
107
|
+
throw new CheckpointError("Checkpoint is missing required fields", "corrupt");
|
|
108
|
+
}
|
|
109
|
+
if (cp.version !== CHECKPOINT_VERSION) {
|
|
110
|
+
throw new CheckpointError(
|
|
111
|
+
`Checkpoint version ${cp.version} does not match ${CHECKPOINT_VERSION}`,
|
|
112
|
+
"version-mismatch"
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return cp;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/workflows/workflow.ts
|
|
119
|
+
function freshContext(input) {
|
|
120
|
+
return { output: input, outputs: {}, round: 0, cursor: 0, errors: {} };
|
|
121
|
+
}
|
|
122
|
+
function contextFromCheckpoint(cp) {
|
|
123
|
+
const s = cp.state;
|
|
124
|
+
return {
|
|
125
|
+
output: s.output ?? "",
|
|
126
|
+
outputs: s.outputs ?? {},
|
|
127
|
+
round: s.round ?? 0,
|
|
128
|
+
cursor: s.cursor ?? 0,
|
|
129
|
+
errors: s.errors ?? {}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function createWorkflow(config) {
|
|
133
|
+
const maxRounds = config.maxRounds ?? 16;
|
|
134
|
+
const id = `wf-${Math.random().toString(36).slice(2)}`;
|
|
135
|
+
let currentStatus = "running";
|
|
136
|
+
const hooks = {
|
|
137
|
+
isComplete: config.isComplete,
|
|
138
|
+
selectNext: config.selectNext,
|
|
139
|
+
maxConcurrency: config.maxConcurrency,
|
|
140
|
+
failurePolicy: config.failurePolicy
|
|
141
|
+
};
|
|
142
|
+
async function stepOnce(ctx, input) {
|
|
143
|
+
switch (config.pattern) {
|
|
144
|
+
case "sequential":
|
|
145
|
+
return (await stepSequential(config.agents, ctx, input, hooks)).complete;
|
|
146
|
+
case "concurrent":
|
|
147
|
+
return (await stepConcurrent(config.agents, ctx, input, hooks)).complete;
|
|
148
|
+
case "handoff":
|
|
149
|
+
return (await stepHandoff(config.agents, ctx, input, hooks)).complete;
|
|
150
|
+
case "group":
|
|
151
|
+
return (await stepGroup(config.agents, ctx, input, hooks)).complete;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function snapshot(ctx) {
|
|
155
|
+
return createCheckpoint(id, { ...ctx });
|
|
156
|
+
}
|
|
157
|
+
async function drive(ctx, input) {
|
|
158
|
+
try {
|
|
159
|
+
for (; ; ) {
|
|
160
|
+
const prompt = config.humanInputGate?.(ctx);
|
|
161
|
+
if (prompt) {
|
|
162
|
+
currentStatus = "awaiting-input";
|
|
163
|
+
return { status: currentStatus, output: ctx.output, awaiting: { prompt }, checkpoint: snapshot(ctx) };
|
|
164
|
+
}
|
|
165
|
+
const complete = await stepOnce(ctx, input);
|
|
166
|
+
ctx.round++;
|
|
167
|
+
if (complete) {
|
|
168
|
+
currentStatus = "completed";
|
|
169
|
+
return { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };
|
|
170
|
+
}
|
|
171
|
+
if (maxRounds !== -1 && ctx.round >= maxRounds) {
|
|
172
|
+
currentStatus = "completed";
|
|
173
|
+
return { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
} catch (e) {
|
|
177
|
+
currentStatus = "failed";
|
|
178
|
+
return {
|
|
179
|
+
status: currentStatus,
|
|
180
|
+
output: ctx.output,
|
|
181
|
+
error: e.message,
|
|
182
|
+
checkpoint: snapshot(ctx)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function run(input) {
|
|
187
|
+
currentStatus = "running";
|
|
188
|
+
return drive(freshContext(input), input);
|
|
189
|
+
}
|
|
190
|
+
async function* runStream(input) {
|
|
191
|
+
currentStatus = "running";
|
|
192
|
+
const ctx = freshContext(input);
|
|
193
|
+
for (; ; ) {
|
|
194
|
+
const prompt = config.humanInputGate?.(ctx);
|
|
195
|
+
if (prompt) {
|
|
196
|
+
currentStatus = "awaiting-input";
|
|
197
|
+
const state = {
|
|
198
|
+
status: currentStatus,
|
|
199
|
+
output: ctx.output,
|
|
200
|
+
awaiting: { prompt },
|
|
201
|
+
checkpoint: snapshot(ctx)
|
|
202
|
+
};
|
|
203
|
+
yield { type: "awaiting-input", prompt, state };
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
let complete;
|
|
207
|
+
try {
|
|
208
|
+
complete = await stepOnce(ctx, input);
|
|
209
|
+
} catch (e) {
|
|
210
|
+
currentStatus = "failed";
|
|
211
|
+
yield {
|
|
212
|
+
type: "done",
|
|
213
|
+
state: { status: "failed", output: ctx.output, error: e.message, checkpoint: snapshot(ctx) }
|
|
214
|
+
};
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
ctx.round++;
|
|
218
|
+
yield { type: "round", round: ctx.round, output: ctx.output };
|
|
219
|
+
if (complete || maxRounds !== -1 && ctx.round >= maxRounds) {
|
|
220
|
+
currentStatus = "completed";
|
|
221
|
+
yield { type: "done", state: { status: "completed", output: ctx.output, checkpoint: snapshot(ctx) } };
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async function resume(state, humanInput) {
|
|
227
|
+
const cp = restoreCheckpoint(state.checkpoint);
|
|
228
|
+
const ctx = contextFromCheckpoint(cp);
|
|
229
|
+
if (humanInput !== void 0) {
|
|
230
|
+
ctx.output = humanInput;
|
|
231
|
+
ctx.outputs["__human__"] = humanInput;
|
|
232
|
+
}
|
|
233
|
+
currentStatus = "running";
|
|
234
|
+
return drive(ctx, ctx.output);
|
|
235
|
+
}
|
|
236
|
+
return { run, runStream, resume, status: () => currentStatus };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export { CHECKPOINT_VERSION, createCheckpoint, createWorkflow, restoreCheckpoint, runBounded, serializeCheckpoint, stepConcurrent, stepGroup, stepHandoff, stepSequential };
|
|
240
|
+
//# sourceMappingURL=chunk-T2GHJ5R4.js.map
|
|
241
|
+
//# sourceMappingURL=chunk-T2GHJ5R4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/workflows/concurrency.ts","../src/workflows/patterns.ts","../src/workflows/checkpoint.ts","../src/workflows/workflow.ts"],"names":[],"mappings":"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","file":"chunk-T2GHJ5R4.js","sourcesContent":["/**\n * Bounded-concurrency execution with a configurable failure policy for concurrent\n * workflows. Fail-soft (default) aggregates partial results; fail-fast cancels\n * remaining work on the first failure. (FR-019b, FR-019c)\n *\n * @packageDocumentation\n */\n\n/** How concurrent branches react to a failure. */\nexport type FailurePolicy = \"fail-soft\" | \"fail-fast\";\n\n/** Per-branch outcome under fail-soft. */\nexport interface BranchResult<T> {\n\tindex: number;\n\tvalue?: T;\n\terror?: Error;\n}\n\n/**\n * Run `tasks` with at most `maxConcurrency` in flight (-1 = unlimited).\n *\n * - `fail-soft`: every branch runs; failures are captured per-branch.\n * - `fail-fast`: the first failure rejects and remaining branches are abandoned.\n *\n * @returns Per-branch results (always, including under fail-fast where the failing\n * branch carries the error). Under fail-fast this throws on first failure.\n */\nexport async function runBounded<T>(\n\ttasks: Array<() => Promise<T>>,\n\tmaxConcurrency: number,\n\tpolicy: FailurePolicy,\n): Promise<Array<BranchResult<T>>> {\n\tconst limit = maxConcurrency === -1 ? tasks.length : Math.max(1, maxConcurrency);\n\tconst results: Array<BranchResult<T>> = new Array(tasks.length);\n\tlet next = 0;\n\tlet failed: Error | undefined;\n\n\tasync function worker(): Promise<void> {\n\t\tfor (; ;) {\n\t\t\tif (policy === \"fail-fast\" && failed) return;\n\t\t\tconst i = next++;\n\t\t\tif (i >= tasks.length) return;\n\t\t\ttry {\n\t\t\t\tresults[i] = { index: i, value: await tasks[i]!() };\n\t\t\t} catch (e) {\n\t\t\t\tconst err = e as Error;\n\t\t\t\tresults[i] = { index: i, error: err };\n\t\t\t\tif (policy === \"fail-fast\") {\n\t\t\t\t\tfailed = err;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst workers = Array.from({ length: Math.min(limit, tasks.length) }, () => worker());\n\tawait Promise.all(workers);\n\n\tif (policy === \"fail-fast\" && failed) throw failed;\n\treturn results;\n}\n","/**\n * Orchestration patterns: sequential, concurrent, handoff, and group collaboration.\n * Each pattern advances a {@link WorkflowContext} by one round and reports whether\n * the workflow is complete. (FR-019)\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"../agents/agent.js\";\nimport { runBounded, type FailurePolicy } from \"./concurrency.js\";\n\n/** Supported orchestration patterns. */\nexport type WorkflowPattern = \"sequential\" | \"concurrent\" | \"handoff\" | \"group\";\n\n/** Mutable state threaded through pattern execution. */\nexport interface WorkflowContext {\n\t/** Latest combined output. */\n\toutput: string;\n\t/** Per-agent latest outputs (by agent name). */\n\toutputs: Record<string, string>;\n\t/** Current round (0-based). */\n\tround: number;\n\t/** Index of the next agent (handoff/sequential). */\n\tcursor: number;\n\t/** Names of agents that errored this run (fail-soft). */\n\terrors: Record<string, string>;\n}\n\n/** Hooks customizing pattern behavior. */\nexport interface PatternHooks {\n\t/** Returns true when an output signals the workflow is complete. (FR-019a) */\n\tisComplete?: (output: string, ctx: WorkflowContext) => boolean;\n\t/** For handoff: choose the next agent name from the latest output (or null to stop). */\n\tselectNext?: (output: string, ctx: WorkflowContext) => string | null;\n\tmaxConcurrency?: number;\n\tfailurePolicy?: FailurePolicy;\n}\n\n/** One step's result. */\nexport interface StepResult {\n\tcomplete: boolean;\n}\n\nasync function invoke(agent: Agent, input: string, ctx: WorkflowContext): Promise<string> {\n\tconst res = await agent.run(input);\n\tif (res.error || res.status === \"failed\") {\n\t\tctx.errors[agent.name] = res.error?.message ?? \"failed\";\n\t\tthrow res.error ?? new Error(`Agent ${agent.name} failed`);\n\t}\n\tctx.outputs[agent.name] = res.output;\n\treturn res.output;\n}\n\n/** Advance a sequential workflow by one agent. */\nexport async function stepSequential(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tconst agent = agents[ctx.cursor];\n\tif (!agent) return { complete: true };\n\tconst feed = ctx.cursor === 0 ? input : ctx.output;\n\tctx.output = await invoke(agent, feed, ctx);\n\tctx.cursor++;\n\tconst done = ctx.cursor >= agents.length || !!hooks.isComplete?.(ctx.output, ctx);\n\treturn { complete: done };\n}\n\n/** Run all agents concurrently on the same input and aggregate outputs. */\nexport async function stepConcurrent(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tconst results = await runBounded(\n\t\tagents.map((a) => () => invoke(a, input, ctx)),\n\t\thooks.maxConcurrency ?? 4,\n\t\thooks.failurePolicy ?? \"fail-soft\",\n\t);\n\tconst outputs = results.filter((r) => r.value !== undefined).map((r) => r.value as string);\n\tctx.output = outputs.join(\"\\n\\n\");\n\treturn { complete: true };\n}\n\n/** Advance a handoff workflow: the current agent may delegate to another. */\nexport async function stepHandoff(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tconst agent = agents[ctx.cursor];\n\tif (!agent) return { complete: true };\n\tconst feed = ctx.round === 0 ? input : ctx.output;\n\tctx.output = await invoke(agent, feed, ctx);\n\n\tif (hooks.isComplete?.(ctx.output, ctx)) return { complete: true };\n\tconst nextName = hooks.selectNext?.(ctx.output, ctx) ?? null;\n\tif (!nextName) return { complete: true };\n\tconst idx = agents.findIndex((a) => a.name === nextName);\n\tif (idx < 0) return { complete: true };\n\tctx.cursor = idx;\n\treturn { complete: false };\n}\n\n/** Group collaboration: every agent contributes each round until complete. */\nexport async function stepGroup(\n\tagents: Agent[],\n\tctx: WorkflowContext,\n\tinput: string,\n\thooks: PatternHooks,\n): Promise<StepResult> {\n\tlet combined = ctx.round === 0 ? input : ctx.output;\n\tfor (const agent of agents) {\n\t\tcombined = await invoke(agent, combined, ctx);\n\t\tif (hooks.isComplete?.(combined, ctx)) {\n\t\t\tctx.output = combined;\n\t\t\treturn { complete: true };\n\t\t}\n\t}\n\tctx.output = combined;\n\treturn { complete: false };\n}\n","/**\n * Workflow checkpointing. A checkpoint is a serializable snapshot enabling resume.\n * Restore fails closed: corrupt or version-mismatched data yields a typed\n * {@link CheckpointError} with no partial restore. (FR-022, FR-022a)\n *\n * @packageDocumentation\n */\n\nimport { CheckpointError } from \"../core/errors.js\";\n\n/** Current checkpoint schema version. */\nexport const CHECKPOINT_VERSION = \"1\";\n\n/** A serializable workflow snapshot. */\nexport interface Checkpoint {\n\tversion: string;\n\tid: string;\n\t/** Opaque workflow state (round, messages, pending node, etc.). */\n\tstate: Record<string, unknown>;\n}\n\n/** Create a checkpoint with the current schema version. */\nexport function createCheckpoint(id: string, state: Record<string, unknown>): Checkpoint {\n\treturn { version: CHECKPOINT_VERSION, id, state };\n}\n\n/** Serialize a checkpoint to a string. */\nexport function serializeCheckpoint(cp: Checkpoint): string {\n\treturn JSON.stringify(cp);\n}\n\n/**\n * Restore a checkpoint from its serialized form or object. Fails closed.\n *\n * @throws {CheckpointError} `corrupt` if the data cannot be parsed/validated.\n * @throws {CheckpointError} `version-mismatch` if the schema version differs.\n */\nexport function restoreCheckpoint(input: string | Checkpoint): Checkpoint {\n\tlet cp: Checkpoint;\n\tif (typeof input === \"string\") {\n\t\ttry {\n\t\t\tcp = JSON.parse(input) as Checkpoint;\n\t\t} catch {\n\t\t\tthrow new CheckpointError(\"Checkpoint data is not valid JSON\", \"corrupt\");\n\t\t}\n\t} else {\n\t\tcp = input;\n\t}\n\n\tif (!cp || typeof cp !== \"object\" || typeof cp.id !== \"string\" || typeof cp.state !== \"object\") {\n\t\tthrow new CheckpointError(\"Checkpoint is missing required fields\", \"corrupt\");\n\t}\n\tif (cp.version !== CHECKPOINT_VERSION) {\n\t\tthrow new CheckpointError(\n\t\t\t`Checkpoint version ${cp.version} does not match ${CHECKPOINT_VERSION}`,\n\t\t\t\"version-mismatch\",\n\t\t);\n\t}\n\treturn cp;\n}\n","/**\n * The workflow engine: composes agents under an orchestration pattern with a\n * completion signal and a configurable max-rounds safety cap, bounded concurrency,\n * a failure policy, streaming, human-in-the-loop yield/resume, and checkpointing.\n * (FR-018, FR-019, FR-019a, FR-019b, FR-019c, FR-020, FR-021, FR-021a, FR-021b, FR-022)\n *\n * @packageDocumentation\n */\n\nimport type { Agent } from \"../agents/agent.js\";\nimport type { FailurePolicy } from \"./concurrency.js\";\nimport {\n\tstepSequential,\n\tstepConcurrent,\n\tstepHandoff,\n\tstepGroup,\n\ttype WorkflowPattern,\n\ttype WorkflowContext,\n\ttype PatternHooks,\n} from \"./patterns.js\";\nimport { createCheckpoint, restoreCheckpoint, type Checkpoint } from \"./checkpoint.js\";\n\n/** Lifecycle status of a workflow run, observable by the host. (FR-021b) */\nexport type WorkflowStatus = \"running\" | \"awaiting-input\" | \"completed\" | \"failed\";\n\n/** Configuration for {@link createWorkflow}. */\nexport interface WorkflowConfig {\n\tpattern: WorkflowPattern;\n\tagents: Agent[];\n\t/** Max rounds; -1 = unlimited. Default 16. (FR-019a) */\n\tmaxRounds?: number;\n\t/** Concurrent failure policy. Default fail-soft. (FR-019b) */\n\tfailurePolicy?: FailurePolicy;\n\t/** Max parallel agent calls; -1 = unlimited. Default 4. (FR-019c) */\n\tmaxConcurrency?: number;\n\t/** Completion signal: end the workflow when this returns true. (FR-019a) */\n\tisComplete?: (output: string, ctx: WorkflowContext) => boolean;\n\t/** Handoff target selector. */\n\tselectNext?: (output: string, ctx: WorkflowContext) => string | null;\n\t/** Human-in-the-loop gate: when it returns a prompt, the workflow yields. (FR-021) */\n\thumanInputGate?: (ctx: WorkflowContext) => string | null;\n}\n\n/** Serializable result/handle of a workflow run. (FR-021a, FR-022) */\nexport interface WorkflowState {\n\tstatus: WorkflowStatus;\n\toutput: string;\n\t/** Present when status is `awaiting-input`. */\n\tawaiting?: { prompt: string };\n\t/** Error message when status is `failed`. */\n\terror?: string;\n\t/** Snapshot enabling resume. */\n\tcheckpoint: Checkpoint;\n}\n\n/** Streamed workflow event. (FR-020) */\nexport type WorkflowEvent =\n\t| { type: \"round\"; round: number; output: string }\n\t| { type: \"awaiting-input\"; prompt: string; state: WorkflowState }\n\t| { type: \"done\"; state: WorkflowState };\n\n/** A runnable multi-agent workflow. */\nexport interface Workflow {\n\trun(input: string): Promise<WorkflowState>;\n\trunStream(input: string): AsyncIterable<WorkflowEvent>;\n\tresume(state: WorkflowState, humanInput?: string): Promise<WorkflowState>;\n\tstatus(): WorkflowStatus;\n}\n\nfunction freshContext(input: string): WorkflowContext {\n\treturn { output: input, outputs: {}, round: 0, cursor: 0, errors: {} };\n}\n\nfunction contextFromCheckpoint(cp: Checkpoint): WorkflowContext {\n\tconst s = cp.state as Partial<WorkflowContext>;\n\treturn {\n\t\toutput: s.output ?? \"\",\n\t\toutputs: s.outputs ?? {},\n\t\tround: s.round ?? 0,\n\t\tcursor: s.cursor ?? 0,\n\t\terrors: s.errors ?? {},\n\t};\n}\n\n/**\n * Create a workflow.\n *\n * @example\n * ```ts\n * const wf = createWorkflow({ pattern: \"sequential\", agents: [researcher, summarizer] });\n * let state = await wf.run(\"Summarize the notes.\");\n * if (state.status === \"awaiting-input\") state = await wf.resume(state, \"approved\");\n * ```\n */\nexport function createWorkflow(config: WorkflowConfig): Workflow {\n\tconst maxRounds = config.maxRounds ?? 16;\n\tconst id = `wf-${Math.random().toString(36).slice(2)}`;\n\tlet currentStatus: WorkflowStatus = \"running\";\n\n\tconst hooks: PatternHooks = {\n\t\tisComplete: config.isComplete,\n\t\tselectNext: config.selectNext,\n\t\tmaxConcurrency: config.maxConcurrency,\n\t\tfailurePolicy: config.failurePolicy,\n\t};\n\n\tasync function stepOnce(ctx: WorkflowContext, input: string): Promise<boolean> {\n\t\tswitch (config.pattern) {\n\t\t\tcase \"sequential\":\n\t\t\t\treturn (await stepSequential(config.agents, ctx, input, hooks)).complete;\n\t\t\tcase \"concurrent\":\n\t\t\t\treturn (await stepConcurrent(config.agents, ctx, input, hooks)).complete;\n\t\t\tcase \"handoff\":\n\t\t\t\treturn (await stepHandoff(config.agents, ctx, input, hooks)).complete;\n\t\t\tcase \"group\":\n\t\t\t\treturn (await stepGroup(config.agents, ctx, input, hooks)).complete;\n\t\t}\n\t}\n\n\tfunction snapshot(ctx: WorkflowContext): Checkpoint {\n\t\treturn createCheckpoint(id, { ...ctx });\n\t}\n\n\tasync function drive(ctx: WorkflowContext, input: string): Promise<WorkflowState> {\n\t\ttry {\n\t\t\tfor (; ;) {\n\t\t\t\t// Human-in-the-loop: yield a serializable awaiting-input state. (FR-021a)\n\t\t\t\tconst prompt = config.humanInputGate?.(ctx);\n\t\t\t\tif (prompt) {\n\t\t\t\t\tcurrentStatus = \"awaiting-input\";\n\t\t\t\t\treturn { status: currentStatus, output: ctx.output, awaiting: { prompt }, checkpoint: snapshot(ctx) };\n\t\t\t\t}\n\n\t\t\t\tconst complete = await stepOnce(ctx, input);\n\t\t\t\tctx.round++;\n\n\t\t\t\tif (complete) {\n\t\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\t\treturn { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };\n\t\t\t\t}\n\t\t\t\tif (maxRounds !== -1 && ctx.round >= maxRounds) {\n\t\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\t\treturn { status: currentStatus, output: ctx.output, checkpoint: snapshot(ctx) };\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tcurrentStatus = \"failed\";\n\t\t\treturn {\n\t\t\t\tstatus: currentStatus,\n\t\t\t\toutput: ctx.output,\n\t\t\t\terror: (e as Error).message,\n\t\t\t\tcheckpoint: snapshot(ctx),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync function run(input: string): Promise<WorkflowState> {\n\t\tcurrentStatus = \"running\";\n\t\treturn drive(freshContext(input), input);\n\t}\n\n\tasync function* runStream(input: string): AsyncIterable<WorkflowEvent> {\n\t\tcurrentStatus = \"running\";\n\t\tconst ctx = freshContext(input);\n\t\tfor (; ;) {\n\t\t\tconst prompt = config.humanInputGate?.(ctx);\n\t\t\tif (prompt) {\n\t\t\t\tcurrentStatus = \"awaiting-input\";\n\t\t\t\tconst state: WorkflowState = {\n\t\t\t\t\tstatus: currentStatus,\n\t\t\t\t\toutput: ctx.output,\n\t\t\t\t\tawaiting: { prompt },\n\t\t\t\t\tcheckpoint: snapshot(ctx),\n\t\t\t\t};\n\t\t\t\tyield { type: \"awaiting-input\", prompt, state };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet complete: boolean;\n\t\t\ttry {\n\t\t\t\tcomplete = await stepOnce(ctx, input);\n\t\t\t} catch (e) {\n\t\t\t\tcurrentStatus = \"failed\";\n\t\t\t\tyield {\n\t\t\t\t\ttype: \"done\",\n\t\t\t\t\tstate: { status: \"failed\", output: ctx.output, error: (e as Error).message, checkpoint: snapshot(ctx) },\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.round++;\n\t\t\tyield { type: \"round\", round: ctx.round, output: ctx.output };\n\t\t\tif (complete || (maxRounds !== -1 && ctx.round >= maxRounds)) {\n\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\tyield { type: \"done\", state: { status: \"completed\", output: ctx.output, checkpoint: snapshot(ctx) } };\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function resume(state: WorkflowState, humanInput?: string): Promise<WorkflowState> {\n\t\t// Fail-closed restore of the checkpoint. (FR-022a)\n\t\tconst cp = restoreCheckpoint(state.checkpoint);\n\t\tconst ctx = contextFromCheckpoint(cp);\n\t\tif (humanInput !== undefined) {\n\t\t\tctx.output = humanInput;\n\t\t\tctx.outputs[\"__human__\"] = humanInput;\n\t\t}\n\t\tcurrentStatus = \"running\";\n\t\treturn drive(ctx, ctx.output);\n\t}\n\n\treturn { run, runStream, resume, status: () => currentStatus };\n}\n"]}
|