@graphrefly/graphrefly 0.13.0 → 0.14.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 (42) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-HA6QMDKQ.js → chunk-2ZICUAUJ.js} +4 -4
  3. package/dist/{chunk-H4UFM6WD.js → chunk-4APC3AFN.js} +3 -3
  4. package/dist/{chunk-UQI4GAHD.js → chunk-CRACCCJY.js} +3 -3
  5. package/dist/{chunk-UPC5OEB5.js → chunk-GKRKDYNT.js} +3 -3
  6. package/dist/{chunk-6B2ZCCNN.js → chunk-H243FWYP.js} +12 -13
  7. package/dist/chunk-H243FWYP.js.map +1 -0
  8. package/dist/{chunk-KNGOJEYP.js → chunk-QVYZD65U.js} +2 -2
  9. package/dist/{chunk-PFMXKG4Y.js → chunk-XQ4UMAU7.js} +2 -2
  10. package/dist/{chunk-5RN7NBNG.js → chunk-YW6LFCFS.js} +3 -3
  11. package/dist/{chunk-QOGWU5K7.js → chunk-ZHTHUX5D.js} +3 -3
  12. package/dist/compat/nestjs/index.cjs +11 -12
  13. package/dist/compat/nestjs/index.cjs.map +1 -1
  14. package/dist/compat/nestjs/index.js +7 -7
  15. package/dist/core/index.cjs +11 -12
  16. package/dist/core/index.cjs.map +1 -1
  17. package/dist/core/index.js +3 -3
  18. package/dist/extra/index.cjs +11 -12
  19. package/dist/extra/index.cjs.map +1 -1
  20. package/dist/extra/index.js +3 -3
  21. package/dist/graph/index.cjs +3 -0
  22. package/dist/graph/index.cjs.map +1 -1
  23. package/dist/graph/index.js +4 -4
  24. package/dist/index.cjs +390 -15
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +359 -56
  27. package/dist/index.d.ts +359 -56
  28. package/dist/index.js +395 -20
  29. package/dist/index.js.map +1 -1
  30. package/dist/patterns/reactive-layout/index.cjs +3 -0
  31. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  32. package/dist/patterns/reactive-layout/index.js +4 -4
  33. package/package.json +3 -1
  34. package/dist/chunk-6B2ZCCNN.js.map +0 -1
  35. /package/dist/{chunk-HA6QMDKQ.js.map → chunk-2ZICUAUJ.js.map} +0 -0
  36. /package/dist/{chunk-H4UFM6WD.js.map → chunk-4APC3AFN.js.map} +0 -0
  37. /package/dist/{chunk-UQI4GAHD.js.map → chunk-CRACCCJY.js.map} +0 -0
  38. /package/dist/{chunk-UPC5OEB5.js.map → chunk-GKRKDYNT.js.map} +0 -0
  39. /package/dist/{chunk-KNGOJEYP.js.map → chunk-QVYZD65U.js.map} +0 -0
  40. /package/dist/{chunk-PFMXKG4Y.js.map → chunk-XQ4UMAU7.js.map} +0 -0
  41. /package/dist/{chunk-5RN7NBNG.js.map → chunk-YW6LFCFS.js.map} +0 -0
  42. /package/dist/{chunk-QOGWU5K7.js.map → chunk-ZHTHUX5D.js.map} +0 -0
package/dist/index.js CHANGED
@@ -137,24 +137,11 @@ import {
137
137
  workerBridge,
138
138
  workerSelf,
139
139
  zip
140
- } from "./chunk-H4UFM6WD.js";
140
+ } from "./chunk-4APC3AFN.js";
141
141
  import {
142
142
  cqrs_exports,
143
143
  nestjs_exports
144
- } from "./chunk-HA6QMDKQ.js";
145
- import {
146
- DEFAULT_DOWN,
147
- bridge,
148
- core_exports
149
- } from "./chunk-5RN7NBNG.js";
150
- import {
151
- JsonCodec,
152
- createDagCborCodec,
153
- createDagCborZstdCodec,
154
- graph_exports,
155
- negotiateCodec,
156
- replayWAL
157
- } from "./chunk-QOGWU5K7.js";
144
+ } from "./chunk-2ZICUAUJ.js";
158
145
  import {
159
146
  cached,
160
147
  createWatermarkController,
@@ -187,7 +174,20 @@ import {
187
174
  toArray,
188
175
  toMessages$,
189
176
  toObservable
190
- } from "./chunk-KNGOJEYP.js";
177
+ } from "./chunk-QVYZD65U.js";
178
+ import {
179
+ JsonCodec,
180
+ createDagCborCodec,
181
+ createDagCborZstdCodec,
182
+ graph_exports,
183
+ negotiateCodec,
184
+ replayWAL
185
+ } from "./chunk-ZHTHUX5D.js";
186
+ import {
187
+ DEFAULT_DOWN,
188
+ bridge,
189
+ core_exports
190
+ } from "./chunk-YW6LFCFS.js";
191
191
  import {
192
192
  ResettableTimer
193
193
  } from "./chunk-WZ2Z2CRV.js";
@@ -195,17 +195,17 @@ import {
195
195
  analyzeAndMeasure,
196
196
  computeLineBreaks,
197
197
  reactive_layout_exports
198
- } from "./chunk-UPC5OEB5.js";
198
+ } from "./chunk-GKRKDYNT.js";
199
199
  import {
200
200
  GRAPH_META_SEGMENT,
201
201
  Graph,
202
202
  reachable
203
- } from "./chunk-UQI4GAHD.js";
203
+ } from "./chunk-CRACCCJY.js";
204
204
  import {
205
205
  describeNode,
206
206
  metaSnapshot,
207
207
  resolveDescribeFields
208
- } from "./chunk-PFMXKG4Y.js";
208
+ } from "./chunk-XQ4UMAU7.js";
209
209
  import {
210
210
  CLEANUP_RESULT,
211
211
  COMPLETE,
@@ -249,7 +249,7 @@ import {
249
249
  propagatesToMeta,
250
250
  state,
251
251
  wallClockNs
252
- } from "./chunk-6B2ZCCNN.js";
252
+ } from "./chunk-H243FWYP.js";
253
253
 
254
254
  // src/compat/index.ts
255
255
  var compat_exports = {};
@@ -1051,6 +1051,7 @@ __export(patterns_exports, {
1051
1051
  demoShell: () => demo_shell_exports,
1052
1052
  domainTemplates: () => domain_templates_exports,
1053
1053
  graphspec: () => graphspec_exports,
1054
+ harness: () => harness_exports,
1054
1055
  layout: () => reactive_layout_exports,
1055
1056
  memory: () => memory_exports,
1056
1057
  messaging: () => messaging_exports,
@@ -4891,6 +4892,59 @@ ${validation.errors.join("\n")}`);
4891
4892
  return parsed;
4892
4893
  }
4893
4894
 
4895
+ // src/patterns/harness/index.ts
4896
+ var harness_exports = {};
4897
+ __export(harness_exports, {
4898
+ DEFAULT_DECAY_RATE: () => DEFAULT_DECAY_RATE2,
4899
+ DEFAULT_QUEUE_CONFIGS: () => DEFAULT_QUEUE_CONFIGS,
4900
+ DEFAULT_SEVERITY_WEIGHTS: () => DEFAULT_SEVERITY_WEIGHTS,
4901
+ HarnessGraph: () => HarnessGraph,
4902
+ defaultErrorClassifier: () => defaultErrorClassifier,
4903
+ evalIntakeBridge: () => evalIntakeBridge,
4904
+ harnessLoop: () => harnessLoop,
4905
+ priorityScore: () => priorityScore,
4906
+ strategyKey: () => strategyKey,
4907
+ strategyModel: () => strategyModel
4908
+ });
4909
+
4910
+ // src/patterns/harness/bridge.ts
4911
+ function evalIntakeBridge(evalSource, intakeTopic, opts) {
4912
+ const defaultSeverity = opts?.defaultSeverity ?? "medium";
4913
+ return effect([evalSource], ([results]) => {
4914
+ if (results == null) return;
4915
+ const runs = Array.isArray(results) ? results : [results];
4916
+ for (const run of runs) {
4917
+ for (const task2 of run.tasks) {
4918
+ if (task2.valid && task2.judge_scores?.every((s) => s.pass)) continue;
4919
+ if (!task2.valid && (!task2.judge_scores || task2.judge_scores.length === 0)) {
4920
+ intakeTopic.publish({
4921
+ source: "eval",
4922
+ summary: `Task ${task2.task_id} invalid (model: ${run.model})`,
4923
+ evidence: `Run ${run.run_id}: task produced invalid output`,
4924
+ affectsAreas: ["graphspec"],
4925
+ affectsEvalTasks: [task2.task_id],
4926
+ severity: defaultSeverity
4927
+ });
4928
+ continue;
4929
+ }
4930
+ if (task2.judge_scores) {
4931
+ for (const score of task2.judge_scores) {
4932
+ if (score.pass) continue;
4933
+ intakeTopic.publish({
4934
+ source: "eval",
4935
+ summary: `${task2.task_id}: ${score.claim} (model: ${run.model})`,
4936
+ evidence: score.reasoning,
4937
+ affectsAreas: ["graphspec"],
4938
+ affectsEvalTasks: [task2.task_id],
4939
+ severity: defaultSeverity
4940
+ });
4941
+ }
4942
+ }
4943
+ }
4944
+ }
4945
+ });
4946
+ }
4947
+
4894
4948
  // src/patterns/messaging.ts
4895
4949
  var messaging_exports = {};
4896
4950
  __export(messaging_exports, {
@@ -5784,6 +5838,326 @@ function onFailure(graph, name, source, recover, opts) {
5784
5838
  return step;
5785
5839
  }
5786
5840
 
5841
+ // src/patterns/harness/types.ts
5842
+ function strategyKey(rootCause, intervention) {
5843
+ return `${rootCause}\u2192${intervention}`;
5844
+ }
5845
+ function defaultErrorClassifier(result) {
5846
+ const d = result.detail.toLowerCase();
5847
+ if (d.includes("parse") || d.includes("json") || d.includes("config") || d.includes("validation") || d.includes("syntax")) {
5848
+ return "self-correctable";
5849
+ }
5850
+ return "structural";
5851
+ }
5852
+ var DEFAULT_SEVERITY_WEIGHTS = {
5853
+ critical: 100,
5854
+ high: 70,
5855
+ medium: 40,
5856
+ low: 10
5857
+ };
5858
+ var DEFAULT_DECAY_RATE2 = Math.LN2 / (7 * 24 * 3600);
5859
+ var DEFAULT_QUEUE_CONFIGS = {
5860
+ "auto-fix": { gated: false },
5861
+ "needs-decision": { gated: true },
5862
+ investigation: { gated: true },
5863
+ backlog: { gated: false, startOpen: false }
5864
+ };
5865
+
5866
+ // src/patterns/harness/strategy.ts
5867
+ function strategyModel() {
5868
+ const _map = reactiveMap({ name: "strategy-entries" });
5869
+ const snapshot = derived(
5870
+ [_map.node],
5871
+ ([mapSnap]) => {
5872
+ const raw = mapSnap.value.map;
5873
+ return new Map(raw);
5874
+ },
5875
+ {
5876
+ name: "strategy-model",
5877
+ equals: (a, b) => {
5878
+ const am = a;
5879
+ const bm = b;
5880
+ if (am.size !== bm.size) return false;
5881
+ for (const [k, v] of am) {
5882
+ const bv = bm.get(k);
5883
+ if (!bv || v.attempts !== bv.attempts || v.successes !== bv.successes) return false;
5884
+ }
5885
+ return true;
5886
+ }
5887
+ }
5888
+ );
5889
+ function record(rootCause, intervention, success) {
5890
+ const key = strategyKey(rootCause, intervention);
5891
+ const existing = _map.get(key);
5892
+ const attempts = (existing?.attempts ?? 0) + 1;
5893
+ const successes = (existing?.successes ?? 0) + (success ? 1 : 0);
5894
+ _map.set(key, {
5895
+ rootCause,
5896
+ intervention,
5897
+ attempts,
5898
+ successes,
5899
+ successRate: successes / attempts
5900
+ });
5901
+ }
5902
+ function lookup(rootCause, intervention) {
5903
+ return _map.get(strategyKey(rootCause, intervention));
5904
+ }
5905
+ const _unsub = snapshot.subscribe(() => {
5906
+ });
5907
+ return { node: snapshot, record, lookup };
5908
+ }
5909
+ function priorityScore(item, strategy, lastInteractionNs, urgency, signals) {
5910
+ const severityWeights = { ...DEFAULT_SEVERITY_WEIGHTS, ...signals?.severityWeights };
5911
+ const decayRate = signals?.decayRate ?? DEFAULT_DECAY_RATE2;
5912
+ const effectivenessThreshold = signals?.effectivenessThreshold ?? 0.7;
5913
+ const effectivenessBoost = signals?.effectivenessBoost ?? 15;
5914
+ const deps = [item, strategy, lastInteractionNs];
5915
+ if (urgency) deps.push(urgency);
5916
+ return derived(
5917
+ deps,
5918
+ (values) => {
5919
+ const itm = values[0];
5920
+ const strat = values[1];
5921
+ const lastNs = values[2];
5922
+ const urg = urgency ? values[3] : 0;
5923
+ const baseWeight = severityWeights[itm.severity ?? "medium"];
5924
+ const ageSeconds = (monotonicNs() - lastNs) / 1e9;
5925
+ let score = decay(baseWeight, ageSeconds, decayRate, 0);
5926
+ const key = strategyKey(itm.rootCause, itm.intervention);
5927
+ const entry = strat.get(key);
5928
+ if (entry && entry.successRate >= effectivenessThreshold) {
5929
+ score += effectivenessBoost;
5930
+ }
5931
+ score += urg * 20;
5932
+ return score;
5933
+ },
5934
+ { name: "priority-score" }
5935
+ );
5936
+ }
5937
+
5938
+ // src/patterns/harness/loop.ts
5939
+ var DEFAULT_TRIAGE_PROMPT = `You are a triage classifier for a reactive collaboration harness.
5940
+
5941
+ Given an intake item, classify it and output JSON:
5942
+ {
5943
+ "rootCause": "composition" | "missing-fn" | "bad-docs" | "schema-gap" | "regression" | "unknown",
5944
+ "intervention": "template" | "catalog-fn" | "docs" | "wrapper" | "schema-change" | "investigate",
5945
+ "route": "auto-fix" | "needs-decision" | "investigation" | "backlog",
5946
+ "priority": <number 0-100>,
5947
+ "triageReasoning": "<one sentence>"
5948
+ }
5949
+
5950
+ Strategy model (past effectiveness):
5951
+ {{strategy}}
5952
+
5953
+ Intake item:
5954
+ {{item}}`;
5955
+ var DEFAULT_EXECUTE_PROMPT = `You are an implementation agent.
5956
+
5957
+ Given a triaged issue with root cause and intervention type, produce a fix.
5958
+
5959
+ Issue:
5960
+ {{item}}
5961
+
5962
+ Output JSON:
5963
+ {
5964
+ "outcome": "success" | "failure" | "partial",
5965
+ "detail": "<description of what was done or what failed>"
5966
+ }`;
5967
+ var DEFAULT_VERIFY_PROMPT = `You are a QA reviewer.
5968
+
5969
+ Given an execution result, verify whether the fix is correct.
5970
+
5971
+ Execution:
5972
+ {{execution}}
5973
+
5974
+ Original issue:
5975
+ {{item}}
5976
+
5977
+ Output JSON:
5978
+ {
5979
+ "verified": true/false,
5980
+ "findings": ["<finding1>", ...],
5981
+ "errorClass": "self-correctable" | "structural" // only if verified=false
5982
+ }`;
5983
+ var QUEUE_NAMES = [
5984
+ "auto-fix",
5985
+ "needs-decision",
5986
+ "investigation",
5987
+ "backlog"
5988
+ ];
5989
+ var HarnessGraph = class extends Graph {
5990
+ /** Intake topic — publish items here to enter the loop. */
5991
+ intake;
5992
+ /** Per-route queue topics. */
5993
+ queues;
5994
+ /** Per-route gate controllers (only for gated queues). */
5995
+ gates;
5996
+ /** Strategy model bundle — record outcomes, lookup effectiveness. */
5997
+ strategy;
5998
+ /** Verify results topic — subscribe to see verification outcomes. */
5999
+ verifyResults;
6000
+ constructor(name, intake, queues, gates, strategy, verifyResults) {
6001
+ super(name);
6002
+ this.intake = intake;
6003
+ this.queues = queues;
6004
+ this.gates = gates;
6005
+ this.strategy = strategy;
6006
+ this.verifyResults = verifyResults;
6007
+ }
6008
+ };
6009
+ function harnessLoop(name, opts) {
6010
+ const adapter = opts.adapter;
6011
+ const maxRetries = opts.maxRetries ?? 2;
6012
+ const retainedLimit = opts.retainedLimit ?? 1e3;
6013
+ const errorClassifier = opts.errorClassifier ?? defaultErrorClassifier;
6014
+ const queueConfigs = /* @__PURE__ */ new Map();
6015
+ for (const route of QUEUE_NAMES) {
6016
+ queueConfigs.set(route, {
6017
+ ...DEFAULT_QUEUE_CONFIGS[route],
6018
+ ...opts.queues?.[route]
6019
+ });
6020
+ }
6021
+ const intake = new TopicGraph("intake", { retainedLimit });
6022
+ const strategy = strategyModel();
6023
+ const triageNode = promptNode(
6024
+ adapter,
6025
+ [intake.latest, strategy.node],
6026
+ opts.triagePrompt ?? ((item, strat) => {
6027
+ return DEFAULT_TRIAGE_PROMPT.replace("{{strategy}}", JSON.stringify(strat)).replace(
6028
+ "{{item}}",
6029
+ JSON.stringify(item)
6030
+ );
6031
+ }),
6032
+ {
6033
+ name: "triage",
6034
+ format: "json",
6035
+ retries: 1
6036
+ }
6037
+ );
6038
+ const queueTopics = /* @__PURE__ */ new Map();
6039
+ for (const route of QUEUE_NAMES) {
6040
+ queueTopics.set(route, new TopicGraph(`queue/${route}`, { retainedLimit }));
6041
+ }
6042
+ const _router = effect([triageNode], ([triaged]) => {
6043
+ const item = triaged;
6044
+ if (!item || !item.route) return;
6045
+ const topic2 = queueTopics.get(item.route);
6046
+ if (topic2) topic2.publish(item);
6047
+ });
6048
+ const gateGraph = new Graph("gates");
6049
+ const gateControllers = /* @__PURE__ */ new Map();
6050
+ for (const route of QUEUE_NAMES) {
6051
+ const config = queueConfigs.get(route);
6052
+ const topic2 = queueTopics.get(route);
6053
+ if (config.gated) {
6054
+ gateGraph.add(`${route}/source`, topic2.latest);
6055
+ const ctrl = gate(gateGraph, `${route}/gate`, `${route}/source`, {
6056
+ maxPending: config.maxPending,
6057
+ startOpen: config.startOpen
6058
+ });
6059
+ gateControllers.set(route, ctrl);
6060
+ }
6061
+ }
6062
+ const retryTopic = new TopicGraph("retry-input", { retainedLimit });
6063
+ const queueOutputs = [];
6064
+ for (const route of QUEUE_NAMES) {
6065
+ const config = queueConfigs.get(route);
6066
+ if (config.gated && gateControllers.has(route)) {
6067
+ queueOutputs.push(gateControllers.get(route).node);
6068
+ } else {
6069
+ queueOutputs.push(queueTopics.get(route).latest);
6070
+ }
6071
+ }
6072
+ queueOutputs.push(retryTopic.latest);
6073
+ const executeInput = merge(...queueOutputs);
6074
+ const executeNode = promptNode(
6075
+ adapter,
6076
+ [executeInput],
6077
+ opts.executePrompt ?? ((item) => {
6078
+ return DEFAULT_EXECUTE_PROMPT.replace("{{item}}", JSON.stringify(item));
6079
+ }),
6080
+ {
6081
+ name: "execute",
6082
+ format: "json",
6083
+ retries: 1
6084
+ }
6085
+ );
6086
+ const verifyResults = new TopicGraph("verify-results", { retainedLimit });
6087
+ const verifyNode = promptNode(
6088
+ adapter,
6089
+ [executeNode, executeInput],
6090
+ opts.verifyPrompt ?? ((execution, item) => {
6091
+ return DEFAULT_VERIFY_PROMPT.replace("{{execution}}", JSON.stringify(execution)).replace(
6092
+ "{{item}}",
6093
+ JSON.stringify(item)
6094
+ );
6095
+ }),
6096
+ {
6097
+ name: "verify",
6098
+ format: "json",
6099
+ retries: 1
6100
+ }
6101
+ );
6102
+ const maxReingestions = opts.maxReingestions ?? 1;
6103
+ let reingestionCount = 0;
6104
+ const _fastRetry = effect([verifyNode], ([result]) => {
6105
+ const vr = result;
6106
+ if (!vr) return;
6107
+ if (vr.verified) {
6108
+ strategy.record(vr.item.rootCause, vr.item.intervention, true);
6109
+ verifyResults.publish(vr);
6110
+ return;
6111
+ }
6112
+ const errClass = vr.errorClass ?? errorClassifier({
6113
+ item: vr.item,
6114
+ outcome: "failure",
6115
+ detail: vr.findings.join("; "),
6116
+ retryCount: 0
6117
+ });
6118
+ const exec = vr.execution;
6119
+ const retryCount = exec?.retryCount ?? 0;
6120
+ if (errClass === "self-correctable" && retryCount < maxRetries) {
6121
+ const retryItem = {
6122
+ ...vr.item,
6123
+ summary: `[RETRY ${retryCount + 1}/${maxRetries}] ${vr.item.summary} \u2014 Previous attempt failed: ${vr.findings.join("; ")}`
6124
+ };
6125
+ retryTopic.publish(retryItem);
6126
+ } else {
6127
+ strategy.record(vr.item.rootCause, vr.item.intervention, false);
6128
+ verifyResults.publish(vr);
6129
+ if (reingestionCount < maxReingestions) {
6130
+ reingestionCount++;
6131
+ intake.publish({
6132
+ source: "eval",
6133
+ summary: `Verification failed for: ${vr.item.summary}`,
6134
+ evidence: vr.findings.join("\n"),
6135
+ affectsAreas: vr.item.affectsAreas,
6136
+ affectsEvalTasks: vr.item.affectsEvalTasks,
6137
+ severity: "high",
6138
+ relatedTo: [vr.item.summary]
6139
+ });
6140
+ }
6141
+ }
6142
+ });
6143
+ const harness = new HarnessGraph(
6144
+ name,
6145
+ intake,
6146
+ queueTopics,
6147
+ gateControllers,
6148
+ strategy,
6149
+ verifyResults
6150
+ );
6151
+ harness.mount("intake", intake);
6152
+ for (const [route, topic2] of queueTopics) {
6153
+ harness.mount(`queue/${route}`, topic2);
6154
+ }
6155
+ harness.mount("gates", gateGraph);
6156
+ harness.mount("retry-input", retryTopic);
6157
+ harness.mount("verify-results", verifyResults);
6158
+ return harness;
6159
+ }
6160
+
5787
6161
  // src/index.ts
5788
6162
  var version = "0.0.0";
5789
6163
  export {
@@ -5907,6 +6281,7 @@ export {
5907
6281
  globToRegExp,
5908
6282
  graph_exports as graph,
5909
6283
  graphspec_exports as graphspec,
6284
+ harness_exports as harness,
5910
6285
  interval,
5911
6286
  isBatching,
5912
6287
  isKnownMessageType,