@tangle-network/agent-eval 0.121.0 → 0.122.1

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.
@@ -25,11 +25,8 @@ import {
25
25
  stripFencedJson
26
26
  } from "./chunk-NJC7U437.js";
27
27
  import {
28
- mcnemar,
29
28
  pairedBootstrap,
30
- pairedRiskDifference,
31
- weightedComposite,
32
- wilcoxonSignedRank
29
+ weightedComposite
33
30
  } from "./chunk-PJQFMIOX.js";
34
31
  import {
35
32
  CostLedger
@@ -299,155 +296,6 @@ async function runJudgeChat(tc, input, judgeName, request) {
299
296
  return paid.value;
300
297
  }
301
298
 
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
-
451
299
  // src/pareto.ts
452
300
  function dominates(a, b, objectives) {
453
301
  let strictlyBetter = false;
@@ -2256,6 +2104,7 @@ function recoverFrom(slice) {
2256
2104
  }
2257
2105
 
2258
2106
  // src/reflective-mutation.ts
2107
+ var EMITTED_EVIDENCE_MAX_CHARS = 2e3;
2259
2108
  var DEFAULT_MUTATION_PRIMITIVES = [
2260
2109
  'Strengthen an imperative ("should" \u2192 "must")',
2261
2110
  "Add a concrete example pulled from a missed-golden phrase",
@@ -2287,7 +2136,7 @@ function buildReflectionPrompt(ctx) {
2287
2136
  );
2288
2137
  if (trial.failureNote) {
2289
2138
  sections.push("");
2290
- sections.push(`**Why it scored low:** ${truncate(trial.failureNote, 600)}`);
2139
+ sections.push(`**Why it scored low:** ${truncate(trial.failureNote, 1500)}`);
2291
2140
  }
2292
2141
  const missed = (trial.expectations ?? []).filter((e) => !e.matched);
2293
2142
  if (missed.length > 0) {
@@ -2301,7 +2150,7 @@ function buildReflectionPrompt(ctx) {
2301
2150
  sections.push("");
2302
2151
  sections.push("**What the agent emitted:**");
2303
2152
  sections.push("```");
2304
- sections.push(truncate(trial.emitted, 600));
2153
+ sections.push(truncate(trial.emitted, EMITTED_EVIDENCE_MAX_CHARS));
2305
2154
  sections.push("```");
2306
2155
  }
2307
2156
  sections.push("");
@@ -2712,7 +2561,11 @@ function buildEvidence(ctx, evidenceK, baseTarget) {
2712
2561
  score: s.composite,
2713
2562
  // The judge's "why it scored low" — grounds the reflection on real failure
2714
2563
  // patterns instead of blind rephrasing. Generalizable by the judge contract.
2715
- ...s.notes ? { failureNote: s.notes } : {}
2564
+ ...s.notes ? { failureNote: s.notes } : {},
2565
+ // The candidate's raw output for the scenario — buildReflectionPrompt
2566
+ // renders it as the "what the agent emitted" block, so the reflection sees
2567
+ // the actual wrong output, not just the score.
2568
+ ...s.emitted ? { emitted: s.emitted } : {}
2716
2569
  });
2717
2570
  const top = byScore.slice(0, evidenceK).map(toTrace);
2718
2571
  const bottom = byScore.slice(-evidenceK).reverse().map(toTrace);
@@ -2737,6 +2590,7 @@ function campaignBreakdown(campaign) {
2737
2590
  const dimCounts = {};
2738
2591
  const byScenario = /* @__PURE__ */ new Map();
2739
2592
  const notesByScenario = /* @__PURE__ */ new Map();
2593
+ const emittedByScenario = /* @__PURE__ */ new Map();
2740
2594
  for (const cell of campaign.cells) {
2741
2595
  const judgeScores = Object.values(cell.judgeScores).filter(
2742
2596
  (score) => score.failed !== true && Number.isFinite(score.composite)
@@ -2746,6 +2600,15 @@ function campaignBreakdown(campaign) {
2746
2600
  const arr = byScenario.get(cell.scenarioId) ?? [];
2747
2601
  arr.push(cellComposite);
2748
2602
  byScenario.set(cell.scenarioId, arr);
2603
+ if (typeof cell.artifact === "string" && cell.artifact.trim().length > 0) {
2604
+ const prev = emittedByScenario.get(cell.scenarioId);
2605
+ if (!prev || cellComposite < prev.composite) {
2606
+ emittedByScenario.set(cell.scenarioId, {
2607
+ composite: cellComposite,
2608
+ text: cell.artifact.slice(0, EMITTED_EVIDENCE_MAX_CHARS)
2609
+ });
2610
+ }
2611
+ }
2749
2612
  for (const s of judgeScores) {
2750
2613
  if (s.notes?.trim()) {
2751
2614
  const set = notesByScenario.get(cell.scenarioId) ?? /* @__PURE__ */ new Set();
@@ -2769,10 +2632,12 @@ function campaignBreakdown(campaign) {
2769
2632
  const scenarios = [...byScenario.entries()].map(([scenarioId, comps]) => {
2770
2633
  const notesSet = notesByScenario.get(scenarioId);
2771
2634
  const notes = notesSet && notesSet.size > 0 ? [...notesSet].join(" | ") : void 0;
2635
+ const emitted = emittedByScenario.get(scenarioId)?.text;
2772
2636
  return {
2773
2637
  scenarioId,
2774
2638
  composite: comps.reduce((a, b) => a + b, 0) / comps.length,
2775
- ...notes ? { notes } : {}
2639
+ ...notes ? { notes } : {},
2640
+ ...emitted ? { emitted } : {}
2776
2641
  };
2777
2642
  });
2778
2643
  return { dimensions, scenarios };
@@ -3811,8 +3676,6 @@ export {
3811
3676
  adversarialJudge,
3812
3677
  createCustomJudge,
3813
3678
  defaultJudges,
3814
- pairArms,
3815
- comparePairedArms,
3816
3679
  recoverTruncatedJson,
3817
3680
  dominates,
3818
3681
  paretoFrontier,
@@ -3875,4 +3738,4 @@ export {
3875
3738
  provenanceSpansPath,
3876
3739
  emitLoopProvenance
3877
3740
  };
3878
- //# sourceMappingURL=chunk-32BZXMSO.js.map
3741
+ //# sourceMappingURL=chunk-VZ6VKOJT.js.map