@agent-relay/sandbox 0.1.2 → 0.1.3
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 +226 -5
- package/dist/agent37/client.d.ts +115 -0
- package/dist/agent37/client.d.ts.map +1 -0
- package/dist/agent37/client.js +270 -0
- package/dist/agent37/client.js.map +1 -0
- package/dist/agent37/runtime.d.ts +415 -0
- package/dist/agent37/runtime.d.ts.map +1 -0
- package/dist/agent37/runtime.js +855 -0
- package/dist/agent37/runtime.js.map +1 -0
- package/dist/agentcore/bench.d.ts +93 -0
- package/dist/agentcore/bench.d.ts.map +1 -0
- package/dist/agentcore/bench.js +125 -0
- package/dist/agentcore/bench.js.map +1 -0
- package/dist/agentcore/capabilities.d.ts +169 -0
- package/dist/agentcore/capabilities.d.ts.map +1 -0
- package/dist/agentcore/capabilities.js +153 -0
- package/dist/agentcore/capabilities.js.map +1 -0
- package/dist/agentcore/config.d.ts +156 -0
- package/dist/agentcore/config.d.ts.map +1 -0
- package/dist/agentcore/config.js +12 -0
- package/dist/agentcore/config.js.map +1 -0
- package/dist/agentcore/internal/sdk.d.ts +181 -0
- package/dist/agentcore/internal/sdk.d.ts.map +1 -0
- package/dist/agentcore/internal/sdk.js +223 -0
- package/dist/agentcore/internal/sdk.js.map +1 -0
- package/dist/agentcore/runtime.d.ts +177 -0
- package/dist/agentcore/runtime.d.ts.map +1 -0
- package/dist/agentcore/runtime.js +706 -0
- package/dist/agentcore/runtime.js.map +1 -0
- package/dist/daytona/runtime.d.ts +23 -0
- package/dist/daytona/runtime.d.ts.map +1 -1
- package/dist/daytona/runtime.js +167 -5
- package/dist/daytona/runtime.js.map +1 -1
- package/dist/daytona/wire-supplement.d.ts +25 -0
- package/dist/daytona/wire-supplement.d.ts.map +1 -0
- package/dist/daytona/wire-supplement.js +16 -0
- package/dist/daytona/wire-supplement.js.map +1 -0
- package/dist/e2b/runtime.d.ts +107 -72
- package/dist/e2b/runtime.d.ts.map +1 -1
- package/dist/e2b/runtime.js +675 -190
- package/dist/e2b/runtime.js.map +1 -1
- package/dist/freestyle/capabilities.d.ts +28 -0
- package/dist/freestyle/capabilities.d.ts.map +1 -0
- package/dist/freestyle/capabilities.js +42 -0
- package/dist/freestyle/capabilities.js.map +1 -0
- package/dist/freestyle/config.d.ts +36 -0
- package/dist/freestyle/config.d.ts.map +1 -0
- package/dist/freestyle/config.js +2 -0
- package/dist/freestyle/config.js.map +1 -0
- package/dist/freestyle/internal/sdk.d.ts +69 -0
- package/dist/freestyle/internal/sdk.d.ts.map +1 -0
- package/dist/freestyle/internal/sdk.js +19 -0
- package/dist/freestyle/internal/sdk.js.map +1 -0
- package/dist/freestyle/runtime.d.ts +163 -0
- package/dist/freestyle/runtime.d.ts.map +1 -0
- package/dist/freestyle/runtime.js +798 -0
- package/dist/freestyle/runtime.js.map +1 -0
- package/dist/index.d.ts +35 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/microsandbox/runtime.d.ts +793 -0
- package/dist/microsandbox/runtime.d.ts.map +1 -0
- package/dist/microsandbox/runtime.js +2303 -0
- package/dist/microsandbox/runtime.js.map +1 -0
- package/dist/modal/bench.d.ts +199 -0
- package/dist/modal/bench.d.ts.map +1 -0
- package/dist/modal/bench.js +450 -0
- package/dist/modal/bench.js.map +1 -0
- package/dist/modal/capabilities.d.ts +180 -0
- package/dist/modal/capabilities.d.ts.map +1 -0
- package/dist/modal/capabilities.js +159 -0
- package/dist/modal/capabilities.js.map +1 -0
- package/dist/modal/config.d.ts +192 -0
- package/dist/modal/config.d.ts.map +1 -0
- package/dist/modal/config.js +169 -0
- package/dist/modal/config.js.map +1 -0
- package/dist/modal/internal/sdk.d.ts +141 -0
- package/dist/modal/internal/sdk.d.ts.map +1 -0
- package/dist/modal/internal/sdk.js +51 -0
- package/dist/modal/internal/sdk.js.map +1 -0
- package/dist/modal/runtime.d.ts +271 -0
- package/dist/modal/runtime.d.ts.map +1 -0
- package/dist/modal/runtime.js +871 -0
- package/dist/modal/runtime.js.map +1 -0
- package/dist/mount-script.d.ts +16 -1
- package/dist/mount-script.d.ts.map +1 -1
- package/dist/mount-script.js +76 -15
- package/dist/mount-script.js.map +1 -1
- package/dist/orchestrator.d.ts +15 -0
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +13 -1
- package/dist/orchestrator.js.map +1 -1
- package/dist/port.d.ts +144 -6
- package/dist/port.d.ts.map +1 -1
- package/dist/port.js +27 -5
- package/dist/port.js.map +1 -1
- package/dist/types.d.ts +50 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/vercel/bench.d.ts +169 -0
- package/dist/vercel/bench.d.ts.map +1 -0
- package/dist/vercel/bench.js +337 -0
- package/dist/vercel/bench.js.map +1 -0
- package/dist/vercel/capabilities.d.ts +106 -0
- package/dist/vercel/capabilities.d.ts.map +1 -0
- package/dist/vercel/capabilities.js +128 -0
- package/dist/vercel/capabilities.js.map +1 -0
- package/dist/vercel/config.d.ts +119 -0
- package/dist/vercel/config.d.ts.map +1 -0
- package/dist/vercel/config.js +8 -0
- package/dist/vercel/config.js.map +1 -0
- package/dist/vercel/internal/sdk.d.ts +173 -0
- package/dist/vercel/internal/sdk.d.ts.map +1 -0
- package/dist/vercel/internal/sdk.js +117 -0
- package/dist/vercel/internal/sdk.js.map +1 -0
- package/dist/vercel/runtime.d.ts +305 -0
- package/dist/vercel/runtime.d.ts.map +1 -0
- package/dist/vercel/runtime.js +1169 -0
- package/dist/vercel/runtime.js.map +1 -0
- package/docs/freestyle.md +110 -0
- package/package.json +35 -4
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live benchmark core for the Vercel adapter.
|
|
3
|
+
*
|
|
4
|
+
* Split out from the CLI in `scripts/vercel-bench.ts` so the safety guards are
|
|
5
|
+
* testable against a fake runtime *before* they are pointed at a real account.
|
|
6
|
+
* A harness whose ledger-before-use and verified-cleanup guards have never been
|
|
7
|
+
* exercised is exactly the unverified claim this package refuses to make about
|
|
8
|
+
* anything else.
|
|
9
|
+
*
|
|
10
|
+
* Not exported from the package barrel: this is an internal measurement tool,
|
|
11
|
+
* not public API.
|
|
12
|
+
*/
|
|
13
|
+
export class BenchBoundsError extends Error {
|
|
14
|
+
constructor(requested, max) {
|
|
15
|
+
super(`benchmark would create ${requested} sandboxes, exceeding the cap of ${max}`);
|
|
16
|
+
this.name = "BenchBoundsError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Cost for one sandbox-hour at a given shape and CPU utilisation.
|
|
21
|
+
*
|
|
22
|
+
* The two lines are always reported separately and never blended. Active CPU
|
|
23
|
+
* excludes I/O wait; provisioned memory does not — it is wall-clock. Collapsing
|
|
24
|
+
* them into one number is precisely how the "cheapest provider" claim gets
|
|
25
|
+
* overstated for idle-heavy agent workloads.
|
|
26
|
+
*/
|
|
27
|
+
export function projectCost(vcpus, utilisation) {
|
|
28
|
+
const memoryGb = vcpus * 2; // the provider allocates 2 GB per vCPU
|
|
29
|
+
const cpuPerHour = vcpus * utilisation * 0.128;
|
|
30
|
+
const memoryPerHour = memoryGb * 0.0212;
|
|
31
|
+
return {
|
|
32
|
+
utilisation,
|
|
33
|
+
cpuPerHour: round4(cpuPerHour),
|
|
34
|
+
memoryPerHour: round4(memoryPerHour),
|
|
35
|
+
totalPerHour: round4(cpuPerHour + memoryPerHour),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Nearest-rank percentile. NaN entries are dropped, not treated as zero. */
|
|
39
|
+
export function percentile(values, p) {
|
|
40
|
+
const clean = values
|
|
41
|
+
.filter((value) => Number.isFinite(value))
|
|
42
|
+
.sort((a, b) => a - b);
|
|
43
|
+
if (clean.length === 0) {
|
|
44
|
+
return NaN;
|
|
45
|
+
}
|
|
46
|
+
const rank = Math.ceil((p / 100) * clean.length) - 1;
|
|
47
|
+
return clean[Math.min(Math.max(rank, 0), clean.length - 1)];
|
|
48
|
+
}
|
|
49
|
+
function round4(value) {
|
|
50
|
+
return Number(value.toFixed(4));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Measure one sandbox end to end.
|
|
54
|
+
*
|
|
55
|
+
* The name is ledgered *before* `launch` is called. A record written after the
|
|
56
|
+
* response would be lost exactly when it matters — a crash between submit and
|
|
57
|
+
* response leaves a live sandbox nobody wrote down.
|
|
58
|
+
*
|
|
59
|
+
* Teardown runs in `finally`, so a failed measurement still destroys what it
|
|
60
|
+
* created. `destroyed` and `verifiedGone` are tracked separately because they
|
|
61
|
+
* are different facts, and conflating them is how a leak gets reported as a
|
|
62
|
+
* clean run.
|
|
63
|
+
*/
|
|
64
|
+
export async function measureOne(deps, index) {
|
|
65
|
+
const clock = deps.now ?? (() => Date.now());
|
|
66
|
+
const sample = {
|
|
67
|
+
index,
|
|
68
|
+
createMs: NaN,
|
|
69
|
+
stateAfterCreate: "unknown",
|
|
70
|
+
firstExecMs: NaN,
|
|
71
|
+
execExitCode: null,
|
|
72
|
+
execOutput: "",
|
|
73
|
+
destroyed: false,
|
|
74
|
+
verifiedGone: false,
|
|
75
|
+
};
|
|
76
|
+
const intended = `${deps.prefix}-s${index}`;
|
|
77
|
+
deps.ledger({ event: "intent", name: intended, index });
|
|
78
|
+
let handle;
|
|
79
|
+
try {
|
|
80
|
+
const t0 = clock();
|
|
81
|
+
handle = await deps.runtime.launch({
|
|
82
|
+
name: intended,
|
|
83
|
+
labels: { bench: deps.runId },
|
|
84
|
+
});
|
|
85
|
+
sample.createMs = clock() - t0;
|
|
86
|
+
sample.stateAfterCreate = handle.state ?? "unknown";
|
|
87
|
+
deps.ledger({
|
|
88
|
+
event: "created",
|
|
89
|
+
name: handle.id,
|
|
90
|
+
createMs: Math.round(sample.createMs),
|
|
91
|
+
});
|
|
92
|
+
const t1 = clock();
|
|
93
|
+
const exec = await deps.runtime.runScript(handle, {
|
|
94
|
+
command: "nproc; free -m | awk '/Mem:/{print $2}'; echo READY",
|
|
95
|
+
timeoutMs: 60_000,
|
|
96
|
+
});
|
|
97
|
+
sample.firstExecMs = clock() - t1;
|
|
98
|
+
sample.execExitCode = exec.exitCode;
|
|
99
|
+
sample.execOutput = exec.output.trim();
|
|
100
|
+
// Fail fast on a readiness probe that did not report a clean exit: a
|
|
101
|
+
// nonzero or null code would otherwise be recorded as a valid latency
|
|
102
|
+
// sample, hiding a broken sandbox behind a green-looking report.
|
|
103
|
+
if (exec.exitCode !== 0) {
|
|
104
|
+
throw new Error(`readiness probe exited with ${exec.exitCode ?? "no exit code"}: `
|
|
105
|
+
+ `${sample.execOutput || "(no output)"}`);
|
|
106
|
+
}
|
|
107
|
+
const owned = await deps.runtime.listOwned({ includeTerminated: true });
|
|
108
|
+
const row = owned.find((entry) => entry.name === handle.id);
|
|
109
|
+
sample.vcpus = row?.vcpus;
|
|
110
|
+
sample.memoryMiB = row?.memoryMiB;
|
|
111
|
+
sample.activeCpuMs = row?.activeCpuMs;
|
|
112
|
+
sample.wallClockMs = row?.wallClockMs;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
sample.error = describe(error);
|
|
116
|
+
deps.ledger({ event: "error", name: intended, error: sample.error });
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
// `finally` rather than a trailing block. Today the catch above is total,
|
|
120
|
+
// so the two are equivalent and no test can tell them apart — but the
|
|
121
|
+
// moment anyone makes that catch selective, a trailing block would silently
|
|
122
|
+
// stop tearing down on the rethrown path. The cost of being right in
|
|
123
|
+
// advance is one keyword.
|
|
124
|
+
if (handle) {
|
|
125
|
+
try {
|
|
126
|
+
await deps.runtime.destroy(handle);
|
|
127
|
+
sample.destroyed = true;
|
|
128
|
+
sample.verifiedGone = true;
|
|
129
|
+
deps.ledger({ event: "destroyed-verified", name: handle.id });
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// Only `VercelDestroyVerificationError` means the delete was accepted
|
|
133
|
+
// by the provider but absence was not proven — that is the case where
|
|
134
|
+
// `destroyed=true, verifiedGone=false` is honest. Any other error is a
|
|
135
|
+
// submission failure and must leave `destroyed=false`, or the cleanup
|
|
136
|
+
// summary would count a still-live sandbox as torn down.
|
|
137
|
+
const verificationFailed = isVerificationFailure(error);
|
|
138
|
+
sample.destroyed = verificationFailed;
|
|
139
|
+
sample.verifiedGone = false;
|
|
140
|
+
deps.ledger({
|
|
141
|
+
event: verificationFailed ? "destroy-unverified" : "destroy-submit-failed",
|
|
142
|
+
name: handle.id,
|
|
143
|
+
error: describe(error),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return sample;
|
|
149
|
+
}
|
|
150
|
+
/** Concurrency probe: launch a burst, then tear all of it down. */
|
|
151
|
+
export async function burstProbe(deps) {
|
|
152
|
+
const width = deps.limits.burstWidth;
|
|
153
|
+
deps.ledger({ event: "burst-start", name: deps.prefix, width });
|
|
154
|
+
const names = Array.from({ length: width }, (_, i) => `${deps.prefix}-b${i}`);
|
|
155
|
+
for (const name of names) {
|
|
156
|
+
deps.ledger({ event: "intent", name, burst: true });
|
|
157
|
+
}
|
|
158
|
+
const settled = await Promise.allSettled(names.map((name) => deps.runtime.launch({ name, labels: { bench: deps.runId, kind: "burst" } })));
|
|
159
|
+
const rejections = settled
|
|
160
|
+
.filter((r) => r.status === "rejected")
|
|
161
|
+
.map((r) => describe(r.reason));
|
|
162
|
+
let verifiedGone = 0;
|
|
163
|
+
for (const result of settled) {
|
|
164
|
+
if (result.status !== "fulfilled") {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
await deps.runtime.destroy(result.value);
|
|
169
|
+
verifiedGone += 1;
|
|
170
|
+
deps.ledger({
|
|
171
|
+
event: "destroyed-verified",
|
|
172
|
+
name: result.value.id,
|
|
173
|
+
burst: true,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
const verificationFailed = isVerificationFailure(error);
|
|
178
|
+
deps.ledger({
|
|
179
|
+
event: verificationFailed ? "destroy-unverified" : "destroy-submit-failed",
|
|
180
|
+
name: result.value.id,
|
|
181
|
+
burst: true,
|
|
182
|
+
error: describe(error),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
width,
|
|
188
|
+
admitted: settled.length - rejections.length,
|
|
189
|
+
rejected: rejections.length,
|
|
190
|
+
rejections: rejections.slice(0, 4),
|
|
191
|
+
verifiedGone,
|
|
192
|
+
// The provider ramps its vCPU allocation rate with sustained use and decays
|
|
193
|
+
// it after ~10 idle minutes, so this is the rate in force now, not a cap.
|
|
194
|
+
caveat: "dynamic vCPU allocation rate — measures the current rate, not a fixed cap",
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/** Independent audit: nothing under this lane's prefix may survive a run. */
|
|
198
|
+
export async function sweep(deps) {
|
|
199
|
+
const survivors = await deps.runtime.listOwned({
|
|
200
|
+
includeTerminated: true,
|
|
201
|
+
states: null,
|
|
202
|
+
});
|
|
203
|
+
for (const entry of survivors) {
|
|
204
|
+
deps.ledger({
|
|
205
|
+
event: "survivor",
|
|
206
|
+
name: entry.name,
|
|
207
|
+
status: entry.providerStatus,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return survivors.map((entry) => entry.name);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Run the benchmark.
|
|
214
|
+
*
|
|
215
|
+
* Refuses up front to exceed the sandbox cap: a bound checked after the fact is
|
|
216
|
+
* not a bound. The sweep runs in `finally`, so an aborted run still audits.
|
|
217
|
+
*/
|
|
218
|
+
export async function runBenchmark(deps, mode) {
|
|
219
|
+
deps.ledger({ event: "run-start", name: deps.prefix, mode });
|
|
220
|
+
const n = mode === "sweep" ? 0 : mode === "full" ? 7 : 1;
|
|
221
|
+
const burstCount = mode === "full" ? deps.limits.burstWidth : 0;
|
|
222
|
+
if (n + burstCount > deps.limits.maxSandboxes) {
|
|
223
|
+
throw new BenchBoundsError(n + burstCount, deps.limits.maxSandboxes);
|
|
224
|
+
}
|
|
225
|
+
const samples = [];
|
|
226
|
+
let burst = null;
|
|
227
|
+
let survivors = [];
|
|
228
|
+
let sweepError;
|
|
229
|
+
try {
|
|
230
|
+
for (let i = 0; i < n; i += 1) {
|
|
231
|
+
samples.push(await measureOne(deps, i));
|
|
232
|
+
}
|
|
233
|
+
if (mode === "full") {
|
|
234
|
+
burst = await burstProbe(deps);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
finally {
|
|
238
|
+
// `run-end` and `sweep` must both attempt regardless of what the main body
|
|
239
|
+
// did — an uncaught error there would otherwise strand admitted burst
|
|
240
|
+
// sandboxes and leave the cleanup audit that was the whole point of the
|
|
241
|
+
// ledger unfinished. Ledger failure must not preempt the audit either.
|
|
242
|
+
try {
|
|
243
|
+
deps.ledger({ event: "run-end", name: deps.prefix });
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// deliberately swallowed; the sweep is what matters here
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
survivors = await sweep(deps);
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
sweepError = describe(error);
|
|
253
|
+
try {
|
|
254
|
+
deps.ledger({
|
|
255
|
+
event: "sweep-failed",
|
|
256
|
+
name: deps.prefix,
|
|
257
|
+
error: sweepError,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
// deliberately swallowed; the error is captured in the report
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const createMs = samples.map((s) => s.createMs);
|
|
266
|
+
const observedVcpus = samples.find((s) => s.vcpus)?.vcpus
|
|
267
|
+
?? deps.limits.vcpus;
|
|
268
|
+
const destroyed = samples.filter((s) => s.destroyed).length
|
|
269
|
+
+ (burst?.admitted ?? 0);
|
|
270
|
+
const verifiedGone = samples.filter((s) => s.verifiedGone).length
|
|
271
|
+
+ (burst?.verifiedGone ?? 0);
|
|
272
|
+
// `created` counts everything admitted by the provider — sequential probes
|
|
273
|
+
// plus burst admits — so it is a coherent denominator for `destroyed` and
|
|
274
|
+
// `verifiedGone`, which already include both.
|
|
275
|
+
const created = samples.filter((s) => Number.isFinite(s.createMs)).length
|
|
276
|
+
+ (burst?.admitted ?? 0);
|
|
277
|
+
return {
|
|
278
|
+
runId: deps.runId,
|
|
279
|
+
prefix: deps.prefix,
|
|
280
|
+
mode,
|
|
281
|
+
n: samples.length,
|
|
282
|
+
coldCreate: {
|
|
283
|
+
p50Ms: Math.round(percentile(createMs, 50)),
|
|
284
|
+
p95Ms: Math.round(percentile(createMs, 95)),
|
|
285
|
+
},
|
|
286
|
+
firstExec: {
|
|
287
|
+
p50Ms: Math.round(percentile(samples.map((s) => s.firstExecMs), 50)),
|
|
288
|
+
p95Ms: Math.round(percentile(samples.map((s) => s.firstExecMs), 95)),
|
|
289
|
+
},
|
|
290
|
+
readyStateAfterCreate: [...new Set(samples.map((s) => s.stateAfterCreate))],
|
|
291
|
+
deliveredShape: {
|
|
292
|
+
vcpus: [...new Set(samples.map((s) => s.vcpus).filter(isNumber))],
|
|
293
|
+
memoryMiB: [...new Set(samples.map((s) => s.memoryMiB).filter(isNumber))],
|
|
294
|
+
documented: "1 or even 2-32 vCPUs, default 2; 2 GB memory per vCPU",
|
|
295
|
+
},
|
|
296
|
+
cleanup: {
|
|
297
|
+
created,
|
|
298
|
+
destroyed,
|
|
299
|
+
verifiedGone,
|
|
300
|
+
survivors,
|
|
301
|
+
...(sweepError ? { sweepError } : {}),
|
|
302
|
+
},
|
|
303
|
+
burst,
|
|
304
|
+
costProjection: {
|
|
305
|
+
shape: `${observedVcpus} vCPU / ${observedVcpus * 2} GB`,
|
|
306
|
+
note: "Active CPU excludes I/O wait; provisioned memory is billed on WALL "
|
|
307
|
+
+ "CLOCK. The memory line is a floor an idle-heavy agent cannot duck.",
|
|
308
|
+
perHour: [1, 0.5, 0.1, 0].map((u) => projectCost(observedVcpus, u)),
|
|
309
|
+
},
|
|
310
|
+
errors: samples
|
|
311
|
+
.filter((s) => s.error)
|
|
312
|
+
.map((s) => ({ index: s.index, error: s.error })),
|
|
313
|
+
// A sweep that never ran cannot certify a clean run.
|
|
314
|
+
clean: sweepError === undefined
|
|
315
|
+
&& survivors.length === 0
|
|
316
|
+
&& destroyed === verifiedGone,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function isNumber(value) {
|
|
320
|
+
return typeof value === "number";
|
|
321
|
+
}
|
|
322
|
+
function describe(error) {
|
|
323
|
+
return error instanceof Error
|
|
324
|
+
? `${error.name}: ${error.message}`
|
|
325
|
+
: String(error);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* The one destroy error where the sandbox may already be gone but we cannot
|
|
329
|
+
* prove it. Matched on name to keep the harness decoupled from the provider
|
|
330
|
+
* error class — a benchmark shim over a different runtime can raise the same
|
|
331
|
+
* name and get the same accounting.
|
|
332
|
+
*/
|
|
333
|
+
function isVerificationFailure(error) {
|
|
334
|
+
return (error instanceof Error
|
|
335
|
+
&& error.name === "VercelDestroyVerificationError");
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=bench.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench.js","sourceRoot":"","sources":["../../src/vercel/bench.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK-free capability metadata for the Vercel Sandbox adapter.
|
|
3
|
+
*
|
|
4
|
+
* Two rules govern this file:
|
|
5
|
+
*
|
|
6
|
+
* 1. A capability means *reachable through this package's ports*. The vendor
|
|
7
|
+
* SDK having a method is not the same as this adapter exposing it, and the
|
|
8
|
+
* gap is where false capability claims come from.
|
|
9
|
+
* 2. A behavioral claim stays `false` until a live probe against the pinned
|
|
10
|
+
* SDK establishes it. Shape is not evidence.
|
|
11
|
+
*/
|
|
12
|
+
export declare const vercelSandboxCapabilities: {
|
|
13
|
+
readonly warmLease: false;
|
|
14
|
+
readonly lifecycle: false;
|
|
15
|
+
};
|
|
16
|
+
export declare const vercelWorkflowCapabilities: {
|
|
17
|
+
readonly pty: false;
|
|
18
|
+
readonly snapshots: false;
|
|
19
|
+
readonly isolation: "strong";
|
|
20
|
+
readonly persistentHandle: true;
|
|
21
|
+
readonly streamingLogs: false;
|
|
22
|
+
};
|
|
23
|
+
export type VercelObservedCapabilities = {
|
|
24
|
+
cleanupVerified: boolean;
|
|
25
|
+
fork: boolean;
|
|
26
|
+
lifecycle: boolean;
|
|
27
|
+
neverIdle: boolean;
|
|
28
|
+
ptySurvival: boolean;
|
|
29
|
+
snapshotCapture: boolean;
|
|
30
|
+
streamingExec: boolean;
|
|
31
|
+
warmLease: boolean;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Cells not yet proven live remain `false` rather than inferred from SDK shape.
|
|
35
|
+
*
|
|
36
|
+
* Promotion protocol: a cell flips to `true` only in a commit that also records
|
|
37
|
+
* the dated live evidence that justified it, exactly as the Freestyle adapter
|
|
38
|
+
* did for `cleanupVerified`.
|
|
39
|
+
*/
|
|
40
|
+
export declare const vercelObservedCapabilities: VercelObservedCapabilities;
|
|
41
|
+
/**
|
|
42
|
+
* Structured capability modes for the Vercel Sandbox adapter.
|
|
43
|
+
*
|
|
44
|
+
* These restate, in the type system, distinctions this file already draws in
|
|
45
|
+
* prose. The booleans above cannot separate "the provider cannot do this" from
|
|
46
|
+
* "the provider can, but this package's port exposes no operation reaching it"
|
|
47
|
+
* from "nobody has checked yet" — and rule 1 of this file is precisely that
|
|
48
|
+
* distinction. `not-exposed` is that rule as a type.
|
|
49
|
+
*
|
|
50
|
+
* Note which cell is **missing**: `filesystem`. See below.
|
|
51
|
+
*/
|
|
52
|
+
export declare const vercelCapabilityModes: {
|
|
53
|
+
/**
|
|
54
|
+
* `Command.logs()` is an async iterator, so the SDK can genuinely stream. This
|
|
55
|
+
* adapter awaits `output("stdout")` and `output("stderr")` to completion and
|
|
56
|
+
* returns a finished `RunScriptResult`, and the port exposes no streaming
|
|
57
|
+
* operation. Both streaming members of the union mean *streamed live*, so
|
|
58
|
+
* `buffered` is the honest shape for this port.
|
|
59
|
+
*/
|
|
60
|
+
readonly outputStreams: "buffered";
|
|
61
|
+
/**
|
|
62
|
+
* Settled, not pending. A Vercel sandbox always carries a wall-clock
|
|
63
|
+
* termination deadline (`sandboxTimeoutMs`) — there is no never-idle tier to
|
|
64
|
+
* promote to, which is the same fact recorded against
|
|
65
|
+
* {@link vercelObservedCapabilities.neverIdle}. Per the union's own note,
|
|
66
|
+
* `deadline` says this without needing `unsupported`.
|
|
67
|
+
*/
|
|
68
|
+
readonly lifetime: "deadline";
|
|
69
|
+
/**
|
|
70
|
+
* `sandbox.openInteractive()` exists in the SDK; `WorkflowRuntime` exposes no
|
|
71
|
+
* PTY operation, so it is unreachable *here*. `not-exposed` rather than
|
|
72
|
+
* `unsupported`: this is a fact about our port, and it moves only if someone
|
|
73
|
+
* adds an operation — never on the strength of a live probe against Vercel.
|
|
74
|
+
*/
|
|
75
|
+
readonly interactive: "not-exposed";
|
|
76
|
+
/**
|
|
77
|
+
* `sandbox.snapshot()` and `Sandbox.fork()` exist in the SDK and are likewise
|
|
78
|
+
* unreachable through this port. Note this is a *different* claim from
|
|
79
|
+
* {@link vercelObservedCapabilities.snapshotCapture}, which is a pending
|
|
80
|
+
* observation about Vercel: a canary may promote that one and must never
|
|
81
|
+
* promote this one.
|
|
82
|
+
*/
|
|
83
|
+
readonly snapshots: "not-exposed";
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Why `filesystem` is deliberately left undeclared, and so resolves to
|
|
87
|
+
* `"unknown"`.
|
|
88
|
+
*
|
|
89
|
+
* Unlike the cells above, this one is not a fact this adapter is in a position
|
|
90
|
+
* to state. Two reasons compound:
|
|
91
|
+
*
|
|
92
|
+
* 1. It is **configurable per instance**, not a property of the provider.
|
|
93
|
+
* `VercelSandboxRuntimeOptions.persistent` selects the durability contract,
|
|
94
|
+
* so no single static value is correct for every `VercelSandboxRuntime`.
|
|
95
|
+
* 2. Even for a `persistent: true` instance, the union's `"persistent"` means
|
|
96
|
+
* *restored across stop/start of the same sandbox* — which is exactly the
|
|
97
|
+
* round trip that `vercelSandboxCapabilities.lifecycle` is still waiting on
|
|
98
|
+
* a live probe to establish. Declaring it would promote, through a mode,
|
|
99
|
+
* the very behavior the boolean is holding back for lack of evidence.
|
|
100
|
+
*
|
|
101
|
+
* `"unknown"` is the accurate answer and the only one that keeps
|
|
102
|
+
* `isPendingEvidence()` truthful: a live stop -> resume -> read-back probe
|
|
103
|
+
* genuinely can settle this, and should be what does.
|
|
104
|
+
*/
|
|
105
|
+
export declare const VERCEL_FILESYSTEM_MODE_UNDECLARED: string;
|
|
106
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/vercel/capabilities.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,yBAAyB;;;CAWiB,CAAC;AAExD,eAAO,MAAM,0BAA0B;;;;;;CAcC,CAAC;AAEzC,MAAM,MAAM,0BAA0B,GAAG;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,0BAexC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB;IAChC;;;;;;OAMG;;IAEH;;;;;;OAMG;;IAEH;;;;;OAKG;;IAEH;;;;;;OAMG;;CAE+C,CAAC;AAErD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,iCAAiC,QAEsB,CAAC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK-free capability metadata for the Vercel Sandbox adapter.
|
|
3
|
+
*
|
|
4
|
+
* Two rules govern this file:
|
|
5
|
+
*
|
|
6
|
+
* 1. A capability means *reachable through this package's ports*. The vendor
|
|
7
|
+
* SDK having a method is not the same as this adapter exposing it, and the
|
|
8
|
+
* gap is where false capability claims come from.
|
|
9
|
+
* 2. A behavioral claim stays `false` until a live probe against the pinned
|
|
10
|
+
* SDK establishes it. Shape is not evidence.
|
|
11
|
+
*/
|
|
12
|
+
export const vercelSandboxCapabilities = {
|
|
13
|
+
// `Sandbox.list` accepts a server-side `tags` filter, so unlike Freestyle the
|
|
14
|
+
// implementation here is a real label search rather than a degraded `[]`.
|
|
15
|
+
// It still declares false: server-side filtering that is silently ignored by
|
|
16
|
+
// the API would return foreign sandboxes as lease candidates, which is worse
|
|
17
|
+
// than no lease at all. Promote only once a live probe shows that a tag query
|
|
18
|
+
// excludes a known non-matching sandbox.
|
|
19
|
+
warmLease: false,
|
|
20
|
+
// `stop()` is real, and `Sandbox.get({ resume: true })` is the resume path.
|
|
21
|
+
// Promotion waits on a live stop -> settled -> resume -> exec round trip.
|
|
22
|
+
lifecycle: false,
|
|
23
|
+
};
|
|
24
|
+
export const vercelWorkflowCapabilities = {
|
|
25
|
+
// `sandbox.openInteractive()` exists in the SDK, but WorkflowRuntime exposes
|
|
26
|
+
// no PTY operation, so it is not reachable through this port.
|
|
27
|
+
pty: false,
|
|
28
|
+
// `sandbox.snapshot()` and `Sandbox.fork()` exist in the SDK; likewise not
|
|
29
|
+
// reachable through this port.
|
|
30
|
+
snapshots: false,
|
|
31
|
+
// Each sandbox is a dedicated Firecracker-class microVM.
|
|
32
|
+
isolation: "strong",
|
|
33
|
+
// `getById` re-resolves a sandbox by name across processes.
|
|
34
|
+
persistentHandle: true,
|
|
35
|
+
// `Command.logs()` is an async iterator in the SDK, but this adapter buffers
|
|
36
|
+
// and returns a completed result; no streaming surface is exposed.
|
|
37
|
+
streamingLogs: false,
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Cells not yet proven live remain `false` rather than inferred from SDK shape.
|
|
41
|
+
*
|
|
42
|
+
* Promotion protocol: a cell flips to `true` only in a commit that also records
|
|
43
|
+
* the dated live evidence that justified it, exactly as the Freestyle adapter
|
|
44
|
+
* did for `cleanupVerified`.
|
|
45
|
+
*/
|
|
46
|
+
export const vercelObservedCapabilities = {
|
|
47
|
+
// Implemented: `destroy` submits the delete and then verifies absence in a
|
|
48
|
+
// fresh prefix listing, treating a same-name row with a different createdAt
|
|
49
|
+
// as a *different* sandbox rather than a survivor. Promotion is gated on the
|
|
50
|
+
// live canary showing destroyed === verifiedGone across the n=7 run.
|
|
51
|
+
cleanupVerified: false,
|
|
52
|
+
fork: false,
|
|
53
|
+
lifecycle: false,
|
|
54
|
+
// Not merely unproven: Vercel sandboxes always carry a termination deadline,
|
|
55
|
+
// so there is no never-idle tier to promote this to. This one is settled.
|
|
56
|
+
neverIdle: false,
|
|
57
|
+
ptySurvival: false,
|
|
58
|
+
snapshotCapture: false,
|
|
59
|
+
streamingExec: false,
|
|
60
|
+
warmLease: false,
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Structured capability modes for the Vercel Sandbox adapter.
|
|
64
|
+
*
|
|
65
|
+
* These restate, in the type system, distinctions this file already draws in
|
|
66
|
+
* prose. The booleans above cannot separate "the provider cannot do this" from
|
|
67
|
+
* "the provider can, but this package's port exposes no operation reaching it"
|
|
68
|
+
* from "nobody has checked yet" — and rule 1 of this file is precisely that
|
|
69
|
+
* distinction. `not-exposed` is that rule as a type.
|
|
70
|
+
*
|
|
71
|
+
* Note which cell is **missing**: `filesystem`. See below.
|
|
72
|
+
*/
|
|
73
|
+
export const vercelCapabilityModes = {
|
|
74
|
+
/**
|
|
75
|
+
* `Command.logs()` is an async iterator, so the SDK can genuinely stream. This
|
|
76
|
+
* adapter awaits `output("stdout")` and `output("stderr")` to completion and
|
|
77
|
+
* returns a finished `RunScriptResult`, and the port exposes no streaming
|
|
78
|
+
* operation. Both streaming members of the union mean *streamed live*, so
|
|
79
|
+
* `buffered` is the honest shape for this port.
|
|
80
|
+
*/
|
|
81
|
+
outputStreams: "buffered",
|
|
82
|
+
/**
|
|
83
|
+
* Settled, not pending. A Vercel sandbox always carries a wall-clock
|
|
84
|
+
* termination deadline (`sandboxTimeoutMs`) — there is no never-idle tier to
|
|
85
|
+
* promote to, which is the same fact recorded against
|
|
86
|
+
* {@link vercelObservedCapabilities.neverIdle}. Per the union's own note,
|
|
87
|
+
* `deadline` says this without needing `unsupported`.
|
|
88
|
+
*/
|
|
89
|
+
lifetime: "deadline",
|
|
90
|
+
/**
|
|
91
|
+
* `sandbox.openInteractive()` exists in the SDK; `WorkflowRuntime` exposes no
|
|
92
|
+
* PTY operation, so it is unreachable *here*. `not-exposed` rather than
|
|
93
|
+
* `unsupported`: this is a fact about our port, and it moves only if someone
|
|
94
|
+
* adds an operation — never on the strength of a live probe against Vercel.
|
|
95
|
+
*/
|
|
96
|
+
interactive: "not-exposed",
|
|
97
|
+
/**
|
|
98
|
+
* `sandbox.snapshot()` and `Sandbox.fork()` exist in the SDK and are likewise
|
|
99
|
+
* unreachable through this port. Note this is a *different* claim from
|
|
100
|
+
* {@link vercelObservedCapabilities.snapshotCapture}, which is a pending
|
|
101
|
+
* observation about Vercel: a canary may promote that one and must never
|
|
102
|
+
* promote this one.
|
|
103
|
+
*/
|
|
104
|
+
snapshots: "not-exposed",
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Why `filesystem` is deliberately left undeclared, and so resolves to
|
|
108
|
+
* `"unknown"`.
|
|
109
|
+
*
|
|
110
|
+
* Unlike the cells above, this one is not a fact this adapter is in a position
|
|
111
|
+
* to state. Two reasons compound:
|
|
112
|
+
*
|
|
113
|
+
* 1. It is **configurable per instance**, not a property of the provider.
|
|
114
|
+
* `VercelSandboxRuntimeOptions.persistent` selects the durability contract,
|
|
115
|
+
* so no single static value is correct for every `VercelSandboxRuntime`.
|
|
116
|
+
* 2. Even for a `persistent: true` instance, the union's `"persistent"` means
|
|
117
|
+
* *restored across stop/start of the same sandbox* — which is exactly the
|
|
118
|
+
* round trip that `vercelSandboxCapabilities.lifecycle` is still waiting on
|
|
119
|
+
* a live probe to establish. Declaring it would promote, through a mode,
|
|
120
|
+
* the very behavior the boolean is holding back for lack of evidence.
|
|
121
|
+
*
|
|
122
|
+
* `"unknown"` is the accurate answer and the only one that keeps
|
|
123
|
+
* `isPendingEvidence()` truthful: a live stop -> resume -> read-back probe
|
|
124
|
+
* genuinely can settle this, and should be what does.
|
|
125
|
+
*/
|
|
126
|
+
export const VERCEL_FILESYSTEM_MODE_UNDECLARED = "filesystem durability is per-instance (options.persistent) and its across-restart "
|
|
127
|
+
+ "behavior is gated on the same unproven live probe as lifecycle";
|
|
128
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/vercel/capabilities.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,8EAA8E;IAC9E,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,8EAA8E;IAC9E,yCAAyC;IACzC,SAAS,EAAE,KAAK;IAChB,4EAA4E;IAC5E,0EAA0E;IAC1E,SAAS,EAAE,KAAK;CACqC,CAAC;AAExD,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,6EAA6E;IAC7E,8DAA8D;IAC9D,GAAG,EAAE,KAAK;IACV,2EAA2E;IAC3E,+BAA+B;IAC/B,SAAS,EAAE,KAAK;IAChB,yDAAyD;IACzD,SAAS,EAAE,QAAQ;IACnB,4DAA4D;IAC5D,gBAAgB,EAAE,IAAI;IACtB,6EAA6E;IAC7E,mEAAmE;IACnE,aAAa,EAAE,KAAK;CACkB,CAAC;AAazC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAA+B;IACpE,2EAA2E;IAC3E,4EAA4E;IAC5E,6EAA6E;IAC7E,qEAAqE;IACrE,eAAe,EAAE,KAAK;IACtB,IAAI,EAAE,KAAK;IACX,SAAS,EAAE,KAAK;IAChB,6EAA6E;IAC7E,0EAA0E;IAC1E,SAAS,EAAE,KAAK;IAChB,WAAW,EAAE,KAAK;IAClB,eAAe,EAAE,KAAK;IACtB,aAAa,EAAE,KAAK;IACpB,SAAS,EAAE,KAAK;CACjB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC;;;;;;OAMG;IACH,aAAa,EAAE,UAAU;IACzB;;;;;;OAMG;IACH,QAAQ,EAAE,UAAU;IACpB;;;;;OAKG;IACH,WAAW,EAAE,aAAa;IAC1B;;;;;;OAMG;IACH,SAAS,EAAE,aAAa;CAC0B,CAAC;AAErD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAC5C,oFAAoF;MAClF,gEAAgE,CAAC"}
|