@bastani/atomic 0.9.45 → 0.9.46-alpha.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 (166) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +11 -0
  3. package/dist/builtin/intercom/broker/broker.ts +124 -10
  4. package/dist/builtin/intercom/broker/client.ts +177 -25
  5. package/dist/builtin/intercom/broker/multinode-router.ts +228 -27
  6. package/dist/builtin/intercom/broker/multinode-state-store.ts +10 -0
  7. package/dist/builtin/intercom/broker/recipient-receipts.ts +38 -4
  8. package/dist/builtin/intercom/broker/send-handler.ts +9 -2
  9. package/dist/builtin/intercom/broker/sql-outbox-store.ts +29 -4
  10. package/dist/builtin/intercom/group.ts +25 -0
  11. package/dist/builtin/intercom/index.bundle.mjs +177 -35
  12. package/dist/builtin/intercom/package.json +1 -1
  13. package/dist/builtin/intercom/retry-policy.ts +7 -0
  14. package/dist/builtin/intercom/types.ts +21 -0
  15. package/dist/builtin/mcp/package.json +1 -1
  16. package/dist/builtin/subagents/CHANGELOG.md +10 -0
  17. package/dist/builtin/subagents/package.json +1 -1
  18. package/dist/builtin/subagents/src/extension/index.bundle.mjs +150 -54
  19. package/dist/builtin/web-access/package.json +1 -1
  20. package/dist/builtin/workflows/CHANGELOG.md +39 -0
  21. package/dist/builtin/workflows/builtin/{chunk-6901nsd6.js → chunk-6jpwc09k.js} +1 -1
  22. package/dist/builtin/workflows/builtin/{chunk-vwx023ge.js → chunk-qhm35ntx.js} +1 -1
  23. package/dist/builtin/workflows/builtin/{chunk-jvna28mq.js → chunk-zhyqnf5g.js} +331 -68
  24. package/dist/builtin/workflows/builtin/goal.js +2 -2
  25. package/dist/builtin/workflows/builtin/index.js +3 -3
  26. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  27. package/dist/builtin/workflows/package.json +1 -1
  28. package/dist/builtin/workflows/skills/prompt-engineer/SKILL.md +1 -0
  29. package/dist/builtin/workflows/skills/prompt-engineer/references/gpt_6.md +2 -2
  30. package/dist/builtin/workflows/skills/prompt-engineer/references/gpt_6_1_sol.md +2 -2
  31. package/dist/builtin/workflows/skills/prompt-engineer/references/gpt_6_1_terra.md +77 -0
  32. package/dist/builtin/workflows/src/authoring.d.ts +1 -1
  33. package/dist/builtin/workflows/src/durable/journal/internal.d.ts +2 -0
  34. package/dist/builtin/workflows/src/extension/index.bundle.mjs +7076 -3386
  35. package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +11075 -7261
  36. package/dist/builtin/workflows/src/index.js +6768 -3605
  37. package/dist/builtin/workflows/src/local-worker-entry.mjs +11075 -7261
  38. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +19 -0
  39. package/dist/core/agent-session-boundaries.d.ts.map +1 -1
  40. package/dist/core/agent-session-boundaries.js +1 -0
  41. package/dist/core/agent-session-boundaries.js.map +1 -1
  42. package/dist/core/agent-session-events.d.ts.map +1 -1
  43. package/dist/core/agent-session-events.js +2 -1
  44. package/dist/core/agent-session-events.js.map +1 -1
  45. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  46. package/dist/core/agent-session-extension-bindings.js +15 -2
  47. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  48. package/dist/core/agent-session-methods.d.ts +3 -2
  49. package/dist/core/agent-session-methods.d.ts.map +1 -1
  50. package/dist/core/agent-session-methods.js.map +1 -1
  51. package/dist/core/agent-session-prompt.d.ts +4 -2
  52. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  53. package/dist/core/agent-session-prompt.js +13 -8
  54. package/dist/core/agent-session-prompt.js.map +1 -1
  55. package/dist/core/agent-session-recovery.d.ts.map +1 -1
  56. package/dist/core/agent-session-recovery.js +92 -1
  57. package/dist/core/agent-session-recovery.js.map +1 -1
  58. package/dist/core/agent-session-transfer.d.ts.map +1 -1
  59. package/dist/core/agent-session-transfer.js +5 -0
  60. package/dist/core/agent-session-transfer.js.map +1 -1
  61. package/dist/core/agent-session.d.ts +2 -0
  62. package/dist/core/agent-session.d.ts.map +1 -1
  63. package/dist/core/agent-session.js +2 -0
  64. package/dist/core/agent-session.js.map +1 -1
  65. package/dist/core/copilot-errors.d.ts +6 -0
  66. package/dist/core/copilot-errors.d.ts.map +1 -0
  67. package/dist/core/copilot-errors.js +17 -0
  68. package/dist/core/copilot-errors.js.map +1 -0
  69. package/dist/core/execution-model-router.d.ts.map +1 -1
  70. package/dist/core/execution-model-router.js +12 -2
  71. package/dist/core/execution-model-router.js.map +1 -1
  72. package/dist/core/extensions/context-types.d.ts +7 -0
  73. package/dist/core/extensions/context-types.d.ts.map +1 -1
  74. package/dist/core/extensions/context-types.js.map +1 -1
  75. package/dist/core/extensions/runner-context.d.ts.map +1 -1
  76. package/dist/core/extensions/runner-context.js +6 -0
  77. package/dist/core/extensions/runner-context.js.map +1 -1
  78. package/dist/core/extensions/workflow-activity-hub.d.ts +4 -0
  79. package/dist/core/extensions/workflow-activity-hub.d.ts.map +1 -1
  80. package/dist/core/extensions/workflow-activity-hub.js +26 -5
  81. package/dist/core/extensions/workflow-activity-hub.js.map +1 -1
  82. package/dist/core/extensions/workflow-events.d.ts +5 -0
  83. package/dist/core/extensions/workflow-events.d.ts.map +1 -1
  84. package/dist/core/extensions/workflow-events.js.map +1 -1
  85. package/dist/core/messages.d.ts +5 -0
  86. package/dist/core/messages.d.ts.map +1 -1
  87. package/dist/core/messages.js +1 -1
  88. package/dist/core/messages.js.map +1 -1
  89. package/dist/core/model-fallback-failures.d.ts +1 -1
  90. package/dist/core/model-fallback-failures.d.ts.map +1 -1
  91. package/dist/core/model-fallback-failures.js +37 -3
  92. package/dist/core/model-fallback-failures.js.map +1 -1
  93. package/dist/core/model-runtime-streaming.js +2 -2
  94. package/dist/core/model-runtime-streaming.js.map +1 -1
  95. package/dist/core/provider-composer.d.ts.map +1 -1
  96. package/dist/core/provider-composer.js +19 -11
  97. package/dist/core/provider-composer.js.map +1 -1
  98. package/dist/core/provider-rate-limits.d.ts +55 -6
  99. package/dist/core/provider-rate-limits.d.ts.map +1 -1
  100. package/dist/core/provider-rate-limits.js +182 -29
  101. package/dist/core/provider-rate-limits.js.map +1 -1
  102. package/dist/core/provider-request-admission.d.ts.map +1 -1
  103. package/dist/core/provider-request-admission.js +42 -18
  104. package/dist/core/provider-request-admission.js.map +1 -1
  105. package/dist/core/storage/node-sqlite.d.ts.map +1 -1
  106. package/dist/core/storage/node-sqlite.js +176 -19
  107. package/dist/core/storage/node-sqlite.js.map +1 -1
  108. package/dist/core/storage/provider.d.ts +4 -2
  109. package/dist/core/storage/provider.d.ts.map +1 -1
  110. package/dist/core/storage/provider.js +94 -5
  111. package/dist/core/storage/provider.js.map +1 -1
  112. package/dist/core/structured-output/index.d.ts.map +1 -1
  113. package/dist/core/structured-output/index.js +15 -8
  114. package/dist/core/structured-output/index.js.map +1 -1
  115. package/dist/core/structured-output/provider-failure.d.ts +17 -0
  116. package/dist/core/structured-output/provider-failure.d.ts.map +1 -0
  117. package/dist/core/structured-output/provider-failure.js +28 -0
  118. package/dist/core/structured-output/provider-failure.js.map +1 -0
  119. package/dist/core/tools/bash.d.ts.map +1 -1
  120. package/dist/core/tools/bash.js +13 -7
  121. package/dist/core/tools/bash.js.map +1 -1
  122. package/dist/core/tools/shell-task-render.d.ts +1 -0
  123. package/dist/core/tools/shell-task-render.d.ts.map +1 -1
  124. package/dist/core/tools/shell-task-render.js +7 -2
  125. package/dist/core/tools/shell-task-render.js.map +1 -1
  126. package/dist/extensions/tool-search/tool.d.ts +5 -0
  127. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  128. package/dist/extensions/tool-search/tool.js +38 -5
  129. package/dist/extensions/tool-search/tool.js.map +1 -1
  130. package/dist/index.d.ts +1 -1
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +1 -1
  133. package/dist/index.js.map +1 -1
  134. package/dist/modes/interactive/components/chat-session-host-actions.js +3 -2
  135. package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
  136. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  137. package/dist/modes/interactive/components/login-dialog.js +42 -14
  138. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  139. package/dist/modes/interactive/interactive-extension-context.js +2 -1
  140. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  141. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  142. package/dist/modes/interactive/interactive-startup.js +5 -6
  143. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  144. package/dist/modes/rpc/rpc-client-process.d.ts.map +1 -1
  145. package/dist/modes/rpc/rpc-client-process.js +8 -1
  146. package/dist/modes/rpc/rpc-client-process.js.map +1 -1
  147. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  148. package/dist/modes/rpc/rpc-client.js +7 -1
  149. package/dist/modes/rpc/rpc-client.js.map +1 -1
  150. package/dist/utils/ansi.d.ts +2 -0
  151. package/dist/utils/ansi.d.ts.map +1 -1
  152. package/dist/utils/ansi.js +5 -0
  153. package/dist/utils/ansi.js.map +1 -1
  154. package/docs/codemode.md +1 -1
  155. package/docs/intercom/reference.md +3 -3
  156. package/docs/models/evals.md +31 -12
  157. package/docs/models/reference.md +23 -51
  158. package/docs/models.md +3 -4
  159. package/docs/providers.md +5 -15
  160. package/docs/settings.md +1 -1
  161. package/docs/storage.md +2 -2
  162. package/docs/tools.md +1 -1
  163. package/docs/workflows/api-reference.md +20 -1
  164. package/docs/workflows/operations.md +17 -4
  165. package/npm-shrinkwrap.json +64 -44
  166. package/package.json +4 -4
@@ -80,7 +80,7 @@ function reciprocalWorkflowRootRunId(runById, runId) {
80
80
  return declaredRoots.every((declared) => declared === currentId) ? currentId : undefined;
81
81
  }
82
82
  const parent = runById.get(parentRunId);
83
- const boundary = parent?.stages.find((stage) => stage.id === parentStageId);
83
+ const boundary = parent === undefined ? undefined : findSnapshotStage(parent.stages, parentStageId);
84
84
  if (parent === undefined || authoritativeWorkflowChildRunId(boundary) !== currentId) {
85
85
  return;
86
86
  }
@@ -88,6 +88,26 @@ function reciprocalWorkflowRootRunId(runById, runId) {
88
88
  }
89
89
  return;
90
90
  }
91
+ var runIndexes = new WeakMap;
92
+ var stageIndexes = new WeakMap;
93
+ function index(items, cache) {
94
+ let byId = cache.get(items);
95
+ if (byId === undefined) {
96
+ const built = new Map;
97
+ for (const item of items)
98
+ if (!built.has(item.id))
99
+ built.set(item.id, item);
100
+ byId = built;
101
+ cache.set(items, byId);
102
+ }
103
+ return byId;
104
+ }
105
+ function findSnapshotRun(runs, runId) {
106
+ return Object.isFrozen(runs) ? index(runs, runIndexes).get(runId) : runs.find((run) => run.id === runId);
107
+ }
108
+ function findSnapshotStage(stages, stageId) {
109
+ return Object.isFrozen(stages) ? index(stages, stageIndexes).get(stageId) : stages.find((stage) => stage.id === stageId);
110
+ }
91
111
 
92
112
  // dist/builtin/workflows/src/durable/prompt-reservations.ts
93
113
  function durablePromptScope(backend, workflowId) {
@@ -1061,26 +1081,172 @@ function compactToolNode(node) {
1061
1081
  ...node.source !== undefined ? { source: boundedToolText(node.source) } : {}
1062
1082
  };
1063
1083
  }
1064
- function compactRun(run) {
1065
- const { inputs: _inputs, result: sourceResult, stages, toolNodes, pendingPrompt, ...metadata } = run;
1084
+ function compactRun(run, stages = run.stages.map(compactStage), toolNodes = run.toolNodes.map(compactToolNode)) {
1085
+ const {
1086
+ inputs: _inputs,
1087
+ result: sourceResult,
1088
+ stages: _stages,
1089
+ toolNodes: _toolNodes,
1090
+ pendingPrompt,
1091
+ ...metadata
1092
+ } = run;
1066
1093
  const result = compactRunResult(sourceResult, run.exited === true && run.status === "failed");
1067
1094
  return {
1068
1095
  ...metadata,
1069
1096
  inputs: {},
1070
- stages: stages.map(compactStage),
1071
- toolNodes: toolNodes.map(compactToolNode),
1097
+ stages,
1098
+ toolNodes,
1072
1099
  ...pendingPrompt !== undefined ? { pendingPrompt: clonePrompt(pendingPrompt) } : {},
1073
1100
  ...result !== undefined ? { result } : {}
1074
1101
  };
1075
1102
  }
1076
- function createGraphStoreSnapshot(runs, notices, version) {
1077
- const snapshot = {
1078
- runs: runs.map(compactRun),
1079
- notices: notices.map((notice) => ({ ...notice })),
1080
- version
1103
+ function sourceShape(value) {
1104
+ const keys = Object.keys(value);
1105
+ return { keys, values: keys.map((key) => value[key]) };
1106
+ }
1107
+ function sameSourceShape(value, shape) {
1108
+ let index = 0;
1109
+ for (const key in value) {
1110
+ if (index >= shape.keys.length || key !== shape.keys[index] || value[key] !== shape.values[index])
1111
+ return false;
1112
+ index++;
1113
+ }
1114
+ return index === shape.keys.length;
1115
+ }
1116
+ function projectStage(stage) {
1117
+ return {
1118
+ shape: sourceShape(stage),
1119
+ parentCount: stage.parentIds.length,
1120
+ toolEventCount: stage.toolEvents.length,
1121
+ lastToolEvent: stage.toolEvents.at(-1),
1122
+ noticeCount: stage.notices?.length,
1123
+ compact: compactStage(stage)
1081
1124
  };
1082
- deepFreezeGraphValue(snapshot);
1083
- return snapshot;
1125
+ }
1126
+ function stageUnchanged(stage, projected) {
1127
+ return sameSourceShape(stage, projected.shape) && stage.parentIds.length === projected.parentCount && stage.toolEvents.length === projected.toolEventCount && stage.toolEvents.at(-1) === projected.lastToolEvent && stage.notices?.length === projected.noticeCount;
1128
+ }
1129
+ function projectToolNode(node) {
1130
+ return { shape: sourceShape(node), parentCount: node.parentIds.length, compact: compactToolNode(node) };
1131
+ }
1132
+ function toolNodeUnchanged(node, projected) {
1133
+ return sameSourceShape(node, projected.shape) && node.parentIds.length === projected.parentCount;
1134
+ }
1135
+
1136
+ class GraphStoreSnapshotBuilder {
1137
+ projected = new Map;
1138
+ changedRuns = new Set;
1139
+ changedStages = new Map;
1140
+ changedToolNodes = new Map;
1141
+ markChanged(change) {
1142
+ if (change === undefined) {
1143
+ this.projected.clear();
1144
+ this.changedRuns.clear();
1145
+ this.changedStages.clear();
1146
+ this.changedToolNodes.clear();
1147
+ return;
1148
+ }
1149
+ if (change.stageId === undefined && change.toolNodeId === undefined) {
1150
+ this.changedRuns.add(change.runId);
1151
+ return;
1152
+ }
1153
+ if (change.stageId !== undefined)
1154
+ addScoped(this.changedStages, change.runId, change.stageId);
1155
+ if (change.toolNodeId !== undefined)
1156
+ addScoped(this.changedToolNodes, change.runId, change.toolNodeId);
1157
+ }
1158
+ build(runs, notices, version) {
1159
+ const previous = this.projected;
1160
+ const next = new Map;
1161
+ const compactRuns = [];
1162
+ for (const run of runs) {
1163
+ const known = previous.get(run.id);
1164
+ const reusable = known?.source === run ? known : undefined;
1165
+ const projected = reusable !== undefined && !this.changedRuns.has(run.id) && this.runUnchanged(run, reusable) ? reusable : this.projectRun(run, reusable);
1166
+ next.set(run.id, projected);
1167
+ compactRuns.push(projected.compact);
1168
+ }
1169
+ this.projected = next;
1170
+ this.changedRuns.clear();
1171
+ this.changedStages.clear();
1172
+ this.changedToolNodes.clear();
1173
+ const snapshot = {
1174
+ runs: compactRuns,
1175
+ notices: notices.map((notice) => ({ ...notice })),
1176
+ version
1177
+ };
1178
+ deepFreezeGraphValue(snapshot);
1179
+ return snapshot;
1180
+ }
1181
+ buildRun(run) {
1182
+ const known = this.projected.get(run.id);
1183
+ const reusable = known?.source === run ? known : undefined;
1184
+ const projected = reusable !== undefined && !this.changedRuns.has(run.id) && this.runUnchanged(run, reusable) ? reusable : this.projectRun(run, reusable);
1185
+ deepFreezeGraphValue(projected.compact);
1186
+ this.projected.set(run.id, projected);
1187
+ this.changedRuns.delete(run.id);
1188
+ this.changedStages.delete(run.id);
1189
+ this.changedToolNodes.delete(run.id);
1190
+ return projected.compact;
1191
+ }
1192
+ runUnchanged(run, projected) {
1193
+ if (!sameSourceShape(run, projected.shape))
1194
+ return false;
1195
+ const { stages, toolNodes } = projected.compact;
1196
+ if (run.stages.length !== stages.length || run.toolNodes.length !== toolNodes.length)
1197
+ return false;
1198
+ const changedStages = this.changedStages.get(run.id);
1199
+ for (let index = 0;index < run.stages.length; index++) {
1200
+ const stage = run.stages[index];
1201
+ const known = projected.stages.get(stage);
1202
+ if (known === undefined || known.compact !== stages[index] || changedStages?.has(stage.id) === true || !stageUnchanged(stage, known))
1203
+ return false;
1204
+ }
1205
+ const changedToolNodes = this.changedToolNodes.get(run.id);
1206
+ for (let index = 0;index < run.toolNodes.length; index++) {
1207
+ const node = run.toolNodes[index];
1208
+ const known = projected.toolNodes.get(node);
1209
+ if (known === undefined || known.compact !== toolNodes[index] || changedToolNodes?.has(node.id) === true || !toolNodeUnchanged(node, known))
1210
+ return false;
1211
+ }
1212
+ return true;
1213
+ }
1214
+ projectRun(run, previous) {
1215
+ const changedStages = this.changedStages.get(run.id);
1216
+ const stages = new Map;
1217
+ const compactStages = [];
1218
+ for (const stage of run.stages) {
1219
+ let projected = stages.get(stage) ?? previous?.stages.get(stage);
1220
+ if (projected === undefined || changedStages?.has(stage.id) === true || !stageUnchanged(stage, projected))
1221
+ projected = projectStage(stage);
1222
+ stages.set(stage, projected);
1223
+ compactStages.push(projected.compact);
1224
+ }
1225
+ const changedToolNodes = this.changedToolNodes.get(run.id);
1226
+ const toolNodes = new Map;
1227
+ const compactToolNodes = [];
1228
+ for (const node of run.toolNodes) {
1229
+ let projected = toolNodes.get(node) ?? previous?.toolNodes.get(node);
1230
+ if (projected === undefined || changedToolNodes?.has(node.id) === true || !toolNodeUnchanged(node, projected))
1231
+ projected = projectToolNode(node);
1232
+ toolNodes.set(node, projected);
1233
+ compactToolNodes.push(projected.compact);
1234
+ }
1235
+ return {
1236
+ source: run,
1237
+ shape: sourceShape(run),
1238
+ stages,
1239
+ toolNodes,
1240
+ compact: compactRun(run, compactStages, compactToolNodes)
1241
+ };
1242
+ }
1243
+ }
1244
+ function addScoped(scopes, runId, nodeId) {
1245
+ const ids = scopes.get(runId);
1246
+ if (ids === undefined)
1247
+ scopes.set(runId, new Set([nodeId]));
1248
+ else
1249
+ ids.add(nodeId);
1084
1250
  }
1085
1251
  function deepFreezeGraphValue(value) {
1086
1252
  if (value === null || typeof value !== "object" || Object.isFrozen(value))
@@ -1099,11 +1265,16 @@ function deepFreezeGraphValue(value) {
1099
1265
  // dist/builtin/workflows/src/shared/workflow-observation-runtime.ts
1100
1266
  import { randomUUID } from "node:crypto";
1101
1267
 
1268
+ // dist/builtin/workflows/src/shared/expanded-workflow-graph.ts
1269
+ var leafExpansions = new WeakMap;
1270
+ var snapshotExpansions = new WeakMap;
1271
+
1102
1272
  // dist/builtin/workflows/src/shared/workflow-activity.ts
1103
1273
  function workflowActivityNodeKey(runId, nodeId) {
1104
1274
  return `${runId}:${nodeId}`;
1105
1275
  }
1106
1276
  var endedStatuses = new Set(["completed", "cached", "failed", "cancelled"]);
1277
+ var projectedGraphNodes = new WeakMap;
1107
1278
 
1108
1279
  // dist/builtin/workflows/src/shared/workflow-observation-runtime.ts
1109
1280
  class WorkflowObservationRuntime {
@@ -1118,6 +1289,7 @@ class WorkflowObservationRuntime {
1118
1289
  listeners = new Set;
1119
1290
  replayStageIds = new Set;
1120
1291
  previous = new Map;
1292
+ owners = new Map;
1121
1293
  recoveryDepth = 0;
1122
1294
  constructor(runs, invalidate) {
1123
1295
  this.runs = runs;
@@ -1143,7 +1315,7 @@ class WorkflowObservationRuntime {
1143
1315
  if (id.startsWith(`${runId}:`))
1144
1316
  ids.delete(id);
1145
1317
  }
1146
- this.invalidate();
1318
+ this.invalidate({ runId });
1147
1319
  }
1148
1320
  emit(event) {
1149
1321
  for (const listener of this.listeners) {
@@ -1192,7 +1364,7 @@ class WorkflowObservationRuntime {
1192
1364
  if (action === "resume")
1193
1365
  this.stoppingRunIds.delete(runId);
1194
1366
  this.lifecycle({ kind: "run", runId, status: run.status, action }, attribution);
1195
- this.invalidate();
1367
+ this.invalidate({ runId });
1196
1368
  }
1197
1369
  heartbeat(runId, scheduledAt, intervalMinutes) {
1198
1370
  const run = this.runs().find((candidate) => candidate.id === runId);
@@ -1217,35 +1389,103 @@ class WorkflowObservationRuntime {
1217
1389
  this.emit({ kind: "availability" });
1218
1390
  };
1219
1391
  }
1220
- capture() {
1221
- const next = new Map;
1222
- const visit = (key, target, historical = false) => {
1392
+ capture(changes) {
1393
+ if (changes === undefined) {
1394
+ const next = new Map;
1395
+ const nextOwners = new Map;
1396
+ for (const run of this.runs()) {
1397
+ const owners = nextOwners.get(run.id) ?? new Map;
1398
+ nextOwners.set(run.id, owners);
1399
+ this.captureRun(run, this.previous.has(`run:${run.id}`), next, owners);
1400
+ }
1401
+ this.previous = next;
1402
+ this.owners = nextOwners;
1403
+ return;
1404
+ }
1405
+ if (changes.length === 0)
1406
+ return;
1407
+ const changed = new Map;
1408
+ for (const change of changes) {
1409
+ const current = changed.get(change.runId);
1410
+ if (current === "run")
1411
+ continue;
1412
+ if (change.stageId === undefined && change.toolNodeId === undefined) {
1413
+ changed.set(change.runId, "run");
1414
+ continue;
1415
+ }
1416
+ const nodes = current ?? { stages: new Set, tools: new Set };
1417
+ if (change.stageId !== undefined)
1418
+ nodes.stages.add(change.stageId);
1419
+ if (change.toolNodeId !== undefined)
1420
+ nodes.tools.add(change.toolNodeId);
1421
+ changed.set(change.runId, nodes);
1422
+ }
1423
+ for (const run of this.runs()) {
1424
+ const change = changed.get(run.id);
1425
+ if (change === undefined)
1426
+ continue;
1427
+ const existing = this.previous.has(`run:${run.id}`);
1428
+ const nodes = change === "run" || !existing ? undefined : change;
1429
+ const next = new Map;
1430
+ const nextOwners = new Map;
1431
+ this.captureRun(run, existing, next, nextOwners, nodes);
1432
+ const owners = this.owners.get(run.id) ?? new Map;
1433
+ const reread = nodes === undefined ? [...owners.keys()] : [...[...nodes.stages].map((id) => `stage:${id}`), ...[...nodes.tools].map((id) => `tool:${id}`)];
1434
+ for (const owner of reread)
1435
+ for (const key of owners.get(owner) ?? [])
1436
+ if (!next.has(key))
1437
+ this.previous.delete(key);
1438
+ for (const [key, target] of next)
1439
+ this.previous.set(key, target);
1440
+ if (nodes === undefined) {
1441
+ this.owners.set(run.id, nextOwners);
1442
+ continue;
1443
+ }
1444
+ for (const owner of reread) {
1445
+ const keys = nextOwners.get(owner);
1446
+ if (keys === undefined)
1447
+ owners.delete(owner);
1448
+ else
1449
+ owners.set(owner, keys);
1450
+ }
1451
+ this.owners.set(run.id, owners);
1452
+ }
1453
+ }
1454
+ captureRun(run, existing, next, owners, nodes) {
1455
+ const visit = (owner, key, target, historical = false) => {
1223
1456
  next.set(key, target);
1457
+ const keys = owners.get(owner);
1458
+ if (keys === undefined)
1459
+ owners.set(owner, [key]);
1460
+ else
1461
+ keys.push(key);
1224
1462
  const previous = this.previous.get(key);
1225
1463
  if (!historical && this.liveRunIds.has(target.runId) && previous?.status !== target.status) {
1226
- this.lifecycle(previous && previous.kind !== "prompt" && target.kind !== "prompt" ? { ...target, previousStatus: previous.status } : target, this.runs().find((run) => run.id === target.runId)?.origin);
1464
+ this.lifecycle(previous && previous.kind !== "prompt" && target.kind !== "prompt" ? { ...target, previousStatus: previous.status } : target, this.runs().find((candidate) => candidate.id === target.runId)?.origin);
1227
1465
  }
1228
1466
  };
1229
- for (const run of this.runs()) {
1230
- const existing = this.previous.has(`run:${run.id}`);
1231
- visit(`run:${run.id}`, { kind: "run", runId: run.id, status: run.status });
1232
- for (const stage of run.stages) {
1233
- visit(`stage:${workflowActivityNodeKey(run.id, stage.id)}`, { kind: "stage", runId: run.id, stageId: stage.id, stageName: stage.name, status: stage.status }, !existing);
1234
- if (stage.pendingPrompt)
1235
- visit(`prompt:${stage.pendingPrompt.id}`, {
1236
- kind: "prompt",
1237
- runId: run.id,
1238
- stageId: stage.id,
1239
- promptId: stage.pendingPrompt.id,
1240
- status: "opened"
1241
- }, !existing);
1242
- }
1243
- for (const tool of run.toolNodes)
1244
- visit(`tool:${workflowActivityNodeKey(run.id, tool.id)}`, { kind: "tool", runId: run.id, toolNodeId: tool.id, toolName: tool.name, status: tool.status }, !existing);
1245
- if (run.pendingPrompt)
1246
- visit(`prompt:${run.pendingPrompt.id}`, { kind: "prompt", runId: run.id, promptId: run.pendingPrompt.id, status: "opened" }, !existing);
1467
+ visit("run", `run:${run.id}`, { kind: "run", runId: run.id, status: run.status });
1468
+ for (const stage of run.stages) {
1469
+ if (nodes !== undefined && !nodes.stages.has(stage.id))
1470
+ continue;
1471
+ const owner = `stage:${stage.id}`;
1472
+ visit(owner, `stage:${workflowActivityNodeKey(run.id, stage.id)}`, { kind: "stage", runId: run.id, stageId: stage.id, stageName: stage.name, status: stage.status }, !existing);
1473
+ if (stage.pendingPrompt)
1474
+ visit(owner, `prompt:${stage.pendingPrompt.id}`, {
1475
+ kind: "prompt",
1476
+ runId: run.id,
1477
+ stageId: stage.id,
1478
+ promptId: stage.pendingPrompt.id,
1479
+ status: "opened"
1480
+ }, !existing);
1481
+ }
1482
+ for (const tool of run.toolNodes) {
1483
+ if (nodes !== undefined && !nodes.tools.has(tool.id))
1484
+ continue;
1485
+ visit(`tool:${tool.id}`, `tool:${workflowActivityNodeKey(run.id, tool.id)}`, { kind: "tool", runId: run.id, toolNodeId: tool.id, toolName: tool.name, status: tool.status }, !existing);
1247
1486
  }
1248
- this.previous = next;
1487
+ if (nodes === undefined && run.pendingPrompt)
1488
+ visit("run", `prompt:${run.pendingPrompt.id}`, { kind: "prompt", runId: run.id, promptId: run.pendingPrompt.id, status: "opened" }, !existing);
1249
1489
  }
1250
1490
  }
1251
1491
  var workflowObservationRuntimeKey = Symbol.for("atomic-workflows/store-observation-runtime@1");
@@ -1363,25 +1603,41 @@ function createStoreState() {
1363
1603
  function createStoreContext(state = createStoreState()) {
1364
1604
  let cachedGraphVersion = -1;
1365
1605
  let cachedGraphSnapshot;
1606
+ const graphBuilder = new GraphStoreSnapshotBuilder;
1366
1607
  const observation = new WorkflowObservationRuntime(() => state.runs, bumpAndNotify);
1367
1608
  function snapshot() {
1368
1609
  return JSON.parse(JSON.stringify({ runs: state.runs, notices: state.notices, version: state.version }));
1369
1610
  }
1370
1611
  function graphSnapshot() {
1371
1612
  if (cachedGraphSnapshot === undefined || cachedGraphVersion !== state.version) {
1372
- cachedGraphSnapshot = createGraphStoreSnapshot(state.runs, state.notices, state.version);
1613
+ cachedGraphSnapshot = graphBuilder.build(state.runs, state.notices, state.version);
1373
1614
  cachedGraphVersion = state.version;
1374
1615
  }
1375
1616
  return cachedGraphSnapshot;
1376
1617
  }
1618
+ function graphRun(runId) {
1619
+ if (cachedGraphSnapshot !== undefined && cachedGraphVersion === state.version)
1620
+ return findSnapshotRun(cachedGraphSnapshot.runs, runId);
1621
+ const run = state.runs.find((candidate) => candidate.id === runId);
1622
+ return run === undefined ? undefined : graphBuilder.buildRun(run);
1623
+ }
1377
1624
  let batchDepth = 0;
1378
1625
  let batchedNotification = false;
1379
- function notify() {
1626
+ let batchedChanges = [];
1627
+ function notify(change) {
1628
+ graphBuilder.markChanged(change);
1380
1629
  if (batchDepth > 0) {
1381
1630
  batchedNotification = true;
1631
+ if (change === undefined)
1632
+ batchedChanges = undefined;
1633
+ else
1634
+ batchedChanges?.push(change);
1382
1635
  return;
1383
1636
  }
1384
- observation.capture();
1637
+ observation.capture(change === undefined ? undefined : [change]);
1638
+ publish();
1639
+ }
1640
+ function publish() {
1385
1641
  for (const fn of state.invalidationListeners) {
1386
1642
  try {
1387
1643
  fn();
@@ -1396,9 +1652,9 @@ function createStoreContext(state = createStoreState()) {
1396
1652
  }
1397
1653
  }
1398
1654
  }
1399
- function bumpAndNotify() {
1655
+ function bumpAndNotify(change) {
1400
1656
  state.version++;
1401
- notify();
1657
+ notify(change);
1402
1658
  }
1403
1659
  function batch(update) {
1404
1660
  batchDepth++;
@@ -1407,8 +1663,11 @@ function createStoreContext(state = createStoreState()) {
1407
1663
  } finally {
1408
1664
  batchDepth--;
1409
1665
  if (batchDepth === 0 && batchedNotification) {
1666
+ const changes = batchedChanges;
1410
1667
  batchedNotification = false;
1411
- notify();
1668
+ batchedChanges = [];
1669
+ observation.capture(changes);
1670
+ publish();
1412
1671
  }
1413
1672
  }
1414
1673
  }
@@ -1464,6 +1723,7 @@ function createStoreContext(state = createStoreState()) {
1464
1723
  observation,
1465
1724
  snapshot,
1466
1725
  graphSnapshot,
1726
+ graphRun,
1467
1727
  notify,
1468
1728
  batch,
1469
1729
  bumpAndNotify,
@@ -2252,7 +2512,7 @@ function createRunStoreMethods(context) {
2252
2512
  state.runs.push(run);
2253
2513
  else
2254
2514
  state.runs[index] = run;
2255
- context.bumpAndNotify();
2515
+ context.bumpAndNotify({ runId: run.id });
2256
2516
  },
2257
2517
  recordRunSummary(runId, summary, summarizedThrough) {
2258
2518
  const run = context.findRun(runId);
@@ -2268,7 +2528,7 @@ function createRunStoreMethods(context) {
2268
2528
  if (update.phase !== undefined && update.phase !== run.phase)
2269
2529
  run.phaseStartedAt = Date.now();
2270
2530
  Object.assign(run, update);
2271
- context.bumpAndNotify();
2531
+ context.bumpAndNotify({ runId });
2272
2532
  },
2273
2533
  reconcileRunParentStage(runId, expectedParentStageId, parentStageId) {
2274
2534
  const run = context.findRun(runId);
@@ -2330,7 +2590,7 @@ function createRunStoreMethods(context) {
2330
2590
  context.rejectPrompt(pending.id, `atomic-workflows: run ${runId} ended before prompt resolved`);
2331
2591
  }
2332
2592
  context.rejectAllStagePrompts(runId, run, `atomic-workflows: run ${runId} ended before prompt resolved`);
2333
- context.bumpAndNotify();
2593
+ context.bumpAndNotify({ runId });
2334
2594
  return true;
2335
2595
  },
2336
2596
  recordRunBlocked(runId, error, metadata) {
@@ -2522,6 +2782,9 @@ function createRunStoreMethods(context) {
2522
2782
  graphSnapshot() {
2523
2783
  return context.graphSnapshot();
2524
2784
  },
2785
+ graphRun(runId) {
2786
+ return context.graphRun(runId);
2787
+ },
2525
2788
  subscribe(fn) {
2526
2789
  state.listeners.add(fn);
2527
2790
  return () => {
@@ -2559,7 +2822,7 @@ function createToolNodeStoreMethods(context) {
2559
2822
  if (node.executionOrder === undefined)
2560
2823
  node.executionOrder = nextExecutionOrder(run);
2561
2824
  nodes.push(node);
2562
- context.bumpAndNotify();
2825
+ context.bumpAndNotify({ runId, toolNodeId: node.id });
2563
2826
  return true;
2564
2827
  },
2565
2828
  recordToolNodeRunning(runId, nodeId, startedAt) {
@@ -2570,7 +2833,7 @@ function createToolNodeStoreMethods(context) {
2570
2833
  node.startedAt = startedAt;
2571
2834
  if (context.observation.liveRunIds.has(runId))
2572
2835
  context.observation.executingToolNodeIds.add(workflowActivityNodeKey(runId, nodeId));
2573
- context.bumpAndNotify();
2836
+ context.bumpAndNotify({ runId, toolNodeId: nodeId });
2574
2837
  return true;
2575
2838
  },
2576
2839
  recordToolNodeEnd(runId, nodeId, update) {
@@ -2589,7 +2852,7 @@ function createToolNodeStoreMethods(context) {
2589
2852
  node.resultSummary = update.resultSummary;
2590
2853
  if (update.error !== undefined)
2591
2854
  node.error = update.error;
2592
- context.bumpAndNotify();
2855
+ context.bumpAndNotify({ runId, toolNodeId: nodeId });
2593
2856
  return true;
2594
2857
  }
2595
2858
  };
@@ -2610,7 +2873,7 @@ function createStageStoreMethods(context) {
2610
2873
  if (stage.status === "running" && context.observation.liveRunIds.has(runId)) {
2611
2874
  context.observation.executingStageIds.add(workflowActivityNodeKey(runId, stage.id));
2612
2875
  }
2613
- context.bumpAndNotify();
2876
+ context.bumpAndNotify({ runId, stageId: stage.id });
2614
2877
  },
2615
2878
  recordStageWorkflowChildRun(runId, stageId, ref) {
2616
2879
  const run = context.findRun(runId);
@@ -2622,11 +2885,11 @@ function createStageStoreMethods(context) {
2622
2885
  const released = context.observation.executingStageIds.delete(workflowActivityNodeKey(runId, stageId));
2623
2886
  if (stage.workflowChildRun?.runId === ref.runId && stage.workflowChildRun.alias === ref.alias && stage.workflowChildRun.workflow === ref.workflow) {
2624
2887
  if (released)
2625
- context.bumpAndNotify();
2888
+ context.bumpAndNotify({ runId, stageId });
2626
2889
  return false;
2627
2890
  }
2628
2891
  stage.workflowChildRun = { ...ref };
2629
- context.bumpAndNotify();
2892
+ context.bumpAndNotify({ runId, stageId });
2630
2893
  return true;
2631
2894
  },
2632
2895
  recordToolStart(runId, stageId, evt) {
@@ -2640,7 +2903,7 @@ function createStageStoreMethods(context) {
2640
2903
  if (!exists) {
2641
2904
  stage.toolEvents.push(evt);
2642
2905
  }
2643
- context.bumpAndNotify();
2906
+ context.bumpAndNotify({ runId, stageId });
2644
2907
  },
2645
2908
  recordToolEnd(runId, stageId, evt) {
2646
2909
  const run = context.findRun(runId);
@@ -2654,7 +2917,7 @@ function createStageStoreMethods(context) {
2654
2917
  existing.endedAt = evt.endedAt;
2655
2918
  existing.output = evt.output;
2656
2919
  }
2657
- context.bumpAndNotify();
2920
+ context.bumpAndNotify({ runId, stageId });
2658
2921
  },
2659
2922
  recordStageEnd(runId, stage) {
2660
2923
  const run = context.findRun(runId);
@@ -2710,7 +2973,7 @@ function createStageStoreMethods(context) {
2710
2973
  delete existing.awaitingInputSince;
2711
2974
  delete existing.inputRequest;
2712
2975
  context.rejectStagePrompt(runId, existing, `atomic-workflows: stage ${stage.id} ended before prompt resolved`);
2713
- context.bumpAndNotify();
2976
+ context.bumpAndNotify({ runId, stageId: stage.id });
2714
2977
  },
2715
2978
  recordStageSession(runId, stageId, session) {
2716
2979
  const run = context.findRun(runId);
@@ -2720,7 +2983,7 @@ function createStageStoreMethods(context) {
2720
2983
  if (!stage || stage.sessionId === session.sessionId)
2721
2984
  return false;
2722
2985
  stage.sessionId = session.sessionId;
2723
- context.bumpAndNotify();
2986
+ context.bumpAndNotify({ runId, stageId });
2724
2987
  return true;
2725
2988
  },
2726
2989
  recordStageAttachable(runId, stageId, attachable) {
@@ -2738,7 +3001,7 @@ function createStageStoreMethods(context) {
2738
3001
  } else {
2739
3002
  stage.attachable = next;
2740
3003
  }
2741
- context.bumpAndNotify();
3004
+ context.bumpAndNotify({ runId, stageId });
2742
3005
  return true;
2743
3006
  },
2744
3007
  recordStageAttached(runId, stageId, attached) {
@@ -2756,7 +3019,7 @@ function createStageStoreMethods(context) {
2756
3019
  } else {
2757
3020
  stage.attached = next;
2758
3021
  }
2759
- context.bumpAndNotify();
3022
+ context.bumpAndNotify({ runId, stageId });
2760
3023
  return true;
2761
3024
  },
2762
3025
  recordStageAwaitingInput(runId, stageId, awaiting, ts) {
@@ -2783,7 +3046,7 @@ function createStageStoreMethods(context) {
2783
3046
  stage.status = "running";
2784
3047
  delete stage.awaitingInputSince;
2785
3048
  }
2786
- context.bumpAndNotify();
3049
+ context.bumpAndNotify({ runId, stageId });
2787
3050
  return true;
2788
3051
  },
2789
3052
  recordStageInputRequest(runId, stageId, request) {
@@ -2800,7 +3063,7 @@ function createStageStoreMethods(context) {
2800
3063
  if (stage.inputRequest?.id === request.id)
2801
3064
  return false;
2802
3065
  stage.inputRequest = { ...request };
2803
- context.bumpAndNotify();
3066
+ context.bumpAndNotify({ runId, stageId });
2804
3067
  return true;
2805
3068
  },
2806
3069
  clearStageInputRequest(runId, stageId) {
@@ -2811,7 +3074,7 @@ function createStageStoreMethods(context) {
2811
3074
  if (!stage || stage.inputRequest === undefined)
2812
3075
  return false;
2813
3076
  delete stage.inputRequest;
2814
- context.bumpAndNotify();
3077
+ context.bumpAndNotify({ runId, stageId });
2815
3078
  return true;
2816
3079
  },
2817
3080
  recordStageBlocked(runId, stageId, blockedBy) {
@@ -2834,7 +3097,7 @@ function createStageStoreMethods(context) {
2834
3097
  stage.blockedByStageId = blockedBy;
2835
3098
  delete stage.awaitingInputSince;
2836
3099
  }
2837
- context.bumpAndNotify();
3100
+ context.bumpAndNotify({ runId, stageId });
2838
3101
  return true;
2839
3102
  },
2840
3103
  recordStageUnblocked(runId, stageId) {
@@ -2847,7 +3110,7 @@ function createStageStoreMethods(context) {
2847
3110
  stage.status = "pending";
2848
3111
  delete stage.blockedByStageId;
2849
3112
  delete stage.awaitingInputSince;
2850
- context.bumpAndNotify();
3113
+ context.bumpAndNotify({ runId, stageId });
2851
3114
  return true;
2852
3115
  },
2853
3116
  recordStageNotice(runId, stageId, notice) {
@@ -2860,7 +3123,7 @@ function createStageStoreMethods(context) {
2860
3123
  if (!stage.notices)
2861
3124
  stage.notices = [];
2862
3125
  stage.notices.push(notice);
2863
- context.bumpAndNotify();
3126
+ context.bumpAndNotify({ runId, stageId });
2864
3127
  return true;
2865
3128
  },
2866
3129
  recordStagePaused(runId, stageId, pausedAt, metadata) {
@@ -2878,7 +3141,7 @@ function createStageStoreMethods(context) {
2878
3141
  if (stage.pauseActor === metadata.actor)
2879
3142
  return false;
2880
3143
  stage.pauseActor = metadata.actor;
2881
- context.bumpAndNotify();
3144
+ context.bumpAndNotify({ runId, stageId });
2882
3145
  return false;
2883
3146
  }
2884
3147
  context.observation.executingStageIds.delete(workflowActivityNodeKey(runId, stageId));
@@ -2891,7 +3154,7 @@ function createStageStoreMethods(context) {
2891
3154
  delete stage.pauseActor;
2892
3155
  else
2893
3156
  stage.pauseActor = metadata.actor;
2894
- context.bumpAndNotify();
3157
+ context.bumpAndNotify({ runId, stageId });
2895
3158
  return true;
2896
3159
  },
2897
3160
  recordStageResumed(runId, stageId, resumedAt, metadata) {
@@ -2910,7 +3173,7 @@ function createStageStoreMethods(context) {
2910
3173
  if (stage.resumeActor === metadata.actor)
2911
3174
  return false;
2912
3175
  stage.resumeActor = metadata.actor;
2913
- context.bumpAndNotify();
3176
+ context.bumpAndNotify({ runId, stageId });
2914
3177
  return false;
2915
3178
  }
2916
3179
  const resumedTs = nextControlTimestamp(resumedAt, stage.pausedAt);
@@ -2929,7 +3192,7 @@ function createStageStoreMethods(context) {
2929
3192
  delete stage.resumeActor;
2930
3193
  else
2931
3194
  stage.resumeActor = metadata.actor;
2932
- context.bumpAndNotify();
3195
+ context.bumpAndNotify({ runId, stageId });
2933
3196
  return true;
2934
3197
  }
2935
3198
  };