@tangle-network/agent-runtime 0.188.1 → 0.190.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activation-C39nGToq.js → activation-BgRWFKZi.js} +3 -3
- package/dist/{activation-C39nGToq.js.map → activation-BgRWFKZi.js.map} +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -3
- package/dist/{authoring-fsUwd9hg.js → authoring-dQQ2z1fT.js} +2 -2
- package/dist/{authoring-fsUwd9hg.js.map → authoring-dQQ2z1fT.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +4 -4
- package/dist/candidate-execution/index.js +5 -5
- package/dist/{candidate-execution-CehLeZmx.js → candidate-execution-BSkZErxD.js} +255 -9
- package/dist/candidate-execution-BSkZErxD.js.map +1 -0
- package/dist/conversation.d.ts +1 -1
- package/dist/{coordination-driver-CtbyZv5d.js → coordination-driver-Da1IGdTP.js} +6 -6
- package/dist/coordination-driver-Da1IGdTP.js.map +1 -0
- package/dist/{durable-file-g3YdfEh4.js → durable-file-D24y9zg7.js} +2 -2
- package/dist/{durable-file-g3YdfEh4.js.map → durable-file-D24y9zg7.js.map} +1 -1
- package/dist/durable.d.ts +2 -2
- package/dist/durable.js +3 -3
- package/dist/{environment-provider-C4AQiUxj.d.ts → environment-provider-Bf-hgR6p.d.ts} +2 -2
- package/dist/{environment-provider-DZxuH3E4.js → environment-provider-DcelIawX.js} +2 -2
- package/dist/{environment-provider-DZxuH3E4.js.map → environment-provider-DcelIawX.js.map} +1 -1
- package/dist/environment-provider.d.ts +1 -1
- package/dist/environment-provider.js +1 -1
- package/dist/{graph-Cox_7pht.js → graph-Bd1elhdL.js} +5 -3
- package/dist/graph-Bd1elhdL.js.map +1 -0
- package/dist/graph.d.ts +3 -3
- package/dist/graph.js +5 -5
- package/dist/{improvement-cycle-CnHGNT5r.js → improvement-cycle-BanlFMyL.js} +7 -7
- package/dist/{improvement-cycle-CnHGNT5r.js.map → improvement-cycle-BanlFMyL.js.map} +1 -1
- package/dist/{index-DdmozvB8.d.ts → index-C-gBk5M9.d.ts} +5 -5
- package/dist/{index-DQv7iCeE.d.ts → index-CUosKU4N.d.ts} +145 -5
- package/dist/{index-DA9jKuJc.d.ts → index-Clb7_qML.d.ts} +2 -2
- package/dist/{index-DVob1IA1.d.ts → index-DpNil9jh.d.ts} +130 -56
- package/dist/index.d.ts +11 -11
- package/dist/index.js +12 -12
- package/dist/intelligence.d.ts +6 -6
- package/dist/intelligence.js +6 -6
- package/dist/kernel.d.ts +6 -6
- package/dist/kernel.js +12 -12
- package/dist/{knowledge-BZDVXRCl.js → knowledge-BXdXlv48.js} +5 -5
- package/dist/{knowledge-BZDVXRCl.js.map → knowledge-BXdXlv48.js.map} +1 -1
- package/dist/knowledge.d.ts +1 -1
- package/dist/knowledge.js +1 -1
- package/dist/{loop-runner-bin-hXqgNrPN.js → loop-runner-bin-CGQzzWAc.js} +3 -3
- package/dist/{loop-runner-bin-hXqgNrPN.js.map → loop-runner-bin-CGQzzWAc.js.map} +1 -1
- package/dist/{loop-runner-bin-g9fWDuOh.d.ts → loop-runner-bin-Cy4f9M6p.d.ts} +3 -3
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +3 -3
- package/dist/mcp/index.js +7 -7
- package/dist/mcp/memory-bin.js +1 -1
- package/dist/{memory-server-DsKOhzGf.js → memory-server-Crkevawz.js} +2 -2
- package/dist/{memory-server-DsKOhzGf.js.map → memory-server-Crkevawz.js.map} +1 -1
- package/dist/{openai-tools-Cz04RKfD.js → openai-tools-BSDk_umV.js} +2 -2
- package/dist/{openai-tools-Cz04RKfD.js.map → openai-tools-BSDk_umV.js.map} +1 -1
- package/dist/{prepare-BpIGs5Tc.js → prepare-B5fJ7mLS.js} +336 -246
- package/dist/prepare-B5fJ7mLS.js.map +1 -0
- package/dist/primeintellect/index.d.ts +1 -1
- package/dist/primeintellect/index.js +1 -1
- package/dist/profiles.js +1 -1
- package/dist/{protected-model-port-YclORl0x.js → protected-model-port-B0xFSAjt.js} +19 -7
- package/dist/protected-model-port-B0xFSAjt.js.map +1 -0
- package/dist/{protected-model-port-B8ssMyUg.d.ts → protected-model-port-BtXp2dUY.d.ts} +2 -2
- package/dist/{provision-supervisor-B-_4I1In.js → provision-supervisor-bwpzajiz.js} +8 -8
- package/dist/{provision-supervisor-B-_4I1In.js.map → provision-supervisor-bwpzajiz.js.map} +1 -1
- package/dist/{redact-C9EWk1FT.d.ts → redact-Cv1GfOFO.d.ts} +3 -3
- package/dist/{run-layout-Cd_l2XWV.js → run-layout-B8I_LXN-.js} +3 -3
- package/dist/{run-layout-Cd_l2XWV.js.map → run-layout-B8I_LXN-.js.map} +1 -1
- package/dist/{runtime-EQgE3942.d.ts → runtime-BMWmSu4A.d.ts} +202 -4
- package/dist/{runtime-CFltmoiL.js → runtime-Ddh7PyCy.js} +15 -15
- package/dist/{runtime-CFltmoiL.js.map → runtime-Ddh7PyCy.js.map} +1 -1
- package/dist/{spawn-journal-CxRa-NJ2.js → spawn-journal-B9eTmVAn.js} +2 -2
- package/dist/{spawn-journal-CxRa-NJ2.js.map → spawn-journal-B9eTmVAn.js.map} +1 -1
- package/dist/{stream-agent-turn-BomJ21AK.d.ts → stream-agent-turn-uqzf9ZEh.d.ts} +2 -2
- package/dist/{structural-rollout-C8sB6B4q.js → structural-rollout-0NKvKuFm.js} +3 -3
- package/dist/{structural-rollout-C8sB6B4q.js.map → structural-rollout-0NKvKuFm.js.map} +1 -1
- package/dist/{supervise-BUy1cr2L.js → supervise-yDiZAqlN.js} +372 -26
- package/dist/supervise-yDiZAqlN.js.map +1 -0
- package/dist/{supervisor-BSNkaM2a.js → supervisor-CqJW4qap.js} +489 -11
- package/dist/supervisor-CqJW4qap.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +13 -13
- package/dist/{top-app-DIBApkt1.js → top-app-KgIFpD9H.js} +3 -3
- package/dist/{top-app-DIBApkt1.js.map → top-app-KgIFpD9H.js.map} +1 -1
- package/dist/tui/bin.js +1 -1
- package/dist/tui/index.d.ts +1 -1
- package/dist/tui/index.js +2 -2
- package/dist/{types-BbkiJR1D.d.ts → types-02hXqnSP.d.ts} +37 -2
- package/dist/{types-19ZOddS3.d.ts → types-1s_29INY.d.ts} +15 -10
- package/dist/{util-BfoW6RU7.js → util-mCNUeboW.js} +21 -2
- package/dist/util-mCNUeboW.js.map +1 -0
- package/dist/{workspace-archive-5K72EnlT.js → workspace-archive-yAPDklLV.js} +4 -4
- package/dist/{workspace-archive-5K72EnlT.js.map → workspace-archive-yAPDklLV.js.map} +1 -1
- package/package.json +9 -9
- package/dist/candidate-execution-CehLeZmx.js.map +0 -1
- package/dist/coordination-driver-CtbyZv5d.js.map +0 -1
- package/dist/graph-Cox_7pht.js.map +0 -1
- package/dist/prepare-BpIGs5Tc.js.map +0 -1
- package/dist/protected-model-port-YclORl0x.js.map +0 -1
- package/dist/supervise-BUy1cr2L.js.map +0 -1
- package/dist/supervisor-BSNkaM2a.js.map +0 -1
- package/dist/util-BfoW6RU7.js.map +0 -1
|
@@ -1,20 +1,20 @@
|
|
|
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-
|
|
5
|
-
import { v as unmeteredSpend } from "./util-
|
|
4
|
+
import { x as contentAddress } from "./spawn-journal-B9eTmVAn.js";
|
|
5
|
+
import { v as unmeteredSpend } from "./util-mCNUeboW.js";
|
|
6
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,
|
|
7
|
+
import { $ as bridgeModelRouteRefusal, Fn as defineProfileMaterializationContract, Gn as unsupportedProfileDimensions, Gt as routerBrain, In as fullProfileMaterialization, J as assertValidBudget, K as DEFAULT_SUCCESSFUL_SHUTDOWN_MS, Ln as profileMaterializationAxes$1, Nn as assertProfileMaterialization, Pn as controlProfileMaterialization, Q as bridgeAdmissionRead, Rn as promptControlProfileMaterialization, St as createInbox, Un as renderUnsupported, X as spendFromUsageEvents, Z as bindReusableExecutorExecutionId, _ as recordScopeOwnerMaterialization, an as buildLoopSpanNodes, at as createExecutor, cn as createOtelExporter, d as driverChild, dn as generateSpanId, et as bridgeRuntimeAttachmentsKey, g as meterRuntimeOwnedProviderAttempt, h as meterRuntimeOwnedAccounting, hn as toOtelAttributes, l as runFinalizer, lt as WORKER_TRACE_PROPAGATION, m as deriveNodeExecutionIdentity, n as createSupervisor, nt as captureReusableExecutorConfig, o as bestDelivered, q as teardownExecutor, qn as worktreeCliProfileMaterialization, st as snapshotExecutorConfig, t as createRootHandle, tt as bridgeStopSignalKey, u as runTree, v as scopeOwnerExecutorNodeContext, zn as promptModelProfileMaterialization } from "./supervisor-CqJW4qap.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-
|
|
10
|
-
import { k as writeRunCancellation, o as readRunCancelRequest, s as readRunCancellation } from "./run-layout-
|
|
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-Da1IGdTP.js";
|
|
10
|
+
import { k as writeRunCancellation, o as readRunCancelRequest, s as readRunCancellation } from "./run-layout-B8I_LXN-.js";
|
|
11
11
|
import { t as createStdioToolServer } from "./tool-server-DEmLr9YY.js";
|
|
12
12
|
import { n as UI_LENSES } from "./substrate-B0TYNrXn.js";
|
|
13
13
|
import { agentProfileSchema, canonicalAgentProfileDigest, canonicalCandidateDigest, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
|
|
14
14
|
import { randomUUID } from "node:crypto";
|
|
15
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
15
16
|
import path, { dirname, resolve } from "node:path";
|
|
16
17
|
import { isMaterializerHarness } from "@tangle-network/agent-profile-materialize";
|
|
17
|
-
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
18
18
|
import { createServer } from "node:http";
|
|
19
19
|
import { Readable, Writable } from "node:stream";
|
|
20
20
|
//#region src/runtime/supervise/completion-gate.ts
|
|
@@ -84,7 +84,7 @@ function gateOnDeliverable(inner, deliverable) {
|
|
|
84
84
|
...inner.metered ? { metered: () => inner.metered?.() } : {},
|
|
85
85
|
execute(task, signal) {
|
|
86
86
|
const r = inner.execute(task, signal);
|
|
87
|
-
if (isAsyncIterable$
|
|
87
|
+
if (isAsyncIterable$2(r)) return (async function* () {
|
|
88
88
|
try {
|
|
89
89
|
for await (const ev of r) yield ev;
|
|
90
90
|
} finally {
|
|
@@ -144,7 +144,7 @@ function mapExecutorResult(inner, map) {
|
|
|
144
144
|
...inner.metered ? { metered: () => inner.metered?.() } : {},
|
|
145
145
|
execute(task, signal) {
|
|
146
146
|
const execution = inner.execute(task, signal);
|
|
147
|
-
if (isAsyncIterable$
|
|
147
|
+
if (isAsyncIterable$2(execution)) return (async function* () {
|
|
148
148
|
for await (const event of execution) yield event;
|
|
149
149
|
await settle(inner.resultArtifact(), task);
|
|
150
150
|
})();
|
|
@@ -157,7 +157,7 @@ function mapExecutorResult(inner, map) {
|
|
|
157
157
|
}
|
|
158
158
|
});
|
|
159
159
|
}
|
|
160
|
-
function isAsyncIterable$
|
|
160
|
+
function isAsyncIterable$2(v) {
|
|
161
161
|
return v != null && typeof v[Symbol.asyncIterator] === "function";
|
|
162
162
|
}
|
|
163
163
|
//#endregion
|
|
@@ -440,6 +440,7 @@ function assignSpend(attrs, value) {
|
|
|
440
440
|
attrs["tangle.platform.box_minutes_provenance"] = spend.boxMinutesProvenance;
|
|
441
441
|
attrs["tangle.platform.box_minutes_known"] = spend.boxMinutesKnown === true;
|
|
442
442
|
}
|
|
443
|
+
if (spend.tokensProvenance !== void 0) attrs["tangle.supervise.tokens_provenance"] = spend.tokensProvenance;
|
|
443
444
|
return spend;
|
|
444
445
|
}
|
|
445
446
|
function assignBudget(attrs, value) {
|
|
@@ -2440,8 +2441,8 @@ function defaultUnmetContractSteer(context) {
|
|
|
2440
2441
|
}
|
|
2441
2442
|
const DEFAULT_MAX_CONSECUTIVE_FAILURES = 3;
|
|
2442
2443
|
const DEFAULT_MAX_ATTEMPTS = 8;
|
|
2443
|
-
const DEFAULT_INITIAL_BACKOFF_MS = 2e3;
|
|
2444
|
-
const DEFAULT_MAX_BACKOFF_MS = 3e4;
|
|
2444
|
+
const DEFAULT_INITIAL_BACKOFF_MS$1 = 2e3;
|
|
2445
|
+
const DEFAULT_MAX_BACKOFF_MS$1 = 3e4;
|
|
2445
2446
|
/**
|
|
2446
2447
|
* Classify one driver failure. Runtime's own typed refusals are decisions and stay terminal;
|
|
2447
2448
|
* anything foreign is an accident and is retryable. A `BackendTransportError` is split by status
|
|
@@ -2506,7 +2507,7 @@ function describeUnknown(value) {
|
|
|
2506
2507
|
return String(value);
|
|
2507
2508
|
}
|
|
2508
2509
|
}
|
|
2509
|
-
async function defaultSleep(ms, signal) {
|
|
2510
|
+
async function defaultSleep$1(ms, signal) {
|
|
2510
2511
|
if (ms <= 0 || signal.aborted) return;
|
|
2511
2512
|
await new Promise((resolve) => {
|
|
2512
2513
|
const done = () => {
|
|
@@ -2529,13 +2530,13 @@ async function defaultSleep(ms, signal) {
|
|
|
2529
2530
|
*/
|
|
2530
2531
|
async function runDriverWithRetry(run) {
|
|
2531
2532
|
const now = run.now ?? Date.now;
|
|
2532
|
-
const sleep = run.sleep ?? defaultSleep;
|
|
2533
|
+
const sleep = run.sleep ?? defaultSleep$1;
|
|
2533
2534
|
const policy = run.policy ?? {};
|
|
2534
2535
|
const retryEnabled = policy.enabled !== false;
|
|
2535
2536
|
const maxConsecutive = Math.max(0, policy.maxConsecutiveFailures ?? DEFAULT_MAX_CONSECUTIVE_FAILURES);
|
|
2536
2537
|
const maxAttempts = Math.max(1, policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS);
|
|
2537
|
-
const initialBackoff = Math.max(0, policy.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS);
|
|
2538
|
-
const maxBackoff = Math.max(initialBackoff, policy.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS);
|
|
2538
|
+
const initialBackoff = Math.max(0, policy.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS$1);
|
|
2539
|
+
const maxBackoff = Math.max(initialBackoff, policy.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS$1);
|
|
2539
2540
|
const maxReprompts = Math.max(0, run.reprompt?.maxReprompts ?? 0);
|
|
2540
2541
|
const attempts = [];
|
|
2541
2542
|
let consecutiveBarren = 0;
|
|
@@ -3266,6 +3267,238 @@ function routerBrainFromProfile(profile, router) {
|
|
|
3266
3267
|
});
|
|
3267
3268
|
}
|
|
3268
3269
|
//#endregion
|
|
3270
|
+
//#region src/runtime/supervise/worker-retry.ts
|
|
3271
|
+
/**
|
|
3272
|
+
* WORKER-SPAWN RETRY — the second chance `driverRetry` gives the root, given to a leaf.
|
|
3273
|
+
*
|
|
3274
|
+
* `driverRetry` guards the root and nothing else. A worker that dies is typed into a `down`
|
|
3275
|
+
* settlement, which is the right shape when the worker RAN. It is the wrong shape when the worker
|
|
3276
|
+
* never started, and one failure produces exactly that:
|
|
3277
|
+
*
|
|
3278
|
+
* bridgeExecutor: bridge stream error: host-executor: acquire timeout after 60000ms
|
|
3279
|
+
* (in_flight=4/4, queued=1)
|
|
3280
|
+
*
|
|
3281
|
+
* Measured 2026-08-22 on discovery-lab cells oscnp s2/s3: two live cells held 2 leads and up to 8
|
|
3282
|
+
* workers on one bridge whose host executor caps live harness children at 4. A worker spawn that
|
|
3283
|
+
* queued past the bridge's single 60 s acquire deadline died there, and the run lost that worker
|
|
3284
|
+
* permanently even though a slot freed seconds later. The bridge retries nothing.
|
|
3285
|
+
*
|
|
3286
|
+
* Retrying execution is dangerous by default, so this seam is FAIL-CLOSED on two independent
|
|
3287
|
+
* proofs that the attempt did no work:
|
|
3288
|
+
*
|
|
3289
|
+
* 1. The error carries a PRE-SPAWN signature — a refusal the backend emits before the harness
|
|
3290
|
+
* child or the box exists ({@link isPreSpawnExecutorFailure}). No provider call started.
|
|
3291
|
+
* 2. The attempt yielded NO execution event. An attempt that streamed anything may have metered
|
|
3292
|
+
* usage, and a blind re-run would double-spend, so it stays fatal whatever its message says.
|
|
3293
|
+
*
|
|
3294
|
+
* Either proof missing means no retry. This is deliberately NARROWER than "is this an
|
|
3295
|
+
* infrastructure hiccup": `ECONNRESET` is a transient transport failure and is NOT retried here,
|
|
3296
|
+
* because it can arrive mid-stream after a metered call.
|
|
3297
|
+
*
|
|
3298
|
+
* Re-entry re-invokes `execute` on the SAME executor object. Nothing is rebuilt, so the executor's
|
|
3299
|
+
* runtime-owned materialization attestation, its bound session id, and its inbox are all the ones
|
|
3300
|
+
* the kernel admitted. For the bridge backend a second `execute` is a fresh session stream over the
|
|
3301
|
+
* same durable execution id, and a saturation refusal happens before that session's child spawned.
|
|
3302
|
+
*
|
|
3303
|
+
* @experimental
|
|
3304
|
+
*/
|
|
3305
|
+
/**
|
|
3306
|
+
* The backend refusals that are emitted BEFORE any child process, box, or provider request exists.
|
|
3307
|
+
*
|
|
3308
|
+
* Each is a queue admission deadline: the executor asked for a slot, waited, and was refused
|
|
3309
|
+
* without anything being started. The three names are the pools cli-bridge and the container host
|
|
3310
|
+
* admit through — the host executor, one scoped per-run host executor, and the container pool.
|
|
3311
|
+
*
|
|
3312
|
+
* The pattern is anchored to the whole phrase, including the `after <n>ms` deadline, so a message
|
|
3313
|
+
* that merely mentions a queue does not qualify.
|
|
3314
|
+
*/
|
|
3315
|
+
const PRE_SPAWN_SIGNATURES = Object.freeze([/\b(?:host-executor|scoped-host-executor|container-pool): acquire timeout after \d+ms\b/u]);
|
|
3316
|
+
const DEFAULT_MAX_TOTAL_MS = 9e5;
|
|
3317
|
+
const DEFAULT_INITIAL_BACKOFF_MS = 5e3;
|
|
3318
|
+
const DEFAULT_MAX_BACKOFF_MS = 6e4;
|
|
3319
|
+
/**
|
|
3320
|
+
* True when `error` is a backend refusal issued before anything ran.
|
|
3321
|
+
*
|
|
3322
|
+
* This answers "did this fail BEFORE any provider call", which is a strictly narrower question
|
|
3323
|
+
* than "is this an infrastructure hiccup". The broader question admits `ECONNRESET` and a bare
|
|
3324
|
+
* `fetch failed`, both of which can arrive after a metered call, and answering the broad question
|
|
3325
|
+
* where the narrow one is required is what makes a retry double-spend.
|
|
3326
|
+
*/
|
|
3327
|
+
function isPreSpawnExecutorFailure(error, additionalSignatures = []) {
|
|
3328
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3329
|
+
for (const signature of PRE_SPAWN_SIGNATURES) if (signature.test(message)) return true;
|
|
3330
|
+
for (const signature of additionalSignatures) if (signature.test(message)) return true;
|
|
3331
|
+
return false;
|
|
3332
|
+
}
|
|
3333
|
+
/** Read the policy, refusing a number a run cannot act on rather than silently clamping it. */
|
|
3334
|
+
function resolveWorkerSpawnRetry(policy) {
|
|
3335
|
+
if (policy === void 0 || policy.enabled === false) return void 0;
|
|
3336
|
+
const maxTotalMs = policy.maxTotalMs ?? DEFAULT_MAX_TOTAL_MS;
|
|
3337
|
+
const initialBackoffMs = policy.initialBackoffMs ?? DEFAULT_INITIAL_BACKOFF_MS;
|
|
3338
|
+
const maxBackoffMs = policy.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
|
|
3339
|
+
for (const [name, value] of [
|
|
3340
|
+
["maxTotalMs", maxTotalMs],
|
|
3341
|
+
["initialBackoffMs", initialBackoffMs],
|
|
3342
|
+
["maxBackoffMs", maxBackoffMs]
|
|
3343
|
+
]) if (!Number.isFinite(value) || value < 0) throw new ValidationError(`workerRetry.${name} must be a nonnegative finite number of milliseconds`);
|
|
3344
|
+
const signatures = policy.additionalPreSpawnSignatures ?? [];
|
|
3345
|
+
for (const signature of signatures) if (!(signature instanceof RegExp)) throw new ValidationError("workerRetry.additionalPreSpawnSignatures must contain RegExp values");
|
|
3346
|
+
return Object.freeze({
|
|
3347
|
+
maxTotalMs,
|
|
3348
|
+
initialBackoffMs,
|
|
3349
|
+
maxBackoffMs: Math.max(initialBackoffMs, maxBackoffMs),
|
|
3350
|
+
signatures: Object.freeze([...signatures])
|
|
3351
|
+
});
|
|
3352
|
+
}
|
|
3353
|
+
/**
|
|
3354
|
+
* Wrap a worker seam so a leaf whose spawn is refused before it runs is re-entered instead of
|
|
3355
|
+
* settling dead.
|
|
3356
|
+
*
|
|
3357
|
+
* The wrapper composes the agent's `executorFactory`, which is where a leaf executor is built with
|
|
3358
|
+
* the real child signal and node context, and it never replaces the executor object the factory
|
|
3359
|
+
* returned: the retry lives in one `execute` wrapper that carries the inner executor's attestation
|
|
3360
|
+
* forward and delegates every other surface to it.
|
|
3361
|
+
*/
|
|
3362
|
+
function withWorkerSpawnRetry(make, policy, hooks = {}) {
|
|
3363
|
+
const resolved = resolveWorkerSpawnRetry(policy);
|
|
3364
|
+
if (resolved === void 0) return make;
|
|
3365
|
+
return (profile, spawnContext) => {
|
|
3366
|
+
const agent = make(profile, spawnContext);
|
|
3367
|
+
const spec = agent.executorSpec;
|
|
3368
|
+
if (spec === void 0) return agent;
|
|
3369
|
+
const seamHooks = {
|
|
3370
|
+
...hooks,
|
|
3371
|
+
...typeof profile.name === "string" ? { worker: profile.name } : {}
|
|
3372
|
+
};
|
|
3373
|
+
if (spec.executorFactory !== void 0) {
|
|
3374
|
+
const innerFactory = spec.executorFactory;
|
|
3375
|
+
const executorFactory = (builtSpec, ctx) => retryPreSpawnRefusals(innerFactory(builtSpec, ctx), resolved, seamHooks);
|
|
3376
|
+
return {
|
|
3377
|
+
...agent,
|
|
3378
|
+
executorSpec: {
|
|
3379
|
+
...spec,
|
|
3380
|
+
executorFactory
|
|
3381
|
+
}
|
|
3382
|
+
};
|
|
3383
|
+
}
|
|
3384
|
+
if (spec.executor !== void 0) {
|
|
3385
|
+
const executor = retryPreSpawnRefusals(spec.executor, resolved, seamHooks);
|
|
3386
|
+
return {
|
|
3387
|
+
...agent,
|
|
3388
|
+
executorSpec: {
|
|
3389
|
+
...spec,
|
|
3390
|
+
executor
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
}
|
|
3394
|
+
return agent;
|
|
3395
|
+
};
|
|
3396
|
+
}
|
|
3397
|
+
/**
|
|
3398
|
+
* Re-enter `execute` on one executor while a pre-spawn refusal keeps proving nothing ran.
|
|
3399
|
+
*
|
|
3400
|
+
* Exported so an owner of `makeLeafAgent` — which builds its own executors — gets the same seam
|
|
3401
|
+
* without reimplementing the two proofs.
|
|
3402
|
+
*/
|
|
3403
|
+
function retryPreSpawnRefusals(inner, policy, hooks = {}) {
|
|
3404
|
+
const now = hooks.now ?? Date.now;
|
|
3405
|
+
const sleep = hooks.sleep ?? defaultSleep;
|
|
3406
|
+
/** The wait before the next attempt, or `null` when this failure stays fatal. */
|
|
3407
|
+
const nextWait = (error, attempt, yielded, startedAt, signal) => {
|
|
3408
|
+
if (yielded) return null;
|
|
3409
|
+
if (signal?.aborted) return null;
|
|
3410
|
+
if (!isPreSpawnExecutorFailure(error, policy.signatures)) return null;
|
|
3411
|
+
const backoff = Math.min(policy.maxBackoffMs, policy.initialBackoffMs * 2 ** (attempt - 1));
|
|
3412
|
+
if (now() - startedAt + backoff >= policy.maxTotalMs) return null;
|
|
3413
|
+
return backoff;
|
|
3414
|
+
};
|
|
3415
|
+
const report = (error, attempt, waitMs) => {
|
|
3416
|
+
hooks.onRetry?.({
|
|
3417
|
+
attempt,
|
|
3418
|
+
waitMs,
|
|
3419
|
+
...hooks.worker === void 0 ? {} : { worker: hooks.worker },
|
|
3420
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3421
|
+
});
|
|
3422
|
+
};
|
|
3423
|
+
const wrapped = {
|
|
3424
|
+
runtime: inner.runtime,
|
|
3425
|
+
...inner.budgetExempt !== void 0 ? { budgetExempt: inner.budgetExempt } : {},
|
|
3426
|
+
...inner.deliver ? { deliver: (message) => inner.deliver?.(message) } : {},
|
|
3427
|
+
...inner.progress ? { progress: () => inner.progress?.() } : {},
|
|
3428
|
+
...inner.traceSource ? { traceSource: () => inner.traceSource?.() } : {},
|
|
3429
|
+
...inner.metered ? { metered: () => inner.metered?.() } : {},
|
|
3430
|
+
...inner.interactive === void 0 ? {} : { interactive: () => interactiveOf(inner) },
|
|
3431
|
+
execute(task, signal) {
|
|
3432
|
+
const first = inner.execute(task, signal);
|
|
3433
|
+
const restart = () => inner.execute(task, signal);
|
|
3434
|
+
return isAsyncIterable$1(first) ? retryStream(first, restart, signal) : retryOneShot(first, restart, signal);
|
|
3435
|
+
},
|
|
3436
|
+
teardown: (grace) => inner.teardown(grace),
|
|
3437
|
+
resultArtifact: () => inner.resultArtifact()
|
|
3438
|
+
};
|
|
3439
|
+
async function* retryStream(first, restart, signal) {
|
|
3440
|
+
const startedAt = now();
|
|
3441
|
+
let execution = first;
|
|
3442
|
+
for (let attempt = 1;; attempt += 1) {
|
|
3443
|
+
let yielded = false;
|
|
3444
|
+
try {
|
|
3445
|
+
for await (const event of execution) {
|
|
3446
|
+
yielded = true;
|
|
3447
|
+
yield event;
|
|
3448
|
+
}
|
|
3449
|
+
return;
|
|
3450
|
+
} catch (error) {
|
|
3451
|
+
const waitMs = nextWait(error, attempt, yielded, startedAt, signal);
|
|
3452
|
+
if (waitMs === null) throw error;
|
|
3453
|
+
report(error, attempt, waitMs);
|
|
3454
|
+
await sleep(waitMs, signal);
|
|
3455
|
+
const next = restart();
|
|
3456
|
+
if (!isAsyncIterable$1(next)) throw new ValidationError("retryPreSpawnRefusals: executor changed execution shape between attempts");
|
|
3457
|
+
execution = next;
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
async function retryOneShot(first, restart, signal) {
|
|
3462
|
+
const startedAt = now();
|
|
3463
|
+
let execution = first;
|
|
3464
|
+
for (let attempt = 1;; attempt += 1) try {
|
|
3465
|
+
return await execution;
|
|
3466
|
+
} catch (error) {
|
|
3467
|
+
const waitMs = nextWait(error, attempt, false, startedAt, signal);
|
|
3468
|
+
if (waitMs === null) throw error;
|
|
3469
|
+
report(error, attempt, waitMs);
|
|
3470
|
+
await sleep(waitMs, signal);
|
|
3471
|
+
const next = restart();
|
|
3472
|
+
if (isAsyncIterable$1(next)) throw new ValidationError("retryPreSpawnRefusals: executor changed execution shape between attempts");
|
|
3473
|
+
execution = next;
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
return inheritRuntimeOwnedExecutorAttestation(inner, wrapped);
|
|
3477
|
+
}
|
|
3478
|
+
/** Forward the inner executor's interactive contract exactly. The method is present only when the
|
|
3479
|
+
* inner executor implements it, so the reachable call always has one to delegate to. */
|
|
3480
|
+
function interactiveOf(inner) {
|
|
3481
|
+
if (inner.interactive === void 0) throw new ValidationError("retryPreSpawnRefusals: inner executor exposes no interactive session");
|
|
3482
|
+
return inner.interactive();
|
|
3483
|
+
}
|
|
3484
|
+
function isAsyncIterable$1(value) {
|
|
3485
|
+
return value !== null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
|
|
3486
|
+
}
|
|
3487
|
+
/** The wait stays REF'd: a worker waiting out a saturated executor is live work, and an unref'd
|
|
3488
|
+
* timer lets the process exit mid-backoff when nothing else is pending. */
|
|
3489
|
+
function defaultSleep(ms, signal) {
|
|
3490
|
+
if (ms <= 0 || signal?.aborted) return Promise.resolve();
|
|
3491
|
+
return new Promise((resolve) => {
|
|
3492
|
+
const done = () => {
|
|
3493
|
+
clearTimeout(timer);
|
|
3494
|
+
signal?.removeEventListener("abort", done);
|
|
3495
|
+
resolve();
|
|
3496
|
+
};
|
|
3497
|
+
const timer = setTimeout(done, ms);
|
|
3498
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
3499
|
+
});
|
|
3500
|
+
}
|
|
3501
|
+
//#endregion
|
|
3269
3502
|
//#region src/runtime/supervise/supervise.ts
|
|
3270
3503
|
/**
|
|
3271
3504
|
* `supervise` — the one-call "just invoke the supervisor". Builds + runs a supervisor from its
|
|
@@ -3321,16 +3554,22 @@ function workerFromBackend(backend, deliverable, seams) {
|
|
|
3321
3554
|
...executionScope === void 0 ? {} : { scope: executionScope }
|
|
3322
3555
|
}));
|
|
3323
3556
|
const boundSessionId = boundBackend.backend === "bridge" ? boundBackend.sessionId : void 0;
|
|
3557
|
+
const peerMailAttachment = peerMailRuntimeAttachment(profile, capturedBackend, spawnContext);
|
|
3324
3558
|
const baseFactory = createExecutor(boundBackend);
|
|
3325
3559
|
const executorFactory = (spec, ctx) => {
|
|
3326
3560
|
if (boundSessionId !== void 0 && ctx.node?.nodeId !== void 0) bridgeSessionByWorker.set(ctx.node.nodeId, boundSessionId);
|
|
3327
3561
|
const extraSeams = seams?.();
|
|
3328
|
-
const
|
|
3562
|
+
const seamsForChild = extraSeams === void 0 && peerMailAttachment === void 0 ? ctx.seams : {
|
|
3563
|
+
...extraSeams,
|
|
3564
|
+
...ctx.seams,
|
|
3565
|
+
...peerMailAttachment === void 0 ? {} : { [bridgeRuntimeAttachmentsKey]: {
|
|
3566
|
+
...readCallerRuntimeAttachments(ctx.seams),
|
|
3567
|
+
...peerMailAttachment
|
|
3568
|
+
} }
|
|
3569
|
+
};
|
|
3570
|
+
const built = baseFactory(spec, seamsForChild === ctx.seams ? ctx : {
|
|
3329
3571
|
...ctx,
|
|
3330
|
-
seams:
|
|
3331
|
-
...extraSeams,
|
|
3332
|
-
...ctx.seams
|
|
3333
|
-
}
|
|
3572
|
+
seams: seamsForChild
|
|
3334
3573
|
});
|
|
3335
3574
|
return deliverable ? gateOnDeliverable(built, deliverable) : built;
|
|
3336
3575
|
};
|
|
@@ -3346,6 +3585,63 @@ function workerFromBackend(backend, deliverable, seams) {
|
|
|
3346
3585
|
};
|
|
3347
3586
|
};
|
|
3348
3587
|
}
|
|
3588
|
+
/**
|
|
3589
|
+
* The reserved MCP alias one worker's PEER MAIL capability endpoint mounts under.
|
|
3590
|
+
*
|
|
3591
|
+
* Distinct from the driver's coordination alias on purpose: the two servers carry different
|
|
3592
|
+
* authority. Coordination mounts spawn_worker / steer_agent / stop; mail mounts send_mail and
|
|
3593
|
+
* read_mail and nothing else, on a per-worker secret path bound to that worker's identity.
|
|
3594
|
+
*/
|
|
3595
|
+
const peerMailMcpAlias = "agent-runtime-peer-mail";
|
|
3596
|
+
/**
|
|
3597
|
+
* The Runtime-owned MCP attachment that carries this spawn's peer-mail endpoint into the worker,
|
|
3598
|
+
* or `undefined` when this backend runs no MCP client at all.
|
|
3599
|
+
*
|
|
3600
|
+
* The endpoint rides the SAME out-of-band channel the driver's coordination MCP rides
|
|
3601
|
+
* (`runtime_attachments` on the bridge wire), for the same reason: the capability path carries
|
|
3602
|
+
* fresh random bytes per process, so writing it into `AgentProfile.mcp` would move the canonical
|
|
3603
|
+
* profile digest a durable session is bound to, and a keyed re-spawn would then fail its identity
|
|
3604
|
+
* check against the journal. Nothing in the authored profile changes, and this runs inside the
|
|
3605
|
+
* leaf factory — after `authorizeSpawn` has already decided the profile — so the authorization
|
|
3606
|
+
* chain is unchanged.
|
|
3607
|
+
*
|
|
3608
|
+
* Three backend classes, three honest answers:
|
|
3609
|
+
*
|
|
3610
|
+
* - `bridge` MOUNTS it. cli-bridge advertises `capabilities.runtimeAttachments.mcp` and mounts
|
|
3611
|
+
* the named servers for the run without binding them into the session profile.
|
|
3612
|
+
* - `router`, `router-tools` and `provider` mount NOTHING. Those workers are in-process tool
|
|
3613
|
+
* loops with no MCP client; their tool surface is the caller's own array, and
|
|
3614
|
+
* `WorkerSpawnContext.peerMailUrl` is the deliverable a caller uses directly.
|
|
3615
|
+
* - Every other backend REFUSES the spawn. A sandbox box or a local CLI harness receives tools
|
|
3616
|
+
* only through its materialized `AgentProfile`, and the runtime has no channel that reaches it
|
|
3617
|
+
* out of band, so minting a capability it can never call would ledger a channel that does not
|
|
3618
|
+
* exist. This is the same rule `bridgeResumeSessionId` applies to `continuity: 'resume'`.
|
|
3619
|
+
*/
|
|
3620
|
+
function peerMailRuntimeAttachment(profile, backend, spawnContext) {
|
|
3621
|
+
const url = spawnContext?.peerMailUrl;
|
|
3622
|
+
if (url === void 0) return void 0;
|
|
3623
|
+
switch (backend.backend) {
|
|
3624
|
+
case "router":
|
|
3625
|
+
case "router-tools":
|
|
3626
|
+
case "provider": return;
|
|
3627
|
+
case "bridge": break;
|
|
3628
|
+
default: throw new ValidationError(`workerFromBackend: the '${backend.backend}' backend seam cannot mount a peer-mail endpoint — it materializes tools only through the AgentProfile, and writing a per-process capability URL there would move the canonical profile digest. Run peer-mail workers on the 'bridge' backend, mount the endpoint yourself from WorkerSpawnContext.peerMailUrl through makeLeafAgent or makeWorkerAgent, or drop peerMail for this run`);
|
|
3629
|
+
}
|
|
3630
|
+
if (profile.mcp?.[peerMailMcpAlias] !== void 0) throw new ValidationError(`workerFromBackend: profile MCP alias ${JSON.stringify(peerMailMcpAlias)} is reserved`);
|
|
3631
|
+
return Object.freeze({ [peerMailMcpAlias]: Object.freeze({
|
|
3632
|
+
transport: "http",
|
|
3633
|
+
url
|
|
3634
|
+
}) });
|
|
3635
|
+
}
|
|
3636
|
+
/**
|
|
3637
|
+
* Runtime attachments a caller already put on the child's `ExecutorContext`, so mounting peer mail
|
|
3638
|
+
* ADDS one server rather than replacing the map. An absent or malformed value contributes nothing;
|
|
3639
|
+
* the executor that reads the seam owns its validation and refuses a malformed map there.
|
|
3640
|
+
*/
|
|
3641
|
+
function readCallerRuntimeAttachments(seams) {
|
|
3642
|
+
const existing = seams[bridgeRuntimeAttachmentsKey];
|
|
3643
|
+
return existing !== null && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
3644
|
+
}
|
|
3349
3645
|
function externalExecutionId(kind, identity) {
|
|
3350
3646
|
return `${kind}-${canonicalCandidateDigest({
|
|
3351
3647
|
kind,
|
|
@@ -3854,7 +4150,9 @@ const superviseOptionKeySet = /* @__PURE__ */ new Set([
|
|
|
3854
4150
|
"stopRule",
|
|
3855
4151
|
"watchWorkers",
|
|
3856
4152
|
"repromptOnUnmet",
|
|
3857
|
-
"onUnmetContract"
|
|
4153
|
+
"onUnmetContract",
|
|
4154
|
+
"workerRetry",
|
|
4155
|
+
"onWorkerRetry"
|
|
3858
4156
|
]);
|
|
3859
4157
|
/**
|
|
3860
4158
|
* Refuse a top-level option key `supervise()` reads nowhere, naming it.
|
|
@@ -3877,13 +4175,47 @@ function captureDeliverable(deliverable, context) {
|
|
|
3877
4175
|
check: deliverable.check
|
|
3878
4176
|
});
|
|
3879
4177
|
}
|
|
4178
|
+
Object.freeze([...[
|
|
4179
|
+
"authorizeMessage",
|
|
4180
|
+
"authorizeSpawn",
|
|
4181
|
+
"driveHarness",
|
|
4182
|
+
"executeExtraTool",
|
|
4183
|
+
"finalizer",
|
|
4184
|
+
"isDriverProfile",
|
|
4185
|
+
"makeLeafAgent",
|
|
4186
|
+
"makeWorkerAgent",
|
|
4187
|
+
"now",
|
|
4188
|
+
"onCoordinationEvent",
|
|
4189
|
+
"onDriverAttempt",
|
|
4190
|
+
"onProgressStop",
|
|
4191
|
+
"onUnmetContract",
|
|
4192
|
+
"onWorkerRetry",
|
|
4193
|
+
"resolveDeliverable",
|
|
4194
|
+
"resolveDriveHarness",
|
|
4195
|
+
"resolveSpawnProfile",
|
|
4196
|
+
"resolveSupervisorTools",
|
|
4197
|
+
"stopRule"
|
|
4198
|
+
]]);
|
|
4199
|
+
/**
|
|
4200
|
+
* Refuse a callback that reached the decision-data remainder, naming the option.
|
|
4201
|
+
*
|
|
4202
|
+
* The type test above cannot see a callback nested inside an object-valued option, and
|
|
4203
|
+
* `detachedSnapshot` would report only that its input is not structured-cloneable. This says which
|
|
4204
|
+
* key carries the callback and what to do about it, so the next occurrence is a five-second fix
|
|
4205
|
+
* instead of a bisect over every option a caller passed.
|
|
4206
|
+
*/
|
|
4207
|
+
function assertNoUncapturedExecutableOption(decisionData) {
|
|
4208
|
+
const carried = Object.entries(decisionData).filter(([, value]) => typeof value === "function").map(([key]) => key);
|
|
4209
|
+
if (carried.length > 0) throw new ValidationError(`supervise: option ${carried.sort().join(", ")} carries a callback that the option capture does not forward, so the run would fail on a structured-clone refusal that names the snapshot instead of the option; lift the key out of the decision data in captureSuperviseOptions and add it to superviseExecutableOptionKeys`);
|
|
4210
|
+
}
|
|
3880
4211
|
/** Capture the public one-call configuration before any asynchronous work starts. Decision data is
|
|
3881
4212
|
* detached and frozen; executable ports are copied as the exact references selected at intake.
|
|
3882
4213
|
* Service internals intentionally remain live, while replacing a callback/service on the caller's
|
|
3883
4214
|
* mutable options object can no longer change an in-flight run. */
|
|
3884
4215
|
function captureSuperviseOptions(opts) {
|
|
3885
4216
|
assertSuperviseOptionKeys(opts, "supervise");
|
|
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;
|
|
4217
|
+
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, onUnmetContract, workerRetry, onWorkerRetry, finalizer, now, signal, rootHandle, ...decisionData } = opts;
|
|
4218
|
+
assertNoUncapturedExecutableOption(decisionData);
|
|
3887
4219
|
const capturedData = detachedSnapshot(decisionData, "supervise options");
|
|
3888
4220
|
const capturedBackend = backend === void 0 ? void 0 : snapshotExecutorConfig(backend);
|
|
3889
4221
|
const capturedDriverBackend = driverBackend === void 0 ? void 0 : snapshotExecutorConfig(driverBackend);
|
|
@@ -3908,6 +4240,15 @@ function captureSuperviseOptions(opts) {
|
|
|
3908
4240
|
...detachedSnapshot({ maxFindingsPerWorker: watchWorkers.maxFindingsPerWorker }, "supervise worker-watch configuration"),
|
|
3909
4241
|
...watchWorkers.detectors === void 0 ? {} : { detectors: Object.freeze([...watchWorkers.detectors]) }
|
|
3910
4242
|
});
|
|
4243
|
+
const capturedWorkerRetry = workerRetry === void 0 ? void 0 : Object.freeze({
|
|
4244
|
+
...detachedSnapshot({
|
|
4245
|
+
...workerRetry.enabled === void 0 ? {} : { enabled: workerRetry.enabled },
|
|
4246
|
+
...workerRetry.maxTotalMs === void 0 ? {} : { maxTotalMs: workerRetry.maxTotalMs },
|
|
4247
|
+
...workerRetry.initialBackoffMs === void 0 ? {} : { initialBackoffMs: workerRetry.initialBackoffMs },
|
|
4248
|
+
...workerRetry.maxBackoffMs === void 0 ? {} : { maxBackoffMs: workerRetry.maxBackoffMs }
|
|
4249
|
+
}, "supervise worker-retry configuration"),
|
|
4250
|
+
...workerRetry.additionalPreSpawnSignatures === void 0 ? {} : { additionalPreSpawnSignatures: Object.freeze([...workerRetry.additionalPreSpawnSignatures]) }
|
|
4251
|
+
});
|
|
3911
4252
|
const capturedAnalysts = analysts === void 0 || typeof analysts === "string" ? analysts : Object.freeze({
|
|
3912
4253
|
kinds: detachedSnapshot(analysts.kinds, "supervise analyst kinds"),
|
|
3913
4254
|
run: analysts.run
|
|
@@ -3939,6 +4280,9 @@ function captureSuperviseOptions(opts) {
|
|
|
3939
4280
|
...stopRule === void 0 ? {} : { stopRule },
|
|
3940
4281
|
...onProgressStop === void 0 ? {} : { onProgressStop },
|
|
3941
4282
|
...onDriverAttempt === void 0 ? {} : { onDriverAttempt },
|
|
4283
|
+
...onUnmetContract === void 0 ? {} : { onUnmetContract },
|
|
4284
|
+
...capturedWorkerRetry === void 0 ? {} : { workerRetry: capturedWorkerRetry },
|
|
4285
|
+
...onWorkerRetry === void 0 ? {} : { onWorkerRetry },
|
|
3942
4286
|
...finalizer === void 0 ? {} : { finalizer },
|
|
3943
4287
|
...now === void 0 ? {} : { now },
|
|
3944
4288
|
...signal === void 0 ? {} : { signal },
|
|
@@ -4111,6 +4455,7 @@ function superviseInternal(profile, task, opts, testBrain) {
|
|
|
4111
4455
|
const canonicalTask = freezeDetached(task);
|
|
4112
4456
|
if (options.makeWorkerAgent && options.authorizeSpawn) throw new ValidationError("supervise: authorizeSpawn cannot be combined with caller-owned makeWorkerAgent; use makeLeafAgent to override leaf execution inside the authorized path, or use backend-derived workers");
|
|
4113
4457
|
if (options.makeWorkerAgent && options.makeLeafAgent) throw new ValidationError("supervise: makeWorkerAgent replaces the worker path and makeLeafAgent overrides a leaf inside it; pass one");
|
|
4458
|
+
if (options.makeWorkerAgent && (options.workerRetry || options.onWorkerRetry)) throw new ValidationError("supervise: workerRetry applies only to backend-derived workers; compose withWorkerSpawnRetry onto a caller-owned makeWorkerAgent explicitly");
|
|
4114
4459
|
if (options.makeWorkerAgent && options.resolveDeliverable) throw new ValidationError("supervise: resolveDeliverable applies only to backend-derived workers; wrap a caller-owned makeWorkerAgent with its completion checks explicitly");
|
|
4115
4460
|
const authorizeDownFor = (parent, depth) => {
|
|
4116
4461
|
if (!options.authorizeSpawn && !options.authorizeMessage) return void 0;
|
|
@@ -4197,7 +4542,8 @@ function superviseInternal(profile, task, opts, testBrain) {
|
|
|
4197
4542
|
let makeWorkerAgent = options.makeWorkerAgent;
|
|
4198
4543
|
if (!makeWorkerAgent) {
|
|
4199
4544
|
if (!options.backend && !options.makeLeafAgent) throw new ValidationError("supervise: provide opts.backend (where workers run), opts.makeLeafAgent, or opts.makeWorkerAgent");
|
|
4200
|
-
const
|
|
4545
|
+
const withRetry = (make) => withWorkerSpawnRetry(make, options.workerRetry, { ...options.onWorkerRetry ? { onRetry: options.onWorkerRetry } : {} });
|
|
4546
|
+
const makeLeaf = withRetry(options.makeLeafAgent ?? workerFromBackend(options.backend, deliverable));
|
|
4201
4547
|
const securityPolicy = options.profileSecurity ?? DEFAULT_AUTHORED_PROFILE_SECURITY_POLICY;
|
|
4202
4548
|
const makeRecursiveWorkerFor = (parent, parentIdentity, depth, parentOwnerId) => {
|
|
4203
4549
|
const makeRecursiveWorker = (authoredProfile, spawnContext) => {
|
|
@@ -4254,7 +4600,7 @@ function superviseInternal(profile, task, opts, testBrain) {
|
|
|
4254
4600
|
const selectedDeliverable = options.resolveDeliverable?.(postAuthorizationContext);
|
|
4255
4601
|
const leafDeliverable = selectedDeliverable === void 0 ? deliverable : captureDeliverable(selectedDeliverable, `supervise deliverable for ${JSON.stringify(spawnContext.label)}`);
|
|
4256
4602
|
if (leafDeliverable !== deliverable && !options.backend) throw new ValidationError("supervise: resolveDeliverable selected a per-spawn deliverable but there is no backend to derive that leaf from; makeLeafAgent owns its own completion check");
|
|
4257
|
-
return (leafDeliverable === deliverable ? makeLeaf : workerFromBackend(options.backend, leafDeliverable))(authorized, Object.freeze({
|
|
4603
|
+
return (leafDeliverable === deliverable ? makeLeaf : withRetry(workerFromBackend(options.backend, leafDeliverable)))(authorized, Object.freeze({
|
|
4258
4604
|
...authorizedContext,
|
|
4259
4605
|
assignmentId: workerAssignmentNamespace(runNamespace, parentOwnerId, spawnContext.assignmentId)
|
|
4260
4606
|
}));
|
|
@@ -4459,6 +4805,6 @@ function rootProviderModelEvidenceFromExecution(evidence) {
|
|
|
4459
4805
|
return evidence ?? rootProviderModelEvidence([]);
|
|
4460
4806
|
}
|
|
4461
4807
|
//#endregion
|
|
4462
|
-
export {
|
|
4808
|
+
export { createDelegateHandler as $, DELEGATION_STATUS_INPUT_SCHEMA as A, DELEGATE_UI_AUDIT_DESCRIPTION as B, DriverAttemptsExhaustedError as C, createInProcessTransport as D, serveCoordinationMcp as E, DELEGATION_HISTORY_INPUT_SCHEMA as F, DELEGATE_FEEDBACK_DESCRIPTION as G, DELEGATE_UI_AUDIT_TOOL_NAME as H, DELEGATION_HISTORY_TOOL_NAME as I, createDelegateFeedbackHandler as J, DELEGATE_FEEDBACK_INPUT_SCHEMA as K, createDelegationHistoryHandler as L, createDelegationStatusHandler as M, validateDelegationStatusArgs as N, createMcpServer as O, DELEGATION_HISTORY_DESCRIPTION as P, DELEGATE_TOOL_NAME as Q, validateDelegationHistoryArgs as R, supervisorPolicyPrompt as S, defaultUnmetContractSteer as T, createDelegateUiAuditHandler as U, DELEGATE_UI_AUDIT_INPUT_SCHEMA as V, validateDelegateUiAuditArgs as W, DELEGATE_DESCRIPTION as X, validateDelegateFeedbackArgs as Y, DELEGATE_INPUT_SCHEMA as Z, dumbContinuationPassPrompt as _, createSupervisorSpanRecorder as _t, isPreSpawnExecutorFailure as a, DELEGATION_TRACE_MAX_BYTES as at, naiveContinuationPrompt as b, withWorkerSpawnRetry as c, capDelegationTrace as ct, supervisorAgent as d, DelegationPersistenceError as dt, validateDelegateArgs as et, supervisorAgentWithTestBrain as f, DelegationStateCorruptError as ft, dumbContinuationFailPrompt as g, eventToSnapshot as gt, delegatesWorkerBriefPrompt as h, InMemoryFeedbackStore as ht, workerFromBackend as i, hashIdempotencyInput as it, DELEGATION_STATUS_TOOL_NAME as j, DELEGATION_STATUS_DESCRIPTION as k, assertCoordinationBinding as l, composeLoopTraceEmitters as lt, createPromptRegistry as m, InMemoryDelegationStore as mt, supervise as n, delegate as nt, resolveWorkerSpawnRetry as o, DELEGATION_TRACE_MAX_SPANS as ot, analyzesFindingsReportPrompt as p, FileDelegationStore as pt, DELEGATE_FEEDBACK_TOOL_NAME as q, superviseWithTestBrain as r, DelegationTaskQueue as rt, retryPreSpawnRefusals as s, buildDelegationTraceSpans as st, DEFAULT_AUTHORED_PROFILE_SECURITY_POLICY as t, defaultDelegateBudget as tt, resolveSupervisorProfile as u, createDelegationTraceCollector as ut, formatPromptHandle as v, gateOnDeliverable as vt, classifyDriverFailure as w, promptHandle as x, kernelPromptRegistry as y, mapExecutorResult as yt, delegationProfiles as z };
|
|
4463
4809
|
|
|
4464
|
-
//# sourceMappingURL=supervise-
|
|
4810
|
+
//# sourceMappingURL=supervise-yDiZAqlN.js.map
|