@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.
Files changed (48) hide show
  1. package/README.md +54 -325
  2. package/dist/agent.js +5 -5
  3. package/dist/analyst-loop.js +2 -2
  4. package/dist/{chunk-VMNEQHJR.js → chunk-3X53HYRW.js} +17 -2
  5. package/dist/chunk-3X53HYRW.js.map +1 -0
  6. package/dist/{chunk-T2HVQVB4.js → chunk-4J6RBI3K.js} +15 -1
  7. package/dist/chunk-4J6RBI3K.js.map +1 -0
  8. package/dist/{chunk-IODKUOBA.js → chunk-C2FZ6GR6.js} +2 -2
  9. package/dist/{chunk-63MHOCIE.js → chunk-DH72UOYR.js} +4 -4
  10. package/dist/{chunk-Z3RRRPRB.js → chunk-H7IBHAFT.js} +23 -14
  11. package/dist/chunk-H7IBHAFT.js.map +1 -0
  12. package/dist/{chunk-PVPFDTO3.js → chunk-LLJRUTE7.js} +2 -2
  13. package/dist/{chunk-PBE35ULD.js → chunk-M3Y362RW.js} +2 -2
  14. package/dist/{chunk-AG335EXG.js → chunk-QSO2TVDS.js} +668 -74
  15. package/dist/chunk-QSO2TVDS.js.map +1 -0
  16. package/dist/{chunk-KRULXIWS.js → chunk-TPII5AU7.js} +55 -7
  17. package/dist/chunk-TPII5AU7.js.map +1 -0
  18. package/dist/{coordination-DCmljYDf.d.ts → coordination-BI9tpcmF.d.ts} +12 -3
  19. package/dist/environment-provider.d.ts +1 -1
  20. package/dist/environment-provider.js +1 -1
  21. package/dist/index.d.ts +4 -4
  22. package/dist/index.js +8 -8
  23. package/dist/intelligence.d.ts +30 -2
  24. package/dist/intelligence.js +33 -23
  25. package/dist/intelligence.js.map +1 -1
  26. package/dist/{loop-runner-bin-C4X0FZ2Z.d.ts → loop-runner-bin-CBkLsyFg.d.ts} +2 -2
  27. package/dist/loop-runner-bin.d.ts +4 -4
  28. package/dist/loop-runner-bin.js +7 -7
  29. package/dist/loops.d.ts +265 -14
  30. package/dist/loops.js +28 -6
  31. package/dist/mcp/bin.js +5 -5
  32. package/dist/mcp/index.d.ts +6 -6
  33. package/dist/mcp/index.js +7 -7
  34. package/dist/{router-client-Ak2IGuXq.d.ts → router-client-D6Ocf4jG.d.ts} +19 -0
  35. package/dist/{types-C1sozrte.d.ts → types-By9LXllv.d.ts} +9 -2
  36. package/dist/{worktree-fanout-CXGzHET4.d.ts → worktree-fanout-D9Z2dMS9.d.ts} +2 -2
  37. package/dist/{worktree-harness-Bmho9SH0.d.ts → worktree-harness-Dx8XULW3.d.ts} +1 -1
  38. package/package.json +1 -1
  39. package/skills/build-with-agent-runtime/SKILL.md +53 -23
  40. package/dist/chunk-AG335EXG.js.map +0 -1
  41. package/dist/chunk-KRULXIWS.js.map +0 -1
  42. package/dist/chunk-T2HVQVB4.js.map +0 -1
  43. package/dist/chunk-VMNEQHJR.js.map +0 -1
  44. package/dist/chunk-Z3RRRPRB.js.map +0 -1
  45. /package/dist/{chunk-IODKUOBA.js.map → chunk-C2FZ6GR6.js.map} +0 -0
  46. /package/dist/{chunk-63MHOCIE.js.map → chunk-DH72UOYR.js.map} +0 -0
  47. /package/dist/{chunk-PVPFDTO3.js.map → chunk-LLJRUTE7.js.map} +0 -0
  48. /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-KRULXIWS.js";
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-Z3RRRPRB.js";
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
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 isAsyncIterable(v) {
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 (isAsyncIterable(produced)) {
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 mean = (xs) => xs.length ? xs.reduce((s, x) => s + x, 0) / xs.length : 0;
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: mean(cells.map((c) => c.score)),
2569
- resolved: mean(cells.map((c) => c.resolved ? 1 : 0)),
2570
- usd: mean(cells.map((c) => c.usd)),
2571
- ms: mean(cells.map((c) => c.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 = pairedBootstrap(
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 pct = (x) => `${(x * 100).toFixed(1)}%`;
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)} ${pct(v.score).padStart(7)} ${pct(v.resolved).padStart(9)} ${`$${v.usd.toFixed(3)}`.padStart(8)} ${(v.ms / 1e3).toFixed(0).padStart(6)}s`
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-AG335EXG.js.map
4788
+ //# sourceMappingURL=chunk-QSO2TVDS.js.map