@graphrefly/graphrefly 0.10.0 → 0.12.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.
Files changed (70) hide show
  1. package/dist/{chunk-QTZSBQGJ.js → chunk-4F2ZFD5L.js} +19 -1
  2. package/dist/chunk-4F2ZFD5L.js.map +1 -0
  3. package/dist/{chunk-LR2CLSEF.js → chunk-6OLNYOGU.js} +2 -3
  4. package/dist/chunk-6OLNYOGU.js.map +1 -0
  5. package/dist/{chunk-TZLX4KIT.js → chunk-BRPCN2HJ.js} +46 -17
  6. package/dist/chunk-BRPCN2HJ.js.map +1 -0
  7. package/dist/{chunk-A2AJJOSJ.js → chunk-IXTW3BIO.js} +3 -3
  8. package/dist/{chunk-XCZPGOVP.js → chunk-JYRHO63K.js} +3 -3
  9. package/dist/{chunk-UCW3VWMN.js → chunk-NULSP7U4.js} +4 -4
  10. package/dist/{chunk-WYI7YW54.js → chunk-VQWLA6XQ.js} +3 -3
  11. package/dist/{chunk-YWTP2XRJ.js → chunk-X732W3QA.js} +2 -2
  12. package/dist/{chunk-E7OH6ZAZ.js → chunk-XWMTVV2D.js} +62 -3
  13. package/dist/chunk-XWMTVV2D.js.map +1 -0
  14. package/dist/compat/nestjs/index.cjs +10 -1
  15. package/dist/compat/nestjs/index.cjs.map +1 -1
  16. package/dist/compat/nestjs/index.d.cts +4 -4
  17. package/dist/compat/nestjs/index.d.ts +4 -4
  18. package/dist/compat/nestjs/index.js +7 -7
  19. package/dist/core/index.cjs +74 -1
  20. package/dist/core/index.cjs.map +1 -1
  21. package/dist/core/index.d.cts +2 -2
  22. package/dist/core/index.d.ts +2 -2
  23. package/dist/core/index.js +12 -3
  24. package/dist/extra/index.cjs +52 -14
  25. package/dist/extra/index.cjs.map +1 -1
  26. package/dist/extra/index.d.cts +4 -4
  27. package/dist/extra/index.d.ts +4 -4
  28. package/dist/extra/index.js +5 -5
  29. package/dist/graph/index.cjs +10 -1
  30. package/dist/graph/index.cjs.map +1 -1
  31. package/dist/graph/index.d.cts +3 -3
  32. package/dist/graph/index.d.ts +3 -3
  33. package/dist/graph/index.js +4 -4
  34. package/dist/{graph-DqTICAY2.d.cts → graph-BE10ujU9.d.cts} +1 -1
  35. package/dist/{graph-X9uwnD_z.d.ts → graph-DXT95WZ3.d.ts} +1 -1
  36. package/dist/{index-DLO8wnYU.d.ts → index-53cDGX7F.d.ts} +3 -3
  37. package/dist/{index-DMv1Etbi.d.ts → index-B10Q0sQB.d.ts} +2 -2
  38. package/dist/{index-BPCeYDS4.d.ts → index-C0_7g9sj.d.ts} +1 -1
  39. package/dist/{index-3U0WxdD-.d.cts → index-CCvzN5GB.d.cts} +2 -2
  40. package/dist/{index-BP1t_38S.d.cts → index-CiAqgfFg.d.ts} +17 -13
  41. package/dist/{index-a5gHmH5b.d.ts → index-CthwPnHQ.d.cts} +17 -13
  42. package/dist/{index-BVG5pjin.d.ts → index-Dzdm20sx.d.ts} +88 -3
  43. package/dist/{index-BYEgosAX.d.cts → index-QfbXNW1N.d.cts} +88 -3
  44. package/dist/{index-BYa2YMat.d.cts → index-aBZ2RoP0.d.cts} +3 -3
  45. package/dist/{index-DbwgQ4Cw.d.cts → index-nRulwTr-.d.cts} +1 -1
  46. package/dist/index.cjs +1084 -118
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +422 -22
  49. package/dist/index.d.ts +422 -22
  50. package/dist/index.js +988 -120
  51. package/dist/index.js.map +1 -1
  52. package/dist/{meta-BJEU8fYz.d.cts → meta-BcuDhtwu.d.cts} +33 -1
  53. package/dist/{meta-BJEU8fYz.d.ts → meta-BcuDhtwu.d.ts} +33 -1
  54. package/dist/patterns/reactive-layout/index.cjs +10 -1
  55. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  56. package/dist/patterns/reactive-layout/index.d.cts +3 -3
  57. package/dist/patterns/reactive-layout/index.d.ts +3 -3
  58. package/dist/patterns/reactive-layout/index.js +4 -4
  59. package/dist/{reactive-log-RhgIog2Z.d.ts → reactive-log-Cu0VdqkT.d.ts} +2 -2
  60. package/dist/{reactive-log-BfX6bOSZ.d.cts → reactive-log-OULQssZg.d.cts} +2 -2
  61. package/package.json +7 -2
  62. package/dist/chunk-E7OH6ZAZ.js.map +0 -1
  63. package/dist/chunk-LR2CLSEF.js.map +0 -1
  64. package/dist/chunk-QTZSBQGJ.js.map +0 -1
  65. package/dist/chunk-TZLX4KIT.js.map +0 -1
  66. /package/dist/{chunk-A2AJJOSJ.js.map → chunk-IXTW3BIO.js.map} +0 -0
  67. /package/dist/{chunk-XCZPGOVP.js.map → chunk-JYRHO63K.js.map} +0 -0
  68. /package/dist/{chunk-UCW3VWMN.js.map → chunk-NULSP7U4.js.map} +0 -0
  69. /package/dist/{chunk-WYI7YW54.js.map → chunk-VQWLA6XQ.js.map} +0 -0
  70. /package/dist/{chunk-YWTP2XRJ.js.map → chunk-X732W3QA.js.map} +0 -0
package/dist/index.js CHANGED
@@ -64,7 +64,6 @@ import {
64
64
  fromSyslog,
65
65
  fromWebSocket,
66
66
  fromWebhook,
67
- gate,
68
67
  interval,
69
68
  last,
70
69
  linear,
@@ -126,6 +125,7 @@ import {
126
125
  toWebSocket,
127
126
  tokenBucket,
128
127
  tokenTracker,
128
+ valve,
129
129
  verifiable,
130
130
  window,
131
131
  windowCount,
@@ -137,14 +137,24 @@ import {
137
137
  workerBridge,
138
138
  workerSelf,
139
139
  zip
140
- } from "./chunk-TZLX4KIT.js";
140
+ } from "./chunk-BRPCN2HJ.js";
141
141
  import {
142
142
  cqrs_exports,
143
143
  nestjs_exports
144
- } from "./chunk-UCW3VWMN.js";
144
+ } from "./chunk-NULSP7U4.js";
145
145
  import {
146
+ DEFAULT_DOWN,
147
+ bridge,
146
148
  core_exports
147
- } from "./chunk-E7OH6ZAZ.js";
149
+ } from "./chunk-XWMTVV2D.js";
150
+ import {
151
+ JsonCodec,
152
+ createDagCborCodec,
153
+ createDagCborZstdCodec,
154
+ graph_exports,
155
+ negotiateCodec,
156
+ replayWAL
157
+ } from "./chunk-IXTW3BIO.js";
148
158
  import {
149
159
  cached,
150
160
  createWatermarkController,
@@ -177,34 +187,27 @@ import {
177
187
  toArray,
178
188
  toMessages$,
179
189
  toObservable
180
- } from "./chunk-YWTP2XRJ.js";
190
+ } from "./chunk-X732W3QA.js";
181
191
  import {
182
192
  ResettableTimer
183
193
  } from "./chunk-WZ2Z2CRV.js";
184
- import {
185
- JsonCodec,
186
- createDagCborCodec,
187
- createDagCborZstdCodec,
188
- graph_exports,
189
- negotiateCodec,
190
- replayWAL
191
- } from "./chunk-A2AJJOSJ.js";
192
194
  import {
193
195
  analyzeAndMeasure,
194
196
  computeLineBreaks,
195
197
  reactive_layout_exports
196
- } from "./chunk-XCZPGOVP.js";
198
+ } from "./chunk-JYRHO63K.js";
197
199
  import {
198
200
  GRAPH_META_SEGMENT,
199
201
  Graph,
200
202
  reachable
201
- } from "./chunk-WYI7YW54.js";
203
+ } from "./chunk-VQWLA6XQ.js";
202
204
  import {
203
205
  describeNode,
204
206
  metaSnapshot,
205
207
  resolveDescribeFields
206
- } from "./chunk-LR2CLSEF.js";
208
+ } from "./chunk-6OLNYOGU.js";
207
209
  import {
210
+ CLEANUP_RESULT,
208
211
  COMPLETE,
209
212
  DATA,
210
213
  DEFAULT_ACTOR,
@@ -221,6 +224,7 @@ import {
221
224
  accessHintForGuard,
222
225
  advanceVersion,
223
226
  batch,
227
+ cleanupResult,
224
228
  createVersioning,
225
229
  defaultHash,
226
230
  derived,
@@ -245,7 +249,7 @@ import {
245
249
  propagatesToMeta,
246
250
  state,
247
251
  wallClockNs
248
- } from "./chunk-QTZSBQGJ.js";
252
+ } from "./chunk-4F2ZFD5L.js";
249
253
 
250
254
  // src/compat/index.ts
251
255
  var compat_exports = {};
@@ -1045,6 +1049,7 @@ __export(patterns_exports, {
1045
1049
  ai: () => ai_exports,
1046
1050
  cqrs: () => cqrs_exports,
1047
1051
  demoShell: () => demo_shell_exports,
1052
+ domainTemplates: () => domain_templates_exports,
1048
1053
  graphspec: () => graphspec_exports,
1049
1054
  layout: () => reactive_layout_exports,
1050
1055
  memory: () => memory_exports,
@@ -1070,6 +1075,7 @@ __export(ai_exports, {
1070
1075
  knobsAsTools: () => knobsAsTools,
1071
1076
  llmConsolidator: () => llmConsolidator,
1072
1077
  llmExtractor: () => llmExtractor,
1078
+ promptNode: () => promptNode,
1073
1079
  suggestStrategy: () => suggestStrategy,
1074
1080
  systemPromptBuilder: () => systemPromptBuilder,
1075
1081
  toolRegistry: () => toolRegistry,
@@ -1585,6 +1591,75 @@ function fromLLMStream(adapter, messages, opts) {
1585
1591
  }
1586
1592
  };
1587
1593
  }
1594
+ function extractContent(resp) {
1595
+ if (resp != null && typeof resp === "object" && "content" in resp) {
1596
+ return String(resp.content);
1597
+ }
1598
+ if (typeof resp === "string") return resp;
1599
+ return String(resp);
1600
+ }
1601
+ function promptNode(adapter, deps, prompt, opts) {
1602
+ const format = opts?.format ?? "text";
1603
+ const retries = opts?.retries ?? 0;
1604
+ const useCache = opts?.cache ?? false;
1605
+ const cache2 = useCache ? /* @__PURE__ */ new Map() : null;
1606
+ const messagesNode = derived(
1607
+ deps,
1608
+ (values) => {
1609
+ const text = typeof prompt === "string" ? prompt : prompt(...values);
1610
+ const msgs = [];
1611
+ if (opts?.systemPrompt) msgs.push({ role: "system", content: opts.systemPrompt });
1612
+ msgs.push({ role: "user", content: text });
1613
+ return msgs;
1614
+ },
1615
+ {
1616
+ name: opts?.name ? `${opts.name}::messages` : "prompt_node::messages",
1617
+ meta: aiMeta("prompt_node")
1618
+ }
1619
+ );
1620
+ const result = switchMap(messagesNode, (msgs) => {
1621
+ if (!msgs || msgs.length === 0) {
1622
+ return state(null);
1623
+ }
1624
+ const cacheKey = useCache ? JSON.stringify(msgs.map((m) => [m.role, m.content])) : "";
1625
+ if (cache2?.has(cacheKey)) {
1626
+ return state(cache2.get(cacheKey));
1627
+ }
1628
+ async function attempt(remaining) {
1629
+ try {
1630
+ const resp = await new Promise((resolve, reject) => {
1631
+ const input = adapter.invoke(msgs, {
1632
+ model: opts?.model,
1633
+ temperature: opts?.temperature,
1634
+ maxTokens: opts?.maxTokens,
1635
+ systemPrompt: opts?.systemPrompt
1636
+ });
1637
+ if (input && typeof input.then === "function") {
1638
+ input.then(resolve, reject);
1639
+ } else if (input && typeof input.get === "function") {
1640
+ resolve(input.get());
1641
+ } else {
1642
+ resolve(input);
1643
+ }
1644
+ });
1645
+ const content = extractContent(resp);
1646
+ let parsed;
1647
+ if (format === "json") {
1648
+ parsed = JSON.parse(stripFences(content));
1649
+ } else {
1650
+ parsed = content;
1651
+ }
1652
+ cache2?.set(cacheKey, parsed);
1653
+ return parsed;
1654
+ } catch (err) {
1655
+ if (remaining > 0) return attempt(remaining - 1);
1656
+ throw err;
1657
+ }
1658
+ }
1659
+ return attempt(retries);
1660
+ });
1661
+ return result;
1662
+ }
1588
1663
  var ChatStreamGraph = class extends Graph {
1589
1664
  _log;
1590
1665
  _keepaliveSubs = [];
@@ -2458,7 +2533,7 @@ function gaugesAsContext(graph, actor, options) {
2458
2533
  const ungrouped = [];
2459
2534
  for (const entry of entries) {
2460
2535
  const node2 = described.nodes[entry.path];
2461
- const tags = (node2.meta ?? {}).tags;
2536
+ const tags = node2.meta?.tags;
2462
2537
  if (tags && tags.length > 0) {
2463
2538
  const tag = tags[0];
2464
2539
  let group = tagGroups.get(tag);
@@ -3025,15 +3100,13 @@ function demoShell(opts) {
3025
3100
  };
3026
3101
  }
3027
3102
 
3028
- // src/patterns/graphspec.ts
3029
- var graphspec_exports = {};
3030
- __export(graphspec_exports, {
3031
- compileSpec: () => compileSpec,
3032
- decompileGraph: () => decompileGraph,
3033
- llmCompose: () => llmCompose,
3034
- llmRefine: () => llmRefine,
3035
- specDiff: () => specDiff,
3036
- validateSpec: () => validateSpec
3103
+ // src/patterns/domain-templates.ts
3104
+ var domain_templates_exports = {};
3105
+ __export(domain_templates_exports, {
3106
+ contentModerationGraph: () => contentModerationGraph,
3107
+ dataQualityGraph: () => dataQualityGraph,
3108
+ issueTrackerGraph: () => issueTrackerGraph,
3109
+ observabilityGraph: () => observabilityGraph
3037
3110
  });
3038
3111
 
3039
3112
  // src/patterns/reduction.ts
@@ -3052,6 +3125,10 @@ function baseMeta(kind, meta) {
3052
3125
  ...meta ?? {}
3053
3126
  };
3054
3127
  }
3128
+ function keepalive2(n) {
3129
+ return n.subscribe(() => {
3130
+ });
3131
+ }
3055
3132
  function stratify(name, source, rules, opts) {
3056
3133
  const g = new Graph(name, opts);
3057
3134
  g.add("source", source);
@@ -3066,18 +3143,27 @@ function stratify(name, source, rules, opts) {
3066
3143
  }
3067
3144
  function _addBranch(graph, source, rulesNode, rule) {
3068
3145
  const branchName = `branch/${rule.name}`;
3146
+ const _noValue = /* @__PURE__ */ Symbol("noValue");
3147
+ let sourceDirty = false;
3148
+ let rulesDirty = false;
3149
+ let sourcePhase2 = false;
3150
+ let sourceValue = _noValue;
3069
3151
  let pendingDirty = false;
3070
- const filterNode = node([source, rulesNode], () => void 0, {
3071
- describeKind: "operator",
3072
- meta: baseMeta("stratify_branch", { branch: rule.name }),
3073
- onMessage(msg, depIndex, actions) {
3074
- if (depIndex !== 0) return false;
3075
- const t = msg[0];
3076
- if (t === DATA) {
3077
- const value = msg[1];
3152
+ function resolve(actions) {
3153
+ if (sourcePhase2) {
3154
+ sourcePhase2 = false;
3155
+ const value = sourceValue;
3156
+ sourceValue = _noValue;
3157
+ if (value !== _noValue) {
3078
3158
  const currentRules = rulesNode.get();
3079
3159
  const currentRule = currentRules.find((r) => r.name === rule.name);
3080
- if (currentRule && currentRule.classify(value)) {
3160
+ let matches = false;
3161
+ try {
3162
+ matches = currentRule?.classify(value) ?? false;
3163
+ } catch {
3164
+ matches = false;
3165
+ }
3166
+ if (matches) {
3081
3167
  pendingDirty = false;
3082
3168
  actions.emit(value);
3083
3169
  } else {
@@ -3086,28 +3172,57 @@ function _addBranch(graph, source, rulesNode, rule) {
3086
3172
  actions.down([[DIRTY], [RESOLVED]]);
3087
3173
  }
3088
3174
  }
3089
- return true;
3090
- }
3091
- if (t === DIRTY) {
3092
- pendingDirty = true;
3093
- return true;
3094
- }
3095
- if (t === RESOLVED) {
3175
+ } else {
3096
3176
  if (pendingDirty) {
3097
3177
  pendingDirty = false;
3098
3178
  actions.down([[DIRTY], [RESOLVED]]);
3099
3179
  } else {
3100
3180
  actions.down([[RESOLVED]]);
3101
3181
  }
3182
+ }
3183
+ }
3184
+ }
3185
+ const filterNode = node([source, rulesNode], () => void 0, {
3186
+ describeKind: "operator",
3187
+ meta: baseMeta("stratify_branch", { branch: rule.name }),
3188
+ onMessage(msg, depIndex, actions) {
3189
+ const t = msg[0];
3190
+ if (t === DIRTY) {
3191
+ if (depIndex === 0) {
3192
+ sourceDirty = true;
3193
+ pendingDirty = true;
3194
+ } else {
3195
+ rulesDirty = true;
3196
+ }
3102
3197
  return true;
3103
3198
  }
3104
- if (t === COMPLETE || t === ERROR) {
3199
+ if (t === DATA || t === RESOLVED) {
3200
+ if (depIndex === 0) {
3201
+ sourceDirty = false;
3202
+ sourcePhase2 = true;
3203
+ sourceValue = t === DATA ? msg[1] : _noValue;
3204
+ } else {
3205
+ rulesDirty = false;
3206
+ }
3207
+ if (sourceDirty || rulesDirty) return true;
3208
+ resolve(actions);
3209
+ return true;
3210
+ }
3211
+ if (t === COMPLETE || t === ERROR || t === TEARDOWN) {
3212
+ sourceDirty = false;
3213
+ rulesDirty = false;
3214
+ sourcePhase2 = false;
3215
+ sourceValue = _noValue;
3105
3216
  pendingDirty = false;
3106
- actions.down([msg]);
3217
+ if (depIndex === 0) {
3218
+ actions.down([msg]);
3219
+ }
3107
3220
  return true;
3108
3221
  }
3222
+ if (depIndex === 1) return true;
3109
3223
  return false;
3110
- }
3224
+ },
3225
+ completeWhenDepsComplete: false
3111
3226
  });
3112
3227
  graph.add(branchName, filterNode);
3113
3228
  graph.connect("source", branchName);
@@ -3143,20 +3258,14 @@ function funnel(name, sources, stages, opts) {
3143
3258
  const prevNode = g.resolve(prevOutputPath);
3144
3259
  const stageInputPath = `${stage.name}::input`;
3145
3260
  const stageInput = g.resolve(stageInputPath);
3146
- prevNode.subscribe((msgs) => {
3147
- for (const msg of msgs) {
3148
- const t = msg[0];
3149
- if (t === DATA) {
3150
- stageInput.down([[DATA, msg[1]]]);
3151
- } else if (t === DIRTY) {
3152
- stageInput.down([[DIRTY]]);
3153
- } else if (t === RESOLVED) {
3154
- stageInput.down([[RESOLVED]]);
3155
- } else if (t === COMPLETE || t === ERROR) {
3156
- stageInput.down([msg]);
3157
- }
3158
- }
3261
+ const bridgeName = `__bridge_${prevOutputPath}\u2192${stage.name}_input`;
3262
+ const br = bridge(prevNode, stageInput, {
3263
+ name: bridgeName,
3264
+ down: DEFAULT_DOWN.filter((t) => t !== TEARDOWN)
3159
3265
  });
3266
+ g.add(bridgeName, br);
3267
+ g.connect(prevOutputPath, bridgeName);
3268
+ keepalive2(br);
3160
3269
  prevOutputPath = `${stage.name}::output`;
3161
3270
  }
3162
3271
  return g;
@@ -3174,38 +3283,41 @@ function feedback(graph, condition, reentry, opts) {
3174
3283
  graph.add(counterName, counter);
3175
3284
  const condNode = graph.resolve(condition);
3176
3285
  const reentryNode = graph.resolve(reentry);
3177
- let tornDown = false;
3178
- let unsubCounter = null;
3179
- const safeUnsub = () => {
3180
- if (tornDown) return;
3181
- tornDown = true;
3182
- unsub();
3183
- unsubCounter?.();
3184
- };
3185
- const unsub = condNode.subscribe((msgs) => {
3186
- for (const msg of msgs) {
3187
- if (msg[0] === DATA) {
3286
+ const feedbackEffectName = `__feedback_effect_${condition}`;
3287
+ const feedbackEffect = node([condNode], void 0, {
3288
+ name: feedbackEffectName,
3289
+ describeKind: "effect",
3290
+ meta: {
3291
+ ...baseMeta("feedback_effect", {
3292
+ feedbackFrom: condition,
3293
+ feedbackTo: reentry
3294
+ }),
3295
+ _internal: true
3296
+ },
3297
+ onMessage(msg, _depIndex, _actions) {
3298
+ const t = msg[0];
3299
+ if (t === DATA) {
3188
3300
  const currentCount = counter.get();
3189
- if (currentCount >= maxIter) continue;
3301
+ if (currentCount >= maxIter) return true;
3190
3302
  const condValue = msg[1];
3191
- if (condValue == null) continue;
3192
- counter.down([[DATA, currentCount + 1]]);
3193
- reentryNode.down([[DATA, condValue]]);
3194
- } else if (msg[0] === COMPLETE || msg[0] === ERROR) {
3195
- const terminal = msg[0] === ERROR && msg.length > 1 ? [ERROR, msg[1]] : [msg[0]];
3196
- counter.down([terminal]);
3197
- safeUnsub();
3303
+ if (condValue == null) return true;
3304
+ batch(() => {
3305
+ counter.down([[DATA, currentCount + 1]]);
3306
+ reentryNode.down([[DATA, condValue]]);
3307
+ });
3308
+ return true;
3198
3309
  }
3199
- }
3200
- });
3201
- unsubCounter = counter.subscribe((msgs) => {
3202
- for (const msg of msgs) {
3203
- if (msg[0] === COMPLETE || msg[0] === ERROR) {
3204
- safeUnsub();
3205
- return;
3310
+ if (t === COMPLETE || t === ERROR) {
3311
+ const terminal = t === ERROR && msg.length > 1 ? [ERROR, msg[1]] : [t];
3312
+ counter.down([terminal]);
3313
+ return true;
3206
3314
  }
3315
+ return false;
3207
3316
  }
3208
3317
  });
3318
+ graph.add(feedbackEffectName, feedbackEffect);
3319
+ graph.connect(condition, feedbackEffectName);
3320
+ keepalive2(feedbackEffect);
3209
3321
  return graph;
3210
3322
  }
3211
3323
  function budgetGate(source, constraints, opts) {
@@ -3221,7 +3333,8 @@ function budgetGate(source, constraints, opts) {
3221
3333
  }
3222
3334
  function flushBuffer(actions) {
3223
3335
  while (buffer2.length > 0 && checkBudget()) {
3224
- const item = buffer2.shift();
3336
+ const item = buffer2[0];
3337
+ buffer2 = buffer2.slice(1);
3225
3338
  actions.emit(item);
3226
3339
  }
3227
3340
  if (buffer2.length === 0 && pendingResolved) {
@@ -3339,7 +3452,600 @@ function scorer(sources, weights, opts) {
3339
3452
  );
3340
3453
  }
3341
3454
 
3455
+ // src/patterns/domain-templates.ts
3456
+ function keepalive3(n) {
3457
+ return n.subscribe(() => {
3458
+ });
3459
+ }
3460
+ function baseMeta2(kind, extra) {
3461
+ return { domain_template: true, template_type: kind, ...extra ?? {} };
3462
+ }
3463
+ function observabilityGraph(name, opts) {
3464
+ const g = new Graph(name, opts);
3465
+ g.add("source", opts.source);
3466
+ const defaultBranches = [
3467
+ { name: "errors", classify: (v) => isTagged(v, "error") },
3468
+ { name: "traces", classify: (v) => isTagged(v, "trace") },
3469
+ { name: "metrics", classify: (v) => isTagged(v, "metric") }
3470
+ ];
3471
+ const branches = opts.branches ?? defaultBranches;
3472
+ const rules = branches.map((b) => ({
3473
+ name: b.name,
3474
+ classify: b.classify
3475
+ }));
3476
+ const strat = stratify("stratify", opts.source, rules);
3477
+ g.mount("stratify", strat);
3478
+ const branchNodes = branches.map((b) => {
3479
+ try {
3480
+ return g.resolve(`stratify::branch/${b.name}`);
3481
+ } catch {
3482
+ return state(null);
3483
+ }
3484
+ });
3485
+ const correlateFn = opts.correlate ?? ((vals) => vals);
3486
+ const correlateNode = derived(
3487
+ branchNodes,
3488
+ (vals) => correlateFn(vals),
3489
+ {
3490
+ meta: baseMeta2("observability", { stage: "correlate" })
3491
+ }
3492
+ );
3493
+ g.add("correlate", correlateNode);
3494
+ for (const b of branches) {
3495
+ try {
3496
+ g.connect(`stratify::branch/${b.name}`, "correlate");
3497
+ } catch {
3498
+ }
3499
+ }
3500
+ const sloCheckFn = opts.sloCheck ?? (() => ({ pass: true }));
3501
+ const sloValue = derived([correlateNode], (vals) => vals[0], {
3502
+ meta: baseMeta2("observability", { stage: "slo_value" })
3503
+ });
3504
+ const sloVerified = derived([sloValue], (vals) => sloCheckFn(vals[0]), {
3505
+ meta: baseMeta2("observability", { stage: "slo_verified" })
3506
+ });
3507
+ g.add("slo_value", sloValue);
3508
+ g.add("slo_verified", sloVerified);
3509
+ g.connect("correlate", "slo_value");
3510
+ g.connect("slo_value", "slo_verified");
3511
+ const weightValues = opts.weights ?? branches.map(() => 1);
3512
+ const signalNodes = branchNodes.map(
3513
+ (bn) => derived([bn], (vals) => vals[0] != null ? 1 : 0)
3514
+ );
3515
+ const weightNodes = weightValues.map((w) => state(w));
3516
+ for (let i = 0; i < signalNodes.length; i++) {
3517
+ g.add(`__signal_${i}`, signalNodes[i]);
3518
+ g.add(`__weight_${i}`, weightNodes[i]);
3519
+ }
3520
+ const alerts = scorer(
3521
+ signalNodes,
3522
+ weightNodes
3523
+ );
3524
+ g.add("alerts", alerts);
3525
+ const output = derived(
3526
+ [alerts, sloVerified],
3527
+ (vals) => ({
3528
+ scored: vals[0],
3529
+ slo: vals[1]
3530
+ }),
3531
+ {
3532
+ meta: baseMeta2("observability", { stage: "output" })
3533
+ }
3534
+ );
3535
+ g.add("output", output);
3536
+ g.connect("alerts", "output");
3537
+ g.connect("slo_verified", "output");
3538
+ const fbReentry = state(null, {
3539
+ meta: baseMeta2("observability", { stage: "feedback_reentry" })
3540
+ });
3541
+ g.add("feedback_reentry", fbReentry);
3542
+ const fbCondition = derived(
3543
+ [sloVerified],
3544
+ (vals) => {
3545
+ const result = vals[0];
3546
+ if (result && result.pass === false) return result;
3547
+ return null;
3548
+ },
3549
+ {
3550
+ meta: baseMeta2("observability", { stage: "feedback_condition" })
3551
+ }
3552
+ );
3553
+ g.add("feedback_condition", fbCondition);
3554
+ g.connect("slo_verified", "feedback_condition");
3555
+ feedback(g, "feedback_condition", "feedback_reentry", {
3556
+ maxIterations: opts.maxFeedbackIterations ?? 5
3557
+ });
3558
+ return g;
3559
+ }
3560
+ function issueTrackerGraph(name, opts) {
3561
+ const g = new Graph(name, opts);
3562
+ g.add("source", opts.source);
3563
+ let _issueCounter = 0;
3564
+ const defaultExtract = (raw) => ({
3565
+ id: `issue-${++_issueCounter}`,
3566
+ title: String(raw),
3567
+ severity: 1,
3568
+ source: "unknown",
3569
+ raw
3570
+ });
3571
+ const extractFn = opts.extract ?? defaultExtract;
3572
+ const extractNode = derived([opts.source], (vals) => extractFn(vals[0]), {
3573
+ meta: baseMeta2("issue_tracker", { stage: "extract" })
3574
+ });
3575
+ g.add("extract", extractNode);
3576
+ g.connect("source", "extract");
3577
+ const verifyFn = opts.verify ?? (() => ({ valid: true }));
3578
+ const verifyNode = derived(
3579
+ [extractNode],
3580
+ (vals) => {
3581
+ const issue = vals[0];
3582
+ return { issue, verification: verifyFn(issue) };
3583
+ },
3584
+ {
3585
+ meta: baseMeta2("issue_tracker", { stage: "verify" })
3586
+ }
3587
+ );
3588
+ g.add("verify", verifyNode);
3589
+ g.connect("extract", "verify");
3590
+ const knownPatterns = state([], {
3591
+ meta: baseMeta2("issue_tracker", { stage: "known_patterns" })
3592
+ });
3593
+ g.add("known_patterns", knownPatterns);
3594
+ const detectFn = opts.detectRegression ?? (() => ({ regression: false }));
3595
+ const regressionNode = derived(
3596
+ [extractNode, knownPatterns],
3597
+ (vals) => {
3598
+ const issue = vals[0];
3599
+ const known = vals[1];
3600
+ return { issue, regression: detectFn(issue, known) };
3601
+ },
3602
+ { meta: baseMeta2("issue_tracker", { stage: "regression" }) }
3603
+ );
3604
+ g.add("regression", regressionNode);
3605
+ g.connect("extract", "regression");
3606
+ g.connect("known_patterns", "regression");
3607
+ const severitySignal = derived([extractNode], (vals) => {
3608
+ const issue = vals[0];
3609
+ return issue?.severity ?? 0;
3610
+ });
3611
+ const regressionSignal = derived([regressionNode], (vals) => {
3612
+ const r = vals[0];
3613
+ return r?.regression ? 2 : 0;
3614
+ });
3615
+ g.add("__severity_signal", severitySignal);
3616
+ g.add("__regression_signal", regressionSignal);
3617
+ const severityWeight = state(1);
3618
+ const regressionWeight = state(1.5);
3619
+ g.add("__severity_weight", severityWeight);
3620
+ g.add("__regression_weight", regressionWeight);
3621
+ const priority = scorer([severitySignal, regressionSignal], [severityWeight, regressionWeight]);
3622
+ g.add("priority", priority);
3623
+ const output = derived(
3624
+ [verifyNode, regressionNode, priority],
3625
+ (vals) => ({
3626
+ verified: vals[0],
3627
+ regression: vals[1],
3628
+ priority: vals[2]
3629
+ }),
3630
+ { meta: baseMeta2("issue_tracker", { stage: "output" }) }
3631
+ );
3632
+ g.add("output", output);
3633
+ g.connect("verify", "output");
3634
+ g.connect("regression", "output");
3635
+ g.connect("priority", "output");
3636
+ const fbReentry = state(null, {
3637
+ meta: baseMeta2("issue_tracker", { stage: "feedback_reentry" })
3638
+ });
3639
+ g.add("feedback_reentry", fbReentry);
3640
+ const fbCondition = derived(
3641
+ [verifyNode],
3642
+ (vals) => {
3643
+ const result = vals[0];
3644
+ if (result) {
3645
+ const v = result.verification;
3646
+ if (v && v.valid === false) return result;
3647
+ }
3648
+ return null;
3649
+ },
3650
+ {
3651
+ meta: baseMeta2("issue_tracker", { stage: "feedback_condition" })
3652
+ }
3653
+ );
3654
+ g.add("feedback_condition", fbCondition);
3655
+ g.connect("verify", "feedback_condition");
3656
+ feedback(g, "feedback_condition", "feedback_reentry", {
3657
+ maxIterations: opts.maxFeedbackIterations ?? 3
3658
+ });
3659
+ return g;
3660
+ }
3661
+ function contentModerationGraph(name, opts) {
3662
+ const g = new Graph(name, opts);
3663
+ g.add("source", opts.source);
3664
+ const defaultClassify = (content) => ({
3665
+ label: "review",
3666
+ confidence: 0.5,
3667
+ original: content
3668
+ });
3669
+ const classifyFn = opts.classify ?? defaultClassify;
3670
+ const classifyNode = derived([opts.source], (vals) => classifyFn(vals[0]), {
3671
+ meta: baseMeta2("content_moderation", { stage: "classify" })
3672
+ });
3673
+ g.add("classify", classifyNode);
3674
+ g.connect("source", "classify");
3675
+ const strat = stratify("stratify", classifyNode, [
3676
+ { name: "safe", classify: (v) => v.label === "safe" },
3677
+ { name: "review", classify: (v) => v.label === "review" },
3678
+ { name: "block", classify: (v) => v.label === "block" }
3679
+ ]);
3680
+ g.mount("stratify", strat);
3681
+ const reviewLog = reactiveLog([], {
3682
+ name: "review_queue",
3683
+ maxSize: opts.maxQueueSize
3684
+ });
3685
+ g.add("review_queue", reviewLog.entries);
3686
+ let reviewBranch;
3687
+ try {
3688
+ reviewBranch = g.resolve("stratify::branch/review");
3689
+ } catch {
3690
+ reviewBranch = state(null);
3691
+ g.add("__review_fallback", reviewBranch);
3692
+ }
3693
+ const reviewAccumulator = effect([reviewBranch], (vals) => {
3694
+ const item = vals[0];
3695
+ if (item) {
3696
+ reviewLog.append(item);
3697
+ }
3698
+ });
3699
+ g.add("__review_accumulator", reviewAccumulator);
3700
+ keepalive3(reviewAccumulator);
3701
+ try {
3702
+ g.connect("stratify::branch/review", "__review_accumulator");
3703
+ } catch {
3704
+ }
3705
+ const policy2 = state(
3706
+ {},
3707
+ {
3708
+ meta: baseMeta2("content_moderation", {
3709
+ stage: "policy",
3710
+ access: "both",
3711
+ description: "Moderation policy rules \u2014 updated via feedback"
3712
+ })
3713
+ }
3714
+ );
3715
+ g.add("policy", policy2);
3716
+ const weights = opts.weights ?? [0.1, 1, 2];
3717
+ const confidenceSignal = derived([classifyNode], (vals) => {
3718
+ const r = vals[0];
3719
+ return r?.confidence ?? 0;
3720
+ });
3721
+ const severitySignal = derived([classifyNode], (vals) => {
3722
+ const r = vals[0];
3723
+ if (!r) return 0;
3724
+ return r.label === "block" ? weights[2] : r.label === "review" ? weights[1] : weights[0];
3725
+ });
3726
+ g.add("__confidence_signal", confidenceSignal);
3727
+ g.add("__severity_signal", severitySignal);
3728
+ const wConfidence = state(1);
3729
+ const wSeverity = state(1);
3730
+ g.add("__w_confidence", wConfidence);
3731
+ g.add("__w_severity", wSeverity);
3732
+ const priority = scorer([confidenceSignal, severitySignal], [wConfidence, wSeverity]);
3733
+ g.add("priority", priority);
3734
+ const output = derived(
3735
+ [classifyNode, priority],
3736
+ (vals) => ({
3737
+ classification: vals[0],
3738
+ priority: vals[1]
3739
+ }),
3740
+ { meta: baseMeta2("content_moderation", { stage: "output" }) }
3741
+ );
3742
+ g.add("output", output);
3743
+ g.connect("classify", "output");
3744
+ g.connect("priority", "output");
3745
+ const fbCondition = derived(
3746
+ [reviewLog.entries, policy2],
3747
+ (vals) => {
3748
+ const snap = vals[0];
3749
+ const entries = snap?.value?.entries;
3750
+ if (entries && entries.length > 0) {
3751
+ const latest = entries[entries.length - 1];
3752
+ if (latest && latest.falsePositive) {
3753
+ return latest;
3754
+ }
3755
+ }
3756
+ return null;
3757
+ },
3758
+ {
3759
+ meta: baseMeta2("content_moderation", { stage: "feedback_condition" })
3760
+ }
3761
+ );
3762
+ g.add("feedback_condition", fbCondition);
3763
+ feedback(g, "feedback_condition", "policy", {
3764
+ maxIterations: opts.maxFeedbackIterations ?? 5
3765
+ });
3766
+ return g;
3767
+ }
3768
+ function dataQualityGraph(name, opts) {
3769
+ const g = new Graph(name, opts);
3770
+ g.add("source", opts.source);
3771
+ const validateFn = opts.validate ?? ((record) => ({
3772
+ valid: true,
3773
+ errors: [],
3774
+ record
3775
+ }));
3776
+ const validateNode = derived(
3777
+ [opts.source],
3778
+ (vals) => vals[0] != null ? validateFn(vals[0]) : void 0,
3779
+ { meta: baseMeta2("data_quality", { stage: "validate" }) }
3780
+ );
3781
+ g.add("validate", validateNode);
3782
+ g.connect("source", "validate");
3783
+ const detectAnomalyFn = opts.detectAnomaly ?? ((record) => ({
3784
+ anomaly: false,
3785
+ score: 0,
3786
+ record
3787
+ }));
3788
+ const anomalyNode = derived(
3789
+ [opts.source],
3790
+ (vals) => vals[0] != null ? detectAnomalyFn(vals[0]) : void 0,
3791
+ { meta: baseMeta2("data_quality", { stage: "anomaly" }) }
3792
+ );
3793
+ g.add("anomaly", anomalyNode);
3794
+ g.connect("source", "anomaly");
3795
+ const baseline = state(null, {
3796
+ meta: baseMeta2("data_quality", {
3797
+ stage: "baseline",
3798
+ description: "Rolling baseline for drift detection"
3799
+ })
3800
+ });
3801
+ g.add("baseline", baseline);
3802
+ const baselineUpdater = effect([validateNode], (vals) => {
3803
+ const result = vals[0];
3804
+ if (result?.valid) {
3805
+ batch(() => {
3806
+ baseline.down([[DATA, result.record]]);
3807
+ });
3808
+ }
3809
+ });
3810
+ g.add("__baseline_updater", baselineUpdater);
3811
+ g.connect("validate", "__baseline_updater");
3812
+ keepalive3(baselineUpdater);
3813
+ const detectDriftFn = opts.detectDrift ?? (() => ({ drift: false }));
3814
+ const driftNode = derived(
3815
+ [opts.source, baseline],
3816
+ (vals) => detectDriftFn(vals[0], vals[1]),
3817
+ { meta: baseMeta2("data_quality", { stage: "drift" }) }
3818
+ );
3819
+ g.add("drift", driftNode);
3820
+ g.connect("source", "drift");
3821
+ g.connect("baseline", "drift");
3822
+ const suggestFn = opts.suggest ?? (() => null);
3823
+ const remediateNode = derived(
3824
+ [validateNode, anomalyNode],
3825
+ (vals) => suggestFn({
3826
+ validation: vals[0],
3827
+ anomaly: vals[1]
3828
+ }),
3829
+ { meta: baseMeta2("data_quality", { stage: "remediate" }) }
3830
+ );
3831
+ g.add("remediate", remediateNode);
3832
+ g.connect("validate", "remediate");
3833
+ g.connect("anomaly", "remediate");
3834
+ const output = derived(
3835
+ [validateNode, anomalyNode, driftNode, remediateNode],
3836
+ (vals) => ({
3837
+ validation: vals[0],
3838
+ anomaly: vals[1],
3839
+ drift: vals[2],
3840
+ remediation: vals[3]
3841
+ }),
3842
+ { meta: baseMeta2("data_quality", { stage: "output" }) }
3843
+ );
3844
+ g.add("output", output);
3845
+ g.connect("validate", "output");
3846
+ g.connect("anomaly", "output");
3847
+ g.connect("drift", "output");
3848
+ g.connect("remediate", "output");
3849
+ const validationRules = state([], {
3850
+ meta: baseMeta2("data_quality", { stage: "validation_rules" })
3851
+ });
3852
+ g.add("validation_rules", validationRules);
3853
+ const fbCondition = derived(
3854
+ [anomalyNode],
3855
+ (vals) => {
3856
+ const a = vals[0];
3857
+ if (a?.anomaly) return a;
3858
+ return null;
3859
+ },
3860
+ {
3861
+ meta: baseMeta2("data_quality", { stage: "feedback_condition" })
3862
+ }
3863
+ );
3864
+ g.add("feedback_condition", fbCondition);
3865
+ g.connect("anomaly", "feedback_condition");
3866
+ feedback(g, "feedback_condition", "validation_rules", {
3867
+ maxIterations: opts.maxFeedbackIterations ?? 3
3868
+ });
3869
+ return g;
3870
+ }
3871
+ function isTagged(value, tag) {
3872
+ if (value == null || typeof value !== "object") return false;
3873
+ const v = value;
3874
+ return v.type === tag || v.kind === tag;
3875
+ }
3876
+
3342
3877
  // src/patterns/graphspec.ts
3878
+ var graphspec_exports = {};
3879
+ __export(graphspec_exports, {
3880
+ compileSpec: () => compileSpec,
3881
+ decompileGraph: () => decompileGraph,
3882
+ extractFnFactory: () => extractFnFactory,
3883
+ extractSourceFactory: () => extractSourceFactory,
3884
+ generateCatalogPrompt: () => generateCatalogPrompt,
3885
+ isRichFnEntry: () => isRichFnEntry,
3886
+ isRichSourceEntry: () => isRichSourceEntry,
3887
+ llmCompose: () => llmCompose,
3888
+ llmRefine: () => llmRefine,
3889
+ specDiff: () => specDiff,
3890
+ validateSpec: () => validateSpec,
3891
+ validateSpecAgainstCatalog: () => validateSpecAgainstCatalog
3892
+ });
3893
+ function isRichFnEntry(entry) {
3894
+ return typeof entry === "object" && entry !== null && "factory" in entry;
3895
+ }
3896
+ function isRichSourceEntry(entry) {
3897
+ return typeof entry === "object" && entry !== null && "factory" in entry;
3898
+ }
3899
+ function extractFnFactory(entry) {
3900
+ return isRichFnEntry(entry) ? entry.factory : entry;
3901
+ }
3902
+ function extractSourceFactory(entry) {
3903
+ return isRichSourceEntry(entry) ? entry.factory : entry;
3904
+ }
3905
+ function generateCatalogPrompt(catalog) {
3906
+ const sections = [];
3907
+ if (catalog.fns) {
3908
+ const groups = /* @__PURE__ */ new Map();
3909
+ for (const [name, entry] of Object.entries(catalog.fns)) {
3910
+ const tag = isRichFnEntry(entry) ? entry.tags?.[0] ?? "Other" : "Other";
3911
+ if (!groups.has(tag)) groups.set(tag, []);
3912
+ groups.get(tag).push(formatFnEntry(name, entry));
3913
+ }
3914
+ for (const [tag, lines] of groups) {
3915
+ sections.push(`${tag}:
3916
+ ${lines.join("\n")}`);
3917
+ }
3918
+ }
3919
+ if (catalog.sources) {
3920
+ const lines = [];
3921
+ for (const [name, entry] of Object.entries(catalog.sources)) {
3922
+ lines.push(formatSourceEntry(name, entry));
3923
+ }
3924
+ if (lines.length > 0) {
3925
+ sections.push(`Sources:
3926
+ ${lines.join("\n")}`);
3927
+ }
3928
+ }
3929
+ return sections.join("\n\n");
3930
+ }
3931
+ function formatFnEntry(name, entry) {
3932
+ if (!isRichFnEntry(entry)) return `- ${name}`;
3933
+ let line = `- ${name}: ${entry.description}`;
3934
+ if (entry.configSchema) {
3935
+ const fields = Object.entries(entry.configSchema).map(([k, v]) => {
3936
+ let desc = `${k}: ${v.type}`;
3937
+ if (v.enum) desc += ` (${v.enum.join("|")})`;
3938
+ if (v.required === false) desc += "?";
3939
+ return desc;
3940
+ });
3941
+ line += `. Config: { ${fields.join(", ")} }`;
3942
+ }
3943
+ return line;
3944
+ }
3945
+ function formatSourceEntry(name, entry) {
3946
+ if (!isRichSourceEntry(entry)) return `- ${name}`;
3947
+ let line = `- ${name}: ${entry.description}`;
3948
+ if (entry.configSchema) {
3949
+ const fields = Object.entries(entry.configSchema).map(([k, v]) => {
3950
+ let desc = `${k}: ${v.type}`;
3951
+ if (v.required === false) desc += "?";
3952
+ return desc;
3953
+ });
3954
+ line += `. Config: { ${fields.join(", ")} }`;
3955
+ }
3956
+ return line;
3957
+ }
3958
+ function validateSpecAgainstCatalog(spec, catalog) {
3959
+ const errors = [];
3960
+ const fnNames = new Set(Object.keys(catalog.fns ?? {}));
3961
+ const sourceNames = new Set(Object.keys(catalog.sources ?? {}));
3962
+ for (const [nodeName, nodeRaw] of Object.entries(spec.nodes)) {
3963
+ if (nodeRaw.type === "template") continue;
3964
+ const node2 = nodeRaw;
3965
+ if (node2.fn && fnNames.size > 0 && !fnNames.has(node2.fn)) {
3966
+ if (sourceNames.has(node2.fn)) {
3967
+ errors.push(
3968
+ `Node "${nodeName}": fn "${node2.fn}" is a source, not a function. Use it as a producer source instead, or use a function from: ${[...fnNames].join(", ")}`
3969
+ );
3970
+ } else {
3971
+ const suggestion = findClosest(node2.fn, fnNames);
3972
+ errors.push(
3973
+ `Node "${nodeName}": fn "${node2.fn}" not found in catalog` + (suggestion ? `. Did you mean "${suggestion}"?` : "")
3974
+ );
3975
+ }
3976
+ }
3977
+ if (node2.source && sourceNames.size > 0 && !sourceNames.has(node2.source)) {
3978
+ if (fnNames.has(node2.source)) {
3979
+ errors.push(
3980
+ `Node "${nodeName}": source "${node2.source}" is a function, not a source. Use it as fn instead, or use a source from: ${[...sourceNames].join(", ")}`
3981
+ );
3982
+ } else {
3983
+ const suggestion = findClosest(node2.source, sourceNames);
3984
+ errors.push(
3985
+ `Node "${nodeName}": source "${node2.source}" not found in catalog` + (suggestion ? `. Did you mean "${suggestion}"?` : "")
3986
+ );
3987
+ }
3988
+ }
3989
+ if (node2.fn && node2.config && catalog.fns?.[node2.fn]) {
3990
+ const entry = catalog.fns[node2.fn];
3991
+ if (isRichFnEntry(entry) && entry.configSchema) {
3992
+ for (const [field, schema] of Object.entries(entry.configSchema)) {
3993
+ if (schema.required !== false && !(field in node2.config)) {
3994
+ errors.push(`Node "${nodeName}": config missing required field "${field}"`);
3995
+ }
3996
+ if (field in node2.config && schema.enum) {
3997
+ const val = node2.config[field];
3998
+ if (!schema.enum.includes(val)) {
3999
+ errors.push(
4000
+ `Node "${nodeName}": config.${field} = ${JSON.stringify(val)}, expected one of: ${schema.enum.join(", ")}`
4001
+ );
4002
+ }
4003
+ }
4004
+ }
4005
+ }
4006
+ }
4007
+ }
4008
+ if (spec.templates) {
4009
+ for (const [tName, template] of Object.entries(spec.templates)) {
4010
+ for (const [nodeName, node2] of Object.entries(template.nodes)) {
4011
+ if (node2.fn && fnNames.size > 0 && !fnNames.has(node2.fn)) {
4012
+ const suggestion = findClosest(node2.fn, fnNames);
4013
+ errors.push(
4014
+ `Template "${tName}" node "${nodeName}": fn "${node2.fn}" not found in catalog` + (suggestion ? `. Did you mean "${suggestion}"?` : "")
4015
+ );
4016
+ }
4017
+ }
4018
+ }
4019
+ }
4020
+ return { valid: errors.length === 0, errors };
4021
+ }
4022
+ function findClosest(input, candidates) {
4023
+ let best = null;
4024
+ let bestDist = Infinity;
4025
+ const lower = input.toLowerCase();
4026
+ for (const c of candidates) {
4027
+ const dist = levenshtein(lower, c.toLowerCase());
4028
+ if (dist < bestDist && dist <= Math.max(3, Math.floor(input.length / 2))) {
4029
+ bestDist = dist;
4030
+ best = c;
4031
+ }
4032
+ }
4033
+ return best;
4034
+ }
4035
+ function levenshtein(a, b) {
4036
+ const m = a.length;
4037
+ const n = b.length;
4038
+ const dp = Array.from(
4039
+ { length: m + 1 },
4040
+ (_, i) => Array.from({ length: n + 1 }, (_2, j) => i === 0 ? j : j === 0 ? i : 0)
4041
+ );
4042
+ for (let i = 1; i <= m; i++) {
4043
+ for (let j = 1; j <= n; j++) {
4044
+ dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
4045
+ }
4046
+ }
4047
+ return dp[m][n];
4048
+ }
3343
4049
  var VALID_NODE_TYPES2 = /* @__PURE__ */ new Set([
3344
4050
  "state",
3345
4051
  "producer",
@@ -3516,6 +4222,21 @@ ${validation.errors.join("\n")}`);
3516
4222
  const catalog = opts?.catalog ?? {};
3517
4223
  const g = new Graph(spec.name);
3518
4224
  const templates = spec.templates ?? {};
4225
+ const catalogValidation = validateSpecAgainstCatalog(spec, catalog);
4226
+ if (!catalogValidation.valid) {
4227
+ throw new Error(
4228
+ `compileSpec: catalog validation errors:
4229
+ ${catalogValidation.errors.join("\n")}`
4230
+ );
4231
+ }
4232
+ const resolveFn = (fnName) => {
4233
+ const entry = catalog.fns?.[fnName];
4234
+ return entry ? extractFnFactory(entry) : void 0;
4235
+ };
4236
+ const resolveSource = (sourceName) => {
4237
+ const entry = catalog.sources?.[sourceName];
4238
+ return entry ? extractSourceFactory(entry) : void 0;
4239
+ };
3519
4240
  const created = /* @__PURE__ */ new Map();
3520
4241
  const deferred = [];
3521
4242
  for (const [name, raw] of Object.entries(spec.nodes)) {
@@ -3529,8 +4250,8 @@ ${validation.errors.join("\n")}`);
3529
4250
  g.add(name, nd);
3530
4251
  created.set(name, nd);
3531
4252
  } else if (n.type === "producer") {
3532
- const sourceFactory = n.source ? catalog.sources?.[n.source] : void 0;
3533
- const fnFactory = n.fn ? catalog.fns?.[n.fn] : void 0;
4253
+ const sourceFactory = n.source ? resolveSource(n.source) : void 0;
4254
+ const fnFactory = n.fn ? resolveFn(n.fn) : void 0;
3534
4255
  if (sourceFactory) {
3535
4256
  const nd = sourceFactory(n.config ?? {});
3536
4257
  g.add(name, nd);
@@ -3560,7 +4281,7 @@ ${validation.errors.join("\n")}`);
3560
4281
  const deps = n.deps ?? [];
3561
4282
  if (!deps.every((dep) => created.has(dep))) continue;
3562
4283
  const resolvedDeps = deps.map((dep) => created.get(dep));
3563
- const fnFactory = n.fn ? catalog.fns?.[n.fn] : void 0;
4284
+ const fnFactory = n.fn ? resolveFn(n.fn) : void 0;
3564
4285
  let nd;
3565
4286
  if (fnFactory) {
3566
4287
  nd = fnFactory(resolvedDeps, n.config ?? {});
@@ -3603,8 +4324,8 @@ ${validation.errors.join("\n")}`);
3603
4324
  sub.add(nName, nd);
3604
4325
  subCreated.set(nName, nd);
3605
4326
  } else if (nSpec.type === "producer") {
3606
- const sourceFactory = nSpec.source ? catalog.sources?.[nSpec.source] : void 0;
3607
- const fnFactory = nSpec.fn ? catalog.fns?.[nSpec.fn] : void 0;
4327
+ const sourceFactory = nSpec.source ? resolveSource(nSpec.source) : void 0;
4328
+ const fnFactory = nSpec.fn ? resolveFn(nSpec.fn) : void 0;
3608
4329
  if (sourceFactory) {
3609
4330
  const nd = sourceFactory(nSpec.config ?? {});
3610
4331
  sub.add(nName, nd);
@@ -3635,7 +4356,7 @@ ${validation.errors.join("\n")}`);
3635
4356
  const allReady = deps.every((dep) => subCreated.has(dep) || created.has(dep));
3636
4357
  if (!allReady) continue;
3637
4358
  const resolvedDeps = deps.map((dep) => subCreated.get(dep) ?? created.get(dep));
3638
- const fnFactory = nSpec.fn ? catalog.fns?.[nSpec.fn] : void 0;
4359
+ const fnFactory = nSpec.fn ? resolveFn(nSpec.fn) : void 0;
3639
4360
  let nd;
3640
4361
  if (fnFactory) {
3641
4362
  nd = fnFactory(resolvedDeps, nSpec.config ?? {});
@@ -3696,14 +4417,15 @@ var INTERNAL_META_KEYS = /* @__PURE__ */ new Set([
3696
4417
  "_templateName",
3697
4418
  "_templateBind",
3698
4419
  "feedbackFrom",
3699
- "feedbackTo"
4420
+ "feedbackTo",
4421
+ "_internal"
3700
4422
  ]);
3701
4423
  function decompileGraph(graph) {
3702
4424
  const desc = graph.describe({ detail: "standard" });
3703
4425
  const nodes = {};
3704
4426
  const feedbackEdges = [];
3705
4427
  const metaSegment = `::${GRAPH_META_SEGMENT}::`;
3706
- const feedbackCounterPattern = /^__feedback_(.+)$/;
4428
+ const feedbackCounterPattern = /^__feedback_(?!effect_)(.+)$/;
3707
4429
  const feedbackConditions = /* @__PURE__ */ new Set();
3708
4430
  for (const path of Object.keys(desc.nodes)) {
3709
4431
  if (path.includes(metaSegment)) continue;
@@ -3723,6 +4445,9 @@ function decompileGraph(graph) {
3723
4445
  for (const [path, nodeDesc] of Object.entries(desc.nodes)) {
3724
4446
  if (path.includes(metaSegment)) continue;
3725
4447
  if (feedbackCounterPattern.test(path)) continue;
4448
+ if (nodeDesc.meta?._internal) continue;
4449
+ if (path.startsWith("__feedback_effect_")) continue;
4450
+ if (path.startsWith("__bridge_")) continue;
3726
4451
  if (path.includes("::")) continue;
3727
4452
  const specNode = {
3728
4453
  type: nodeDesc.type
@@ -4055,11 +4780,12 @@ function stripFences2(text) {
4055
4780
  }
4056
4781
  async function llmCompose(problem, adapter, opts) {
4057
4782
  let systemPrompt = LLM_COMPOSE_SYSTEM_PROMPT;
4058
- if (opts?.catalogDescription) {
4783
+ const catalogPrompt = opts?.catalogDescription ?? (opts?.catalog ? generateCatalogPrompt(opts.catalog) : void 0);
4784
+ if (catalogPrompt) {
4059
4785
  systemPrompt += `
4060
4786
 
4061
- Available catalog:
4062
- ${opts.catalogDescription}`;
4787
+ Available catalog (use ONLY these names):
4788
+ ${catalogPrompt}`;
4063
4789
  }
4064
4790
  if (opts?.systemPromptExtra) {
4065
4791
  systemPrompt += `
@@ -4091,7 +4817,30 @@ ${opts.systemPromptExtra}`;
4091
4817
  throw new Error(`llmCompose: invalid GraphSpec:
4092
4818
  ${validation.errors.join("\n")}`);
4093
4819
  }
4094
- return parsed;
4820
+ let spec = parsed;
4821
+ if (opts?.catalog) {
4822
+ const maxRefine = opts.maxAutoRefine ?? 0;
4823
+ for (let attempt = 0; attempt <= maxRefine; attempt++) {
4824
+ const catalogValidation = validateSpecAgainstCatalog(spec, opts.catalog);
4825
+ if (catalogValidation.valid) break;
4826
+ if (attempt === maxRefine) {
4827
+ throw new Error(
4828
+ `llmCompose: catalog validation failed after ${maxRefine} refine attempts:
4829
+ ${catalogValidation.errors.join("\n")}`
4830
+ );
4831
+ }
4832
+ spec = await llmRefine(
4833
+ spec,
4834
+ `Fix these catalog errors:
4835
+ ${catalogValidation.errors.join("\n")}
4836
+
4837
+ Use ONLY functions and sources from the catalog.`,
4838
+ adapter,
4839
+ { ...opts, catalogDescription: catalogPrompt }
4840
+ );
4841
+ }
4842
+ }
4843
+ return spec;
4095
4844
  }
4096
4845
  async function llmRefine(currentSpec, feedback2, adapter, opts) {
4097
4846
  let systemPrompt = LLM_COMPOSE_SYSTEM_PROMPT;
@@ -4163,7 +4912,7 @@ function requireNonNegativeInt(value, label) {
4163
4912
  }
4164
4913
  return value;
4165
4914
  }
4166
- function keepalive2(n) {
4915
+ function keepalive4(n) {
4167
4916
  return n.subscribe(() => {
4168
4917
  });
4169
4918
  }
@@ -4199,7 +4948,7 @@ var TopicGraph = class extends Graph {
4199
4948
  );
4200
4949
  this.add("latest", this.latest);
4201
4950
  this.connect("events", "latest");
4202
- this._keepaliveDisposers.push(keepalive2(this.latest));
4951
+ this._keepaliveDisposers.push(keepalive4(this.latest));
4203
4952
  }
4204
4953
  destroy() {
4205
4954
  for (const dispose of this._keepaliveDisposers) dispose();
@@ -4255,8 +5004,8 @@ var SubscriptionGraph = class extends Graph {
4255
5004
  this.connect("topic::events", "source");
4256
5005
  this.connect("source", "available");
4257
5006
  this.connect("cursor", "available");
4258
- this._keepaliveDisposers.push(keepalive2(this.source));
4259
- this._keepaliveDisposers.push(keepalive2(this.available));
5007
+ this._keepaliveDisposers.push(keepalive4(this.source));
5008
+ this._keepaliveDisposers.push(keepalive4(this.available));
4260
5009
  }
4261
5010
  destroy() {
4262
5011
  for (const dispose of this._keepaliveDisposers) dispose();
@@ -4308,7 +5057,7 @@ var JobQueueGraph = class extends Graph {
4308
5057
  );
4309
5058
  this.add("depth", this.depth);
4310
5059
  this.connect("pending", "depth");
4311
- this._keepaliveDisposers.push(keepalive2(this.depth));
5060
+ this._keepaliveDisposers.push(keepalive4(this.depth));
4312
5061
  }
4313
5062
  destroy() {
4314
5063
  for (const dispose of this._keepaliveDisposers) dispose();
@@ -4408,7 +5157,7 @@ var JobFlowGraph = class extends Graph {
4408
5157
  );
4409
5158
  this.add("completedCount", this.completedCount);
4410
5159
  this.connect("completed", "completedCount");
4411
- this._keepaliveDisposers.push(keepalive2(this.completedCount));
5160
+ this._keepaliveDisposers.push(keepalive4(this.completedCount));
4412
5161
  const maxPerPump = Math.max(
4413
5162
  1,
4414
5163
  requireNonNegativeInt(opts.maxPerPump ?? DEFAULT_MAX_PER_PUMP, "job flow maxPerPump")
@@ -4448,7 +5197,7 @@ var JobFlowGraph = class extends Graph {
4448
5197
  );
4449
5198
  this.add(`pump_${stage}`, pump);
4450
5199
  this.connect(`${stage}::pending`, `pump_${stage}`);
4451
- this._keepaliveDisposers.push(keepalive2(pump));
5200
+ this._keepaliveDisposers.push(keepalive4(pump));
4452
5201
  }
4453
5202
  }
4454
5203
  destroy() {
@@ -4520,7 +5269,7 @@ var TopicBridgeGraph = class extends Graph {
4520
5269
  );
4521
5270
  this.add("pump", pump);
4522
5271
  this.connect("subscription::available", "pump");
4523
- this._keepaliveDisposers.push(keepalive2(pump));
5272
+ this._keepaliveDisposers.push(keepalive4(pump));
4524
5273
  }
4525
5274
  destroy() {
4526
5275
  for (const dispose of this._keepaliveDisposers) dispose();
@@ -4550,7 +5299,7 @@ __export(orchestration_exports, {
4550
5299
  approval: () => approval,
4551
5300
  branch: () => branch,
4552
5301
  forEach: () => forEach2,
4553
- gate: () => gate2,
5302
+ gate: () => gate,
4554
5303
  join: () => join,
4555
5304
  loop: () => loop,
4556
5305
  onFailure: () => onFailure,
@@ -4558,6 +5307,7 @@ __export(orchestration_exports, {
4558
5307
  sensor: () => sensor,
4559
5308
  subPipeline: () => subPipeline,
4560
5309
  task: () => task,
5310
+ valve: () => valve2,
4561
5311
  wait: () => wait
4562
5312
  });
4563
5313
  function resolveDep(graph, dep) {
@@ -4590,7 +5340,7 @@ function registerStep(graph, name, step, depPaths) {
4590
5340
  graph.connect(path, name);
4591
5341
  }
4592
5342
  }
4593
- function baseMeta2(kind, meta) {
5343
+ function baseMeta3(kind, meta) {
4594
5344
  return {
4595
5345
  orchestration: true,
4596
5346
  orchestration_type: kind,
@@ -4628,7 +5378,7 @@ function task(graph, name, run, opts) {
4628
5378
  ...nodeOpts,
4629
5379
  name,
4630
5380
  describeKind: "derived",
4631
- meta: baseMeta2("task", opts?.meta)
5381
+ meta: baseMeta3("task", opts?.meta)
4632
5382
  }
4633
5383
  );
4634
5384
  registerStep(
@@ -4651,13 +5401,13 @@ function branch(graph, name, source, predicate, opts) {
4651
5401
  ...opts,
4652
5402
  name,
4653
5403
  describeKind: "derived",
4654
- meta: baseMeta2("branch", opts?.meta)
5404
+ meta: baseMeta3("branch", opts?.meta)
4655
5405
  }
4656
5406
  );
4657
5407
  registerStep(graph, name, step, src.path ? [src.path] : []);
4658
5408
  return step;
4659
5409
  }
4660
- function gate2(graph, name, source, control, opts) {
5410
+ function valve2(graph, name, source, control, opts) {
4661
5411
  const src = resolveDep(graph, source);
4662
5412
  const ctrl = resolveDep(graph, control);
4663
5413
  const step = node(
@@ -4674,7 +5424,7 @@ function gate2(graph, name, source, control, opts) {
4674
5424
  ...opts,
4675
5425
  name,
4676
5426
  describeKind: "operator",
4677
- meta: baseMeta2("gate", opts?.meta)
5427
+ meta: baseMeta3("valve", opts?.meta)
4678
5428
  }
4679
5429
  );
4680
5430
  registerStep(
@@ -4702,7 +5452,7 @@ function approval(graph, name, source, approver, opts) {
4702
5452
  ...opts,
4703
5453
  name,
4704
5454
  describeKind: "operator",
4705
- meta: baseMeta2("approval", opts?.meta)
5455
+ meta: baseMeta3("approval", opts?.meta)
4706
5456
  }
4707
5457
  );
4708
5458
  registerStep(
@@ -4713,6 +5463,119 @@ function approval(graph, name, source, approver, opts) {
4713
5463
  );
4714
5464
  return step;
4715
5465
  }
5466
+ function gate(graph, name, source, opts) {
5467
+ const maxPending = opts?.maxPending ?? Infinity;
5468
+ if (maxPending < 1 && maxPending !== Infinity) {
5469
+ throw new RangeError("gate: maxPending must be >= 1");
5470
+ }
5471
+ const startOpen = opts?.startOpen ?? false;
5472
+ const src = resolveDep(graph, source);
5473
+ const pendingNode = state([], { name: "pending", equals: () => false });
5474
+ const isOpenNode = state(startOpen, { name: "isOpen" });
5475
+ const countNode = node([pendingNode], ([arr]) => arr.length, {
5476
+ name: "count",
5477
+ describeKind: "derived"
5478
+ });
5479
+ let queue = [];
5480
+ let torn = false;
5481
+ function syncPending() {
5482
+ pendingNode.down([[DATA, [...queue]]]);
5483
+ }
5484
+ function enqueue(value) {
5485
+ queue.push(value);
5486
+ if (queue.length > maxPending) queue.shift();
5487
+ syncPending();
5488
+ }
5489
+ function dequeue(n) {
5490
+ const items = queue.splice(0, n);
5491
+ syncPending();
5492
+ return items;
5493
+ }
5494
+ function guardTorn(method) {
5495
+ if (torn) throw new Error(`gate: ${method}() called after gate was torn down`);
5496
+ }
5497
+ const output = node([src.node], () => void 0, {
5498
+ name,
5499
+ describeKind: "operator",
5500
+ meta: baseMeta3("gate", opts?.meta),
5501
+ onMessage(msg, _depIndex, actions) {
5502
+ if (msg[0] === DATA) {
5503
+ if (isOpenNode.get()) {
5504
+ actions.emit(msg[1]);
5505
+ } else {
5506
+ enqueue(msg[1]);
5507
+ actions.down([[RESOLVED]]);
5508
+ }
5509
+ return true;
5510
+ }
5511
+ if (msg[0] === TEARDOWN) {
5512
+ torn = true;
5513
+ queue = [];
5514
+ syncPending();
5515
+ actions.down([msg]);
5516
+ return true;
5517
+ }
5518
+ if (msg[0] === COMPLETE || msg[0] === ERROR) {
5519
+ torn = true;
5520
+ queue = [];
5521
+ syncPending();
5522
+ actions.down([msg]);
5523
+ return true;
5524
+ }
5525
+ actions.down([msg]);
5526
+ return true;
5527
+ }
5528
+ });
5529
+ const controller = {
5530
+ node: output,
5531
+ pending: pendingNode,
5532
+ count: countNode,
5533
+ isOpen: isOpenNode,
5534
+ approve(count = 1) {
5535
+ guardTorn("approve");
5536
+ const items = dequeue(count);
5537
+ for (const item of items) {
5538
+ if (torn) break;
5539
+ output.down([[DATA, item]]);
5540
+ }
5541
+ },
5542
+ reject(count = 1) {
5543
+ guardTorn("reject");
5544
+ dequeue(count);
5545
+ },
5546
+ modify(fn, count = 1) {
5547
+ guardTorn("modify");
5548
+ const snapshot = [...queue];
5549
+ const items = dequeue(count);
5550
+ for (let i = 0; i < items.length; i++) {
5551
+ if (torn) break;
5552
+ output.down([[DATA, fn(items[i], i, snapshot)]]);
5553
+ }
5554
+ },
5555
+ open() {
5556
+ guardTorn("open");
5557
+ isOpenNode.down([[DATA, true]]);
5558
+ const items = dequeue(queue.length);
5559
+ for (const item of items) {
5560
+ if (torn) break;
5561
+ output.down([[DATA, item]]);
5562
+ }
5563
+ },
5564
+ close() {
5565
+ guardTorn("close");
5566
+ isOpenNode.down([[DATA, false]]);
5567
+ }
5568
+ };
5569
+ countNode.subscribe(() => void 0);
5570
+ registerStep(graph, name, output, src.path ? [src.path] : []);
5571
+ const internal = new Graph(`${name}_state`);
5572
+ internal.add("pending", pendingNode);
5573
+ internal.add("isOpen", isOpenNode);
5574
+ internal.add("count", countNode);
5575
+ internal.connect("pending", "count");
5576
+ graph.mount(`${name}_state`, internal);
5577
+ return controller;
5578
+ }
4716
5579
  function forEach2(graph, name, source, run, opts) {
4717
5580
  const src = resolveDep(graph, source);
4718
5581
  let terminated = false;
@@ -4721,7 +5584,7 @@ function forEach2(graph, name, source, run, opts) {
4721
5584
  name,
4722
5585
  describeKind: "effect",
4723
5586
  completeWhenDepsComplete: false,
4724
- meta: baseMeta2("forEach", opts?.meta),
5587
+ meta: baseMeta3("forEach", opts?.meta),
4725
5588
  onMessage(msg, depIndex, actions) {
4726
5589
  if (terminated) return true;
4727
5590
  if (depIndex !== 0) {
@@ -4756,7 +5619,7 @@ function join(graph, name, deps, opts) {
4756
5619
  ...opts,
4757
5620
  name,
4758
5621
  describeKind: "derived",
4759
- meta: baseMeta2("join", opts?.meta)
5622
+ meta: baseMeta3("join", opts?.meta)
4760
5623
  }
4761
5624
  );
4762
5625
  registerStep(
@@ -4787,7 +5650,7 @@ function loop(graph, name, source, iterate, opts) {
4787
5650
  ...opts,
4788
5651
  name,
4789
5652
  describeKind: "derived",
4790
- meta: baseMeta2("loop", opts?.meta)
5653
+ meta: baseMeta3("loop", opts?.meta)
4791
5654
  }
4792
5655
  );
4793
5656
  registerStep(
@@ -4812,7 +5675,7 @@ function sensor(graph, name, initial, opts) {
4812
5675
  name,
4813
5676
  initial,
4814
5677
  describeKind: "producer",
4815
- meta: baseMeta2("sensor", opts?.meta)
5678
+ meta: baseMeta3("sensor", opts?.meta)
4816
5679
  });
4817
5680
  registerStep(graph, name, source, []);
4818
5681
  return {
@@ -4850,7 +5713,7 @@ function wait(graph, name, source, ms, opts) {
4850
5713
  initial: src.node.get(),
4851
5714
  describeKind: "operator",
4852
5715
  completeWhenDepsComplete: false,
4853
- meta: baseMeta2("wait", opts?.meta),
5716
+ meta: baseMeta3("wait", opts?.meta),
4854
5717
  onMessage(msg, depIndex, actions) {
4855
5718
  if (terminated) return true;
4856
5719
  if (depIndex !== 0) {
@@ -4900,7 +5763,7 @@ function onFailure(graph, name, source, recover, opts) {
4900
5763
  name,
4901
5764
  describeKind: "operator",
4902
5765
  completeWhenDepsComplete: false,
4903
- meta: baseMeta2("onFailure", opts?.meta),
5766
+ meta: baseMeta3("onFailure", opts?.meta),
4904
5767
  onMessage(msg, _depIndex, actions) {
4905
5768
  if (terminated) return true;
4906
5769
  if (msg[0] === ERROR) {
@@ -4924,10 +5787,12 @@ function onFailure(graph, name, source, recover, opts) {
4924
5787
  // src/index.ts
4925
5788
  var version = "0.0.0";
4926
5789
  export {
5790
+ CLEANUP_RESULT,
4927
5791
  COMPLETE,
4928
5792
  CircuitOpenError,
4929
5793
  DATA,
4930
5794
  DEFAULT_ACTOR,
5795
+ DEFAULT_DOWN,
4931
5796
  DIRTY,
4932
5797
  DictCheckpointAdapter,
4933
5798
  DynamicNodeImpl,
@@ -4953,6 +5818,7 @@ export {
4953
5818
  ai_exports as ai,
4954
5819
  audit,
4955
5820
  batch,
5821
+ bridge,
4956
5822
  buffer,
4957
5823
  bufferCount,
4958
5824
  bufferTime,
@@ -4964,6 +5830,7 @@ export {
4964
5830
  checkpointToRedis,
4965
5831
  checkpointToS3,
4966
5832
  circuitBreaker,
5833
+ cleanupResult,
4967
5834
  combine,
4968
5835
  combineLatest,
4969
5836
  compat_exports as compat,
@@ -4988,6 +5855,7 @@ export {
4988
5855
  deserializeError,
4989
5856
  distill,
4990
5857
  distinctUntilChanged,
5858
+ domain_templates_exports as domainTemplates,
4991
5859
  dynamicNode,
4992
5860
  effect,
4993
5861
  elementAt,
@@ -5036,7 +5904,6 @@ export {
5036
5904
  fromTimer,
5037
5905
  fromWebSocket,
5038
5906
  fromWebhook,
5039
- gate,
5040
5907
  globToRegExp,
5041
5908
  graph_exports as graph,
5042
5909
  graphspec_exports as graphspec,
@@ -5152,6 +6019,7 @@ export {
5152
6019
  toWebSocket,
5153
6020
  tokenBucket,
5154
6021
  tokenTracker,
6022
+ valve,
5155
6023
  verifiable,
5156
6024
  version,
5157
6025
  vue_exports as vue,