@tangle-network/agent-eval 0.119.0 → 0.120.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/CHANGELOG.md +25 -3
- package/README.md +0 -26
- package/dist/analyst/index.d.ts +30 -39
- package/dist/analyst/index.js +9 -5
- package/dist/analyst/index.js.map +1 -1
- package/dist/benchmarks/index.d.ts +11 -5
- package/dist/benchmarks/index.js +7 -7
- package/dist/campaign/index.d.ts +121 -66
- package/dist/campaign/index.js +26 -10
- package/dist/{chunk-RLCJQ6VZ.js → chunk-32BZXMSO.js} +385 -120
- package/dist/chunk-32BZXMSO.js.map +1 -0
- package/dist/{chunk-XJ7JVCHB.js → chunk-3A246TSA.js} +2 -2
- package/dist/{chunk-LMJ2TGWJ.js → chunk-JM2SKQMS.js} +2 -2
- package/dist/{chunk-F6YUH3L4.js → chunk-JN2FCO5W.js} +14 -168
- package/dist/chunk-JN2FCO5W.js.map +1 -0
- package/dist/{chunk-D7AEXSM5.js → chunk-PICTDURQ.js} +2 -2
- package/dist/{chunk-6QIM2EAP.js → chunk-PXD6ZFNY.js} +99 -1
- package/dist/chunk-PXD6ZFNY.js.map +1 -0
- package/dist/{chunk-GERDAIAL.js → chunk-QWMPPZ3X.js} +3 -3
- package/dist/{chunk-7A4LIMMY.js → chunk-S5TT5R3L.js} +229 -97
- package/dist/chunk-S5TT5R3L.js.map +1 -0
- package/dist/{chunk-ZYHJNKI3.js → chunk-ULOKLHIQ.js} +42 -5
- package/dist/chunk-ULOKLHIQ.js.map +1 -0
- package/dist/{chunk-FIUFRXP3.js → chunk-WW2A73HW.js} +49 -91
- package/dist/chunk-WW2A73HW.js.map +1 -0
- package/dist/{chunk-PAHNGS65.js → chunk-XDIRG3TO.js} +175 -11
- package/dist/chunk-XDIRG3TO.js.map +1 -0
- package/dist/contract/index.d.ts +76 -43
- package/dist/contract/index.js +596 -32
- package/dist/contract/index.js.map +1 -1
- package/dist/index.d.ts +92 -75
- package/dist/index.js +38 -35
- package/dist/index.js.map +1 -1
- package/dist/openapi.json +1 -1
- package/dist/rl.d.ts +11 -5
- package/dist/{run-campaign-OBXSN5WK.js → run-campaign-HNFPJET4.js} +2 -2
- package/dist/traces.d.ts +39 -25
- package/dist/traces.js +3 -5
- package/docs/trace-analysis.md +6 -2
- package/package.json +2 -7
- package/dist/chunk-6QIM2EAP.js.map +0 -1
- package/dist/chunk-7A4LIMMY.js.map +0 -1
- package/dist/chunk-F6YUH3L4.js.map +0 -1
- package/dist/chunk-FIUFRXP3.js.map +0 -1
- package/dist/chunk-PAHNGS65.js.map +0 -1
- package/dist/chunk-RLCJQ6VZ.js.map +0 -1
- package/dist/chunk-ZYHJNKI3.js.map +0 -1
- package/dist/primeintellect/index.d.ts +0 -311
- package/dist/primeintellect/index.js +0 -348
- package/dist/primeintellect/index.js.map +0 -1
- /package/dist/{chunk-XJ7JVCHB.js.map → chunk-3A246TSA.js.map} +0 -0
- /package/dist/{chunk-LMJ2TGWJ.js.map → chunk-JM2SKQMS.js.map} +0 -0
- /package/dist/{chunk-D7AEXSM5.js.map → chunk-PICTDURQ.js.map} +0 -0
- /package/dist/{chunk-GERDAIAL.js.map → chunk-QWMPPZ3X.js.map} +0 -0
- /package/dist/{run-campaign-OBXSN5WK.js.map → run-campaign-HNFPJET4.js.map} +0 -0
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
|
+
assertCampaignSplitIdentity,
|
|
3
|
+
campaignCoverage,
|
|
4
|
+
canonicalJson,
|
|
2
5
|
contentHash,
|
|
3
6
|
createRunCostLedger,
|
|
7
|
+
formatCoverageFailures,
|
|
4
8
|
fsCampaignStorage,
|
|
5
9
|
resolveRunDir,
|
|
6
10
|
runCampaign,
|
|
7
|
-
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
summarizeAgentReceiptIntegrity
|
|
12
|
+
} from "./chunk-XDIRG3TO.js";
|
|
9
13
|
import {
|
|
10
14
|
clamp01,
|
|
11
15
|
validatePolicyEditCandidateRecord
|
|
12
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-S5TT5R3L.js";
|
|
13
17
|
import {
|
|
14
18
|
detectRewardHacking
|
|
15
19
|
} from "./chunk-ARU2PZFM.js";
|
|
@@ -21,8 +25,11 @@ import {
|
|
|
21
25
|
stripFencedJson
|
|
22
26
|
} from "./chunk-NJC7U437.js";
|
|
23
27
|
import {
|
|
28
|
+
mcnemar,
|
|
24
29
|
pairedBootstrap,
|
|
25
|
-
|
|
30
|
+
pairedRiskDifference,
|
|
31
|
+
weightedComposite,
|
|
32
|
+
wilcoxonSignedRank
|
|
26
33
|
} from "./chunk-PJQFMIOX.js";
|
|
27
34
|
import {
|
|
28
35
|
CostLedger
|
|
@@ -292,6 +299,155 @@ async function runJudgeChat(tc, input, judgeName, request) {
|
|
|
292
299
|
return paid.value;
|
|
293
300
|
}
|
|
294
301
|
|
|
302
|
+
// src/paired-arms.ts
|
|
303
|
+
function pairArms(rows, opts) {
|
|
304
|
+
const { baselineArm, treatmentArm } = opts;
|
|
305
|
+
if (baselineArm === treatmentArm) {
|
|
306
|
+
throw new ValidationError(
|
|
307
|
+
`pairArms: baselineArm and treatmentArm are both '${baselineArm}' \u2014 an arm cannot be compared to itself`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
const byArm = /* @__PURE__ */ new Map();
|
|
311
|
+
const armsSeen = /* @__PURE__ */ new Set();
|
|
312
|
+
for (const row of rows) {
|
|
313
|
+
armsSeen.add(row.arm);
|
|
314
|
+
if (row.arm !== baselineArm && row.arm !== treatmentArm) continue;
|
|
315
|
+
const byKey = byArm.get(row.arm) ?? /* @__PURE__ */ new Map();
|
|
316
|
+
const group = byKey.get(row.pairKey) ?? [];
|
|
317
|
+
group.push(row);
|
|
318
|
+
byKey.set(row.pairKey, group);
|
|
319
|
+
byArm.set(row.arm, byKey);
|
|
320
|
+
}
|
|
321
|
+
for (const arm of [baselineArm, treatmentArm]) {
|
|
322
|
+
if (!byArm.has(arm)) {
|
|
323
|
+
const seen = [...armsSeen].sort().join(", ") || "<none>";
|
|
324
|
+
throw new ValidationError(`pairArms: no rows for arm '${arm}' (arms present: ${seen})`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const baselineByKey = byArm.get(baselineArm);
|
|
328
|
+
const treatmentByKey = byArm.get(treatmentArm);
|
|
329
|
+
const allKeys = [.../* @__PURE__ */ new Set([...baselineByKey.keys(), ...treatmentByKey.keys()])].sort();
|
|
330
|
+
const pairs = [];
|
|
331
|
+
const unpairedBaseline = [];
|
|
332
|
+
const unpairedTreatment = [];
|
|
333
|
+
for (const pairKey of allKeys) {
|
|
334
|
+
const b = baselineByKey.get(pairKey) ?? [];
|
|
335
|
+
const t = treatmentByKey.get(pairKey) ?? [];
|
|
336
|
+
if (b.length <= 1 && t.length <= 1) {
|
|
337
|
+
if (b.length === 1 && t.length === 1) {
|
|
338
|
+
pairs.push({ pairKey, repIndex: 0, baseline: b[0], treatment: t[0] });
|
|
339
|
+
} else {
|
|
340
|
+
unpairedBaseline.push(...b);
|
|
341
|
+
unpairedTreatment.push(...t);
|
|
342
|
+
}
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
const bByRep = indexByRepKey(b, pairKey, baselineArm);
|
|
346
|
+
const tByRep = indexByRepKey(t, pairKey, treatmentArm);
|
|
347
|
+
const repKeys = [.../* @__PURE__ */ new Set([...bByRep.keys(), ...tByRep.keys()])].sort();
|
|
348
|
+
let repIndex = 0;
|
|
349
|
+
for (const repKey of repKeys) {
|
|
350
|
+
const baseline = bByRep.get(repKey);
|
|
351
|
+
const treatment = tByRep.get(repKey);
|
|
352
|
+
if (baseline !== void 0 && treatment !== void 0) {
|
|
353
|
+
pairs.push({ pairKey, repIndex: repIndex++, baseline, treatment });
|
|
354
|
+
} else if (baseline !== void 0) {
|
|
355
|
+
unpairedBaseline.push(baseline);
|
|
356
|
+
} else if (treatment !== void 0) {
|
|
357
|
+
unpairedTreatment.push(treatment);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return { pairs, unpairedBaseline, unpairedTreatment };
|
|
362
|
+
}
|
|
363
|
+
function indexByRepKey(group, pairKey, arm) {
|
|
364
|
+
const byRep = /* @__PURE__ */ new Map();
|
|
365
|
+
for (const row of group) {
|
|
366
|
+
if (row.repKey === void 0) {
|
|
367
|
+
throw new ValidationError(
|
|
368
|
+
`pairArms: pairKey '${pairKey}' has multiple reps in an arm, but a row in arm '${arm}' is missing repKey \u2014 multi-rep items require an explicit repKey on every row so reps pair by identity (pairing reps by outcome or by index would bias the paired statistics)`
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
if (byRep.has(row.repKey)) {
|
|
372
|
+
throw new ValidationError(
|
|
373
|
+
`pairArms: duplicate repKey '${row.repKey}' for pairKey '${pairKey}' in arm '${arm}' \u2014 (pairKey, repKey) must uniquely identify a rep within an arm`
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
byRep.set(row.repKey, row);
|
|
377
|
+
}
|
|
378
|
+
return byRep;
|
|
379
|
+
}
|
|
380
|
+
function comparePairedArms(rows, opts) {
|
|
381
|
+
const { pairs, unpairedBaseline, unpairedTreatment } = pairArms(rows, opts);
|
|
382
|
+
let correctness = null;
|
|
383
|
+
const baselinePass = [];
|
|
384
|
+
const treatmentPass = [];
|
|
385
|
+
for (const pair of pairs) {
|
|
386
|
+
if (pair.baseline.pass === void 0 || pair.treatment.pass === void 0) continue;
|
|
387
|
+
baselinePass.push(pair.baseline.pass ? 1 : 0);
|
|
388
|
+
treatmentPass.push(pair.treatment.pass ? 1 : 0);
|
|
389
|
+
}
|
|
390
|
+
if (baselinePass.length > 0) {
|
|
391
|
+
const mc = mcnemar(baselinePass, treatmentPass);
|
|
392
|
+
correctness = {
|
|
393
|
+
b10: mc.b,
|
|
394
|
+
b01: mc.c,
|
|
395
|
+
mcnemar: mc,
|
|
396
|
+
riskDifference: pairedRiskDifference(baselinePass, treatmentPass)
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
const metricNames = opts.metricNames ?? [
|
|
400
|
+
...new Set(
|
|
401
|
+
pairs.flatMap((p) => [
|
|
402
|
+
...Object.keys(p.baseline.metrics ?? {}),
|
|
403
|
+
...Object.keys(p.treatment.metrics ?? {})
|
|
404
|
+
])
|
|
405
|
+
)
|
|
406
|
+
].sort();
|
|
407
|
+
const metricDeltas = metricNames.map((name) => {
|
|
408
|
+
const before = [];
|
|
409
|
+
const after = [];
|
|
410
|
+
let nMissing = 0;
|
|
411
|
+
for (const pair of pairs) {
|
|
412
|
+
const b = metricValue(pair.baseline, name);
|
|
413
|
+
const t = metricValue(pair.treatment, name);
|
|
414
|
+
if (b === void 0 || t === void 0) {
|
|
415
|
+
nMissing++;
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
before.push(b);
|
|
419
|
+
after.push(t);
|
|
420
|
+
}
|
|
421
|
+
const bootstrapCi = before.length === 0 ? null : pairedBootstrap(before, after, opts.bootstrap);
|
|
422
|
+
return {
|
|
423
|
+
name,
|
|
424
|
+
n: before.length,
|
|
425
|
+
nMissing,
|
|
426
|
+
medianDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.median,
|
|
427
|
+
meanDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.mean,
|
|
428
|
+
bootstrapCi,
|
|
429
|
+
wilcoxon: before.length === 0 ? null : wilcoxonSignedRank(before, after)
|
|
430
|
+
};
|
|
431
|
+
});
|
|
432
|
+
return {
|
|
433
|
+
nPairs: pairs.length,
|
|
434
|
+
nUnpairedBaseline: unpairedBaseline.length,
|
|
435
|
+
nUnpairedTreatment: unpairedTreatment.length,
|
|
436
|
+
correctness,
|
|
437
|
+
metricDeltas
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function metricValue(row, name) {
|
|
441
|
+
const v = row.metrics?.[name];
|
|
442
|
+
if (v === void 0) return void 0;
|
|
443
|
+
if (!Number.isFinite(v)) {
|
|
444
|
+
throw new ValidationError(
|
|
445
|
+
`comparePairedArms: non-finite value for metric '${name}' on pairKey '${row.pairKey}' (arm '${row.arm}'): ${v}`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
return v;
|
|
449
|
+
}
|
|
450
|
+
|
|
295
451
|
// src/pareto.ts
|
|
296
452
|
function dominates(a, b, objectives) {
|
|
297
453
|
let strictlyBetter = false;
|
|
@@ -1679,7 +1835,7 @@ function defaultProductionGate(options) {
|
|
|
1679
1835
|
detail: {
|
|
1680
1836
|
candidateUsd: ctx.cost.candidate,
|
|
1681
1837
|
baselineUsd: ctx.cost.baseline,
|
|
1682
|
-
budgetUsd: options.budgetUsd
|
|
1838
|
+
...options.budgetUsd === void 0 ? {} : { budgetUsd: options.budgetUsd }
|
|
1683
1839
|
}
|
|
1684
1840
|
});
|
|
1685
1841
|
if (!budgetPass) {
|
|
@@ -2326,7 +2482,7 @@ function assertCodeSurfaceIdentity(surface) {
|
|
|
2326
2482
|
function codeSurfaceIdentityMaterial(surface) {
|
|
2327
2483
|
assertCodeSurfaceIdentity(surface);
|
|
2328
2484
|
return JSON.stringify({
|
|
2329
|
-
schema: "tangle.code-surface
|
|
2485
|
+
schema: "tangle.code-surface",
|
|
2330
2486
|
baseCommit: surface.baseCommit,
|
|
2331
2487
|
baseTree: surface.baseTree,
|
|
2332
2488
|
candidateTree: surface.candidateTree,
|
|
@@ -2344,6 +2500,33 @@ function surfaceContentHash(surface) {
|
|
|
2344
2500
|
function surfaceHash(surface) {
|
|
2345
2501
|
return surfaceContentHash(surface).slice("sha256:".length, "sha256:".length + 16);
|
|
2346
2502
|
}
|
|
2503
|
+
function renderSurfaceDiff(winnerSurface, baselineSurface) {
|
|
2504
|
+
if (typeof winnerSurface === "string" && typeof baselineSurface === "string") {
|
|
2505
|
+
return [
|
|
2506
|
+
"--- baseline",
|
|
2507
|
+
"+++ winner",
|
|
2508
|
+
...baselineSurface.split("\n").map((line) => `- ${line}`),
|
|
2509
|
+
...winnerSurface.split("\n").map((line) => `+ ${line}`)
|
|
2510
|
+
].join("\n");
|
|
2511
|
+
}
|
|
2512
|
+
const describe = (surface) => {
|
|
2513
|
+
if (typeof surface === "string") return "(prompt surface)";
|
|
2514
|
+
assertCodeSurfaceIdentity(surface);
|
|
2515
|
+
return [
|
|
2516
|
+
`baseCommit=${surface.baseCommit}`,
|
|
2517
|
+
`baseTree=${surface.baseTree}`,
|
|
2518
|
+
`candidateCommit=${surface.candidateCommit}`,
|
|
2519
|
+
`candidateTree=${surface.candidateTree}`,
|
|
2520
|
+
`patch=${surface.patch.sha256}`,
|
|
2521
|
+
`patchBytes=${surface.patch.byteLength}`,
|
|
2522
|
+
...surface.summary ? [surface.summary] : []
|
|
2523
|
+
].join("\n");
|
|
2524
|
+
};
|
|
2525
|
+
return `--- baseline
|
|
2526
|
+
${describe(baselineSurface)}
|
|
2527
|
+
+++ winner
|
|
2528
|
+
${describe(winnerSurface)}`;
|
|
2529
|
+
}
|
|
2347
2530
|
|
|
2348
2531
|
// src/campaign/proposers/gepa.ts
|
|
2349
2532
|
var REFLECTION_SYSTEM = 'You are an expert prompt engineer performing GEPA-style reflective mutation. You are given a prompt surface, its top trials (preserve what works) and its bottom trials (the evidence to fix). For each proposal, reason in this order before writing the payload: (1) LOCALIZE \u2014 point to the exact span of the current surface responsible for a bottom-trial failure; (2) DIAGNOSE the root cause (a missing rule, an ambiguous instruction, an over-broad directive), not just the symptom; (3) propose the MINIMAL, GENERALIZABLE edit that fixes the whole failure class \u2014 state it as a rule the agent should follow, never a patch memorized to the shown trials (that is overfitting and will not transfer to the held-out set); (4) PRESERVE every instruction the top trials depend on \u2014 do not delete or weaken working guidance. Put this localize\u2192diagnose\u2192fix reasoning in each proposal\'s `rationale`. Output ONLY a JSON object of shape {"proposals":[{"label":string,"rationale":string,"payload":string}]} where each `payload` is the FULL improved surface text. No prose outside the JSON.';
|
|
@@ -2595,79 +2778,6 @@ function campaignBreakdown(campaign) {
|
|
|
2595
2778
|
return { dimensions, scenarios };
|
|
2596
2779
|
}
|
|
2597
2780
|
|
|
2598
|
-
// src/campaign/coverage.ts
|
|
2599
|
-
function campaignCoverage(cells, scenarios, reps, requireJudgeScore) {
|
|
2600
|
-
const expectedCellIds = designedCellIds(scenarios, reps);
|
|
2601
|
-
const cellsById = /* @__PURE__ */ new Map();
|
|
2602
|
-
for (const cell of cells) {
|
|
2603
|
-
const matches = cellsById.get(cell.cellId) ?? [];
|
|
2604
|
-
matches.push(cell);
|
|
2605
|
-
cellsById.set(cell.cellId, matches);
|
|
2606
|
-
}
|
|
2607
|
-
const scorableCellIds = [];
|
|
2608
|
-
const unscorableCells = [];
|
|
2609
|
-
for (const cellId of expectedCellIds) {
|
|
2610
|
-
const matches = cellsById.get(cellId) ?? [];
|
|
2611
|
-
if (matches.length === 0) {
|
|
2612
|
-
unscorableCells.push({ cellId, reason: "missing campaign cell" });
|
|
2613
|
-
continue;
|
|
2614
|
-
}
|
|
2615
|
-
if (matches.length > 1) {
|
|
2616
|
-
unscorableCells.push({ cellId, reason: `duplicate campaign cell (${matches.length})` });
|
|
2617
|
-
continue;
|
|
2618
|
-
}
|
|
2619
|
-
const cell = matches[0];
|
|
2620
|
-
const scoreEntries = Object.entries(cell.judgeScores);
|
|
2621
|
-
const successfulScores = scoreEntries.map(([, score]) => score).filter((score) => score.failed !== true && Number.isFinite(score.composite));
|
|
2622
|
-
const nonFiniteScores = scoreEntries.filter(
|
|
2623
|
-
([, score]) => score.failed !== true && (!Number.isFinite(score.composite) || Object.values(score.dimensions).some((value) => !Number.isFinite(value)))
|
|
2624
|
-
);
|
|
2625
|
-
const reasons = [];
|
|
2626
|
-
if (cell.error) reasons.push(cell.error);
|
|
2627
|
-
if (cell.artifact === null || cell.artifact === void 0) reasons.push("missing artifact");
|
|
2628
|
-
if (!cell.error && requireJudgeScore && successfulScores.length === 0) {
|
|
2629
|
-
reasons.push("no successful finite judge score");
|
|
2630
|
-
}
|
|
2631
|
-
if (scoreEntries.some(([, score]) => score.failed === true)) {
|
|
2632
|
-
reasons.push("judge score marked failed");
|
|
2633
|
-
}
|
|
2634
|
-
if (nonFiniteScores.length > 0) {
|
|
2635
|
-
reasons.push(
|
|
2636
|
-
`non-finite judge score: ${nonFiniteScores.map(([name]) => name).sort().join(", ")}`
|
|
2637
|
-
);
|
|
2638
|
-
}
|
|
2639
|
-
if (reasons.length > 0) {
|
|
2640
|
-
unscorableCells.push({ cellId, reason: reasons.join("; ") });
|
|
2641
|
-
} else {
|
|
2642
|
-
scorableCellIds.push(cellId);
|
|
2643
|
-
}
|
|
2644
|
-
}
|
|
2645
|
-
const expected = new Set(expectedCellIds);
|
|
2646
|
-
for (const cell of cells) {
|
|
2647
|
-
if (!expected.has(cell.cellId)) {
|
|
2648
|
-
unscorableCells.push({ cellId: cell.cellId, reason: "unexpected campaign cell" });
|
|
2649
|
-
}
|
|
2650
|
-
}
|
|
2651
|
-
return {
|
|
2652
|
-
complete: unscorableCells.length === 0 && scorableCellIds.length === expectedCellIds.length,
|
|
2653
|
-
expectedCellIds,
|
|
2654
|
-
scorableCellIds,
|
|
2655
|
-
unscorableCells
|
|
2656
|
-
};
|
|
2657
|
-
}
|
|
2658
|
-
function formatCoverageFailures(coverage) {
|
|
2659
|
-
const shown = coverage.unscorableCells.slice(0, 3).map((cell) => `${cell.cellId}: ${cell.reason}`).join("; ");
|
|
2660
|
-
const remainder = coverage.unscorableCells.length - Math.min(3, coverage.unscorableCells.length);
|
|
2661
|
-
return remainder > 0 ? `${shown}; +${remainder} more` : shown || "unknown coverage failure";
|
|
2662
|
-
}
|
|
2663
|
-
function designedCellIds(scenarios, reps) {
|
|
2664
|
-
const ids = [];
|
|
2665
|
-
for (const scenario of scenarios) {
|
|
2666
|
-
for (let rep = 0; rep < reps; rep++) ids.push(`${scenario.id}:${rep}`);
|
|
2667
|
-
}
|
|
2668
|
-
return ids;
|
|
2669
|
-
}
|
|
2670
|
-
|
|
2671
2781
|
// src/campaign/presets/run-optimization.ts
|
|
2672
2782
|
async function runOptimization(opts) {
|
|
2673
2783
|
const { proposer } = opts;
|
|
@@ -2760,6 +2870,7 @@ async function runOptimization(opts) {
|
|
|
2760
2870
|
costLedger,
|
|
2761
2871
|
costPhase: "search.proposal"
|
|
2762
2872
|
});
|
|
2873
|
+
if (proposed.length === 0) break;
|
|
2763
2874
|
const candidates = proposed.map(
|
|
2764
2875
|
(p) => isProposedCandidate(p) ? p : { surface: p, label: "", rationale: "" }
|
|
2765
2876
|
);
|
|
@@ -2937,7 +3048,7 @@ var DEFAULT_DISPATCH_TIMEOUT_MS = 6e5;
|
|
|
2937
3048
|
async function runImprovementLoop(opts) {
|
|
2938
3049
|
if (opts.autoOnPromote === "config") {
|
|
2939
3050
|
throw new Error(
|
|
2940
|
-
"runImprovementLoop: autoOnPromote='config'
|
|
3051
|
+
"runImprovementLoop: autoOnPromote='config' requires isolated deployment, rollback, and independent validation. Use 'pr' or 'none'."
|
|
2941
3052
|
);
|
|
2942
3053
|
}
|
|
2943
3054
|
if (opts.tracing === "off" && opts.proposer) {
|
|
@@ -2970,7 +3081,7 @@ async function runImprovementLoop(opts) {
|
|
|
2970
3081
|
const dispatchTimeoutMs = opts.dispatchTimeoutMs ?? DEFAULT_DISPATCH_TIMEOUT_MS;
|
|
2971
3082
|
const optimization = await runOptimization({ ...opts, dispatchTimeoutMs, costLedger });
|
|
2972
3083
|
const winnerIsBaseline = optimization.winnerSurfaceHash === surfaceHash(opts.baselineSurface);
|
|
2973
|
-
const { runCampaign: runCampaign2 } = await import("./run-campaign-
|
|
3084
|
+
const { runCampaign: runCampaign2 } = await import("./run-campaign-HNFPJET4.js");
|
|
2974
3085
|
const baselineOnHoldout = await runCampaign2({
|
|
2975
3086
|
...opts,
|
|
2976
3087
|
costLedger,
|
|
@@ -3020,15 +3131,18 @@ async function runImprovementLoop(opts) {
|
|
|
3020
3131
|
}
|
|
3021
3132
|
let neutralizedArtifacts;
|
|
3022
3133
|
let neutralizedJudgeScores;
|
|
3134
|
+
let neutralizedOnHoldout;
|
|
3135
|
+
let neutralizedSurface;
|
|
3023
3136
|
if (opts.neutralize && !winnerIsBaseline) {
|
|
3024
|
-
const
|
|
3025
|
-
|
|
3137
|
+
const surface = opts.neutralize(optimization.winnerSurface, opts.baselineSurface);
|
|
3138
|
+
neutralizedSurface = surface;
|
|
3139
|
+
neutralizedOnHoldout = await runCampaign2({
|
|
3026
3140
|
...opts,
|
|
3027
3141
|
costLedger,
|
|
3028
3142
|
costPhase: "holdout.neutralized",
|
|
3029
3143
|
dispatchTimeoutMs,
|
|
3030
3144
|
scenarios: opts.holdoutScenarios,
|
|
3031
|
-
dispatch: (scenario, ctx) => opts.dispatchWithSurface(
|
|
3145
|
+
dispatch: (scenario, ctx) => opts.dispatchWithSurface(surface, scenario, ctx),
|
|
3032
3146
|
runDir: `${opts.runDir}/holdout-neutralized`
|
|
3033
3147
|
});
|
|
3034
3148
|
assertCompleteHoldout("neutralized", neutralizedOnHoldout);
|
|
@@ -3064,8 +3178,7 @@ async function runImprovementLoop(opts) {
|
|
|
3064
3178
|
costPhase: "promotion.gate",
|
|
3065
3179
|
signal: new AbortController().signal
|
|
3066
3180
|
});
|
|
3067
|
-
const
|
|
3068
|
-
const promotedDiff = optimization.winnerSurfaceHash === surfaceHash(opts.baselineSurface) ? "" : render(optimization.winnerSurface, opts.baselineSurface);
|
|
3181
|
+
const promotedDiff = optimization.winnerSurfaceHash === surfaceHash(opts.baselineSurface) ? "" : renderSurfaceDiff(optimization.winnerSurface, opts.baselineSurface);
|
|
3069
3182
|
let prResult;
|
|
3070
3183
|
if (opts.autoOnPromote === "pr" && gateResult.decision === "ship") {
|
|
3071
3184
|
prResult = openAutoPr({
|
|
@@ -3080,28 +3193,13 @@ async function runImprovementLoop(opts) {
|
|
|
3080
3193
|
...optimization,
|
|
3081
3194
|
baselineOnHoldout,
|
|
3082
3195
|
winnerOnHoldout,
|
|
3196
|
+
...neutralizedOnHoldout && neutralizedSurface ? { neutralizedOnHoldout, neutralizedSurface } : {},
|
|
3083
3197
|
gateResult,
|
|
3084
3198
|
promotedDiff,
|
|
3085
3199
|
prResult,
|
|
3086
3200
|
cost: costLedger.summary()
|
|
3087
3201
|
};
|
|
3088
3202
|
}
|
|
3089
|
-
function defaultRenderDiff(winnerSurface, baselineSurface) {
|
|
3090
|
-
if (typeof winnerSurface !== "string" || typeof baselineSurface !== "string") {
|
|
3091
|
-
const fmt = (s) => typeof s === "string" ? "(prompt surface)" : `worktree=${s.worktreeRef}${s.baseRef ? ` base=${s.baseRef}` : ""}${s.summary ? `
|
|
3092
|
-
${s.summary}` : ""}`;
|
|
3093
|
-
return `--- baseline
|
|
3094
|
-
${fmt(baselineSurface)}
|
|
3095
|
-
+++ winner
|
|
3096
|
-
${fmt(winnerSurface)}`;
|
|
3097
|
-
}
|
|
3098
|
-
const lines = [];
|
|
3099
|
-
lines.push("--- baseline");
|
|
3100
|
-
lines.push("+++ winner");
|
|
3101
|
-
for (const l of baselineSurface.split("\n")) lines.push(`- ${l}`);
|
|
3102
|
-
for (const l of winnerSurface.split("\n")) lines.push(`+ ${l}`);
|
|
3103
|
-
return lines.join("\n");
|
|
3104
|
-
}
|
|
3105
3203
|
|
|
3106
3204
|
// src/campaign/presets/run-eval.ts
|
|
3107
3205
|
async function runEval(opts) {
|
|
@@ -3126,6 +3224,39 @@ function evolutionaryProposer(opts) {
|
|
|
3126
3224
|
// src/campaign/provenance.ts
|
|
3127
3225
|
import { createHash as createHash2 } from "crypto";
|
|
3128
3226
|
import { join as join2 } from "path";
|
|
3227
|
+
function loopProvenanceArgsFromResult(input) {
|
|
3228
|
+
const { result } = input;
|
|
3229
|
+
return {
|
|
3230
|
+
runId: input.runId,
|
|
3231
|
+
runDir: input.runDir,
|
|
3232
|
+
timestamp: input.timestamp,
|
|
3233
|
+
baselineSurface: input.baselineSurface,
|
|
3234
|
+
winnerSurface: result.winnerSurface,
|
|
3235
|
+
...result.winnerLabel ? { winnerLabel: result.winnerLabel } : {},
|
|
3236
|
+
...result.winnerRationale ? { winnerRationale: result.winnerRationale } : {},
|
|
3237
|
+
baselineSearchCampaign: result.baselineCampaign,
|
|
3238
|
+
generations: result.generations.map(({ record, surfaces }) => ({
|
|
3239
|
+
generationIndex: record.generationIndex,
|
|
3240
|
+
candidates: record.candidates,
|
|
3241
|
+
promoted: record.promoted,
|
|
3242
|
+
surfaces: surfaces.map(({ surfaceHash: surfaceHash2, surface, campaign }) => ({
|
|
3243
|
+
surfaceHash: surfaceHash2,
|
|
3244
|
+
surface,
|
|
3245
|
+
campaign
|
|
3246
|
+
}))
|
|
3247
|
+
})),
|
|
3248
|
+
gate: result.gateResult,
|
|
3249
|
+
baselineOnHoldout: result.baselineOnHoldout,
|
|
3250
|
+
winnerOnHoldout: result.winnerOnHoldout,
|
|
3251
|
+
...result.neutralizedSurface && result.neutralizedOnHoldout ? {
|
|
3252
|
+
neutralizedSurface: result.neutralizedSurface,
|
|
3253
|
+
neutralizedOnHoldout: result.neutralizedOnHoldout
|
|
3254
|
+
} : {},
|
|
3255
|
+
costReceipts: input.costReceipts,
|
|
3256
|
+
totalCostUsd: input.totalCostUsd,
|
|
3257
|
+
totalDurationMs: input.totalDurationMs
|
|
3258
|
+
};
|
|
3259
|
+
}
|
|
3129
3260
|
function meanHoldoutComposite(campaign) {
|
|
3130
3261
|
const xs = [];
|
|
3131
3262
|
for (const cell of campaign.cells) {
|
|
@@ -3136,29 +3267,41 @@ function meanHoldoutComposite(campaign) {
|
|
|
3136
3267
|
return xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : 0;
|
|
3137
3268
|
}
|
|
3138
3269
|
function buildLoopProvenanceRecord(args) {
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3270
|
+
if (!args.runId.trim() || !args.runDir.trim()) {
|
|
3271
|
+
throw new Error("buildLoopProvenanceRecord: runId and runDir must be non-empty");
|
|
3272
|
+
}
|
|
3273
|
+
const timestampMs = Date.parse(args.timestamp);
|
|
3274
|
+
if (!Number.isFinite(timestampMs) || new Date(timestampMs).toISOString() !== args.timestamp) {
|
|
3275
|
+
throw new Error("buildLoopProvenanceRecord: timestamp must be a canonical ISO instant");
|
|
3276
|
+
}
|
|
3277
|
+
const agentReceipts = args.costReceipts.filter((receipt) => receipt.channel === "agent");
|
|
3278
|
+
const integrity = summarizeAgentReceiptIntegrity(agentReceipts);
|
|
3279
|
+
const models = [...new Set(agentReceipts.map((receipt) => receipt.model))].sort();
|
|
3280
|
+
const baselineSearchComposite = campaignMeanComposite(args.baselineSearchCampaign);
|
|
3281
|
+
if (!Number.isFinite(baselineSearchComposite)) {
|
|
3142
3282
|
throw new Error("buildLoopProvenanceRecord: baselineSearchComposite must be finite");
|
|
3143
3283
|
}
|
|
3144
3284
|
const candidates = [];
|
|
3145
3285
|
let incumbentSurfaceHash = surfaceHash(args.baselineSurface);
|
|
3146
|
-
let incumbentComposite =
|
|
3286
|
+
let incumbentComposite = baselineSearchComposite;
|
|
3147
3287
|
let previousGeneration = -1;
|
|
3148
3288
|
for (const gen of args.generations) {
|
|
3149
|
-
if (!Number.isSafeInteger(gen.generationIndex) || gen.generationIndex
|
|
3289
|
+
if (!Number.isSafeInteger(gen.generationIndex) || gen.generationIndex !== previousGeneration + 1) {
|
|
3150
3290
|
throw new Error(
|
|
3151
|
-
"buildLoopProvenanceRecord: generation indices must be
|
|
3291
|
+
"buildLoopProvenanceRecord: generation indices must be contiguous integers starting at zero"
|
|
3152
3292
|
);
|
|
3153
3293
|
}
|
|
3154
3294
|
previousGeneration = gen.generationIndex;
|
|
3295
|
+
if (gen.candidates.length === 0) {
|
|
3296
|
+
throw new Error("buildLoopProvenanceRecord: a recorded generation must contain a candidate");
|
|
3297
|
+
}
|
|
3155
3298
|
if (new Set(gen.promoted).size !== gen.promoted.length || gen.promoted.length > 1) {
|
|
3156
3299
|
throw new Error(
|
|
3157
3300
|
"buildLoopProvenanceRecord: each generation may promote at most one candidate"
|
|
3158
3301
|
);
|
|
3159
3302
|
}
|
|
3160
3303
|
const promotedSet = new Set(gen.promoted);
|
|
3161
|
-
const surfaceByHash = new Map(gen.surfaces.map((
|
|
3304
|
+
const surfaceByHash = new Map(gen.surfaces.map((measured) => [measured.surfaceHash, measured]));
|
|
3162
3305
|
const candidateByHash = new Map(
|
|
3163
3306
|
gen.candidates.map((candidate) => [candidate.surfaceHash, candidate])
|
|
3164
3307
|
);
|
|
@@ -3185,19 +3328,26 @@ function buildLoopProvenanceRecord(args) {
|
|
|
3185
3328
|
incumbentComposite,
|
|
3186
3329
|
promotedSet.has(c.surfaceHash)
|
|
3187
3330
|
);
|
|
3188
|
-
const
|
|
3189
|
-
if (
|
|
3331
|
+
const measured = surfaceByHash.get(c.surfaceHash);
|
|
3332
|
+
if (measured === void 0) {
|
|
3190
3333
|
throw new Error("buildLoopProvenanceRecord: measured candidate is missing its surface");
|
|
3191
3334
|
}
|
|
3335
|
+
const { surface, campaign } = measured;
|
|
3192
3336
|
if (surfaceHash(surface) !== c.surfaceHash) {
|
|
3193
3337
|
throw new Error(
|
|
3194
3338
|
"buildLoopProvenanceRecord: candidate surface hash does not match its surface bytes"
|
|
3195
3339
|
);
|
|
3196
3340
|
}
|
|
3341
|
+
if (campaign.splitDigest !== args.baselineSearchCampaign.splitDigest) {
|
|
3342
|
+
throw new Error(
|
|
3343
|
+
"buildLoopProvenanceRecord: candidate campaign does not match the search split"
|
|
3344
|
+
);
|
|
3345
|
+
}
|
|
3197
3346
|
const entry = {
|
|
3198
3347
|
generation: gen.generationIndex,
|
|
3199
3348
|
surfaceHash: c.surfaceHash,
|
|
3200
3349
|
contentHash: surfaceContentHash(surface),
|
|
3350
|
+
campaignDigest: campaignMeasurementDigest(campaign),
|
|
3201
3351
|
parentSurfaceHash: c.parentSurfaceHash,
|
|
3202
3352
|
parentComposite: c.parentComposite,
|
|
3203
3353
|
eligibleForPromotion: c.eligibleForPromotion,
|
|
@@ -3233,23 +3383,61 @@ function buildLoopProvenanceRecord(args) {
|
|
|
3233
3383
|
}
|
|
3234
3384
|
const baselineHoldoutComposite = meanHoldoutComposite(args.baselineOnHoldout);
|
|
3235
3385
|
const winnerHoldoutComposite = meanHoldoutComposite(args.winnerOnHoldout);
|
|
3236
|
-
|
|
3237
|
-
|
|
3386
|
+
if (args.baselineOnHoldout.splitDigest !== args.winnerOnHoldout.splitDigest) {
|
|
3387
|
+
throw new Error("buildLoopProvenanceRecord: baseline and winner use different holdout splits");
|
|
3388
|
+
}
|
|
3389
|
+
if (args.neutralizedSurface === void 0 !== (args.neutralizedOnHoldout === void 0)) {
|
|
3390
|
+
throw new Error(
|
|
3391
|
+
"buildLoopProvenanceRecord: neutralized surface and campaign must be supplied together"
|
|
3392
|
+
);
|
|
3393
|
+
}
|
|
3394
|
+
if (args.neutralizedOnHoldout && args.neutralizedOnHoldout.splitDigest !== args.baselineOnHoldout.splitDigest) {
|
|
3395
|
+
throw new Error(
|
|
3396
|
+
"buildLoopProvenanceRecord: neutralized campaign uses a different holdout split"
|
|
3397
|
+
);
|
|
3398
|
+
}
|
|
3399
|
+
const neutralizedComposite = args.neutralizedOnHoldout ? meanHoldoutComposite(args.neutralizedOnHoldout) : void 0;
|
|
3400
|
+
const diff = surfaceContentHash(args.baselineSurface) === surfaceContentHash(args.winnerSurface) ? "" : renderSurfaceDiff(args.winnerSurface, args.baselineSurface);
|
|
3401
|
+
const recordWithoutDigest = {
|
|
3402
|
+
schema: "tangle.loop-provenance",
|
|
3238
3403
|
runId: args.runId,
|
|
3239
3404
|
runDir: args.runDir,
|
|
3240
3405
|
timestamp: args.timestamp,
|
|
3241
3406
|
baselineContentHash: surfaceContentHash(args.baselineSurface),
|
|
3242
3407
|
winnerContentHash: surfaceContentHash(args.winnerSurface),
|
|
3243
|
-
diff
|
|
3408
|
+
diff,
|
|
3244
3409
|
candidates,
|
|
3245
|
-
|
|
3410
|
+
evidence: {
|
|
3411
|
+
search: {
|
|
3412
|
+
splitDigest: args.baselineSearchCampaign.splitDigest,
|
|
3413
|
+
baselineCampaignDigest: campaignMeasurementDigest(args.baselineSearchCampaign)
|
|
3414
|
+
},
|
|
3415
|
+
holdout: {
|
|
3416
|
+
splitDigest: args.baselineOnHoldout.splitDigest,
|
|
3417
|
+
baselineCampaignDigest: campaignMeasurementDigest(args.baselineOnHoldout),
|
|
3418
|
+
winnerCampaignDigest: campaignMeasurementDigest(args.winnerOnHoldout),
|
|
3419
|
+
...args.neutralizedSurface && args.neutralizedOnHoldout && neutralizedComposite !== void 0 ? {
|
|
3420
|
+
neutralized: {
|
|
3421
|
+
contentHash: surfaceContentHash(args.neutralizedSurface),
|
|
3422
|
+
campaignDigest: campaignMeasurementDigest(args.neutralizedOnHoldout),
|
|
3423
|
+
composite: neutralizedComposite,
|
|
3424
|
+
lift: neutralizedComposite - baselineHoldoutComposite
|
|
3425
|
+
}
|
|
3426
|
+
} : {}
|
|
3427
|
+
},
|
|
3428
|
+
costReceiptsDigest: canonicalDigest(
|
|
3429
|
+
[...args.costReceipts].sort((left, right) => left.callId.localeCompare(right.callId))
|
|
3430
|
+
)
|
|
3431
|
+
},
|
|
3432
|
+
baselineSearchComposite,
|
|
3246
3433
|
gate: {
|
|
3247
3434
|
decision: args.gate.decision,
|
|
3248
3435
|
reasons: args.gate.reasons,
|
|
3249
3436
|
delta: args.gate.delta,
|
|
3250
3437
|
contributingGates: args.gate.contributingGates.map((g) => ({
|
|
3251
3438
|
name: g.name,
|
|
3252
|
-
passed: g.passed
|
|
3439
|
+
passed: g.passed,
|
|
3440
|
+
detail: durableGateDetail(g.detail)
|
|
3253
3441
|
}))
|
|
3254
3442
|
},
|
|
3255
3443
|
baselineHoldoutComposite,
|
|
@@ -3266,10 +3454,81 @@ function buildLoopProvenanceRecord(args) {
|
|
|
3266
3454
|
totalCostUsd: args.totalCostUsd,
|
|
3267
3455
|
totalDurationMs: args.totalDurationMs
|
|
3268
3456
|
};
|
|
3269
|
-
if (args.winnerLabel)
|
|
3270
|
-
if (args.winnerRationale)
|
|
3457
|
+
if (args.winnerLabel) recordWithoutDigest.winnerLabel = args.winnerLabel;
|
|
3458
|
+
if (args.winnerRationale) recordWithoutDigest.winnerRationale = args.winnerRationale;
|
|
3459
|
+
return {
|
|
3460
|
+
...recordWithoutDigest,
|
|
3461
|
+
recordDigest: canonicalDigest(recordWithoutDigest)
|
|
3462
|
+
};
|
|
3463
|
+
}
|
|
3464
|
+
function campaignMeasurementDigest(campaign) {
|
|
3465
|
+
assertCampaignSplitIdentity(campaign.scenarios, campaign.reps, campaign.splitDigest);
|
|
3466
|
+
return canonicalDigest({
|
|
3467
|
+
schema: "tangle.campaign-measurement",
|
|
3468
|
+
manifestHash: campaign.manifestHash,
|
|
3469
|
+
splitDigest: campaign.splitDigest,
|
|
3470
|
+
seed: campaign.seed,
|
|
3471
|
+
reps: campaign.reps,
|
|
3472
|
+
runDir: campaign.runDir,
|
|
3473
|
+
scenarios: campaign.scenarios,
|
|
3474
|
+
cells: [...campaign.cells].sort((left, right) => left.cellId.localeCompare(right.cellId)).map((cell) => ({
|
|
3475
|
+
manifestHash: cell.manifestHash ?? null,
|
|
3476
|
+
cellId: cell.cellId,
|
|
3477
|
+
scenarioId: cell.scenarioId,
|
|
3478
|
+
rep: cell.rep,
|
|
3479
|
+
generation: cell.generation ?? null,
|
|
3480
|
+
judgeScores: cell.judgeScores,
|
|
3481
|
+
costUsd: cell.costUsd,
|
|
3482
|
+
costEstimated: cell.costEstimated ?? null,
|
|
3483
|
+
costCallIds: [...cell.costCallIds ?? []].sort(),
|
|
3484
|
+
tokenUsage: cell.tokenUsage,
|
|
3485
|
+
resolvedModel: cell.resolvedModel ?? null,
|
|
3486
|
+
durationMs: cell.durationMs,
|
|
3487
|
+
seed: cell.seed,
|
|
3488
|
+
cached: cell.cached,
|
|
3489
|
+
error: cell.error ?? null
|
|
3490
|
+
}))
|
|
3491
|
+
});
|
|
3492
|
+
}
|
|
3493
|
+
function verifyLoopProvenanceRecord(record) {
|
|
3494
|
+
if (record.schema !== "tangle.loop-provenance") {
|
|
3495
|
+
throw new Error("loop provenance has an unsupported schema");
|
|
3496
|
+
}
|
|
3497
|
+
const { recordDigest, ...recordWithoutDigest } = record;
|
|
3498
|
+
if (recordDigest !== canonicalDigest(recordWithoutDigest)) {
|
|
3499
|
+
throw new Error("loop provenance record digest does not match its contents");
|
|
3500
|
+
}
|
|
3271
3501
|
return record;
|
|
3272
3502
|
}
|
|
3503
|
+
function canonicalDigest(value) {
|
|
3504
|
+
const json = JSON.stringify(value, function strictJson(_key, item) {
|
|
3505
|
+
if (typeof item === "number" && !Number.isFinite(item)) {
|
|
3506
|
+
throw new Error("canonical digest cannot encode a non-finite number");
|
|
3507
|
+
}
|
|
3508
|
+
if (typeof item === "bigint" || typeof item === "function" || typeof item === "symbol") {
|
|
3509
|
+
throw new Error(`canonical digest cannot encode ${typeof item}`);
|
|
3510
|
+
}
|
|
3511
|
+
if (item === void 0 && Array.isArray(this)) {
|
|
3512
|
+
throw new Error("canonical digest cannot encode an undefined array item");
|
|
3513
|
+
}
|
|
3514
|
+
if (item instanceof Map || item instanceof Set) {
|
|
3515
|
+
throw new Error(`canonical digest cannot encode ${item instanceof Map ? "Map" : "Set"}`);
|
|
3516
|
+
}
|
|
3517
|
+
return item;
|
|
3518
|
+
});
|
|
3519
|
+
if (json === void 0) throw new Error("canonical digest value is not serializable");
|
|
3520
|
+
return `sha256:${contentHash(JSON.parse(json))}`;
|
|
3521
|
+
}
|
|
3522
|
+
function durableGateDetail(detail) {
|
|
3523
|
+
if (detail === void 0) return null;
|
|
3524
|
+
try {
|
|
3525
|
+
return JSON.parse(canonicalJson(detail));
|
|
3526
|
+
} catch (cause) {
|
|
3527
|
+
throw new Error("buildLoopProvenanceRecord: gate detail must be canonical JSON", {
|
|
3528
|
+
cause
|
|
3529
|
+
});
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3273
3532
|
function validateCandidateMeasurement(candidate, expectedParentHash, expectedParentComposite, promoted) {
|
|
3274
3533
|
if (!Number.isFinite(candidate.composite)) {
|
|
3275
3534
|
throw new Error("buildLoopProvenanceRecord: candidate composite must be finite");
|
|
@@ -3552,6 +3811,8 @@ export {
|
|
|
3552
3811
|
adversarialJudge,
|
|
3553
3812
|
createCustomJudge,
|
|
3554
3813
|
defaultJudges,
|
|
3814
|
+
pairArms,
|
|
3815
|
+
comparePairedArms,
|
|
3555
3816
|
recoverTruncatedJson,
|
|
3556
3817
|
dominates,
|
|
3557
3818
|
paretoFrontier,
|
|
@@ -3594,6 +3855,7 @@ export {
|
|
|
3594
3855
|
codeSurfaceIdentityMaterial,
|
|
3595
3856
|
surfaceContentHash,
|
|
3596
3857
|
surfaceHash,
|
|
3858
|
+
renderSurfaceDiff,
|
|
3597
3859
|
gepaProposer,
|
|
3598
3860
|
extractH2Sections,
|
|
3599
3861
|
countSentenceEdits,
|
|
@@ -3601,13 +3863,16 @@ export {
|
|
|
3601
3863
|
campaignBreakdown,
|
|
3602
3864
|
runOptimization,
|
|
3603
3865
|
runImprovementLoop,
|
|
3604
|
-
defaultRenderDiff,
|
|
3605
3866
|
runEval,
|
|
3606
3867
|
evolutionaryProposer,
|
|
3868
|
+
loopProvenanceArgsFromResult,
|
|
3607
3869
|
buildLoopProvenanceRecord,
|
|
3870
|
+
campaignMeasurementDigest,
|
|
3871
|
+
verifyLoopProvenanceRecord,
|
|
3872
|
+
canonicalDigest,
|
|
3608
3873
|
loopProvenanceSpans,
|
|
3609
3874
|
provenanceRecordPath,
|
|
3610
3875
|
provenanceSpansPath,
|
|
3611
3876
|
emitLoopProvenance
|
|
3612
3877
|
};
|
|
3613
|
-
//# sourceMappingURL=chunk-
|
|
3878
|
+
//# sourceMappingURL=chunk-32BZXMSO.js.map
|