yaml-flow 5.1.0 → 5.2.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.
Files changed (105) hide show
  1. package/{examples/example-board/reusable-server-runtime.js → board-livecards-server-runtime.js} +42 -20
  2. package/{examples/example-board/reusable-board-runtime-client.js → browser/board-livecards-runtime-client.js} +6 -2
  3. package/browser/{board-livegraph-runtime.js → board-livegraph-engine.js} +212 -16
  4. package/browser/board-livegraph-engine.js.map +1 -0
  5. package/browser/live-cards.js +362 -38
  6. package/browser/live-cards.schema.json +20 -4
  7. package/dist/board-livegraph-runtime/index.cjs +210 -14
  8. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  9. package/dist/board-livegraph-runtime/index.d.cts +49 -5
  10. package/dist/board-livegraph-runtime/index.d.ts +49 -5
  11. package/dist/board-livegraph-runtime/index.js +209 -15
  12. package/dist/board-livegraph-runtime/index.js.map +1 -1
  13. package/dist/card-compute/index.cjs +63 -7
  14. package/dist/card-compute/index.cjs.map +1 -1
  15. package/dist/card-compute/index.d.cts +2 -2
  16. package/dist/card-compute/index.d.ts +2 -2
  17. package/dist/card-compute/index.js +63 -7
  18. package/dist/card-compute/index.js.map +1 -1
  19. package/dist/cli/board-live-cards-cli.cjs +664 -75
  20. package/dist/cli/board-live-cards-cli.cjs.map +1 -1
  21. package/dist/cli/board-live-cards-cli.d.cts +33 -5
  22. package/dist/cli/board-live-cards-cli.d.ts +33 -5
  23. package/dist/cli/board-live-cards-cli.js +661 -76
  24. package/dist/cli/board-live-cards-cli.js.map +1 -1
  25. package/dist/{constants-ozjf1Ejw.d.cts → constants-BzZUyYlp.d.cts} +1 -1
  26. package/dist/{constants-DuzE5n03.d.ts → constants-oCEbNpul.d.ts} +1 -1
  27. package/dist/continuous-event-graph/index.cjs +47 -14
  28. package/dist/continuous-event-graph/index.cjs.map +1 -1
  29. package/dist/continuous-event-graph/index.d.cts +9 -9
  30. package/dist/continuous-event-graph/index.d.ts +9 -9
  31. package/dist/continuous-event-graph/index.js +47 -14
  32. package/dist/continuous-event-graph/index.js.map +1 -1
  33. package/dist/event-graph/index.cjs +29 -12
  34. package/dist/event-graph/index.cjs.map +1 -1
  35. package/dist/event-graph/index.d.cts +5 -5
  36. package/dist/event-graph/index.d.ts +5 -5
  37. package/dist/event-graph/index.js +29 -12
  38. package/dist/event-graph/index.js.map +1 -1
  39. package/dist/index.cjs +93 -20
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +7 -7
  42. package/dist/index.d.ts +7 -7
  43. package/dist/index.js +93 -20
  44. package/dist/index.js.map +1 -1
  45. package/dist/inference/index.cjs +29 -12
  46. package/dist/inference/index.cjs.map +1 -1
  47. package/dist/inference/index.d.cts +2 -2
  48. package/dist/inference/index.d.ts +2 -2
  49. package/dist/inference/index.js +29 -12
  50. package/dist/inference/index.js.map +1 -1
  51. package/dist/{journal-NLYuqege.d.ts → journal-9HEgs7dU.d.ts} +1 -1
  52. package/dist/{journal-DRfJiheM.d.cts → journal-B-JCfQnh.d.cts} +1 -1
  53. package/dist/{live-cards-bridge-Or7fdEJV.d.ts → live-cards-bridge-CeNxiVcm.d.ts} +6 -2
  54. package/dist/{live-cards-bridge-vGJ6tMzN.d.cts → live-cards-bridge-z_rJCSbi.d.cts} +6 -2
  55. package/dist/{schedule-CMcZe5Ny.d.ts → schedule-Cszq9LYY.d.ts} +1 -1
  56. package/dist/{schedule-CiucyCan.d.cts → schedule-qWNL0RQh.d.cts} +1 -1
  57. package/dist/{types-CMFSIjpc.d.cts → types-BBhqYGhE.d.cts} +4 -0
  58. package/dist/{types-CMFSIjpc.d.ts → types-BBhqYGhE.d.ts} +4 -0
  59. package/dist/{types-BzLD8bjb.d.cts → types-CHSdoAAA.d.cts} +1 -1
  60. package/dist/{types-C2eJ7DAV.d.ts → types-CoW0gQl3.d.ts} +1 -1
  61. package/dist/{validate-DJQTQ6bP.d.ts → validate-BAVzUJWa.d.ts} +1 -1
  62. package/dist/{validate-ke92Cleg.d.cts → validate-Dbu7ygys.d.cts} +1 -1
  63. package/examples/browser/boards/portfolio-tracker/cards/portfolio-risk-assessment.json +28 -0
  64. package/examples/browser/boards/portfolio-tracker/cards/rebalancing-strategy.json +28 -0
  65. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-inference-adapter.js +187 -0
  66. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.js +139 -5
  67. package/examples/example-board/agent-instructions-cardlayout.md +28 -0
  68. package/examples/example-board/agent-instructions.md +603 -0
  69. package/examples/example-board/cards/card-concentration.json +42 -0
  70. package/examples/example-board/cards/card-market-prices.json +51 -0
  71. package/examples/example-board/cards/card-portfolio-action.json +19 -0
  72. package/examples/example-board/cards/card-portfolio-risks.json +19 -0
  73. package/examples/example-board/cards/card-portfolio-value.json +62 -0
  74. package/examples/example-board/cards/card-portfolio.json +44 -0
  75. package/examples/example-board/demo-chat-handler.js +373 -33
  76. package/examples/example-board/demo-server-config.json +0 -2
  77. package/examples/example-board/demo-server.js +46 -7
  78. package/examples/example-board/demo-shell-browser.html +75 -207
  79. package/examples/example-board/demo-shell-with-server.html +15 -9
  80. package/examples/example-board/demo-shell.html +1 -1
  81. package/examples/example-board/demo-task-executor.js +259 -41
  82. package/package.json +6 -2
  83. package/schema/live-cards.schema.json +20 -4
  84. package/browser/board-livegraph-runtime.js.map +0 -1
  85. package/examples/example-board/board.yaml +0 -23
  86. package/examples/example-board/bootstrap_payload.json +0 -1
  87. package/examples/example-board/cards/card-chain-region-alert.json +0 -39
  88. package/examples/example-board/cards/card-chain-region-totals.json +0 -26
  89. package/examples/example-board/cards/card-chain-top-region.json +0 -24
  90. package/examples/example-board/cards/card-ex-actions.json +0 -32
  91. package/examples/example-board/cards/card-ex-chart.json +0 -30
  92. package/examples/example-board/cards/card-ex-filter.json +0 -36
  93. package/examples/example-board/cards/card-ex-filtered-by-preference.json +0 -59
  94. package/examples/example-board/cards/card-ex-form.json +0 -91
  95. package/examples/example-board/cards/card-ex-list.json +0 -22
  96. package/examples/example-board/cards/card-ex-markdown.json +0 -17
  97. package/examples/example-board/cards/card-ex-metric.json +0 -19
  98. package/examples/example-board/cards/card-ex-narrative.json +0 -36
  99. package/examples/example-board/cards/card-ex-source-http.json +0 -28
  100. package/examples/example-board/cards/card-ex-source.json +0 -21
  101. package/examples/example-board/cards/card-ex-status.json +0 -35
  102. package/examples/example-board/cards/card-ex-table.json +0 -30
  103. package/examples/example-board/cards/card-ex-todo.json +0 -29
  104. package/examples/example-board/mock.db +0 -15
  105. package/examples/example-board/reusable-runtime-artifacts-adapter.js +0 -233
@@ -141,13 +141,29 @@ function validateNode(node) {
141
141
  if (!Array.isArray(n.sources)) {
142
142
  errors.push("sources: must be an array");
143
143
  } else {
144
+ const bindTos = /* @__PURE__ */ new Set();
145
+ const outputFiles = /* @__PURE__ */ new Set();
144
146
  n.sources.forEach((src, i) => {
145
147
  if (!src || typeof src !== "object" || Array.isArray(src)) {
146
148
  errors.push(`sources[${i}]: must be an object`);
147
149
  } else {
148
150
  const s = src;
149
- if (typeof s.bindTo !== "string" || !s.bindTo) errors.push(`sources[${i}]: missing required "bindTo" property`);
150
- if (s.outputFile != null && typeof s.outputFile !== "string") errors.push(`sources[${i}]: outputFile must be a string`);
151
+ if (typeof s.bindTo !== "string" || !s.bindTo) {
152
+ errors.push(`sources[${i}]: missing required "bindTo" property`);
153
+ } else {
154
+ if (bindTos.has(s.bindTo)) {
155
+ errors.push(`sources[${i}]: bindTo "${s.bindTo}" is not unique across sources`);
156
+ }
157
+ bindTos.add(s.bindTo);
158
+ }
159
+ if (typeof s.outputFile !== "string" || !s.outputFile) {
160
+ errors.push(`sources[${i}]: missing required "outputFile" property`);
161
+ } else {
162
+ if (outputFiles.has(s.outputFile)) {
163
+ errors.push(`sources[${i}]: outputFile "${s.outputFile}" is not unique across sources`);
164
+ }
165
+ outputFiles.add(s.outputFile);
166
+ }
151
167
  if (s.optionalForCompletionGating != null && typeof s.optionalForCompletionGating !== "boolean") {
152
168
  errors.push(`sources[${i}]: optionalForCompletionGating must be a boolean`);
153
169
  }
@@ -263,15 +279,30 @@ function groupTasksByProvides(candidateTaskNames, tasks) {
263
279
  }
264
280
 
265
281
  // src/event-graph/task-transitions.ts
266
- function applyTaskStart(state, taskName) {
282
+ function applyTaskStart(state, taskName, graph) {
267
283
  const existingTask = state.tasks[taskName] ?? createDefaultGraphEngineStore();
284
+ const startConsumedHashes = {};
285
+ if (graph) {
286
+ const taskConfig = graph.tasks[taskName];
287
+ const requires = getRequires(taskConfig);
288
+ for (const token of requires) {
289
+ for (const [otherName, otherConfig] of Object.entries(graph.tasks)) {
290
+ if (getProvides(otherConfig).includes(token)) {
291
+ const otherState = state.tasks[otherName];
292
+ if (otherState?.lastDataHash) startConsumedHashes[token] = otherState.lastDataHash;
293
+ break;
294
+ }
295
+ }
296
+ }
297
+ }
268
298
  const updatedTask = {
269
299
  ...existingTask,
270
300
  status: "running",
271
301
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
272
302
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
273
303
  progress: 0,
274
- error: void 0
304
+ error: void 0,
305
+ startConsumedHashes
275
306
  };
276
307
  return {
277
308
  ...state,
@@ -291,16 +322,18 @@ function applyTaskCompletion(state, graph, taskName, result, dataHash, data) {
291
322
  } else {
292
323
  outputTokens = getProvides(taskConfig);
293
324
  }
294
- const lastConsumedHashes = { ...existingTask.lastConsumedHashes };
295
- const requires = taskConfig.requires ?? [];
296
- for (const token of requires) {
297
- for (const [otherName, otherConfig] of Object.entries(graph.tasks)) {
298
- if (getProvides(otherConfig).includes(token)) {
299
- const otherState = state.tasks[otherName];
300
- if (otherState?.lastDataHash) {
301
- lastConsumedHashes[token] = otherState.lastDataHash;
325
+ const lastConsumedHashes = existingTask.startConsumedHashes ? { ...existingTask.startConsumedHashes } : { ...existingTask.lastConsumedHashes };
326
+ if (!existingTask.startConsumedHashes) {
327
+ const requires = taskConfig.requires ?? [];
328
+ for (const token of requires) {
329
+ for (const [otherName, otherConfig] of Object.entries(graph.tasks)) {
330
+ if (getProvides(otherConfig).includes(token)) {
331
+ const otherState = state.tasks[otherName];
332
+ if (otherState?.lastDataHash) {
333
+ lastConsumedHashes[token] = otherState.lastDataHash;
334
+ }
335
+ break;
302
336
  }
303
- break;
304
337
  }
305
338
  }
306
339
  }
@@ -445,7 +478,7 @@ function applyEvent(live, event) {
445
478
  switch (event.type) {
446
479
  // --- Execution state transitions ---
447
480
  case "task-started":
448
- return { config, state: applyTaskStart(state, event.taskName) };
481
+ return { config, state: applyTaskStart(state, event.taskName, config) };
449
482
  case "task-completed":
450
483
  return { config, state: applyTaskCompletion(state, config, event.taskName, event.result, event.dataHash, event.data) };
451
484
  case "task-failed":
@@ -1441,8 +1474,171 @@ function createBoardLiveGraphRuntime(input, options = {}) {
1441
1474
  };
1442
1475
  return runtime;
1443
1476
  }
1477
+ function taskStatusToCardStatus(taskStatus) {
1478
+ if (taskStatus === "running" || taskStatus === "in-progress") return "loading";
1479
+ if (taskStatus === "failed") return "error";
1480
+ if (taskStatus === "completed") return "fresh";
1481
+ return "fresh";
1482
+ }
1483
+ function cardStatusToTaskStatus(cardStatus) {
1484
+ if (cardStatus === "loading") return "in-progress";
1485
+ if (cardStatus === "error") return "failed";
1486
+ if (cardStatus === "stale") return "pending";
1487
+ if (cardStatus === "fresh") return "completed";
1488
+ return "pending";
1489
+ }
1490
+ function normalizeCardRuntimeArtifact(cardId, artifact) {
1491
+ const safe = artifact && typeof artifact === "object" && !Array.isArray(artifact) ? artifact : {};
1492
+ return {
1493
+ schema_version: safe.schema_version || "v1",
1494
+ card_id: typeof safe.card_id === "string" ? safe.card_id : cardId,
1495
+ card_data: safe.card_data && typeof safe.card_data === "object" && !Array.isArray(safe.card_data) ? structuredClone(safe.card_data) : {},
1496
+ computed_values: safe.computed_values && typeof safe.computed_values === "object" && !Array.isArray(safe.computed_values) ? structuredClone(safe.computed_values) : {},
1497
+ fetched_sources: safe.fetched_sources && typeof safe.fetched_sources === "object" && !Array.isArray(safe.fetched_sources) ? structuredClone(safe.fetched_sources) : {},
1498
+ requires: safe.requires && typeof safe.requires === "object" && !Array.isArray(safe.requires) ? structuredClone(safe.requires) : {}
1499
+ };
1500
+ }
1501
+ function buildLiveCardModelsFromArtifacts(payload) {
1502
+ if (!payload || typeof payload !== "object") throw new Error("payload must be an object");
1503
+ const cardDefinitions = Array.isArray(payload.cardDefinitions) ? payload.cardDefinitions : [];
1504
+ const statusSnapshot = payload.statusSnapshot && typeof payload.statusSnapshot === "object" ? payload.statusSnapshot : {};
1505
+ const cardRuntimeById = payload.cardRuntimeById && typeof payload.cardRuntimeById === "object" ? payload.cardRuntimeById : {};
1506
+ const dataObjectsByToken = payload.dataObjectsByToken && typeof payload.dataObjectsByToken === "object" ? payload.dataObjectsByToken : {};
1507
+ const statusCards = Array.isArray(statusSnapshot.cards) ? statusSnapshot.cards : [];
1508
+ const statusById = new Map(statusCards.map((c) => [c.name, c]));
1509
+ return cardDefinitions.map((cardDefinition) => {
1510
+ const card = structuredClone(cardDefinition);
1511
+ const cardId = card.id;
1512
+ if (!cardId) throw new Error("cardDefinitions entry missing id");
1513
+ const statusCard = statusById.get(cardId);
1514
+ const runtimeArtifact = normalizeCardRuntimeArtifact(cardId, cardRuntimeById[cardId]);
1515
+ const baseCardData = card.card_data && typeof card.card_data === "object" && !Array.isArray(card.card_data) ? card.card_data : {};
1516
+ const card_data = {
1517
+ ...baseCardData,
1518
+ ...runtimeArtifact.card_data || {},
1519
+ status: taskStatusToCardStatus(statusCard?.status),
1520
+ lastRun: statusCard?.runtime?.last_transition_at ?? null
1521
+ };
1522
+ if (statusCard?.error?.message) card_data["error"] = statusCard.error.message;
1523
+ const runtime_state = statusCard ? {
1524
+ task_status: statusCard.status ?? null,
1525
+ card_status: taskStatusToCardStatus(statusCard.status),
1526
+ runtime: structuredClone(statusCard.runtime ?? {}),
1527
+ error: statusCard.error ? structuredClone(statusCard.error) : null,
1528
+ blocked_by: Array.isArray(statusCard.blocked_by) ? structuredClone(statusCard.blocked_by) : [],
1529
+ requires_missing: Array.isArray(statusCard.requires_missing) ? structuredClone(statusCard.requires_missing) : []
1530
+ } : {
1531
+ task_status: null,
1532
+ card_status: card_data["status"] ?? "fresh",
1533
+ runtime: { last_transition_at: card_data["lastRun"] ?? null },
1534
+ error: card_data["error"] ? { message: card_data["error"] } : null,
1535
+ blocked_by: [],
1536
+ requires_missing: []
1537
+ };
1538
+ const requiresTokens = Array.isArray(card.requires) ? card.requires : [];
1539
+ const requires = {};
1540
+ for (const token of requiresTokens) {
1541
+ if (Object.prototype.hasOwnProperty.call(dataObjectsByToken, token)) {
1542
+ requires[token] = structuredClone(dataObjectsByToken[token]);
1543
+ }
1544
+ }
1545
+ return {
1546
+ id: cardId,
1547
+ card,
1548
+ card_data,
1549
+ fetched_sources: runtimeArtifact.fetched_sources,
1550
+ requires,
1551
+ computed_values: runtimeArtifact.computed_values,
1552
+ runtime_state
1553
+ };
1554
+ });
1555
+ }
1556
+ function buildBrowserArtifactsFromRuntime({
1557
+ boardPath,
1558
+ cardDefinitions,
1559
+ runtimeModels,
1560
+ graphState
1561
+ }) {
1562
+ const safeCardDefs = Array.isArray(cardDefinitions) ? cardDefinitions : [];
1563
+ const safeModels = Array.isArray(runtimeModels) ? runtimeModels : [];
1564
+ const runtimeModelById = new Map(safeModels.map((m) => [m.id, m]));
1565
+ const graphStateAny = graphState;
1566
+ const taskStates = graphStateAny.state?.tasks ?? {};
1567
+ const cardRuntimeById = {};
1568
+ for (const model of safeModels) {
1569
+ if (!model?.id) continue;
1570
+ cardRuntimeById[model.id] = {
1571
+ schema_version: "v1",
1572
+ card_id: model.id,
1573
+ card_data: structuredClone(model.card_data ?? {}),
1574
+ computed_values: structuredClone(model.computed_values ?? {}),
1575
+ fetched_sources: structuredClone(model.fetched_sources ?? {}),
1576
+ requires: structuredClone(model.requires ?? {})
1577
+ };
1578
+ }
1579
+ const dataObjectsByToken = {};
1580
+ for (const taskName of Object.keys(taskStates)) {
1581
+ const providesData = taskStates[taskName]?.data?.provides_data;
1582
+ if (providesData && typeof providesData === "object") {
1583
+ for (const token of Object.keys(providesData)) {
1584
+ dataObjectsByToken[token] = structuredClone(providesData[token]);
1585
+ }
1586
+ }
1587
+ }
1588
+ const statusCards = safeCardDefs.map((cardDef) => {
1589
+ const model = runtimeModelById.get(cardDef.id) ?? {};
1590
+ const taskState = taskStates[cardDef.id];
1591
+ const taskStatus = typeof taskState?.status === "string" ? taskState.status : cardStatusToTaskStatus(model.card_data?.["status"]);
1592
+ const errorMessage = typeof taskState?.error === "string" ? taskState.error : typeof model.card_data?.["error"] === "string" ? model.card_data["error"] : null;
1593
+ return {
1594
+ name: cardDef.id,
1595
+ status: taskStatus,
1596
+ ...errorMessage ? { error: { message: errorMessage, code: "TASK_FAILED", at: taskState?.failedAt ?? null, source: "browser-runtime" } } : {},
1597
+ requires: Array.isArray(cardDef.requires) ? cardDef.requires : [],
1598
+ requires_satisfied: [],
1599
+ requires_missing: [],
1600
+ provides_declared: Array.isArray(cardDef.provides) ? cardDef.provides.map((e) => e.bindTo) : [cardDef.id],
1601
+ provides_runtime: Object.keys(taskState?.data?.provides_data ?? {}).sort(),
1602
+ blocked_by: [],
1603
+ unblocks: [],
1604
+ runtime: {
1605
+ attempt_count: taskState?.executionCount ?? 0,
1606
+ restart_count: taskState?.retryCount ?? 0,
1607
+ in_progress_since: taskStatus === "in-progress" ? taskState?.startedAt ?? null : null,
1608
+ last_transition_at: taskState?.lastUpdated ?? model.card_data?.["lastRun"] ?? null,
1609
+ last_completed_at: taskState?.completedAt ?? null,
1610
+ last_restarted_at: taskState?.startedAt ?? null,
1611
+ status_age_ms: null
1612
+ }
1613
+ };
1614
+ });
1615
+ return {
1616
+ cardDefinitions: structuredClone(safeCardDefs),
1617
+ cardRuntimeById,
1618
+ dataObjectsByToken,
1619
+ statusSnapshot: {
1620
+ schema_version: "v1",
1621
+ meta: { board: { path: boardPath ?? "browser-runtime" } },
1622
+ summary: {
1623
+ card_count: statusCards.length,
1624
+ completed: statusCards.filter((c) => c.status === "completed").length,
1625
+ eligible: 0,
1626
+ pending: statusCards.filter((c) => c.status === "pending").length,
1627
+ blocked: 0,
1628
+ unresolved: 0,
1629
+ failed: statusCards.filter((c) => c.status === "failed").length,
1630
+ in_progress: statusCards.filter((c) => c.status === "in-progress").length,
1631
+ orphan_cards: 0,
1632
+ topology: { edge_count: 0, max_fan_out_card: null, max_fan_out: 0 }
1633
+ },
1634
+ cards: statusCards
1635
+ }
1636
+ };
1637
+ }
1444
1638
 
1445
1639
  exports.LocalStorageService = LocalStorageService;
1640
+ exports.buildBrowserArtifactsFromRuntime = buildBrowserArtifactsFromRuntime;
1641
+ exports.buildLiveCardModelsFromArtifacts = buildLiveCardModelsFromArtifacts;
1446
1642
  exports.createBoardLiveGraphRuntime = createBoardLiveGraphRuntime;
1447
1643
  //# sourceMappingURL=index.cjs.map
1448
1644
  //# sourceMappingURL=index.cjs.map