@tangle-network/agent-runtime 4.0.0 → 6.0.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.
- package/CHANGELOG.md +5279 -0
- package/dist/{activation-BiQYCayd.js → activation-BRfZOfwb.js} +4 -4
- package/dist/{activation-BiQYCayd.js.map → activation-BRfZOfwb.js.map} +1 -1
- package/dist/{activation-B49A14V5.d.ts → activation-DEKw9CDD.d.ts} +2 -2
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +4 -4
- package/dist/{bundle-CV4Ts0cS.js → bundle-vFFiCigS.js} +2 -2
- package/dist/{bundle-CV4Ts0cS.js.map → bundle-vFFiCigS.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +71 -4
- package/dist/candidate-execution/index.js +4 -4
- package/dist/{coordination-manager-C-ZoeZ73.js → coordination-manager-RSJg5GmY.js} +12 -11
- package/dist/coordination-manager-RSJg5GmY.js.map +1 -0
- package/dist/{coordination-map-routing-SnsZp287.js → coordination-map-routing-DVjW5Gx0.js} +2 -2
- package/dist/coordination-map-routing-DVjW5Gx0.js.map +1 -0
- package/dist/{delegate-d9HcOFC5.js → delegate-C0cprMUN.js} +2 -2
- package/dist/{delegate-d9HcOFC5.js.map → delegate-C0cprMUN.js.map} +1 -1
- package/dist/durable.d.ts +5 -3
- package/dist/durable.js +14 -186
- package/dist/durable.js.map +1 -1
- package/dist/{graph-C_Z0Ua10.js → graph-cEg-gquv.js} +6 -8
- package/dist/{graph-C_Z0Ua10.js.map → graph-cEg-gquv.js.map} +1 -1
- package/dist/{graph-registry-CI1o16DH.js → graph-registry-B25FxBZN.js} +5 -5
- package/dist/graph-registry-B25FxBZN.js.map +1 -0
- package/dist/{graph-registry-BU7pcrUW.js → graph-registry-C-hjRx2t.js} +1 -1
- package/dist/{improve-B4v4S8jY.js → improve-DNl4_6lP.js} +8 -8
- package/dist/{improve-B4v4S8jY.js.map → improve-DNl4_6lP.js.map} +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +11 -11
- package/dist/intelligence.d.ts +5 -5
- package/dist/intelligence.js +8 -8
- package/dist/{jsonl-file-CvPuwM0a.js → jsonl-file-CeVYTIQJ.js} +41 -32
- package/dist/jsonl-file-CeVYTIQJ.js.map +1 -0
- package/dist/kernel.d.ts +3 -3
- package/dist/kernel.js +14 -13
- package/dist/{loop-runner-DKvA0JJr.d.ts → loop-runner-CDad0CCY.d.ts} +2 -2
- package/dist/{loop-runner-DMZkwlND.js → loop-runner-DQJjowz0.js} +2 -2
- package/dist/{loop-runner-DMZkwlND.js.map → loop-runner-DQJjowz0.js.map} +1 -1
- 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 +1 -1
- package/dist/mcp/index.js +6 -6
- package/dist/{prepare-DutbxpWr.js → prepare-B6SQA12v.js} +3 -3
- package/dist/{prepare-DutbxpWr.js.map → prepare-B6SQA12v.js.map} +1 -1
- package/dist/{profile-ClvuI8aY.js → profile-DN8Dw2Kp.js} +2 -2
- package/dist/{profile-ClvuI8aY.js.map → profile-DN8Dw2Kp.js.map} +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/{protected-model-port-DEsNIYi1.d.ts → protected-model-port-uN4M48vT.d.ts} +2 -2
- package/dist/{provision-supervisor-Cjs4SQ9Q.js → provision-supervisor-CtAaJCUa.js} +6 -6
- package/dist/{provision-supervisor-Cjs4SQ9Q.js.map → provision-supervisor-CtAaJCUa.js.map} +1 -1
- package/dist/{run-cancellation-CGgk54Md.js → run-cancellation-BCuu6khW.js} +3 -3
- package/dist/{run-cancellation-CGgk54Md.js.map → run-cancellation-BCuu6khW.js.map} +1 -1
- package/dist/run-state-ByHiAjUs.js +351 -0
- package/dist/run-state-ByHiAjUs.js.map +1 -0
- package/dist/{runtime-BmxmsaNz.js → runtime-9EYvBcHG.js} +19 -18
- package/dist/runtime-9EYvBcHG.js.map +1 -0
- package/dist/runtime-hooks-CsW2pfFk.js.map +1 -1
- package/dist/{runtime-hooks-ZQqPw-0g.d.ts → runtime-hooks-DPghSHV7.d.ts} +11 -16
- package/dist/{scope-CJ7xtrs8.js → scope-DzhBJrRN.js} +3632 -3528
- package/dist/scope-DzhBJrRN.js.map +1 -0
- package/dist/{search-executor-DSB6XAl1.js → search-executor-BJRNavck.js} +4 -4
- package/dist/{search-executor-DSB6XAl1.js.map → search-executor-BJRNavck.js.map} +1 -1
- package/dist/{server-FWT2Nt_w.js → server-DH0P6OY_.js} +4 -4
- package/dist/{server-FWT2Nt_w.js.map → server-DH0P6OY_.js.map} +1 -1
- package/dist/settle-record-BSDDf9Z4.js +130 -0
- package/dist/settle-record-BSDDf9Z4.js.map +1 -0
- package/dist/{structural-rollout-Bl23HSOd.js → structural-rollout-DgvJLTO0.js} +4 -4
- package/dist/{structural-rollout-Bl23HSOd.js.map → structural-rollout-DgvJLTO0.js.map} +1 -1
- package/dist/{supervise-MAzd0hOk.js → supervise-Cqhkb2Oj.js} +402 -450
- package/dist/supervise-Cqhkb2Oj.js.map +1 -0
- package/dist/{supervision-discovery-6EtvKCsU.js → supervision-discovery-DI5GIFBJ.js} +5 -130
- package/dist/supervision-discovery-DI5GIFBJ.js.map +1 -0
- package/dist/{supervisor-CwANBb9-.js → supervisor-B6sl14OR.js} +408 -1069
- package/dist/supervisor-B6sl14OR.js.map +1 -0
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +13 -13
- package/dist/tool-loop.d.ts +1 -1
- package/dist/{top-web-CZP3RRhD.js → top-web-DGoXGxH8.js} +13 -9
- package/dist/{top-web-CZP3RRhD.js.map → top-web-DGoXGxH8.js.map} +1 -1
- package/dist/tui/bin.js +3 -3
- package/dist/tui/index.d.ts +2 -2
- package/dist/tui/index.js +2 -2
- package/dist/{types-ooyUaxq_.d.ts → types-niKnm6ux.d.ts} +270 -461
- package/dist/{workspace-streams-DbKiDOWA.d.ts → workspace-archive-DS9E9tUr.d.ts} +2 -69
- package/dist/{workspace-streams-8ALHaZzx.js → workspace-streams-BqNM06y4.js} +34 -9
- package/dist/workspace-streams-BqNM06y4.js.map +1 -0
- package/package.json +9 -10
- package/dist/coordination-manager-C-ZoeZ73.js.map +0 -1
- package/dist/coordination-map-routing-SnsZp287.js.map +0 -1
- package/dist/graph-registry-CI1o16DH.js.map +0 -1
- package/dist/jsonl-file-CvPuwM0a.js.map +0 -1
- package/dist/runtime-BmxmsaNz.js.map +0 -1
- package/dist/scope-CJ7xtrs8.js.map +0 -1
- package/dist/supervise-MAzd0hOk.js.map +0 -1
- package/dist/supervision-discovery-6EtvKCsU.js.map +0 -1
- package/dist/supervisor-CwANBb9-.js.map +0 -1
- package/dist/workspace-streams-8ALHaZzx.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $
|
|
1
|
+
import { $ as hasRetriableTeardowns, $i as parseCodexUsageRecord, $r as RetainedExecutionPendingError, An as mergeTraceEnv, Ar as recordRuntimeOwnedProviderModel, Bi as extractTransportEventIdentity, Br as executableAgentProfileSnapshot, Ci as hashJson, Cr as knownMaterializationReceipt, D as prepareScopeResume, Dn as workerTraceEnv, Dr as recordRuntimeOwnedProviderAttemptStart, E as resolveWorkerSlots, Ei as createBudgetPool, En as WORKER_TRACE_PROPAGATION, Fi as sandboxLeafOutputFromEvents, Gr as reportedFailureCause, Hi as canonicalSandboxUsageMode, Ht as scopeRetainedOwnerCheckpointing, Ii as sandboxOutputMarker, Ir as runtimeOwnedScopeOwnerControl, It as scopeRetainedOwnerSettled, Ji as sameModelId, Jn as harnessTranscriptFromLines, Jr as runtimeFailureRemediationSchema, Jt as ownedTreeRootSpawn, K as assertRecursiveReservationPolicy, Ki as isSandboxTerminalEvent, Kn as captureHarnessTranscript, Kr as runtimeFailureCause, Li as sandboxProgressEvents, Lr as runtimeOwnedScopeOwnerRuntime, Mi as createSandboxToolPartState, Mr as runtimeOwnedExecutorExecutionBinding, N as nestedScopeSeamKey, Nr as runtimeOwnedExecutorMaterialization, O as sumSpendFromEvents, On as workerTraceHeaders, Or as recordRuntimeOwnedProviderDispatchNotStarted, Q as closeScopeAdmission, Qr as DISPATCH_NOT_ADMITTED_CODE, Qt as nestedDriverTreeRoot, Rr as unknownExecutionBindingReceipt, Si as turnFailurePolicy, Sr as knownExecutionBindingReceipt, Ti as isCredentialRefusal, Tn as environmentGone, Tt as finalizeScopeOwnerMaterialization, U as appendTeardownConfirmation, Ui as createSandboxTurnEventCollector, V as appendSpawnEvents, Vi as assertSandboxServedModel, Vr as executableAgentSpecSnapshot, W as reenteredWorkers, Wi as createSandboxUsageLedger, Wn as HARNESS_TRANSCRIPT_SETTLE_TIMEOUT_MS, Wt as bindScopeRetainedOwnerProvider, Xi as sandboxTerminalUsageField, Xt as attestNestedDriverTreeOwner, Yi as sandboxEventServedBackend, Yn as harnessTranscriptUnavailable, Yr as runtimeProviderCode, Z as closeRetainedSlots, Zr as DISPATCH_EXECUTION_CHANGED_CODE, Zt as driverRuntime, _i as contentAddress, aa as freezeControlRef, ai as retainedExecutorSeamKey, bi as executorFailureInfra, br as finalizeRuntimeOwnedPendingExecutor, ca as abortReason, cn as stopRetainedNativeExecution, ct as releaseRetainedEnvironments, di as reportedResetAt, dn as mintRetainedIdentity, dt as startScopeRecoveries, ea as recordValue, ei as TRANSPORT_ERROR_CODES, en as encodeResultBlob, fi as unavailablePauseMs, fn as reconnectRetainedRun, ft as unconfirmedTeardowns, gr as attestRuntimeOwnedPendingExecutor, hr as attestRuntimeOwnedExecutor, ia as exactSession, ii as retainedExecutorContext, in as executorObservation, ir as describeToolArgs, kr as recordRuntimeOwnedProviderIdentityConflict, la as linkAbort, ln as verifyWorkspaceMarker, lt as retryUnconfirmedTeardowns, mi as unavailableSignalOfFailure, mn as startRetainedRun, mr as attestRuntimeOwnedDeferredExecutor, na as assertEventBinding, ni as isSchemaRejection, nn as closesCursorSlot, oa as sameControlCoordinates, oi as UNAVAILABLE_CODES, on as observeModelRequest, or as isLiveNodeStatus, ot as registerNestedTeardownScope, pa as promptOptionsFromAgentTurnInput, pi as unavailableResumeAt, pn as recoverRetainedRun, pr as subscriptionUsageLimitSignal, pt as waitForScopeChildren, qi as notifySandboxEventObserver, qt as loadSpawnForest, ra as awaitAbortable, rr as createActivityLog, sa as RunCancellationReason, si as UNAVAILABLE_STATUSES, sn as describeRetainedNativeStops, st as releaseHeldEnvironments, t as createScope, ta as RetainedRunProviderContractError, ti as isProvisioningRefusal, tn as SpawnEventIndex, ua as runAbortable, ui as printedStatus, un as assertRetainedRunReplayMaterial, ut as settleManagerWork, vi as contentRef, wi as credentialCommandExit, wr as newExecutionAttemptId, xi as turnFailureOf, xr as inheritRuntimeOwnedExecutorAttestation, zr as unknownMaterializationReceipt } from "./scope-DzhBJrRN.js";
|
|
2
2
|
import { f as RuntimeRunStateError, i as ConfigError, m as ValidationError$1, r as BackendTransportError, t as AgentEvalError } from "./errors-AzSuGI23.js";
|
|
3
|
-
import { $ as
|
|
3
|
+
import { $ as mapWithConcurrency, B as hasControlCharacter, H as addSpend, J as errorMessage, K as cloneTokenUsage, Ot as teardownSurfaces, Q as isAsyncIterable, St as armDeadlineTimer, Tt as isDeadlineAbortReason, U as addTokenUsage, Z as isAbortError, _t as ACCEPTED_RESULT_GRACE_MS, at as stringifySafe, ct as unmeteredSpend, dt as zeroSpend, et as promptCacheTokenClasses, ft as zeroTokenUsage, gt as withBudgetResources, it as sleep, lt as unreportedSpend, nt as randomUuid, ot as throwAbort, pt as addResourceSpend, q as deleteBoxSafe, rt as roundBoxMinutes, st as throwIfAborted, tt as randomSuffix, ut as withTimeout, xt as ROOT_DEADLINE_REASON } from "./workspace-streams-BqNM06y4.js";
|
|
4
4
|
import { t as runTaskQueue } from "./task-queue-DbpZAp6C.js";
|
|
5
|
-
import { _ as errorText, d as detachedSnapshot, g as errorProperty, h as errorHttpStatus, l as sha256, m as errMessage, p as causeChain, v as defaultRedactor } from "./jsonl-file-
|
|
5
|
+
import { _ as errorText, d as detachedSnapshot, g as errorProperty, h as errorHttpStatus, l as sha256, m as errMessage, p as causeChain, v as defaultRedactor } from "./jsonl-file-CeVYTIQJ.js";
|
|
6
6
|
import { _ as agentHarness, a as concreteProfileModel, c as profileModelExecutionSettings, d as assertRouterAutoDeclaration, f as assertRouterAutoResponse, g as observedModelMatchesDeclared, h as observedModelHasSnapshot, l as profileProviderModel, m as mergeObservedModelIdentity, o as enforceTokenLimits, s as profileBridgeWireModel, t as assertExecutableAgentProfile, u as resolveRouterRetryPolicy } from "./model-policy-JOcg3NRs.js";
|
|
7
7
|
import { r as nativeSystemPrompt, t as assertSandboxProfileCompatibility } from "./sandbox-profile-compat-oFGWESLn.js";
|
|
8
8
|
import { a as writeAtomicDurableFile, s as fenceRunWrite } from "./durable-file-DstVeHcj.js";
|
|
@@ -5591,13 +5591,7 @@ const causedByPartialFailure = (error) => causeChain(error).some((cause) => caus
|
|
|
5591
5591
|
function abandonablePending(error) {
|
|
5592
5592
|
return error instanceof RetainedExecutionPendingError && (error.pendingCause === "unobservable" || error.pendingCause === "nested-recovery") ? error : void 0;
|
|
5593
5593
|
}
|
|
5594
|
-
/**
|
|
5595
|
-
* Bridge error classes the bridge itself never retries: a request that fails identically on
|
|
5596
|
-
* every attempt, mapped below 5xx on its HTTP path (`parse_error` 400, the other two 501). On the
|
|
5597
|
-
* stream path the same failure arrives with no status at all — a profile that cannot materialize
|
|
5598
|
-
* is a `parse_error` — and the status split alone read it as a bad moment and re-drove it to the
|
|
5599
|
-
* attempt ceiling.
|
|
5600
|
-
*/
|
|
5594
|
+
/** Deterministic bridge refusals remain terminal even when transport omits HTTP status. */
|
|
5601
5595
|
const DETERMINISTIC_BRIDGE_CODES = /* @__PURE__ */ new Set([
|
|
5602
5596
|
"parse_error",
|
|
5603
5597
|
"not_configured",
|
|
@@ -5612,15 +5606,7 @@ const DETERMINISTIC_BRIDGE_CODES = /* @__PURE__ */ new Set([
|
|
|
5612
5606
|
*/
|
|
5613
5607
|
const CONTENT_FILTER_REASON = "refused by the model provider's content filter";
|
|
5614
5608
|
const isContentFilterRefusal = (error) => causeChain(error).some((cause) => cause instanceof Error && /\bcontent was flagged for possible\b/iu.test(errorProperty(cause, "message") ?? ""));
|
|
5615
|
-
/**
|
|
5616
|
-
* A driver's harness turn ran to its terminal result, and that result reported failure.
|
|
5617
|
-
*
|
|
5618
|
-
* A provider executor returns a failed turn as an outcome; without this error it reads as a
|
|
5619
|
-
* completed drive and never reaches the retry decision (a turn ended `status code 524`).
|
|
5620
|
-
*
|
|
5621
|
-
* `errorCode` is the provider's machine code when it reported one. The classifier reads the code;
|
|
5622
|
-
* text decides only a printed capacity code and a content-filter refusal, which have none.
|
|
5623
|
-
*/
|
|
5609
|
+
/** A completed failed turn enters retry with its producer classification and legacy metadata intact. */
|
|
5624
5610
|
var HarnessTurnFailedError = class extends Error {
|
|
5625
5611
|
runtime;
|
|
5626
5612
|
/** The failure as the harness reported it, before this error's framing. */
|
|
@@ -5629,11 +5615,13 @@ var HarnessTurnFailedError = class extends Error {
|
|
|
5629
5615
|
statusCode;
|
|
5630
5616
|
/** The shared HTTP error reader also uses this status for persisted diagnostics. */
|
|
5631
5617
|
status;
|
|
5618
|
+
failure;
|
|
5632
5619
|
constructor(runtime, failure) {
|
|
5633
5620
|
super(`${runtime} harness turn ended with a failed outcome` + (failure.errorCode === void 0 ? "" : ` (${failure.errorCode})`) + `: ${failure.error}`);
|
|
5634
5621
|
this.name = "HarnessTurnFailedError";
|
|
5635
5622
|
this.runtime = runtime;
|
|
5636
5623
|
this.reported = failure.error;
|
|
5624
|
+
if (failure.failure !== void 0) this.failure = failure.failure;
|
|
5637
5625
|
if (failure.errorCode !== void 0) this.errorCode = failure.errorCode;
|
|
5638
5626
|
if (failure.statusCode !== void 0) {
|
|
5639
5627
|
this.statusCode = failure.statusCode;
|
|
@@ -5665,23 +5653,21 @@ function isDispatchExecutionChanged(value) {
|
|
|
5665
5653
|
return false;
|
|
5666
5654
|
}
|
|
5667
5655
|
}
|
|
5668
|
-
/**
|
|
5669
|
-
* The code or status that marks `error` as an upstream capacity refusal, or `undefined`.
|
|
5670
|
-
*
|
|
5671
|
-
* A structured field is read first: a turn outcome's `errorCode`, a transport error's
|
|
5672
|
-
* `upstreamCode` and `status`, a provider SDK error's `code` and `status`. The failure text is read
|
|
5673
|
-
* only as {@link unavailableSignalOfFailure} says, because a harness CLI reports the router's
|
|
5674
|
-
* refusal as text and Sandbox's held-room refusal shares its code with a shape that never fits.
|
|
5675
|
-
*/
|
|
5656
|
+
/** Read Runtime admission evidence before producer hints and legacy transport metadata. */
|
|
5676
5657
|
function upstreamUnavailableSignal(error) {
|
|
5677
5658
|
if (undispatchedCredentialExit(error) !== void 0) return "credential-unavailable";
|
|
5659
|
+
if (error instanceof CheckUnavailableError) return "check-unavailable";
|
|
5660
|
+
if (error instanceof CoordinationUnreachableError) return "coordination-unreachable";
|
|
5661
|
+
const typed = turnFailureOf(error);
|
|
5662
|
+
if (typed) return turnFailurePolicy(typed).classification === "unavailable" ? subscriptionUsageLimitSignal({
|
|
5663
|
+
error: "",
|
|
5664
|
+
errorCode: typed.code
|
|
5665
|
+
}) ?? typed.code : void 0;
|
|
5678
5666
|
const refusal = retainedAdmissionCause(error) ?? reconciliationCapacityRefusal(error);
|
|
5679
5667
|
if (refusal !== void 0) return upstreamUnavailableSignal(refusal);
|
|
5680
5668
|
if (!(error instanceof Error)) return void 0;
|
|
5681
5669
|
if (isCredentialRefusal(error)) return void 0;
|
|
5682
5670
|
if (isProviderSchemaRejection(error)) return void 0;
|
|
5683
|
-
if (error instanceof CheckUnavailableError) return "check-unavailable";
|
|
5684
|
-
if (error instanceof CoordinationUnreachableError) return "coordination-unreachable";
|
|
5685
5671
|
const transport = error instanceof BackendTransportError;
|
|
5686
5672
|
if (error instanceof AgentEvalError && !transport) return void 0;
|
|
5687
5673
|
const harness = error instanceof HarnessTurnFailedError;
|
|
@@ -5692,13 +5678,7 @@ function upstreamUnavailableSignal(error) {
|
|
|
5692
5678
|
};
|
|
5693
5679
|
return (harness ? subscriptionUsageLimitSignal(failure) : void 0) ?? unavailableSignalOfFailure(failure);
|
|
5694
5680
|
}
|
|
5695
|
-
/**
|
|
5696
|
-
* The capacity refusal an admitted execution's reconciliation met: a cause with an upstream
|
|
5697
|
-
* capacity code or HTTP 429. The execution is unresolved, not failed, so the driver pauses and
|
|
5698
|
-
* reconciles it again, never abandoning it; a contract violation stays terminal (#1204).
|
|
5699
|
-
* magnetar-rust-sandbox-20261102a's managers met `TangleCredentialCapacityError: HTTP 429` on
|
|
5700
|
-
* 1,407 reconciliations, each classed transient.
|
|
5701
|
-
*/
|
|
5681
|
+
/** Capacity encountered while reconciling an admitted execution pauses that same execution. */
|
|
5702
5682
|
function reconciliationCapacityRefusal(error) {
|
|
5703
5683
|
if (!(error instanceof RetainedExecutionPendingError) || error.phase !== "execution") return void 0;
|
|
5704
5684
|
if (error.pendingCause !== "unobservable" && error.pendingCause !== "transport") return void 0;
|
|
@@ -5714,21 +5694,10 @@ function ownCode(error) {
|
|
|
5714
5694
|
return;
|
|
5715
5695
|
}
|
|
5716
5696
|
}
|
|
5717
|
-
/**
|
|
5718
|
-
* Classify one driver failure. Runtime's own typed refusals are decisions and stay terminal; an
|
|
5719
|
-
* upstream capacity refusal is `unavailable`; anything else foreign is an accident and is
|
|
5720
|
-
* retryable. A `BackendTransportError` is split by status because the taxonomy already promises
|
|
5721
|
-
* consumers may branch on it: a 5xx/408 is the upstream having a bad moment, a 429/503/529 is the
|
|
5722
|
-
* upstream out of capacity, and a 401/404/422 is a request that will fail identically forever. The
|
|
5723
|
-
* bridge's own never-retry classes are terminal whether or not a status rides with them.
|
|
5724
|
-
*
|
|
5725
|
-
* An `AbortError` is the run's own only when `signal` (the run) or `stopSignal` (the manager's own
|
|
5726
|
-
* stop: an accepted result, `stop`, a stop rule) has fired. Any other is a lost stream and is
|
|
5727
|
-
* retried: on magnetar-rust-20261019b a 4.0 h root turn ended "bridgeExecutor: turn aborted" and,
|
|
5728
|
-
* classed terminal, settled the run after one attempt.
|
|
5729
|
-
*/
|
|
5697
|
+
/** Runtime cancellation/contracts dominate producer policy; untyped foreign failures retain legacy rules. */
|
|
5730
5698
|
function classifyDriverFailure(error, signal, stopSignal) {
|
|
5731
5699
|
if (signal?.aborted) return "terminal";
|
|
5700
|
+
if (error instanceof CheckUnavailableError || error instanceof CoordinationUnreachableError) return "unavailable";
|
|
5732
5701
|
if (error instanceof RetainedExecutionPendingError && error.pendingCause === "provider-contract") return "terminal";
|
|
5733
5702
|
if (undispatchedCredentialExit(error) !== void 0) return "unavailable";
|
|
5734
5703
|
const admission = retainedAdmissionCause(error);
|
|
@@ -5739,6 +5708,9 @@ function classifyDriverFailure(error, signal, stopSignal) {
|
|
|
5739
5708
|
if (error instanceof Error && isProviderSchemaRejection(error)) return "terminal";
|
|
5740
5709
|
if (isCredentialRefusal(error)) return "terminal";
|
|
5741
5710
|
if (causeChain(error).some(isProvisioningRefusal)) return "terminal";
|
|
5711
|
+
if (error instanceof AgentEvalError && !(error instanceof BackendTransportError)) return "terminal";
|
|
5712
|
+
const typed = turnFailureOf(error);
|
|
5713
|
+
if (typed) return turnFailurePolicy(typed).classification;
|
|
5742
5714
|
if (error instanceof HarnessTurnFailedError) {
|
|
5743
5715
|
if (error.errorCode !== void 0 && DETERMINISTIC_BRIDGE_CODES.has(error.errorCode)) return "terminal";
|
|
5744
5716
|
if (upstreamUnavailableSignal(error) !== void 0) return "unavailable";
|
|
@@ -5750,7 +5722,6 @@ function classifyDriverFailure(error, signal, stopSignal) {
|
|
|
5750
5722
|
const status = error.status;
|
|
5751
5723
|
return status === void 0 || status === 408 || status >= 500 ? "transient" : "terminal";
|
|
5752
5724
|
}
|
|
5753
|
-
if (error instanceof AgentEvalError) return "terminal";
|
|
5754
5725
|
if (upstreamUnavailableSignal(error) !== void 0) return "unavailable";
|
|
5755
5726
|
return foreignHttpStatusVerdict(error) ?? "transient";
|
|
5756
5727
|
}
|
|
@@ -5821,14 +5792,10 @@ const TRANSPORT_NAMES = /* @__PURE__ */ new Set([
|
|
|
5821
5792
|
"AbortError",
|
|
5822
5793
|
"RetainedStreamError"
|
|
5823
5794
|
]);
|
|
5824
|
-
/**
|
|
5825
|
-
* A transient failure's kind, read from typed fields on any cause, never its text. `infra` is a
|
|
5826
|
-
* transport that dropped, timed out or answered 408 or 5xx, and earns the outage bound; anything
|
|
5827
|
-
* else foreign is `deterministic`, an answer that repeats, and earns no window. Of 4,449 failed
|
|
5828
|
-
* attempts over the week to 2026-11-04, 2,019 were deterministic answers retried as transient
|
|
5829
|
-
* (a failed box's 409, a play repository's exit 128, an expired key's 401, a harness refusal).
|
|
5830
|
-
*/
|
|
5795
|
+
/** Producer infra earns the outage window; producer work earns only the bounded deterministic streak. */
|
|
5831
5796
|
function transientFailureKind(error) {
|
|
5797
|
+
const typed = turnFailureOf(error);
|
|
5798
|
+
if (typed) return turnFailurePolicy(typed).failureKind;
|
|
5832
5799
|
if (causedByPartialFailure(error)) return "deterministic";
|
|
5833
5800
|
return causeChain(error).some((cause) => {
|
|
5834
5801
|
if (!(cause instanceof Error)) return false;
|
|
@@ -6217,6 +6184,11 @@ function* chunkProgress(chunk, ledger, args) {
|
|
|
6217
6184
|
progress: {
|
|
6218
6185
|
kind: "tool_result",
|
|
6219
6186
|
toolName: result.name,
|
|
6187
|
+
status: result.status === "completed" ? "ok" : "error",
|
|
6188
|
+
...result.status === "error" ? { error: {
|
|
6189
|
+
type: "bridge-tool-error",
|
|
6190
|
+
message: result.error ?? "tool failed"
|
|
6191
|
+
} } : {},
|
|
6220
6192
|
...result.id === void 0 ? {} : { toolCallId: result.id },
|
|
6221
6193
|
result: result.status === "completed" ? result.output : { error: result.error }
|
|
6222
6194
|
}
|
|
@@ -7648,7 +7620,6 @@ function executionTaskPrompt$1(task, configuredPrompt) {
|
|
|
7648
7620
|
return prompt;
|
|
7649
7621
|
}
|
|
7650
7622
|
// src/runtime/supervise/runtime-seams.ts
|
|
7651
|
-
const sandboxCaptureOutputSeamKey = "runtime.sandboxCaptureOutput";
|
|
7652
7623
|
const routerSeamKey = "router";
|
|
7653
7624
|
const sandboxSeamKey = "sandbox";
|
|
7654
7625
|
const cliWorktreeSeamKey = "cli-worktree";
|
|
@@ -7995,374 +7966,6 @@ function publicCreateOptions(create) {
|
|
|
7995
7966
|
...secrets === void 0 ? {} : { secretNames: Array.isArray(secrets) ? [...secrets].sort() : Object.keys(secrets).sort() }
|
|
7996
7967
|
};
|
|
7997
7968
|
}
|
|
7998
|
-
// src/runtime/environment-provider/provider-retention-lifecycle.ts
|
|
7999
|
-
function createProviderCaptureMirrors(options, createProfile, node, state) {
|
|
8000
|
-
const nativePort = options.workspaceRetention?.captureNative === void 0 ? void 0 : options.workspaceRetention;
|
|
8001
|
-
let nativeInFlight;
|
|
8002
|
-
let nativeRunningInFlight;
|
|
8003
|
-
let nativeRunningStop;
|
|
8004
|
-
let nativeTimer;
|
|
8005
|
-
let nativeEvents = 0;
|
|
8006
|
-
let nativeEventsAtCopy;
|
|
8007
|
-
let lastNativeCopyMs = 0;
|
|
8008
|
-
let closeNativeMirror;
|
|
8009
|
-
const livePort = options.workspaceRetention?.captureLive === void 0 ? void 0 : options.workspaceRetention;
|
|
8010
|
-
let liveInFlight;
|
|
8011
|
-
let liveTimer;
|
|
8012
|
-
let liveStop;
|
|
8013
|
-
const stopLiveMirror = () => {
|
|
8014
|
-
if (liveTimer !== void 0) clearTimeout(liveTimer);
|
|
8015
|
-
liveTimer = void 0;
|
|
8016
|
-
liveStop?.abort(/* @__PURE__ */ new Error("live workspace capture stopped: its turn ended"));
|
|
8017
|
-
liveStop = void 0;
|
|
8018
|
-
};
|
|
8019
|
-
const startLiveMirror = (next) => {
|
|
8020
|
-
if (livePort?.liveIntervalMs === void 0) return;
|
|
8021
|
-
stopLiveMirror();
|
|
8022
|
-
const stop = new AbortController();
|
|
8023
|
-
liveStop = stop;
|
|
8024
|
-
const schedule = () => {
|
|
8025
|
-
liveTimer = setTimeout(() => {
|
|
8026
|
-
if (liveInFlight === void 0 && state.workspaceCapturePromise === void 0) {
|
|
8027
|
-
const tracked = captureProviderLiveWorkspace(livePort, {
|
|
8028
|
-
environment: next,
|
|
8029
|
-
executionId: state.workspaceExecutionId,
|
|
8030
|
-
...state.workspaceControlRef === void 0 ? {} : { controlRef: state.workspaceControlRef },
|
|
8031
|
-
...node === void 0 ? {} : { node },
|
|
8032
|
-
providerSessionId: state.providerSessionId,
|
|
8033
|
-
nativeSessionId: null,
|
|
8034
|
-
profile: createProfile
|
|
8035
|
-
}, stop.signal).then(() => void 0, () => void 0).finally(() => {
|
|
8036
|
-
if (liveInFlight === tracked) liveInFlight = void 0;
|
|
8037
|
-
});
|
|
8038
|
-
liveInFlight = tracked;
|
|
8039
|
-
}
|
|
8040
|
-
schedule();
|
|
8041
|
-
}, livePort.liveIntervalMs);
|
|
8042
|
-
liveTimer.unref?.();
|
|
8043
|
-
};
|
|
8044
|
-
schedule();
|
|
8045
|
-
};
|
|
8046
|
-
let nativeHoldsTranscript = false;
|
|
8047
|
-
const noteCaptureFailure = (error) => {
|
|
8048
|
-
if (nativeHoldsTranscript || state.harnessTranscript.status !== "unavailable") return;
|
|
8049
|
-
if (state.harnessTranscript.reason !== "capture-did-not-run" && state.harnessTranscript.reason !== "enumeration-failed") return;
|
|
8050
|
-
state.harnessTranscript = {
|
|
8051
|
-
status: "unavailable",
|
|
8052
|
-
reason: "enumeration-failed",
|
|
8053
|
-
skipped: [{
|
|
8054
|
-
path: state.workspaceExecutionId,
|
|
8055
|
-
reason: errorText(error instanceof Error ? error.message : error)
|
|
8056
|
-
}]
|
|
8057
|
-
};
|
|
8058
|
-
};
|
|
8059
|
-
const stopNativeMirror = async () => {
|
|
8060
|
-
if (nativeTimer !== void 0) clearTimeout(nativeTimer);
|
|
8061
|
-
nativeTimer = void 0;
|
|
8062
|
-
closeNativeMirror?.();
|
|
8063
|
-
closeNativeMirror = void 0;
|
|
8064
|
-
nativeRunningStop?.abort(/* @__PURE__ */ new Error("native session copy stopped: its turn ended"));
|
|
8065
|
-
nativeRunningStop = void 0;
|
|
8066
|
-
await nativeInFlight;
|
|
8067
|
-
};
|
|
8068
|
-
const captureNative = (next, phase, admitted, afterStop = false) => {
|
|
8069
|
-
if (nativePort === void 0 || createProfile.harness === void 0) return Promise.resolve();
|
|
8070
|
-
const harness = createProfile.harness;
|
|
8071
|
-
const stop = phase === "running" ? new AbortController() : void 0;
|
|
8072
|
-
if (stop !== void 0) nativeRunningStop = stop;
|
|
8073
|
-
const tracked = (nativeInFlight ?? Promise.resolve()).then(async () => {
|
|
8074
|
-
stop?.signal.throwIfAborted();
|
|
8075
|
-
const controlRef = state.workspaceControlRef ?? admitted;
|
|
8076
|
-
const sessionId = state.providerSessionId ?? admitted?.sessionId ?? null;
|
|
8077
|
-
if (state.workspaceSnapshot !== void 0 && !nativeHoldsTranscript) return;
|
|
8078
|
-
const invocationId = state.workspaceExecutionId;
|
|
8079
|
-
const eventsAtStart = nativeEvents;
|
|
8080
|
-
const copyStartedAt = Date.now();
|
|
8081
|
-
try {
|
|
8082
|
-
const takeCopy = () => captureProviderWorkspaceSnapshot(nativePort, {
|
|
8083
|
-
environment: next,
|
|
8084
|
-
executionId: invocationId,
|
|
8085
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
8086
|
-
...node === void 0 ? {} : { node },
|
|
8087
|
-
providerSessionId: sessionId,
|
|
8088
|
-
nativeSessionId: null,
|
|
8089
|
-
profile: createProfile,
|
|
8090
|
-
phase
|
|
8091
|
-
}, "native", void 0, stop?.signal);
|
|
8092
|
-
let captured = await takeCopy();
|
|
8093
|
-
const settleBy = Date.now() + NATIVE_SETTLE_WINDOW_MS;
|
|
8094
|
-
while (afterStop && captured.coverageComplete !== true && (captured.provenance.attempts ?? []).some((attempt) => attempt.outcome === "unknown") && Date.now() < settleBy) {
|
|
8095
|
-
await sleep(NATIVE_SETTLE_POLL_MS);
|
|
8096
|
-
captured = await takeCopy();
|
|
8097
|
-
}
|
|
8098
|
-
if (state.workspaceSnapshot !== void 0 && !nativeHoldsTranscript) return;
|
|
8099
|
-
const copy = retainHarnessTranscript(providerWorkspaceCaptureReceipt({
|
|
8100
|
-
executionId: invocationId,
|
|
8101
|
-
profile: createProfile,
|
|
8102
|
-
...node === void 0 ? {} : { node },
|
|
8103
|
-
workspaceControlRef: () => controlRef,
|
|
8104
|
-
workspaceProvenance: () => captured.provenance,
|
|
8105
|
-
workspaceCoverage: () => ({
|
|
8106
|
-
complete: captured.coverageComplete ?? false,
|
|
8107
|
-
incompleteReason: captured.incompleteReason
|
|
8108
|
-
})
|
|
8109
|
-
}, next, captured.snapshot, sessionId), harness);
|
|
8110
|
-
if (nativeHoldsTranscript && !(copy.status === "retained" && copy.fileCount > 0)) return;
|
|
8111
|
-
state.harnessTranscript = copy;
|
|
8112
|
-
nativeHoldsTranscript = true;
|
|
8113
|
-
nativeEventsAtCopy = eventsAtStart;
|
|
8114
|
-
} catch (error) {
|
|
8115
|
-
if (stop?.signal.aborted) return;
|
|
8116
|
-
noteCaptureFailure(error);
|
|
8117
|
-
} finally {
|
|
8118
|
-
lastNativeCopyMs = Date.now() - copyStartedAt;
|
|
8119
|
-
}
|
|
8120
|
-
}).catch(() => void 0).finally(() => {
|
|
8121
|
-
if (nativeInFlight === tracked) nativeInFlight = void 0;
|
|
8122
|
-
if (nativeRunningInFlight === tracked) nativeRunningInFlight = void 0;
|
|
8123
|
-
if (nativeRunningStop === stop) nativeRunningStop = void 0;
|
|
8124
|
-
});
|
|
8125
|
-
nativeInFlight = tracked;
|
|
8126
|
-
if (stop !== void 0) nativeRunningInFlight = tracked;
|
|
8127
|
-
return tracked;
|
|
8128
|
-
};
|
|
8129
|
-
const startNativeMirror = (next) => {
|
|
8130
|
-
startLiveMirror(next);
|
|
8131
|
-
if (nativePort === void 0) return;
|
|
8132
|
-
if (nativeTimer !== void 0) clearTimeout(nativeTimer);
|
|
8133
|
-
closeNativeMirror?.();
|
|
8134
|
-
closeNativeMirror = openNativeMirror(nativePort);
|
|
8135
|
-
const port = nativePort;
|
|
8136
|
-
const interval = nativePort.nativeIntervalMs ?? 12e4;
|
|
8137
|
-
const schedule = () => {
|
|
8138
|
-
nativeTimer = setTimeout(() => {
|
|
8139
|
-
if (nativeInFlight === void 0 && !(nativeHoldsTranscript && nativeEventsAtCopy === nativeEvents)) captureNative(next, "running");
|
|
8140
|
-
schedule();
|
|
8141
|
-
}, nativeCopyDelayMs(port, interval, lastNativeCopyMs));
|
|
8142
|
-
nativeTimer.unref?.();
|
|
8143
|
-
};
|
|
8144
|
-
schedule();
|
|
8145
|
-
};
|
|
8146
|
-
const finishNativeMirror = async (next, phase) => {
|
|
8147
|
-
stopLiveMirror();
|
|
8148
|
-
await stopNativeMirror();
|
|
8149
|
-
if (state.workspaceSnapshot !== void 0 && !nativeHoldsTranscript) return;
|
|
8150
|
-
await captureNative(next, phase, void 0, state.harnessStopped);
|
|
8151
|
-
};
|
|
8152
|
-
return {
|
|
8153
|
-
get nativePort() {
|
|
8154
|
-
return nativePort;
|
|
8155
|
-
},
|
|
8156
|
-
get nativeRunningInFlight() {
|
|
8157
|
-
return nativeRunningInFlight;
|
|
8158
|
-
},
|
|
8159
|
-
get liveInFlight() {
|
|
8160
|
-
return liveInFlight;
|
|
8161
|
-
},
|
|
8162
|
-
get holdsTranscript() {
|
|
8163
|
-
return nativeHoldsTranscript;
|
|
8164
|
-
},
|
|
8165
|
-
set holdsTranscript(value) {
|
|
8166
|
-
nativeHoldsTranscript = value;
|
|
8167
|
-
},
|
|
8168
|
-
stopScheduledNativeCapture() {
|
|
8169
|
-
if (nativeTimer !== void 0) clearTimeout(nativeTimer);
|
|
8170
|
-
nativeTimer = void 0;
|
|
8171
|
-
},
|
|
8172
|
-
noteProviderEvent() {
|
|
8173
|
-
nativeEvents += 1;
|
|
8174
|
-
},
|
|
8175
|
-
noteCaptureFailure,
|
|
8176
|
-
stopLiveMirror,
|
|
8177
|
-
captureNative,
|
|
8178
|
-
startNativeMirror,
|
|
8179
|
-
finishNativeMirror
|
|
8180
|
-
};
|
|
8181
|
-
}
|
|
8182
|
-
/** How long the final copy of a stopped harness waits for the provider to record how it ended. */
|
|
8183
|
-
const NATIVE_SETTLE_WINDOW_MS = 15e3;
|
|
8184
|
-
const NATIVE_SETTLE_POLL_MS = 1e3;
|
|
8185
|
-
function createProviderNativeControl(provider, retention, managerStop, state) {
|
|
8186
|
-
let nativeStop;
|
|
8187
|
-
const cancelRetainedOnManagerStop = (handle) => {
|
|
8188
|
-
if (managerStop === void 0) return;
|
|
8189
|
-
const cancel = () => {
|
|
8190
|
-
if (state.retained !== handle || !state.workspaceRunActive) return;
|
|
8191
|
-
handle.cancel({
|
|
8192
|
-
operationId: `manager-stop:${randomUUID()}`,
|
|
8193
|
-
reason: String(managerStop.reason ?? "the manager stopped")
|
|
8194
|
-
}).catch(() => void 0);
|
|
8195
|
-
};
|
|
8196
|
-
const stop = () => managerStop.reason === "result-accepted" ? void armDeadlineTimer(ACCEPTED_RESULT_GRACE_MS, cancel) : cancel();
|
|
8197
|
-
if (managerStop.aborted) stop();
|
|
8198
|
-
else managerStop.addEventListener("abort", stop, { once: true });
|
|
8199
|
-
};
|
|
8200
|
-
/** Stop the native harness of this executor's retained execution, which local observation ending
|
|
8201
|
-
* never stops. Undefined when nothing was dispatched. */
|
|
8202
|
-
const stopNativeExecution = () => {
|
|
8203
|
-
if (nativeStop !== void 0) return nativeStop;
|
|
8204
|
-
const controlRef = state.retained?.controlRef ?? admittedControlRef(retention);
|
|
8205
|
-
if (controlRef === void 0) return Promise.resolve(void 0);
|
|
8206
|
-
const stopping = stopRetainedNativeExecution({
|
|
8207
|
-
provider,
|
|
8208
|
-
controlRef,
|
|
8209
|
-
...state.retained === void 0 ? {} : { handle: state.retained },
|
|
8210
|
-
signal: AbortSignal.timeout(NATIVE_STOP_TIMEOUT_MS)
|
|
8211
|
-
}).then((stop) => {
|
|
8212
|
-
if (stop.effect === "cancelled" || stop.effect === "not_live") state.harnessStopped = true;
|
|
8213
|
-
else if (nativeStop === stopping) nativeStop = void 0;
|
|
8214
|
-
return stop;
|
|
8215
|
-
});
|
|
8216
|
-
nativeStop = stopping;
|
|
8217
|
-
return stopping;
|
|
8218
|
-
};
|
|
8219
|
-
/** A turn its deadline or an explicit cancellation ended stops its harness, within the stop's
|
|
8220
|
-
* bound, before the turn's final native copy, which otherwise reads a session still written. */
|
|
8221
|
-
const stopEndedHarness = async (signal) => {
|
|
8222
|
-
if (!isDeadlineAbortReason(signal.reason) && !state.cancelledExplicitly()) return;
|
|
8223
|
-
await stopNativeExecution();
|
|
8224
|
-
};
|
|
8225
|
-
/**
|
|
8226
|
-
* A release that keeps an environment keeps its files, never its running harness. The root has
|
|
8227
|
-
* settled and no process will reconcile this execution, so its native process stops before the
|
|
8228
|
-
* release records what it kept.
|
|
8229
|
-
*/
|
|
8230
|
-
const withoutRunningHarness = (release) => async (signal) => {
|
|
8231
|
-
const stop = await awaitAbortable(stopNativeExecution(), signal).catch(() => void 0);
|
|
8232
|
-
const stopped = stop === void 0 ? "native stop unconfirmed: no exact dispatch or cleanup interrupted" : describeRetainedNativeStops([stop]);
|
|
8233
|
-
const environmentId = (state.retained?.controlRef ?? admittedControlRef(retention))?.environmentId ?? admittedEnvironmentId(retention);
|
|
8234
|
-
if (environmentId !== void 0 && !state.harnessStopped) {
|
|
8235
|
-
state.workspacePreservationRequired = true;
|
|
8236
|
-
return [{
|
|
8237
|
-
provider: provider.name,
|
|
8238
|
-
environmentId,
|
|
8239
|
-
destroyed: false,
|
|
8240
|
-
detail: stopped,
|
|
8241
|
-
permanent: true
|
|
8242
|
-
}];
|
|
8243
|
-
}
|
|
8244
|
-
return (await release(signal)).map((receipt) => receipt.destroyed ? receipt : {
|
|
8245
|
-
...receipt,
|
|
8246
|
-
detail: receipt.detail ? `${receipt.detail}; ${stopped}` : stopped
|
|
8247
|
-
});
|
|
8248
|
-
};
|
|
8249
|
-
return {
|
|
8250
|
-
cancelRetainedOnManagerStop,
|
|
8251
|
-
stopNativeExecution,
|
|
8252
|
-
stopEndedHarness,
|
|
8253
|
-
withoutRunningHarness
|
|
8254
|
-
};
|
|
8255
|
-
}
|
|
8256
|
-
/** The exact run the latest durable dispatch names, when dispatch got that far. */
|
|
8257
|
-
function admittedControlRef(retention) {
|
|
8258
|
-
for (const admission of [...retention?.admissions ?? []].reverse()) if (admission.phase === "dispatched") return admission.controlRef;
|
|
8259
|
-
}
|
|
8260
|
-
/** Bounds one provider stop: a reconnect, the exact cancellation and its status read. */
|
|
8261
|
-
const NATIVE_STOP_TIMEOUT_MS = 3e4;
|
|
8262
|
-
function providerWorkspaceCaptureReceipt(args, environment, snapshot, fallbackSessionId) {
|
|
8263
|
-
const coverage = args.workspaceCoverage();
|
|
8264
|
-
const controlRef = args.workspaceControlRef();
|
|
8265
|
-
return workspaceCaptureReceipt({
|
|
8266
|
-
executionId: args.executionId,
|
|
8267
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
8268
|
-
...args.node === void 0 ? {} : { node: args.node },
|
|
8269
|
-
environment,
|
|
8270
|
-
profile: args.profile,
|
|
8271
|
-
providerSessionId: controlRef?.sessionId ?? fallbackSessionId
|
|
8272
|
-
}, {
|
|
8273
|
-
snapshot,
|
|
8274
|
-
provenance: args.workspaceProvenance() ?? {
|
|
8275
|
-
status: "unavailable",
|
|
8276
|
-
missing: ["Capture coverage metadata was not retained"]
|
|
8277
|
-
},
|
|
8278
|
-
coverageComplete: coverage.complete,
|
|
8279
|
-
...coverage.incompleteReason === void 0 ? {} : { incompleteReason: coverage.incompleteReason }
|
|
8280
|
-
});
|
|
8281
|
-
}
|
|
8282
|
-
// src/runtime/environment-provider/provider-workspace-capture.ts
|
|
8283
|
-
/** Capture the environment's workspace once per generation; later callers share that capture. */
|
|
8284
|
-
async function captureExecutorWorkspace(scope, next, outcome) {
|
|
8285
|
-
const { state } = scope;
|
|
8286
|
-
const workspaceRetention = scope.options.workspaceRetention;
|
|
8287
|
-
if (workspaceRetention === void 0) return void 0;
|
|
8288
|
-
state.resetWorkspace(next);
|
|
8289
|
-
if (state.workspaceSnapshot !== void 0) return state.workspaceSnapshot;
|
|
8290
|
-
if (state.workspaceCapturePromise === void 0) state.workspaceCapturePromise = startWorkspaceCapture(scope, workspaceRetention, next, outcome);
|
|
8291
|
-
return await state.workspaceCapturePromise;
|
|
8292
|
-
}
|
|
8293
|
-
function startWorkspaceCapture(scope, workspaceRetention, next, outcome) {
|
|
8294
|
-
const { state, mirrors, retention, node, createProfile } = scope;
|
|
8295
|
-
state.workspaceOutcome = outcome;
|
|
8296
|
-
mirrors.stopLiveMirror();
|
|
8297
|
-
mirrors.stopScheduledNativeCapture();
|
|
8298
|
-
const captureContext = {
|
|
8299
|
-
environment: next,
|
|
8300
|
-
executionId: state.workspaceExecutionId,
|
|
8301
|
-
...state.workspaceControlRef === void 0 ? {} : { controlRef: state.workspaceControlRef },
|
|
8302
|
-
...node === void 0 ? {} : { node },
|
|
8303
|
-
providerSessionId: state.providerSessionId,
|
|
8304
|
-
nativeSessionId: null,
|
|
8305
|
-
profile: createProfile,
|
|
8306
|
-
...outcome === void 0 ? {} : { outcome }
|
|
8307
|
-
};
|
|
8308
|
-
const reportTiming = retention?.onWorkspaceCapture;
|
|
8309
|
-
let timing;
|
|
8310
|
-
const capturedExecutionId = state.workspaceExecutionId;
|
|
8311
|
-
const started = retention?.onWorkspaceCaptureStarted?.({
|
|
8312
|
-
executionId: capturedExecutionId,
|
|
8313
|
-
environmentId: next.id
|
|
8314
|
-
}).catch(() => void 0) ?? Promise.resolve();
|
|
8315
|
-
return Promise.all([mirrors.nativeRunningInFlight, mirrors.liveInFlight]).then(() => captureProviderWorkspaceSnapshot(workspaceRetention, captureContext, "environment", reportTiming === void 0 ? void 0 : (measured) => {
|
|
8316
|
-
timing = measured;
|
|
8317
|
-
})).finally(async () => {
|
|
8318
|
-
await started;
|
|
8319
|
-
if (timing === void 0 || reportTiming === void 0) return;
|
|
8320
|
-
await reportTiming({
|
|
8321
|
-
executionId: capturedExecutionId,
|
|
8322
|
-
environmentId: next.id,
|
|
8323
|
-
...timing
|
|
8324
|
-
}).catch(() => void 0);
|
|
8325
|
-
}).then((captured) => {
|
|
8326
|
-
recordCapturedWorkspace(scope, workspaceRetention, next, captured);
|
|
8327
|
-
return captured.snapshot;
|
|
8328
|
-
}).catch((error) => {
|
|
8329
|
-
state.workspaceCaptureFailure = error;
|
|
8330
|
-
mirrors.noteCaptureFailure(error);
|
|
8331
|
-
throw error;
|
|
8332
|
-
});
|
|
8333
|
-
}
|
|
8334
|
-
/** Keep the capture's snapshot and provenance, and project its transcript for the executor. */
|
|
8335
|
-
function recordCapturedWorkspace(scope, workspaceRetention, next, { snapshot, provenance, coverageComplete, incompleteReason }) {
|
|
8336
|
-
const { state, mirrors, node, createProfile } = scope;
|
|
8337
|
-
state.workspaceSnapshot = snapshot;
|
|
8338
|
-
state.workspaceProvenance = provenance;
|
|
8339
|
-
state.workspaceCoverageComplete = coverageComplete ?? false;
|
|
8340
|
-
state.workspaceIncompleteReason = incompleteReason;
|
|
8341
|
-
try {
|
|
8342
|
-
state.harnessTranscript = createProfile.harness === void 0 ? harnessTranscriptUnavailable("unknown-harness") : retainHarnessTranscript(providerWorkspaceCaptureReceipt({
|
|
8343
|
-
executionId: state.workspaceExecutionId,
|
|
8344
|
-
profile: createProfile,
|
|
8345
|
-
...node === void 0 ? {} : { node },
|
|
8346
|
-
workspaceControlRef: () => state.workspaceControlRef,
|
|
8347
|
-
workspaceProvenance: () => provenance,
|
|
8348
|
-
workspaceCoverage: () => ({
|
|
8349
|
-
complete: coverageComplete ?? false,
|
|
8350
|
-
incompleteReason
|
|
8351
|
-
})
|
|
8352
|
-
}, next, snapshot, state.providerSessionId), createProfile.harness);
|
|
8353
|
-
mirrors.holdsTranscript = false;
|
|
8354
|
-
} catch (error) {
|
|
8355
|
-
if (!mirrors.holdsTranscript) state.harnessTranscript = {
|
|
8356
|
-
status: "unavailable",
|
|
8357
|
-
reason: "retained-projection-failed",
|
|
8358
|
-
skipped: [{
|
|
8359
|
-
path: state.workspaceExecutionId,
|
|
8360
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
8361
|
-
}]
|
|
8362
|
-
};
|
|
8363
|
-
}
|
|
8364
|
-
if (workspaceRetention.requireCompleteProvenance && !coverageComplete) state.workspacePreservationRequired = true;
|
|
8365
|
-
}
|
|
8366
7969
|
// src/runtime/environment-provider/provider-environment-teardown.ts
|
|
8367
7970
|
/** The environment id the latest durable admission names, when creation got that far. */
|
|
8368
7971
|
function admittedEnvironmentId(retention) {
|
|
@@ -8372,56 +7975,28 @@ function admittedEnvironmentId(retention) {
|
|
|
8372
7975
|
}
|
|
8373
7976
|
}
|
|
8374
7977
|
const destroyFailed = (scope, error) => `providerAsExecutor(${scope.provider.name}): environment.destroy() failed — ${error instanceof Error ? error.message : String(error)}`;
|
|
8375
|
-
function workspaceFailureDetail(scope) {
|
|
8376
|
-
const { workspaceCaptureFailure } = scope.state;
|
|
8377
|
-
const reason = workspaceCaptureFailure instanceof Error ? workspaceCaptureFailure.message : String(workspaceCaptureFailure ?? "capture was not accepted");
|
|
8378
|
-
return `providerAsExecutor(${scope.provider.name}): workspace retention failed — ${reason}; source environment preserved`;
|
|
8379
|
-
}
|
|
8380
7978
|
/** Destroy the environment once, however many callers ask; a failed attempt may be retried. */
|
|
8381
7979
|
async function destroyExecutorEnvironment(scope, cleanupSignal) {
|
|
8382
|
-
const { state
|
|
7980
|
+
const { state } = scope;
|
|
8383
7981
|
if (state.workspaceCleanupPromise !== void 0) return await state.workspaceCleanupPromise;
|
|
8384
7982
|
const cleanupPromise = attemptDestroy(scope, cleanupSignal);
|
|
8385
7983
|
let cleanupReference;
|
|
8386
7984
|
cleanupReference = cleanupPromise.then((result) => {
|
|
8387
|
-
if (!result.destroyed && state.workspaceCleanupPromise === cleanupReference && !state.workspacePreservationRequired
|
|
8388
|
-
if (options.workspaceRetention !== void 0) {
|
|
8389
|
-
state.workspaceSnapshot = void 0;
|
|
8390
|
-
state.workspaceCapturePromise = void 0;
|
|
8391
|
-
}
|
|
8392
|
-
state.workspaceCleanupPromise = void 0;
|
|
8393
|
-
}
|
|
7985
|
+
if (!result.destroyed && state.workspaceCleanupPromise === cleanupReference && !state.workspacePreservationRequired) state.workspaceCleanupPromise = void 0;
|
|
8394
7986
|
return result;
|
|
8395
7987
|
});
|
|
8396
7988
|
state.workspaceCleanupPromise = cleanupReference;
|
|
8397
7989
|
return await cleanupReference;
|
|
8398
7990
|
}
|
|
8399
7991
|
async function attemptDestroy(scope, cleanupSignal) {
|
|
8400
|
-
const { state,
|
|
7992
|
+
const { state, provider } = scope;
|
|
8401
7993
|
const target = state.environment;
|
|
8402
7994
|
if (target === void 0) return { destroyed: true };
|
|
8403
7995
|
if (state.workspacePreservationRequired) return {
|
|
8404
7996
|
destroyed: false,
|
|
8405
|
-
detail:
|
|
7997
|
+
detail: "provider native stop was not confirmed; source environment preserved",
|
|
8406
7998
|
permanent: true
|
|
8407
7999
|
};
|
|
8408
|
-
if (options.workspaceRetention !== void 0) try {
|
|
8409
|
-
const currentSnapshot = await captureExecutorWorkspace(scope, target, state.workspaceOutcome);
|
|
8410
|
-
if (state.workspacePublishedSnapshot !== void 0 && currentSnapshot !== void 0 && currentSnapshot.digest !== state.workspacePublishedSnapshot.digest) {
|
|
8411
|
-
state.workspacePreservationRequired = true;
|
|
8412
|
-
return {
|
|
8413
|
-
destroyed: false,
|
|
8414
|
-
detail: "provider workspace retention: live workspace changed after the published receipt; source preserved",
|
|
8415
|
-
permanent: true
|
|
8416
|
-
};
|
|
8417
|
-
}
|
|
8418
|
-
} catch {
|
|
8419
|
-
return {
|
|
8420
|
-
destroyed: false,
|
|
8421
|
-
detail: workspaceFailureDetail(scope),
|
|
8422
|
-
permanent: true
|
|
8423
|
-
};
|
|
8424
|
-
}
|
|
8425
8000
|
if (state.destroyed) return { destroyed: true };
|
|
8426
8001
|
try {
|
|
8427
8002
|
await awaitAbortable(Promise.resolve(target.destroy?.()), cleanupSignal);
|
|
@@ -8440,7 +8015,7 @@ async function attemptDestroy(scope, cleanupSignal) {
|
|
|
8440
8015
|
}
|
|
8441
8016
|
/** Release the environment of a retained execution once no process will reconcile it. */
|
|
8442
8017
|
async function releaseRetainedExecution(scope, signal) {
|
|
8443
|
-
const { state,
|
|
8018
|
+
const { state, provider, retention } = scope;
|
|
8444
8019
|
scope.controller.abort();
|
|
8445
8020
|
if (!state.pending) return [];
|
|
8446
8021
|
const environmentId = state.retained?.controlRef.environmentId ?? state.environment?.id ?? admittedEnvironmentId(retention);
|
|
@@ -8452,12 +8027,11 @@ async function releaseRetainedExecution(scope, signal) {
|
|
|
8452
8027
|
...detail === void 0 ? {} : { detail },
|
|
8453
8028
|
...permanent === true ? { permanent } : {}
|
|
8454
8029
|
});
|
|
8455
|
-
if (options.workspaceRetention !== void 0 && state.workspaceRunActive) return [receipt(false, "provider workspace retention: source preserved while execution is still active")];
|
|
8456
8030
|
if (state.retainedReleasePromise !== void 0) return await state.retainedReleasePromise;
|
|
8457
8031
|
const releasePromise = releaseReceipts(scope, environmentId, signal, receipt);
|
|
8458
8032
|
let releaseReference;
|
|
8459
8033
|
releaseReference = releasePromise.then((receipts) => {
|
|
8460
|
-
if (state.retainedReleasePromise === releaseReference && !receipts.every((entry) => entry.destroyed) && !state.workspacePreservationRequired
|
|
8034
|
+
if (state.retainedReleasePromise === releaseReference && !receipts.every((entry) => entry.destroyed) && !state.workspacePreservationRequired) state.retainedReleasePromise = void 0;
|
|
8461
8035
|
return receipts;
|
|
8462
8036
|
});
|
|
8463
8037
|
state.retainedReleasePromise = releaseReference;
|
|
@@ -8478,7 +8052,7 @@ async function releaseReceipts(scope, environmentId, signal, receipt) {
|
|
|
8478
8052
|
state.environment = target;
|
|
8479
8053
|
state.resetWorkspace(target);
|
|
8480
8054
|
}
|
|
8481
|
-
await captureBeforeDestroy
|
|
8055
|
+
await captureBeforeDestroy(scope, target, signal);
|
|
8482
8056
|
const result = await destroyExecutorEnvironment(scope, signal);
|
|
8483
8057
|
if (!result.destroyed) return [receipt(false, result.detail, result.permanent)];
|
|
8484
8058
|
state.pending = false;
|
|
@@ -8493,18 +8067,13 @@ async function releaseReceipts(scope, environmentId, signal, receipt) {
|
|
|
8493
8067
|
* Discovery fleet of 2026-09-23/24, 105 carry `enumeration-failed`. A box the release can reach
|
|
8494
8068
|
* is read once more before it is destroyed.
|
|
8495
8069
|
*/
|
|
8496
|
-
async function captureBeforeDestroy
|
|
8497
|
-
const { state
|
|
8498
|
-
if (
|
|
8070
|
+
async function captureBeforeDestroy(scope, target, signal) {
|
|
8071
|
+
const { state } = scope;
|
|
8072
|
+
if (state.harnessTranscript.status !== "captured" && !state.releaseReadTried) {
|
|
8499
8073
|
state.releaseReadTried = true;
|
|
8500
8074
|
const capture = await captureHarnessTranscript(target, scope.profile.harness, signal);
|
|
8501
8075
|
if (capture.status === "captured") state.harnessTranscript = capture;
|
|
8502
8076
|
}
|
|
8503
|
-
if (mirrors.nativePort !== void 0 && state.harnessTranscript.status !== "retained" && !state.releaseNativeTried) {
|
|
8504
|
-
state.releaseNativeTried = true;
|
|
8505
|
-
const admitted = state.retained?.controlRef ?? admittedControlRef(retention);
|
|
8506
|
-
await awaitAbortable(mirrors.captureNative(target, "interrupted", admitted === void 0 ? void 0 : freezeControlRef(admitted)), signal).catch(() => void 0);
|
|
8507
|
-
}
|
|
8508
8077
|
}
|
|
8509
8078
|
// src/runtime/environment-provider/provider-validation-error.ts
|
|
8510
8079
|
var ValidationError = class extends Error {
|
|
@@ -8576,13 +8145,15 @@ function providerFailureEvent(event, sandboxEvent) {
|
|
|
8576
8145
|
const detail = failureDetail(sandboxEvent.data) ?? failureDetail(outcome) ?? failureDetail(result) ?? (normalized?.type === "status" ? normalized.detail : void 0);
|
|
8577
8146
|
const errorCode = failureCode(sandboxEvent.data) ?? failureCode(outcome) ?? failureCode(result);
|
|
8578
8147
|
const statusCode = failureStatusCode(sandboxEvent.data) ?? failureStatusCode(outcome) ?? failureStatusCode(result);
|
|
8148
|
+
const failure = turnFailureOf(sandboxEvent.data) ?? turnFailureOf(outcome) ?? turnFailureOf(result);
|
|
8579
8149
|
return {
|
|
8580
8150
|
type: "result",
|
|
8581
8151
|
data: {
|
|
8582
8152
|
status: "failed",
|
|
8583
8153
|
...detail ? { error: detail } : {},
|
|
8584
8154
|
...errorCode ? { errorCode } : {},
|
|
8585
|
-
...statusCode === void 0 ? {} : { statusCode }
|
|
8155
|
+
...statusCode === void 0 ? {} : { statusCode },
|
|
8156
|
+
...failure === void 0 ? {} : { failure }
|
|
8586
8157
|
}
|
|
8587
8158
|
};
|
|
8588
8159
|
}
|
|
@@ -8617,26 +8188,7 @@ function providerTerminalSuccess(event, sandboxEvent) {
|
|
|
8617
8188
|
result?.status
|
|
8618
8189
|
].some((status) => typeof status === "string" && TERMINAL_SUCCESS_STATUSES.has(status));
|
|
8619
8190
|
}
|
|
8620
|
-
/**
|
|
8621
|
-
* Holds a stream's failure frames until it ends, so the terminal frame decides the outcome.
|
|
8622
|
-
*
|
|
8623
|
-
* The sandbox outcome tracker latches the first `error` frame as the run's error and settles
|
|
8624
|
-
* `failed` on it whatever the terminal frame says; and until this ledger existed the runtime
|
|
8625
|
-
* only ever showed the tracker its failure frames, so a terminal `success: true` was never in
|
|
8626
|
-
* evidence at all. A transport error that the harness recovered from — a stream break the
|
|
8627
|
-
* sidecar re-attached, a tool backend that failed once — therefore settled the whole child
|
|
8628
|
-
* `down` with the transient error as its reason, and the artifact the child had banked was
|
|
8629
|
-
* discarded. On the 2026-09-20 fleet corpus, 25 children that finished their work settled that
|
|
8630
|
-
* way.
|
|
8631
|
-
*
|
|
8632
|
-
* The rule: `error` frames are forgiven when the stream reports success and carries no verdict;
|
|
8633
|
-
* a failed status or a failed terminal frame is the provider's own verdict on the run, and once
|
|
8634
|
-
* one exists every failure frame is evidence again, in order, so the tracker names the first
|
|
8635
|
-
* `error` as it always did. The existing contracts hold unchanged: `status: failed` then
|
|
8636
|
-
* `done: {}` is failed, and the retained Claude tail `completed → failed → error → done` is
|
|
8637
|
-
* failed with the error frame's message. The forgiven frames stay in the event archive the trace
|
|
8638
|
-
* reads; only the outcome stops claiming them.
|
|
8639
|
-
*/
|
|
8191
|
+
/** Terminal success forgives recovered error frames; explicit failed verdicts retain their evidence. */
|
|
8640
8192
|
function createProviderFailureLedger() {
|
|
8641
8193
|
const failures = [];
|
|
8642
8194
|
let verdicts = 0;
|
|
@@ -8655,7 +8207,12 @@ function createProviderFailureLedger() {
|
|
|
8655
8207
|
if (failures.length === 0 || verdicts === 0 && succeeded) return void 0;
|
|
8656
8208
|
const tracker = createAgentRunOutcomeTracker();
|
|
8657
8209
|
for (const frame of failures) tracker.observe(frame);
|
|
8658
|
-
|
|
8210
|
+
const outcome = tracker.finish();
|
|
8211
|
+
const failure = turnFailureOf(outcome) ?? failures.slice().reverse().map((frame) => turnFailureOf(frame.data)).find((value) => value !== void 0);
|
|
8212
|
+
return outcome === void 0 ? void 0 : {
|
|
8213
|
+
...outcome,
|
|
8214
|
+
failure
|
|
8215
|
+
};
|
|
8659
8216
|
}
|
|
8660
8217
|
};
|
|
8661
8218
|
}
|
|
@@ -8838,12 +8395,8 @@ function stringValue(value) {
|
|
|
8838
8395
|
const RETAINED_AWAITING_RESULT_AFTER_MS = 48e4;
|
|
8839
8396
|
const RETAINED_STATUS_READ_MS = 6e4;
|
|
8840
8397
|
const RETAINED_OBSERVATION_BATCH_EVENTS = 1024;
|
|
8841
|
-
/** After its exact result, a stream owing its terminal frame reads on while each frame comes this
|
|
8842
|
-
* soon after the result or the last frame: a provider sends the two on separate connections. */
|
|
8843
8398
|
const RETAINED_TAIL_FLOW_MS = 100;
|
|
8844
|
-
/** The event stream stopped short: a transport fact the retry policy reads by this name. */
|
|
8845
8399
|
const streamFailure = (message) => Object.assign(new Error(message), { name: "RetainedStreamError" });
|
|
8846
|
-
/** Why the event stream stopped short, as bounded redacted text for the settlement reason. */
|
|
8847
8400
|
function observationFailureText({ error }) {
|
|
8848
8401
|
const text = error instanceof Error ? error.message : String(error);
|
|
8849
8402
|
return String(defaultRedactor(text)).slice(0, 2048);
|
|
@@ -8853,23 +8406,29 @@ function exactQuotaRefusal(error) {
|
|
|
8853
8406
|
try {
|
|
8854
8407
|
const refusal = causeChain(error).find((cause) => Reflect.get(cause, "name") === "TangleCredentialCapacityError" && Reflect.get(cause, "code") === "provider_quota_exhausted");
|
|
8855
8408
|
if (refusal === void 0) return void 0;
|
|
8409
|
+
const failure = turnFailureOf(refusal);
|
|
8856
8410
|
const resetAt = Reflect.get(refusal, "resetAt");
|
|
8857
8411
|
return {
|
|
8858
8412
|
text: "",
|
|
8859
8413
|
success: false,
|
|
8860
8414
|
error: `Subscription account capacity is unavailable${typeof resetAt === "string" ? ` until ${resetAt}` : ""}`,
|
|
8861
8415
|
errorCode: "provider_quota_exhausted",
|
|
8862
|
-
statusCode: 429
|
|
8416
|
+
statusCode: 429,
|
|
8417
|
+
failure: failure ?? {
|
|
8418
|
+
kind: "capacity",
|
|
8419
|
+
code: "provider_quota_exhausted",
|
|
8420
|
+
...typeof resetAt === "string" && Number.isFinite(Date.parse(resetAt)) ? { resetAt: new Date(resetAt).toISOString() } : {}
|
|
8421
|
+
}
|
|
8863
8422
|
};
|
|
8864
8423
|
} catch {
|
|
8865
8424
|
return;
|
|
8866
8425
|
}
|
|
8867
8426
|
}
|
|
8868
|
-
/** Everything one retained dispatch has observed of its event stream and exact result. */
|
|
8869
8427
|
var RetainedObservation = class {
|
|
8870
8428
|
handle;
|
|
8871
8429
|
signal;
|
|
8872
8430
|
position;
|
|
8431
|
+
quietMs;
|
|
8873
8432
|
failure;
|
|
8874
8433
|
lastReplayPosition;
|
|
8875
8434
|
resumedFrom;
|
|
@@ -8883,14 +8442,14 @@ var RetainedObservation = class {
|
|
|
8883
8442
|
exactWakers = /* @__PURE__ */ new Set();
|
|
8884
8443
|
seenEvents = /* @__PURE__ */ new Map();
|
|
8885
8444
|
pendingRead;
|
|
8886
|
-
constructor(handle, signal, position) {
|
|
8445
|
+
constructor(handle, signal, position, quietMs = RETAINED_AWAITING_RESULT_AFTER_MS) {
|
|
8887
8446
|
this.handle = handle;
|
|
8888
8447
|
this.signal = signal;
|
|
8889
8448
|
this.position = position;
|
|
8449
|
+
this.quietMs = quietMs;
|
|
8890
8450
|
const observed = position?.observed;
|
|
8891
8451
|
if (observed?.executionId === handle.controlRef.executionId) this.lastReplayPosition = this.resumedFrom = observed.replayPosition;
|
|
8892
8452
|
}
|
|
8893
|
-
/** Stream the provider's frames, resume once after a break, then yield the exact result. */
|
|
8894
8453
|
async *observe(session) {
|
|
8895
8454
|
this.lastObservedAt = Date.now();
|
|
8896
8455
|
if (!(yield* this.drain(session, this.resumedFrom)) && !this.sawTerminal && this.lastReplayPosition !== void 0) {
|
|
@@ -8901,11 +8460,13 @@ var RetainedObservation = class {
|
|
|
8901
8460
|
const resumed = this.resumedFrom && `retained provider stream resumed after ${this.resumedFrom}`;
|
|
8902
8461
|
if (resumed) this.failure ??= { error: streamFailure(resumed) };
|
|
8903
8462
|
if (!this.sawTerminal && this.failure === void 0) this.failure = { error: streamFailure("retained provider stream did not yield a terminal event") };
|
|
8904
|
-
if (!this.sawTerminal && !this.exactResultSettled && this.silenceHandledAt === void 0)
|
|
8905
|
-
|
|
8463
|
+
if (!this.sawTerminal && !this.exactResultSettled && this.silenceHandledAt === void 0) {
|
|
8464
|
+
yield this.awaitingResult(Date.now());
|
|
8465
|
+
this.lastObservedAt = Date.now();
|
|
8466
|
+
}
|
|
8467
|
+
while (!await this.exactOrQuiet()) await this.stopQuietObservation(session);
|
|
8906
8468
|
yield await this.resultFrame();
|
|
8907
8469
|
}
|
|
8908
|
-
/** True once the exact result settles, false once a quiet interval passes first. */
|
|
8909
8470
|
exactOrQuiet() {
|
|
8910
8471
|
let unwatch = [() => {}];
|
|
8911
8472
|
return new Promise((resolve) => {
|
|
@@ -8914,21 +8475,17 @@ var RetainedObservation = class {
|
|
|
8914
8475
|
}
|
|
8915
8476
|
armQuiet(onQuiet) {
|
|
8916
8477
|
const quietFrom = Math.max(this.lastObservedAt, this.silenceHandledAt ?? 0);
|
|
8917
|
-
const quietMs =
|
|
8478
|
+
const quietMs = this.quietMs - (Date.now() - quietFrom);
|
|
8918
8479
|
return armDeadlineTimer(Math.max(0, quietMs), onQuiet);
|
|
8919
8480
|
}
|
|
8920
|
-
/**
|
|
8921
|
-
async
|
|
8481
|
+
/** Status diagnoses the observation stop; it cannot substitute for a frame or exact result. */
|
|
8482
|
+
async stopQuietObservation(session) {
|
|
8922
8483
|
const deadline = new AbortController();
|
|
8923
8484
|
const clear = armDeadlineTimer(RETAINED_STATUS_READ_MS, () => deadline.abort(/* @__PURE__ */ new Error(`no status answer within ${RETAINED_STATUS_READ_MS} ms`)));
|
|
8924
8485
|
const signal = AbortSignal.any([this.signal, deadline.signal]);
|
|
8925
8486
|
let cause;
|
|
8926
8487
|
try {
|
|
8927
8488
|
const status = await awaitAbortable(Promise.resolve().then(() => session.status({ signal })), signal);
|
|
8928
|
-
if (status !== null && !isTerminalSessionStatus(status)) {
|
|
8929
|
-
this.silenceHandledAt = Date.now();
|
|
8930
|
-
return;
|
|
8931
|
-
}
|
|
8932
8489
|
cause = /* @__PURE__ */ new Error(`provider status reads ${status}`);
|
|
8933
8490
|
} catch (error) {
|
|
8934
8491
|
if (this.signal.aborted) throw error;
|
|
@@ -8936,7 +8493,8 @@ var RetainedObservation = class {
|
|
|
8936
8493
|
} finally {
|
|
8937
8494
|
clear();
|
|
8938
8495
|
}
|
|
8939
|
-
|
|
8496
|
+
if (this.exactResultSettled) return;
|
|
8497
|
+
throw Object.assign(streamFailure("retained provider observation exceeded its quiet interval; exact execution remains pending"), { cause });
|
|
8940
8498
|
}
|
|
8941
8499
|
async resultFrame() {
|
|
8942
8500
|
let result;
|
|
@@ -8955,6 +8513,7 @@ var RetainedObservation = class {
|
|
|
8955
8513
|
finalText: result.text,
|
|
8956
8514
|
success: result.success,
|
|
8957
8515
|
...result.error ? { error: result.error } : {},
|
|
8516
|
+
...result.failure === void 0 ? {} : { failure: result.failure },
|
|
8958
8517
|
...result.errorCode ? {
|
|
8959
8518
|
errorCode: result.errorCode,
|
|
8960
8519
|
statusCode: result.statusCode
|
|
@@ -8995,7 +8554,6 @@ var RetainedObservation = class {
|
|
|
8995
8554
|
this.silenceHandledAt = Date.now();
|
|
8996
8555
|
return { awaitingResultSince: new Date(since).toISOString() };
|
|
8997
8556
|
}
|
|
8998
|
-
/** Read the stream's next frame, or learn first that the wait should publish or the result won. */
|
|
8999
8557
|
async raceNextRead(iterator) {
|
|
9000
8558
|
let wake;
|
|
9001
8559
|
let grace;
|
|
@@ -9006,7 +8564,10 @@ var RetainedObservation = class {
|
|
|
9006
8564
|
wake = setImmediate(() => {
|
|
9007
8565
|
const close = () => {
|
|
9008
8566
|
const flowing = this.sawTerminal ? 0 : RETAINED_TAIL_FLOW_MS - (Date.now() - this.lastObservedAt);
|
|
9009
|
-
if (flowing <= 0)
|
|
8567
|
+
if (flowing <= 0) {
|
|
8568
|
+
wake = setImmediate(() => resolve({ kind: "exact-result" }));
|
|
8569
|
+
return;
|
|
8570
|
+
}
|
|
9010
8571
|
grace = setTimeout(() => {
|
|
9011
8572
|
wake = setImmediate(() => resolve({ kind: "exact-result" }));
|
|
9012
8573
|
}, flowing);
|
|
@@ -9034,7 +8595,6 @@ var RetainedObservation = class {
|
|
|
9034
8595
|
clearQuiet?.();
|
|
9035
8596
|
}
|
|
9036
8597
|
}
|
|
9037
|
-
/** Bind a frame to its run and drop an exact replay; false when it carries no new evidence. */
|
|
9038
8598
|
acceptFrame(event) {
|
|
9039
8599
|
this.observedFrames += 1;
|
|
9040
8600
|
if (this.exactResultSettled) this.framesAfterResult += 1;
|
|
@@ -9076,17 +8636,18 @@ var RetainedObservation = class {
|
|
|
9076
8636
|
this.readExactResult();
|
|
9077
8637
|
return true;
|
|
9078
8638
|
}
|
|
9079
|
-
/** Yield one subscription's new frames; false when the stream failed rather than ended. */
|
|
9080
8639
|
async *drain(session, since) {
|
|
8640
|
+
const subscription = linkAbort(this.signal);
|
|
9081
8641
|
let iterator;
|
|
9082
8642
|
let failed = false;
|
|
9083
8643
|
try {
|
|
9084
8644
|
iterator = session.events({
|
|
9085
8645
|
executionId: this.handle.controlRef.executionId,
|
|
9086
8646
|
...since === void 0 ? {} : { since },
|
|
9087
|
-
signal:
|
|
8647
|
+
signal: subscription.signal
|
|
9088
8648
|
})[Symbol.asyncIterator]();
|
|
9089
8649
|
} catch (error) {
|
|
8650
|
+
subscription.abort();
|
|
9090
8651
|
if (this.signal.aborted) throw error;
|
|
9091
8652
|
this.failure = { error };
|
|
9092
8653
|
return false;
|
|
@@ -9109,8 +8670,11 @@ var RetainedObservation = class {
|
|
|
9109
8670
|
break;
|
|
9110
8671
|
}
|
|
9111
8672
|
if (observed.kind === "quiet") {
|
|
9112
|
-
if (this.silenceHandledAt !== void 0) await this.
|
|
9113
|
-
else
|
|
8673
|
+
if (this.silenceHandledAt !== void 0) await this.stopQuietObservation(session);
|
|
8674
|
+
else {
|
|
8675
|
+
yield this.awaitingResult(this.lastObservedAt);
|
|
8676
|
+
this.lastObservedAt = Date.now();
|
|
8677
|
+
}
|
|
9114
8678
|
continue;
|
|
9115
8679
|
}
|
|
9116
8680
|
if (observed.kind === "exact-result") {
|
|
@@ -9119,9 +8683,14 @@ var RetainedObservation = class {
|
|
|
9119
8683
|
}
|
|
9120
8684
|
this.pendingRead = void 0;
|
|
9121
8685
|
if (observed.value.done) break;
|
|
9122
|
-
if (this.acceptFrame(observed.value.value))
|
|
8686
|
+
if (this.acceptFrame(observed.value.value)) {
|
|
8687
|
+
yield observed.value.value;
|
|
8688
|
+
this.lastObservedAt = Date.now();
|
|
8689
|
+
}
|
|
9123
8690
|
}
|
|
9124
8691
|
} finally {
|
|
8692
|
+
subscription.abort();
|
|
8693
|
+
this.pendingRead = void 0;
|
|
9125
8694
|
Promise.resolve().then(() => iterator?.return?.()).catch(() => void 0);
|
|
9126
8695
|
}
|
|
9127
8696
|
return !failed;
|
|
@@ -9411,7 +8980,6 @@ var ProviderTurnObserver = class {
|
|
|
9411
8980
|
};
|
|
9412
8981
|
continue;
|
|
9413
8982
|
}
|
|
9414
|
-
this.args.scope.mirrors.noteProviderEvent();
|
|
9415
8983
|
this.archive.append(event);
|
|
9416
8984
|
this.text += textFromEnvironmentEvent(event);
|
|
9417
8985
|
const sandboxEvent = sandboxEventFromEnvironmentEvent(event);
|
|
@@ -9441,10 +9009,6 @@ var ProviderTurnObserver = class {
|
|
|
9441
9009
|
// src/runtime/environment-provider/provider-sandbox-adapter.ts
|
|
9442
9010
|
/** Expose a neutral provider through the existing Sandbox client port. @experimental */
|
|
9443
9011
|
function providerAsSandboxClient(provider, options = {}) {
|
|
9444
|
-
if (options.workspaceRetention !== void 0) {
|
|
9445
|
-
assertProviderWorkspaceRetentionPort(options.workspaceRetention, `providerAsSandboxClient(${provider.name})`);
|
|
9446
|
-
if (options.retentionIdentity === void 0) throw new ValidationError("providerAsSandboxClient: retentionIdentity is required with workspaceRetention");
|
|
9447
|
-
}
|
|
9448
9012
|
return { async create(createOptions) {
|
|
9449
9013
|
const defaults = options.defaults ?? {};
|
|
9450
9014
|
const sandboxInput = createInputFromSandboxOptions(createOptions, options.mapCreateOptions !== void 0);
|
|
@@ -9488,15 +9052,12 @@ function providerAsSandboxClient(provider, options = {}) {
|
|
|
9488
9052
|
if (options.requireSession && (!capabilities?.streaming.live || !capabilities.sessions.continue)) throw new ValidationError(`providerAsSandboxClient(${provider.name}): live session continuation is required`);
|
|
9489
9053
|
const environment = await provider.create(mapped);
|
|
9490
9054
|
if (options.requireSession && !environment.session) {
|
|
9491
|
-
|
|
9055
|
+
await environment.destroy?.();
|
|
9492
9056
|
throw new ValidationError(`providerAsSandboxClient(${provider.name}): session() is required`);
|
|
9493
9057
|
}
|
|
9494
9058
|
return environmentAsSandboxInstance(environment, {
|
|
9495
9059
|
...typeof mapped.profile === "string" ? {} : { profile: mapped.profile },
|
|
9496
|
-
requireTerminalEvent: options.requireTerminalEvent ?? true
|
|
9497
|
-
workspaceRetention: options.workspaceRetention,
|
|
9498
|
-
retentionIdentity: options.retentionIdentity,
|
|
9499
|
-
onWorkspaceCaptured: options.onWorkspaceCaptured
|
|
9060
|
+
requireTerminalEvent: options.requireTerminalEvent ?? true
|
|
9500
9061
|
});
|
|
9501
9062
|
} };
|
|
9502
9063
|
}
|
|
@@ -9564,18 +9125,6 @@ function createInputFromSandboxOptions(options, customMapping) {
|
|
|
9564
9125
|
};
|
|
9565
9126
|
}
|
|
9566
9127
|
function environmentAsSandboxInstance(environment, options) {
|
|
9567
|
-
let providerSessionId = null;
|
|
9568
|
-
let controlRef;
|
|
9569
|
-
const noteControlRef = (candidate) => {
|
|
9570
|
-
if (options.workspaceRetention === void 0) return;
|
|
9571
|
-
const parsed = AgentExactRunControlRefSchema.safeParse(candidate);
|
|
9572
|
-
if (!parsed.success) return;
|
|
9573
|
-
if (parsed.data.environmentId !== environment.id || parsed.data.provider !== environment.provider) throw new ValidationError("providerAsSandboxClient: capture control reference names another environment");
|
|
9574
|
-
controlRef = freezeControlRef(parsed.data);
|
|
9575
|
-
providerSessionId = controlRef.sessionId;
|
|
9576
|
-
};
|
|
9577
|
-
let capture;
|
|
9578
|
-
let publication;
|
|
9579
9128
|
return {
|
|
9580
9129
|
id: environment.id,
|
|
9581
9130
|
name: environment.name,
|
|
@@ -9586,8 +9135,6 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9586
9135
|
async *streamPrompt(message, promptOptions) {
|
|
9587
9136
|
let terminal = false;
|
|
9588
9137
|
const input = turnInputFromPrompt(message, promptOptions, options.profile);
|
|
9589
|
-
providerSessionId = input.sessionId ?? null;
|
|
9590
|
-
noteControlRef(input.controlRef);
|
|
9591
9138
|
let cancellation;
|
|
9592
9139
|
let cancellationStarted = false;
|
|
9593
9140
|
let cancellationFailed = false;
|
|
@@ -9648,8 +9195,6 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9648
9195
|
let terminal = false;
|
|
9649
9196
|
const failures = createProviderFailureLedger();
|
|
9650
9197
|
const input = turnInputFromPrompt(message, promptOptions, options.profile);
|
|
9651
|
-
providerSessionId = input.sessionId ?? null;
|
|
9652
|
-
noteControlRef(input.controlRef);
|
|
9653
9198
|
for await (const event of environment.stream(input)) {
|
|
9654
9199
|
lastResultText = resultTextFromData(event.data) ?? lastResultText;
|
|
9655
9200
|
if (isTerminalEnvironmentEvent(event)) terminal = true;
|
|
@@ -9676,11 +9221,9 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9676
9221
|
...environment.dispatch && environment.session ? { async dispatchPrompt(message, promptOptions) {
|
|
9677
9222
|
const session = await environment.dispatch?.(turnInputFromPrompt(message, promptOptions, options.profile));
|
|
9678
9223
|
if (!session) throw new ValidationError("providerAsSandboxClient: dispatch returned no session");
|
|
9679
|
-
noteControlRef(session.controlRef);
|
|
9680
9224
|
return sandboxDispatchResultFromSessionRef(session);
|
|
9681
9225
|
} } : {},
|
|
9682
9226
|
...environment.session ? { session(id, sessionOptions) {
|
|
9683
|
-
noteControlRef(sessionOptions?.controlRef);
|
|
9684
9227
|
return sandboxSessionFromAgentSession(environment.session?.(id, sessionOptions), sessionOptions?.controlRef, options.profile);
|
|
9685
9228
|
} } : {},
|
|
9686
9229
|
...environment.read ? { read: environment.read.bind(environment) } : {},
|
|
@@ -9699,38 +9242,6 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9699
9242
|
return environmentAsSandboxInstance(forked, options);
|
|
9700
9243
|
} } : {},
|
|
9701
9244
|
async delete() {
|
|
9702
|
-
if (options.workspaceRetention !== void 0) {
|
|
9703
|
-
const identity = options.retentionIdentity;
|
|
9704
|
-
if (identity === void 0) throw new ValidationError("providerAsSandboxClient: retention identity missing before delete");
|
|
9705
|
-
capture ??= captureProviderWorkspaceSnapshot(options.workspaceRetention, {
|
|
9706
|
-
environment,
|
|
9707
|
-
executionId: identity.executionId,
|
|
9708
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
9709
|
-
...identity.node === void 0 ? {} : { node: identity.node },
|
|
9710
|
-
providerSessionId,
|
|
9711
|
-
nativeSessionId: null,
|
|
9712
|
-
profile: identity.profile
|
|
9713
|
-
}).then((captured) => workspaceCaptureReceipt({
|
|
9714
|
-
environment,
|
|
9715
|
-
executionId: identity.executionId,
|
|
9716
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
9717
|
-
...identity.node === void 0 ? {} : { node: identity.node },
|
|
9718
|
-
profile: identity.profile,
|
|
9719
|
-
providerSessionId
|
|
9720
|
-
}, captured));
|
|
9721
|
-
const receipt = await capture;
|
|
9722
|
-
publication ??= Promise.resolve().then(async () => {
|
|
9723
|
-
await options.onWorkspaceCaptured?.(receipt);
|
|
9724
|
-
});
|
|
9725
|
-
const publishing = publication;
|
|
9726
|
-
try {
|
|
9727
|
-
await publishing;
|
|
9728
|
-
} catch (error) {
|
|
9729
|
-
if (publication === publishing) publication = void 0;
|
|
9730
|
-
throw error;
|
|
9731
|
-
}
|
|
9732
|
-
if (options.workspaceRetention.requireCompleteProvenance && !receipt.coverageComplete) throw new Error(receipt.incompleteReason ?? "provider workspace retention coverage incomplete");
|
|
9733
|
-
}
|
|
9734
9245
|
await environment.destroy?.();
|
|
9735
9246
|
}
|
|
9736
9247
|
};
|
|
@@ -9884,7 +9395,6 @@ var ProviderTurnSettlement = class {
|
|
|
9884
9395
|
args;
|
|
9885
9396
|
environment;
|
|
9886
9397
|
retained;
|
|
9887
|
-
sessionId;
|
|
9888
9398
|
observer;
|
|
9889
9399
|
usage;
|
|
9890
9400
|
started;
|
|
@@ -9896,14 +9406,11 @@ var ProviderTurnSettlement = class {
|
|
|
9896
9406
|
failed = false;
|
|
9897
9407
|
/** Set when the turn was refused for capacity and the caller will continue in this environment. */
|
|
9898
9408
|
unavailable;
|
|
9899
|
-
/** Whether the final session copy was taken before the workspace capture was handed to the owner. */
|
|
9900
|
-
finalCopyTaken = false;
|
|
9901
9409
|
harnessStop;
|
|
9902
|
-
constructor(args, environment, retained,
|
|
9410
|
+
constructor(args, environment, retained, observer, usage, started) {
|
|
9903
9411
|
this.args = args;
|
|
9904
9412
|
this.environment = environment;
|
|
9905
9413
|
this.retained = retained;
|
|
9906
|
-
this.sessionId = sessionId;
|
|
9907
9414
|
this.observer = observer;
|
|
9908
9415
|
this.usage = usage;
|
|
9909
9416
|
this.started = started;
|
|
@@ -9918,54 +9425,18 @@ var ProviderTurnSettlement = class {
|
|
|
9918
9425
|
durationMs: Date.now() - this.started
|
|
9919
9426
|
};
|
|
9920
9427
|
}
|
|
9921
|
-
/**
|
|
9922
|
-
* Whether this turn's owner takes its workspace capture over, so the turn ends without waiting
|
|
9923
|
-
* for it: the owner awaits it before the environment's next turn and before destroying the
|
|
9924
|
-
* environment, and journals its receipt. Only a port that copies the session on its own queue
|
|
9925
|
-
* hands it over; without one the capture is the only record of the session.
|
|
9926
|
-
*/
|
|
9927
|
-
ownerTakesCapture() {
|
|
9928
|
-
const { args } = this;
|
|
9929
|
-
return args.options.workspaceRetention?.captureNative !== void 0 && args.createProfile.harness !== void 0 && this.retained && args.retention?.preserveEnvironment === true && args.retention.onEndOfTurnWork !== void 0;
|
|
9930
|
-
}
|
|
9931
|
-
captureReceipt(snapshot) {
|
|
9932
|
-
return providerWorkspaceCaptureReceipt(this.args, this.environment, snapshot, this.sessionId);
|
|
9933
|
-
}
|
|
9934
|
-
/** Hand the workspace capture to the owner. Its receipt reaches the journal as evidence of this
|
|
9935
|
-
* invocation; a capture that fails leaves none, and the owner's release then keeps the source. */
|
|
9936
|
-
handCaptureToOwner(reported, captureOutcome, settled) {
|
|
9937
|
-
const { args, environment } = this;
|
|
9938
|
-
this.finalCopyTaken = true;
|
|
9939
|
-
args.retention?.onEndOfTurnWork?.((async () => {
|
|
9940
|
-
const copy = settled ? args.scope.mirrors.finishNativeMirror(environment, "settled").catch(() => void 0) : Promise.resolve();
|
|
9941
|
-
let snapshot;
|
|
9942
|
-
try {
|
|
9943
|
-
snapshot = await args.captureWorkspace(environment, captureOutcome);
|
|
9944
|
-
} finally {
|
|
9945
|
-
await copy;
|
|
9946
|
-
}
|
|
9947
|
-
if (settled) args.onPublishedSnapshot(snapshot);
|
|
9948
|
-
if (snapshot === void 0) return;
|
|
9949
|
-
await args.retention?.onEvidence?.({
|
|
9950
|
-
...reported,
|
|
9951
|
-
workspaceSnapshot: snapshot,
|
|
9952
|
-
workspaceCapture: this.captureReceipt(snapshot)
|
|
9953
|
-
});
|
|
9954
|
-
})().catch(() => void 0));
|
|
9955
|
-
}
|
|
9956
9428
|
stopEndedHarness() {
|
|
9957
9429
|
const { signal } = this.args;
|
|
9958
9430
|
if (this.settled !== void 0 || !signal.aborted) return Promise.resolve();
|
|
9959
9431
|
this.harnessStop ??= this.args.scope.nativeControl.stopEndedHarness(signal);
|
|
9960
9432
|
return this.harnessStop;
|
|
9961
9433
|
}
|
|
9962
|
-
/**
|
|
9434
|
+
/** Read the provider transcript while its environment is still available. */
|
|
9963
9435
|
async readLiveTranscript() {
|
|
9964
9436
|
const { args } = this;
|
|
9965
|
-
if (args.options.workspaceRetention !== void 0) return;
|
|
9966
9437
|
args.scope.state.harnessTranscript = await captureHarnessTranscript(this.environment, args.profile.harness, args.signal);
|
|
9967
9438
|
}
|
|
9968
|
-
/**
|
|
9439
|
+
/** Commit the consumed turn, validator verdict and measured spend. */
|
|
9969
9440
|
async *settle() {
|
|
9970
9441
|
const { args, usage } = this;
|
|
9971
9442
|
yield* usage.settleTurn();
|
|
@@ -9989,38 +9460,14 @@ var ProviderTurnSettlement = class {
|
|
|
9989
9460
|
}),
|
|
9990
9461
|
signal: args.signal
|
|
9991
9462
|
});
|
|
9992
|
-
const
|
|
9993
|
-
/**
|
|
9994
|
-
* A capture that fails or exceeds its deadline after settlement is a fact about the evidence,
|
|
9995
|
-
* never the turn's outcome. On Runtime 0.295.4 a capture past its 1,200,000 ms
|
|
9996
|
-
* deadline behind a two-slot queue shared by 34 workers threw an AbortError, the driver
|
|
9997
|
-
* classified it terminal, and two research roots ended with 13 and 0 children settled. With no
|
|
9998
|
-
* receipt the source stays preserved and the owner reads a retention failure; the turn is not re-run.
|
|
9999
|
-
*/
|
|
10000
|
-
let retainedWorkspace;
|
|
10001
|
-
let workspaceCaptureFailure;
|
|
10002
|
-
if (!deferCapture) {
|
|
10003
|
-
try {
|
|
10004
|
-
retainedWorkspace = await args.captureWorkspace(this.environment, outcome);
|
|
10005
|
-
} catch (error) {
|
|
10006
|
-
workspaceCaptureFailure = `${errorText(error instanceof Error ? error.message : error)}; source environment preserved`;
|
|
10007
|
-
}
|
|
10008
|
-
args.onPublishedSnapshot(retainedWorkspace);
|
|
10009
|
-
}
|
|
10010
|
-
const settledResult = {
|
|
10011
|
-
...result,
|
|
10012
|
-
...workspaceCaptureFailure === void 0 ? {} : { workspaceCaptureFailure },
|
|
10013
|
-
...retainedWorkspace === void 0 ? {} : {
|
|
10014
|
-
workspaceSnapshot: retainedWorkspace,
|
|
10015
|
-
workspaceCapture: this.captureReceipt(retainedWorkspace)
|
|
10016
|
-
}
|
|
10017
|
-
};
|
|
9463
|
+
const settledResult = result;
|
|
10018
9464
|
const jsonOutput = args.options.outputFormat === "json";
|
|
10019
9465
|
if (jsonOutput) await args.retention?.onEvidence?.(settledResult);
|
|
10020
9466
|
const output = jsonOutput && outcome?.status !== "failed" ? jsonResultFromEvents(result.events) : { out: settledResult };
|
|
10021
9467
|
const statusCode = failureStatusCode(outcome);
|
|
10022
9468
|
const nativeFailure = outcome?.status === "failed" ? {
|
|
10023
9469
|
success: false,
|
|
9470
|
+
...outcome.failure === void 0 ? {} : { failure: outcome.failure },
|
|
10024
9471
|
...outcome.error ? { error: outcome.error } : {},
|
|
10025
9472
|
...outcome.errorCode ? { errorCode: outcome.errorCode } : {},
|
|
10026
9473
|
...statusCode === void 0 ? {} : { statusCode }
|
|
@@ -10041,57 +9488,28 @@ var ProviderTurnSettlement = class {
|
|
|
10041
9488
|
});
|
|
10042
9489
|
if (signal !== void 0) this.unavailable = {
|
|
10043
9490
|
signal,
|
|
10044
|
-
cause: errorText(nativeFailure.error ?? "")
|
|
9491
|
+
cause: errorText(nativeFailure.error ?? ""),
|
|
9492
|
+
...nativeFailure.failure ? { failure: nativeFailure.failure } : {}
|
|
10045
9493
|
};
|
|
10046
9494
|
}
|
|
10047
9495
|
if (this.retained) await args.retention?.onResult(settled);
|
|
10048
|
-
else if (retainedWorkspace !== void 0 && !jsonOutput) await args.retention?.onEvidence?.(settledResult);
|
|
10049
9496
|
args.scope.state.pending = false;
|
|
10050
9497
|
args.scope.state.artifact = settled;
|
|
10051
|
-
if (deferCapture) this.handCaptureToOwner(settledResult, outcome, true);
|
|
10052
9498
|
}
|
|
10053
9499
|
/** Record the turn's failure, then capture what evidence its environment still holds. */
|
|
10054
9500
|
async *fail(error) {
|
|
10055
|
-
const { args
|
|
9501
|
+
const { args } = this;
|
|
10056
9502
|
yield* this.usage.settleTurn();
|
|
10057
9503
|
this.failure = this.retained ? new RetainedExecutionPendingError(error) : error;
|
|
10058
9504
|
this.failed = true;
|
|
10059
|
-
if (args.options.workspaceRetention !== void 0) args.scope.state.workspacePreservationRequired = true;
|
|
10060
|
-
const failureOutcome = this.observer.failures.finish() ?? {
|
|
10061
|
-
success: false,
|
|
10062
|
-
status: "failed",
|
|
10063
|
-
error: error instanceof Error ? error.message : String(error),
|
|
10064
|
-
...args.signal.aborted ? { errorCode: "cancelled" } : {}
|
|
10065
|
-
};
|
|
10066
9505
|
await this.stopEndedHarness();
|
|
10067
|
-
if (args.signal.aborted) await args.scope.mirrors.finishNativeMirror(environment, "failed");
|
|
10068
9506
|
args.scope.state.settleTranscript();
|
|
10069
|
-
if (this.ownerTakesCapture()) {
|
|
10070
|
-
if (!args.signal.aborted) await args.scope.mirrors.finishNativeMirror(environment, "failed");
|
|
10071
|
-
this.handCaptureToOwner({
|
|
10072
|
-
...resultFromEvents(this.observer.archive.events(), this.observer.text),
|
|
10073
|
-
outcome: failureOutcome
|
|
10074
|
-
}, failureOutcome, false);
|
|
10075
|
-
} else try {
|
|
10076
|
-
const retainedWorkspace = await args.captureWorkspace(this.environment, failureOutcome);
|
|
10077
|
-
if (retainedWorkspace !== void 0 && args.retention?.onEvidence !== void 0) await args.retention.onEvidence({
|
|
10078
|
-
...resultFromEvents(this.observer.archive.events(), this.observer.text),
|
|
10079
|
-
outcome: failureOutcome,
|
|
10080
|
-
workspaceSnapshot: retainedWorkspace,
|
|
10081
|
-
workspaceCapture: this.captureReceipt(retainedWorkspace)
|
|
10082
|
-
});
|
|
10083
|
-
} catch (captureError) {
|
|
10084
|
-
if (!(captureError instanceof Error) || captureError === error) this.failure = captureError;
|
|
10085
|
-
else if (captureError.cause === void 0) this.failure = Object.assign(captureError, { cause: this.failure });
|
|
10086
|
-
else this.failure = new AggregateError([captureError, this.failure], captureError.message, { cause: captureError });
|
|
10087
|
-
}
|
|
10088
9507
|
await this.readLiveTranscript();
|
|
10089
9508
|
}
|
|
10090
|
-
/**
|
|
9509
|
+
/** Stop the harness when required, then settle its environment's custody. */
|
|
10091
9510
|
async release() {
|
|
10092
9511
|
const { args } = this;
|
|
10093
9512
|
await this.stopEndedHarness();
|
|
10094
|
-
if (!this.finalCopyTaken) await args.scope.mirrors.finishNativeMirror(this.environment, this.failed ? "failed" : this.settled !== void 0 ? "settled" : "interrupted");
|
|
10095
9513
|
const held = this.retained && this.settled !== void 0 && !this.failed && this.unavailable === void 0 && args.retention?.preserveEnvironment !== true && args.retention?.holdOnSettle?.(this.settled.spent) === true;
|
|
10096
9514
|
if (held) args.scope.state.holdingForContinuation = true;
|
|
10097
9515
|
if ((!this.retained || this.settled !== void 0 && !this.failed) && !(this.retained && args.retention?.preserveEnvironment) && !(this.unavailable !== void 0 && !this.failed) && !held && (args.options.destroyOnSettle ?? true)) {
|
|
@@ -10301,10 +9719,9 @@ async function* streamProviderExecutor(args) {
|
|
|
10301
9719
|
const source = await providerExecutionSource(args, turn, args.signal);
|
|
10302
9720
|
const environment = source.environment;
|
|
10303
9721
|
args.onEnvironment(environment);
|
|
10304
|
-
args.scope.mirrors.startNativeMirror(environment);
|
|
10305
9722
|
const usage = new ProviderUsageAccount(args, turn.model);
|
|
10306
9723
|
const observer = new ProviderTurnObserver(args, usage, source.retained, turn.model);
|
|
10307
|
-
const settlement = new ProviderTurnSettlement(args, environment, source.retained,
|
|
9724
|
+
const settlement = new ProviderTurnSettlement(args, environment, source.retained, observer, usage, started);
|
|
10308
9725
|
try {
|
|
10309
9726
|
yield* observer.consume(source.events);
|
|
10310
9727
|
yield* settlement.settle();
|
|
@@ -10359,18 +9776,7 @@ function invocationArgs(scope, invocation, signal, carried, executionStartedAt,
|
|
|
10359
9776
|
if (!continued) return adoptEnvironment(scope, env);
|
|
10360
9777
|
if (env.id !== state.environment?.id) throw new ValidationError(`providerAsExecutor(${provider.name}): a continuation ran in environment ${env.id}, not ${state.environment?.id ?? "<none>"}`);
|
|
10361
9778
|
state.environment = env;
|
|
10362
|
-
}
|
|
10363
|
-
onPublishedSnapshot: (snapshot) => {
|
|
10364
|
-
state.workspacePublishedSnapshot = snapshot;
|
|
10365
|
-
if (continued && snapshot !== void 0 && (!options.workspaceRetention?.requireCompleteProvenance || state.workspaceCoverageComplete)) state.workspacePreservationRequired = false;
|
|
10366
|
-
},
|
|
10367
|
-
captureWorkspace: (next, outcome) => captureExecutorWorkspace(scope, next, outcome),
|
|
10368
|
-
workspaceControlRef: () => state.workspaceControlRef,
|
|
10369
|
-
workspaceProvenance: () => state.workspaceProvenance,
|
|
10370
|
-
workspaceCoverage: () => ({
|
|
10371
|
-
complete: state.workspaceCoverageComplete,
|
|
10372
|
-
incompleteReason: state.workspaceIncompleteReason
|
|
10373
|
-
})
|
|
9779
|
+
}
|
|
10374
9780
|
};
|
|
10375
9781
|
}
|
|
10376
9782
|
/**
|
|
@@ -10380,12 +9786,8 @@ function invocationArgs(scope, invocation, signal, carried, executionStartedAt,
|
|
|
10380
9786
|
* resolving its unreceipted source.
|
|
10381
9787
|
*/
|
|
10382
9788
|
function beginWorkspaceExecution(scope) {
|
|
10383
|
-
const { state,
|
|
9789
|
+
const { state, provider } = scope;
|
|
10384
9790
|
if (state.workspaceRunActive) throw new ValidationError(`providerAsExecutor(${provider.name}): executor is already running`);
|
|
10385
|
-
if (options.workspaceRetention !== void 0) {
|
|
10386
|
-
if (state.workspacePreservationRequired) throw new ValidationError(`providerAsExecutor(${provider.name}): a prior failed execution has no retrievable workspace receipt; source remains preserved and this executor cannot be reused`);
|
|
10387
|
-
if (state.environment !== void 0 && !state.destroyed) throw new ValidationError(`providerAsExecutor(${provider.name}): the prior workspace environment is still live; teardown must release it before this executor can be reused`);
|
|
10388
|
-
}
|
|
10389
9791
|
if (runtimeOwnedExecutorMaterialization(scope.executor()) !== void 0) throw new ValidationError(`providerAsExecutor(${provider.name}): this executor has already materialized; create a new executor for another run`);
|
|
10390
9792
|
if (state.environment !== void 0 && state.destroyed) {
|
|
10391
9793
|
state.environment = void 0;
|
|
@@ -10401,7 +9803,7 @@ function beginWorkspaceExecution(scope) {
|
|
|
10401
9803
|
* same environment after the upstream refused a turn for capacity.
|
|
10402
9804
|
*/
|
|
10403
9805
|
async function* runProviderExecution(scope, task, signal, recovering = false) {
|
|
10404
|
-
const { state,
|
|
9806
|
+
const { state, retention } = scope;
|
|
10405
9807
|
beginWorkspaceExecution(scope);
|
|
10406
9808
|
const linked = linkAbort(scope.ctx.signal, signal, scope.controller.signal);
|
|
10407
9809
|
state.runSignal = linked.signal;
|
|
@@ -10425,7 +9827,6 @@ async function* runProviderExecution(scope, task, signal, recovering = false) {
|
|
|
10425
9827
|
state.resetWorkspace(state.environment, invocation.executionId);
|
|
10426
9828
|
state.workspaceControlRef = void 0;
|
|
10427
9829
|
state.providerSessionId = null;
|
|
10428
|
-
state.workspacePreservationRequired = options.workspaceRetention !== void 0;
|
|
10429
9830
|
}
|
|
10430
9831
|
const ended = yield* streamProviderExecutor(invocationArgs(scope, invocation, linked.signal, carried, executionStartedAt, continued));
|
|
10431
9832
|
const next = await pauseForContinuation(scope, invocation, ended, attempt, refusalsInARow, linked.signal);
|
|
@@ -10445,9 +9846,11 @@ async function pauseForContinuation(scope, invocation, ended, attempt, refusalsB
|
|
|
10445
9846
|
const { state, options, provider } = scope;
|
|
10446
9847
|
const refusal = ended.unavailable;
|
|
10447
9848
|
const continueInvocation = invocation.retention?.continueInvocation;
|
|
10448
|
-
if (refusal === void 0 || continueInvocation === void 0 || state.workspacePreservationRequired
|
|
9849
|
+
if (refusal === void 0 || continueInvocation === void 0 || state.workspacePreservationRequired) return;
|
|
10449
9850
|
const refusalsInARow = ended.madeProgress ? 1 : refusalsBefore + 1;
|
|
10450
|
-
const
|
|
9851
|
+
const now = Date.now();
|
|
9852
|
+
const reset = unavailableResumeAt(reportedResetAt(refusal, now), now);
|
|
9853
|
+
const pauseMs = reset === void 0 ? unavailablePauseMs(refusalsInARow, options.unavailablePause || {}) : Math.max(1e3, reset - now);
|
|
10451
9854
|
await invocation.retention?.onPause?.({
|
|
10452
9855
|
attempt,
|
|
10453
9856
|
signal: refusal.signal,
|
|
@@ -10496,18 +9899,9 @@ var ProviderExecutorState = class {
|
|
|
10496
9899
|
* environment is released or handed to the successor node. */
|
|
10497
9900
|
holdingForContinuation = false;
|
|
10498
9901
|
workspaceEnvironmentId;
|
|
10499
|
-
workspaceSnapshot;
|
|
10500
|
-
workspaceProvenance;
|
|
10501
|
-
workspaceCoverageComplete = false;
|
|
10502
|
-
workspaceIncompleteReason;
|
|
10503
|
-
workspacePublishedSnapshot;
|
|
10504
|
-
workspaceCaptureFailure;
|
|
10505
|
-
workspaceCapturePromise;
|
|
10506
9902
|
workspaceCleanupPromise;
|
|
10507
9903
|
retainedReleasePromise;
|
|
10508
9904
|
releaseReadTried = false;
|
|
10509
|
-
releaseNativeTried = false;
|
|
10510
|
-
workspaceOutcome;
|
|
10511
9905
|
workspacePreservationRequired = false;
|
|
10512
9906
|
workspaceRunActive = false;
|
|
10513
9907
|
providerSessionId = null;
|
|
@@ -10529,16 +9923,8 @@ var ProviderExecutorState = class {
|
|
|
10529
9923
|
}
|
|
10530
9924
|
/** Forget the capture generation: the next one owns its own snapshot, receipts and verdicts. */
|
|
10531
9925
|
clearWorkspaceCapture() {
|
|
10532
|
-
this.workspaceSnapshot = void 0;
|
|
10533
|
-
this.workspaceProvenance = void 0;
|
|
10534
|
-
this.workspaceCoverageComplete = false;
|
|
10535
|
-
this.workspaceIncompleteReason = void 0;
|
|
10536
|
-
this.workspacePublishedSnapshot = void 0;
|
|
10537
|
-
this.workspaceCaptureFailure = void 0;
|
|
10538
|
-
this.workspaceCapturePromise = void 0;
|
|
10539
9926
|
this.workspaceCleanupPromise = void 0;
|
|
10540
9927
|
this.retainedReleasePromise = void 0;
|
|
10541
|
-
this.workspaceOutcome = void 0;
|
|
10542
9928
|
this.workspacePreservationRequired = false;
|
|
10543
9929
|
this.destroyed = false;
|
|
10544
9930
|
}
|
|
@@ -10600,9 +9986,87 @@ function providerMaterialization(provider, createProfile, node, executionId, ret
|
|
|
10600
9986
|
}
|
|
10601
9987
|
};
|
|
10602
9988
|
}
|
|
9989
|
+
// src/runtime/environment-provider/provider-retention-lifecycle.ts
|
|
9990
|
+
function createProviderNativeControl(provider, retention, managerStop, state) {
|
|
9991
|
+
let nativeStop;
|
|
9992
|
+
const cancelRetainedOnManagerStop = (handle) => {
|
|
9993
|
+
if (managerStop === void 0) return;
|
|
9994
|
+
const cancel = () => {
|
|
9995
|
+
if (state.retained !== handle || !state.workspaceRunActive) return;
|
|
9996
|
+
handle.cancel({
|
|
9997
|
+
operationId: `manager-stop:${randomUUID()}`,
|
|
9998
|
+
reason: String(managerStop.reason ?? "the manager stopped")
|
|
9999
|
+
}).catch(() => void 0);
|
|
10000
|
+
};
|
|
10001
|
+
const stop = () => managerStop.reason === "result-accepted" ? void armDeadlineTimer(ACCEPTED_RESULT_GRACE_MS, cancel) : cancel();
|
|
10002
|
+
if (managerStop.aborted) stop();
|
|
10003
|
+
else managerStop.addEventListener("abort", stop, { once: true });
|
|
10004
|
+
};
|
|
10005
|
+
/** Stop the native harness of this executor's retained execution, which local observation ending
|
|
10006
|
+
* never stops. Undefined when nothing was dispatched. */
|
|
10007
|
+
const stopNativeExecution = () => {
|
|
10008
|
+
if (nativeStop !== void 0) return nativeStop;
|
|
10009
|
+
const controlRef = state.retained?.controlRef ?? admittedControlRef(retention);
|
|
10010
|
+
if (controlRef === void 0) return Promise.resolve(void 0);
|
|
10011
|
+
const stopping = stopRetainedNativeExecution({
|
|
10012
|
+
provider,
|
|
10013
|
+
controlRef,
|
|
10014
|
+
...state.retained === void 0 ? {} : { handle: state.retained },
|
|
10015
|
+
signal: AbortSignal.timeout(NATIVE_STOP_TIMEOUT_MS)
|
|
10016
|
+
}).then((stop) => {
|
|
10017
|
+
if (stop.effect === "cancelled" || stop.effect === "not_live") {
|
|
10018
|
+
state.harnessStopped = true;
|
|
10019
|
+
state.workspacePreservationRequired = false;
|
|
10020
|
+
} else if (nativeStop === stopping) nativeStop = void 0;
|
|
10021
|
+
return stop;
|
|
10022
|
+
});
|
|
10023
|
+
nativeStop = stopping;
|
|
10024
|
+
return stopping;
|
|
10025
|
+
};
|
|
10026
|
+
/** Stop a retained harness when its turn's deadline or explicit cancellation ends it. */
|
|
10027
|
+
const stopEndedHarness = async (signal) => {
|
|
10028
|
+
if (!isDeadlineAbortReason(signal.reason) && !state.cancelledExplicitly()) return;
|
|
10029
|
+
await stopNativeExecution();
|
|
10030
|
+
};
|
|
10031
|
+
/**
|
|
10032
|
+
* A release that keeps an environment keeps its files, never its running harness. The root has
|
|
10033
|
+
* settled and no process will reconcile this execution, so its native process stops before the
|
|
10034
|
+
* release records what it kept.
|
|
10035
|
+
*/
|
|
10036
|
+
const withoutRunningHarness = (release) => async (signal) => {
|
|
10037
|
+
const stop = await awaitAbortable(stopNativeExecution(), signal).catch(() => void 0);
|
|
10038
|
+
const stopped = stop === void 0 ? "native stop unconfirmed: no exact dispatch or cleanup interrupted" : describeRetainedNativeStops([stop]);
|
|
10039
|
+
const environmentId = (state.retained?.controlRef ?? admittedControlRef(retention))?.environmentId ?? admittedEnvironmentId(retention);
|
|
10040
|
+
if (environmentId !== void 0 && !state.harnessStopped) {
|
|
10041
|
+
state.workspacePreservationRequired = true;
|
|
10042
|
+
return [{
|
|
10043
|
+
provider: provider.name,
|
|
10044
|
+
environmentId,
|
|
10045
|
+
destroyed: false,
|
|
10046
|
+
detail: stopped,
|
|
10047
|
+
permanent: true
|
|
10048
|
+
}];
|
|
10049
|
+
}
|
|
10050
|
+
return (await release(signal)).map((receipt) => receipt.destroyed ? receipt : {
|
|
10051
|
+
...receipt,
|
|
10052
|
+
detail: receipt.detail ? `${receipt.detail}; ${stopped}` : stopped
|
|
10053
|
+
});
|
|
10054
|
+
};
|
|
10055
|
+
return {
|
|
10056
|
+
cancelRetainedOnManagerStop,
|
|
10057
|
+
stopNativeExecution,
|
|
10058
|
+
stopEndedHarness,
|
|
10059
|
+
withoutRunningHarness
|
|
10060
|
+
};
|
|
10061
|
+
}
|
|
10062
|
+
/** The exact run the latest durable dispatch names, when dispatch got that far. */
|
|
10063
|
+
function admittedControlRef(retention) {
|
|
10064
|
+
for (const admission of [...retention?.admissions ?? []].reverse()) if (admission.phase === "dispatched") return admission.controlRef;
|
|
10065
|
+
}
|
|
10066
|
+
/** Bounds one provider stop: a reconnect, the exact cancellation and its status read. */
|
|
10067
|
+
const NATIVE_STOP_TIMEOUT_MS = 3e4;
|
|
10603
10068
|
// src/runtime/environment-provider/provider-executor-lifecycle.ts
|
|
10604
10069
|
function createProviderExecutor(provider, profile, ctx, options, placement) {
|
|
10605
|
-
if (options.workspaceRetention !== void 0) assertProviderWorkspaceRetentionPort(options.workspaceRetention, `providerAsExecutor(${provider.name})`);
|
|
10606
10070
|
const node = detachedSnapshot(ctx.node, "provider executor node");
|
|
10607
10071
|
const retention = retainedExecutorContext(ctx);
|
|
10608
10072
|
if (options.outputFormat !== void 0 && (options.outputFormat !== "json" || retention?.onEvidence === void 0 || options.requireTerminalEvent === false)) throw new ValidationError("providerAsExecutor: JSON output requires Runtime-owned durable evidence and a native terminal receipt");
|
|
@@ -10627,7 +10091,6 @@ function createProviderExecutor(provider, profile, ctx, options, placement) {
|
|
|
10627
10091
|
state,
|
|
10628
10092
|
controller: new AbortController(),
|
|
10629
10093
|
nativeControl: createProviderNativeControl(provider, retention, managerStop, state),
|
|
10630
|
-
mirrors: createProviderCaptureMirrors(options, createProfile, node, state),
|
|
10631
10094
|
trace: createPushTraceSource({ runId: executionId }),
|
|
10632
10095
|
materialization: providerMaterialization(provider, createProfile, node, executionId, retention, options, placement),
|
|
10633
10096
|
continuationTask: LEAF_CONTINUATION_TASK,
|
|
@@ -10683,17 +10146,13 @@ async function cancelExecution(scope, request) {
|
|
|
10683
10146
|
};
|
|
10684
10147
|
}
|
|
10685
10148
|
async function teardownExecution(scope) {
|
|
10686
|
-
const { state
|
|
10149
|
+
const { state } = scope;
|
|
10687
10150
|
scope.controller.abort();
|
|
10688
10151
|
if (state.holdingForContinuation) return {
|
|
10689
10152
|
destroyed: false,
|
|
10690
10153
|
detail: "environment held for a keyed continuation after a budget stop"
|
|
10691
10154
|
};
|
|
10692
10155
|
if (state.pending && state.cancelledExplicitly()) scope.nativeControl.stopNativeExecution();
|
|
10693
|
-
if (options.workspaceRetention !== void 0 && state.workspaceRunActive) return {
|
|
10694
|
-
destroyed: false,
|
|
10695
|
-
detail: state.harnessStopped ? "provider workspace retention: source preserved while the stopped execution writes its failure capture" : "provider workspace retention: source preserved while the execution is still active"
|
|
10696
|
-
};
|
|
10697
10156
|
if (state.pending) return {
|
|
10698
10157
|
destroyed: false,
|
|
10699
10158
|
detail: "retained execution requires reconciliation",
|
|
@@ -10706,7 +10165,7 @@ function heldEnvironments(scope) {
|
|
|
10706
10165
|
if (state.destroyed) return [];
|
|
10707
10166
|
const environmentId = state.environment?.id ?? state.retained?.controlRef.environmentId ?? admittedEnvironmentId(scope.retention);
|
|
10708
10167
|
if (environmentId === void 0) return [];
|
|
10709
|
-
const preserved = state.workspacePreservationRequired
|
|
10168
|
+
const preserved = state.workspacePreservationRequired;
|
|
10710
10169
|
return [{
|
|
10711
10170
|
provider: scope.provider.name,
|
|
10712
10171
|
environmentId,
|
|
@@ -12121,7 +11580,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
12121
11580
|
const started = Date.now();
|
|
12122
11581
|
const linked = linkAbort(signal, controller.signal).signal;
|
|
12123
11582
|
recordRuntimeOwnedProviderAttemptStart(executor);
|
|
12124
|
-
const r = await runRouterTransport("routerInlineExecutor", () => seam.tools ? (profileExecution.stream === true ? streamRouterChatWithTools : routerChatWithTools)(routerTransportConfig(seam, model, profileExecution.retry), messages, seam.tools, {
|
|
11583
|
+
const r = await observeModelRequest(executorObservation(ctx), model, () => runRouterTransport("routerInlineExecutor", () => seam.tools ? (profileExecution.stream === true ? streamRouterChatWithTools : routerChatWithTools)(routerTransportConfig(seam, model, profileExecution.retry), messages, seam.tools, {
|
|
12125
11584
|
...profileExecution.temperature !== void 0 ? { temperature: profileExecution.temperature } : {},
|
|
12126
11585
|
...linked ? { signal: linked } : {},
|
|
12127
11586
|
...profileExecution.toolChoice ? { toolChoice: profileExecution.toolChoice } : {},
|
|
@@ -12132,7 +11591,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
12132
11591
|
...linked ? { signal: linked } : {},
|
|
12133
11592
|
...routerGenerationOptions(profileExecution),
|
|
12134
11593
|
...requestIdentity
|
|
12135
|
-
}));
|
|
11594
|
+
})));
|
|
12136
11595
|
if (r.model !== void 0) recordRuntimeOwnedProviderModel(executor, r.model);
|
|
12137
11596
|
transcript.reply({
|
|
12138
11597
|
content: r.content,
|
|
@@ -12614,6 +12073,13 @@ async function executeGranted(env, state, task, external, name, raw, context) {
|
|
|
12614
12073
|
name,
|
|
12615
12074
|
arguments: JSON.stringify(args)
|
|
12616
12075
|
});
|
|
12076
|
+
const nested = context.callId !== context.parentCallId;
|
|
12077
|
+
if (nested) env.observation?.progress({
|
|
12078
|
+
kind: "tool_call",
|
|
12079
|
+
toolName: name,
|
|
12080
|
+
toolCallId: context.callId,
|
|
12081
|
+
args
|
|
12082
|
+
});
|
|
12617
12083
|
const startedAt = Date.now();
|
|
12618
12084
|
let status = "ok";
|
|
12619
12085
|
try {
|
|
@@ -12623,6 +12089,12 @@ async function executeGranted(env, state, task, external, name, raw, context) {
|
|
|
12623
12089
|
throw error;
|
|
12624
12090
|
} finally {
|
|
12625
12091
|
const endedAt = Date.now();
|
|
12092
|
+
if (nested) env.observation?.progress({
|
|
12093
|
+
kind: "tool_result",
|
|
12094
|
+
toolName: name,
|
|
12095
|
+
toolCallId: context.callId,
|
|
12096
|
+
status
|
|
12097
|
+
});
|
|
12626
12098
|
try {
|
|
12627
12099
|
seam.onToolStep?.({
|
|
12628
12100
|
toolName: name,
|
|
@@ -12666,7 +12138,7 @@ async function requestModelTurn(env, state, actions, turn, signal, t) {
|
|
|
12666
12138
|
transcript.observe(state.messages);
|
|
12667
12139
|
try {
|
|
12668
12140
|
recordRuntimeOwnedProviderAttemptStart(env.executor);
|
|
12669
|
-
const res = await (profileExecution.stream === true ? streamRouterChatWithTools : routerChatWithTools)(routerTransportConfig(seam, env.model, profileExecution.retry), state.messages, actions.presentedTools, {
|
|
12141
|
+
const res = await observeModelRequest(env.observation, env.model, () => (profileExecution.stream === true ? streamRouterChatWithTools : routerChatWithTools)(routerTransportConfig(seam, env.model, profileExecution.retry), state.messages, actions.presentedTools, {
|
|
12670
12142
|
...profileExecution.temperature !== void 0 ? { temperature: profileExecution.temperature } : {},
|
|
12671
12143
|
signal: turn.controller.signal,
|
|
12672
12144
|
onResponse: async (receipt) => {
|
|
@@ -12677,7 +12149,7 @@ async function requestModelTurn(env, state, actions, turn, signal, t) {
|
|
|
12677
12149
|
...profileExecution.toolChoice ? { toolChoice: profileExecution.toolChoice } : {},
|
|
12678
12150
|
...routerGenerationOptions(profileExecution),
|
|
12679
12151
|
...routerTurnRequestIdentity(env.requestIdentity, t)
|
|
12680
|
-
});
|
|
12152
|
+
}));
|
|
12681
12153
|
turn.cleanup();
|
|
12682
12154
|
return res;
|
|
12683
12155
|
} catch (e) {
|
|
@@ -12751,12 +12223,27 @@ async function runToolCalls(env, state, actions, turn, external, task, toolCalls
|
|
|
12751
12223
|
name: toolName,
|
|
12752
12224
|
arguments: tc?.arguments ?? ""
|
|
12753
12225
|
});
|
|
12226
|
+
env.observation?.progress({
|
|
12227
|
+
kind: "tool_call",
|
|
12228
|
+
toolName,
|
|
12229
|
+
toolCallId: id
|
|
12230
|
+
});
|
|
12754
12231
|
if (!actions.modelToolNames.has(toolName)) {
|
|
12755
12232
|
state.messages.push({
|
|
12756
12233
|
role: "tool",
|
|
12757
12234
|
tool_call_id: id,
|
|
12758
12235
|
content: `error: tool ${JSON.stringify(toolName)} is not enabled by AgentProfile.tools`
|
|
12759
12236
|
});
|
|
12237
|
+
env.observation?.progress({
|
|
12238
|
+
kind: "tool_result",
|
|
12239
|
+
toolName,
|
|
12240
|
+
toolCallId: id,
|
|
12241
|
+
status: "error",
|
|
12242
|
+
error: {
|
|
12243
|
+
type: "ToolNotGranted",
|
|
12244
|
+
message: "Tool is not enabled by AgentProfile.tools"
|
|
12245
|
+
}
|
|
12246
|
+
});
|
|
12760
12247
|
try {
|
|
12761
12248
|
env.seam.onToolStep?.({
|
|
12762
12249
|
toolName,
|
|
@@ -12775,6 +12262,16 @@ async function runToolCalls(env, state, actions, turn, external, task, toolCalls
|
|
|
12775
12262
|
tool_call_id: id,
|
|
12776
12263
|
content: "error: tool arguments were not valid JSON"
|
|
12777
12264
|
});
|
|
12265
|
+
env.observation?.progress({
|
|
12266
|
+
kind: "tool_result",
|
|
12267
|
+
toolName,
|
|
12268
|
+
toolCallId: id,
|
|
12269
|
+
status: "error",
|
|
12270
|
+
error: {
|
|
12271
|
+
type: "ToolArguments",
|
|
12272
|
+
message: "Tool arguments were not valid JSON"
|
|
12273
|
+
}
|
|
12274
|
+
});
|
|
12778
12275
|
continue;
|
|
12779
12276
|
}
|
|
12780
12277
|
let result;
|
|
@@ -12790,6 +12287,16 @@ async function runToolCalls(env, state, actions, turn, external, task, toolCalls
|
|
|
12790
12287
|
succeeded = false;
|
|
12791
12288
|
result = `error: ${e instanceof Error ? e.message : String(e)}`;
|
|
12792
12289
|
}
|
|
12290
|
+
env.observation?.progress({
|
|
12291
|
+
kind: "tool_result",
|
|
12292
|
+
toolName,
|
|
12293
|
+
toolCallId: id,
|
|
12294
|
+
status: succeeded ? "ok" : "error",
|
|
12295
|
+
...succeeded ? {} : { error: {
|
|
12296
|
+
type: "ToolExecution",
|
|
12297
|
+
message: String(result)
|
|
12298
|
+
} }
|
|
12299
|
+
});
|
|
12793
12300
|
const projected = succeeded && actions.codeMode && toolName === "codemode" ? codeModeModelOutput(result) : void 0;
|
|
12794
12301
|
if (projected) images.push(...projected.images);
|
|
12795
12302
|
state.messages.push({
|
|
@@ -12912,6 +12419,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
12912
12419
|
async execute(task, signal) {
|
|
12913
12420
|
artifact = await runRouterToolLoop({
|
|
12914
12421
|
seam,
|
|
12422
|
+
observation: executorObservation(ctx),
|
|
12915
12423
|
spec,
|
|
12916
12424
|
model,
|
|
12917
12425
|
profileExecution,
|
|
@@ -13201,125 +12709,6 @@ const TERMINAL_DECISIONS = [
|
|
|
13201
12709
|
function isTerminalDecision(decision) {
|
|
13202
12710
|
return TERMINAL_DECISIONS.includes(decision);
|
|
13203
12711
|
}
|
|
13204
|
-
// src/runtime/sandbox-evidence-retention.ts
|
|
13205
|
-
/** A failed capture keeps the live source handle available for an explicit retry. */
|
|
13206
|
-
var SandboxEvidenceRetentionError = class extends Error {
|
|
13207
|
-
box;
|
|
13208
|
-
constructor(box, cause) {
|
|
13209
|
-
super(`Sandbox evidence retention failed for box ${String(box.id)}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
13210
|
-
this.name = "SandboxEvidenceRetentionError";
|
|
13211
|
-
this.box = box;
|
|
13212
|
-
}
|
|
13213
|
-
};
|
|
13214
|
-
/** Capture, verify, durably record, then destroy. A failure leaves the source intact. */
|
|
13215
|
-
async function captureBeforeDestroy(port, context, destroy) {
|
|
13216
|
-
const environment = {
|
|
13217
|
-
id: String(context.box.id),
|
|
13218
|
-
provider: "sandbox"
|
|
13219
|
-
};
|
|
13220
|
-
const result = await captureProviderWorkspaceSnapshot({
|
|
13221
|
-
timeoutMs: port.timeoutMs,
|
|
13222
|
-
...port.limits === void 0 ? {} : { limits: port.limits },
|
|
13223
|
-
artifacts: port.artifacts,
|
|
13224
|
-
capture: ({ signal }) => port.capture({
|
|
13225
|
-
...context,
|
|
13226
|
-
signal
|
|
13227
|
-
})
|
|
13228
|
-
}, {
|
|
13229
|
-
environment,
|
|
13230
|
-
executionId: context.executionId,
|
|
13231
|
-
providerSessionId: context.sandboxSessionIds[0] ?? null,
|
|
13232
|
-
nativeSessionId: null,
|
|
13233
|
-
profile: context.profile
|
|
13234
|
-
});
|
|
13235
|
-
const missing = context.sandboxSessionIds.filter((id) => !result.provenance.sessions?.some((session) => session.id === id && session.executionId === context.executionId));
|
|
13236
|
-
for (const nativeId of context.nativeSessionIds ?? []) if (!result.provenance.sessions?.some((session) => session.nativeSessionId === nativeId)) missing.push(`native/${nativeId}`);
|
|
13237
|
-
for (const sessionId of context.sandboxSessionIds) if ((context.sessionExecutionIds[sessionId]?.length ?? 0) === 0) missing.push(`${sessionId}/execution-id-unobserved`);
|
|
13238
|
-
for (const [sessionId, executionIds] of Object.entries(context.sessionExecutionIds)) {
|
|
13239
|
-
const session = result.provenance.sessions?.find((item) => item.id === sessionId);
|
|
13240
|
-
for (const executionId of executionIds) if (!session?.executionIds?.includes(executionId) || !session.eventCountsByExecutionId?.[executionId]) missing.push(`${sessionId}/${executionId}`);
|
|
13241
|
-
}
|
|
13242
|
-
const coverageComplete = result.coverageComplete === true && missing.length === 0;
|
|
13243
|
-
const incompleteReason = coverageComplete ? void 0 : [result.incompleteReason, ...missing.map((id) => `Sandbox session ${id} missing from capture`)].filter((reason) => reason !== void 0).join("; ");
|
|
13244
|
-
const receipt = {
|
|
13245
|
-
boxId: String(context.box.id),
|
|
13246
|
-
executionId: context.executionId,
|
|
13247
|
-
profileDigest: canonicalAgentProfileDigest(context.profile),
|
|
13248
|
-
scope: "box",
|
|
13249
|
-
sandboxSessionIds: [...context.sandboxSessionIds],
|
|
13250
|
-
...context.nativeSessionIds === void 0 ? {} : { nativeSessionIds: [...context.nativeSessionIds] },
|
|
13251
|
-
sessionExecutionIds: Object.fromEntries(Object.entries(context.sessionExecutionIds).map(([id, executions]) => [id, [...executions]])),
|
|
13252
|
-
snapshot: result.snapshot,
|
|
13253
|
-
provenance: result.provenance,
|
|
13254
|
-
coverageComplete,
|
|
13255
|
-
...incompleteReason === void 0 ? {} : { incompleteReason }
|
|
13256
|
-
};
|
|
13257
|
-
await port.record(receipt);
|
|
13258
|
-
if (!coverageComplete) throw new Error(incompleteReason ?? "Sandbox evidence coverage incomplete");
|
|
13259
|
-
await destroy();
|
|
13260
|
-
return receipt;
|
|
13261
|
-
}
|
|
13262
|
-
/** Execution-scoped inventory of every Sandbox session and turn observed by a loop. */
|
|
13263
|
-
var SandboxEvidenceTracker = class {
|
|
13264
|
-
port;
|
|
13265
|
-
runId;
|
|
13266
|
-
boxes = /* @__PURE__ */ new Map();
|
|
13267
|
-
constructor(port, runId) {
|
|
13268
|
-
this.port = port;
|
|
13269
|
-
this.runId = runId;
|
|
13270
|
-
if (!Number.isSafeInteger(port.timeoutMs) || port.timeoutMs <= 0) throw new ValidationError$1("Sandbox evidence retention.timeoutMs must be a positive safe integer");
|
|
13271
|
-
if (typeof port.artifacts?.read !== "function") throw new ValidationError$1("Sandbox evidence retention.artifacts.read is required");
|
|
13272
|
-
if (typeof port.capture !== "function") throw new ValidationError$1("Sandbox evidence retention.capture is required");
|
|
13273
|
-
if (typeof port.record !== "function") throw new ValidationError$1("Sandbox evidence retention.record is required");
|
|
13274
|
-
}
|
|
13275
|
-
register(box, profile, sessionId) {
|
|
13276
|
-
let state = this.boxes.get(box);
|
|
13277
|
-
if (state === void 0) {
|
|
13278
|
-
state = {
|
|
13279
|
-
profile,
|
|
13280
|
-
sessions: /* @__PURE__ */ new Map()
|
|
13281
|
-
};
|
|
13282
|
-
this.boxes.set(box, state);
|
|
13283
|
-
}
|
|
13284
|
-
if (sessionId !== void 0 && !state.sessions.has(sessionId)) state.sessions.set(sessionId, /* @__PURE__ */ new Set());
|
|
13285
|
-
}
|
|
13286
|
-
recordDispatch(box, sessionId, executionId) {
|
|
13287
|
-
const state = this.boxes.get(box);
|
|
13288
|
-
if (state === void 0) throw new Error("Sandbox evidence dispatched before box registration");
|
|
13289
|
-
const executions = state.sessions.get(sessionId) ?? /* @__PURE__ */ new Set();
|
|
13290
|
-
executions.add(executionId);
|
|
13291
|
-
state.sessions.set(sessionId, executions);
|
|
13292
|
-
}
|
|
13293
|
-
observe(box, event, sessionHint) {
|
|
13294
|
-
const state = this.boxes.get(box);
|
|
13295
|
-
if (state === void 0) throw new Error("Sandbox evidence observed before box registration");
|
|
13296
|
-
const sessionId = typeof event.data.runtimeSessionId === "string" ? event.data.runtimeSessionId : sessionHint;
|
|
13297
|
-
if (sessionId === void 0) return;
|
|
13298
|
-
const executions = state.sessions.get(sessionId) ?? /* @__PURE__ */ new Set();
|
|
13299
|
-
if (typeof event.data.executionId === "string") executions.add(event.data.executionId);
|
|
13300
|
-
state.sessions.set(sessionId, executions);
|
|
13301
|
-
}
|
|
13302
|
-
async destroy(box) {
|
|
13303
|
-
const state = this.boxes.get(box);
|
|
13304
|
-
if (state === void 0) throw new Error(`Sandbox evidence has no registered source ${String(box.id)}`);
|
|
13305
|
-
const sandboxSessionIds = [...state.sessions.keys()].sort();
|
|
13306
|
-
const sessionExecutionIds = Object.fromEntries([...state.sessions.entries()].map(([id, executions]) => [id, [...executions].sort()]));
|
|
13307
|
-
try {
|
|
13308
|
-
await captureBeforeDestroy(this.port, {
|
|
13309
|
-
box,
|
|
13310
|
-
executionId: this.runId,
|
|
13311
|
-
profile: state.profile,
|
|
13312
|
-
sandboxSessionIds,
|
|
13313
|
-
sessionExecutionIds
|
|
13314
|
-
}, async () => {
|
|
13315
|
-
await box.delete();
|
|
13316
|
-
});
|
|
13317
|
-
this.boxes.delete(box);
|
|
13318
|
-
} catch (error) {
|
|
13319
|
-
throw new SandboxEvidenceRetentionError(box, error);
|
|
13320
|
-
}
|
|
13321
|
-
}
|
|
13322
|
-
};
|
|
13323
12712
|
// src/runtime/sandbox-acquire.ts
|
|
13324
12713
|
/**
|
|
13325
12714
|
* HTTP statuses where create should be retried — gateway timeouts
|
|
@@ -13364,20 +12753,14 @@ async function acquireSandbox(client, options, acquire = {}) {
|
|
|
13364
12753
|
while (now() < deadline) {
|
|
13365
12754
|
throwIfAborted(acquire.signal);
|
|
13366
12755
|
try {
|
|
13367
|
-
|
|
13368
|
-
acquire.onAcquire?.(box);
|
|
13369
|
-
return await waitReadyOrDestroy(box, deadline, pollMs, acquire.signal, now, sleep$1, acquire.beforeDelete);
|
|
12756
|
+
return await waitReadyOrDestroy(await client.create(createOpts, acquire.signal === void 0 ? void 0 : { signal: acquire.signal }), deadline, pollMs, acquire.signal, now, sleep$1);
|
|
13370
12757
|
} catch (err) {
|
|
13371
|
-
if (err instanceof SandboxEvidenceRetentionError) throw err;
|
|
13372
12758
|
throwIfAborted(acquire.signal);
|
|
13373
12759
|
if (!isRetryable(err)) throw err;
|
|
13374
12760
|
lastErr = err;
|
|
13375
12761
|
if (typeof c.list === "function") for (let scan = 0; scan < appearScans && now() < deadline; scan += 1) {
|
|
13376
12762
|
const found = (await c.list().catch(() => []))?.find((b) => b.name === name);
|
|
13377
|
-
if (found)
|
|
13378
|
-
acquire.onAcquire?.(found);
|
|
13379
|
-
return await waitReadyOrDestroy(found, deadline, pollMs, acquire.signal, now, sleep$1, acquire.beforeDelete);
|
|
13380
|
-
}
|
|
12763
|
+
if (found) return await waitReadyOrDestroy(found, deadline, pollMs, acquire.signal, now, sleep$1);
|
|
13381
12764
|
if (scan < 4) await sleep$1(pollMs);
|
|
13382
12765
|
}
|
|
13383
12766
|
attempt += 1;
|
|
@@ -13388,12 +12771,11 @@ async function acquireSandbox(client, options, acquire = {}) {
|
|
|
13388
12771
|
}
|
|
13389
12772
|
/** `waitUntilReady`, tearing the box down (best-effort) on any throw so a box
|
|
13390
12773
|
* that never reaches `running` (abort, terminal status, budget) does not leak. */
|
|
13391
|
-
async function waitReadyOrDestroy(box, deadline, pollMs, signal, now, sleep
|
|
12774
|
+
async function waitReadyOrDestroy(box, deadline, pollMs, signal, now, sleep) {
|
|
13392
12775
|
try {
|
|
13393
12776
|
return await waitUntilReady(box, deadline, pollMs, signal, now, sleep);
|
|
13394
12777
|
} catch (err) {
|
|
13395
|
-
|
|
13396
|
-
else await beforeDelete(box);
|
|
12778
|
+
await deleteBoxSafe(box);
|
|
13397
12779
|
throw err;
|
|
13398
12780
|
}
|
|
13399
12781
|
}
|
|
@@ -13575,14 +12957,9 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13575
12957
|
const profiles = /* @__PURE__ */ new Map();
|
|
13576
12958
|
const acquireFresh = async (spec, signal) => {
|
|
13577
12959
|
if (signal.aborted) throwAbort();
|
|
13578
|
-
const box = await acquireSandbox(client, buildBackendOptions(spec.profile, spec.sandboxOverrides), {
|
|
13579
|
-
signal,
|
|
13580
|
-
...options.onAcquire === void 0 ? {} : { onAcquire: (source) => options.onAcquire?.(source, spec.profile) },
|
|
13581
|
-
...options.beforeDelete === void 0 ? {} : { beforeDelete: options.beforeDelete }
|
|
13582
|
-
});
|
|
12960
|
+
const box = await acquireSandbox(client, buildBackendOptions(spec.profile, spec.sandboxOverrides), { signal });
|
|
13583
12961
|
owned.push(box);
|
|
13584
12962
|
profiles.set(box, spec.profile);
|
|
13585
|
-
options.onAcquire?.(box, spec.profile);
|
|
13586
12963
|
try {
|
|
13587
12964
|
await spec.prepareBox?.(box, {
|
|
13588
12965
|
signal,
|
|
@@ -13590,7 +12967,7 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13590
12967
|
});
|
|
13591
12968
|
} catch (error) {
|
|
13592
12969
|
try {
|
|
13593
|
-
await destroyBounded(box, options.failOnDestroyError
|
|
12970
|
+
await destroyBounded(box, options.failOnDestroyError);
|
|
13594
12971
|
owned.splice(owned.indexOf(box), 1);
|
|
13595
12972
|
} catch (captureError) {
|
|
13596
12973
|
throw new AggregateError([error, captureError], "Sandbox preparation and evidence cleanup failed");
|
|
@@ -13629,19 +13006,13 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13629
13006
|
if (branched !== void 0) {
|
|
13630
13007
|
owned.push(...branched);
|
|
13631
13008
|
const inheritedProfile = profiles.get(parent.box);
|
|
13632
|
-
if (inheritedProfile !== void 0) for (const box of branched)
|
|
13633
|
-
profiles.set(box, inheritedProfile);
|
|
13634
|
-
options.onAcquire?.(box, inheritedProfile);
|
|
13635
|
-
}
|
|
13009
|
+
if (inheritedProfile !== void 0) for (const box of branched) profiles.set(box, inheritedProfile);
|
|
13636
13010
|
if (branched.length !== prompts.length) throw new ValidationError$1(`SandboxLineage.fork: Sandbox returned ${branched.length} of ${prompts.length} requested children`);
|
|
13637
13011
|
return mapWithConcurrency(branched, forkConcurrency, async (box, i) => {
|
|
13638
13012
|
throwIfAborted(signal);
|
|
13639
13013
|
const spec = specs[i % specs.length];
|
|
13640
13014
|
if (!spec) throw new ValidationError$1("SandboxLineage.fork: no AgentRunSpec for branch");
|
|
13641
|
-
if (inheritedProfile === void 0)
|
|
13642
|
-
profiles.set(box, spec.profile);
|
|
13643
|
-
options.onAcquire?.(box, spec.profile);
|
|
13644
|
-
}
|
|
13015
|
+
if (inheritedProfile === void 0) profiles.set(box, spec.profile);
|
|
13645
13016
|
await spec.prepareBox?.(box, {
|
|
13646
13017
|
signal,
|
|
13647
13018
|
recordMount
|
|
@@ -13678,7 +13049,7 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13678
13049
|
const doomed = [];
|
|
13679
13050
|
for (const box of owned) (keepBoxes.has(box) ? survivors : doomed).push(box);
|
|
13680
13051
|
if (doomed.length === 0) return;
|
|
13681
|
-
const results = await Promise.allSettled(doomed.map((box) => destroyBounded(box, options.failOnDestroyError
|
|
13052
|
+
const results = await Promise.allSettled(doomed.map((box) => destroyBounded(box, options.failOnDestroyError)));
|
|
13682
13053
|
const failed = results.flatMap((result, index) => result.status === "rejected" ? [doomed[index]] : []);
|
|
13683
13054
|
owned.length = 0;
|
|
13684
13055
|
owned.push(...survivors, ...failed);
|
|
@@ -13686,7 +13057,7 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13686
13057
|
},
|
|
13687
13058
|
async teardown() {
|
|
13688
13059
|
const boxes = owned.splice(0, owned.length);
|
|
13689
|
-
const results = await Promise.allSettled(boxes.map((box) => destroyBounded(box, options.failOnDestroyError
|
|
13060
|
+
const results = await Promise.allSettled(boxes.map((box) => destroyBounded(box, options.failOnDestroyError)));
|
|
13690
13061
|
const failed = results.flatMap((result, index) => result.status === "rejected" ? [boxes[index]] : []);
|
|
13691
13062
|
owned.push(...failed);
|
|
13692
13063
|
if (failed.length > 0) throw new AggregateError(results.filter((result) => result.status === "rejected").map((result) => result.reason), "Sandbox evidence capture failed before teardown");
|
|
@@ -13733,11 +13104,7 @@ async function assertSessionLive(box, sessionId) {
|
|
|
13733
13104
|
if (typeof session !== "function") return;
|
|
13734
13105
|
if (await session.call(box, sessionId).status() === null) throw new ValidationError$1(`SandboxLineage.continue: session ${sessionId} is not known to the sandbox — the platform did not preserve the client-minted session id (or it was reaped). Continuing would run without prior context; refusing to silently lose conversation continuity.`);
|
|
13735
13106
|
}
|
|
13736
|
-
async function destroyBounded(box, failOnError = false
|
|
13737
|
-
if (beforeDelete !== void 0) {
|
|
13738
|
-
await beforeDelete(box);
|
|
13739
|
-
return;
|
|
13740
|
-
}
|
|
13107
|
+
async function destroyBounded(box, failOnError = false) {
|
|
13741
13108
|
if (failOnError) {
|
|
13742
13109
|
await box.delete();
|
|
13743
13110
|
return;
|
|
@@ -13751,7 +13118,7 @@ async function destroyBounded(box, failOnError = false, beforeDelete) {
|
|
|
13751
13118
|
* Rejects the lineage + `onWorkerBox` combination: both claim the same
|
|
13752
13119
|
* box-ownership channel, and silently honoring one would leak or double-free.
|
|
13753
13120
|
*/
|
|
13754
|
-
async function setUpLineage(options, maxConcurrency, recordMount, promptOptions
|
|
13121
|
+
async function setUpLineage(options, maxConcurrency, recordMount, promptOptions) {
|
|
13755
13122
|
const lineageOpts = options.lineage;
|
|
13756
13123
|
if (!lineageOpts || !lineageOpts.sessionContinuity && !lineageOpts.forkFanout) return void 0;
|
|
13757
13124
|
if (options.onWorkerBox) throw new ValidationError$1("runAgentRounds: `lineage` and `onWorkerBox` both own worker boxes — pass only one");
|
|
@@ -13759,12 +13126,7 @@ async function setUpLineage(options, maxConcurrency, recordMount, promptOptions,
|
|
|
13759
13126
|
lineage: createSandboxLineage(options.ctx.sandboxClient, {
|
|
13760
13127
|
maxConcurrency,
|
|
13761
13128
|
streaming: lineageOpts.streaming,
|
|
13762
|
-
recordMount
|
|
13763
|
-
...evidenceTracker === void 0 ? {} : {
|
|
13764
|
-
failOnDestroyError: true,
|
|
13765
|
-
onAcquire: (box, profile) => evidenceTracker.register(box, profile),
|
|
13766
|
-
beforeDelete: (box) => evidenceTracker.destroy(box)
|
|
13767
|
-
}
|
|
13129
|
+
recordMount
|
|
13768
13130
|
}),
|
|
13769
13131
|
options: lineageOpts,
|
|
13770
13132
|
...promptOptions === void 0 ? {} : { promptOptions },
|
|
@@ -13785,12 +13147,7 @@ async function setUpLineage(options, maxConcurrency, recordMount, promptOptions,
|
|
|
13785
13147
|
* Round 0 (parentIndex undefined) always starts fresh — the independence of the
|
|
13786
13148
|
* first batch is preserved.
|
|
13787
13149
|
*/
|
|
13788
|
-
function planLineageRound(state, specs, slice, parentIndex, signal
|
|
13789
|
-
const executionIds = retainEvidence ? slice.map(() => randomUuid()) : [];
|
|
13790
|
-
const promptForOffset = (offset) => retainEvidence ? {
|
|
13791
|
-
...state.promptOptions ?? {},
|
|
13792
|
-
executionId: executionIds[offset]
|
|
13793
|
-
} : state.promptOptions;
|
|
13150
|
+
function planLineageRound(state, specs, slice, parentIndex, signal) {
|
|
13794
13151
|
const lineage = state.lineage;
|
|
13795
13152
|
const parent = parentIndex !== void 0 ? state.handles.get(parentIndex) : void 0;
|
|
13796
13153
|
const promptFor = (offset) => {
|
|
@@ -13805,9 +13162,8 @@ function planLineageRound(state, specs, slice, parentIndex, signal, retainEviden
|
|
|
13805
13162
|
};
|
|
13806
13163
|
if (slice.length === 1 && parent && state.options.sessionContinuity) return [{ async acquire() {
|
|
13807
13164
|
return {
|
|
13808
|
-
events: await lineage.continue(parent, promptFor(0), signal,
|
|
13809
|
-
handle: parent
|
|
13810
|
-
...retainEvidence ? { executionId: executionIds[0] } : {}
|
|
13165
|
+
events: await lineage.continue(parent, promptFor(0), signal, state.promptOptions),
|
|
13166
|
+
handle: parent
|
|
13811
13167
|
};
|
|
13812
13168
|
} }];
|
|
13813
13169
|
if (slice.length > 1 && parent && state.options.forkFanout) {
|
|
@@ -13815,23 +13171,17 @@ function planLineageRound(state, specs, slice, parentIndex, signal, retainEviden
|
|
|
13815
13171
|
const childSpecs = slice.map((_, offset) => specAt(offset));
|
|
13816
13172
|
let forked;
|
|
13817
13173
|
const ensureForked = () => {
|
|
13818
|
-
forked ??= lineage.fork(parent, prompts, childSpecs, signal, state.promptOptions
|
|
13174
|
+
forked ??= lineage.fork(parent, prompts, childSpecs, signal, state.promptOptions);
|
|
13819
13175
|
return forked;
|
|
13820
13176
|
};
|
|
13821
13177
|
return slice.map((_, offset) => ({ async acquire() {
|
|
13822
13178
|
const branch = (await ensureForked())[offset];
|
|
13823
13179
|
if (!branch) throw new ValidationError$1("runAgentRounds: lineage fork produced no branch for offset");
|
|
13824
|
-
return
|
|
13825
|
-
...branch,
|
|
13826
|
-
...retainEvidence ? { executionId: executionIds[offset] } : {}
|
|
13827
|
-
};
|
|
13180
|
+
return branch;
|
|
13828
13181
|
} }));
|
|
13829
13182
|
}
|
|
13830
13183
|
return slice.map((_, offset) => ({ async acquire() {
|
|
13831
|
-
return
|
|
13832
|
-
...await lineage.start(specAt(offset), promptFor(offset), signal, promptForOffset(offset)),
|
|
13833
|
-
...retainEvidence ? { executionId: executionIds[offset] } : {}
|
|
13834
|
-
};
|
|
13184
|
+
return await lineage.start(specAt(offset), promptFor(offset), signal, state.promptOptions);
|
|
13835
13185
|
} }));
|
|
13836
13186
|
}
|
|
13837
13187
|
/**
|
|
@@ -13936,22 +13286,14 @@ function readSandboxId(box) {
|
|
|
13936
13286
|
* loop kernel passes its per-run recorder; other callers (which have no
|
|
13937
13287
|
* `LoopResult` to attach to) omit it and the prepareBox recorder is a no-op.
|
|
13938
13288
|
*/
|
|
13939
|
-
async function createSandboxForSpec(client, spec, signal, recordMount
|
|
13289
|
+
async function createSandboxForSpec(client, spec, signal, recordMount) {
|
|
13940
13290
|
const opts = buildBackendOptions(spec.profile, spec.sandboxOverrides);
|
|
13941
13291
|
if (signal.aborted) throwAbort();
|
|
13942
|
-
const box = await acquireSandbox(client, opts, {
|
|
13943
|
-
signal,
|
|
13944
|
-
...evidenceTracker === void 0 ? {} : {
|
|
13945
|
-
onAcquire: (source) => evidenceTracker.register(source, spec.profile),
|
|
13946
|
-
beforeDelete: (source) => evidenceTracker.destroy(source)
|
|
13947
|
-
}
|
|
13948
|
-
});
|
|
13949
|
-
evidenceTracker?.register(box, spec.profile);
|
|
13292
|
+
const box = await acquireSandbox(client, opts, { signal });
|
|
13950
13293
|
try {
|
|
13951
13294
|
await invokePrepareBox(spec, box, signal, recordMount);
|
|
13952
13295
|
} catch (error) {
|
|
13953
|
-
|
|
13954
|
-
else await evidenceTracker.destroy(box);
|
|
13296
|
+
await deleteBoxSafe(box);
|
|
13955
13297
|
throw error;
|
|
13956
13298
|
}
|
|
13957
13299
|
return box;
|
|
@@ -14039,8 +13381,6 @@ async function executeIteration(args) {
|
|
|
14039
13381
|
};
|
|
14040
13382
|
try {
|
|
14041
13383
|
let stream;
|
|
14042
|
-
let sandboxSessionId;
|
|
14043
|
-
let dispatchedExecutionId;
|
|
14044
13384
|
const source = args.lineagePlan?.[args.item.index - args.baseIndex];
|
|
14045
13385
|
if (source) {
|
|
14046
13386
|
const acquired = await source.acquire();
|
|
@@ -14048,28 +13388,16 @@ async function executeIteration(args) {
|
|
|
14048
13388
|
boxAcquiredAt = args.now();
|
|
14049
13389
|
lineageOwned = true;
|
|
14050
13390
|
args.lineageState?.handles.set(args.item.index, acquired.handle);
|
|
14051
|
-
args.evidenceTracker?.register(box, spec.profile, acquired.handle.sessionId);
|
|
14052
13391
|
stream = acquired.events;
|
|
14053
|
-
sandboxSessionId = acquired.handle.sessionId;
|
|
14054
|
-
dispatchedExecutionId = acquired.executionId;
|
|
14055
13392
|
} else {
|
|
14056
|
-
box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal, args.recordMount
|
|
13393
|
+
box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal, args.recordMount);
|
|
14057
13394
|
boxAcquiredAt = args.now();
|
|
14058
13395
|
const prompt = spec.taskToPrompt(args.item.task);
|
|
14059
|
-
|
|
14060
|
-
sandboxSessionId = sandboxSessionIdForTurn;
|
|
14061
|
-
dispatchedExecutionId = args.evidenceTracker === void 0 ? void 0 : randomUuid();
|
|
14062
|
-
const promptOptions = dispatchedExecutionId === void 0 ? args.promptOptions : {
|
|
13396
|
+
stream = args.streaming === "poll" ? promptEvents("poll", box, prompt, `${args.runId}-i${args.item.index}`, args.signal, args.promptOptions) : box.streamPrompt(prompt, {
|
|
14063
13397
|
...args.promptOptions ?? {},
|
|
14064
|
-
executionId: dispatchedExecutionId
|
|
14065
|
-
};
|
|
14066
|
-
stream = args.streaming === "poll" ? promptEvents("poll", box, prompt, sandboxSessionIdForTurn ?? `${args.runId}-i${args.item.index}`, args.signal, promptOptions) : box.streamPrompt(prompt, {
|
|
14067
|
-
...promptOptions ?? {},
|
|
14068
|
-
...sandboxSessionIdForTurn === void 0 ? {} : { sessionId: sandboxSessionIdForTurn },
|
|
14069
13398
|
signal: args.signal
|
|
14070
13399
|
});
|
|
14071
13400
|
}
|
|
14072
|
-
if (box !== void 0 && sandboxSessionId !== void 0 && dispatchedExecutionId !== void 0) args.evidenceTracker?.recordDispatch(box, sandboxSessionId, dispatchedExecutionId);
|
|
14073
13401
|
const placement = describeSandboxPlacement(args.ctx.sandboxClient, box);
|
|
14074
13402
|
await emitTrace(args.ctx.traceEmitter, {
|
|
14075
13403
|
kind: "loop.iteration.dispatch",
|
|
@@ -14096,7 +13424,6 @@ async function executeIteration(args) {
|
|
|
14096
13424
|
try {
|
|
14097
13425
|
for await (const event of stream) {
|
|
14098
13426
|
collector.push(event);
|
|
14099
|
-
if (box !== void 0) args.evidenceTracker?.observe(box, event, source ? args.lineageState?.handles.get(args.item.index)?.sessionId : void 0);
|
|
14100
13427
|
outcomeTracker.observe(event);
|
|
14101
13428
|
notifySandboxEventObserver(event, args.ctx.onSandboxEvent, {
|
|
14102
13429
|
iterationIndex: args.item.index,
|
|
@@ -14156,7 +13483,7 @@ async function executeIteration(args) {
|
|
|
14156
13483
|
});
|
|
14157
13484
|
if (lineageOwned) {} else if (args.collectBox && box) args.collectBox(box);
|
|
14158
13485
|
else {
|
|
14159
|
-
const teardown =
|
|
13486
|
+
const teardown = await destroySandboxSafe(box, args.ctx.traceEmitter, args.runId, args.now);
|
|
14160
13487
|
if (boxAcquiredAt !== void 0 && teardown !== "no-delete-api") {
|
|
14161
13488
|
slot.boxLiveMs = Math.max(0, args.now() - boxAcquiredAt);
|
|
14162
13489
|
if (teardown !== "deleted") slot.boxLiveMsKnown = false;
|
|
@@ -14248,8 +13575,6 @@ async function runAgentRounds(options) {
|
|
|
14248
13575
|
const promptOptions = readPromptOptions(options.ctx.promptOptions, "runAgentRounds: ctx.promptOptions");
|
|
14249
13576
|
const now = options.now ?? Date.now;
|
|
14250
13577
|
const runId = options.runId ?? `loop-${randomSuffix()}`;
|
|
14251
|
-
if (options.evidenceRetention !== void 0 && options.onWorkerBox !== void 0) throw new ValidationError$1("runAgentRounds: evidenceRetention cannot cover sessions dispatched through onWorkerBox");
|
|
14252
|
-
const evidenceTracker = options.evidenceRetention === void 0 ? void 0 : new SandboxEvidenceTracker(options.evidenceRetention, runId);
|
|
14253
13578
|
const loopStart = now();
|
|
14254
13579
|
const driverName = options.driver.name ?? "driver";
|
|
14255
13580
|
const iterations = [];
|
|
@@ -14263,7 +13588,7 @@ async function runAgentRounds(options) {
|
|
|
14263
13588
|
ownedBoxes.push(box);
|
|
14264
13589
|
options.onWorkerBox?.(box);
|
|
14265
13590
|
} : void 0;
|
|
14266
|
-
const lineageState = await setUpLineage(options, maxConcurrency, recordMount, promptOptions
|
|
13591
|
+
const lineageState = await setUpLineage(options, maxConcurrency, recordMount, promptOptions);
|
|
14267
13592
|
emitRunLoopHook(options, {
|
|
14268
13593
|
target: "agent.run",
|
|
14269
13594
|
phase: "before",
|
|
@@ -14359,7 +13684,7 @@ async function runAgentRounds(options) {
|
|
|
14359
13684
|
tokenUsage: zeroTokenUsage()
|
|
14360
13685
|
});
|
|
14361
13686
|
}
|
|
14362
|
-
const lineagePlan = lineageState ? planLineageRound(lineageState, specs, slice, parentIndex, controller.signal
|
|
13687
|
+
const lineagePlan = lineageState ? planLineageRound(lineageState, specs, slice, parentIndex, controller.signal) : void 0;
|
|
14363
13688
|
await runBatch({
|
|
14364
13689
|
slice,
|
|
14365
13690
|
baseIndex,
|
|
@@ -14378,7 +13703,6 @@ async function runAgentRounds(options) {
|
|
|
14378
13703
|
collectBox,
|
|
14379
13704
|
lineagePlan,
|
|
14380
13705
|
lineageState,
|
|
14381
|
-
evidenceTracker,
|
|
14382
13706
|
recordMount,
|
|
14383
13707
|
...promptOptions === void 0 ? {} : { promptOptions }
|
|
14384
13708
|
});
|
|
@@ -14418,7 +13742,7 @@ async function runAgentRounds(options) {
|
|
|
14418
13742
|
return await decideAndFinalize(options, iterations, loopStart, now, runId, mounts);
|
|
14419
13743
|
} finally {
|
|
14420
13744
|
if (options.ctx.signal) options.ctx.signal.removeEventListener("abort", onOuterAbort);
|
|
14421
|
-
const cleanup = await Promise.allSettled(ownedBoxes.map((box) =>
|
|
13745
|
+
const cleanup = await Promise.allSettled(ownedBoxes.map((box) => destroySandboxSafe(box, options.ctx.traceEmitter, runId, now)));
|
|
14422
13746
|
if (options.onWorkerBox) options.onWorkerBox(void 0);
|
|
14423
13747
|
let lineageFailure;
|
|
14424
13748
|
try {
|
|
@@ -14477,7 +13801,6 @@ function sandboxSessionOutput(run) {
|
|
|
14477
13801
|
toolCalls: run.toolCalls,
|
|
14478
13802
|
...run.latestOutcome ? { outcome: run.latestOutcome } : {},
|
|
14479
13803
|
...run.usageFailure === void 0 ? {} : { tokensUnknownReason: run.usageFailure },
|
|
14480
|
-
...run.args.workspaceCaptures === void 0 ? {} : { workspaceCaptures: run.args.workspaceCaptures() },
|
|
14481
13804
|
...run.preservationFailure === void 0 ? {} : { preservationFailure: run.preservationFailure }
|
|
14482
13805
|
};
|
|
14483
13806
|
}
|
|
@@ -14950,7 +14273,6 @@ function sandboxExecutorForPath(spec, ctx, modelPath) {
|
|
|
14950
14273
|
harness,
|
|
14951
14274
|
sandboxClient: seam.sandboxClient,
|
|
14952
14275
|
failOnDestroyError: seam.failOnDestroyError,
|
|
14953
|
-
workspaceCaptures: seam.workspaceCaptures,
|
|
14954
14276
|
inbox,
|
|
14955
14277
|
taskToPrompt: (t) => taskToPrompt$1(t),
|
|
14956
14278
|
options: seam.steering,
|
|
@@ -14958,8 +14280,6 @@ function sandboxExecutorForPath(spec, ctx, modelPath) {
|
|
|
14958
14280
|
...Object.keys(traceEnv).length > 0 ? { traceEnv } : {},
|
|
14959
14281
|
contentRef
|
|
14960
14282
|
});
|
|
14961
|
-
const bindCaptureOutput = ctx.seams[sandboxCaptureOutputSeamKey];
|
|
14962
|
-
if (typeof bindCaptureOutput === "function") bindCaptureOutput(() => session.output());
|
|
14963
14283
|
return attestRuntimeOwnedExecutor({
|
|
14964
14284
|
runtime: "sandbox",
|
|
14965
14285
|
deliver: (m) => inbox.deliver(m),
|
|
@@ -15195,7 +14515,7 @@ function singleShotDriver(maxIterations) {
|
|
|
15195
14515
|
* model, process, limits, or backend behavior is detached and deeply frozen.
|
|
15196
14516
|
* Explicit service/function fields remain live by reference because they are executable ports,
|
|
15197
14517
|
* not portable configuration. */
|
|
15198
|
-
function snapshotExecutorConfig(config) {
|
|
14518
|
+
function snapshotExecutorConfig(config, mode = "execution") {
|
|
15199
14519
|
switch (config.backend) {
|
|
15200
14520
|
case "router-tools": {
|
|
15201
14521
|
const { complete, executeToolCall, onMessages, onToolStep, onProviderResponse, ...decisionData } = config;
|
|
@@ -15250,17 +14570,16 @@ function snapshotExecutorConfig(config) {
|
|
|
15250
14570
|
}
|
|
15251
14571
|
case "provider": {
|
|
15252
14572
|
if (config.outputFormat !== void 0 && config.steering !== void 0) throw new ValidationError$1("createExecutor(provider): JSON output is not supported with steering");
|
|
15253
|
-
const { provider, registry, profileForCreate, taskToTurn, validator,
|
|
15254
|
-
if (shared !== void 0 && (decisionData.steering !== void 0 || decisionData.placements !== void 0
|
|
14573
|
+
const { provider, registry, profileForCreate, taskToTurn, validator, shared, ...decisionData } = config;
|
|
14574
|
+
if (shared !== void 0 && (decisionData.steering !== void 0 || decisionData.placements !== void 0)) throw new ValidationError$1("createExecutor(provider): shared placement cannot combine with steering or placements");
|
|
15255
14575
|
const snapshot = detachedSnapshot(decisionData, "createExecutor provider config");
|
|
15256
|
-
const resolvedProvider = resolveAgentEnvironmentProvider(provider, registry);
|
|
14576
|
+
const resolvedProvider = mode === "control" && typeof provider === "string" ? registry?.get(provider) ?? provider : resolveAgentEnvironmentProvider(provider, registry);
|
|
15257
14577
|
return Object.freeze({
|
|
15258
14578
|
...snapshot,
|
|
15259
14579
|
provider: resolvedProvider,
|
|
15260
14580
|
...profileForCreate === void 0 ? {} : { profileForCreate },
|
|
15261
14581
|
...taskToTurn === void 0 ? {} : { taskToTurn },
|
|
15262
14582
|
...validator === void 0 ? {} : { validator },
|
|
15263
|
-
...workspaceRetention === void 0 ? {} : { workspaceRetention },
|
|
15264
14583
|
...shared === void 0 ? {} : { shared }
|
|
15265
14584
|
});
|
|
15266
14585
|
}
|
|
@@ -15268,7 +14587,6 @@ function snapshotExecutorConfig(config) {
|
|
|
15268
14587
|
assertExactConfigKeys(config, /* @__PURE__ */ new Set([
|
|
15269
14588
|
"backend",
|
|
15270
14589
|
"failOnDestroyError",
|
|
15271
|
-
"workspaceCaptures",
|
|
15272
14590
|
"lineage",
|
|
15273
14591
|
"loopCtx",
|
|
15274
14592
|
"maxIterations",
|
|
@@ -15276,11 +14594,10 @@ function snapshotExecutorConfig(config) {
|
|
|
15276
14594
|
"steering",
|
|
15277
14595
|
"validator"
|
|
15278
14596
|
]), "createExecutor sandbox config");
|
|
15279
|
-
const { sandboxClient, loopCtx, validator,
|
|
14597
|
+
const { sandboxClient, loopCtx, validator, ...decisionData } = config;
|
|
15280
14598
|
const port = {
|
|
15281
14599
|
sandboxClient,
|
|
15282
|
-
...validator === void 0 ? {} : { validator }
|
|
15283
|
-
...workspaceCaptures === void 0 ? {} : { workspaceCaptures }
|
|
14600
|
+
...validator === void 0 ? {} : { validator }
|
|
15284
14601
|
};
|
|
15285
14602
|
if (loopCtx === void 0) {
|
|
15286
14603
|
const snapshot = detachedSnapshot(decisionData, "createExecutor sandbox config");
|
|
@@ -15408,9 +14725,6 @@ function createExecutor(config) {
|
|
|
15408
14725
|
if (providerSeam.destroyOnSettle === false) throw new ValidationError$1("createExecutor(provider, steering): destroyOnSettle=false conflicts with the session-owned environment lifecycle");
|
|
15409
14726
|
if (providerSeam.validator) throw new ValidationError$1("createExecutor(provider, steering): validator is not representable with steering — the steerable session is a multi-turn session on one environment, not a scored single-shot leaf, so the score would be silently dropped");
|
|
15410
14727
|
const harness = requiredProviderProfileHarness(spec, providerSeam);
|
|
15411
|
-
const workspaceCaptures = [];
|
|
15412
|
-
let capturedOutput;
|
|
15413
|
-
const publishEvidence = retainedExecutorContext(seamed)?.onEvidence;
|
|
15414
14728
|
const sandboxClient = providerAsSandboxClient(provider, {
|
|
15415
14729
|
defaults: {
|
|
15416
14730
|
...providerSeam.defaults ?? {},
|
|
@@ -15418,34 +14732,14 @@ function createExecutor(config) {
|
|
|
15418
14732
|
signal: seamed.signal
|
|
15419
14733
|
},
|
|
15420
14734
|
requireTerminalEvent: providerSeam.requireTerminalEvent,
|
|
15421
|
-
requireSession: true
|
|
15422
|
-
...providerSeam.workspaceRetention === void 0 ? {} : {
|
|
15423
|
-
workspaceRetention: providerSeam.workspaceRetention,
|
|
15424
|
-
retentionIdentity: {
|
|
15425
|
-
executionId: seamed.node?.nodeId ?? `provider-run-${randomUUID()}`,
|
|
15426
|
-
profile: spec.profile,
|
|
15427
|
-
...seamed.node === void 0 ? {} : { node: seamed.node }
|
|
15428
|
-
},
|
|
15429
|
-
onWorkspaceCaptured: async (receipt) => {
|
|
15430
|
-
if (!workspaceCaptures.includes(receipt)) workspaceCaptures.push(receipt);
|
|
15431
|
-
if (publishEvidence !== void 0) {
|
|
15432
|
-
if (capturedOutput === void 0) throw new ValidationError$1("provider capture has no bound session output");
|
|
15433
|
-
await publishEvidence(capturedOutput());
|
|
15434
|
-
}
|
|
15435
|
-
}
|
|
15436
|
-
}
|
|
14735
|
+
requireSession: true
|
|
15437
14736
|
});
|
|
15438
14737
|
const providerCtx = {
|
|
15439
14738
|
...seamed,
|
|
15440
14739
|
seams: {
|
|
15441
14740
|
...seamed.seams,
|
|
15442
|
-
[sandboxCaptureOutputSeamKey]: (read) => {
|
|
15443
|
-
capturedOutput = read;
|
|
15444
|
-
},
|
|
15445
14741
|
[sandboxSeamKey]: {
|
|
15446
14742
|
sandboxClient,
|
|
15447
|
-
failOnDestroyError: providerSeam.workspaceRetention !== void 0,
|
|
15448
|
-
...providerSeam.workspaceRetention === void 0 ? {} : { workspaceCaptures: () => workspaceCaptures },
|
|
15449
14743
|
steering: providerSeam.steering,
|
|
15450
14744
|
...providerSeam.promptOptions === void 0 ? {} : { loopCtx: { promptOptions: providerSeam.promptOptions } }
|
|
15451
14745
|
}
|
|
@@ -15718,13 +15012,11 @@ const driverExecutorFactory = (rawSpec, ctx) => {
|
|
|
15718
15012
|
const unconfirmedDescendants = () => nestedScopeHeld === void 0 ? [] : unconfirmedTeardowns(nestedScopeHeld);
|
|
15719
15013
|
const closeActive = (reason) => {
|
|
15720
15014
|
if (active === void 0) return Promise.resolve();
|
|
15721
|
-
if (!active.
|
|
15722
|
-
|
|
15723
|
-
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
-
});
|
|
15727
|
-
}
|
|
15015
|
+
if (reason !== void 0 && !active.controller.signal.aborted) active.controller.abort(reason);
|
|
15016
|
+
if (!active.close) active.close = closeNestedScope(active.scope).then(() => void 0, (error) => {
|
|
15017
|
+
cleanupFailure = error;
|
|
15018
|
+
throw error;
|
|
15019
|
+
});
|
|
15728
15020
|
return active.close;
|
|
15729
15021
|
};
|
|
15730
15022
|
const rollUp = (events) => {
|
|
@@ -15760,9 +15052,11 @@ const driverExecutorFactory = (rawSpec, ctx) => {
|
|
|
15760
15052
|
const ownedSpawn = ownedTreeRootSpawn(parentSpawn);
|
|
15761
15053
|
previouslyMetered = recovering ? sumMetered((parentEvents ?? []).filter((event) => event.id === seam.nodeId)) : zeroSpend();
|
|
15762
15054
|
await journal.beginTree(nestedRoot, (/* @__PURE__ */ new Date(0)).toISOString());
|
|
15763
|
-
|
|
15764
|
-
if (prior.length === 0)
|
|
15765
|
-
|
|
15055
|
+
let prior = await journal.loadTree(nestedRoot) ?? [];
|
|
15056
|
+
if (prior.length === 0) {
|
|
15057
|
+
await journal.appendEvent(nestedRoot, ownedSpawn);
|
|
15058
|
+
prior = [ownedSpawn];
|
|
15059
|
+
} else if (contentAddress(prior[0]) !== contentAddress(ownedSpawn)) throw new ValidationError$1("driverExecutor: nested recovery changed its owning parent spawn");
|
|
15766
15060
|
else if (prior.length !== 1 && !recovering) throw new RetainedExecutionPendingError(new ValidationError$1("driverExecutor: interrupted nested execution requires recovery"), "nested-recovery");
|
|
15767
15061
|
if (recovering && (!spec.recoverExecutor || !seam.restore)) throw new RetainedExecutionPendingError(new ValidationError$1("driverExecutor: nested recovery has no original executor reconstruction"), "nested-recovery");
|
|
15768
15062
|
signal.throwIfAborted();
|
|
@@ -15797,8 +15091,7 @@ const driverExecutorFactory = (rawSpec, ctx) => {
|
|
|
15797
15091
|
}
|
|
15798
15092
|
const out = await runAbortable(() => driver.act(task, nestedScope), controller.signal, "driver aborted");
|
|
15799
15093
|
await finalizeScopeOwnerMaterialization(nestedScope);
|
|
15800
|
-
await closeActive(
|
|
15801
|
-
releaseManagerEnvironment(nestedScope).catch(() => void 0);
|
|
15094
|
+
await closeActive();
|
|
15802
15095
|
const events = await loadTreeEvents(journal, nestedRoot);
|
|
15803
15096
|
const childWork = rollUp(events);
|
|
15804
15097
|
const acceptedSubmission = spec.acceptedSubmission?.() === true;
|
|
@@ -15899,8 +15192,8 @@ function isTerminalAdmissionRefusal(error) {
|
|
|
15899
15192
|
const failure = error instanceof DriverAttemptsExhaustedError && error.stop === "terminal-error" ? error.cause : error;
|
|
15900
15193
|
return (isCredentialRefusal(failure) || failure instanceof RetainedExecutionPendingError && failure.phase === "admission" && failure.pendingCause === "request-rejected") && classifyDriverFailure(failure) === "terminal";
|
|
15901
15194
|
}
|
|
15902
|
-
async function closeNestedScope(scope
|
|
15903
|
-
|
|
15195
|
+
async function closeNestedScope(scope) {
|
|
15196
|
+
closeScopeAdmission(scope);
|
|
15904
15197
|
for (;;) if (await scope.next() === null) break;
|
|
15905
15198
|
await releaseHeldEnvironments(scope);
|
|
15906
15199
|
const view = scope.view;
|
|
@@ -15974,38 +15267,6 @@ function readNestedScopeSeam(ctx) {
|
|
|
15974
15267
|
function isAgent(value) {
|
|
15975
15268
|
return typeof value === "object" && value !== null && typeof value.act === "function" && typeof value.name === "string";
|
|
15976
15269
|
}
|
|
15977
|
-
/** Parent journals may already contain an interrupted driver's inference prefix. */
|
|
15978
|
-
function unreportedSpend(total, prior) {
|
|
15979
|
-
const tokens = { ...total.tokens };
|
|
15980
|
-
for (const key of [
|
|
15981
|
-
"input",
|
|
15982
|
-
"output",
|
|
15983
|
-
"freshInput",
|
|
15984
|
-
"cacheRead",
|
|
15985
|
-
"cacheWrite"
|
|
15986
|
-
]) {
|
|
15987
|
-
const value = total.tokens[key];
|
|
15988
|
-
if (value !== void 0) tokens[key] = Math.max(0, value - (prior.tokens[key] ?? 0));
|
|
15989
|
-
}
|
|
15990
|
-
return {
|
|
15991
|
-
...total,
|
|
15992
|
-
...addResourceSpend(total.resources === void 0 ? void 0 : Object.fromEntries(Object.entries(total.resources).map(([name, value]) => {
|
|
15993
|
-
const previous = prior.resources?.[name];
|
|
15994
|
-
if (previous && previous.unit !== value.unit) throw new ValidationError$1(`resource ${name}: unit mismatch`);
|
|
15995
|
-
return [name, {
|
|
15996
|
-
...value,
|
|
15997
|
-
amount: Math.max(0, value.amount - (previous?.amount ?? 0)),
|
|
15998
|
-
known: value.known && (previous?.known ?? true)
|
|
15999
|
-
}];
|
|
16000
|
-
}))),
|
|
16001
|
-
iterations: Math.max(0, total.iterations - prior.iterations),
|
|
16002
|
-
tokens,
|
|
16003
|
-
usd: Math.max(0, total.usd - prior.usd),
|
|
16004
|
-
ms: Math.max(0, total.ms - prior.ms),
|
|
16005
|
-
...total.usdEstimated === void 0 ? {} : { usdEstimated: Math.max(0, total.usdEstimated - (prior.usdEstimated ?? 0)) },
|
|
16006
|
-
...total.boxMinutes === void 0 ? {} : { boxMinutes: Math.max(0, total.boxMinutes - (prior.boxMinutes ?? 0)) }
|
|
16007
|
-
};
|
|
16008
|
-
}
|
|
16009
15270
|
// src/runtime/supervise/supervisor-root-handle.ts
|
|
16010
15271
|
/** Module-private channel from a minted `RootHandle` to its `RootControl`, so `attach`
|
|
16011
15272
|
* can prove a handle is ours and reach its binding without leaking the control onto the
|
|
@@ -16844,8 +16105,8 @@ function allSpawnedChildrenDown(tree) {
|
|
|
16844
16105
|
}
|
|
16845
16106
|
function poolExhausted(pool, opts) {
|
|
16846
16107
|
const r = pool.readout();
|
|
16847
|
-
if (r.iterationsLeft <= 0) return true;
|
|
16848
|
-
if (r.tokensLeft <= 0) return true;
|
|
16108
|
+
if (r.iterationsCapped !== false && r.iterationsLeft <= 0) return true;
|
|
16109
|
+
if (r.tokensCapped !== false && r.tokensLeft <= 0) return true;
|
|
16849
16110
|
return opts.budget.maxUsd !== void 0 && r.usdLeft <= 0;
|
|
16850
16111
|
}
|
|
16851
16112
|
function deadlinePassed(pool, opts) {
|
|
@@ -17059,7 +16320,7 @@ function guardRunPersistence(journal, blobs, interrupt) {
|
|
|
17059
16320
|
/** Read every caller-owned field once, then detach and freeze all decision data before the first
|
|
17060
16321
|
* await; stateful collaborators stay live by reference, but later opts mutation cannot redirect the run. */
|
|
17061
16322
|
function admitSupervisorRun(task, opts) {
|
|
17062
|
-
const { budget, rootIdentity, rootSegment, rootMaterialization, runId, journal: journalStore, blobs: blobStore, executors: executorRegistry, recoverExecutor, maxDepth, workerSlots, reservationPolicy, deadlineCheckIn, budgetStopHoldMs, maxRestarts, withinMs, childSettleGraceMs, teardownConfirmMs, resume, retainedAtSettlement: requestedRetainedAtSettlement,
|
|
16323
|
+
const { budget, rootIdentity, rootSegment, rootMaterialization, runId, journal: journalStore, blobs: blobStore, executors: executorRegistry, recoverExecutor, maxDepth, workerSlots, reservationPolicy, deadlineCheckIn, budgetStopHoldMs, maxRestarts, withinMs, childSettleGraceMs, teardownConfirmMs, resume, retainedAtSettlement: requestedRetainedAtSettlement, now: suppliedNow, signal, hooks, workerTrace, workerTraceUnpropagated, interactiveBindingDir } = opts;
|
|
17063
16324
|
const input = detachedSnapshot({
|
|
17064
16325
|
task,
|
|
17065
16326
|
options: {
|
|
@@ -17077,7 +16338,6 @@ function admitSupervisorRun(task, opts) {
|
|
|
17077
16338
|
...teardownConfirmMs === void 0 ? {} : { teardownConfirmMs },
|
|
17078
16339
|
...resume === void 0 ? {} : { resume },
|
|
17079
16340
|
...requestedRetainedAtSettlement === void 0 ? {} : { retainedAtSettlement: requestedRetainedAtSettlement },
|
|
17080
|
-
...ownerWorkspaceRetention === void 0 ? {} : { ownerWorkspaceRetention },
|
|
17081
16341
|
...interactiveBindingDir === void 0 ? {} : { interactiveBindingDir }
|
|
17082
16342
|
}
|
|
17083
16343
|
}, "supervisor.run");
|
|
@@ -17108,7 +16368,6 @@ function admitSupervisorRun(task, opts) {
|
|
|
17108
16368
|
slots,
|
|
17109
16369
|
controller,
|
|
17110
16370
|
persistence,
|
|
17111
|
-
ownerWorkspaceRetention,
|
|
17112
16371
|
deadlineCheckIn,
|
|
17113
16372
|
budgetStopHoldMs
|
|
17114
16373
|
};
|
|
@@ -17126,10 +16385,11 @@ async function joinRunChildren(join, settleGraceMs) {
|
|
|
17126
16385
|
await releaseHeldEnvironments(scope);
|
|
17127
16386
|
join.teardownUnconfirmed = unconfirmedTeardowns(scope);
|
|
17128
16387
|
await settleManagerWork(scope);
|
|
16388
|
+
join.teardownUnconfirmed = unconfirmedTeardowns(scope);
|
|
17129
16389
|
if (!persistence.failed && join.retainedAtSettlement === "release") join.teardownUnconfirmed = await releaseRetainedEnvironments(scope);
|
|
17130
16390
|
const releasing = !persistence.failed && join.retainedAtSettlement === "release";
|
|
17131
16391
|
await confirmRetriableTeardowns(join, releasing);
|
|
17132
|
-
join.teardownUnconfirmed =
|
|
16392
|
+
join.teardownUnconfirmed = await unrecoveredRetainedChildren(join);
|
|
17133
16393
|
for (const node of join.teardownUnconfirmed) await join.opts.journal.appendEvent(join.opts.runId, {
|
|
17134
16394
|
kind: "teardown-unconfirmed",
|
|
17135
16395
|
...unconfirmedRecord(node),
|
|
@@ -17138,36 +16398,9 @@ async function joinRunChildren(join, settleGraceMs) {
|
|
|
17138
16398
|
});
|
|
17139
16399
|
if (releasing) await closeRetainedSlots(scope);
|
|
17140
16400
|
}
|
|
17141
|
-
/**
|
|
17142
|
-
|
|
17143
|
-
|
|
17144
|
-
* left 2 workers running. Ask again until confirmed or out of time.
|
|
17145
|
-
*/
|
|
17146
|
-
async function confirmRetriableTeardowns(join, releasing) {
|
|
17147
|
-
const { opts, scope } = join;
|
|
17148
|
-
const confirmWindowMs = opts.teardownConfirmMs ?? 3e5;
|
|
17149
|
-
if (!(join.teardownUnconfirmed.length > 0 && confirmWindowMs > 0 && hasRetriableTeardowns(scope, releasing))) return;
|
|
17150
|
-
const pending = join.teardownUnconfirmed;
|
|
17151
|
-
for (const node of pending) await opts.journal.appendEvent(opts.runId, {
|
|
17152
|
-
kind: "teardown-pending",
|
|
17153
|
-
...unconfirmedRecord(node),
|
|
17154
|
-
seq: join.teardownSeq++,
|
|
17155
|
-
at: new Date(join.now()).toISOString()
|
|
17156
|
-
});
|
|
17157
|
-
join.teardownUnconfirmed = await confirmSettledTeardowns(scope, confirmWindowMs, releasing);
|
|
17158
|
-
const still = new Set(join.teardownUnconfirmed.map((node) => node.id));
|
|
17159
|
-
for (const node of pending) {
|
|
17160
|
-
if (still.has(node.id)) continue;
|
|
17161
|
-
await opts.journal.appendEvent(opts.runId, {
|
|
17162
|
-
kind: "teardown-confirmed",
|
|
17163
|
-
id: node.id,
|
|
17164
|
-
seq: join.teardownSeq++,
|
|
17165
|
-
at: new Date(join.now()).toISOString()
|
|
17166
|
-
});
|
|
17167
|
-
}
|
|
17168
|
-
}
|
|
17169
|
-
/** Retained children a resume restored from the journal but never adopted into the live scope. */
|
|
17170
|
-
function unrecoveredRetainedChildren(scope, resumeFrom) {
|
|
16401
|
+
/** Retained custody absent from the live scope, including a cold cancellation without ports. */
|
|
16402
|
+
async function unrecoveredRetainedChildren(join) {
|
|
16403
|
+
const { scope, resumeFrom } = join;
|
|
17171
16404
|
const adopted = new Set(scope.view.nodes.map((node) => node.id));
|
|
17172
16405
|
const unrecovered = [];
|
|
17173
16406
|
for (const recovery of resumeFrom?.recoveries ?? []) {
|
|
@@ -17193,7 +16426,107 @@ function unrecoveredRetainedChildren(scope, resumeFrom) {
|
|
|
17193
16426
|
detail: "Retained child was not recovered before settlement; source evidence and teardown remain unverified."
|
|
17194
16427
|
});
|
|
17195
16428
|
}
|
|
17196
|
-
|
|
16429
|
+
const unconfirmed = new Map([...join.teardownUnconfirmed, ...unrecovered].map((node) => [node.id, node]));
|
|
16430
|
+
if (resumeFrom === void 0 || !(join.opts.signal?.reason instanceof RunCancellationReason)) return [...unconfirmed.values()];
|
|
16431
|
+
const forest = await loadSpawnForest(join.opts.journal, join.opts.runId);
|
|
16432
|
+
const nestedOwners = new Set(forest.nodes.filter((node) => node.ownedTreeRoot !== void 0).map((node) => node.id));
|
|
16433
|
+
const destroyed = /* @__PURE__ */ new Map();
|
|
16434
|
+
const confirmed = /* @__PURE__ */ new Map();
|
|
16435
|
+
const refs = /* @__PURE__ */ new Map();
|
|
16436
|
+
const pending = /* @__PURE__ */ new Map();
|
|
16437
|
+
const keyOf = (provider, environmentId) => JSON.stringify([provider, environmentId]);
|
|
16438
|
+
const later = (proof, admission) => proof.tree === admission.tree ? proof.index > admission.index : Number.isFinite(proof.at) && Number.isFinite(admission.at) && proof.at > admission.at;
|
|
16439
|
+
for (const [index, { treeRoot, event }] of forest.events.entries()) {
|
|
16440
|
+
const position = {
|
|
16441
|
+
tree: treeRoot,
|
|
16442
|
+
index,
|
|
16443
|
+
at: Date.parse(event.at)
|
|
16444
|
+
};
|
|
16445
|
+
const invocation = JSON.stringify([treeRoot, event.id]);
|
|
16446
|
+
if (event.kind === "environment-teardown" && event.destroyed) {
|
|
16447
|
+
const key = keyOf(event.provider, event.environmentId);
|
|
16448
|
+
destroyed.set(key, [...destroyed.get(key) ?? [], position]);
|
|
16449
|
+
}
|
|
16450
|
+
if (event.kind === "teardown-confirmed") confirmed.set(event.id, [...confirmed.get(event.id) ?? [], position]);
|
|
16451
|
+
if (event.kind === "execution-input" || event.kind === "execution-result" || event.kind === "execution-abandoned") pending.delete(invocation);
|
|
16452
|
+
if (event.kind !== "execution-admitted") continue;
|
|
16453
|
+
const admission = event.admission;
|
|
16454
|
+
const environment = admission.phase === "environment" ? admission : admission.phase === "dispatched" ? admission.controlRef : void 0;
|
|
16455
|
+
if (environment === void 0) {
|
|
16456
|
+
pending.set(invocation, {
|
|
16457
|
+
id: event.id,
|
|
16458
|
+
position
|
|
16459
|
+
});
|
|
16460
|
+
continue;
|
|
16461
|
+
}
|
|
16462
|
+
pending.delete(invocation);
|
|
16463
|
+
const held = refs.get(event.id) ?? /* @__PURE__ */ new Map();
|
|
16464
|
+
const key = keyOf(environment.provider, environment.environmentId);
|
|
16465
|
+
const custody = held.get(key) ?? {
|
|
16466
|
+
ref: {
|
|
16467
|
+
provider: environment.provider,
|
|
16468
|
+
environmentId: environment.environmentId,
|
|
16469
|
+
keptFor: "evidence"
|
|
16470
|
+
},
|
|
16471
|
+
admissions: /* @__PURE__ */ new Map()
|
|
16472
|
+
};
|
|
16473
|
+
custody.admissions.set(treeRoot, position);
|
|
16474
|
+
held.set(key, custody);
|
|
16475
|
+
refs.set(event.id, held);
|
|
16476
|
+
}
|
|
16477
|
+
const discharged = (id, key, custody) => [...custody.admissions.values()].every((admission) => [...destroyed.get(key) ?? [], ...nestedOwners.has(id) ? [] : confirmed.get(id) ?? []].some((proof) => later(proof, admission)));
|
|
16478
|
+
const unknown = new Set([...pending.values()].filter(({ id, position }) => !(confirmed.get(id) ?? []).some((proof) => later(proof, position))).map(({ id }) => id));
|
|
16479
|
+
for (const [id, node] of unconfirmed) {
|
|
16480
|
+
if (node.attempts !== 0 || node.environments?.length || !node.kept?.length || unknown.has(id)) continue;
|
|
16481
|
+
if (node.kept.every((ref) => {
|
|
16482
|
+
const key = keyOf(ref.provider, ref.environmentId);
|
|
16483
|
+
const custody = refs.get(id)?.get(key);
|
|
16484
|
+
return custody !== void 0 && discharged(id, key, custody);
|
|
16485
|
+
})) unconfirmed.delete(id);
|
|
16486
|
+
}
|
|
16487
|
+
for (const node of forest.nodes) {
|
|
16488
|
+
const kept = [...refs.get(node.id) ?? []].filter(([key, custody]) => !discharged(node.id, key, custody)).map(([, custody]) => custody.ref);
|
|
16489
|
+
if (kept.length === 0 && !unknown.has(node.id)) continue;
|
|
16490
|
+
const prior = unconfirmed.get(node.id);
|
|
16491
|
+
const covered = new Set([...prior?.kept ?? [], ...prior?.environments ?? []].map((ref) => keyOf(ref.provider, ref.environmentId)));
|
|
16492
|
+
const missing = kept.filter((ref) => !covered.has(keyOf(ref.provider, ref.environmentId)));
|
|
16493
|
+
if (prior !== void 0 && missing.length === 0) continue;
|
|
16494
|
+
unconfirmed.set(node.id, {
|
|
16495
|
+
...prior ?? {
|
|
16496
|
+
id: node.id,
|
|
16497
|
+
label: node.label,
|
|
16498
|
+
runtime: node.runtime,
|
|
16499
|
+
status: node.status,
|
|
16500
|
+
attempts: 0
|
|
16501
|
+
},
|
|
16502
|
+
...(prior?.kept?.length ?? 0) + missing.length > 0 ? { kept: [...prior?.kept ?? [], ...missing] } : {},
|
|
16503
|
+
detail: prior?.detail ?? "Prior admitted execution has no confirmed teardown; source custody remains unverified."
|
|
16504
|
+
});
|
|
16505
|
+
}
|
|
16506
|
+
return [...unconfirmed.values()];
|
|
16507
|
+
}
|
|
16508
|
+
/**
|
|
16509
|
+
* A first teardown that failed or answered late is not the provider's last word, and a run that
|
|
16510
|
+
* settles over it leaves the sandbox running: cancelling 20 Discovery lanes
|
|
16511
|
+
* left 2 workers running. Ask again until confirmed or out of time.
|
|
16512
|
+
*/
|
|
16513
|
+
async function confirmRetriableTeardowns(join, releasing) {
|
|
16514
|
+
const { opts, scope } = join;
|
|
16515
|
+
const confirmWindowMs = opts.teardownConfirmMs ?? 3e5;
|
|
16516
|
+
if (!(join.teardownUnconfirmed.length > 0 && confirmWindowMs > 0 && hasRetriableTeardowns(scope, releasing))) return;
|
|
16517
|
+
const pending = join.teardownUnconfirmed;
|
|
16518
|
+
for (const node of pending) await opts.journal.appendEvent(opts.runId, {
|
|
16519
|
+
kind: "teardown-pending",
|
|
16520
|
+
...unconfirmedRecord(node),
|
|
16521
|
+
seq: join.teardownSeq++,
|
|
16522
|
+
at: new Date(join.now()).toISOString()
|
|
16523
|
+
});
|
|
16524
|
+
join.teardownUnconfirmed = await confirmSettledTeardowns(scope, confirmWindowMs, releasing);
|
|
16525
|
+
const still = new Set(join.teardownUnconfirmed.map((node) => node.id));
|
|
16526
|
+
for (const node of pending) {
|
|
16527
|
+
if (still.has(node.id)) continue;
|
|
16528
|
+
await appendTeardownConfirmation(opts.journal, opts.runId, node.id, new Date(join.now()).toISOString());
|
|
16529
|
+
}
|
|
17197
16530
|
}
|
|
17198
16531
|
// src/runtime/supervise/supervisor-run-tree.ts
|
|
17199
16532
|
async function openRunTree(opts, now) {
|
|
@@ -17294,6 +16627,8 @@ function createSupervisor() {
|
|
|
17294
16627
|
const journal = wrapJournalForBreaker(opts.journal, breaker);
|
|
17295
16628
|
const scope = createRootScope(intake, opened, journal, now);
|
|
17296
16629
|
const openScope = scope;
|
|
16630
|
+
const ownerControl = runtimeOwnedScopeOwnerControl(root);
|
|
16631
|
+
if (ownerControl !== void 0) bindScopeRetainedOwnerProvider(openScope, ownerControl.provider);
|
|
17297
16632
|
if (rootLease) rootLease.bind({
|
|
17298
16633
|
scope: openScope,
|
|
17299
16634
|
cascadeAbort: (reason) => cascade.abort(new RunCancellationReason("root-handle", reason ?? "root handle aborted")),
|
|
@@ -17375,7 +16710,7 @@ function createRootScope(intake, opened, journal, now) {
|
|
|
17375
16710
|
journal,
|
|
17376
16711
|
blobs: opts.blobs,
|
|
17377
16712
|
executors: opts.executors,
|
|
17378
|
-
seams: {
|
|
16713
|
+
seams: {},
|
|
17379
16714
|
depth: 0,
|
|
17380
16715
|
maxDepth: opts.maxDepth ?? 16,
|
|
17381
16716
|
workerSlots: intake.slots,
|
|
@@ -17449,11 +16784,15 @@ async function executeRoot(root) {
|
|
|
17449
16784
|
let executionAborted = controller.signal.aborted;
|
|
17450
16785
|
let allChildrenDownAtSettle = false;
|
|
17451
16786
|
let parked = false;
|
|
16787
|
+
let rootStarted = false;
|
|
17452
16788
|
try {
|
|
17453
16789
|
await startScopeRecoveries(scope);
|
|
17454
16790
|
actOutcome = {
|
|
17455
16791
|
ok: true,
|
|
17456
|
-
out: await runAbortable(
|
|
16792
|
+
out: await runAbortable(() => {
|
|
16793
|
+
rootStarted = true;
|
|
16794
|
+
return root.run();
|
|
16795
|
+
}, controller.signal, "supervisor aborted")
|
|
17457
16796
|
};
|
|
17458
16797
|
} catch (error) {
|
|
17459
16798
|
if (error instanceof RunParkedError && error.runId === opts.runId) {
|
|
@@ -17480,7 +16819,7 @@ async function executeRoot(root) {
|
|
|
17480
16819
|
error
|
|
17481
16820
|
};
|
|
17482
16821
|
}
|
|
17483
|
-
if (!persistence.failed) try {
|
|
16822
|
+
if (rootStarted && !persistence.failed) try {
|
|
17484
16823
|
await finalizeScopeOwnerMaterialization(scope);
|
|
17485
16824
|
} catch (error) {
|
|
17486
16825
|
if (actOutcome?.ok !== false) actOutcome = {
|
|
@@ -17585,4 +16924,4 @@ async function noWinner(settled, rejection) {
|
|
|
17585
16924
|
}
|
|
17586
16925
|
export { DEFAULT_PEER_MAIL_LIMITS as $, promptModelProfileMaterialization as $t, createSandboxForSpec as A, bridgeModelRouteRefusal as At, createRouterTranscript as B, defaultRunCommand as Bt, createExecutor as C, admitContinuationPolicy as Ct, runAgentRounds as D, failedItems as Dt, createSteerableSandboxSession as E, createContinuationKeeper as Et, codeModeArguments as F, harnessUsageIsEmpty as Ft, LEAF_CONTINUATION_TASK as G, terminateProcessTreeAndConfirm as Gt, createAgentEnvironmentProviderRegistry as H, runWorktreeHarness as Ht, codeModeModelOutput as I, readCodexRolloutSession as It, createInPlaceCliExecutor as J, controlProfileMaterialization as Jt, providerAsSandboxClient as K, assertProfileMaterialization as Kt, createCodeModeTools as L, createPushTraceSource as Lt, acquireSandbox as M, ROUTER_PRICE_SOURCE as Mt, TERMINAL_DECISIONS as N, addHarnessUsage as Nt, assertBoxlessPromptOptions as O, isFiniteNumber as Ot, defaultSelectWinner as P, createCodexRolloutStoreReader as Pt, AUTHORITY_MARKERS as Q, promptControlProfileMaterialization as Qt, runCodeMode as R, bridgeRuntimeAttachmentsKey as Rt, captureReusableExecutorConfig as S, CONTINUATIONS_DIR as St, DEFAULT_SANDBOX_STEERING_MAX_TURNS as T, checkVerdictOf as Tt, resolveAgentEnvironmentProvider as U, LOCAL_HARNESSES as Ut, routerBrain as V, runSettledCommand as Vt, providerAsExecutor as W, harnessInvocation as Wt, createInbox as X, fullProfileMaterialization as Xt, INBOX_RECEIPT_KEY as Y, defineProfileMaterializationContract as Yt, failPendingAfter as Z, profileMaterializationAxes$1 as Zt, withDriverExecutor as _, CheckUnavailableError as _t, assertRunParking as a, projectSandboxOutcome as an, peerMailVerbNames as at, createExecutorRegistry as b, mapExecutorResult as bt, sleepScopeWait as c, HarnessTurnFailedError as ct, runFinalizer as d, isContentFilterRefusal as dt, renderUnsupported as en, PEER_MAIL_WIRE_KEY as et, runTree as f, summarizeDriverAttempts as ft, isDriverSpec as g, preflightPublicCoordination as gt, driverExecutorFactory as h, upstreamUnavailableSignal as ht, RunParkedError as i, worktreeCliProfileMaterialization as in, peerMailTools as it, createSandboxLineage as j, priceTokens as jt, readPromptOptions as k, bridgeAdmissionRefusal as kt, withRunParking as l, abandonablePending as lt, driverChild as m, undispatchedCredentialExit as mt, createSupervisor as n, sandboxProfileMaterialization as nn, createPeerMailbox as nt, bindScopeParkingDrain as o, readSandboxOutcome as on, taskToPrompt$1 as ot, createRootHandle as p, transientFailureKind as pt, createWorktreeCliExecutor as q, assertProfileMaterializes as qt, assertResumeLimits as r, unsupportedProfileDimensions as rn, isPeerMailEnvelope as rt, readRunParking as s, DriverAttemptsExhaustedError as st, DEFAULT_MAX_DEPTH as t, sandboxActProfileMaterialization as tn, claimsAuthority as tt, bestDelivered as u, classifyDriverFailure as ut, InMemoryResultBlobStore as v, gateFactoryOnDeliverable as vt, snapshotExecutorConfig as w, bestComposite as wt, bindReusableExecutorExecutionId as x, verdictFromJudgeScore as xt, InMemorySpawnJournal as y, gateOnDeliverable as yt, toolResultText as z, bridgeStopSignalKey as zt };
|
|
17587
16926
|
|
|
17588
|
-
//# sourceMappingURL=supervisor-
|
|
16927
|
+
//# sourceMappingURL=supervisor-B6sl14OR.js.map
|