tensorlake 0.5.9 → 0.5.10

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.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
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.9";
38
+ SDK_VERSION = "0.5.10";
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";
@@ -426,11 +426,12 @@ var init_models = __esm({
426
426
  SandboxStatus3["TERMINATED"] = "terminated";
427
427
  return SandboxStatus3;
428
428
  })(SandboxStatus || {});
429
- SnapshotStatus = /* @__PURE__ */ ((SnapshotStatus3) => {
430
- SnapshotStatus3["IN_PROGRESS"] = "in_progress";
431
- SnapshotStatus3["COMPLETED"] = "completed";
432
- SnapshotStatus3["FAILED"] = "failed";
433
- return SnapshotStatus3;
429
+ SnapshotStatus = /* @__PURE__ */ ((SnapshotStatus2) => {
430
+ SnapshotStatus2["IN_PROGRESS"] = "in_progress";
431
+ SnapshotStatus2["LOCAL_READY"] = "local_ready";
432
+ SnapshotStatus2["COMPLETED"] = "completed";
433
+ SnapshotStatus2["FAILED"] = "failed";
434
+ return SnapshotStatus2;
434
435
  })(SnapshotStatus || {});
435
436
  ProcessStatus = /* @__PURE__ */ ((ProcessStatus2) => {
436
437
  ProcessStatus2["RUNNING"] = "running";
@@ -3395,11 +3396,10 @@ var init_sandbox = __esm({
3395
3396
  await client.resume(this.lifecycleIdentifier, options);
3396
3397
  }
3397
3398
  /**
3398
- * Create a snapshot of this sandbox's filesystem and wait for it to
3399
- * be committed.
3399
+ * Create a checkpoint of this sandbox and wait for it to be locally ready.
3400
3400
  *
3401
- * By default blocks until the snapshot artifact is ready and returns
3402
- * the completed `SnapshotInfo`. Pass `{ wait: false }` to fire-and-return
3401
+ * By default blocks until the checkpoint is resumable and returns
3402
+ * `SnapshotInfo`. Pass `{ wait: false }` to fire-and-return
3403
3403
  * (returns `undefined`).
3404
3404
  */
3405
3405
  async checkpoint(options) {
@@ -3411,7 +3411,8 @@ var init_sandbox = __esm({
3411
3411
  return client.snapshotAndWait(this.lifecycleIdentifier, {
3412
3412
  timeout: options?.timeout,
3413
3413
  pollInterval: options?.pollInterval,
3414
- snapshotType: options?.checkpointType
3414
+ snapshotType: options?.checkpointType,
3415
+ waitUntil: options?.waitUntil
3415
3416
  });
3416
3417
  }
3417
3418
  /**
@@ -3806,6 +3807,12 @@ __export(client_exports, {
3806
3807
  function sleep2(ms) {
3807
3808
  return new Promise((resolve) => setTimeout(resolve, ms));
3808
3809
  }
3810
+ function snapshotStatusSatisfiesWaitCondition(status, waitUntil) {
3811
+ if (waitUntil === "local_ready") {
3812
+ return status === "local_ready" /* LOCAL_READY */ || status === "completed" /* COMPLETED */;
3813
+ }
3814
+ return status === "completed" /* COMPLETED */;
3815
+ }
3809
3816
  function formatStartupFailureMessage(sandboxId, status, options) {
3810
3817
  const prefix = status === "terminated" /* TERMINATED */ ? `Sandbox ${sandboxId} terminated during startup` : `Sandbox ${sandboxId} became ${status} during startup`;
3811
3818
  const detail = formatErrorDetails(options.errorDetails);
@@ -4106,7 +4113,8 @@ var init_client = __esm({
4106
4113
  *
4107
4114
  * This call **returns immediately** with a `snapshotId` and `in_progress`
4108
4115
  * status — the snapshot is created asynchronously. Poll `getSnapshot()` until
4109
- * `completed` or `failed`, or use `snapshotAndWait()` to block automatically.
4116
+ * `local_ready`, `completed`, or `failed`, or use `snapshotAndWait()` to
4117
+ * block automatically.
4110
4118
  *
4111
4119
  * @param options.snapshotType - `"filesystem"` for cold-boot snapshots (e.g. image builds).
4112
4120
  * Omit to use the server default (`filesystem`).
@@ -4147,9 +4155,11 @@ var init_client = __esm({
4147
4155
  );
4148
4156
  }
4149
4157
  /**
4150
- * Create a snapshot and block until it is committed.
4158
+ * Create a snapshot and block until it is locally ready.
4151
4159
  *
4152
- * Combines `snapshot()` with polling `getSnapshot()` until `completed`.
4160
+ * Combines `snapshot()` with polling `getSnapshot()` until `local_ready`
4161
+ * or `completed`. Pass `{ waitUntil: "completed" }` when durable
4162
+ * `snapshotUri` metadata is required.
4153
4163
  * Prefer `sandbox.checkpoint()` on a `Sandbox` handle for the same behavior
4154
4164
  * without managing the client separately.
4155
4165
  *
@@ -4162,13 +4172,14 @@ var init_client = __esm({
4162
4172
  async snapshotAndWait(sandboxId, options) {
4163
4173
  const timeout = options?.timeout ?? 300;
4164
4174
  const pollInterval = options?.pollInterval ?? 1;
4175
+ const waitUntil = options?.waitUntil ?? "local_ready";
4165
4176
  const result = await this.snapshot(sandboxId, {
4166
4177
  snapshotType: options?.snapshotType
4167
4178
  });
4168
4179
  const deadline = Date.now() + timeout * 1e3;
4169
4180
  while (Date.now() < deadline) {
4170
4181
  const info = await this.getSnapshot(result.snapshotId);
4171
- if (info.status === "completed" /* COMPLETED */) return info;
4182
+ if (snapshotStatusSatisfiesWaitCondition(info.status, waitUntil)) return info;
4172
4183
  if (info.status === "failed" /* FAILED */) {
4173
4184
  throw new SandboxError(
4174
4185
  `Snapshot ${result.snapshotId} failed: ${info.error}`
@@ -4177,7 +4188,7 @@ var init_client = __esm({
4177
4188
  await sleep2(pollInterval * 1e3);
4178
4189
  }
4179
4190
  throw new SandboxError(
4180
- `Snapshot ${result.snapshotId} did not complete within ${timeout}s`
4191
+ `Snapshot ${result.snapshotId} did not reach ${waitUntil} within ${timeout}s`
4181
4192
  );
4182
4193
  }
4183
4194
  // --- Pools ---
@@ -4462,6 +4473,7 @@ __export(sandbox_image_exports, {
4462
4473
  loadDockerfilePlan: () => loadDockerfilePlan,
4463
4474
  loadImagePlan: () => loadImagePlan,
4464
4475
  logicalDockerfileLines: () => logicalDockerfileLines,
4476
+ registerImage: () => registerImage,
4465
4477
  runCreateSandboxImageCli: () => runCreateSandboxImageCli
4466
4478
  });
4467
4479
  function defaultRegisteredName(dockerfilePath) {
@@ -5084,23 +5096,26 @@ async function executeDockerfilePlan(sandbox, plan, emit, sleep3) {
5084
5096
  );
5085
5097
  }
5086
5098
  }
5087
- async function registerImage(context, name, dockerfile, snapshotId, snapshotSandboxId, snapshotUri, snapshotSizeBytes, rootfsDiskBytes, isPublic) {
5088
- if (!context.organizationId || !context.projectId) {
5089
- throw new Error(
5090
- "Organization ID and Project ID are required. Run 'tl login' and 'tl init'."
5091
- );
5092
- }
5099
+ async function registerImage(context, name, dockerfile, snapshotId, snapshotSandboxId, snapshotUri, snapshotSizeBytes, rootfsDiskBytes, isPublic, snapshotFormatVersion) {
5093
5100
  const bearerToken = context.apiKey ?? context.personalAccessToken;
5094
5101
  if (!bearerToken) {
5095
5102
  throw new Error("Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT.");
5096
5103
  }
5097
5104
  const baseUrl = context.apiUrl.replace(/\/+$/, "");
5098
- const url = `${baseUrl}/platform/v1/organizations/${encodeURIComponent(context.organizationId)}/projects/${encodeURIComponent(context.projectId)}/sandbox-templates`;
5099
5105
  const headers = {
5100
5106
  Authorization: `Bearer ${bearerToken}`,
5101
5107
  "Content-Type": "application/json"
5102
5108
  };
5103
- if (context.personalAccessToken && !context.apiKey) {
5109
+ let url;
5110
+ if (context.apiKey) {
5111
+ url = `${baseUrl}/platform/v1/sandbox-templates`;
5112
+ } else {
5113
+ if (!context.organizationId || !context.projectId) {
5114
+ throw new Error(
5115
+ "Personal Access Token authentication requires TENSORLAKE_ORGANIZATION_ID and TENSORLAKE_PROJECT_ID to be set (e.g. via 'tl login && tl init'). To skip this requirement, authenticate with TENSORLAKE_API_KEY instead \u2014 API keys are bound to a single project at creation."
5116
+ );
5117
+ }
5118
+ url = `${baseUrl}/platform/v1/organizations/${encodeURIComponent(context.organizationId)}/projects/${encodeURIComponent(context.projectId)}/sandbox-templates`;
5104
5119
  headers["X-Forwarded-Organization-Id"] = context.organizationId;
5105
5120
  headers["X-Forwarded-Project-Id"] = context.projectId;
5106
5121
  }
@@ -5113,6 +5128,7 @@ async function registerImage(context, name, dockerfile, snapshotId, snapshotSand
5113
5128
  snapshotId,
5114
5129
  snapshotSandboxId,
5115
5130
  snapshotUri,
5131
+ ...snapshotFormatVersion ? { snapshotFormatVersion } : {},
5116
5132
  snapshotSizeBytes,
5117
5133
  rootfsDiskBytes,
5118
5134
  public: isPublic
@@ -5155,7 +5171,8 @@ async function createSandboxImage(source, options = {}, deps = {}) {
5155
5171
  await executeDockerfilePlan(sandbox, plan, emit, sleep3);
5156
5172
  emit({ type: "status", message: "Creating snapshot..." });
5157
5173
  const snapshot = await client.snapshotAndWait(sandbox.sandboxId, {
5158
- snapshotType: "filesystem"
5174
+ snapshotType: "filesystem",
5175
+ waitUntil: "completed"
5159
5176
  });
5160
5177
  emit({
5161
5178
  type: "snapshot_created",
@@ -5189,7 +5206,8 @@ async function createSandboxImage(source, options = {}, deps = {}) {
5189
5206
  snapshot.snapshotUri,
5190
5207
  snapshot.sizeBytes,
5191
5208
  snapshot.rootfsDiskBytes,
5192
- options.isPublic ?? false
5209
+ options.isPublic ?? false,
5210
+ snapshot.snapshotFormatVersion
5193
5211
  );
5194
5212
  emit({
5195
5213
  type: "image_registered",