@tangle-network/agent-eval 0.126.7 → 0.128.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 +59 -0
- package/README.md +6 -2
- package/dist/analyst/index.d.ts +52 -43
- package/dist/analyst/index.js +4 -4
- package/dist/belief-state/index.d.ts +35 -40
- package/dist/belief-state/index.js +2 -2
- package/dist/benchmarks/index.d.ts +30 -12
- package/dist/benchmarks/index.js +12 -11
- package/dist/builder-eval/index.js +1 -1
- package/dist/campaign/index.d.ts +441 -160
- package/dist/campaign/index.js +11 -10
- package/dist/{chunk-IILEIWGW.js → chunk-2JX3CFMB.js} +100 -40
- package/dist/chunk-2JX3CFMB.js.map +1 -0
- package/dist/chunk-2MKQIFS4.js +183 -0
- package/dist/chunk-2MKQIFS4.js.map +1 -0
- package/dist/{chunk-NUKSVU3W.js → chunk-5DTSBUL2.js} +2 -2
- package/dist/{chunk-H5UD2323.js → chunk-7ZZMD7UK.js} +102 -2
- package/dist/chunk-7ZZMD7UK.js.map +1 -0
- package/dist/{chunk-474LBSOX.js → chunk-BYT7ELPS.js} +45 -18
- package/dist/chunk-BYT7ELPS.js.map +1 -0
- package/dist/{chunk-LUNF2SEL.js → chunk-DJKY2TSY.js} +3 -3
- package/dist/chunk-DPUHNQLN.js +232 -0
- package/dist/chunk-DPUHNQLN.js.map +1 -0
- package/dist/chunk-DRYIUNWY.js +622 -0
- package/dist/chunk-DRYIUNWY.js.map +1 -0
- package/dist/{chunk-IPYXE555.js → chunk-EJGRPCO3.js} +36 -13
- package/dist/chunk-EJGRPCO3.js.map +1 -0
- package/dist/{chunk-OCFJACJU.js → chunk-EOSZT7PL.js} +82 -18
- package/dist/chunk-EOSZT7PL.js.map +1 -0
- package/dist/{chunk-ZVCHKKOP.js → chunk-EZJEIH2R.js} +39 -15
- package/dist/chunk-EZJEIH2R.js.map +1 -0
- package/dist/{chunk-M7AH34KV.js → chunk-IHQDPH7D.js} +32 -16
- package/dist/chunk-IHQDPH7D.js.map +1 -0
- package/dist/{chunk-PJQFMIOX.js → chunk-MHELPNRP.js} +31 -1
- package/dist/chunk-MHELPNRP.js.map +1 -0
- package/dist/{chunk-K6IAZZ6L.js → chunk-NACAGYSY.js} +153 -122
- package/dist/chunk-NACAGYSY.js.map +1 -0
- package/dist/{chunk-BTACVO2W.js → chunk-NKAGIDE2.js} +542 -258
- package/dist/chunk-NKAGIDE2.js.map +1 -0
- package/dist/{chunk-ARU2PZFM.js → chunk-NYLOYM6N.js} +43 -23
- package/dist/chunk-NYLOYM6N.js.map +1 -0
- package/dist/{chunk-QOTFXW5L.js → chunk-P5W7RQKK.js} +2 -2
- package/dist/{chunk-IR3KBHOY.js → chunk-P6FYH6K4.js} +39 -3
- package/dist/chunk-P6FYH6K4.js.map +1 -0
- package/dist/{chunk-J5SQWP6Y.js → chunk-PBE2LOSS.js} +18 -2
- package/dist/chunk-PBE2LOSS.js.map +1 -0
- package/dist/{chunk-X4UCIOTZ.js → chunk-S5YLIBFX.js} +2 -2
- package/dist/{chunk-7VYEGHWF.js → chunk-SZLVEKMJ.js} +41 -20
- package/dist/chunk-SZLVEKMJ.js.map +1 -0
- package/dist/{chunk-P22LJ3Y2.js → chunk-TBL77AUT.js} +8 -8
- package/dist/chunk-TBL77AUT.js.map +1 -0
- package/dist/{chunk-LKKT3IVV.js → chunk-TSN7JT6D.js} +6 -4
- package/dist/{chunk-LKKT3IVV.js.map → chunk-TSN7JT6D.js.map} +1 -1
- package/dist/{chunk-E3IADPLG.js → chunk-UB2LOJ6Q.js} +51 -227
- package/dist/chunk-UB2LOJ6Q.js.map +1 -0
- package/dist/{chunk-MAX3TN3C.js → chunk-UWZZKKU7.js} +7 -19
- package/dist/chunk-UWZZKKU7.js.map +1 -0
- package/dist/{chunk-DPZAEKA6.js → chunk-VLOATJQ2.js} +85 -57
- package/dist/chunk-VLOATJQ2.js.map +1 -0
- package/dist/{chunk-MOXWMGPC.js → chunk-XDWDC2MP.js} +197 -79
- package/dist/chunk-XDWDC2MP.js.map +1 -0
- package/dist/{chunk-CGG5SLH3.js → chunk-XPRT64IE.js} +2 -2
- package/dist/{chunk-FO7HEH76.js → chunk-YJBNWCAA.js} +2 -2
- package/dist/{chunk-KE2VWPZX.js → chunk-ZUUWPZCV.js} +3 -3
- package/dist/cli.js +4 -4
- package/dist/contract/index.d.ts +438 -138
- package/dist/contract/index.js +259 -113
- package/dist/contract/index.js.map +1 -1
- package/dist/control.d.ts +56 -39
- package/dist/control.js +2 -3
- package/dist/hosted/index.d.ts +152 -51
- package/dist/hosted/index.js +24 -1
- package/dist/index.d.ts +399 -277
- package/dist/index.js +363 -244
- package/dist/index.js.map +1 -1
- package/dist/meta-eval/index.d.ts +33 -36
- package/dist/meta-eval/index.js +2 -2
- package/dist/multishot/index.d.ts +1 -0
- package/dist/openapi.json +1 -1
- package/dist/pipelines/index.js +2 -2
- package/dist/reporting.d.ts +101 -80
- package/dist/reporting.js +7 -5
- package/dist/rl.d.ts +198 -142
- package/dist/rl.js +235 -127
- package/dist/rl.js.map +1 -1
- package/dist/rollout/index.d.ts +54 -67
- package/dist/rollout/index.js +6 -5
- package/dist/{run-campaign-FFRM3RH5.js → run-campaign-ISHFZ7FJ.js} +6 -3
- package/dist/supervisor-run/index.d.ts +7 -15
- package/dist/supervisor-run/index.js +2 -2
- package/dist/traces.d.ts +72 -50
- package/dist/traces.js +9 -6
- package/dist/wire/index.d.ts +1 -0
- package/dist/wire/index.js +2 -2
- package/docs/concepts.md +18 -1
- package/docs/customer-journeys.md +7 -6
- package/docs/hosted-ingest-spec.md +37 -40
- package/docs/insight-report.md +78 -7
- package/docs/research-report-methodology.md +20 -21
- package/docs/rollout.md +13 -8
- package/package.json +4 -3
- package/dist/chunk-474LBSOX.js.map +0 -1
- package/dist/chunk-7VYEGHWF.js.map +0 -1
- package/dist/chunk-ARU2PZFM.js.map +0 -1
- package/dist/chunk-BTACVO2W.js.map +0 -1
- package/dist/chunk-DPZAEKA6.js.map +0 -1
- package/dist/chunk-E3IADPLG.js.map +0 -1
- package/dist/chunk-H5UD2323.js.map +0 -1
- package/dist/chunk-IILEIWGW.js.map +0 -1
- package/dist/chunk-IPYXE555.js.map +0 -1
- package/dist/chunk-IR3KBHOY.js.map +0 -1
- package/dist/chunk-J5SQWP6Y.js.map +0 -1
- package/dist/chunk-K6IAZZ6L.js.map +0 -1
- package/dist/chunk-M7AH34KV.js.map +0 -1
- package/dist/chunk-MAX3TN3C.js.map +0 -1
- package/dist/chunk-MOXWMGPC.js.map +0 -1
- package/dist/chunk-OCFJACJU.js.map +0 -1
- package/dist/chunk-P22LJ3Y2.js.map +0 -1
- package/dist/chunk-PJQFMIOX.js.map +0 -1
- package/dist/chunk-VSMTAMNK.js +0 -53
- package/dist/chunk-VSMTAMNK.js.map +0 -1
- package/dist/chunk-ZVCHKKOP.js.map +0 -1
- package/dist/chunk-ZZUXHH3R.js +0 -99
- package/dist/chunk-ZZUXHH3R.js.map +0 -1
- /package/dist/{chunk-NUKSVU3W.js.map → chunk-5DTSBUL2.js.map} +0 -0
- /package/dist/{chunk-LUNF2SEL.js.map → chunk-DJKY2TSY.js.map} +0 -0
- /package/dist/{chunk-QOTFXW5L.js.map → chunk-P5W7RQKK.js.map} +0 -0
- /package/dist/{chunk-X4UCIOTZ.js.map → chunk-S5YLIBFX.js.map} +0 -0
- /package/dist/{chunk-CGG5SLH3.js.map → chunk-XPRT64IE.js.map} +0 -0
- /package/dist/{chunk-FO7HEH76.js.map → chunk-YJBNWCAA.js.map} +0 -0
- /package/dist/{chunk-KE2VWPZX.js.map → chunk-ZUUWPZCV.js.map} +0 -0
- /package/dist/{run-campaign-FFRM3RH5.js.map → run-campaign-ISHFZ7FJ.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
checkBehavioralCanary,
|
|
10
10
|
checkCanaries,
|
|
11
11
|
runBehavioralCanaries
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-NACAGYSY.js";
|
|
13
13
|
import {
|
|
14
14
|
mintRolloutRows,
|
|
15
15
|
rolloutReward
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-IHQDPH7D.js";
|
|
17
17
|
import {
|
|
18
18
|
SUPERVISOR_RUN_SCHEMA,
|
|
19
19
|
analyzeSupervisorRun,
|
|
@@ -27,26 +27,25 @@ import {
|
|
|
27
27
|
showMeasured,
|
|
28
28
|
supervisorRunRolloutLines,
|
|
29
29
|
writeSupervisorRunReport
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-TSN7JT6D.js";
|
|
31
31
|
import "./chunk-VBQ3CRKH.js";
|
|
32
32
|
import {
|
|
33
33
|
toJsonl,
|
|
34
34
|
toRewardRows,
|
|
35
35
|
toSftRows
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-EJGRPCO3.js";
|
|
37
37
|
import {
|
|
38
|
-
ROLLOUT_FORMAT,
|
|
39
38
|
ROLLOUT_SCHEMA,
|
|
40
39
|
assertRolloutLine,
|
|
41
40
|
isRolloutLine,
|
|
42
41
|
isTrainableSplit,
|
|
43
42
|
validateRolloutLine
|
|
44
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-UWZZKKU7.js";
|
|
45
44
|
import {
|
|
46
45
|
BENCHMARK_SPLIT_SEED,
|
|
47
46
|
benchmarks_exports,
|
|
48
47
|
deterministicSplit
|
|
49
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-XPRT64IE.js";
|
|
50
49
|
import {
|
|
51
50
|
DEFAULT_RULES,
|
|
52
51
|
classifyFailure,
|
|
@@ -54,7 +53,7 @@ import {
|
|
|
54
53
|
computeToolUseMetrics,
|
|
55
54
|
iqr,
|
|
56
55
|
welchsTTest
|
|
57
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-P5W7RQKK.js";
|
|
58
57
|
import {
|
|
59
58
|
buildTrajectory
|
|
60
59
|
} from "./chunk-RZTMDUO7.js";
|
|
@@ -77,17 +76,15 @@ import {
|
|
|
77
76
|
agentProfileHash,
|
|
78
77
|
agentProfileId,
|
|
79
78
|
agentProfileModelId,
|
|
80
|
-
comparePairedArms,
|
|
81
79
|
completionVerdict,
|
|
82
80
|
createLlmCorrectnessChecker,
|
|
83
81
|
createTokenRecallChecker,
|
|
84
82
|
expandProfileAxes,
|
|
85
83
|
extractProducedState,
|
|
86
84
|
harnessAxisOf,
|
|
87
|
-
pairArms,
|
|
88
85
|
parseCorrectnessResponse,
|
|
89
86
|
verifyCompletion
|
|
90
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-UB2LOJ6Q.js";
|
|
91
88
|
import {
|
|
92
89
|
DEFAULT_MUTATION_PRIMITIVES,
|
|
93
90
|
DEFAULT_RED_TEAM_CORPUS,
|
|
@@ -121,7 +118,7 @@ import {
|
|
|
121
118
|
scoreRedTeamOutput,
|
|
122
119
|
surfaceContentHash,
|
|
123
120
|
toolNamesForRun
|
|
124
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-NKAGIDE2.js";
|
|
125
122
|
import {
|
|
126
123
|
BackendIntegrityError,
|
|
127
124
|
assertRealAgentReceipts,
|
|
@@ -133,7 +130,7 @@ import {
|
|
|
133
130
|
inMemoryVerdictCache,
|
|
134
131
|
summarizeAgentReceiptIntegrity,
|
|
135
132
|
summarizeBackendIntegrity
|
|
136
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-EZJEIH2R.js";
|
|
137
134
|
import {
|
|
138
135
|
DEFAULT_COMPLEXITY_WEIGHTS,
|
|
139
136
|
FindingsStore,
|
|
@@ -146,7 +143,7 @@ import {
|
|
|
146
143
|
defaultIsMaterial,
|
|
147
144
|
diffFindings,
|
|
148
145
|
runSemanticConceptJudge
|
|
149
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-ZUUWPZCV.js";
|
|
150
147
|
import {
|
|
151
148
|
AnalystRegistry,
|
|
152
149
|
DEFAULT_TRACE_ANALYST_KINDS,
|
|
@@ -163,7 +160,7 @@ import {
|
|
|
163
160
|
makeFinding,
|
|
164
161
|
renderPriorFindings,
|
|
165
162
|
renderUpstreamFindings
|
|
166
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-DJKY2TSY.js";
|
|
167
164
|
import "./chunk-HHWE3POT.js";
|
|
168
165
|
import {
|
|
169
166
|
DEFAULT_RUN_SCORE_WEIGHTS,
|
|
@@ -192,18 +189,19 @@ import {
|
|
|
192
189
|
stopOnNoProgress,
|
|
193
190
|
stopOnRepeatedAction,
|
|
194
191
|
subjectiveEval
|
|
195
|
-
} from "./chunk-
|
|
192
|
+
} from "./chunk-BYT7ELPS.js";
|
|
196
193
|
import {
|
|
197
194
|
assertReleaseConfidence,
|
|
198
195
|
bootstrapCi,
|
|
199
196
|
evaluateReleaseConfidence,
|
|
200
197
|
judgeReplayGate,
|
|
201
198
|
renderReleaseReport
|
|
202
|
-
} from "./chunk-
|
|
199
|
+
} from "./chunk-XDWDC2MP.js";
|
|
203
200
|
import {
|
|
204
201
|
runEvalCampaign
|
|
205
|
-
} from "./chunk-
|
|
206
|
-
import "./chunk-
|
|
202
|
+
} from "./chunk-TBL77AUT.js";
|
|
203
|
+
import "./chunk-NYLOYM6N.js";
|
|
204
|
+
import "./chunk-2MKQIFS4.js";
|
|
207
205
|
import {
|
|
208
206
|
LlmCallError,
|
|
209
207
|
LlmClient,
|
|
@@ -219,7 +217,7 @@ import {
|
|
|
219
217
|
maximumChargeForLlmRequest,
|
|
220
218
|
probeLlm,
|
|
221
219
|
stripFencedJson
|
|
222
|
-
} from "./chunk-
|
|
220
|
+
} from "./chunk-PBE2LOSS.js";
|
|
223
221
|
import {
|
|
224
222
|
evaluateInterimReleaseConfidence,
|
|
225
223
|
pairedEvalueSequence
|
|
@@ -230,7 +228,12 @@ import {
|
|
|
230
228
|
paretoChart,
|
|
231
229
|
researchReport,
|
|
232
230
|
summaryTable
|
|
233
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-VLOATJQ2.js";
|
|
232
|
+
import {
|
|
233
|
+
comparePairedArms,
|
|
234
|
+
pairArms,
|
|
235
|
+
pairRunRecords
|
|
236
|
+
} from "./chunk-DPUHNQLN.js";
|
|
234
237
|
import {
|
|
235
238
|
benjaminiHochberg,
|
|
236
239
|
bonferroni,
|
|
@@ -253,6 +256,7 @@ import {
|
|
|
253
256
|
mulberry32,
|
|
254
257
|
normalizeScores,
|
|
255
258
|
pairedBootstrap,
|
|
259
|
+
pairedCohensDz,
|
|
256
260
|
pairedMde,
|
|
257
261
|
pairedRiskDifference,
|
|
258
262
|
pairedSignTest,
|
|
@@ -262,6 +266,7 @@ import {
|
|
|
262
266
|
pearsonR,
|
|
263
267
|
positionalBias,
|
|
264
268
|
ranks,
|
|
269
|
+
requiredPairedSampleSize,
|
|
265
270
|
requiredSampleSize,
|
|
266
271
|
selfPreference,
|
|
267
272
|
spearmanR,
|
|
@@ -270,7 +275,7 @@ import {
|
|
|
270
275
|
weightedMean,
|
|
271
276
|
wilcoxonSignedRank,
|
|
272
277
|
wilson
|
|
273
|
-
} from "./chunk-
|
|
278
|
+
} from "./chunk-MHELPNRP.js";
|
|
274
279
|
import {
|
|
275
280
|
CostAccountingIncompleteError,
|
|
276
281
|
CostCallConflictError,
|
|
@@ -321,8 +326,8 @@ import {
|
|
|
321
326
|
scoreTraceInsightReadiness,
|
|
322
327
|
tokenizeDomainWords,
|
|
323
328
|
traceAnalystOnRunComplete
|
|
324
|
-
} from "./chunk-
|
|
325
|
-
import "./chunk-
|
|
329
|
+
} from "./chunk-EOSZT7PL.js";
|
|
330
|
+
import "./chunk-7ZZMD7UK.js";
|
|
326
331
|
import {
|
|
327
332
|
extractUsage,
|
|
328
333
|
extractUsageFromResponse,
|
|
@@ -343,7 +348,7 @@ import {
|
|
|
343
348
|
TRACE_ANALYST_ACTOR_DESCRIPTION,
|
|
344
349
|
TRACE_ANALYST_ACTOR_DESCRIPTION_VERSION,
|
|
345
350
|
analyzeTraces
|
|
346
|
-
} from "./chunk-
|
|
351
|
+
} from "./chunk-5DTSBUL2.js";
|
|
347
352
|
import {
|
|
348
353
|
DEFAULT_REDACTION_RULES,
|
|
349
354
|
REDACTION_VERSION,
|
|
@@ -360,15 +365,17 @@ import {
|
|
|
360
365
|
applyToolSpanOtlpAttributes,
|
|
361
366
|
asString,
|
|
362
367
|
buildTraceAnalystTools,
|
|
368
|
+
classifyOtlpSpanRole,
|
|
363
369
|
extractOtlpAttributes,
|
|
364
370
|
firstStringAttr,
|
|
365
371
|
inferOtlpKind,
|
|
372
|
+
isOtlpModelCall,
|
|
366
373
|
projectOtlpFlatLine,
|
|
367
374
|
readOtlpStatus,
|
|
368
375
|
stringField,
|
|
369
376
|
traceAnalystFunctionGroup,
|
|
370
377
|
traceSpanKindToOpenInferenceKind
|
|
371
|
-
} from "./chunk-
|
|
378
|
+
} from "./chunk-P6FYH6K4.js";
|
|
372
379
|
import {
|
|
373
380
|
RunIntegrityError,
|
|
374
381
|
assertRunCaptured,
|
|
@@ -394,18 +401,23 @@ import {
|
|
|
394
401
|
assertRunAgentProfileCell,
|
|
395
402
|
buildAgentInterfaceProfileCell,
|
|
396
403
|
buildAgentProfileCell,
|
|
404
|
+
canonicalize,
|
|
405
|
+
evaluateHypothesis,
|
|
397
406
|
groupRunsByAgentProfileCell,
|
|
407
|
+
hashJson,
|
|
398
408
|
isRunRecord,
|
|
399
409
|
modelHasSnapshot,
|
|
400
410
|
parseRunRecordSafe,
|
|
401
411
|
requireAgentProfileCell,
|
|
402
|
-
resolveRunCostProvenance,
|
|
403
412
|
roundTripRunRecord,
|
|
413
|
+
runTaskScore,
|
|
414
|
+
signManifest,
|
|
404
415
|
toAgentProfileJson,
|
|
405
416
|
validateAgentProfileCell,
|
|
406
417
|
validateRunRecord,
|
|
407
|
-
verifyAgentProfileCell
|
|
408
|
-
|
|
418
|
+
verifyAgentProfileCell,
|
|
419
|
+
verifyManifest
|
|
420
|
+
} from "./chunk-2JX3CFMB.js";
|
|
409
421
|
import {
|
|
410
422
|
FAILURE_CLASSES,
|
|
411
423
|
TRACE_SCHEMA_VERSION,
|
|
@@ -415,13 +427,6 @@ import {
|
|
|
415
427
|
isSandboxSpan,
|
|
416
428
|
isToolSpan
|
|
417
429
|
} from "./chunk-MA6HLL3S.js";
|
|
418
|
-
import {
|
|
419
|
-
canonicalize,
|
|
420
|
-
evaluateHypothesis,
|
|
421
|
-
hashJson,
|
|
422
|
-
signManifest,
|
|
423
|
-
verifyManifest
|
|
424
|
-
} from "./chunk-VSMTAMNK.js";
|
|
425
430
|
import {
|
|
426
431
|
AgentEvalError,
|
|
427
432
|
CaptureIntegrityError,
|
|
@@ -918,8 +923,8 @@ async function executeScenario(tc, scenario, config) {
|
|
|
918
923
|
console.log(` ${judgeName} retry ${attempt}/2 (waiting ${wait / 1e3}s)`);
|
|
919
924
|
await sleep2(wait);
|
|
920
925
|
}
|
|
921
|
-
const
|
|
922
|
-
judgeResults.push(
|
|
926
|
+
const scores = await judge(tc, judgeInput);
|
|
927
|
+
judgeResults.push(scores);
|
|
923
928
|
await sleep2(3e3);
|
|
924
929
|
lastError = void 0;
|
|
925
930
|
break;
|
|
@@ -1536,19 +1541,19 @@ function projectSelectedRows(rows, options) {
|
|
|
1536
1541
|
const arm = options.arm(original);
|
|
1537
1542
|
assertNonEmptyString("arm", arm);
|
|
1538
1543
|
if (arm !== options.baselineArm && arm !== options.treatmentArm) continue;
|
|
1539
|
-
const
|
|
1544
|
+
const pairKey = options.pairKey(original);
|
|
1540
1545
|
const clusterKey = options.clusterKey(original);
|
|
1541
1546
|
const pass = options.pass(original);
|
|
1542
1547
|
const repKey = options.repKey?.(original);
|
|
1543
|
-
assertNonEmptyString("pairKey",
|
|
1548
|
+
assertNonEmptyString("pairKey", pairKey);
|
|
1544
1549
|
assertNonEmptyString("clusterKey", clusterKey);
|
|
1545
1550
|
if (typeof pass !== "boolean") {
|
|
1546
1551
|
throw new ValidationError(
|
|
1547
|
-
`clusteredPairedBinary: pass accessor must return boolean for pairKey '${
|
|
1552
|
+
`clusteredPairedBinary: pass accessor must return boolean for pairKey '${pairKey}'`
|
|
1548
1553
|
);
|
|
1549
1554
|
}
|
|
1550
1555
|
if (repKey !== void 0) assertNonEmptyString("repKey", repKey);
|
|
1551
|
-
projected.push({ pairKey
|
|
1556
|
+
projected.push({ pairKey, clusterKey, arm, pass, repKey, original });
|
|
1552
1557
|
}
|
|
1553
1558
|
return projected;
|
|
1554
1559
|
}
|
|
@@ -2941,9 +2946,9 @@ function scorePrReviewComments(auditCase, comments, source, weights = {}) {
|
|
|
2941
2946
|
})
|
|
2942
2947
|
};
|
|
2943
2948
|
}
|
|
2944
|
-
function summarizePrReviewBenchmark(
|
|
2949
|
+
function summarizePrReviewBenchmark(scores) {
|
|
2945
2950
|
const bySource = /* @__PURE__ */ new Map();
|
|
2946
|
-
for (const score of
|
|
2951
|
+
for (const score of scores) {
|
|
2947
2952
|
bySource.set(score.source, [...bySource.get(score.source) ?? [], score]);
|
|
2948
2953
|
}
|
|
2949
2954
|
return [...bySource.entries()].map(([source, sourceScores]) => ({
|
|
@@ -3688,12 +3693,12 @@ function runJudgesTool(judges) {
|
|
|
3688
3693
|
}
|
|
3689
3694
|
const signal = ctx?.signal ?? new AbortController().signal;
|
|
3690
3695
|
const scenario = a.scenario;
|
|
3691
|
-
const
|
|
3696
|
+
const scores = {};
|
|
3692
3697
|
for (const judge of selected) {
|
|
3693
3698
|
if (scenario !== void 0 && judge.appliesTo && !judge.appliesTo(scenario)) continue;
|
|
3694
|
-
|
|
3699
|
+
scores[judge.name] = await judge.score({ artifact: a.artifact, scenario, signal });
|
|
3695
3700
|
}
|
|
3696
|
-
return { scores
|
|
3701
|
+
return { scores };
|
|
3697
3702
|
}
|
|
3698
3703
|
};
|
|
3699
3704
|
}
|
|
@@ -3807,14 +3812,14 @@ async function runHarnessExperiment(config) {
|
|
|
3807
3812
|
const score = config.score ?? ((trace) => critic.scoreTrace(trace));
|
|
3808
3813
|
const results = await mapLimit(jobs, config.parallelism ?? 1, async (request) => {
|
|
3809
3814
|
const trace = await config.adapter.run(request);
|
|
3810
|
-
const
|
|
3815
|
+
const runScore3 = await score(trace, request);
|
|
3811
3816
|
const result = {
|
|
3812
3817
|
variant: request.variant,
|
|
3813
3818
|
scenario: request.scenario,
|
|
3814
3819
|
trialIndex: request.trialIndex,
|
|
3815
3820
|
trace,
|
|
3816
|
-
score:
|
|
3817
|
-
aggregate: aggregateRunScore(
|
|
3821
|
+
score: runScore3,
|
|
3822
|
+
aggregate: aggregateRunScore(runScore3, config.weights)
|
|
3818
3823
|
};
|
|
3819
3824
|
await config.onResult?.(result);
|
|
3820
3825
|
return result;
|
|
@@ -3884,20 +3889,20 @@ async function mapLimit(items, limit, fn) {
|
|
|
3884
3889
|
function mean3(values) {
|
|
3885
3890
|
return values.length ? values.reduce((sum4, value) => sum4 + value, 0) / values.length : 0;
|
|
3886
3891
|
}
|
|
3887
|
-
function meanRunScore(
|
|
3892
|
+
function meanRunScore(scores) {
|
|
3888
3893
|
return {
|
|
3889
|
-
success: mean3(
|
|
3890
|
-
goalProgress: mean3(
|
|
3891
|
-
repoGroundedness: mean3(
|
|
3892
|
-
driftPenalty: mean3(
|
|
3893
|
-
toolUseQuality: mean3(
|
|
3894
|
-
patchQuality: mean3(
|
|
3895
|
-
testReality: mean3(
|
|
3896
|
-
finalGate: mean3(
|
|
3897
|
-
reviewerBlockers: mean3(
|
|
3898
|
-
costUsd: mean3(
|
|
3899
|
-
wallSeconds: mean3(
|
|
3900
|
-
notes:
|
|
3894
|
+
success: mean3(scores.map((s) => s.success)),
|
|
3895
|
+
goalProgress: mean3(scores.map((s) => s.goalProgress)),
|
|
3896
|
+
repoGroundedness: mean3(scores.map((s) => s.repoGroundedness)),
|
|
3897
|
+
driftPenalty: mean3(scores.map((s) => s.driftPenalty)),
|
|
3898
|
+
toolUseQuality: mean3(scores.map((s) => s.toolUseQuality)),
|
|
3899
|
+
patchQuality: mean3(scores.map((s) => s.patchQuality)),
|
|
3900
|
+
testReality: mean3(scores.map((s) => s.testReality)),
|
|
3901
|
+
finalGate: mean3(scores.map((s) => s.finalGate)),
|
|
3902
|
+
reviewerBlockers: mean3(scores.map((s) => s.reviewerBlockers)),
|
|
3903
|
+
costUsd: mean3(scores.map((s) => s.costUsd)),
|
|
3904
|
+
wallSeconds: mean3(scores.map((s) => s.wallSeconds)),
|
|
3905
|
+
notes: scores.flatMap((s) => s.notes ?? [])
|
|
3901
3906
|
};
|
|
3902
3907
|
}
|
|
3903
3908
|
|
|
@@ -4837,12 +4842,7 @@ function assertNonNegative(n, name) {
|
|
|
4837
4842
|
|
|
4838
4843
|
// src/eval-trace-store.ts
|
|
4839
4844
|
function runScore(record) {
|
|
4840
|
-
|
|
4841
|
-
if (typeof holdoutScore === "number") return holdoutScore;
|
|
4842
|
-
if (typeof searchScore === "number") return searchScore;
|
|
4843
|
-
throw new ValidationError(
|
|
4844
|
-
`EvalTraceStore: run ${record.runId} has neither holdoutScore nor searchScore`
|
|
4845
|
-
);
|
|
4845
|
+
return runTaskScore(record);
|
|
4846
4846
|
}
|
|
4847
4847
|
function matches(record, f) {
|
|
4848
4848
|
if (f.experimentId && record.experimentId !== f.experimentId) return false;
|
|
@@ -4850,8 +4850,12 @@ function matches(record, f) {
|
|
|
4850
4850
|
if (f.scenarioId && record.scenarioId !== f.scenarioId) return false;
|
|
4851
4851
|
if (f.model && record.model !== f.model) return false;
|
|
4852
4852
|
if (f.splitTag && record.splitTag !== f.splitTag) return false;
|
|
4853
|
-
if (f.minScore !== void 0
|
|
4854
|
-
|
|
4853
|
+
if (f.minScore !== void 0 || f.maxScore !== void 0) {
|
|
4854
|
+
const score = runScore(record);
|
|
4855
|
+
if (score === void 0) return false;
|
|
4856
|
+
if (f.minScore !== void 0 && score < f.minScore) return false;
|
|
4857
|
+
if (f.maxScore !== void 0 && score > f.maxScore) return false;
|
|
4858
|
+
}
|
|
4855
4859
|
if (f.rawEquals && record.outcome.raw[f.rawEquals.key] !== f.rawEquals.value) return false;
|
|
4856
4860
|
if (f.where && !f.where(record)) return false;
|
|
4857
4861
|
return true;
|
|
@@ -4941,13 +4945,17 @@ var EvalTraceStore = class {
|
|
|
4941
4945
|
candidateId: opts.candidateId,
|
|
4942
4946
|
splitTag: opts.splitTag
|
|
4943
4947
|
});
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4948
|
+
const scored = rows.flatMap((record) => {
|
|
4949
|
+
const score = runScore(record);
|
|
4950
|
+
return score === void 0 ? [] : [{ record, score }];
|
|
4951
|
+
});
|
|
4952
|
+
if (scored.length === 0) return null;
|
|
4953
|
+
let best = scored[0].record;
|
|
4954
|
+
let bestScore = scored[0].score;
|
|
4955
|
+
for (let i = 1; i < scored.length; i++) {
|
|
4956
|
+
const s = scored[i].score;
|
|
4949
4957
|
if (s > bestScore) {
|
|
4950
|
-
best =
|
|
4958
|
+
best = scored[i].record;
|
|
4951
4959
|
bestScore = s;
|
|
4952
4960
|
}
|
|
4953
4961
|
}
|
|
@@ -4973,6 +4981,7 @@ var EvalTraceStore = class {
|
|
|
4973
4981
|
const sid = r.scenarioId;
|
|
4974
4982
|
if (!sid) continue;
|
|
4975
4983
|
const s = runScore(r);
|
|
4984
|
+
if (s === void 0) continue;
|
|
4976
4985
|
const prev = m.get(sid);
|
|
4977
4986
|
if (prev === void 0 || s > prev) m.set(sid, s);
|
|
4978
4987
|
}
|
|
@@ -5050,9 +5059,9 @@ function median(sorted) {
|
|
|
5050
5059
|
const mid = Math.floor(n / 2);
|
|
5051
5060
|
return n % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
5052
5061
|
}
|
|
5053
|
-
function stddev(values,
|
|
5062
|
+
function stddev(values, mean6) {
|
|
5054
5063
|
if (values.length < 2) return 0;
|
|
5055
|
-
const variance = values.reduce((acc, v) => acc + (v -
|
|
5064
|
+
const variance = values.reduce((acc, v) => acc + (v - mean6) ** 2, 0) / values.length;
|
|
5056
5065
|
return Math.sqrt(variance);
|
|
5057
5066
|
}
|
|
5058
5067
|
function computeExperimentStats(reps, thresholds) {
|
|
@@ -5071,22 +5080,22 @@ function computeExperimentStats(reps, thresholds) {
|
|
|
5071
5080
|
stable: false
|
|
5072
5081
|
};
|
|
5073
5082
|
}
|
|
5074
|
-
const
|
|
5083
|
+
const scores = reps.map((r) => {
|
|
5075
5084
|
if (!Number.isFinite(r.score)) {
|
|
5076
5085
|
throw new ValidationError(`experiment-tracker: rep ${r.rep} has non-finite score ${r.score}`);
|
|
5077
5086
|
}
|
|
5078
5087
|
return r.score;
|
|
5079
5088
|
});
|
|
5080
|
-
const sorted = [...
|
|
5081
|
-
const
|
|
5082
|
-
const sd = stddev(
|
|
5083
|
-
const spread = iqr(
|
|
5089
|
+
const sorted = [...scores].sort((a, b) => a - b);
|
|
5090
|
+
const mean6 = scores.reduce((s, v) => s + v, 0) / n;
|
|
5091
|
+
const sd = stddev(scores, mean6);
|
|
5092
|
+
const spread = iqr(scores);
|
|
5084
5093
|
const rated = reps.filter((r) => typeof r.passed === "boolean");
|
|
5085
5094
|
const passRate = rated.length === 0 ? null : rated.filter((r) => r.passed).length / rated.length;
|
|
5086
5095
|
const stable = spread < t.iqrUnstableAbove && sd < t.stddevUnstableAbove;
|
|
5087
5096
|
return {
|
|
5088
5097
|
median: median(sorted),
|
|
5089
|
-
mean:
|
|
5098
|
+
mean: mean6,
|
|
5090
5099
|
min: sorted[0],
|
|
5091
5100
|
max: sorted[n - 1],
|
|
5092
5101
|
iqr: spread,
|
|
@@ -5275,6 +5284,7 @@ function leaderboard(records, opts) {
|
|
|
5275
5284
|
const profile = rs[0].agentProfile;
|
|
5276
5285
|
const harness = profile?.harness?.id;
|
|
5277
5286
|
const model = profile?.model;
|
|
5287
|
+
const knownCosts = rs.map((r) => r.costUsd).filter(isFiniteNumber);
|
|
5278
5288
|
return {
|
|
5279
5289
|
key,
|
|
5280
5290
|
label: harness && model ? `${harness} \xB7 ${model}` : key,
|
|
@@ -5284,7 +5294,7 @@ function leaderboard(records, opts) {
|
|
|
5284
5294
|
n: rs.length,
|
|
5285
5295
|
passRate: ci.estimate,
|
|
5286
5296
|
passRateCi95: [ci.lower, ci.upper],
|
|
5287
|
-
meanCostUsd:
|
|
5297
|
+
meanCostUsd: knownCosts.length === rs.length ? mean4(knownCosts) : null,
|
|
5288
5298
|
meanTokensIn: mean4(rs.map((r) => r.tokenUsage.input)),
|
|
5289
5299
|
meanTokensOut: mean4(rs.map((r) => r.tokenUsage.output)),
|
|
5290
5300
|
meanWallMs: mean4(rs.map((r) => r.wallMs))
|
|
@@ -5298,6 +5308,9 @@ function leaderboard(records, opts) {
|
|
|
5298
5308
|
});
|
|
5299
5309
|
return rows;
|
|
5300
5310
|
}
|
|
5311
|
+
function isFiniteNumber(value) {
|
|
5312
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
5313
|
+
}
|
|
5301
5314
|
|
|
5302
5315
|
// src/muffled-gate-scanner.ts
|
|
5303
5316
|
import { existsSync, readdirSync, readFileSync, statSync } from "fs";
|
|
@@ -5687,9 +5700,6 @@ function median2(xs) {
|
|
|
5687
5700
|
const mid = Math.floor(sorted.length / 2);
|
|
5688
5701
|
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
5689
5702
|
}
|
|
5690
|
-
function runScore2(run) {
|
|
5691
|
-
return run.outcome.holdoutScore ?? run.outcome.searchScore;
|
|
5692
|
-
}
|
|
5693
5703
|
function aggregatePerDimension(runs) {
|
|
5694
5704
|
const sums = /* @__PURE__ */ new Map();
|
|
5695
5705
|
for (const run of runs) {
|
|
@@ -5722,14 +5732,14 @@ function recordRuns(runs, opts) {
|
|
|
5722
5732
|
}
|
|
5723
5733
|
const lines = [];
|
|
5724
5734
|
for (const [scenarioId, scenarioRuns] of byScenario) {
|
|
5725
|
-
const scored = scenarioRuns.map((run) => ({ run, score:
|
|
5735
|
+
const scored = scenarioRuns.map((run) => ({ run, score: runTaskScore(run) })).filter((s) => s.score !== void 0);
|
|
5726
5736
|
if (scored.length === 0) continue;
|
|
5727
|
-
const
|
|
5737
|
+
const scores = scored.map((s) => s.score);
|
|
5728
5738
|
const entry = {
|
|
5729
5739
|
commitSha: opts.commitSha,
|
|
5730
5740
|
timestamp,
|
|
5731
|
-
scores
|
|
5732
|
-
composite: median2(
|
|
5741
|
+
scores,
|
|
5742
|
+
composite: median2(scores),
|
|
5733
5743
|
runIds: scored.map((s) => s.run.runId)
|
|
5734
5744
|
};
|
|
5735
5745
|
const perDimension = aggregatePerDimension(scenarioRuns);
|
|
@@ -6317,20 +6327,20 @@ function checkRule(rule, ordered) {
|
|
|
6317
6327
|
function evaluateTraceContract(contract, spans) {
|
|
6318
6328
|
assertContract(contract);
|
|
6319
6329
|
const ordered = orderSpans(spans);
|
|
6320
|
-
const
|
|
6330
|
+
const scores = {};
|
|
6321
6331
|
const violations = [];
|
|
6322
6332
|
for (const rule of contract.rules) {
|
|
6323
6333
|
const ruleViolations = checkRule(rule, ordered);
|
|
6324
|
-
|
|
6334
|
+
scores[rule.label] = ruleViolations.length === 0 ? 1 : 0;
|
|
6325
6335
|
violations.push(...ruleViolations);
|
|
6326
6336
|
}
|
|
6327
6337
|
const ruleCount = contract.rules.length;
|
|
6328
|
-
const passCount = Object.values(
|
|
6338
|
+
const passCount = Object.values(scores).filter((s) => s === 1).length;
|
|
6329
6339
|
return {
|
|
6330
6340
|
contract: contract.name,
|
|
6331
6341
|
valid: passCount === ruleCount,
|
|
6332
6342
|
score: passCount / ruleCount,
|
|
6333
|
-
scores
|
|
6343
|
+
scores,
|
|
6334
6344
|
violations,
|
|
6335
6345
|
notes: `${passCount}/${ruleCount} rules passed`
|
|
6336
6346
|
};
|
|
@@ -6658,12 +6668,12 @@ function renderMarkdownReport(reports) {
|
|
|
6658
6668
|
async function aggregateRunMetrics(runs, store) {
|
|
6659
6669
|
if (runs.length === 0) return {};
|
|
6660
6670
|
const durations = [];
|
|
6661
|
-
const
|
|
6671
|
+
const scores = [];
|
|
6662
6672
|
const passes = [];
|
|
6663
6673
|
const costs = [];
|
|
6664
6674
|
for (const r of runs) {
|
|
6665
6675
|
if (r.endedAt) durations.push(r.endedAt - r.startedAt);
|
|
6666
|
-
if (r.outcome?.score !== void 0)
|
|
6676
|
+
if (r.outcome?.score !== void 0) scores.push(r.outcome.score);
|
|
6667
6677
|
passes.push(r.outcome?.pass === true ? 1 : 0);
|
|
6668
6678
|
const llm = await llmSpans(store, r.runId);
|
|
6669
6679
|
costs.push(aggregateLlm(llm).costUsd);
|
|
@@ -6672,7 +6682,7 @@ async function aggregateRunMetrics(runs, store) {
|
|
|
6672
6682
|
provisionMs: average(durations),
|
|
6673
6683
|
firstTokenMs: average(durations),
|
|
6674
6684
|
wallMs: average(durations),
|
|
6675
|
-
overallScore: average(
|
|
6685
|
+
overallScore: average(scores),
|
|
6676
6686
|
passRate: average(passes),
|
|
6677
6687
|
costUsd: average(costs)
|
|
6678
6688
|
};
|
|
@@ -6735,7 +6745,7 @@ async function toLangfuseEnvelope(store, runId) {
|
|
|
6735
6745
|
},
|
|
6736
6746
|
metadata: { finishReason: s.finishReason, cachedTokens: s.cachedTokens }
|
|
6737
6747
|
}));
|
|
6738
|
-
const
|
|
6748
|
+
const scores = judges.map((j) => ({
|
|
6739
6749
|
id: j.spanId,
|
|
6740
6750
|
traceId: run.runId,
|
|
6741
6751
|
observationId: j.targetSpanId,
|
|
@@ -6743,7 +6753,7 @@ async function toLangfuseEnvelope(store, runId) {
|
|
|
6743
6753
|
value: j.score,
|
|
6744
6754
|
comment: j.rationale
|
|
6745
6755
|
}));
|
|
6746
|
-
return { traceId: run.runId, generations, scores
|
|
6756
|
+
return { traceId: run.runId, generations, scores };
|
|
6747
6757
|
}
|
|
6748
6758
|
async function toPrometheusText(store) {
|
|
6749
6759
|
const runs = await store.listRuns();
|
|
@@ -6844,12 +6854,12 @@ async function paraphraseRobustness(prompt, mutators, scoreFn, options = {}) {
|
|
|
6844
6854
|
variantScores.push({ mutator: id, score, mutated });
|
|
6845
6855
|
all.push(score);
|
|
6846
6856
|
}
|
|
6847
|
-
const
|
|
6848
|
-
const variance = all.reduce((a, v) => a + (v -
|
|
6857
|
+
const mean6 = all.reduce((a, b) => a + b, 0) / all.length;
|
|
6858
|
+
const variance = all.reduce((a, v) => a + (v - mean6) ** 2, 0) / all.length;
|
|
6849
6859
|
const stdDev = Math.sqrt(variance);
|
|
6850
|
-
const ref = Math.abs(
|
|
6860
|
+
const ref = Math.abs(mean6) > 1e-9 ? Math.abs(mean6) : 1;
|
|
6851
6861
|
const robustness = Math.max(0, 1 - stdDev / ref);
|
|
6852
|
-
return { originalScore, variantScores, meanScore:
|
|
6862
|
+
return { originalScore, variantScores, meanScore: mean6, stdDev, robustness };
|
|
6853
6863
|
}
|
|
6854
6864
|
var lowercaseMutator = (p) => p.toLowerCase();
|
|
6855
6865
|
var sentenceReorderMutator = (p, seed) => {
|
|
@@ -6906,18 +6916,18 @@ async function paraphraseRobustnessScenarios(args) {
|
|
|
6906
6916
|
const deltas = {};
|
|
6907
6917
|
const paraphrasedAll = [];
|
|
6908
6918
|
for (const m of args.mutators) {
|
|
6909
|
-
const
|
|
6919
|
+
const scores = [];
|
|
6910
6920
|
for (let r = 0; r < reps; r++) {
|
|
6911
6921
|
const mutatedTurns = scenario.userTurns.map((t) => m.mutator(t));
|
|
6912
6922
|
const out = await args.runScenario({
|
|
6913
6923
|
id: scenario.id,
|
|
6914
6924
|
userTurns: mutatedTurns
|
|
6915
6925
|
});
|
|
6916
|
-
|
|
6926
|
+
scores.push(out.score);
|
|
6917
6927
|
}
|
|
6918
|
-
const
|
|
6919
|
-
deltas[m.name] =
|
|
6920
|
-
paraphrasedAll.push(...
|
|
6928
|
+
const mean6 = scores.reduce((a, b) => a + b, 0) / scores.length;
|
|
6929
|
+
deltas[m.name] = mean6 - originalScore;
|
|
6930
|
+
paraphrasedAll.push(...scores);
|
|
6921
6931
|
}
|
|
6922
6932
|
const paraphrasedMean = paraphrasedAll.length === 0 ? originalScore : paraphrasedAll.reduce((a, b) => a + b, 0) / paraphrasedAll.length;
|
|
6923
6933
|
perScenario.push({ id: scenario.id, originalScore, paraphrasedMean, deltas });
|
|
@@ -7332,10 +7342,10 @@ async function proposeSynthesisTargets(dataset, traceStore, options = {}) {
|
|
|
7332
7342
|
}
|
|
7333
7343
|
for (const s of scenarios) {
|
|
7334
7344
|
const sRuns = runs.filter((r) => r.scenarioId === s.id);
|
|
7335
|
-
const
|
|
7336
|
-
if (
|
|
7337
|
-
const
|
|
7338
|
-
const variance =
|
|
7345
|
+
const scores = sRuns.map((r) => r.outcome?.score).filter((x) => typeof x === "number");
|
|
7346
|
+
if (scores.length < 3) continue;
|
|
7347
|
+
const mean6 = scores.reduce((a, b) => a + b, 0) / scores.length;
|
|
7348
|
+
const variance = scores.reduce((a, b) => a + (b - mean6) ** 2, 0) / scores.length;
|
|
7339
7349
|
if (variance > varianceThreshold) {
|
|
7340
7350
|
targets.push({
|
|
7341
7351
|
reason: "high-variance",
|
|
@@ -7570,15 +7580,15 @@ async function runSelfPlay(proposer, scorer, targets, options = {}) {
|
|
|
7570
7580
|
const rejected = [];
|
|
7571
7581
|
const surviving = [];
|
|
7572
7582
|
for (const candidate of proposed) {
|
|
7573
|
-
const
|
|
7574
|
-
if (
|
|
7583
|
+
const scores = await scorer.scoreCandidate(candidate, targets);
|
|
7584
|
+
if (scores.length < 2) {
|
|
7575
7585
|
rejected.push({ candidate, reason: "scorer returned <2 results" });
|
|
7576
7586
|
continue;
|
|
7577
7587
|
}
|
|
7578
|
-
const values =
|
|
7588
|
+
const values = scores.map((s) => s.score);
|
|
7579
7589
|
const spread = Math.max(...values) - Math.min(...values);
|
|
7580
7590
|
const maxScore = Math.max(...values);
|
|
7581
|
-
scored.push({ candidate, scores
|
|
7591
|
+
scored.push({ candidate, scores, spread });
|
|
7582
7592
|
if (maxScore < floor) {
|
|
7583
7593
|
rejected.push({
|
|
7584
7594
|
candidate,
|
|
@@ -8406,13 +8416,32 @@ var MultiLayerVerifier = class {
|
|
|
8406
8416
|
) : null;
|
|
8407
8417
|
const layerStart = Date.now();
|
|
8408
8418
|
let result;
|
|
8419
|
+
let rejectOnAbort;
|
|
8420
|
+
const abortPromise = new Promise((_resolve, reject) => {
|
|
8421
|
+
const rejectWithReason = () => {
|
|
8422
|
+
const reason = mergedSignal.reason;
|
|
8423
|
+
reject(reason instanceof Error ? reason : new Error(String(reason ?? "aborted")));
|
|
8424
|
+
};
|
|
8425
|
+
if (mergedSignal.aborted) {
|
|
8426
|
+
rejectWithReason();
|
|
8427
|
+
return;
|
|
8428
|
+
}
|
|
8429
|
+
mergedSignal.addEventListener("abort", rejectWithReason, { once: true });
|
|
8430
|
+
rejectOnAbort = () => mergedSignal.removeEventListener("abort", rejectWithReason);
|
|
8431
|
+
});
|
|
8409
8432
|
try {
|
|
8410
|
-
result = await
|
|
8433
|
+
result = await Promise.race([
|
|
8434
|
+
Promise.resolve(
|
|
8435
|
+
layer.run({ env: opts.env, prior: { ...byName }, signal: mergedSignal })
|
|
8436
|
+
),
|
|
8437
|
+
abortPromise
|
|
8438
|
+
]);
|
|
8411
8439
|
} catch (err) {
|
|
8412
8440
|
const aborted = mergedSignal.aborted;
|
|
8413
8441
|
result = {
|
|
8414
8442
|
layer: layer.name,
|
|
8415
8443
|
status: aborted ? "timeout" : "error",
|
|
8444
|
+
errorSource: layer.errorSource ?? "execution",
|
|
8416
8445
|
durationMs: Date.now() - layerStart,
|
|
8417
8446
|
findings: [
|
|
8418
8447
|
{
|
|
@@ -8424,8 +8453,12 @@ var MultiLayerVerifier = class {
|
|
|
8424
8453
|
reason: err instanceof Error ? err.message : String(err)
|
|
8425
8454
|
};
|
|
8426
8455
|
} finally {
|
|
8456
|
+
rejectOnAbort?.();
|
|
8427
8457
|
if (layerTimer) clearTimeout(layerTimer);
|
|
8428
8458
|
}
|
|
8459
|
+
if (result.status === "error" || result.status === "timeout") {
|
|
8460
|
+
result.errorSource ??= layer.errorSource ?? "execution";
|
|
8461
|
+
}
|
|
8429
8462
|
result.findings = result.findings.map((f) => ({ ...f, layer: f.layer ?? layer.name }));
|
|
8430
8463
|
results.push(result);
|
|
8431
8464
|
byName[layer.name] = result;
|
|
@@ -8452,8 +8485,6 @@ function aggregate(layers, results, startedAt, startedAtMs) {
|
|
|
8452
8485
|
let errorCount = 0;
|
|
8453
8486
|
let scoredWeightSum = 0;
|
|
8454
8487
|
let scoredWeightedTotal = 0;
|
|
8455
|
-
let ranAnyScoredLayer = false;
|
|
8456
|
-
let anyScoredLayerFailed = false;
|
|
8457
8488
|
for (const r of results) {
|
|
8458
8489
|
const weight = weightByName.get(r.layer) ?? 1;
|
|
8459
8490
|
const failContrib = failContribByName.get(r.layer) ?? false;
|
|
@@ -8461,26 +8492,32 @@ function aggregate(layers, results, startedAt, startedAtMs) {
|
|
|
8461
8492
|
else if (r.status === "fail") failCount++;
|
|
8462
8493
|
else if (r.status === "skipped") skippedCount++;
|
|
8463
8494
|
else errorCount++;
|
|
8464
|
-
if (r
|
|
8495
|
+
if (isValidTaskMeasurement(r) && weight > 0) {
|
|
8465
8496
|
if (r.status === "pass") {
|
|
8466
|
-
ranAnyScoredLayer = true;
|
|
8467
8497
|
scoredWeightSum += weight;
|
|
8468
8498
|
scoredWeightedTotal += weight * r.score;
|
|
8469
8499
|
} else if (r.status === "fail") {
|
|
8470
8500
|
if (failContrib) {
|
|
8471
|
-
ranAnyScoredLayer = true;
|
|
8472
8501
|
scoredWeightSum += weight;
|
|
8473
8502
|
scoredWeightedTotal += weight * r.score;
|
|
8474
8503
|
}
|
|
8475
|
-
anyScoredLayerFailed = true;
|
|
8476
8504
|
}
|
|
8477
|
-
} else if (r.status === "fail") {
|
|
8478
|
-
anyScoredLayerFailed = true;
|
|
8479
8505
|
}
|
|
8480
8506
|
}
|
|
8481
8507
|
const finishedAtMs = Date.now();
|
|
8482
|
-
const allPass = ranAnyScoredLayer && !anyScoredLayerFailed && failCount === 0 && errorCount === 0;
|
|
8483
8508
|
const blendedScore = scoredWeightSum > 0 ? scoredWeightedTotal / scoredWeightSum : 0;
|
|
8509
|
+
const resultByName = new Map(results.map((result) => [result.layer, result]));
|
|
8510
|
+
const completeTaskMeasurement = scoredWeightSum > 0 && results.length === layers.length && layers.every((layer) => {
|
|
8511
|
+
const result = resultByName.get(layer.name);
|
|
8512
|
+
if (!result) return false;
|
|
8513
|
+
if ((layer.weight ?? 1) <= 0) return true;
|
|
8514
|
+
if (result.status === "pass") {
|
|
8515
|
+
return result.score === void 0 || isValidTaskMeasurement(result);
|
|
8516
|
+
}
|
|
8517
|
+
return result.status === "fail" && layer.failContributesToScore === true && isValidTaskMeasurement(result);
|
|
8518
|
+
});
|
|
8519
|
+
const taskScore = completeTaskMeasurement && scoredWeightSum > 0 && Number.isFinite(blendedScore) ? blendedScore : void 0;
|
|
8520
|
+
const allPass = taskScore !== void 0 && results.length === layers.length && failCount === 0 && skippedCount === 0 && errorCount === 0;
|
|
8484
8521
|
return {
|
|
8485
8522
|
layers: results,
|
|
8486
8523
|
passCount,
|
|
@@ -8489,13 +8526,17 @@ function aggregate(layers, results, startedAt, startedAtMs) {
|
|
|
8489
8526
|
errorCount,
|
|
8490
8527
|
allPass,
|
|
8491
8528
|
blendedScore,
|
|
8529
|
+
...taskScore === void 0 ? {} : { taskScore },
|
|
8492
8530
|
valid: allPass,
|
|
8493
|
-
score:
|
|
8531
|
+
score: taskScore ?? 0,
|
|
8494
8532
|
durationMs: finishedAtMs - startedAtMs,
|
|
8495
8533
|
startedAt,
|
|
8496
8534
|
finishedAt: new Date(finishedAtMs).toISOString()
|
|
8497
8535
|
};
|
|
8498
8536
|
}
|
|
8537
|
+
function isValidTaskMeasurement(result) {
|
|
8538
|
+
return (result.status === "pass" || result.status === "fail") && typeof result.score === "number" && Number.isFinite(result.score) && result.score >= 0 && result.score <= 1;
|
|
8539
|
+
}
|
|
8499
8540
|
function mergeSignals(a, b) {
|
|
8500
8541
|
if (a.aborted) return a;
|
|
8501
8542
|
if (b.aborted) return b;
|
|
@@ -8797,15 +8838,15 @@ function scoreReferenceReplay(scenarios, options = {}) {
|
|
|
8797
8838
|
const threshold = options.matchThreshold ?? DEFAULT_MATCH_THRESHOLD;
|
|
8798
8839
|
const matchStrategy = options.matchStrategy ?? "reference-order";
|
|
8799
8840
|
const allowedSplits = new Set(options.splits ?? ALL_SPLITS);
|
|
8800
|
-
const
|
|
8841
|
+
const scores = scenarios.filter((scenario) => {
|
|
8801
8842
|
const split = scenario.split ?? "train";
|
|
8802
8843
|
if (split === "holdout" && !options.includeHoldout) return false;
|
|
8803
8844
|
return allowedSplits.has(split);
|
|
8804
8845
|
}).map((scenario) => scoreScenario(scenario, matcher, threshold, matchStrategy));
|
|
8805
8846
|
return {
|
|
8806
|
-
scenarios:
|
|
8807
|
-
aggregate: aggregateScenarioScores(
|
|
8808
|
-
bySplit: aggregateBySplit(
|
|
8847
|
+
scenarios: scores,
|
|
8848
|
+
aggregate: aggregateScenarioScores(scores),
|
|
8849
|
+
bySplit: aggregateBySplit(scores)
|
|
8809
8850
|
};
|
|
8810
8851
|
}
|
|
8811
8852
|
function compareReferenceReplay(baseline, candidate) {
|
|
@@ -9028,20 +9069,20 @@ function buildScenarioScore(scenario, matches2, falsePositives) {
|
|
|
9028
9069
|
matches: matches2
|
|
9029
9070
|
};
|
|
9030
9071
|
}
|
|
9031
|
-
function aggregateBySplit(
|
|
9072
|
+
function aggregateBySplit(scores) {
|
|
9032
9073
|
const out = {};
|
|
9033
9074
|
for (const split of ALL_SPLITS) {
|
|
9034
|
-
const scoped =
|
|
9075
|
+
const scoped = scores.filter((score) => score.split === split);
|
|
9035
9076
|
if (scoped.length > 0) out[split] = aggregateScenarioScores(scoped);
|
|
9036
9077
|
}
|
|
9037
9078
|
return out;
|
|
9038
9079
|
}
|
|
9039
|
-
function aggregateScenarioScores(
|
|
9040
|
-
const matched = sum2(
|
|
9041
|
-
const total = sum2(
|
|
9042
|
-
const falsePositives = sum2(
|
|
9043
|
-
const matchedWeight = sum2(
|
|
9044
|
-
const totalWeight = sum2(
|
|
9080
|
+
function aggregateScenarioScores(scores) {
|
|
9081
|
+
const matched = sum2(scores.map((score) => score.matched));
|
|
9082
|
+
const total = sum2(scores.map((score) => score.total));
|
|
9083
|
+
const falsePositives = sum2(scores.map((score) => score.falsePositives));
|
|
9084
|
+
const matchedWeight = sum2(scores.map((score) => score.matchedWeight));
|
|
9085
|
+
const totalWeight = sum2(scores.map((score) => score.totalWeight));
|
|
9045
9086
|
const precision2 = ratio(matched, matched + falsePositives);
|
|
9046
9087
|
const recall = ratio(matched, total);
|
|
9047
9088
|
return {
|
|
@@ -9305,18 +9346,16 @@ function createDefaultReviewer(options) {
|
|
|
9305
9346
|
|
|
9306
9347
|
// src/description-length-gate.ts
|
|
9307
9348
|
import { gzipSync } from "zlib";
|
|
9308
|
-
function
|
|
9309
|
-
|
|
9310
|
-
const s = o.holdoutScore ?? o.searchScore ?? o.raw?.score;
|
|
9311
|
-
return typeof s === "number" && Number.isFinite(s) ? s : void 0;
|
|
9349
|
+
function runScore2(run) {
|
|
9350
|
+
return runTaskScore(run);
|
|
9312
9351
|
}
|
|
9313
9352
|
function taskKey(run) {
|
|
9314
|
-
return run.scenarioId
|
|
9353
|
+
return run.scenarioId;
|
|
9315
9354
|
}
|
|
9316
9355
|
function perTaskMeanScore(runs) {
|
|
9317
9356
|
const acc = /* @__PURE__ */ new Map();
|
|
9318
9357
|
for (const run of runs) {
|
|
9319
|
-
const s =
|
|
9358
|
+
const s = runScore2(run);
|
|
9320
9359
|
if (s === void 0) continue;
|
|
9321
9360
|
const key = taskKey(run);
|
|
9322
9361
|
const cur = acc.get(key) ?? { sum: 0, n: 0 };
|
|
@@ -9564,55 +9603,82 @@ var HeldOutGate = class {
|
|
|
9564
9603
|
}
|
|
9565
9604
|
this.costPerTaskCeiling = config.costPerTaskCeiling;
|
|
9566
9605
|
}
|
|
9567
|
-
/** Decide whether `candidate` should replace `baseline`.
|
|
9568
|
-
* is by (experimentId, seed)
|
|
9569
|
-
*
|
|
9570
|
-
* a holdout score on both sides are dropped. */
|
|
9606
|
+
/** Decide whether `candidate` should replace `baseline`.
|
|
9607
|
+
* Pairing is by `(experimentId, scenarioId, seed)`.
|
|
9608
|
+
* Missing or duplicate identities throw instead of comparing by position. */
|
|
9571
9609
|
evaluate(candidate, baseline) {
|
|
9572
9610
|
const candidateId = inferCandidateId2(candidate, this.baselineKey);
|
|
9573
9611
|
const baselineId = this.baselineKey;
|
|
9574
|
-
|
|
9575
|
-
const
|
|
9576
|
-
const
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
}
|
|
9612
|
+
assertScenarioIdentities([...candidate, ...baseline]);
|
|
9613
|
+
const candidateSearch = scoredRuns(candidate, "searchScore", "search");
|
|
9614
|
+
const baselineSearch = scoredRuns(baseline, "searchScore", "search");
|
|
9615
|
+
const candidateHoldout = scoredRuns(candidate, "holdoutScore", "holdout");
|
|
9616
|
+
const baselineHoldout = scoredRuns(baseline, "holdoutScore", "holdout");
|
|
9617
|
+
const searchPairing = pairRunRecords(baselineSearch, candidateSearch);
|
|
9618
|
+
const holdoutPairing = pairRunRecords(baselineHoldout, candidateHoldout);
|
|
9619
|
+
const beforeSearch = searchPairing.pairs.map((pair) => pair.baseline.outcome.searchScore);
|
|
9620
|
+
const afterSearch = searchPairing.pairs.map((pair) => pair.treatment.outcome.searchScore);
|
|
9621
|
+
const beforeHoldout = holdoutPairing.pairs.map((pair) => pair.baseline.outcome.holdoutScore);
|
|
9622
|
+
const afterHoldout = holdoutPairing.pairs.map((pair) => pair.treatment.outcome.holdoutScore);
|
|
9586
9623
|
const productiveRuns = beforeHoldout.length;
|
|
9587
|
-
const candidateSearchMean =
|
|
9588
|
-
const candidateHoldoutMean =
|
|
9589
|
-
const baselineSearchMean =
|
|
9590
|
-
const baselineHoldoutMean =
|
|
9591
|
-
const overfitGap =
|
|
9592
|
-
const baselineOverfitGap =
|
|
9593
|
-
const medianCandidateCost =
|
|
9594
|
-
const medianBaselineCost =
|
|
9624
|
+
const candidateSearchMean = meanOrNull(afterSearch);
|
|
9625
|
+
const candidateHoldoutMean = meanOrNull(afterHoldout);
|
|
9626
|
+
const baselineSearchMean = meanOrNull(beforeSearch);
|
|
9627
|
+
const baselineHoldoutMean = meanOrNull(beforeHoldout);
|
|
9628
|
+
const overfitGap = diffOrNull(candidateSearchMean, candidateHoldoutMean);
|
|
9629
|
+
const baselineOverfitGap = diffOrNull(baselineSearchMean, baselineHoldoutMean);
|
|
9630
|
+
const medianCandidateCost = completeCostMedian(candidate);
|
|
9631
|
+
const medianBaselineCost = completeCostMedian(baseline);
|
|
9632
|
+
const commonEvidence = {
|
|
9633
|
+
productiveRuns,
|
|
9634
|
+
unpairedCandidateRuns: holdoutPairing.unpairedTreatment.length,
|
|
9635
|
+
unpairedBaselineRuns: holdoutPairing.unpairedBaseline.length,
|
|
9636
|
+
searchScore: candidateSearchMean,
|
|
9637
|
+
holdoutScore: candidateHoldoutMean,
|
|
9638
|
+
overfitGap,
|
|
9639
|
+
baselineOverfitGap,
|
|
9640
|
+
medianCandidateCost,
|
|
9641
|
+
medianBaselineCost
|
|
9642
|
+
};
|
|
9643
|
+
const missingSplitScores = [
|
|
9644
|
+
candidateSearch.length === 0 ? "candidate search" : null,
|
|
9645
|
+
candidateHoldout.length === 0 ? "candidate holdout" : null,
|
|
9646
|
+
baselineSearch.length === 0 ? "baseline search" : null,
|
|
9647
|
+
baselineHoldout.length === 0 ? "baseline holdout" : null
|
|
9648
|
+
].filter((label) => label !== null);
|
|
9649
|
+
if (missingSplitScores.length > 0) {
|
|
9650
|
+
return {
|
|
9651
|
+
promote: false,
|
|
9652
|
+
candidateId,
|
|
9653
|
+
baselineId,
|
|
9654
|
+
evidence: {
|
|
9655
|
+
...commonEvidence,
|
|
9656
|
+
medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) : null,
|
|
9657
|
+
pairedCI: null,
|
|
9658
|
+
pairedPValue: null
|
|
9659
|
+
},
|
|
9660
|
+
reason: `missing_split_scores: ${missingSplitScores.join(", ")} score evidence is absent`,
|
|
9661
|
+
rejectionCode: "missing_split_scores"
|
|
9662
|
+
};
|
|
9663
|
+
}
|
|
9595
9664
|
if (productiveRuns < this.minProductiveRuns) {
|
|
9596
9665
|
return {
|
|
9597
9666
|
promote: false,
|
|
9598
9667
|
candidateId,
|
|
9599
9668
|
baselineId,
|
|
9600
9669
|
evidence: {
|
|
9601
|
-
|
|
9602
|
-
medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) :
|
|
9603
|
-
pairedCI:
|
|
9604
|
-
pairedPValue:
|
|
9605
|
-
searchScore: candidateSearchMean,
|
|
9606
|
-
holdoutScore: candidateHoldoutMean,
|
|
9607
|
-
overfitGap,
|
|
9608
|
-
baselineOverfitGap,
|
|
9609
|
-
medianCandidateCost,
|
|
9610
|
-
medianBaselineCost
|
|
9670
|
+
...commonEvidence,
|
|
9671
|
+
medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) : null,
|
|
9672
|
+
pairedCI: null,
|
|
9673
|
+
pairedPValue: null
|
|
9611
9674
|
},
|
|
9612
9675
|
reason: `few_runs: ${productiveRuns} paired holdout observation(s) < min ${this.minProductiveRuns}`,
|
|
9613
9676
|
rejectionCode: "few_runs"
|
|
9614
9677
|
};
|
|
9615
9678
|
}
|
|
9679
|
+
if (overfitGap === null || baselineOverfitGap === null) {
|
|
9680
|
+
throw new Error("HeldOutGate: complete split scores did not produce overfit gaps");
|
|
9681
|
+
}
|
|
9616
9682
|
const ci = pairedBootstrap(beforeHoldout, afterHoldout, {
|
|
9617
9683
|
confidence: this.confidence,
|
|
9618
9684
|
resamples: this.resamples,
|
|
@@ -9621,16 +9687,10 @@ var HeldOutGate = class {
|
|
|
9621
9687
|
});
|
|
9622
9688
|
const wilcoxon = wilcoxonSignedRank(beforeHoldout, afterHoldout);
|
|
9623
9689
|
const evidence = {
|
|
9624
|
-
|
|
9690
|
+
...commonEvidence,
|
|
9625
9691
|
medianPairedDelta: ci.median,
|
|
9626
9692
|
pairedCI: { low: ci.low, high: ci.high },
|
|
9627
|
-
pairedPValue: wilcoxon.p
|
|
9628
|
-
searchScore: candidateSearchMean,
|
|
9629
|
-
holdoutScore: candidateHoldoutMean,
|
|
9630
|
-
overfitGap,
|
|
9631
|
-
baselineOverfitGap,
|
|
9632
|
-
medianCandidateCost,
|
|
9633
|
-
medianBaselineCost
|
|
9693
|
+
pairedPValue: wilcoxon.p
|
|
9634
9694
|
};
|
|
9635
9695
|
if (!(ci.low > this.pairedDeltaThreshold)) {
|
|
9636
9696
|
return {
|
|
@@ -9642,7 +9702,7 @@ var HeldOutGate = class {
|
|
|
9642
9702
|
rejectionCode: "negative_delta"
|
|
9643
9703
|
};
|
|
9644
9704
|
}
|
|
9645
|
-
if (
|
|
9705
|
+
if (overfitGap > baselineOverfitGap + this.overfitGapThreshold) {
|
|
9646
9706
|
return {
|
|
9647
9707
|
promote: false,
|
|
9648
9708
|
candidateId,
|
|
@@ -9652,7 +9712,17 @@ var HeldOutGate = class {
|
|
|
9652
9712
|
rejectionCode: "overfit_gap"
|
|
9653
9713
|
};
|
|
9654
9714
|
}
|
|
9655
|
-
if (this.costPerTaskCeiling !== void 0 &&
|
|
9715
|
+
if (this.costPerTaskCeiling !== void 0 && medianCandidateCost === null) {
|
|
9716
|
+
return {
|
|
9717
|
+
promote: false,
|
|
9718
|
+
candidateId,
|
|
9719
|
+
baselineId,
|
|
9720
|
+
evidence,
|
|
9721
|
+
reason: "missing_cost: candidate cost evidence is incomplete",
|
|
9722
|
+
rejectionCode: "missing_cost"
|
|
9723
|
+
};
|
|
9724
|
+
}
|
|
9725
|
+
if (this.costPerTaskCeiling !== void 0 && medianCandidateCost !== null && medianCandidateCost > this.costPerTaskCeiling) {
|
|
9656
9726
|
return {
|
|
9657
9727
|
promote: false,
|
|
9658
9728
|
candidateId,
|
|
@@ -9678,49 +9748,50 @@ function inferCandidateId2(candidate, baselineKey) {
|
|
|
9678
9748
|
}
|
|
9679
9749
|
return candidate[0]?.candidateId ?? "(unknown candidate)";
|
|
9680
9750
|
}
|
|
9681
|
-
function
|
|
9682
|
-
const
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
out.set(pairKey(r), r.outcome.holdoutScore);
|
|
9751
|
+
function assertScenarioIdentities(runs) {
|
|
9752
|
+
for (const run of runs) {
|
|
9753
|
+
if (typeof run.scenarioId !== "string" || run.scenarioId.trim() === "") {
|
|
9754
|
+
throw new Error(`HeldOutGate: run ${run.runId} is missing scenarioId`);
|
|
9755
|
+
}
|
|
9687
9756
|
}
|
|
9688
|
-
return out;
|
|
9689
|
-
}
|
|
9690
|
-
function pairKey(r) {
|
|
9691
|
-
return `${r.experimentId}::${r.seed}`;
|
|
9692
9757
|
}
|
|
9693
|
-
function
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
const v = r.outcome[field];
|
|
9698
|
-
if (typeof v === "number" && Number.isFinite(v)) out.push(v);
|
|
9699
|
-
}
|
|
9700
|
-
return out;
|
|
9758
|
+
function scoredRuns(runs, field, splitFilter) {
|
|
9759
|
+
return runs.filter(
|
|
9760
|
+
(run) => run.splitTag === splitFilter && typeof run.outcome[field] === "number" && Number.isFinite(run.outcome[field])
|
|
9761
|
+
);
|
|
9701
9762
|
}
|
|
9702
|
-
function
|
|
9703
|
-
if (xs.length === 0) return
|
|
9763
|
+
function meanOrNull(xs) {
|
|
9764
|
+
if (xs.length === 0) return null;
|
|
9704
9765
|
return xs.reduce((s, x) => s + x, 0) / xs.length;
|
|
9705
9766
|
}
|
|
9706
|
-
function
|
|
9707
|
-
if (
|
|
9767
|
+
function diffOrNull(a, b) {
|
|
9768
|
+
if (a === null || b === null) return null;
|
|
9708
9769
|
return a - b;
|
|
9709
9770
|
}
|
|
9710
9771
|
function medianDelta(before, after) {
|
|
9711
9772
|
const ds = before.map((b, i) => after[i] - b).sort((x, y) => x - y);
|
|
9712
|
-
if (ds.length === 0)
|
|
9773
|
+
if (ds.length === 0) throw new Error("HeldOutGate: median delta requires at least one pair");
|
|
9713
9774
|
const mid = Math.floor(ds.length / 2);
|
|
9714
9775
|
return ds.length % 2 === 0 ? (ds[mid - 1] + ds[mid]) / 2 : ds[mid];
|
|
9715
9776
|
}
|
|
9716
9777
|
function medianFinite(xs) {
|
|
9717
9778
|
const ys = xs.filter((x) => Number.isFinite(x)).sort((x, y) => x - y);
|
|
9718
|
-
if (ys.length === 0) return
|
|
9779
|
+
if (ys.length === 0) return null;
|
|
9719
9780
|
const mid = Math.floor(ys.length / 2);
|
|
9720
9781
|
return ys.length % 2 === 0 ? (ys[mid - 1] + ys[mid]) / 2 : ys[mid];
|
|
9721
9782
|
}
|
|
9783
|
+
function completeCostMedian(runs) {
|
|
9784
|
+
if (runs.length === 0) return null;
|
|
9785
|
+
const costs = [];
|
|
9786
|
+
for (const run of runs) {
|
|
9787
|
+
const provenance = run.costProvenance;
|
|
9788
|
+
if (provenance.kind === "uncaptured") return null;
|
|
9789
|
+
costs.push(provenance.usd);
|
|
9790
|
+
}
|
|
9791
|
+
return medianFinite(costs);
|
|
9792
|
+
}
|
|
9722
9793
|
function fmt(x) {
|
|
9723
|
-
if (
|
|
9794
|
+
if (x === null) return "n/a";
|
|
9724
9795
|
return x.toFixed(4);
|
|
9725
9796
|
}
|
|
9726
9797
|
|
|
@@ -9739,9 +9810,9 @@ function passOrthogonality(input) {
|
|
|
9739
9810
|
sims.push(cosineSimilarity(vectors[i], vectors[j]));
|
|
9740
9811
|
}
|
|
9741
9812
|
}
|
|
9742
|
-
const
|
|
9813
|
+
const mean6 = sims.length === 0 ? 0 : sims.reduce((a, b) => a + b, 0) / sims.length;
|
|
9743
9814
|
return {
|
|
9744
|
-
orthogonality: Math.max(0, Math.min(1, 1 -
|
|
9815
|
+
orthogonality: Math.max(0, Math.min(1, 1 - mean6)),
|
|
9745
9816
|
passCount: passes.length,
|
|
9746
9817
|
similarities: sims
|
|
9747
9818
|
};
|
|
@@ -10255,17 +10326,17 @@ function traceJudge(judge, judgeName, opts) {
|
|
|
10255
10326
|
}
|
|
10256
10327
|
});
|
|
10257
10328
|
try {
|
|
10258
|
-
const
|
|
10259
|
-
const composite =
|
|
10329
|
+
const scores = await judge(tc, input);
|
|
10330
|
+
const composite = scores.length > 0 ? scores.reduce((sum4, s) => sum4 + s.score, 0) / scores.length : 0;
|
|
10260
10331
|
await span.end({
|
|
10261
10332
|
attributes: {
|
|
10262
10333
|
"judge.name": judgeName,
|
|
10263
10334
|
"judge.composite_score": composite,
|
|
10264
|
-
"judge.dimension_count":
|
|
10335
|
+
"judge.dimension_count": scores.length,
|
|
10265
10336
|
"eval.phase": "judge"
|
|
10266
10337
|
}
|
|
10267
10338
|
});
|
|
10268
|
-
return
|
|
10339
|
+
return scores;
|
|
10269
10340
|
} catch (err) {
|
|
10270
10341
|
await span.fail(err instanceof Error ? err : String(err));
|
|
10271
10342
|
throw err;
|
|
@@ -10294,8 +10365,8 @@ function traceJudgeEnsemble(judges, judgeNames, opts) {
|
|
|
10294
10365
|
parentSpanId: ensembleSpan.span.spanId
|
|
10295
10366
|
});
|
|
10296
10367
|
try {
|
|
10297
|
-
const
|
|
10298
|
-
allScores.push(...
|
|
10368
|
+
const scores = await tracedFn(tc, input);
|
|
10369
|
+
allScores.push(...scores);
|
|
10299
10370
|
} catch (err) {
|
|
10300
10371
|
if (!(err instanceof JudgeParseError)) throw err;
|
|
10301
10372
|
failedJudges++;
|
|
@@ -10556,10 +10627,16 @@ function splitOf(record, opts) {
|
|
|
10556
10627
|
return "practice";
|
|
10557
10628
|
}
|
|
10558
10629
|
function scoreOf(record) {
|
|
10559
|
-
const score = record
|
|
10560
|
-
if (
|
|
10561
|
-
|
|
10562
|
-
|
|
10630
|
+
const score = runTaskScore(record);
|
|
10631
|
+
if (score !== void 0) return clamp014(score);
|
|
10632
|
+
if ((record.outcome.judgeScores?.failedJudges?.length ?? 0) > 0 || (record.outcome.raw.judge_error_count ?? 0) > 0) {
|
|
10633
|
+
throw new ValidationError(
|
|
10634
|
+
`Run ${record.runId} has incomplete judge evidence; product benchmark rows require a complete task score`
|
|
10635
|
+
);
|
|
10636
|
+
}
|
|
10637
|
+
throw new ValidationError(
|
|
10638
|
+
`Run ${record.runId} has no task score; product benchmark rows require an explicit score`
|
|
10639
|
+
);
|
|
10563
10640
|
}
|
|
10564
10641
|
function rawPassOf(record) {
|
|
10565
10642
|
const rawPass = record.outcome.raw.pass;
|
|
@@ -10569,17 +10646,28 @@ function rawPassOf(record) {
|
|
|
10569
10646
|
}
|
|
10570
10647
|
function passOf(record, score, threshold) {
|
|
10571
10648
|
const rawPass = rawPassOf(record);
|
|
10572
|
-
|
|
10573
|
-
|
|
10649
|
+
const hasTaskFailure = record.failureClass !== void 0 && record.failureClass !== "success";
|
|
10650
|
+
if (rawPass !== null) return rawPass && !hasTaskFailure;
|
|
10651
|
+
return score >= threshold && !hasTaskFailure;
|
|
10574
10652
|
}
|
|
10575
|
-
function
|
|
10576
|
-
if (record.
|
|
10653
|
+
function failureOf(record, score, threshold) {
|
|
10654
|
+
if (record.failureClass !== void 0 && record.failureClass !== "success") {
|
|
10655
|
+
return {
|
|
10656
|
+
failureClass: record.failureClass,
|
|
10657
|
+
failureDetail: record.failureMode ?? null
|
|
10658
|
+
};
|
|
10659
|
+
}
|
|
10577
10660
|
const belowThreshold = `quality-below-threshold: ${Math.round(score * 100)}% < ${Math.round(threshold * 100)}%`;
|
|
10578
10661
|
if (rawPassOf(record) === false) {
|
|
10579
|
-
return
|
|
10662
|
+
return {
|
|
10663
|
+
failureClass: "unknown",
|
|
10664
|
+
failureDetail: score < threshold ? belowThreshold : "product-pass-failed"
|
|
10665
|
+
};
|
|
10580
10666
|
}
|
|
10581
|
-
if (passOf(record, score, threshold))
|
|
10582
|
-
|
|
10667
|
+
if (passOf(record, score, threshold)) {
|
|
10668
|
+
return { failureClass: null, failureDetail: null };
|
|
10669
|
+
}
|
|
10670
|
+
return { failureClass: "unknown", failureDetail: belowThreshold };
|
|
10583
10671
|
}
|
|
10584
10672
|
function numericDimensions(record) {
|
|
10585
10673
|
const dimensions = {};
|
|
@@ -10696,18 +10784,25 @@ function runRecordToProductBenchmarkRecord(record, runDir, artifactRoot, artifac
|
|
|
10696
10784
|
const opts = resolveOptions(options);
|
|
10697
10785
|
const runtime = runtimeResolution(record, opts);
|
|
10698
10786
|
const score = scoreOf(record);
|
|
10787
|
+
const failure = failureOf(record, score, opts.passThreshold);
|
|
10699
10788
|
const armId = armIdOf(record);
|
|
10700
10789
|
const inputTokens = record.tokenUsage.input;
|
|
10701
10790
|
const outputTokens = record.tokenUsage.output;
|
|
10702
10791
|
const toolCallCount = toolCallsOf(record, runDir, opts);
|
|
10703
10792
|
const dimensions = numericDimensions(record);
|
|
10793
|
+
if (record.costUsd === null) {
|
|
10794
|
+
throw new ValidationError(
|
|
10795
|
+
`run '${record.runId}' has no USD cost; product benchmark exports require priced runs`
|
|
10796
|
+
);
|
|
10797
|
+
}
|
|
10798
|
+
const costUsd = record.costUsd;
|
|
10704
10799
|
if (!("tool_calls" in dimensions)) dimensions.tool_calls = toolCallCount;
|
|
10705
10800
|
const product = {
|
|
10706
10801
|
schemaVersion: 1,
|
|
10707
10802
|
projectId: opts.projectId,
|
|
10708
10803
|
benchmarkId: opts.benchmarkId,
|
|
10709
10804
|
runId: record.runId,
|
|
10710
|
-
scenarioId: record.scenarioId
|
|
10805
|
+
scenarioId: record.scenarioId,
|
|
10711
10806
|
split: splitOf(record, opts),
|
|
10712
10807
|
armId,
|
|
10713
10808
|
rep: Number(record.seed ?? 0) + 1,
|
|
@@ -10724,12 +10819,12 @@ function runRecordToProductBenchmarkRecord(record, runDir, artifactRoot, artifac
|
|
|
10724
10819
|
pass: passOf(record, score, opts.passThreshold),
|
|
10725
10820
|
score,
|
|
10726
10821
|
dimensions,
|
|
10727
|
-
|
|
10822
|
+
...failure
|
|
10728
10823
|
},
|
|
10729
10824
|
usage: {
|
|
10730
10825
|
inputTokens,
|
|
10731
10826
|
outputTokens,
|
|
10732
|
-
costUsd
|
|
10827
|
+
costUsd,
|
|
10733
10828
|
// Rounded: the bundle contract requires integer milliseconds.
|
|
10734
10829
|
wallMs: Math.round(record.wallMs),
|
|
10735
10830
|
toolCalls: toolCallCount
|
|
@@ -10739,7 +10834,7 @@ function runRecordToProductBenchmarkRecord(record, runDir, artifactRoot, artifac
|
|
|
10739
10834
|
rawCapture: existsArtifact(artifactRoot, artifacts.raws),
|
|
10740
10835
|
traceCapture: existsArtifact(artifactRoot, artifacts.traces),
|
|
10741
10836
|
noStubRows: inputTokens + outputTokens > 0,
|
|
10742
|
-
priced:
|
|
10837
|
+
priced: costUsd > 0,
|
|
10743
10838
|
profileMaterialized: Boolean(record.agentProfile?.cellId)
|
|
10744
10839
|
},
|
|
10745
10840
|
artifacts
|
|
@@ -10939,6 +11034,13 @@ function expectString(value, path) {
|
|
|
10939
11034
|
fail(path, "must be a non-empty string");
|
|
10940
11035
|
return value;
|
|
10941
11036
|
}
|
|
11037
|
+
function expectFailureClass(value, path) {
|
|
11038
|
+
const parsed = expectString(value, path);
|
|
11039
|
+
if (parsed === "success" || !FAILURE_CLASSES.includes(parsed)) {
|
|
11040
|
+
fail(path, `expected a non-success FailureClass, received ${JSON.stringify(parsed)}`);
|
|
11041
|
+
}
|
|
11042
|
+
return parsed;
|
|
11043
|
+
}
|
|
10942
11044
|
function expectBoolean(value, path) {
|
|
10943
11045
|
if (typeof value !== "boolean") fail(path, "must be a boolean");
|
|
10944
11046
|
return value;
|
|
@@ -11081,6 +11183,18 @@ function validateProductBenchmarkRecord(value) {
|
|
|
11081
11183
|
const usage = expectObject(obj.usage, "record.usage");
|
|
11082
11184
|
const integrity = expectObject(obj.integrity, "record.integrity");
|
|
11083
11185
|
const artifacts = expectObject(obj.artifacts, "record.artifacts");
|
|
11186
|
+
const outcomePass = expectBoolean(outcome.pass, "record.outcome.pass");
|
|
11187
|
+
const failureClass = outcome.failureClass === null ? null : expectFailureClass(outcome.failureClass, "record.outcome.failureClass");
|
|
11188
|
+
const failureDetail = outcome.failureDetail === null ? null : expectString(outcome.failureDetail, "record.outcome.failureDetail");
|
|
11189
|
+
if (outcomePass && (failureClass !== null || failureDetail !== null)) {
|
|
11190
|
+
fail("record.outcome", "a passing row cannot carry failure evidence");
|
|
11191
|
+
}
|
|
11192
|
+
if (!outcomePass && failureClass === null) {
|
|
11193
|
+
fail("record.outcome.failureClass", "a failed row requires a failure class");
|
|
11194
|
+
}
|
|
11195
|
+
if (failureClass === null && failureDetail !== null) {
|
|
11196
|
+
fail("record.outcome.failureDetail", "failure detail requires a failure class");
|
|
11197
|
+
}
|
|
11084
11198
|
const record = {
|
|
11085
11199
|
schemaVersion: 1,
|
|
11086
11200
|
projectId: expectString(obj.projectId, "record.projectId"),
|
|
@@ -11106,10 +11220,11 @@ function validateProductBenchmarkRecord(value) {
|
|
|
11106
11220
|
version: expectString(backend.version, "record.backend.version")
|
|
11107
11221
|
},
|
|
11108
11222
|
outcome: {
|
|
11109
|
-
pass:
|
|
11223
|
+
pass: outcomePass,
|
|
11110
11224
|
score: expectNumber(outcome.score, "record.outcome.score", { min: 0, max: 1 }),
|
|
11111
11225
|
dimensions: expectDimensions(outcome.dimensions, "record.outcome.dimensions"),
|
|
11112
|
-
|
|
11226
|
+
failureClass,
|
|
11227
|
+
failureDetail
|
|
11113
11228
|
},
|
|
11114
11229
|
usage: {
|
|
11115
11230
|
inputTokens: expectNumber(usage.inputTokens, "record.usage.inputTokens", {
|
|
@@ -11379,7 +11494,6 @@ export {
|
|
|
11379
11494
|
REFERENCE_EQUIVALENCE_INPUT_LIMITS,
|
|
11380
11495
|
REFERENCE_EQUIVALENCE_JUDGE_VERSION,
|
|
11381
11496
|
RESEARCH_REPORT_HARD_PAIR_FLOOR,
|
|
11382
|
-
ROLLOUT_FORMAT,
|
|
11383
11497
|
ROLLOUT_SCHEMA,
|
|
11384
11498
|
RUN_COST_ATTR_KEYS,
|
|
11385
11499
|
ReplayCache,
|
|
@@ -11498,6 +11612,7 @@ export {
|
|
|
11498
11612
|
checkTraceContracts,
|
|
11499
11613
|
clamp01,
|
|
11500
11614
|
classifyFailure,
|
|
11615
|
+
classifyOtlpSpanRole,
|
|
11501
11616
|
classifyTreatment,
|
|
11502
11617
|
claudeCodeSupervisorRunReader,
|
|
11503
11618
|
cliffsDelta,
|
|
@@ -11661,6 +11776,7 @@ export {
|
|
|
11661
11776
|
isLlmSpan,
|
|
11662
11777
|
isModelPriced,
|
|
11663
11778
|
isOtelConfigured,
|
|
11779
|
+
isOtlpModelCall,
|
|
11664
11780
|
isRetrievalSpan,
|
|
11665
11781
|
isRolloutLine,
|
|
11666
11782
|
isRunRecord,
|
|
@@ -11719,7 +11835,9 @@ export {
|
|
|
11719
11835
|
otlpToRunRecords,
|
|
11720
11836
|
otlpToTraceRunRecords,
|
|
11721
11837
|
pairArms,
|
|
11838
|
+
pairRunRecords,
|
|
11722
11839
|
pairedBootstrap,
|
|
11840
|
+
pairedCohensDz,
|
|
11723
11841
|
pairedEvalueSequence,
|
|
11724
11842
|
pairedMde,
|
|
11725
11843
|
pairedRiskDifference,
|
|
@@ -11788,10 +11906,10 @@ export {
|
|
|
11788
11906
|
replayScorerOverCorpus,
|
|
11789
11907
|
replayTraceThroughJudge,
|
|
11790
11908
|
requireAgentProfileCell,
|
|
11909
|
+
requiredPairedSampleSize,
|
|
11791
11910
|
requiredSampleSize,
|
|
11792
11911
|
researchReport,
|
|
11793
11912
|
resolveModelPricing,
|
|
11794
|
-
resolveRunCostProvenance,
|
|
11795
11913
|
resolveSeat,
|
|
11796
11914
|
rolloutReward,
|
|
11797
11915
|
rollupSupervisorRuns,
|
|
@@ -11822,6 +11940,7 @@ export {
|
|
|
11822
11940
|
runScore,
|
|
11823
11941
|
runSelfPlay,
|
|
11824
11942
|
runSemanticConceptJudge,
|
|
11943
|
+
runTaskScore,
|
|
11825
11944
|
runTestGradedScenario,
|
|
11826
11945
|
runsForScenario,
|
|
11827
11946
|
scalarScore,
|