@opengeni/runtime 0.14.1 → 0.14.15
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/{chunk-4YJ5Z52Z.js → chunk-7E2ZSCZK.js} +6 -6
- package/dist/{chunk-4YJ5Z52Z.js.map → chunk-7E2ZSCZK.js.map} +1 -1
- package/dist/{chunk-HHWIZHQM.js → chunk-GNEGANUF.js} +942 -300
- package/dist/chunk-GNEGANUF.js.map +1 -0
- package/dist/codex-tool-search.d.ts +100 -0
- package/dist/context-compaction.d.ts +236 -0
- package/dist/history-sanitizer.d.ts +320 -0
- package/dist/index.d.ts +186 -718
- package/dist/index.js +612 -126
- package/dist/index.js.map +1 -1
- package/dist/{localSources-T3HZ6KY4.js → localSources-BXHBKGF4.js} +2 -2
- package/dist/mcp-network.d.ts +32 -35
- package/dist/metrics.d.ts +33 -0
- package/dist/sandbox/capabilities.d.ts +11 -0
- package/dist/sandbox/channel-a.d.ts +226 -0
- package/dist/sandbox/display-stack.d.ts +99 -0
- package/dist/sandbox/errors.d.ts +16 -0
- package/dist/sandbox/exec-banner.d.ts +19 -0
- package/dist/sandbox/index.d.ts +190 -6
- package/dist/sandbox/index.js +20 -4
- package/dist/sandbox/op-correlation.d.ts +24 -0
- package/dist/sandbox/provider-errors.d.ts +32 -0
- package/dist/sandbox/provider-operation-gate.d.ts +12 -0
- package/dist/sandbox/providers/blaxel.d.ts +2 -0
- package/dist/sandbox/providers/cloudflare.d.ts +2 -0
- package/dist/sandbox/providers/daytona.d.ts +2 -0
- package/dist/sandbox/providers/docker.d.ts +2 -0
- package/dist/sandbox/providers/e2b.d.ts +2 -0
- package/dist/sandbox/providers/index.d.ts +11 -0
- package/dist/sandbox/providers/local.d.ts +2 -0
- package/dist/sandbox/providers/modal.d.ts +132 -0
- package/dist/sandbox/providers/none.d.ts +2 -0
- package/dist/sandbox/providers/runloop.d.ts +2 -0
- package/dist/sandbox/providers/selfhosted.d.ts +2 -0
- package/dist/sandbox/providers/types.d.ts +30 -0
- package/dist/sandbox/providers/vercel.d.ts +2 -0
- package/dist/sandbox/recording.d.ts +80 -0
- package/dist/sandbox/routing/backend-resolver.d.ts +173 -0
- package/dist/sandbox/routing/routing-session.d.ts +401 -0
- package/dist/sandbox/run-credentials.d.ts +65 -0
- package/dist/sandbox/select.d.ts +120 -0
- package/dist/sandbox/selfhosted/capabilities.d.ts +91 -0
- package/dist/sandbox/selfhosted/control-rpc.d.ts +175 -0
- package/dist/sandbox/selfhosted/fault-rendering.d.ts +40 -0
- package/dist/sandbox/selfhosted/op-observer.d.ts +40 -0
- package/dist/sandbox/selfhosted/op-stream.d.ts +104 -0
- package/dist/sandbox/selfhosted/op-testing.d.ts +108 -0
- package/dist/sandbox/selfhosted/op-transport.d.ts +60 -0
- package/dist/sandbox/selfhosted/retry-policy.d.ts +106 -0
- package/dist/sandbox/selfhosted/session.d.ts +552 -0
- package/dist/sandbox/selfhosted/testing.d.ts +48 -0
- package/dist/sandbox/stream-port.d.ts +80 -0
- package/dist/sandbox/stream-token.d.ts +44 -0
- package/dist/sandbox/terminal-server.d.ts +67 -0
- package/dist/sandbox/toolspace-token.d.ts +23 -0
- package/dist/sandbox/turn-tool-cancellation.d.ts +72 -0
- package/dist/sandbox/workspace-archive.d.ts +39 -0
- package/dist/sandbox-computer.d.ts +227 -0
- package/dist/screenshot-error-card.d.ts +1 -0
- package/dist/skill-library.d.ts +10 -12
- package/dist/usage-telemetry.d.ts +45 -0
- package/dist/workspace-skills.d.ts +31 -0
- package/package.json +7 -7
- package/src/context-compaction.ts +600 -6
- package/src/history-sanitizer.ts +10 -92
- package/src/index.ts +301 -62
- package/src/sandbox/channel-a.ts +267 -81
- package/src/sandbox/index.ts +56 -94
- package/src/sandbox/provider-operation-gate.ts +110 -0
- package/src/sandbox/providers/docker.ts +13 -1
- package/src/sandbox/providers/modal.ts +433 -3
- package/src/sandbox/routing/routing-session.ts +84 -8
- package/src/sandbox/selfhosted/session.ts +7 -6
- package/src/sandbox/turn-tool-cancellation.ts +47 -7
- package/src/sandbox/workspace-archive.ts +176 -73
- package/src/sandbox-computer.ts +25 -75
- package/dist/chunk-HHWIZHQM.js.map +0 -1
- package/dist/index-BraazrAO.d.ts +0 -2931
- /package/dist/{localSources-T3HZ6KY4.js.map → localSources-BXHBKGF4.js.map} +0 -0
package/dist/sandbox/index.d.ts
CHANGED
|
@@ -1,6 +1,190 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
|
|
1
|
+
import type { Settings } from "@opengeni/config";
|
|
2
|
+
import { type SandboxBackend } from "@opengeni/contracts";
|
|
3
|
+
import type { SandboxClient, SandboxSessionState } from "@openai/agents/sandbox";
|
|
4
|
+
import { type WorkspaceArchiveDescriptor } from "./workspace-archive";
|
|
5
|
+
import type { RuntimeMetricsHooks } from "../metrics";
|
|
6
|
+
export { collectSandboxEnvironment, parseExposedPorts } from "@opengeni/config";
|
|
7
|
+
export { CAPABILITY_DESCRIPTORS, DESKTOP_STREAM_PORT, assertDescriptorRegistryInvariants, type CapabilityDescriptor, } from "./capabilities";
|
|
8
|
+
export { SandboxConfigError, SandboxProviderUnavailableError, SandboxResumeStateUnavailableError, } from "./errors";
|
|
9
|
+
export { PROVIDER_REGISTRY, assertProviderRegistryInvariants, type ProviderRegistration, type ProviderConstructionContext, } from "./providers";
|
|
10
|
+
export { classifyProviderSandboxFailure, isProviderSandboxGoneDuringRoutedOperation, isProviderSandboxNotFoundError, isProviderSandboxTransientError, type ProviderSandboxFailure, type ProviderSandboxFailureKind, } from "./provider-errors";
|
|
11
|
+
export { WORKSPACE_ARCHIVE_DESCRIPTOR_VERSION, WorkspaceArchiveIntegrityError, captureVerifiedWorkspaceArchive, decodeNativeSnapshotRef, describeLegacyNativeSnapshotArchive, describeNativeSnapshotArchive, fingerprintSandboxWorkspace, parseWorkspaceArchiveDescriptor, readVerifiedWorkspaceArchive, verifyRestoredWorkspace, type NativeSnapshotDescriptor, type NativeSnapshotProvider, type NativeSnapshotRef, type TarWorkspaceArchiveDescriptor, type VerifiedWorkspaceArchive, type WorkspaceArchiveDescriptor, type WorkspaceArchiveIntegrityCode, type WorkspaceTreeFingerprint, } from "./workspace-archive";
|
|
12
|
+
export { ensureModalRegistryImage, deleteModalCheckpointSnapshot, inspectModalSandboxLifecycle, modalSessionMatchesCheckpointProviderBinding, modalSandboxAttributionEnvironment, modalSandboxAttributionTags, resolveModalCheckpointProviderBinding, resolveModalCheckpointProviderBindingForLiveSandbox, resolveModalCheckpointProviderBindingForSession, sweepModalOrphanSandboxes, tagModalSandbox, terminateModalSandboxById, type LiveModalSandboxLeaseAttribution, type ModalModuleLoader, type ModalCheckpointProviderBinding, type ModalOrphanSweepResult, type ModalOrphanSweepTermination, type ModalSandboxAttribution, type RevalidateModalOrphanTermination, } from "./providers/modal";
|
|
13
|
+
export { selectBackend, backendSupportsOs, desktopCapableBackend, negotiateCapabilities, type NegotiationContext, } from "./select";
|
|
14
|
+
export { STREAM_TOKEN_DEFAULT_TTL_SECONDS, mintStreamToken, verifyStreamToken, StreamTokenPayload, type MintStreamTokenInput, type StreamTokenPayloadType, } from "./stream-token";
|
|
15
|
+
export { STREAM_PORT, DISPLAY_STACK_TIMEOUT_MS, DEFAULT_DESKTOP_GEOMETRY, DisplayStackError, DisplayStackUnsupportedError, buildDisplayStackScript, ensureDisplayStack, tearDownDisplayStack, type DesktopGeometry, type DisplayStackCallerKind, type DisplayStackClassification, type DisplayStackTelemetryContext, type DisplayStackTelemetryEvent, type DisplayStackTelemetryStatus, type EnsureDisplayStackOptions, type EnsureDisplayStackResult, } from "./display-stack";
|
|
16
|
+
export { TERMINAL_STREAM_PORT, TERMINAL_SERVER_TIMEOUT_MS, TerminalServerError, TerminalServerUnsupportedError, buildTerminalServerScript, ensureTerminalServer, tearDownTerminalServer, type EnsureTerminalServerOptions, type EnsureTerminalServerResult, } from "./terminal-server";
|
|
17
|
+
export { RunCredentialValidationError, normalizeRunCredentialsResolution, runCredentialRoot, runCredentialPointerFile, materializeRunCredentials, clearRunCredentials, clearRunCredentialsForAttempt, withRunCredentialEnvironment, withRunCredentialsSession, withRunCredentialsClient, type RunCredentialExpectedScope, type NormalizedRunCredentialMaterial, type RunCredentialCommandSession, type RunCredentialCommandRunner, type RunCredentialSessionReady, type MaterializeRunCredentialsOptions, } from "./run-credentials";
|
|
18
|
+
export { ToolspaceTokenPathError, toolspaceTokenFileForSession, toolspaceTokenFileFromEnvironment, withToolspaceTokenEnvironment, withToolspaceTokenSession, withToolspaceTokenClient, } from "./toolspace-token";
|
|
19
|
+
export { exposeStreamPort, buildStreamUrl, StreamPortUnavailableError, type ExposedPortEndpoint, type ExposeStreamPortInput, type ExposeStreamPortResult, } from "./stream-port";
|
|
20
|
+
export { startRecording, stopRecording, inspectRecordingArtifact, uploadRecordingArtifact, deleteRecordingArtifacts, recordingStorageKey, contentTypeForCodec, extForCodec, RecordingUnavailableError, RecordingError, type RecordingCodec, type RecordingContentType, type StartRecordingInput, type RecordingProcess, type RecordingArtifactMetadata, } from "./recording";
|
|
21
|
+
export { SandboxChannelAService, ChannelAValidationError, ChannelAUnavailableError, ChannelAConflictError, ChannelANotFoundError, ChannelAUnsupportedError, stripExecBanner, parseExecBannerSessionId, parseExecBannerExitCode, isExecSessionLostBanner, assertSafeRelPath, parsePorcelainV2, parseNumstatZ, parseUnifiedPatch, REPOSITORY_DISCOVERY_LIMIT, type ChannelASession, type ChannelAExecArgs, type ChannelAExecResult, type ChannelAEmitter, type SandboxChannelAServiceOptions, type RepositoryDiscoveryDegradedReason, type RepositoryDiscoveryResult, type NumstatEntry, } from "./channel-a";
|
|
22
|
+
export { type ControlRpc, NatsControlRpc, SelfhostedControlError, agentErrorToControlError, subjectFor, offlineControlResponse, timeoutControlResponse, offlineAgentError, timeoutAgentError, drainingExhaustedError, payloadTooLargeMessage, drainingMessage, execDeadlineHint, NEVER_SENT_DETAIL_KEY, type NatsRequestConnection, type SelfhostedUnavailableReason, } from "./selfhosted/control-rpc";
|
|
23
|
+
export type { SelfhostedOpObserver, SelfhostedOpObservation } from "./selfhosted/op-observer";
|
|
24
|
+
export { selfhostedFaultClass, SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES, renderSelfhostedFault, FAULT_FIELD_WHAT_HAPPENED, FAULT_FIELD_WHICH_LAYER, FAULT_FIELD_WHAT_PRESERVED, FAULT_FIELD_WHAT_TO_TRY, } from "./selfhosted/fault-rendering";
|
|
25
|
+
export { decideSelfhostedRetry, selfhostedRetryBackoffMs, defaultSelfhostedRetryClock, SELFHOSTED_IDEMPOTENT_READONLY_OPS, SELFHOSTED_DRAINING_MAX_RETRIES, SELFHOSTED_EXEC_DRAINING_MAX_RETRIES, SELFHOSTED_TIMEOUT_MAX_RETRIES, SELFHOSTED_NEVER_SENT_MAX_RETRIES, SELFHOSTED_RETRY_BACKOFF_BASE_MS, SELFHOSTED_RETRY_BACKOFF_FACTOR, SELFHOSTED_RETRY_BACKOFF_CAP_MS, type SelfhostedRetryClock, type SelfhostedRetryDecision, } from "./selfhosted/retry-policy";
|
|
26
|
+
export { SelfhostedSession, SelfhostedSandboxClient, buildSelfhostedBackendSession, isSelfhostedProviderNotFoundError, setSelfhostedApplyDiff, SELFHOSTED_DEFAULT_TIMEOUT_MS, SELFHOSTED_RELAY_STREAM_PATH, type SelfhostedSessionState, type SelfhostedSessionDeps, type SelfhostedSessionBuild, type SelfhostedRelayConfig, type SelfhostedExecArgs, type SelfhostedExecResult, type SelfhostedApplyDiff, type SelfhostedEditor, type SelfhostedImageOutput, type SelfhostedOpStreamDeps, } from "./selfhosted/session";
|
|
27
|
+
export { NatsOpStreamTransport, OpStreamUnavailableError, opAckSubject, opFrameSubject, type NatsOpStreamConnection, type OpStreamSubscription, type OpStreamTransport, } from "./selfhosted/op-transport";
|
|
28
|
+
export { OP_STREAM_ACK_INTERVAL_MS, OP_STREAM_DEFAULT_WINDOW_BYTES, OP_STREAM_RECONNECT_HOLD_MS, OP_STREAM_SILENCE_TIMEOUT_MS, type OpStreamExecOutcome, type OpStreamJournal, } from "./selfhosted/op-stream";
|
|
29
|
+
export { nextDurableOpId, runWithToolCallCorrelation, sanitizeOpIdToken } from "./op-correlation";
|
|
30
|
+
export { negotiateSelfhostedCapabilities, selfhostedLiveness, SELFHOSTED_RECONNECT_WINDOW_MS, type SelfhostedNegotiationInput, type SelfhostedLivenessState, type SelfhostedEnrollment, } from "./selfhosted/capabilities";
|
|
31
|
+
export { MockAgentResponder, type MockAgentResponderOptions, type MockExecHandler, } from "./selfhosted/testing";
|
|
32
|
+
export { RoutingBackendRecoveryRequiredError, RoutingMutationOutcomeUnknownError, RoutingRetainedProcessNotFoundError, RoutingSandboxSession, RoutingUnsupportedError, type ActivePointer, type DefaultBackendLossResult, type RoutableBackendSession, type ResolvedActiveBackend, type RoutingMutationSettlementResult, type RoutingRetainedProcess, type RoutingRetainedProcessAdoption, type RoutingRetainedProcessTerminalProof, type RoutingSandboxSessionDeps, type RoutingTransitionEvent, } from "./routing/routing-session";
|
|
33
|
+
export { makeActiveBackendResolver, ActiveBackendUnresolvableError, swapTargetEstablishability, type ActiveBackendResolverDeps, type RoutableSandbox, type BackendUnresolvableCode, type SwapTargetEstablishability, } from "./routing/backend-resolver";
|
|
34
|
+
/**
|
|
35
|
+
* Construct the raw provider SandboxClient for the configured backend. Registry-
|
|
36
|
+
* driven (the old flat if/else is gone): the backend's ProviderRegistration owns
|
|
37
|
+
* validateCredentials + build, with per-provider units/field-names. Returns
|
|
38
|
+
* undefined for "none".
|
|
39
|
+
*
|
|
40
|
+
* The desktop stream port (6080) is merged into exposedPorts for every desktop-
|
|
41
|
+
* capable (backend, os) when desktop is enabled AND the provider cannot expose
|
|
42
|
+
* ports on demand (modal/runloop/e2b pre-declare; blaxel resolves on demand).
|
|
43
|
+
* Existing modal/docker/local construction is behavior-preserved.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createSandboxClient(settings: Settings, environment?: Record<string, string>): unknown;
|
|
46
|
+
/**
|
|
47
|
+
* Construct the raw provider SandboxClient for an EXPLICIT backend, independent
|
|
48
|
+
* of settings.sandboxBackend. This is the resume-by-id builder the per-turn
|
|
49
|
+
* resume path (and the API-direct control plane) call: a lease's box was created
|
|
50
|
+
* on a specific backend (the envelope's backendId / the lease's
|
|
51
|
+
* resume_backend_id), and the client that reattaches to it must be built for
|
|
52
|
+
* THAT backend, not the process's currently-configured default. When the backend
|
|
53
|
+
* equals settings.sandboxBackend this is identical to createSandboxClient
|
|
54
|
+
* (behavior-preserved). Returns undefined for "none".
|
|
55
|
+
*/
|
|
56
|
+
export declare function createSandboxClientForBackend(backend: SandboxBackend, settings: Settings, environment?: Record<string, string>): unknown;
|
|
57
|
+
/**
|
|
58
|
+
* Extract the sandbox recovery entry from a run state as a plain JSON record,
|
|
59
|
+
* for storage decoupled from the RunState blob (issue #35). Encapsulates the
|
|
60
|
+
* underscore-internal `_sandbox` read in exactly one place.
|
|
61
|
+
*/
|
|
62
|
+
export declare function sandboxStateEntryFromRunState(state: unknown): Record<string, unknown> | null;
|
|
63
|
+
/**
|
|
64
|
+
* Items-mode counterpart of restoredSandboxSessionState: rebuild the live
|
|
65
|
+
* sandbox session state from a stored entry (as produced by
|
|
66
|
+
* sandboxStateEntryFromRunState) instead of from a RunState blob.
|
|
67
|
+
*/
|
|
68
|
+
export declare function restoredSandboxSessionStateFromEntry(entry: Record<string, unknown>, client: unknown): Promise<SandboxSessionState | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Read the persisted /workspace snapshot archive off a lease envelope's
|
|
71
|
+
* `sessionState` (sandbox-file-persistence). The reaper (persistDrainSnapshot)
|
|
72
|
+
* folds the base64 archive — a Modal native snapshot-ref or a tar archive, the
|
|
73
|
+
* exact bytes `session.persistWorkspace()` returned — at
|
|
74
|
+
* `sessionState.workspaceArchive`. Cold-restore decodes it and replays it via
|
|
75
|
+
* `session.hydrateWorkspace(archive)` on the freshly-created box so /workspace is
|
|
76
|
+
* restored. Returns undefined when the envelope carries no archive (a box that
|
|
77
|
+
* was never drain-persisted, or a non-persistence config that stored none).
|
|
78
|
+
*
|
|
79
|
+
* It is deliberately read SEPARATELY from deserializeSandboxSessionStateEnvelope:
|
|
80
|
+
* the archive does NOT ride serializeSessionState (it originates at reaper time),
|
|
81
|
+
* and the SDK's deserializeSessionState must NOT receive it (it is an opaque
|
|
82
|
+
* runtime-level field, not provider state).
|
|
83
|
+
*/
|
|
84
|
+
export declare function readWorkspaceArchiveFromEnvelopeSessionState(sessionState: unknown): Uint8Array | undefined;
|
|
85
|
+
/** Decode the Modal snapshot id out of a persisted base64 archive ref, or
|
|
86
|
+
* undefined when the archive is a tar payload or is unparseable. */
|
|
87
|
+
export declare function decodeModalSnapshotId(archive: Uint8Array): string | undefined;
|
|
88
|
+
export declare function deserializeSandboxSessionStateEnvelope(client: SandboxClient, envelope: unknown): Promise<SandboxSessionState | undefined>;
|
|
89
|
+
/** A live, externally-owned sandbox session re-established from the group lease
|
|
90
|
+
* envelope. The caller injects `{client, session, sessionState}` NON-OWNED into
|
|
91
|
+
* the run (or drives session.exec/readFile/resolveExposedPort directly) and
|
|
92
|
+
* drops the handle when done — the lease, not this handle, owns the box. */
|
|
93
|
+
export type EstablishedSandboxSession = {
|
|
94
|
+
client: unknown;
|
|
95
|
+
session: unknown;
|
|
96
|
+
sessionState: unknown;
|
|
97
|
+
instanceId: string;
|
|
98
|
+
backendId: string;
|
|
99
|
+
/** How this establish reached a live box: warm reattach by id ("resumed"),
|
|
100
|
+
* fresh create ("created"), or fresh create + archive hydration
|
|
101
|
+
* ("restored"). Callers use it to emit the durable sandbox.box.* lifecycle
|
|
102
|
+
* events — box transitions were previously unrecorded, which made both
|
|
103
|
+
* 2026-07-06 incidents near-unattributable. Optional so external/legacy
|
|
104
|
+
* constructors of this shape stay valid. */
|
|
105
|
+
origin?: "resumed" | "created" | "restored";
|
|
106
|
+
/** Set when a create-authorized reattach found the envelope's box GONE
|
|
107
|
+
* (provider NotFound) and fell through to cold-restore. */
|
|
108
|
+
lostInstanceId?: string;
|
|
109
|
+
/** Exact durable archive revision verified byte-for-byte after hydration. */
|
|
110
|
+
restoredArchive?: WorkspaceArchiveDescriptor;
|
|
111
|
+
};
|
|
112
|
+
export declare class SandboxExecReadinessError extends Error {
|
|
113
|
+
readonly backend: string;
|
|
114
|
+
readonly code: "exec_probe_unavailable" | "exec_probe_timeout" | "exec_probe_failed";
|
|
115
|
+
readonly timeoutMs: number;
|
|
116
|
+
readonly exitCode: number | null;
|
|
117
|
+
readonly name = "SandboxExecReadinessError";
|
|
118
|
+
constructor(backend: string, code: "exec_probe_unavailable" | "exec_probe_timeout" | "exec_probe_failed", timeoutMs: number, exitCode?: number | null);
|
|
119
|
+
}
|
|
120
|
+
/** A provider handle is not workspace readiness. Modal can return a handle
|
|
121
|
+
* before its command router accepts exec, so every create path must pass this
|
|
122
|
+
* bounded probe before atomically publishing the lease warm/ready. */
|
|
123
|
+
export declare function verifySandboxExecReadiness(established: EstablishedSandboxSession, timeoutMs?: number): Promise<void>;
|
|
124
|
+
export type SandboxCreatedCallback = (established: EstablishedSandboxSession) => Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Establish from one recovery envelope under an explicit creation policy. The
|
|
127
|
+
* envelope is the lease's box-identity descriptor (the same per-turn `_sandbox`
|
|
128
|
+
* envelope upserted by the turn activity).
|
|
129
|
+
*
|
|
130
|
+
* - `opts.backendOverride ?? envelope.backendId ?? settings.sandboxBackend`
|
|
131
|
+
* selects the backend; the client is built for THAT backend (resume-by-id is
|
|
132
|
+
* fenced to the original provider).
|
|
133
|
+
* - warm reattach: deserialize the envelope sessionState → client.resume(state)
|
|
134
|
+
* (no lock; R4-safe). `resume-only` propagates provider NotFound.
|
|
135
|
+
* - `create-or-restore`: the elected owner may replace a missing warm instance,
|
|
136
|
+
* or create directly from a cold/null envelope.
|
|
137
|
+
*/
|
|
138
|
+
export declare function establishSandboxSessionFromEnvelope(settings: Settings, envelope: Record<string, unknown> | null, opts: {
|
|
139
|
+
sessionId: string;
|
|
140
|
+
recovery: "create-or-restore" | "resume-only";
|
|
141
|
+
backendOverride?: SandboxBackend;
|
|
142
|
+
environment?: Record<string, string>;
|
|
143
|
+
onSandboxCreated?: SandboxCreatedCallback;
|
|
144
|
+
/** Called after archive hydration but immediately before the exact workspace
|
|
145
|
+
* fingerprint probe. Lease-aware callers persist `verifying` here so a box
|
|
146
|
+
* is never observable as ready while verification is in flight. */
|
|
147
|
+
onWorkspaceRestoreVerifying?: (descriptor: WorkspaceArchiveDescriptor) => Promise<void>;
|
|
148
|
+
metrics?: RuntimeMetricsHooks;
|
|
149
|
+
/** Isolated conformance-test/embedding seam. Ordinary runtime callers use
|
|
150
|
+
* the validated provider registry. */
|
|
151
|
+
clientFactory?: (backend: SandboxBackend, settings: Settings, environment: Record<string, string>) => unknown;
|
|
152
|
+
}): Promise<EstablishedSandboxSession>;
|
|
153
|
+
/**
|
|
154
|
+
* Fold a freshly-established (or resumed) sandbox session into the persistable
|
|
155
|
+
* `resume_state` envelope the lease stores — the SAME `{ backendId, sessionState }`
|
|
156
|
+
* shape `establishSandboxSessionFromEnvelope` consumes to RESUME BY ID. The
|
|
157
|
+
* API-direct control plane (viewer attach / Channel-A) MUST persist this onto the
|
|
158
|
+
* lease at warm-commit time, or a later op (which reads the lease's resume_state)
|
|
159
|
+
* has nothing to resume from and COLD-CREATES A RIVAL BOX — the box-churn the
|
|
160
|
+
* prove-it surfaced (fs.write then fs.read 404'd on a different box; N Channel-A
|
|
161
|
+
* ops leaked N boxes). Returns null when the client cannot serialize (the caller
|
|
162
|
+
* stores null and the box rides the provider idle-timeout — no rival spawn, just
|
|
163
|
+
* no warm-reattach).
|
|
164
|
+
*/
|
|
165
|
+
export declare function serializeEstablishedSandboxEnvelope(established: EstablishedSandboxSession): Promise<Record<string, unknown> | null>;
|
|
166
|
+
/**
|
|
167
|
+
* Whether a replacement envelope contains a provider-resumable identity. An
|
|
168
|
+
* archive-only envelope is intentionally valid recovery metadata, but it is
|
|
169
|
+
* never proof that the newly-created provider box can be resumed or attached.
|
|
170
|
+
*/
|
|
171
|
+
export declare function hasPersistableSandboxProviderIdentity(envelope: Record<string, unknown> | null | undefined): envelope is Record<string, unknown>;
|
|
172
|
+
/** A replacement provider may not be published warm without a resumable
|
|
173
|
+
* identity. Archive-only state is retained only when the caller rolls back to
|
|
174
|
+
* cold and needs the verified workspace bytes for the next attempt. */
|
|
175
|
+
export declare class SandboxReplacementProviderStateError extends Error {
|
|
176
|
+
readonly backend: string;
|
|
177
|
+
readonly code: "replacement_provider_state_unpersistable";
|
|
178
|
+
constructor(backend: string);
|
|
179
|
+
}
|
|
180
|
+
export declare function requirePersistableReplacementSandboxEnvelope(envelope: Record<string, unknown> | null, backend: string): Record<string, unknown>;
|
|
181
|
+
/**
|
|
182
|
+
* Build the only resume envelope that may be published for a newly-created
|
|
183
|
+
* replacement sandbox. Historical state contributes durable archive pointers
|
|
184
|
+
* only; it can never substitute for serialization of the replacement's provider
|
|
185
|
+
* identity. If replacement serialization is unavailable or fails, publication
|
|
186
|
+
* keeps an archive-only envelope (when one exists) or null. The new instance id
|
|
187
|
+
* remains separately fenced on the lease, while later attach/resume fails closed
|
|
188
|
+
* rather than targeting the dead provider that initiated rematerialization.
|
|
189
|
+
*/
|
|
190
|
+
export declare function serializeReplacementSandboxEnvelope(established: EstablishedSandboxSession, archiveSource: Record<string, unknown> | null): Promise<Record<string, unknown> | null>;
|
package/dist/sandbox/index.js
CHANGED
|
@@ -85,9 +85,12 @@ import {
|
|
|
85
85
|
createSandboxClientForBackend,
|
|
86
86
|
decideSelfhostedRetry,
|
|
87
87
|
decodeModalSnapshotId,
|
|
88
|
+
decodeNativeSnapshotRef,
|
|
88
89
|
defaultSelfhostedRetryClock,
|
|
89
|
-
|
|
90
|
+
deleteModalCheckpointSnapshot,
|
|
90
91
|
deleteRecordingArtifacts,
|
|
92
|
+
describeLegacyNativeSnapshotArchive,
|
|
93
|
+
describeNativeSnapshotArchive,
|
|
91
94
|
deserializeSandboxSessionStateEnvelope,
|
|
92
95
|
desktopCapableBackend,
|
|
93
96
|
drainingExhaustedError,
|
|
@@ -101,6 +104,7 @@ import {
|
|
|
101
104
|
extForCodec,
|
|
102
105
|
fingerprintSandboxWorkspace,
|
|
103
106
|
hasPersistableSandboxProviderIdentity,
|
|
107
|
+
inspectModalSandboxLifecycle,
|
|
104
108
|
inspectRecordingArtifact,
|
|
105
109
|
isExecSessionLostBanner,
|
|
106
110
|
isProviderSandboxGoneDuringRoutedOperation,
|
|
@@ -112,6 +116,7 @@ import {
|
|
|
112
116
|
mintStreamToken,
|
|
113
117
|
modalSandboxAttributionEnvironment,
|
|
114
118
|
modalSandboxAttributionTags,
|
|
119
|
+
modalSessionMatchesCheckpointProviderBinding,
|
|
115
120
|
negotiateCapabilities,
|
|
116
121
|
negotiateSelfhostedCapabilities,
|
|
117
122
|
nextDurableOpId,
|
|
@@ -133,6 +138,9 @@ import {
|
|
|
133
138
|
recordingStorageKey,
|
|
134
139
|
renderSelfhostedFault,
|
|
135
140
|
requirePersistableReplacementSandboxEnvelope,
|
|
141
|
+
resolveModalCheckpointProviderBinding,
|
|
142
|
+
resolveModalCheckpointProviderBindingForLiveSandbox,
|
|
143
|
+
resolveModalCheckpointProviderBindingForSession,
|
|
136
144
|
restoredSandboxSessionStateFromEntry,
|
|
137
145
|
runCredentialPointerFile,
|
|
138
146
|
runCredentialRoot,
|
|
@@ -170,8 +178,8 @@ import {
|
|
|
170
178
|
withToolspaceTokenClient,
|
|
171
179
|
withToolspaceTokenEnvironment,
|
|
172
180
|
withToolspaceTokenSession
|
|
173
|
-
} from "../chunk-
|
|
174
|
-
import "../chunk-
|
|
181
|
+
} from "../chunk-GNEGANUF.js";
|
|
182
|
+
import "../chunk-7E2ZSCZK.js";
|
|
175
183
|
import "../chunk-K4V4QYCL.js";
|
|
176
184
|
import "../chunk-PZ5AY32C.js";
|
|
177
185
|
export {
|
|
@@ -261,9 +269,12 @@ export {
|
|
|
261
269
|
createSandboxClientForBackend,
|
|
262
270
|
decideSelfhostedRetry,
|
|
263
271
|
decodeModalSnapshotId,
|
|
272
|
+
decodeNativeSnapshotRef,
|
|
264
273
|
defaultSelfhostedRetryClock,
|
|
265
|
-
|
|
274
|
+
deleteModalCheckpointSnapshot,
|
|
266
275
|
deleteRecordingArtifacts,
|
|
276
|
+
describeLegacyNativeSnapshotArchive,
|
|
277
|
+
describeNativeSnapshotArchive,
|
|
267
278
|
deserializeSandboxSessionStateEnvelope,
|
|
268
279
|
desktopCapableBackend,
|
|
269
280
|
drainingExhaustedError,
|
|
@@ -277,6 +288,7 @@ export {
|
|
|
277
288
|
extForCodec,
|
|
278
289
|
fingerprintSandboxWorkspace,
|
|
279
290
|
hasPersistableSandboxProviderIdentity,
|
|
291
|
+
inspectModalSandboxLifecycle,
|
|
280
292
|
inspectRecordingArtifact,
|
|
281
293
|
isExecSessionLostBanner,
|
|
282
294
|
isProviderSandboxGoneDuringRoutedOperation,
|
|
@@ -288,6 +300,7 @@ export {
|
|
|
288
300
|
mintStreamToken,
|
|
289
301
|
modalSandboxAttributionEnvironment,
|
|
290
302
|
modalSandboxAttributionTags,
|
|
303
|
+
modalSessionMatchesCheckpointProviderBinding,
|
|
291
304
|
negotiateCapabilities,
|
|
292
305
|
negotiateSelfhostedCapabilities,
|
|
293
306
|
nextDurableOpId,
|
|
@@ -309,6 +322,9 @@ export {
|
|
|
309
322
|
recordingStorageKey,
|
|
310
323
|
renderSelfhostedFault,
|
|
311
324
|
requirePersistableReplacementSandboxEnvelope,
|
|
325
|
+
resolveModalCheckpointProviderBinding,
|
|
326
|
+
resolveModalCheckpointProviderBindingForLiveSandbox,
|
|
327
|
+
resolveModalCheckpointProviderBindingForSession,
|
|
312
328
|
restoredSandboxSessionStateFromEntry,
|
|
313
329
|
runCredentialPointerFile,
|
|
314
330
|
runCredentialRoot,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitize a tool call id into a legal NATS subject TOKEN fragment. The op id
|
|
3
|
+
* is interpolated into the per-op frame subject, whose tokens must not contain
|
|
4
|
+
* whitespace/control characters or the subject-structure characters (`.`,
|
|
5
|
+
* `*`, `>`); the runner refuses illegal ids loudly. The mapping is INJECTIVE
|
|
6
|
+
* (each disallowed char becomes `_<hex>_`), so two distinct call ids can never
|
|
7
|
+
* collide into one op id — a collision would merge two different execs through
|
|
8
|
+
* the idempotent-OpStart dedup and return the wrong result.
|
|
9
|
+
*/
|
|
10
|
+
export declare function sanitizeOpIdToken(raw: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Bind a tool-call correlation context around `fn` (the tool's execute). Every
|
|
13
|
+
* durable op id minted inside — however deep in the transport — is
|
|
14
|
+
* `{callId}:{ordinal}` with ordinals starting at 0 per invocation.
|
|
15
|
+
*/
|
|
16
|
+
export declare function runWithToolCallCorrelation<T>(callId: string, fn: () => T): T;
|
|
17
|
+
/**
|
|
18
|
+
* Mint the next durable op id for the current tool invocation, or null when no
|
|
19
|
+
* correlation context is bound (a non-tool caller, e.g. Channel-A structural
|
|
20
|
+
* exec). Callers fall back to a random unique id — safe (never collides, never
|
|
21
|
+
* wrongly dedups), merely not stable across a turn re-dispatch, which degrades
|
|
22
|
+
* that one op to today's at-least-once semantics.
|
|
23
|
+
*/
|
|
24
|
+
export declare function nextDurableOpId(): string | null;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider sandbox failure classification.
|
|
3
|
+
*
|
|
4
|
+
* This is deliberately structural and fail-closed. DNS failures often contain
|
|
5
|
+
* the word "not found" (`ENOTFOUND`) while gRPC status values are also used by
|
|
6
|
+
* unrelated SDKs and command routers. A bare numeric status (including gRPC's
|
|
7
|
+
* numeric 5) is therefore not enough to retire a provider instance. Only
|
|
8
|
+
* authoritative, non-transient evidence may retire a provider instance and
|
|
9
|
+
* license lease recovery.
|
|
10
|
+
*/
|
|
11
|
+
export type ProviderSandboxFailureKind = "not_found" | "transient_transport" | "other";
|
|
12
|
+
export type ProviderSandboxFailure = {
|
|
13
|
+
kind: ProviderSandboxFailureKind;
|
|
14
|
+
/** Bounded, non-secret diagnostic suitable for logs and lifecycle events. */
|
|
15
|
+
diagnostic: string;
|
|
16
|
+
};
|
|
17
|
+
/** Typed transport evidence always dominates nested/string NotFound text. */
|
|
18
|
+
export declare function classifyProviderSandboxFailure(backendId: string, error: unknown): ProviderSandboxFailure;
|
|
19
|
+
export declare function isProviderSandboxNotFoundError(backendId: string, error: unknown): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether a failure from an operation routed through an already-established
|
|
22
|
+
* sandbox proves that exact provider sandbox disappeared.
|
|
23
|
+
*
|
|
24
|
+
* Routed operations can legitimately return HTTP 404 / `NOT_FOUND` for paths,
|
|
25
|
+
* files, ports, processes, and other subresources. Those generic signals are
|
|
26
|
+
* sufficient for provider create/resume APIs, but they must never retire the
|
|
27
|
+
* live sandbox identity after an arbitrary operation. Only an explicit
|
|
28
|
+
* sandbox-scoped provider code or Modal's exact terminal sandbox grammar is
|
|
29
|
+
* authoritative on this path. Transient transport evidence still dominates.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isProviderSandboxGoneDuringRoutedOperation(backendId: string, error: unknown): boolean;
|
|
32
|
+
export declare function isProviderSandboxTransientError(backendId: string, error: unknown): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordinate every command/filesystem/control call against one in-process
|
|
3
|
+
* provider session. Ordinary operations may overlap; once a capture queues,
|
|
4
|
+
* later operations wait until its exclusive provider pause completes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function withSandboxProviderOperation<T>(session: unknown, operation: () => Promise<T>): Promise<T>;
|
|
7
|
+
/**
|
|
8
|
+
* Hold the provider session exclusively for the complete verified archive
|
|
9
|
+
* capture. The durable lease claim handles other workers; this local gate
|
|
10
|
+
* closes the same-holder race between native reads and the heartbeat capture.
|
|
11
|
+
*/
|
|
12
|
+
export declare function withSandboxProviderCapture<T>(session: unknown, capture: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SandboxBackend } from "@opengeni/contracts";
|
|
2
|
+
import type { ProviderRegistration } from "./types";
|
|
3
|
+
export declare const PROVIDER_REGISTRY: Record<SandboxBackend, ProviderRegistration>;
|
|
4
|
+
/**
|
|
5
|
+
* Assert the descriptor table AND that each registered provider's SDK client
|
|
6
|
+
* reports the backendId its descriptor claims. The latter is the
|
|
7
|
+
* deferred-from-P0.1 invariant — it can only run here because it constructs the
|
|
8
|
+
* real clients. Called once at registry build (and from a unit test).
|
|
9
|
+
*/
|
|
10
|
+
export declare function assertProviderRegistryInvariants(): void;
|
|
11
|
+
export type { ProviderRegistration, ProviderConstructionContext } from "./types";
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { ModalImageSelector, ModalSandboxClient, type ModalSandboxSession, type ModalSandboxSessionState } from "@openai/agents-extensions/sandbox/modal";
|
|
2
|
+
import type { Settings } from "@opengeni/config";
|
|
3
|
+
import { type ModalCheckpointProviderBinding } from "@opengeni/contracts";
|
|
4
|
+
import type { ProviderRegistration } from "./types";
|
|
5
|
+
export type { ModalCheckpointProviderBinding } from "@opengeni/contracts";
|
|
6
|
+
export type ModalSandboxAttribution = {
|
|
7
|
+
leaseId: string;
|
|
8
|
+
workspaceId: string;
|
|
9
|
+
sandboxGroupId: string;
|
|
10
|
+
};
|
|
11
|
+
export type LiveModalSandboxLeaseAttribution = ModalSandboxAttribution & {
|
|
12
|
+
instanceId: string | null;
|
|
13
|
+
liveness?: string;
|
|
14
|
+
};
|
|
15
|
+
export type ModalOrphanSweepTermination = {
|
|
16
|
+
sandboxId: string;
|
|
17
|
+
reason: "stale_attribution" | "unattributed";
|
|
18
|
+
tags: Record<string, string>;
|
|
19
|
+
};
|
|
20
|
+
export type ModalOrphanSweepResult = {
|
|
21
|
+
examined: number;
|
|
22
|
+
terminated: ModalOrphanSweepTermination[];
|
|
23
|
+
skipped: number;
|
|
24
|
+
};
|
|
25
|
+
export type RevalidateModalOrphanTermination = (candidate: ModalOrphanSweepTermination) => Promise<boolean>;
|
|
26
|
+
export declare function modalSandboxAttributionEnvironment(input: ModalSandboxAttribution): Record<string, string>;
|
|
27
|
+
export declare function modalSandboxAttributionTags(input: ModalSandboxAttribution): Record<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Modal proves that the exact exec has already terminated with a typed
|
|
30
|
+
* FAILED_PRECONDITION from its stdin-write RPC. Keep this deliberately
|
|
31
|
+
* structural and exact: other FAILED_PRECONDITION errors are not process
|
|
32
|
+
* lifetime authority.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isModalExecAlreadyCompletedError(error: unknown): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Bridge the pinned Agents Extensions Modal adapter to Modal 0.9's provider
|
|
37
|
+
* contracts. The wrapper re-checks the private provider sandbox on every
|
|
38
|
+
* capture because snapshot_filesystem hydration replaces that object.
|
|
39
|
+
*/
|
|
40
|
+
export declare function installOpenGeniModalSnapshotPolicy<T extends object>(session: T): T;
|
|
41
|
+
export declare class OpenGeniModalSandboxClient extends ModalSandboxClient {
|
|
42
|
+
create(args?: Parameters<ModalSandboxClient["create"]>[0], manifestOptions?: Parameters<ModalSandboxClient["create"]>[1]): Promise<ModalSandboxSession>;
|
|
43
|
+
resume(state: ModalSandboxSessionState): Promise<ModalSandboxSession>;
|
|
44
|
+
}
|
|
45
|
+
export declare const modalProvider: ProviderRegistration;
|
|
46
|
+
type ModalModule = typeof import("modal");
|
|
47
|
+
type ModalClientLike = InstanceType<ModalModule["ModalClient"]>;
|
|
48
|
+
/** Loader seam so unit tests can inject a fake modal module. */
|
|
49
|
+
export type ModalModuleLoader = () => Promise<Pick<ModalModule, "ModalClient">>;
|
|
50
|
+
/**
|
|
51
|
+
* Resolve + cache the private-registry Modal image. No-op unless BOTH
|
|
52
|
+
* `modalImageRef` and `modalImageRegistrySecret` are set. Memoized per
|
|
53
|
+
* (imageRef, secret, environment) so it runs once per worker process. Awaited at
|
|
54
|
+
* worker boot for the deployment-global image and at turn time for pack-scoped
|
|
55
|
+
* images BEFORE the first sandbox using that ref is created; `build` then reads the
|
|
56
|
+
* resolved image and otherwise falls back to the public `fromTag` path.
|
|
57
|
+
*/
|
|
58
|
+
export declare function ensureModalRegistryImage(settings: Settings, loadModal?: ModalModuleLoader): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Choose the image selector for a Modal sandbox client from settings. Returns:
|
|
61
|
+
* - `fromImage(resolved)` when a private-registry secret is configured AND the
|
|
62
|
+
* image has been resolved (ensureModalRegistryImage ran before create);
|
|
63
|
+
* - `fromTag(modalImageRef)` for the public path (no secret, or cold cache — the
|
|
64
|
+
* resume/attach paths never pull an image so the tag branch is harmless there);
|
|
65
|
+
* - `undefined` when no image ref is set (Modal uses its default image).
|
|
66
|
+
* Exported for unit tests.
|
|
67
|
+
*/
|
|
68
|
+
export declare function resolveModalImageSelector(settings: Settings): ModalImageSelector | undefined;
|
|
69
|
+
/** Test-only: clear the resolved/in-flight image caches. */
|
|
70
|
+
export declare function __resetModalRegistryImageCacheForTest(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Resolve checkpoint ownership through the exact authenticated Modal client
|
|
73
|
+
* embedded in the session that creates the snapshot. The field is private in
|
|
74
|
+
* the pinned Agents extension, so this adapter is intentionally fail-closed:
|
|
75
|
+
* an upstream shape change disables native publication instead of guessing
|
|
76
|
+
* ownership from a newly-resolved ambient profile.
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveModalCheckpointProviderBindingForSession(settings: Settings, session: unknown): Promise<{
|
|
79
|
+
key: string;
|
|
80
|
+
binding: ModalCheckpointProviderBinding;
|
|
81
|
+
}>;
|
|
82
|
+
/** Compare a restore receipt against the exact authenticated Modal client
|
|
83
|
+
* embedded in the created session. This deliberately does not resolve a second
|
|
84
|
+
* ambient client: the session that will consume the snapshot is the authority. */
|
|
85
|
+
export declare function modalSessionMatchesCheckpointProviderBinding(settings: Settings, session: unknown, expectedBindingKey: string): Promise<boolean>;
|
|
86
|
+
/** Resolve the authoritative Modal workspace behind the configured credential.
|
|
87
|
+
* Snapshot ids are workspace-scoped; persisting this non-secret binding lets GC
|
|
88
|
+
* reject a credential rotation that points at a different workspace instead of
|
|
89
|
+
* issuing a destructive call under ambient credentials. */
|
|
90
|
+
export declare function resolveModalCheckpointProviderBinding(settings: Settings, createClient?: (settings: Settings) => Promise<ModalClientLike>): Promise<{
|
|
91
|
+
key: string;
|
|
92
|
+
binding: ModalCheckpointProviderBinding;
|
|
93
|
+
}>;
|
|
94
|
+
/** Prove a legacy lease's live sandbox is visible in the same Modal namespace
|
|
95
|
+
* whose identity will own the adopted checkpoint row. */
|
|
96
|
+
export declare function resolveModalCheckpointProviderBindingForLiveSandbox(settings: Settings, sandboxId: string, createClient?: (settings: Settings) => Promise<ModalClientLike>): Promise<{
|
|
97
|
+
key: string;
|
|
98
|
+
binding: ModalCheckpointProviderBinding;
|
|
99
|
+
}>;
|
|
100
|
+
/**
|
|
101
|
+
* Observe one exact historical Modal sandbox without consulting the current
|
|
102
|
+
* lease or its (possibly successor-owned) resume envelope. This is deliberately
|
|
103
|
+
* lifecycle-only: a running sandbox does not prove whether an individual
|
|
104
|
+
* retained process is still running, while a terminal/missing sandbox proves
|
|
105
|
+
* that none of its processes can still execute.
|
|
106
|
+
*/
|
|
107
|
+
export declare function inspectModalSandboxLifecycle(settings: Settings, sandboxId: string, expectedBindingKey?: string | null, createClient?: (settings: Settings) => Promise<ModalClientLike>): Promise<{
|
|
108
|
+
status: "running";
|
|
109
|
+
providerBindingKey: string;
|
|
110
|
+
providerBinding: ModalCheckpointProviderBinding;
|
|
111
|
+
} | {
|
|
112
|
+
status: "terminated";
|
|
113
|
+
exitCode: number;
|
|
114
|
+
providerBindingKey: string;
|
|
115
|
+
providerBinding: ModalCheckpointProviderBinding;
|
|
116
|
+
} | {
|
|
117
|
+
status: "not_found";
|
|
118
|
+
providerBindingKey: string;
|
|
119
|
+
providerBinding: ModalCheckpointProviderBinding;
|
|
120
|
+
}>;
|
|
121
|
+
export declare function deleteModalCheckpointSnapshot(settings: Settings, expectedBindingKey: string, snapshotId: string, createClient?: (settings: Settings) => Promise<ModalClientLike>): Promise<"deleted" | "not_found">;
|
|
122
|
+
export declare function tagModalSandbox(settings: Settings, sandboxId: string, attribution: ModalSandboxAttribution): Promise<boolean>;
|
|
123
|
+
export declare function terminateModalSandboxById(settings: Settings, sandboxId: string): Promise<boolean>;
|
|
124
|
+
export declare function sweepModalOrphanSandboxes(settings: Settings, liveLeases: LiveModalSandboxLeaseAttribution[], options?: {
|
|
125
|
+
now?: Date;
|
|
126
|
+
maxTerminations?: number;
|
|
127
|
+
unattributedGraceMs?: number;
|
|
128
|
+
client?: ModalClientLike;
|
|
129
|
+
/** Re-read durable ownership immediately before provider termination. A
|
|
130
|
+
* false result or callback failure skips the destructive action. */
|
|
131
|
+
revalidateTermination?: RevalidateModalOrphanTermination;
|
|
132
|
+
}): Promise<ModalOrphanSweepResult>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Settings } from "@opengeni/config";
|
|
2
|
+
import type { CapabilityDescriptor, SandboxBackend } from "@opengeni/contracts";
|
|
3
|
+
export interface ProviderConstructionContext {
|
|
4
|
+
settings: Settings;
|
|
5
|
+
/** The env map for the box (collectSandboxEnvironment / per-run environment). */
|
|
6
|
+
environment: Record<string, string>;
|
|
7
|
+
/**
|
|
8
|
+
* Parsed exposed ports (config string -> number[]); already includes the
|
|
9
|
+
* desktop stream port (6080) when this is a desktop tier with desktop enabled
|
|
10
|
+
* and the provider cannot expose ports on demand (the merge happens in
|
|
11
|
+
* createSandboxClient before build()).
|
|
12
|
+
*/
|
|
13
|
+
exposedPorts: number[];
|
|
14
|
+
}
|
|
15
|
+
export interface ProviderRegistration {
|
|
16
|
+
backend: SandboxBackend;
|
|
17
|
+
descriptor: CapabilityDescriptor;
|
|
18
|
+
/**
|
|
19
|
+
* Validate that the settings carry the credentials/config this provider
|
|
20
|
+
* REQUIRES. Throw SandboxConfigError on any missing/contradictory field.
|
|
21
|
+
* Pure — no network. Called by both the factory and a deploy-time preflight.
|
|
22
|
+
* The factory calls this before build(), so build() may assume valid settings.
|
|
23
|
+
*/
|
|
24
|
+
validateCredentials(settings: Settings): void;
|
|
25
|
+
/**
|
|
26
|
+
* Build the raw SDK SandboxClient. Returns undefined ONLY for "none".
|
|
27
|
+
* The factory calls validateCredentials() first, so build() can assume valid.
|
|
28
|
+
*/
|
|
29
|
+
build(ctx: ProviderConstructionContext): unknown;
|
|
30
|
+
}
|