@tangle-network/browser-agent-driver 0.31.0 → 0.32.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 (104) hide show
  1. package/dist/brain/index.d.ts +12 -0
  2. package/dist/brain/index.d.ts.map +1 -1
  3. package/dist/brain/index.js +36 -8
  4. package/dist/brain/index.js.map +1 -1
  5. package/dist/cli-design-audit.d.ts.map +1 -1
  6. package/dist/cli-design-audit.js +8 -18
  7. package/dist/cli-design-audit.js.map +1 -1
  8. package/dist/cli-jobs.js +4 -13
  9. package/dist/cli-jobs.js.map +1 -1
  10. package/dist/cli-patterns.d.ts +1 -1
  11. package/dist/cli-patterns.d.ts.map +1 -1
  12. package/dist/design/audit/attribution/types.d.ts +3 -3
  13. package/dist/design/audit/attribution/types.d.ts.map +1 -1
  14. package/dist/design/audit/attribution/types.js +2 -2
  15. package/dist/design/audit/build-result.d.ts +68 -0
  16. package/dist/design/audit/build-result.d.ts.map +1 -0
  17. package/dist/design/audit/build-result.js +243 -0
  18. package/dist/design/audit/build-result.js.map +1 -0
  19. package/dist/design/audit/classify-ensemble.d.ts +1 -1
  20. package/dist/design/audit/classify-ensemble.d.ts.map +1 -1
  21. package/dist/design/audit/ethics/check.d.ts +2 -2
  22. package/dist/design/audit/ethics/check.d.ts.map +1 -1
  23. package/dist/design/audit/ethics/check.js +1 -1
  24. package/dist/design/audit/ethics/loader.d.ts +1 -1
  25. package/dist/design/audit/ethics/loader.d.ts.map +1 -1
  26. package/dist/design/audit/evaluate.js +1 -1
  27. package/dist/design/audit/evaluate.js.map +1 -1
  28. package/dist/design/audit/first-principles-mode.d.ts +1 -1
  29. package/dist/design/audit/first-principles-mode.d.ts.map +1 -1
  30. package/dist/design/audit/modality/android.d.ts +1 -1
  31. package/dist/design/audit/modality/android.d.ts.map +1 -1
  32. package/dist/design/audit/modality/html.d.ts +1 -1
  33. package/dist/design/audit/modality/html.d.ts.map +1 -1
  34. package/dist/design/audit/modality/ios.d.ts +1 -1
  35. package/dist/design/audit/modality/ios.d.ts.map +1 -1
  36. package/dist/design/audit/modality/types.d.ts +2 -2
  37. package/dist/design/audit/modality/types.d.ts.map +1 -1
  38. package/dist/design/audit/modality/types.js +1 -1
  39. package/dist/design/audit/patches/generate.d.ts +45 -0
  40. package/dist/design/audit/patches/generate.d.ts.map +1 -0
  41. package/dist/design/audit/patches/generate.js +161 -0
  42. package/dist/design/audit/patches/generate.js.map +1 -0
  43. package/dist/design/audit/patches/parse.d.ts +1 -1
  44. package/dist/design/audit/patches/parse.d.ts.map +1 -1
  45. package/dist/design/audit/patches/render.d.ts +1 -1
  46. package/dist/design/audit/patches/render.d.ts.map +1 -1
  47. package/dist/design/audit/patches/severity-enforcement.d.ts +1 -1
  48. package/dist/design/audit/patches/severity-enforcement.d.ts.map +1 -1
  49. package/dist/design/audit/patches/validate.d.ts +7 -1
  50. package/dist/design/audit/patches/validate.d.ts.map +1 -1
  51. package/dist/design/audit/patches/validate.js +8 -1
  52. package/dist/design/audit/patches/validate.js.map +1 -1
  53. package/dist/design/audit/patterns/match.d.ts +1 -1
  54. package/dist/design/audit/patterns/match.d.ts.map +1 -1
  55. package/dist/design/audit/patterns/types.d.ts +2 -2
  56. package/dist/design/audit/patterns/types.d.ts.map +1 -1
  57. package/dist/design/audit/pipeline.d.ts +1 -1
  58. package/dist/design/audit/pipeline.d.ts.map +1 -1
  59. package/dist/design/audit/pipeline.js +41 -27
  60. package/dist/design/audit/pipeline.js.map +1 -1
  61. package/dist/design/audit/rubric/loader.d.ts +1 -1
  62. package/dist/design/audit/rubric/loader.d.ts.map +1 -1
  63. package/dist/design/audit/rubric/rollup-weights.d.ts +1 -1
  64. package/dist/design/audit/rubric/rollup-weights.d.ts.map +1 -1
  65. package/dist/design/audit/{v2/types.d.ts → score-types.d.ts} +10 -10
  66. package/dist/design/audit/score-types.d.ts.map +1 -0
  67. package/dist/design/audit/{v2/types.js → score-types.js} +2 -2
  68. package/dist/design/audit/score-types.js.map +1 -0
  69. package/dist/design/audit/{v2/score.d.ts → score.d.ts} +9 -9
  70. package/dist/design/audit/score.d.ts.map +1 -0
  71. package/dist/design/audit/{v2/score.js → score.js} +17 -17
  72. package/dist/design/audit/score.js.map +1 -0
  73. package/dist/design/audit/types.d.ts +7 -7
  74. package/dist/design/audit/types.d.ts.map +1 -1
  75. package/dist/jobs/anti-bot.js +1 -1
  76. package/dist/jobs/anti-bot.js.map +1 -1
  77. package/dist/jobs/types.d.ts +1 -1
  78. package/dist/jobs/types.d.ts.map +1 -1
  79. package/dist/reports/aggregate.js +6 -6
  80. package/dist/reports/aggregate.js.map +1 -1
  81. package/dist/reports/tokens.d.ts +0 -8
  82. package/dist/reports/tokens.d.ts.map +1 -1
  83. package/dist/reports/tokens.js +1 -15
  84. package/dist/reports/tokens.js.map +1 -1
  85. package/dist/reports/types.d.ts +2 -2
  86. package/dist/reports/types.d.ts.map +1 -1
  87. package/dist/run-state.d.ts +36 -1
  88. package/dist/run-state.d.ts.map +1 -1
  89. package/dist/run-state.js +36 -1
  90. package/dist/run-state.js.map +1 -1
  91. package/dist/runner/runner.d.ts.map +1 -1
  92. package/dist/runner/runner.js +73 -3
  93. package/dist/runner/runner.js.map +1 -1
  94. package/dist/types.d.ts +7 -0
  95. package/dist/types.d.ts.map +1 -1
  96. package/package.json +4 -1
  97. package/dist/design/audit/v2/build-result.d.ts +0 -47
  98. package/dist/design/audit/v2/build-result.d.ts.map +0 -1
  99. package/dist/design/audit/v2/build-result.js +0 -163
  100. package/dist/design/audit/v2/build-result.js.map +0 -1
  101. package/dist/design/audit/v2/score.d.ts.map +0 -1
  102. package/dist/design/audit/v2/score.js.map +0 -1
  103. package/dist/design/audit/v2/types.d.ts.map +0 -1
  104. package/dist/design/audit/v2/types.js.map +0 -1
package/dist/run-state.js CHANGED
@@ -19,7 +19,24 @@
19
19
  * Override per-case via Scenario.tokenBudget or globally via the
20
20
  * BAD_TOKEN_BUDGET env var.
21
21
  */
22
- export const DEFAULT_TOKEN_BUDGET = 100_000;
22
+ /**
23
+ * Default token budget per case. The cap aborts a run with `cost_cap_exceeded`
24
+ * once total LLM tokens (input + output + cache) exceed this number.
25
+ *
26
+ * History:
27
+ * - Gen 9: 100k cap added to bound runaway recovery loops (after Gen 8.1
28
+ * burned 130-173k tokens / $0.25-$0.32 per case in death-spiral runs).
29
+ * - 2026-04-27: bumped 100k → 300k. The Gen 11-era 100k cap was set when
30
+ * the brain default was a smaller model (gpt-5.2 family). gpt-5.4 is
31
+ * materially more verbose per turn — the production-shipping cap was
32
+ * dominating the failure mode (10/12 WebVoyager curated-30 misses were
33
+ * `cost_cap_exceeded` at the 100k cap). Bumping to 300k took curated-30
34
+ * pass rate from 60.0% → 86.7% with zero cost_cap aborts.
35
+ *
36
+ * Override per-case via Scenario.tokenBudget or globally via the
37
+ * BAD_TOKEN_BUDGET env var (env wins — see RunState constructor).
38
+ */
39
+ export const DEFAULT_TOKEN_BUDGET = 300_000;
23
40
  export class RunState {
24
41
  consecutiveErrors = 0;
25
42
  totalErrors = 0;
@@ -33,6 +50,24 @@ export class RunState {
33
50
  searchScoutUrls = new Set();
34
51
  // Gen 24b: checkpoint replay — save known-good URLs for rollback on wrong-path
35
52
  checkpoints = [];
53
+ /**
54
+ * Last turn at which the agent showed verifiable progress: URL changed,
55
+ * snapshot DOM materially changed, or evidence was extracted. Drives the
56
+ * 2026-04-28 adaptive-max-turns extension — the runner grants up to 5
57
+ * extra turns past the configured maxTurns IF the last 3 turns showed
58
+ * progress, on the theory that an agent making demonstrable progress
59
+ * 3 turns from the cap should not be cut off arbitrarily.
60
+ *
61
+ * Initial value `-Infinity` so a brand-new run with zero observations
62
+ * cannot trigger the extension on its way in.
63
+ *
64
+ * Updated by:
65
+ * - URL change between consecutive observe-completed events
66
+ * - Snapshot byte delta > 5% of prior turn (filters noise from
67
+ * decorative animations / dynamic IDs / timestamps)
68
+ * - firstSufficientEvidenceTurn being set this turn
69
+ */
70
+ lastProgressTurn = -Infinity;
36
71
  maxTotalErrors;
37
72
  /** Total LLM tokens (input + output + cache) charged to this case so far. */
38
73
  totalTokensUsed = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"run-state.js","sourceRoot":"","sources":["../src/run-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAE5C,MAAM,OAAO,QAAQ;IACnB,iBAAiB,GAAG,CAAC,CAAC;IACtB,WAAW,GAAG,CAAC,CAAC;IAChB,0BAA0B,GAAG,CAAC,CAAC;IAC/B,2BAA2B,CAAqB;IAChD,uBAAuB,GAAG,CAAC,CAAC;IAC5B,kBAAkB,GAAG,CAAC,QAAQ,CAAC;IAC/B,wBAAwB,GAAa,EAAE,CAAC;IACxC,4DAA4D;IAC5D,iBAAiB,GAAa,EAAE,CAAC;IACjC,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,+EAA+E;IAC/E,WAAW,GAAyC,EAAE,CAAC;IAE9C,cAAc,CAAS;IAEhC,6EAA6E;IAC7E,eAAe,GAAG,CAAC,CAAC;IACpB,wFAAwF;IAC/E,WAAW,CAAS;IAE7B,YAAY,QAAgB,EAAE,WAAoB;QAChD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,kEAAkE;QAClE,qEAAqE;QACrE,gEAAgE;QAChE,sEAAsE;QACtE,gEAAgE;QAChE,kEAAkE;QAClE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,GAAG,WAAW,IAAI,oBAAoB,CAAC;QACzD,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED,sBAAsB;QACpB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY,CAAC,MAA0B;QACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,eAAe,IAAI,MAAM,CAAC;QACjC,CAAC;IACH,CAAC;IAED,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,cAAc,CAAC;IACjD,CAAC;IAED,IAAI,4BAA4B;QAC9B,OAAO,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,WAAW,CAAC;IAClD,CAAC;IAED,cAAc,CAAC,QAAgB;QAC7B,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC3E,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"run-state.js","sourceRoot":"","sources":["../src/run-state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;GAeG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAE5C,MAAM,OAAO,QAAQ;IACnB,iBAAiB,GAAG,CAAC,CAAC;IACtB,WAAW,GAAG,CAAC,CAAC;IAChB,0BAA0B,GAAG,CAAC,CAAC;IAC/B,2BAA2B,CAAqB;IAChD,uBAAuB,GAAG,CAAC,CAAC;IAC5B,kBAAkB,GAAG,CAAC,QAAQ,CAAC;IAC/B,wBAAwB,GAAa,EAAE,CAAC;IACxC,4DAA4D;IAC5D,iBAAiB,GAAa,EAAE,CAAC;IACjC,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,+EAA+E;IAC/E,WAAW,GAAyC,EAAE,CAAC;IAEvD;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,GAAG,CAAC,QAAQ,CAAC;IAEpB,cAAc,CAAS;IAEhC,6EAA6E;IAC7E,eAAe,GAAG,CAAC,CAAC;IACpB,wFAAwF;IAC/E,WAAW,CAAS;IAE7B,YAAY,QAAgB,EAAE,WAAoB;QAChD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,kEAAkE;QAClE,qEAAqE;QACrE,gEAAgE;QAChE,sEAAsE;QACtE,gEAAgE;QAChE,kEAAkE;QAClE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,GAAG,WAAW,IAAI,oBAAoB,CAAC;QACzD,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED,sBAAsB;QACpB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY,CAAC,MAA0B;QACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,eAAe,IAAI,MAAM,CAAC;QACjC,CAAC;IACH,CAAC;IAED,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,cAAc,CAAC;IACjD,CAAC;IAED,IAAI,4BAA4B;QAC9B,OAAO,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,sBAAsB;QACxB,OAAO,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,WAAW,CAAC;IAClD,CAAC;IAED,cAAc,CAAC,QAAgB;QAC7B,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC3E,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"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"}
@@ -337,7 +337,20 @@ export class BrowserAgent {
337
337
  const baseMaxTurns = scenario.maxTurns || DEFAULT_MAX_TURNS;
338
338
  // Gen 26: 30 turn minimum for vision. 15/51 failures were turn budget
339
339
  // exhaustion at 20. The cost cap (200k tokens) is the real bound.
340
- const maxTurns = isVisionMode ? Math.max(baseMaxTurns, 30) : baseMaxTurns;
340
+ //
341
+ // 2026-04-28 update: `maxTurns` is now `let`, not `const`, because the
342
+ // adaptive-extension logic at the top of each iteration may bump it
343
+ // by EXTENSION_TURNS_GRANTED when the agent shows recent progress at
344
+ // the cap. WebVoyager-590 baseline showed 21/54 fails were
345
+ // "agent_gave_up_at_max_turns" mid-flow; the extension converts those
346
+ // near-misses into successes without rewarding stuck loops (extension
347
+ // requires URL-or-DOM progress in the prior 3 turns; capped absolute
348
+ // at EXTENSION_HARD_CAP).
349
+ let maxTurns = isVisionMode ? Math.max(baseMaxTurns, 30) : baseMaxTurns;
350
+ let extensionGranted = false;
351
+ const EXTENSION_TURNS_GRANTED = 5;
352
+ const EXTENSION_HARD_CAP = 25;
353
+ const EXTENSION_PROGRESS_LOOKBACK = 3;
341
354
  const retries = this.config.retries ?? DEFAULT_RETRIES;
342
355
  const retryDelayMs = this.config.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;
343
356
  const turns = [];
@@ -658,6 +671,33 @@ export class BrowserAgent {
658
671
  // markers so a ledger the agent keeps re-emitting doesn't spam badges.
659
672
  const verdictTracker = new VerdictTracker();
660
673
  for (let i = 1 + plannerStartTurn; i <= maxTurns; i++) {
674
+ // 2026-04-28: adaptive-max-turns extension. When we hit the
675
+ // configured cap AND the agent has shown progress in the last
676
+ // EXTENSION_PROGRESS_LOOKBACK turns, grant a one-time extension up
677
+ // to EXTENSION_HARD_CAP. Triggers only on the original maxTurns
678
+ // boundary (extensionGranted guards against cascading); the
679
+ // recovery-fired event is emitted so the trace is honest about the
680
+ // turns being borrowed. No-op for vision-mode (already gets +5
681
+ // baseline boost) and for explicitly-large maxTurns settings.
682
+ if (i === maxTurns
683
+ && !extensionGranted
684
+ && !isVisionMode
685
+ && maxTurns < EXTENSION_HARD_CAP
686
+ && runState.lastProgressTurn >= maxTurns - EXTENSION_PROGRESS_LOOKBACK) {
687
+ const extendedMax = Math.min(maxTurns + EXTENSION_TURNS_GRANTED, EXTENSION_HARD_CAP);
688
+ const extra = extendedMax - maxTurns;
689
+ if (extra > 0) {
690
+ this.bus.emitNow({
691
+ type: 'recovery-fired',
692
+ runId,
693
+ turn: i,
694
+ strategy: 'max-turns-extension',
695
+ feedback: `Granted +${extra} extra turns (cap ${maxTurns} → ${extendedMax}); progress at turn ${runState.lastProgressTurn}.`,
696
+ });
697
+ maxTurns = extendedMax;
698
+ extensionGranted = true;
699
+ }
700
+ }
661
701
  // Gen 32 — honor user-driven pause from the interrupt controller.
662
702
  // Blocks until `r` is pressed (resume) or `q` is pressed (abort).
663
703
  // A rejected beforeTurn is treated as an abort.
@@ -803,6 +843,31 @@ export class BrowserAgent {
803
843
  ...(screenshotDataUrl ? { screenshot: screenshotDataUrl } : {}),
804
844
  durationMs: observeDurationMs,
805
845
  });
846
+ // 2026-04-28: progress-turn tracking for the adaptive-max-turns
847
+ // extension at the end of the loop. We mark this turn as
848
+ // "progress" when the URL changed from the prior turn, OR the
849
+ // snapshot byte size moved more than 5% (which filters out
850
+ // decorative animations + dynamic-id reshuffles but catches
851
+ // real DOM changes from clicks/typing/navigation). The 5% floor
852
+ // is intentionally loose — false positives just keep the run
853
+ // alive longer; false negatives cut off agents mid-flow on
854
+ // hot-spot sites (booking, google-flights), which is the
855
+ // failure mode we're trying to fix.
856
+ const priorTurn = turns[turns.length - 1];
857
+ if (priorTurn) {
858
+ const urlChanged = priorTurn.state?.url !== state.url;
859
+ const priorSize = priorTurn.state?.snapshot?.length ?? 0;
860
+ const sizeDelta = priorSize > 0
861
+ ? Math.abs(state.snapshot.length - priorSize) / priorSize
862
+ : 1; // first comparison counts as change
863
+ if (urlChanged || sizeDelta > 0.05) {
864
+ runState.lastProgressTurn = i;
865
+ }
866
+ }
867
+ else {
868
+ // No prior turn — this is the first observe. Count as progress.
869
+ runState.lastProgressTurn = i;
870
+ }
806
871
  // Auto-navigate: if we're on about:blank with a startUrl, navigate without
807
872
  // consuming an LLM turn. The agent always does wait->navigate on blank pages.
808
873
  if (state.url === 'about:blank' &&
@@ -2076,10 +2141,15 @@ export class BrowserAgent {
2076
2141
  }
2077
2142
  }
2078
2143
  }
2079
- // Max turns reached
2144
+ // Max turns reached. The adaptive extension fired (or didn't) inside
2145
+ // the loop body — see the `extensionGranted` check at the start of
2146
+ // each iteration. By the time we reach this point, the (possibly
2147
+ // extended) cap was exhausted.
2080
2148
  return buildResult({
2081
2149
  success: false,
2082
- reason: `Max turns (${maxTurns}) reached`,
2150
+ reason: extensionGranted
2151
+ ? `Max turns (${maxTurns}) reached after +${EXTENSION_TURNS_GRANTED} extension; recent progress at turn ${runState.lastProgressTurn}.`
2152
+ : `Max turns (${maxTurns}) reached`,
2083
2153
  turns,
2084
2154
  totalMs: Date.now() - startTime,
2085
2155
  });