@claxedo/sandbox-manager 0.6.0 → 0.9.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/README.md +60 -15
- package/dist/checkpoint-manager.d.ts +47 -0
- package/dist/checkpoint-manager.mjs +116 -0
- package/dist/daytona-allow-list.d.ts +11 -0
- package/dist/daytona-allow-list.mjs +5 -1
- package/dist/driver-catalog.d.ts +5 -52
- package/dist/driver-catalog.mjs +263 -121
- package/dist/drivers/box.mjs +309 -39
- package/dist/drivers/cloudflare.d.ts +18 -7
- package/dist/drivers/cloudflare.mjs +423 -34
- package/dist/drivers/daytona.d.ts +82 -13
- package/dist/drivers/daytona.mjs +495 -45
- package/dist/drivers/docker.mjs +284 -38
- package/dist/drivers/exe.d.ts +26 -0
- package/dist/drivers/exe.mjs +492 -0
- package/dist/drivers/fetch-bridge.mjs +29 -5
- package/dist/drivers/modal.d.ts +2 -5
- package/dist/drivers/modal.mjs +296 -46
- package/dist/drivers/transient-error.d.ts +11 -0
- package/dist/drivers/vercel.d.ts +27 -11
- package/dist/drivers/vercel.mjs +339 -59
- package/dist/hosted-network-policy.d.ts +87 -0
- package/dist/hosted-network-policy.mjs +61 -0
- package/dist/image-name.mjs +34 -0
- package/dist/image.d.ts +18 -3
- package/dist/image.mjs +47 -32
- package/dist/index.d.ts +281 -17
- package/dist/index.mjs +393 -26
- package/dist/json.d.ts +13 -0
- package/dist/lease-policy.d.ts +6 -3
- package/dist/lease-policy.mjs +213 -54
- package/dist/lease-types.d.ts +17 -3
- package/dist/runtime-env.d.ts +12 -1
- package/dist/runtime-env.mjs +14 -0
- package/dist/runtime-version.mjs +1 -9
- package/dist/service-url-exposure.d.ts +1 -2
- package/dist/service-url-exposure.mjs +1 -17
- package/dist/stores/memory.mjs +39 -4
- package/package.json +67 -51
- package/dist/drivers/cloudflare-egress.d.ts +0 -40
- package/dist/drivers/cloudflare-egress.mjs +0 -113
package/dist/lease-policy.mjs
CHANGED
|
@@ -1,56 +1,230 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
// src/hosted-network-policy.ts
|
|
2
|
+
var SANDBOX_MODEL_PROVIDER_HOSTS = [
|
|
3
|
+
"api.anthropic.com",
|
|
4
|
+
"api.openai.com",
|
|
5
|
+
"generativelanguage.googleapis.com",
|
|
6
|
+
"openrouter.ai",
|
|
7
|
+
// Model catalog + engine config, fetched on runner startup.
|
|
8
|
+
"models.dev",
|
|
9
|
+
"opencode.ai"
|
|
10
|
+
];
|
|
11
|
+
var SANDBOX_PACKAGE_REGISTRY_HOSTS = [
|
|
12
|
+
"registry.npmjs.org",
|
|
13
|
+
"nodejs.org",
|
|
14
|
+
"pypi.org",
|
|
15
|
+
"files.pythonhosted.org",
|
|
16
|
+
"crates.io",
|
|
17
|
+
"static.crates.io",
|
|
18
|
+
"index.crates.io",
|
|
19
|
+
"proxy.golang.org",
|
|
20
|
+
"sum.golang.org"
|
|
21
|
+
];
|
|
22
|
+
var SANDBOX_BASELINE_EGRESS_HOSTS = [
|
|
23
|
+
...SANDBOX_MODEL_PROVIDER_HOSTS,
|
|
24
|
+
...SANDBOX_PACKAGE_REGISTRY_HOSTS
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// ../sandbox-contract/dist/index.mjs
|
|
28
|
+
var sandboxDriverCredentialFields = {
|
|
29
|
+
exe: [{ key: "api_token", label: "API Token", secret: true }],
|
|
30
|
+
daytona: [{ key: "api_key", label: "API Key", secret: true }],
|
|
31
|
+
modal: [
|
|
32
|
+
{ key: "token_id", label: "Token ID", secret: true },
|
|
33
|
+
{ key: "token_secret", label: "Token Secret", secret: true }
|
|
34
|
+
],
|
|
35
|
+
vercel: [
|
|
36
|
+
{ key: "access_token", label: "Access Token", secret: true },
|
|
37
|
+
{ key: "team_id", label: "Team ID" },
|
|
38
|
+
{ key: "project_id", label: "Project ID" }
|
|
39
|
+
],
|
|
40
|
+
cloudflare: [
|
|
41
|
+
{ key: "api_token", label: "API Token", secret: true },
|
|
42
|
+
{ key: "worker_url", label: "Worker URL" }
|
|
43
|
+
],
|
|
44
|
+
box: [{ key: "api_key", label: "API Key", secret: true }],
|
|
45
|
+
docker: [{ key: "image", label: "Image" }]
|
|
46
|
+
};
|
|
47
|
+
var sandboxDriverLabels = {
|
|
48
|
+
exe: "exe.dev",
|
|
49
|
+
daytona: "Daytona",
|
|
50
|
+
modal: "Modal",
|
|
51
|
+
vercel: "Vercel",
|
|
52
|
+
cloudflare: "Cloudflare",
|
|
53
|
+
box: "Box",
|
|
54
|
+
docker: "Docker"
|
|
7
55
|
};
|
|
8
|
-
|
|
56
|
+
|
|
57
|
+
// src/driver-catalog.ts
|
|
58
|
+
var sandboxDriverCatalog = {
|
|
59
|
+
exe: {
|
|
60
|
+
id: "exe",
|
|
61
|
+
label: sandboxDriverLabels.exe,
|
|
62
|
+
credentialFields: sandboxDriverCredentialFields.exe,
|
|
63
|
+
metadata: {
|
|
64
|
+
driverRunsIn: ["worker", "node"],
|
|
65
|
+
hostStopBehavior: "not-supported",
|
|
66
|
+
hostResumeBehavior: "same-host",
|
|
67
|
+
targetAccess: "relay",
|
|
68
|
+
secretBrokering: "none",
|
|
69
|
+
egressControl: "none",
|
|
70
|
+
persistence: {
|
|
71
|
+
resume: "same-sandbox",
|
|
72
|
+
capture: "none",
|
|
73
|
+
clone: true,
|
|
74
|
+
captureSource: "not-applicable",
|
|
75
|
+
retention: "provider-managed",
|
|
76
|
+
restoreMount: "same-resource"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
9
80
|
daytona: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
81
|
+
id: "daytona",
|
|
82
|
+
label: sandboxDriverLabels.daytona,
|
|
83
|
+
credentialFields: sandboxDriverCredentialFields.daytona,
|
|
84
|
+
metadata: {
|
|
85
|
+
driverRunsIn: ["worker", "node"],
|
|
86
|
+
hostStopBehavior: "suspends-host",
|
|
87
|
+
hostResumeBehavior: "same-host",
|
|
88
|
+
targetAccess: "relay",
|
|
89
|
+
secretBrokering: "native",
|
|
90
|
+
// The driver translates names to domainAllowList, or addresses to networkAllowList.
|
|
91
|
+
egressControl: "hosts-and-cidrs",
|
|
92
|
+
persistence: {
|
|
93
|
+
resume: "same-sandbox",
|
|
94
|
+
capture: "filesystem",
|
|
95
|
+
clone: false,
|
|
96
|
+
captureSource: "preserved",
|
|
97
|
+
retention: "provider-managed",
|
|
98
|
+
restoreMount: "new-resource"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
15
101
|
},
|
|
16
102
|
modal: {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
103
|
+
id: "modal",
|
|
104
|
+
label: sandboxDriverLabels.modal,
|
|
105
|
+
credentialFields: sandboxDriverCredentialFields.modal,
|
|
106
|
+
metadata: {
|
|
107
|
+
driverRunsIn: ["node"],
|
|
108
|
+
hostStopBehavior: "terminates-host",
|
|
109
|
+
hostResumeBehavior: "replacement-host",
|
|
110
|
+
targetAccess: "relay",
|
|
111
|
+
secretBrokering: "none",
|
|
112
|
+
// The driver does not install Modal's domain allowlist or alpha sidecar.
|
|
113
|
+
egressControl: "none",
|
|
114
|
+
persistence: {
|
|
115
|
+
resume: "replacement-restore",
|
|
116
|
+
capture: "filesystem",
|
|
117
|
+
clone: false,
|
|
118
|
+
captureSource: "preserved",
|
|
119
|
+
retention: "provider-managed",
|
|
120
|
+
restoreMount: "new-resource"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
22
123
|
},
|
|
23
124
|
vercel: {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
125
|
+
id: "vercel",
|
|
126
|
+
label: sandboxDriverLabels.vercel,
|
|
127
|
+
credentialFields: sandboxDriverCredentialFields.vercel,
|
|
128
|
+
metadata: {
|
|
129
|
+
driverRunsIn: ["node"],
|
|
130
|
+
hostStopBehavior: "terminates-host",
|
|
131
|
+
hostResumeBehavior: "replacement-host",
|
|
132
|
+
targetAccess: "relay",
|
|
133
|
+
secretBrokering: "native",
|
|
134
|
+
// The driver translates hosts only; the SDK's subnet rules are not wired to net.cidrs.
|
|
135
|
+
egressControl: "hosts",
|
|
136
|
+
persistence: {
|
|
137
|
+
resume: "replacement-restore",
|
|
138
|
+
capture: "filesystem",
|
|
139
|
+
clone: false,
|
|
140
|
+
captureSource: "stopped",
|
|
141
|
+
retention: "explicit",
|
|
142
|
+
restoreMount: "new-resource"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
29
145
|
},
|
|
30
146
|
cloudflare: {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
147
|
+
id: "cloudflare",
|
|
148
|
+
label: sandboxDriverLabels.cloudflare,
|
|
149
|
+
credentialFields: sandboxDriverCredentialFields.cloudflare,
|
|
150
|
+
metadata: {
|
|
151
|
+
driverRunsIn: ["worker"],
|
|
152
|
+
hostStopBehavior: "not-supported",
|
|
153
|
+
hostResumeBehavior: "same-host",
|
|
154
|
+
targetAccess: "relay",
|
|
155
|
+
secretBrokering: "native",
|
|
156
|
+
// Credential handlers do not restrict unrelated destinations.
|
|
157
|
+
egressControl: "none",
|
|
158
|
+
persistence: {
|
|
159
|
+
resume: "replacement-restore",
|
|
160
|
+
capture: "directories",
|
|
161
|
+
clone: false,
|
|
162
|
+
captureSource: "preserved",
|
|
163
|
+
retention: "provider-managed",
|
|
164
|
+
restoreMount: "copy-on-write"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
36
167
|
},
|
|
37
168
|
box: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
169
|
+
id: "box",
|
|
170
|
+
label: sandboxDriverLabels.box,
|
|
171
|
+
credentialFields: sandboxDriverCredentialFields.box,
|
|
172
|
+
metadata: {
|
|
173
|
+
driverRunsIn: ["node"],
|
|
174
|
+
hostStopBehavior: "suspends-host",
|
|
175
|
+
hostResumeBehavior: "same-host",
|
|
176
|
+
targetAccess: "relay",
|
|
177
|
+
secretBrokering: "none",
|
|
178
|
+
egressControl: "none",
|
|
179
|
+
persistence: {
|
|
180
|
+
resume: "same-sandbox",
|
|
181
|
+
capture: "none",
|
|
182
|
+
clone: false,
|
|
183
|
+
captureSource: "not-applicable",
|
|
184
|
+
retention: "provider-managed",
|
|
185
|
+
restoreMount: "same-resource"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
43
188
|
},
|
|
44
189
|
docker: {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
190
|
+
id: "docker",
|
|
191
|
+
label: sandboxDriverLabels.docker,
|
|
192
|
+
credentialFields: sandboxDriverCredentialFields.docker,
|
|
193
|
+
metadata: {
|
|
194
|
+
driverRunsIn: ["local"],
|
|
195
|
+
hostStopBehavior: "terminates-host",
|
|
196
|
+
hostResumeBehavior: "same-host",
|
|
197
|
+
targetAccess: "loopback",
|
|
198
|
+
secretBrokering: "none",
|
|
199
|
+
egressControl: "none",
|
|
200
|
+
persistence: {
|
|
201
|
+
resume: "replacement-restore",
|
|
202
|
+
capture: "same-resource",
|
|
203
|
+
clone: false,
|
|
204
|
+
captureSource: "preserved",
|
|
205
|
+
retention: "provider-managed",
|
|
206
|
+
restoreMount: "same-resource"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
50
209
|
}
|
|
51
210
|
};
|
|
211
|
+
|
|
212
|
+
// src/lease-policy.ts
|
|
213
|
+
var DEFAULT_WORKSPACE_HOST_DECISION_CONFIG = {
|
|
214
|
+
maxRetries: 8,
|
|
215
|
+
idleMs: 10 * 60 * 1e3,
|
|
216
|
+
backoffMaxMs: 3e4,
|
|
217
|
+
healthTimeoutMs: 6e4
|
|
218
|
+
};
|
|
52
219
|
function sandboxDriverPlacement(driver) {
|
|
53
|
-
|
|
220
|
+
const metadata = sandboxDriverCatalog[driver].metadata;
|
|
221
|
+
return {
|
|
222
|
+
canPauseAndRestartSameResource: metadata.persistence.resume === "same-sandbox",
|
|
223
|
+
canCreateFilesystemSnapshot: metadata.persistence.capture === "filesystem" || metadata.persistence.capture === "directories",
|
|
224
|
+
canStartFromPreparedImage: driver === "exe" || driver === "daytona" || driver === "modal" || driver === "box" || driver === "docker",
|
|
225
|
+
canStopExplicitly: metadata.hostStopBehavior !== "not-supported",
|
|
226
|
+
hasHealthProbe: true
|
|
227
|
+
};
|
|
54
228
|
}
|
|
55
229
|
function decideSandboxStart(lease, placement, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
56
230
|
if (lease.status === "ready") {
|
|
@@ -72,7 +246,7 @@ function decideSandboxStart(lease, placement, now, config = DEFAULT_WORKSPACE_HO
|
|
|
72
246
|
}
|
|
73
247
|
return decideStartMethod(lease, placement);
|
|
74
248
|
}
|
|
75
|
-
function decideSandboxHealthFailure(lease,
|
|
249
|
+
function decideSandboxHealthFailure(lease, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
76
250
|
if (lease.status !== "ready" && lease.status !== "unhealthy") {
|
|
77
251
|
return { action: "skip", reason: `status is ${lease.status}, health check not applicable` };
|
|
78
252
|
}
|
|
@@ -83,20 +257,6 @@ function decideSandboxHealthFailure(lease, _placement, now, config = DEFAULT_WOR
|
|
|
83
257
|
const backoff = Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount - 1));
|
|
84
258
|
return { action: "wait", until: now + backoff, reason: `health failure #${retryCount}, backoff ${backoff}ms` };
|
|
85
259
|
}
|
|
86
|
-
function decideSandboxIdle(lease, activeHoldCount, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
87
|
-
if (lease.status !== "ready") {
|
|
88
|
-
return { action: "skip", reason: `status is ${lease.status}, not ready` };
|
|
89
|
-
}
|
|
90
|
-
if (activeHoldCount > 0) {
|
|
91
|
-
return { action: "skip", reason: `${activeHoldCount} active hold(s)` };
|
|
92
|
-
}
|
|
93
|
-
const lastActivity = lease.last_activity_at ?? lease.created_at;
|
|
94
|
-
const idleFor = now - lastActivity;
|
|
95
|
-
if (idleFor < config.idleMs) {
|
|
96
|
-
return { action: "wait", until: lastActivity + config.idleMs, reason: `idle for ${idleFor}ms, need ${config.idleMs}ms` };
|
|
97
|
-
}
|
|
98
|
-
return { action: "stop_idle", reason: `idle for ${idleFor}ms (threshold: ${config.idleMs}ms)` };
|
|
99
|
-
}
|
|
100
260
|
function nextSandboxRetryAt(retryCount, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
101
261
|
if (retryCount >= config.maxRetries) return null;
|
|
102
262
|
return now + Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount));
|
|
@@ -124,7 +284,6 @@ function decideStartMethod(lease, placement) {
|
|
|
124
284
|
export {
|
|
125
285
|
DEFAULT_WORKSPACE_HOST_DECISION_CONFIG,
|
|
126
286
|
decideSandboxHealthFailure,
|
|
127
|
-
decideSandboxIdle,
|
|
128
287
|
decideSandboxStart,
|
|
129
288
|
nextSandboxRetryAt,
|
|
130
289
|
sandboxDriverPlacement
|
package/dist/lease-types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type SandboxLeaseRowStatus = "pending" | "acquiring" | "starting" | "ready" | "unhealthy" | "backoff" | "stopping" | "stopped" | "failed";
|
|
1
|
+
import type { SandboxCheckpointReference, SandboxPersistenceCapabilities, SandboxRestoreStatus } from "./index";
|
|
2
|
+
export type SandboxLeaseRowStatus = "pending" | "acquiring" | "starting" | "ready" | "unhealthy" | "backoff" | "stopping" | "stopped" | "destroyed" | "failed";
|
|
3
3
|
export type SandboxComputeClass = "small" | "medium" | "large" | "gpu";
|
|
4
4
|
export type SandboxLeaseRow = {
|
|
5
5
|
workspace_id: string;
|
|
@@ -7,7 +7,17 @@ export type SandboxLeaseRow = {
|
|
|
7
7
|
home_region?: string;
|
|
8
8
|
epoch: number;
|
|
9
9
|
status: SandboxLeaseRowStatus;
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The id the driver was registered with, which is any string: the manager
|
|
12
|
+
* dispatches on whatever a composition registers (`stores/d1.test.ts`
|
|
13
|
+
* provisions one called `"test-provider"`), and every other type this value
|
|
14
|
+
* flows between — `SandboxLease["driver"]`, `SandboxLeaseAcquireInput["driver"]`,
|
|
15
|
+
* `SandboxTarget["driver"]["id"]` — is already `string`. Typing the row as the
|
|
16
|
+
* closed `SandboxDriverID` made it the odd one out and forced every store to
|
|
17
|
+
* assert into it. Narrow with `isSandboxDriverID` where a CATALOG entry is
|
|
18
|
+
* needed, which is the only place the closed set is the right question.
|
|
19
|
+
*/
|
|
20
|
+
driver: string;
|
|
11
21
|
driver_resource_id: string | null;
|
|
12
22
|
driver_snapshot_id: string | null;
|
|
13
23
|
sandbox_id: string | null;
|
|
@@ -22,6 +32,10 @@ export type SandboxLeaseRow = {
|
|
|
22
32
|
accel_base_image_id: string | null;
|
|
23
33
|
accel_prepared_image_id: string | null;
|
|
24
34
|
accel_snapshot_id: string | null;
|
|
35
|
+
labels?: Record<string, string> | null;
|
|
36
|
+
checkpoint: SandboxCheckpointReference | null;
|
|
37
|
+
persistence: SandboxPersistenceCapabilities | null;
|
|
38
|
+
restore: SandboxRestoreStatus | null;
|
|
25
39
|
created_at: number;
|
|
26
40
|
updated_at: number;
|
|
27
41
|
};
|
package/dist/runtime-env.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import type { SandboxDriverID } from "
|
|
1
|
+
import type { SandboxDriverID } from "@claxedo/sandbox-contract";
|
|
2
|
+
export type WorkspaceRuntimeControlEnv = {
|
|
3
|
+
relayJwksUrl?: string;
|
|
4
|
+
relayVerifyPem?: string;
|
|
5
|
+
managementJwksUrl?: string;
|
|
6
|
+
sessionAuthorityUrl?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function workspaceRuntimeBootEnv(input: Parameters<typeof workspaceRuntimeTargetEnv>[0] & Parameters<typeof workspaceRuntimeSourceEnv>[0] & {
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
runner?: string;
|
|
11
|
+
controlEnv?: WorkspaceRuntimeControlEnv;
|
|
12
|
+
}): Record<string, string>;
|
|
2
13
|
export declare function workspaceRuntimeTargetEnv(input: {
|
|
3
14
|
workspaceId: string;
|
|
4
15
|
hostId?: string;
|
package/dist/runtime-env.mjs
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
// src/runtime-env.ts
|
|
2
|
+
function workspaceRuntimeBootEnv(input) {
|
|
3
|
+
const env = {
|
|
4
|
+
...workspaceRuntimeTargetEnv(input),
|
|
5
|
+
...workspaceRuntimeSourceEnv(input),
|
|
6
|
+
...input.env
|
|
7
|
+
};
|
|
8
|
+
if (input.runner) env.WORKSPACE_RUNTIME_RUNNER = input.runner;
|
|
9
|
+
if (input.controlEnv?.relayJwksUrl) env.WORKSPACE_RUNTIME_RELAY_JWKS_URL = input.controlEnv.relayJwksUrl;
|
|
10
|
+
if (input.controlEnv?.relayVerifyPem) env.WORKSPACE_RUNTIME_RELAY_HOST_VERIFY_PEM = input.controlEnv.relayVerifyPem;
|
|
11
|
+
if (input.controlEnv?.managementJwksUrl) env.WORKSPACE_RUNTIME_MANAGEMENT_JWKS_URL = input.controlEnv.managementJwksUrl;
|
|
12
|
+
if (input.controlEnv?.sessionAuthorityUrl) env.WORKSPACE_RUNTIME_SESSION_AUTHORITY_URL = input.controlEnv.sessionAuthorityUrl;
|
|
13
|
+
return env;
|
|
14
|
+
}
|
|
2
15
|
function workspaceRuntimeTargetEnv(input) {
|
|
3
16
|
return {
|
|
4
17
|
WORKSPACE_RUNTIME_WORKSPACE_ID: input.workspaceId,
|
|
@@ -27,6 +40,7 @@ function workspaceRuntimeServiceExposureEnv(input) {
|
|
|
27
40
|
};
|
|
28
41
|
}
|
|
29
42
|
export {
|
|
43
|
+
workspaceRuntimeBootEnv,
|
|
30
44
|
workspaceRuntimeServiceExposureEnv,
|
|
31
45
|
workspaceRuntimeSourceEnv,
|
|
32
46
|
workspaceRuntimeTargetEnv
|
package/dist/runtime-version.mjs
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
// src/runtime-version.ts
|
|
2
2
|
var DEFAULT_WORKSPACE_RUNTIME_VERSION = "0.5.2";
|
|
3
|
-
var versionCache;
|
|
4
3
|
function workspaceRuntimeVersion() {
|
|
5
|
-
|
|
6
|
-
const envVersion = process.env.WORKSPACE_RUNTIME_VERSION;
|
|
7
|
-
if (envVersion) {
|
|
8
|
-
versionCache = envVersion;
|
|
9
|
-
return versionCache;
|
|
10
|
-
}
|
|
11
|
-
versionCache = DEFAULT_WORKSPACE_RUNTIME_VERSION;
|
|
12
|
-
return versionCache;
|
|
4
|
+
return process.env.WORKSPACE_RUNTIME_VERSION || DEFAULT_WORKSPACE_RUNTIME_VERSION;
|
|
13
5
|
}
|
|
14
6
|
export {
|
|
15
7
|
workspaceRuntimeVersion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SandboxDriverID } from "
|
|
1
|
+
import type { SandboxDriverID } from "@claxedo/sandbox-contract";
|
|
2
2
|
export type SandboxServiceUrlExposure = {
|
|
3
3
|
source: "driver-service-url";
|
|
4
4
|
access: "private" | "public" | "driver-authenticated" | "unknown";
|
|
@@ -7,4 +7,3 @@ export type SandboxServiceUrlExposure = {
|
|
|
7
7
|
note?: string;
|
|
8
8
|
};
|
|
9
9
|
export declare function sandboxServiceUrlExposure(driver: SandboxDriverID): SandboxServiceUrlExposure;
|
|
10
|
-
export declare function sandboxServiceUrlExposureEnv(driver: SandboxDriverID): Record<string, string>;
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
// src/runtime-env.ts
|
|
2
|
-
function workspaceRuntimeServiceExposureEnv(input) {
|
|
3
|
-
return {
|
|
4
|
-
...input.driver === "docker" ? { WORKSPACE_RUNTIME_HOST: "0.0.0.0" } : {},
|
|
5
|
-
WORKSPACE_RUNTIME_SERVICE_EXPOSURE_SOURCE: input.source,
|
|
6
|
-
WORKSPACE_RUNTIME_SERVICE_EXPOSURE_ACCESS: input.access,
|
|
7
|
-
WORKSPACE_RUNTIME_SERVICE_EXPOSURE_DRIVER: input.driver,
|
|
8
|
-
...input.fallbackAccess ? { WORKSPACE_RUNTIME_SERVICE_EXPOSURE_FALLBACK_ACCESS: input.fallbackAccess } : {},
|
|
9
|
-
...input.note ? { WORKSPACE_RUNTIME_SERVICE_EXPOSURE_NOTE: input.note } : {}
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
1
|
// src/service-url-exposure.ts
|
|
14
2
|
function sandboxServiceUrlExposure(driver) {
|
|
15
3
|
if (driver === "docker") {
|
|
@@ -35,10 +23,6 @@ function sandboxServiceUrlExposure(driver) {
|
|
|
35
23
|
driver
|
|
36
24
|
};
|
|
37
25
|
}
|
|
38
|
-
function sandboxServiceUrlExposureEnv(driver) {
|
|
39
|
-
return workspaceRuntimeServiceExposureEnv(sandboxServiceUrlExposure(driver));
|
|
40
|
-
}
|
|
41
26
|
export {
|
|
42
|
-
sandboxServiceUrlExposure
|
|
43
|
-
sandboxServiceUrlExposureEnv
|
|
27
|
+
sandboxServiceUrlExposure
|
|
44
28
|
};
|
package/dist/stores/memory.mjs
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
// src/hosted-network-policy.ts
|
|
2
|
+
var SANDBOX_MODEL_PROVIDER_HOSTS = [
|
|
3
|
+
"api.anthropic.com",
|
|
4
|
+
"api.openai.com",
|
|
5
|
+
"generativelanguage.googleapis.com",
|
|
6
|
+
"openrouter.ai",
|
|
7
|
+
// Model catalog + engine config, fetched on runner startup.
|
|
8
|
+
"models.dev",
|
|
9
|
+
"opencode.ai"
|
|
10
|
+
];
|
|
11
|
+
var SANDBOX_PACKAGE_REGISTRY_HOSTS = [
|
|
12
|
+
"registry.npmjs.org",
|
|
13
|
+
"nodejs.org",
|
|
14
|
+
"pypi.org",
|
|
15
|
+
"files.pythonhosted.org",
|
|
16
|
+
"crates.io",
|
|
17
|
+
"static.crates.io",
|
|
18
|
+
"index.crates.io",
|
|
19
|
+
"proxy.golang.org",
|
|
20
|
+
"sum.golang.org"
|
|
21
|
+
];
|
|
22
|
+
var SANDBOX_BASELINE_EGRESS_HOSTS = [
|
|
23
|
+
...SANDBOX_MODEL_PROVIDER_HOSTS,
|
|
24
|
+
...SANDBOX_PACKAGE_REGISTRY_HOSTS
|
|
25
|
+
];
|
|
26
|
+
|
|
1
27
|
// src/index.ts
|
|
2
28
|
function applySandboxLeasePatch(current, patch, updatedAt) {
|
|
3
29
|
return {
|
|
@@ -13,6 +39,9 @@ function applySandboxLeasePatch(current, patch, updatedAt) {
|
|
|
13
39
|
...patch.labels === void 0 ? {} : { labels: patch.labels },
|
|
14
40
|
...patch.nextRetryAt === void 0 ? {} : { nextRetryAt: patch.nextRetryAt ?? void 0 },
|
|
15
41
|
...patch.lastError === void 0 ? {} : { lastError: patch.lastError ?? void 0 },
|
|
42
|
+
...patch.checkpoint === void 0 ? {} : { checkpoint: patch.checkpoint ?? void 0 },
|
|
43
|
+
...patch.persistence === void 0 ? {} : { persistence: patch.persistence ?? void 0 },
|
|
44
|
+
...patch.restore === void 0 ? {} : { restore: patch.restore ?? void 0 },
|
|
16
45
|
updatedAt
|
|
17
46
|
};
|
|
18
47
|
}
|
|
@@ -50,21 +79,24 @@ function createMemoryLeaseStore(seed = []) {
|
|
|
50
79
|
driverResourceId: resumable ? current.driverResourceId : void 0,
|
|
51
80
|
lastHeartbeatAt: resumable ? current.lastHeartbeatAt : void 0,
|
|
52
81
|
lastActivityAt: resumable ? current.lastActivityAt : void 0,
|
|
53
|
-
labels: resumable ? current.labels : void 0
|
|
82
|
+
labels: resumable ? current.labels : void 0,
|
|
83
|
+
checkpoint: current?.checkpoint,
|
|
84
|
+
persistence: current?.persistence,
|
|
85
|
+
restore: current?.restore
|
|
54
86
|
};
|
|
55
87
|
leases.set(workspaceId, next);
|
|
56
88
|
return { acquired: true, lease: next };
|
|
57
89
|
},
|
|
58
90
|
async update(workspaceId, expectedEpoch, patch) {
|
|
59
91
|
const current = leases.get(workspaceId);
|
|
60
|
-
if (!current || current.epoch !== expectedEpoch) return;
|
|
92
|
+
if (!current || current.epoch !== expectedEpoch) return void 0;
|
|
61
93
|
const next = applySandboxLeasePatch(current, patch, Date.now());
|
|
62
94
|
leases.set(workspaceId, next);
|
|
63
95
|
return next;
|
|
64
96
|
},
|
|
65
97
|
async recordFailure(workspaceId, expectedEpoch, error, nextRetryAt) {
|
|
66
98
|
const current = leases.get(workspaceId);
|
|
67
|
-
if (!current || current.epoch !== expectedEpoch) return;
|
|
99
|
+
if (!current || current.epoch !== expectedEpoch) return void 0;
|
|
68
100
|
const next = {
|
|
69
101
|
...current,
|
|
70
102
|
status: "unavailable",
|
|
@@ -106,7 +138,10 @@ function sandboxLease(input) {
|
|
|
106
138
|
lastError: input.lastError,
|
|
107
139
|
lastHeartbeatAt: input.lastHeartbeatAt,
|
|
108
140
|
lastActivityAt: input.lastActivityAt,
|
|
109
|
-
labels: input.labels
|
|
141
|
+
labels: input.labels,
|
|
142
|
+
checkpoint: input.checkpoint,
|
|
143
|
+
persistence: input.persistence,
|
|
144
|
+
restore: input.restore
|
|
110
145
|
};
|
|
111
146
|
}
|
|
112
147
|
export {
|