@tangle-network/agent-runtime 0.79.3 → 0.80.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/README.md +54 -325
- package/dist/agent.js +5 -5
- package/dist/analyst-loop.js +2 -2
- package/dist/{chunk-VMNEQHJR.js → chunk-3X53HYRW.js} +17 -2
- package/dist/chunk-3X53HYRW.js.map +1 -0
- package/dist/{chunk-T2HVQVB4.js → chunk-4J6RBI3K.js} +15 -1
- package/dist/chunk-4J6RBI3K.js.map +1 -0
- package/dist/{chunk-IODKUOBA.js → chunk-C2FZ6GR6.js} +2 -2
- package/dist/{chunk-63MHOCIE.js → chunk-DH72UOYR.js} +4 -4
- package/dist/{chunk-Z3RRRPRB.js → chunk-H7IBHAFT.js} +23 -14
- package/dist/chunk-H7IBHAFT.js.map +1 -0
- package/dist/{chunk-PVPFDTO3.js → chunk-LLJRUTE7.js} +2 -2
- package/dist/{chunk-PBE35ULD.js → chunk-M3Y362RW.js} +2 -2
- package/dist/{chunk-AG335EXG.js → chunk-QSO2TVDS.js} +668 -74
- package/dist/chunk-QSO2TVDS.js.map +1 -0
- package/dist/{chunk-KRULXIWS.js → chunk-TPII5AU7.js} +55 -7
- package/dist/chunk-TPII5AU7.js.map +1 -0
- package/dist/{coordination-DCmljYDf.d.ts → coordination-BI9tpcmF.d.ts} +12 -3
- package/dist/environment-provider.d.ts +1 -1
- package/dist/environment-provider.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +8 -8
- package/dist/intelligence.d.ts +30 -2
- package/dist/intelligence.js +33 -23
- package/dist/intelligence.js.map +1 -1
- package/dist/{loop-runner-bin-C4X0FZ2Z.d.ts → loop-runner-bin-CBkLsyFg.d.ts} +2 -2
- package/dist/loop-runner-bin.d.ts +4 -4
- package/dist/loop-runner-bin.js +7 -7
- package/dist/loops.d.ts +265 -14
- package/dist/loops.js +28 -6
- package/dist/mcp/bin.js +5 -5
- package/dist/mcp/index.d.ts +6 -6
- package/dist/mcp/index.js +7 -7
- package/dist/{router-client-Ak2IGuXq.d.ts → router-client-D6Ocf4jG.d.ts} +19 -0
- package/dist/{types-C1sozrte.d.ts → types-By9LXllv.d.ts} +9 -2
- package/dist/{worktree-fanout-CXGzHET4.d.ts → worktree-fanout-D9Z2dMS9.d.ts} +2 -2
- package/dist/{worktree-harness-Bmho9SH0.d.ts → worktree-harness-Dx8XULW3.d.ts} +1 -1
- package/package.json +1 -1
- package/skills/build-with-agent-runtime/SKILL.md +53 -23
- package/dist/chunk-AG335EXG.js.map +0 -1
- package/dist/chunk-KRULXIWS.js.map +0 -1
- package/dist/chunk-T2HVQVB4.js.map +0 -1
- package/dist/chunk-VMNEQHJR.js.map +0 -1
- package/dist/chunk-Z3RRRPRB.js.map +0 -1
- /package/dist/{chunk-IODKUOBA.js.map → chunk-C2FZ6GR6.js.map} +0 -0
- /package/dist/{chunk-63MHOCIE.js.map → chunk-DH72UOYR.js.map} +0 -0
- /package/dist/{chunk-PVPFDTO3.js.map → chunk-LLJRUTE7.js.map} +0 -0
- /package/dist/{chunk-PBE35ULD.js.map → chunk-M3Y362RW.js.map} +0 -0
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
routerToolLoop,
|
|
13
13
|
runLoop,
|
|
14
14
|
settledToIteration,
|
|
15
|
+
supervise,
|
|
15
16
|
withDriverExecutor
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-TPII5AU7.js";
|
|
17
18
|
import {
|
|
18
19
|
addTokenUsage,
|
|
19
20
|
isAbortError,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
sleep,
|
|
22
23
|
stringifySafe,
|
|
23
24
|
zeroTokenUsage
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-H7IBHAFT.js";
|
|
25
26
|
import {
|
|
26
27
|
AnalystError,
|
|
27
28
|
PlannerError,
|
|
@@ -205,6 +206,495 @@ Audit the route: revealed intent, verdict, evidence, one recommendation.`
|
|
|
205
206
|
};
|
|
206
207
|
}
|
|
207
208
|
|
|
209
|
+
// src/runtime/benchmark-report.ts
|
|
210
|
+
import {
|
|
211
|
+
benjaminiHochberg,
|
|
212
|
+
confidenceInterval,
|
|
213
|
+
pairedBootstrap,
|
|
214
|
+
pairedTTest,
|
|
215
|
+
wilson
|
|
216
|
+
} from "@tangle-network/agent-eval";
|
|
217
|
+
var defaultScoreOf = (r) => {
|
|
218
|
+
const o = r.outcome;
|
|
219
|
+
if (typeof o.holdoutScore === "number") return o.holdoutScore;
|
|
220
|
+
if (typeof o.searchScore === "number") return o.searchScore;
|
|
221
|
+
const raw = o.raw ?? {};
|
|
222
|
+
for (const k of ["composite", "score", "passed", "resolved"]) {
|
|
223
|
+
if (typeof raw[k] === "number") return raw[k];
|
|
224
|
+
}
|
|
225
|
+
return void 0;
|
|
226
|
+
};
|
|
227
|
+
var defaultProfileKeyOf = (r) => {
|
|
228
|
+
const cell = r.agentProfile;
|
|
229
|
+
const harness = cell?.harness;
|
|
230
|
+
return harness ? `${harness}\xB7${r.model}` : r.model;
|
|
231
|
+
};
|
|
232
|
+
var defaultGroupOf = (r) => r.scenarioId ?? r.experimentId;
|
|
233
|
+
function quantile(sorted, q) {
|
|
234
|
+
if (sorted.length === 0) return 0;
|
|
235
|
+
const idx = Math.min(sorted.length - 1, Math.floor(q * (sorted.length - 1)));
|
|
236
|
+
return sorted[idx] ?? 0;
|
|
237
|
+
}
|
|
238
|
+
function mean(xs) {
|
|
239
|
+
return xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length;
|
|
240
|
+
}
|
|
241
|
+
function meanByScenario(records, scoreOf) {
|
|
242
|
+
const sums = /* @__PURE__ */ new Map();
|
|
243
|
+
for (const r of records) {
|
|
244
|
+
const s = scoreOf(r);
|
|
245
|
+
if (typeof s !== "number") continue;
|
|
246
|
+
const id = r.scenarioId;
|
|
247
|
+
if (!id) {
|
|
248
|
+
throw new Error(
|
|
249
|
+
`benchmark-report: RunRecord (candidate ${r.candidateId ?? "unknown"}) is missing scenarioId \u2014 cannot pair or interval it honestly. Pass opts.stats only on a scenario-tagged corpus.`
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
const acc = sums.get(id) ?? { total: 0, n: 0 };
|
|
253
|
+
acc.total += s;
|
|
254
|
+
acc.n += 1;
|
|
255
|
+
sums.set(id, acc);
|
|
256
|
+
}
|
|
257
|
+
const out = /* @__PURE__ */ new Map();
|
|
258
|
+
for (const [id, acc] of sums) out.set(id, acc.n ? acc.total / acc.n : 0);
|
|
259
|
+
return out;
|
|
260
|
+
}
|
|
261
|
+
function leaderboard(records, opts = {}) {
|
|
262
|
+
const scoreOf = opts.scoreOf ?? defaultScoreOf;
|
|
263
|
+
const profileKeyOf = opts.profileKeyOf ?? defaultProfileKeyOf;
|
|
264
|
+
const groupOf = opts.groupOf ?? defaultGroupOf;
|
|
265
|
+
const labelOf = opts.labelOf ?? ((k) => k);
|
|
266
|
+
const axisSet = /* @__PURE__ */ new Set();
|
|
267
|
+
if (opts.axisScoresOf) {
|
|
268
|
+
for (const r of records) for (const k of Object.keys(opts.axisScoresOf(r))) axisSet.add(k);
|
|
269
|
+
} else {
|
|
270
|
+
for (const r of records) axisSet.add(groupOf(r));
|
|
271
|
+
}
|
|
272
|
+
const axes = [...axisSet].sort();
|
|
273
|
+
const byProfile = /* @__PURE__ */ new Map();
|
|
274
|
+
for (const r of records) {
|
|
275
|
+
const key = profileKeyOf(r);
|
|
276
|
+
const bucket = byProfile.get(key);
|
|
277
|
+
if (bucket) bucket.push(r);
|
|
278
|
+
else byProfile.set(key, [r]);
|
|
279
|
+
}
|
|
280
|
+
const rows = [];
|
|
281
|
+
for (const [profileKey, recs] of byProfile) {
|
|
282
|
+
const scores = recs.map(scoreOf).filter((s) => typeof s === "number");
|
|
283
|
+
const axisBuckets = /* @__PURE__ */ new Map();
|
|
284
|
+
for (const r of recs) {
|
|
285
|
+
if (opts.axisScoresOf) {
|
|
286
|
+
for (const [axis, s] of Object.entries(opts.axisScoresOf(r))) {
|
|
287
|
+
const b = axisBuckets.get(axis) ?? [];
|
|
288
|
+
b.push(s);
|
|
289
|
+
axisBuckets.set(axis, b);
|
|
290
|
+
}
|
|
291
|
+
} else {
|
|
292
|
+
const s = scoreOf(r);
|
|
293
|
+
if (typeof s === "number") {
|
|
294
|
+
const axis = groupOf(r);
|
|
295
|
+
const b = axisBuckets.get(axis) ?? [];
|
|
296
|
+
b.push(s);
|
|
297
|
+
axisBuckets.set(axis, b);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const perAxis = {};
|
|
302
|
+
for (const [axis, b] of axisBuckets) perAxis[axis] = mean(b);
|
|
303
|
+
const latencies = recs.map((r) => r.wallMs).sort((a, b) => a - b);
|
|
304
|
+
const pass = opts.passThreshold ?? 0.999;
|
|
305
|
+
let scoreCi;
|
|
306
|
+
let passCi;
|
|
307
|
+
if (opts.stats) {
|
|
308
|
+
const collapsed = [...meanByScenario(recs, scoreOf).values()];
|
|
309
|
+
if (collapsed.length > 0) {
|
|
310
|
+
const ci2 = confidenceInterval(collapsed, 0.95, { seed: 7 });
|
|
311
|
+
scoreCi = { lower: ci2.lower, upper: ci2.upper };
|
|
312
|
+
const w = wilson(collapsed.filter((s) => s >= pass).length, collapsed.length, 0.95);
|
|
313
|
+
passCi = { lower: w.lower, upper: w.upper };
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
rows.push({
|
|
317
|
+
profileKey,
|
|
318
|
+
label: labelOf(profileKey),
|
|
319
|
+
model: recs[0]?.model ?? profileKey,
|
|
320
|
+
n: recs.length,
|
|
321
|
+
meanScore: mean(scores),
|
|
322
|
+
solveRate: scores.length === 0 ? 0 : scores.filter((s) => s >= pass).length / scores.length,
|
|
323
|
+
perAxis,
|
|
324
|
+
costUsd: recs.reduce((a, r) => a + r.costUsd, 0),
|
|
325
|
+
tokensIn: recs.reduce((a, r) => a + (r.tokenUsage?.input ?? 0), 0),
|
|
326
|
+
tokensOut: recs.reduce((a, r) => a + (r.tokenUsage?.output ?? 0), 0),
|
|
327
|
+
latencyP50Ms: quantile(latencies, 0.5),
|
|
328
|
+
latencyP90Ms: quantile(latencies, 0.9),
|
|
329
|
+
...scoreCi ? { scoreCi } : {},
|
|
330
|
+
...passCi ? { passCi } : {}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
rows.sort(
|
|
334
|
+
(a, b) => b.meanScore - a.meanScore || a.costUsd - b.costUsd || a.label.localeCompare(b.label)
|
|
335
|
+
);
|
|
336
|
+
const models = [...new Set(records.map((r) => r.model))].sort();
|
|
337
|
+
return {
|
|
338
|
+
title: opts.title ?? "Benchmark report",
|
|
339
|
+
axes,
|
|
340
|
+
profiles: rows,
|
|
341
|
+
meta: opts.meta ?? {},
|
|
342
|
+
provenance: {
|
|
343
|
+
records: records.length,
|
|
344
|
+
profiles: rows.length,
|
|
345
|
+
axes: axes.length,
|
|
346
|
+
models,
|
|
347
|
+
totalCostUsd: records.reduce((a, r) => a + r.costUsd, 0)
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function pairwiseSignificance(records, opts = {}) {
|
|
352
|
+
const scoreOf = opts.scoreOf ?? defaultScoreOf;
|
|
353
|
+
const profileKeyOf = opts.profileKeyOf ?? defaultProfileKeyOf;
|
|
354
|
+
const labelOf = opts.labelOf ?? ((k) => k);
|
|
355
|
+
const minPairs = opts.minPairs ?? 12;
|
|
356
|
+
const byProfile = /* @__PURE__ */ new Map();
|
|
357
|
+
for (const r of records) {
|
|
358
|
+
const k = profileKeyOf(r);
|
|
359
|
+
const b = byProfile.get(k);
|
|
360
|
+
if (b) b.push(r);
|
|
361
|
+
else byProfile.set(k, [r]);
|
|
362
|
+
}
|
|
363
|
+
const keys = [...byProfile.keys()].sort();
|
|
364
|
+
const collapsed = new Map(keys.map((k) => [k, meanByScenario(byProfile.get(k) ?? [], scoreOf)]));
|
|
365
|
+
const raw = [];
|
|
366
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
367
|
+
for (let j = i + 1; j < keys.length; j += 1) {
|
|
368
|
+
const ka = keys[i];
|
|
369
|
+
const kb = keys[j];
|
|
370
|
+
const am = collapsed.get(ka);
|
|
371
|
+
const bm = collapsed.get(kb);
|
|
372
|
+
const aScores = [];
|
|
373
|
+
const bScores = [];
|
|
374
|
+
for (const sid of [...am.keys()].sort()) {
|
|
375
|
+
const bv = bm.get(sid);
|
|
376
|
+
if (bv !== void 0) {
|
|
377
|
+
aScores.push(am.get(sid));
|
|
378
|
+
bScores.push(bv);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (aScores.length === 0) continue;
|
|
382
|
+
const boot = pairedBootstrap(aScores, bScores, { seed: 7, statistic: "median" });
|
|
383
|
+
const p = pairedTTest(aScores, bScores).p;
|
|
384
|
+
raw.push({
|
|
385
|
+
a: labelOf(ka),
|
|
386
|
+
b: labelOf(kb),
|
|
387
|
+
pairs: aScores.length,
|
|
388
|
+
delta: boot.median,
|
|
389
|
+
ciLow: boot.low,
|
|
390
|
+
ciHigh: boot.high,
|
|
391
|
+
p
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const { significant } = benjaminiHochberg(
|
|
396
|
+
raw.map((r) => r.p),
|
|
397
|
+
opts.fdr ?? 0.05
|
|
398
|
+
);
|
|
399
|
+
return raw.map((r, i) => ({
|
|
400
|
+
...r,
|
|
401
|
+
significant: (significant[i] ?? false) && r.pairs >= minPairs
|
|
402
|
+
}));
|
|
403
|
+
}
|
|
404
|
+
var pct = (x) => `${(100 * x).toFixed(1)}%`;
|
|
405
|
+
var ci = (iv) => iv ? ` [${pct(iv.lower)}, ${pct(iv.upper)}]` : "";
|
|
406
|
+
function renderLeaderboardMarkdown(report) {
|
|
407
|
+
const lines = [];
|
|
408
|
+
lines.push(`# ${report.title}`, "");
|
|
409
|
+
const p = report.provenance;
|
|
410
|
+
lines.push(
|
|
411
|
+
`**${p.profiles} profiles \xD7 ${p.axes} axes**, ${p.records} runs, ${p.models.length} models \xB7 total $${p.totalCostUsd.toFixed(2)}`,
|
|
412
|
+
""
|
|
413
|
+
);
|
|
414
|
+
for (const [k, v] of Object.entries(report.meta)) lines.push(`- **${k}:** ${v}`);
|
|
415
|
+
if (Object.keys(report.meta).length) lines.push("");
|
|
416
|
+
lines.push("## Leaderboard", "");
|
|
417
|
+
lines.push(
|
|
418
|
+
"| # | Profile | Score (95% CI) | Solved (95% CI) | Runs | Cost | Tok in/out | p50 | p90 |"
|
|
419
|
+
);
|
|
420
|
+
lines.push("|---|---|--:|--:|--:|--:|--:|--:|--:|");
|
|
421
|
+
report.profiles.forEach((r, i) => {
|
|
422
|
+
lines.push(
|
|
423
|
+
`| ${i + 1} | ${r.label} | ${pct(r.meanScore)}${ci(r.scoreCi)} | ${pct(r.solveRate)}${ci(r.passCi)} | ${r.n} | $${r.costUsd.toFixed(3)} | ${r.tokensIn}/${r.tokensOut} | ${(r.latencyP50Ms / 1e3).toFixed(1)}s | ${(r.latencyP90Ms / 1e3).toFixed(1)}s |`
|
|
424
|
+
);
|
|
425
|
+
});
|
|
426
|
+
lines.push("");
|
|
427
|
+
lines.push("## Score matrix \u2014 profile \xD7 axis", "");
|
|
428
|
+
lines.push(`| Profile | ${report.axes.join(" | ")} |`);
|
|
429
|
+
lines.push(`|---|${report.axes.map(() => "--:").join("|")}|`);
|
|
430
|
+
for (const r of report.profiles) {
|
|
431
|
+
const cells = report.axes.map((a) => {
|
|
432
|
+
const v = r.perAxis[a];
|
|
433
|
+
return v === void 0 ? "\xB7" : pct(v);
|
|
434
|
+
});
|
|
435
|
+
lines.push(`| ${r.label} | ${cells.join(" | ")} |`);
|
|
436
|
+
}
|
|
437
|
+
lines.push("");
|
|
438
|
+
lines.push("> `\xB7` = the profile never ran that axis (blank, never zero).");
|
|
439
|
+
return lines.join("\n");
|
|
440
|
+
}
|
|
441
|
+
function renderPairwiseMarkdown(verdicts, title = "Pairwise significance (paired, BH-corrected)") {
|
|
442
|
+
const lines = [`## ${title}`, ""];
|
|
443
|
+
if (verdicts.length === 0) return lines.concat("_no comparable pairs_").join("\n");
|
|
444
|
+
lines.push("| A vs B | \u0394(b\u2212a) median | 95% CI | pairs | p | verdict |");
|
|
445
|
+
lines.push("|---|--:|--:|--:|--:|---|");
|
|
446
|
+
for (const v of verdicts) {
|
|
447
|
+
const verdict = v.significant ? `**${v.delta >= 0 ? v.b : v.a} wins**` : "ns";
|
|
448
|
+
lines.push(
|
|
449
|
+
`| ${v.a} vs ${v.b} | ${v.delta >= 0 ? "+" : ""}${pct(v.delta)} | [${pct(v.ciLow)}, ${pct(v.ciHigh)}] | ${v.pairs} | ${v.p.toFixed(3)} | ${verdict} |`
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
lines.push(
|
|
453
|
+
"",
|
|
454
|
+
"> `ns` = not significant after Benjamini\u2013Hochberg (or below the paired-count floor)."
|
|
455
|
+
);
|
|
456
|
+
return lines.join("\n");
|
|
457
|
+
}
|
|
458
|
+
function esc(s) {
|
|
459
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
460
|
+
}
|
|
461
|
+
function ramp(score) {
|
|
462
|
+
const x = Math.max(0, Math.min(1, score));
|
|
463
|
+
const r = Math.round(x < 0.5 ? 220 : 220 - (x - 0.5) * 2 * 160);
|
|
464
|
+
const g = Math.round(x < 0.5 ? x * 2 * 170 : 170);
|
|
465
|
+
return `rgb(${r},${g},60)`;
|
|
466
|
+
}
|
|
467
|
+
function renderLeaderboardSvg(report) {
|
|
468
|
+
const rowH = 26;
|
|
469
|
+
const labelW = 220;
|
|
470
|
+
const cellW = 54;
|
|
471
|
+
const pad = 16;
|
|
472
|
+
const barAreaW = 360;
|
|
473
|
+
const profiles = report.profiles;
|
|
474
|
+
const barsH = profiles.length * rowH + pad;
|
|
475
|
+
const heatTop = barsH + 48;
|
|
476
|
+
const heatW = labelW + report.axes.length * cellW + pad;
|
|
477
|
+
const heatH = profiles.length * rowH + pad;
|
|
478
|
+
const width = Math.max(labelW + barAreaW + pad * 2, heatW);
|
|
479
|
+
const height = heatTop + heatH + pad;
|
|
480
|
+
const out = [];
|
|
481
|
+
out.push(
|
|
482
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" font-family="ui-sans-serif,system-ui,sans-serif" font-size="12">`
|
|
483
|
+
);
|
|
484
|
+
out.push(`<rect width="${width}" height="${height}" fill="white"/>`);
|
|
485
|
+
out.push(
|
|
486
|
+
`<text x="${pad}" y="${pad + 4}" font-weight="700" font-size="14">${esc(report.title)} \u2014 score</text>`
|
|
487
|
+
);
|
|
488
|
+
profiles.forEach((r, i) => {
|
|
489
|
+
const y = pad + 12 + i * rowH;
|
|
490
|
+
out.push(`<text x="${pad}" y="${y + 14}">${esc(r.label)}</text>`);
|
|
491
|
+
const w = Math.round(r.meanScore * barAreaW);
|
|
492
|
+
out.push(`<rect x="${labelW}" y="${y + 4}" width="${barAreaW}" height="16" fill="#eef0f2"/>`);
|
|
493
|
+
out.push(
|
|
494
|
+
`<rect x="${labelW}" y="${y + 4}" width="${w}" height="16" fill="${ramp(r.meanScore)}"/>`
|
|
495
|
+
);
|
|
496
|
+
out.push(`<text x="${labelW + barAreaW + 6}" y="${y + 16}">${pct(r.meanScore)}</text>`);
|
|
497
|
+
});
|
|
498
|
+
out.push(
|
|
499
|
+
`<text x="${pad}" y="${heatTop - 12}" font-weight="700" font-size="14">profile \xD7 axis</text>`
|
|
500
|
+
);
|
|
501
|
+
report.axes.forEach((a, c) => {
|
|
502
|
+
const x = labelW + c * cellW;
|
|
503
|
+
out.push(
|
|
504
|
+
`<text x="${x + cellW / 2}" y="${heatTop}" text-anchor="middle" fill="#555">${esc(a.length > 8 ? `${a.slice(0, 7)}\u2026` : a)}</text>`
|
|
505
|
+
);
|
|
506
|
+
});
|
|
507
|
+
profiles.forEach((r, i) => {
|
|
508
|
+
const y = heatTop + 8 + i * rowH;
|
|
509
|
+
out.push(`<text x="${pad}" y="${y + 16}">${esc(r.label)}</text>`);
|
|
510
|
+
report.axes.forEach((a, c) => {
|
|
511
|
+
const x = labelW + c * cellW;
|
|
512
|
+
const s = r.perAxis[a];
|
|
513
|
+
if (s !== void 0) {
|
|
514
|
+
out.push(
|
|
515
|
+
`<rect x="${x}" y="${y}" width="${cellW - 3}" height="${rowH - 4}" fill="${ramp(s)}"/>`
|
|
516
|
+
);
|
|
517
|
+
out.push(
|
|
518
|
+
`<text x="${x + (cellW - 3) / 2}" y="${y + 15}" text-anchor="middle" fill="white" font-size="10">${Math.round(100 * s)}</text>`
|
|
519
|
+
);
|
|
520
|
+
} else {
|
|
521
|
+
out.push(
|
|
522
|
+
`<rect x="${x}" y="${y}" width="${cellW - 3}" height="${rowH - 4}" fill="#f3f4f6"/>`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
out.push("</svg>");
|
|
528
|
+
return out.join("\n");
|
|
529
|
+
}
|
|
530
|
+
function renderLeaderboardHtml(report) {
|
|
531
|
+
const svg = renderLeaderboardSvg(report);
|
|
532
|
+
const p = report.provenance;
|
|
533
|
+
const rows = report.profiles.map(
|
|
534
|
+
(r, i) => `<tr><td>${i + 1}</td><td>${esc(r.label)}</td><td class="n">${pct(r.meanScore)}</td><td class="n">${pct(r.solveRate)}</td><td class="n">${r.n}</td><td class="n">$${r.costUsd.toFixed(3)}</td>${report.axes.map((a) => {
|
|
535
|
+
const v = r.perAxis[a];
|
|
536
|
+
return `<td class="n">${v === void 0 ? "\xB7" : pct(v)}</td>`;
|
|
537
|
+
}).join("")}</tr>`
|
|
538
|
+
).join("\n");
|
|
539
|
+
const axisHead = report.axes.map((a) => `<th>${esc(a)}</th>`).join("");
|
|
540
|
+
return `<!doctype html><html><head><meta charset="utf-8"><title>${esc(report.title)}</title>
|
|
541
|
+
<style>
|
|
542
|
+
body{font:14px ui-sans-serif,system-ui,sans-serif;margin:2rem;color:#111}
|
|
543
|
+
h1{font-size:1.4rem}.sub{color:#555;margin:.2rem 0 1.2rem}
|
|
544
|
+
table{border-collapse:collapse;margin-top:1rem}td,th{border:1px solid #e5e7eb;padding:.35rem .6rem}
|
|
545
|
+
th{background:#f9fafb;text-align:left}.n{text-align:right;font-variant-numeric:tabular-nums}
|
|
546
|
+
tr:first-child td{font-weight:600}
|
|
547
|
+
</style></head><body>
|
|
548
|
+
<h1>${esc(report.title)}</h1>
|
|
549
|
+
<div class="sub">${p.profiles} profiles \xD7 ${p.axes} axes \xB7 ${p.records} runs \xB7 ${p.models.length} models \xB7 total $${p.totalCostUsd.toFixed(2)}</div>
|
|
550
|
+
${svg}
|
|
551
|
+
<table><thead><tr><th>#</th><th>Profile</th><th>Score</th><th>Solved</th><th>Runs</th><th>Cost</th>${axisHead}</tr></thead>
|
|
552
|
+
<tbody>
|
|
553
|
+
${rows}
|
|
554
|
+
</tbody></table>
|
|
555
|
+
</body></html>`;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// src/runtime/inline-sandbox-client.ts
|
|
559
|
+
function isAsyncIterable(v) {
|
|
560
|
+
return typeof v === "object" && v !== null && Symbol.asyncIterator in v;
|
|
561
|
+
}
|
|
562
|
+
async function settle(exec, task, signal) {
|
|
563
|
+
const r = exec.execute(task, signal);
|
|
564
|
+
if (isAsyncIterable(r)) {
|
|
565
|
+
for await (const _ of r) {
|
|
566
|
+
}
|
|
567
|
+
return exec.resultArtifact();
|
|
568
|
+
}
|
|
569
|
+
return r;
|
|
570
|
+
}
|
|
571
|
+
function inlineSandboxClient(factory) {
|
|
572
|
+
let seq = 0;
|
|
573
|
+
return {
|
|
574
|
+
async create(options) {
|
|
575
|
+
const id = `inline-${seq++}`;
|
|
576
|
+
const createOptions = options;
|
|
577
|
+
return {
|
|
578
|
+
id,
|
|
579
|
+
async *streamPrompt(message) {
|
|
580
|
+
const controller = new AbortController();
|
|
581
|
+
const spec = { profile: { name: id }, harness: null };
|
|
582
|
+
const exec = factory(spec, { signal: controller.signal, seams: { createOptions } });
|
|
583
|
+
try {
|
|
584
|
+
const artifact = await settle(exec, message, controller.signal);
|
|
585
|
+
const out = artifact.out;
|
|
586
|
+
const tokensIn = artifact.spent.tokens.input;
|
|
587
|
+
const tokensOut = artifact.spent.tokens.output;
|
|
588
|
+
const costUsd = artifact.spent.usd;
|
|
589
|
+
if (tokensIn || tokensOut || costUsd) {
|
|
590
|
+
yield {
|
|
591
|
+
type: "llm_call",
|
|
592
|
+
data: { tokensIn, tokensOut, costUsd }
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
yield {
|
|
596
|
+
type: "result",
|
|
597
|
+
data: {
|
|
598
|
+
finalText: out?.content ?? "",
|
|
599
|
+
tokenUsage: {
|
|
600
|
+
inputTokens: tokensIn,
|
|
601
|
+
outputTokens: tokensOut
|
|
602
|
+
},
|
|
603
|
+
costUsd
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
} finally {
|
|
607
|
+
await exec.teardown("brutalKill").catch(() => {
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
},
|
|
611
|
+
async delete() {
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/runtime/cli-bridge-sandbox-client.ts
|
|
619
|
+
var DEFAULT_BRIDGE_URL = "http://127.0.0.1:3355";
|
|
620
|
+
var BRIDGE_TIMEOUT_MS = 9e5;
|
|
621
|
+
function bridgeModelId(harness, model) {
|
|
622
|
+
return model.startsWith(`${harness}/`) ? model : `${harness}/${model}`;
|
|
623
|
+
}
|
|
624
|
+
function resolveTarget(cfg, createOptions) {
|
|
625
|
+
const backend = createOptions?.backend;
|
|
626
|
+
const harness = backend?.type ?? cfg.harness;
|
|
627
|
+
const model = backend?.model?.model ?? cfg.model;
|
|
628
|
+
if (!harness)
|
|
629
|
+
throw new Error(
|
|
630
|
+
"cliBridgeSandboxClient: no harness (set cfg.harness or create({ backend: { type } }))"
|
|
631
|
+
);
|
|
632
|
+
if (!model)
|
|
633
|
+
throw new Error(
|
|
634
|
+
"cliBridgeSandboxClient: no model (set cfg.model or create({ backend: { model: { model } } }))"
|
|
635
|
+
);
|
|
636
|
+
return { harness, model };
|
|
637
|
+
}
|
|
638
|
+
async function bridgePost(url, bearer, bridgeModel, prompt, signal) {
|
|
639
|
+
const res = await fetch(`${url}/v1/chat/completions`, {
|
|
640
|
+
method: "POST",
|
|
641
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${bearer}` },
|
|
642
|
+
body: JSON.stringify({ model: bridgeModel, messages: [{ role: "user", content: prompt }] }),
|
|
643
|
+
signal
|
|
644
|
+
});
|
|
645
|
+
if (!res.ok) {
|
|
646
|
+
throw new Error(
|
|
647
|
+
`cli-bridge ${bridgeModel}: HTTP ${res.status} ${(await res.text()).slice(0, 300)}`
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
const j = await res.json();
|
|
651
|
+
if (j.error) throw new Error(`cli-bridge ${bridgeModel}: ${j.error.message}`);
|
|
652
|
+
return {
|
|
653
|
+
content: j.choices?.[0]?.message?.content ?? "",
|
|
654
|
+
input: j.usage?.prompt_tokens ?? 0,
|
|
655
|
+
output: j.usage?.completion_tokens ?? 0
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
function cliBridgeSandboxClient(cfg) {
|
|
659
|
+
if (!cfg.bearer) throw new Error("cliBridgeSandboxClient: bearer is required");
|
|
660
|
+
const url = cfg.url ?? DEFAULT_BRIDGE_URL;
|
|
661
|
+
let seq = 0;
|
|
662
|
+
const factory = (_spec, ctx) => {
|
|
663
|
+
const id = `cli-bridge-${seq++}`;
|
|
664
|
+
const createOptions = ctx.seams.createOptions;
|
|
665
|
+
const { harness, model } = resolveTarget(cfg, createOptions);
|
|
666
|
+
const bridgeModel = bridgeModelId(harness, model);
|
|
667
|
+
let artifact;
|
|
668
|
+
return {
|
|
669
|
+
runtime: "cli",
|
|
670
|
+
async execute(task, signal) {
|
|
671
|
+
const started = Date.now();
|
|
672
|
+
const timeout = AbortSignal.timeout(BRIDGE_TIMEOUT_MS);
|
|
673
|
+
const composed = AbortSignal.any([signal, timeout]);
|
|
674
|
+
const r = await bridgePost(url, cfg.bearer, bridgeModel, String(task), composed);
|
|
675
|
+
artifact = {
|
|
676
|
+
outRef: `cli-bridge:${id}`,
|
|
677
|
+
out: { content: r.content },
|
|
678
|
+
spent: {
|
|
679
|
+
iterations: 1,
|
|
680
|
+
tokens: { input: r.input, output: r.output },
|
|
681
|
+
usd: 0,
|
|
682
|
+
ms: Date.now() - started
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
return artifact;
|
|
686
|
+
},
|
|
687
|
+
teardown: () => Promise.resolve({ destroyed: true }),
|
|
688
|
+
resultArtifact() {
|
|
689
|
+
if (!artifact)
|
|
690
|
+
throw new Error("cliBridgeSandboxClient: resultArtifact() read before execute()");
|
|
691
|
+
return artifact;
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
};
|
|
695
|
+
return inlineSandboxClient(factory);
|
|
696
|
+
}
|
|
697
|
+
|
|
208
698
|
// src/runtime/completion.ts
|
|
209
699
|
function completionAuthorizes(v, policy) {
|
|
210
700
|
if (!v?.done) return false;
|
|
@@ -466,7 +956,7 @@ import { mkdtempSync, rmSync } from "fs";
|
|
|
466
956
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
467
957
|
import { tmpdir } from "os";
|
|
468
958
|
import { dirname, join } from "path";
|
|
469
|
-
function
|
|
959
|
+
function isAsyncIterable2(v) {
|
|
470
960
|
return typeof v === "object" && v !== null && Symbol.asyncIterator in v;
|
|
471
961
|
}
|
|
472
962
|
function inProcessSandboxClient(options) {
|
|
@@ -517,7 +1007,7 @@ function inProcessSandboxClient(options) {
|
|
|
517
1007
|
const ctx = { round, workdir: boxWorkdir, signal };
|
|
518
1008
|
round += 1;
|
|
519
1009
|
const produced = await onPrompt(prompt, ctx);
|
|
520
|
-
if (
|
|
1010
|
+
if (isAsyncIterable2(produced)) {
|
|
521
1011
|
for await (const ev of produced) yield ev;
|
|
522
1012
|
} else {
|
|
523
1013
|
for (const ev of produced) yield ev;
|
|
@@ -533,65 +1023,6 @@ function inProcessSandboxClient(options) {
|
|
|
533
1023
|
};
|
|
534
1024
|
}
|
|
535
1025
|
|
|
536
|
-
// src/runtime/inline-sandbox-client.ts
|
|
537
|
-
function isAsyncIterable2(v) {
|
|
538
|
-
return typeof v === "object" && v !== null && Symbol.asyncIterator in v;
|
|
539
|
-
}
|
|
540
|
-
async function settle(exec, task, signal) {
|
|
541
|
-
const r = exec.execute(task, signal);
|
|
542
|
-
if (isAsyncIterable2(r)) {
|
|
543
|
-
for await (const _ of r) {
|
|
544
|
-
}
|
|
545
|
-
return exec.resultArtifact();
|
|
546
|
-
}
|
|
547
|
-
return r;
|
|
548
|
-
}
|
|
549
|
-
function inlineSandboxClient(factory) {
|
|
550
|
-
let seq = 0;
|
|
551
|
-
return {
|
|
552
|
-
async create(_options) {
|
|
553
|
-
const id = `inline-${seq++}`;
|
|
554
|
-
return {
|
|
555
|
-
id,
|
|
556
|
-
async *streamPrompt(message) {
|
|
557
|
-
const controller = new AbortController();
|
|
558
|
-
const spec = { profile: { name: id }, harness: null };
|
|
559
|
-
const exec = factory(spec, { signal: controller.signal, seams: {} });
|
|
560
|
-
try {
|
|
561
|
-
const artifact = await settle(exec, message, controller.signal);
|
|
562
|
-
const out = artifact.out;
|
|
563
|
-
const tokensIn = artifact.spent.tokens.input;
|
|
564
|
-
const tokensOut = artifact.spent.tokens.output;
|
|
565
|
-
const costUsd = artifact.spent.usd;
|
|
566
|
-
if (tokensIn || tokensOut || costUsd) {
|
|
567
|
-
yield {
|
|
568
|
-
type: "llm_call",
|
|
569
|
-
data: { tokensIn, tokensOut, costUsd }
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
yield {
|
|
573
|
-
type: "result",
|
|
574
|
-
data: {
|
|
575
|
-
finalText: out?.content ?? "",
|
|
576
|
-
tokenUsage: {
|
|
577
|
-
inputTokens: tokensIn,
|
|
578
|
-
outputTokens: tokensOut
|
|
579
|
-
},
|
|
580
|
-
costUsd
|
|
581
|
-
}
|
|
582
|
-
};
|
|
583
|
-
} finally {
|
|
584
|
-
await exec.teardown("brutalKill").catch(() => {
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
},
|
|
588
|
-
async delete() {
|
|
589
|
-
}
|
|
590
|
-
};
|
|
591
|
-
}
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
|
|
595
1026
|
// src/runtime/report-usage.ts
|
|
596
1027
|
function reportLoopUsage(cost, result, source = "loop") {
|
|
597
1028
|
cost.observe(result.costUsd, source);
|
|
@@ -608,6 +1039,9 @@ function campaignTraceToLoopEmitter(trace) {
|
|
|
608
1039
|
}
|
|
609
1040
|
async function runLoopForCell(opts, scenario, profile, ctx) {
|
|
610
1041
|
const loopOptions = opts.toLoopOptions(scenario, profile);
|
|
1042
|
+
return runLoopWithCampaignContext(opts, loopOptions, ctx);
|
|
1043
|
+
}
|
|
1044
|
+
async function runLoopWithCampaignContext(opts, loopOptions, ctx) {
|
|
611
1045
|
const result = await runLoop({
|
|
612
1046
|
...loopOptions,
|
|
613
1047
|
ctx: {
|
|
@@ -620,6 +1054,9 @@ async function runLoopForCell(opts, scenario, profile, ctx) {
|
|
|
620
1054
|
const toArtifact = opts.toArtifact ?? ((r) => r.winner?.output);
|
|
621
1055
|
return toArtifact(result);
|
|
622
1056
|
}
|
|
1057
|
+
function loopCampaignDispatch(opts) {
|
|
1058
|
+
return (scenario, ctx) => runLoopWithCampaignContext(opts, opts.toLoopOptions(scenario), ctx);
|
|
1059
|
+
}
|
|
623
1060
|
function loopDispatch(opts) {
|
|
624
1061
|
return (profile, scenario, ctx) => runLoopForCell(opts, scenario, profile, ctx);
|
|
625
1062
|
}
|
|
@@ -1863,7 +2300,7 @@ function promotionGate(opts) {
|
|
|
1863
2300
|
}
|
|
1864
2301
|
|
|
1865
2302
|
// src/runtime/run-benchmark.ts
|
|
1866
|
-
import { pairedBootstrap, paretoFrontier } from "@tangle-network/agent-eval";
|
|
2303
|
+
import { pairedBootstrap as pairedBootstrap2, paretoFrontier } from "@tangle-network/agent-eval";
|
|
1867
2304
|
|
|
1868
2305
|
// src/runtime/strategy.ts
|
|
1869
2306
|
import { createChatClient, estimateCost, isModelPriced } from "@tangle-network/agent-eval";
|
|
@@ -2560,15 +2997,15 @@ async function runBenchmark(cfg) {
|
|
|
2560
2997
|
const ok = perTask.filter(
|
|
2561
2998
|
(r) => !!r.cells
|
|
2562
2999
|
);
|
|
2563
|
-
const
|
|
3000
|
+
const mean2 = (xs) => xs.length ? xs.reduce((s, x) => s + x, 0) / xs.length : 0;
|
|
2564
3001
|
const perStrategy = {};
|
|
2565
3002
|
for (const s of strategies) {
|
|
2566
3003
|
const cells = ok.map((r) => r.cells[s.name]).filter((c) => !!c);
|
|
2567
3004
|
perStrategy[s.name] = {
|
|
2568
|
-
score:
|
|
2569
|
-
resolved:
|
|
2570
|
-
usd:
|
|
2571
|
-
ms:
|
|
3005
|
+
score: mean2(cells.map((c) => c.score)),
|
|
3006
|
+
resolved: mean2(cells.map((c) => c.resolved ? 1 : 0)),
|
|
3007
|
+
usd: mean2(cells.map((c) => c.usd)),
|
|
3008
|
+
ms: mean2(cells.map((c) => c.ms))
|
|
2572
3009
|
};
|
|
2573
3010
|
}
|
|
2574
3011
|
const frontier = paretoFrontier(
|
|
@@ -2587,7 +3024,7 @@ async function runBenchmark(cfg) {
|
|
|
2587
3024
|
};
|
|
2588
3025
|
const names = strategies.map((s) => s.name);
|
|
2589
3026
|
if (names.includes("refine") && names.includes("sample") && ok.length >= 2) {
|
|
2590
|
-
const b =
|
|
3027
|
+
const b = pairedBootstrap2(
|
|
2591
3028
|
ok.map((r) => r.cells.sample?.score ?? 0),
|
|
2592
3029
|
ok.map((r) => r.cells.refine?.score ?? 0)
|
|
2593
3030
|
);
|
|
@@ -2596,7 +3033,7 @@ async function runBenchmark(cfg) {
|
|
|
2596
3033
|
return report;
|
|
2597
3034
|
}
|
|
2598
3035
|
function printBenchmarkReport(report) {
|
|
2599
|
-
const
|
|
3036
|
+
const pct2 = (x) => `${(x * 100).toFixed(1)}%`;
|
|
2600
3037
|
const pp = (x) => `${x >= 0 ? "+" : ""}${(x * 100).toFixed(1)}pp`;
|
|
2601
3038
|
console.log(
|
|
2602
3039
|
`
|
|
@@ -2607,7 +3044,7 @@ function printBenchmarkReport(report) {
|
|
|
2607
3044
|
);
|
|
2608
3045
|
for (const [s, v] of Object.entries(report.perStrategy))
|
|
2609
3046
|
console.log(
|
|
2610
|
-
` ${(report.pareto.includes(s) ? `${s} *` : s).padEnd(16)} ${
|
|
3047
|
+
` ${(report.pareto.includes(s) ? `${s} *` : s).padEnd(16)} ${pct2(v.score).padStart(7)} ${pct2(v.resolved).padStart(9)} ${`$${v.usd.toFixed(3)}`.padStart(8)} ${(v.ms / 1e3).toFixed(0).padStart(6)}s`
|
|
2611
3048
|
);
|
|
2612
3049
|
if (report.pareto.length) console.log(` * = on the (score, $) Pareto frontier`);
|
|
2613
3050
|
for (const row of report.perTask)
|
|
@@ -3824,6 +4261,153 @@ function worktreeFanout(options) {
|
|
|
3824
4261
|
});
|
|
3825
4262
|
}
|
|
3826
4263
|
|
|
4264
|
+
// src/runtime/supervise-surface.ts
|
|
4265
|
+
function captureFailures(base) {
|
|
4266
|
+
let lastReport = "";
|
|
4267
|
+
const surface = {
|
|
4268
|
+
name: base.name,
|
|
4269
|
+
open: (t) => base.open(t),
|
|
4270
|
+
tools: (t, h) => base.tools(t, h),
|
|
4271
|
+
async call(h, name, args) {
|
|
4272
|
+
const out = await base.call(h, name, args);
|
|
4273
|
+
if (name === "run_tests") lastReport = out;
|
|
4274
|
+
return out;
|
|
4275
|
+
},
|
|
4276
|
+
score: (t, h) => base.score(t, h),
|
|
4277
|
+
close: (h) => base.close(h)
|
|
4278
|
+
};
|
|
4279
|
+
const failing = () => {
|
|
4280
|
+
const body = /FAILING:\s*(.+)/i.exec(lastReport)?.[1];
|
|
4281
|
+
return body ? body.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
4282
|
+
};
|
|
4283
|
+
return { surface, failing };
|
|
4284
|
+
}
|
|
4285
|
+
function failuresAnalyst() {
|
|
4286
|
+
return {
|
|
4287
|
+
kinds: [
|
|
4288
|
+
{
|
|
4289
|
+
id: "failures",
|
|
4290
|
+
description: "Surface the worker's still-failing tests so the driver targets them next.",
|
|
4291
|
+
area: "progress"
|
|
4292
|
+
}
|
|
4293
|
+
],
|
|
4294
|
+
run: async (_kindId, trace) => {
|
|
4295
|
+
const w = trace ?? {};
|
|
4296
|
+
if (!(typeof w === "object" && w !== null && "resolved" in w))
|
|
4297
|
+
return { summary: `worker produced: ${JSON.stringify(trace).slice(0, 300)}` };
|
|
4298
|
+
if (w.resolved) return { summary: "worker RESOLVED \u2014 every check passed; stop." };
|
|
4299
|
+
const failing = w.failing ?? [];
|
|
4300
|
+
const head = `worker did NOT resolve \u2014 score ${(100 * (w.score ?? 0)).toFixed(0)}%, ${w.shots ?? "?"} shot(s)`;
|
|
4301
|
+
return {
|
|
4302
|
+
summary: failing.length ? `${head}. STILL FAILING (${failing.length}): ${failing.slice(0, 12).join(", ")}. Spawn the next worker to fix exactly these; if a test keeps failing across workers, give it concrete guidance about that case.` : `${head}. (no failing-test list available this round)`
|
|
4303
|
+
};
|
|
4304
|
+
}
|
|
4305
|
+
};
|
|
4306
|
+
}
|
|
4307
|
+
function surfaceWorkerExecutor(surface, task, worker, strategy) {
|
|
4308
|
+
let artifact;
|
|
4309
|
+
return {
|
|
4310
|
+
runtime: "surface-worker",
|
|
4311
|
+
async execute(brief) {
|
|
4312
|
+
const guidance = typeof brief === "string" ? brief.trim() : brief ? JSON.stringify(brief) : "";
|
|
4313
|
+
const attemptTask = guidance ? {
|
|
4314
|
+
...task,
|
|
4315
|
+
systemPrompt: `${task.systemPrompt ?? ""}
|
|
4316
|
+
|
|
4317
|
+
\u2014 Supervisor guidance for THIS attempt (incorporate it; do not just repeat a prior approach) \u2014
|
|
4318
|
+
${guidance}`
|
|
4319
|
+
} : task;
|
|
4320
|
+
const cap = captureFailures(surface);
|
|
4321
|
+
const r = await runAgentic({
|
|
4322
|
+
surface: cap.surface,
|
|
4323
|
+
task: attemptTask,
|
|
4324
|
+
strategy,
|
|
4325
|
+
budget: worker.budget ?? 1,
|
|
4326
|
+
routerBaseUrl: worker.routerBaseUrl,
|
|
4327
|
+
routerKey: worker.routerKey,
|
|
4328
|
+
model: worker.model,
|
|
4329
|
+
...worker.maxTokens !== void 0 ? { maxTokens: worker.maxTokens } : {},
|
|
4330
|
+
...worker.innerTurns !== void 0 ? { innerTurns: worker.innerTurns } : {}
|
|
4331
|
+
});
|
|
4332
|
+
const out = {
|
|
4333
|
+
resolved: r.resolved,
|
|
4334
|
+
score: r.score,
|
|
4335
|
+
shots: r.shots,
|
|
4336
|
+
summary: `${strategy.name} ${r.shots} shot(s) \u2192 ${(100 * r.score).toFixed(0)}% (${r.resolved ? "resolved" : "unresolved"})`,
|
|
4337
|
+
failing: r.resolved ? [] : cap.failing()
|
|
4338
|
+
};
|
|
4339
|
+
const spent = { iterations: r.completions, tokens: r.tokens, usd: r.usd, ms: r.ms };
|
|
4340
|
+
artifact = {
|
|
4341
|
+
outRef: `surface-worker:${task.id}:${r.shots}:${r.resolved ? "ok" : "no"}`,
|
|
4342
|
+
out,
|
|
4343
|
+
verdict: { valid: r.resolved, score: r.score },
|
|
4344
|
+
spent
|
|
4345
|
+
};
|
|
4346
|
+
return artifact;
|
|
4347
|
+
},
|
|
4348
|
+
teardown: () => Promise.resolve({ destroyed: true }),
|
|
4349
|
+
resultArtifact() {
|
|
4350
|
+
if (!artifact) throw new Error("surfaceWorkerExecutor: resultArtifact before execute");
|
|
4351
|
+
return artifact;
|
|
4352
|
+
}
|
|
4353
|
+
};
|
|
4354
|
+
}
|
|
4355
|
+
async function superviseSurface(profile, task, opts) {
|
|
4356
|
+
const strategy = opts.strategy ?? refine;
|
|
4357
|
+
const innerTurns = opts.worker.innerTurns ?? 6;
|
|
4358
|
+
const router = opts.router ?? {
|
|
4359
|
+
routerBaseUrl: opts.worker.routerBaseUrl,
|
|
4360
|
+
routerKey: opts.worker.routerKey,
|
|
4361
|
+
model: opts.worker.model
|
|
4362
|
+
};
|
|
4363
|
+
const budget = opts.budget ?? {
|
|
4364
|
+
maxIterations: (innerTurns + 2) * 5 + 16,
|
|
4365
|
+
maxTokens: (opts.worker.maxTokens ?? 4e3) * 8
|
|
4366
|
+
};
|
|
4367
|
+
const makeWorkerAgent = (rawProfile) => {
|
|
4368
|
+
const p = rawProfile ?? {};
|
|
4369
|
+
const name = typeof p.name === "string" && p.name.length > 0 ? p.name : "surface-worker";
|
|
4370
|
+
const spec = {
|
|
4371
|
+
profile: rawProfile,
|
|
4372
|
+
harness: null,
|
|
4373
|
+
executor: surfaceWorkerExecutor(
|
|
4374
|
+
opts.surface,
|
|
4375
|
+
task,
|
|
4376
|
+
opts.worker,
|
|
4377
|
+
strategy
|
|
4378
|
+
)
|
|
4379
|
+
};
|
|
4380
|
+
return { name, act: async () => "", executorSpec: spec };
|
|
4381
|
+
};
|
|
4382
|
+
const deliverable = {
|
|
4383
|
+
describe: `resolve the surface task ${task.id} (every required check passes)`,
|
|
4384
|
+
check: (out2) => out2?.resolved === true
|
|
4385
|
+
};
|
|
4386
|
+
const analysts = opts.analysts === null ? void 0 : opts.analysts ?? failuresAnalyst();
|
|
4387
|
+
const result = await supervise(profile, task, {
|
|
4388
|
+
makeWorkerAgent,
|
|
4389
|
+
deliverable,
|
|
4390
|
+
budget,
|
|
4391
|
+
maxLiveWorkers: opts.maxLiveWorkers ?? 1,
|
|
4392
|
+
// A SMALL per-worker reservation so MULTIPLE workers fit the pool (the default reserves the whole pool
|
|
4393
|
+
// per worker → only one ever spawns, defeating the spawn-a-targeted-worker steering).
|
|
4394
|
+
perWorker: { maxIterations: innerTurns + 2, maxTokens: opts.worker.maxTokens ?? 4e3 },
|
|
4395
|
+
router,
|
|
4396
|
+
...analysts ? { analysts, analyzeOnSettle: analysts.kinds.map((k) => k.id) } : {}
|
|
4397
|
+
});
|
|
4398
|
+
const out = result.kind === "winner" ? result.out : void 0;
|
|
4399
|
+
const sp = result.spentTotal;
|
|
4400
|
+
return {
|
|
4401
|
+
resolved: out?.resolved ?? false,
|
|
4402
|
+
score: out?.score ?? 0,
|
|
4403
|
+
usd: sp.usd,
|
|
4404
|
+
tokensIn: sp.tokens.input,
|
|
4405
|
+
tokensOut: sp.tokens.output,
|
|
4406
|
+
ms: sp.ms,
|
|
4407
|
+
completions: sp.iterations
|
|
4408
|
+
};
|
|
4409
|
+
}
|
|
4410
|
+
|
|
3827
4411
|
// src/runtime/verifier-environment.ts
|
|
3828
4412
|
var submitTool = {
|
|
3829
4413
|
type: "function",
|
|
@@ -4116,6 +4700,14 @@ export {
|
|
|
4116
4700
|
renderAnytimeTable,
|
|
4117
4701
|
defaultAuditorInstruction,
|
|
4118
4702
|
auditIntent,
|
|
4703
|
+
leaderboard,
|
|
4704
|
+
pairwiseSignificance,
|
|
4705
|
+
renderLeaderboardMarkdown,
|
|
4706
|
+
renderPairwiseMarkdown,
|
|
4707
|
+
renderLeaderboardSvg,
|
|
4708
|
+
renderLeaderboardHtml,
|
|
4709
|
+
inlineSandboxClient,
|
|
4710
|
+
cliBridgeSandboxClient,
|
|
4119
4711
|
completionAuthorizes,
|
|
4120
4712
|
stopSentinel,
|
|
4121
4713
|
sentinelCompletion,
|
|
@@ -4125,8 +4717,8 @@ export {
|
|
|
4125
4717
|
renderReport,
|
|
4126
4718
|
harvestCorpus,
|
|
4127
4719
|
inProcessSandboxClient,
|
|
4128
|
-
inlineSandboxClient,
|
|
4129
4720
|
reportLoopUsage,
|
|
4721
|
+
loopCampaignDispatch,
|
|
4130
4722
|
loopDispatch,
|
|
4131
4723
|
createMcpEnvironment,
|
|
4132
4724
|
assertTraceDerivedFindings,
|
|
@@ -4182,6 +4774,8 @@ export {
|
|
|
4182
4774
|
sandboxSessionTraceSource,
|
|
4183
4775
|
analyzeTrace,
|
|
4184
4776
|
worktreeFanout,
|
|
4777
|
+
failuresAnalyst,
|
|
4778
|
+
superviseSurface,
|
|
4185
4779
|
createVerifierEnvironment,
|
|
4186
4780
|
createWaterfallCollector,
|
|
4187
4781
|
localShell,
|
|
@@ -4191,4 +4785,4 @@ export {
|
|
|
4191
4785
|
computeFindingId,
|
|
4192
4786
|
makeFinding2 as makeFinding
|
|
4193
4787
|
};
|
|
4194
|
-
//# sourceMappingURL=chunk-
|
|
4788
|
+
//# sourceMappingURL=chunk-QSO2TVDS.js.map
|