@tangle-network/agent-eval 0.92.0 → 0.94.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/dist/adapters/otel.d.ts +4 -4
- package/dist/analyst/index.d.ts +10 -10
- package/dist/analyst/index.js +6 -6
- package/dist/{analyze-runs-DwCEkpO_.d.ts → analyze-runs-B6Ljo_dI.d.ts} +2 -2
- package/dist/{baseline-DE36-Np7.d.ts → baseline-Bbid3WoO.d.ts} +1 -1
- package/dist/belief-state/index.d.ts +2 -2
- package/dist/belief-state/index.js +1 -1
- package/dist/builder-eval/index.d.ts +3 -3
- package/dist/builder-eval/index.js +2 -2
- package/dist/{calibration-Cpr3WaX3.d.ts → calibration-BPmzuVPk.d.ts} +1 -1
- package/dist/campaign/index.d.ts +13 -13
- package/dist/campaign/index.js +8 -8
- package/dist/{chunk-TWS7AZEY.js → chunk-2K6UUZ7P.js} +2 -2
- package/dist/{chunk-Y47J2LJ3.js → chunk-2KNZHH3P.js} +5 -5
- package/dist/{chunk-LMZQ2Z4U.js → chunk-56GC6VYO.js} +126 -1
- package/dist/chunk-56GC6VYO.js.map +1 -0
- package/dist/{chunk-QG2OVF2D.js → chunk-CTBHKLEU.js} +99 -30
- package/dist/chunk-CTBHKLEU.js.map +1 -0
- package/dist/{chunk-CVVHBFGN.js → chunk-CWNP4DV4.js} +53 -5
- package/dist/chunk-CWNP4DV4.js.map +1 -0
- package/dist/{chunk-QS3RBQPI.js → chunk-D5KBVULY.js} +2 -2
- package/dist/{chunk-RTWFUK6A.js → chunk-E4GH6USR.js} +2 -2
- package/dist/{chunk-ZFIBGEOL.js → chunk-EGPMSBEZ.js} +4 -4
- package/dist/{chunk-GSH6QNNS.js → chunk-KW53MSA5.js} +101 -78
- package/dist/chunk-KW53MSA5.js.map +1 -0
- package/dist/{chunk-UMMZHCPB.js → chunk-MIFZUPEK.js} +7 -5
- package/dist/chunk-MIFZUPEK.js.map +1 -0
- package/dist/{chunk-XY4DDNEG.js → chunk-MPQWFX6Y.js} +2 -2
- package/dist/{chunk-L3JOU6XM.js → chunk-NACM5RS7.js} +3 -3
- package/dist/{chunk-3CKU6VGU.js → chunk-Q2JRAWRI.js} +2 -2
- package/dist/{chunk-D3V5B42D.js → chunk-Q5LIB7BC.js} +7 -4
- package/dist/{chunk-D3V5B42D.js.map → chunk-Q5LIB7BC.js.map} +1 -1
- package/dist/{chunk-QAY5UIJO.js → chunk-QMUEXQJS.js} +99 -57
- package/dist/chunk-QMUEXQJS.js.map +1 -0
- package/dist/{chunk-4FBZZIYD.js → chunk-QTMYW64F.js} +2 -2
- package/dist/{chunk-6SOJM3VR.js → chunk-SD2YFWQQ.js} +4 -4
- package/dist/{chunk-UHMJT4T7.js → chunk-TBDR6PAI.js} +2 -2
- package/dist/{chunk-47X6LRCE.js → chunk-UFSG7ACU.js} +10 -7
- package/dist/chunk-UFSG7ACU.js.map +1 -0
- package/dist/{chunk-CY6U5S3X.js → chunk-URWVKRCS.js} +2 -2
- package/dist/{chunk-NCRFYPS3.js → chunk-YEHAEDUD.js} +130 -44
- package/dist/chunk-YEHAEDUD.js.map +1 -0
- package/dist/{chunk-T375SUOZ.js → chunk-ZOPLCJSY.js} +86 -31
- package/dist/chunk-ZOPLCJSY.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/contract/index.d.ts +17 -17
- package/dist/contract/index.js +11 -11
- package/dist/{control-_Qb7skHX.d.ts → control-D6qwHXIR.d.ts} +4 -4
- package/dist/{control-runtime-DuFBYg7A.d.ts → control-runtime-Acf9CGhw.d.ts} +2 -2
- package/dist/control.d.ts +5 -5
- package/dist/control.js +2 -2
- package/dist/{corpus-BoR-041R.d.ts → corpus-B8A4BDR3.d.ts} +1 -1
- package/dist/{counterfactual-Dwibr5IW.d.ts → counterfactual-DlOz8PBx.d.ts} +3 -3
- package/dist/{default-registry-zoGHUQEH.d.ts → default-registry-6dhErQbs.d.ts} +2 -2
- package/dist/diagnose.d.ts +9 -9
- package/dist/diagnose.js +1 -1
- package/dist/{emitter-DEZwY14K.d.ts → emitter-C2rqGH_l.d.ts} +1 -1
- package/dist/{failure-cluster-CL7IVgkJ.d.ts → failure-cluster-DH9Flgcf.d.ts} +1 -1
- package/dist/{feedback-trajectory-D9OVLrg9.d.ts → feedback-trajectory-BxY0cKfs.d.ts} +1 -1
- package/dist/governance/index.d.ts +2 -2
- package/dist/{harness-optimizer-EnEnQPsr.d.ts → harness-optimizer-mOl9XX_O.d.ts} +1 -1
- package/dist/hosted/index.d.ts +4 -4
- package/dist/index.d.ts +181 -49
- package/dist/index.js +309 -90
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-BBwvOh6x.d.ts → insight-report-DWl3z9tl.d.ts} +1 -1
- package/dist/{integrity-VJ9A7aST.d.ts → integrity-D2t12mMw.d.ts} +1 -1
- package/dist/{kind-factory-5b7xXXOr.d.ts → kind-factory-0BhLSI27.d.ts} +1 -1
- package/dist/knowledge/index.d.ts +3 -3
- package/dist/knowledge/index.js +2 -2
- package/dist/{llm-client-BeEcAokY.d.ts → llm-client-Bj7g0rqu.d.ts} +31 -0
- package/dist/meta-eval/index.d.ts +4 -4
- package/dist/meta-eval/index.js +1 -1
- package/dist/openapi.json +1 -1
- package/dist/pipelines/index.d.ts +6 -6
- package/dist/pipelines/index.js +40 -15
- package/dist/pipelines/index.js.map +1 -1
- package/dist/prm/index.d.ts +11 -7
- package/dist/prm/index.js +55 -12
- package/dist/prm/index.js.map +1 -1
- package/dist/{provenance-LnqRT0sS.d.ts → provenance-P-bCL2Fo.d.ts} +3 -3
- package/dist/{query-CqTxMwDw.d.ts → query-B7GGjRox.d.ts} +2 -1
- package/dist/{red-team-BXHil6c8.d.ts → red-team-BWdoyleI.d.ts} +1 -1
- package/dist/{release-report-euXIV_Sk.d.ts → release-report-BEbWmVYj.d.ts} +1 -1
- package/dist/reporting.d.ts +6 -6
- package/dist/reporting.js +3 -3
- package/dist/{researcher-DE6Gpnb4.d.ts → researcher-B0C2_fVO.d.ts} +5 -5
- package/dist/rl.d.ts +10 -10
- package/dist/rl.js +4 -4
- package/dist/{rubric-BOfxn4ja.d.ts → rubric-Cc6UHvUb.d.ts} +2 -2
- package/dist/{run-campaign-RDGAM5KJ.js → run-campaign-7WNXMDSN.js} +3 -3
- package/dist/{run-critic-BAIjX99r.d.ts → run-critic-CmMf05uV.d.ts} +1 -1
- package/dist/{run-improvement-loop-5z_l5zDz.d.ts → run-improvement-loop-DBahB8Ax.d.ts} +1 -1
- package/dist/{semantic-concept-judge-Dn8Z6KEG.d.ts → semantic-concept-judge-B9MgmBnM.d.ts} +3 -3
- package/dist/{statistics-C7PozGrZ.d.ts → statistics-CCJpTGOS.d.ts} +117 -2
- package/dist/{store-CKUAgsJz.d.ts → store-BcFXE6LG.d.ts} +16 -1
- package/dist/{summary-report-DGmUucwQ.d.ts → summary-report-BDOFevaT.d.ts} +1 -1
- package/dist/{test-graded-scenario-BdVaPyHT.d.ts → test-graded-scenario-DeODGLra.d.ts} +21 -2
- package/dist/traces.d.ts +19 -6
- package/dist/traces.js +4 -4
- package/dist/{trajectory-GEdXJCL5.d.ts → trajectory-2TkpSEVh.d.ts} +1 -1
- package/dist/{types-Croy5h7V.d.ts → types-C7DGg5ex.d.ts} +2 -0
- package/dist/{types-2VVIL04s.d.ts → types-Ce17tDlG.d.ts} +2 -2
- package/dist/wire/index.d.ts +8 -8
- package/dist/wire/index.js +2 -2
- package/dist/workflow/index.d.ts +13 -13
- package/dist/workflow/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-47X6LRCE.js.map +0 -1
- package/dist/chunk-CVVHBFGN.js.map +0 -1
- package/dist/chunk-GSH6QNNS.js.map +0 -1
- package/dist/chunk-LMZQ2Z4U.js.map +0 -1
- package/dist/chunk-NCRFYPS3.js.map +0 -1
- package/dist/chunk-QAY5UIJO.js.map +0 -1
- package/dist/chunk-QG2OVF2D.js.map +0 -1
- package/dist/chunk-T375SUOZ.js.map +0 -1
- package/dist/chunk-UMMZHCPB.js.map +0 -1
- /package/dist/{chunk-TWS7AZEY.js.map → chunk-2K6UUZ7P.js.map} +0 -0
- /package/dist/{chunk-Y47J2LJ3.js.map → chunk-2KNZHH3P.js.map} +0 -0
- /package/dist/{chunk-QS3RBQPI.js.map → chunk-D5KBVULY.js.map} +0 -0
- /package/dist/{chunk-RTWFUK6A.js.map → chunk-E4GH6USR.js.map} +0 -0
- /package/dist/{chunk-ZFIBGEOL.js.map → chunk-EGPMSBEZ.js.map} +0 -0
- /package/dist/{chunk-XY4DDNEG.js.map → chunk-MPQWFX6Y.js.map} +0 -0
- /package/dist/{chunk-L3JOU6XM.js.map → chunk-NACM5RS7.js.map} +0 -0
- /package/dist/{chunk-3CKU6VGU.js.map → chunk-Q2JRAWRI.js.map} +0 -0
- /package/dist/{chunk-4FBZZIYD.js.map → chunk-QTMYW64F.js.map} +0 -0
- /package/dist/{chunk-6SOJM3VR.js.map → chunk-SD2YFWQQ.js.map} +0 -0
- /package/dist/{chunk-UHMJT4T7.js.map → chunk-TBDR6PAI.js.map} +0 -0
- /package/dist/{chunk-CY6U5S3X.js.map → chunk-URWVKRCS.js.map} +0 -0
- /package/dist/{run-campaign-RDGAM5KJ.js.map → run-campaign-7WNXMDSN.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
pairedBootstrap,
|
|
6
6
|
pairedMde,
|
|
7
7
|
wilcoxonSignedRank
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-56GC6VYO.js";
|
|
9
9
|
import {
|
|
10
10
|
canonicalize,
|
|
11
11
|
hashJson
|
|
@@ -877,4 +877,4 @@ export {
|
|
|
877
877
|
RESEARCH_REPORT_HARD_PAIR_FLOOR,
|
|
878
878
|
researchReport
|
|
879
879
|
};
|
|
880
|
-
//# sourceMappingURL=chunk-
|
|
880
|
+
//# sourceMappingURL=chunk-URWVKRCS.js.map
|
|
@@ -2,6 +2,112 @@ import {
|
|
|
2
2
|
TraceEmitter
|
|
3
3
|
} from "./chunk-TVVP3ZZQ.js";
|
|
4
4
|
|
|
5
|
+
// src/detectors/index.ts
|
|
6
|
+
function repeatedActionDetector(opts = {}) {
|
|
7
|
+
const max = opts.maxRepeated ?? 3;
|
|
8
|
+
const severity = opts.severity ?? "warn";
|
|
9
|
+
const failureClass = opts.failureClass ?? "tool_recovery_failure";
|
|
10
|
+
let last;
|
|
11
|
+
let streak = 0;
|
|
12
|
+
return {
|
|
13
|
+
id: "repeated-action",
|
|
14
|
+
get streak() {
|
|
15
|
+
return streak;
|
|
16
|
+
},
|
|
17
|
+
observe(event) {
|
|
18
|
+
const fp = event.actionFingerprint;
|
|
19
|
+
if (fp === void 0) return null;
|
|
20
|
+
streak = fp === last ? streak + 1 : 1;
|
|
21
|
+
last = fp;
|
|
22
|
+
if (max <= 0 || streak < max) return null;
|
|
23
|
+
return {
|
|
24
|
+
detector: "repeated-action",
|
|
25
|
+
severity,
|
|
26
|
+
failureClass,
|
|
27
|
+
reason: `stuck: repeated same action for ${streak} step(s)`,
|
|
28
|
+
streak,
|
|
29
|
+
...event.label ? { evidence: { action: event.label } } : {}
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
reset() {
|
|
33
|
+
last = void 0;
|
|
34
|
+
streak = 0;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function noProgressDetector(opts = {}) {
|
|
39
|
+
const max = opts.maxNoProgress ?? 3;
|
|
40
|
+
const minScoreDelta = opts.minScoreDelta ?? 1e-3;
|
|
41
|
+
const severity = opts.severity ?? "warn";
|
|
42
|
+
const failureClass = opts.failureClass ?? "tool_recovery_failure";
|
|
43
|
+
let lastState;
|
|
44
|
+
let lastScore;
|
|
45
|
+
let streak = 0;
|
|
46
|
+
return {
|
|
47
|
+
id: "no-progress",
|
|
48
|
+
get streak() {
|
|
49
|
+
return streak;
|
|
50
|
+
},
|
|
51
|
+
observe(event) {
|
|
52
|
+
const stateUnchanged = lastState !== void 0 && lastState === event.stateFingerprint;
|
|
53
|
+
const scoreFlat = Math.abs((event.score ?? 0) - (lastScore ?? 0)) < minScoreDelta;
|
|
54
|
+
streak = stateUnchanged && scoreFlat ? streak + 1 : 0;
|
|
55
|
+
lastState = event.stateFingerprint;
|
|
56
|
+
lastScore = event.score;
|
|
57
|
+
if (max <= 0 || streak < max) return null;
|
|
58
|
+
return {
|
|
59
|
+
detector: "no-progress",
|
|
60
|
+
severity,
|
|
61
|
+
failureClass,
|
|
62
|
+
reason: `stuck: no state/score progress for ${streak} step(s)`,
|
|
63
|
+
streak,
|
|
64
|
+
...event.label ? { evidence: { state: event.label } } : {}
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
reset() {
|
|
68
|
+
lastState = void 0;
|
|
69
|
+
lastScore = void 0;
|
|
70
|
+
streak = 0;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function errorStreakDetector(opts = {}) {
|
|
75
|
+
const max = opts.maxErrors ?? 3;
|
|
76
|
+
const severity = opts.severity ?? "warn";
|
|
77
|
+
const failureClass = opts.failureClass ?? "tool_recovery_failure";
|
|
78
|
+
let streak = 0;
|
|
79
|
+
return {
|
|
80
|
+
id: "error-streak",
|
|
81
|
+
get streak() {
|
|
82
|
+
return streak;
|
|
83
|
+
},
|
|
84
|
+
observe(event) {
|
|
85
|
+
if (event.status === void 0) return null;
|
|
86
|
+
streak = event.status === "error" ? streak + 1 : 0;
|
|
87
|
+
if (max <= 0 || streak < max) return null;
|
|
88
|
+
return {
|
|
89
|
+
detector: "error-streak",
|
|
90
|
+
severity,
|
|
91
|
+
failureClass,
|
|
92
|
+
reason: `stuck: ${streak} consecutive errored step(s)`,
|
|
93
|
+
streak,
|
|
94
|
+
...event.label ? { evidence: { lastError: event.label } } : {}
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
reset() {
|
|
98
|
+
streak = 0;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function observeAll(detectors, event) {
|
|
103
|
+
const signals = [];
|
|
104
|
+
for (const d of detectors) {
|
|
105
|
+
const s = d.observe(event);
|
|
106
|
+
if (s) signals.push(s);
|
|
107
|
+
}
|
|
108
|
+
return signals;
|
|
109
|
+
}
|
|
110
|
+
|
|
5
111
|
// src/control-runtime.ts
|
|
6
112
|
var DEFAULT_BUDGET = {
|
|
7
113
|
maxSteps: 8,
|
|
@@ -25,10 +131,13 @@ async function runAgentControlLoop(config) {
|
|
|
25
131
|
const emitter = config.store ? new TraceEmitter(config.store) : void 0;
|
|
26
132
|
let spentCostUsd = 0;
|
|
27
133
|
const runtimeErrors = [];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
134
|
+
const repeatedDetector = repeatedActionDetector({
|
|
135
|
+
maxRepeated: config.stopPolicies?.maxRepeatedActions ?? 0
|
|
136
|
+
});
|
|
137
|
+
const progressDetector = noProgressDetector({
|
|
138
|
+
maxNoProgress: config.stopPolicies?.maxNoProgressSteps ?? 0,
|
|
139
|
+
minScoreDelta: config.stopPolicies?.minScoreDelta ?? 1e-3
|
|
140
|
+
});
|
|
32
141
|
try {
|
|
33
142
|
if (emitter) {
|
|
34
143
|
await runTrace(
|
|
@@ -97,7 +206,10 @@ async function runAgentControlLoop(config) {
|
|
|
97
206
|
stoppedBy: "runtime-error"
|
|
98
207
|
});
|
|
99
208
|
}
|
|
100
|
-
|
|
209
|
+
progressDetector.observe({
|
|
210
|
+
stateFingerprint: fingerprintState(state, config.stopPolicies),
|
|
211
|
+
score: averageScore(evals)
|
|
212
|
+
});
|
|
101
213
|
for (let stepIndex = 0; stepIndex < budget.maxSteps; stepIndex++) {
|
|
102
214
|
if (controller.signal.aborted) {
|
|
103
215
|
return finish(emitter, {
|
|
@@ -229,18 +341,14 @@ async function runAgentControlLoop(config) {
|
|
|
229
341
|
});
|
|
230
342
|
}
|
|
231
343
|
const actionFingerprint = fingerprintAction(decision.action, config.stopPolicies);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
config.stopPolicies,
|
|
236
|
-
repeatedActionStreak
|
|
237
|
-
);
|
|
238
|
-
if (repeatedActionStop.stop) {
|
|
344
|
+
const repeatedActionSignal = repeatedDetector.observe({ actionFingerprint });
|
|
345
|
+
const repeatedActionStreak = repeatedDetector.streak;
|
|
346
|
+
if (repeatedActionSignal) {
|
|
239
347
|
return finish(emitter, {
|
|
240
348
|
intent: config.intent,
|
|
241
349
|
pass: false,
|
|
242
350
|
completed: true,
|
|
243
|
-
reason:
|
|
351
|
+
reason: repeatedActionSignal.reason,
|
|
244
352
|
score: averageScore(evals),
|
|
245
353
|
steps: history,
|
|
246
354
|
finalState: state,
|
|
@@ -435,16 +543,8 @@ async function runAgentControlLoop(config) {
|
|
|
435
543
|
}
|
|
436
544
|
const scoreAfter = averageScore(evals);
|
|
437
545
|
const stateFingerprint = fingerprintState(state, config.stopPolicies);
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
lastStateFingerprint,
|
|
441
|
-
stateFingerprint,
|
|
442
|
-
scoreBefore,
|
|
443
|
-
scoreAfter,
|
|
444
|
-
currentStreak: noProgressStreak
|
|
445
|
-
});
|
|
446
|
-
noProgressStreak = noProgressStop.streak;
|
|
447
|
-
lastStateFingerprint = stateFingerprint;
|
|
546
|
+
const noProgressSignal = progressDetector.observe({ stateFingerprint, score: scoreAfter });
|
|
547
|
+
const noProgressStreak = progressDetector.streak;
|
|
448
548
|
const step = {
|
|
449
549
|
index: stepIndex,
|
|
450
550
|
decision,
|
|
@@ -484,12 +584,12 @@ async function runAgentControlLoop(config) {
|
|
|
484
584
|
);
|
|
485
585
|
}
|
|
486
586
|
await runOnStep(config.onStep, step, runtimeErrors);
|
|
487
|
-
if (
|
|
587
|
+
if (noProgressSignal) {
|
|
488
588
|
return finish(emitter, {
|
|
489
589
|
intent: config.intent,
|
|
490
590
|
pass: false,
|
|
491
591
|
completed: true,
|
|
492
|
-
reason:
|
|
592
|
+
reason: noProgressSignal.reason,
|
|
493
593
|
score: scoreAfter,
|
|
494
594
|
steps: history,
|
|
495
595
|
finalState: state,
|
|
@@ -759,24 +859,6 @@ async function runTrace(runtimeErrors, stepIndex, write) {
|
|
|
759
859
|
return void 0;
|
|
760
860
|
}
|
|
761
861
|
}
|
|
762
|
-
function noProgressStopDecision(args) {
|
|
763
|
-
const max = args.policies?.maxNoProgressSteps;
|
|
764
|
-
if (!max || max <= 0) return { stop: false, reason: "", streak: 0 };
|
|
765
|
-
const minScoreDelta = args.policies?.minScoreDelta ?? 1e-3;
|
|
766
|
-
const scoreDelta = Math.abs((args.scoreAfter ?? 0) - (args.scoreBefore ?? 0));
|
|
767
|
-
const stateUnchanged = args.lastStateFingerprint !== void 0 && args.lastStateFingerprint === args.stateFingerprint;
|
|
768
|
-
const scoreFlat = scoreDelta < minScoreDelta;
|
|
769
|
-
const streak = stateUnchanged && scoreFlat ? args.currentStreak + 1 : 0;
|
|
770
|
-
return streak >= max ? { stop: true, reason: `stuck: no state/score progress for ${streak} step(s)`, streak } : { stop: false, reason: "", streak };
|
|
771
|
-
}
|
|
772
|
-
function repeatedActionStopDecision(policies, streak) {
|
|
773
|
-
const max = policies?.maxRepeatedActions;
|
|
774
|
-
if (!max || max <= 0 || streak < max) return { stop: false, reason: "" };
|
|
775
|
-
return {
|
|
776
|
-
stop: true,
|
|
777
|
-
reason: `stuck: repeated same action for ${streak} step(s)`
|
|
778
|
-
};
|
|
779
|
-
}
|
|
780
862
|
function fingerprintState(state, policies) {
|
|
781
863
|
if (policies?.stateFingerprint) return policies.stateFingerprint(state);
|
|
782
864
|
return stableFingerprint(state);
|
|
@@ -828,6 +910,10 @@ async function finish(emitter, result) {
|
|
|
828
910
|
}
|
|
829
911
|
|
|
830
912
|
export {
|
|
913
|
+
repeatedActionDetector,
|
|
914
|
+
noProgressDetector,
|
|
915
|
+
errorStreakDetector,
|
|
916
|
+
observeAll,
|
|
831
917
|
runAgentControlLoop,
|
|
832
918
|
stopOnNoProgress,
|
|
833
919
|
stopOnRepeatedAction,
|
|
@@ -835,4 +921,4 @@ export {
|
|
|
835
921
|
subjectiveEval,
|
|
836
922
|
allCriticalPassed
|
|
837
923
|
};
|
|
838
|
-
//# sourceMappingURL=chunk-
|
|
924
|
+
//# sourceMappingURL=chunk-YEHAEDUD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/detectors/index.ts","../src/control-runtime.ts"],"sourcesContent":["/**\n * Streaming detectors — the canonical, online failure-mode kernel.\n *\n * A `StreamingDetector` is a pure incremental reducer: fold one normalized step, get a signal the\n * moment a threshold trips (else null). The SAME kernel runs in two places, so the logic lives once:\n * - ONLINE, over a live agent pipe (a worker's tool-call stream) → raise a finding mid-run.\n * - INSIDE the control loop (`control-runtime`) → its `stopOn*` policies fold these detectors.\n *\n * Detectors are stateful but self-contained; `streak` is exposed for telemetry and `reset` clears it.\n * Fingerprinting is the CALLER's job — the control loop hashes state/action with `stableFingerprint`,\n * a tool-call pipe hashes args with `argHash` — so a detector stays agnostic to what it's watching.\n */\n\nimport type { FailureClass } from '../trace/schema'\n\nexport type DetectorSeverity = 'info' | 'warn' | 'critical'\n\n/** A normalized step a detector folds over. Fields are optional; each detector reads only what it\n * needs (repeated-action → `actionFingerprint`; no-progress → `stateFingerprint` + `score`;\n * error-streak → `status`). */\nexport interface DetectorEvent {\n /** Fingerprint of the action/tool-call this step took (caller pre-hashes). */\n readonly actionFingerprint?: string\n /** Fingerprint of observable state AFTER this step. */\n readonly stateFingerprint?: string\n /** Score after this step (the score-flat half of no-progress). */\n readonly score?: number\n /** Whether this step errored. */\n readonly status?: 'ok' | 'error'\n /** Free-form label carried into the signal evidence (e.g. the tool name). */\n readonly label?: string\n}\n\nexport interface DetectorSignal {\n readonly detector: string\n readonly severity: DetectorSeverity\n readonly failureClass?: FailureClass\n readonly reason: string\n /** Consecutive matching steps at the moment the signal fired. */\n readonly streak: number\n readonly evidence?: Record<string, unknown>\n}\n\nexport interface StreamingDetector {\n readonly id: string\n /** Current streak (consecutive matching steps) — for telemetry/introspection between observes. */\n readonly streak: number\n /** Fold one event; return a signal when the threshold trips, else null. */\n observe(event: DetectorEvent): DetectorSignal | null\n /** Clear all state. */\n reset(): void\n}\n\nexport interface RepeatedActionOptions {\n /** Signal once the same action fingerprint repeats this many CONSECUTIVE steps (default 3).\n * `<= 0` disables the signal (the streak is still tracked, for telemetry). */\n readonly maxRepeated?: number\n readonly severity?: DetectorSeverity\n /** Failure class to stamp on the signal (default `tool_recovery_failure`). */\n readonly failureClass?: FailureClass\n}\n\n/** Same action fingerprint N consecutive steps = a stuck loop (the #1 long-horizon failure mode). */\nexport function repeatedActionDetector(opts: RepeatedActionOptions = {}): StreamingDetector {\n const max = opts.maxRepeated ?? 3\n const severity = opts.severity ?? 'warn'\n const failureClass: FailureClass = opts.failureClass ?? 'tool_recovery_failure'\n let last: string | undefined\n let streak = 0\n return {\n id: 'repeated-action',\n get streak() {\n return streak\n },\n observe(event) {\n const fp = event.actionFingerprint\n if (fp === undefined) return null\n streak = fp === last ? streak + 1 : 1\n last = fp\n if (max <= 0 || streak < max) return null\n return {\n detector: 'repeated-action',\n severity,\n failureClass,\n reason: `stuck: repeated same action for ${streak} step(s)`,\n streak,\n ...(event.label ? { evidence: { action: event.label } } : {}),\n }\n },\n reset() {\n last = undefined\n streak = 0\n },\n }\n}\n\nexport interface NoProgressOptions {\n /** Signal once state is unchanged AND score is flat for this many CONSECUTIVE steps (default 3).\n * `<= 0` disables the signal. */\n readonly maxNoProgress?: number\n /** Minimum |score change| that counts as progress (default 0.001). */\n readonly minScoreDelta?: number\n readonly severity?: DetectorSeverity\n readonly failureClass?: FailureClass\n}\n\n/** State + score unchanged across N steps = spinning wheels. Compares each step to the previous one,\n * so prime with the initial state (observe it once before the first real step) to detect on step 1. */\nexport function noProgressDetector(opts: NoProgressOptions = {}): StreamingDetector {\n const max = opts.maxNoProgress ?? 3\n const minScoreDelta = opts.minScoreDelta ?? 0.001\n const severity = opts.severity ?? 'warn'\n const failureClass: FailureClass = opts.failureClass ?? 'tool_recovery_failure'\n let lastState: string | undefined\n let lastScore: number | undefined\n let streak = 0\n return {\n id: 'no-progress',\n get streak() {\n return streak\n },\n observe(event) {\n const stateUnchanged = lastState !== undefined && lastState === event.stateFingerprint\n const scoreFlat = Math.abs((event.score ?? 0) - (lastScore ?? 0)) < minScoreDelta\n streak = stateUnchanged && scoreFlat ? streak + 1 : 0\n lastState = event.stateFingerprint\n lastScore = event.score\n if (max <= 0 || streak < max) return null\n return {\n detector: 'no-progress',\n severity,\n failureClass,\n reason: `stuck: no state/score progress for ${streak} step(s)`,\n streak,\n ...(event.label ? { evidence: { state: event.label } } : {}),\n }\n },\n reset() {\n lastState = undefined\n lastScore = undefined\n streak = 0\n },\n }\n}\n\nexport interface ErrorStreakOptions {\n /** Signal once this many CONSECUTIVE steps errored (default 3). `<= 0` disables. */\n readonly maxErrors?: number\n readonly severity?: DetectorSeverity\n readonly failureClass?: FailureClass\n}\n\n/** N consecutive tool errors = the worker is hammering a broken approach. */\nexport function errorStreakDetector(opts: ErrorStreakOptions = {}): StreamingDetector {\n const max = opts.maxErrors ?? 3\n const severity = opts.severity ?? 'warn'\n const failureClass: FailureClass = opts.failureClass ?? 'tool_recovery_failure'\n let streak = 0\n return {\n id: 'error-streak',\n get streak() {\n return streak\n },\n observe(event) {\n if (event.status === undefined) return null\n streak = event.status === 'error' ? streak + 1 : 0\n if (max <= 0 || streak < max) return null\n return {\n detector: 'error-streak',\n severity,\n failureClass,\n reason: `stuck: ${streak} consecutive errored step(s)`,\n streak,\n ...(event.label ? { evidence: { lastError: event.label } } : {}),\n }\n },\n reset() {\n streak = 0\n },\n }\n}\n\n/** Fold one event through many detectors at once; returns every signal that fired this step. The\n * natural shape for an online pipe watching with a whole panel of detectors. */\nexport function observeAll(\n detectors: ReadonlyArray<StreamingDetector>,\n event: DetectorEvent,\n): DetectorSignal[] {\n const signals: DetectorSignal[] = []\n for (const d of detectors) {\n const s = d.observe(event)\n if (s) signals.push(s)\n }\n return signals\n}\n","/**\n * Policy-based agent control runtime.\n *\n * This is the minimal reusable loop behind driver-agent patterns:\n *\n * observe state -> validate -> decide next action -> act -> observe -> ...\n *\n * It deliberately does not model named \"topologies\". Direct execution,\n * critic/revise, driver intervention, specialist calls, and human escalation\n * are all just actions chosen by the control policy.\n */\n\nimport { noProgressDetector, repeatedActionDetector } from './detectors'\nimport { type SpanHandle, TraceEmitter } from './trace/emitter'\nimport type { FailureClass } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport type ControlSeverity = 'info' | 'warning' | 'error' | 'critical'\nexport type ControlActionFailureMode = 'continue' | 'stop'\n\nexport interface ControlEvalResult {\n /** Stable validator or judge id. */\n id: string\n /** Whether this check passed. */\n passed: boolean\n /** Optional normalized score. 1 = best, 0 = worst. */\n score?: number\n /** Objective validators should usually be \"error\" or \"critical\" when failed. */\n severity?: ControlSeverity\n /** Human-readable result. */\n detail?: string\n /** Small evidence string or pointer. Avoid large payloads. */\n evidence?: string\n /** True when the result came from deterministic state, not LLM judgment. */\n objective?: boolean\n /** Structured details for downstream control policies and reports. */\n metadata?: Record<string, unknown>\n}\n\nexport interface ControlBudget {\n maxSteps: number\n maxWallMs?: number\n maxCostUsd?: number\n}\n\nexport interface ControlStopPolicies<TState, TAction> {\n /**\n * Stop after N consecutive steps with no state fingerprint change and\n * less than `minScoreDelta` score movement. Disabled when omitted.\n */\n maxNoProgressSteps?: number\n /**\n * Stop after the same action fingerprint is selected N consecutive\n * times. Disabled when omitted.\n */\n maxRepeatedActions?: number\n /** Minimum score movement that counts as progress. Default 0.001. */\n minScoreDelta?: number\n /** Override the default JSON/string fingerprint for state comparisons. */\n stateFingerprint?: (state: TState) => string\n /** Override the default JSON/string fingerprint for repeated-action checks. */\n actionFingerprint?: (action: TAction) => string\n}\n\nexport interface ControlContext<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n intent: string\n state: TState\n evals: TEval[]\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n budget: ControlBudget\n stepIndex: number\n wallMs: number\n spentCostUsd: number\n remainingCostUsd?: number\n abortSignal: AbortSignal\n emitter?: TraceEmitter\n}\n\nexport type ControlDecision<TAction> =\n | {\n type: 'continue'\n action: TAction\n reason?: string\n }\n | {\n type: 'stop'\n reason: string\n pass?: boolean\n score?: number\n }\n\nexport interface StopDecision {\n stop: boolean\n pass: boolean\n reason: string\n score?: number\n failureClass?: FailureClass\n}\n\nexport interface ControlActionOutcome<TActionResult> {\n ok: boolean\n result?: TActionResult\n error?: string\n costUsd?: number\n durationMs: number\n}\n\nexport interface ControlRuntimeError {\n phase: 'observe' | 'validate' | 'decide' | 'act' | 'stop-policy' | 'on-step' | 'trace'\n stepIndex: number\n message: string\n}\n\nexport interface ControlStep<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n index: number\n decision: ControlDecision<TAction>\n beforeState: TState\n afterState: TState\n evalsBefore: TEval[]\n evalsAfter: TEval[]\n actionOutcome?: ControlActionOutcome<TActionResult>\n startedAt: string\n endedAt: string\n}\n\nexport interface ControlRunResult<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n intent: string\n pass: boolean\n completed: boolean\n reason: string\n score?: number\n steps: ControlStep<TState, TAction, TActionResult, TEval>[]\n finalState: TState | undefined\n finalEvals: TEval[]\n wallMs: number\n spentCostUsd: number\n /** null when the run executed without a TraceEmitter wired (no run record was persisted). */\n runId: string | null\n failureClass?: FailureClass\n runtimeErrors: ControlRuntimeError[]\n stoppedBy: 'policy' | 'stop-policy' | 'budget' | 'abort' | 'runtime-error'\n}\n\nexport interface ControlRuntimeConfig<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n intent: string\n budget?: Partial<ControlBudget>\n signal?: AbortSignal\n /** Defaults to `continue`: action failures are recorded, then the policy gets another chance. */\n actionFailure?: ControlActionFailureMode\n /**\n * Extract cost from an action result. Used for `maxCostUsd` budget\n * enforcement and trace budget ledger emission.\n */\n getActionCostUsd?: (ctx: {\n action: TAction\n result: TActionResult\n state: TState\n evals: TEval[]\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n }) => number | undefined\n\n /** Read typed task/product state. Prefer structured state over transcript-only context. */\n observe: (ctx: {\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n abortSignal: AbortSignal\n }) => Promise<TState> | TState\n\n /** Objective validators first, subjective judges only where objective state is insufficient. */\n validate: (ctx: {\n intent: string\n state: TState\n history: ControlStep<TState, TAction, TActionResult, TEval>[]\n abortSignal: AbortSignal\n }) => Promise<TEval[]> | TEval[]\n\n /** Choose the next control action. Can call a worker, ask user, run critic, inspect state, or stop. */\n decide: (\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n ) => Promise<ControlDecision<TAction>> | ControlDecision<TAction>\n\n /** Execute the action selected by the policy. */\n act: (\n action: TAction,\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n ) => Promise<TActionResult> | TActionResult\n\n /** Final stopping policy. Called before decide and after each action. */\n shouldStop?: (\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n ) => Promise<StopDecision> | StopDecision\n\n /** Optional hook for tracing or live progress updates. */\n onStep?: (step: ControlStep<TState, TAction, TActionResult, TEval>) => Promise<void> | void\n\n /** Optional generic stuck-loop policies. Custom `shouldStop` still runs first. */\n stopPolicies?: ControlStopPolicies<TState, TAction>\n\n /** Optional trace sink. Emits one run plus one span per control step. */\n store?: TraceStore\n scenarioId?: string\n projectId?: string\n variantId?: string\n}\n\nconst DEFAULT_BUDGET: ControlBudget = {\n maxSteps: 8,\n maxWallMs: 5 * 60 * 1000,\n}\n\nexport async function runAgentControlLoop<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n config: ControlRuntimeConfig<TState, TAction, TActionResult, TEval>,\n): Promise<ControlRunResult<TState, TAction, TActionResult, TEval>> {\n const budget = normalizeBudget(config.budget)\n const actionFailure = config.actionFailure ?? 'continue'\n const controller = new AbortController()\n const upstreamAbort = () => controller.abort(config.signal?.reason)\n if (config.signal) {\n if (config.signal.aborted) controller.abort(config.signal.reason)\n else config.signal.addEventListener('abort', upstreamAbort, { once: true })\n }\n\n const started = Date.now()\n const wallTimer = budget.maxWallMs\n ? setTimeout(\n () => controller.abort(new Error('control runtime wall timeout')),\n budget.maxWallMs,\n )\n : undefined\n const history: ControlStep<TState, TAction, TActionResult, TEval>[] = []\n const emitter = config.store ? new TraceEmitter(config.store) : undefined\n let spentCostUsd = 0\n const runtimeErrors: ControlRuntimeError[] = []\n // The stuck-detection kernels (shared with the online detectors). Thresholds 0 = disabled; the\n // streak is still tracked for telemetry. Both stops report `tool_recovery_failure`.\n const repeatedDetector = repeatedActionDetector({\n maxRepeated: config.stopPolicies?.maxRepeatedActions ?? 0,\n })\n const progressDetector = noProgressDetector({\n maxNoProgress: config.stopPolicies?.maxNoProgressSteps ?? 0,\n minScoreDelta: config.stopPolicies?.minScoreDelta ?? 0.001,\n })\n\n try {\n if (emitter) {\n await runTrace(runtimeErrors, 0, () =>\n emitter.startRun({\n scenarioId: config.scenarioId ?? 'agent-control-loop',\n projectId: config.projectId,\n variantId: config.variantId,\n layer: 'meta',\n tags: {\n intent: config.intent.slice(0, 120),\n maxSteps: String(budget.maxSteps),\n ...(budget.maxCostUsd !== undefined ? { maxCostUsd: String(budget.maxCostUsd) } : {}),\n },\n }),\n )\n }\n\n let state: TState\n let evals: TEval[]\n try {\n state = await config.observe({ history, abortSignal: controller.signal })\n } catch (err) {\n const error = runtimeError('observe', 0, err)\n runtimeErrors.push(error)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: error.message,\n steps: history,\n finalState: undefined,\n finalEvals: [],\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n try {\n evals = await config.validate({\n intent: config.intent,\n state,\n history,\n abortSignal: controller.signal,\n })\n await recordEvalSpans(emitter, evals, 'initial', runtimeErrors, 0)\n } catch (err) {\n const error = runtimeError('validate', 0, err)\n runtimeErrors.push(error)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: error.message,\n steps: history,\n finalState: state,\n finalEvals: [],\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n // Prime the no-progress detector with the initial state + score so step 0 can already detect a\n // no-op (mirrors the pre-loop fingerprint baseline). The priming observe never signals (streak 0).\n progressDetector.observe({\n stateFingerprint: fingerprintState(state, config.stopPolicies),\n score: averageScore(evals),\n })\n\n for (let stepIndex = 0; stepIndex < budget.maxSteps; stepIndex++) {\n if (controller.signal.aborted) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: abortReason(controller.signal),\n score: undefined,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'timeout',\n runtimeErrors,\n stoppedBy: 'abort',\n })\n }\n\n const budgetStop = budgetStopDecision(budget, spentCostUsd)\n if (budgetStop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: budgetStop.reason,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'budget_exceeded',\n runtimeErrors,\n stoppedBy: 'budget',\n })\n }\n\n const ctx = makeContext(\n config.intent,\n state,\n evals,\n history,\n budget,\n stepIndex,\n started,\n spentCostUsd,\n controller.signal,\n emitter,\n )\n let stop: StopDecision\n try {\n stop = config.shouldStop ? await config.shouldStop(ctx) : defaultStopDecision(evals)\n } catch (err) {\n runtimeErrors.push(runtimeError('stop-policy', stepIndex, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n if (stop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: stop.pass,\n completed: true,\n reason: stop.reason,\n score: stop.score,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: stop.failureClass,\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n\n let decision: ControlDecision<TAction>\n try {\n decision = await config.decide(ctx)\n } catch (err) {\n runtimeErrors.push(runtimeError('decide', stepIndex, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n if (decision.type === 'stop') {\n return finish(emitter, {\n intent: config.intent,\n pass: decision.pass ?? false,\n completed: true,\n reason: decision.reason,\n score: decision.score,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: decision.pass === false ? 'unknown' : undefined,\n runtimeErrors,\n stoppedBy: 'policy',\n })\n }\n\n const actionFingerprint = fingerprintAction(decision.action, config.stopPolicies)\n const repeatedActionSignal = repeatedDetector.observe({ actionFingerprint })\n const repeatedActionStreak = repeatedDetector.streak\n if (repeatedActionSignal) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: true,\n reason: repeatedActionSignal.reason,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'tool_recovery_failure',\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n\n const beforeState = state\n const evalsBefore = evals\n const scoreBefore = averageScore(evals)\n const actionStarted = Date.now()\n const stepHandle = emitter\n ? await runTrace(runtimeErrors, stepIndex, () =>\n emitter.tool({\n name: `control-step-${stepIndex}`,\n toolName: 'agent-control-action',\n args: decision.action,\n attributes: {\n decision: decision.reason ?? 'continue',\n repeatedActionStreak,\n },\n }),\n )\n : undefined\n let actionOutcome: ControlActionOutcome<TActionResult>\n try {\n const result = await config.act(decision.action, ctx)\n const rawCostUsd = config.getActionCostUsd?.({\n action: decision.action,\n result,\n state,\n evals,\n history,\n })\n const costUsd = normalizeActionCostUsd(rawCostUsd, runtimeErrors, stepIndex)\n if (costUsd !== undefined && Number.isFinite(costUsd) && costUsd > 0) {\n spentCostUsd += costUsd\n await recordCostBudget(\n emitter,\n budget,\n spentCostUsd,\n stepHandle,\n runtimeErrors,\n stepIndex,\n )\n }\n actionOutcome = {\n ok: true,\n result,\n ...(costUsd !== undefined ? { costUsd } : {}),\n durationMs: Date.now() - actionStarted,\n }\n } catch (err) {\n runtimeErrors.push(runtimeError('act', stepIndex, err))\n actionOutcome = {\n ok: false,\n error: runtimeErrors[runtimeErrors.length - 1]!.message,\n durationMs: Date.now() - actionStarted,\n }\n if (actionFailure === 'stop') {\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(actionOutcome.error ?? 'action failed'),\n )\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: state,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n await runOnStep(config.onStep, step, runtimeErrors)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: actionOutcome.error ?? 'action failed',\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n }\n\n try {\n state = await config.observe({ history, abortSignal: controller.signal })\n } catch (err) {\n runtimeErrors.push(runtimeError('observe', stepIndex, err))\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: beforeState,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(runtimeErrors[runtimeErrors.length - 1]!.message),\n )\n await runOnStep(config.onStep, step, runtimeErrors)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: beforeState,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n try {\n evals = await config.validate({\n intent: config.intent,\n state,\n history,\n abortSignal: controller.signal,\n })\n await recordEvalSpans(\n emitter,\n evals,\n `step-${stepIndex}`,\n runtimeErrors,\n stepIndex,\n stepHandle?.span.spanId,\n )\n } catch (err) {\n runtimeErrors.push(runtimeError('validate', stepIndex, err))\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: state,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(runtimeErrors[runtimeErrors.length - 1]!.message),\n )\n await runOnStep(config.onStep, step, runtimeErrors)\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n const scoreAfter = averageScore(evals)\n const stateFingerprint = fingerprintState(state, config.stopPolicies)\n const noProgressSignal = progressDetector.observe({ stateFingerprint, score: scoreAfter })\n const noProgressStreak = progressDetector.streak\n\n const step: ControlStep<TState, TAction, TActionResult, TEval> = {\n index: stepIndex,\n decision,\n beforeState,\n afterState: state,\n evalsBefore,\n evalsAfter: evals,\n actionOutcome,\n startedAt: new Date(actionStarted).toISOString(),\n endedAt: new Date().toISOString(),\n }\n history.push(step)\n if (actionOutcome.ok) {\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.end({\n attributes: {\n actionCostUsd: actionOutcome.costUsd ?? null,\n spentCostUsd,\n scoreBefore: scoreBefore ?? null,\n scoreAfter: scoreAfter ?? null,\n noProgressStreak,\n },\n }),\n )\n } else {\n await runTrace(runtimeErrors, stepIndex, () =>\n stepHandle?.fail(actionOutcome.error ?? 'action failed', {\n attributes: {\n spentCostUsd,\n noProgressStreak,\n },\n }),\n )\n }\n await runOnStep(config.onStep, step, runtimeErrors)\n\n if (noProgressSignal) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: true,\n reason: noProgressSignal.reason,\n score: scoreAfter,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'tool_recovery_failure',\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n\n const postStepBudgetStop = budgetStopDecision(budget, spentCostUsd)\n if (postStepBudgetStop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: postStepBudgetStop.reason,\n score: scoreAfter,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'budget_exceeded',\n runtimeErrors,\n stoppedBy: 'budget',\n })\n }\n\n const postStepCtx = makeContext(\n config.intent,\n state,\n evals,\n history,\n budget,\n stepIndex + 1,\n started,\n spentCostUsd,\n controller.signal,\n emitter,\n )\n let postStepStop: StopDecision\n try {\n postStepStop = config.shouldStop\n ? await config.shouldStop(postStepCtx)\n : defaultStopDecision(evals)\n } catch (err) {\n runtimeErrors.push(runtimeError('stop-policy', stepIndex + 1, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n score: averageScore(evals),\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n }\n if (postStepStop.stop) {\n return finish(emitter, {\n intent: config.intent,\n pass: postStepStop.pass,\n completed: true,\n reason: postStepStop.reason,\n score: postStepStop.score,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: postStepStop.failureClass,\n runtimeErrors,\n stoppedBy: 'stop-policy',\n })\n }\n }\n\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: `budget exhausted: maxSteps=${budget.maxSteps}`,\n steps: history,\n finalState: state,\n finalEvals: evals,\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'budget_exceeded',\n runtimeErrors,\n stoppedBy: 'budget',\n })\n } catch (err) {\n runtimeErrors.push(runtimeError('act', history.length, err))\n return finish(emitter, {\n intent: config.intent,\n pass: false,\n completed: false,\n reason: runtimeErrors[runtimeErrors.length - 1]!.message,\n steps: history,\n finalState: undefined,\n finalEvals: [],\n wallMs: Date.now() - started,\n spentCostUsd,\n runId: emitter?.runId ?? null,\n failureClass: 'unknown',\n runtimeErrors,\n stoppedBy: 'runtime-error',\n })\n } finally {\n if (wallTimer) clearTimeout(wallTimer)\n if (config.signal) config.signal.removeEventListener('abort', upstreamAbort)\n }\n}\n\nexport function stopOnNoProgress<TState, TAction>(\n maxNoProgressSteps: number,\n options: Omit<ControlStopPolicies<TState, TAction>, 'maxNoProgressSteps'> = {},\n): ControlStopPolicies<TState, TAction> {\n return { ...options, maxNoProgressSteps }\n}\n\nexport function stopOnRepeatedAction<TState, TAction>(\n maxRepeatedActions: number,\n options: Omit<ControlStopPolicies<TState, TAction>, 'maxRepeatedActions'> = {},\n): ControlStopPolicies<TState, TAction> {\n return { ...options, maxRepeatedActions }\n}\n\nexport function objectiveEval(input: Omit<ControlEvalResult, 'objective'>): ControlEvalResult {\n return { ...input, objective: true }\n}\n\nexport function subjectiveEval(input: Omit<ControlEvalResult, 'objective'>): ControlEvalResult {\n return { ...input, objective: false }\n}\n\nfunction normalizeBudget(input: Partial<ControlBudget> | undefined): ControlBudget {\n const raw = { ...DEFAULT_BUDGET, ...input } as Record<string, unknown>\n if (!Number.isInteger(raw.maxSteps) || (raw.maxSteps as number) < 1) {\n throw new RangeError(\n `ControlRuntime budget.maxSteps must be an integer >= 1, got ${String(raw.maxSteps)}`,\n )\n }\n const budget: ControlBudget = { maxSteps: raw.maxSteps as number }\n if (raw.maxWallMs !== undefined) {\n if (\n typeof raw.maxWallMs !== 'number' ||\n !Number.isFinite(raw.maxWallMs) ||\n raw.maxWallMs <= 0\n ) {\n throw new RangeError(\n `ControlRuntime budget.maxWallMs must be a positive finite number, got ${String(raw.maxWallMs)}`,\n )\n }\n budget.maxWallMs = raw.maxWallMs\n }\n if (raw.maxCostUsd !== undefined) {\n if (\n typeof raw.maxCostUsd !== 'number' ||\n !Number.isFinite(raw.maxCostUsd) ||\n raw.maxCostUsd < 0\n ) {\n throw new RangeError(\n `ControlRuntime budget.maxCostUsd must be a nonnegative finite number, got ${String(raw.maxCostUsd)}`,\n )\n }\n budget.maxCostUsd = raw.maxCostUsd\n }\n return budget\n}\n\nfunction normalizeActionCostUsd(\n costUsd: number | undefined,\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n): number | undefined {\n if (costUsd === undefined) return undefined\n if (!Number.isFinite(costUsd) || costUsd < 0) {\n runtimeErrors.push(\n runtimeError('act', stepIndex, new Error(`invalid action costUsd: ${String(costUsd)}`)),\n )\n return undefined\n }\n return costUsd\n}\n\nexport function allCriticalPassed(evals: ControlEvalResult[]): boolean {\n return evals.every(\n (result) => result.passed || (result.severity !== 'critical' && result.severity !== 'error'),\n )\n}\n\nfunction makeContext<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n intent: string,\n state: TState,\n evals: TEval[],\n history: ControlStep<TState, TAction, TActionResult, TEval>[],\n budget: ControlBudget,\n stepIndex: number,\n started: number,\n spentCostUsd: number,\n abortSignal: AbortSignal,\n emitter?: TraceEmitter,\n): ControlContext<TState, TAction, TActionResult, TEval> {\n return {\n intent,\n state,\n evals,\n history,\n budget,\n stepIndex,\n wallMs: Date.now() - started,\n spentCostUsd,\n remainingCostUsd:\n budget.maxCostUsd === undefined ? undefined : Math.max(0, budget.maxCostUsd - spentCostUsd),\n abortSignal,\n emitter,\n }\n}\n\nfunction defaultStopDecision(evals: ControlEvalResult[]): StopDecision {\n if (!evals.length) return { stop: false, pass: false, reason: 'no evals yet' }\n const pass = allCriticalPassed(evals)\n return pass\n ? { stop: true, pass: true, reason: 'all critical evals passed', score: averageScore(evals) }\n : {\n stop: false,\n pass: false,\n reason: 'critical evals still failing',\n score: averageScore(evals),\n }\n}\n\nfunction averageScore(evals: ControlEvalResult[]): number | undefined {\n const scored = evals\n .map((result) => result.score)\n .filter((score): score is number => typeof score === 'number')\n if (!scored.length) return undefined\n return Math.round((scored.reduce((sum, score) => sum + score, 0) / scored.length) * 1000) / 1000\n}\n\nfunction budgetStopDecision(\n budget: ControlBudget,\n spentCostUsd: number,\n): { stop: boolean; reason: string } {\n if (budget.maxCostUsd !== undefined && spentCostUsd >= budget.maxCostUsd) {\n return {\n stop: true,\n reason: `budget exhausted: maxCostUsd=${budget.maxCostUsd}`,\n }\n }\n return { stop: false, reason: '' }\n}\n\nasync function recordCostBudget(\n emitter: TraceEmitter | undefined,\n budget: ControlBudget,\n spentCostUsd: number,\n handle: SpanHandle | undefined,\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n): Promise<void> {\n if (!emitter || budget.maxCostUsd === undefined) return\n const maxCostUsd = budget.maxCostUsd\n await runTrace(runtimeErrors, stepIndex, () =>\n emitter.recordBudget({\n dimension: 'usd',\n limit: maxCostUsd,\n consumed: spentCostUsd,\n remaining: Math.max(0, maxCostUsd - spentCostUsd),\n breached: spentCostUsd >= maxCostUsd,\n spanId: handle?.span.spanId,\n }),\n )\n}\n\nasync function recordEvalSpans(\n emitter: TraceEmitter | undefined,\n evals: ControlEvalResult[],\n phase: string,\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n targetSpanId?: string,\n): Promise<void> {\n if (!emitter) return\n for (const result of evals) {\n await runTrace(runtimeErrors, stepIndex, () =>\n emitter.recordJudge({\n judgeId: result.objective ? 'objective-validator' : 'subjective-judge',\n targetSpanId: targetSpanId ?? emitter.runId,\n name: `control-eval/${result.id}`,\n dimension: result.id,\n score: typeof result.score === 'number' ? result.score : result.passed ? 1 : 0,\n rationale: result.detail,\n evidence: result.evidence,\n attributes: {\n phase,\n passed: result.passed,\n severity: result.severity,\n objective: result.objective,\n },\n }),\n )\n }\n}\n\nasync function runOnStep<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n onStep: ControlRuntimeConfig<TState, TAction, TActionResult, TEval>['onStep'] | undefined,\n step: ControlStep<TState, TAction, TActionResult, TEval>,\n runtimeErrors: ControlRuntimeError[],\n): Promise<void> {\n if (!onStep) return\n try {\n await onStep(step)\n } catch (err) {\n runtimeErrors.push(runtimeError('on-step', step.index, err))\n }\n}\n\nasync function runTrace<T>(\n runtimeErrors: ControlRuntimeError[],\n stepIndex: number,\n write: () => Promise<T | undefined> | T | undefined,\n): Promise<T | undefined> {\n try {\n return await write()\n } catch (err) {\n runtimeErrors.push(runtimeError('trace', stepIndex, err))\n return undefined\n }\n}\n\nfunction fingerprintState<TState, TAction>(\n state: TState,\n policies?: ControlStopPolicies<TState, TAction>,\n): string {\n if (policies?.stateFingerprint) return policies.stateFingerprint(state)\n return stableFingerprint(state)\n}\n\nfunction fingerprintAction<TState, TAction>(\n action: TAction,\n policies?: ControlStopPolicies<TState, TAction>,\n): string {\n if (policies?.actionFingerprint) return policies.actionFingerprint(action)\n return stableFingerprint(action)\n}\n\nfunction stableFingerprint(value: unknown): string {\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean' || value == null) return String(value)\n try {\n return JSON.stringify(sortForFingerprint(value))\n } catch {\n return String(value)\n }\n}\n\nfunction sortForFingerprint(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortForFingerprint)\n if (!value || typeof value !== 'object') return value\n const record = value as Record<string, unknown>\n const sorted: Record<string, unknown> = {}\n for (const key of Object.keys(record).sort()) {\n sorted[key] = sortForFingerprint(record[key])\n }\n return sorted\n}\n\nfunction abortReason(signal: AbortSignal): string {\n const reason = signal.reason\n if (reason instanceof Error) return reason.message\n return reason ? String(reason) : 'aborted'\n}\n\nfunction runtimeError(\n phase: ControlRuntimeError['phase'],\n stepIndex: number,\n err: unknown,\n): ControlRuntimeError {\n const message = err instanceof Error ? err.message : String(err)\n return { phase, stepIndex, message }\n}\n\nasync function finish<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n emitter: TraceEmitter | undefined,\n result: ControlRunResult<TState, TAction, TActionResult, TEval>,\n): Promise<ControlRunResult<TState, TAction, TActionResult, TEval>> {\n await runTrace(result.runtimeErrors, result.steps.length, () =>\n emitter?.endRun({\n pass: result.pass,\n score: result.score ?? averageScore(result.finalEvals),\n failureClass: result.failureClass,\n notes: result.reason,\n }),\n )\n return result\n}\n"],"mappings":"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","names":["step"]}
|
|
@@ -67,48 +67,101 @@ var SubprocessSandboxDriver = class {
|
|
|
67
67
|
const start = Date.now();
|
|
68
68
|
const effectiveCwd = config.cwd ?? this.defaultCwd;
|
|
69
69
|
const effectiveEnv = { ...process.env, ...this.defaultEnv ?? {}, ...config.env ?? {} };
|
|
70
|
+
const maxOutputBytes = config.maxOutputBytes ?? 16 * 1024 * 1024;
|
|
70
71
|
return await new Promise((resolve) => {
|
|
71
72
|
const child = spawn(command, {
|
|
72
73
|
shell: true,
|
|
73
74
|
cwd: effectiveCwd,
|
|
74
|
-
env: effectiveEnv
|
|
75
|
+
env: effectiveEnv,
|
|
76
|
+
// Own process group so a timeout can SIGKILL the whole tree, not
|
|
77
|
+
// just the shell — otherwise a runaway grandchild keeps the pipes
|
|
78
|
+
// open and `close` never fires (the timeout silently does nothing).
|
|
79
|
+
detached: process.platform !== "win32"
|
|
75
80
|
});
|
|
76
81
|
let stdout = "";
|
|
77
82
|
let stderr = "";
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
let outputBytes = 0;
|
|
84
|
+
let outputTruncated = false;
|
|
85
|
+
let killedByTimeout = false;
|
|
86
|
+
let settled = false;
|
|
87
|
+
const onStdout = (d) => {
|
|
88
|
+
const chunk = capture(String(d));
|
|
89
|
+
if (chunk) stdout += chunk;
|
|
90
|
+
};
|
|
91
|
+
const onStderr = (d) => {
|
|
92
|
+
const chunk = capture(String(d));
|
|
93
|
+
if (chunk) stderr += chunk;
|
|
94
|
+
};
|
|
95
|
+
function capture(s) {
|
|
96
|
+
if (outputBytes >= maxOutputBytes) {
|
|
97
|
+
outputTruncated = true;
|
|
98
|
+
return "";
|
|
99
|
+
}
|
|
100
|
+
const room = maxOutputBytes - outputBytes;
|
|
101
|
+
if (s.length > room) {
|
|
102
|
+
outputBytes = maxOutputBytes;
|
|
103
|
+
outputTruncated = true;
|
|
104
|
+
return s.slice(0, room);
|
|
105
|
+
}
|
|
106
|
+
outputBytes += s.length;
|
|
107
|
+
return s;
|
|
108
|
+
}
|
|
109
|
+
child.stdout?.on("data", onStdout);
|
|
110
|
+
child.stderr?.on("data", onStderr);
|
|
111
|
+
const cleanup = () => {
|
|
95
112
|
clearTimeout(timeout);
|
|
113
|
+
if (forceResolve) clearTimeout(forceResolve);
|
|
114
|
+
child.stdout?.off("data", onStdout);
|
|
115
|
+
child.stderr?.off("data", onStderr);
|
|
116
|
+
child.removeAllListeners("close");
|
|
117
|
+
child.removeAllListeners("error");
|
|
118
|
+
};
|
|
119
|
+
const finish = (outcome) => {
|
|
120
|
+
if (settled) return;
|
|
121
|
+
settled = true;
|
|
122
|
+
cleanup();
|
|
96
123
|
const wallMs = Date.now() - start;
|
|
97
|
-
const
|
|
124
|
+
const exitCode = killedByTimeout ? outcome.code && outcome.code !== 0 ? outcome.code : 124 : outcome.code ?? 1;
|
|
125
|
+
const parsed = !killedByTimeout && phase === "test" && config.testParser ? config.testParser.parse(stdout, stderr, exitCode) : void 0;
|
|
98
126
|
resolve({
|
|
99
127
|
phase,
|
|
100
|
-
exitCode
|
|
128
|
+
exitCode,
|
|
101
129
|
stdout,
|
|
102
|
-
stderr,
|
|
130
|
+
stderr: outcome.runnerError ? stderr + outcome.runnerError : stderr,
|
|
103
131
|
wallMs,
|
|
104
132
|
testsTotal: parsed?.testsTotal,
|
|
105
|
-
testsPassed: parsed?.testsPassed
|
|
133
|
+
testsPassed: parsed?.testsPassed,
|
|
134
|
+
killedByTimeout: killedByTimeout || void 0,
|
|
135
|
+
outputTruncated: outputTruncated || void 0
|
|
106
136
|
});
|
|
137
|
+
};
|
|
138
|
+
const killTree = () => {
|
|
139
|
+
try {
|
|
140
|
+
if (process.platform !== "win32" && typeof child.pid === "number") {
|
|
141
|
+
process.kill(-child.pid, "SIGKILL");
|
|
142
|
+
} else {
|
|
143
|
+
child.kill("SIGKILL");
|
|
144
|
+
}
|
|
145
|
+
} catch (err) {
|
|
146
|
+
console.warn("[sandbox-harness] SIGKILL on timeout failed:", err);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
let forceResolve;
|
|
150
|
+
const timeout = setTimeout(
|
|
151
|
+
() => {
|
|
152
|
+
killedByTimeout = true;
|
|
153
|
+
killTree();
|
|
154
|
+
forceResolve = setTimeout(() => finish({ code: null }), 2e3);
|
|
155
|
+
},
|
|
156
|
+
config.timeoutMs ?? 10 * 6e4
|
|
157
|
+
);
|
|
158
|
+
child.on("close", (code) => {
|
|
159
|
+
if (forceResolve) clearTimeout(forceResolve);
|
|
160
|
+
finish({ code });
|
|
107
161
|
});
|
|
108
162
|
child.on("error", (err) => {
|
|
109
|
-
clearTimeout(
|
|
110
|
-
|
|
111
|
-
resolve({ phase, exitCode: 127, stdout, stderr: stderr + String(err), wallMs });
|
|
163
|
+
if (forceResolve) clearTimeout(forceResolve);
|
|
164
|
+
finish({ code: 127, runnerError: String(err) });
|
|
112
165
|
});
|
|
113
166
|
});
|
|
114
167
|
}
|
|
@@ -143,8 +196,9 @@ var SandboxHarness = class {
|
|
|
143
196
|
if (config.setupCommand) {
|
|
144
197
|
result.setup = await this.driver.exec("setup", config.setupCommand, config);
|
|
145
198
|
result.totalWallMs += result.setup.wallMs;
|
|
146
|
-
if (result.setup.exitCode !== 0) {
|
|
147
|
-
|
|
199
|
+
if (result.setup.killedByTimeout || result.setup.exitCode !== 0) {
|
|
200
|
+
const reason = result.setup.killedByTimeout ? `setup timed out after ${result.setup.wallMs}ms` : `setup failed (exit ${result.setup.exitCode})`;
|
|
201
|
+
await handle.fail(reason, {
|
|
148
202
|
exitCode: result.setup.exitCode,
|
|
149
203
|
wallMs: result.totalWallMs
|
|
150
204
|
});
|
|
@@ -154,8 +208,9 @@ var SandboxHarness = class {
|
|
|
154
208
|
if (config.runCommand) {
|
|
155
209
|
result.run = await this.driver.exec("run", config.runCommand, config);
|
|
156
210
|
result.totalWallMs += result.run.wallMs;
|
|
157
|
-
if (result.run.exitCode !== 0) {
|
|
158
|
-
|
|
211
|
+
if (result.run.killedByTimeout || result.run.exitCode !== 0) {
|
|
212
|
+
const reason = result.run.killedByTimeout ? `run timed out after ${result.run.wallMs}ms` : `run failed (exit ${result.run.exitCode})`;
|
|
213
|
+
await handle.fail(reason, {
|
|
159
214
|
exitCode: result.run.exitCode,
|
|
160
215
|
wallMs: result.totalWallMs
|
|
161
216
|
});
|
|
@@ -165,7 +220,7 @@ var SandboxHarness = class {
|
|
|
165
220
|
if (config.testCommand) {
|
|
166
221
|
result.test = await this.driver.exec("test", config.testCommand, config);
|
|
167
222
|
result.totalWallMs += result.test.wallMs;
|
|
168
|
-
const passed = result.test.exitCode === 0;
|
|
223
|
+
const passed = !result.test.killedByTimeout && result.test.exitCode === 0;
|
|
169
224
|
result.passed = passed;
|
|
170
225
|
if (result.test.testsTotal !== void 0 && result.test.testsTotal > 0) {
|
|
171
226
|
result.score = (result.test.testsPassed ?? 0) / result.test.testsTotal;
|
|
@@ -248,4 +303,4 @@ export {
|
|
|
248
303
|
SandboxHarness,
|
|
249
304
|
runTestGradedScenario
|
|
250
305
|
};
|
|
251
|
-
//# sourceMappingURL=chunk-
|
|
306
|
+
//# sourceMappingURL=chunk-ZOPLCJSY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sandbox-harness.ts","../src/test-graded-scenario.ts"],"sourcesContent":["/**\n * SandboxHarness — executes a scenario in an isolated environment and\n * emits a rich SandboxSpan into the trace.\n *\n * Two built-in drivers:\n * - `SubprocessSandboxDriver` — spawn in a local cwd with env vars.\n * Fast, no dependencies, fine for unit tests and most CI gates.\n * - `DockerSandboxDriver` — lifted from tangle-router's sandbox path;\n * shells out to `docker run`. Stronger isolation, slower startup.\n *\n * Consumers implement `SandboxDriver` for custom backends (Firecracker,\n * Cloudflare sandbox product, etc.). The harness doesn't care which.\n */\n\nimport { ConfigError } from './errors'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { SandboxSpan } from './trace/schema'\n\nexport interface HarnessConfig {\n /** Setup command (e.g. \"pnpm install\"). Non-zero exit fails the run. */\n setupCommand?: string\n /** Run command (e.g. \"pnpm build\"). */\n runCommand?: string\n /** Test command (e.g. \"pnpm test --run\"). Drives the test count + pass count. */\n testCommand?: string\n /** Absolute cwd for the subprocess driver. Ignored by docker driver. */\n cwd?: string\n /** Max wall-clock per phase in ms. Default 10 minutes. */\n timeoutMs?: number\n /**\n * Cap on captured stdout+stderr bytes per phase. A runaway process can\n * otherwise grow the in-memory buffer without bound. Once hit, further\n * output is dropped and `outputTruncated` is set. Default 16 MiB.\n */\n maxOutputBytes?: number\n /** Image for the docker driver. */\n image?: string\n /** Extra env vars (validated; shell-escaped). */\n env?: Record<string, string>\n /** Parser for the test output — maps stdout/stderr/exit code → pass count. */\n testParser?: TestOutputParser\n}\n\nexport interface TestOutputParser {\n id: string\n parse(\n stdout: string,\n stderr: string,\n exitCode: number,\n ): { testsTotal: number; testsPassed: number } | undefined\n}\n\nexport interface SandboxResult {\n phase: 'setup' | 'run' | 'test'\n exitCode: number\n stdout: string\n stderr: string\n wallMs: number\n testsTotal?: number\n testsPassed?: number\n /**\n * True when the process was killed because it exceeded `timeoutMs`. A\n * SIGKILLed child can still close with exit code 0; callers MUST treat\n * a timed-out phase as a hard failure regardless of `exitCode`, never\n * as a pass. `undefined`/`false` means the process completed on its own.\n */\n killedByTimeout?: boolean\n /**\n * True when captured stdout/stderr hit `maxOutputBytes` and further\n * output was dropped. The result is still returned (the process was\n * not killed for this), but downstream parsers see truncated text.\n */\n outputTruncated?: boolean\n}\n\nexport interface SandboxDriver {\n id: string\n exec(\n phase: SandboxResult['phase'],\n command: string,\n config: HarnessConfig,\n ): Promise<SandboxResult>\n}\n\n// ── Parsers ──────────────────────────────────────────────────────────\n\n/** Vitest default summary line: \"Tests X passed | Y failed\". */\nexport const vitestTestParser: TestOutputParser = {\n id: 'vitest',\n parse(stdout) {\n const m = stdout.match(/Tests\\s+(\\d+)\\s+(passed|failed)(?:\\s*\\|\\s*(\\d+)\\s+(passed|failed))?/i)\n if (!m) return undefined\n let passed = 0\n let failed = 0\n const a = parseInt(m[1]!, 10)\n const aLabel = m[2]!.toLowerCase()\n if (aLabel === 'passed') passed += a\n else failed += a\n if (m[3] && m[4]) {\n const b = parseInt(m[3], 10)\n if (m[4].toLowerCase() === 'passed') passed += b\n else failed += b\n }\n return { testsTotal: passed + failed, testsPassed: passed }\n },\n}\n\n/** Pytest default: \"collected N items\" + \" X passed, Y failed\". */\nexport const pytestTestParser: TestOutputParser = {\n id: 'pytest',\n parse(stdout) {\n const total = stdout.match(/collected\\s+(\\d+)\\s+items?/i)\n const passed = stdout.match(/(\\d+)\\s+passed/)\n if (!total || !passed) return undefined\n return { testsTotal: parseInt(total[1]!, 10), testsPassed: parseInt(passed[1]!, 10) }\n },\n}\n\n/** Jest: \"Tests: X passed, Y total\" (and optional failed). */\nexport const jestTestParser: TestOutputParser = {\n id: 'jest',\n parse(stdout) {\n const m = stdout.match(/Tests:\\s+(?:(\\d+)\\s+failed[^,]*,\\s*)?(\\d+)\\s+passed,\\s+(\\d+)\\s+total/i)\n if (!m) return undefined\n return { testsTotal: parseInt(m[3]!, 10), testsPassed: parseInt(m[2]!, 10) }\n },\n}\n\n/** Composite parser — tries a list of parsers in order. */\nexport function composeParsers(...parsers: TestOutputParser[]): TestOutputParser {\n return {\n id: parsers.map((p) => p.id).join('|'),\n parse(stdout, stderr, exitCode) {\n for (const p of parsers) {\n const res = p.parse(stdout, stderr, exitCode)\n if (res) return res\n }\n return undefined\n },\n }\n}\n\n// ── Drivers ──────────────────────────────────────────────────────────\n\nexport interface SubprocessSandboxDriverOptions {\n /**\n * Default cwd for all `exec` calls. Used when the per-call `HarnessConfig`\n * does not set its own `cwd`. Lets callers bind the driver to a working\n * directory once instead of spreading cwd into every harness config —\n * useful when the harness config is constructed far from the call site\n * (e.g. starter-foundry's promoter passes a static HarnessConfig per\n * family taxonomy but needs a per-run composed-scaffold cwd).\n */\n cwd?: string\n /**\n * Default env merged into every `exec` call's env (per-call `HarnessConfig.env`\n * still wins on key collision). Same ergonomic rationale as `cwd` above.\n */\n env?: Record<string, string>\n}\n\nexport class SubprocessSandboxDriver implements SandboxDriver {\n id = 'subprocess'\n private defaultCwd?: string\n private defaultEnv?: Record<string, string>\n\n constructor(options: SubprocessSandboxDriverOptions = {}) {\n this.defaultCwd = options.cwd\n this.defaultEnv = options.env\n }\n\n async exec(\n phase: SandboxResult['phase'],\n command: string,\n config: HarnessConfig,\n ): Promise<SandboxResult> {\n const { spawn } = await import('node:child_process')\n const start = Date.now()\n // Per-call config wins; fall back to constructor defaults. Honoring\n // the constructor `cwd` keeps the subprocess from inheriting Node's\n // cwd when only the constructor arg is supplied.\n const effectiveCwd = config.cwd ?? this.defaultCwd\n const effectiveEnv = { ...process.env, ...(this.defaultEnv ?? {}), ...(config.env ?? {}) }\n const maxOutputBytes = config.maxOutputBytes ?? 16 * 1024 * 1024\n return await new Promise<SandboxResult>((resolve) => {\n const child = spawn(command, {\n shell: true,\n cwd: effectiveCwd,\n env: effectiveEnv,\n // Own process group so a timeout can SIGKILL the whole tree, not\n // just the shell — otherwise a runaway grandchild keeps the pipes\n // open and `close` never fires (the timeout silently does nothing).\n detached: process.platform !== 'win32',\n })\n let stdout = ''\n let stderr = ''\n let outputBytes = 0\n let outputTruncated = false\n let killedByTimeout = false\n let settled = false\n\n const onStdout = (d: unknown) => {\n const chunk = capture(String(d))\n if (chunk) stdout += chunk\n }\n const onStderr = (d: unknown) => {\n const chunk = capture(String(d))\n if (chunk) stderr += chunk\n }\n // Bound the in-memory buffer so a runaway process can't OOM the\n // harness. Once the cap is hit we keep draining the streams (to let\n // the child reach `close`) but discard the bytes.\n function capture(s: string): string {\n if (outputBytes >= maxOutputBytes) {\n outputTruncated = true\n return ''\n }\n const room = maxOutputBytes - outputBytes\n if (s.length > room) {\n outputBytes = maxOutputBytes\n outputTruncated = true\n return s.slice(0, room)\n }\n outputBytes += s.length\n return s\n }\n\n child.stdout?.on('data', onStdout)\n child.stderr?.on('data', onStderr)\n\n const cleanup = () => {\n clearTimeout(timeout)\n if (forceResolve) clearTimeout(forceResolve)\n child.stdout?.off('data', onStdout)\n child.stderr?.off('data', onStderr)\n child.removeAllListeners('close')\n child.removeAllListeners('error')\n }\n\n // Resolve exactly once. `code`/`signal` come from `close`; on the\n // timeout path we force a non-zero exit so a SIGKILLed child that\n // reports exit 0 can never read as a clean pass downstream.\n const finish = (outcome: { code: number | null; runnerError?: string }) => {\n if (settled) return\n settled = true\n cleanup()\n const wallMs = Date.now() - start\n const exitCode = killedByTimeout\n ? outcome.code && outcome.code !== 0\n ? outcome.code\n : 124\n : (outcome.code ?? 1)\n const parsed =\n !killedByTimeout && phase === 'test' && config.testParser\n ? config.testParser.parse(stdout, stderr, exitCode)\n : undefined\n resolve({\n phase,\n exitCode,\n stdout,\n stderr: outcome.runnerError ? stderr + outcome.runnerError : stderr,\n wallMs,\n testsTotal: parsed?.testsTotal,\n testsPassed: parsed?.testsPassed,\n killedByTimeout: killedByTimeout || undefined,\n outputTruncated: outputTruncated || undefined,\n })\n }\n\n // Kill the whole process group on win32-less platforms (we spawned\n // detached). On a clean close this is a no-op.\n const killTree = () => {\n try {\n if (process.platform !== 'win32' && typeof child.pid === 'number') {\n process.kill(-child.pid, 'SIGKILL')\n } else {\n child.kill('SIGKILL')\n }\n } catch (err) {\n console.warn('[sandbox-harness] SIGKILL on timeout failed:', err)\n }\n }\n\n let forceResolve: ReturnType<typeof setTimeout> | undefined\n const timeout = setTimeout(\n () => {\n killedByTimeout = true\n killTree()\n // Give `close` a brief window to fire (flushing any final output)\n // after the group dies; if an orphaned grandchild keeps the pipes\n // open, force-resolve so the harness can't hang on a runaway.\n forceResolve = setTimeout(() => finish({ code: null }), 2000)\n },\n config.timeoutMs ?? 10 * 60_000,\n )\n\n child.on('close', (code) => {\n if (forceResolve) clearTimeout(forceResolve)\n finish({ code })\n })\n child.on('error', (err) => {\n if (forceResolve) clearTimeout(forceResolve)\n finish({ code: 127, runnerError: String(err) })\n })\n })\n }\n}\n\nexport class DockerSandboxDriver implements SandboxDriver {\n id = 'docker'\n\n async exec(\n phase: SandboxResult['phase'],\n command: string,\n config: HarnessConfig,\n ): Promise<SandboxResult> {\n if (!config.image) throw new ConfigError('DockerSandboxDriver requires config.image')\n const sub = new SubprocessSandboxDriver()\n const envArgs = Object.entries(config.env ?? {})\n .map(([k, v]) => `-e ${shellQuote(k)}=${shellQuote(v)}`)\n .join(' ')\n const wrapped = `docker run --rm ${envArgs} ${shellQuote(config.image)} sh -c ${shellQuote(command)}`\n return sub.exec(phase, wrapped, { ...config, env: undefined })\n }\n}\n\nfunction shellQuote(v: string): string {\n if (/^[A-Za-z0-9_\\-/.@:=]+$/.test(v)) return v\n return `'${v.replace(/'/g, `'\\\\''`)}'`\n}\n\n// ── Harness orchestration ────────────────────────────────────────────\n\nexport interface SandboxHarnessResult {\n passed: boolean\n setup?: SandboxResult\n run?: SandboxResult\n test?: SandboxResult\n totalWallMs: number\n /** Final score — 0 when no tests; otherwise testsPassed/testsTotal. */\n score: number\n}\n\nexport class SandboxHarness {\n private driver: SandboxDriver\n constructor(driver: SandboxDriver = new SubprocessSandboxDriver()) {\n this.driver = driver\n }\n\n async run(config: HarnessConfig, emitter: TraceEmitter): Promise<SandboxHarnessResult> {\n const handle = await emitter.sandbox({\n name: `sandbox(${this.driver.id})`,\n image: config.image,\n command: [config.setupCommand, config.runCommand, config.testCommand]\n .filter(Boolean)\n .join(' && '),\n })\n const result: SandboxHarnessResult = { passed: false, totalWallMs: 0, score: 0 }\n try {\n if (config.setupCommand) {\n result.setup = await this.driver.exec('setup', config.setupCommand, config)\n result.totalWallMs += result.setup.wallMs\n if (result.setup.killedByTimeout || result.setup.exitCode !== 0) {\n const reason = result.setup.killedByTimeout\n ? `setup timed out after ${result.setup.wallMs}ms`\n : `setup failed (exit ${result.setup.exitCode})`\n await handle.fail(reason, {\n exitCode: result.setup.exitCode,\n wallMs: result.totalWallMs,\n } as Partial<SandboxSpan>)\n return result\n }\n }\n if (config.runCommand) {\n result.run = await this.driver.exec('run', config.runCommand, config)\n result.totalWallMs += result.run.wallMs\n if (result.run.killedByTimeout || result.run.exitCode !== 0) {\n const reason = result.run.killedByTimeout\n ? `run timed out after ${result.run.wallMs}ms`\n : `run failed (exit ${result.run.exitCode})`\n await handle.fail(reason, {\n exitCode: result.run.exitCode,\n wallMs: result.totalWallMs,\n } as Partial<SandboxSpan>)\n return result\n }\n }\n if (config.testCommand) {\n result.test = await this.driver.exec('test', config.testCommand, config)\n result.totalWallMs += result.test.wallMs\n // A timed-out test phase is a hard fail regardless of the exit code\n // a SIGKILLed child happens to report — never let it score as a pass.\n const passed = !result.test.killedByTimeout && result.test.exitCode === 0\n result.passed = passed\n if (result.test.testsTotal !== undefined && result.test.testsTotal > 0) {\n result.score = (result.test.testsPassed ?? 0) / result.test.testsTotal\n } else {\n result.score = passed ? 1 : 0\n }\n await handle.end({\n exitCode: result.test.exitCode,\n testsTotal: result.test.testsTotal,\n testsPassed: result.test.testsPassed,\n wallMs: result.totalWallMs,\n status: passed ? 'ok' : 'error',\n } as Partial<SandboxSpan>)\n } else {\n result.passed = true\n result.score = 1\n await handle.end({ wallMs: result.totalWallMs } as Partial<SandboxSpan>)\n }\n } catch (err) {\n await handle.fail(err instanceof Error ? err : String(err))\n throw err\n }\n return result\n }\n}\n","/**\n * TestGradedScenario — a scenario whose score comes from a test suite.\n *\n * This is the SWE-bench pattern generalized. The scenario ships:\n * - fixture data (setup instructions)\n * - a test command the harness runs\n * - optional assertion overrides\n *\n * The runner emits a run, delegates to SandboxHarness, records the\n * outcome, and returns a structured verdict. Consumers bind their own\n * agent execution to this contract.\n */\n\nimport type { HarnessConfig, SandboxDriver, SandboxHarnessResult } from './sandbox-harness'\nimport { SandboxHarness } from './sandbox-harness'\nimport { TraceEmitter } from './trace/emitter'\nimport type { FailureClass, Run } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport interface TestGradedScenario {\n id: string\n description?: string\n harness: HarnessConfig\n /** Optional pass threshold in 0..1 (default 1.0 = all tests must pass). */\n passThreshold?: number\n /** Provenance for dataset tracking. */\n datasetVersion?: string\n /** Free-form tags (difficulty, category, etc.). */\n tags?: Record<string, string>\n}\n\nexport interface TestGradedRunOptions {\n variantId?: string\n driver?: SandboxDriver\n /** Metadata recorded on the Run (codeSha, promptSha, modelFingerprint, seed). */\n provenance?: Pick<Run, 'codeSha' | 'promptSha' | 'modelFingerprint' | 'seed' | 'envFingerprint'>\n}\n\nexport interface TestGradedRunResult {\n runId: string\n scenario: TestGradedScenario\n harness: SandboxHarnessResult\n pass: boolean\n score: number\n failureClass?: FailureClass\n}\n\nexport async function runTestGradedScenario(\n scenario: TestGradedScenario,\n store: TraceStore,\n options: TestGradedRunOptions = {},\n): Promise<TestGradedRunResult> {\n const emitter = new TraceEmitter(store)\n await emitter.startRun({\n scenarioId: scenario.id,\n variantId: options.variantId,\n datasetVersion: scenario.datasetVersion,\n tags: scenario.tags,\n ...options.provenance,\n })\n const harness = new SandboxHarness(options.driver)\n const result = await harness.run(scenario.harness, emitter)\n const threshold = scenario.passThreshold ?? 1.0\n const pass = result.passed && result.score >= threshold\n const setupFailed = result.setup !== undefined && result.setup.exitCode !== 0\n const runFailed = result.run !== undefined && result.run.exitCode !== 0\n const testFailed = result.test !== undefined && result.test.exitCode !== 0\n const failureClass: FailureClass | undefined = pass\n ? 'success'\n : setupFailed || runFailed\n ? 'sandbox_failure'\n : testFailed\n ? 'format_drift'\n : 'unknown'\n await emitter.endRun({\n pass,\n score: result.score,\n failureClass,\n notes: pass ? undefined : reasonForFailure(result),\n })\n return {\n runId: emitter.runId,\n scenario,\n harness: result,\n pass,\n score: result.score,\n failureClass,\n }\n}\n\nfunction reasonForFailure(result: SandboxHarnessResult): string {\n if (result.setup && result.setup.exitCode !== 0)\n return `setup failed: exit ${result.setup.exitCode}`\n if (result.run && result.run.exitCode !== 0) return `run failed: exit ${result.run.exitCode}`\n if (result.test) {\n if (result.test.testsTotal !== undefined) {\n return `tests: ${result.test.testsPassed ?? 0}/${result.test.testsTotal}`\n }\n return `test exit ${result.test.exitCode}`\n }\n return 'no test command'\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
runRpcBatch,
|
|
6
6
|
runRpcOnce,
|
|
7
7
|
startServer
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-D5KBVULY.js";
|
|
9
|
+
import "./chunk-CWNP4DV4.js";
|
|
10
10
|
import "./chunk-PC4UYEBM.js";
|
|
11
11
|
import "./chunk-3BFEG2F6.js";
|
|
12
12
|
import "./chunk-PZ5AY32C.js";
|