tensorlake 0.4.45 → 0.4.47
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/bin/darwin-arm64/tensorlake +0 -0
- package/dist/bin/darwin-arm64/tl +0 -0
- package/dist/bin/linux-x64/tensorlake +0 -0
- package/dist/bin/linux-x64/tl +0 -0
- package/dist/bin/win32-x64/tensorlake.exe +0 -0
- package/dist/bin/win32-x64/tl.exe +0 -0
- package/dist/index.cjs +62 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +62 -46
- package/dist/index.js.map +1 -1
- package/dist/{sandbox-image-B5Fa0xqb.d.cts → sandbox-image-B130uMYt.d.cts} +2 -0
- package/dist/{sandbox-image-B5Fa0xqb.d.ts → sandbox-image-B130uMYt.d.ts} +2 -0
- package/dist/sandbox-image.cjs +62 -46
- package/dist/sandbox-image.cjs.map +1 -1
- package/dist/sandbox-image.d.cts +1 -1
- package/dist/sandbox-image.d.ts +1 -1
- package/dist/sandbox-image.js +62 -46
- package/dist/sandbox-image.js.map +1 -1
- package/package.json +1 -1
|
@@ -76,6 +76,7 @@ interface UpdateSandboxOptions {
|
|
|
76
76
|
interface CreateSandboxResponse {
|
|
77
77
|
sandboxId: string;
|
|
78
78
|
status: SandboxStatus;
|
|
79
|
+
routingHint?: string;
|
|
79
80
|
}
|
|
80
81
|
interface SandboxInfo {
|
|
81
82
|
sandboxId: string;
|
|
@@ -267,6 +268,7 @@ interface SandboxOptions {
|
|
|
267
268
|
apiKey?: string;
|
|
268
269
|
organizationId?: string;
|
|
269
270
|
projectId?: string;
|
|
271
|
+
routingHint?: string;
|
|
270
272
|
}
|
|
271
273
|
interface CreateAndConnectOptions extends CreateSandboxOptions {
|
|
272
274
|
poolId?: string;
|
|
@@ -76,6 +76,7 @@ interface UpdateSandboxOptions {
|
|
|
76
76
|
interface CreateSandboxResponse {
|
|
77
77
|
sandboxId: string;
|
|
78
78
|
status: SandboxStatus;
|
|
79
|
+
routingHint?: string;
|
|
79
80
|
}
|
|
80
81
|
interface SandboxInfo {
|
|
81
82
|
sandboxId: string;
|
|
@@ -267,6 +268,7 @@ interface SandboxOptions {
|
|
|
267
268
|
apiKey?: string;
|
|
268
269
|
organizationId?: string;
|
|
269
270
|
projectId?: string;
|
|
271
|
+
routingHint?: string;
|
|
270
272
|
}
|
|
271
273
|
interface CreateAndConnectOptions extends CreateSandboxOptions {
|
|
272
274
|
poolId?: string;
|
package/dist/sandbox-image.cjs
CHANGED
|
@@ -177,6 +177,9 @@ var HttpClient = class {
|
|
|
177
177
|
if (options.hostHeader) {
|
|
178
178
|
this.headers["Host"] = options.hostHeader;
|
|
179
179
|
}
|
|
180
|
+
if (options.routingHint) {
|
|
181
|
+
this.headers["X-Tensorlake-Route-Hint"] = options.routingHint;
|
|
182
|
+
}
|
|
180
183
|
}
|
|
181
184
|
close() {
|
|
182
185
|
this.abortController?.abort();
|
|
@@ -211,12 +214,13 @@ var HttpClient = class {
|
|
|
211
214
|
const buffer = await response.arrayBuffer();
|
|
212
215
|
return new Uint8Array(buffer);
|
|
213
216
|
}
|
|
214
|
-
/** Make a request and return the
|
|
217
|
+
/** Make a request and return the response body as an SSE stream. */
|
|
215
218
|
async requestStream(method, path2, options) {
|
|
216
219
|
const response = await this.requestResponse(
|
|
217
220
|
method,
|
|
218
221
|
path2,
|
|
219
222
|
{
|
|
223
|
+
json: options?.json,
|
|
220
224
|
headers: { Accept: "text/event-stream" },
|
|
221
225
|
signal: options?.signal
|
|
222
226
|
}
|
|
@@ -3070,7 +3074,8 @@ var Sandbox = class {
|
|
|
3070
3074
|
apiKey: options.apiKey,
|
|
3071
3075
|
organizationId: options.organizationId,
|
|
3072
3076
|
projectId: options.projectId,
|
|
3073
|
-
hostHeader
|
|
3077
|
+
hostHeader,
|
|
3078
|
+
routingHint: options.routingHint
|
|
3074
3079
|
});
|
|
3075
3080
|
}
|
|
3076
3081
|
/** @internal Used by SandboxClient.createAndConnect to set ownership. */
|
|
@@ -3091,37 +3096,45 @@ var Sandbox = class {
|
|
|
3091
3096
|
}
|
|
3092
3097
|
}
|
|
3093
3098
|
// --- High-level convenience ---
|
|
3099
|
+
/**
|
|
3100
|
+
* Run a command to completion and return its output.
|
|
3101
|
+
*
|
|
3102
|
+
* Uses a single streaming `POST /api/v1/processes/run` request that starts
|
|
3103
|
+
* the process, streams output, and delivers the exit code over one connection.
|
|
3104
|
+
*/
|
|
3094
3105
|
async run(command, options) {
|
|
3095
|
-
const
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
const
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3106
|
+
const body = { command };
|
|
3107
|
+
if (options?.args) body.args = options.args;
|
|
3108
|
+
if (options?.env) body.env = options.env;
|
|
3109
|
+
if (options?.workingDir) body.working_dir = options.workingDir;
|
|
3110
|
+
if (options?.timeout != null) body.timeout = options.timeout;
|
|
3111
|
+
const sseStream = await this.http.requestStream(
|
|
3112
|
+
"POST",
|
|
3113
|
+
"/api/v1/processes/run",
|
|
3114
|
+
{ json: body }
|
|
3115
|
+
);
|
|
3116
|
+
const stdoutLines = [];
|
|
3117
|
+
const stderrLines = [];
|
|
3118
|
+
let exitCode = -1;
|
|
3119
|
+
for await (const raw of parseSSEStream(sseStream)) {
|
|
3120
|
+
if (typeof raw.line === "string") {
|
|
3121
|
+
if (raw.stream === "stderr") {
|
|
3122
|
+
stderrLines.push(raw.line);
|
|
3123
|
+
} else {
|
|
3124
|
+
stdoutLines.push(raw.line);
|
|
3125
|
+
}
|
|
3126
|
+
} else if ("exit_code" in raw || "signal" in raw) {
|
|
3127
|
+
if (typeof raw.exit_code === "number") {
|
|
3128
|
+
exitCode = raw.exit_code;
|
|
3129
|
+
} else if (typeof raw.signal === "number") {
|
|
3130
|
+
exitCode = -raw.signal;
|
|
3131
|
+
}
|
|
3108
3132
|
}
|
|
3109
|
-
await sleep2(100);
|
|
3110
|
-
}
|
|
3111
|
-
const stdoutResp = await this.getStdout(proc.pid);
|
|
3112
|
-
const stderrResp = await this.getStderr(proc.pid);
|
|
3113
|
-
let exitCode;
|
|
3114
|
-
if (info.exitCode != null) {
|
|
3115
|
-
exitCode = info.exitCode;
|
|
3116
|
-
} else if (info.signal != null) {
|
|
3117
|
-
exitCode = -info.signal;
|
|
3118
|
-
} else {
|
|
3119
|
-
exitCode = -1;
|
|
3120
3133
|
}
|
|
3121
3134
|
return {
|
|
3122
3135
|
exitCode,
|
|
3123
|
-
stdout:
|
|
3124
|
-
stderr:
|
|
3136
|
+
stdout: stdoutLines.join("\n"),
|
|
3137
|
+
stderr: stderrLines.join("\n")
|
|
3125
3138
|
};
|
|
3126
3139
|
}
|
|
3127
3140
|
// --- Process management ---
|
|
@@ -3370,9 +3383,6 @@ var Sandbox = class {
|
|
|
3370
3383
|
return fromSnakeKeys(raw);
|
|
3371
3384
|
}
|
|
3372
3385
|
};
|
|
3373
|
-
function sleep2(ms) {
|
|
3374
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3375
|
-
}
|
|
3376
3386
|
|
|
3377
3387
|
// src/client.ts
|
|
3378
3388
|
var SandboxClient = class _SandboxClient {
|
|
@@ -3588,7 +3598,7 @@ var SandboxClient = class _SandboxClient {
|
|
|
3588
3598
|
`Snapshot ${result.snapshotId} failed: ${info.error}`
|
|
3589
3599
|
);
|
|
3590
3600
|
}
|
|
3591
|
-
await
|
|
3601
|
+
await sleep2(pollInterval * 1e3);
|
|
3592
3602
|
}
|
|
3593
3603
|
throw new SandboxError(
|
|
3594
3604
|
`Snapshot ${result.snapshotId} did not complete within ${timeout}s`
|
|
@@ -3660,14 +3670,15 @@ var SandboxClient = class _SandboxClient {
|
|
|
3660
3670
|
);
|
|
3661
3671
|
}
|
|
3662
3672
|
// --- Connect ---
|
|
3663
|
-
connect(identifier, proxyUrl) {
|
|
3673
|
+
connect(identifier, proxyUrl, routingHint) {
|
|
3664
3674
|
const resolvedProxy = proxyUrl ?? resolveProxyUrl(this.apiUrl);
|
|
3665
3675
|
return new Sandbox({
|
|
3666
3676
|
sandboxId: identifier,
|
|
3667
3677
|
proxyUrl: resolvedProxy,
|
|
3668
3678
|
apiKey: this.apiKey,
|
|
3669
3679
|
organizationId: this.organizationId,
|
|
3670
|
-
projectId: this.projectId
|
|
3680
|
+
projectId: this.projectId,
|
|
3681
|
+
routingHint
|
|
3671
3682
|
});
|
|
3672
3683
|
}
|
|
3673
3684
|
async createAndConnect(options) {
|
|
@@ -3678,6 +3689,11 @@ var SandboxClient = class _SandboxClient {
|
|
|
3678
3689
|
} else {
|
|
3679
3690
|
result = await this.create(options);
|
|
3680
3691
|
}
|
|
3692
|
+
if (result.status === "running" /* RUNNING */) {
|
|
3693
|
+
const sandbox = this.connect(result.sandboxId, options?.proxyUrl, result.routingHint);
|
|
3694
|
+
sandbox._setOwner(this);
|
|
3695
|
+
return sandbox;
|
|
3696
|
+
}
|
|
3681
3697
|
const deadline = Date.now() + startupTimeout * 1e3;
|
|
3682
3698
|
while (Date.now() < deadline) {
|
|
3683
3699
|
const info = await this.get(result.sandboxId);
|
|
@@ -3691,7 +3707,7 @@ var SandboxClient = class _SandboxClient {
|
|
|
3691
3707
|
`Sandbox ${result.sandboxId} terminated during startup`
|
|
3692
3708
|
);
|
|
3693
3709
|
}
|
|
3694
|
-
await
|
|
3710
|
+
await sleep2(500);
|
|
3695
3711
|
}
|
|
3696
3712
|
try {
|
|
3697
3713
|
await this.delete(result.sandboxId);
|
|
@@ -3702,7 +3718,7 @@ var SandboxClient = class _SandboxClient {
|
|
|
3702
3718
|
);
|
|
3703
3719
|
}
|
|
3704
3720
|
};
|
|
3705
|
-
function
|
|
3721
|
+
function sleep2(ms) {
|
|
3706
3722
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3707
3723
|
}
|
|
3708
3724
|
var RESERVED_SANDBOX_MANAGEMENT_PORT = 9501;
|
|
@@ -4125,7 +4141,7 @@ async function runChecked(sandbox, command, args, env, workingDir) {
|
|
|
4125
4141
|
}
|
|
4126
4142
|
return result;
|
|
4127
4143
|
}
|
|
4128
|
-
async function runStreaming(sandbox, emit,
|
|
4144
|
+
async function runStreaming(sandbox, emit, sleep3, command, args = [], env, workingDir) {
|
|
4129
4145
|
const proc = await sandbox.startProcess(command, {
|
|
4130
4146
|
args,
|
|
4131
4147
|
env,
|
|
@@ -4150,13 +4166,13 @@ async function runStreaming(sandbox, emit, sleep4, command, args = [], env, work
|
|
|
4150
4166
|
emitOutputLines(emit, "stderr", finalStderr, stderrSeen);
|
|
4151
4167
|
break;
|
|
4152
4168
|
}
|
|
4153
|
-
await
|
|
4169
|
+
await sleep3(300);
|
|
4154
4170
|
}
|
|
4155
4171
|
for (let i = 0; i < 10; i++) {
|
|
4156
4172
|
if (info.exitCode != null || info.signal != null) {
|
|
4157
4173
|
break;
|
|
4158
4174
|
}
|
|
4159
|
-
await
|
|
4175
|
+
await sleep3(200);
|
|
4160
4176
|
info = await sandbox.getProcess(proc.pid);
|
|
4161
4177
|
}
|
|
4162
4178
|
const exitCode = info.exitCode != null ? info.exitCode : info.signal != null ? -info.signal : 0;
|
|
@@ -4254,7 +4270,7 @@ async function copyFromContext(sandbox, emit, contextDir, sources, destination,
|
|
|
4254
4270
|
await copyLocalPathToSandbox(sandbox, localSource, remoteDestination);
|
|
4255
4271
|
}
|
|
4256
4272
|
}
|
|
4257
|
-
async function addUrlToSandbox(sandbox, emit, url, destination, workingDir, processEnv,
|
|
4273
|
+
async function addUrlToSandbox(sandbox, emit, url, destination, workingDir, processEnv, sleep3) {
|
|
4258
4274
|
let destinationPath = resolveContainerPath(destination, workingDir);
|
|
4259
4275
|
const parsedUrl = new URL(url);
|
|
4260
4276
|
const fileName = import_node_path.default.posix.basename(parsedUrl.pathname.replace(/\/$/, "")) || "downloaded";
|
|
@@ -4270,7 +4286,7 @@ async function addUrlToSandbox(sandbox, emit, url, destination, workingDir, proc
|
|
|
4270
4286
|
await runStreaming(
|
|
4271
4287
|
sandbox,
|
|
4272
4288
|
emit,
|
|
4273
|
-
|
|
4289
|
+
sleep3,
|
|
4274
4290
|
"sh",
|
|
4275
4291
|
[
|
|
4276
4292
|
"-c",
|
|
@@ -4280,7 +4296,7 @@ async function addUrlToSandbox(sandbox, emit, url, destination, workingDir, proc
|
|
|
4280
4296
|
workingDir
|
|
4281
4297
|
);
|
|
4282
4298
|
}
|
|
4283
|
-
async function executeDockerfilePlan(sandbox, plan, emit,
|
|
4299
|
+
async function executeDockerfilePlan(sandbox, plan, emit, sleep3) {
|
|
4284
4300
|
const processEnv = { ...BUILD_SANDBOX_PIP_ENV };
|
|
4285
4301
|
let workingDir = "/";
|
|
4286
4302
|
for (const instruction of plan.instructions) {
|
|
@@ -4290,7 +4306,7 @@ async function executeDockerfilePlan(sandbox, plan, emit, sleep4) {
|
|
|
4290
4306
|
await runStreaming(
|
|
4291
4307
|
sandbox,
|
|
4292
4308
|
emit,
|
|
4293
|
-
|
|
4309
|
+
sleep3,
|
|
4294
4310
|
"sh",
|
|
4295
4311
|
["-c", value],
|
|
4296
4312
|
processEnv,
|
|
@@ -4347,7 +4363,7 @@ async function executeDockerfilePlan(sandbox, plan, emit, sleep4) {
|
|
|
4347
4363
|
destination,
|
|
4348
4364
|
workingDir,
|
|
4349
4365
|
processEnv,
|
|
4350
|
-
|
|
4366
|
+
sleep3
|
|
4351
4367
|
);
|
|
4352
4368
|
} else {
|
|
4353
4369
|
await copyFromContext(
|
|
@@ -4415,7 +4431,7 @@ async function registerImage(context, name, dockerfile, snapshotId, snapshotUri,
|
|
|
4415
4431
|
}
|
|
4416
4432
|
async function createSandboxImage(source, options = {}, deps = {}) {
|
|
4417
4433
|
const emit = deps.emit ?? defaultEmit;
|
|
4418
|
-
const
|
|
4434
|
+
const sleep3 = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
4419
4435
|
const context = buildContextFromEnv();
|
|
4420
4436
|
const clientFactory = deps.createClient ?? createDefaultClient;
|
|
4421
4437
|
const register = deps.registerImage ?? ((...args) => registerImage(...args));
|
|
@@ -4438,7 +4454,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
|
|
|
4438
4454
|
type: "status",
|
|
4439
4455
|
message: `Materializing image in sandbox ${sandbox.sandboxId}...`
|
|
4440
4456
|
});
|
|
4441
|
-
await executeDockerfilePlan(sandbox, plan, emit,
|
|
4457
|
+
await executeDockerfilePlan(sandbox, plan, emit, sleep3);
|
|
4442
4458
|
emit({ type: "status", message: "Creating snapshot..." });
|
|
4443
4459
|
const snapshot = await client.snapshotAndWait(sandbox.sandboxId, {
|
|
4444
4460
|
contentMode: "filesystem_only"
|