yaml-flow 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +486 -255
- package/dist/constants-D1fTEbbM.d.cts +330 -0
- package/dist/constants-D1fTEbbM.d.ts +330 -0
- package/dist/event-graph/index.cjs +895 -0
- package/dist/event-graph/index.cjs.map +1 -0
- package/dist/event-graph/index.d.cts +53 -0
- package/dist/event-graph/index.d.ts +53 -0
- package/dist/event-graph/index.js +855 -0
- package/dist/event-graph/index.js.map +1 -0
- package/dist/index.cjs +1128 -312
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1093 -306
- package/dist/index.js.map +1 -1
- package/dist/step-machine/index.cjs +513 -0
- package/dist/step-machine/index.cjs.map +1 -0
- package/dist/step-machine/index.d.cts +77 -0
- package/dist/step-machine/index.d.ts +77 -0
- package/dist/step-machine/index.js +502 -0
- package/dist/step-machine/index.js.map +1 -0
- package/dist/stores/file.cjs.map +1 -1
- package/dist/stores/file.d.cts +4 -4
- package/dist/stores/file.d.ts +4 -4
- package/dist/stores/file.js.map +1 -1
- package/dist/stores/index.cjs +232 -0
- package/dist/stores/index.cjs.map +1 -0
- package/dist/stores/index.d.cts +4 -0
- package/dist/stores/index.d.ts +4 -0
- package/dist/stores/index.js +228 -0
- package/dist/stores/index.js.map +1 -0
- package/dist/stores/localStorage.cjs.map +1 -1
- package/dist/stores/localStorage.d.cts +4 -4
- package/dist/stores/localStorage.d.ts +4 -4
- package/dist/stores/localStorage.js.map +1 -1
- package/dist/stores/memory.cjs.map +1 -1
- package/dist/stores/memory.d.cts +4 -4
- package/dist/stores/memory.d.ts +4 -4
- package/dist/stores/memory.js.map +1 -1
- package/dist/types-FZ_eyErS.d.cts +115 -0
- package/dist/types-FZ_eyErS.d.ts +115 -0
- package/package.json +16 -6
- package/dist/core/index.cjs +0 -557
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.d.cts +0 -102
- package/dist/core/index.d.ts +0 -102
- package/dist/core/index.js +0 -549
- package/dist/core/index.js.map +0 -1
- package/dist/types-BoWndaAJ.d.cts +0 -237
- package/dist/types-BoWndaAJ.d.ts +0 -237
package/dist/core/index.js
DELETED
|
@@ -1,549 +0,0 @@
|
|
|
1
|
-
// src/stores/memory.ts
|
|
2
|
-
var MemoryStore = class {
|
|
3
|
-
runs = /* @__PURE__ */ new Map();
|
|
4
|
-
data = /* @__PURE__ */ new Map();
|
|
5
|
-
async saveRunState(runId, state) {
|
|
6
|
-
this.runs.set(runId, { ...state });
|
|
7
|
-
}
|
|
8
|
-
async loadRunState(runId) {
|
|
9
|
-
const state = this.runs.get(runId);
|
|
10
|
-
return state ? { ...state } : null;
|
|
11
|
-
}
|
|
12
|
-
async deleteRunState(runId) {
|
|
13
|
-
this.runs.delete(runId);
|
|
14
|
-
this.data.delete(runId);
|
|
15
|
-
}
|
|
16
|
-
async setData(runId, key, value) {
|
|
17
|
-
if (!this.data.has(runId)) {
|
|
18
|
-
this.data.set(runId, {});
|
|
19
|
-
}
|
|
20
|
-
const runData = this.data.get(runId);
|
|
21
|
-
runData[key] = value;
|
|
22
|
-
}
|
|
23
|
-
async getData(runId, key) {
|
|
24
|
-
return this.data.get(runId)?.[key];
|
|
25
|
-
}
|
|
26
|
-
async getAllData(runId) {
|
|
27
|
-
return { ...this.data.get(runId) ?? {} };
|
|
28
|
-
}
|
|
29
|
-
async clearData(runId) {
|
|
30
|
-
this.data.delete(runId);
|
|
31
|
-
}
|
|
32
|
-
async listRuns() {
|
|
33
|
-
return Array.from(this.runs.keys());
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Clear all data (useful for testing)
|
|
37
|
-
*/
|
|
38
|
-
clear() {
|
|
39
|
-
this.runs.clear();
|
|
40
|
-
this.data.clear();
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// src/core/engine.ts
|
|
45
|
-
function generateRunId() {
|
|
46
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
47
|
-
return crypto.randomUUID();
|
|
48
|
-
}
|
|
49
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
50
|
-
const r = Math.random() * 16 | 0;
|
|
51
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
52
|
-
return v.toString(16);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
var FlowEngine = class {
|
|
56
|
-
flow;
|
|
57
|
-
handlers;
|
|
58
|
-
store;
|
|
59
|
-
components;
|
|
60
|
-
options;
|
|
61
|
-
listeners = /* @__PURE__ */ new Map();
|
|
62
|
-
aborted = false;
|
|
63
|
-
constructor(flow, handlers, options = {}) {
|
|
64
|
-
this.flow = flow;
|
|
65
|
-
this.handlers = new Map(Object.entries(handlers));
|
|
66
|
-
this.store = options.store ?? new MemoryStore();
|
|
67
|
-
this.components = options.components ?? {};
|
|
68
|
-
this.options = options;
|
|
69
|
-
if (options.signal) {
|
|
70
|
-
options.signal.addEventListener("abort", () => {
|
|
71
|
-
this.aborted = true;
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
this.validateFlow();
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Validate the flow configuration
|
|
78
|
-
*/
|
|
79
|
-
validateFlow() {
|
|
80
|
-
const { settings, steps, terminal_states } = this.flow;
|
|
81
|
-
if (!settings?.start_step) {
|
|
82
|
-
throw new Error("Flow must have settings.start_step defined");
|
|
83
|
-
}
|
|
84
|
-
if (!steps || Object.keys(steps).length === 0) {
|
|
85
|
-
throw new Error("Flow must have at least one step defined");
|
|
86
|
-
}
|
|
87
|
-
if (!terminal_states || Object.keys(terminal_states).length === 0) {
|
|
88
|
-
throw new Error("Flow must have at least one terminal_state defined");
|
|
89
|
-
}
|
|
90
|
-
if (!steps[settings.start_step] && !terminal_states[settings.start_step]) {
|
|
91
|
-
throw new Error(`Start step "${settings.start_step}" not found in steps or terminal_states`);
|
|
92
|
-
}
|
|
93
|
-
for (const [stepName, stepConfig] of Object.entries(steps)) {
|
|
94
|
-
for (const [result, target] of Object.entries(stepConfig.transitions)) {
|
|
95
|
-
if (!steps[target] && !terminal_states[target]) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
`Step "${stepName}" transition "${result}" points to unknown step "${target}"`
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Run the flow from the start
|
|
105
|
-
*/
|
|
106
|
-
async run(initialData) {
|
|
107
|
-
const runId = generateRunId();
|
|
108
|
-
const startedAt = Date.now();
|
|
109
|
-
const runState = {
|
|
110
|
-
runId,
|
|
111
|
-
flowId: this.flow.id ?? "unnamed",
|
|
112
|
-
currentStep: this.flow.settings.start_step,
|
|
113
|
-
status: "running",
|
|
114
|
-
stepHistory: [],
|
|
115
|
-
iterationCounts: {},
|
|
116
|
-
retryCounts: {},
|
|
117
|
-
startedAt,
|
|
118
|
-
updatedAt: startedAt
|
|
119
|
-
};
|
|
120
|
-
await this.store.saveRunState(runId, runState);
|
|
121
|
-
if (initialData) {
|
|
122
|
-
for (const [key, value] of Object.entries(initialData)) {
|
|
123
|
-
await this.store.setData(runId, key, value);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
this.emit({
|
|
127
|
-
type: "flow:start",
|
|
128
|
-
runId,
|
|
129
|
-
timestamp: startedAt,
|
|
130
|
-
data: { initialData }
|
|
131
|
-
});
|
|
132
|
-
try {
|
|
133
|
-
return await this.executeLoop(runId, runState, startedAt);
|
|
134
|
-
} catch (error) {
|
|
135
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
136
|
-
this.emit({
|
|
137
|
-
type: "flow:error",
|
|
138
|
-
runId,
|
|
139
|
-
timestamp: Date.now(),
|
|
140
|
-
data: { error: err.message }
|
|
141
|
-
});
|
|
142
|
-
this.options.onError?.(err);
|
|
143
|
-
runState.status = "failed";
|
|
144
|
-
runState.updatedAt = Date.now();
|
|
145
|
-
await this.store.saveRunState(runId, runState);
|
|
146
|
-
return {
|
|
147
|
-
runId,
|
|
148
|
-
status: "failed",
|
|
149
|
-
data: await this.store.getAllData(runId),
|
|
150
|
-
finalStep: runState.currentStep,
|
|
151
|
-
stepHistory: runState.stepHistory,
|
|
152
|
-
durationMs: Date.now() - startedAt,
|
|
153
|
-
error: err
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Resume a paused or interrupted flow
|
|
159
|
-
*/
|
|
160
|
-
async resume(runId) {
|
|
161
|
-
const runState = await this.store.loadRunState(runId);
|
|
162
|
-
if (!runState) {
|
|
163
|
-
throw new Error(`No run found with ID: ${runId}`);
|
|
164
|
-
}
|
|
165
|
-
if (runState.status === "completed" || runState.status === "failed") {
|
|
166
|
-
throw new Error(`Cannot resume a ${runState.status} run`);
|
|
167
|
-
}
|
|
168
|
-
const startedAt = runState.startedAt;
|
|
169
|
-
runState.status = "running";
|
|
170
|
-
runState.pausedAt = void 0;
|
|
171
|
-
runState.updatedAt = Date.now();
|
|
172
|
-
await this.store.saveRunState(runId, runState);
|
|
173
|
-
this.emit({
|
|
174
|
-
type: "flow:resumed",
|
|
175
|
-
runId,
|
|
176
|
-
timestamp: Date.now(),
|
|
177
|
-
data: { currentStep: runState.currentStep }
|
|
178
|
-
});
|
|
179
|
-
return this.executeLoop(runId, runState, startedAt);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Pause a running flow
|
|
183
|
-
*/
|
|
184
|
-
async pause(runId) {
|
|
185
|
-
const runState = await this.store.loadRunState(runId);
|
|
186
|
-
if (!runState) {
|
|
187
|
-
throw new Error(`No run found with ID: ${runId}`);
|
|
188
|
-
}
|
|
189
|
-
runState.status = "paused";
|
|
190
|
-
runState.pausedAt = Date.now();
|
|
191
|
-
runState.updatedAt = Date.now();
|
|
192
|
-
await this.store.saveRunState(runId, runState);
|
|
193
|
-
this.emit({
|
|
194
|
-
type: "flow:paused",
|
|
195
|
-
runId,
|
|
196
|
-
timestamp: Date.now(),
|
|
197
|
-
data: { currentStep: runState.currentStep }
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Main execution loop
|
|
202
|
-
*/
|
|
203
|
-
async executeLoop(runId, runState, startedAt) {
|
|
204
|
-
const maxSteps = this.flow.settings.max_total_steps ?? 100;
|
|
205
|
-
const timeoutMs = this.flow.settings.timeout_ms;
|
|
206
|
-
let iterations = 0;
|
|
207
|
-
while (iterations < maxSteps) {
|
|
208
|
-
if (this.aborted) {
|
|
209
|
-
runState.status = "cancelled";
|
|
210
|
-
runState.updatedAt = Date.now();
|
|
211
|
-
await this.store.saveRunState(runId, runState);
|
|
212
|
-
return {
|
|
213
|
-
runId,
|
|
214
|
-
status: "cancelled",
|
|
215
|
-
data: await this.store.getAllData(runId),
|
|
216
|
-
finalStep: runState.currentStep,
|
|
217
|
-
stepHistory: runState.stepHistory,
|
|
218
|
-
durationMs: Date.now() - startedAt
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
if (timeoutMs && Date.now() - startedAt > timeoutMs) {
|
|
222
|
-
runState.status = "completed";
|
|
223
|
-
runState.updatedAt = Date.now();
|
|
224
|
-
await this.store.saveRunState(runId, runState);
|
|
225
|
-
return {
|
|
226
|
-
runId,
|
|
227
|
-
status: "timeout",
|
|
228
|
-
intent: "timeout",
|
|
229
|
-
data: await this.store.getAllData(runId),
|
|
230
|
-
finalStep: runState.currentStep,
|
|
231
|
-
stepHistory: runState.stepHistory,
|
|
232
|
-
durationMs: Date.now() - startedAt
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
const currentStep = runState.currentStep;
|
|
236
|
-
const terminalState = this.flow.terminal_states[currentStep];
|
|
237
|
-
if (terminalState) {
|
|
238
|
-
runState.status = "completed";
|
|
239
|
-
runState.updatedAt = Date.now();
|
|
240
|
-
await this.store.saveRunState(runId, runState);
|
|
241
|
-
const allData = await this.store.getAllData(runId);
|
|
242
|
-
const returnData = this.extractReturnData(terminalState.return_artifacts, allData);
|
|
243
|
-
const result = {
|
|
244
|
-
runId,
|
|
245
|
-
status: "completed",
|
|
246
|
-
intent: terminalState.return_intent,
|
|
247
|
-
data: returnData,
|
|
248
|
-
finalStep: currentStep,
|
|
249
|
-
stepHistory: runState.stepHistory,
|
|
250
|
-
durationMs: Date.now() - startedAt
|
|
251
|
-
};
|
|
252
|
-
this.emit({
|
|
253
|
-
type: "flow:complete",
|
|
254
|
-
runId,
|
|
255
|
-
timestamp: Date.now(),
|
|
256
|
-
data: { ...result }
|
|
257
|
-
});
|
|
258
|
-
this.options.onComplete?.(result);
|
|
259
|
-
return result;
|
|
260
|
-
}
|
|
261
|
-
const stepConfig = this.flow.steps[currentStep];
|
|
262
|
-
if (!stepConfig) {
|
|
263
|
-
throw new Error(`Step "${currentStep}" not found in flow configuration`);
|
|
264
|
-
}
|
|
265
|
-
if (stepConfig.circuit_breaker) {
|
|
266
|
-
const count = runState.iterationCounts[currentStep] ?? 0;
|
|
267
|
-
if (count >= stepConfig.circuit_breaker.max_iterations) {
|
|
268
|
-
runState.currentStep = stepConfig.circuit_breaker.on_open;
|
|
269
|
-
runState.updatedAt = Date.now();
|
|
270
|
-
await this.store.saveRunState(runId, runState);
|
|
271
|
-
iterations++;
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
runState.iterationCounts[currentStep] = (runState.iterationCounts[currentStep] ?? 0) + 1;
|
|
276
|
-
const stepResult = await this.executeStep(runId, currentStep, stepConfig);
|
|
277
|
-
if (stepResult.result === "failure" && stepConfig.retry) {
|
|
278
|
-
const retryCount = runState.retryCounts[currentStep] ?? 0;
|
|
279
|
-
if (retryCount < stepConfig.retry.max_attempts) {
|
|
280
|
-
runState.retryCounts[currentStep] = retryCount + 1;
|
|
281
|
-
if (stepConfig.retry.delay_ms) {
|
|
282
|
-
const delay = stepConfig.retry.backoff_multiplier ? stepConfig.retry.delay_ms * Math.pow(stepConfig.retry.backoff_multiplier, retryCount) : stepConfig.retry.delay_ms;
|
|
283
|
-
await this.sleep(delay);
|
|
284
|
-
}
|
|
285
|
-
iterations++;
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
const nextStep = stepConfig.transitions[stepResult.result];
|
|
290
|
-
if (!nextStep) {
|
|
291
|
-
throw new Error(
|
|
292
|
-
`No transition defined for result "${stepResult.result}" in step "${currentStep}"`
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
runState.stepHistory.push(currentStep);
|
|
296
|
-
runState.currentStep = nextStep;
|
|
297
|
-
runState.updatedAt = Date.now();
|
|
298
|
-
runState.retryCounts[currentStep] = 0;
|
|
299
|
-
await this.store.saveRunState(runId, runState);
|
|
300
|
-
this.emit({
|
|
301
|
-
type: "transition",
|
|
302
|
-
runId,
|
|
303
|
-
timestamp: Date.now(),
|
|
304
|
-
data: { from: currentStep, to: nextStep, result: stepResult.result }
|
|
305
|
-
});
|
|
306
|
-
this.options.onTransition?.(currentStep, nextStep);
|
|
307
|
-
iterations++;
|
|
308
|
-
}
|
|
309
|
-
runState.status = "completed";
|
|
310
|
-
runState.updatedAt = Date.now();
|
|
311
|
-
await this.store.saveRunState(runId, runState);
|
|
312
|
-
return {
|
|
313
|
-
runId,
|
|
314
|
-
status: "max_iterations",
|
|
315
|
-
intent: "max_iterations",
|
|
316
|
-
data: await this.store.getAllData(runId),
|
|
317
|
-
finalStep: runState.currentStep,
|
|
318
|
-
stepHistory: runState.stepHistory,
|
|
319
|
-
durationMs: Date.now() - startedAt
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Execute a single step
|
|
324
|
-
*/
|
|
325
|
-
async executeStep(runId, stepName, stepConfig) {
|
|
326
|
-
const handler = this.handlers.get(stepName);
|
|
327
|
-
if (!handler) {
|
|
328
|
-
throw new Error(`No handler registered for step "${stepName}"`);
|
|
329
|
-
}
|
|
330
|
-
const allData = await this.store.getAllData(runId);
|
|
331
|
-
const input = {};
|
|
332
|
-
if (stepConfig.expects_data) {
|
|
333
|
-
for (const key of stepConfig.expects_data) {
|
|
334
|
-
input[key] = allData[key];
|
|
335
|
-
}
|
|
336
|
-
} else {
|
|
337
|
-
Object.assign(input, allData);
|
|
338
|
-
}
|
|
339
|
-
const context = {
|
|
340
|
-
runId,
|
|
341
|
-
stepName,
|
|
342
|
-
components: this.components,
|
|
343
|
-
store: this.store,
|
|
344
|
-
signal: this.options.signal,
|
|
345
|
-
emit: (event, data) => {
|
|
346
|
-
this.emit({
|
|
347
|
-
type: "step:complete",
|
|
348
|
-
// Custom events map to step:complete
|
|
349
|
-
runId,
|
|
350
|
-
timestamp: Date.now(),
|
|
351
|
-
data: { event, payload: data }
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
};
|
|
355
|
-
this.emit({
|
|
356
|
-
type: "step:start",
|
|
357
|
-
runId,
|
|
358
|
-
timestamp: Date.now(),
|
|
359
|
-
data: { step: stepName, input }
|
|
360
|
-
});
|
|
361
|
-
try {
|
|
362
|
-
const result = await handler(input, context);
|
|
363
|
-
if (result.data) {
|
|
364
|
-
for (const [key, value] of Object.entries(result.data)) {
|
|
365
|
-
await this.store.setData(runId, key, value);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
this.emit({
|
|
369
|
-
type: "step:complete",
|
|
370
|
-
runId,
|
|
371
|
-
timestamp: Date.now(),
|
|
372
|
-
data: { step: stepName, result: result.result, outputKeys: Object.keys(result.data ?? {}) }
|
|
373
|
-
});
|
|
374
|
-
this.options.onStep?.(stepName, result);
|
|
375
|
-
return result;
|
|
376
|
-
} catch (error) {
|
|
377
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
378
|
-
this.emit({
|
|
379
|
-
type: "step:error",
|
|
380
|
-
runId,
|
|
381
|
-
timestamp: Date.now(),
|
|
382
|
-
data: { step: stepName, error: err.message }
|
|
383
|
-
});
|
|
384
|
-
return { result: "failure", data: { error: err.message } };
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Extract data to return based on return_artifacts configuration
|
|
389
|
-
*/
|
|
390
|
-
extractReturnData(returnArtifacts, allData) {
|
|
391
|
-
if (returnArtifacts === false || returnArtifacts === void 0) {
|
|
392
|
-
return {};
|
|
393
|
-
}
|
|
394
|
-
if (typeof returnArtifacts === "string") {
|
|
395
|
-
return { [returnArtifacts]: allData[returnArtifacts] };
|
|
396
|
-
}
|
|
397
|
-
if (Array.isArray(returnArtifacts)) {
|
|
398
|
-
const result = {};
|
|
399
|
-
for (const key of returnArtifacts) {
|
|
400
|
-
result[key] = allData[key];
|
|
401
|
-
}
|
|
402
|
-
return result;
|
|
403
|
-
}
|
|
404
|
-
return allData;
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Sleep helper
|
|
408
|
-
*/
|
|
409
|
-
sleep(ms) {
|
|
410
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Subscribe to flow events
|
|
414
|
-
*/
|
|
415
|
-
on(type, listener) {
|
|
416
|
-
if (!this.listeners.has(type)) {
|
|
417
|
-
this.listeners.set(type, /* @__PURE__ */ new Set());
|
|
418
|
-
}
|
|
419
|
-
this.listeners.get(type).add(listener);
|
|
420
|
-
return () => {
|
|
421
|
-
this.listeners.get(type)?.delete(listener);
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Emit an event
|
|
426
|
-
*/
|
|
427
|
-
emit(event) {
|
|
428
|
-
const typeListeners = this.listeners.get(event.type);
|
|
429
|
-
if (typeListeners) {
|
|
430
|
-
for (const listener of typeListeners) {
|
|
431
|
-
try {
|
|
432
|
-
listener(event);
|
|
433
|
-
} catch {
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Get the current store instance
|
|
440
|
-
*/
|
|
441
|
-
getStore() {
|
|
442
|
-
return this.store;
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
function createEngine(flow, handlers, options) {
|
|
446
|
-
return new FlowEngine(flow, handlers, options);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// src/core/loader.ts
|
|
450
|
-
async function parseYaml(yamlString) {
|
|
451
|
-
const yaml = await import('yaml');
|
|
452
|
-
return yaml.parse(yamlString);
|
|
453
|
-
}
|
|
454
|
-
async function loadFlowFromUrl(url) {
|
|
455
|
-
const response = await fetch(url);
|
|
456
|
-
if (!response.ok) {
|
|
457
|
-
throw new Error(`Failed to load flow from ${url}: ${response.statusText}`);
|
|
458
|
-
}
|
|
459
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
460
|
-
const text = await response.text();
|
|
461
|
-
if (contentType.includes("json") || url.endsWith(".json")) {
|
|
462
|
-
return JSON.parse(text);
|
|
463
|
-
}
|
|
464
|
-
return parseYaml(text);
|
|
465
|
-
}
|
|
466
|
-
async function loadFlowFromFile(filePath) {
|
|
467
|
-
const fs = await import('fs/promises');
|
|
468
|
-
const text = await fs.readFile(filePath, "utf-8");
|
|
469
|
-
if (filePath.endsWith(".json")) {
|
|
470
|
-
return JSON.parse(text);
|
|
471
|
-
}
|
|
472
|
-
return parseYaml(text);
|
|
473
|
-
}
|
|
474
|
-
function validateFlowConfig(flow) {
|
|
475
|
-
const errors = [];
|
|
476
|
-
if (!flow || typeof flow !== "object") {
|
|
477
|
-
return ["Flow must be an object"];
|
|
478
|
-
}
|
|
479
|
-
const f = flow;
|
|
480
|
-
if (!f.settings || typeof f.settings !== "object") {
|
|
481
|
-
errors.push('Flow must have a "settings" object');
|
|
482
|
-
} else {
|
|
483
|
-
const settings = f.settings;
|
|
484
|
-
if (typeof settings.start_step !== "string") {
|
|
485
|
-
errors.push("settings.start_step must be a string");
|
|
486
|
-
}
|
|
487
|
-
if (settings.max_total_steps !== void 0 && typeof settings.max_total_steps !== "number") {
|
|
488
|
-
errors.push("settings.max_total_steps must be a number");
|
|
489
|
-
}
|
|
490
|
-
if (settings.timeout_ms !== void 0 && typeof settings.timeout_ms !== "number") {
|
|
491
|
-
errors.push("settings.timeout_ms must be a number");
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
if (!f.steps || typeof f.steps !== "object") {
|
|
495
|
-
errors.push('Flow must have a "steps" object');
|
|
496
|
-
} else {
|
|
497
|
-
const steps = f.steps;
|
|
498
|
-
for (const [stepName, stepConfig] of Object.entries(steps)) {
|
|
499
|
-
if (!stepConfig || typeof stepConfig !== "object") {
|
|
500
|
-
errors.push(`Step "${stepName}" must be an object`);
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
const step = stepConfig;
|
|
504
|
-
if (!step.transitions || typeof step.transitions !== "object") {
|
|
505
|
-
errors.push(`Step "${stepName}" must have a "transitions" object`);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
if (!f.terminal_states || typeof f.terminal_states !== "object") {
|
|
510
|
-
errors.push('Flow must have a "terminal_states" object');
|
|
511
|
-
} else {
|
|
512
|
-
const terminals = f.terminal_states;
|
|
513
|
-
for (const [name, config] of Object.entries(terminals)) {
|
|
514
|
-
if (!config || typeof config !== "object") {
|
|
515
|
-
errors.push(`Terminal state "${name}" must be an object`);
|
|
516
|
-
continue;
|
|
517
|
-
}
|
|
518
|
-
const terminal = config;
|
|
519
|
-
if (typeof terminal.return_intent !== "string") {
|
|
520
|
-
errors.push(`Terminal state "${name}" must have a "return_intent" string`);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
return errors;
|
|
525
|
-
}
|
|
526
|
-
async function loadFlow(source) {
|
|
527
|
-
let flow;
|
|
528
|
-
if (typeof source === "string") {
|
|
529
|
-
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
530
|
-
flow = await loadFlowFromUrl(source);
|
|
531
|
-
} else if (source.includes("{")) {
|
|
532
|
-
flow = JSON.parse(source);
|
|
533
|
-
} else {
|
|
534
|
-
flow = await loadFlowFromFile(source);
|
|
535
|
-
}
|
|
536
|
-
} else {
|
|
537
|
-
flow = source;
|
|
538
|
-
}
|
|
539
|
-
const errors = validateFlowConfig(flow);
|
|
540
|
-
if (errors.length > 0) {
|
|
541
|
-
throw new Error(`Invalid flow configuration:
|
|
542
|
-
- ${errors.join("\n- ")}`);
|
|
543
|
-
}
|
|
544
|
-
return flow;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
export { FlowEngine, createEngine, loadFlow, loadFlowFromFile, loadFlowFromUrl, parseYaml, validateFlowConfig };
|
|
548
|
-
//# sourceMappingURL=index.js.map
|
|
549
|
-
//# sourceMappingURL=index.js.map
|
package/dist/core/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/stores/memory.ts","../../src/core/engine.ts","../../src/core/loader.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * yaml-flow - Memory Store\n * \n * In-memory store implementation. Works in both browser and Node.js.\n * Data is lost when the process exits - use for testing or short-lived flows.\n */\n\nimport type { FlowStore, RunState } from '../core/types.js';\n\nexport class MemoryStore implements FlowStore {\n private runs: Map<string, RunState> = new Map();\n private data: Map<string, Record<string, unknown>> = new Map();\n\n async saveRunState(runId: string, state: RunState): Promise<void> {\n this.runs.set(runId, { ...state });\n }\n\n async loadRunState(runId: string): Promise<RunState | null> {\n const state = this.runs.get(runId);\n return state ? { ...state } : null;\n }\n\n async deleteRunState(runId: string): Promise<void> {\n this.runs.delete(runId);\n this.data.delete(runId);\n }\n\n async setData(runId: string, key: string, value: unknown): Promise<void> {\n if (!this.data.has(runId)) {\n this.data.set(runId, {});\n }\n const runData = this.data.get(runId)!;\n runData[key] = value;\n }\n\n async getData(runId: string, key: string): Promise<unknown> {\n return this.data.get(runId)?.[key];\n }\n\n async getAllData(runId: string): Promise<Record<string, unknown>> {\n return { ...(this.data.get(runId) ?? {}) };\n }\n\n async clearData(runId: string): Promise<void> {\n this.data.delete(runId);\n }\n\n async listRuns(): Promise<string[]> {\n return Array.from(this.runs.keys());\n }\n\n /**\n * Clear all data (useful for testing)\n */\n clear(): void {\n this.runs.clear();\n this.data.clear();\n }\n}\n","/**\n * yaml-flow - Core Flow Engine\n * \n * Isomorphic workflow engine that executes declarative flows.\n * Works in both browser and Node.js environments.\n */\n\nimport type {\n FlowConfig,\n FlowStore,\n FlowResult,\n StepHandler,\n StepContext,\n StepResult,\n EngineOptions,\n RunState,\n FlowEvent,\n FlowEventListener,\n FlowEventType,\n} from './types.js';\nimport { MemoryStore } from '../stores/memory.js';\n\n/**\n * Generate a unique run ID\n */\nfunction generateRunId(): string {\n // Use crypto.randomUUID if available (modern browsers + Node 19+)\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * FlowEngine - The main workflow execution engine\n */\nexport class FlowEngine {\n private flow: FlowConfig;\n private handlers: Map<string, StepHandler>;\n private store: FlowStore;\n private components: Record<string, unknown>;\n private options: EngineOptions;\n private listeners: Map<FlowEventType, Set<FlowEventListener>> = new Map();\n private aborted: boolean = false;\n\n constructor(\n flow: FlowConfig,\n handlers: Record<string, StepHandler>,\n options: EngineOptions = {}\n ) {\n this.flow = flow;\n this.handlers = new Map(Object.entries(handlers));\n this.store = options.store ?? new MemoryStore();\n this.components = options.components ?? {};\n this.options = options;\n\n // Wire up abort signal\n if (options.signal) {\n options.signal.addEventListener('abort', () => {\n this.aborted = true;\n });\n }\n\n // Validate flow configuration\n this.validateFlow();\n }\n\n /**\n * Validate the flow configuration\n */\n private validateFlow(): void {\n const { settings, steps, terminal_states } = this.flow;\n\n if (!settings?.start_step) {\n throw new Error('Flow must have settings.start_step defined');\n }\n\n if (!steps || Object.keys(steps).length === 0) {\n throw new Error('Flow must have at least one step defined');\n }\n\n if (!terminal_states || Object.keys(terminal_states).length === 0) {\n throw new Error('Flow must have at least one terminal_state defined');\n }\n\n // Check start step exists\n if (!steps[settings.start_step] && !terminal_states[settings.start_step]) {\n throw new Error(`Start step \"${settings.start_step}\" not found in steps or terminal_states`);\n }\n\n // Validate all transitions point to valid steps\n for (const [stepName, stepConfig] of Object.entries(steps)) {\n for (const [result, target] of Object.entries(stepConfig.transitions)) {\n if (!steps[target] && !terminal_states[target]) {\n throw new Error(\n `Step \"${stepName}\" transition \"${result}\" points to unknown step \"${target}\"`\n );\n }\n }\n }\n }\n\n /**\n * Run the flow from the start\n */\n async run(initialData?: Record<string, unknown>): Promise<FlowResult> {\n const runId = generateRunId();\n const startedAt = Date.now();\n\n // Initialize run state\n const runState: RunState = {\n runId,\n flowId: this.flow.id ?? 'unnamed',\n currentStep: this.flow.settings.start_step,\n status: 'running',\n stepHistory: [],\n iterationCounts: {},\n retryCounts: {},\n startedAt,\n updatedAt: startedAt,\n };\n\n await this.store.saveRunState(runId, runState);\n\n // Store initial data\n if (initialData) {\n for (const [key, value] of Object.entries(initialData)) {\n await this.store.setData(runId, key, value);\n }\n }\n\n this.emit({\n type: 'flow:start',\n runId,\n timestamp: startedAt,\n data: { initialData },\n });\n\n try {\n return await this.executeLoop(runId, runState, startedAt);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n \n this.emit({\n type: 'flow:error',\n runId,\n timestamp: Date.now(),\n data: { error: err.message },\n });\n\n this.options.onError?.(err);\n\n // Update state to failed\n runState.status = 'failed';\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n\n return {\n runId,\n status: 'failed',\n data: await this.store.getAllData(runId),\n finalStep: runState.currentStep,\n stepHistory: runState.stepHistory,\n durationMs: Date.now() - startedAt,\n error: err,\n };\n }\n }\n\n /**\n * Resume a paused or interrupted flow\n */\n async resume(runId: string): Promise<FlowResult> {\n const runState = await this.store.loadRunState(runId);\n \n if (!runState) {\n throw new Error(`No run found with ID: ${runId}`);\n }\n\n if (runState.status === 'completed' || runState.status === 'failed') {\n throw new Error(`Cannot resume a ${runState.status} run`);\n }\n\n const startedAt = runState.startedAt;\n runState.status = 'running';\n runState.pausedAt = undefined;\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n\n this.emit({\n type: 'flow:resumed',\n runId,\n timestamp: Date.now(),\n data: { currentStep: runState.currentStep },\n });\n\n return this.executeLoop(runId, runState, startedAt);\n }\n\n /**\n * Pause a running flow\n */\n async pause(runId: string): Promise<void> {\n const runState = await this.store.loadRunState(runId);\n \n if (!runState) {\n throw new Error(`No run found with ID: ${runId}`);\n }\n\n runState.status = 'paused';\n runState.pausedAt = Date.now();\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n\n this.emit({\n type: 'flow:paused',\n runId,\n timestamp: Date.now(),\n data: { currentStep: runState.currentStep },\n });\n }\n\n /**\n * Main execution loop\n */\n private async executeLoop(\n runId: string,\n runState: RunState,\n startedAt: number\n ): Promise<FlowResult> {\n const maxSteps = this.flow.settings.max_total_steps ?? 100;\n const timeoutMs = this.flow.settings.timeout_ms;\n let iterations = 0;\n\n while (iterations < maxSteps) {\n // Check for abort\n if (this.aborted) {\n runState.status = 'cancelled';\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n\n return {\n runId,\n status: 'cancelled',\n data: await this.store.getAllData(runId),\n finalStep: runState.currentStep,\n stepHistory: runState.stepHistory,\n durationMs: Date.now() - startedAt,\n };\n }\n\n // Check for timeout\n if (timeoutMs && Date.now() - startedAt > timeoutMs) {\n runState.status = 'completed';\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n\n return {\n runId,\n status: 'timeout',\n intent: 'timeout',\n data: await this.store.getAllData(runId),\n finalStep: runState.currentStep,\n stepHistory: runState.stepHistory,\n durationMs: Date.now() - startedAt,\n };\n }\n\n const currentStep = runState.currentStep;\n\n // Check if we're at a terminal state\n const terminalState = this.flow.terminal_states[currentStep];\n if (terminalState) {\n runState.status = 'completed';\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n\n const allData = await this.store.getAllData(runId);\n const returnData = this.extractReturnData(terminalState.return_artifacts, allData);\n\n const result: FlowResult = {\n runId,\n status: 'completed',\n intent: terminalState.return_intent,\n data: returnData,\n finalStep: currentStep,\n stepHistory: runState.stepHistory,\n durationMs: Date.now() - startedAt,\n };\n\n this.emit({\n type: 'flow:complete',\n runId,\n timestamp: Date.now(),\n data: { ...result },\n });\n\n this.options.onComplete?.(result);\n\n return result;\n }\n\n // Get step configuration\n const stepConfig = this.flow.steps[currentStep];\n if (!stepConfig) {\n throw new Error(`Step \"${currentStep}\" not found in flow configuration`);\n }\n\n // Check circuit breaker\n if (stepConfig.circuit_breaker) {\n const count = runState.iterationCounts[currentStep] ?? 0;\n if (count >= stepConfig.circuit_breaker.max_iterations) {\n runState.currentStep = stepConfig.circuit_breaker.on_open;\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n iterations++;\n continue;\n }\n }\n\n // Update iteration count\n runState.iterationCounts[currentStep] = (runState.iterationCounts[currentStep] ?? 0) + 1;\n\n // Execute the step\n const stepResult = await this.executeStep(runId, currentStep, stepConfig);\n\n // Handle retry logic\n if (stepResult.result === 'failure' && stepConfig.retry) {\n const retryCount = runState.retryCounts[currentStep] ?? 0;\n if (retryCount < stepConfig.retry.max_attempts) {\n runState.retryCounts[currentStep] = retryCount + 1;\n \n // Apply delay if configured\n if (stepConfig.retry.delay_ms) {\n const delay = stepConfig.retry.backoff_multiplier\n ? stepConfig.retry.delay_ms * Math.pow(stepConfig.retry.backoff_multiplier, retryCount)\n : stepConfig.retry.delay_ms;\n await this.sleep(delay);\n }\n \n // Retry same step\n iterations++;\n continue;\n }\n }\n\n // Find transition\n const nextStep = stepConfig.transitions[stepResult.result];\n if (!nextStep) {\n throw new Error(\n `No transition defined for result \"${stepResult.result}\" in step \"${currentStep}\"`\n );\n }\n\n // Update state\n runState.stepHistory.push(currentStep);\n runState.currentStep = nextStep;\n runState.updatedAt = Date.now();\n // Reset retry count when moving to new step\n runState.retryCounts[currentStep] = 0;\n await this.store.saveRunState(runId, runState);\n\n this.emit({\n type: 'transition',\n runId,\n timestamp: Date.now(),\n data: { from: currentStep, to: nextStep, result: stepResult.result },\n });\n\n this.options.onTransition?.(currentStep, nextStep);\n\n iterations++;\n }\n\n // Max iterations reached\n runState.status = 'completed';\n runState.updatedAt = Date.now();\n await this.store.saveRunState(runId, runState);\n\n return {\n runId,\n status: 'max_iterations',\n intent: 'max_iterations',\n data: await this.store.getAllData(runId),\n finalStep: runState.currentStep,\n stepHistory: runState.stepHistory,\n durationMs: Date.now() - startedAt,\n };\n }\n\n /**\n * Execute a single step\n */\n private async executeStep(\n runId: string,\n stepName: string,\n stepConfig: FlowConfig['steps'][string]\n ): Promise<StepResult> {\n // Find handler\n const handler = this.handlers.get(stepName);\n if (!handler) {\n throw new Error(`No handler registered for step \"${stepName}\"`);\n }\n\n // Build input from expected data\n const allData = await this.store.getAllData(runId);\n const input: Record<string, unknown> = {};\n \n if (stepConfig.expects_data) {\n for (const key of stepConfig.expects_data) {\n input[key] = allData[key];\n }\n } else {\n // If no expects_data, pass all data\n Object.assign(input, allData);\n }\n\n // Build context\n const context: StepContext = {\n runId,\n stepName,\n components: this.components,\n store: this.store,\n signal: this.options.signal,\n emit: (event: string, data: unknown) => {\n this.emit({\n type: 'step:complete' as FlowEventType, // Custom events map to step:complete\n runId,\n timestamp: Date.now(),\n data: { event, payload: data },\n });\n },\n };\n\n this.emit({\n type: 'step:start',\n runId,\n timestamp: Date.now(),\n data: { step: stepName, input },\n });\n\n try {\n // Execute handler\n const result = await handler(input, context);\n\n // Store produced data\n if (result.data) {\n for (const [key, value] of Object.entries(result.data)) {\n await this.store.setData(runId, key, value);\n }\n }\n\n this.emit({\n type: 'step:complete',\n runId,\n timestamp: Date.now(),\n data: { step: stepName, result: result.result, outputKeys: Object.keys(result.data ?? {}) },\n });\n\n this.options.onStep?.(stepName, result);\n\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n \n this.emit({\n type: 'step:error',\n runId,\n timestamp: Date.now(),\n data: { step: stepName, error: err.message },\n });\n\n // Return failure result for retry handling\n return { result: 'failure', data: { error: err.message } };\n }\n }\n\n /**\n * Extract data to return based on return_artifacts configuration\n */\n private extractReturnData(\n returnArtifacts: string | string[] | false | undefined,\n allData: Record<string, unknown>\n ): Record<string, unknown> {\n if (returnArtifacts === false || returnArtifacts === undefined) {\n return {};\n }\n\n if (typeof returnArtifacts === 'string') {\n return { [returnArtifacts]: allData[returnArtifacts] };\n }\n\n if (Array.isArray(returnArtifacts)) {\n const result: Record<string, unknown> = {};\n for (const key of returnArtifacts) {\n result[key] = allData[key];\n }\n return result;\n }\n\n return allData;\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * Subscribe to flow events\n */\n on(type: FlowEventType, listener: FlowEventListener): () => void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(listener);\n\n // Return unsubscribe function\n return () => {\n this.listeners.get(type)?.delete(listener);\n };\n }\n\n /**\n * Emit an event\n */\n private emit(event: FlowEvent): void {\n const typeListeners = this.listeners.get(event.type);\n if (typeListeners) {\n for (const listener of typeListeners) {\n try {\n listener(event);\n } catch {\n // Ignore listener errors\n }\n }\n }\n }\n\n /**\n * Get the current store instance\n */\n getStore(): FlowStore {\n return this.store;\n }\n}\n\n/**\n * Create a flow engine instance\n */\nexport function createEngine(\n flow: FlowConfig,\n handlers: Record<string, StepHandler>,\n options?: EngineOptions\n): FlowEngine {\n return new FlowEngine(flow, handlers, options);\n}\n","/**\n * yaml-flow - Flow Loader\n * \n * Utilities for loading and validating flow configurations.\n */\n\nimport type { FlowConfig } from './types.js';\n\n/**\n * Parse YAML string to FlowConfig\n * Requires 'yaml' package to be installed\n */\nexport async function parseYaml(yamlString: string): Promise<FlowConfig> {\n const yaml = await import('yaml');\n return yaml.parse(yamlString) as FlowConfig;\n}\n\n/**\n * Load flow from a URL (browser-friendly)\n */\nexport async function loadFlowFromUrl(url: string): Promise<FlowConfig> {\n const response = await fetch(url);\n \n if (!response.ok) {\n throw new Error(`Failed to load flow from ${url}: ${response.statusText}`);\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n const text = await response.text();\n\n if (contentType.includes('json') || url.endsWith('.json')) {\n return JSON.parse(text) as FlowConfig;\n }\n\n // Assume YAML\n return parseYaml(text);\n}\n\n/**\n * Load flow from file path (Node.js only)\n */\nexport async function loadFlowFromFile(filePath: string): Promise<FlowConfig> {\n const fs = await import('fs/promises');\n const text = await fs.readFile(filePath, 'utf-8');\n\n if (filePath.endsWith('.json')) {\n return JSON.parse(text) as FlowConfig;\n }\n\n // Assume YAML\n return parseYaml(text);\n}\n\n/**\n * Validate a flow configuration\n * Returns array of validation errors (empty if valid)\n */\nexport function validateFlowConfig(flow: unknown): string[] {\n const errors: string[] = [];\n\n if (!flow || typeof flow !== 'object') {\n return ['Flow must be an object'];\n }\n\n const f = flow as Record<string, unknown>;\n\n // Check settings\n if (!f.settings || typeof f.settings !== 'object') {\n errors.push('Flow must have a \"settings\" object');\n } else {\n const settings = f.settings as Record<string, unknown>;\n if (typeof settings.start_step !== 'string') {\n errors.push('settings.start_step must be a string');\n }\n if (settings.max_total_steps !== undefined && typeof settings.max_total_steps !== 'number') {\n errors.push('settings.max_total_steps must be a number');\n }\n if (settings.timeout_ms !== undefined && typeof settings.timeout_ms !== 'number') {\n errors.push('settings.timeout_ms must be a number');\n }\n }\n\n // Check steps\n if (!f.steps || typeof f.steps !== 'object') {\n errors.push('Flow must have a \"steps\" object');\n } else {\n const steps = f.steps as Record<string, unknown>;\n for (const [stepName, stepConfig] of Object.entries(steps)) {\n if (!stepConfig || typeof stepConfig !== 'object') {\n errors.push(`Step \"${stepName}\" must be an object`);\n continue;\n }\n const step = stepConfig as Record<string, unknown>;\n if (!step.transitions || typeof step.transitions !== 'object') {\n errors.push(`Step \"${stepName}\" must have a \"transitions\" object`);\n }\n }\n }\n\n // Check terminal_states\n if (!f.terminal_states || typeof f.terminal_states !== 'object') {\n errors.push('Flow must have a \"terminal_states\" object');\n } else {\n const terminals = f.terminal_states as Record<string, unknown>;\n for (const [name, config] of Object.entries(terminals)) {\n if (!config || typeof config !== 'object') {\n errors.push(`Terminal state \"${name}\" must be an object`);\n continue;\n }\n const terminal = config as Record<string, unknown>;\n if (typeof terminal.return_intent !== 'string') {\n errors.push(`Terminal state \"${name}\" must have a \"return_intent\" string`);\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Load and validate flow, throwing if invalid\n */\nexport async function loadFlow(source: string | FlowConfig): Promise<FlowConfig> {\n let flow: FlowConfig;\n\n if (typeof source === 'string') {\n // Check if it's a URL or file path\n if (source.startsWith('http://') || source.startsWith('https://')) {\n flow = await loadFlowFromUrl(source);\n } else if (source.includes('{')) {\n // Looks like JSON string\n flow = JSON.parse(source);\n } else {\n // Assume file path (Node.js)\n flow = await loadFlowFromFile(source);\n }\n } else {\n flow = source;\n }\n\n const errors = validateFlowConfig(flow);\n if (errors.length > 0) {\n throw new Error(`Invalid flow configuration:\\n- ${errors.join('\\n- ')}`);\n }\n\n return flow;\n}\n"]}
|