@tangle-network/agent-runtime 0.101.1 → 0.102.1

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 (78) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +5 -3
  3. package/dist/agent.js.map +1 -1
  4. package/dist/analyst-loop.d.ts +1 -1
  5. package/dist/candidate-execution/index.d.ts +13 -2
  6. package/dist/candidate-execution/index.js +8 -3
  7. package/dist/chunk-377GOJHJ.js +578 -0
  8. package/dist/chunk-377GOJHJ.js.map +1 -0
  9. package/dist/{chunk-DI677IPX.js → chunk-3DW5DEKQ.js} +3 -3
  10. package/dist/{chunk-KVJQV342.js → chunk-6MR4IJRW.js} +25 -1777
  11. package/dist/chunk-6MR4IJRW.js.map +1 -0
  12. package/dist/{chunk-RJPQLUDA.js → chunk-7FJJUC73.js} +336 -43
  13. package/dist/chunk-7FJJUC73.js.map +1 -0
  14. package/dist/{chunk-TA4RBJLE.js → chunk-CI7WS6S2.js} +5 -5
  15. package/dist/{chunk-U4PRAATQ.js → chunk-CK76OZPM.js} +3 -3
  16. package/dist/{chunk-KSBUSEUA.js → chunk-KJ2Q4T7F.js} +2 -2
  17. package/dist/{chunk-MAONWP4R.js → chunk-KPHTCHQ4.js} +611 -1419
  18. package/dist/chunk-KPHTCHQ4.js.map +1 -0
  19. package/dist/{chunk-BXZ7GPL4.js → chunk-KSM6GFHP.js} +2 -2
  20. package/dist/chunk-L5DST3QC.js +351 -0
  21. package/dist/chunk-L5DST3QC.js.map +1 -0
  22. package/dist/{chunk-HGSHPVJ6.js → chunk-LJLG734E.js} +200 -441
  23. package/dist/chunk-LJLG734E.js.map +1 -0
  24. package/dist/chunk-ROILMKDL.js +1338 -0
  25. package/dist/chunk-ROILMKDL.js.map +1 -0
  26. package/dist/{chunk-N2CEE5Q3.js → chunk-RTB3TC73.js} +3 -3
  27. package/dist/chunk-SQ3ZJH3Y.js +3082 -0
  28. package/dist/chunk-SQ3ZJH3Y.js.map +1 -0
  29. package/dist/chunk-UPWGXKXB.js +254 -0
  30. package/dist/chunk-UPWGXKXB.js.map +1 -0
  31. package/dist/{completion-gate-C80jiRfN.d.ts → completion-gate-C6dhVN-N.d.ts} +2 -2
  32. package/dist/{coordination-BFE3Den7.d.ts → coordination-D9l_YmwW.d.ts} +6 -6
  33. package/dist/environment-provider.d.ts +2 -2
  34. package/dist/{improve-g75IE2Cx.d.ts → improve-B40dRu0X.d.ts} +47 -19
  35. package/dist/index.d.ts +331 -23
  36. package/dist/index.js +544 -136
  37. package/dist/index.js.map +1 -1
  38. package/dist/intelligence.d.ts +63 -62
  39. package/dist/intelligence.js +62 -471
  40. package/dist/intelligence.js.map +1 -1
  41. package/dist/knowledge.d.ts +8 -8
  42. package/dist/knowledge.js +9 -7
  43. package/dist/{local-harness-ZqCx51u7.d.ts → local-harness-CtK9dSny.d.ts} +14 -2
  44. package/dist/{loop-runner-bin-Cn1N2rRo.d.ts → loop-runner-bin-PnWslIw4.d.ts} +2 -2
  45. package/dist/loop-runner-bin.d.ts +6 -6
  46. package/dist/loop-runner-bin.js +6 -4
  47. package/dist/loops.d.ts +231 -460
  48. package/dist/loops.js +58 -37
  49. package/dist/mcp/bin.js +2 -2
  50. package/dist/mcp/index.d.ts +184 -12
  51. package/dist/mcp/index.js +31 -9
  52. package/dist/mcp/index.js.map +1 -1
  53. package/dist/mcp/memory-bin.d.ts +1 -0
  54. package/dist/mcp/memory-bin.js +22 -0
  55. package/dist/mcp/memory-bin.js.map +1 -0
  56. package/dist/profiles.d.ts +3 -3
  57. package/dist/structural-rollout-D7xik9XR.d.ts +446 -0
  58. package/dist/{substrate-DO2GHNg2.d.ts → substrate-Dyiqmd3o.d.ts} +1 -1
  59. package/dist/{supervise-BLPI50-w.d.ts → supervise-BQdNAXtK.d.ts} +4 -4
  60. package/dist/testing.js +255 -211
  61. package/dist/testing.js.map +1 -1
  62. package/dist/{types-B3vAW0Oq.d.ts → types-CLat4bT9.d.ts} +1 -1
  63. package/dist/{types-CmnA2iL3.d.ts → types-D870JlH0.d.ts} +2 -2
  64. package/dist/{worktree-fanout-DCA3G4bO.d.ts → worktree-fanout-DsIR4d6w.d.ts} +234 -234
  65. package/package.json +6 -5
  66. package/dist/chunk-HGSHPVJ6.js.map +0 -1
  67. package/dist/chunk-IKGCKPDX.js +0 -1115
  68. package/dist/chunk-IKGCKPDX.js.map +0 -1
  69. package/dist/chunk-KVJQV342.js.map +0 -1
  70. package/dist/chunk-MAONWP4R.js.map +0 -1
  71. package/dist/chunk-RJPQLUDA.js.map +0 -1
  72. package/dist/{chunk-DI677IPX.js.map → chunk-3DW5DEKQ.js.map} +0 -0
  73. package/dist/{chunk-TA4RBJLE.js.map → chunk-CI7WS6S2.js.map} +0 -0
  74. package/dist/{chunk-U4PRAATQ.js.map → chunk-CK76OZPM.js.map} +0 -0
  75. package/dist/{chunk-KSBUSEUA.js.map → chunk-KJ2Q4T7F.js.map} +0 -0
  76. package/dist/{chunk-BXZ7GPL4.js.map → chunk-KSM6GFHP.js.map} +0 -0
  77. package/dist/{chunk-N2CEE5Q3.js.map → chunk-RTB3TC73.js.map} +0 -0
  78. package/dist/{sanitize-BTSsdBXw.d.ts → sanitize-DEbPNtyI.d.ts} +58 -58
@@ -16,12 +16,17 @@ import {
16
16
  verifiedResourceTextByDigest,
17
17
  verifyAgentCandidateBundle,
18
18
  verifyCanonicalCandidateDocument
19
- } from "./chunk-HGSHPVJ6.js";
19
+ } from "./chunk-LJLG734E.js";
20
+ import {
21
+ defaultStructuralRolloutPolicy,
22
+ optimizerMethod
23
+ } from "./chunk-ROILMKDL.js";
20
24
  import {
21
25
  assertModelAllowed,
22
26
  harnessInvocation,
23
- runLocalHarness
24
- } from "./chunk-IKGCKPDX.js";
27
+ runLocalHarness,
28
+ runSettledCommand
29
+ } from "./chunk-SQ3ZJH3Y.js";
25
30
  import {
26
31
  runAnalystLoop
27
32
  } from "./chunk-FD2MBMOH.js";
@@ -80,6 +85,7 @@ function agenticGenerator(opts = {}) {
80
85
  costLedger,
81
86
  costPhase
82
87
  }) {
88
+ signal.throwIfAborted();
83
89
  let reproducibleCostLedger;
84
90
  if (opts.codexReproducible) {
85
91
  if (!costLedger) {
@@ -97,7 +103,7 @@ function agenticGenerator(opts = {}) {
97
103
  const shots = Math.max(1, maxShots);
98
104
  let attemptNote = "";
99
105
  for (let shot = 0; shot < shots; shot++) {
100
- if (signal.aborted) break;
106
+ signal.throwIfAborted();
101
107
  const taskPrompt = attemptNote ? `${basePrompt}
102
108
 
103
109
  ${attemptNote}` : basePrompt;
@@ -191,6 +197,7 @@ ${attemptNote}` : basePrompt;
191
197
  error: shotError
192
198
  });
193
199
  await emitShotReceipt(opts.onShotCompleted, receipt, execution, shotError);
200
+ signal.throwIfAborted();
194
201
  if (!execution) {
195
202
  throw new Error("agenticGenerator: author shot completed without a harness result");
196
203
  }
@@ -198,6 +205,7 @@ ${attemptNote}` : basePrompt;
198
205
  try {
199
206
  worktreeChanged = dirty(worktreePath);
200
207
  } catch (cause) {
208
+ signal.throwIfAborted();
201
209
  return rethrowShotSetupError(
202
210
  opts.onShotDisposition,
203
211
  receipt,
@@ -207,10 +215,12 @@ ${attemptNote}` : basePrompt;
207
215
  );
208
216
  }
209
217
  if (!worktreeChanged) {
218
+ signal.throwIfAborted();
210
219
  await emitShotDisposition(opts.onShotDisposition, receipt, {
211
220
  kind: "clean",
212
221
  worktreePath
213
222
  });
223
+ signal.throwIfAborted();
214
224
  attemptNote = EMPTY_TREE_NOTE;
215
225
  continue;
216
226
  }
@@ -219,6 +229,7 @@ ${attemptNote}` : basePrompt;
219
229
  try {
220
230
  problem = rawTraceEvidenceProblem(worktreePath, findings);
221
231
  } catch (cause) {
232
+ signal.throwIfAborted();
222
233
  return rethrowShotSetupError(
223
234
  opts.onShotDisposition,
224
235
  receipt,
@@ -228,28 +239,35 @@ ${attemptNote}` : basePrompt;
228
239
  );
229
240
  }
230
241
  if (problem) {
242
+ signal.throwIfAborted();
231
243
  await emitShotDisposition(opts.onShotDisposition, receipt, {
232
244
  kind: "rejected",
233
245
  worktreePath,
234
246
  stage: "raw-trace-evidence",
235
247
  feedback: problem
236
248
  });
249
+ signal.throwIfAborted();
237
250
  attemptNote = problem;
238
251
  continue;
239
252
  }
240
253
  }
241
254
  if (!verify) {
255
+ signal.throwIfAborted();
242
256
  await emitShotDisposition(opts.onShotDisposition, receipt, {
243
257
  kind: "accepted",
244
258
  worktreePath,
245
259
  verified: false
246
260
  });
247
- return { applied: true, summary: summarize(findings) };
261
+ signal.throwIfAborted();
262
+ return acceptedCandidate(findings);
248
263
  }
249
264
  let result;
250
265
  try {
251
- result = await verify(worktreePath);
266
+ signal.throwIfAborted();
267
+ result = await verify(worktreePath, signal);
268
+ signal.throwIfAborted();
252
269
  } catch (cause) {
270
+ signal.throwIfAborted();
253
271
  return rethrowShotSetupError(
254
272
  opts.onShotDisposition,
255
273
  receipt,
@@ -259,19 +277,23 @@ ${attemptNote}` : basePrompt;
259
277
  );
260
278
  }
261
279
  if (result.ok) {
280
+ signal.throwIfAborted();
262
281
  await emitShotDisposition(opts.onShotDisposition, receipt, {
263
282
  kind: "accepted",
264
283
  worktreePath,
265
284
  verified: true
266
285
  });
267
- return { applied: true, summary: summarize(findings) };
286
+ signal.throwIfAborted();
287
+ return acceptedCandidate(findings);
268
288
  }
289
+ signal.throwIfAborted();
269
290
  await emitShotDisposition(opts.onShotDisposition, receipt, {
270
291
  kind: "rejected",
271
292
  worktreePath,
272
293
  stage: "verification",
273
294
  feedback: result.feedback ?? null
274
295
  });
296
+ signal.throwIfAborted();
275
297
  attemptNote = failureNote(result.feedback);
276
298
  }
277
299
  return { applied: false, summary: "" };
@@ -420,6 +442,7 @@ function shotExecutionSnapshot(result) {
420
442
  killedBySignal: result.killedBySignal,
421
443
  durationMs: result.durationMs,
422
444
  timedOut: result.timedOut,
445
+ ...result.aborted !== void 0 ? { aborted: result.aborted } : {},
423
446
  ...usage ? { usage } : {},
424
447
  ...evidence ? { evidence } : {}
425
448
  });
@@ -445,6 +468,7 @@ function shotReceipt(input) {
445
468
  durationMs: result?.durationMs ?? input.completedAt.getTime() - input.startedAt.getTime(),
446
469
  exitCode: result?.exitCode ?? null,
447
470
  timedOut: result?.timedOut ?? false,
471
+ aborted: result?.aborted ?? false,
448
472
  killedBySignal: result?.killedBySignal ?? null,
449
473
  stdoutBytes: result ? Buffer.byteLength(result.stdout) : null,
450
474
  stdoutSha256: result ? sha256(result.stdout) : null,
@@ -473,6 +497,9 @@ function shotFailure(result, exactPrompt, codexReproducible) {
473
497
  if (result.timedOut) {
474
498
  return new Error("agenticGenerator: author shot timed out");
475
499
  }
500
+ if (result.aborted) {
501
+ return new Error("agenticGenerator: author shot was cancelled by the caller");
502
+ }
476
503
  if (result.killedBySignal) {
477
504
  return new Error(`agenticGenerator: author shot was killed by ${result.killedBySignal}`);
478
505
  }
@@ -509,11 +536,20 @@ function sha256(value) {
509
536
  }
510
537
  function defaultBuildPrompt(args) {
511
538
  const lines = [
512
- "You are improving this codebase based on an evaluation analysis.",
513
- "Make the smallest set of edits that addresses the findings below, then stop.",
514
- "Do not change unrelated code. Do not commit \u2014 leave changes in the working tree.",
539
+ "You are improving this codebase based on an evaluation analysis: real runs failed, an",
540
+ "analyst distilled the findings below, and your change will be measured on held-out tasks",
541
+ "against the unchanged baseline \u2014 only a real lift promotes it.",
542
+ "",
543
+ optimizerMethod,
515
544
  "",
516
- "Findings:"
545
+ "THE SURFACE \u2014 what a deliverable change looks like here:",
546
+ "- edit this codebase in place: the smallest coherent change set that fully tests your",
547
+ " hypothesis about the dominant failure mode (see the method above \u2014 no unrelated edits,",
548
+ " they confound the measurement),",
549
+ "- keep the diff reviewable: a reviewer should be able to trace every hunk back to a finding,",
550
+ "- do not commit \u2014 leave changes in the working tree.",
551
+ "",
552
+ "FINDINGS \u2014 ranked evidence from real failed runs:"
517
553
  ];
518
554
  for (const f of args.findings) {
519
555
  const where = f.subject ? ` [${f.subject}]` : "";
@@ -588,37 +624,63 @@ function traceEvidencePaths(findings) {
588
624
  return [...new Set(out)];
589
625
  }
590
626
  function commandVerifier(command, args = [], timeoutMs = 3e5) {
591
- return (worktreePath) => {
592
- const result = spawnSync(command, args, {
593
- cwd: worktreePath,
594
- encoding: "utf-8",
595
- timeout: timeoutMs
596
- });
597
- if (result.signal) {
598
- return {
599
- ok: false,
600
- feedback: `verifier '${command}' killed by ${result.signal} (likely timeout after ${timeoutMs}ms)`
601
- };
602
- }
603
- if (result.error) {
604
- const code = result.error.code;
627
+ return async (worktreePath, signal) => {
628
+ let result;
629
+ try {
630
+ result = await runSettledCommand({
631
+ command,
632
+ args,
633
+ cwd: worktreePath,
634
+ timeoutMs,
635
+ ...signal ? { signal } : {}
636
+ });
637
+ } catch (err) {
638
+ signal?.throwIfAborted();
639
+ const code = err.code;
605
640
  if (code === "ENOENT") {
606
641
  throw new Error(
607
642
  `commandVerifier: '${command}' not found in PATH (setup bug, not a failed candidate)`
608
643
  );
609
644
  }
610
- throw new Error(`commandVerifier: '${command}' failed to spawn: ${result.error.message}`);
645
+ const reason = err instanceof Error ? err.message : String(err);
646
+ throw new Error(`commandVerifier: '${command}' failed to spawn: ${reason}`);
611
647
  }
612
- if (result.status === 0) return { ok: true };
613
- const out = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
614
- return { ok: false, feedback: out.length > 0 ? out : `exit ${result.status}` };
648
+ if (result.timedOut || result.killedBySignal) {
649
+ return {
650
+ ok: false,
651
+ feedback: `verifier '${command}' ${result.killedBySignal ? `killed by ${result.killedBySignal}` : "timed out"} after ${timeoutMs}ms`
652
+ };
653
+ }
654
+ if (result.exitCode === 0) return { ok: true };
655
+ const out = `${result.stdout}${result.stderr}`.trim();
656
+ return { ok: false, feedback: out.length > 0 ? out : `exit ${result.exitCode}` };
615
657
  };
616
658
  }
617
- function summarize(findings) {
659
+ function summarizeFindings(findings) {
618
660
  if (findings.length === 0) return "agentic improvement";
619
661
  if (findings.length === 1) return `agentic: ${truncate(findings[0].claim, 64)}`;
620
662
  return `agentic: ${findings.length} findings addressed`;
621
663
  }
664
+ function acceptedCandidate(findings) {
665
+ const summary = summarizeFindings(findings);
666
+ return {
667
+ applied: true,
668
+ summary,
669
+ label: slugify(summary.split("\n", 1)[0] ?? summary),
670
+ rationale: boundedRationale(summary, findings)
671
+ };
672
+ }
673
+ function slugify(line) {
674
+ const slug = line.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
675
+ return truncate(slug || "agentic-improvement", 48);
676
+ }
677
+ function boundedRationale(summary, findings) {
678
+ if (findings.length === 0) return summary;
679
+ return truncate(
680
+ findings.map((finding) => `(${finding.severity}) ${finding.claim}`).join("; "),
681
+ 400
682
+ );
683
+ }
622
684
  function truncate(s, n) {
623
685
  return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
624
686
  }
@@ -643,6 +705,59 @@ function worktreeChangedPaths(worktreePath) {
643
705
  return result.stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => line.slice(3).trim());
644
706
  }
645
707
 
708
+ // src/improvement/findings.ts
709
+ import { makeFinding } from "@tangle-network/agent-eval";
710
+ var SEVERITIES = /* @__PURE__ */ new Set(["critical", "high", "medium", "low", "info"]);
711
+ var LIFTED_FINDING_ANALYST_ID = "lifted-seed";
712
+ function isAnalystFinding(value) {
713
+ if (!value || typeof value !== "object") return false;
714
+ const o = value;
715
+ return o.schema_version === "1.0.0" && typeof o.finding_id === "string" && typeof o.analyst_id === "string" && typeof o.severity === "string" && SEVERITIES.has(o.severity) && typeof o.area === "string" && typeof o.claim === "string" && typeof o.confidence === "number" && Array.isArray(o.evidence_refs);
716
+ }
717
+ function liftedClaim(value) {
718
+ if (typeof value === "string") return value.trim() || null;
719
+ if (value && typeof value === "object") {
720
+ const o = value;
721
+ for (const key of ["recommended_action", "claim", "lesson", "notes", "text", "message"]) {
722
+ const v = o[key];
723
+ if (typeof v === "string" && v.trim()) return v.trim();
724
+ }
725
+ try {
726
+ const json = JSON.stringify(value);
727
+ if (json && json !== "{}" && json !== "[]") {
728
+ return json.length > 400 ? `${json.slice(0, 399)}\u2026` : json;
729
+ }
730
+ } catch {
731
+ }
732
+ }
733
+ return null;
734
+ }
735
+ function toAnalystFindings(findings, opts = {}) {
736
+ const analystId = opts.analystId ?? LIFTED_FINDING_ANALYST_ID;
737
+ const area = opts.area ?? "seed";
738
+ const out = [];
739
+ for (const f of findings) {
740
+ if (isAnalystFinding(f)) {
741
+ out.push(f);
742
+ continue;
743
+ }
744
+ const claim = liftedClaim(f);
745
+ if (!claim) continue;
746
+ out.push(
747
+ makeFinding({
748
+ analyst_id: analystId,
749
+ severity: "info",
750
+ area,
751
+ confidence: 0.5,
752
+ claim,
753
+ evidence_refs: [],
754
+ ...f && typeof f === "object" ? { metadata: { raw: f } } : {}
755
+ })
756
+ );
757
+ }
758
+ return out;
759
+ }
760
+
646
761
  // src/improvement/improvement-driver.ts
647
762
  import { spawnSync as spawnSync2 } from "child_process";
648
763
  import {
@@ -688,7 +803,7 @@ function improvementDriver(opts) {
688
803
  owned.set(wt.path, wt);
689
804
  try {
690
805
  if (incumbent) advanceToIncumbent(wt, incumbent);
691
- const { applied, summary } = await opts.generator.generate({
806
+ const { applied, summary, label, rationale } = await opts.generator.generate({
692
807
  worktreePath: wt.path,
693
808
  report: ctx.report,
694
809
  findings,
@@ -706,7 +821,9 @@ function improvementDriver(opts) {
706
821
  continue;
707
822
  }
708
823
  const surface = await opts.worktree.finalize(wt, summary);
709
- surfaces.push(surface);
824
+ surfaces.push(
825
+ label || rationale ? { surface, label: label ?? "", rationale: rationale ?? "" } : surface
826
+ );
710
827
  owned.delete(wt.path);
711
828
  owned.set(surface.worktreeRef, wt);
712
829
  } catch (err) {
@@ -777,15 +894,18 @@ function resolveFindings(ctx) {
777
894
  const report = ctx.report;
778
895
  if (report && typeof report === "object" && "findings" in report) {
779
896
  const f = report.findings;
780
- if (Array.isArray(f) && f.length > 0) return f;
897
+ if (Array.isArray(f) && f.length > 0) {
898
+ const lifted = toAnalystFindings(f, { analystId: "report-findings", area: "report" });
899
+ if (lifted.length > 0) return lifted;
900
+ }
781
901
  }
782
- return ctx.findings;
902
+ return toAnalystFindings(ctx.findings ?? [], { analystId: "loop-context", area: "seed" });
783
903
  }
784
904
 
785
905
  // src/improvement/raw-trace-distiller.ts
786
906
  import { existsSync as existsSync2, readdirSync } from "fs";
787
907
  import { basename, join as join2, resolve as resolve2 } from "path";
788
- import { makeFinding } from "@tangle-network/agent-eval";
908
+ import { makeFinding as makeFinding2 } from "@tangle-network/agent-eval";
789
909
  var ANALYST_ID = "raw-trace-distiller";
790
910
  var PASS_THRESHOLD = 0.999;
791
911
  function rawTraceDistiller(options = {}) {
@@ -807,7 +927,7 @@ function rawTraceDistiller(options = {}) {
807
927
  return options.fallbackFindings;
808
928
  }
809
929
  return [
810
- makeFinding({
930
+ makeFinding2({
811
931
  analyst_id: ANALYST_ID,
812
932
  severity: "info",
813
933
  area: "raw-trace-context",
@@ -821,7 +941,7 @@ function rawTraceDistiller(options = {}) {
821
941
  }
822
942
  const findings = [];
823
943
  findings.push(
824
- makeFinding({
944
+ makeFinding2({
825
945
  analyst_id: ANALYST_ID,
826
946
  severity: "high",
827
947
  area: "raw-trace-context",
@@ -849,7 +969,7 @@ function rawTraceDistiller(options = {}) {
849
969
  ${files}${more}` : header;
850
970
  }).join("\n");
851
971
  findings.push(
852
- makeFinding({
972
+ makeFinding2({
853
973
  analyst_id: ANALYST_ID,
854
974
  severity: cand.composite < 0.5 ? "critical" : "high",
855
975
  area: "raw-trace-context",
@@ -954,8 +1074,123 @@ function truncate2(s, n) {
954
1074
  return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
955
1075
  }
956
1076
 
1077
+ // src/improvement/rollout-policy.ts
1078
+ var ROLLOUT_POLICY_EXTENSION = "structural-rollout";
1079
+ var ROLLOUT_POLICY_BOUNDS = {
1080
+ k: { min: 1, max: 10, step: 2 },
1081
+ repairRounds: { min: 0, max: 3, step: 1 },
1082
+ testgen: { min: 0, max: 10, step: 3 }
1083
+ };
1084
+ var MAX_CANDIDATES_PER_GENERATION = 4;
1085
+ var clamp = (v, min, max) => Math.min(max, Math.max(min, v));
1086
+ var isBoundedInt = (v, min) => typeof v === "number" && Number.isInteger(v) && v >= min;
1087
+ function parseRolloutPolicy(surface) {
1088
+ if (typeof surface !== "string" || surface.trim().length === 0) return void 0;
1089
+ let raw;
1090
+ try {
1091
+ raw = JSON.parse(surface);
1092
+ } catch {
1093
+ return void 0;
1094
+ }
1095
+ return normalizeRolloutPolicy(raw);
1096
+ }
1097
+ function normalizeRolloutPolicy(raw) {
1098
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return void 0;
1099
+ const bag = raw;
1100
+ const k = bag.k ?? defaultStructuralRolloutPolicy.k;
1101
+ const repairRounds = bag.repairRounds ?? defaultStructuralRolloutPolicy.repairRounds;
1102
+ const testgen = bag.testgen ?? defaultStructuralRolloutPolicy.testgen;
1103
+ if (!isBoundedInt(k, 1) || !isBoundedInt(repairRounds, 0) || !isBoundedInt(testgen, 0)) {
1104
+ return void 0;
1105
+ }
1106
+ return {
1107
+ k,
1108
+ repairRounds,
1109
+ testgen,
1110
+ ...typeof bag.diverse === "boolean" ? { diverse: bag.diverse } : {},
1111
+ ...typeof bag.temperature === "number" ? { temperature: bag.temperature } : {}
1112
+ };
1113
+ }
1114
+ function serializeRolloutPolicy(policy) {
1115
+ return JSON.stringify({
1116
+ k: policy.k,
1117
+ repairRounds: policy.repairRounds,
1118
+ testgen: policy.testgen,
1119
+ ...policy.diverse !== void 0 ? { diverse: policy.diverse } : {},
1120
+ ...policy.temperature !== void 0 ? { temperature: policy.temperature } : {}
1121
+ });
1122
+ }
1123
+ function structuralRolloutPolicyFromProfile(profile) {
1124
+ const bag = profile.extensions?.[ROLLOUT_POLICY_EXTENSION];
1125
+ if (bag === void 0) return void 0;
1126
+ return normalizeRolloutPolicy(bag);
1127
+ }
1128
+ function applyRolloutPolicyToProfile(profile, policy) {
1129
+ const bag = {
1130
+ k: policy.k,
1131
+ repairRounds: policy.repairRounds,
1132
+ testgen: policy.testgen,
1133
+ ...policy.diverse !== void 0 ? { diverse: policy.diverse } : {},
1134
+ ...policy.temperature !== void 0 ? { temperature: policy.temperature } : {}
1135
+ };
1136
+ return {
1137
+ ...profile,
1138
+ extensions: { ...profile.extensions, [ROLLOUT_POLICY_EXTENSION]: bag }
1139
+ };
1140
+ }
1141
+ function enumerateNeighborPolicies(policy) {
1142
+ const moves = [
1143
+ { dial: "k", delta: 1 },
1144
+ { dial: "k", delta: -1 },
1145
+ { dial: "repairRounds", delta: 1 },
1146
+ { dial: "repairRounds", delta: -1 },
1147
+ { dial: "testgen", delta: 1 },
1148
+ { dial: "testgen", delta: -1 }
1149
+ ];
1150
+ const seen = /* @__PURE__ */ new Set([serializeRolloutPolicy(policy)]);
1151
+ const neighbors = [];
1152
+ for (const move of moves) {
1153
+ const bounds = ROLLOUT_POLICY_BOUNDS[move.dial];
1154
+ const next = clamp(policy[move.dial] + move.delta * bounds.step, bounds.min, bounds.max);
1155
+ const candidate = { ...policy, [move.dial]: next };
1156
+ const key = serializeRolloutPolicy(candidate);
1157
+ if (seen.has(key)) continue;
1158
+ seen.add(key);
1159
+ neighbors.push(candidate);
1160
+ }
1161
+ return neighbors;
1162
+ }
1163
+ function candidateLabel(base, next) {
1164
+ for (const dial of ["k", "repairRounds", "testgen"]) {
1165
+ if (next[dial] !== base[dial]) return `${dial} ${base[dial]}\u2192${next[dial]}`;
1166
+ }
1167
+ return "unchanged";
1168
+ }
1169
+ function rolloutPolicyProposer() {
1170
+ return {
1171
+ kind: "rollout-policy",
1172
+ async propose(ctx) {
1173
+ const policy = parseRolloutPolicy(ctx.currentSurface);
1174
+ if (!policy) return [];
1175
+ const neighbors = enumerateNeighborPolicies(policy);
1176
+ if (neighbors.length === 0) return [];
1177
+ const cap = Math.max(1, Math.min(ctx.populationSize, MAX_CANDIDATES_PER_GENERATION));
1178
+ const start = ctx.generation * cap % neighbors.length;
1179
+ const window = [];
1180
+ for (let i = 0; i < Math.min(cap, neighbors.length); i += 1) {
1181
+ window.push(neighbors[(start + i) % neighbors.length]);
1182
+ }
1183
+ return window.map((candidate) => ({
1184
+ surface: serializeRolloutPolicy(candidate),
1185
+ label: candidateLabel(policy, candidate),
1186
+ rationale: "bounded single-dial neighbor of the current structuralRollout policy; the held-out gate decides (deterministic enumeration \u2014 the dial space is tiny and prompt-style reflective proposals are a measured zero here)"
1187
+ }));
1188
+ }
1189
+ };
1190
+ }
1191
+
957
1192
  // src/improvement/improve.ts
958
- import { canonicalJson } from "@tangle-network/agent-eval";
1193
+ import { canonicalJson, makeFinding as makeFinding3 } from "@tangle-network/agent-eval";
959
1194
  import {
960
1195
  gepaProposer,
961
1196
  gitWorktreeAdapter,
@@ -981,6 +1216,8 @@ function defaultGeneratorFor(surface, llm) {
981
1216
  return skillOptProposer({ llm: llmClientOptions(llm), model, target: "agent skill document" });
982
1217
  case "memory":
983
1218
  return memoryCurationProposer();
1219
+ case "rollout-policy":
1220
+ return rolloutPolicyProposer();
984
1221
  default:
985
1222
  return void 0;
986
1223
  }
@@ -1003,6 +1240,10 @@ function baselineSurfaceFor(profile, surface, skills) {
1003
1240
  return canonicalJson(profile);
1004
1241
  case "memory":
1005
1242
  return profileInstructions(profile);
1243
+ case "rollout-policy": {
1244
+ const policy = structuralRolloutPolicyFromProfile(profile);
1245
+ return policy ? serializeRolloutPolicy(policy) : "";
1246
+ }
1006
1247
  case "code":
1007
1248
  throw new ConfigError(
1008
1249
  "improve(): code requires the isolated baseline created from opts.code.repoRoot"
@@ -1038,7 +1279,23 @@ function generationFailureDistiller(staticFindings) {
1038
1279
  }
1039
1280
  if (failures.length === 0) return staticFindings;
1040
1281
  failures.sort((a, b) => a.composite - b.composite);
1041
- return failures.slice(0, CAP);
1282
+ return failures.slice(0, CAP).map(
1283
+ (f) => makeFinding3({
1284
+ analyst_id: "generation-failure-distiller",
1285
+ severity: f.error !== void 0 || f.composite < 0.5 ? "high" : "medium",
1286
+ area: "generation-failure",
1287
+ confidence: 1,
1288
+ subject: f.scenario,
1289
+ claim: `Scenario ${f.scenario} scored composite ${f.composite}${f.notes ? `: ${f.notes}` : ""}${f.error ? ` (error: ${f.error})` : ""}`,
1290
+ evidence_refs: [],
1291
+ metadata: {
1292
+ scenario: f.scenario,
1293
+ composite: f.composite,
1294
+ ...f.notes ? { notes: f.notes } : {},
1295
+ ...f.error !== void 0 ? { error: f.error } : {}
1296
+ }
1297
+ })
1298
+ );
1042
1299
  };
1043
1300
  }
1044
1301
  function memoryGenerationDistiller(staticFindings) {
@@ -1048,6 +1305,14 @@ function memoryGenerationDistiller(staticFindings) {
1048
1305
  return fresh === staticFindings ? staticFindings : [...staticFindings, ...fresh];
1049
1306
  };
1050
1307
  }
1308
+ function defaultDistillerFor(opts, findings) {
1309
+ const surface = opts.surface ?? "prompt";
1310
+ const durableRun = opts.runDir !== void 0 && !opts.runDir.startsWith("mem://");
1311
+ const useRawTraces = opts.rawTraceContext ?? (surface === "memory" ? false : durableRun);
1312
+ if (useRawTraces) return rawTraceDistiller({ fallbackFindings: findings });
1313
+ if (surface === "memory") return memoryGenerationDistiller(findings);
1314
+ return generationFailureDistiller(findings);
1315
+ }
1051
1316
  async function discardPreparedBaseline(worktree, baselineWorktree, cause) {
1052
1317
  return rethrowAfterCleanup(
1053
1318
  cause,
@@ -1179,6 +1444,17 @@ function materializeImprovementProfileCandidate(profile, surface, winner, skills
1179
1444
  }
1180
1445
  };
1181
1446
  break;
1447
+ case "rollout-policy": {
1448
+ if (winner === "") return void 0;
1449
+ const policy = normalizeRolloutPolicy(parseWinnerJson(winner, surface));
1450
+ if (!policy) {
1451
+ throw new ConfigError(
1452
+ `improve(): the shipped 'rollout-policy' winner is not a valid StructuralRolloutPolicy (integer k >= 1, repairRounds >= 0, testgen >= 0), so it cannot be applied: ${winner}`
1453
+ );
1454
+ }
1455
+ candidate = applyRolloutPolicyToProfile(profile, policy);
1456
+ break;
1457
+ }
1182
1458
  case "code":
1183
1459
  return void 0;
1184
1460
  }
@@ -1289,7 +1565,7 @@ async function improve(profile, findings, opts) {
1289
1565
  findings,
1290
1566
  ...promotionGate !== void 0 ? { gate: promotionGate } : {},
1291
1567
  ...analyzeGeneration === null ? {} : {
1292
- analyzeGeneration: analyzeGeneration ?? (rawTraceContext ? rawTraceDistiller({ fallbackFindings: findings }) : surface === "memory" ? memoryGenerationDistiller(findings) : generationFailureDistiller(findings))
1568
+ analyzeGeneration: analyzeGeneration ?? defaultDistillerFor(opts, findings)
1293
1569
  }
1294
1570
  });
1295
1571
  } catch (cause) {
@@ -1335,7 +1611,7 @@ async function improve(profile, findings, opts) {
1335
1611
  return {
1336
1612
  candidate,
1337
1613
  decision: raw.gateDecision,
1338
- lift: raw.lift,
1614
+ ...raw.lift !== void 0 ? { lift: raw.lift } : {},
1339
1615
  raw,
1340
1616
  dispose
1341
1617
  };
@@ -2017,9 +2293,26 @@ function assertNoJudgeDerivedProposalFindings(findings) {
2017
2293
  export {
2018
2294
  AGENTIC_PROFILE_RESOURCE_ROOT,
2019
2295
  agenticGenerator,
2296
+ defaultBuildPrompt,
2297
+ rawTraceEvidenceProblem,
2298
+ requiresRawTraceEvidence,
2020
2299
  commandVerifier,
2300
+ summarizeFindings,
2301
+ worktreeChangedPaths,
2302
+ LIFTED_FINDING_ANALYST_ID,
2303
+ isAnalystFinding,
2304
+ toAnalystFindings,
2021
2305
  improvementDriver,
2022
2306
  rawTraceDistiller,
2307
+ ROLLOUT_POLICY_EXTENSION,
2308
+ ROLLOUT_POLICY_BOUNDS,
2309
+ parseRolloutPolicy,
2310
+ normalizeRolloutPolicy,
2311
+ serializeRolloutPolicy,
2312
+ structuralRolloutPolicyFromProfile,
2313
+ applyRolloutPolicyToProfile,
2314
+ enumerateNeighborPolicies,
2315
+ rolloutPolicyProposer,
2023
2316
  improve,
2024
2317
  AGENT_IMPROVEMENT_PROFILE_SURFACES,
2025
2318
  buildAgentImprovementActivationTargets,
@@ -2042,4 +2335,4 @@ export {
2042
2335
  verifyAgentImprovementActivation,
2043
2336
  verifyCandidateExecutionEvidence
2044
2337
  };
2045
- //# sourceMappingURL=chunk-RJPQLUDA.js.map
2338
+ //# sourceMappingURL=chunk-7FJJUC73.js.map