@tangle-network/agent-eval 0.122.8 → 0.123.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 (29) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/analyst/index.js +4 -4
  3. package/dist/benchmarks/index.js +5 -5
  4. package/dist/campaign/index.d.ts +140 -11
  5. package/dist/campaign/index.js +5 -5
  6. package/dist/{chunk-ULOKLHIQ.js → chunk-A5S77LSE.js} +3 -3
  7. package/dist/{chunk-MUS5DOH7.js → chunk-FC5NDO3E.js} +2 -2
  8. package/dist/{chunk-MI2H23RV.js → chunk-G2GPNLSX.js} +2 -2
  9. package/dist/{chunk-ZDAKRZG5.js → chunk-GS3FJGUF.js} +25 -6
  10. package/dist/{chunk-ZDAKRZG5.js.map → chunk-GS3FJGUF.js.map} +1 -1
  11. package/dist/{chunk-S6IL3R5I.js → chunk-HZJF4IUO.js} +72 -33
  12. package/dist/{chunk-S6IL3R5I.js.map → chunk-HZJF4IUO.js.map} +1 -1
  13. package/dist/{chunk-PXD6ZFNY.js → chunk-IR3KBHOY.js} +19 -1
  14. package/dist/{chunk-PXD6ZFNY.js.map → chunk-IR3KBHOY.js.map} +1 -1
  15. package/dist/{chunk-WW2A73HW.js → chunk-NUKSVU3W.js} +2 -2
  16. package/dist/{chunk-BVMWQDC5.js → chunk-VJ7T5WIO.js} +3 -3
  17. package/dist/contract/index.d.ts +62 -11
  18. package/dist/contract/index.js +36 -11
  19. package/dist/contract/index.js.map +1 -1
  20. package/dist/index.d.ts +4 -0
  21. package/dist/index.js +8 -8
  22. package/dist/openapi.json +1 -1
  23. package/dist/traces.js +3 -3
  24. package/package.json +1 -1
  25. /package/dist/{chunk-ULOKLHIQ.js.map → chunk-A5S77LSE.js.map} +0 -0
  26. /package/dist/{chunk-MUS5DOH7.js.map → chunk-FC5NDO3E.js.map} +0 -0
  27. /package/dist/{chunk-MI2H23RV.js.map → chunk-G2GPNLSX.js.map} +0 -0
  28. /package/dist/{chunk-WW2A73HW.js.map → chunk-NUKSVU3W.js.map} +0 -0
  29. /package/dist/{chunk-BVMWQDC5.js.map → chunk-VJ7T5WIO.js.map} +0 -0
@@ -15,7 +15,7 @@ import {
15
15
  clamp01,
16
16
  mapConcurrent,
17
17
  validatePolicyEditCandidateRecord
18
- } from "./chunk-MUS5DOH7.js";
18
+ } from "./chunk-FC5NDO3E.js";
19
19
  import {
20
20
  detectRewardHacking
21
21
  } from "./chunk-ARU2PZFM.js";
@@ -3006,7 +3006,18 @@ async function runImprovementLoop(opts) {
3006
3006
  const optimization = await runOptimization({ ...opts, dispatchTimeoutMs, costLedger });
3007
3007
  const winnerIsBaseline = optimization.winnerSurfaceHash === surfaceHash(opts.baselineSurface);
3008
3008
  const { runCampaign: runCampaign2 } = await import("./run-campaign-ZKR5MQMQ.js");
3009
- const baselineOnHoldout = await runCampaign2({
3009
+ const holdoutDeferred = (opts.holdout ?? "measured") === "deferred";
3010
+ const baselineOnHoldout = holdoutDeferred ? await runCampaign2({
3011
+ ...opts,
3012
+ costLedger,
3013
+ costPhase: "holdout.deferred",
3014
+ dispatchTimeoutMs,
3015
+ scenarios: [],
3016
+ dispatch: async () => {
3017
+ throw new Error("runImprovementLoop: unreachable dispatch \u2014 holdout is deferred");
3018
+ },
3019
+ runDir: `${opts.runDir}/holdout-deferred`
3020
+ }) : await runCampaign2({
3010
3021
  ...opts,
3011
3022
  costLedger,
3012
3023
  costPhase: "holdout.baseline",
@@ -3015,7 +3026,7 @@ async function runImprovementLoop(opts) {
3015
3026
  dispatch: (scenario, ctx) => opts.dispatchWithSurface(opts.baselineSurface, scenario, ctx),
3016
3027
  runDir: `${opts.runDir}/holdout-baseline`
3017
3028
  });
3018
- const winnerOnHoldout = winnerIsBaseline ? baselineOnHoldout : await runCampaign2({
3029
+ const winnerOnHoldout = winnerIsBaseline || holdoutDeferred ? baselineOnHoldout : await runCampaign2({
3019
3030
  ...opts,
3020
3031
  costLedger,
3021
3032
  costPhase: "holdout.winner",
@@ -3039,8 +3050,10 @@ async function runImprovementLoop(opts) {
3039
3050
  );
3040
3051
  }
3041
3052
  };
3042
- assertCompleteHoldout("baseline", baselineOnHoldout);
3043
- assertCompleteHoldout("winner", winnerOnHoldout);
3053
+ if (!holdoutDeferred) {
3054
+ assertCompleteHoldout("baseline", baselineOnHoldout);
3055
+ assertCompleteHoldout("winner", winnerOnHoldout);
3056
+ }
3044
3057
  const candidateArtifacts = /* @__PURE__ */ new Map();
3045
3058
  const baselineArtifacts = /* @__PURE__ */ new Map();
3046
3059
  const judgeScores = /* @__PURE__ */ new Map();
@@ -3057,7 +3070,7 @@ async function runImprovementLoop(opts) {
3057
3070
  let neutralizedJudgeScores;
3058
3071
  let neutralizedOnHoldout;
3059
3072
  let neutralizedSurface;
3060
- if (opts.neutralize && !winnerIsBaseline) {
3073
+ if (opts.neutralize && !winnerIsBaseline && !holdoutDeferred) {
3061
3074
  const surface = opts.neutralize(optimization.winnerSurface, opts.baselineSurface);
3062
3075
  neutralizedSurface = surface;
3063
3076
  neutralizedOnHoldout = await runCampaign2({
@@ -3077,7 +3090,15 @@ async function runImprovementLoop(opts) {
3077
3090
  neutralizedJudgeScores.set(cell.cellId, cell.judgeScores);
3078
3091
  }
3079
3092
  }
3080
- const gateResult = winnerIsBaseline ? {
3093
+ const gateResult = holdoutDeferred ? {
3094
+ decision: "hold",
3095
+ reasons: [
3096
+ "holdout deferred \u2014 improvement-set search completed without a held-out measurement; nothing to promote from this run"
3097
+ ],
3098
+ contributingGates: [
3099
+ { name: "holdout-deferred", passed: false, detail: { holdout: "deferred" } }
3100
+ ]
3101
+ } : winnerIsBaseline ? {
3081
3102
  decision: "hold",
3082
3103
  reasons: [
3083
3104
  "no candidate beat the training baseline \u2014 winner == baseline (empty diff); nothing to promote"
@@ -3118,6 +3139,7 @@ async function runImprovementLoop(opts) {
3118
3139
  baselineOnHoldout,
3119
3140
  winnerOnHoldout,
3120
3141
  ...neutralizedOnHoldout && neutralizedSurface ? { neutralizedOnHoldout, neutralizedSurface } : {},
3142
+ ...holdoutDeferred ? { holdout: "deferred" } : {},
3121
3143
  gateResult,
3122
3144
  promotedDiff,
3123
3145
  prResult,
@@ -3170,6 +3192,7 @@ function loopProvenanceArgsFromResult(input) {
3170
3192
  }))
3171
3193
  })),
3172
3194
  gate: result.gateResult,
3195
+ ...result.holdout === "deferred" ? { holdout: "deferred" } : {},
3173
3196
  baselineOnHoldout: result.baselineOnHoldout,
3174
3197
  winnerOnHoldout: result.winnerOnHoldout,
3175
3198
  ...result.neutralizedSurface && result.neutralizedOnHoldout ? {
@@ -3305,6 +3328,7 @@ function buildLoopProvenanceRecord(args) {
3305
3328
  "buildLoopProvenanceRecord: winner surface does not match the final promoted incumbent"
3306
3329
  );
3307
3330
  }
3331
+ const holdoutDeferred = args.holdout === "deferred";
3308
3332
  const baselineHoldoutComposite = meanHoldoutComposite(args.baselineOnHoldout);
3309
3333
  const winnerHoldoutComposite = meanHoldoutComposite(args.winnerOnHoldout);
3310
3334
  if (args.baselineOnHoldout.splitDigest !== args.winnerOnHoldout.splitDigest) {
@@ -3364,9 +3388,13 @@ function buildLoopProvenanceRecord(args) {
3364
3388
  detail: durableGateDetail(g.detail)
3365
3389
  }))
3366
3390
  },
3367
- baselineHoldoutComposite,
3368
- winnerHoldoutComposite,
3369
- heldOutLift: winnerHoldoutComposite - baselineHoldoutComposite,
3391
+ // Deferred holdout records the MODE, never a fabricated 0-lift: the
3392
+ // held-out comparison intentionally did not run in this loop.
3393
+ ...holdoutDeferred ? { holdout: "deferred" } : {
3394
+ baselineHoldoutComposite,
3395
+ winnerHoldoutComposite,
3396
+ heldOutLift: winnerHoldoutComposite - baselineHoldoutComposite
3397
+ },
3370
3398
  backend: {
3371
3399
  verdict: integrity.verdict,
3372
3400
  workerCallCount: integrity.totalRecords,
@@ -3537,24 +3565,26 @@ function loopProvenanceSpans(record, opts = {}) {
3537
3565
  const endNano = baseNano + Math.max(1, record.totalDurationMs) * 1e6;
3538
3566
  const spans = [];
3539
3567
  const rootSpanId = hashId(["root", record.runId]).slice(0, 16);
3568
+ const rootAttributes = {
3569
+ "tangle.runId": record.runId,
3570
+ "tangle.runDir": record.runDir,
3571
+ "tangle.baselineContentHash": record.baselineContentHash,
3572
+ "tangle.winnerContentHash": record.winnerContentHash,
3573
+ "tangle.baselineSearchComposite": record.baselineSearchComposite,
3574
+ "tangle.gateDecision": record.gate.decision,
3575
+ "tangle.backendVerdict": record.backend.verdict,
3576
+ "tangle.workerCallCount": record.backend.workerCallCount,
3577
+ "tangle.totalCostUsd": record.totalCostUsd
3578
+ };
3579
+ if (record.heldOutLift !== void 0) rootAttributes["tangle.heldOutLift"] = record.heldOutLift;
3580
+ if (record.holdout) rootAttributes["tangle.holdout"] = record.holdout;
3540
3581
  spans.push({
3541
3582
  traceId,
3542
3583
  spanId: rootSpanId,
3543
3584
  name: "improvement-loop",
3544
3585
  startTimeUnixNano: baseNano,
3545
3586
  endTimeUnixNano: endNano,
3546
- attributes: {
3547
- "tangle.runId": record.runId,
3548
- "tangle.runDir": record.runDir,
3549
- "tangle.baselineContentHash": record.baselineContentHash,
3550
- "tangle.winnerContentHash": record.winnerContentHash,
3551
- "tangle.baselineSearchComposite": record.baselineSearchComposite,
3552
- "tangle.heldOutLift": record.heldOutLift,
3553
- "tangle.gateDecision": record.gate.decision,
3554
- "tangle.backendVerdict": record.backend.verdict,
3555
- "tangle.workerCallCount": record.backend.workerCallCount,
3556
- "tangle.totalCostUsd": record.totalCostUsd
3557
- },
3587
+ attributes: rootAttributes,
3558
3588
  status: gateStatus(record.gate.decision),
3559
3589
  "tangle.runId": record.runId
3560
3590
  });
@@ -3625,6 +3655,21 @@ function loopProvenanceSpans(record, opts = {}) {
3625
3655
  }
3626
3656
  }
3627
3657
  const gateSpanId = hashId(["gate", record.runId]).slice(0, 16);
3658
+ const gateAttributes = {
3659
+ "tangle.runId": record.runId,
3660
+ "tangle.gateDecision": record.gate.decision,
3661
+ "tangle.gateReasons": JSON.stringify(record.gate.reasons)
3662
+ };
3663
+ const gateDelta = record.gate.delta ?? record.heldOutLift;
3664
+ if (gateDelta !== void 0) gateAttributes["tangle.gateDelta"] = gateDelta;
3665
+ if (record.heldOutLift !== void 0) gateAttributes["tangle.heldOutLift"] = record.heldOutLift;
3666
+ if (record.baselineHoldoutComposite !== void 0) {
3667
+ gateAttributes["tangle.baselineHoldoutComposite"] = record.baselineHoldoutComposite;
3668
+ }
3669
+ if (record.winnerHoldoutComposite !== void 0) {
3670
+ gateAttributes["tangle.winnerHoldoutComposite"] = record.winnerHoldoutComposite;
3671
+ }
3672
+ if (record.holdout) gateAttributes["tangle.holdout"] = record.holdout;
3628
3673
  spans.push({
3629
3674
  traceId,
3630
3675
  spanId: gateSpanId,
@@ -3632,15 +3677,7 @@ function loopProvenanceSpans(record, opts = {}) {
3632
3677
  name: "gate-decision",
3633
3678
  startTimeUnixNano: endNano,
3634
3679
  endTimeUnixNano: endNano,
3635
- attributes: {
3636
- "tangle.runId": record.runId,
3637
- "tangle.gateDecision": record.gate.decision,
3638
- "tangle.gateDelta": record.gate.delta ?? record.heldOutLift,
3639
- "tangle.gateReasons": JSON.stringify(record.gate.reasons),
3640
- "tangle.heldOutLift": record.heldOutLift,
3641
- "tangle.baselineHoldoutComposite": record.baselineHoldoutComposite,
3642
- "tangle.winnerHoldoutComposite": record.winnerHoldoutComposite
3643
- },
3680
+ attributes: gateAttributes,
3644
3681
  status: gateStatus(record.gate.decision),
3645
3682
  "tangle.runId": record.runId
3646
3683
  });
@@ -3695,7 +3732,9 @@ function buildEvalRunEvent(args, record) {
3695
3732
  snapshotFromHoldout(1, record.winnerContentHash, args.winnerSurface, args.winnerOnHoldout)
3696
3733
  ],
3697
3734
  gateDecision: args.gate.decision,
3698
- holdoutLift: record.heldOutLift,
3735
+ // Deferred holdout ships NO lift — the wire field is optional and a 0
3736
+ // would read downstream as a measured no-improvement.
3737
+ ...record.heldOutLift !== void 0 ? { holdoutLift: record.heldOutLift } : {},
3699
3738
  totalCostUsd: args.totalCostUsd,
3700
3739
  totalDurationMs: args.totalDurationMs
3701
3740
  };
@@ -3797,4 +3836,4 @@ export {
3797
3836
  provenanceSpansPath,
3798
3837
  emitLoopProvenance
3799
3838
  };
3800
- //# sourceMappingURL=chunk-S6IL3R5I.js.map
3839
+ //# sourceMappingURL=chunk-HZJF4IUO.js.map