@tangle-network/agent-eval 0.173.2 → 0.174.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 (128) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/{proposal-findings-bko3GGy-.js → abort-signal-CtzAM_sJ.js} +11 -11
  3. package/dist/abort-signal-CtzAM_sJ.js.map +1 -0
  4. package/dist/adapters/http.d.ts +2 -2
  5. package/dist/agent-profile-_xPxqVJt.d.ts +488 -0
  6. package/dist/agent-profile-_xPxqVJt.d.ts.map +1 -0
  7. package/dist/analyst/index.d.ts +7 -9
  8. package/dist/analyst/index.d.ts.map +1 -1
  9. package/dist/analyst/index.js +8 -8
  10. package/dist/{benchmark-C4wk_Sjr.js → benchmark-DQKzykkO.js} +2 -2
  11. package/dist/{benchmark-C4wk_Sjr.js.map → benchmark-DQKzykkO.js.map} +1 -1
  12. package/dist/{benchmark-command-CS6gVHVq.js → benchmark-command-mZIlR-ra.js} +13 -13
  13. package/dist/{benchmark-command-CS6gVHVq.js.map → benchmark-command-mZIlR-ra.js.map} +1 -1
  14. package/dist/benchmarks/index.d.ts +3 -4
  15. package/dist/benchmarks/index.d.ts.map +1 -1
  16. package/dist/benchmarks/index.js +3 -3
  17. package/dist/campaign/index.d.ts +5 -9
  18. package/dist/campaign/index.js +7 -7
  19. package/dist/{campaign-B3kPMU8S.js → campaign-BzMSCejE.js} +8 -8
  20. package/dist/{campaign-B3kPMU8S.js.map → campaign-BzMSCejE.js.map} +1 -1
  21. package/dist/cli.js +1 -1
  22. package/dist/{client-DlqdbM7n.d.ts → client-vyYQg3bm.d.ts} +2 -2
  23. package/dist/{client-DlqdbM7n.d.ts.map → client-vyYQg3bm.d.ts.map} +1 -1
  24. package/dist/contract/index.d.ts +9 -10
  25. package/dist/contract/index.js +8 -8
  26. package/dist/{default-registry-B0bKikCb.js → default-registry-CrAp0pYq.js} +4 -4
  27. package/dist/{default-registry-B0bKikCb.js.map → default-registry-CrAp0pYq.js.map} +1 -1
  28. package/dist/{default-registry-BKwc8bN5.d.ts → default-registry-FfNzaUHV.d.ts} +3 -3
  29. package/dist/{default-registry-BKwc8bN5.d.ts.map → default-registry-FfNzaUHV.d.ts.map} +1 -1
  30. package/dist/{define-agent-eval-CY6qdlGV.d.ts → define-agent-eval-V1jQyCDR.d.ts} +102 -11
  31. package/dist/define-agent-eval-V1jQyCDR.d.ts.map +1 -0
  32. package/dist/{define-agent-eval-8h3lXXee.js → define-agent-eval-ox5McL6e.js} +331 -144
  33. package/dist/define-agent-eval-ox5McL6e.js.map +1 -0
  34. package/dist/{dspy-rlm-engine-CF0t2ITD.js → dspy-rlm-engine-Caz2pl4L.js} +3 -3
  35. package/dist/{dspy-rlm-engine-CF0t2ITD.js.map → dspy-rlm-engine-Caz2pl4L.js.map} +1 -1
  36. package/dist/{engine-DhFir3Ys.d.ts → engine-CvW_I72-.d.ts} +2 -2
  37. package/dist/{engine-DhFir3Ys.d.ts.map → engine-CvW_I72-.d.ts.map} +1 -1
  38. package/dist/experiment/index.d.ts +1 -4
  39. package/dist/experiment/index.d.ts.map +1 -1
  40. package/dist/{external-optimizer-process-BwITA9Jp.js → external-optimizer-process-CxnFL1hd.js} +2 -2
  41. package/dist/{external-optimizer-process-BwITA9Jp.js.map → external-optimizer-process-CxnFL1hd.js.map} +1 -1
  42. package/dist/{external-optimizer-subprocess-wBWeoG6A.js → external-optimizer-subprocess-CQi27uEI.js} +2 -2
  43. package/dist/{external-optimizer-subprocess-wBWeoG6A.js.map → external-optimizer-subprocess-CQi27uEI.js.map} +1 -1
  44. package/dist/fuzz.js +1 -1
  45. package/dist/fuzz.js.map +1 -1
  46. package/dist/hosted/index.d.ts +1 -1
  47. package/dist/{index-BQqOjerE.d.ts → index-BTrx5s8m.d.ts} +8 -9
  48. package/dist/index-BTrx5s8m.d.ts.map +1 -0
  49. package/dist/{index-D0Db5X-4.d.ts → index-Bn-nlnSV.d.ts} +4 -4
  50. package/dist/{index-D0Db5X-4.d.ts.map → index-Bn-nlnSV.d.ts.map} +1 -1
  51. package/dist/index-DKXuBPXf.d.ts +3840 -0
  52. package/dist/index-DKXuBPXf.d.ts.map +1 -0
  53. package/dist/index.d.ts +11 -13
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +10 -10
  56. package/dist/{kind-factory-gP6lDySe.js → kind-factory-BLvL-E44.js} +2 -2
  57. package/dist/{kind-factory-gP6lDySe.js.map → kind-factory-BLvL-E44.js.map} +1 -1
  58. package/dist/{llm-judge-BfqMFo4h.js → llm-judge-DmNaBrXB.js} +2541 -2435
  59. package/dist/llm-judge-DmNaBrXB.js.map +1 -0
  60. package/dist/{matrix-DGu8KhSs.d.ts → matrix-CJtXz1ky.d.ts} +2 -2
  61. package/dist/{matrix-DGu8KhSs.d.ts.map → matrix-CJtXz1ky.d.ts.map} +1 -1
  62. package/dist/multishot/golden/index.d.ts +1 -1
  63. package/dist/multishot/index.d.ts +2 -2
  64. package/dist/openapi.json +1 -1
  65. package/dist/{produced-state-D91uDvQw.js → produced-state-B8mw6zj9.js} +2 -2
  66. package/dist/{produced-state-D91uDvQw.js.map → produced-state-B8mw6zj9.js.map} +1 -1
  67. package/dist/rl.d.ts +1 -1
  68. package/dist/rl.d.ts.map +1 -1
  69. package/dist/rl.js.map +1 -1
  70. package/dist/{semantic-concept-judge-Dok7_35a.js → semantic-concept-judge-E3s_fEjB.js} +3 -3
  71. package/dist/{semantic-concept-judge-Dok7_35a.js.map → semantic-concept-judge-E3s_fEjB.js.map} +1 -1
  72. package/dist/{skillopt-optimization-method-DDw3v3gA.js → skillopt-optimization-method-f7399oGb.js} +5 -5
  73. package/dist/{skillopt-optimization-method-DDw3v3gA.js.map → skillopt-optimization-method-f7399oGb.js.map} +1 -1
  74. package/dist/statistical-heldout-Cqb73yE9.d.ts +1127 -0
  75. package/dist/statistical-heldout-Cqb73yE9.d.ts.map +1 -0
  76. package/dist/{store-otlp-Dow0pk_5.js → store-otlp-DV_H2HDu.js} +2 -2
  77. package/dist/{store-otlp-Dow0pk_5.js.map → store-otlp-DV_H2HDu.js.map} +1 -1
  78. package/dist/{store-tool-spans-CCZNsihA.d.ts → store-tool-spans-4o55ABER.d.ts} +3 -3
  79. package/dist/{store-tool-spans-CCZNsihA.d.ts.map → store-tool-spans-4o55ABER.d.ts.map} +1 -1
  80. package/dist/{store-tool-spans-CeNj_m2L.js → store-tool-spans-B9tjys_h.js} +3 -3
  81. package/dist/{store-tool-spans-CeNj_m2L.js.map → store-tool-spans-B9tjys_h.js.map} +1 -1
  82. package/dist/supervisor-run/index.d.ts.map +1 -1
  83. package/dist/supervisor-run/index.js +25 -7
  84. package/dist/supervisor-run/index.js.map +1 -1
  85. package/dist/{task-failure-attributes-CZjZeBsY.js → task-failure-attributes-CUy9mkIY.js} +2 -2
  86. package/dist/{task-failure-attributes-CZjZeBsY.js.map → task-failure-attributes-CUy9mkIY.js.map} +1 -1
  87. package/dist/{tool-groups-Cp4Xdzrp.d.ts → tool-groups-DAe1t6zb.d.ts} +2 -2
  88. package/dist/tool-groups-DAe1t6zb.d.ts.map +1 -0
  89. package/dist/trace-repair/index.d.ts +1 -1
  90. package/dist/traces.d.ts +2 -2
  91. package/dist/traces.js +4 -4
  92. package/dist/{types-Ba5UQyVD.d.ts → types-BJz2CPTM.d.ts} +2 -2
  93. package/dist/{types-Ba5UQyVD.d.ts.map → types-BJz2CPTM.d.ts.map} +1 -1
  94. package/dist/{types-CiWITkGo.js → types-DQ0e2E7y.js} +2 -2
  95. package/dist/types-DQ0e2E7y.js.map +1 -0
  96. package/dist/{types-BDV4PiMR.d.ts → types-Dd1ejaeI.d.ts} +2 -2
  97. package/dist/{types-BDV4PiMR.d.ts.map → types-Dd1ejaeI.d.ts.map} +1 -1
  98. package/docs/campaign-proposers.md +42 -0
  99. package/package.json +1 -1
  100. package/dist/agent-profile-B9_GGsG8.d.ts +0 -84
  101. package/dist/agent-profile-B9_GGsG8.d.ts.map +0 -1
  102. package/dist/backend-integrity-CeuTgqsd.d.ts +0 -280
  103. package/dist/backend-integrity-CeuTgqsd.d.ts.map +0 -1
  104. package/dist/benchmark-BjLGkfnN.d.ts +0 -236
  105. package/dist/benchmark-BjLGkfnN.d.ts.map +0 -1
  106. package/dist/define-agent-eval-8h3lXXee.js.map +0 -1
  107. package/dist/define-agent-eval-CY6qdlGV.d.ts.map +0 -1
  108. package/dist/external-optimizer-contracts-CQCpyrIL.d.ts +0 -172
  109. package/dist/external-optimizer-contracts-CQCpyrIL.d.ts.map +0 -1
  110. package/dist/heldout-gate-Df5hsqmm.d.ts +0 -453
  111. package/dist/heldout-gate-Df5hsqmm.d.ts.map +0 -1
  112. package/dist/index-BQqOjerE.d.ts.map +0 -1
  113. package/dist/index-CFDffsKz.d.ts +0 -1135
  114. package/dist/index-CFDffsKz.d.ts.map +0 -1
  115. package/dist/llm-judge-BfqMFo4h.js.map +0 -1
  116. package/dist/power-preflight-Ptse_Kq7.d.ts +0 -117
  117. package/dist/power-preflight-Ptse_Kq7.d.ts.map +0 -1
  118. package/dist/pre-registration-BoI4ucR3.d.ts +0 -592
  119. package/dist/pre-registration-BoI4ucR3.d.ts.map +0 -1
  120. package/dist/promotion-policy-CvMda3kU.d.ts +0 -134
  121. package/dist/promotion-policy-CvMda3kU.d.ts.map +0 -1
  122. package/dist/proposal-findings-bko3GGy-.js.map +0 -1
  123. package/dist/provenance-CRY67X50.d.ts +0 -1995
  124. package/dist/provenance-CRY67X50.d.ts.map +0 -1
  125. package/dist/statistical-heldout-DTyB_6-1.d.ts +0 -295
  126. package/dist/statistical-heldout-DTyB_6-1.d.ts.map +0 -1
  127. package/dist/tool-groups-Cp4Xdzrp.d.ts.map +0 -1
  128. package/dist/types-CiWITkGo.js.map +0 -1
@@ -10,9 +10,9 @@ import "./query-D1nLIKt7.js";
10
10
  import { r as observedSplitScore } from "./reward-nw2xZGZG.js";
11
11
  import { c as validateRunRecord, i as modelHasSnapshot } from "./run-record-ZIsR9Fif.js";
12
12
  import { r as paretoChart } from "./summary-report-Bgh8CpNK.js";
13
- import { D as assertOptimizationResult, I as surfaceContentHash, L as surfaceHash, Q as defaultProductionGate, _ as runImprovementLoop, d as emitLoopProvenance, f as loopProvenanceArgsFromResult, it as runEval, st as resolveRunDir } from "./llm-judge-BfqMFo4h.js";
13
+ import { J as defaultProductionGate, K as runFinalComparison, T as runImprovementLoop, _ as campaignMeasurementDigest, at as surfaceDispatchRef, b as loopProvenanceArgsFromResult, c as assertOptimizationResult, h as createMethodCostScope, it as surfaceContentHash, m as costFromLedgerSummary, ot as surfaceHash, p as combineComparisonCosts, q as openAutoPr, st as runEval, ut as resolveRunDir, v as canonicalDigest, vt as campaignSplitDigest, y as emitLoopProvenance } from "./llm-judge-DmNaBrXB.js";
14
14
  import { c as campaignCellTaskScore, l as campaignCellToRunRecord, o as campaignCellExecutionEvidence, s as campaignCellJudgeDimensions } from "./reward-hacking-CKW4teig.js";
15
- import { C as inMemoryCampaignStorage, S as fsCampaignStorage, x as createRunCostLedger } from "./external-optimizer-subprocess-wBWeoG6A.js";
15
+ import { C as inMemoryCampaignStorage, S as fsCampaignStorage, x as createRunCostLedger } from "./external-optimizer-subprocess-CQi27uEI.js";
16
16
  import { t as powerPreflight } from "./power-preflight-CFXm0Vjo.js";
17
17
  import { t as createHostedClient } from "./client-BlLY6o2w.js";
18
18
  //#region src/contamination-guard.ts
@@ -965,6 +965,306 @@ function buildRecommendations(ctx) {
965
965
  return out;
966
966
  }
967
967
  //#endregion
968
+ //#region src/contract/self-improve-reporting.ts
969
+ function meanComposite(byScenario) {
970
+ const perScenario = {};
971
+ const values = [];
972
+ for (const [id, agg] of Object.entries(byScenario)) {
973
+ perScenario[id] = agg.meanComposite;
974
+ values.push(agg.meanComposite);
975
+ }
976
+ return {
977
+ compositeMean: values.length === 0 ? 0 : values.reduce((s, v) => s + v, 0) / values.length,
978
+ perScenario
979
+ };
980
+ }
981
+ /** 32-bit FNV-1a over raw UTF-16 code units, rendered as hex for a cell key.
982
+ *
983
+ * Frozen: the key names a persisted cell, so a change orphans every cell
984
+ * already written. This is a cell-key function, not a general-purpose hash. */
985
+ function hashString(s) {
986
+ let h = 2166136261;
987
+ for (let i = 0; i < s.length; i++) {
988
+ h ^= s.charCodeAt(i);
989
+ h = Math.imul(h, 16777619) >>> 0;
990
+ }
991
+ return h.toString(16).padStart(8, "0");
992
+ }
993
+ /**
994
+ * Adapt campaign cells into the `RunRecord` shape `analyzeRuns()` consumes.
995
+ * Each cell becomes one run; `candidateId` is the caller-supplied label so
996
+ * baseline + winner pair cleanly on `(experimentId, scenarioId, seed)`.
997
+ *
998
+ * `promptHash` identifies the executed surface; `configHash` identifies the candidate label.
999
+ */
1000
+ function cellsToRunRecords(cells, candidateId, runId, surface, splitTag, fallbackModel) {
1001
+ const promptHash = surfaceContentHash(surface);
1002
+ const configHash = surfaceContentHash(candidateId);
1003
+ return cells.map((cell) => {
1004
+ const receiptModels = cell.resolvedModels ?? (cell.resolvedModel ? [cell.resolvedModel] : []);
1005
+ if (receiptModels.length > 1) throw new ValidationError(`selfImprove cell ${cell.cellId} used multiple agent models: ${receiptModels.join(", ")}`);
1006
+ const model = receiptModels[0] ?? fallbackModel;
1007
+ if (!model) throw new ValidationError(`selfImprove.model is required when cell ${cell.cellId} has no paid-call model receipt`);
1008
+ if (!modelHasSnapshot(model)) throw new ValidationError(`selfImprove model "${model}" lacks a snapshot version for cell ${cell.cellId}`);
1009
+ return campaignCellToRunRecord(cell, {
1010
+ runId: `${runId}::${candidateId}::${cell.cellId}`,
1011
+ experimentId: runId,
1012
+ candidateId,
1013
+ seed: cell.rep * 1e6 + hashString(cell.scenarioId).slice(0, 6).split("").reduce((a, c) => a * 31 + c.charCodeAt(0) >>> 0, 0),
1014
+ model,
1015
+ promptHash,
1016
+ configHash,
1017
+ commitSha: "cell",
1018
+ splitTag
1019
+ });
1020
+ });
1021
+ }
1022
+ //#endregion
1023
+ //#region src/contract/self-improve-method.ts
1024
+ /** Complete methods own search and selection; this path only measures their final choice. */
1025
+ async function runSelfImproveMethod(args) {
1026
+ const { opts, train, selection, holdout, costLedger, storage, runDir, startedAt } = args;
1027
+ const budget = opts.budget ?? {};
1028
+ if (opts.autoOnPromote === "pr" && (!opts.ghOwner || !opts.ghRepo)) throw new Error("selfImprove: autoOnPromote='pr' requires ghOwner + ghRepo");
1029
+ const baselineSurface = structuredClone(opts.baselineSurface);
1030
+ const judge = {
1031
+ ...opts.judge,
1032
+ dimensions: opts.judge.dimensions.map((dimension) => Object.freeze({ ...dimension }))
1033
+ };
1034
+ Object.freeze(judge.dimensions);
1035
+ Object.freeze(judge);
1036
+ const methodCostScope = createMethodCostScope(costLedger, opts.method.name);
1037
+ const method = await opts.method.optimize(Object.freeze({
1038
+ baselineSurface: structuredClone(baselineSurface),
1039
+ trainScenarios: Object.freeze(train.map((scenario) => structuredClone(scenario))),
1040
+ selectionScenarios: Object.freeze(selection.map((scenario) => structuredClone(scenario))),
1041
+ dispatchWithSurface: opts.agent,
1042
+ judges: Object.freeze([judge]),
1043
+ runDir: `${runDir}/optimization/${opts.method.name.replace(/[^a-zA-Z0-9._-]/g, "_")}`,
1044
+ seed: 42,
1045
+ runOptions: Object.freeze({
1046
+ storage,
1047
+ maxConcurrency: budget.maxConcurrency ?? 2,
1048
+ reps: budget.reps,
1049
+ dispatchRef: opts.dispatchRef,
1050
+ dispatchTimeoutMs: opts.dispatchTimeoutMs,
1051
+ cellRetry: opts.cellRetry,
1052
+ cellPlacement: opts.cellPlacement,
1053
+ labeledStore: opts.labeledStore,
1054
+ captureSource: opts.captureSource,
1055
+ expectUsage: opts.expectUsage ?? "assert"
1056
+ }),
1057
+ costLedger: methodCostScope.ledger
1058
+ }));
1059
+ assertOptimizationResult(opts.method.name, method);
1060
+ const selected = structuredClone(method);
1061
+ const methodCost = methodCostScope.reconcile(selected.cost);
1062
+ const finalPhase = "selfImprove.method-final";
1063
+ const finalCost = () => combineComparisonCosts([
1064
+ "holdout.baseline",
1065
+ "holdout.winner",
1066
+ "holdout.neutralized",
1067
+ "promotion.gate"
1068
+ ].map((phase) => ({
1069
+ label: phase,
1070
+ cost: costFromLedgerSummary(costLedger.summary({ phase: `${finalPhase}.${phase}` }))
1071
+ })));
1072
+ const totalCost = () => combineComparisonCosts([{
1073
+ label: opts.method.name,
1074
+ cost: methodCost
1075
+ }, {
1076
+ label: "final comparison",
1077
+ cost: finalCost()
1078
+ }]);
1079
+ const gate = opts.gate ?? defaultProductionGate({
1080
+ holdoutScenarios: holdout,
1081
+ deltaThreshold: .05
1082
+ });
1083
+ const comparison = await runFinalComparison({
1084
+ baselineSurface,
1085
+ winnerSurface: selected.winnerSurface,
1086
+ scenarios: holdout,
1087
+ dispatchWithSurface: opts.agent,
1088
+ dispatchRef: opts.dispatchRef,
1089
+ judges: [judge],
1090
+ holdout: budget.holdout,
1091
+ neutralize: opts.neutralize,
1092
+ gate: {
1093
+ ...gate,
1094
+ async decide(context) {
1095
+ const cost = totalCost();
1096
+ if (budget.dollars !== void 0 && (!cost.accountingComplete || cost.totalCostUsd > budget.dollars)) return {
1097
+ decision: "hold",
1098
+ reasons: ["complete method spend cannot satisfy the declared run budget"],
1099
+ contributingGates: [{
1100
+ name: "budget",
1101
+ status: "fail",
1102
+ detail: {
1103
+ cost,
1104
+ budgetUsd: budget.dollars
1105
+ }
1106
+ }]
1107
+ };
1108
+ return gate.decide(context);
1109
+ }
1110
+ },
1111
+ runDir,
1112
+ storage,
1113
+ costLedger,
1114
+ costPhase: finalPhase,
1115
+ reps: budget.reps,
1116
+ maxConcurrency: budget.maxConcurrency ?? 2,
1117
+ dispatchTimeoutMs: opts.dispatchTimeoutMs,
1118
+ cellRetry: opts.cellRetry,
1119
+ cellPlacement: opts.cellPlacement,
1120
+ expectUsage: opts.expectUsage ?? "assert",
1121
+ label: "selfImprove"
1122
+ });
1123
+ const deferred = comparison.holdout === "deferred";
1124
+ const baseline = deferred ? null : meanComposite(comparison.baselineOnHoldout.aggregates.byScenario);
1125
+ const winner = deferred ? null : meanComposite(comparison.winnerOnHoldout.aggregates.byScenario);
1126
+ const lift = baseline && winner ? winner.compositeMean - baseline.compositeMean : void 0;
1127
+ const insight = deferred ? void 0 : await analyzeRuns({
1128
+ runs: [...cellsToRunRecords(comparison.baselineOnHoldout.cells, "baseline", runDir, baselineSurface, "holdout", opts.model), ...comparison.winnerOnHoldout === comparison.baselineOnHoldout ? [] : cellsToRunRecords(comparison.winnerOnHoldout.cells, "winner", runDir, selected.winnerSurface, "holdout", opts.model)],
1129
+ baselineCandidateId: "baseline",
1130
+ ...comparison.winnerOnHoldout === comparison.baselineOnHoldout ? {} : { candidateCandidateId: "winner" }
1131
+ });
1132
+ const cost = totalCost();
1133
+ const optimization = {
1134
+ name: opts.method.name,
1135
+ cost: methodCost,
1136
+ ...selected.durationMs === void 0 ? {} : { durationMs: selected.durationMs },
1137
+ ...selected.provenance === void 0 ? {} : { provenance: selected.provenance }
1138
+ };
1139
+ const durationMs = Date.now() - startedAt;
1140
+ const receipts = costLedger.list();
1141
+ const record = {
1142
+ schema: "tangle.method-improvement",
1143
+ runId: `${runDir}#${startedAt}`,
1144
+ runDir,
1145
+ timestamp: new Date(startedAt).toISOString(),
1146
+ baselineContentHash: surfaceContentHash(baselineSurface),
1147
+ winnerContentHash: surfaceContentHash(selected.winnerSurface),
1148
+ diff: comparison.promotedDiff,
1149
+ optimizationMethod: optimization,
1150
+ evidence: {
1151
+ trainSplitDigest: campaignSplitDigest(train, budget.reps ?? 1),
1152
+ selectionSplitDigest: campaignSplitDigest(selection, budget.reps ?? 1),
1153
+ holdoutSplitDigest: campaignSplitDigest(holdout, budget.reps ?? 1),
1154
+ baselineCampaignDigest: campaignMeasurementDigest(comparison.baselineOnHoldout),
1155
+ winnerCampaignDigest: campaignMeasurementDigest(comparison.winnerOnHoldout),
1156
+ costReceiptsDigest: canonicalDigest(receipts),
1157
+ ...comparison.neutralizedOnHoldout ? { neutralizedCampaignDigest: campaignMeasurementDigest(comparison.neutralizedOnHoldout) } : {}
1158
+ },
1159
+ gate: comparison.gateResult,
1160
+ ...deferred ? { holdout: "deferred" } : {},
1161
+ ...baseline && winner ? {
1162
+ baselineHoldoutComposite: baseline.compositeMean,
1163
+ winnerHoldoutComposite: winner.compositeMean,
1164
+ heldOutLift: lift
1165
+ } : {},
1166
+ cost,
1167
+ totalCostUsd: cost.totalCostUsd,
1168
+ totalDurationMs: durationMs
1169
+ };
1170
+ const serialized = JSON.parse(JSON.stringify(record));
1171
+ const provenance = {
1172
+ ...serialized,
1173
+ recordDigest: canonicalDigest(serialized)
1174
+ };
1175
+ storage.ensureDir(runDir);
1176
+ storage.write(`${runDir}/method-provenance.json`, JSON.stringify(provenance, null, 2));
1177
+ opts.onProvenance?.(provenance);
1178
+ opts.onProgress?.({
1179
+ kind: "gate.decided",
1180
+ decision: comparison.gateResult.decision,
1181
+ ...lift === void 0 ? {} : { lift }
1182
+ });
1183
+ const prResult = opts.autoOnPromote === "pr" && comparison.gateResult.decision === "ship" ? openAutoPr({
1184
+ result: comparison.winnerOnHoldout,
1185
+ gate: comparison.gateResult,
1186
+ promotedDiff: comparison.promotedDiff,
1187
+ ghOwner: opts.ghOwner,
1188
+ ghRepo: opts.ghRepo
1189
+ }) : void 0;
1190
+ const result = {
1191
+ mode: "method",
1192
+ baseline,
1193
+ winner: {
1194
+ surface: selected.winnerSurface,
1195
+ compositeMean: winner?.compositeMean ?? null,
1196
+ perScenario: winner?.perScenario ?? {},
1197
+ label: opts.method.name
1198
+ },
1199
+ ...lift === void 0 ? {} : { lift },
1200
+ diff: comparison.promotedDiff,
1201
+ gateDecision: comparison.gateResult.decision,
1202
+ provenance,
1203
+ optimization,
1204
+ cost,
1205
+ ledgerCost: costLedger.summary(),
1206
+ totalCostUsd: cost.totalCostUsd,
1207
+ durationMs,
1208
+ receipts,
1209
+ ...insight ? { insight } : {},
1210
+ ...selected.searchHistory ? { searchHistory: selected.searchHistory } : {},
1211
+ raw: {
1212
+ ...comparison,
1213
+ kind: "method",
1214
+ baselineSurface,
1215
+ winnerSurface: selected.winnerSurface,
1216
+ winnerSurfaceHash: surfaceHash(selected.winnerSurface),
1217
+ method: selected,
1218
+ cost,
1219
+ ...prResult ? { prResult } : {}
1220
+ }
1221
+ };
1222
+ if (opts.hostedTenant) {
1223
+ const snapshot = (index, surface, campaign) => ({
1224
+ index,
1225
+ surfaceHash: surfaceHash(surface),
1226
+ surface,
1227
+ cells: campaign.cells.map((cell) => {
1228
+ const execution = campaignCellExecutionEvidence(cell);
1229
+ return {
1230
+ scenarioId: cell.scenarioId,
1231
+ rep: cell.rep,
1232
+ compositeMean: campaignCellTaskScore(cell) ?? null,
1233
+ dimensions: campaignCellJudgeDimensions(cell),
1234
+ terminalOutcome: execution.terminalOutcome,
1235
+ executionErrorCount: execution.executionErrorCount ?? null,
1236
+ ...cell.error ? { errorMessage: cell.error } : {}
1237
+ };
1238
+ }),
1239
+ compositeMean: deferred ? null : meanComposite(campaign.aggregates.byScenario).compositeMean,
1240
+ costUsd: campaign.aggregates.cost.totalCostUsd,
1241
+ durationMs: campaign.durationMs
1242
+ });
1243
+ try {
1244
+ await createHostedClient(opts.hostedTenant).ingestEvalRun({
1245
+ runId: provenance.runId,
1246
+ runDir,
1247
+ timestamp: provenance.timestamp,
1248
+ status: "finished",
1249
+ labels: {
1250
+ ...opts.hostedLabels,
1251
+ mode: "method"
1252
+ },
1253
+ baseline: snapshot(0, baselineSurface, comparison.baselineOnHoldout),
1254
+ generations: [snapshot(1, selected.winnerSurface, comparison.winnerOnHoldout)],
1255
+ gateDecision: result.gateDecision,
1256
+ ...lift === void 0 ? {} : { holdoutLift: lift },
1257
+ totalCostUsd: result.totalCostUsd,
1258
+ totalDurationMs: durationMs,
1259
+ ...insight ? { insightReport: insight } : {}
1260
+ });
1261
+ } catch (error) {
1262
+ console.warn(`[agent-eval] hosted ingest failed (continuing): ${error instanceof Error ? error.message : String(error)}`);
1263
+ }
1264
+ }
1265
+ return result;
1266
+ }
1267
+ //#endregion
968
1268
  //#region src/contract/self-improve.ts
969
1269
  /** Failed self-improvement run with an immutable receipt snapshot. */
970
1270
  var SelfImproveRunError = class extends Error {
@@ -986,9 +1286,9 @@ function assertSelfImproveSearchMode(opts) {
986
1286
  }
987
1287
  if (typeof opts.method.name !== "string" || !opts.method.name.trim() || opts.method.name.trim() !== opts.method.name || typeof opts.method.optimize !== "function") throw new Error("selfImprove: method must have a trimmed name and optimize(input)");
988
1288
  const budget = opts.budget;
989
- if (budget?.generations !== void 0 && budget.generations !== 1) throw new Error("selfImprove: method owns its rounds; budget.generations must be 1 when set");
990
- if (budget?.populationSize !== void 0 && budget.populationSize !== 1) throw new Error("selfImprove: method owns its candidates; budget.populationSize must be 1 when set");
991
- if (budget?.candidateConcurrency !== void 0 || budget?.maxImprovementShots !== void 0 || opts.analyzeGeneration !== void 0 || opts.findings !== void 0 || opts.selectParent !== void 0) throw new Error("selfImprove: candidateConcurrency, maxImprovementShots, analyzeGeneration, findings, and selectParent apply only to proposer mode");
1289
+ if (budget?.generations !== void 0) throw new Error("selfImprove: method owns its rounds; budget.generations applies only to proposer mode");
1290
+ if (budget?.populationSize !== void 0) throw new Error("selfImprove: method owns its candidates; budget.populationSize applies only to proposer mode");
1291
+ if (budget?.candidateConcurrency !== void 0 || budget?.maxImprovementShots !== void 0 || opts.analyzeGeneration !== void 0 || opts.findings !== void 0 || opts.selectParent !== void 0 || opts.premeasuredBaseline !== void 0 || opts.selectionRankKey !== void 0 || opts.searchLedger !== void 0) throw new Error("selfImprove: candidateConcurrency, maxImprovementShots, analyzeGeneration, findings, selectParent, premeasuredBaseline, selectionRankKey, and searchLedger apply only to proposer mode");
992
1292
  }
993
1293
  function splitMethodPartitions(searchScenarios, explicitSelection, fraction) {
994
1294
  if (!Number.isFinite(fraction) || fraction <= 0 || fraction >= 1) throw new Error("selfImprove: budget.selectionFraction must be in (0, 1)");
@@ -1020,9 +1320,6 @@ function splitMethodPartitions(searchScenarios, explicitSelection, fraction) {
1020
1320
  train: sorted.slice(count)
1021
1321
  };
1022
1322
  }
1023
- function safeRunComponent(value) {
1024
- return value.replace(/[^a-zA-Z0-9._-]/g, "_");
1025
- }
1026
1323
  /** 32-bit FNV-1a over raw UTF-16 code units, read as an unsigned int and used
1027
1324
  * only to order scenarios deterministically.
1028
1325
  *
@@ -1050,18 +1347,6 @@ function splitTrainHoldout(scenarios, fraction) {
1050
1347
  train: sorted.slice(nHoldout)
1051
1348
  };
1052
1349
  }
1053
- function meanComposite(byScenario) {
1054
- const perScenario = {};
1055
- const values = [];
1056
- for (const [id, agg] of Object.entries(byScenario)) {
1057
- perScenario[id] = agg.meanComposite;
1058
- values.push(agg.meanComposite);
1059
- }
1060
- return {
1061
- compositeMean: values.length === 0 ? 0 : values.reduce((s, v) => s + v, 0) / values.length,
1062
- perScenario
1063
- };
1064
- }
1065
1350
  /**
1066
1351
  * Latest search campaign measured for the winner surface; the baseline search
1067
1352
  * campaign when the winner IS the baseline. Used by the deferred-holdout
@@ -1074,32 +1359,6 @@ function winnerSearchCampaign(result) {
1074
1359
  }
1075
1360
  return result.baselineCampaign;
1076
1361
  }
1077
- /**
1078
- * One-shot self-improvement loop. See module docstring for defaults +
1079
- * extension points.
1080
- *
1081
- * @example Minimum:
1082
- *
1083
- * const result = await selfImprove({
1084
- * agent: (surface, scenario, ctx) => myAgent(surface, scenario, ctx.signal),
1085
- * scenarios,
1086
- * judge,
1087
- * baselineSurface: DEFAULT_PROMPT,
1088
- * proposer,
1089
- * })
1090
- * console.log(`lift: ${result.lift.toFixed(3)} (${result.gateDecision})`)
1091
- *
1092
- * @example Distributed (workers in three regions):
1093
- *
1094
- * await selfImprove({
1095
- * agent: httpDispatch({ resolveUrl: ({ placement }) => REGION_URLS[placement!] }),
1096
- * scenarios,
1097
- * judge,
1098
- * baselineSurface: DEFAULT_PROMPT,
1099
- * cellPlacement: ({ scenario }) => scenario.region,
1100
- * budget: { maxConcurrency: 12 },
1101
- * })
1102
- */
1103
1362
  async function selfImprove(opts) {
1104
1363
  const startedAt = Date.now();
1105
1364
  const runDir = resolveRunDir(opts.runDir ?? (opts.method ? `.agent-eval/runs/self-improve-${startedAt}` : `mem://selfImprove-${startedAt}`));
@@ -1118,8 +1377,6 @@ async function selfImprove(opts) {
1118
1377
  async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
1119
1378
  const budget = opts.budget ?? {};
1120
1379
  assertSelfImproveSearchMode(opts);
1121
- const generations = opts.method ? 1 : budget.generations ?? 3;
1122
- const populationSize = opts.method ? 1 : budget.populationSize ?? 2;
1123
1380
  const maxConcurrency = budget.maxConcurrency ?? 2;
1124
1381
  const holdoutFraction = budget.holdoutFraction ?? .25;
1125
1382
  const holdoutMode = budget.holdout ?? "measured";
@@ -1135,41 +1392,26 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
1135
1392
  } : splitTrainHoldout(opts.scenarios, holdoutFraction);
1136
1393
  if (train.length === 0) throw new Error("selfImprove: train split is empty. Reduce holdoutFraction or pass more scenarios.");
1137
1394
  if (holdout.length === 0 && !holdoutDeferred) throw new Error("selfImprove: holdout split is empty. Pass more scenarios.");
1138
- if (generations > 0 && !opts.proposer && !opts.method) throw new Error("selfImprove: method or proposer is required when budget.generations is greater than zero");
1139
- let optimizationResult;
1140
- const methodPartitions = opts.method ? splitMethodPartitions(train, opts.selectionScenarios, budget.selectionFraction ?? .25) : void 0;
1141
- const proposer = opts.method ? {
1142
- kind: `method:${opts.method.name}`,
1143
- propose: async (context) => {
1144
- if (context.generation > 0) return [];
1145
- const result = await opts.method.optimize(Object.freeze({
1146
- baselineSurface: structuredClone(context.currentSurface),
1147
- trainScenarios: Object.freeze(methodPartitions.train.map((scenario) => structuredClone(scenario))),
1148
- selectionScenarios: Object.freeze(methodPartitions.selection.map((scenario) => structuredClone(scenario))),
1149
- dispatchWithSurface: opts.agent,
1150
- judges: Object.freeze([opts.judge]),
1151
- runDir: `${runDir}/optimization/${safeRunComponent(opts.method.name)}`,
1152
- seed: 42,
1153
- runOptions: Object.freeze({
1154
- storage,
1155
- maxConcurrency,
1156
- reps: budget.reps,
1157
- dispatchTimeoutMs: opts.dispatchTimeoutMs,
1158
- cellRetry: opts.cellRetry,
1159
- expectUsage,
1160
- costCeiling: budget.dollars
1161
- }),
1162
- costLedger
1163
- }));
1164
- assertOptimizationResult(opts.method.name, result);
1165
- optimizationResult = structuredClone(result);
1166
- return [{
1167
- surface: structuredClone(result.winnerSurface),
1168
- label: opts.method.name,
1169
- rationale: `${opts.method.name} selected this surface without final cases.`
1170
- }];
1171
- }
1172
- } : opts.proposer ?? {
1395
+ if (opts.method) {
1396
+ const partitions = splitMethodPartitions(train, opts.selectionScenarios, budget.selectionFraction ?? .25);
1397
+ return runSelfImproveMethod({
1398
+ opts: {
1399
+ ...opts,
1400
+ method: opts.method
1401
+ },
1402
+ train: partitions.train,
1403
+ selection: partitions.selection,
1404
+ holdout,
1405
+ costLedger,
1406
+ storage,
1407
+ runDir,
1408
+ startedAt
1409
+ });
1410
+ }
1411
+ const generations = budget.generations ?? 3;
1412
+ const populationSize = budget.populationSize ?? 2;
1413
+ if (generations > 0 && !opts.proposer) throw new Error("selfImprove: method or proposer is required when budget.generations is greater than zero");
1414
+ const proposer = opts.proposer ?? {
1173
1415
  kind: "baseline-only",
1174
1416
  propose: async () => []
1175
1417
  };
@@ -1186,6 +1428,7 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
1186
1428
  baselineSurface: opts.baselineSurface,
1187
1429
  premeasuredBaseline: opts.premeasuredBaseline,
1188
1430
  dispatchWithSurface: opts.agent,
1431
+ dispatchRef: opts.dispatchRef,
1189
1432
  proposer,
1190
1433
  judges: [opts.judge],
1191
1434
  populationSize,
@@ -1255,9 +1498,9 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
1255
1498
  const cost = result.cost;
1256
1499
  const totalCost = cost.totalCostUsd;
1257
1500
  const insight = await analyzeRuns({
1258
- runs: [...cellsToRunRecords(reportBaselineCampaign.cells, "baseline", runDir, opts.baselineSurface, reportSplit, opts.model), ...cellsToRunRecords(reportWinnerCampaign.cells, "winner", runDir, result.winnerSurface, reportSplit, opts.model)],
1501
+ runs: [...cellsToRunRecords(reportBaselineCampaign.cells, "baseline", runDir, opts.baselineSurface, reportSplit, opts.model), ...reportWinnerCampaign === reportBaselineCampaign ? [] : cellsToRunRecords(reportWinnerCampaign.cells, "winner", runDir, result.winnerSurface, reportSplit, opts.model)],
1259
1502
  baselineCandidateId: "baseline",
1260
- candidateCandidateId: "winner"
1503
+ ...reportWinnerCampaign === reportBaselineCampaign ? {} : { candidateCandidateId: "winner" }
1261
1504
  });
1262
1505
  const durationMs = Date.now() - startedAt;
1263
1506
  const { record: provenance } = await emitLoopProvenance({
@@ -1271,17 +1514,12 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
1271
1514
  totalCostUsd: totalCost,
1272
1515
  totalDurationMs: durationMs
1273
1516
  }),
1274
- ...optimizationResult ? { optimizationMethod: {
1275
- name: opts.method.name,
1276
- cost: structuredClone(optimizationResult.cost),
1277
- ...optimizationResult.durationMs === void 0 ? {} : { durationMs: optimizationResult.durationMs },
1278
- ...optimizationResult.provenance === void 0 ? {} : { provenance: structuredClone(optimizationResult.provenance) }
1279
- } } : {},
1280
1517
  storage,
1281
1518
  hostedClient: opts.hostedTenant ? createHostedClient(opts.hostedTenant) : void 0
1282
1519
  });
1283
1520
  if (opts.onProvenance) opts.onProvenance(provenance);
1284
1521
  const summary = {
1522
+ mode: "proposer",
1285
1523
  baseline,
1286
1524
  winner: {
1287
1525
  ...winnerStats,
@@ -1298,12 +1536,6 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
1298
1536
  totalCostUsd: totalCost,
1299
1537
  cost,
1300
1538
  receipts: costLedger.list(),
1301
- ...optimizationResult ? { optimization: {
1302
- name: opts.method.name,
1303
- cost: structuredClone(optimizationResult.cost),
1304
- ...optimizationResult.durationMs === void 0 ? {} : { durationMs: optimizationResult.durationMs },
1305
- ...optimizationResult.provenance === void 0 ? {} : { provenance: structuredClone(optimizationResult.provenance) }
1306
- } } : {},
1307
1539
  ...result.searchHistory ? { searchHistory: result.searchHistory } : {},
1308
1540
  insight,
1309
1541
  ...power ? { power } : {},
@@ -1371,52 +1603,6 @@ function averageComposite(campaign) {
1371
1603
  const aggs = Object.values(campaign.aggregates.byScenario);
1372
1604
  return aggs.length === 0 ? 0 : aggs.reduce((s, a) => s + a.meanComposite, 0) / aggs.length;
1373
1605
  }
1374
- /** 32-bit FNV-1a over raw UTF-16 code units, rendered as hex for a cell key.
1375
- *
1376
- * Frozen: the key names a persisted cell, so a change orphans every cell
1377
- * already written. Same loop as `stableScenarioHash` above but a different
1378
- * return form; neither is a general-purpose hash. */
1379
- function hashString(s) {
1380
- let h = 2166136261;
1381
- for (let i = 0; i < s.length; i++) {
1382
- h ^= s.charCodeAt(i);
1383
- h = Math.imul(h, 16777619) >>> 0;
1384
- }
1385
- return h.toString(16).padStart(8, "0");
1386
- }
1387
- /**
1388
- * Adapt campaign cells into the `RunRecord` shape `analyzeRuns()` consumes.
1389
- * Each cell becomes one run; `candidateId` is the caller-supplied label so
1390
- * baseline + winner pair cleanly on `(experimentId, scenarioId, seed)`.
1391
- *
1392
- * `promptHash` is the REAL sha256 content hash of the surface this cell ran
1393
- * (baseline vs winner are byte-distinguishable + byte-identical-verifiable);
1394
- * `configHash` is the sha256 of the candidate label so the two candidates'
1395
- * config rows differ. Both were previously the literal `'sha256:cell'`, which
1396
- * made baseline and winner indistinguishable in every downstream record.
1397
- */
1398
- function cellsToRunRecords(cells, candidateId, runId, surface, splitTag, fallbackModel) {
1399
- const promptHash = surfaceContentHash(surface);
1400
- const configHash = surfaceContentHash(candidateId);
1401
- return cells.map((cell) => {
1402
- const receiptModels = cell.resolvedModels ?? (cell.resolvedModel ? [cell.resolvedModel] : []);
1403
- if (receiptModels.length > 1) throw new ValidationError(`selfImprove cell ${cell.cellId} used multiple agent models: ${receiptModels.join(", ")}`);
1404
- const model = receiptModels[0] ?? fallbackModel;
1405
- if (!model) throw new ValidationError(`selfImprove.model is required when cell ${cell.cellId} has no paid-call model receipt`);
1406
- if (!modelHasSnapshot(model)) throw new ValidationError(`selfImprove model "${model}" lacks a snapshot version for cell ${cell.cellId}`);
1407
- return campaignCellToRunRecord(cell, {
1408
- runId: `${runId}::${candidateId}::${cell.cellId}`,
1409
- experimentId: runId,
1410
- candidateId,
1411
- seed: cell.rep * 1e6 + hashString(cell.scenarioId).slice(0, 6).split("").reduce((a, c) => a * 31 + c.charCodeAt(0) >>> 0, 0),
1412
- model,
1413
- promptHash,
1414
- configHash,
1415
- commitSha: "cell",
1416
- splitTag
1417
- });
1418
- });
1419
- }
1420
1606
  //#endregion
1421
1607
  //#region src/contract/define-agent-eval.ts
1422
1608
  /**
@@ -1444,6 +1630,7 @@ function defineAgentEval(defaults) {
1444
1630
  runDir: selectedRunDir,
1445
1631
  scenarios: scenarios ?? defaults.scenarios,
1446
1632
  dispatch: (scenario, ctx) => selectedAgent(selectedSurface, scenario, ctx),
1633
+ dispatchRef: surfaceDispatchRef(selectedSurface, campaignOpts.dispatchRef ?? defaults.dispatchRef),
1447
1634
  judges: evaluateJudges(judges, judge ?? defaults.judge)
1448
1635
  };
1449
1636
  if (evalOptions.reps !== void 0) evalOptions.reps = requirePositiveInteger(evalOptions.reps, "reps");
@@ -1509,4 +1696,4 @@ function requirePositiveInteger(value, field) {
1509
1696
  //#endregion
1510
1697
  export { summarizeExecution as a, analyzeRuns as i, SelfImproveRunError as n, checkCanaries as o, selfImprove as r, defineAgentEval as t };
1511
1698
 
1512
- //# sourceMappingURL=define-agent-eval-8h3lXXee.js.map
1699
+ //# sourceMappingURL=define-agent-eval-ox5McL6e.js.map