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