tensorlake 0.5.89 → 0.5.91
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/index.cjs +124 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +124 -29
- package/dist/index.js.map +1 -1
- package/dist/native/darwin-arm64/tensorlake-node.node +0 -0
- package/dist/native/linux-arm64/tensorlake-node.node +0 -0
- package/dist/native/linux-arm64-musl/tensorlake-node.node +0 -0
- package/dist/native/linux-x64/tensorlake-node.node +0 -0
- package/dist/native/linux-x64-musl/tensorlake-node.node +0 -0
- package/dist/native/win32-x64/tensorlake-node.node +0 -0
- package/dist/sandbox-image.cjs +47 -4
- package/dist/sandbox-image.cjs.map +1 -1
- package/dist/sandbox-image.js +47 -4
- package/dist/sandbox-image.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ var SDK_VERSION, API_URL, API_KEY, NAMESPACE, SANDBOX_PROXY_URL, DEFAULT_HTTP_TI
|
|
|
35
35
|
var init_defaults = __esm({
|
|
36
36
|
"src/defaults.ts"() {
|
|
37
37
|
"use strict";
|
|
38
|
-
SDK_VERSION = "0.5.
|
|
38
|
+
SDK_VERSION = "0.5.91";
|
|
39
39
|
API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
|
|
40
40
|
API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
|
|
41
41
|
NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
|
|
@@ -339,7 +339,8 @@ function parseTimestamp(v) {
|
|
|
339
339
|
return new Date(ts * 1e3);
|
|
340
340
|
}
|
|
341
341
|
function fromSnakeKeys(obj, idField) {
|
|
342
|
-
if (Array.isArray(obj))
|
|
342
|
+
if (Array.isArray(obj))
|
|
343
|
+
return obj.map((item) => fromSnakeKeys(item, idField));
|
|
343
344
|
if (obj !== null && typeof obj === "object" && !(obj instanceof Date)) {
|
|
344
345
|
const result = {};
|
|
345
346
|
for (const [k, v] of Object.entries(obj)) {
|
|
@@ -4031,13 +4032,17 @@ function resolveRequestTimeoutMs(options) {
|
|
|
4031
4032
|
}
|
|
4032
4033
|
function secondsToMillis3(seconds) {
|
|
4033
4034
|
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
4034
|
-
throw new SandboxError(
|
|
4035
|
+
throw new SandboxError(
|
|
4036
|
+
"requestTimeout must be a positive number of seconds"
|
|
4037
|
+
);
|
|
4035
4038
|
}
|
|
4036
4039
|
return Math.ceil(seconds * 1e3);
|
|
4037
4040
|
}
|
|
4038
4041
|
function validateTimeoutMs(timeoutMs) {
|
|
4039
4042
|
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
4040
|
-
throw new SandboxError(
|
|
4043
|
+
throw new SandboxError(
|
|
4044
|
+
"timeoutMs must be a positive number of milliseconds"
|
|
4045
|
+
);
|
|
4041
4046
|
}
|
|
4042
4047
|
}
|
|
4043
4048
|
function sleep2(ms) {
|
|
@@ -4240,7 +4245,9 @@ var init_client = __esm({
|
|
|
4240
4245
|
}
|
|
4241
4246
|
/** List all sandboxes in the namespace. */
|
|
4242
4247
|
async list() {
|
|
4243
|
-
const { traceId, json } = await callNative(
|
|
4248
|
+
const { traceId, json } = await callNative(
|
|
4249
|
+
() => this.native.listSandboxes()
|
|
4250
|
+
);
|
|
4244
4251
|
const parsed = JSON.parse(json);
|
|
4245
4252
|
const sandboxes = (parsed.sandboxes ?? []).map(
|
|
4246
4253
|
(s) => fromSnakeKeys(s, "sandboxId")
|
|
@@ -4318,7 +4325,9 @@ var init_client = __esm({
|
|
|
4318
4325
|
body.exposed_ports = normalizeUserPorts(options.exposedPorts);
|
|
4319
4326
|
}
|
|
4320
4327
|
if (Object.keys(body).length === 0) {
|
|
4321
|
-
throw new SandboxError(
|
|
4328
|
+
throw new SandboxError(
|
|
4329
|
+
"At least one sandbox update field must be provided."
|
|
4330
|
+
);
|
|
4322
4331
|
}
|
|
4323
4332
|
return this.tracedJson(
|
|
4324
4333
|
() => this.native.updateSandbox(sandboxId, JSON.stringify(body)),
|
|
@@ -4354,7 +4363,9 @@ var init_client = __esm({
|
|
|
4354
4363
|
const requestedPorts = normalizeUserPorts(ports);
|
|
4355
4364
|
const current = await this.getPortAccess(sandboxId);
|
|
4356
4365
|
const toRemove = new Set(requestedPorts);
|
|
4357
|
-
const desiredPorts = current.exposedPorts.filter(
|
|
4366
|
+
const desiredPorts = current.exposedPorts.filter(
|
|
4367
|
+
(port) => !toRemove.has(port)
|
|
4368
|
+
);
|
|
4358
4369
|
return this.update(sandboxId, {
|
|
4359
4370
|
allowUnauthenticatedAccess: desiredPorts.length ? current.allowUnauthenticatedAccess : false,
|
|
4360
4371
|
exposedPorts: desiredPorts
|
|
@@ -4362,7 +4373,10 @@ var init_client = __esm({
|
|
|
4362
4373
|
}
|
|
4363
4374
|
/** Terminate and delete a sandbox. */
|
|
4364
4375
|
async delete(sandboxId) {
|
|
4365
|
-
await callNative(() => this.native.deleteSandbox(sandboxId), {
|
|
4376
|
+
await callNative(() => this.native.deleteSandbox(sandboxId), {
|
|
4377
|
+
sandboxId,
|
|
4378
|
+
notFoundKind: "sandbox"
|
|
4379
|
+
});
|
|
4366
4380
|
}
|
|
4367
4381
|
/**
|
|
4368
4382
|
* Suspend a named sandbox, preserving its state for later resume.
|
|
@@ -4373,7 +4387,10 @@ var init_client = __esm({
|
|
|
4373
4387
|
* (fire-and-return); the server processes the suspend asynchronously.
|
|
4374
4388
|
*/
|
|
4375
4389
|
async suspend(sandboxId, options) {
|
|
4376
|
-
await callNative(() => this.native.suspendSandbox(sandboxId), {
|
|
4390
|
+
await callNative(() => this.native.suspendSandbox(sandboxId), {
|
|
4391
|
+
sandboxId,
|
|
4392
|
+
notFoundKind: "sandbox"
|
|
4393
|
+
});
|
|
4377
4394
|
if (options?.wait === false) return;
|
|
4378
4395
|
const timeout = options?.timeout ?? 300;
|
|
4379
4396
|
const pollInterval = options?.pollInterval ?? 1;
|
|
@@ -4382,11 +4399,15 @@ var init_client = __esm({
|
|
|
4382
4399
|
const info = await this.get(sandboxId);
|
|
4383
4400
|
if (info.status === "suspended" /* SUSPENDED */) return;
|
|
4384
4401
|
if (info.status === "terminated" /* TERMINATED */) {
|
|
4385
|
-
throw new SandboxError(
|
|
4402
|
+
throw new SandboxError(
|
|
4403
|
+
`Sandbox ${sandboxId} terminated while waiting for suspend`
|
|
4404
|
+
);
|
|
4386
4405
|
}
|
|
4387
4406
|
await sleep2(pollInterval * 1e3);
|
|
4388
4407
|
}
|
|
4389
|
-
throw new SandboxError(
|
|
4408
|
+
throw new SandboxError(
|
|
4409
|
+
`Sandbox ${sandboxId} did not suspend within ${timeout}s`
|
|
4410
|
+
);
|
|
4390
4411
|
}
|
|
4391
4412
|
/**
|
|
4392
4413
|
* Resume a suspended sandbox and bring it back to `Running`.
|
|
@@ -4396,7 +4417,10 @@ var init_client = __esm({
|
|
|
4396
4417
|
* (fire-and-return); the server processes the resume asynchronously.
|
|
4397
4418
|
*/
|
|
4398
4419
|
async resume(sandboxId, options) {
|
|
4399
|
-
await callNative(() => this.native.resumeSandbox(sandboxId), {
|
|
4420
|
+
await callNative(() => this.native.resumeSandbox(sandboxId), {
|
|
4421
|
+
sandboxId,
|
|
4422
|
+
notFoundKind: "sandbox"
|
|
4423
|
+
});
|
|
4400
4424
|
if (options?.wait === false) return;
|
|
4401
4425
|
const timeout = options?.timeout ?? 300;
|
|
4402
4426
|
const pollInterval = options?.pollInterval ?? 1;
|
|
@@ -4405,11 +4429,15 @@ var init_client = __esm({
|
|
|
4405
4429
|
const info = await this.get(sandboxId);
|
|
4406
4430
|
if (info.status === "running" /* RUNNING */) return;
|
|
4407
4431
|
if (info.status === "terminated" /* TERMINATED */) {
|
|
4408
|
-
throw new SandboxError(
|
|
4432
|
+
throw new SandboxError(
|
|
4433
|
+
`Sandbox ${sandboxId} terminated while waiting for resume`
|
|
4434
|
+
);
|
|
4409
4435
|
}
|
|
4410
4436
|
await sleep2(pollInterval * 1e3);
|
|
4411
4437
|
}
|
|
4412
|
-
throw new SandboxError(
|
|
4438
|
+
throw new SandboxError(
|
|
4439
|
+
`Sandbox ${sandboxId} did not resume within ${timeout}s`
|
|
4440
|
+
);
|
|
4413
4441
|
}
|
|
4414
4442
|
/**
|
|
4415
4443
|
* Attach a registered file system to a running sandbox at `mountPath`.
|
|
@@ -4489,7 +4517,9 @@ var init_client = __esm({
|
|
|
4489
4517
|
}
|
|
4490
4518
|
/** List all snapshots in the namespace. */
|
|
4491
4519
|
async listSnapshots() {
|
|
4492
|
-
const { traceId, json } = await callNative(
|
|
4520
|
+
const { traceId, json } = await callNative(
|
|
4521
|
+
() => this.native.listSnapshots()
|
|
4522
|
+
);
|
|
4493
4523
|
const parsed = JSON.parse(json);
|
|
4494
4524
|
const snapshots = (parsed.snapshots ?? []).map(
|
|
4495
4525
|
(s) => fromSnakeKeys(s, "snapshotId")
|
|
@@ -4517,7 +4547,8 @@ var init_client = __esm({
|
|
|
4517
4547
|
const deadline = Date.now() + timeout * 1e3;
|
|
4518
4548
|
while (Date.now() < deadline) {
|
|
4519
4549
|
const info = await this.getSnapshot(result.snapshotId);
|
|
4520
|
-
if (snapshotStatusSatisfiesWaitCondition(info.status, waitUntil))
|
|
4550
|
+
if (snapshotStatusSatisfiesWaitCondition(info.status, waitUntil))
|
|
4551
|
+
return info;
|
|
4521
4552
|
if (info.status === "failed" /* FAILED */) {
|
|
4522
4553
|
throw new SandboxError(
|
|
4523
4554
|
`Snapshot ${result.snapshotId} failed: ${info.error}`
|
|
@@ -4542,8 +4573,11 @@ var init_client = __esm({
|
|
|
4542
4573
|
timeout_secs: options.timeoutSecs ?? 0
|
|
4543
4574
|
};
|
|
4544
4575
|
if (options.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4545
|
-
if (options.maxContainers != null)
|
|
4546
|
-
|
|
4576
|
+
if (options.maxContainers != null)
|
|
4577
|
+
body.max_containers = options.maxContainers;
|
|
4578
|
+
if (options.warmContainers != null)
|
|
4579
|
+
body.warm_containers = options.warmContainers;
|
|
4580
|
+
if (options.network != null) body.network = toSnakeKeys(options.network);
|
|
4547
4581
|
return this.plainJson(
|
|
4548
4582
|
() => this.native.createPool(JSON.stringify(body)),
|
|
4549
4583
|
"poolId"
|
|
@@ -4566,7 +4600,13 @@ var init_client = __esm({
|
|
|
4566
4600
|
);
|
|
4567
4601
|
return Object.assign(pools, { traceId });
|
|
4568
4602
|
}
|
|
4569
|
-
/**
|
|
4603
|
+
/**
|
|
4604
|
+
* Replace a pool configuration. Omit `network` to keep the pool's current
|
|
4605
|
+
* network policy, set it to replace the policy, or pass `null` to remove the
|
|
4606
|
+
* policy entirely. On a change the service recycles the pool's unclaimed
|
|
4607
|
+
* warm containers onto the new policy, while containers already claimed by
|
|
4608
|
+
* sandboxes keep the policy they booted with.
|
|
4609
|
+
*/
|
|
4570
4610
|
async updatePool(poolId, options) {
|
|
4571
4611
|
const body = {
|
|
4572
4612
|
image: options.image,
|
|
@@ -4578,8 +4618,13 @@ var init_client = __esm({
|
|
|
4578
4618
|
timeout_secs: options.timeoutSecs ?? 0
|
|
4579
4619
|
};
|
|
4580
4620
|
if (options.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4581
|
-
if (options.maxContainers != null)
|
|
4582
|
-
|
|
4621
|
+
if (options.maxContainers != null)
|
|
4622
|
+
body.max_containers = options.maxContainers;
|
|
4623
|
+
if (options.warmContainers != null)
|
|
4624
|
+
body.warm_containers = options.warmContainers;
|
|
4625
|
+
if (options.network !== void 0) {
|
|
4626
|
+
body.network = options.network === null ? null : toSnakeKeys(options.network);
|
|
4627
|
+
}
|
|
4583
4628
|
return this.plainJson(
|
|
4584
4629
|
() => this.native.updatePool(poolId, JSON.stringify(body)),
|
|
4585
4630
|
"poolId",
|
|
@@ -4588,7 +4633,10 @@ var init_client = __esm({
|
|
|
4588
4633
|
}
|
|
4589
4634
|
/** Delete a sandbox pool. Fails if the pool has active containers. */
|
|
4590
4635
|
async deletePool(poolId) {
|
|
4591
|
-
await callNative(() => this.native.deletePool(poolId), {
|
|
4636
|
+
await callNative(() => this.native.deletePool(poolId), {
|
|
4637
|
+
poolId,
|
|
4638
|
+
notFoundKind: "pool"
|
|
4639
|
+
});
|
|
4592
4640
|
}
|
|
4593
4641
|
// --- Connect ---
|
|
4594
4642
|
/** Return a `Sandbox` handle for an existing running sandbox without verifying it exists. */
|
|
@@ -4625,11 +4673,16 @@ var init_client = __esm({
|
|
|
4625
4673
|
});
|
|
4626
4674
|
const createStart = nowMs();
|
|
4627
4675
|
const result = options?.poolId != null ? await requestClient.claim(options.poolId) : await requestClient.create(options);
|
|
4628
|
-
logSdkTiming(
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4676
|
+
logSdkTiming(
|
|
4677
|
+
"sandbox.create",
|
|
4678
|
+
options?.poolId != null ? "claim_response" : "create_response",
|
|
4679
|
+
createStart,
|
|
4680
|
+
{
|
|
4681
|
+
sandbox_id: result.sandboxId,
|
|
4682
|
+
status: result.status,
|
|
4683
|
+
server_trace_id: result.traceId
|
|
4684
|
+
}
|
|
4685
|
+
);
|
|
4633
4686
|
const requestedName = options?.poolId != null ? null : options?.name ?? null;
|
|
4634
4687
|
const finishConnect = (sandboxId, routingHint, name, ingressEndpoint, sandboxUrl) => {
|
|
4635
4688
|
const explicitProxyUrl = options?.proxyUrl ?? explicitProxyUrlOverride() ?? void 0;
|
|
@@ -5093,6 +5146,21 @@ var init_sse = __esm({
|
|
|
5093
5146
|
});
|
|
5094
5147
|
|
|
5095
5148
|
// src/cloud-client.ts
|
|
5149
|
+
function applicationAllowsUnauthenticatedRequests(manifest) {
|
|
5150
|
+
return Array.isArray(manifest.allow) && manifest.allow.includes(UNAUTHENTICATED_REQUESTS);
|
|
5151
|
+
}
|
|
5152
|
+
function publicEndpointIdFromManifest(manifest) {
|
|
5153
|
+
for (const key of ["public_endpoint_id", "publicEndpointId"]) {
|
|
5154
|
+
const value = manifest[key];
|
|
5155
|
+
if (typeof value === "string" && value.length > 0) {
|
|
5156
|
+
return value;
|
|
5157
|
+
}
|
|
5158
|
+
}
|
|
5159
|
+
return void 0;
|
|
5160
|
+
}
|
|
5161
|
+
function generatePublicEndpointId() {
|
|
5162
|
+
return `endpoint_${(0, import_nanoid.nanoid)()}`;
|
|
5163
|
+
}
|
|
5096
5164
|
function createApplicationBuildForm(request, imageContexts) {
|
|
5097
5165
|
const contextsByPartName = /* @__PURE__ */ new Map();
|
|
5098
5166
|
for (const context of imageContexts) {
|
|
@@ -5162,10 +5230,11 @@ async function parseJsonResponse(response) {
|
|
|
5162
5230
|
}
|
|
5163
5231
|
return JSON.parse(text);
|
|
5164
5232
|
}
|
|
5165
|
-
var CloudClient;
|
|
5233
|
+
var import_nanoid, CloudClient, UNAUTHENTICATED_REQUESTS;
|
|
5166
5234
|
var init_cloud_client = __esm({
|
|
5167
5235
|
"src/cloud-client.ts"() {
|
|
5168
5236
|
"use strict";
|
|
5237
|
+
import_nanoid = require("nanoid");
|
|
5169
5238
|
init_defaults();
|
|
5170
5239
|
init_http();
|
|
5171
5240
|
init_models();
|
|
@@ -5195,6 +5264,19 @@ var init_cloud_client = __esm({
|
|
|
5195
5264
|
this.http.close();
|
|
5196
5265
|
}
|
|
5197
5266
|
async upsertApplication(manifest, codeZip, upgradeRunningRequests = false) {
|
|
5267
|
+
const applicationManifest = { ...manifest };
|
|
5268
|
+
let publicEndpointId = publicEndpointIdFromManifest(applicationManifest);
|
|
5269
|
+
if (applicationAllowsUnauthenticatedRequests(applicationManifest) && publicEndpointId === void 0) {
|
|
5270
|
+
const applicationName = applicationManifest.name;
|
|
5271
|
+
if (typeof applicationName === "string" && applicationName.length > 0) {
|
|
5272
|
+
publicEndpointId = await this.existingApplicationPublicEndpointId(applicationName);
|
|
5273
|
+
}
|
|
5274
|
+
publicEndpointId ??= generatePublicEndpointId();
|
|
5275
|
+
}
|
|
5276
|
+
if (publicEndpointId !== void 0) {
|
|
5277
|
+
applicationManifest.public_endpoint_id = publicEndpointId;
|
|
5278
|
+
delete applicationManifest.publicEndpointId;
|
|
5279
|
+
}
|
|
5198
5280
|
const form = new FormData();
|
|
5199
5281
|
form.append(
|
|
5200
5282
|
"code",
|
|
@@ -5202,7 +5284,7 @@ var init_cloud_client = __esm({
|
|
|
5202
5284
|
"code.zip"
|
|
5203
5285
|
);
|
|
5204
5286
|
form.append("code_content_type", "application/zip");
|
|
5205
|
-
form.append("application", JSON.stringify(
|
|
5287
|
+
form.append("application", JSON.stringify(applicationManifest));
|
|
5206
5288
|
form.append(
|
|
5207
5289
|
"upgrade_requests_to_latest_code",
|
|
5208
5290
|
String(upgradeRunningRequests)
|
|
@@ -5515,6 +5597,18 @@ var init_cloud_client = __esm({
|
|
|
5515
5597
|
namespacePath(subpath) {
|
|
5516
5598
|
return `/v1/namespaces/${encodeURIComponent(this.namespace)}/${subpath.replace(/^\/+/, "")}`;
|
|
5517
5599
|
}
|
|
5600
|
+
async existingApplicationPublicEndpointId(applicationName) {
|
|
5601
|
+
const response = await this.http.requestResponse(
|
|
5602
|
+
"GET",
|
|
5603
|
+
this.namespacePath(`applications/${encodeURIComponent(applicationName)}`),
|
|
5604
|
+
{ allowedErrorStatusCodes: /* @__PURE__ */ new Set([404]) }
|
|
5605
|
+
);
|
|
5606
|
+
if (response.status === 404) {
|
|
5607
|
+
return void 0;
|
|
5608
|
+
}
|
|
5609
|
+
const application = await parseJsonResponse(response);
|
|
5610
|
+
return publicEndpointIdFromManifest(application);
|
|
5611
|
+
}
|
|
5518
5612
|
resolveScope(organizationId, projectId) {
|
|
5519
5613
|
const resolvedOrganizationId = organizationId ?? this.organizationId;
|
|
5520
5614
|
const resolvedProjectId = projectId ?? this.projectId;
|
|
@@ -5529,6 +5623,7 @@ var init_cloud_client = __esm({
|
|
|
5529
5623
|
};
|
|
5530
5624
|
}
|
|
5531
5625
|
};
|
|
5626
|
+
UNAUTHENTICATED_REQUESTS = "unauthenticated_requests";
|
|
5532
5627
|
}
|
|
5533
5628
|
});
|
|
5534
5629
|
|