@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.
- package/CHANGELOG.md +2 -0
- package/dist/analyst/index.js +4 -4
- package/dist/benchmarks/index.js +5 -5
- package/dist/campaign/index.d.ts +140 -11
- package/dist/campaign/index.js +5 -5
- package/dist/{chunk-ULOKLHIQ.js → chunk-A5S77LSE.js} +3 -3
- package/dist/{chunk-MUS5DOH7.js → chunk-FC5NDO3E.js} +2 -2
- package/dist/{chunk-MI2H23RV.js → chunk-G2GPNLSX.js} +2 -2
- package/dist/{chunk-ZDAKRZG5.js → chunk-GS3FJGUF.js} +25 -6
- package/dist/{chunk-ZDAKRZG5.js.map → chunk-GS3FJGUF.js.map} +1 -1
- package/dist/{chunk-S6IL3R5I.js → chunk-HZJF4IUO.js} +72 -33
- package/dist/{chunk-S6IL3R5I.js.map → chunk-HZJF4IUO.js.map} +1 -1
- package/dist/{chunk-PXD6ZFNY.js → chunk-IR3KBHOY.js} +19 -1
- package/dist/{chunk-PXD6ZFNY.js.map → chunk-IR3KBHOY.js.map} +1 -1
- package/dist/{chunk-WW2A73HW.js → chunk-NUKSVU3W.js} +2 -2
- package/dist/{chunk-BVMWQDC5.js → chunk-VJ7T5WIO.js} +3 -3
- package/dist/contract/index.d.ts +62 -11
- package/dist/contract/index.js +36 -11
- package/dist/contract/index.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +8 -8
- package/dist/openapi.json +1 -1
- package/dist/traces.js +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-ULOKLHIQ.js.map → chunk-A5S77LSE.js.map} +0 -0
- /package/dist/{chunk-MUS5DOH7.js.map → chunk-FC5NDO3E.js.map} +0 -0
- /package/dist/{chunk-MI2H23RV.js.map → chunk-G2GPNLSX.js.map} +0 -0
- /package/dist/{chunk-WW2A73HW.js.map → chunk-NUKSVU3W.js.map} +0 -0
- /package/dist/{chunk-BVMWQDC5.js.map → chunk-VJ7T5WIO.js.map} +0 -0
package/dist/contract/index.d.ts
CHANGED
|
@@ -2386,6 +2386,15 @@ type RunImprovementLoopOptions<TScenario extends Scenario, TArtifact> = RunOptim
|
|
|
2386
2386
|
/** Holdout scenarios kept OUT of the training optimization pool — used
|
|
2387
2387
|
* ONLY to score baseline vs winner for the gate. */
|
|
2388
2388
|
holdoutScenarios: TScenario[];
|
|
2389
|
+
/** Holdout policy. Default `'measured'`: baseline + winner are re-scored on
|
|
2390
|
+
* `holdoutScenarios` and the gate decides on that held-out comparison.
|
|
2391
|
+
* `'deferred'`: the improvement-set (search) campaigns run exactly as usual,
|
|
2392
|
+
* but ZERO holdout cells are dispatched, the gate is forced to `'hold'`, and
|
|
2393
|
+
* the result + provenance record carry `holdout: 'deferred'` with NO
|
|
2394
|
+
* held-out lift — for callers that measure the held-out comparison in a
|
|
2395
|
+
* separate later run instead of faking a static holdout scenario and
|
|
2396
|
+
* recording a meaningless lift. */
|
|
2397
|
+
holdout?: 'measured' | 'deferred';
|
|
2389
2398
|
/** Promotion gate. Substrate strongly recommends `defaultProductionGate`
|
|
2390
2399
|
* for production wiring (composes red-team / reward-hacking / canary /
|
|
2391
2400
|
* heldout). */
|
|
@@ -2413,6 +2422,10 @@ interface RunImprovementLoopResult<TArtifact, TScenario extends Scenario> extend
|
|
|
2413
2422
|
neutralizedOnHoldout?: CampaignResult<TArtifact, TScenario>;
|
|
2414
2423
|
neutralizedSurface?: MutableSurface;
|
|
2415
2424
|
gateResult: Awaited<ReturnType<Gate<TArtifact, TScenario>['decide']>>;
|
|
2425
|
+
/** Present iff the loop ran with `holdout: 'deferred'`. When set,
|
|
2426
|
+
* `baselineOnHoldout`/`winnerOnHoldout` are the shared EMPTY campaign (zero
|
|
2427
|
+
* cells dispatched) and the gate verdict is the forced `'hold'`. */
|
|
2428
|
+
holdout?: 'deferred';
|
|
2416
2429
|
/** Unified baseline→winner surface diff. Computed UNCONDITIONALLY (not only
|
|
2417
2430
|
* when `autoOnPromote === 'pr'`) so the diff that the gate decided on is
|
|
2418
2431
|
* always present on the result + in the emitted provenance record. Empty
|
|
@@ -3715,12 +3728,18 @@ interface LoopProvenanceRecord {
|
|
|
3715
3728
|
detail: unknown;
|
|
3716
3729
|
}>;
|
|
3717
3730
|
};
|
|
3718
|
-
/**
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3731
|
+
/** Present iff the loop ran with `holdout: 'deferred'` — the held-out
|
|
3732
|
+
* comparison was intentionally not measured in this run, so the holdout
|
|
3733
|
+
* composites and `heldOutLift` are ABSENT rather than recorded as a
|
|
3734
|
+
* meaningless 0. */
|
|
3735
|
+
holdout?: 'deferred';
|
|
3736
|
+
/** baseline-on-holdout composite mean. Absent when `holdout === 'deferred'`. */
|
|
3737
|
+
baselineHoldoutComposite?: number;
|
|
3738
|
+
/** winner-on-holdout composite mean. Absent when `holdout === 'deferred'`. */
|
|
3739
|
+
winnerHoldoutComposite?: number;
|
|
3740
|
+
/** winnerHoldout - baselineHoldout — RECOMPUTABLE from this record. Absent
|
|
3741
|
+
* when `holdout === 'deferred'` (no held-out measurement ran). */
|
|
3742
|
+
heldOutLift?: number;
|
|
3724
3743
|
/** Backend provenance: stub-vs-real verdict + worker call count + models. */
|
|
3725
3744
|
backend: LoopProvenanceBackend;
|
|
3726
3745
|
totalCostUsd: number;
|
|
@@ -3767,8 +3786,22 @@ interface SelfImproveBudget {
|
|
|
3767
3786
|
holdoutFraction?: number;
|
|
3768
3787
|
/** Explicit held-out scenarios; overrides `holdoutFraction`. */
|
|
3769
3788
|
holdoutScenarios?: Scenario[];
|
|
3789
|
+
/** Holdout policy. Default `'measured'`: split, re-score baseline vs winner
|
|
3790
|
+
* on the held-out set, gate on that comparison. `'deferred'`: run the
|
|
3791
|
+
* improvement-set campaigns + search promotion, dispatch ZERO holdout cells,
|
|
3792
|
+
* force the gate to `'hold'`, return `lift: undefined`, and record
|
|
3793
|
+
* `holdout: 'deferred'` in the provenance record — for callers that measure
|
|
3794
|
+
* the held-out comparison in a separate later run instead of faking a
|
|
3795
|
+
* static holdout scenario and recording a meaningless lift. Unless
|
|
3796
|
+
* `holdoutScenarios` reserves an explicit set, ALL scenarios train. */
|
|
3797
|
+
holdout?: 'measured' | 'deferred';
|
|
3770
3798
|
/** Per-scenario replicates per cell — raises bootstrap-CI tightness. Default 1. */
|
|
3771
3799
|
reps?: number;
|
|
3800
|
+
/** DEPTH dial forwarded to the proposer's `propose()` as
|
|
3801
|
+
* `ctx.maxImprovementShots` — max iterations an agentic candidate generator
|
|
3802
|
+
* may take per candidate (verify-in-session retries). Unset ⇒ the
|
|
3803
|
+
* proposer's own default. */
|
|
3804
|
+
maxImprovementShots?: number;
|
|
3772
3805
|
/** @deprecated Must be 1 when supplied. The loop promotes only a candidate
|
|
3773
3806
|
* that replaces its single global incumbent. */
|
|
3774
3807
|
promoteTopK?: number;
|
|
@@ -3801,7 +3834,7 @@ type SelfImproveProgressEvent = {
|
|
|
3801
3834
|
} | {
|
|
3802
3835
|
kind: 'gate.decided';
|
|
3803
3836
|
decision: string;
|
|
3804
|
-
lift
|
|
3837
|
+
lift?: number;
|
|
3805
3838
|
} | {
|
|
3806
3839
|
kind: 'power.estimated';
|
|
3807
3840
|
n: number;
|
|
@@ -3835,6 +3868,18 @@ interface SelfImproveOptions<TScenario extends Scenario, TArtifact> {
|
|
|
3835
3868
|
baselineSurface: MutableSurface;
|
|
3836
3869
|
/** Budget + loop shape. All fields optional. */
|
|
3837
3870
|
budget?: SelfImproveBudget;
|
|
3871
|
+
/**
|
|
3872
|
+
* Complete prior measurement of `baselineSurface` over the TRAIN split.
|
|
3873
|
+
* Forwarded to the loop body, which validates its surface hash, scenario
|
|
3874
|
+
* split, seed (42), reps, and coverage, then skips the baseline search
|
|
3875
|
+
* campaign entirely — no baseline dispatch, no resumability lookup. The
|
|
3876
|
+
* train split is `scenarios` minus the holdout split, so premeasure with
|
|
3877
|
+
* exactly that scenario set (explicit `budget.holdoutScenarios`, or
|
|
3878
|
+
* `budget.holdout: 'deferred'` with no reserved set, makes the train split
|
|
3879
|
+
* deterministic). Prior spend stays in the imported campaign aggregates and
|
|
3880
|
+
* is not re-added to this run's cost ledger.
|
|
3881
|
+
*/
|
|
3882
|
+
premeasuredBaseline?: PremeasuredOptimizationBaseline<TArtifact, TScenario>;
|
|
3838
3883
|
/** Custom surface proposer. Default is `gepaProposer` configured from `llm` +
|
|
3839
3884
|
* `mutationPrimitives`. */
|
|
3840
3885
|
proposer?: SurfaceProposer;
|
|
@@ -3934,12 +3979,16 @@ interface SelfImproveOptions<TScenario extends Scenario, TArtifact> {
|
|
|
3934
3979
|
findings?: unknown[];
|
|
3935
3980
|
}
|
|
3936
3981
|
interface SelfImproveResult<TScenario extends Scenario, TArtifact> {
|
|
3937
|
-
/** Composite mean across all scenarios, baseline run.
|
|
3982
|
+
/** Composite mean across all scenarios, baseline run. When
|
|
3983
|
+
* `budget.holdout === 'deferred'` this is measured on the improvement
|
|
3984
|
+
* (search) split — no holdout campaign ran. */
|
|
3938
3985
|
baseline: {
|
|
3939
3986
|
compositeMean: number;
|
|
3940
3987
|
perScenario: Record<string, number>;
|
|
3941
3988
|
};
|
|
3942
|
-
/** Composite mean on the held-out set, winner run.
|
|
3989
|
+
/** Composite mean on the held-out set, winner run. When
|
|
3990
|
+
* `budget.holdout === 'deferred'` this is the winner's improvement-set
|
|
3991
|
+
* (search) measurement — no holdout campaign ran. */
|
|
3943
3992
|
winner: {
|
|
3944
3993
|
compositeMean: number;
|
|
3945
3994
|
perScenario: Record<string, number>;
|
|
@@ -3953,8 +4002,10 @@ interface SelfImproveResult<TScenario extends Scenario, TArtifact> {
|
|
|
3953
4002
|
rationale?: string;
|
|
3954
4003
|
};
|
|
3955
4004
|
/** `winner.compositeMean - baselineOnHoldout.compositeMean`. Positive
|
|
3956
|
-
* means the gate observed improvement.
|
|
3957
|
-
|
|
4005
|
+
* means the gate observed improvement. Absent iff
|
|
4006
|
+
* `budget.holdout === 'deferred'` — no held-out measurement ran, so there
|
|
4007
|
+
* is no lift to report (never a fabricated 0). */
|
|
4008
|
+
lift?: number;
|
|
3958
4009
|
/** The explicit baseline→winner unified diff. Always present (empty string
|
|
3959
4010
|
* when winner == baseline). */
|
|
3960
4011
|
diff: string;
|
package/dist/contract/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
runReferenceEquivalenceJudge,
|
|
37
37
|
surfaceContentHash,
|
|
38
38
|
surfaceHash
|
|
39
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-HZJF4IUO.js";
|
|
40
40
|
import {
|
|
41
41
|
campaignSplitDigest,
|
|
42
42
|
createRunCostLedger,
|
|
@@ -48,9 +48,9 @@ import {
|
|
|
48
48
|
import {
|
|
49
49
|
buildDefaultAnalystRegistry,
|
|
50
50
|
createChatClient
|
|
51
|
-
} from "../chunk-
|
|
51
|
+
} from "../chunk-VJ7T5WIO.js";
|
|
52
52
|
import "../chunk-HHWE3POT.js";
|
|
53
|
-
import "../chunk-
|
|
53
|
+
import "../chunk-FC5NDO3E.js";
|
|
54
54
|
import {
|
|
55
55
|
FileSystemOutcomeStore,
|
|
56
56
|
InMemoryOutcomeStore
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
import "../chunk-PXE2VKMX.js";
|
|
71
71
|
import "../chunk-ZET2UAYW.js";
|
|
72
72
|
import "../chunk-GGE4NNQT.js";
|
|
73
|
-
import "../chunk-
|
|
73
|
+
import "../chunk-IR3KBHOY.js";
|
|
74
74
|
import "../chunk-PC4UYEBM.js";
|
|
75
75
|
import {
|
|
76
76
|
parseRunRecordSafe
|
|
@@ -125,6 +125,15 @@ function meanComposite(byScenario) {
|
|
|
125
125
|
perScenario
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
+
function winnerSearchCampaign(result) {
|
|
129
|
+
for (let i = result.generations.length - 1; i >= 0; i--) {
|
|
130
|
+
const measured = result.generations[i]?.surfaces.find(
|
|
131
|
+
(s) => s.surfaceHash === result.winnerSurfaceHash
|
|
132
|
+
);
|
|
133
|
+
if (measured) return measured.campaign;
|
|
134
|
+
}
|
|
135
|
+
return result.baselineCampaign;
|
|
136
|
+
}
|
|
128
137
|
async function selfImprove(opts) {
|
|
129
138
|
const startedAt = Date.now();
|
|
130
139
|
const requestedRunDir = opts.runDir ?? `mem://selfImprove-${startedAt}`;
|
|
@@ -147,18 +156,20 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
|
|
|
147
156
|
const populationSize = budget.populationSize ?? 2;
|
|
148
157
|
const maxConcurrency = budget.maxConcurrency ?? 2;
|
|
149
158
|
const holdoutFraction = budget.holdoutFraction ?? 0.25;
|
|
159
|
+
const holdoutMode = budget.holdout ?? "measured";
|
|
160
|
+
const holdoutDeferred = holdoutMode === "deferred";
|
|
150
161
|
const expectUsage = opts.expectUsage ?? "assert";
|
|
151
162
|
const explicitHoldout = budget.holdoutScenarios;
|
|
152
163
|
const { train, holdout } = explicitHoldout ? {
|
|
153
164
|
train: opts.scenarios.filter((s) => !explicitHoldout.some((h) => h.id === s.id)),
|
|
154
165
|
holdout: explicitHoldout
|
|
155
|
-
} : splitTrainHoldout(opts.scenarios, holdoutFraction);
|
|
166
|
+
} : holdoutDeferred ? { train: opts.scenarios, holdout: [] } : splitTrainHoldout(opts.scenarios, holdoutFraction);
|
|
156
167
|
if (train.length === 0) {
|
|
157
168
|
throw new Error(
|
|
158
169
|
"selfImprove: train split is empty. Reduce holdoutFraction or pass more scenarios."
|
|
159
170
|
);
|
|
160
171
|
}
|
|
161
|
-
if (holdout.length === 0) {
|
|
172
|
+
if (holdout.length === 0 && !holdoutDeferred) {
|
|
162
173
|
throw new Error("selfImprove: holdout split is empty. Pass more scenarios.");
|
|
163
174
|
}
|
|
164
175
|
const proposer = opts.proposer ?? gepaProposer({
|
|
@@ -182,6 +193,7 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
|
|
|
182
193
|
const result = await runImprovementLoop({
|
|
183
194
|
scenarios: train,
|
|
184
195
|
baselineSurface: opts.baselineSurface,
|
|
196
|
+
premeasuredBaseline: opts.premeasuredBaseline,
|
|
185
197
|
dispatchWithSurface: opts.agent,
|
|
186
198
|
proposer,
|
|
187
199
|
judges: [opts.judge],
|
|
@@ -189,7 +201,9 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
|
|
|
189
201
|
maxGenerations: generations,
|
|
190
202
|
promoteTopK: budget.promoteTopK,
|
|
191
203
|
reps: budget.reps,
|
|
204
|
+
maxImprovementShots: budget.maxImprovementShots,
|
|
192
205
|
holdoutScenarios: holdout,
|
|
206
|
+
holdout: holdoutMode,
|
|
193
207
|
gate,
|
|
194
208
|
neutralize: opts.neutralize,
|
|
195
209
|
autoOnPromote: opts.autoOnPromote ?? "none",
|
|
@@ -207,8 +221,11 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
|
|
|
207
221
|
analyzeGeneration: opts.analyzeGeneration,
|
|
208
222
|
findings: opts.findings
|
|
209
223
|
});
|
|
210
|
-
const
|
|
211
|
-
const
|
|
224
|
+
const winnerSearch = holdoutDeferred ? winnerSearchCampaign(result) : void 0;
|
|
225
|
+
const baseline = meanComposite(
|
|
226
|
+
(holdoutDeferred ? result.baselineCampaign : result.baselineOnHoldout).aggregates.byScenario
|
|
227
|
+
);
|
|
228
|
+
const winnerStats = meanComposite((winnerSearch ?? result.winnerOnHoldout).aggregates.byScenario);
|
|
212
229
|
let power;
|
|
213
230
|
const baselineHoldoutComposites = result.baselineOnHoldout.cells.filter((cell) => !cell.error).map((cell) => {
|
|
214
231
|
const scores = Object.values(cell.judgeScores);
|
|
@@ -241,7 +258,10 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
|
|
|
241
258
|
opts.onProgress({
|
|
242
259
|
kind: "gate.decided",
|
|
243
260
|
decision: result.gateResult.decision,
|
|
244
|
-
|
|
261
|
+
// Deferred holdout has no held-out measurement: in that mode the summary
|
|
262
|
+
// stats are search-split numbers, and emitting their delta as `lift`
|
|
263
|
+
// would misreport a train-split delta as a held-out one. Omit instead.
|
|
264
|
+
...holdoutDeferred ? {} : { lift: winnerStats.compositeMean - baseline.compositeMean }
|
|
245
265
|
});
|
|
246
266
|
}
|
|
247
267
|
const cost = result.cost;
|
|
@@ -249,7 +269,12 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
|
|
|
249
269
|
const insight = await analyzeRuns({
|
|
250
270
|
runs: [
|
|
251
271
|
...cellsToRunRecords(result.baselineCampaign.cells, "baseline", runDir, opts.baselineSurface),
|
|
252
|
-
...cellsToRunRecords(
|
|
272
|
+
...cellsToRunRecords(
|
|
273
|
+
(winnerSearch ?? result.winnerOnHoldout).cells,
|
|
274
|
+
"winner",
|
|
275
|
+
runDir,
|
|
276
|
+
result.winnerSurface
|
|
277
|
+
)
|
|
253
278
|
],
|
|
254
279
|
baselineCandidateId: "baseline",
|
|
255
280
|
candidateCandidateId: "winner"
|
|
@@ -278,7 +303,7 @@ async function runSelfImprove(opts, costLedger, startedAt, runDir, storage) {
|
|
|
278
303
|
...result.winnerLabel ? { label: result.winnerLabel } : {},
|
|
279
304
|
...result.winnerRationale ? { rationale: result.winnerRationale } : {}
|
|
280
305
|
},
|
|
281
|
-
lift: winnerStats.compositeMean - baseline.compositeMean,
|
|
306
|
+
...holdoutDeferred ? {} : { lift: winnerStats.compositeMean - baseline.compositeMean },
|
|
282
307
|
diff: result.promotedDiff,
|
|
283
308
|
provenance,
|
|
284
309
|
gateDecision: result.gateResult.decision,
|