@tangle-network/agent-runtime 0.138.1 → 0.139.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{activation-AyIFaunX.js → activation-eLJ6uRlP.js} +3 -3
- package/dist/{activation-AyIFaunX.js.map → activation-eLJ6uRlP.js.map} +1 -1
- package/dist/agent.d.ts +4 -4
- package/dist/agent.js +3 -3
- package/dist/{analyst-loop-Dk6_xfhI.js → analyst-loop-DtOEXGzR.js} +3 -3
- package/dist/{analyst-loop-Dk6_xfhI.js.map → analyst-loop-DtOEXGzR.js.map} +1 -1
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/analyst-loop.js +1 -1
- package/dist/{authoring-Cw6Ufsng.js → authoring-J93uFAwd.js} +3 -3
- package/dist/{authoring-Cw6Ufsng.js.map → authoring-J93uFAwd.js.map} +1 -1
- package/dist/candidate-execution/index.d.ts +3 -3
- package/dist/candidate-execution/index.js +4 -4
- package/dist/{candidate-execution-CN2hO-og.js → candidate-execution-uuUeFSc6.js} +5 -5
- package/dist/{candidate-execution-CN2hO-og.js.map → candidate-execution-uuUeFSc6.js.map} +1 -1
- package/dist/{conversation-DIUtiLkC.js → conversation-C3eZCvLd.js} +8 -6
- package/dist/conversation-C3eZCvLd.js.map +1 -0
- package/dist/conversation.d.ts +1 -1
- package/dist/conversation.js +1 -1
- package/dist/durable.d.ts +1 -1
- package/dist/{environment-provider-CLNVqp6H.js → environment-provider-BAO8wt1_.js} +147 -48
- package/dist/environment-provider-BAO8wt1_.js.map +1 -0
- package/dist/{environment-provider-DA8LqBV-.d.ts → environment-provider-Bu3S3v78.d.ts} +3 -3
- package/dist/environment-provider.d.ts +1 -1
- package/dist/environment-provider.js +1 -1
- package/dist/{errors-CVIDr7GQ.js → errors-CDZ8XsVj.js} +34 -9
- package/dist/errors-CDZ8XsVj.js.map +1 -0
- package/dist/{graph-DxU92LTL.js → graph-BbMjq7-x.js} +5 -5
- package/dist/{graph-DxU92LTL.js.map → graph-BbMjq7-x.js.map} +1 -1
- package/dist/{improvement-cycle-hIOGxDtV.js → improvement-cycle-D6rhMJR0.js} +67 -66
- package/dist/improvement-cycle-D6rhMJR0.js.map +1 -0
- package/dist/{index-Bdgpx2Dx.d.ts → index-C6yfz0QN.d.ts} +5 -5
- package/dist/{index-BOgzou1U.d.ts → index-COnuT0h7.d.ts} +263 -82
- package/dist/{index-CETQJlqT.d.ts → index-CTz17pH6.d.ts} +11 -11
- package/dist/{index-DQxQgKDs.d.ts → index-DQv7iCeE.d.ts} +6 -6
- package/dist/index.d.ts +16 -16
- package/dist/index.js +16 -16
- package/dist/intelligence.d.ts +736 -681
- package/dist/intelligence.js +113 -8
- package/dist/intelligence.js.map +1 -1
- package/dist/kernel.d.ts +7 -7
- package/dist/kernel.js +12 -12
- package/dist/{knowledge-C-JiS5Xg.js → knowledge-CD-_FbJT.js} +7 -7
- package/dist/{knowledge-C-JiS5Xg.js.map → knowledge-CD-_FbJT.js.map} +1 -1
- package/dist/knowledge.d.ts +1 -1
- package/dist/knowledge.js +1 -1
- package/dist/{loop-runner-bin-B_Ww2iqY.js → loop-runner-bin-BBz_ACfQ.js} +5 -5
- package/dist/{loop-runner-bin-B_Ww2iqY.js.map → loop-runner-bin-BBz_ACfQ.js.map} +1 -1
- package/dist/{loop-runner-bin-OH61zEVw.d.ts → loop-runner-bin-DUNxyuaG.d.ts} +3 -3
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/{materialization-BP5zspr2.js → materialization-CrdcfWXp.js} +4 -4
- package/dist/{materialization-BP5zspr2.js.map → materialization-CrdcfWXp.js.map} +1 -1
- package/dist/mcp/bin.js +4 -4
- package/dist/mcp/index.d.ts +5 -5
- package/dist/mcp/index.js +8 -8
- package/dist/mcp/memory-bin.js +1 -1
- package/dist/{memory-server-Cdpy7Uu8.js → memory-server-DsKOhzGf.js} +3 -3
- package/dist/{memory-server-Cdpy7Uu8.js.map → memory-server-DsKOhzGf.js.map} +1 -1
- package/dist/{model-policy-UTTc9Z-A.js → model-policy-DgRJIJse.js} +2 -2
- package/dist/{model-policy-UTTc9Z-A.js.map → model-policy-DgRJIJse.js.map} +1 -1
- package/dist/{openai-tools-BKJqaQ1b.js → openai-tools-DIKr72_l.js} +2 -2
- package/dist/{openai-tools-BKJqaQ1b.js.map → openai-tools-DIKr72_l.js.map} +1 -1
- package/dist/{openai-tools-DU3TZvFY.d.ts → openai-tools-yoRRzAUW.d.ts} +2 -2
- package/dist/{prepare-CYqGSYza.js → prepare-DK1qnk7-.js} +3 -3
- package/dist/{prepare-CYqGSYza.js.map → prepare-DK1qnk7-.js.map} +1 -1
- package/dist/primeintellect/index.d.ts +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.js +1 -1
- package/dist/{protected-model-port-DEsTWOFs.d.ts → protected-model-port-B8ssMyUg.d.ts} +7 -7
- package/dist/{protected-model-port-B6DW_x2I.js → protected-model-port-DHeCm_UF.js} +2 -2
- package/dist/{protected-model-port-B6DW_x2I.js.map → protected-model-port-DHeCm_UF.js.map} +1 -1
- package/dist/{redact-BwEdhuVH.d.ts → redact-CLw2B7Qj.d.ts} +9 -9
- package/dist/{researcher-DBfKdnAz.js → researcher-CiSY6Wzb.js} +3 -3
- package/dist/{researcher-DBfKdnAz.js.map → researcher-CiSY6Wzb.js.map} +1 -1
- package/dist/retained-run-binding-Dp2e8xne.js +268 -0
- package/dist/retained-run-binding-Dp2e8xne.js.map +1 -0
- package/dist/{runtime-DhPCNvuH.d.ts → runtime-CVNWEw16.d.ts} +4 -4
- package/dist/{runtime-CUpB4rEP.js → runtime-tTA2iCZQ.js} +650 -222
- package/dist/runtime-tTA2iCZQ.js.map +1 -0
- package/dist/{sandbox-events-CA2amHoA.js → sandbox-events-DPmXlcKw.js} +24 -2
- package/dist/sandbox-events-DPmXlcKw.js.map +1 -0
- package/dist/{snapshot-BOIprwBk.js → snapshot-cK9K420n.js} +2 -2
- package/dist/{snapshot-BOIprwBk.js.map → snapshot-cK9K420n.js.map} +1 -1
- package/dist/{spawn-journal-DVFqdzO9.js → spawn-journal-DGXei3xG.js} +3 -3
- package/dist/{spawn-journal-DVFqdzO9.js.map → spawn-journal-DGXei3xG.js.map} +1 -1
- package/dist/{stream-agent-turn-Q5ellSUu.js → stream-agent-turn-4kUH8Nnn.js} +77 -34
- package/dist/stream-agent-turn-4kUH8Nnn.js.map +1 -0
- package/dist/{stream-agent-turn-DhPlvHwp.d.ts → stream-agent-turn-RjrKGk6S.d.ts} +5 -8
- package/dist/{structural-rollout-CwtVIJf-.js → structural-rollout-7LP9Ex0F.js} +9 -9
- package/dist/structural-rollout-7LP9Ex0F.js.map +1 -0
- package/dist/{supervise-CUJRmx3s.js → supervise-Cx1QY_hj.js} +9 -9
- package/dist/{supervise-CUJRmx3s.js.map → supervise-Cx1QY_hj.js.map} +1 -1
- package/dist/{supervisor-BoC2tFgH.js → supervisor-BV72aDmP.js} +13 -9
- package/dist/supervisor-BV72aDmP.js.map +1 -0
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +12 -12
- package/dist/{tool-server-Dh-NcbHr.js → tool-server-DEmLr9YY.js} +2 -2
- package/dist/{tool-server-Dh-NcbHr.js.map → tool-server-DEmLr9YY.js.map} +1 -1
- package/dist/{types-CxU37Uzr.d.ts → types-19ZOddS3.d.ts} +2 -2
- package/dist/{types-BBwGSiAj.d.ts → types-C244Huc9.d.ts} +16 -7
- package/dist/{types-BCkweg3w.d.ts → types-D4arYjUl.d.ts} +6 -6
- package/dist/{workspace-archive-C7AvjSVb.js → workspace-archive-HYlsPhfm.js} +2 -2
- package/dist/{workspace-archive-C7AvjSVb.js.map → workspace-archive-HYlsPhfm.js.map} +1 -1
- package/package.json +1 -1
- package/dist/conversation-DIUtiLkC.js.map +0 -1
- package/dist/environment-provider-CLNVqp6H.js.map +0 -1
- package/dist/errors-CVIDr7GQ.js.map +0 -1
- package/dist/improvement-cycle-hIOGxDtV.js.map +0 -1
- package/dist/runtime-CUpB4rEP.js.map +0 -1
- package/dist/sandbox-events-CA2amHoA.js.map +0 -1
- package/dist/stream-agent-turn-Q5ellSUu.js.map +0 -1
- package/dist/structural-rollout-CwtVIJf-.js.map +0 -1
- package/dist/supervisor-BoC2tFgH.js.map +0 -1
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import { c as
|
|
2
|
-
import "./
|
|
3
|
-
import
|
|
1
|
+
import { C as sameControlCoordinates, S as isTerminalSessionStatus, _ as exactSession, a as assertEventBinding, b as freezeControlRef, c as assertSequence, d as awaitAbortable, f as cancellationRequest, g as exactControlRef, h as exactContinuedControlRef, i as assertCanonicalEventBinding, l as assertStableText, m as delay, n as abortError, o as assertInteractionBinding, p as copyControlRef, r as assertBoundaryBinding, s as assertResultBinding, t as RetainedRunProviderContractError, u as assertWaitDuration, v as exactSessionCancel, w as freshTurnInput, x as hasDurableCancel, y as exactSessionResult } from "./retained-run-binding-Dp2e8xne.js";
|
|
2
|
+
import { c as RetainedInteractiveAdmissionError, d as RetainedRunDispatchBindingError, l as RetainedInteractiveBindingError, m as ValidationError, n as AnalystError, s as PlannerError, u as RetainedRunAdmissionError } from "./errors-CDZ8XsVj.js";
|
|
3
|
+
import "./stream-agent-turn-4kUH8Nnn.js";
|
|
4
|
+
import { t as detachedSnapshot } from "./snapshot-cK9K420n.js";
|
|
5
|
+
import { g as isTraceAnalysisStore, i as InMemorySpawnJournal, r as InMemoryResultBlobStore, y as contentAddress } from "./spawn-journal-DGXei3xG.js";
|
|
4
6
|
import { _ as zeroTokenUsage, a as hasCompleteCacheBreakdown, d as sleep, f as stringifySafe, h as usdEstimatedOf, l as randomSuffix, n as chargedTokens, o as isAbortError, r as cloneTokenUsage, t as addTokenUsage } from "./util-C1bv6yog.js";
|
|
5
7
|
import { i as redactProtectedValue, r as redactProtectedReason } from "./protected-redaction--F3v1oo8.js";
|
|
6
|
-
import {
|
|
7
|
-
import { c as profileProviderModel, i as concreteModelId, s as profileModelExecutionSettings, t as assertExecutableAgentProfile } from "./model-policy-
|
|
8
|
-
import { E as executableAgentSpecSnapshot, T as executableAgentProfileSnapshot } from "./materialization-
|
|
9
|
-
import { E as rollingDispatch, I as createExecutor, L as createExecutorRegistry, _t as runBrainLoop, ft as runAgentRounds, g as settledToIteration, gt as routerBrain, l as withDriverExecutor, mt as probeSandboxCapabilities, n as createSupervisor, pt as createSandboxLineage, q as createPushTraceSource, ut as defaultSelectWinner, vt as canonicalObservedModel, z as createWorktreeCliExecutor } from "./supervisor-
|
|
10
|
-
import "./environment-provider-
|
|
8
|
+
import { c as extractTransportEventIdentity, l as parseCanonicalTransportEvent, o as notifySandboxEventObserver } from "./sandbox-events-DPmXlcKw.js";
|
|
9
|
+
import { c as profileProviderModel, i as concreteModelId, s as profileModelExecutionSettings, t as assertExecutableAgentProfile } from "./model-policy-DgRJIJse.js";
|
|
10
|
+
import { E as executableAgentSpecSnapshot, T as executableAgentProfileSnapshot } from "./materialization-CrdcfWXp.js";
|
|
11
|
+
import { E as rollingDispatch, I as createExecutor, L as createExecutorRegistry, _t as runBrainLoop, ft as runAgentRounds, g as settledToIteration, gt as routerBrain, l as withDriverExecutor, mt as probeSandboxCapabilities, n as createSupervisor, pt as createSandboxLineage, q as createPushTraceSource, ut as defaultSelectWinner, vt as canonicalObservedModel, z as createWorktreeCliExecutor } from "./supervisor-BV72aDmP.js";
|
|
12
|
+
import "./environment-provider-BAO8wt1_.js";
|
|
11
13
|
import { i as notifyRuntimeHookEvent } from "./runtime-hooks-C7iJOWm3.js";
|
|
12
|
-
import { C as observe, O as strategyAuthorMethod, T as profileChatClient, b as sample, v as refine, x as sampleThenRefine, y as runAgentic } from "./structural-rollout-
|
|
13
|
-
import { It as gateOnDeliverable, Lt as mapExecutorResult, n as supervise } from "./supervise-
|
|
14
|
-
import "./authoring-
|
|
15
|
-
import "./graph-
|
|
14
|
+
import { C as observe, O as strategyAuthorMethod, T as profileChatClient, b as sample, v as refine, x as sampleThenRefine, y as runAgentic } from "./structural-rollout-7LP9Ex0F.js";
|
|
15
|
+
import { It as gateOnDeliverable, Lt as mapExecutorResult, n as supervise } from "./supervise-Cx1QY_hj.js";
|
|
16
|
+
import "./authoring-J93uFAwd.js";
|
|
17
|
+
import "./graph-BbMjq7-x.js";
|
|
18
|
+
import { AgentEnvironmentCapabilitiesSchema, AgentExactRunControlRefSchema, AgentInteractiveSessionControlClaimAcknowledgementSchema, AgentInteractiveSessionControlClaimSchema, AgentInteractiveSessionPromptAcknowledgementSchema, AgentInteractiveSessionRefSchema, AgentInteractiveSessionStatusSchema, AgentInteractiveSessionStopAcknowledgementSchema, AgentNativeContextContinuationResultSchema, AgentTurnResultSchema, InteractionAcknowledgementSchema, InteractionResponseCommandSchema, NativeContextBoundaryProofSchema, NativeContextContinuationRequestSchema, RuntimeEventEnvelopeSchema, TerminalReplayWindowSchema, TerminalSessionRefSchema, agentInteractiveSessionControlClaimAcknowledgementMatchesRequest, agentInteractiveSessionControlClaimMatchesRef, agentInteractiveSessionControlClaimRequestDigest, agentInteractiveSessionPromptAcknowledgementMatchesCommand, agentInteractiveSessionRefMatchesStart, agentInteractiveSessionRunRef, agentInteractiveSessionStatusMatchesRef, agentInteractiveSessionStopAcknowledgementMatchesCommand, agentNativeContextContinuationResultMatchesRequest, agentProfileSchema, canonicalAgentProfileDigest, canonicalCandidateDigest, exactAgentInteractiveSessionStart, nativeContextContinuationTurnDigest, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
|
|
16
19
|
import { CODING_HARNESSES, InMemoryTraceStore, OUTPUT_VALUE, benjaminiHochberg, buildTrajectory, computeFindingId as computeFindingId$1, confidenceInterval, expandProfileAxes, makeFinding as makeFinding$1, pairedBootstrap, paretoFrontier, wilcoxonSignedRank, wilson } from "@tangle-network/agent-eval";
|
|
17
20
|
import { heldoutSignificance, runProfileMatrix } from "@tangle-network/agent-eval/campaign";
|
|
18
|
-
import { AgentEnvironmentCapabilitiesSchema, AgentExactRunControlRefSchema, AgentNativeContextContinuationResultSchema, AgentRunCancellationAcknowledgementSchema, AgentRunCancellationRequestSchema, AgentTurnResultSchema, InteractionAcknowledgementSchema, InteractionResponseCommandSchema, NativeContextBoundaryProofSchema, NativeContextContinuationRequestSchema, RuntimeEventEnvelopeSchema, agentNativeContextContinuationResultMatchesRequest, agentProfileSchema, agentRunCancellationAcknowledgementMatchesRequest, agentRunCancellationRequestDigest, canonicalAgentProfileDigest, canonicalCandidateDigest, nativeContextContinuationTurnDigest, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
|
|
19
21
|
import { createHash } from "node:crypto";
|
|
20
22
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
21
23
|
import { mkdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
@@ -3483,187 +3485,242 @@ function promotionGate(opts) {
|
|
|
3483
3485
|
};
|
|
3484
3486
|
}
|
|
3485
3487
|
//#endregion
|
|
3486
|
-
//#region src/runtime/retained-
|
|
3487
|
-
function
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
if (
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
}
|
|
3501
|
-
function sameControlCoordinates(left, right) {
|
|
3502
|
-
return canonicalCandidateDigest(left) === canonicalCandidateDigest(right);
|
|
3503
|
-
}
|
|
3504
|
-
function freezeControlRef(controlRef) {
|
|
3505
|
-
return Object.freeze({ ...AgentExactRunControlRefSchema.parse(controlRef) });
|
|
3506
|
-
}
|
|
3507
|
-
function copyControlRef(controlRef) {
|
|
3508
|
-
return { ...controlRef };
|
|
3509
|
-
}
|
|
3510
|
-
function exactControlRef(candidate, expected) {
|
|
3511
|
-
if (!candidate) throw new Error("provider dispatch returned no durable run control reference");
|
|
3512
|
-
const controlRef = AgentExactRunControlRefSchema.parse(candidate);
|
|
3513
|
-
if (controlRef.provider !== expected.provider || controlRef.environmentId !== expected.environmentId || controlRef.sessionId !== expected.sessionId) throw new Error("provider dispatch returned control coordinates for another run");
|
|
3514
|
-
return controlRef;
|
|
3515
|
-
}
|
|
3516
|
-
function exactContinuedControlRef(candidate, initial) {
|
|
3517
|
-
const controlRef = AgentExactRunControlRefSchema.parse(candidate);
|
|
3518
|
-
if (controlRef.provider !== initial.provider || controlRef.environmentId !== initial.environmentId || controlRef.sessionId !== initial.sessionId) throw new Error("provider continuation advanced to another retained session");
|
|
3519
|
-
if (controlRef.runId === initial.runId && controlRef.executionId === initial.executionId) throw new Error("provider continuation did not return a new exact run execution");
|
|
3520
|
-
return controlRef;
|
|
3488
|
+
//#region src/runtime/retained-interactive-handle.ts
|
|
3489
|
+
function createRetainedInteractiveRunHandle(environment, inputRef, capabilities, requestedStart) {
|
|
3490
|
+
const ref = freezeInteractiveRef(inputRef);
|
|
3491
|
+
const source = environment.interactive(ref);
|
|
3492
|
+
if (!sameInteractiveRef(source.ref, ref)) throw new Error("provider reconstructed a different interactive process");
|
|
3493
|
+
if (!source.sendPrompt) throw new Error("provider declared interactive prompt support but exposed no prompt method");
|
|
3494
|
+
return Object.freeze({
|
|
3495
|
+
ref,
|
|
3496
|
+
capabilities,
|
|
3497
|
+
claimControl: async (request, options) => exactClaim(ref, request, await awaitAbortable(Promise.resolve().then(() => source.claimControl(request, options)), options?.signal)),
|
|
3498
|
+
status: async (options) => exactStatus(ref, await awaitAbortable(Promise.resolve().then(() => source.status(options)), options?.signal), requestedStart),
|
|
3499
|
+
attach: async (request, options) => exactTerminal(ref, request, await awaitAbortable(Promise.resolve().then(() => source.attach(request, options)), options?.signal)),
|
|
3500
|
+
sendPrompt: async (command, options) => exactPrompt(ref, await awaitAbortable(Promise.resolve().then(() => source.sendPrompt(command, options)), options?.signal), command),
|
|
3501
|
+
stop: async (command, options) => exactStop(ref, await awaitAbortable(Promise.resolve().then(() => source.stop(command, options)), options?.signal), command)
|
|
3502
|
+
});
|
|
3521
3503
|
}
|
|
3522
|
-
function
|
|
3523
|
-
|
|
3504
|
+
function freezeInteractiveRef(value) {
|
|
3505
|
+
return detachedSnapshot(AgentInteractiveSessionRefSchema.parse(value), "interactive session ref");
|
|
3524
3506
|
}
|
|
3525
|
-
function
|
|
3526
|
-
|
|
3507
|
+
function exactClaim(ref, request, value) {
|
|
3508
|
+
const acknowledgement = parseProviderAcknowledgement(AgentInteractiveSessionControlClaimAcknowledgementSchema, value, "control claim");
|
|
3509
|
+
if (!agentInteractiveSessionControlClaimAcknowledgementMatchesRequest(request, acknowledgement)) throw new RetainedRunProviderContractError("provider returned a control claim acknowledgement for another request");
|
|
3510
|
+
if (acknowledgement.control && !agentInteractiveSessionControlClaimMatchesRef(ref, acknowledgement.control)) throw new RetainedRunProviderContractError("provider returned a control claim for another interactive process");
|
|
3511
|
+
return acknowledgement;
|
|
3527
3512
|
}
|
|
3528
|
-
function
|
|
3529
|
-
|
|
3513
|
+
function exactPrompt(ref, value, command) {
|
|
3514
|
+
const acknowledgement = parseProviderAcknowledgement(AgentInteractiveSessionPromptAcknowledgementSchema, value, "prompt");
|
|
3515
|
+
if (!agentInteractiveSessionPromptAcknowledgementMatchesCommand(command, acknowledgement)) throw new RetainedRunProviderContractError("provider returned a prompt acknowledgement for another request");
|
|
3516
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(ref, acknowledgement.control)) throw new RetainedRunProviderContractError("provider returned a prompt acknowledgement for another interactive process");
|
|
3517
|
+
return acknowledgement;
|
|
3530
3518
|
}
|
|
3531
|
-
function
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
if (
|
|
3535
|
-
|
|
3536
|
-
if (metadata?.requestDigest !== controlRef.requestDigest) throw new Error("provider returned a result for another retained request");
|
|
3519
|
+
function exactStop(ref, value, command) {
|
|
3520
|
+
const acknowledgement = parseProviderAcknowledgement(AgentInteractiveSessionStopAcknowledgementSchema, value, "stop");
|
|
3521
|
+
if (!agentInteractiveSessionStopAcknowledgementMatchesCommand(command, acknowledgement)) throw new RetainedRunProviderContractError("provider returned a stop acknowledgement for another request");
|
|
3522
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(ref, acknowledgement.control)) throw new RetainedRunProviderContractError("provider returned a stop acknowledgement for another interactive process");
|
|
3523
|
+
return acknowledgement;
|
|
3537
3524
|
}
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3525
|
+
function parseProviderAcknowledgement(schema, value, operation) {
|
|
3526
|
+
try {
|
|
3527
|
+
return schema.parse(value);
|
|
3528
|
+
} catch {
|
|
3529
|
+
throw new RetainedRunProviderContractError(`provider returned an invalid interactive ${operation} acknowledgement`);
|
|
3542
3530
|
}
|
|
3543
|
-
};
|
|
3544
|
-
function cancellationRequest(controlRef, operationId, reason) {
|
|
3545
|
-
const material = {
|
|
3546
|
-
operationId,
|
|
3547
|
-
run: AgentExactRunControlRefSchema.parse(controlRef),
|
|
3548
|
-
...reason === void 0 ? {} : { reason }
|
|
3549
|
-
};
|
|
3550
|
-
return AgentRunCancellationRequestSchema.parse({
|
|
3551
|
-
...material,
|
|
3552
|
-
requestDigest: agentRunCancellationRequestDigest(material)
|
|
3553
|
-
});
|
|
3554
3531
|
}
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
let acknowledgement;
|
|
3532
|
+
function exactStatus(ref, value, requestedStart) {
|
|
3533
|
+
let status;
|
|
3558
3534
|
try {
|
|
3559
|
-
|
|
3535
|
+
status = AgentInteractiveSessionStatusSchema.parse(value);
|
|
3560
3536
|
} catch (error) {
|
|
3561
|
-
if (
|
|
3562
|
-
throw error;
|
|
3537
|
+
if (requestedStart === void 0) throw error;
|
|
3538
|
+
throw new RetainedInteractiveBindingError(detachedSnapshot(requestedStart, "interactive status binding request"), {}, { cause: error });
|
|
3563
3539
|
}
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
} catch {
|
|
3568
|
-
throw new RetainedRunProviderContractError("provider returned an invalid retained cancellation acknowledgement");
|
|
3540
|
+
if (!agentInteractiveSessionStatusMatchesRef(ref, status)) {
|
|
3541
|
+
if (requestedStart !== void 0) throw new RetainedInteractiveBindingError(detachedSnapshot(requestedStart, "interactive status binding request"), detachedSnapshot({ status: detachedSnapshot(status, "interactive provider status") }, "interactive provider status result"), { cause: /* @__PURE__ */ new Error("provider returned status for another interactive process") });
|
|
3542
|
+
throw new Error("provider returned status for another interactive process");
|
|
3569
3543
|
}
|
|
3570
|
-
|
|
3571
|
-
|
|
3544
|
+
return status;
|
|
3545
|
+
}
|
|
3546
|
+
function exactTerminal(ref, request, terminal) {
|
|
3547
|
+
const terminalRef = TerminalSessionRefSchema.parse(terminal.ref);
|
|
3548
|
+
TerminalReplayWindowSchema.parse(terminal.cursors);
|
|
3549
|
+
if (terminalRef.parentExecutionId !== ref.run.executionId) throw new Error("provider attached a terminal from another interactive run");
|
|
3550
|
+
AgentInteractiveSessionControlClaimSchema.parse(terminal.control);
|
|
3551
|
+
if (!agentInteractiveSessionControlClaimMatchesRef(ref, terminal.control)) throw new Error("provider attached a terminal with a claim for another interactive process");
|
|
3552
|
+
if (canonicalCandidateDigest(terminal.control) !== canonicalCandidateDigest(request.control)) throw new Error("provider attached a terminal with a different interactive control claim");
|
|
3553
|
+
return terminal;
|
|
3554
|
+
}
|
|
3555
|
+
function sameInteractiveRef(left, right) {
|
|
3556
|
+
return canonicalCandidateDigest(left) === canonicalCandidateDigest(right);
|
|
3572
3557
|
}
|
|
3573
|
-
|
|
3574
|
-
|
|
3558
|
+
//#endregion
|
|
3559
|
+
//#region src/runtime/retained-interactive-lifecycle.ts
|
|
3560
|
+
const INTERACTIVE_CLEANUP_TIMEOUT_MS = 3e4;
|
|
3561
|
+
/** Create one environment while retaining ownership if cancellation wins the race. */
|
|
3562
|
+
async function createInteractiveEnvironment(create, signal) {
|
|
3563
|
+
if (signal?.aborted) throw abortError(signal.reason);
|
|
3564
|
+
const creation = Promise.resolve().then(create);
|
|
3565
|
+
if (signal === void 0) return creation;
|
|
3566
|
+
return new Promise((resolve, reject) => {
|
|
3567
|
+
let owner = "pending";
|
|
3568
|
+
const removeAbortListener = () => signal.removeEventListener("abort", onAbort);
|
|
3569
|
+
const onAbort = () => {
|
|
3570
|
+
if (owner !== "pending") return;
|
|
3571
|
+
owner = "runtime";
|
|
3572
|
+
removeAbortListener();
|
|
3573
|
+
disposeInteractiveEnvironment(creation, signal.reason);
|
|
3574
|
+
reject(abortError(signal.reason));
|
|
3575
|
+
};
|
|
3576
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3577
|
+
creation.then((environment) => {
|
|
3578
|
+
if (owner !== "pending") return;
|
|
3579
|
+
owner = "caller";
|
|
3580
|
+
removeAbortListener();
|
|
3581
|
+
resolve(environment);
|
|
3582
|
+
}, (error) => {
|
|
3583
|
+
if (owner !== "pending") return;
|
|
3584
|
+
owner = "runtime";
|
|
3585
|
+
removeAbortListener();
|
|
3586
|
+
reject(error);
|
|
3587
|
+
});
|
|
3588
|
+
});
|
|
3575
3589
|
}
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
if (signal
|
|
3579
|
-
Promise.resolve(
|
|
3590
|
+
/** Start one process while destroying its unreturned environment on cancellation. */
|
|
3591
|
+
async function startInteractiveProcess(environment, start, signal) {
|
|
3592
|
+
if (signal?.aborted) {
|
|
3593
|
+
disposeInteractiveEnvironment(Promise.resolve(environment), signal.reason);
|
|
3580
3594
|
throw abortError(signal.reason);
|
|
3581
3595
|
}
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3596
|
+
const pending = Promise.resolve().then(start);
|
|
3597
|
+
if (signal === void 0) return pending;
|
|
3598
|
+
return new Promise((resolve, reject) => {
|
|
3599
|
+
let owner = "pending";
|
|
3600
|
+
const removeAbortListener = () => signal.removeEventListener("abort", onAbort);
|
|
3585
3601
|
const onAbort = () => {
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
});
|
|
3602
|
+
if (owner !== "pending") return;
|
|
3603
|
+
owner = "runtime";
|
|
3604
|
+
removeAbortListener();
|
|
3605
|
+
disposeInteractiveEnvironment(Promise.resolve(environment), signal.reason);
|
|
3606
|
+
reject(abortError(signal.reason));
|
|
3592
3607
|
};
|
|
3593
3608
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
3594
|
-
|
|
3595
|
-
if (
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
resolve(
|
|
3609
|
+
pending.then((result) => {
|
|
3610
|
+
if (owner !== "pending") return;
|
|
3611
|
+
owner = "caller";
|
|
3612
|
+
removeAbortListener();
|
|
3613
|
+
resolve(result);
|
|
3599
3614
|
}, (error) => {
|
|
3600
|
-
if (
|
|
3601
|
-
|
|
3602
|
-
|
|
3615
|
+
if (owner !== "pending") return;
|
|
3616
|
+
owner = "runtime";
|
|
3617
|
+
removeAbortListener();
|
|
3603
3618
|
reject(error);
|
|
3604
3619
|
});
|
|
3605
3620
|
});
|
|
3606
3621
|
}
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
}
|
|
3610
|
-
|
|
3611
|
-
const
|
|
3612
|
-
|
|
3613
|
-
const
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
value: providerEvent,
|
|
3625
|
-
checkSessionId: true
|
|
3626
|
-
}
|
|
3627
|
-
];
|
|
3628
|
-
for (const { value, checkSessionId } of bindings) {
|
|
3629
|
-
if (value === void 0) continue;
|
|
3630
|
-
if (value.runId !== void 0 && value.runId !== controlRef.runId) throw new Error("provider returned an event for another retained run");
|
|
3631
|
-
if (value.executionId !== void 0 && value.executionId !== controlRef.executionId) throw new Error("provider returned an event for another retained execution");
|
|
3632
|
-
if (checkSessionId && value.sessionId !== void 0 && value.sessionId !== controlRef.sessionId) throw new Error("provider returned an event for another retained session");
|
|
3622
|
+
/** Destroy an environment with fresh, bounded cleanup authority. */
|
|
3623
|
+
async function destroyInteractiveEnvironment(environment) {
|
|
3624
|
+
if (!environment.destroy) throw new Error(`provider environment "${environment.id}" does not expose destroy()`);
|
|
3625
|
+
const controller = new AbortController();
|
|
3626
|
+
const timeout = /* @__PURE__ */ new Error("interactive environment cleanup timed out");
|
|
3627
|
+
let timer;
|
|
3628
|
+
const destruction = Promise.resolve().then(() => environment.destroy?.({ signal: controller.signal }));
|
|
3629
|
+
destruction.catch(() => void 0);
|
|
3630
|
+
try {
|
|
3631
|
+
await Promise.race([destruction, new Promise((_resolve, reject) => {
|
|
3632
|
+
timer = setTimeout(() => {
|
|
3633
|
+
controller.abort(timeout);
|
|
3634
|
+
reject(timeout);
|
|
3635
|
+
}, INTERACTIVE_CLEANUP_TIMEOUT_MS);
|
|
3636
|
+
})]);
|
|
3637
|
+
} finally {
|
|
3638
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
3633
3639
|
}
|
|
3634
3640
|
}
|
|
3635
|
-
function
|
|
3636
|
-
|
|
3641
|
+
function disposeInteractiveEnvironment(environment, abortReason) {
|
|
3642
|
+
environment.then(destroyInteractiveEnvironment, () => void 0).catch((cleanupError) => {
|
|
3643
|
+
const reason = abortReason instanceof Error ? abortReason : new Error(String(abortReason));
|
|
3644
|
+
const failure = new AggregateError([reason, cleanupError], "cancelled interactive environment cleanup failed");
|
|
3645
|
+
process.emitWarning(failure, { code: "AGENT_RUNTIME_INTERACTIVE_CLEANUP_FAILED" });
|
|
3646
|
+
});
|
|
3637
3647
|
}
|
|
3638
|
-
|
|
3639
|
-
|
|
3648
|
+
//#endregion
|
|
3649
|
+
//#region src/runtime/retained-run-intent.ts
|
|
3650
|
+
/**
|
|
3651
|
+
* Project environment creation input into public digest material.
|
|
3652
|
+
*
|
|
3653
|
+
* Opaque values never enter the material or its digest. Public scalar fields
|
|
3654
|
+
* remain bound directly, while opaque records retain only their key names.
|
|
3655
|
+
* Secret names remain public binding data, so changing requested credentials
|
|
3656
|
+
* still conflicts before provider effects begin.
|
|
3657
|
+
*/
|
|
3658
|
+
function retainedCreateMaterial(environment) {
|
|
3659
|
+
return {
|
|
3660
|
+
...environment.backend === void 0 ? {} : { backend: environment.backend },
|
|
3661
|
+
...environment.workspace === void 0 ? {} : { workspaceDigest: canonicalCandidateDigest(publicWorkspaceMaterial(environment.workspace)) },
|
|
3662
|
+
...environment.resources === void 0 ? {} : { resourcesDigest: canonicalCandidateDigest(publicResourceMaterial(environment.resources)) },
|
|
3663
|
+
...environment.name === void 0 ? {} : { name: environment.name },
|
|
3664
|
+
...environment.env === void 0 ? {} : { environmentVariableNames: retainedObjectNames(environment.env) },
|
|
3665
|
+
...environment.secrets === void 0 ? {} : { secretNames: retainedSecretNames(environment.secrets) },
|
|
3666
|
+
...environment.metadata === void 0 ? {} : { metadataKeys: retainedObjectNames(environment.metadata) },
|
|
3667
|
+
...environment.providerOptions === void 0 ? {} : { providerOptionNames: retainedObjectNames(environment.providerOptions) }
|
|
3668
|
+
};
|
|
3640
3669
|
}
|
|
3641
|
-
function
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3670
|
+
function publicWorkspaceMaterial(workspace) {
|
|
3671
|
+
return {
|
|
3672
|
+
...workspace.environment === void 0 ? {} : { environment: workspace.environment },
|
|
3673
|
+
...workspace.image === void 0 ? {} : { image: workspace.image },
|
|
3674
|
+
...workspace.repoUrl === void 0 ? {} : { repoUrl: workspace.repoUrl },
|
|
3675
|
+
...workspace.gitRef === void 0 ? {} : { gitRef: workspace.gitRef },
|
|
3676
|
+
...workspace.cwd === void 0 ? {} : { cwd: workspace.cwd },
|
|
3677
|
+
...workspace.providerOptions === void 0 ? {} : { providerOptionNames: retainedObjectNames(workspace.providerOptions) }
|
|
3678
|
+
};
|
|
3645
3679
|
}
|
|
3646
|
-
function
|
|
3647
|
-
|
|
3680
|
+
function publicResourceMaterial(resources) {
|
|
3681
|
+
return {
|
|
3682
|
+
...resources.cpu === void 0 ? {} : { cpu: resources.cpu },
|
|
3683
|
+
...resources.memoryMb === void 0 ? {} : { memoryMb: resources.memoryMb },
|
|
3684
|
+
...resources.diskMb === void 0 ? {} : { diskMb: resources.diskMb },
|
|
3685
|
+
...resources.gpu === void 0 ? {} : { gpu: resources.gpu },
|
|
3686
|
+
...resources.providerOptions === void 0 ? {} : { providerOptionNames: retainedObjectNames(resources.providerOptions) }
|
|
3687
|
+
};
|
|
3648
3688
|
}
|
|
3649
|
-
function
|
|
3650
|
-
return
|
|
3689
|
+
function retainedObjectNames(value) {
|
|
3690
|
+
return Object.keys(value).sort();
|
|
3651
3691
|
}
|
|
3652
|
-
function
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
}
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
}
|
|
3665
|
-
|
|
3666
|
-
|
|
3692
|
+
function retainedSecretNames(secrets) {
|
|
3693
|
+
return Array.isArray(secrets) ? [...secrets].sort() : Object.keys(secrets).sort();
|
|
3694
|
+
}
|
|
3695
|
+
/** Project one headless turn into the material that `freshTurnInput` forwards. */
|
|
3696
|
+
function retainedTurnMaterial(input) {
|
|
3697
|
+
return {
|
|
3698
|
+
...input.prompt === void 0 ? {} : { prompt: input.prompt },
|
|
3699
|
+
...input.parts === void 0 ? {} : { parts: input.parts },
|
|
3700
|
+
...input.model === void 0 ? {} : { model: input.model },
|
|
3701
|
+
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs },
|
|
3702
|
+
...input.context === void 0 ? {} : { context: input.context },
|
|
3703
|
+
...input.interactions === void 0 ? {} : { interactions: input.interactions },
|
|
3704
|
+
...input.providerOptions === void 0 ? {} : { providerOptions: input.providerOptions }
|
|
3705
|
+
};
|
|
3706
|
+
}
|
|
3707
|
+
//#endregion
|
|
3708
|
+
//#region src/runtime/interaction-capabilities.ts
|
|
3709
|
+
/**
|
|
3710
|
+
* Check one turn's interaction request before the provider can dispatch it.
|
|
3711
|
+
*
|
|
3712
|
+
* A requested interaction is durable only when the provider can replay its
|
|
3713
|
+
* event and safely replay the response command. An unsupported request fails
|
|
3714
|
+
* before environment creation or dispatch begins.
|
|
3715
|
+
*/
|
|
3716
|
+
function assertRequestedInteractionCapabilities(providerName, requested, capabilities) {
|
|
3717
|
+
const requestedKinds = Object.entries(requested ?? {}).filter(([, enabled]) => enabled === true).map(([kind]) => kind);
|
|
3718
|
+
if (requestedKinds.length === 0) return;
|
|
3719
|
+
const interactions = capabilities.interactions;
|
|
3720
|
+
if (!interactions) throw new Error(`provider "${providerName}" does not support requested interactions: ${requestedKinds.join(", ")}`);
|
|
3721
|
+
const unsupportedKinds = requestedKinds.filter((kind) => !interactions.kinds.includes(kind));
|
|
3722
|
+
if (unsupportedKinds.length > 0) throw new Error(`provider "${providerName}" does not support requested interaction kinds: ${unsupportedKinds.join(", ")}`);
|
|
3723
|
+
if (interactions.replay !== true || interactions.responseIdempotency !== true) throw new Error(`provider "${providerName}" cannot safely dispatch requested interactions without replay and response idempotency`);
|
|
3667
3724
|
}
|
|
3668
3725
|
//#endregion
|
|
3669
3726
|
//#region src/runtime/retained-run-events.ts
|
|
@@ -3693,6 +3750,7 @@ async function* retainedRunEvents(session, controlRef, options, now) {
|
|
|
3693
3750
|
if (sourceCursor === after?.cursor) continue;
|
|
3694
3751
|
const event = canonicalEvent(source);
|
|
3695
3752
|
if (!event) continue;
|
|
3753
|
+
assertCanonicalEventBinding(controlRef, event);
|
|
3696
3754
|
if (firstAfterEvent && after !== void 0) {
|
|
3697
3755
|
if (identity.sequence !== void 0 && identity.sequence <= after.sequence) throw new Error("provider replay did not prove that the first event follows the requested cursor");
|
|
3698
3756
|
firstAfterEvent = false;
|
|
@@ -3736,6 +3794,7 @@ function canonicalEvent(source) {
|
|
|
3736
3794
|
//#region src/runtime/retained-run-handle.ts
|
|
3737
3795
|
function createRetainedRunHandle(environment, session, initialControlRef, capabilities, now) {
|
|
3738
3796
|
const clock = now ?? Date.now;
|
|
3797
|
+
const measuredCapabilities = structuredClone(capabilities);
|
|
3739
3798
|
let activeControlRef = freezeControlRef(initialControlRef);
|
|
3740
3799
|
const snapshot = async (reason, signal) => {
|
|
3741
3800
|
if (signal?.aborted) throw abortError(signal.reason);
|
|
@@ -3761,6 +3820,9 @@ function createRetainedRunHandle(environment, session, initialControlRef, capabi
|
|
|
3761
3820
|
get controlRef() {
|
|
3762
3821
|
return copyControlRef(activeControlRef);
|
|
3763
3822
|
},
|
|
3823
|
+
get capabilities() {
|
|
3824
|
+
return structuredClone(measuredCapabilities);
|
|
3825
|
+
},
|
|
3764
3826
|
status: async (options) => {
|
|
3765
3827
|
const waitMs = options?.waitMs ?? 0;
|
|
3766
3828
|
assertWaitDuration(waitMs, "retained status wait");
|
|
@@ -3784,7 +3846,7 @@ function createRetainedRunHandle(environment, session, initialControlRef, capabi
|
|
|
3784
3846
|
async respondToInteraction(command, options) {
|
|
3785
3847
|
const exactCommand = InteractionResponseCommandSchema.parse(command);
|
|
3786
3848
|
assertInteractionBinding(activeControlRef, exactCommand);
|
|
3787
|
-
if (
|
|
3849
|
+
if (measuredCapabilities.interactions?.replay !== true || measuredCapabilities.interactions.responseIdempotency !== true) throw new Error(`provider "${activeControlRef.provider}" does not promise retry-safe interaction responses`);
|
|
3788
3850
|
const respond = session.respondToInteraction ?? environment.respondToInteraction;
|
|
3789
3851
|
if (!respond) throw new Error(`provider "${activeControlRef.provider}" does not support interaction responses`);
|
|
3790
3852
|
const acknowledgement = InteractionAcknowledgementSchema.parse(await awaitAbortable(Promise.resolve().then(() => respond.call(session.respondToInteraction ? session : environment, exactCommand, options)), options?.signal));
|
|
@@ -3804,7 +3866,7 @@ function createRetainedRunHandle(environment, session, initialControlRef, capabi
|
|
|
3804
3866
|
if (!sameControlCoordinates(exactRequest.run, activeControlRef)) throw new Error("native continuation request targets another retained run");
|
|
3805
3867
|
const { timeoutMs, signal, ...semanticTurn } = turn;
|
|
3806
3868
|
if (nativeContextContinuationTurnDigest(semanticTurn) !== exactRequest.turnDigest) throw new Error("native continuation request targets another user turn");
|
|
3807
|
-
if (
|
|
3869
|
+
if (measuredCapabilities.nativeContinuation?.atomicBoundary !== true || measuredCapabilities.nativeContinuation.requestIdempotency !== true || !session.continueNative) throw new Error(`provider "${activeControlRef.provider}" does not support retry-safe native continuation`);
|
|
3808
3870
|
const outcome = AgentNativeContextContinuationResultSchema.parse(await awaitAbortable(Promise.resolve().then(() => session.continueNative(exactRequest, {
|
|
3809
3871
|
turn: semanticTurn,
|
|
3810
3872
|
...timeoutMs === void 0 ? {} : { timeoutMs },
|
|
@@ -3862,31 +3924,6 @@ function createRetainedRunHandle(environment, session, initialControlRef, capabi
|
|
|
3862
3924
|
};
|
|
3863
3925
|
}
|
|
3864
3926
|
//#endregion
|
|
3865
|
-
//#region src/runtime/turn-input.ts
|
|
3866
|
-
/**
|
|
3867
|
-
* Copy only fields that describe a new provider turn.
|
|
3868
|
-
*
|
|
3869
|
-
* Session, replay, continuation, and transfer coordinates are runtime-owned
|
|
3870
|
-
* and are injected by the caller that owns that lifecycle. Keeping this copy
|
|
3871
|
-
* explicit also makes JavaScript callers subject to the same boundary.
|
|
3872
|
-
*/
|
|
3873
|
-
function freshTurnInput(input, runtime) {
|
|
3874
|
-
return {
|
|
3875
|
-
...input.prompt === void 0 ? {} : { prompt: input.prompt },
|
|
3876
|
-
...input.parts === void 0 ? {} : { parts: input.parts },
|
|
3877
|
-
...input.model === void 0 ? {} : { model: input.model },
|
|
3878
|
-
...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs },
|
|
3879
|
-
...input.context === void 0 ? {} : { context: input.context },
|
|
3880
|
-
...input.providerOptions === void 0 ? {} : { providerOptions: input.providerOptions },
|
|
3881
|
-
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
3882
|
-
turnId: runtime.turnId,
|
|
3883
|
-
detach: runtime.detach,
|
|
3884
|
-
...runtime.sessionId === void 0 ? {} : { sessionId: runtime.sessionId },
|
|
3885
|
-
...runtime.executionId === void 0 ? {} : { executionId: runtime.executionId },
|
|
3886
|
-
...runtime.contextTransfer === void 0 ? {} : { contextTransfer: runtime.contextTransfer }
|
|
3887
|
-
};
|
|
3888
|
-
}
|
|
3889
|
-
//#endregion
|
|
3890
3927
|
//#region src/runtime/retained-run-start.ts
|
|
3891
3928
|
/**
|
|
3892
3929
|
* Mint deterministic dispatch coordinates from the two caller-supplied keys.
|
|
@@ -3911,11 +3948,10 @@ function mintRetainedIdentity(idempotencyKey, turnId) {
|
|
|
3911
3948
|
* Dispatch one detached, replayable run and return only after exact durable
|
|
3912
3949
|
* coordinates are confirmed by the provider and persisted by the caller.
|
|
3913
3950
|
*
|
|
3914
|
-
* The required `onAdmission` hook
|
|
3915
|
-
*
|
|
3916
|
-
* reference
|
|
3917
|
-
*
|
|
3918
|
-
* whose exact reference a crash would lose.
|
|
3951
|
+
* The required `onAdmission` hook first records a digest-only intent before
|
|
3952
|
+
* creation, then records recovery coordinates and the verified exact control
|
|
3953
|
+
* reference. The returned promise resolves only after the dispatched admission
|
|
3954
|
+
* is durable, so a crash cannot lose a successful start's exact reference.
|
|
3919
3955
|
*
|
|
3920
3956
|
* @stable
|
|
3921
3957
|
*/
|
|
@@ -3928,17 +3964,35 @@ async function startRetainedRun(options) {
|
|
|
3928
3964
|
}
|
|
3929
3965
|
if (typeof options.onAdmission !== "function") throw new Error("startRetainedRun requires an awaited onAdmission durability hook");
|
|
3930
3966
|
const identity = options.identity ?? mintRetainedIdentity(options.environment.idempotencyKey, options.turn.turnId);
|
|
3931
|
-
const capabilities = await assertRetainedCapabilities(options.provider);
|
|
3932
3967
|
if (!options.provider.get) throw new Error(`provider "${options.provider.name}" cannot reconstruct an environment by id`);
|
|
3968
|
+
const intent = retainedRunIntent(options, identity);
|
|
3969
|
+
if (options.intent === void 0) await admitDurably(options.onAdmission, intent);
|
|
3970
|
+
else assertExactRetainedRunIntent(options.intent, intent);
|
|
3971
|
+
const providerCapabilities = await assertRetainedCapabilities(options.provider);
|
|
3972
|
+
assertRequestedInteractionCapabilities(options.provider.name, options.turn.interactions, providerCapabilities);
|
|
3933
3973
|
const environment = await options.provider.create({
|
|
3934
3974
|
...options.environment,
|
|
3935
3975
|
metadata: {
|
|
3936
3976
|
...options.environment.metadata,
|
|
3937
3977
|
retainedIdempotencyKey: options.environment.idempotencyKey,
|
|
3978
|
+
retainedIntentDigest: intent.requestDigest,
|
|
3979
|
+
retainedRunId: intent.runId,
|
|
3938
3980
|
sessionId: identity.sessionId,
|
|
3939
3981
|
executionId: identity.executionId
|
|
3940
3982
|
}
|
|
3941
3983
|
});
|
|
3984
|
+
let capabilities;
|
|
3985
|
+
try {
|
|
3986
|
+
capabilities = retainedCapabilitiesForEnvironment(options.provider.name, providerCapabilities, environment);
|
|
3987
|
+
assertRequestedInteractionCapabilities(options.provider.name, options.turn.interactions, capabilities);
|
|
3988
|
+
} catch (error) {
|
|
3989
|
+
try {
|
|
3990
|
+
await environment.destroy?.();
|
|
3991
|
+
} catch (cleanupError) {
|
|
3992
|
+
throw new AggregateError([error, cleanupError], "retained run environment published invalid capabilities and could not be destroyed");
|
|
3993
|
+
}
|
|
3994
|
+
throw error;
|
|
3995
|
+
}
|
|
3942
3996
|
if (!environment.dispatch || !environment.session) {
|
|
3943
3997
|
try {
|
|
3944
3998
|
await environment.destroy?.();
|
|
@@ -3977,11 +4031,13 @@ async function startRetainedRunInEnvironment(options) {
|
|
|
3977
4031
|
}
|
|
3978
4032
|
if (typeof options.onAdmission !== "function") throw new Error("startRetainedRunInEnvironment requires an awaited onAdmission durability hook");
|
|
3979
4033
|
const identity = options.identity ?? mintRetainedIdentity(options.environment.idempotencyKey, options.turn.turnId);
|
|
3980
|
-
const
|
|
4034
|
+
const providerCapabilities = await assertRetainedCapabilities(options.provider);
|
|
3981
4035
|
if (!options.provider.get) throw new Error(`provider "${options.provider.name}" cannot reconstruct an environment by id`);
|
|
3982
4036
|
const environment = await options.provider.get(options.environment.id);
|
|
3983
4037
|
if (!environment) throw new Error(`provider "${options.provider.name}" no longer holds environment "${options.environment.id}"`);
|
|
3984
4038
|
if (environment.id !== options.environment.id || environment.provider !== options.provider.name) throw new Error("provider reconstructed a different retained environment");
|
|
4039
|
+
const capabilities = retainedCapabilitiesForEnvironment(options.provider.name, providerCapabilities, environment);
|
|
4040
|
+
assertRequestedInteractionCapabilities(options.provider.name, options.turn.interactions, capabilities);
|
|
3985
4041
|
if (!environment.dispatch || !environment.session) throw new Error(`provider "${options.provider.name}" does not expose detached session control`);
|
|
3986
4042
|
await assertRetainedEnvironmentOwnership(options.provider, environment.id, options.environment.idempotencyKey);
|
|
3987
4043
|
return dispatchRetainedRun({
|
|
@@ -4002,6 +4058,7 @@ async function assertRetainedEnvironmentOwnership(provider, environmentId, idemp
|
|
|
4002
4058
|
}
|
|
4003
4059
|
async function dispatchRetainedRun(options) {
|
|
4004
4060
|
const { environment, identity } = options;
|
|
4061
|
+
assertRequestedInteractionCapabilities(options.provider.name, options.turn.interactions, options.capabilities);
|
|
4005
4062
|
await admitDurably(options.onAdmission, {
|
|
4006
4063
|
phase: "environment",
|
|
4007
4064
|
provider: options.provider.name,
|
|
@@ -4054,37 +4111,39 @@ async function dispatchRetainedRun(options) {
|
|
|
4054
4111
|
* callers can distinguish a persistence failure from a provider failure.
|
|
4055
4112
|
*/
|
|
4056
4113
|
async function admitDurably(onAdmission, admission) {
|
|
4114
|
+
const stableAdmission = detachedSnapshot(admission, "retained run admission");
|
|
4057
4115
|
try {
|
|
4058
|
-
await onAdmission(
|
|
4116
|
+
await onAdmission(stableAdmission);
|
|
4059
4117
|
} catch (error) {
|
|
4060
|
-
throw new
|
|
4118
|
+
if (isInteractiveAdmission(stableAdmission)) throw new RetainedInteractiveAdmissionError(stableAdmission, { cause: error });
|
|
4119
|
+
throw new RetainedRunAdmissionError(stableAdmission, { cause: error });
|
|
4061
4120
|
}
|
|
4062
4121
|
}
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
*
|
|
4067
|
-
* `not_found`: the provider no longer holds the environment, so nothing
|
|
4068
|
-
* remains to destroy. `recovered`: the provider self-identified the session
|
|
4069
|
-
* with a strict exact reference matching the recorded coordinates.
|
|
4070
|
-
* `unverifiable`: the environment exists but the provider cannot
|
|
4071
|
-
* self-identify the session — no session accessor, an accessor that throws,
|
|
4072
|
-
* a lazy accessor with no stored reference, or a loose reference. That
|
|
4073
|
-
* outcome is never destroy-safe: keep the environment, retry
|
|
4074
|
-
* `reconnectRetainedRun` with a dispatched admission record, or inspect the
|
|
4075
|
-
* environment with provider-native tools. A session that self-identifies
|
|
4076
|
-
* with different coordinates throws: something live is not the recorded run.
|
|
4077
|
-
*
|
|
4078
|
-
* @stable
|
|
4079
|
-
*/
|
|
4122
|
+
function isInteractiveAdmission(admission) {
|
|
4123
|
+
return admission.phase === "interactive_intent" || admission.phase === "interactive_environment" || admission.phase === "interactive_started";
|
|
4124
|
+
}
|
|
4080
4125
|
async function recoverRetainedRun(options) {
|
|
4126
|
+
if ("admission" in options) {
|
|
4127
|
+
if (options.admission.provider !== options.provider.name) throw new Error("retained run intent belongs to another provider");
|
|
4128
|
+
return {
|
|
4129
|
+
outcome: "recovered",
|
|
4130
|
+
handle: await startRetainedRun({
|
|
4131
|
+
provider: options.provider,
|
|
4132
|
+
...options.replay,
|
|
4133
|
+
intent: options.admission,
|
|
4134
|
+
onAdmission: options.onAdmission,
|
|
4135
|
+
now: options.now
|
|
4136
|
+
})
|
|
4137
|
+
};
|
|
4138
|
+
}
|
|
4081
4139
|
assertStableText(options.environmentId, "retained environment id");
|
|
4082
4140
|
assertStableText(options.sessionId, "retained session id");
|
|
4083
4141
|
assertStableText(options.executionId, "retained execution id");
|
|
4084
|
-
const
|
|
4142
|
+
const providerCapabilities = await assertRetainedCapabilities(options.provider);
|
|
4085
4143
|
if (!options.provider.get) throw new Error(`provider "${options.provider.name}" cannot reconstruct an environment by id`);
|
|
4086
4144
|
const environment = await options.provider.get(options.environmentId);
|
|
4087
4145
|
if (!environment) return { outcome: "not_found" };
|
|
4146
|
+
const capabilities = retainedCapabilitiesForEnvironment(options.provider.name, providerCapabilities, environment);
|
|
4088
4147
|
if (!environment.session) return {
|
|
4089
4148
|
outcome: "unverifiable",
|
|
4090
4149
|
environment
|
|
@@ -4111,23 +4170,392 @@ async function recoverRetainedRun(options) {
|
|
|
4111
4170
|
handle: createRetainedRunHandle(environment, exact.session, exact.controlRef, capabilities, options.now)
|
|
4112
4171
|
};
|
|
4113
4172
|
}
|
|
4173
|
+
function retainedRunIntent(options, identity) {
|
|
4174
|
+
const requestedProfileDigest = canonicalCandidateDigest(options.environment.profile);
|
|
4175
|
+
const requestDigest = canonicalCandidateDigest({
|
|
4176
|
+
kind: "retained-run-intent.v1",
|
|
4177
|
+
provider: options.provider.name,
|
|
4178
|
+
idempotencyKey: options.environment.idempotencyKey,
|
|
4179
|
+
turnId: options.turn.turnId,
|
|
4180
|
+
sessionId: identity.sessionId,
|
|
4181
|
+
executionId: identity.executionId,
|
|
4182
|
+
requestedProfileDigest,
|
|
4183
|
+
create: retainedCreateMaterial(options.environment),
|
|
4184
|
+
turn: retainedTurnMaterial(options.turn)
|
|
4185
|
+
});
|
|
4186
|
+
return {
|
|
4187
|
+
phase: "intent",
|
|
4188
|
+
provider: options.provider.name,
|
|
4189
|
+
idempotencyKey: options.environment.idempotencyKey,
|
|
4190
|
+
turnId: options.turn.turnId,
|
|
4191
|
+
sessionId: identity.sessionId,
|
|
4192
|
+
executionId: identity.executionId,
|
|
4193
|
+
runId: `retained-intent-run:${requestDigest.slice(7)}`,
|
|
4194
|
+
requestedProfileDigest,
|
|
4195
|
+
requestDigest
|
|
4196
|
+
};
|
|
4197
|
+
}
|
|
4198
|
+
function assertExactRetainedRunIntent(received, expected) {
|
|
4199
|
+
if (canonicalCandidateDigest(parseRetainedRunIntent(received)) !== canonicalCandidateDigest(expected)) throw new Error("retained run intent conflicts with replay material");
|
|
4200
|
+
}
|
|
4201
|
+
function parseRetainedRunIntent(value) {
|
|
4202
|
+
const stable = detachedSnapshot(value, "retained run intent");
|
|
4203
|
+
if (stable === null || typeof stable !== "object" || Array.isArray(stable)) throw new Error("retained run intent is malformed");
|
|
4204
|
+
const record = stable;
|
|
4205
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
4206
|
+
"phase",
|
|
4207
|
+
"provider",
|
|
4208
|
+
"idempotencyKey",
|
|
4209
|
+
"turnId",
|
|
4210
|
+
"sessionId",
|
|
4211
|
+
"executionId",
|
|
4212
|
+
"runId",
|
|
4213
|
+
"requestedProfileDigest",
|
|
4214
|
+
"requestDigest"
|
|
4215
|
+
]);
|
|
4216
|
+
if (Object.keys(record).some((key) => !allowed.has(key))) throw new Error("retained run intent contains unsupported material");
|
|
4217
|
+
if (record.phase !== "intent") throw new Error("retained run intent has an invalid phase");
|
|
4218
|
+
for (const [key, value] of Object.entries(record)) {
|
|
4219
|
+
if (key === "phase") continue;
|
|
4220
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`retained run intent field "${key}" is invalid`);
|
|
4221
|
+
}
|
|
4222
|
+
assertDigest$1(record.requestedProfileDigest, "retained run intent profile digest");
|
|
4223
|
+
assertDigest$1(record.requestDigest, "retained run intent request digest");
|
|
4224
|
+
return stable;
|
|
4225
|
+
}
|
|
4226
|
+
function assertDigest$1(value, label) {
|
|
4227
|
+
if (typeof value !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(value)) throw new Error(`${label} is invalid`);
|
|
4228
|
+
}
|
|
4114
4229
|
/** Rebuild a retained-run client without retaining any object from the starter. @stable */
|
|
4115
4230
|
async function reconnectRetainedRun(options) {
|
|
4116
4231
|
const controlRef = AgentExactRunControlRefSchema.parse(options.controlRef);
|
|
4117
4232
|
if (controlRef.provider !== options.provider.name) throw new Error(`run provider "${controlRef.provider}" does not match "${options.provider.name}"`);
|
|
4118
|
-
const
|
|
4233
|
+
const providerCapabilities = await assertRetainedCapabilities(options.provider);
|
|
4119
4234
|
if (!options.provider.get) throw new Error(`provider "${options.provider.name}" cannot reconstruct an environment by id`);
|
|
4120
4235
|
const environment = await options.provider.get(controlRef.environmentId);
|
|
4121
4236
|
if (!environment) return null;
|
|
4237
|
+
const capabilities = retainedCapabilitiesForEnvironment(options.provider.name, providerCapabilities, environment);
|
|
4122
4238
|
const exact = exactSession(environment, controlRef);
|
|
4123
4239
|
return createRetainedRunHandle(environment, exact.session, exact.controlRef, capabilities, options.now);
|
|
4124
4240
|
}
|
|
4125
4241
|
async function assertRetainedCapabilities(provider) {
|
|
4126
4242
|
const capabilities = AgentEnvironmentCapabilitiesSchema.parse(await provider.capabilities());
|
|
4243
|
+
assertRetainedCapabilityRequirements(provider.name, capabilities);
|
|
4244
|
+
return capabilities;
|
|
4245
|
+
}
|
|
4246
|
+
/**
|
|
4247
|
+
* Select the capability document for one concrete environment.
|
|
4248
|
+
*
|
|
4249
|
+
* A measured environment document is authoritative. An absent document uses
|
|
4250
|
+
* the provider document because that provider claims the same guarantee for
|
|
4251
|
+
* every environment it creates.
|
|
4252
|
+
*/
|
|
4253
|
+
function retainedCapabilitiesForEnvironment(providerName, providerCapabilities, environment) {
|
|
4254
|
+
if (environment.capabilities === void 0) return providerCapabilities;
|
|
4255
|
+
const measured = AgentEnvironmentCapabilitiesSchema.parse(environment.capabilities);
|
|
4256
|
+
assertRetainedCapabilityRequirements(providerName, measured);
|
|
4257
|
+
return measured;
|
|
4258
|
+
}
|
|
4259
|
+
function assertRetainedCapabilityRequirements(providerName, capabilities) {
|
|
4127
4260
|
const retained = capabilities.retainedControl;
|
|
4128
|
-
if (retained?.exactRunIdentity !== true || retained.resultIdentity !== true || retained.eventIdentity !== true || retained.cancellationIdempotency !== true || !capabilities.streaming.detach || !capabilities.streaming.replay || !capabilities.streaming.turnIdempotency) throw new Error(`provider "${
|
|
4261
|
+
if (retained?.exactRunIdentity !== true || retained.resultIdentity !== true || retained.eventIdentity !== true || retained.cancellationIdempotency !== true || !capabilities.streaming.detach || !capabilities.streaming.replay || !capabilities.streaming.turnIdempotency) throw new Error(`provider "${providerName}" cannot control a retry-safe retained run`);
|
|
4262
|
+
}
|
|
4263
|
+
//#endregion
|
|
4264
|
+
//#region src/runtime/retained-interactive.ts
|
|
4265
|
+
/**
|
|
4266
|
+
* Start one retry-safe native coding-agent TUI without dispatching a headless turn.
|
|
4267
|
+
* The intent admission is durable before provider.create; the environment and
|
|
4268
|
+
* process admissions follow only after their exact provider coordinates exist.
|
|
4269
|
+
* @stable
|
|
4270
|
+
*/
|
|
4271
|
+
async function startRetainedInteractiveRun(options) {
|
|
4272
|
+
options.signal?.throwIfAborted();
|
|
4273
|
+
assertStableText(options.environment.idempotencyKey, "environment idempotency key");
|
|
4274
|
+
assertStableText(options.interactiveIdempotencyKey, "interactive idempotency key");
|
|
4275
|
+
if (typeof options.onAdmission !== "function") throw new Error("startRetainedInteractiveRun requires an awaited onAdmission durability hook");
|
|
4276
|
+
if (!options.provider.get) throw new Error(`provider "${options.provider.name}" cannot reconstruct an environment by id`);
|
|
4277
|
+
const profile = agentProfileSchema.parse(options.environment.profile);
|
|
4278
|
+
if (profile.harness === void 0) throw new Error("retained interactive runs require AgentProfile.harness");
|
|
4279
|
+
const requestedProfileDigest = canonicalAgentProfileDigest(profile);
|
|
4280
|
+
const identity = mintRetainedIdentity(options.environment.idempotencyKey, options.interactiveIdempotencyKey);
|
|
4281
|
+
const intent = interactiveIntent(options, profile, identity);
|
|
4282
|
+
if (options.intent === void 0) await admitDurably(options.onAdmission, intent);
|
|
4283
|
+
else assertExactInteractiveIntent(options.intent, intent);
|
|
4284
|
+
const providerCapabilities = AgentEnvironmentCapabilitiesSchema.parse(await awaitAbortable(Promise.resolve().then(() => options.provider.capabilities()), options.signal));
|
|
4285
|
+
assertInteractiveCapabilities(options.provider.name, providerCapabilities);
|
|
4286
|
+
const environment = await createInteractiveEnvironment(() => options.provider.create({
|
|
4287
|
+
...options.environment,
|
|
4288
|
+
profile,
|
|
4289
|
+
signal: options.signal,
|
|
4290
|
+
metadata: {
|
|
4291
|
+
...options.environment.metadata,
|
|
4292
|
+
retainedIdempotencyKey: options.environment.idempotencyKey,
|
|
4293
|
+
interactiveIdempotencyKey: options.interactiveIdempotencyKey,
|
|
4294
|
+
requestedProfileDigest,
|
|
4295
|
+
interactiveIntentDigest: intent.requestDigest,
|
|
4296
|
+
interactiveRunId: intent.runId,
|
|
4297
|
+
sessionId: identity.sessionId,
|
|
4298
|
+
executionId: identity.executionId
|
|
4299
|
+
}
|
|
4300
|
+
}), options.signal);
|
|
4301
|
+
let capabilities;
|
|
4302
|
+
try {
|
|
4303
|
+
assertExactEnvironment(options.provider.name, environment);
|
|
4304
|
+
options.signal?.throwIfAborted();
|
|
4305
|
+
capabilities = interactiveCapabilitiesForEnvironment(options.provider.name, providerCapabilities, environment);
|
|
4306
|
+
assertInteractiveMethods(options.provider.name, environment);
|
|
4307
|
+
} catch (error) {
|
|
4308
|
+
await destroyUnusedEnvironment(environment, error);
|
|
4309
|
+
throw error;
|
|
4310
|
+
}
|
|
4311
|
+
const request = interactiveRequest(options, environment, profile, requestedProfileDigest, identity);
|
|
4312
|
+
await admitDurably(options.onAdmission, {
|
|
4313
|
+
phase: "interactive_environment",
|
|
4314
|
+
provider: options.provider.name,
|
|
4315
|
+
environmentId: environment.id,
|
|
4316
|
+
idempotencyKey: options.environment.idempotencyKey,
|
|
4317
|
+
interactiveIdempotencyKey: options.interactiveIdempotencyKey,
|
|
4318
|
+
request
|
|
4319
|
+
});
|
|
4320
|
+
const ref = exactStartedRef(request, await startInteractiveProcess(environment, () => environment.startInteractive(request, { signal: options.signal }), options.signal));
|
|
4321
|
+
await admitDurably(options.onAdmission, {
|
|
4322
|
+
phase: "interactive_started",
|
|
4323
|
+
idempotencyKey: options.environment.idempotencyKey,
|
|
4324
|
+
interactiveIdempotencyKey: options.interactiveIdempotencyKey,
|
|
4325
|
+
ref
|
|
4326
|
+
});
|
|
4327
|
+
return createRetainedInteractiveRunHandle(environment, ref, capabilities, request);
|
|
4328
|
+
}
|
|
4329
|
+
/** Retry one exact start after its provider response may have been lost. @stable */
|
|
4330
|
+
async function recoverRetainedInteractiveRun(options) {
|
|
4331
|
+
options.signal?.throwIfAborted();
|
|
4332
|
+
if (typeof options.onAdmission !== "function") throw new Error("recoverRetainedInteractiveRun requires an awaited onAdmission durability hook");
|
|
4333
|
+
const admission = options.admission;
|
|
4334
|
+
if (admission.provider !== options.provider.name) throw new Error("interactive admission belongs to another provider");
|
|
4335
|
+
if (admission.phase === "interactive_intent") {
|
|
4336
|
+
if (options.replay === void 0) throw new Error("recoverRetainedInteractiveRun requires the original start material for an interactive intent");
|
|
4337
|
+
return startRetainedInteractiveRun({
|
|
4338
|
+
provider: options.provider,
|
|
4339
|
+
...options.replay,
|
|
4340
|
+
intent: admission,
|
|
4341
|
+
onAdmission: options.onAdmission,
|
|
4342
|
+
signal: options.signal
|
|
4343
|
+
});
|
|
4344
|
+
}
|
|
4345
|
+
const request = exactRecoveryRequest(admission);
|
|
4346
|
+
const { environment, capabilities } = await reconstructEnvironment(options.provider, admission.environmentId, options.signal);
|
|
4347
|
+
if (!environment || !capabilities) return null;
|
|
4348
|
+
const ref = exactStartedRef(request, await awaitAbortable(Promise.resolve().then(() => environment.startInteractive(request, { signal: options.signal })), options.signal));
|
|
4349
|
+
await admitDurably(options.onAdmission, {
|
|
4350
|
+
phase: "interactive_started",
|
|
4351
|
+
idempotencyKey: admission.idempotencyKey,
|
|
4352
|
+
interactiveIdempotencyKey: admission.interactiveIdempotencyKey,
|
|
4353
|
+
ref
|
|
4354
|
+
});
|
|
4355
|
+
return createRetainedInteractiveRunHandle(environment, ref, capabilities, request);
|
|
4356
|
+
}
|
|
4357
|
+
function exactRecoveryRequest(admission) {
|
|
4358
|
+
assertStableText(admission.environmentId, "interactive environment id");
|
|
4359
|
+
assertStableText(admission.idempotencyKey, "environment idempotency key");
|
|
4360
|
+
assertStableText(admission.interactiveIdempotencyKey, "interactive idempotency key");
|
|
4361
|
+
const request = exactAgentInteractiveSessionStart(admission.request);
|
|
4362
|
+
const identity = mintRetainedIdentity(admission.idempotencyKey, admission.interactiveIdempotencyKey);
|
|
4363
|
+
if (request.run.provider !== admission.provider || request.run.environmentId !== admission.environmentId || request.run.sessionId !== identity.sessionId || request.run.executionId !== identity.executionId) throw new Error("interactive admission does not match its recovery coordinates");
|
|
4364
|
+
return request;
|
|
4365
|
+
}
|
|
4366
|
+
/** Rebuild controls for one exact provider-owned coding-agent process. @stable */
|
|
4367
|
+
async function reconnectRetainedInteractiveRun(options) {
|
|
4368
|
+
options.signal?.throwIfAborted();
|
|
4369
|
+
const ref = AgentInteractiveSessionRefSchema.parse(options.ref);
|
|
4370
|
+
if (ref.run.provider !== options.provider.name) throw new Error("interactive session reference belongs to another provider");
|
|
4371
|
+
const { environment, capabilities } = await reconstructEnvironment(options.provider, ref.run.environmentId, options.signal);
|
|
4372
|
+
if (!environment || !capabilities) return null;
|
|
4373
|
+
const handle = createRetainedInteractiveRunHandle(environment, ref, capabilities);
|
|
4374
|
+
await handle.status({ signal: options.signal });
|
|
4375
|
+
return handle;
|
|
4376
|
+
}
|
|
4377
|
+
function interactiveRequest(options, environment, profile, requestedProfileDigest, identity) {
|
|
4378
|
+
const start = {
|
|
4379
|
+
profile,
|
|
4380
|
+
requestedProfileDigest,
|
|
4381
|
+
...options.initialPrompt === void 0 ? {} : { initialPrompt: options.initialPrompt },
|
|
4382
|
+
...options.cwd === void 0 ? {} : { cwd: options.cwd },
|
|
4383
|
+
...options.cols === void 0 ? {} : { cols: options.cols },
|
|
4384
|
+
...options.rows === void 0 ? {} : { rows: options.rows }
|
|
4385
|
+
};
|
|
4386
|
+
return exactAgentInteractiveSessionStart({
|
|
4387
|
+
run: agentInteractiveSessionRunRef({
|
|
4388
|
+
provider: options.provider.name,
|
|
4389
|
+
environmentId: environment.id,
|
|
4390
|
+
...identity
|
|
4391
|
+
}, start),
|
|
4392
|
+
...start
|
|
4393
|
+
});
|
|
4394
|
+
}
|
|
4395
|
+
function interactiveIntent(options, profile, identity) {
|
|
4396
|
+
const requestedProfileDigest = canonicalAgentProfileDigest(profile);
|
|
4397
|
+
const requestDigest = canonicalCandidateDigest({
|
|
4398
|
+
kind: "retained-interactive-intent.v1",
|
|
4399
|
+
provider: options.provider.name,
|
|
4400
|
+
idempotencyKey: options.environment.idempotencyKey,
|
|
4401
|
+
interactiveIdempotencyKey: options.interactiveIdempotencyKey,
|
|
4402
|
+
sessionId: identity.sessionId,
|
|
4403
|
+
executionId: identity.executionId,
|
|
4404
|
+
requestedProfileDigest,
|
|
4405
|
+
create: retainedCreateMaterial(options.environment),
|
|
4406
|
+
start: sanitizedStartMaterial(options)
|
|
4407
|
+
});
|
|
4408
|
+
return {
|
|
4409
|
+
phase: "interactive_intent",
|
|
4410
|
+
provider: options.provider.name,
|
|
4411
|
+
idempotencyKey: options.environment.idempotencyKey,
|
|
4412
|
+
interactiveIdempotencyKey: options.interactiveIdempotencyKey,
|
|
4413
|
+
sessionId: identity.sessionId,
|
|
4414
|
+
executionId: identity.executionId,
|
|
4415
|
+
runId: `interactive-intent-run:${requestDigest.slice(7)}`,
|
|
4416
|
+
requestedProfileDigest,
|
|
4417
|
+
requestDigest
|
|
4418
|
+
};
|
|
4419
|
+
}
|
|
4420
|
+
function sanitizedStartMaterial(options) {
|
|
4421
|
+
return {
|
|
4422
|
+
...options.initialPrompt === void 0 ? {} : { initialPrompt: options.initialPrompt },
|
|
4423
|
+
...options.cwd === void 0 ? {} : { cwd: options.cwd },
|
|
4424
|
+
...options.cols === void 0 ? {} : { cols: options.cols },
|
|
4425
|
+
...options.rows === void 0 ? {} : { rows: options.rows }
|
|
4426
|
+
};
|
|
4427
|
+
}
|
|
4428
|
+
function assertExactInteractiveIntent(received, expected) {
|
|
4429
|
+
if (canonicalCandidateDigest(parseInteractiveIntent(received)) !== canonicalCandidateDigest(expected)) throw new Error("interactive intent conflicts with replay material");
|
|
4430
|
+
}
|
|
4431
|
+
function parseInteractiveIntent(value) {
|
|
4432
|
+
const stable = detachedSnapshot(value, "interactive intent");
|
|
4433
|
+
if (stable === null || typeof stable !== "object" || Array.isArray(stable)) throw new Error("interactive intent is malformed");
|
|
4434
|
+
const record = stable;
|
|
4435
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
4436
|
+
"phase",
|
|
4437
|
+
"provider",
|
|
4438
|
+
"idempotencyKey",
|
|
4439
|
+
"interactiveIdempotencyKey",
|
|
4440
|
+
"sessionId",
|
|
4441
|
+
"executionId",
|
|
4442
|
+
"runId",
|
|
4443
|
+
"requestedProfileDigest",
|
|
4444
|
+
"requestDigest"
|
|
4445
|
+
]);
|
|
4446
|
+
if (Object.keys(record).some((key) => !allowed.has(key))) throw new Error("interactive intent contains unsupported material");
|
|
4447
|
+
if (record.phase !== "interactive_intent") throw new Error("interactive intent has an invalid phase");
|
|
4448
|
+
for (const [key, value] of Object.entries(record)) {
|
|
4449
|
+
if (key === "phase") continue;
|
|
4450
|
+
if (typeof value !== "string" || value.length === 0) throw new Error(`interactive intent field "${key}" is invalid`);
|
|
4451
|
+
}
|
|
4452
|
+
assertDigest(record.requestedProfileDigest, "interactive intent profile digest");
|
|
4453
|
+
assertDigest(record.requestDigest, "interactive intent request digest");
|
|
4454
|
+
return stable;
|
|
4455
|
+
}
|
|
4456
|
+
function assertDigest(value, label) {
|
|
4457
|
+
if (typeof value !== "string" || !/^sha256:[a-f0-9]{64}$/u.test(value)) throw new Error(`${label} is invalid`);
|
|
4458
|
+
}
|
|
4459
|
+
async function reconstructEnvironment(provider, environmentId, signal) {
|
|
4460
|
+
if (!provider.get) throw new Error(`provider "${provider.name}" cannot reconstruct an environment by id`);
|
|
4461
|
+
const providerCapabilities = AgentEnvironmentCapabilitiesSchema.parse(await awaitAbortable(Promise.resolve().then(() => provider.capabilities()), signal));
|
|
4462
|
+
assertInteractiveCapabilities(provider.name, providerCapabilities);
|
|
4463
|
+
const environment = await awaitAbortable(Promise.resolve().then(() => provider.get(environmentId, { signal })), signal);
|
|
4464
|
+
if (!environment) return {
|
|
4465
|
+
environment: null,
|
|
4466
|
+
capabilities: null
|
|
4467
|
+
};
|
|
4468
|
+
assertExactEnvironment(provider.name, environment, environmentId);
|
|
4469
|
+
const capabilities = interactiveCapabilitiesForEnvironment(provider.name, providerCapabilities, environment);
|
|
4470
|
+
assertInteractiveMethods(provider.name, environment);
|
|
4471
|
+
return {
|
|
4472
|
+
environment,
|
|
4473
|
+
capabilities
|
|
4474
|
+
};
|
|
4475
|
+
}
|
|
4476
|
+
function exactStartedRef(request, value) {
|
|
4477
|
+
const stableRequest = detachedSnapshot(request, "interactive start binding request");
|
|
4478
|
+
let ref;
|
|
4479
|
+
try {
|
|
4480
|
+
ref = AgentInteractiveSessionRefSchema.parse(value);
|
|
4481
|
+
} catch (error) {
|
|
4482
|
+
throw new RetainedInteractiveBindingError(stableRequest, {}, { cause: error });
|
|
4483
|
+
}
|
|
4484
|
+
if (!agentInteractiveSessionRefMatchesStart(request, ref)) throw new RetainedInteractiveBindingError(stableRequest, detachedSnapshot({ ref: detachedSnapshot(ref, "interactive provider start reference") }, "interactive provider start result"), { cause: /* @__PURE__ */ new Error("provider started another interactive run than requested") });
|
|
4485
|
+
return freezeInteractiveRef(ref);
|
|
4486
|
+
}
|
|
4487
|
+
function assertExactEnvironment(providerName, environment, environmentId) {
|
|
4488
|
+
if (environment.provider !== providerName || environmentId && environment.id !== environmentId) throw new Error("provider returned another interactive environment");
|
|
4489
|
+
assertStableText(environment.id, "interactive environment id");
|
|
4490
|
+
}
|
|
4491
|
+
function interactiveCapabilitiesForEnvironment(providerName, providerCapabilities, environment) {
|
|
4492
|
+
const capabilities = environment.capabilities === void 0 ? providerCapabilities : AgentEnvironmentCapabilitiesSchema.parse(environment.capabilities);
|
|
4493
|
+
assertInteractiveCapabilities(providerName, capabilities);
|
|
4129
4494
|
return capabilities;
|
|
4130
4495
|
}
|
|
4496
|
+
function assertInteractiveCapabilities(providerName, capabilities) {
|
|
4497
|
+
const interactive = capabilities.interactiveAgent;
|
|
4498
|
+
if (!interactive?.start || !interactive.control || !interactive.status || !interactive.attach || !interactive.reattach || !interactive.sendPrompt || !interactive.input || !interactive.resize || !interactive.stop) throw new Error(`provider "${providerName}" cannot control an exact interactive agent`);
|
|
4499
|
+
}
|
|
4500
|
+
function assertInteractiveMethods(providerName, environment) {
|
|
4501
|
+
if (!environment.startInteractive || !environment.interactive) throw new Error(`provider "${providerName}" exposes incomplete interactive agent controls`);
|
|
4502
|
+
}
|
|
4503
|
+
async function destroyUnusedEnvironment(environment, cause) {
|
|
4504
|
+
try {
|
|
4505
|
+
await destroyInteractiveEnvironment(environment);
|
|
4506
|
+
} catch (cleanupError) {
|
|
4507
|
+
throw new AggregateError([cause, cleanupError], "interactive environment was invalid and could not be destroyed");
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
//#endregion
|
|
4511
|
+
//#region src/runtime/retained-interactive-control.ts
|
|
4512
|
+
const MAX_GENERATION_CONFLICTS = 8;
|
|
4513
|
+
/**
|
|
4514
|
+
* Acquire provider-issued write authority without reading authority from status.
|
|
4515
|
+
*
|
|
4516
|
+
* A new coordinator starts at generation zero. If another claim already exists,
|
|
4517
|
+
* the provider returns its public generation and this helper retries one new
|
|
4518
|
+
* compare-and-swap operation. Every generation has a deterministic operation
|
|
4519
|
+
* identifier, so retrying after an ambiguous response cannot create two claims.
|
|
4520
|
+
* @stable
|
|
4521
|
+
*/
|
|
4522
|
+
async function claimRetainedInteractiveControl(options) {
|
|
4523
|
+
const expected = options.expectedGeneration ?? 0;
|
|
4524
|
+
if (!Number.isSafeInteger(expected) || expected < 0) throw new Error("interactive control expectedGeneration must be a non-negative integer");
|
|
4525
|
+
let generation = expected;
|
|
4526
|
+
for (let conflict = 0; conflict <= MAX_GENERATION_CONFLICTS; conflict += 1) {
|
|
4527
|
+
if (options.signal?.aborted) throw abortError(options.signal.reason);
|
|
4528
|
+
const material = {
|
|
4529
|
+
operationId: controlClaimOperationId(options.handle, options.holderId, generation),
|
|
4530
|
+
ref: options.handle.ref,
|
|
4531
|
+
holderId: options.holderId,
|
|
4532
|
+
expectedGeneration: generation
|
|
4533
|
+
};
|
|
4534
|
+
const acknowledgement = await options.handle.claimControl({
|
|
4535
|
+
...material,
|
|
4536
|
+
requestDigest: agentInteractiveSessionControlClaimRequestDigest(material)
|
|
4537
|
+
}, options.signal === void 0 ? void 0 : { signal: options.signal });
|
|
4538
|
+
if (acknowledgement.status === "accepted" || acknowledgement.status === "replayed") {
|
|
4539
|
+
const control = acknowledgement.control;
|
|
4540
|
+
if (control === void 0) throw new Error("provider accepted interactive control without returning its claim");
|
|
4541
|
+
if (Date.parse(control.expiresAt) <= Date.now()) throw new Error("provider returned an expired interactive control claim");
|
|
4542
|
+
return control;
|
|
4543
|
+
}
|
|
4544
|
+
if (acknowledgement.status !== "conflict" || acknowledgement.conflictReason !== "generation_mismatch") throw new Error(acknowledgement.status === "unknown" ? "interactive control claim outcome is unknown; retry the same acquisition" : "interactive control claim operation conflicts with different request material");
|
|
4545
|
+
const current = acknowledgement.currentGeneration;
|
|
4546
|
+
if (current === void 0 || current <= generation) throw new Error("provider returned a non-advancing interactive control generation");
|
|
4547
|
+
generation = current;
|
|
4548
|
+
}
|
|
4549
|
+
throw new Error("interactive control changed too often to acquire safely");
|
|
4550
|
+
}
|
|
4551
|
+
function controlClaimOperationId(handle, holderId, expectedGeneration) {
|
|
4552
|
+
return `interactive-claim-${canonicalCandidateDigest({
|
|
4553
|
+
kind: "retained-interactive-control-claim.v1",
|
|
4554
|
+
ref: handle.ref,
|
|
4555
|
+
holderId,
|
|
4556
|
+
expectedGeneration
|
|
4557
|
+
}).slice(7, 47)}`;
|
|
4558
|
+
}
|
|
4131
4559
|
//#endregion
|
|
4132
4560
|
//#region src/runtime/run-benchmark.ts
|
|
4133
4561
|
/**
|
|
@@ -6670,6 +7098,6 @@ function tail(s) {
|
|
|
6670
7098
|
return s.slice(-400);
|
|
6671
7099
|
}
|
|
6672
7100
|
//#endregion
|
|
6673
|
-
export {
|
|
7101
|
+
export { runPersonified as $, pickChampion as A, stopSentinel as At, runBenchmark as B, connectStdioMcp as Bt, analyzeTrace as C, inlineSandboxClient as Ct, chatWorkerSeam as D, completionAuthorizes as Dt, chatTransportExecutor as E, superviseDispatch as Et, strategyAuthorContract as F, renderLeaderboardSvg as Ft, reconnectRetainedRun as G, mcpSecretEnvMetadataKey as Gt, reconnectRetainedInteractiveRun as H, createMcpEnvironment as Ht, strategyAuthorSystemPrompt as I, renderPairwiseMarkdown as It, startRetainedRunInEnvironment as J, secretEnvOfMcpServer as Jt, recoverRetainedRun as K, resolveMcpServerLaunch as Kt, SandboxRunAbortError as L, auditIntent as Lt, selectChampion as M, pairwiseSignificance as Mt, assertStrategyContract as N, renderLeaderboardHtml as Nt, createChatSessionStore as O, deterministicCompletion as Ot, authorStrategy as P, renderLeaderboardMarkdown as Pt, definePersona as Q, openSandboxRun as R, defaultAuditorInstruction as Rt, withUntrackedArtifacts as S, localSandboxClient as St, runCoderChecks as T, loopDispatch as Tt, recoverRetainedInteractiveRun as U, sanitizeMcpToolSchema as Ut, claimRetainedInteractiveControl as V, materializeLocalMcp as Vt, startRetainedInteractiveRun as W, envKeyProvider as Wt, equalKOnCost as X, promotionGate as Y, trajectoryReport as Z, VERIFY_TAIL_CHARS as _, registryScopeAnalyst as _t, localShell as a, renderCorpusToInstructions as at, settledWorkerOut as b, defineLeaderboard as bt, createVerifierEnvironment as c, loopUntil as ct, harvestSurfaceDiffs as d, selectValidWinner as dt, builtinShapes as et, failuresAnalyst as f, verify as ft, NOTE_MAX_CHARS as g, createScopeAnalyst as gt, EVIDENCE_MAX_CHARS as h, buildSteerContext as ht, jjWorkspace as i, InMemoryCorpus as it, runStrategyEvolution as j, leaderboard as jt, discriminatingMeans as k, sentinelCompletion as kt, boxSurfaceReader as l, panel as lt, worktreeFanout as m, assertTraceDerivedFindings as mt, makeFinding$1 as n, registerShape as nt, runInWorkspace as o, fanout as ot, superviseSurface as p, widen as pt, startRetainedRun as q, resolveSecretEnv as qt, gitWorkspace as r, FileCorpus as rt, createWaterfallCollector as s, flatWidenGate as st, computeFindingId$1 as t, createShapeRegistry as tt, fsSurfaceReader as u, pipeline as ut, closingWorkerNote as v, inProcessSandboxClient as vt, patchDelivered as w, loopCampaignDispatch as wt, copyUntrackedIntoClone as x, resolveSandboxClient as xt, composeWorkerEvidence as y, harvestCorpus as yt, printBenchmarkReport as z, McpSpawnFault as zt };
|
|
6674
7102
|
|
|
6675
|
-
//# sourceMappingURL=runtime-
|
|
7103
|
+
//# sourceMappingURL=runtime-tTA2iCZQ.js.map
|