yaml-flow 2.0.0 → 2.2.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 +332 -2
- package/dist/batch/index.cjs +109 -0
- package/dist/batch/index.cjs.map +1 -0
- package/dist/batch/index.d.cts +126 -0
- package/dist/batch/index.d.ts +126 -0
- package/dist/batch/index.js +107 -0
- package/dist/batch/index.js.map +1 -0
- package/dist/config/index.cjs +80 -0
- package/dist/config/index.cjs.map +1 -0
- package/dist/config/index.d.cts +71 -0
- package/dist/config/index.d.ts +71 -0
- package/dist/config/index.js +77 -0
- package/dist/config/index.js.map +1 -0
- package/dist/{constants-D1fTEbbM.d.ts → constants-Bwvkbr5s.d.cts} +128 -1
- package/dist/{constants-D1fTEbbM.d.cts → constants-Ewufm5cK.d.ts} +128 -1
- package/dist/event-graph/index.cjs +409 -0
- package/dist/event-graph/index.cjs.map +1 -1
- package/dist/event-graph/index.d.cts +3 -2
- package/dist/event-graph/index.d.ts +3 -2
- package/dist/event-graph/index.js +403 -1
- package/dist/event-graph/index.js.map +1 -1
- package/dist/index.cjs +590 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +581 -1
- package/dist/index.js.map +1 -1
- package/package.json +11 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { StepMachine as FlowEngine, StepMachine, applyStepResult, checkCircuitBreaker, computeStepInput, createStepMachine as createEngine, createInitialState, createStepMachine, extractReturnData, loadStepFlow, validateStepFlowConfig } from './step-machine/index.cjs';
|
|
2
2
|
export { C as CircuitBreakerConfig, R as RetryConfig, S as StepConfig, a as StepContext, b as StepEvent, c as StepEventListener, d as StepEventType, e as StepFlowConfig, f as StepFlowSettings, g as StepHandler, h as StepInput, i as StepMachineOptions, j as StepMachineResult, k as StepMachineState, l as StepMachineStore, m as StepReducerResult, n as StepResult, T as TerminalStateConfig } from './types-FZ_eyErS.cjs';
|
|
3
|
-
export { A as AgentActionEvent, C as COMPLETION_STRATEGIES, a as CONFLICT_STRATEGIES, b as CompletionResult, c as CompletionStrategy, d as ConflictStrategy, D as DEFAULTS, E as EXECUTION_MODES, e as EXECUTION_STATUS, f as ExecutionConfig, g as ExecutionMode, h as
|
|
3
|
+
export { A as AgentActionEvent, C as COMPLETION_STRATEGIES, a as CONFLICT_STRATEGIES, b as CompletionResult, c as CompletionStrategy, d as ConflictStrategy, D as DEFAULTS, E as EXECUTION_MODES, e as EXECUTION_STATUS, f as ExecutionConfig, g as ExecutionMode, h as ExecutionPlan, i as ExecutionState, j as ExecutionStatus, k as ExportOptions, G as GraphConfig, l as GraphEvent, m as GraphSettings, T as GraphTaskConfig, I as InjectTokensEvent, M as MermaidOptions, S as SchedulerResult, n as StuckDetection, o as TASK_STATUS, p as TaskCompletedEvent, q as TaskCreationEvent, r as TaskFailedEvent, s as TaskStartedEvent, t as TaskState, u as TaskStatus, v as addDynamicTask, w as apply, x as applyAll, y as computeAvailableOutputs, z as createDefaultTaskState, B as createInitialExecutionState, F as detectStuckState, H as exportGraphConfig, J as exportGraphConfigToFile, K as flowToMermaid, L as getAllTasks, N as getCandidateTasks, O as getProvides, P as getRequires, Q as getTask, R as graphToMermaid, U as hasTask, V as isExecutionComplete, W as isNonActiveTask, X as isRepeatableTask, Y as isTaskCompleted, Z as isTaskRunning, _ as loadGraphConfig, $ as next, a0 as planExecution, a1 as validateGraphConfig } from './constants-Bwvkbr5s.cjs';
|
|
4
4
|
export { MemoryStore } from './stores/memory.cjs';
|
|
5
5
|
export { LocalStorageStore } from './stores/localStorage.cjs';
|
|
6
6
|
export { FileStore } from './stores/file.cjs';
|
|
7
|
+
export { BatchItemResult, BatchOptions, BatchProgress, BatchResult, batch } from './batch/index.cjs';
|
|
8
|
+
export { ConfigTemplates, Variables, resolveConfigTemplates, resolveVariables } from './config/index.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { StepMachine as FlowEngine, StepMachine, applyStepResult, checkCircuitBreaker, computeStepInput, createStepMachine as createEngine, createInitialState, createStepMachine, extractReturnData, loadStepFlow, validateStepFlowConfig } from './step-machine/index.js';
|
|
2
2
|
export { C as CircuitBreakerConfig, R as RetryConfig, S as StepConfig, a as StepContext, b as StepEvent, c as StepEventListener, d as StepEventType, e as StepFlowConfig, f as StepFlowSettings, g as StepHandler, h as StepInput, i as StepMachineOptions, j as StepMachineResult, k as StepMachineState, l as StepMachineStore, m as StepReducerResult, n as StepResult, T as TerminalStateConfig } from './types-FZ_eyErS.js';
|
|
3
|
-
export { A as AgentActionEvent, C as COMPLETION_STRATEGIES, a as CONFLICT_STRATEGIES, b as CompletionResult, c as CompletionStrategy, d as ConflictStrategy, D as DEFAULTS, E as EXECUTION_MODES, e as EXECUTION_STATUS, f as ExecutionConfig, g as ExecutionMode, h as
|
|
3
|
+
export { A as AgentActionEvent, C as COMPLETION_STRATEGIES, a as CONFLICT_STRATEGIES, b as CompletionResult, c as CompletionStrategy, d as ConflictStrategy, D as DEFAULTS, E as EXECUTION_MODES, e as EXECUTION_STATUS, f as ExecutionConfig, g as ExecutionMode, h as ExecutionPlan, i as ExecutionState, j as ExecutionStatus, k as ExportOptions, G as GraphConfig, l as GraphEvent, m as GraphSettings, T as GraphTaskConfig, I as InjectTokensEvent, M as MermaidOptions, S as SchedulerResult, n as StuckDetection, o as TASK_STATUS, p as TaskCompletedEvent, q as TaskCreationEvent, r as TaskFailedEvent, s as TaskStartedEvent, t as TaskState, u as TaskStatus, v as addDynamicTask, w as apply, x as applyAll, y as computeAvailableOutputs, z as createDefaultTaskState, B as createInitialExecutionState, F as detectStuckState, H as exportGraphConfig, J as exportGraphConfigToFile, K as flowToMermaid, L as getAllTasks, N as getCandidateTasks, O as getProvides, P as getRequires, Q as getTask, R as graphToMermaid, U as hasTask, V as isExecutionComplete, W as isNonActiveTask, X as isRepeatableTask, Y as isTaskCompleted, Z as isTaskRunning, _ as loadGraphConfig, $ as next, a0 as planExecution, a1 as validateGraphConfig } from './constants-Ewufm5cK.js';
|
|
4
4
|
export { MemoryStore } from './stores/memory.js';
|
|
5
5
|
export { LocalStorageStore } from './stores/localStorage.js';
|
|
6
6
|
export { FileStore } from './stores/file.js';
|
|
7
|
+
export { BatchItemResult, BatchOptions, BatchProgress, BatchResult, batch } from './batch/index.js';
|
|
8
|
+
export { ConfigTemplates, Variables, resolveConfigTemplates, resolveVariables } from './config/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1331,6 +1331,408 @@ function applyTaskCreation(state, taskName, taskConfig) {
|
|
|
1331
1331
|
};
|
|
1332
1332
|
}
|
|
1333
1333
|
|
|
1334
|
+
// src/event-graph/plan.ts
|
|
1335
|
+
function buildProducerMap(tasks) {
|
|
1336
|
+
const map = {};
|
|
1337
|
+
for (const [name, config] of Object.entries(tasks)) {
|
|
1338
|
+
for (const token of getProvides(config)) {
|
|
1339
|
+
if (!map[token]) map[token] = [];
|
|
1340
|
+
map[token].push(name);
|
|
1341
|
+
}
|
|
1342
|
+
if (config.on) {
|
|
1343
|
+
for (const tokens of Object.values(config.on)) {
|
|
1344
|
+
for (const token of tokens) {
|
|
1345
|
+
if (!map[token]) map[token] = [];
|
|
1346
|
+
if (!map[token].includes(name)) map[token].push(name);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
if (config.on_failure) {
|
|
1351
|
+
for (const token of config.on_failure) {
|
|
1352
|
+
if (!map[token]) map[token] = [];
|
|
1353
|
+
if (!map[token].includes(name)) map[token].push(name);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return map;
|
|
1358
|
+
}
|
|
1359
|
+
function buildDependencies(tasks, producerMap) {
|
|
1360
|
+
const deps = {};
|
|
1361
|
+
for (const [name, config] of Object.entries(tasks)) {
|
|
1362
|
+
const required = getRequires(config);
|
|
1363
|
+
const taskDeps = /* @__PURE__ */ new Set();
|
|
1364
|
+
for (const token of required) {
|
|
1365
|
+
const producers = producerMap[token] || [];
|
|
1366
|
+
for (const producer of producers) {
|
|
1367
|
+
if (producer !== name) taskDeps.add(producer);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
deps[name] = [...taskDeps];
|
|
1371
|
+
}
|
|
1372
|
+
return deps;
|
|
1373
|
+
}
|
|
1374
|
+
function computePhases(taskNames, dependencies) {
|
|
1375
|
+
const taskSet = new Set(taskNames);
|
|
1376
|
+
const inDegree = {};
|
|
1377
|
+
const dependents = {};
|
|
1378
|
+
for (const name of taskNames) {
|
|
1379
|
+
inDegree[name] = 0;
|
|
1380
|
+
dependents[name] = [];
|
|
1381
|
+
}
|
|
1382
|
+
for (const name of taskNames) {
|
|
1383
|
+
for (const dep of dependencies[name] || []) {
|
|
1384
|
+
if (taskSet.has(dep)) {
|
|
1385
|
+
inDegree[name]++;
|
|
1386
|
+
dependents[dep].push(name);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
const phases = [];
|
|
1391
|
+
const remaining = new Set(taskNames);
|
|
1392
|
+
while (remaining.size > 0) {
|
|
1393
|
+
const phase = [];
|
|
1394
|
+
for (const name of remaining) {
|
|
1395
|
+
if (inDegree[name] === 0) {
|
|
1396
|
+
phase.push(name);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
if (phase.length === 0) {
|
|
1400
|
+
phases.push([...remaining]);
|
|
1401
|
+
break;
|
|
1402
|
+
}
|
|
1403
|
+
phase.sort();
|
|
1404
|
+
phases.push(phase);
|
|
1405
|
+
for (const name of phase) {
|
|
1406
|
+
remaining.delete(name);
|
|
1407
|
+
for (const dependent of dependents[name] || []) {
|
|
1408
|
+
if (remaining.has(dependent)) {
|
|
1409
|
+
inDegree[dependent]--;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
return phases;
|
|
1415
|
+
}
|
|
1416
|
+
function planExecution(graph) {
|
|
1417
|
+
const tasks = getAllTasks(graph);
|
|
1418
|
+
const taskNames = Object.keys(tasks);
|
|
1419
|
+
if (taskNames.length === 0) {
|
|
1420
|
+
return {
|
|
1421
|
+
phases: [],
|
|
1422
|
+
dependencies: {},
|
|
1423
|
+
conflicts: {},
|
|
1424
|
+
entryPoints: [],
|
|
1425
|
+
leafTasks: [],
|
|
1426
|
+
unreachableTokens: [],
|
|
1427
|
+
blockedTasks: [],
|
|
1428
|
+
depth: 0,
|
|
1429
|
+
maxParallelism: 0
|
|
1430
|
+
};
|
|
1431
|
+
}
|
|
1432
|
+
const producerMap = buildProducerMap(tasks);
|
|
1433
|
+
const dependencies = buildDependencies(tasks, producerMap);
|
|
1434
|
+
const conflicts = {};
|
|
1435
|
+
for (const [token, producers] of Object.entries(producerMap)) {
|
|
1436
|
+
if (producers.length > 1) {
|
|
1437
|
+
conflicts[token] = producers;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
const entryPoints = taskNames.filter((name) => getRequires(tasks[name]).length === 0);
|
|
1441
|
+
const dependedOn = /* @__PURE__ */ new Set();
|
|
1442
|
+
for (const deps of Object.values(dependencies)) {
|
|
1443
|
+
for (const dep of deps) dependedOn.add(dep);
|
|
1444
|
+
}
|
|
1445
|
+
const leafTasks = taskNames.filter((name) => !dependedOn.has(name));
|
|
1446
|
+
const allRequired = /* @__PURE__ */ new Set();
|
|
1447
|
+
for (const config of Object.values(tasks)) {
|
|
1448
|
+
for (const token of getRequires(config)) {
|
|
1449
|
+
allRequired.add(token);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
const unreachableTokens = [...allRequired].filter((token) => !producerMap[token]);
|
|
1453
|
+
const unreachableSet = new Set(unreachableTokens);
|
|
1454
|
+
const blockedTasks = taskNames.filter(
|
|
1455
|
+
(name) => getRequires(tasks[name]).some((token) => unreachableSet.has(token))
|
|
1456
|
+
);
|
|
1457
|
+
const phases = computePhases(taskNames, dependencies);
|
|
1458
|
+
return {
|
|
1459
|
+
phases,
|
|
1460
|
+
dependencies,
|
|
1461
|
+
conflicts,
|
|
1462
|
+
entryPoints,
|
|
1463
|
+
leafTasks: leafTasks.sort(),
|
|
1464
|
+
unreachableTokens: unreachableTokens.sort(),
|
|
1465
|
+
blockedTasks: blockedTasks.sort(),
|
|
1466
|
+
depth: phases.length,
|
|
1467
|
+
maxParallelism: Math.max(0, ...phases.map((p) => p.length))
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
// src/event-graph/mermaid.ts
|
|
1472
|
+
function sanitizeId(name) {
|
|
1473
|
+
return name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1474
|
+
}
|
|
1475
|
+
function graphToMermaid(graph, options = {}) {
|
|
1476
|
+
const { direction = "TD", showTokens = true, title } = options;
|
|
1477
|
+
const tasks = getAllTasks(graph);
|
|
1478
|
+
const taskNames = Object.keys(tasks);
|
|
1479
|
+
if (taskNames.length === 0) {
|
|
1480
|
+
return `graph ${direction}
|
|
1481
|
+
empty[No tasks defined]`;
|
|
1482
|
+
}
|
|
1483
|
+
const producerMap = {};
|
|
1484
|
+
for (const [name, config] of Object.entries(tasks)) {
|
|
1485
|
+
for (const token of getProvides(config)) {
|
|
1486
|
+
if (!producerMap[token]) producerMap[token] = [];
|
|
1487
|
+
producerMap[token].push(name);
|
|
1488
|
+
}
|
|
1489
|
+
if (config.on) {
|
|
1490
|
+
for (const tokens of Object.values(config.on)) {
|
|
1491
|
+
for (const token of tokens) {
|
|
1492
|
+
if (!producerMap[token]) producerMap[token] = [];
|
|
1493
|
+
if (!producerMap[token].includes(name)) producerMap[token].push(name);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
const lines = [];
|
|
1499
|
+
const diagramTitle = title || graph.id || "Event Graph";
|
|
1500
|
+
lines.push(`%% ${diagramTitle}`);
|
|
1501
|
+
lines.push(`graph ${direction}`);
|
|
1502
|
+
const allRequired = /* @__PURE__ */ new Set();
|
|
1503
|
+
for (const config of Object.values(tasks)) {
|
|
1504
|
+
for (const token of getRequires(config)) {
|
|
1505
|
+
allRequired.add(token);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
const leafTaskSet = new Set(
|
|
1509
|
+
taskNames.filter((name) => {
|
|
1510
|
+
const prov = getProvides(tasks[name]);
|
|
1511
|
+
return prov.length === 0 || prov.every((token) => !allRequired.has(token));
|
|
1512
|
+
})
|
|
1513
|
+
);
|
|
1514
|
+
for (const name of taskNames) {
|
|
1515
|
+
const id = sanitizeId(name);
|
|
1516
|
+
const req = getRequires(tasks[name]);
|
|
1517
|
+
if (req.length === 0) {
|
|
1518
|
+
lines.push(` ${id}([${name}])`);
|
|
1519
|
+
} else if (leafTaskSet.has(name)) {
|
|
1520
|
+
lines.push(` ${id}[[${name}]]`);
|
|
1521
|
+
} else {
|
|
1522
|
+
lines.push(` ${id}[${name}]`);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
const edgeSet = /* @__PURE__ */ new Set();
|
|
1526
|
+
for (const [name, config] of Object.entries(tasks)) {
|
|
1527
|
+
const required = getRequires(config);
|
|
1528
|
+
for (const token of required) {
|
|
1529
|
+
const producers = producerMap[token] || [];
|
|
1530
|
+
for (const producer of producers) {
|
|
1531
|
+
if (producer === name) continue;
|
|
1532
|
+
const edgeKey = `${producer}->${name}:${token}`;
|
|
1533
|
+
if (edgeSet.has(edgeKey)) continue;
|
|
1534
|
+
edgeSet.add(edgeKey);
|
|
1535
|
+
const fromId = sanitizeId(producer);
|
|
1536
|
+
const toId = sanitizeId(name);
|
|
1537
|
+
if (showTokens) {
|
|
1538
|
+
lines.push(` ${fromId} -->|${token}| ${toId}`);
|
|
1539
|
+
} else {
|
|
1540
|
+
lines.push(` ${fromId} --> ${toId}`);
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
for (const token of required) {
|
|
1545
|
+
if (!producerMap[token]) {
|
|
1546
|
+
const warnId = `warn_${sanitizeId(token)}`;
|
|
1547
|
+
const toId = sanitizeId(name);
|
|
1548
|
+
lines.push(` ${warnId}{{\u26A0 ${token}}} -.->|missing| ${toId}`);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
return lines.join("\n");
|
|
1553
|
+
}
|
|
1554
|
+
function flowToMermaid(flow, options = {}) {
|
|
1555
|
+
const { direction = "TD", title } = options;
|
|
1556
|
+
const steps = flow.steps;
|
|
1557
|
+
const terminals = flow.terminal_states;
|
|
1558
|
+
const startStep = flow.settings.start_step;
|
|
1559
|
+
const lines = [];
|
|
1560
|
+
const diagramTitle = title || flow.id || "Step Machine";
|
|
1561
|
+
lines.push(`%% ${diagramTitle}`);
|
|
1562
|
+
lines.push(`graph ${direction}`);
|
|
1563
|
+
lines.push(` START(( ))`);
|
|
1564
|
+
lines.push(` START --> ${sanitizeId(startStep)}`);
|
|
1565
|
+
for (const name of Object.keys(steps)) {
|
|
1566
|
+
const id = sanitizeId(name);
|
|
1567
|
+
lines.push(` ${id}[${name}]`);
|
|
1568
|
+
}
|
|
1569
|
+
for (const [name, config] of Object.entries(terminals)) {
|
|
1570
|
+
const id = sanitizeId(name);
|
|
1571
|
+
lines.push(` ${id}([${name}: ${config.return_intent}])`);
|
|
1572
|
+
}
|
|
1573
|
+
for (const [stepName, stepConfig] of Object.entries(steps)) {
|
|
1574
|
+
const fromId = sanitizeId(stepName);
|
|
1575
|
+
for (const [result, target] of Object.entries(stepConfig.transitions)) {
|
|
1576
|
+
const toId = sanitizeId(target);
|
|
1577
|
+
lines.push(` ${fromId} -->|${result}| ${toId}`);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
return lines.join("\n");
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
// src/event-graph/loader.ts
|
|
1584
|
+
function validateGraphConfig(config) {
|
|
1585
|
+
const errors = [];
|
|
1586
|
+
if (!config || typeof config !== "object") {
|
|
1587
|
+
return ["Graph config must be an object"];
|
|
1588
|
+
}
|
|
1589
|
+
const c = config;
|
|
1590
|
+
if (!c.settings || typeof c.settings !== "object") {
|
|
1591
|
+
errors.push('Graph config must have a "settings" object');
|
|
1592
|
+
} else {
|
|
1593
|
+
const settings = c.settings;
|
|
1594
|
+
if (!settings.completion || typeof settings.completion !== "string") {
|
|
1595
|
+
errors.push("settings.completion must be a string");
|
|
1596
|
+
}
|
|
1597
|
+
if (settings.completion === "goal-reached") {
|
|
1598
|
+
if (!Array.isArray(settings.goal) || settings.goal.length === 0) {
|
|
1599
|
+
errors.push('settings.goal must be a non-empty array when completion is "goal-reached"');
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
if (!c.tasks || typeof c.tasks !== "object") {
|
|
1604
|
+
errors.push('Graph config must have a "tasks" object');
|
|
1605
|
+
} else {
|
|
1606
|
+
const tasks = c.tasks;
|
|
1607
|
+
if (Object.keys(tasks).length === 0) {
|
|
1608
|
+
errors.push("Graph config must have at least one task");
|
|
1609
|
+
}
|
|
1610
|
+
for (const [name, task] of Object.entries(tasks)) {
|
|
1611
|
+
if (!task || typeof task !== "object") {
|
|
1612
|
+
errors.push(`Task "${name}" must be an object`);
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
const t = task;
|
|
1616
|
+
if (!Array.isArray(t.provides)) {
|
|
1617
|
+
errors.push(`Task "${name}" must have a "provides" array`);
|
|
1618
|
+
}
|
|
1619
|
+
if (t.requires !== void 0 && !Array.isArray(t.requires)) {
|
|
1620
|
+
errors.push(`Task "${name}".requires must be an array if present`);
|
|
1621
|
+
}
|
|
1622
|
+
if (t.on !== void 0) {
|
|
1623
|
+
if (typeof t.on !== "object" || Array.isArray(t.on)) {
|
|
1624
|
+
errors.push(`Task "${name}".on must be an object mapping result keys to token arrays`);
|
|
1625
|
+
} else {
|
|
1626
|
+
for (const [key, tokens] of Object.entries(t.on)) {
|
|
1627
|
+
if (!Array.isArray(tokens)) {
|
|
1628
|
+
errors.push(`Task "${name}".on.${key} must be an array of tokens`);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
return errors;
|
|
1636
|
+
}
|
|
1637
|
+
async function parseGraphYaml(yamlString) {
|
|
1638
|
+
const yaml = await import('yaml');
|
|
1639
|
+
return yaml.parse(yamlString);
|
|
1640
|
+
}
|
|
1641
|
+
async function loadGraphConfig(source) {
|
|
1642
|
+
let config;
|
|
1643
|
+
if (typeof source === "string") {
|
|
1644
|
+
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
1645
|
+
const response = await fetch(source);
|
|
1646
|
+
if (!response.ok) {
|
|
1647
|
+
throw new Error(`Failed to load graph config from ${source}: ${response.statusText}`);
|
|
1648
|
+
}
|
|
1649
|
+
const text = await response.text();
|
|
1650
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
1651
|
+
if (contentType.includes("json") || source.endsWith(".json")) {
|
|
1652
|
+
config = JSON.parse(text);
|
|
1653
|
+
} else {
|
|
1654
|
+
config = await parseGraphYaml(text);
|
|
1655
|
+
}
|
|
1656
|
+
} else if (source.includes("{")) {
|
|
1657
|
+
config = JSON.parse(source);
|
|
1658
|
+
} else {
|
|
1659
|
+
const fs = await import('fs/promises');
|
|
1660
|
+
const text = await fs.readFile(source, "utf-8");
|
|
1661
|
+
if (source.endsWith(".json")) {
|
|
1662
|
+
config = JSON.parse(text);
|
|
1663
|
+
} else {
|
|
1664
|
+
config = await parseGraphYaml(text);
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
} else {
|
|
1668
|
+
config = source;
|
|
1669
|
+
}
|
|
1670
|
+
const errors = validateGraphConfig(config);
|
|
1671
|
+
if (errors.length > 0) {
|
|
1672
|
+
throw new Error(`Invalid graph configuration:
|
|
1673
|
+
- ${errors.join("\n- ")}`);
|
|
1674
|
+
}
|
|
1675
|
+
return config;
|
|
1676
|
+
}
|
|
1677
|
+
function exportGraphConfig(config, options = {}) {
|
|
1678
|
+
const { format = "json", indent = 2 } = options;
|
|
1679
|
+
if (format === "yaml") {
|
|
1680
|
+
return toYaml(config, indent);
|
|
1681
|
+
}
|
|
1682
|
+
return JSON.stringify(config, null, indent);
|
|
1683
|
+
}
|
|
1684
|
+
async function exportGraphConfigToFile(config, filePath, options = {}) {
|
|
1685
|
+
const format = options.format ?? (filePath.endsWith(".yaml") || filePath.endsWith(".yml") ? "yaml" : "json");
|
|
1686
|
+
const content = exportGraphConfig(config, { ...options, format });
|
|
1687
|
+
const fs = await import('fs/promises');
|
|
1688
|
+
await fs.writeFile(filePath, content, "utf-8");
|
|
1689
|
+
}
|
|
1690
|
+
function toYaml(obj, indent, depth = 0) {
|
|
1691
|
+
const pad = " ".repeat(indent * depth);
|
|
1692
|
+
if (obj === null || obj === void 0) return "null";
|
|
1693
|
+
if (typeof obj === "boolean") return String(obj);
|
|
1694
|
+
if (typeof obj === "number") return String(obj);
|
|
1695
|
+
if (typeof obj === "string") {
|
|
1696
|
+
if (obj.includes(":") || obj.includes("#") || obj.includes("\n") || obj.includes('"') || obj.includes("'") || obj.startsWith(" ") || obj.startsWith("{") || obj.startsWith("[") || obj === "") {
|
|
1697
|
+
return JSON.stringify(obj);
|
|
1698
|
+
}
|
|
1699
|
+
return obj;
|
|
1700
|
+
}
|
|
1701
|
+
if (Array.isArray(obj)) {
|
|
1702
|
+
if (obj.length === 0) return "[]";
|
|
1703
|
+
if (obj.every((v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean")) {
|
|
1704
|
+
return `[${obj.map((v) => typeof v === "string" ? toYaml(v, indent, 0) : String(v)).join(", ")}]`;
|
|
1705
|
+
}
|
|
1706
|
+
return obj.map((item) => {
|
|
1707
|
+
const val = toYaml(item, indent, depth + 1);
|
|
1708
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
1709
|
+
const lines = val.trimStart().split("\n");
|
|
1710
|
+
return `${pad}- ${lines[0]}
|
|
1711
|
+
${lines.slice(1).map((l) => `${pad} ${l.trimStart() ? l : ""}`).filter(Boolean).join("\n")}`;
|
|
1712
|
+
}
|
|
1713
|
+
return `${pad}- ${val}`;
|
|
1714
|
+
}).join("\n");
|
|
1715
|
+
}
|
|
1716
|
+
if (typeof obj === "object") {
|
|
1717
|
+
const entries = Object.entries(obj);
|
|
1718
|
+
if (entries.length === 0) return "{}";
|
|
1719
|
+
return entries.map(([key, value]) => {
|
|
1720
|
+
if (value === void 0) return "";
|
|
1721
|
+
const serialized = toYaml(value, indent, depth + 1);
|
|
1722
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0) {
|
|
1723
|
+
return `${pad}${key}:
|
|
1724
|
+
${serialized}`;
|
|
1725
|
+
}
|
|
1726
|
+
if (Array.isArray(value) && value.length > 0 && !value.every((v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean")) {
|
|
1727
|
+
return `${pad}${key}:
|
|
1728
|
+
${serialized}`;
|
|
1729
|
+
}
|
|
1730
|
+
return `${pad}${key}: ${serialized}`;
|
|
1731
|
+
}).filter(Boolean).join("\n");
|
|
1732
|
+
}
|
|
1733
|
+
return String(obj);
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1334
1736
|
// src/stores/localStorage.ts
|
|
1335
1737
|
var LocalStorageStore = class {
|
|
1336
1738
|
prefix;
|
|
@@ -1513,6 +1915,184 @@ var FileStore = class {
|
|
|
1513
1915
|
}
|
|
1514
1916
|
};
|
|
1515
1917
|
|
|
1516
|
-
|
|
1918
|
+
// src/batch/runner.ts
|
|
1919
|
+
async function batch(items, options) {
|
|
1920
|
+
const {
|
|
1921
|
+
concurrency = 5,
|
|
1922
|
+
processor,
|
|
1923
|
+
onItemComplete,
|
|
1924
|
+
onItemError,
|
|
1925
|
+
onProgress,
|
|
1926
|
+
signal
|
|
1927
|
+
} = options;
|
|
1928
|
+
const total = items.length;
|
|
1929
|
+
const results = new Array(total);
|
|
1930
|
+
const batchStart = Date.now();
|
|
1931
|
+
let completed = 0;
|
|
1932
|
+
let failed = 0;
|
|
1933
|
+
let nextIndex = 0;
|
|
1934
|
+
function makeProgress(active) {
|
|
1935
|
+
const done = completed + failed;
|
|
1936
|
+
return {
|
|
1937
|
+
completed,
|
|
1938
|
+
failed,
|
|
1939
|
+
active,
|
|
1940
|
+
pending: total - done - active,
|
|
1941
|
+
total,
|
|
1942
|
+
percent: total === 0 ? 100 : Math.round(done / total * 100),
|
|
1943
|
+
elapsedMs: Date.now() - batchStart
|
|
1944
|
+
};
|
|
1945
|
+
}
|
|
1946
|
+
if (total === 0) {
|
|
1947
|
+
return { items: [], completed: 0, failed: 0, total: 0, durationMs: 0 };
|
|
1948
|
+
}
|
|
1949
|
+
return new Promise((resolve) => {
|
|
1950
|
+
let active = 0;
|
|
1951
|
+
function tryStartNext() {
|
|
1952
|
+
while (active < concurrency && nextIndex < total) {
|
|
1953
|
+
if (signal?.aborted) {
|
|
1954
|
+
while (nextIndex < total) {
|
|
1955
|
+
const idx2 = nextIndex++;
|
|
1956
|
+
results[idx2] = {
|
|
1957
|
+
item: items[idx2],
|
|
1958
|
+
index: idx2,
|
|
1959
|
+
status: "failed",
|
|
1960
|
+
error: new Error("Batch aborted"),
|
|
1961
|
+
durationMs: 0
|
|
1962
|
+
};
|
|
1963
|
+
failed++;
|
|
1964
|
+
}
|
|
1965
|
+
if (active === 0 && completed + failed === total) {
|
|
1966
|
+
resolve({
|
|
1967
|
+
items: results,
|
|
1968
|
+
completed,
|
|
1969
|
+
failed,
|
|
1970
|
+
total,
|
|
1971
|
+
durationMs: Date.now() - batchStart
|
|
1972
|
+
});
|
|
1973
|
+
}
|
|
1974
|
+
break;
|
|
1975
|
+
}
|
|
1976
|
+
const idx = nextIndex++;
|
|
1977
|
+
const item = items[idx];
|
|
1978
|
+
active++;
|
|
1979
|
+
const itemStart = Date.now();
|
|
1980
|
+
processor(item, idx).then((result) => {
|
|
1981
|
+
results[idx] = {
|
|
1982
|
+
item,
|
|
1983
|
+
index: idx,
|
|
1984
|
+
status: "completed",
|
|
1985
|
+
result,
|
|
1986
|
+
durationMs: Date.now() - itemStart
|
|
1987
|
+
};
|
|
1988
|
+
completed++;
|
|
1989
|
+
onItemComplete?.(item, result, idx);
|
|
1990
|
+
}).catch((err) => {
|
|
1991
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1992
|
+
results[idx] = {
|
|
1993
|
+
item,
|
|
1994
|
+
index: idx,
|
|
1995
|
+
status: "failed",
|
|
1996
|
+
error,
|
|
1997
|
+
durationMs: Date.now() - itemStart
|
|
1998
|
+
};
|
|
1999
|
+
failed++;
|
|
2000
|
+
onItemError?.(item, error, idx);
|
|
2001
|
+
}).finally(() => {
|
|
2002
|
+
active--;
|
|
2003
|
+
onProgress?.(makeProgress(active));
|
|
2004
|
+
if (completed + failed === total) {
|
|
2005
|
+
resolve({
|
|
2006
|
+
items: results,
|
|
2007
|
+
completed,
|
|
2008
|
+
failed,
|
|
2009
|
+
total,
|
|
2010
|
+
durationMs: Date.now() - batchStart
|
|
2011
|
+
});
|
|
2012
|
+
} else {
|
|
2013
|
+
tryStartNext();
|
|
2014
|
+
}
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
tryStartNext();
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
// src/config/resolve-variables.ts
|
|
2023
|
+
function interpolateString(template, vars) {
|
|
2024
|
+
return template.replace(/\$\{([^}]+)\}/g, (match, key) => {
|
|
2025
|
+
const value = vars[key.trim()];
|
|
2026
|
+
return value !== void 0 ? String(value) : match;
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
function walkAndInterpolate(value, vars) {
|
|
2030
|
+
if (typeof value === "string") {
|
|
2031
|
+
return interpolateString(value, vars);
|
|
2032
|
+
}
|
|
2033
|
+
if (Array.isArray(value)) {
|
|
2034
|
+
return value.map((item) => walkAndInterpolate(item, vars));
|
|
2035
|
+
}
|
|
2036
|
+
if (value !== null && typeof value === "object") {
|
|
2037
|
+
const result = {};
|
|
2038
|
+
for (const [k, v] of Object.entries(value)) {
|
|
2039
|
+
result[k] = walkAndInterpolate(v, vars);
|
|
2040
|
+
}
|
|
2041
|
+
return result;
|
|
2042
|
+
}
|
|
2043
|
+
return value;
|
|
2044
|
+
}
|
|
2045
|
+
function resolveVariables(config, variables) {
|
|
2046
|
+
return walkAndInterpolate(config, variables);
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
// src/config/resolve-config-templates.ts
|
|
2050
|
+
function mergeConfigs(template, taskConfig) {
|
|
2051
|
+
const merged = { ...template };
|
|
2052
|
+
for (const [key, value] of Object.entries(taskConfig)) {
|
|
2053
|
+
if (key === "config-template") continue;
|
|
2054
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value) && merged[key] !== null && typeof merged[key] === "object" && !Array.isArray(merged[key])) {
|
|
2055
|
+
merged[key] = {
|
|
2056
|
+
...merged[key],
|
|
2057
|
+
...value
|
|
2058
|
+
};
|
|
2059
|
+
} else {
|
|
2060
|
+
merged[key] = value;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
return merged;
|
|
2064
|
+
}
|
|
2065
|
+
function resolveConfigTemplates(config) {
|
|
2066
|
+
const templates = config["configTemplates"] ?? config["config-templates"] ?? {};
|
|
2067
|
+
const tasksKey = "tasks" in config ? "tasks" : "steps" in config ? "steps" : null;
|
|
2068
|
+
if (!tasksKey) return config;
|
|
2069
|
+
const tasks = config[tasksKey];
|
|
2070
|
+
if (!tasks || typeof tasks !== "object") return config;
|
|
2071
|
+
const resolvedTasks = {};
|
|
2072
|
+
for (const [name, task] of Object.entries(tasks)) {
|
|
2073
|
+
const taskConfig = task["config"];
|
|
2074
|
+
const templateName = taskConfig?.["config-template"];
|
|
2075
|
+
if (!templateName || !taskConfig) {
|
|
2076
|
+
resolvedTasks[name] = task;
|
|
2077
|
+
continue;
|
|
2078
|
+
}
|
|
2079
|
+
const template = templates[templateName];
|
|
2080
|
+
if (!template) {
|
|
2081
|
+
const { "config-template": _, ...rest } = taskConfig;
|
|
2082
|
+
resolvedTasks[name] = { ...task, config: rest };
|
|
2083
|
+
continue;
|
|
2084
|
+
}
|
|
2085
|
+
resolvedTasks[name] = {
|
|
2086
|
+
...task,
|
|
2087
|
+
config: mergeConfigs(template, taskConfig)
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
const result = { ...config, [tasksKey]: resolvedTasks };
|
|
2091
|
+
delete result["configTemplates"];
|
|
2092
|
+
delete result["config-templates"];
|
|
2093
|
+
return result;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
export { COMPLETION_STRATEGIES, CONFLICT_STRATEGIES, DEFAULTS, EXECUTION_MODES, EXECUTION_STATUS, FileStore, StepMachine as FlowEngine, LocalStorageStore, MemoryStore, StepMachine, TASK_STATUS, addDynamicTask, apply, applyAll, applyStepResult, batch, checkCircuitBreaker, computeAvailableOutputs, computeStepInput, createDefaultTaskState, createStepMachine as createEngine, createInitialExecutionState, createInitialState, createStepMachine, detectStuckState, exportGraphConfig, exportGraphConfigToFile, extractReturnData, flowToMermaid, getAllTasks, getCandidateTasks, getProvides, getRequires, getTask, graphToMermaid, hasTask, isExecutionComplete, isNonActiveTask, isRepeatableTask, isTaskCompleted, isTaskRunning, loadGraphConfig, loadStepFlow, next, planExecution, resolveConfigTemplates, resolveVariables, validateGraphConfig, validateStepFlowConfig };
|
|
1517
2097
|
//# sourceMappingURL=index.js.map
|
|
1518
2098
|
//# sourceMappingURL=index.js.map
|