@tangle-network/agent-runtime 5.0.0 → 6.0.2
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 +20 -0
- package/dist/{activation-DGLWxFJu.js → activation-BRfZOfwb.js} +4 -4
- package/dist/{activation-DGLWxFJu.js.map → activation-BRfZOfwb.js.map} +1 -1
- package/dist/{activation-CtLdCiH3.d.ts → activation-DEKw9CDD.d.ts} +2 -2
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -3
- 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 +70 -3
- package/dist/candidate-execution/index.js +4 -4
- package/dist/{coordination-manager-D74AZg7m.js → coordination-manager-RSJg5GmY.js} +10 -9
- package/dist/coordination-manager-RSJg5GmY.js.map +1 -0
- package/dist/coordination-map-routing-DVjW5Gx0.js.map +1 -1
- package/dist/{delegate-BVyFJ9AX.js → delegate-C0cprMUN.js} +2 -2
- package/dist/{delegate-BVyFJ9AX.js.map → delegate-C0cprMUN.js.map} +1 -1
- package/dist/durable.d.ts +2 -2
- package/dist/durable.js +9 -9
- package/dist/{graph-r8zcRxbi.js → graph-cEg-gquv.js} +5 -5
- package/dist/{graph-r8zcRxbi.js.map → graph-cEg-gquv.js.map} +1 -1
- package/dist/{improve-D12GulmK.js → improve-DNl4_6lP.js} +7 -7
- package/dist/{improve-D12GulmK.js.map → improve-DNl4_6lP.js.map} +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +10 -10
- package/dist/intelligence.d.ts +4 -4
- package/dist/intelligence.js +7 -7
- package/dist/kernel.d.ts +3 -3
- package/dist/kernel.js +12 -12
- package/dist/{loop-runner-BHBabRIw.d.ts → loop-runner-CDad0CCY.d.ts} +2 -2
- package/dist/{loop-runner-CYcN11I4.js → loop-runner-DQJjowz0.js} +2 -2
- package/dist/{loop-runner-CYcN11I4.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-BiqHJ-d4.js → provision-supervisor-CtAaJCUa.js} +5 -5
- package/dist/{provision-supervisor-BiqHJ-d4.js.map → provision-supervisor-CtAaJCUa.js.map} +1 -1
- package/dist/{run-cancellation-D5R-7UQt.js → run-cancellation-BCuu6khW.js} +2 -2
- package/dist/{run-cancellation-D5R-7UQt.js.map → run-cancellation-BCuu6khW.js.map} +1 -1
- package/dist/{run-state-DRh8BOFi.js → run-state-ByHiAjUs.js} +6 -5
- package/dist/{run-state-DRh8BOFi.js.map → run-state-ByHiAjUs.js.map} +1 -1
- package/dist/{runtime-BX_9-DJB.js → runtime-9EYvBcHG.js} +13 -13
- package/dist/{runtime-BX_9-DJB.js.map → runtime-9EYvBcHG.js.map} +1 -1
- 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-JcCkUy_z.js → scope-DzhBJrRN.js} +3510 -3451
- package/dist/scope-DzhBJrRN.js.map +1 -0
- package/dist/{search-executor-CdmaS5r4.js → search-executor-BJRNavck.js} +4 -4
- package/dist/{search-executor-CdmaS5r4.js.map → search-executor-BJRNavck.js.map} +1 -1
- package/dist/{server-BY6OluUf.js → server-DH0P6OY_.js} +4 -4
- package/dist/{server-BY6OluUf.js.map → server-DH0P6OY_.js.map} +1 -1
- package/dist/{structural-rollout-BjMUUXLn.js → structural-rollout-DgvJLTO0.js} +4 -4
- package/dist/{structural-rollout-BjMUUXLn.js.map → structural-rollout-DgvJLTO0.js.map} +1 -1
- package/dist/{supervise-rYEsVVcn.js → supervise-Cqhkb2Oj.js} +244 -80
- package/dist/supervise-Cqhkb2Oj.js.map +1 -0
- package/dist/{supervision-discovery-D95Ack4J.js → supervision-discovery-DI5GIFBJ.js} +3 -3
- package/dist/{supervision-discovery-D95Ack4J.js.map → supervision-discovery-DI5GIFBJ.js.map} +1 -1
- package/dist/{supervisor-B-bX69uL.js → supervisor-B6sl14OR.js} +243 -962
- 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-D-wH9ipn.js → top-web-DGoXGxH8.js} +4 -4
- package/dist/{top-web-D-wH9ipn.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-DblV14Oe.d.ts → types-niKnm6ux.d.ts} +86 -242
- 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 +5 -5
- package/dist/coordination-manager-D74AZg7m.js.map +0 -1
- package/dist/scope-JcCkUy_z.js.map +0 -1
- package/dist/supervise-rYEsVVcn.js.map +0 -1
- package/dist/supervisor-B-bX69uL.js.map +0 -1
- package/dist/workspace-streams-8ALHaZzx.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
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
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";
|
|
@@ -6184,6 +6184,11 @@ function* chunkProgress(chunk, ledger, args) {
|
|
|
6184
6184
|
progress: {
|
|
6185
6185
|
kind: "tool_result",
|
|
6186
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
|
+
} } : {},
|
|
6187
6192
|
...result.id === void 0 ? {} : { toolCallId: result.id },
|
|
6188
6193
|
result: result.status === "completed" ? result.output : { error: result.error }
|
|
6189
6194
|
}
|
|
@@ -7615,7 +7620,6 @@ function executionTaskPrompt$1(task, configuredPrompt) {
|
|
|
7615
7620
|
return prompt;
|
|
7616
7621
|
}
|
|
7617
7622
|
// src/runtime/supervise/runtime-seams.ts
|
|
7618
|
-
const sandboxCaptureOutputSeamKey = "runtime.sandboxCaptureOutput";
|
|
7619
7623
|
const routerSeamKey = "router";
|
|
7620
7624
|
const sandboxSeamKey = "sandbox";
|
|
7621
7625
|
const cliWorktreeSeamKey = "cli-worktree";
|
|
@@ -7962,374 +7966,6 @@ function publicCreateOptions(create) {
|
|
|
7962
7966
|
...secrets === void 0 ? {} : { secretNames: Array.isArray(secrets) ? [...secrets].sort() : Object.keys(secrets).sort() }
|
|
7963
7967
|
};
|
|
7964
7968
|
}
|
|
7965
|
-
// src/runtime/environment-provider/provider-retention-lifecycle.ts
|
|
7966
|
-
function createProviderCaptureMirrors(options, createProfile, node, state) {
|
|
7967
|
-
const nativePort = options.workspaceRetention?.captureNative === void 0 ? void 0 : options.workspaceRetention;
|
|
7968
|
-
let nativeInFlight;
|
|
7969
|
-
let nativeRunningInFlight;
|
|
7970
|
-
let nativeRunningStop;
|
|
7971
|
-
let nativeTimer;
|
|
7972
|
-
let nativeEvents = 0;
|
|
7973
|
-
let nativeEventsAtCopy;
|
|
7974
|
-
let lastNativeCopyMs = 0;
|
|
7975
|
-
let closeNativeMirror;
|
|
7976
|
-
const livePort = options.workspaceRetention?.captureLive === void 0 ? void 0 : options.workspaceRetention;
|
|
7977
|
-
let liveInFlight;
|
|
7978
|
-
let liveTimer;
|
|
7979
|
-
let liveStop;
|
|
7980
|
-
const stopLiveMirror = () => {
|
|
7981
|
-
if (liveTimer !== void 0) clearTimeout(liveTimer);
|
|
7982
|
-
liveTimer = void 0;
|
|
7983
|
-
liveStop?.abort(/* @__PURE__ */ new Error("live workspace capture stopped: its turn ended"));
|
|
7984
|
-
liveStop = void 0;
|
|
7985
|
-
};
|
|
7986
|
-
const startLiveMirror = (next) => {
|
|
7987
|
-
if (livePort?.liveIntervalMs === void 0) return;
|
|
7988
|
-
stopLiveMirror();
|
|
7989
|
-
const stop = new AbortController();
|
|
7990
|
-
liveStop = stop;
|
|
7991
|
-
const schedule = () => {
|
|
7992
|
-
liveTimer = setTimeout(() => {
|
|
7993
|
-
if (liveInFlight === void 0 && state.workspaceCapturePromise === void 0) {
|
|
7994
|
-
const tracked = captureProviderLiveWorkspace(livePort, {
|
|
7995
|
-
environment: next,
|
|
7996
|
-
executionId: state.workspaceExecutionId,
|
|
7997
|
-
...state.workspaceControlRef === void 0 ? {} : { controlRef: state.workspaceControlRef },
|
|
7998
|
-
...node === void 0 ? {} : { node },
|
|
7999
|
-
providerSessionId: state.providerSessionId,
|
|
8000
|
-
nativeSessionId: null,
|
|
8001
|
-
profile: createProfile
|
|
8002
|
-
}, stop.signal).then(() => void 0, () => void 0).finally(() => {
|
|
8003
|
-
if (liveInFlight === tracked) liveInFlight = void 0;
|
|
8004
|
-
});
|
|
8005
|
-
liveInFlight = tracked;
|
|
8006
|
-
}
|
|
8007
|
-
schedule();
|
|
8008
|
-
}, livePort.liveIntervalMs);
|
|
8009
|
-
liveTimer.unref?.();
|
|
8010
|
-
};
|
|
8011
|
-
schedule();
|
|
8012
|
-
};
|
|
8013
|
-
let nativeHoldsTranscript = false;
|
|
8014
|
-
const noteCaptureFailure = (error) => {
|
|
8015
|
-
if (nativeHoldsTranscript || state.harnessTranscript.status !== "unavailable") return;
|
|
8016
|
-
if (state.harnessTranscript.reason !== "capture-did-not-run" && state.harnessTranscript.reason !== "enumeration-failed") return;
|
|
8017
|
-
state.harnessTranscript = {
|
|
8018
|
-
status: "unavailable",
|
|
8019
|
-
reason: "enumeration-failed",
|
|
8020
|
-
skipped: [{
|
|
8021
|
-
path: state.workspaceExecutionId,
|
|
8022
|
-
reason: errorText(error instanceof Error ? error.message : error)
|
|
8023
|
-
}]
|
|
8024
|
-
};
|
|
8025
|
-
};
|
|
8026
|
-
const stopNativeMirror = async () => {
|
|
8027
|
-
if (nativeTimer !== void 0) clearTimeout(nativeTimer);
|
|
8028
|
-
nativeTimer = void 0;
|
|
8029
|
-
closeNativeMirror?.();
|
|
8030
|
-
closeNativeMirror = void 0;
|
|
8031
|
-
nativeRunningStop?.abort(/* @__PURE__ */ new Error("native session copy stopped: its turn ended"));
|
|
8032
|
-
nativeRunningStop = void 0;
|
|
8033
|
-
await nativeInFlight;
|
|
8034
|
-
};
|
|
8035
|
-
const captureNative = (next, phase, admitted, afterStop = false) => {
|
|
8036
|
-
if (nativePort === void 0 || createProfile.harness === void 0) return Promise.resolve();
|
|
8037
|
-
const harness = createProfile.harness;
|
|
8038
|
-
const stop = phase === "running" ? new AbortController() : void 0;
|
|
8039
|
-
if (stop !== void 0) nativeRunningStop = stop;
|
|
8040
|
-
const tracked = (nativeInFlight ?? Promise.resolve()).then(async () => {
|
|
8041
|
-
stop?.signal.throwIfAborted();
|
|
8042
|
-
const controlRef = state.workspaceControlRef ?? admitted;
|
|
8043
|
-
const sessionId = state.providerSessionId ?? admitted?.sessionId ?? null;
|
|
8044
|
-
if (state.workspaceSnapshot !== void 0 && !nativeHoldsTranscript) return;
|
|
8045
|
-
const invocationId = state.workspaceExecutionId;
|
|
8046
|
-
const eventsAtStart = nativeEvents;
|
|
8047
|
-
const copyStartedAt = Date.now();
|
|
8048
|
-
try {
|
|
8049
|
-
const takeCopy = () => captureProviderWorkspaceSnapshot(nativePort, {
|
|
8050
|
-
environment: next,
|
|
8051
|
-
executionId: invocationId,
|
|
8052
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
8053
|
-
...node === void 0 ? {} : { node },
|
|
8054
|
-
providerSessionId: sessionId,
|
|
8055
|
-
nativeSessionId: null,
|
|
8056
|
-
profile: createProfile,
|
|
8057
|
-
phase
|
|
8058
|
-
}, "native", void 0, stop?.signal);
|
|
8059
|
-
let captured = await takeCopy();
|
|
8060
|
-
const settleBy = Date.now() + NATIVE_SETTLE_WINDOW_MS;
|
|
8061
|
-
while (afterStop && captured.coverageComplete !== true && (captured.provenance.attempts ?? []).some((attempt) => attempt.outcome === "unknown") && Date.now() < settleBy) {
|
|
8062
|
-
await sleep(NATIVE_SETTLE_POLL_MS);
|
|
8063
|
-
captured = await takeCopy();
|
|
8064
|
-
}
|
|
8065
|
-
if (state.workspaceSnapshot !== void 0 && !nativeHoldsTranscript) return;
|
|
8066
|
-
const copy = retainHarnessTranscript(providerWorkspaceCaptureReceipt({
|
|
8067
|
-
executionId: invocationId,
|
|
8068
|
-
profile: createProfile,
|
|
8069
|
-
...node === void 0 ? {} : { node },
|
|
8070
|
-
workspaceControlRef: () => controlRef,
|
|
8071
|
-
workspaceProvenance: () => captured.provenance,
|
|
8072
|
-
workspaceCoverage: () => ({
|
|
8073
|
-
complete: captured.coverageComplete ?? false,
|
|
8074
|
-
incompleteReason: captured.incompleteReason
|
|
8075
|
-
})
|
|
8076
|
-
}, next, captured.snapshot, sessionId), harness);
|
|
8077
|
-
if (nativeHoldsTranscript && !(copy.status === "retained" && copy.fileCount > 0)) return;
|
|
8078
|
-
state.harnessTranscript = copy;
|
|
8079
|
-
nativeHoldsTranscript = true;
|
|
8080
|
-
nativeEventsAtCopy = eventsAtStart;
|
|
8081
|
-
} catch (error) {
|
|
8082
|
-
if (stop?.signal.aborted) return;
|
|
8083
|
-
noteCaptureFailure(error);
|
|
8084
|
-
} finally {
|
|
8085
|
-
lastNativeCopyMs = Date.now() - copyStartedAt;
|
|
8086
|
-
}
|
|
8087
|
-
}).catch(() => void 0).finally(() => {
|
|
8088
|
-
if (nativeInFlight === tracked) nativeInFlight = void 0;
|
|
8089
|
-
if (nativeRunningInFlight === tracked) nativeRunningInFlight = void 0;
|
|
8090
|
-
if (nativeRunningStop === stop) nativeRunningStop = void 0;
|
|
8091
|
-
});
|
|
8092
|
-
nativeInFlight = tracked;
|
|
8093
|
-
if (stop !== void 0) nativeRunningInFlight = tracked;
|
|
8094
|
-
return tracked;
|
|
8095
|
-
};
|
|
8096
|
-
const startNativeMirror = (next) => {
|
|
8097
|
-
startLiveMirror(next);
|
|
8098
|
-
if (nativePort === void 0) return;
|
|
8099
|
-
if (nativeTimer !== void 0) clearTimeout(nativeTimer);
|
|
8100
|
-
closeNativeMirror?.();
|
|
8101
|
-
closeNativeMirror = openNativeMirror(nativePort);
|
|
8102
|
-
const port = nativePort;
|
|
8103
|
-
const interval = nativePort.nativeIntervalMs ?? 12e4;
|
|
8104
|
-
const schedule = () => {
|
|
8105
|
-
nativeTimer = setTimeout(() => {
|
|
8106
|
-
if (nativeInFlight === void 0 && !(nativeHoldsTranscript && nativeEventsAtCopy === nativeEvents)) captureNative(next, "running");
|
|
8107
|
-
schedule();
|
|
8108
|
-
}, nativeCopyDelayMs(port, interval, lastNativeCopyMs));
|
|
8109
|
-
nativeTimer.unref?.();
|
|
8110
|
-
};
|
|
8111
|
-
schedule();
|
|
8112
|
-
};
|
|
8113
|
-
const finishNativeMirror = async (next, phase) => {
|
|
8114
|
-
stopLiveMirror();
|
|
8115
|
-
await stopNativeMirror();
|
|
8116
|
-
if (state.workspaceSnapshot !== void 0 && !nativeHoldsTranscript) return;
|
|
8117
|
-
await captureNative(next, phase, void 0, state.harnessStopped);
|
|
8118
|
-
};
|
|
8119
|
-
return {
|
|
8120
|
-
get nativePort() {
|
|
8121
|
-
return nativePort;
|
|
8122
|
-
},
|
|
8123
|
-
get nativeRunningInFlight() {
|
|
8124
|
-
return nativeRunningInFlight;
|
|
8125
|
-
},
|
|
8126
|
-
get liveInFlight() {
|
|
8127
|
-
return liveInFlight;
|
|
8128
|
-
},
|
|
8129
|
-
get holdsTranscript() {
|
|
8130
|
-
return nativeHoldsTranscript;
|
|
8131
|
-
},
|
|
8132
|
-
set holdsTranscript(value) {
|
|
8133
|
-
nativeHoldsTranscript = value;
|
|
8134
|
-
},
|
|
8135
|
-
stopScheduledNativeCapture() {
|
|
8136
|
-
if (nativeTimer !== void 0) clearTimeout(nativeTimer);
|
|
8137
|
-
nativeTimer = void 0;
|
|
8138
|
-
},
|
|
8139
|
-
noteProviderEvent() {
|
|
8140
|
-
nativeEvents += 1;
|
|
8141
|
-
},
|
|
8142
|
-
noteCaptureFailure,
|
|
8143
|
-
stopLiveMirror,
|
|
8144
|
-
captureNative,
|
|
8145
|
-
startNativeMirror,
|
|
8146
|
-
finishNativeMirror
|
|
8147
|
-
};
|
|
8148
|
-
}
|
|
8149
|
-
/** How long the final copy of a stopped harness waits for the provider to record how it ended. */
|
|
8150
|
-
const NATIVE_SETTLE_WINDOW_MS = 15e3;
|
|
8151
|
-
const NATIVE_SETTLE_POLL_MS = 1e3;
|
|
8152
|
-
function createProviderNativeControl(provider, retention, managerStop, state) {
|
|
8153
|
-
let nativeStop;
|
|
8154
|
-
const cancelRetainedOnManagerStop = (handle) => {
|
|
8155
|
-
if (managerStop === void 0) return;
|
|
8156
|
-
const cancel = () => {
|
|
8157
|
-
if (state.retained !== handle || !state.workspaceRunActive) return;
|
|
8158
|
-
handle.cancel({
|
|
8159
|
-
operationId: `manager-stop:${randomUUID()}`,
|
|
8160
|
-
reason: String(managerStop.reason ?? "the manager stopped")
|
|
8161
|
-
}).catch(() => void 0);
|
|
8162
|
-
};
|
|
8163
|
-
const stop = () => managerStop.reason === "result-accepted" ? void armDeadlineTimer(ACCEPTED_RESULT_GRACE_MS, cancel) : cancel();
|
|
8164
|
-
if (managerStop.aborted) stop();
|
|
8165
|
-
else managerStop.addEventListener("abort", stop, { once: true });
|
|
8166
|
-
};
|
|
8167
|
-
/** Stop the native harness of this executor's retained execution, which local observation ending
|
|
8168
|
-
* never stops. Undefined when nothing was dispatched. */
|
|
8169
|
-
const stopNativeExecution = () => {
|
|
8170
|
-
if (nativeStop !== void 0) return nativeStop;
|
|
8171
|
-
const controlRef = state.retained?.controlRef ?? admittedControlRef(retention);
|
|
8172
|
-
if (controlRef === void 0) return Promise.resolve(void 0);
|
|
8173
|
-
const stopping = stopRetainedNativeExecution({
|
|
8174
|
-
provider,
|
|
8175
|
-
controlRef,
|
|
8176
|
-
...state.retained === void 0 ? {} : { handle: state.retained },
|
|
8177
|
-
signal: AbortSignal.timeout(NATIVE_STOP_TIMEOUT_MS)
|
|
8178
|
-
}).then((stop) => {
|
|
8179
|
-
if (stop.effect === "cancelled" || stop.effect === "not_live") state.harnessStopped = true;
|
|
8180
|
-
else if (nativeStop === stopping) nativeStop = void 0;
|
|
8181
|
-
return stop;
|
|
8182
|
-
});
|
|
8183
|
-
nativeStop = stopping;
|
|
8184
|
-
return stopping;
|
|
8185
|
-
};
|
|
8186
|
-
/** A turn its deadline or an explicit cancellation ended stops its harness, within the stop's
|
|
8187
|
-
* bound, before the turn's final native copy, which otherwise reads a session still written. */
|
|
8188
|
-
const stopEndedHarness = async (signal) => {
|
|
8189
|
-
if (!isDeadlineAbortReason(signal.reason) && !state.cancelledExplicitly()) return;
|
|
8190
|
-
await stopNativeExecution();
|
|
8191
|
-
};
|
|
8192
|
-
/**
|
|
8193
|
-
* A release that keeps an environment keeps its files, never its running harness. The root has
|
|
8194
|
-
* settled and no process will reconcile this execution, so its native process stops before the
|
|
8195
|
-
* release records what it kept.
|
|
8196
|
-
*/
|
|
8197
|
-
const withoutRunningHarness = (release) => async (signal) => {
|
|
8198
|
-
const stop = await awaitAbortable(stopNativeExecution(), signal).catch(() => void 0);
|
|
8199
|
-
const stopped = stop === void 0 ? "native stop unconfirmed: no exact dispatch or cleanup interrupted" : describeRetainedNativeStops([stop]);
|
|
8200
|
-
const environmentId = (state.retained?.controlRef ?? admittedControlRef(retention))?.environmentId ?? admittedEnvironmentId(retention);
|
|
8201
|
-
if (environmentId !== void 0 && !state.harnessStopped) {
|
|
8202
|
-
state.workspacePreservationRequired = true;
|
|
8203
|
-
return [{
|
|
8204
|
-
provider: provider.name,
|
|
8205
|
-
environmentId,
|
|
8206
|
-
destroyed: false,
|
|
8207
|
-
detail: stopped,
|
|
8208
|
-
permanent: true
|
|
8209
|
-
}];
|
|
8210
|
-
}
|
|
8211
|
-
return (await release(signal)).map((receipt) => receipt.destroyed ? receipt : {
|
|
8212
|
-
...receipt,
|
|
8213
|
-
detail: receipt.detail ? `${receipt.detail}; ${stopped}` : stopped
|
|
8214
|
-
});
|
|
8215
|
-
};
|
|
8216
|
-
return {
|
|
8217
|
-
cancelRetainedOnManagerStop,
|
|
8218
|
-
stopNativeExecution,
|
|
8219
|
-
stopEndedHarness,
|
|
8220
|
-
withoutRunningHarness
|
|
8221
|
-
};
|
|
8222
|
-
}
|
|
8223
|
-
/** The exact run the latest durable dispatch names, when dispatch got that far. */
|
|
8224
|
-
function admittedControlRef(retention) {
|
|
8225
|
-
for (const admission of [...retention?.admissions ?? []].reverse()) if (admission.phase === "dispatched") return admission.controlRef;
|
|
8226
|
-
}
|
|
8227
|
-
/** Bounds one provider stop: a reconnect, the exact cancellation and its status read. */
|
|
8228
|
-
const NATIVE_STOP_TIMEOUT_MS = 3e4;
|
|
8229
|
-
function providerWorkspaceCaptureReceipt(args, environment, snapshot, fallbackSessionId) {
|
|
8230
|
-
const coverage = args.workspaceCoverage();
|
|
8231
|
-
const controlRef = args.workspaceControlRef();
|
|
8232
|
-
return workspaceCaptureReceipt({
|
|
8233
|
-
executionId: args.executionId,
|
|
8234
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
8235
|
-
...args.node === void 0 ? {} : { node: args.node },
|
|
8236
|
-
environment,
|
|
8237
|
-
profile: args.profile,
|
|
8238
|
-
providerSessionId: controlRef?.sessionId ?? fallbackSessionId
|
|
8239
|
-
}, {
|
|
8240
|
-
snapshot,
|
|
8241
|
-
provenance: args.workspaceProvenance() ?? {
|
|
8242
|
-
status: "unavailable",
|
|
8243
|
-
missing: ["Capture coverage metadata was not retained"]
|
|
8244
|
-
},
|
|
8245
|
-
coverageComplete: coverage.complete,
|
|
8246
|
-
...coverage.incompleteReason === void 0 ? {} : { incompleteReason: coverage.incompleteReason }
|
|
8247
|
-
});
|
|
8248
|
-
}
|
|
8249
|
-
// src/runtime/environment-provider/provider-workspace-capture.ts
|
|
8250
|
-
/** Capture the environment's workspace once per generation; later callers share that capture. */
|
|
8251
|
-
async function captureExecutorWorkspace(scope, next, outcome) {
|
|
8252
|
-
const { state } = scope;
|
|
8253
|
-
const workspaceRetention = scope.options.workspaceRetention;
|
|
8254
|
-
if (workspaceRetention === void 0) return void 0;
|
|
8255
|
-
state.resetWorkspace(next);
|
|
8256
|
-
if (state.workspaceSnapshot !== void 0) return state.workspaceSnapshot;
|
|
8257
|
-
if (state.workspaceCapturePromise === void 0) state.workspaceCapturePromise = startWorkspaceCapture(scope, workspaceRetention, next, outcome);
|
|
8258
|
-
return await state.workspaceCapturePromise;
|
|
8259
|
-
}
|
|
8260
|
-
function startWorkspaceCapture(scope, workspaceRetention, next, outcome) {
|
|
8261
|
-
const { state, mirrors, retention, node, createProfile } = scope;
|
|
8262
|
-
state.workspaceOutcome = outcome;
|
|
8263
|
-
mirrors.stopLiveMirror();
|
|
8264
|
-
mirrors.stopScheduledNativeCapture();
|
|
8265
|
-
const captureContext = {
|
|
8266
|
-
environment: next,
|
|
8267
|
-
executionId: state.workspaceExecutionId,
|
|
8268
|
-
...state.workspaceControlRef === void 0 ? {} : { controlRef: state.workspaceControlRef },
|
|
8269
|
-
...node === void 0 ? {} : { node },
|
|
8270
|
-
providerSessionId: state.providerSessionId,
|
|
8271
|
-
nativeSessionId: null,
|
|
8272
|
-
profile: createProfile,
|
|
8273
|
-
...outcome === void 0 ? {} : { outcome }
|
|
8274
|
-
};
|
|
8275
|
-
const reportTiming = retention?.onWorkspaceCapture;
|
|
8276
|
-
let timing;
|
|
8277
|
-
const capturedExecutionId = state.workspaceExecutionId;
|
|
8278
|
-
const started = retention?.onWorkspaceCaptureStarted?.({
|
|
8279
|
-
executionId: capturedExecutionId,
|
|
8280
|
-
environmentId: next.id
|
|
8281
|
-
}).catch(() => void 0) ?? Promise.resolve();
|
|
8282
|
-
return Promise.all([mirrors.nativeRunningInFlight, mirrors.liveInFlight]).then(() => captureProviderWorkspaceSnapshot(workspaceRetention, captureContext, "environment", reportTiming === void 0 ? void 0 : (measured) => {
|
|
8283
|
-
timing = measured;
|
|
8284
|
-
})).finally(async () => {
|
|
8285
|
-
await started;
|
|
8286
|
-
if (timing === void 0 || reportTiming === void 0) return;
|
|
8287
|
-
await reportTiming({
|
|
8288
|
-
executionId: capturedExecutionId,
|
|
8289
|
-
environmentId: next.id,
|
|
8290
|
-
...timing
|
|
8291
|
-
}).catch(() => void 0);
|
|
8292
|
-
}).then((captured) => {
|
|
8293
|
-
recordCapturedWorkspace(scope, workspaceRetention, next, captured);
|
|
8294
|
-
return captured.snapshot;
|
|
8295
|
-
}).catch((error) => {
|
|
8296
|
-
state.workspaceCaptureFailure = error;
|
|
8297
|
-
mirrors.noteCaptureFailure(error);
|
|
8298
|
-
throw error;
|
|
8299
|
-
});
|
|
8300
|
-
}
|
|
8301
|
-
/** Keep the capture's snapshot and provenance, and project its transcript for the executor. */
|
|
8302
|
-
function recordCapturedWorkspace(scope, workspaceRetention, next, { snapshot, provenance, coverageComplete, incompleteReason }) {
|
|
8303
|
-
const { state, mirrors, node, createProfile } = scope;
|
|
8304
|
-
state.workspaceSnapshot = snapshot;
|
|
8305
|
-
state.workspaceProvenance = provenance;
|
|
8306
|
-
state.workspaceCoverageComplete = coverageComplete ?? false;
|
|
8307
|
-
state.workspaceIncompleteReason = incompleteReason;
|
|
8308
|
-
try {
|
|
8309
|
-
state.harnessTranscript = createProfile.harness === void 0 ? harnessTranscriptUnavailable("unknown-harness") : retainHarnessTranscript(providerWorkspaceCaptureReceipt({
|
|
8310
|
-
executionId: state.workspaceExecutionId,
|
|
8311
|
-
profile: createProfile,
|
|
8312
|
-
...node === void 0 ? {} : { node },
|
|
8313
|
-
workspaceControlRef: () => state.workspaceControlRef,
|
|
8314
|
-
workspaceProvenance: () => provenance,
|
|
8315
|
-
workspaceCoverage: () => ({
|
|
8316
|
-
complete: coverageComplete ?? false,
|
|
8317
|
-
incompleteReason
|
|
8318
|
-
})
|
|
8319
|
-
}, next, snapshot, state.providerSessionId), createProfile.harness);
|
|
8320
|
-
mirrors.holdsTranscript = false;
|
|
8321
|
-
} catch (error) {
|
|
8322
|
-
if (!mirrors.holdsTranscript) state.harnessTranscript = {
|
|
8323
|
-
status: "unavailable",
|
|
8324
|
-
reason: "retained-projection-failed",
|
|
8325
|
-
skipped: [{
|
|
8326
|
-
path: state.workspaceExecutionId,
|
|
8327
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
8328
|
-
}]
|
|
8329
|
-
};
|
|
8330
|
-
}
|
|
8331
|
-
if (workspaceRetention.requireCompleteProvenance && !coverageComplete) state.workspacePreservationRequired = true;
|
|
8332
|
-
}
|
|
8333
7969
|
// src/runtime/environment-provider/provider-environment-teardown.ts
|
|
8334
7970
|
/** The environment id the latest durable admission names, when creation got that far. */
|
|
8335
7971
|
function admittedEnvironmentId(retention) {
|
|
@@ -8339,56 +7975,28 @@ function admittedEnvironmentId(retention) {
|
|
|
8339
7975
|
}
|
|
8340
7976
|
}
|
|
8341
7977
|
const destroyFailed = (scope, error) => `providerAsExecutor(${scope.provider.name}): environment.destroy() failed — ${error instanceof Error ? error.message : String(error)}`;
|
|
8342
|
-
function workspaceFailureDetail(scope) {
|
|
8343
|
-
const { workspaceCaptureFailure } = scope.state;
|
|
8344
|
-
const reason = workspaceCaptureFailure instanceof Error ? workspaceCaptureFailure.message : String(workspaceCaptureFailure ?? "capture was not accepted");
|
|
8345
|
-
return `providerAsExecutor(${scope.provider.name}): workspace retention failed — ${reason}; source environment preserved`;
|
|
8346
|
-
}
|
|
8347
7978
|
/** Destroy the environment once, however many callers ask; a failed attempt may be retried. */
|
|
8348
7979
|
async function destroyExecutorEnvironment(scope, cleanupSignal) {
|
|
8349
|
-
const { state
|
|
7980
|
+
const { state } = scope;
|
|
8350
7981
|
if (state.workspaceCleanupPromise !== void 0) return await state.workspaceCleanupPromise;
|
|
8351
7982
|
const cleanupPromise = attemptDestroy(scope, cleanupSignal);
|
|
8352
7983
|
let cleanupReference;
|
|
8353
7984
|
cleanupReference = cleanupPromise.then((result) => {
|
|
8354
|
-
if (!result.destroyed && state.workspaceCleanupPromise === cleanupReference && !state.workspacePreservationRequired
|
|
8355
|
-
if (options.workspaceRetention !== void 0) {
|
|
8356
|
-
state.workspaceSnapshot = void 0;
|
|
8357
|
-
state.workspaceCapturePromise = void 0;
|
|
8358
|
-
}
|
|
8359
|
-
state.workspaceCleanupPromise = void 0;
|
|
8360
|
-
}
|
|
7985
|
+
if (!result.destroyed && state.workspaceCleanupPromise === cleanupReference && !state.workspacePreservationRequired) state.workspaceCleanupPromise = void 0;
|
|
8361
7986
|
return result;
|
|
8362
7987
|
});
|
|
8363
7988
|
state.workspaceCleanupPromise = cleanupReference;
|
|
8364
7989
|
return await cleanupReference;
|
|
8365
7990
|
}
|
|
8366
7991
|
async function attemptDestroy(scope, cleanupSignal) {
|
|
8367
|
-
const { state,
|
|
7992
|
+
const { state, provider } = scope;
|
|
8368
7993
|
const target = state.environment;
|
|
8369
7994
|
if (target === void 0) return { destroyed: true };
|
|
8370
7995
|
if (state.workspacePreservationRequired) return {
|
|
8371
7996
|
destroyed: false,
|
|
8372
|
-
detail:
|
|
7997
|
+
detail: "provider native stop was not confirmed; source environment preserved",
|
|
8373
7998
|
permanent: true
|
|
8374
7999
|
};
|
|
8375
|
-
if (options.workspaceRetention !== void 0) try {
|
|
8376
|
-
const currentSnapshot = await captureExecutorWorkspace(scope, target, state.workspaceOutcome);
|
|
8377
|
-
if (state.workspacePublishedSnapshot !== void 0 && currentSnapshot !== void 0 && currentSnapshot.digest !== state.workspacePublishedSnapshot.digest) {
|
|
8378
|
-
state.workspacePreservationRequired = true;
|
|
8379
|
-
return {
|
|
8380
|
-
destroyed: false,
|
|
8381
|
-
detail: "provider workspace retention: live workspace changed after the published receipt; source preserved",
|
|
8382
|
-
permanent: true
|
|
8383
|
-
};
|
|
8384
|
-
}
|
|
8385
|
-
} catch {
|
|
8386
|
-
return {
|
|
8387
|
-
destroyed: false,
|
|
8388
|
-
detail: workspaceFailureDetail(scope),
|
|
8389
|
-
permanent: true
|
|
8390
|
-
};
|
|
8391
|
-
}
|
|
8392
8000
|
if (state.destroyed) return { destroyed: true };
|
|
8393
8001
|
try {
|
|
8394
8002
|
await awaitAbortable(Promise.resolve(target.destroy?.()), cleanupSignal);
|
|
@@ -8407,7 +8015,7 @@ async function attemptDestroy(scope, cleanupSignal) {
|
|
|
8407
8015
|
}
|
|
8408
8016
|
/** Release the environment of a retained execution once no process will reconcile it. */
|
|
8409
8017
|
async function releaseRetainedExecution(scope, signal) {
|
|
8410
|
-
const { state,
|
|
8018
|
+
const { state, provider, retention } = scope;
|
|
8411
8019
|
scope.controller.abort();
|
|
8412
8020
|
if (!state.pending) return [];
|
|
8413
8021
|
const environmentId = state.retained?.controlRef.environmentId ?? state.environment?.id ?? admittedEnvironmentId(retention);
|
|
@@ -8419,12 +8027,11 @@ async function releaseRetainedExecution(scope, signal) {
|
|
|
8419
8027
|
...detail === void 0 ? {} : { detail },
|
|
8420
8028
|
...permanent === true ? { permanent } : {}
|
|
8421
8029
|
});
|
|
8422
|
-
if (options.workspaceRetention !== void 0 && state.workspaceRunActive) return [receipt(false, "provider workspace retention: source preserved while execution is still active")];
|
|
8423
8030
|
if (state.retainedReleasePromise !== void 0) return await state.retainedReleasePromise;
|
|
8424
8031
|
const releasePromise = releaseReceipts(scope, environmentId, signal, receipt);
|
|
8425
8032
|
let releaseReference;
|
|
8426
8033
|
releaseReference = releasePromise.then((receipts) => {
|
|
8427
|
-
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;
|
|
8428
8035
|
return receipts;
|
|
8429
8036
|
});
|
|
8430
8037
|
state.retainedReleasePromise = releaseReference;
|
|
@@ -8445,7 +8052,7 @@ async function releaseReceipts(scope, environmentId, signal, receipt) {
|
|
|
8445
8052
|
state.environment = target;
|
|
8446
8053
|
state.resetWorkspace(target);
|
|
8447
8054
|
}
|
|
8448
|
-
await captureBeforeDestroy
|
|
8055
|
+
await captureBeforeDestroy(scope, target, signal);
|
|
8449
8056
|
const result = await destroyExecutorEnvironment(scope, signal);
|
|
8450
8057
|
if (!result.destroyed) return [receipt(false, result.detail, result.permanent)];
|
|
8451
8058
|
state.pending = false;
|
|
@@ -8460,18 +8067,13 @@ async function releaseReceipts(scope, environmentId, signal, receipt) {
|
|
|
8460
8067
|
* Discovery fleet of 2026-09-23/24, 105 carry `enumeration-failed`. A box the release can reach
|
|
8461
8068
|
* is read once more before it is destroyed.
|
|
8462
8069
|
*/
|
|
8463
|
-
async function captureBeforeDestroy
|
|
8464
|
-
const { state
|
|
8465
|
-
if (
|
|
8070
|
+
async function captureBeforeDestroy(scope, target, signal) {
|
|
8071
|
+
const { state } = scope;
|
|
8072
|
+
if (state.harnessTranscript.status !== "captured" && !state.releaseReadTried) {
|
|
8466
8073
|
state.releaseReadTried = true;
|
|
8467
8074
|
const capture = await captureHarnessTranscript(target, scope.profile.harness, signal);
|
|
8468
8075
|
if (capture.status === "captured") state.harnessTranscript = capture;
|
|
8469
8076
|
}
|
|
8470
|
-
if (mirrors.nativePort !== void 0 && state.harnessTranscript.status !== "retained" && !state.releaseNativeTried) {
|
|
8471
|
-
state.releaseNativeTried = true;
|
|
8472
|
-
const admitted = state.retained?.controlRef ?? admittedControlRef(retention);
|
|
8473
|
-
await awaitAbortable(mirrors.captureNative(target, "interrupted", admitted === void 0 ? void 0 : freezeControlRef(admitted)), signal).catch(() => void 0);
|
|
8474
|
-
}
|
|
8475
8077
|
}
|
|
8476
8078
|
// src/runtime/environment-provider/provider-validation-error.ts
|
|
8477
8079
|
var ValidationError = class extends Error {
|
|
@@ -8606,10 +8208,10 @@ function createProviderFailureLedger() {
|
|
|
8606
8208
|
const tracker = createAgentRunOutcomeTracker();
|
|
8607
8209
|
for (const frame of failures) tracker.observe(frame);
|
|
8608
8210
|
const outcome = tracker.finish();
|
|
8609
|
-
const failure = failures.slice().reverse().map((frame) => turnFailureOf(frame.data)).find((value) => value !== void 0);
|
|
8211
|
+
const failure = turnFailureOf(outcome) ?? failures.slice().reverse().map((frame) => turnFailureOf(frame.data)).find((value) => value !== void 0);
|
|
8610
8212
|
return outcome === void 0 ? void 0 : {
|
|
8611
8213
|
...outcome,
|
|
8612
|
-
|
|
8214
|
+
failure
|
|
8613
8215
|
};
|
|
8614
8216
|
}
|
|
8615
8217
|
};
|
|
@@ -8793,12 +8395,8 @@ function stringValue(value) {
|
|
|
8793
8395
|
const RETAINED_AWAITING_RESULT_AFTER_MS = 48e4;
|
|
8794
8396
|
const RETAINED_STATUS_READ_MS = 6e4;
|
|
8795
8397
|
const RETAINED_OBSERVATION_BATCH_EVENTS = 1024;
|
|
8796
|
-
/** After its exact result, a stream owing its terminal frame reads on while each frame comes this
|
|
8797
|
-
* soon after the result or the last frame: a provider sends the two on separate connections. */
|
|
8798
8398
|
const RETAINED_TAIL_FLOW_MS = 100;
|
|
8799
|
-
/** The event stream stopped short: a transport fact the retry policy reads by this name. */
|
|
8800
8399
|
const streamFailure = (message) => Object.assign(new Error(message), { name: "RetainedStreamError" });
|
|
8801
|
-
/** Why the event stream stopped short, as bounded redacted text for the settlement reason. */
|
|
8802
8400
|
function observationFailureText({ error }) {
|
|
8803
8401
|
const text = error instanceof Error ? error.message : String(error);
|
|
8804
8402
|
return String(defaultRedactor(text)).slice(0, 2048);
|
|
@@ -8826,11 +8424,11 @@ function exactQuotaRefusal(error) {
|
|
|
8826
8424
|
return;
|
|
8827
8425
|
}
|
|
8828
8426
|
}
|
|
8829
|
-
/** Everything one retained dispatch has observed of its event stream and exact result. */
|
|
8830
8427
|
var RetainedObservation = class {
|
|
8831
8428
|
handle;
|
|
8832
8429
|
signal;
|
|
8833
8430
|
position;
|
|
8431
|
+
quietMs;
|
|
8834
8432
|
failure;
|
|
8835
8433
|
lastReplayPosition;
|
|
8836
8434
|
resumedFrom;
|
|
@@ -8844,14 +8442,14 @@ var RetainedObservation = class {
|
|
|
8844
8442
|
exactWakers = /* @__PURE__ */ new Set();
|
|
8845
8443
|
seenEvents = /* @__PURE__ */ new Map();
|
|
8846
8444
|
pendingRead;
|
|
8847
|
-
constructor(handle, signal, position) {
|
|
8445
|
+
constructor(handle, signal, position, quietMs = RETAINED_AWAITING_RESULT_AFTER_MS) {
|
|
8848
8446
|
this.handle = handle;
|
|
8849
8447
|
this.signal = signal;
|
|
8850
8448
|
this.position = position;
|
|
8449
|
+
this.quietMs = quietMs;
|
|
8851
8450
|
const observed = position?.observed;
|
|
8852
8451
|
if (observed?.executionId === handle.controlRef.executionId) this.lastReplayPosition = this.resumedFrom = observed.replayPosition;
|
|
8853
8452
|
}
|
|
8854
|
-
/** Stream the provider's frames, resume once after a break, then yield the exact result. */
|
|
8855
8453
|
async *observe(session) {
|
|
8856
8454
|
this.lastObservedAt = Date.now();
|
|
8857
8455
|
if (!(yield* this.drain(session, this.resumedFrom)) && !this.sawTerminal && this.lastReplayPosition !== void 0) {
|
|
@@ -8862,11 +8460,13 @@ var RetainedObservation = class {
|
|
|
8862
8460
|
const resumed = this.resumedFrom && `retained provider stream resumed after ${this.resumedFrom}`;
|
|
8863
8461
|
if (resumed) this.failure ??= { error: streamFailure(resumed) };
|
|
8864
8462
|
if (!this.sawTerminal && this.failure === void 0) this.failure = { error: streamFailure("retained provider stream did not yield a terminal event") };
|
|
8865
|
-
if (!this.sawTerminal && !this.exactResultSettled && this.silenceHandledAt === void 0)
|
|
8866
|
-
|
|
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);
|
|
8867
8468
|
yield await this.resultFrame();
|
|
8868
8469
|
}
|
|
8869
|
-
/** True once the exact result settles, false once a quiet interval passes first. */
|
|
8870
8470
|
exactOrQuiet() {
|
|
8871
8471
|
let unwatch = [() => {}];
|
|
8872
8472
|
return new Promise((resolve) => {
|
|
@@ -8875,21 +8475,17 @@ var RetainedObservation = class {
|
|
|
8875
8475
|
}
|
|
8876
8476
|
armQuiet(onQuiet) {
|
|
8877
8477
|
const quietFrom = Math.max(this.lastObservedAt, this.silenceHandledAt ?? 0);
|
|
8878
|
-
const quietMs =
|
|
8478
|
+
const quietMs = this.quietMs - (Date.now() - quietFrom);
|
|
8879
8479
|
return armDeadlineTimer(Math.max(0, quietMs), onQuiet);
|
|
8880
8480
|
}
|
|
8881
|
-
/**
|
|
8882
|
-
async
|
|
8481
|
+
/** Status diagnoses the observation stop; it cannot substitute for a frame or exact result. */
|
|
8482
|
+
async stopQuietObservation(session) {
|
|
8883
8483
|
const deadline = new AbortController();
|
|
8884
8484
|
const clear = armDeadlineTimer(RETAINED_STATUS_READ_MS, () => deadline.abort(/* @__PURE__ */ new Error(`no status answer within ${RETAINED_STATUS_READ_MS} ms`)));
|
|
8885
8485
|
const signal = AbortSignal.any([this.signal, deadline.signal]);
|
|
8886
8486
|
let cause;
|
|
8887
8487
|
try {
|
|
8888
8488
|
const status = await awaitAbortable(Promise.resolve().then(() => session.status({ signal })), signal);
|
|
8889
|
-
if (status !== null && !isTerminalSessionStatus(status)) {
|
|
8890
|
-
this.silenceHandledAt = Date.now();
|
|
8891
|
-
return;
|
|
8892
|
-
}
|
|
8893
8489
|
cause = /* @__PURE__ */ new Error(`provider status reads ${status}`);
|
|
8894
8490
|
} catch (error) {
|
|
8895
8491
|
if (this.signal.aborted) throw error;
|
|
@@ -8897,7 +8493,8 @@ var RetainedObservation = class {
|
|
|
8897
8493
|
} finally {
|
|
8898
8494
|
clear();
|
|
8899
8495
|
}
|
|
8900
|
-
|
|
8496
|
+
if (this.exactResultSettled) return;
|
|
8497
|
+
throw Object.assign(streamFailure("retained provider observation exceeded its quiet interval; exact execution remains pending"), { cause });
|
|
8901
8498
|
}
|
|
8902
8499
|
async resultFrame() {
|
|
8903
8500
|
let result;
|
|
@@ -8957,7 +8554,6 @@ var RetainedObservation = class {
|
|
|
8957
8554
|
this.silenceHandledAt = Date.now();
|
|
8958
8555
|
return { awaitingResultSince: new Date(since).toISOString() };
|
|
8959
8556
|
}
|
|
8960
|
-
/** Read the stream's next frame, or learn first that the wait should publish or the result won. */
|
|
8961
8557
|
async raceNextRead(iterator) {
|
|
8962
8558
|
let wake;
|
|
8963
8559
|
let grace;
|
|
@@ -8999,7 +8595,6 @@ var RetainedObservation = class {
|
|
|
8999
8595
|
clearQuiet?.();
|
|
9000
8596
|
}
|
|
9001
8597
|
}
|
|
9002
|
-
/** Bind a frame to its run and drop an exact replay; false when it carries no new evidence. */
|
|
9003
8598
|
acceptFrame(event) {
|
|
9004
8599
|
this.observedFrames += 1;
|
|
9005
8600
|
if (this.exactResultSettled) this.framesAfterResult += 1;
|
|
@@ -9041,17 +8636,18 @@ var RetainedObservation = class {
|
|
|
9041
8636
|
this.readExactResult();
|
|
9042
8637
|
return true;
|
|
9043
8638
|
}
|
|
9044
|
-
/** Yield one subscription's new frames; false when the stream failed rather than ended. */
|
|
9045
8639
|
async *drain(session, since) {
|
|
8640
|
+
const subscription = linkAbort(this.signal);
|
|
9046
8641
|
let iterator;
|
|
9047
8642
|
let failed = false;
|
|
9048
8643
|
try {
|
|
9049
8644
|
iterator = session.events({
|
|
9050
8645
|
executionId: this.handle.controlRef.executionId,
|
|
9051
8646
|
...since === void 0 ? {} : { since },
|
|
9052
|
-
signal:
|
|
8647
|
+
signal: subscription.signal
|
|
9053
8648
|
})[Symbol.asyncIterator]();
|
|
9054
8649
|
} catch (error) {
|
|
8650
|
+
subscription.abort();
|
|
9055
8651
|
if (this.signal.aborted) throw error;
|
|
9056
8652
|
this.failure = { error };
|
|
9057
8653
|
return false;
|
|
@@ -9074,8 +8670,11 @@ var RetainedObservation = class {
|
|
|
9074
8670
|
break;
|
|
9075
8671
|
}
|
|
9076
8672
|
if (observed.kind === "quiet") {
|
|
9077
|
-
if (this.silenceHandledAt !== void 0) await this.
|
|
9078
|
-
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
|
+
}
|
|
9079
8678
|
continue;
|
|
9080
8679
|
}
|
|
9081
8680
|
if (observed.kind === "exact-result") {
|
|
@@ -9090,6 +8689,8 @@ var RetainedObservation = class {
|
|
|
9090
8689
|
}
|
|
9091
8690
|
}
|
|
9092
8691
|
} finally {
|
|
8692
|
+
subscription.abort();
|
|
8693
|
+
this.pendingRead = void 0;
|
|
9093
8694
|
Promise.resolve().then(() => iterator?.return?.()).catch(() => void 0);
|
|
9094
8695
|
}
|
|
9095
8696
|
return !failed;
|
|
@@ -9379,7 +8980,6 @@ var ProviderTurnObserver = class {
|
|
|
9379
8980
|
};
|
|
9380
8981
|
continue;
|
|
9381
8982
|
}
|
|
9382
|
-
this.args.scope.mirrors.noteProviderEvent();
|
|
9383
8983
|
this.archive.append(event);
|
|
9384
8984
|
this.text += textFromEnvironmentEvent(event);
|
|
9385
8985
|
const sandboxEvent = sandboxEventFromEnvironmentEvent(event);
|
|
@@ -9409,10 +9009,6 @@ var ProviderTurnObserver = class {
|
|
|
9409
9009
|
// src/runtime/environment-provider/provider-sandbox-adapter.ts
|
|
9410
9010
|
/** Expose a neutral provider through the existing Sandbox client port. @experimental */
|
|
9411
9011
|
function providerAsSandboxClient(provider, options = {}) {
|
|
9412
|
-
if (options.workspaceRetention !== void 0) {
|
|
9413
|
-
assertProviderWorkspaceRetentionPort(options.workspaceRetention, `providerAsSandboxClient(${provider.name})`);
|
|
9414
|
-
if (options.retentionIdentity === void 0) throw new ValidationError("providerAsSandboxClient: retentionIdentity is required with workspaceRetention");
|
|
9415
|
-
}
|
|
9416
9012
|
return { async create(createOptions) {
|
|
9417
9013
|
const defaults = options.defaults ?? {};
|
|
9418
9014
|
const sandboxInput = createInputFromSandboxOptions(createOptions, options.mapCreateOptions !== void 0);
|
|
@@ -9456,15 +9052,12 @@ function providerAsSandboxClient(provider, options = {}) {
|
|
|
9456
9052
|
if (options.requireSession && (!capabilities?.streaming.live || !capabilities.sessions.continue)) throw new ValidationError(`providerAsSandboxClient(${provider.name}): live session continuation is required`);
|
|
9457
9053
|
const environment = await provider.create(mapped);
|
|
9458
9054
|
if (options.requireSession && !environment.session) {
|
|
9459
|
-
|
|
9055
|
+
await environment.destroy?.();
|
|
9460
9056
|
throw new ValidationError(`providerAsSandboxClient(${provider.name}): session() is required`);
|
|
9461
9057
|
}
|
|
9462
9058
|
return environmentAsSandboxInstance(environment, {
|
|
9463
9059
|
...typeof mapped.profile === "string" ? {} : { profile: mapped.profile },
|
|
9464
|
-
requireTerminalEvent: options.requireTerminalEvent ?? true
|
|
9465
|
-
workspaceRetention: options.workspaceRetention,
|
|
9466
|
-
retentionIdentity: options.retentionIdentity,
|
|
9467
|
-
onWorkspaceCaptured: options.onWorkspaceCaptured
|
|
9060
|
+
requireTerminalEvent: options.requireTerminalEvent ?? true
|
|
9468
9061
|
});
|
|
9469
9062
|
} };
|
|
9470
9063
|
}
|
|
@@ -9532,18 +9125,6 @@ function createInputFromSandboxOptions(options, customMapping) {
|
|
|
9532
9125
|
};
|
|
9533
9126
|
}
|
|
9534
9127
|
function environmentAsSandboxInstance(environment, options) {
|
|
9535
|
-
let providerSessionId = null;
|
|
9536
|
-
let controlRef;
|
|
9537
|
-
const noteControlRef = (candidate) => {
|
|
9538
|
-
if (options.workspaceRetention === void 0) return;
|
|
9539
|
-
const parsed = AgentExactRunControlRefSchema.safeParse(candidate);
|
|
9540
|
-
if (!parsed.success) return;
|
|
9541
|
-
if (parsed.data.environmentId !== environment.id || parsed.data.provider !== environment.provider) throw new ValidationError("providerAsSandboxClient: capture control reference names another environment");
|
|
9542
|
-
controlRef = freezeControlRef(parsed.data);
|
|
9543
|
-
providerSessionId = controlRef.sessionId;
|
|
9544
|
-
};
|
|
9545
|
-
let capture;
|
|
9546
|
-
let publication;
|
|
9547
9128
|
return {
|
|
9548
9129
|
id: environment.id,
|
|
9549
9130
|
name: environment.name,
|
|
@@ -9554,8 +9135,6 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9554
9135
|
async *streamPrompt(message, promptOptions) {
|
|
9555
9136
|
let terminal = false;
|
|
9556
9137
|
const input = turnInputFromPrompt(message, promptOptions, options.profile);
|
|
9557
|
-
providerSessionId = input.sessionId ?? null;
|
|
9558
|
-
noteControlRef(input.controlRef);
|
|
9559
9138
|
let cancellation;
|
|
9560
9139
|
let cancellationStarted = false;
|
|
9561
9140
|
let cancellationFailed = false;
|
|
@@ -9616,8 +9195,6 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9616
9195
|
let terminal = false;
|
|
9617
9196
|
const failures = createProviderFailureLedger();
|
|
9618
9197
|
const input = turnInputFromPrompt(message, promptOptions, options.profile);
|
|
9619
|
-
providerSessionId = input.sessionId ?? null;
|
|
9620
|
-
noteControlRef(input.controlRef);
|
|
9621
9198
|
for await (const event of environment.stream(input)) {
|
|
9622
9199
|
lastResultText = resultTextFromData(event.data) ?? lastResultText;
|
|
9623
9200
|
if (isTerminalEnvironmentEvent(event)) terminal = true;
|
|
@@ -9644,11 +9221,9 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9644
9221
|
...environment.dispatch && environment.session ? { async dispatchPrompt(message, promptOptions) {
|
|
9645
9222
|
const session = await environment.dispatch?.(turnInputFromPrompt(message, promptOptions, options.profile));
|
|
9646
9223
|
if (!session) throw new ValidationError("providerAsSandboxClient: dispatch returned no session");
|
|
9647
|
-
noteControlRef(session.controlRef);
|
|
9648
9224
|
return sandboxDispatchResultFromSessionRef(session);
|
|
9649
9225
|
} } : {},
|
|
9650
9226
|
...environment.session ? { session(id, sessionOptions) {
|
|
9651
|
-
noteControlRef(sessionOptions?.controlRef);
|
|
9652
9227
|
return sandboxSessionFromAgentSession(environment.session?.(id, sessionOptions), sessionOptions?.controlRef, options.profile);
|
|
9653
9228
|
} } : {},
|
|
9654
9229
|
...environment.read ? { read: environment.read.bind(environment) } : {},
|
|
@@ -9667,38 +9242,6 @@ function environmentAsSandboxInstance(environment, options) {
|
|
|
9667
9242
|
return environmentAsSandboxInstance(forked, options);
|
|
9668
9243
|
} } : {},
|
|
9669
9244
|
async delete() {
|
|
9670
|
-
if (options.workspaceRetention !== void 0) {
|
|
9671
|
-
const identity = options.retentionIdentity;
|
|
9672
|
-
if (identity === void 0) throw new ValidationError("providerAsSandboxClient: retention identity missing before delete");
|
|
9673
|
-
capture ??= captureProviderWorkspaceSnapshot(options.workspaceRetention, {
|
|
9674
|
-
environment,
|
|
9675
|
-
executionId: identity.executionId,
|
|
9676
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
9677
|
-
...identity.node === void 0 ? {} : { node: identity.node },
|
|
9678
|
-
providerSessionId,
|
|
9679
|
-
nativeSessionId: null,
|
|
9680
|
-
profile: identity.profile
|
|
9681
|
-
}).then((captured) => workspaceCaptureReceipt({
|
|
9682
|
-
environment,
|
|
9683
|
-
executionId: identity.executionId,
|
|
9684
|
-
...controlRef === void 0 ? {} : { controlRef },
|
|
9685
|
-
...identity.node === void 0 ? {} : { node: identity.node },
|
|
9686
|
-
profile: identity.profile,
|
|
9687
|
-
providerSessionId
|
|
9688
|
-
}, captured));
|
|
9689
|
-
const receipt = await capture;
|
|
9690
|
-
publication ??= Promise.resolve().then(async () => {
|
|
9691
|
-
await options.onWorkspaceCaptured?.(receipt);
|
|
9692
|
-
});
|
|
9693
|
-
const publishing = publication;
|
|
9694
|
-
try {
|
|
9695
|
-
await publishing;
|
|
9696
|
-
} catch (error) {
|
|
9697
|
-
if (publication === publishing) publication = void 0;
|
|
9698
|
-
throw error;
|
|
9699
|
-
}
|
|
9700
|
-
if (options.workspaceRetention.requireCompleteProvenance && !receipt.coverageComplete) throw new Error(receipt.incompleteReason ?? "provider workspace retention coverage incomplete");
|
|
9701
|
-
}
|
|
9702
9245
|
await environment.destroy?.();
|
|
9703
9246
|
}
|
|
9704
9247
|
};
|
|
@@ -9852,7 +9395,6 @@ var ProviderTurnSettlement = class {
|
|
|
9852
9395
|
args;
|
|
9853
9396
|
environment;
|
|
9854
9397
|
retained;
|
|
9855
|
-
sessionId;
|
|
9856
9398
|
observer;
|
|
9857
9399
|
usage;
|
|
9858
9400
|
started;
|
|
@@ -9864,14 +9406,11 @@ var ProviderTurnSettlement = class {
|
|
|
9864
9406
|
failed = false;
|
|
9865
9407
|
/** Set when the turn was refused for capacity and the caller will continue in this environment. */
|
|
9866
9408
|
unavailable;
|
|
9867
|
-
/** Whether the final session copy was taken before the workspace capture was handed to the owner. */
|
|
9868
|
-
finalCopyTaken = false;
|
|
9869
9409
|
harnessStop;
|
|
9870
|
-
constructor(args, environment, retained,
|
|
9410
|
+
constructor(args, environment, retained, observer, usage, started) {
|
|
9871
9411
|
this.args = args;
|
|
9872
9412
|
this.environment = environment;
|
|
9873
9413
|
this.retained = retained;
|
|
9874
|
-
this.sessionId = sessionId;
|
|
9875
9414
|
this.observer = observer;
|
|
9876
9415
|
this.usage = usage;
|
|
9877
9416
|
this.started = started;
|
|
@@ -9886,54 +9425,18 @@ var ProviderTurnSettlement = class {
|
|
|
9886
9425
|
durationMs: Date.now() - this.started
|
|
9887
9426
|
};
|
|
9888
9427
|
}
|
|
9889
|
-
/**
|
|
9890
|
-
* Whether this turn's owner takes its workspace capture over, so the turn ends without waiting
|
|
9891
|
-
* for it: the owner awaits it before the environment's next turn and before destroying the
|
|
9892
|
-
* environment, and journals its receipt. Only a port that copies the session on its own queue
|
|
9893
|
-
* hands it over; without one the capture is the only record of the session.
|
|
9894
|
-
*/
|
|
9895
|
-
ownerTakesCapture() {
|
|
9896
|
-
const { args } = this;
|
|
9897
|
-
return args.options.workspaceRetention?.captureNative !== void 0 && args.createProfile.harness !== void 0 && this.retained && args.retention?.preserveEnvironment === true && args.retention.onEndOfTurnWork !== void 0;
|
|
9898
|
-
}
|
|
9899
|
-
captureReceipt(snapshot) {
|
|
9900
|
-
return providerWorkspaceCaptureReceipt(this.args, this.environment, snapshot, this.sessionId);
|
|
9901
|
-
}
|
|
9902
|
-
/** Hand the workspace capture to the owner. Its receipt reaches the journal as evidence of this
|
|
9903
|
-
* invocation; a capture that fails leaves none, and the owner's release then keeps the source. */
|
|
9904
|
-
handCaptureToOwner(reported, captureOutcome, settled) {
|
|
9905
|
-
const { args, environment } = this;
|
|
9906
|
-
this.finalCopyTaken = true;
|
|
9907
|
-
args.retention?.onEndOfTurnWork?.((async () => {
|
|
9908
|
-
const copy = settled ? args.scope.mirrors.finishNativeMirror(environment, "settled").catch(() => void 0) : Promise.resolve();
|
|
9909
|
-
let snapshot;
|
|
9910
|
-
try {
|
|
9911
|
-
snapshot = await args.captureWorkspace(environment, captureOutcome);
|
|
9912
|
-
} finally {
|
|
9913
|
-
await copy;
|
|
9914
|
-
}
|
|
9915
|
-
if (settled) args.onPublishedSnapshot(snapshot);
|
|
9916
|
-
if (snapshot === void 0) return;
|
|
9917
|
-
await args.retention?.onEvidence?.({
|
|
9918
|
-
...reported,
|
|
9919
|
-
workspaceSnapshot: snapshot,
|
|
9920
|
-
workspaceCapture: this.captureReceipt(snapshot)
|
|
9921
|
-
});
|
|
9922
|
-
})().catch(() => void 0));
|
|
9923
|
-
}
|
|
9924
9428
|
stopEndedHarness() {
|
|
9925
9429
|
const { signal } = this.args;
|
|
9926
9430
|
if (this.settled !== void 0 || !signal.aborted) return Promise.resolve();
|
|
9927
9431
|
this.harnessStop ??= this.args.scope.nativeControl.stopEndedHarness(signal);
|
|
9928
9432
|
return this.harnessStop;
|
|
9929
9433
|
}
|
|
9930
|
-
/**
|
|
9434
|
+
/** Read the provider transcript while its environment is still available. */
|
|
9931
9435
|
async readLiveTranscript() {
|
|
9932
9436
|
const { args } = this;
|
|
9933
|
-
if (args.options.workspaceRetention !== void 0) return;
|
|
9934
9437
|
args.scope.state.harnessTranscript = await captureHarnessTranscript(this.environment, args.profile.harness, args.signal);
|
|
9935
9438
|
}
|
|
9936
|
-
/**
|
|
9439
|
+
/** Commit the consumed turn, validator verdict and measured spend. */
|
|
9937
9440
|
async *settle() {
|
|
9938
9441
|
const { args, usage } = this;
|
|
9939
9442
|
yield* usage.settleTurn();
|
|
@@ -9957,32 +9460,7 @@ var ProviderTurnSettlement = class {
|
|
|
9957
9460
|
}),
|
|
9958
9461
|
signal: args.signal
|
|
9959
9462
|
});
|
|
9960
|
-
const
|
|
9961
|
-
/**
|
|
9962
|
-
* A capture that fails or exceeds its deadline after settlement is a fact about the evidence,
|
|
9963
|
-
* never the turn's outcome. On Runtime 0.295.4 a capture past its 1,200,000 ms
|
|
9964
|
-
* deadline behind a two-slot queue shared by 34 workers threw an AbortError, the driver
|
|
9965
|
-
* classified it terminal, and two research roots ended with 13 and 0 children settled. With no
|
|
9966
|
-
* receipt the source stays preserved and the owner reads a retention failure; the turn is not re-run.
|
|
9967
|
-
*/
|
|
9968
|
-
let retainedWorkspace;
|
|
9969
|
-
let workspaceCaptureFailure;
|
|
9970
|
-
if (!deferCapture) {
|
|
9971
|
-
try {
|
|
9972
|
-
retainedWorkspace = await args.captureWorkspace(this.environment, outcome);
|
|
9973
|
-
} catch (error) {
|
|
9974
|
-
workspaceCaptureFailure = `${errorText(error instanceof Error ? error.message : error)}; source environment preserved`;
|
|
9975
|
-
}
|
|
9976
|
-
args.onPublishedSnapshot(retainedWorkspace);
|
|
9977
|
-
}
|
|
9978
|
-
const settledResult = {
|
|
9979
|
-
...result,
|
|
9980
|
-
...workspaceCaptureFailure === void 0 ? {} : { workspaceCaptureFailure },
|
|
9981
|
-
...retainedWorkspace === void 0 ? {} : {
|
|
9982
|
-
workspaceSnapshot: retainedWorkspace,
|
|
9983
|
-
workspaceCapture: this.captureReceipt(retainedWorkspace)
|
|
9984
|
-
}
|
|
9985
|
-
};
|
|
9463
|
+
const settledResult = result;
|
|
9986
9464
|
const jsonOutput = args.options.outputFormat === "json";
|
|
9987
9465
|
if (jsonOutput) await args.retention?.onEvidence?.(settledResult);
|
|
9988
9466
|
const output = jsonOutput && outcome?.status !== "failed" ? jsonResultFromEvents(result.events) : { out: settledResult };
|
|
@@ -10015,53 +9493,23 @@ var ProviderTurnSettlement = class {
|
|
|
10015
9493
|
};
|
|
10016
9494
|
}
|
|
10017
9495
|
if (this.retained) await args.retention?.onResult(settled);
|
|
10018
|
-
else if (retainedWorkspace !== void 0 && !jsonOutput) await args.retention?.onEvidence?.(settledResult);
|
|
10019
9496
|
args.scope.state.pending = false;
|
|
10020
9497
|
args.scope.state.artifact = settled;
|
|
10021
|
-
if (deferCapture) this.handCaptureToOwner(settledResult, outcome, true);
|
|
10022
9498
|
}
|
|
10023
9499
|
/** Record the turn's failure, then capture what evidence its environment still holds. */
|
|
10024
9500
|
async *fail(error) {
|
|
10025
|
-
const { args
|
|
9501
|
+
const { args } = this;
|
|
10026
9502
|
yield* this.usage.settleTurn();
|
|
10027
9503
|
this.failure = this.retained ? new RetainedExecutionPendingError(error) : error;
|
|
10028
9504
|
this.failed = true;
|
|
10029
|
-
if (args.options.workspaceRetention !== void 0) args.scope.state.workspacePreservationRequired = true;
|
|
10030
|
-
const failureOutcome = this.observer.failures.finish() ?? {
|
|
10031
|
-
success: false,
|
|
10032
|
-
status: "failed",
|
|
10033
|
-
error: error instanceof Error ? error.message : String(error),
|
|
10034
|
-
...args.signal.aborted ? { errorCode: "cancelled" } : {}
|
|
10035
|
-
};
|
|
10036
9505
|
await this.stopEndedHarness();
|
|
10037
|
-
if (args.signal.aborted) await args.scope.mirrors.finishNativeMirror(environment, "failed");
|
|
10038
9506
|
args.scope.state.settleTranscript();
|
|
10039
|
-
if (this.ownerTakesCapture()) {
|
|
10040
|
-
if (!args.signal.aborted) await args.scope.mirrors.finishNativeMirror(environment, "failed");
|
|
10041
|
-
this.handCaptureToOwner({
|
|
10042
|
-
...resultFromEvents(this.observer.archive.events(), this.observer.text),
|
|
10043
|
-
outcome: failureOutcome
|
|
10044
|
-
}, failureOutcome, false);
|
|
10045
|
-
} else try {
|
|
10046
|
-
const retainedWorkspace = await args.captureWorkspace(this.environment, failureOutcome);
|
|
10047
|
-
if (retainedWorkspace !== void 0 && args.retention?.onEvidence !== void 0) await args.retention.onEvidence({
|
|
10048
|
-
...resultFromEvents(this.observer.archive.events(), this.observer.text),
|
|
10049
|
-
outcome: failureOutcome,
|
|
10050
|
-
workspaceSnapshot: retainedWorkspace,
|
|
10051
|
-
workspaceCapture: this.captureReceipt(retainedWorkspace)
|
|
10052
|
-
});
|
|
10053
|
-
} catch (captureError) {
|
|
10054
|
-
if (!(captureError instanceof Error) || captureError === error) this.failure = captureError;
|
|
10055
|
-
else if (captureError.cause === void 0) this.failure = Object.assign(captureError, { cause: this.failure });
|
|
10056
|
-
else this.failure = new AggregateError([captureError, this.failure], captureError.message, { cause: captureError });
|
|
10057
|
-
}
|
|
10058
9507
|
await this.readLiveTranscript();
|
|
10059
9508
|
}
|
|
10060
|
-
/**
|
|
9509
|
+
/** Stop the harness when required, then settle its environment's custody. */
|
|
10061
9510
|
async release() {
|
|
10062
9511
|
const { args } = this;
|
|
10063
9512
|
await this.stopEndedHarness();
|
|
10064
|
-
if (!this.finalCopyTaken) await args.scope.mirrors.finishNativeMirror(this.environment, this.failed ? "failed" : this.settled !== void 0 ? "settled" : "interrupted");
|
|
10065
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;
|
|
10066
9514
|
if (held) args.scope.state.holdingForContinuation = true;
|
|
10067
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)) {
|
|
@@ -10271,10 +9719,9 @@ async function* streamProviderExecutor(args) {
|
|
|
10271
9719
|
const source = await providerExecutionSource(args, turn, args.signal);
|
|
10272
9720
|
const environment = source.environment;
|
|
10273
9721
|
args.onEnvironment(environment);
|
|
10274
|
-
args.scope.mirrors.startNativeMirror(environment);
|
|
10275
9722
|
const usage = new ProviderUsageAccount(args, turn.model);
|
|
10276
9723
|
const observer = new ProviderTurnObserver(args, usage, source.retained, turn.model);
|
|
10277
|
-
const settlement = new ProviderTurnSettlement(args, environment, source.retained,
|
|
9724
|
+
const settlement = new ProviderTurnSettlement(args, environment, source.retained, observer, usage, started);
|
|
10278
9725
|
try {
|
|
10279
9726
|
yield* observer.consume(source.events);
|
|
10280
9727
|
yield* settlement.settle();
|
|
@@ -10329,18 +9776,7 @@ function invocationArgs(scope, invocation, signal, carried, executionStartedAt,
|
|
|
10329
9776
|
if (!continued) return adoptEnvironment(scope, env);
|
|
10330
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>"}`);
|
|
10331
9778
|
state.environment = env;
|
|
10332
|
-
}
|
|
10333
|
-
onPublishedSnapshot: (snapshot) => {
|
|
10334
|
-
state.workspacePublishedSnapshot = snapshot;
|
|
10335
|
-
if (continued && snapshot !== void 0 && (!options.workspaceRetention?.requireCompleteProvenance || state.workspaceCoverageComplete)) state.workspacePreservationRequired = false;
|
|
10336
|
-
},
|
|
10337
|
-
captureWorkspace: (next, outcome) => captureExecutorWorkspace(scope, next, outcome),
|
|
10338
|
-
workspaceControlRef: () => state.workspaceControlRef,
|
|
10339
|
-
workspaceProvenance: () => state.workspaceProvenance,
|
|
10340
|
-
workspaceCoverage: () => ({
|
|
10341
|
-
complete: state.workspaceCoverageComplete,
|
|
10342
|
-
incompleteReason: state.workspaceIncompleteReason
|
|
10343
|
-
})
|
|
9779
|
+
}
|
|
10344
9780
|
};
|
|
10345
9781
|
}
|
|
10346
9782
|
/**
|
|
@@ -10350,12 +9786,8 @@ function invocationArgs(scope, invocation, signal, carried, executionStartedAt,
|
|
|
10350
9786
|
* resolving its unreceipted source.
|
|
10351
9787
|
*/
|
|
10352
9788
|
function beginWorkspaceExecution(scope) {
|
|
10353
|
-
const { state,
|
|
9789
|
+
const { state, provider } = scope;
|
|
10354
9790
|
if (state.workspaceRunActive) throw new ValidationError(`providerAsExecutor(${provider.name}): executor is already running`);
|
|
10355
|
-
if (options.workspaceRetention !== void 0) {
|
|
10356
|
-
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`);
|
|
10357
|
-
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`);
|
|
10358
|
-
}
|
|
10359
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`);
|
|
10360
9792
|
if (state.environment !== void 0 && state.destroyed) {
|
|
10361
9793
|
state.environment = void 0;
|
|
@@ -10371,7 +9803,7 @@ function beginWorkspaceExecution(scope) {
|
|
|
10371
9803
|
* same environment after the upstream refused a turn for capacity.
|
|
10372
9804
|
*/
|
|
10373
9805
|
async function* runProviderExecution(scope, task, signal, recovering = false) {
|
|
10374
|
-
const { state,
|
|
9806
|
+
const { state, retention } = scope;
|
|
10375
9807
|
beginWorkspaceExecution(scope);
|
|
10376
9808
|
const linked = linkAbort(scope.ctx.signal, signal, scope.controller.signal);
|
|
10377
9809
|
state.runSignal = linked.signal;
|
|
@@ -10395,7 +9827,6 @@ async function* runProviderExecution(scope, task, signal, recovering = false) {
|
|
|
10395
9827
|
state.resetWorkspace(state.environment, invocation.executionId);
|
|
10396
9828
|
state.workspaceControlRef = void 0;
|
|
10397
9829
|
state.providerSessionId = null;
|
|
10398
|
-
state.workspacePreservationRequired = options.workspaceRetention !== void 0;
|
|
10399
9830
|
}
|
|
10400
9831
|
const ended = yield* streamProviderExecutor(invocationArgs(scope, invocation, linked.signal, carried, executionStartedAt, continued));
|
|
10401
9832
|
const next = await pauseForContinuation(scope, invocation, ended, attempt, refusalsInARow, linked.signal);
|
|
@@ -10415,7 +9846,7 @@ async function pauseForContinuation(scope, invocation, ended, attempt, refusalsB
|
|
|
10415
9846
|
const { state, options, provider } = scope;
|
|
10416
9847
|
const refusal = ended.unavailable;
|
|
10417
9848
|
const continueInvocation = invocation.retention?.continueInvocation;
|
|
10418
|
-
if (refusal === void 0 || continueInvocation === void 0 || state.workspacePreservationRequired
|
|
9849
|
+
if (refusal === void 0 || continueInvocation === void 0 || state.workspacePreservationRequired) return;
|
|
10419
9850
|
const refusalsInARow = ended.madeProgress ? 1 : refusalsBefore + 1;
|
|
10420
9851
|
const now = Date.now();
|
|
10421
9852
|
const reset = unavailableResumeAt(reportedResetAt(refusal, now), now);
|
|
@@ -10468,18 +9899,9 @@ var ProviderExecutorState = class {
|
|
|
10468
9899
|
* environment is released or handed to the successor node. */
|
|
10469
9900
|
holdingForContinuation = false;
|
|
10470
9901
|
workspaceEnvironmentId;
|
|
10471
|
-
workspaceSnapshot;
|
|
10472
|
-
workspaceProvenance;
|
|
10473
|
-
workspaceCoverageComplete = false;
|
|
10474
|
-
workspaceIncompleteReason;
|
|
10475
|
-
workspacePublishedSnapshot;
|
|
10476
|
-
workspaceCaptureFailure;
|
|
10477
|
-
workspaceCapturePromise;
|
|
10478
9902
|
workspaceCleanupPromise;
|
|
10479
9903
|
retainedReleasePromise;
|
|
10480
9904
|
releaseReadTried = false;
|
|
10481
|
-
releaseNativeTried = false;
|
|
10482
|
-
workspaceOutcome;
|
|
10483
9905
|
workspacePreservationRequired = false;
|
|
10484
9906
|
workspaceRunActive = false;
|
|
10485
9907
|
providerSessionId = null;
|
|
@@ -10501,16 +9923,8 @@ var ProviderExecutorState = class {
|
|
|
10501
9923
|
}
|
|
10502
9924
|
/** Forget the capture generation: the next one owns its own snapshot, receipts and verdicts. */
|
|
10503
9925
|
clearWorkspaceCapture() {
|
|
10504
|
-
this.workspaceSnapshot = void 0;
|
|
10505
|
-
this.workspaceProvenance = void 0;
|
|
10506
|
-
this.workspaceCoverageComplete = false;
|
|
10507
|
-
this.workspaceIncompleteReason = void 0;
|
|
10508
|
-
this.workspacePublishedSnapshot = void 0;
|
|
10509
|
-
this.workspaceCaptureFailure = void 0;
|
|
10510
|
-
this.workspaceCapturePromise = void 0;
|
|
10511
9926
|
this.workspaceCleanupPromise = void 0;
|
|
10512
9927
|
this.retainedReleasePromise = void 0;
|
|
10513
|
-
this.workspaceOutcome = void 0;
|
|
10514
9928
|
this.workspacePreservationRequired = false;
|
|
10515
9929
|
this.destroyed = false;
|
|
10516
9930
|
}
|
|
@@ -10572,9 +9986,87 @@ function providerMaterialization(provider, createProfile, node, executionId, ret
|
|
|
10572
9986
|
}
|
|
10573
9987
|
};
|
|
10574
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;
|
|
10575
10068
|
// src/runtime/environment-provider/provider-executor-lifecycle.ts
|
|
10576
10069
|
function createProviderExecutor(provider, profile, ctx, options, placement) {
|
|
10577
|
-
if (options.workspaceRetention !== void 0) assertProviderWorkspaceRetentionPort(options.workspaceRetention, `providerAsExecutor(${provider.name})`);
|
|
10578
10070
|
const node = detachedSnapshot(ctx.node, "provider executor node");
|
|
10579
10071
|
const retention = retainedExecutorContext(ctx);
|
|
10580
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");
|
|
@@ -10599,7 +10091,6 @@ function createProviderExecutor(provider, profile, ctx, options, placement) {
|
|
|
10599
10091
|
state,
|
|
10600
10092
|
controller: new AbortController(),
|
|
10601
10093
|
nativeControl: createProviderNativeControl(provider, retention, managerStop, state),
|
|
10602
|
-
mirrors: createProviderCaptureMirrors(options, createProfile, node, state),
|
|
10603
10094
|
trace: createPushTraceSource({ runId: executionId }),
|
|
10604
10095
|
materialization: providerMaterialization(provider, createProfile, node, executionId, retention, options, placement),
|
|
10605
10096
|
continuationTask: LEAF_CONTINUATION_TASK,
|
|
@@ -10655,17 +10146,13 @@ async function cancelExecution(scope, request) {
|
|
|
10655
10146
|
};
|
|
10656
10147
|
}
|
|
10657
10148
|
async function teardownExecution(scope) {
|
|
10658
|
-
const { state
|
|
10149
|
+
const { state } = scope;
|
|
10659
10150
|
scope.controller.abort();
|
|
10660
10151
|
if (state.holdingForContinuation) return {
|
|
10661
10152
|
destroyed: false,
|
|
10662
10153
|
detail: "environment held for a keyed continuation after a budget stop"
|
|
10663
10154
|
};
|
|
10664
10155
|
if (state.pending && state.cancelledExplicitly()) scope.nativeControl.stopNativeExecution();
|
|
10665
|
-
if (options.workspaceRetention !== void 0 && state.workspaceRunActive) return {
|
|
10666
|
-
destroyed: false,
|
|
10667
|
-
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"
|
|
10668
|
-
};
|
|
10669
10156
|
if (state.pending) return {
|
|
10670
10157
|
destroyed: false,
|
|
10671
10158
|
detail: "retained execution requires reconciliation",
|
|
@@ -10678,7 +10165,7 @@ function heldEnvironments(scope) {
|
|
|
10678
10165
|
if (state.destroyed) return [];
|
|
10679
10166
|
const environmentId = state.environment?.id ?? state.retained?.controlRef.environmentId ?? admittedEnvironmentId(scope.retention);
|
|
10680
10167
|
if (environmentId === void 0) return [];
|
|
10681
|
-
const preserved = state.workspacePreservationRequired
|
|
10168
|
+
const preserved = state.workspacePreservationRequired;
|
|
10682
10169
|
return [{
|
|
10683
10170
|
provider: scope.provider.name,
|
|
10684
10171
|
environmentId,
|
|
@@ -12093,7 +11580,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
12093
11580
|
const started = Date.now();
|
|
12094
11581
|
const linked = linkAbort(signal, controller.signal).signal;
|
|
12095
11582
|
recordRuntimeOwnedProviderAttemptStart(executor);
|
|
12096
|
-
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, {
|
|
12097
11584
|
...profileExecution.temperature !== void 0 ? { temperature: profileExecution.temperature } : {},
|
|
12098
11585
|
...linked ? { signal: linked } : {},
|
|
12099
11586
|
...profileExecution.toolChoice ? { toolChoice: profileExecution.toolChoice } : {},
|
|
@@ -12104,7 +11591,7 @@ const routerInlineExecutor = (spec, ctx) => {
|
|
|
12104
11591
|
...linked ? { signal: linked } : {},
|
|
12105
11592
|
...routerGenerationOptions(profileExecution),
|
|
12106
11593
|
...requestIdentity
|
|
12107
|
-
}));
|
|
11594
|
+
})));
|
|
12108
11595
|
if (r.model !== void 0) recordRuntimeOwnedProviderModel(executor, r.model);
|
|
12109
11596
|
transcript.reply({
|
|
12110
11597
|
content: r.content,
|
|
@@ -12586,6 +12073,13 @@ async function executeGranted(env, state, task, external, name, raw, context) {
|
|
|
12586
12073
|
name,
|
|
12587
12074
|
arguments: JSON.stringify(args)
|
|
12588
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
|
+
});
|
|
12589
12083
|
const startedAt = Date.now();
|
|
12590
12084
|
let status = "ok";
|
|
12591
12085
|
try {
|
|
@@ -12595,6 +12089,12 @@ async function executeGranted(env, state, task, external, name, raw, context) {
|
|
|
12595
12089
|
throw error;
|
|
12596
12090
|
} finally {
|
|
12597
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
|
+
});
|
|
12598
12098
|
try {
|
|
12599
12099
|
seam.onToolStep?.({
|
|
12600
12100
|
toolName: name,
|
|
@@ -12638,7 +12138,7 @@ async function requestModelTurn(env, state, actions, turn, signal, t) {
|
|
|
12638
12138
|
transcript.observe(state.messages);
|
|
12639
12139
|
try {
|
|
12640
12140
|
recordRuntimeOwnedProviderAttemptStart(env.executor);
|
|
12641
|
-
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, {
|
|
12642
12142
|
...profileExecution.temperature !== void 0 ? { temperature: profileExecution.temperature } : {},
|
|
12643
12143
|
signal: turn.controller.signal,
|
|
12644
12144
|
onResponse: async (receipt) => {
|
|
@@ -12649,7 +12149,7 @@ async function requestModelTurn(env, state, actions, turn, signal, t) {
|
|
|
12649
12149
|
...profileExecution.toolChoice ? { toolChoice: profileExecution.toolChoice } : {},
|
|
12650
12150
|
...routerGenerationOptions(profileExecution),
|
|
12651
12151
|
...routerTurnRequestIdentity(env.requestIdentity, t)
|
|
12652
|
-
});
|
|
12152
|
+
}));
|
|
12653
12153
|
turn.cleanup();
|
|
12654
12154
|
return res;
|
|
12655
12155
|
} catch (e) {
|
|
@@ -12723,12 +12223,27 @@ async function runToolCalls(env, state, actions, turn, external, task, toolCalls
|
|
|
12723
12223
|
name: toolName,
|
|
12724
12224
|
arguments: tc?.arguments ?? ""
|
|
12725
12225
|
});
|
|
12226
|
+
env.observation?.progress({
|
|
12227
|
+
kind: "tool_call",
|
|
12228
|
+
toolName,
|
|
12229
|
+
toolCallId: id
|
|
12230
|
+
});
|
|
12726
12231
|
if (!actions.modelToolNames.has(toolName)) {
|
|
12727
12232
|
state.messages.push({
|
|
12728
12233
|
role: "tool",
|
|
12729
12234
|
tool_call_id: id,
|
|
12730
12235
|
content: `error: tool ${JSON.stringify(toolName)} is not enabled by AgentProfile.tools`
|
|
12731
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
|
+
});
|
|
12732
12247
|
try {
|
|
12733
12248
|
env.seam.onToolStep?.({
|
|
12734
12249
|
toolName,
|
|
@@ -12747,6 +12262,16 @@ async function runToolCalls(env, state, actions, turn, external, task, toolCalls
|
|
|
12747
12262
|
tool_call_id: id,
|
|
12748
12263
|
content: "error: tool arguments were not valid JSON"
|
|
12749
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
|
+
});
|
|
12750
12275
|
continue;
|
|
12751
12276
|
}
|
|
12752
12277
|
let result;
|
|
@@ -12762,6 +12287,16 @@ async function runToolCalls(env, state, actions, turn, external, task, toolCalls
|
|
|
12762
12287
|
succeeded = false;
|
|
12763
12288
|
result = `error: ${e instanceof Error ? e.message : String(e)}`;
|
|
12764
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
|
+
});
|
|
12765
12300
|
const projected = succeeded && actions.codeMode && toolName === "codemode" ? codeModeModelOutput(result) : void 0;
|
|
12766
12301
|
if (projected) images.push(...projected.images);
|
|
12767
12302
|
state.messages.push({
|
|
@@ -12884,6 +12419,7 @@ const routerToolsInlineExecutor = (spec, ctx) => {
|
|
|
12884
12419
|
async execute(task, signal) {
|
|
12885
12420
|
artifact = await runRouterToolLoop({
|
|
12886
12421
|
seam,
|
|
12422
|
+
observation: executorObservation(ctx),
|
|
12887
12423
|
spec,
|
|
12888
12424
|
model,
|
|
12889
12425
|
profileExecution,
|
|
@@ -13173,125 +12709,6 @@ const TERMINAL_DECISIONS = [
|
|
|
13173
12709
|
function isTerminalDecision(decision) {
|
|
13174
12710
|
return TERMINAL_DECISIONS.includes(decision);
|
|
13175
12711
|
}
|
|
13176
|
-
// src/runtime/sandbox-evidence-retention.ts
|
|
13177
|
-
/** A failed capture keeps the live source handle available for an explicit retry. */
|
|
13178
|
-
var SandboxEvidenceRetentionError = class extends Error {
|
|
13179
|
-
box;
|
|
13180
|
-
constructor(box, cause) {
|
|
13181
|
-
super(`Sandbox evidence retention failed for box ${String(box.id)}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
13182
|
-
this.name = "SandboxEvidenceRetentionError";
|
|
13183
|
-
this.box = box;
|
|
13184
|
-
}
|
|
13185
|
-
};
|
|
13186
|
-
/** Capture, verify, durably record, then destroy. A failure leaves the source intact. */
|
|
13187
|
-
async function captureBeforeDestroy(port, context, destroy) {
|
|
13188
|
-
const environment = {
|
|
13189
|
-
id: String(context.box.id),
|
|
13190
|
-
provider: "sandbox"
|
|
13191
|
-
};
|
|
13192
|
-
const result = await captureProviderWorkspaceSnapshot({
|
|
13193
|
-
timeoutMs: port.timeoutMs,
|
|
13194
|
-
...port.limits === void 0 ? {} : { limits: port.limits },
|
|
13195
|
-
artifacts: port.artifacts,
|
|
13196
|
-
capture: ({ signal }) => port.capture({
|
|
13197
|
-
...context,
|
|
13198
|
-
signal
|
|
13199
|
-
})
|
|
13200
|
-
}, {
|
|
13201
|
-
environment,
|
|
13202
|
-
executionId: context.executionId,
|
|
13203
|
-
providerSessionId: context.sandboxSessionIds[0] ?? null,
|
|
13204
|
-
nativeSessionId: null,
|
|
13205
|
-
profile: context.profile
|
|
13206
|
-
});
|
|
13207
|
-
const missing = context.sandboxSessionIds.filter((id) => !result.provenance.sessions?.some((session) => session.id === id && session.executionId === context.executionId));
|
|
13208
|
-
for (const nativeId of context.nativeSessionIds ?? []) if (!result.provenance.sessions?.some((session) => session.nativeSessionId === nativeId)) missing.push(`native/${nativeId}`);
|
|
13209
|
-
for (const sessionId of context.sandboxSessionIds) if ((context.sessionExecutionIds[sessionId]?.length ?? 0) === 0) missing.push(`${sessionId}/execution-id-unobserved`);
|
|
13210
|
-
for (const [sessionId, executionIds] of Object.entries(context.sessionExecutionIds)) {
|
|
13211
|
-
const session = result.provenance.sessions?.find((item) => item.id === sessionId);
|
|
13212
|
-
for (const executionId of executionIds) if (!session?.executionIds?.includes(executionId) || !session.eventCountsByExecutionId?.[executionId]) missing.push(`${sessionId}/${executionId}`);
|
|
13213
|
-
}
|
|
13214
|
-
const coverageComplete = result.coverageComplete === true && missing.length === 0;
|
|
13215
|
-
const incompleteReason = coverageComplete ? void 0 : [result.incompleteReason, ...missing.map((id) => `Sandbox session ${id} missing from capture`)].filter((reason) => reason !== void 0).join("; ");
|
|
13216
|
-
const receipt = {
|
|
13217
|
-
boxId: String(context.box.id),
|
|
13218
|
-
executionId: context.executionId,
|
|
13219
|
-
profileDigest: canonicalAgentProfileDigest(context.profile),
|
|
13220
|
-
scope: "box",
|
|
13221
|
-
sandboxSessionIds: [...context.sandboxSessionIds],
|
|
13222
|
-
...context.nativeSessionIds === void 0 ? {} : { nativeSessionIds: [...context.nativeSessionIds] },
|
|
13223
|
-
sessionExecutionIds: Object.fromEntries(Object.entries(context.sessionExecutionIds).map(([id, executions]) => [id, [...executions]])),
|
|
13224
|
-
snapshot: result.snapshot,
|
|
13225
|
-
provenance: result.provenance,
|
|
13226
|
-
coverageComplete,
|
|
13227
|
-
...incompleteReason === void 0 ? {} : { incompleteReason }
|
|
13228
|
-
};
|
|
13229
|
-
await port.record(receipt);
|
|
13230
|
-
if (!coverageComplete) throw new Error(incompleteReason ?? "Sandbox evidence coverage incomplete");
|
|
13231
|
-
await destroy();
|
|
13232
|
-
return receipt;
|
|
13233
|
-
}
|
|
13234
|
-
/** Execution-scoped inventory of every Sandbox session and turn observed by a loop. */
|
|
13235
|
-
var SandboxEvidenceTracker = class {
|
|
13236
|
-
port;
|
|
13237
|
-
runId;
|
|
13238
|
-
boxes = /* @__PURE__ */ new Map();
|
|
13239
|
-
constructor(port, runId) {
|
|
13240
|
-
this.port = port;
|
|
13241
|
-
this.runId = runId;
|
|
13242
|
-
if (!Number.isSafeInteger(port.timeoutMs) || port.timeoutMs <= 0) throw new ValidationError$1("Sandbox evidence retention.timeoutMs must be a positive safe integer");
|
|
13243
|
-
if (typeof port.artifacts?.read !== "function") throw new ValidationError$1("Sandbox evidence retention.artifacts.read is required");
|
|
13244
|
-
if (typeof port.capture !== "function") throw new ValidationError$1("Sandbox evidence retention.capture is required");
|
|
13245
|
-
if (typeof port.record !== "function") throw new ValidationError$1("Sandbox evidence retention.record is required");
|
|
13246
|
-
}
|
|
13247
|
-
register(box, profile, sessionId) {
|
|
13248
|
-
let state = this.boxes.get(box);
|
|
13249
|
-
if (state === void 0) {
|
|
13250
|
-
state = {
|
|
13251
|
-
profile,
|
|
13252
|
-
sessions: /* @__PURE__ */ new Map()
|
|
13253
|
-
};
|
|
13254
|
-
this.boxes.set(box, state);
|
|
13255
|
-
}
|
|
13256
|
-
if (sessionId !== void 0 && !state.sessions.has(sessionId)) state.sessions.set(sessionId, /* @__PURE__ */ new Set());
|
|
13257
|
-
}
|
|
13258
|
-
recordDispatch(box, sessionId, executionId) {
|
|
13259
|
-
const state = this.boxes.get(box);
|
|
13260
|
-
if (state === void 0) throw new Error("Sandbox evidence dispatched before box registration");
|
|
13261
|
-
const executions = state.sessions.get(sessionId) ?? /* @__PURE__ */ new Set();
|
|
13262
|
-
executions.add(executionId);
|
|
13263
|
-
state.sessions.set(sessionId, executions);
|
|
13264
|
-
}
|
|
13265
|
-
observe(box, event, sessionHint) {
|
|
13266
|
-
const state = this.boxes.get(box);
|
|
13267
|
-
if (state === void 0) throw new Error("Sandbox evidence observed before box registration");
|
|
13268
|
-
const sessionId = typeof event.data.runtimeSessionId === "string" ? event.data.runtimeSessionId : sessionHint;
|
|
13269
|
-
if (sessionId === void 0) return;
|
|
13270
|
-
const executions = state.sessions.get(sessionId) ?? /* @__PURE__ */ new Set();
|
|
13271
|
-
if (typeof event.data.executionId === "string") executions.add(event.data.executionId);
|
|
13272
|
-
state.sessions.set(sessionId, executions);
|
|
13273
|
-
}
|
|
13274
|
-
async destroy(box) {
|
|
13275
|
-
const state = this.boxes.get(box);
|
|
13276
|
-
if (state === void 0) throw new Error(`Sandbox evidence has no registered source ${String(box.id)}`);
|
|
13277
|
-
const sandboxSessionIds = [...state.sessions.keys()].sort();
|
|
13278
|
-
const sessionExecutionIds = Object.fromEntries([...state.sessions.entries()].map(([id, executions]) => [id, [...executions].sort()]));
|
|
13279
|
-
try {
|
|
13280
|
-
await captureBeforeDestroy(this.port, {
|
|
13281
|
-
box,
|
|
13282
|
-
executionId: this.runId,
|
|
13283
|
-
profile: state.profile,
|
|
13284
|
-
sandboxSessionIds,
|
|
13285
|
-
sessionExecutionIds
|
|
13286
|
-
}, async () => {
|
|
13287
|
-
await box.delete();
|
|
13288
|
-
});
|
|
13289
|
-
this.boxes.delete(box);
|
|
13290
|
-
} catch (error) {
|
|
13291
|
-
throw new SandboxEvidenceRetentionError(box, error);
|
|
13292
|
-
}
|
|
13293
|
-
}
|
|
13294
|
-
};
|
|
13295
12712
|
// src/runtime/sandbox-acquire.ts
|
|
13296
12713
|
/**
|
|
13297
12714
|
* HTTP statuses where create should be retried — gateway timeouts
|
|
@@ -13336,20 +12753,14 @@ async function acquireSandbox(client, options, acquire = {}) {
|
|
|
13336
12753
|
while (now() < deadline) {
|
|
13337
12754
|
throwIfAborted(acquire.signal);
|
|
13338
12755
|
try {
|
|
13339
|
-
|
|
13340
|
-
acquire.onAcquire?.(box);
|
|
13341
|
-
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);
|
|
13342
12757
|
} catch (err) {
|
|
13343
|
-
if (err instanceof SandboxEvidenceRetentionError) throw err;
|
|
13344
12758
|
throwIfAborted(acquire.signal);
|
|
13345
12759
|
if (!isRetryable(err)) throw err;
|
|
13346
12760
|
lastErr = err;
|
|
13347
12761
|
if (typeof c.list === "function") for (let scan = 0; scan < appearScans && now() < deadline; scan += 1) {
|
|
13348
12762
|
const found = (await c.list().catch(() => []))?.find((b) => b.name === name);
|
|
13349
|
-
if (found)
|
|
13350
|
-
acquire.onAcquire?.(found);
|
|
13351
|
-
return await waitReadyOrDestroy(found, deadline, pollMs, acquire.signal, now, sleep$1, acquire.beforeDelete);
|
|
13352
|
-
}
|
|
12763
|
+
if (found) return await waitReadyOrDestroy(found, deadline, pollMs, acquire.signal, now, sleep$1);
|
|
13353
12764
|
if (scan < 4) await sleep$1(pollMs);
|
|
13354
12765
|
}
|
|
13355
12766
|
attempt += 1;
|
|
@@ -13360,12 +12771,11 @@ async function acquireSandbox(client, options, acquire = {}) {
|
|
|
13360
12771
|
}
|
|
13361
12772
|
/** `waitUntilReady`, tearing the box down (best-effort) on any throw so a box
|
|
13362
12773
|
* that never reaches `running` (abort, terminal status, budget) does not leak. */
|
|
13363
|
-
async function waitReadyOrDestroy(box, deadline, pollMs, signal, now, sleep
|
|
12774
|
+
async function waitReadyOrDestroy(box, deadline, pollMs, signal, now, sleep) {
|
|
13364
12775
|
try {
|
|
13365
12776
|
return await waitUntilReady(box, deadline, pollMs, signal, now, sleep);
|
|
13366
12777
|
} catch (err) {
|
|
13367
|
-
|
|
13368
|
-
else await beforeDelete(box);
|
|
12778
|
+
await deleteBoxSafe(box);
|
|
13369
12779
|
throw err;
|
|
13370
12780
|
}
|
|
13371
12781
|
}
|
|
@@ -13547,14 +12957,9 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13547
12957
|
const profiles = /* @__PURE__ */ new Map();
|
|
13548
12958
|
const acquireFresh = async (spec, signal) => {
|
|
13549
12959
|
if (signal.aborted) throwAbort();
|
|
13550
|
-
const box = await acquireSandbox(client, buildBackendOptions(spec.profile, spec.sandboxOverrides), {
|
|
13551
|
-
signal,
|
|
13552
|
-
...options.onAcquire === void 0 ? {} : { onAcquire: (source) => options.onAcquire?.(source, spec.profile) },
|
|
13553
|
-
...options.beforeDelete === void 0 ? {} : { beforeDelete: options.beforeDelete }
|
|
13554
|
-
});
|
|
12960
|
+
const box = await acquireSandbox(client, buildBackendOptions(spec.profile, spec.sandboxOverrides), { signal });
|
|
13555
12961
|
owned.push(box);
|
|
13556
12962
|
profiles.set(box, spec.profile);
|
|
13557
|
-
options.onAcquire?.(box, spec.profile);
|
|
13558
12963
|
try {
|
|
13559
12964
|
await spec.prepareBox?.(box, {
|
|
13560
12965
|
signal,
|
|
@@ -13562,7 +12967,7 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13562
12967
|
});
|
|
13563
12968
|
} catch (error) {
|
|
13564
12969
|
try {
|
|
13565
|
-
await destroyBounded(box, options.failOnDestroyError
|
|
12970
|
+
await destroyBounded(box, options.failOnDestroyError);
|
|
13566
12971
|
owned.splice(owned.indexOf(box), 1);
|
|
13567
12972
|
} catch (captureError) {
|
|
13568
12973
|
throw new AggregateError([error, captureError], "Sandbox preparation and evidence cleanup failed");
|
|
@@ -13601,19 +13006,13 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13601
13006
|
if (branched !== void 0) {
|
|
13602
13007
|
owned.push(...branched);
|
|
13603
13008
|
const inheritedProfile = profiles.get(parent.box);
|
|
13604
|
-
if (inheritedProfile !== void 0) for (const box of branched)
|
|
13605
|
-
profiles.set(box, inheritedProfile);
|
|
13606
|
-
options.onAcquire?.(box, inheritedProfile);
|
|
13607
|
-
}
|
|
13009
|
+
if (inheritedProfile !== void 0) for (const box of branched) profiles.set(box, inheritedProfile);
|
|
13608
13010
|
if (branched.length !== prompts.length) throw new ValidationError$1(`SandboxLineage.fork: Sandbox returned ${branched.length} of ${prompts.length} requested children`);
|
|
13609
13011
|
return mapWithConcurrency(branched, forkConcurrency, async (box, i) => {
|
|
13610
13012
|
throwIfAborted(signal);
|
|
13611
13013
|
const spec = specs[i % specs.length];
|
|
13612
13014
|
if (!spec) throw new ValidationError$1("SandboxLineage.fork: no AgentRunSpec for branch");
|
|
13613
|
-
if (inheritedProfile === void 0)
|
|
13614
|
-
profiles.set(box, spec.profile);
|
|
13615
|
-
options.onAcquire?.(box, spec.profile);
|
|
13616
|
-
}
|
|
13015
|
+
if (inheritedProfile === void 0) profiles.set(box, spec.profile);
|
|
13617
13016
|
await spec.prepareBox?.(box, {
|
|
13618
13017
|
signal,
|
|
13619
13018
|
recordMount
|
|
@@ -13650,7 +13049,7 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13650
13049
|
const doomed = [];
|
|
13651
13050
|
for (const box of owned) (keepBoxes.has(box) ? survivors : doomed).push(box);
|
|
13652
13051
|
if (doomed.length === 0) return;
|
|
13653
|
-
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)));
|
|
13654
13053
|
const failed = results.flatMap((result, index) => result.status === "rejected" ? [doomed[index]] : []);
|
|
13655
13054
|
owned.length = 0;
|
|
13656
13055
|
owned.push(...survivors, ...failed);
|
|
@@ -13658,7 +13057,7 @@ function createSandboxLineage(client, options = {}) {
|
|
|
13658
13057
|
},
|
|
13659
13058
|
async teardown() {
|
|
13660
13059
|
const boxes = owned.splice(0, owned.length);
|
|
13661
|
-
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)));
|
|
13662
13061
|
const failed = results.flatMap((result, index) => result.status === "rejected" ? [boxes[index]] : []);
|
|
13663
13062
|
owned.push(...failed);
|
|
13664
13063
|
if (failed.length > 0) throw new AggregateError(results.filter((result) => result.status === "rejected").map((result) => result.reason), "Sandbox evidence capture failed before teardown");
|
|
@@ -13705,11 +13104,7 @@ async function assertSessionLive(box, sessionId) {
|
|
|
13705
13104
|
if (typeof session !== "function") return;
|
|
13706
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.`);
|
|
13707
13106
|
}
|
|
13708
|
-
async function destroyBounded(box, failOnError = false
|
|
13709
|
-
if (beforeDelete !== void 0) {
|
|
13710
|
-
await beforeDelete(box);
|
|
13711
|
-
return;
|
|
13712
|
-
}
|
|
13107
|
+
async function destroyBounded(box, failOnError = false) {
|
|
13713
13108
|
if (failOnError) {
|
|
13714
13109
|
await box.delete();
|
|
13715
13110
|
return;
|
|
@@ -13723,7 +13118,7 @@ async function destroyBounded(box, failOnError = false, beforeDelete) {
|
|
|
13723
13118
|
* Rejects the lineage + `onWorkerBox` combination: both claim the same
|
|
13724
13119
|
* box-ownership channel, and silently honoring one would leak or double-free.
|
|
13725
13120
|
*/
|
|
13726
|
-
async function setUpLineage(options, maxConcurrency, recordMount, promptOptions
|
|
13121
|
+
async function setUpLineage(options, maxConcurrency, recordMount, promptOptions) {
|
|
13727
13122
|
const lineageOpts = options.lineage;
|
|
13728
13123
|
if (!lineageOpts || !lineageOpts.sessionContinuity && !lineageOpts.forkFanout) return void 0;
|
|
13729
13124
|
if (options.onWorkerBox) throw new ValidationError$1("runAgentRounds: `lineage` and `onWorkerBox` both own worker boxes — pass only one");
|
|
@@ -13731,12 +13126,7 @@ async function setUpLineage(options, maxConcurrency, recordMount, promptOptions,
|
|
|
13731
13126
|
lineage: createSandboxLineage(options.ctx.sandboxClient, {
|
|
13732
13127
|
maxConcurrency,
|
|
13733
13128
|
streaming: lineageOpts.streaming,
|
|
13734
|
-
recordMount
|
|
13735
|
-
...evidenceTracker === void 0 ? {} : {
|
|
13736
|
-
failOnDestroyError: true,
|
|
13737
|
-
onAcquire: (box, profile) => evidenceTracker.register(box, profile),
|
|
13738
|
-
beforeDelete: (box) => evidenceTracker.destroy(box)
|
|
13739
|
-
}
|
|
13129
|
+
recordMount
|
|
13740
13130
|
}),
|
|
13741
13131
|
options: lineageOpts,
|
|
13742
13132
|
...promptOptions === void 0 ? {} : { promptOptions },
|
|
@@ -13757,12 +13147,7 @@ async function setUpLineage(options, maxConcurrency, recordMount, promptOptions,
|
|
|
13757
13147
|
* Round 0 (parentIndex undefined) always starts fresh — the independence of the
|
|
13758
13148
|
* first batch is preserved.
|
|
13759
13149
|
*/
|
|
13760
|
-
function planLineageRound(state, specs, slice, parentIndex, signal
|
|
13761
|
-
const executionIds = retainEvidence ? slice.map(() => randomUuid()) : [];
|
|
13762
|
-
const promptForOffset = (offset) => retainEvidence ? {
|
|
13763
|
-
...state.promptOptions ?? {},
|
|
13764
|
-
executionId: executionIds[offset]
|
|
13765
|
-
} : state.promptOptions;
|
|
13150
|
+
function planLineageRound(state, specs, slice, parentIndex, signal) {
|
|
13766
13151
|
const lineage = state.lineage;
|
|
13767
13152
|
const parent = parentIndex !== void 0 ? state.handles.get(parentIndex) : void 0;
|
|
13768
13153
|
const promptFor = (offset) => {
|
|
@@ -13777,9 +13162,8 @@ function planLineageRound(state, specs, slice, parentIndex, signal, retainEviden
|
|
|
13777
13162
|
};
|
|
13778
13163
|
if (slice.length === 1 && parent && state.options.sessionContinuity) return [{ async acquire() {
|
|
13779
13164
|
return {
|
|
13780
|
-
events: await lineage.continue(parent, promptFor(0), signal,
|
|
13781
|
-
handle: parent
|
|
13782
|
-
...retainEvidence ? { executionId: executionIds[0] } : {}
|
|
13165
|
+
events: await lineage.continue(parent, promptFor(0), signal, state.promptOptions),
|
|
13166
|
+
handle: parent
|
|
13783
13167
|
};
|
|
13784
13168
|
} }];
|
|
13785
13169
|
if (slice.length > 1 && parent && state.options.forkFanout) {
|
|
@@ -13787,23 +13171,17 @@ function planLineageRound(state, specs, slice, parentIndex, signal, retainEviden
|
|
|
13787
13171
|
const childSpecs = slice.map((_, offset) => specAt(offset));
|
|
13788
13172
|
let forked;
|
|
13789
13173
|
const ensureForked = () => {
|
|
13790
|
-
forked ??= lineage.fork(parent, prompts, childSpecs, signal, state.promptOptions
|
|
13174
|
+
forked ??= lineage.fork(parent, prompts, childSpecs, signal, state.promptOptions);
|
|
13791
13175
|
return forked;
|
|
13792
13176
|
};
|
|
13793
13177
|
return slice.map((_, offset) => ({ async acquire() {
|
|
13794
13178
|
const branch = (await ensureForked())[offset];
|
|
13795
13179
|
if (!branch) throw new ValidationError$1("runAgentRounds: lineage fork produced no branch for offset");
|
|
13796
|
-
return
|
|
13797
|
-
...branch,
|
|
13798
|
-
...retainEvidence ? { executionId: executionIds[offset] } : {}
|
|
13799
|
-
};
|
|
13180
|
+
return branch;
|
|
13800
13181
|
} }));
|
|
13801
13182
|
}
|
|
13802
13183
|
return slice.map((_, offset) => ({ async acquire() {
|
|
13803
|
-
return
|
|
13804
|
-
...await lineage.start(specAt(offset), promptFor(offset), signal, promptForOffset(offset)),
|
|
13805
|
-
...retainEvidence ? { executionId: executionIds[offset] } : {}
|
|
13806
|
-
};
|
|
13184
|
+
return await lineage.start(specAt(offset), promptFor(offset), signal, state.promptOptions);
|
|
13807
13185
|
} }));
|
|
13808
13186
|
}
|
|
13809
13187
|
/**
|
|
@@ -13908,22 +13286,14 @@ function readSandboxId(box) {
|
|
|
13908
13286
|
* loop kernel passes its per-run recorder; other callers (which have no
|
|
13909
13287
|
* `LoopResult` to attach to) omit it and the prepareBox recorder is a no-op.
|
|
13910
13288
|
*/
|
|
13911
|
-
async function createSandboxForSpec(client, spec, signal, recordMount
|
|
13289
|
+
async function createSandboxForSpec(client, spec, signal, recordMount) {
|
|
13912
13290
|
const opts = buildBackendOptions(spec.profile, spec.sandboxOverrides);
|
|
13913
13291
|
if (signal.aborted) throwAbort();
|
|
13914
|
-
const box = await acquireSandbox(client, opts, {
|
|
13915
|
-
signal,
|
|
13916
|
-
...evidenceTracker === void 0 ? {} : {
|
|
13917
|
-
onAcquire: (source) => evidenceTracker.register(source, spec.profile),
|
|
13918
|
-
beforeDelete: (source) => evidenceTracker.destroy(source)
|
|
13919
|
-
}
|
|
13920
|
-
});
|
|
13921
|
-
evidenceTracker?.register(box, spec.profile);
|
|
13292
|
+
const box = await acquireSandbox(client, opts, { signal });
|
|
13922
13293
|
try {
|
|
13923
13294
|
await invokePrepareBox(spec, box, signal, recordMount);
|
|
13924
13295
|
} catch (error) {
|
|
13925
|
-
|
|
13926
|
-
else await evidenceTracker.destroy(box);
|
|
13296
|
+
await deleteBoxSafe(box);
|
|
13927
13297
|
throw error;
|
|
13928
13298
|
}
|
|
13929
13299
|
return box;
|
|
@@ -14011,8 +13381,6 @@ async function executeIteration(args) {
|
|
|
14011
13381
|
};
|
|
14012
13382
|
try {
|
|
14013
13383
|
let stream;
|
|
14014
|
-
let sandboxSessionId;
|
|
14015
|
-
let dispatchedExecutionId;
|
|
14016
13384
|
const source = args.lineagePlan?.[args.item.index - args.baseIndex];
|
|
14017
13385
|
if (source) {
|
|
14018
13386
|
const acquired = await source.acquire();
|
|
@@ -14020,28 +13388,16 @@ async function executeIteration(args) {
|
|
|
14020
13388
|
boxAcquiredAt = args.now();
|
|
14021
13389
|
lineageOwned = true;
|
|
14022
13390
|
args.lineageState?.handles.set(args.item.index, acquired.handle);
|
|
14023
|
-
args.evidenceTracker?.register(box, spec.profile, acquired.handle.sessionId);
|
|
14024
13391
|
stream = acquired.events;
|
|
14025
|
-
sandboxSessionId = acquired.handle.sessionId;
|
|
14026
|
-
dispatchedExecutionId = acquired.executionId;
|
|
14027
13392
|
} else {
|
|
14028
|
-
box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal, args.recordMount
|
|
13393
|
+
box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal, args.recordMount);
|
|
14029
13394
|
boxAcquiredAt = args.now();
|
|
14030
13395
|
const prompt = spec.taskToPrompt(args.item.task);
|
|
14031
|
-
|
|
14032
|
-
sandboxSessionId = sandboxSessionIdForTurn;
|
|
14033
|
-
dispatchedExecutionId = args.evidenceTracker === void 0 ? void 0 : randomUuid();
|
|
14034
|
-
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, {
|
|
14035
13397
|
...args.promptOptions ?? {},
|
|
14036
|
-
executionId: dispatchedExecutionId
|
|
14037
|
-
};
|
|
14038
|
-
stream = args.streaming === "poll" ? promptEvents("poll", box, prompt, sandboxSessionIdForTurn ?? `${args.runId}-i${args.item.index}`, args.signal, promptOptions) : box.streamPrompt(prompt, {
|
|
14039
|
-
...promptOptions ?? {},
|
|
14040
|
-
...sandboxSessionIdForTurn === void 0 ? {} : { sessionId: sandboxSessionIdForTurn },
|
|
14041
13398
|
signal: args.signal
|
|
14042
13399
|
});
|
|
14043
13400
|
}
|
|
14044
|
-
if (box !== void 0 && sandboxSessionId !== void 0 && dispatchedExecutionId !== void 0) args.evidenceTracker?.recordDispatch(box, sandboxSessionId, dispatchedExecutionId);
|
|
14045
13401
|
const placement = describeSandboxPlacement(args.ctx.sandboxClient, box);
|
|
14046
13402
|
await emitTrace(args.ctx.traceEmitter, {
|
|
14047
13403
|
kind: "loop.iteration.dispatch",
|
|
@@ -14068,7 +13424,6 @@ async function executeIteration(args) {
|
|
|
14068
13424
|
try {
|
|
14069
13425
|
for await (const event of stream) {
|
|
14070
13426
|
collector.push(event);
|
|
14071
|
-
if (box !== void 0) args.evidenceTracker?.observe(box, event, source ? args.lineageState?.handles.get(args.item.index)?.sessionId : void 0);
|
|
14072
13427
|
outcomeTracker.observe(event);
|
|
14073
13428
|
notifySandboxEventObserver(event, args.ctx.onSandboxEvent, {
|
|
14074
13429
|
iterationIndex: args.item.index,
|
|
@@ -14128,7 +13483,7 @@ async function executeIteration(args) {
|
|
|
14128
13483
|
});
|
|
14129
13484
|
if (lineageOwned) {} else if (args.collectBox && box) args.collectBox(box);
|
|
14130
13485
|
else {
|
|
14131
|
-
const teardown =
|
|
13486
|
+
const teardown = await destroySandboxSafe(box, args.ctx.traceEmitter, args.runId, args.now);
|
|
14132
13487
|
if (boxAcquiredAt !== void 0 && teardown !== "no-delete-api") {
|
|
14133
13488
|
slot.boxLiveMs = Math.max(0, args.now() - boxAcquiredAt);
|
|
14134
13489
|
if (teardown !== "deleted") slot.boxLiveMsKnown = false;
|
|
@@ -14220,8 +13575,6 @@ async function runAgentRounds(options) {
|
|
|
14220
13575
|
const promptOptions = readPromptOptions(options.ctx.promptOptions, "runAgentRounds: ctx.promptOptions");
|
|
14221
13576
|
const now = options.now ?? Date.now;
|
|
14222
13577
|
const runId = options.runId ?? `loop-${randomSuffix()}`;
|
|
14223
|
-
if (options.evidenceRetention !== void 0 && options.onWorkerBox !== void 0) throw new ValidationError$1("runAgentRounds: evidenceRetention cannot cover sessions dispatched through onWorkerBox");
|
|
14224
|
-
const evidenceTracker = options.evidenceRetention === void 0 ? void 0 : new SandboxEvidenceTracker(options.evidenceRetention, runId);
|
|
14225
13578
|
const loopStart = now();
|
|
14226
13579
|
const driverName = options.driver.name ?? "driver";
|
|
14227
13580
|
const iterations = [];
|
|
@@ -14235,7 +13588,7 @@ async function runAgentRounds(options) {
|
|
|
14235
13588
|
ownedBoxes.push(box);
|
|
14236
13589
|
options.onWorkerBox?.(box);
|
|
14237
13590
|
} : void 0;
|
|
14238
|
-
const lineageState = await setUpLineage(options, maxConcurrency, recordMount, promptOptions
|
|
13591
|
+
const lineageState = await setUpLineage(options, maxConcurrency, recordMount, promptOptions);
|
|
14239
13592
|
emitRunLoopHook(options, {
|
|
14240
13593
|
target: "agent.run",
|
|
14241
13594
|
phase: "before",
|
|
@@ -14331,7 +13684,7 @@ async function runAgentRounds(options) {
|
|
|
14331
13684
|
tokenUsage: zeroTokenUsage()
|
|
14332
13685
|
});
|
|
14333
13686
|
}
|
|
14334
|
-
const lineagePlan = lineageState ? planLineageRound(lineageState, specs, slice, parentIndex, controller.signal
|
|
13687
|
+
const lineagePlan = lineageState ? planLineageRound(lineageState, specs, slice, parentIndex, controller.signal) : void 0;
|
|
14335
13688
|
await runBatch({
|
|
14336
13689
|
slice,
|
|
14337
13690
|
baseIndex,
|
|
@@ -14350,7 +13703,6 @@ async function runAgentRounds(options) {
|
|
|
14350
13703
|
collectBox,
|
|
14351
13704
|
lineagePlan,
|
|
14352
13705
|
lineageState,
|
|
14353
|
-
evidenceTracker,
|
|
14354
13706
|
recordMount,
|
|
14355
13707
|
...promptOptions === void 0 ? {} : { promptOptions }
|
|
14356
13708
|
});
|
|
@@ -14390,7 +13742,7 @@ async function runAgentRounds(options) {
|
|
|
14390
13742
|
return await decideAndFinalize(options, iterations, loopStart, now, runId, mounts);
|
|
14391
13743
|
} finally {
|
|
14392
13744
|
if (options.ctx.signal) options.ctx.signal.removeEventListener("abort", onOuterAbort);
|
|
14393
|
-
const cleanup = await Promise.allSettled(ownedBoxes.map((box) =>
|
|
13745
|
+
const cleanup = await Promise.allSettled(ownedBoxes.map((box) => destroySandboxSafe(box, options.ctx.traceEmitter, runId, now)));
|
|
14394
13746
|
if (options.onWorkerBox) options.onWorkerBox(void 0);
|
|
14395
13747
|
let lineageFailure;
|
|
14396
13748
|
try {
|
|
@@ -14449,7 +13801,6 @@ function sandboxSessionOutput(run) {
|
|
|
14449
13801
|
toolCalls: run.toolCalls,
|
|
14450
13802
|
...run.latestOutcome ? { outcome: run.latestOutcome } : {},
|
|
14451
13803
|
...run.usageFailure === void 0 ? {} : { tokensUnknownReason: run.usageFailure },
|
|
14452
|
-
...run.args.workspaceCaptures === void 0 ? {} : { workspaceCaptures: run.args.workspaceCaptures() },
|
|
14453
13804
|
...run.preservationFailure === void 0 ? {} : { preservationFailure: run.preservationFailure }
|
|
14454
13805
|
};
|
|
14455
13806
|
}
|
|
@@ -14922,7 +14273,6 @@ function sandboxExecutorForPath(spec, ctx, modelPath) {
|
|
|
14922
14273
|
harness,
|
|
14923
14274
|
sandboxClient: seam.sandboxClient,
|
|
14924
14275
|
failOnDestroyError: seam.failOnDestroyError,
|
|
14925
|
-
workspaceCaptures: seam.workspaceCaptures,
|
|
14926
14276
|
inbox,
|
|
14927
14277
|
taskToPrompt: (t) => taskToPrompt$1(t),
|
|
14928
14278
|
options: seam.steering,
|
|
@@ -14930,8 +14280,6 @@ function sandboxExecutorForPath(spec, ctx, modelPath) {
|
|
|
14930
14280
|
...Object.keys(traceEnv).length > 0 ? { traceEnv } : {},
|
|
14931
14281
|
contentRef
|
|
14932
14282
|
});
|
|
14933
|
-
const bindCaptureOutput = ctx.seams[sandboxCaptureOutputSeamKey];
|
|
14934
|
-
if (typeof bindCaptureOutput === "function") bindCaptureOutput(() => session.output());
|
|
14935
14283
|
return attestRuntimeOwnedExecutor({
|
|
14936
14284
|
runtime: "sandbox",
|
|
14937
14285
|
deliver: (m) => inbox.deliver(m),
|
|
@@ -15222,8 +14570,8 @@ function snapshotExecutorConfig(config, mode = "execution") {
|
|
|
15222
14570
|
}
|
|
15223
14571
|
case "provider": {
|
|
15224
14572
|
if (config.outputFormat !== void 0 && config.steering !== void 0) throw new ValidationError$1("createExecutor(provider): JSON output is not supported with steering");
|
|
15225
|
-
const { provider, registry, profileForCreate, taskToTurn, validator,
|
|
15226
|
-
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");
|
|
15227
14575
|
const snapshot = detachedSnapshot(decisionData, "createExecutor provider config");
|
|
15228
14576
|
const resolvedProvider = mode === "control" && typeof provider === "string" ? registry?.get(provider) ?? provider : resolveAgentEnvironmentProvider(provider, registry);
|
|
15229
14577
|
return Object.freeze({
|
|
@@ -15232,7 +14580,6 @@ function snapshotExecutorConfig(config, mode = "execution") {
|
|
|
15232
14580
|
...profileForCreate === void 0 ? {} : { profileForCreate },
|
|
15233
14581
|
...taskToTurn === void 0 ? {} : { taskToTurn },
|
|
15234
14582
|
...validator === void 0 ? {} : { validator },
|
|
15235
|
-
...workspaceRetention === void 0 ? {} : { workspaceRetention },
|
|
15236
14583
|
...shared === void 0 ? {} : { shared }
|
|
15237
14584
|
});
|
|
15238
14585
|
}
|
|
@@ -15240,7 +14587,6 @@ function snapshotExecutorConfig(config, mode = "execution") {
|
|
|
15240
14587
|
assertExactConfigKeys(config, /* @__PURE__ */ new Set([
|
|
15241
14588
|
"backend",
|
|
15242
14589
|
"failOnDestroyError",
|
|
15243
|
-
"workspaceCaptures",
|
|
15244
14590
|
"lineage",
|
|
15245
14591
|
"loopCtx",
|
|
15246
14592
|
"maxIterations",
|
|
@@ -15248,11 +14594,10 @@ function snapshotExecutorConfig(config, mode = "execution") {
|
|
|
15248
14594
|
"steering",
|
|
15249
14595
|
"validator"
|
|
15250
14596
|
]), "createExecutor sandbox config");
|
|
15251
|
-
const { sandboxClient, loopCtx, validator,
|
|
14597
|
+
const { sandboxClient, loopCtx, validator, ...decisionData } = config;
|
|
15252
14598
|
const port = {
|
|
15253
14599
|
sandboxClient,
|
|
15254
|
-
...validator === void 0 ? {} : { validator }
|
|
15255
|
-
...workspaceCaptures === void 0 ? {} : { workspaceCaptures }
|
|
14600
|
+
...validator === void 0 ? {} : { validator }
|
|
15256
14601
|
};
|
|
15257
14602
|
if (loopCtx === void 0) {
|
|
15258
14603
|
const snapshot = detachedSnapshot(decisionData, "createExecutor sandbox config");
|
|
@@ -15380,9 +14725,6 @@ function createExecutor(config) {
|
|
|
15380
14725
|
if (providerSeam.destroyOnSettle === false) throw new ValidationError$1("createExecutor(provider, steering): destroyOnSettle=false conflicts with the session-owned environment lifecycle");
|
|
15381
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");
|
|
15382
14727
|
const harness = requiredProviderProfileHarness(spec, providerSeam);
|
|
15383
|
-
const workspaceCaptures = [];
|
|
15384
|
-
let capturedOutput;
|
|
15385
|
-
const publishEvidence = retainedExecutorContext(seamed)?.onEvidence;
|
|
15386
14728
|
const sandboxClient = providerAsSandboxClient(provider, {
|
|
15387
14729
|
defaults: {
|
|
15388
14730
|
...providerSeam.defaults ?? {},
|
|
@@ -15390,34 +14732,14 @@ function createExecutor(config) {
|
|
|
15390
14732
|
signal: seamed.signal
|
|
15391
14733
|
},
|
|
15392
14734
|
requireTerminalEvent: providerSeam.requireTerminalEvent,
|
|
15393
|
-
requireSession: true
|
|
15394
|
-
...providerSeam.workspaceRetention === void 0 ? {} : {
|
|
15395
|
-
workspaceRetention: providerSeam.workspaceRetention,
|
|
15396
|
-
retentionIdentity: {
|
|
15397
|
-
executionId: seamed.node?.nodeId ?? `provider-run-${randomUUID()}`,
|
|
15398
|
-
profile: spec.profile,
|
|
15399
|
-
...seamed.node === void 0 ? {} : { node: seamed.node }
|
|
15400
|
-
},
|
|
15401
|
-
onWorkspaceCaptured: async (receipt) => {
|
|
15402
|
-
if (!workspaceCaptures.includes(receipt)) workspaceCaptures.push(receipt);
|
|
15403
|
-
if (publishEvidence !== void 0) {
|
|
15404
|
-
if (capturedOutput === void 0) throw new ValidationError$1("provider capture has no bound session output");
|
|
15405
|
-
await publishEvidence(capturedOutput());
|
|
15406
|
-
}
|
|
15407
|
-
}
|
|
15408
|
-
}
|
|
14735
|
+
requireSession: true
|
|
15409
14736
|
});
|
|
15410
14737
|
const providerCtx = {
|
|
15411
14738
|
...seamed,
|
|
15412
14739
|
seams: {
|
|
15413
14740
|
...seamed.seams,
|
|
15414
|
-
[sandboxCaptureOutputSeamKey]: (read) => {
|
|
15415
|
-
capturedOutput = read;
|
|
15416
|
-
},
|
|
15417
14741
|
[sandboxSeamKey]: {
|
|
15418
14742
|
sandboxClient,
|
|
15419
|
-
failOnDestroyError: providerSeam.workspaceRetention !== void 0,
|
|
15420
|
-
...providerSeam.workspaceRetention === void 0 ? {} : { workspaceCaptures: () => workspaceCaptures },
|
|
15421
14743
|
steering: providerSeam.steering,
|
|
15422
14744
|
...providerSeam.promptOptions === void 0 ? {} : { loopCtx: { promptOptions: providerSeam.promptOptions } }
|
|
15423
14745
|
}
|
|
@@ -15690,13 +15012,11 @@ const driverExecutorFactory = (rawSpec, ctx) => {
|
|
|
15690
15012
|
const unconfirmedDescendants = () => nestedScopeHeld === void 0 ? [] : unconfirmedTeardowns(nestedScopeHeld);
|
|
15691
15013
|
const closeActive = (reason) => {
|
|
15692
15014
|
if (active === void 0) return Promise.resolve();
|
|
15693
|
-
if (!active.
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
});
|
|
15699
|
-
}
|
|
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
|
+
});
|
|
15700
15020
|
return active.close;
|
|
15701
15021
|
};
|
|
15702
15022
|
const rollUp = (events) => {
|
|
@@ -15732,9 +15052,11 @@ const driverExecutorFactory = (rawSpec, ctx) => {
|
|
|
15732
15052
|
const ownedSpawn = ownedTreeRootSpawn(parentSpawn);
|
|
15733
15053
|
previouslyMetered = recovering ? sumMetered((parentEvents ?? []).filter((event) => event.id === seam.nodeId)) : zeroSpend();
|
|
15734
15054
|
await journal.beginTree(nestedRoot, (/* @__PURE__ */ new Date(0)).toISOString());
|
|
15735
|
-
|
|
15736
|
-
if (prior.length === 0)
|
|
15737
|
-
|
|
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");
|
|
15738
15060
|
else if (prior.length !== 1 && !recovering) throw new RetainedExecutionPendingError(new ValidationError$1("driverExecutor: interrupted nested execution requires recovery"), "nested-recovery");
|
|
15739
15061
|
if (recovering && (!spec.recoverExecutor || !seam.restore)) throw new RetainedExecutionPendingError(new ValidationError$1("driverExecutor: nested recovery has no original executor reconstruction"), "nested-recovery");
|
|
15740
15062
|
signal.throwIfAborted();
|
|
@@ -15769,8 +15091,7 @@ const driverExecutorFactory = (rawSpec, ctx) => {
|
|
|
15769
15091
|
}
|
|
15770
15092
|
const out = await runAbortable(() => driver.act(task, nestedScope), controller.signal, "driver aborted");
|
|
15771
15093
|
await finalizeScopeOwnerMaterialization(nestedScope);
|
|
15772
|
-
await closeActive(
|
|
15773
|
-
releaseManagerEnvironment(nestedScope).catch(() => void 0);
|
|
15094
|
+
await closeActive();
|
|
15774
15095
|
const events = await loadTreeEvents(journal, nestedRoot);
|
|
15775
15096
|
const childWork = rollUp(events);
|
|
15776
15097
|
const acceptedSubmission = spec.acceptedSubmission?.() === true;
|
|
@@ -15871,8 +15192,8 @@ function isTerminalAdmissionRefusal(error) {
|
|
|
15871
15192
|
const failure = error instanceof DriverAttemptsExhaustedError && error.stop === "terminal-error" ? error.cause : error;
|
|
15872
15193
|
return (isCredentialRefusal(failure) || failure instanceof RetainedExecutionPendingError && failure.phase === "admission" && failure.pendingCause === "request-rejected") && classifyDriverFailure(failure) === "terminal";
|
|
15873
15194
|
}
|
|
15874
|
-
async function closeNestedScope(scope
|
|
15875
|
-
|
|
15195
|
+
async function closeNestedScope(scope) {
|
|
15196
|
+
closeScopeAdmission(scope);
|
|
15876
15197
|
for (;;) if (await scope.next() === null) break;
|
|
15877
15198
|
await releaseHeldEnvironments(scope);
|
|
15878
15199
|
const view = scope.view;
|
|
@@ -15946,38 +15267,6 @@ function readNestedScopeSeam(ctx) {
|
|
|
15946
15267
|
function isAgent(value) {
|
|
15947
15268
|
return typeof value === "object" && value !== null && typeof value.act === "function" && typeof value.name === "string";
|
|
15948
15269
|
}
|
|
15949
|
-
/** Parent journals may already contain an interrupted driver's inference prefix. */
|
|
15950
|
-
function unreportedSpend(total, prior) {
|
|
15951
|
-
const tokens = { ...total.tokens };
|
|
15952
|
-
for (const key of [
|
|
15953
|
-
"input",
|
|
15954
|
-
"output",
|
|
15955
|
-
"freshInput",
|
|
15956
|
-
"cacheRead",
|
|
15957
|
-
"cacheWrite"
|
|
15958
|
-
]) {
|
|
15959
|
-
const value = total.tokens[key];
|
|
15960
|
-
if (value !== void 0) tokens[key] = Math.max(0, value - (prior.tokens[key] ?? 0));
|
|
15961
|
-
}
|
|
15962
|
-
return {
|
|
15963
|
-
...total,
|
|
15964
|
-
...addResourceSpend(total.resources === void 0 ? void 0 : Object.fromEntries(Object.entries(total.resources).map(([name, value]) => {
|
|
15965
|
-
const previous = prior.resources?.[name];
|
|
15966
|
-
if (previous && previous.unit !== value.unit) throw new ValidationError$1(`resource ${name}: unit mismatch`);
|
|
15967
|
-
return [name, {
|
|
15968
|
-
...value,
|
|
15969
|
-
amount: Math.max(0, value.amount - (previous?.amount ?? 0)),
|
|
15970
|
-
known: value.known && (previous?.known ?? true)
|
|
15971
|
-
}];
|
|
15972
|
-
}))),
|
|
15973
|
-
iterations: Math.max(0, total.iterations - prior.iterations),
|
|
15974
|
-
tokens,
|
|
15975
|
-
usd: Math.max(0, total.usd - prior.usd),
|
|
15976
|
-
ms: Math.max(0, total.ms - prior.ms),
|
|
15977
|
-
...total.usdEstimated === void 0 ? {} : { usdEstimated: Math.max(0, total.usdEstimated - (prior.usdEstimated ?? 0)) },
|
|
15978
|
-
...total.boxMinutes === void 0 ? {} : { boxMinutes: Math.max(0, total.boxMinutes - (prior.boxMinutes ?? 0)) }
|
|
15979
|
-
};
|
|
15980
|
-
}
|
|
15981
15270
|
// src/runtime/supervise/supervisor-root-handle.ts
|
|
15982
15271
|
/** Module-private channel from a minted `RootHandle` to its `RootControl`, so `attach`
|
|
15983
15272
|
* can prove a handle is ours and reach its binding without leaking the control onto the
|
|
@@ -17031,7 +16320,7 @@ function guardRunPersistence(journal, blobs, interrupt) {
|
|
|
17031
16320
|
/** Read every caller-owned field once, then detach and freeze all decision data before the first
|
|
17032
16321
|
* await; stateful collaborators stay live by reference, but later opts mutation cannot redirect the run. */
|
|
17033
16322
|
function admitSupervisorRun(task, opts) {
|
|
17034
|
-
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;
|
|
17035
16324
|
const input = detachedSnapshot({
|
|
17036
16325
|
task,
|
|
17037
16326
|
options: {
|
|
@@ -17049,7 +16338,6 @@ function admitSupervisorRun(task, opts) {
|
|
|
17049
16338
|
...teardownConfirmMs === void 0 ? {} : { teardownConfirmMs },
|
|
17050
16339
|
...resume === void 0 ? {} : { resume },
|
|
17051
16340
|
...requestedRetainedAtSettlement === void 0 ? {} : { retainedAtSettlement: requestedRetainedAtSettlement },
|
|
17052
|
-
...ownerWorkspaceRetention === void 0 ? {} : { ownerWorkspaceRetention },
|
|
17053
16341
|
...interactiveBindingDir === void 0 ? {} : { interactiveBindingDir }
|
|
17054
16342
|
}
|
|
17055
16343
|
}, "supervisor.run");
|
|
@@ -17080,7 +16368,6 @@ function admitSupervisorRun(task, opts) {
|
|
|
17080
16368
|
slots,
|
|
17081
16369
|
controller,
|
|
17082
16370
|
persistence,
|
|
17083
|
-
ownerWorkspaceRetention,
|
|
17084
16371
|
deadlineCheckIn,
|
|
17085
16372
|
budgetStopHoldMs
|
|
17086
16373
|
};
|
|
@@ -17098,6 +16385,7 @@ async function joinRunChildren(join, settleGraceMs) {
|
|
|
17098
16385
|
await releaseHeldEnvironments(scope);
|
|
17099
16386
|
join.teardownUnconfirmed = unconfirmedTeardowns(scope);
|
|
17100
16387
|
await settleManagerWork(scope);
|
|
16388
|
+
join.teardownUnconfirmed = unconfirmedTeardowns(scope);
|
|
17101
16389
|
if (!persistence.failed && join.retainedAtSettlement === "release") join.teardownUnconfirmed = await releaseRetainedEnvironments(scope);
|
|
17102
16390
|
const releasing = !persistence.failed && join.retainedAtSettlement === "release";
|
|
17103
16391
|
await confirmRetriableTeardowns(join, releasing);
|
|
@@ -17141,6 +16429,7 @@ async function unrecoveredRetainedChildren(join) {
|
|
|
17141
16429
|
const unconfirmed = new Map([...join.teardownUnconfirmed, ...unrecovered].map((node) => [node.id, node]));
|
|
17142
16430
|
if (resumeFrom === void 0 || !(join.opts.signal?.reason instanceof RunCancellationReason)) return [...unconfirmed.values()];
|
|
17143
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));
|
|
17144
16433
|
const destroyed = /* @__PURE__ */ new Map();
|
|
17145
16434
|
const confirmed = /* @__PURE__ */ new Map();
|
|
17146
16435
|
const refs = /* @__PURE__ */ new Map();
|
|
@@ -17185,7 +16474,7 @@ async function unrecoveredRetainedChildren(join) {
|
|
|
17185
16474
|
held.set(key, custody);
|
|
17186
16475
|
refs.set(event.id, held);
|
|
17187
16476
|
}
|
|
17188
|
-
const discharged = (id, key, custody) => [...custody.admissions.values()].every((admission) => [...destroyed.get(key) ?? [], ...confirmed.get(id) ?? []].some((proof) => later(proof, admission)));
|
|
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)));
|
|
17189
16478
|
const unknown = new Set([...pending.values()].filter(({ id, position }) => !(confirmed.get(id) ?? []).some((proof) => later(proof, position))).map(({ id }) => id));
|
|
17190
16479
|
for (const [id, node] of unconfirmed) {
|
|
17191
16480
|
if (node.attempts !== 0 || node.environments?.length || !node.kept?.length || unknown.has(id)) continue;
|
|
@@ -17236,12 +16525,7 @@ async function confirmRetriableTeardowns(join, releasing) {
|
|
|
17236
16525
|
const still = new Set(join.teardownUnconfirmed.map((node) => node.id));
|
|
17237
16526
|
for (const node of pending) {
|
|
17238
16527
|
if (still.has(node.id)) continue;
|
|
17239
|
-
await opts.journal
|
|
17240
|
-
kind: "teardown-confirmed",
|
|
17241
|
-
id: node.id,
|
|
17242
|
-
seq: join.teardownSeq++,
|
|
17243
|
-
at: new Date(join.now()).toISOString()
|
|
17244
|
-
});
|
|
16528
|
+
await appendTeardownConfirmation(opts.journal, opts.runId, node.id, new Date(join.now()).toISOString());
|
|
17245
16529
|
}
|
|
17246
16530
|
}
|
|
17247
16531
|
// src/runtime/supervise/supervisor-run-tree.ts
|
|
@@ -17344,10 +16628,7 @@ function createSupervisor() {
|
|
|
17344
16628
|
const scope = createRootScope(intake, opened, journal, now);
|
|
17345
16629
|
const openScope = scope;
|
|
17346
16630
|
const ownerControl = runtimeOwnedScopeOwnerControl(root);
|
|
17347
|
-
if (ownerControl !== void 0)
|
|
17348
|
-
bindScopeRetainedOwnerProvider(openScope, ownerControl.provider, ownerControl.checkpointCapture);
|
|
17349
|
-
bindScopeRetainedOwnerWorkspaceRetention(openScope, ownerControl.checkpointCapture !== void 0);
|
|
17350
|
-
}
|
|
16631
|
+
if (ownerControl !== void 0) bindScopeRetainedOwnerProvider(openScope, ownerControl.provider);
|
|
17351
16632
|
if (rootLease) rootLease.bind({
|
|
17352
16633
|
scope: openScope,
|
|
17353
16634
|
cascadeAbort: (reason) => cascade.abort(new RunCancellationReason("root-handle", reason ?? "root handle aborted")),
|
|
@@ -17429,7 +16710,7 @@ function createRootScope(intake, opened, journal, now) {
|
|
|
17429
16710
|
journal,
|
|
17430
16711
|
blobs: opts.blobs,
|
|
17431
16712
|
executors: opts.executors,
|
|
17432
|
-
seams: {
|
|
16713
|
+
seams: {},
|
|
17433
16714
|
depth: 0,
|
|
17434
16715
|
maxDepth: opts.maxDepth ?? 16,
|
|
17435
16716
|
workerSlots: intake.slots,
|
|
@@ -17643,4 +16924,4 @@ async function noWinner(settled, rejection) {
|
|
|
17643
16924
|
}
|
|
17644
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 };
|
|
17645
16926
|
|
|
17646
|
-
//# sourceMappingURL=supervisor-
|
|
16927
|
+
//# sourceMappingURL=supervisor-B6sl14OR.js.map
|