@tangle-network/agent-runtime 0.185.1 → 0.187.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 (110) hide show
  1. package/dist/{activation-h6zO-0Rd.js → activation-CpEoQaj5.js} +3 -3
  2. package/dist/{activation-h6zO-0Rd.js.map → activation-CpEoQaj5.js.map} +1 -1
  3. package/dist/agent.d.ts +2 -2
  4. package/dist/agent.js +3 -3
  5. package/dist/{analyst-loop-DCTra9Qy.js → analyst-loop-CSH7P-Bf.js} +2 -2
  6. package/dist/{analyst-loop-DCTra9Qy.js.map → analyst-loop-CSH7P-Bf.js.map} +1 -1
  7. package/dist/analyst-loop.d.ts +1 -1
  8. package/dist/analyst-loop.js +1 -1
  9. package/dist/{authoring-BNQKWhto.js → authoring-fsUwd9hg.js} +2 -2
  10. package/dist/{authoring-BNQKWhto.js.map → authoring-fsUwd9hg.js.map} +1 -1
  11. package/dist/candidate-execution/index.js +4 -4
  12. package/dist/{candidate-execution-7lVEly33.js → candidate-execution-CehLeZmx.js} +4 -4
  13. package/dist/{candidate-execution-7lVEly33.js.map → candidate-execution-CehLeZmx.js.map} +1 -1
  14. package/dist/{conversation-BSgEebIo.js → conversation-DILnmy84.js} +3 -3
  15. package/dist/{conversation-BSgEebIo.js.map → conversation-DILnmy84.js.map} +1 -1
  16. package/dist/conversation.d.ts +1 -1
  17. package/dist/conversation.js +1 -1
  18. package/dist/{coordination-driver-Dh_0SvXr.js → coordination-driver-CtbyZv5d.js} +4 -4
  19. package/dist/{coordination-driver-Dh_0SvXr.js.map → coordination-driver-CtbyZv5d.js.map} +1 -1
  20. package/dist/durable.d.ts +24 -3
  21. package/dist/durable.js +12 -2
  22. package/dist/durable.js.map +1 -1
  23. package/dist/environment-provider-C4AQiUxj.d.ts +143 -0
  24. package/dist/{environment-provider-6QtI-u5j.js → environment-provider-DZxuH3E4.js} +56 -9
  25. package/dist/environment-provider-DZxuH3E4.js.map +1 -0
  26. package/dist/environment-provider.d.ts +2 -2
  27. package/dist/environment-provider.js +1 -1
  28. package/dist/{executable-spec-CkGvdPds.js → executable-spec-DxuiDFAU.js} +2 -2
  29. package/dist/{executable-spec-CkGvdPds.js.map → executable-spec-DxuiDFAU.js.map} +1 -1
  30. package/dist/{graph-VTmSuXNo.js → graph-Cox_7pht.js} +93 -5
  31. package/dist/graph-Cox_7pht.js.map +1 -0
  32. package/dist/graph.d.ts +3 -3
  33. package/dist/graph.js +5 -5
  34. package/dist/{improvement-cycle-Cmpe5Uev.js → improvement-cycle-BYHefgVo.js} +7 -7
  35. package/dist/{improvement-cycle-Cmpe5Uev.js.map → improvement-cycle-BYHefgVo.js.map} +1 -1
  36. package/dist/{index-DHSZjuLC.d.ts → index-DA9jKuJc.d.ts} +3 -3
  37. package/dist/{index-BhtdFMnG.d.ts → index-DVob1IA1.d.ts} +117 -14
  38. package/dist/{index-Dg2UXocB.d.ts → index-DdmozvB8.d.ts} +4 -4
  39. package/dist/index.d.ts +9 -9
  40. package/dist/index.js +13 -13
  41. package/dist/intelligence.d.ts +5 -5
  42. package/dist/intelligence.js +6 -6
  43. package/dist/kernel.d.ts +7 -7
  44. package/dist/kernel.js +14 -14
  45. package/dist/{knowledge-SVRitzcp.js → knowledge-Bj1rDycX.js} +7 -7
  46. package/dist/{knowledge-SVRitzcp.js.map → knowledge-Bj1rDycX.js.map} +1 -1
  47. package/dist/knowledge.d.ts +1 -1
  48. package/dist/knowledge.js +1 -1
  49. package/dist/{loop-runner-bin-D2A4NfN7.js → loop-runner-bin-DgmtU0F0.js} +4 -4
  50. package/dist/{loop-runner-bin-D2A4NfN7.js.map → loop-runner-bin-DgmtU0F0.js.map} +1 -1
  51. package/dist/{loop-runner-bin-NanoP_bG.d.ts → loop-runner-bin-g9fWDuOh.d.ts} +3 -3
  52. package/dist/loop-runner-bin.d.ts +1 -1
  53. package/dist/loop-runner-bin.js +1 -1
  54. package/dist/mcp/bin.js +3 -3
  55. package/dist/mcp/index.d.ts +6 -6
  56. package/dist/mcp/index.js +7 -7
  57. package/dist/{model-policy-Sw4ywhtL.js → model-policy-Wf2MxXJ9.js} +12 -4
  58. package/dist/model-policy-Wf2MxXJ9.js.map +1 -0
  59. package/dist/{openai-tools-Cbk5uBUu.d.ts → openai-tools-BDwAdxk5.d.ts} +2 -2
  60. package/dist/{openai-tools-DCorsAv3.js → openai-tools-Cz04RKfD.js} +2 -2
  61. package/dist/{openai-tools-DCorsAv3.js.map → openai-tools-Cz04RKfD.js.map} +1 -1
  62. package/dist/{prepare-Tip-2ZoZ.js → prepare-BpIGs5Tc.js} +123 -40
  63. package/dist/prepare-BpIGs5Tc.js.map +1 -0
  64. package/dist/primeintellect/index.d.ts +1 -1
  65. package/dist/profiles.d.ts +2 -2
  66. package/dist/profiles.js +1 -1
  67. package/dist/{protected-model-port-Dd3a1SRm.js → protected-model-port-YclORl0x.js} +2 -2
  68. package/dist/{protected-model-port-Dd3a1SRm.js.map → protected-model-port-YclORl0x.js.map} +1 -1
  69. package/dist/{provision-supervisor-ey6o68i7.js → provision-supervisor-B-_4I1In.js} +7 -7
  70. package/dist/{provision-supervisor-ey6o68i7.js.map → provision-supervisor-B-_4I1In.js.map} +1 -1
  71. package/dist/{redact-BYcuQ6R_.d.ts → redact-C9EWk1FT.d.ts} +3 -3
  72. package/dist/{researcher-BMFFPwKb.js → researcher-hgPa5p9i.js} +2 -2
  73. package/dist/{researcher-BMFFPwKb.js.map → researcher-hgPa5p9i.js.map} +1 -1
  74. package/dist/{runtime-C90NMh9Y.js → runtime-DN0SxAaM.js} +15 -15
  75. package/dist/{runtime-C90NMh9Y.js.map → runtime-DN0SxAaM.js.map} +1 -1
  76. package/dist/{runtime-B-DLSfE5.d.ts → runtime-EQgE3942.d.ts} +23 -7
  77. package/dist/{sandbox-events-DGXLxiuX.js → sandbox-events-DWeQRWxg.js} +4 -2
  78. package/dist/sandbox-events-DWeQRWxg.js.map +1 -0
  79. package/dist/{spawn-journal--N8Ten1q.js → spawn-journal-CxRa-NJ2.js} +2 -2
  80. package/dist/{spawn-journal--N8Ten1q.js.map → spawn-journal-CxRa-NJ2.js.map} +1 -1
  81. package/dist/{stream-agent-turn-DY-y9yW1.d.ts → stream-agent-turn-BomJ21AK.d.ts} +3 -3
  82. package/dist/{stream-agent-turn-B5Cmq-u3.js → stream-agent-turn-DWWe_7bh.js} +4 -4
  83. package/dist/{stream-agent-turn-B5Cmq-u3.js.map → stream-agent-turn-DWWe_7bh.js.map} +1 -1
  84. package/dist/{structural-rollout-CsHxVoVH.js → structural-rollout-DPmVZaLI.js} +6 -6
  85. package/dist/{structural-rollout-CsHxVoVH.js.map → structural-rollout-DPmVZaLI.js.map} +1 -1
  86. package/dist/{substrate-RrmNZoL3.d.ts → substrate-qLePHqvH.d.ts} +2 -2
  87. package/dist/{supervise-rbZ-ppOC.js → supervise-BUy1cr2L.js} +246 -30
  88. package/dist/supervise-BUy1cr2L.js.map +1 -0
  89. package/dist/{supervisor-DBUmrQsF.js → supervisor-BSNkaM2a.js} +154 -23
  90. package/dist/supervisor-BSNkaM2a.js.map +1 -0
  91. package/dist/testing.d.ts +2 -2
  92. package/dist/testing.js +13 -13
  93. package/dist/tui/index.d.ts +1 -1
  94. package/dist/tui/index.js +1 -1
  95. package/dist/{types-B-rWcun_.d.ts → types-BbkiJR1D.d.ts} +37 -4
  96. package/dist/{types-CrTTgig6.d.ts → types-BdolQ6Zi.d.ts} +20 -1
  97. package/dist/{util-D6ZEuBMi.js → util-BfoW6RU7.js} +53 -4
  98. package/dist/util-BfoW6RU7.js.map +1 -0
  99. package/dist/{workspace-archive-ByonPBl-.js → workspace-archive-5K72EnlT.js} +2 -2
  100. package/dist/{workspace-archive-ByonPBl-.js.map → workspace-archive-5K72EnlT.js.map} +1 -1
  101. package/package.json +8 -8
  102. package/dist/environment-provider-6QtI-u5j.js.map +0 -1
  103. package/dist/environment-provider-CzohJCuk.d.ts +0 -89
  104. package/dist/graph-VTmSuXNo.js.map +0 -1
  105. package/dist/model-policy-Sw4ywhtL.js.map +0 -1
  106. package/dist/prepare-Tip-2ZoZ.js.map +0 -1
  107. package/dist/sandbox-events-DGXLxiuX.js.map +0 -1
  108. package/dist/supervise-rbZ-ppOC.js.map +0 -1
  109. package/dist/supervisor-DBUmrQsF.js.map +0 -1
  110. package/dist/util-D6ZEuBMi.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { k as Validator, r as Driver, t as AgentRunSpec, w as OutputAdapter } from "./types-CrTTgig6.js";
1
+ import { k as Validator, r as Driver, t as AgentRunSpec, w as OutputAdapter } from "./types-BdolQ6Zi.js";
2
2
  import { AgentProfile } from "@tangle-network/agent-interface";
3
3
  //#region src/profiles/coder.d.ts
4
4
  /**
@@ -281,4 +281,4 @@ interface UiFinding {
281
281
  }
282
282
  //#endregion
283
283
  export { CoderTask as _, UiFindingSeverity as a, KnowledgeUpdate as c, ResearchSource as d, ResearchTask as f, researcherProfile as g, multiHarnessResearcherFanout as h, UiFindingScreenshot as i, MultiHarnessResearcherFanoutOptions as l, createResearcherValidator as m, UI_LENSES as n, UiLens as o, ResearcherProfileOptions as p, UiFinding as r, KnowledgeItem as s, UI_FINDING_SEVERITIES as t, ResearchOutput as u, coderTaskToPrompt as v };
284
- //# sourceMappingURL=substrate-RrmNZoL3.d.ts.map
284
+ //# sourceMappingURL=substrate-qLePHqvH.d.ts.map
@@ -1,12 +1,12 @@
1
1
  import { C as runtimeOwnedScopeOwnerRuntime, S as runtimeOwnedPendingExecutorMaterialization, b as runtimeOwnedExecutorMaterialization, d as providerAttemptEvidence, f as recordRuntimeOwnedDriveHarnessProviderEvidence, i as attestRuntimeOwnedScopeOwner, s as inheritRuntimeOwnedExecutorAttestation, v as runtimeOwnedDriveHarnessProviderEvidence, x as runtimeOwnedExecutorProviderEvidence, y as runtimeOwnedExecutorExecutionBinding } from "./materialization-CekWK6OO.js";
2
2
  import { f as RuntimeRunStateError, i as ConfigError, m as ValidationError, o as NotFoundError, r as BackendTransportError, t as AgentEvalError } from "./errors-CDZ8XsVj.js";
3
3
  import { n as detachedSnapshot } from "./snapshot-CTAf4uuA.js";
4
- import { x as contentAddress } from "./spawn-journal--N8Ten1q.js";
5
- import { _ as unmeteredSpend } from "./util-D6ZEuBMi.js";
6
- import { a as concreteProfileModel, c as profileModelExecutionSettings, d as agentHarness, f as harnessRunsAgent, n as assertModelAllowed, o as enforceTokenLimits, r as assertProfileModelsAllowed, s as profileBridgeWireModel, t as assertExecutableAgentProfile } from "./model-policy-Sw4ywhtL.js";
7
- import { $ as bridgeModelRouteRefusal, An as controlProfileMaterialization, Fn as promptModelProfileMaterialization, Gt as routerBrain, J as assertValidBudget, K as DEFAULT_SUCCESSFUL_SHUTDOWN_MS, Mn as fullProfileMaterialization, Nn as profileMaterializationAxes$1, Pn as promptControlProfileMaterialization, Q as bridgeAdmissionRead, St as createInbox, Un as worktreeCliProfileMaterialization, Vn as unsupportedProfileDimensions, X as spendFromUsageEvents, Z as bindReusableExecutorExecutionId, _ as recordScopeOwnerMaterialization, at as createExecutor, d as driverChild, dn as toOtelAttributes, et as bridgeRuntimeAttachmentsKey, g as meterRuntimeOwnedProviderAttempt, h as meterRuntimeOwnedAccounting, in as createOtelExporter, jn as defineProfileMaterializationContract, kn as assertProfileMaterialization, l as runFinalizer, lt as WORKER_TRACE_PROPAGATION, m as deriveNodeExecutionIdentity, n as createSupervisor, nt as captureReusableExecutorConfig, o as bestDelivered, q as teardownExecutor, sn as generateSpanId, st as snapshotExecutorConfig, t as createRootHandle, tn as buildLoopSpanNodes, tt as bridgeStopSignalKey, u as runTree, v as scopeOwnerExecutorNodeContext, zn as renderUnsupported } from "./supervisor-DBUmrQsF.js";
4
+ import { x as contentAddress } from "./spawn-journal-CxRa-NJ2.js";
5
+ import { v as unmeteredSpend } from "./util-BfoW6RU7.js";
6
+ import { a as concreteProfileModel, c as profileModelExecutionSettings, d as agentHarness, f as harnessRunsAgent, n as assertModelAllowed, o as enforceTokenLimits, r as assertProfileModelsAllowed, s as profileBridgeWireModel, t as assertExecutableAgentProfile } from "./model-policy-Wf2MxXJ9.js";
7
+ import { $ as bridgeModelRouteRefusal, An as controlProfileMaterialization, Fn as promptModelProfileMaterialization, Gt as routerBrain, J as assertValidBudget, K as DEFAULT_SUCCESSFUL_SHUTDOWN_MS, Mn as fullProfileMaterialization, Nn as profileMaterializationAxes$1, Pn as promptControlProfileMaterialization, Q as bridgeAdmissionRead, St as createInbox, Un as worktreeCliProfileMaterialization, Vn as unsupportedProfileDimensions, X as spendFromUsageEvents, Z as bindReusableExecutorExecutionId, _ as recordScopeOwnerMaterialization, at as createExecutor, d as driverChild, dn as toOtelAttributes, et as bridgeRuntimeAttachmentsKey, g as meterRuntimeOwnedProviderAttempt, h as meterRuntimeOwnedAccounting, in as createOtelExporter, jn as defineProfileMaterializationContract, kn as assertProfileMaterialization, l as runFinalizer, lt as WORKER_TRACE_PROPAGATION, m as deriveNodeExecutionIdentity, n as createSupervisor, nt as captureReusableExecutorConfig, o as bestDelivered, q as teardownExecutor, sn as generateSpanId, st as snapshotExecutorConfig, t as createRootHandle, tn as buildLoopSpanNodes, tt as bridgeStopSignalKey, u as runTree, v as scopeOwnerExecutorNodeContext, zn as renderUnsupported } from "./supervisor-BSNkaM2a.js";
8
8
  import { t as composeRuntimeHooks } from "./runtime-hooks-tXpAarhW.js";
9
- import { C as coordinationVerbNames, c as createProgressTracker, d as progressStop, r as driverAgent, v as createFileRunContext, w as createCoordinationTools, y as createInMemoryRunContext } from "./coordination-driver-Dh_0SvXr.js";
9
+ import { C as coordinationVerbNames, c as createProgressTracker, d as progressStop, r as driverAgent, v as createFileRunContext, w as createCoordinationTools, y as createInMemoryRunContext } from "./coordination-driver-CtbyZv5d.js";
10
10
  import { k as writeRunCancellation, o as readRunCancelRequest, s as readRunCancellation } from "./run-layout-Cd_l2XWV.js";
11
11
  import { t as createStdioToolServer } from "./tool-server-DEmLr9YY.js";
12
12
  import { n as UI_LENSES } from "./substrate-B0TYNrXn.js";
@@ -435,6 +435,11 @@ function assignSpend(attrs, value) {
435
435
  }
436
436
  if (typeof spend.iterations === "number") attrs["tangle.supervise.iterations"] = spend.iterations;
437
437
  if (typeof spend.ms === "number" && spend.ms > 0) attrs["tangle.supervise.duration_ms"] = spend.ms;
438
+ if (typeof spend.boxMinutes === "number" && Number.isFinite(spend.boxMinutes)) attrs["tangle.platform.box_minutes"] = spend.boxMinutes;
439
+ if (spend.boxMinutesProvenance !== void 0) {
440
+ attrs["tangle.platform.box_minutes_provenance"] = spend.boxMinutesProvenance;
441
+ attrs["tangle.platform.box_minutes_known"] = spend.boxMinutesKnown === true;
442
+ }
438
443
  return spend;
439
444
  }
440
445
  function assignBudget(attrs, value) {
@@ -2393,11 +2398,46 @@ async function servePeerMail(mailbox, host) {
2393
2398
  *
2394
2399
  * The one loop the budget alone cannot bound is a driver that dies INSTANTLY and repeatedly — a
2395
2400
  * dead-on-arrival credential, a harness that refuses to start. Spending nothing, it would retry
2396
- * until the deadline hours later. So progress is measured between attempts (metered driver spend,
2397
- * settled children, an accepted submission), and a run of attempts that changes none of them stops
2398
- * at `maxConsecutiveFailures`. A failure that made progress resets that counter: a long run may be
2399
- * rescued many times, a hopeless one gives up in seconds.
2401
+ * until the deadline hours later. So progress is measured between attempts, and a run of attempts
2402
+ * that changes nothing stops at `maxConsecutiveFailures`. A failure that made progress resets that
2403
+ * counter: a long run may be rescued many times, a hopeless one gives up in seconds.
2404
+ *
2405
+ * WHAT COUNTS AS PROGRESS is the part this module got wrong first, and the correction is measured.
2406
+ * The original mark read metered spend, settled children, and an accepted submission — the
2407
+ * filesystem and the meter, never the goal. Across 1,422 settled discovery-lab runs (2026-09-01)
2408
+ * that reading retried the runs that had produced NOTHING 629 of 827 times (76.1%) while retrying
2409
+ * the runs that HAD left an artifact 21 of 399 times (5.3%): the loop spent its second chances on
2410
+ * the hopeless runs and measured persistence by burn rate. So when the caller declares a completion
2411
+ * check, spend and settlements alone are NOT progress while that check is unmet; only a delivery —
2412
+ * an accepted submission, a child that passed the check, or the contract turning met — resets the
2413
+ * barren counter. A caller that declares no check reports `contract: 'none'` and keeps the exact
2414
+ * historical reading.
2415
+ *
2416
+ * THE SECOND HALF of the same defect: `budgetStop` used to be consulted only after a failure, and a
2417
+ * driver that RETURNED with the contract unmet ended the run silently — 376 of 376 winning lab runs
2418
+ * ended on this loop's own `stop: 'completed'`, with the completion gate left to label the result
2419
+ * rather than to change it. A completed drive whose contract is unmet is now a first-class moment:
2420
+ * `reprompt.maxReprompts` re-enters the SAME live session with the unmet items, and every re-entry
2421
+ * crosses the same budget, deadline, abort, and attempt bounds a retry crosses.
2400
2422
  */
2423
+ /**
2424
+ * The instruction a completed-but-undelivered drive is re-entered with when the caller supplies no
2425
+ * `onUnmetContract`. It states the verdict, names what is owed, reports the ledger, and gives the
2426
+ * three steps — the same shape `depthStrategy` re-prompts a resumed session with, said in the
2427
+ * driver's own terms.
2428
+ */
2429
+ function defaultUnmetContractSteer(context) {
2430
+ const owed = context.describe?.trim();
2431
+ return [
2432
+ "The completion check has not passed. This run has delivered nothing yet.",
2433
+ owed === void 0 || owed.length === 0 ? "The deliverable this run owes is still missing." : `The deliverable this run owes: ${owed}`,
2434
+ `Workers settled: ${context.progress.settledCount}. Workers that passed the check: ${context.progress.deliveredCount ?? 0}.`,
2435
+ "Do the unfinished work with the tools.",
2436
+ "Verify that the check passes.",
2437
+ "Then submit the result.",
2438
+ "Do not restate work you already did."
2439
+ ].join("\n");
2440
+ }
2401
2441
  const DEFAULT_MAX_CONSECUTIVE_FAILURES = 3;
2402
2442
  const DEFAULT_MAX_ATTEMPTS = 8;
2403
2443
  const DEFAULT_INITIAL_BACKOFF_MS = 2e3;
@@ -2428,8 +2468,22 @@ function budgetStop(budget, atMs) {
2428
2468
  if (budget.usdCapped && budget.usdLeft <= 0) return "budget-exhausted";
2429
2469
  if (budget.usdCapped && budget.usdKnown === false) return "budget-exhausted";
2430
2470
  }
2471
+ function contractOf(mark) {
2472
+ return mark.contract ?? "none";
2473
+ }
2474
+ /**
2475
+ * Did this attempt move the run toward its DELIVERABLE?
2476
+ *
2477
+ * A delivery always counts: an accepted submission, one more child that passed the check, or the
2478
+ * contract turning met. Spend and settlements count only while no declared check is outstanding —
2479
+ * with a check unmet they are the burn-rate reading this module's header measures and rejects.
2480
+ */
2431
2481
  function madeProgress(before, after) {
2432
- return after.poolTokensSpent > before.poolTokensSpent || after.settledCount > before.settledCount || after.submitted && !before.submitted;
2482
+ if (after.submitted && !before.submitted) return true;
2483
+ if ((after.deliveredCount ?? 0) > (before.deliveredCount ?? 0)) return true;
2484
+ if (contractOf(before) !== "met" && contractOf(after) === "met") return true;
2485
+ if (contractOf(after) === "unmet") return false;
2486
+ return after.poolTokensSpent > before.poolTokensSpent || after.settledCount > before.settledCount;
2433
2487
  }
2434
2488
  /** The error a give-up throws: the original cause, re-described with the attempt history so
2435
2489
  * `driver-failed` carries a diagnosable message instead of one backend's last words. */
@@ -2466,9 +2520,12 @@ async function defaultSleep(ms, signal) {
2466
2520
  });
2467
2521
  }
2468
2522
  /**
2469
- * Run the driver, retrying transient failures until the budget, the deadline, an abort, a terminal
2470
- * error, or the no-progress ceiling stops it. Returns when an attempt completes; throws
2471
- * `DriverAttemptsExhaustedError` (cause = the last real failure) when it does not.
2523
+ * Run the driver until it completes WITH ITS CONTRACT MET, or until the budget, the deadline, an
2524
+ * abort, a terminal error, or a ceiling stops it. Transient failures are retried. A drive that
2525
+ * returns with its completion check unmet is re-entered on the same live session with the unmet
2526
+ * items, up to `reprompt.maxReprompts`. Throws `DriverAttemptsExhaustedError` (cause = the last
2527
+ * real failure) when a FAILURE ends the loop; a completed drive returns, met contract or not,
2528
+ * because deciding what an undelivered run is worth belongs to the finalizer, not to this loop.
2472
2529
  */
2473
2530
  async function runDriverWithRetry(run) {
2474
2531
  const now = run.now ?? Date.now;
@@ -2479,24 +2536,45 @@ async function runDriverWithRetry(run) {
2479
2536
  const maxAttempts = Math.max(1, policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);
2480
2537
  const initialBackoff = Math.max(0, policy.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS);
2481
2538
  const maxBackoff = Math.max(initialBackoff, policy.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS);
2539
+ const maxReprompts = Math.max(0, run.reprompt?.maxReprompts ?? 0);
2482
2540
  const attempts = [];
2483
2541
  let consecutiveBarren = 0;
2542
+ let reprompts = 0;
2543
+ let reentry;
2484
2544
  const emit = async (record) => {
2485
2545
  attempts.push(record);
2486
2546
  await run.onAttempt?.(record);
2487
2547
  };
2548
+ /**
2549
+ * Decide what a completed-but-undelivered drive does next. Every bound the FAILURE path applies
2550
+ * is applied here too — that is the fix for `budgetStop` having lived only in the catch arm — and
2551
+ * the caller's hook is consulted last, so no hook can talk the loop past a deadline.
2552
+ */
2553
+ const decideReprompt = async (attempt, after) => {
2554
+ if (reprompts >= maxReprompts) return { refusedBy: "reprompts-exhausted" };
2555
+ if (run.signal.aborted) return { refusedBy: "aborted" };
2556
+ const byBudget = budgetStop(run.budget(), now());
2557
+ if (byBudget === "deadline" || byBudget === "budget-exhausted") return { refusedBy: byBudget };
2558
+ if (attempt >= maxAttempts) return { refusedBy: "max-attempts" };
2559
+ const context = {
2560
+ attempt,
2561
+ reprompts,
2562
+ maxReprompts,
2563
+ progress: after,
2564
+ budget: run.budget(),
2565
+ ...run.reprompt?.describe === void 0 ? {} : { describe: run.reprompt.describe }
2566
+ };
2567
+ const decision = await run.reprompt?.onUnmetContract?.(context) ?? { steer: defaultUnmetContractSteer(context) };
2568
+ if (decision === "stop") return { refusedBy: "caller-stop" };
2569
+ const steer = typeof decision.steer === "string" ? decision.steer.trim() : "";
2570
+ if (steer.length === 0) throw new ValidationError("runDriverWithRetry: onUnmetContract returned an empty steer — return a non-empty instruction or 'stop'");
2571
+ return { steer };
2572
+ };
2488
2573
  for (let attempt = 1;; attempt += 1) {
2489
2574
  const before = run.progress();
2490
2575
  const startedAt = now();
2491
2576
  try {
2492
- await run.drive(attempt);
2493
- await emit({
2494
- attempt,
2495
- durationMs: now() - startedAt,
2496
- madeProgress: madeProgress(before, run.progress()),
2497
- stop: "completed"
2498
- });
2499
- return;
2577
+ await run.drive(attempt, reentry);
2500
2578
  } catch (error) {
2501
2579
  const durationMs = now() - startedAt;
2502
2580
  const classification = classifyDriverFailure(error, run.signal);
@@ -2523,6 +2601,7 @@ async function runDriverWithRetry(run) {
2523
2601
  throw new DriverAttemptsExhaustedError(error, attempts, stop);
2524
2602
  }
2525
2603
  consecutiveBarren = progressed ? 0 : consecutiveBarren + 1;
2604
+ reentry = void 0;
2526
2605
  const backoff = Math.min(maxBackoff, initialBackoff * 2 ** Math.max(0, consecutiveBarren - 1));
2527
2606
  await emit({
2528
2607
  attempt,
@@ -2536,7 +2615,50 @@ async function runDriverWithRetry(run) {
2536
2615
  if (run.signal.aborted) throw new DriverAttemptsExhaustedError(error, attempts, "aborted");
2537
2616
  const afterWait = budgetStop(run.budget(), now());
2538
2617
  if (afterWait) throw new DriverAttemptsExhaustedError(error, attempts, afterWait);
2618
+ continue;
2539
2619
  }
2620
+ const durationMs = now() - startedAt;
2621
+ const after = run.progress();
2622
+ const progressed = madeProgress(before, after);
2623
+ const contract = contractOf(after);
2624
+ const contractField = contract === "none" ? {} : { contract };
2625
+ if (contract === "unmet" && maxReprompts > 0) {
2626
+ const decision = await decideReprompt(attempt, after);
2627
+ if ("steer" in decision) {
2628
+ reprompts += 1;
2629
+ reentry = {
2630
+ reason: "unmet-contract",
2631
+ steer: decision.steer,
2632
+ reprompt: reprompts
2633
+ };
2634
+ await emit({
2635
+ attempt,
2636
+ durationMs,
2637
+ madeProgress: progressed,
2638
+ ...contractField,
2639
+ reprompted: true,
2640
+ retryInMs: 0
2641
+ });
2642
+ continue;
2643
+ }
2644
+ await emit({
2645
+ attempt,
2646
+ durationMs,
2647
+ madeProgress: progressed,
2648
+ ...contractField,
2649
+ repromptRefusedBy: decision.refusedBy,
2650
+ stop: "completed"
2651
+ });
2652
+ return;
2653
+ }
2654
+ await emit({
2655
+ attempt,
2656
+ durationMs,
2657
+ madeProgress: progressed,
2658
+ ...contractField,
2659
+ stop: "completed"
2660
+ });
2661
+ return;
2540
2662
  }
2541
2663
  }
2542
2664
  //#endregion
@@ -2890,6 +3012,10 @@ function buildSupervisorAgent(profile, deps, testBrain) {
2890
3012
  if (harness === null && coordination !== void 0) throw new ConfigError("supervisorAgent: coordination binding is only meaningful for a harness-brained supervisor (profile.harness set). A router-brained supervisor calls the coordination verbs in process and serves no MCP, so this binding would be silently ignored.");
2891
3013
  if (harness === null && deps.peerMail) throw new ValidationError("supervisorAgent: peerMail is only served by a harness-brained supervisor (profile.harness set). A router-brained supervisor serves no coordination MCP listener, so there is no peer-mail post office to mint worker capabilities from.");
2892
3014
  if (harness !== null && deps.compaction) throw new ValidationError("supervisorAgent: compaction is only supported for router-brained supervisors (profile.harness omitted or cli-base)");
3015
+ if (harness === null && (deps.repromptOnUnmet !== void 0 || deps.onUnmetContract !== void 0)) throw new ValidationError("supervisorAgent: repromptOnUnmet/onUnmetContract apply to an EXTERNAL-harness supervisor only (profile.harness set). A router-brained supervisor runs its own turn loop in process, so this option would be silently ignored.");
3016
+ if (deps.repromptOnUnmet !== void 0 && (!Number.isInteger(deps.repromptOnUnmet) || deps.repromptOnUnmet < 0)) throw new ValidationError("supervisorAgent: repromptOnUnmet must be a non-negative integer (0 = never re-prompt)");
3017
+ if (deps.onUnmetContract !== void 0 && (deps.repromptOnUnmet ?? 0) <= 0) throw new ValidationError("supervisorAgent: onUnmetContract needs repromptOnUnmet >= 1 — without a cap the hook is never consulted");
3018
+ if ((deps.repromptOnUnmet ?? 0) > 0 && deps.deliverable === void 0) throw new ValidationError("supervisorAgent: repromptOnUnmet needs a `deliverable` completion check — with no check there is no contract that can be unmet, and every run would re-prompt");
2893
3019
  if (harness === null) {
2894
3020
  assertRouterArmResourcePolicy(stableProfile);
2895
3021
  const brain = testBrain ?? routerBrainFromProfile(stableProfile, stableRouter);
@@ -3006,13 +3132,27 @@ function buildSupervisorAgent(profile, deps, testBrain) {
3006
3132
  ledger = mcp;
3007
3133
  try {
3008
3134
  const baseTokensLeft = scope.budget.tokensLeft;
3135
+ const contractDeclared = deps.deliverable !== void 0;
3136
+ const maxReprompts = deps.repromptOnUnmet ?? 0;
3137
+ const readProgress = () => {
3138
+ const settled = mcp.settled();
3139
+ const deliveredCount = settled.filter((w) => w.status === "done" && w.valid === true).length;
3140
+ const submitted = Boolean(mcp.submittedResult());
3141
+ return {
3142
+ poolTokensSpent: baseTokensLeft - scope.budget.tokensLeft,
3143
+ settledCount: settled.length,
3144
+ submitted,
3145
+ deliveredCount,
3146
+ contract: !contractDeclared ? "none" : submitted || deliveredCount > 0 ? "met" : "unmet"
3147
+ };
3148
+ };
3009
3149
  await runDriverWithRetry({
3010
- drive: async () => {
3150
+ drive: async (_attempt, reentry) => {
3011
3151
  try {
3012
3152
  await driveHarness({
3013
3153
  profile: stableProfile,
3014
3154
  ...profilePrompt !== void 0 ? { systemPrompt: profilePrompt } : {},
3015
- task,
3155
+ task: reentry === void 0 ? task : reentry.steer,
3016
3156
  scope,
3017
3157
  coordinationMcpUrl: mcp.url,
3018
3158
  stopSignal: stopController.signal,
@@ -3026,14 +3166,18 @@ function buildSupervisorAgent(profile, deps, testBrain) {
3026
3166
  if (!mcp.submittedResult() && !mcp.isStopped()) throw error;
3027
3167
  }
3028
3168
  },
3029
- progress: () => ({
3030
- poolTokensSpent: baseTokensLeft - scope.budget.tokensLeft,
3031
- settledCount: mcp.settled().length,
3032
- submitted: Boolean(mcp.submittedResult())
3033
- }),
3169
+ progress: readProgress,
3034
3170
  budget: () => scope.budget,
3035
3171
  signal: scope.signal,
3036
3172
  ...deps.driverRetry ? { policy: deps.driverRetry } : {},
3173
+ ...maxReprompts > 0 ? { reprompt: {
3174
+ maxReprompts,
3175
+ ...deps.deliverable?.describe === void 0 ? {} : { describe: deps.deliverable.describe },
3176
+ onUnmetContract: async (context) => {
3177
+ if (mcp.isStopped()) return "stop";
3178
+ return await deps.onUnmetContract?.(context) ?? { steer: defaultUnmetContractSteer(context) };
3179
+ }
3180
+ } } : {},
3037
3181
  ...deps.onDriverAttempt ? { onAttempt: deps.onDriverAttempt } : {}
3038
3182
  });
3039
3183
  await mcp.drainResolved();
@@ -3656,6 +3800,75 @@ function resolveNamed(option, table, value, registry) {
3656
3800
  if (entry === void 0) throw new ConfigError(`supervise: opts.${option} = ${JSON.stringify(value)} is not in opts.registry.${table} — the table resolved no entry under that name`);
3657
3801
  return entry;
3658
3802
  }
3803
+ const superviseOptionKeySet = /* @__PURE__ */ new Set([
3804
+ "allowedModels",
3805
+ "analysts",
3806
+ "analyzeOnSettle",
3807
+ "authorizeMessage",
3808
+ "authorizeSpawn",
3809
+ "backend",
3810
+ "blobs",
3811
+ "budget",
3812
+ "childSettleGraceMs",
3813
+ "compaction",
3814
+ "continuityByProfile",
3815
+ "coordination",
3816
+ "deliverable",
3817
+ "driveHarness",
3818
+ "driveHarnessMaterialization",
3819
+ "driverBackend",
3820
+ "driverRetry",
3821
+ "executeExtraTool",
3822
+ "execution",
3823
+ "extraTools",
3824
+ "finalizer",
3825
+ "hooks",
3826
+ "isDriverProfile",
3827
+ "journal",
3828
+ "makeLeafAgent",
3829
+ "makeWorkerAgent",
3830
+ "maxDepth",
3831
+ "maxLiveWorkers",
3832
+ "maxTurns",
3833
+ "now",
3834
+ "onCoordinationEvent",
3835
+ "onDriverAttempt",
3836
+ "onProgressStop",
3837
+ "otel",
3838
+ "peerMail",
3839
+ "perWorker",
3840
+ "probes",
3841
+ "profileSecurity",
3842
+ "registry",
3843
+ "resolveDeliverable",
3844
+ "resolveDriveHarness",
3845
+ "resolveSpawnProfile",
3846
+ "resolveSupervisorTools",
3847
+ "rootDriverFromBackend",
3848
+ "rootHandle",
3849
+ "router",
3850
+ "runDir",
3851
+ "runId",
3852
+ "signal",
3853
+ "stallAfterMs",
3854
+ "stopRule",
3855
+ "watchWorkers",
3856
+ "repromptOnUnmet",
3857
+ "onUnmetContract"
3858
+ ]);
3859
+ /**
3860
+ * Refuse a top-level option key `supervise()` reads nowhere, naming it.
3861
+ *
3862
+ * The shape is `assertExactConfigKeys`, which does the same for one executor configuration: an
3863
+ * unknown field is a caller asking for behavior that will not happen, and intake is the only
3864
+ * moment it is observable. The error class is not the same, on purpose. A bad `SuperviseOptions`
3865
+ * key is a configuration fault, and `ConfigError` is already what `supervise()` throws for one —
3866
+ * see `resolveNamed`, for an option that names a registry entry the registry does not hold.
3867
+ */
3868
+ function assertSuperviseOptionKeys(opts, context) {
3869
+ const unknown = Object.keys(opts).filter((key) => !superviseOptionKeySet.has(key));
3870
+ if (unknown.length > 0) throw new ConfigError(`${context}: unknown option ${unknown.sort().join(", ")} — no reader consults that name, so the value would be discarded and the capability it asks for would silently be absent`);
3871
+ }
3659
3872
  function captureDeliverable(deliverable, context) {
3660
3873
  if (typeof deliverable !== "object" || deliverable === null || Array.isArray(deliverable)) throw new ValidationError(`${context}: deliverable must be an object`);
3661
3874
  if (typeof deliverable.check !== "function") throw new ValidationError(`${context}: deliverable.check must be a function`);
@@ -3669,6 +3882,7 @@ function captureDeliverable(deliverable, context) {
3669
3882
  * Service internals intentionally remain live, while replacing a callback/service on the caller's
3670
3883
  * mutable options object can no longer change an in-flight run. */
3671
3884
  function captureSuperviseOptions(opts) {
3885
+ assertSuperviseOptionKeys(opts, "supervise");
3672
3886
  const { backend, driverBackend, deliverable, resolveDeliverable, router, compaction, watchWorkers, analysts, makeWorkerAgent, makeLeafAgent, resolveSpawnProfile, blobs, journal, probes, registry, hooks, otel, authorizeSpawn, authorizeMessage, isDriverProfile, driveHarness, resolveDriveHarness, resolveSupervisorTools, onCoordinationEvent, executeExtraTool, stopRule, onProgressStop, onDriverAttempt, finalizer, now, signal, rootHandle, ...decisionData } = opts;
3673
3887
  const capturedData = detachedSnapshot(decisionData, "supervise options");
3674
3888
  const capturedBackend = backend === void 0 ? void 0 : snapshotExecutorConfig(backend);
@@ -4161,6 +4375,8 @@ function superviseInternal(profile, task, opts, testBrain) {
4161
4375
  ...options.compaction ? { compaction: options.compaction } : {},
4162
4376
  ...options.driverRetry ? { driverRetry: options.driverRetry } : {},
4163
4377
  ...options.onDriverAttempt ? { onDriverAttempt: options.onDriverAttempt } : {},
4378
+ ...options.repromptOnUnmet !== void 0 ? { repromptOnUnmet: options.repromptOnUnmet } : {},
4379
+ ...options.onUnmetContract ? { onUnmetContract: options.onUnmetContract } : {},
4164
4380
  ...options.runDir === void 0 || runControl === void 0 ? {} : {
4165
4381
  controlDir: resolve(options.runDir),
4166
4382
  abortRun: (reason) => runControl.abort(reason)
@@ -4243,6 +4459,6 @@ function rootProviderModelEvidenceFromExecution(evidence) {
4243
4459
  return evidence ?? rootProviderModelEvidence([]);
4244
4460
  }
4245
4461
  //#endregion
4246
- export { hashIdempotencyInput as $, DELEGATION_HISTORY_INPUT_SCHEMA as A, DELEGATE_FEEDBACK_DESCRIPTION as B, createMcpServer as C, createDelegationStatusHandler as D, DELEGATION_STATUS_TOOL_NAME as E, DELEGATE_UI_AUDIT_DESCRIPTION as F, DELEGATE_DESCRIPTION as G, DELEGATE_FEEDBACK_TOOL_NAME as H, DELEGATE_UI_AUDIT_INPUT_SCHEMA as I, createDelegateHandler as J, DELEGATE_INPUT_SCHEMA as K, DELEGATE_UI_AUDIT_TOOL_NAME as L, createDelegationHistoryHandler as M, validateDelegationHistoryArgs as N, validateDelegationStatusArgs as O, delegationProfiles as P, DelegationTaskQueue as Q, createDelegateUiAuditHandler as R, createInProcessTransport as S, DELEGATION_STATUS_INPUT_SCHEMA as T, createDelegateFeedbackHandler as U, DELEGATE_FEEDBACK_INPUT_SCHEMA as V, validateDelegateFeedbackArgs as W, defaultDelegateBudget as X, validateDelegateArgs as Y, delegate as Z, promptHandle as _, assertCoordinationBinding as a, createDelegationTraceCollector as at, classifyDriverFailure as b, supervisorAgentWithTestBrain as c, FileDelegationStore as ct, delegatesWorkerBriefPrompt as d, eventToSnapshot as dt, DELEGATION_TRACE_MAX_BYTES as et, dumbContinuationFailPrompt as f, createSupervisorSpanRecorder as ft, naiveContinuationPrompt as g, kernelPromptRegistry as h, workerFromBackend as i, composeLoopTraceEmitters as it, DELEGATION_HISTORY_TOOL_NAME as j, DELEGATION_HISTORY_DESCRIPTION as k, analyzesFindingsReportPrompt as l, InMemoryDelegationStore as lt, formatPromptHandle as m, mapExecutorResult as mt, supervise as n, buildDelegationTraceSpans as nt, resolveSupervisorProfile as o, DelegationPersistenceError as ot, dumbContinuationPassPrompt as p, gateOnDeliverable as pt, DELEGATE_TOOL_NAME as q, superviseWithTestBrain as r, capDelegationTrace as rt, supervisorAgent as s, DelegationStateCorruptError as st, DEFAULT_AUTHORED_PROFILE_SECURITY_POLICY as t, DELEGATION_TRACE_MAX_SPANS as tt, createPromptRegistry as u, InMemoryFeedbackStore as ut, supervisorPolicyPrompt as v, DELEGATION_STATUS_DESCRIPTION as w, serveCoordinationMcp as x, DriverAttemptsExhaustedError as y, validateDelegateUiAuditArgs as z };
4462
+ export { DelegationTaskQueue as $, DELEGATION_HISTORY_DESCRIPTION as A, validateDelegateUiAuditArgs as B, createInProcessTransport as C, DELEGATION_STATUS_TOOL_NAME as D, DELEGATION_STATUS_INPUT_SCHEMA as E, delegationProfiles as F, validateDelegateFeedbackArgs as G, DELEGATE_FEEDBACK_INPUT_SCHEMA as H, DELEGATE_UI_AUDIT_DESCRIPTION as I, DELEGATE_TOOL_NAME as J, DELEGATE_DESCRIPTION as K, DELEGATE_UI_AUDIT_INPUT_SCHEMA as L, DELEGATION_HISTORY_TOOL_NAME as M, createDelegationHistoryHandler as N, createDelegationStatusHandler as O, validateDelegationHistoryArgs as P, delegate as Q, DELEGATE_UI_AUDIT_TOOL_NAME as R, serveCoordinationMcp as S, DELEGATION_STATUS_DESCRIPTION as T, DELEGATE_FEEDBACK_TOOL_NAME as U, DELEGATE_FEEDBACK_DESCRIPTION as V, createDelegateFeedbackHandler as W, validateDelegateArgs as X, createDelegateHandler as Y, defaultDelegateBudget as Z, promptHandle as _, assertCoordinationBinding as a, composeLoopTraceEmitters as at, classifyDriverFailure as b, supervisorAgentWithTestBrain as c, DelegationStateCorruptError as ct, delegatesWorkerBriefPrompt as d, InMemoryFeedbackStore as dt, hashIdempotencyInput as et, dumbContinuationFailPrompt as f, eventToSnapshot as ft, naiveContinuationPrompt as g, kernelPromptRegistry as h, mapExecutorResult as ht, workerFromBackend as i, capDelegationTrace as it, DELEGATION_HISTORY_INPUT_SCHEMA as j, validateDelegationStatusArgs as k, analyzesFindingsReportPrompt as l, FileDelegationStore as lt, formatPromptHandle as m, gateOnDeliverable as mt, supervise as n, DELEGATION_TRACE_MAX_SPANS as nt, resolveSupervisorProfile as o, createDelegationTraceCollector as ot, dumbContinuationPassPrompt as p, createSupervisorSpanRecorder as pt, DELEGATE_INPUT_SCHEMA as q, superviseWithTestBrain as r, buildDelegationTraceSpans as rt, supervisorAgent as s, DelegationPersistenceError as st, DEFAULT_AUTHORED_PROFILE_SECURITY_POLICY as t, DELEGATION_TRACE_MAX_BYTES as tt, createPromptRegistry as u, InMemoryDelegationStore as ut, supervisorPolicyPrompt as v, createMcpServer as w, defaultUnmetContractSteer as x, DriverAttemptsExhaustedError as y, createDelegateUiAuditHandler as z };
4247
4463
 
4248
- //# sourceMappingURL=supervise-rbZ-ppOC.js.map
4464
+ //# sourceMappingURL=supervise-BUy1cr2L.js.map