@graphrefly/graphrefly 0.19.0 → 0.21.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 (52) hide show
  1. package/README.md +20 -3
  2. package/dist/{chunk-JC2SN46B.js → chunk-2UDLYZHT.js} +3 -3
  3. package/dist/{chunk-YXR3WW3Q.js → chunk-4MQ2J6IG.js} +4 -4
  4. package/dist/{chunk-YXR3WW3Q.js.map → chunk-4MQ2J6IG.js.map} +1 -1
  5. package/dist/{chunk-XUOY3YKN.js → chunk-7IGHIFTT.js} +2 -2
  6. package/dist/{chunk-AHRKWMNI.js → chunk-DOSLSFKL.js} +3 -3
  7. package/dist/{chunk-BER7UYLM.js → chunk-ECN37NVS.js} +161 -199
  8. package/dist/chunk-ECN37NVS.js.map +1 -0
  9. package/dist/{chunk-YLR5JUJZ.js → chunk-G66H6ZRK.js} +3 -3
  10. package/dist/{chunk-IRZAGZUB.js → chunk-VOQFK7YN.js} +26 -2
  11. package/dist/chunk-VOQFK7YN.js.map +1 -0
  12. package/dist/{chunk-OO5QOAXI.js → chunk-XWBVAO2R.js} +22 -9
  13. package/dist/chunk-XWBVAO2R.js.map +1 -0
  14. package/dist/{chunk-UW77D7SP.js → chunk-ZTCDY5NQ.js} +3 -3
  15. package/dist/compat/nestjs/index.cjs +15 -6
  16. package/dist/compat/nestjs/index.cjs.map +1 -1
  17. package/dist/compat/nestjs/index.js +7 -7
  18. package/dist/core/index.cjs +3 -3
  19. package/dist/core/index.cjs.map +1 -1
  20. package/dist/core/index.d.cts +1 -1
  21. package/dist/core/index.d.ts +1 -1
  22. package/dist/core/index.js +3 -3
  23. package/dist/extra/index.cjs +183 -199
  24. package/dist/extra/index.cjs.map +1 -1
  25. package/dist/extra/index.d.cts +1 -1
  26. package/dist/extra/index.d.ts +1 -1
  27. package/dist/extra/index.js +7 -3
  28. package/dist/graph/index.cjs +1 -1
  29. package/dist/graph/index.cjs.map +1 -1
  30. package/dist/graph/index.js +4 -4
  31. package/dist/{index-CvKzv0AW.d.ts → index-BHfg_Ez3.d.ts} +1 -1
  32. package/dist/{index-BBUYZfJ1.d.cts → index-Bc_diYYJ.d.cts} +1 -1
  33. package/dist/{index-BnkMgNNa.d.ts → index-DuN3bhtm.d.ts} +47 -2
  34. package/dist/{index-Bjh5C1Tp.d.cts → index-SFzE_KTa.d.cts} +47 -2
  35. package/dist/index.cjs +463 -281
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +275 -10
  38. package/dist/index.d.ts +275 -10
  39. package/dist/index.js +284 -90
  40. package/dist/index.js.map +1 -1
  41. package/dist/patterns/reactive-layout/index.cjs +1 -1
  42. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  43. package/dist/patterns/reactive-layout/index.js +4 -4
  44. package/package.json +3 -2
  45. package/dist/chunk-BER7UYLM.js.map +0 -1
  46. package/dist/chunk-IRZAGZUB.js.map +0 -1
  47. package/dist/chunk-OO5QOAXI.js.map +0 -1
  48. /package/dist/{chunk-JC2SN46B.js.map → chunk-2UDLYZHT.js.map} +0 -0
  49. /package/dist/{chunk-XUOY3YKN.js.map → chunk-7IGHIFTT.js.map} +0 -0
  50. /package/dist/{chunk-AHRKWMNI.js.map → chunk-DOSLSFKL.js.map} +0 -0
  51. /package/dist/{chunk-YLR5JUJZ.js.map → chunk-G66H6ZRK.js.map} +0 -0
  52. /package/dist/{chunk-UW77D7SP.js.map → chunk-ZTCDY5NQ.js.map} +0 -0
package/dist/index.js CHANGED
@@ -136,16 +136,26 @@ import {
136
136
  workerBridge,
137
137
  workerSelf,
138
138
  zip
139
- } from "./chunk-BER7UYLM.js";
139
+ } from "./chunk-ECN37NVS.js";
140
140
  import {
141
141
  cqrs_exports,
142
- nestjs_exports
143
- } from "./chunk-OO5QOAXI.js";
142
+ domainMeta,
143
+ nestjs_exports,
144
+ trackingKey
145
+ } from "./chunk-XWBVAO2R.js";
146
+ import {
147
+ JsonCodec,
148
+ createDagCborCodec,
149
+ createDagCborZstdCodec,
150
+ graph_exports,
151
+ negotiateCodec,
152
+ replayWAL
153
+ } from "./chunk-G66H6ZRK.js";
144
154
  import {
145
155
  DEFAULT_DOWN,
146
156
  bridge,
147
157
  core_exports
148
- } from "./chunk-AHRKWMNI.js";
158
+ } from "./chunk-DOSLSFKL.js";
149
159
  import {
150
160
  cached,
151
161
  createWatermarkController,
@@ -163,12 +173,14 @@ import {
163
173
  fromPromise,
164
174
  fromTimer,
165
175
  globToRegExp,
176
+ keepalive,
166
177
  logSlice,
167
178
  matchesAnyPattern,
168
179
  matchesCron,
169
180
  never,
170
181
  of,
171
182
  parseCron,
183
+ reactiveCounter,
172
184
  reactiveLog,
173
185
  replay,
174
186
  share,
@@ -176,34 +188,26 @@ import {
176
188
  throwError,
177
189
  toArray,
178
190
  toObservable
179
- } from "./chunk-IRZAGZUB.js";
191
+ } from "./chunk-VOQFK7YN.js";
180
192
  import {
181
193
  ResettableTimer
182
194
  } from "./chunk-WZ2Z2CRV.js";
183
- import {
184
- JsonCodec,
185
- createDagCborCodec,
186
- createDagCborZstdCodec,
187
- graph_exports,
188
- negotiateCodec,
189
- replayWAL
190
- } from "./chunk-YLR5JUJZ.js";
191
195
  import {
192
196
  analyzeAndMeasure,
193
197
  computeLineBreaks,
194
198
  reactive_layout_exports
195
- } from "./chunk-UW77D7SP.js";
199
+ } from "./chunk-ZTCDY5NQ.js";
196
200
  import {
197
201
  GRAPH_META_SEGMENT,
198
202
  Graph,
199
203
  graphProfile,
200
204
  reachable,
201
205
  sizeof
202
- } from "./chunk-JC2SN46B.js";
206
+ } from "./chunk-2UDLYZHT.js";
203
207
  import {
204
208
  describeNode,
205
209
  resolveDescribeFields
206
- } from "./chunk-XUOY3YKN.js";
210
+ } from "./chunk-7IGHIFTT.js";
207
211
  import {
208
212
  CLEANUP_RESULT,
209
213
  COMPLETE,
@@ -249,7 +253,7 @@ import {
249
253
  propagatesToMeta,
250
254
  state,
251
255
  wallClockNs
252
- } from "./chunk-YXR3WW3Q.js";
256
+ } from "./chunk-4MQ2J6IG.js";
253
257
 
254
258
  // src/compat/index.ts
255
259
  var compat_exports = {};
@@ -1101,6 +1105,7 @@ __export(ai_exports, {
1101
1105
  agentLoop: () => agentLoop,
1102
1106
  agentMemory: () => agentMemory,
1103
1107
  chatStream: () => chatStream,
1108
+ contentGate: () => contentGate,
1104
1109
  costMeterExtractor: () => costMeterExtractor,
1105
1110
  fromLLM: () => fromLLM,
1106
1111
  gatedStream: () => gatedStream,
@@ -1111,6 +1116,7 @@ __export(ai_exports, {
1111
1116
  llmConsolidator: () => llmConsolidator,
1112
1117
  llmExtractor: () => llmExtractor,
1113
1118
  promptNode: () => promptNode,
1119
+ redactor: () => redactor,
1114
1120
  streamExtractor: () => streamExtractor,
1115
1121
  streamingPromptNode: () => streamingPromptNode,
1116
1122
  suggestStrategy: () => suggestStrategy,
@@ -1517,16 +1523,8 @@ function requireNonNegativeInt(value, label) {
1517
1523
  }
1518
1524
  return value;
1519
1525
  }
1520
- function keepalive(n) {
1521
- return n.subscribe(() => {
1522
- });
1523
- }
1524
1526
  function messagingMeta(kind, extra) {
1525
- return {
1526
- messaging: true,
1527
- messaging_type: kind,
1528
- ...extra ?? {}
1529
- };
1527
+ return domainMeta("messaging", kind, extra);
1530
1528
  }
1531
1529
  var TopicGraph = class extends Graph {
1532
1530
  _log;
@@ -1909,11 +1907,7 @@ function registerStep(graph, name, step, depPaths) {
1909
1907
  }
1910
1908
  }
1911
1909
  function baseMeta(kind, meta) {
1912
- return {
1913
- orchestration: true,
1914
- orchestration_type: kind,
1915
- ...meta ?? {}
1916
- };
1910
+ return domainMeta("orchestration", kind, meta);
1917
1911
  }
1918
1912
  function coerceLoopIterations(raw) {
1919
1913
  const parseString = (value) => {
@@ -2359,14 +2353,7 @@ function onFailure(graph, name, source, recover, opts) {
2359
2353
 
2360
2354
  // src/patterns/ai.ts
2361
2355
  function aiMeta(kind, extra) {
2362
- return {
2363
- ai: true,
2364
- ai_type: kind,
2365
- ...extra ?? {}
2366
- };
2367
- }
2368
- function keepalive2(n) {
2369
- return n.subscribe(() => void 0);
2356
+ return domainMeta("ai", kind, extra);
2370
2357
  }
2371
2358
  function isPromiseLike(x) {
2372
2359
  return x != null && typeof x.then === "function";
@@ -2500,7 +2487,7 @@ function streamingPromptNode(adapter, deps, prompt, opts) {
2500
2487
  }
2501
2488
  return fromAny(pumpAndCollect());
2502
2489
  });
2503
- const unsub = keepalive2(output);
2490
+ const unsub = keepalive(output);
2504
2491
  return {
2505
2492
  output,
2506
2493
  stream: streamTopic,
@@ -2626,6 +2613,53 @@ function costMeterExtractor(streamTopic, opts) {
2626
2613
  }
2627
2614
  );
2628
2615
  }
2616
+ function redactor(streamTopic, patterns, replaceFn, opts) {
2617
+ const replace = replaceFn ?? (() => "[REDACTED]");
2618
+ function sanitize(text) {
2619
+ let result = text;
2620
+ for (const pat of patterns) {
2621
+ const global = pat.global ? pat : new RegExp(pat.source, `${pat.flags}g`);
2622
+ result = result.replace(global, (m) => replace(m, pat));
2623
+ }
2624
+ return result;
2625
+ }
2626
+ return derived(
2627
+ [streamTopic.latest],
2628
+ ([chunk]) => {
2629
+ if (chunk == null) {
2630
+ return { source: "", token: "", accumulated: "", index: -1 };
2631
+ }
2632
+ const c = chunk;
2633
+ const sanitizedAccumulated = sanitize(c.accumulated);
2634
+ const sanitizedToken = sanitize(c.token);
2635
+ return {
2636
+ source: c.source,
2637
+ token: sanitizedToken,
2638
+ accumulated: sanitizedAccumulated,
2639
+ index: c.index
2640
+ };
2641
+ },
2642
+ { name: opts?.name ?? "redactor" }
2643
+ );
2644
+ }
2645
+ function contentGate(streamTopic, classifier, threshold, opts) {
2646
+ const hardThreshold = threshold * (opts?.hardMultiplier ?? 1.5);
2647
+ const isNodeClassifier = typeof classifier !== "function";
2648
+ const deps = [streamTopic.latest];
2649
+ if (isNodeClassifier) deps.push(classifier);
2650
+ return derived(
2651
+ deps,
2652
+ (values) => {
2653
+ const chunk = values[0];
2654
+ if (chunk == null) return "allow";
2655
+ const score = isNodeClassifier ? values[1] ?? 0 : classifier(chunk.accumulated);
2656
+ if (score >= hardThreshold) return "block";
2657
+ if (score >= threshold) return "review";
2658
+ return "allow";
2659
+ },
2660
+ { name: opts?.name ?? "content-gate", initial: "allow" }
2661
+ );
2662
+ }
2629
2663
  function gatedStream(graph, name, adapter, deps, prompt, opts) {
2630
2664
  const cancelSignal = state(0, { name: `${name}/cancel` });
2631
2665
  let cancelCounter = 0;
@@ -2685,7 +2719,7 @@ function gatedStream(graph, name, adapter, deps, prompt, opts) {
2685
2719
  }
2686
2720
  return fromAny(pumpAndCollect());
2687
2721
  });
2688
- const unsub = keepalive2(output);
2722
+ const unsub = keepalive(output);
2689
2723
  const nonNullOutput = derived(
2690
2724
  [output],
2691
2725
  ([v]) => {
@@ -2816,7 +2850,7 @@ var ChatStreamGraph = class extends Graph {
2816
2850
  );
2817
2851
  this.add("latest", this.latest);
2818
2852
  this.connect("messages", "latest");
2819
- this.addDisposer(keepalive2(this.latest));
2853
+ this.addDisposer(keepalive(this.latest));
2820
2854
  this.messageCount = derived(
2821
2855
  [this.messages],
2822
2856
  ([snapshot]) => snapshot.length,
@@ -2829,7 +2863,7 @@ var ChatStreamGraph = class extends Graph {
2829
2863
  );
2830
2864
  this.add("messageCount", this.messageCount);
2831
2865
  this.connect("messages", "messageCount");
2832
- this.addDisposer(keepalive2(this.messageCount));
2866
+ this.addDisposer(keepalive(this.messageCount));
2833
2867
  }
2834
2868
  append(role, content, extra) {
2835
2869
  this._log.append({ role, content, ...extra });
@@ -2870,7 +2904,7 @@ var ToolRegistryGraph = class extends Graph {
2870
2904
  );
2871
2905
  this.add("schemas", this.schemas);
2872
2906
  this.connect("definitions", "schemas");
2873
- this.addDisposer(keepalive2(this.schemas));
2907
+ this.addDisposer(keepalive(this.schemas));
2874
2908
  }
2875
2909
  register(tool) {
2876
2910
  const current = this.definitions.get();
@@ -2912,7 +2946,7 @@ function systemPromptBuilder(sections, opts) {
2912
2946
  initial: ""
2913
2947
  }
2914
2948
  );
2915
- const unsub = keepalive2(prompt);
2949
+ const unsub = keepalive(prompt);
2916
2950
  return Object.assign(prompt, { dispose: unsub });
2917
2951
  }
2918
2952
  function llmExtractor(systemPrompt, opts) {
@@ -4225,21 +4259,14 @@ __export(domain_templates_exports, {
4225
4259
  var reduction_exports = {};
4226
4260
  __export(reduction_exports, {
4227
4261
  budgetGate: () => budgetGate,
4262
+ effectivenessTracker: () => effectivenessTracker,
4228
4263
  feedback: () => feedback,
4229
4264
  funnel: () => funnel,
4230
4265
  scorer: () => scorer,
4231
4266
  stratify: () => stratify
4232
4267
  });
4233
4268
  function baseMeta2(kind, meta) {
4234
- return {
4235
- reduction: true,
4236
- reduction_type: kind,
4237
- ...meta ?? {}
4238
- };
4239
- }
4240
- function keepalive3(n) {
4241
- return n.subscribe(() => {
4242
- });
4269
+ return domainMeta("reduction", kind, meta);
4243
4270
  }
4244
4271
  function stratify(name, source, rules, opts) {
4245
4272
  const g = new Graph(name, opts);
@@ -4377,7 +4404,7 @@ function funnel(name, sources, stages, opts) {
4377
4404
  });
4378
4405
  g.add(bridgeName, br);
4379
4406
  g.connect(prevOutputPath, bridgeName);
4380
- g.addDisposer(keepalive3(br));
4407
+ g.addDisposer(keepalive(br));
4381
4408
  prevOutputPath = `${stage.name}::output`;
4382
4409
  }
4383
4410
  return g;
@@ -4429,7 +4456,7 @@ function feedback(graph, condition, reentry, opts) {
4429
4456
  });
4430
4457
  graph.add(feedbackEffectName, feedbackEffect);
4431
4458
  graph.connect(condition, feedbackEffectName);
4432
- graph.addDisposer(keepalive3(feedbackEffect));
4459
+ graph.addDisposer(keepalive(feedbackEffect));
4433
4460
  return graph;
4434
4461
  }
4435
4462
  function budgetGate(source, constraints, opts) {
@@ -4563,14 +4590,55 @@ function scorer(sources, weights, opts) {
4563
4590
  }
4564
4591
  );
4565
4592
  }
4566
-
4567
- // src/patterns/domain-templates.ts
4568
- function keepalive4(n) {
4569
- return n.subscribe(() => {
4593
+ function effectivenessTracker(opts) {
4594
+ const _map = reactiveMap({
4595
+ name: opts?.name ?? "effectiveness-entries"
4570
4596
  });
4597
+ const snapshot = derived(
4598
+ [_map.entries],
4599
+ ([mapSnap]) => {
4600
+ return new Map(mapSnap);
4601
+ },
4602
+ {
4603
+ name: `${opts?.name ?? "effectiveness"}-snapshot`,
4604
+ equals: (a, b) => {
4605
+ const am = a;
4606
+ const bm = b;
4607
+ if (am.size !== bm.size) return false;
4608
+ for (const [k, v] of am) {
4609
+ const bv = bm.get(k);
4610
+ if (!bv || v.attempts !== bv.attempts || v.successes !== bv.successes) return false;
4611
+ }
4612
+ return true;
4613
+ }
4614
+ }
4615
+ );
4616
+ function record(key, success) {
4617
+ const existing = _map.get(key);
4618
+ const attempts = (existing?.attempts ?? 0) + 1;
4619
+ const successes = (existing?.successes ?? 0) + (success ? 1 : 0);
4620
+ _map.set(key, {
4621
+ key,
4622
+ attempts,
4623
+ successes,
4624
+ successRate: successes / attempts
4625
+ });
4626
+ }
4627
+ function lookup(key) {
4628
+ return _map.get(key);
4629
+ }
4630
+ const _unsub = keepalive(snapshot);
4631
+ return {
4632
+ node: snapshot,
4633
+ record,
4634
+ lookup,
4635
+ dispose: () => _unsub()
4636
+ };
4571
4637
  }
4638
+
4639
+ // src/patterns/domain-templates.ts
4572
4640
  function baseMeta3(kind, extra) {
4573
- return { domain_template: true, template_type: kind, ...extra ?? {} };
4641
+ return domainMeta("domain_template", kind, extra);
4574
4642
  }
4575
4643
  function observabilityGraph(name, opts) {
4576
4644
  const g = new Graph(name, opts);
@@ -4810,7 +4878,7 @@ function contentModerationGraph(name, opts) {
4810
4878
  }
4811
4879
  });
4812
4880
  g.add("__review_accumulator", reviewAccumulator);
4813
- g.addDisposer(keepalive4(reviewAccumulator));
4881
+ g.addDisposer(keepalive(reviewAccumulator));
4814
4882
  try {
4815
4883
  g.connect("stratify::branch/review", "__review_accumulator");
4816
4884
  } catch {
@@ -4921,7 +4989,7 @@ function dataQualityGraph(name, opts) {
4921
4989
  });
4922
4990
  g.add("__baseline_updater", baselineUpdater);
4923
4991
  g.connect("validate", "__baseline_updater");
4924
- keepalive4(baselineUpdater);
4992
+ keepalive(baselineUpdater);
4925
4993
  const detectDriftFn = opts.detectDrift ?? (() => ({ drift: false }));
4926
4994
  const driftNode = derived(
4927
4995
  [opts.source, baseline],
@@ -6011,52 +6079,179 @@ __export(harness_exports, {
6011
6079
  DEFAULT_SEVERITY_WEIGHTS: () => DEFAULT_SEVERITY_WEIGHTS,
6012
6080
  HarnessGraph: () => HarnessGraph,
6013
6081
  QUEUE_NAMES: () => QUEUE_NAMES,
6082
+ affectedTaskFilter: () => affectedTaskFilter,
6083
+ beforeAfterCompare: () => beforeAfterCompare,
6084
+ codeChangeBridge: () => codeChangeBridge,
6085
+ createIntakeBridge: () => createIntakeBridge,
6014
6086
  defaultErrorClassifier: () => defaultErrorClassifier,
6015
6087
  evalIntakeBridge: () => evalIntakeBridge,
6088
+ evalSource: () => evalSource,
6016
6089
  harnessLoop: () => harnessLoop,
6017
6090
  harnessProfile: () => harnessProfile,
6018
6091
  harnessTrace: () => harnessTrace,
6092
+ notifyEffect: () => notifyEffect,
6019
6093
  priorityScore: () => priorityScore,
6020
6094
  strategyKey: () => strategyKey,
6021
6095
  strategyModel: () => strategyModel
6022
6096
  });
6023
6097
 
6024
6098
  // src/patterns/harness/bridge.ts
6025
- function evalIntakeBridge(evalSource, intakeTopic, opts) {
6099
+ function createIntakeBridge(source, intakeTopic, parser, opts) {
6100
+ return effect(
6101
+ [source],
6102
+ ([value]) => {
6103
+ if (value == null) return;
6104
+ const items = parser(value);
6105
+ for (const item of items) {
6106
+ intakeTopic.publish(item);
6107
+ }
6108
+ },
6109
+ { name: opts?.name ?? "intake-bridge" }
6110
+ );
6111
+ }
6112
+ function evalIntakeBridge(evalSource2, intakeTopic, opts) {
6026
6113
  const defaultSeverity = opts?.defaultSeverity ?? "medium";
6027
- return effect([evalSource], ([results]) => {
6028
- if (results == null) return;
6029
- const runs = Array.isArray(results) ? results : [results];
6030
- for (const run of runs) {
6031
- for (const task2 of run.tasks) {
6032
- if (task2.valid && task2.judge_scores?.every((s) => s.pass)) continue;
6033
- if (!task2.valid && (!task2.judge_scores || task2.judge_scores.length === 0)) {
6034
- intakeTopic.publish({
6035
- source: "eval",
6036
- summary: `Task ${task2.task_id} invalid (model: ${run.model})`,
6037
- evidence: `Run ${run.run_id}: task produced invalid output`,
6038
- affectsAreas: ["graphspec"],
6039
- affectsEvalTasks: [task2.task_id],
6040
- severity: defaultSeverity
6041
- });
6042
- continue;
6043
- }
6044
- if (task2.judge_scores) {
6045
- for (const score of task2.judge_scores) {
6046
- if (score.pass) continue;
6114
+ return effect(
6115
+ [evalSource2],
6116
+ ([results]) => {
6117
+ if (results == null) return;
6118
+ const runs = Array.isArray(results) ? results : [results];
6119
+ for (const run of runs) {
6120
+ for (const task2 of run.tasks) {
6121
+ if (task2.valid && task2.judge_scores?.every((s) => s.pass)) continue;
6122
+ if (!task2.valid && (!task2.judge_scores || task2.judge_scores.length === 0)) {
6047
6123
  intakeTopic.publish({
6048
6124
  source: "eval",
6049
- summary: `${task2.task_id}: ${score.claim} (model: ${run.model})`,
6050
- evidence: score.reasoning,
6125
+ summary: `Task ${task2.task_id} invalid (model: ${run.model})`,
6126
+ evidence: `Run ${run.run_id}: task produced invalid output`,
6051
6127
  affectsAreas: ["graphspec"],
6052
6128
  affectsEvalTasks: [task2.task_id],
6053
6129
  severity: defaultSeverity
6054
6130
  });
6131
+ continue;
6055
6132
  }
6133
+ if (task2.judge_scores) {
6134
+ for (const score of task2.judge_scores) {
6135
+ if (score.pass) continue;
6136
+ intakeTopic.publish({
6137
+ source: "eval",
6138
+ summary: `${task2.task_id}: ${score.claim} (model: ${run.model})`,
6139
+ evidence: score.reasoning,
6140
+ affectsAreas: ["graphspec"],
6141
+ affectsEvalTasks: [task2.task_id],
6142
+ severity: defaultSeverity
6143
+ });
6144
+ }
6145
+ }
6146
+ }
6147
+ }
6148
+ },
6149
+ { name: opts?.name ?? "eval-intake-bridge" }
6150
+ );
6151
+ }
6152
+ function evalSource(trigger2, runner) {
6153
+ return switchMap(trigger2, () => fromAny(runner()));
6154
+ }
6155
+ function beforeAfterCompare(before, after) {
6156
+ return derived(
6157
+ [before, after],
6158
+ ([b, a]) => {
6159
+ const bRes = b;
6160
+ const aRes = a;
6161
+ const beforeMap = new Map(bRes.tasks.map((t) => [t.task_id, t]));
6162
+ const afterMap = new Map(aRes.tasks.map((t) => [t.task_id, t]));
6163
+ const allIds = /* @__PURE__ */ new Set([...beforeMap.keys(), ...afterMap.keys()]);
6164
+ const taskDeltas = [];
6165
+ const newFailures = [];
6166
+ const resolved = [];
6167
+ for (const id of allIds) {
6168
+ const bt = beforeMap.get(id);
6169
+ const at = afterMap.get(id);
6170
+ const beforeValid = bt?.valid ?? false;
6171
+ const afterValid = at?.valid ?? false;
6172
+ const beforeScore = bt?.judge_scores ? bt.judge_scores.filter((s) => s.pass).length : void 0;
6173
+ const afterScore = at?.judge_scores ? at.judge_scores.filter((s) => s.pass).length : void 0;
6174
+ const scoreDiff = beforeScore !== void 0 && afterScore !== void 0 ? afterScore - beforeScore : void 0;
6175
+ taskDeltas.push({ taskId: id, before: beforeValid, after: afterValid, scoreDiff });
6176
+ if (beforeValid && !afterValid) newFailures.push(id);
6177
+ if (!beforeValid && afterValid) resolved.push(id);
6178
+ }
6179
+ return {
6180
+ newFailures,
6181
+ resolved,
6182
+ taskDeltas,
6183
+ overallImproved: resolved.length > newFailures.length
6184
+ };
6185
+ },
6186
+ { name: "eval-delta" }
6187
+ );
6188
+ }
6189
+ function affectedTaskFilter(issues, fullTaskSet) {
6190
+ const taskSetNode = fullTaskSet == null ? null : Array.isArray(fullTaskSet) ? state(fullTaskSet) : fullTaskSet;
6191
+ const deps = [issues];
6192
+ if (taskSetNode) deps.push(taskSetNode);
6193
+ return derived(
6194
+ deps,
6195
+ (values) => {
6196
+ const items = values[0];
6197
+ const all = taskSetNode ? new Set(values[1]) : null;
6198
+ const affected = /* @__PURE__ */ new Set();
6199
+ for (const item of items) {
6200
+ for (const id of item.affectsEvalTasks ?? []) {
6201
+ if (all == null || all.has(id)) affected.add(id);
6056
6202
  }
6057
6203
  }
6204
+ return [...affected].sort();
6205
+ },
6206
+ { name: "affected-task-filter" }
6207
+ );
6208
+ }
6209
+ function codeChangeBridge(source, intakeTopic, parser, opts) {
6210
+ const defaultSeverity = opts?.defaultSeverity ?? "high";
6211
+ function defaultParser(change) {
6212
+ const items = [];
6213
+ for (const err of change.lintErrors ?? []) {
6214
+ items.push({
6215
+ source: "code-change",
6216
+ summary: `Lint: ${err.rule} in ${err.file}:${err.line}`,
6217
+ evidence: err.message,
6218
+ affectsAreas: [err.file],
6219
+ severity: defaultSeverity
6220
+ });
6058
6221
  }
6059
- });
6222
+ for (const fail of change.testFailures ?? []) {
6223
+ items.push({
6224
+ source: "test",
6225
+ summary: `Test failure: ${fail.testId}`,
6226
+ evidence: fail.message,
6227
+ affectsAreas: [fail.file],
6228
+ affectsEvalTasks: [fail.testId],
6229
+ severity: defaultSeverity
6230
+ });
6231
+ }
6232
+ return items;
6233
+ }
6234
+ const resolve = parser ?? defaultParser;
6235
+ return effect(
6236
+ [source],
6237
+ ([change]) => {
6238
+ if (change == null) return;
6239
+ for (const item of resolve(change)) {
6240
+ intakeTopic.publish(item);
6241
+ }
6242
+ },
6243
+ { name: opts?.name ?? "code-change-bridge" }
6244
+ );
6245
+ }
6246
+ function notifyEffect(topic2, transport, opts) {
6247
+ return effect(
6248
+ [topic2.latest],
6249
+ ([item]) => {
6250
+ if (item == null) return;
6251
+ void transport(item);
6252
+ },
6253
+ { name: opts?.name ?? "notify-effect" }
6254
+ );
6060
6255
  }
6061
6256
 
6062
6257
  // src/patterns/harness/types.ts
@@ -6166,9 +6361,6 @@ function priorityScore(item, strategy, lastInteractionNs, urgency, signals) {
6166
6361
  }
6167
6362
 
6168
6363
  // src/patterns/harness/loop.ts
6169
- function trackingKey(item) {
6170
- return item.relatedTo?.[0] ?? item.summary;
6171
- }
6172
6364
  var DEFAULT_TRIAGE_PROMPT = `You are a triage classifier for a reactive collaboration harness.
6173
6365
 
6174
6366
  Given an intake item, classify it and output JSON:
@@ -6684,6 +6876,7 @@ export {
6684
6876
  isTerminalMessage,
6685
6877
  isV1,
6686
6878
  jotai_exports as jotai,
6879
+ keepalive,
6687
6880
  knownMessageTypes,
6688
6881
  last,
6689
6882
  reactive_layout_exports as layout,
@@ -6726,6 +6919,7 @@ export {
6726
6919
  rateLimiter,
6727
6920
  reachable,
6728
6921
  react_exports as react,
6922
+ reactiveCounter,
6729
6923
  reactiveIndex,
6730
6924
  reactiveList,
6731
6925
  reactiveLog,