@tensorlakeai/tensorlake 0.5.153 → 0.5.156

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.
Files changed (35) hide show
  1. package/dist/applications/index.cjs +260 -71
  2. package/dist/applications/index.cjs.map +1 -1
  3. package/dist/applications/index.d.cts +3 -3
  4. package/dist/applications/index.d.ts +3 -3
  5. package/dist/applications/index.js +260 -71
  6. package/dist/applications/index.js.map +1 -1
  7. package/dist/function-agent/main.cjs +1 -1
  8. package/dist/function-agent/main.js +1 -1
  9. package/dist/function-executor/main.cjs +2 -2
  10. package/dist/function-executor/main.js +2 -2
  11. package/dist/index.cjs +344 -106
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +95 -38
  14. package/dist/index.d.ts +95 -38
  15. package/dist/index.js +339 -106
  16. package/dist/index.js.map +1 -1
  17. package/dist/{remote-B3vn4tt1.d.cts → remote-CEs4GFGP.d.cts} +1 -1
  18. package/dist/{remote-DqBUuciu.d.ts → remote-DYBXCTNC.d.ts} +1 -1
  19. package/dist/{sandbox-image-BMiFlzAs.d.cts → sandbox-image-C2GTVnx3.d.cts} +99 -52
  20. package/dist/{sandbox-image-BMiFlzAs.d.ts → sandbox-image-C2GTVnx3.d.ts} +99 -52
  21. package/dist/sandbox-image.cjs +248 -61
  22. package/dist/sandbox-image.cjs.map +1 -1
  23. package/dist/sandbox-image.d.cts +1 -1
  24. package/dist/sandbox-image.d.ts +1 -1
  25. package/dist/sandbox-image.js +248 -61
  26. package/dist/sandbox-image.js.map +1 -1
  27. package/package.json +7 -7
  28. package/runtime/function-executor/manifest.json +5 -5
  29. package/runtime/function-executor/package/dist/function-executor/main.js +2 -2
  30. package/runtime/function-executor/package/npm-shrinkwrap.json +2 -2
  31. package/runtime/function-executor/package/package.json +1 -1
  32. package/runtime/typescript-function-runner/manifest.json +5 -5
  33. package/runtime/typescript-function-runner/package/dist/function-agent/main.js +1 -1
  34. package/runtime/typescript-function-runner/package/npm-shrinkwrap.json +26 -26
  35. package/runtime/typescript-function-runner/package/package.json +7 -7
@@ -189,7 +189,24 @@ var init_native_binding = __esm({
189
189
  }
190
190
  });
191
191
 
192
+ // src/enum.ts
193
+ function enumValue(values, value) {
194
+ return typeof value === "string" && Object.values(values).includes(value) ? value : values.UNKNOWN;
195
+ }
196
+ function withRaw(value, raw) {
197
+ return Object.defineProperty(value, "raw", { value: raw, enumerable: false, configurable: true });
198
+ }
199
+ var init_enum = __esm({
200
+ "src/enum.ts"() {
201
+ "use strict";
202
+ init_cjs_shims();
203
+ }
204
+ });
205
+
192
206
  // src/image-builds.ts
207
+ function isConfirmedCancellation(outcome) {
208
+ return outcome === "cancelled" /* CANCELLED */ || outcome === "already_cancelled" /* ALREADY_CANCELLED */ || outcome === "already_failed" /* ALREADY_FAILED */;
209
+ }
193
210
  function camelize(key) {
194
211
  return key.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
195
212
  }
@@ -207,48 +224,73 @@ function toImageBuildError(error) {
207
224
  if (key === "category") continue;
208
225
  details[camelize(key)] = value;
209
226
  }
227
+ details.code = enumValue(ImageBuildErrorCode, details.code || "internal" /* INTERNAL */);
228
+ if ("activeKind" in details) details.activeKind = details.activeKind ? enumValue(ImageBuildKind, details.activeKind) : null;
229
+ if ("activeStatus" in details) details.activeStatus = details.activeStatus ? enumValue(ImageBuildStatus, details.activeStatus) : null;
230
+ if ("outcome" in details) details.outcome = details.outcome ? enumValue(ImageBuildCancellationOutcome, details.outcome) : null;
231
+ if ("info" in details) details.info = buildInfoOrNull(details.info);
210
232
  const typed = details;
211
- switch (typed.code) {
212
- case "not_found":
213
- return new ImageBuildNotFoundError(typed);
214
- case "image_build_in_progress":
215
- return new ImageBuildInProgressError(typed);
216
- case "failed":
217
- return new ImageBuildFailedError(typed);
218
- case "cancelled":
219
- return new ImageBuildCancelledError(typed);
220
- case "timeout":
221
- return new ImageBuildTimeoutError(typed);
222
- case "interrupted":
223
- return new ImageBuildInterruptedError(typed);
224
- default:
225
- return new ImageBuildError(typed);
226
- }
233
+ const errors = {
234
+ not_found: ImageBuildNotFoundError,
235
+ image_build_in_progress: ImageBuildInProgressError,
236
+ failed: ImageBuildFailedError,
237
+ cancelled: ImageBuildCancelledError,
238
+ timeout: ImageBuildTimeoutError,
239
+ interrupted: ImageBuildInterruptedError
240
+ };
241
+ const ErrorClass = errors[typed.code] ?? ImageBuildError;
242
+ return withRaw(new ErrorClass(typed), payload);
227
243
  }
228
244
  function camelizeRecord(value) {
229
245
  const out = {};
230
246
  for (const [key, inner] of Object.entries(value)) out[camelize(key)] = inner;
231
247
  return out;
232
248
  }
233
- function parseBuildInfo(raw) {
249
+ function buildInfoOrNull(value) {
250
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
251
+ try {
252
+ return parseBuildInfo(value);
253
+ } catch (error) {
254
+ if (error instanceof ImageBuildError) return null;
255
+ throw error;
256
+ }
257
+ }
258
+ function decodeResponse(value) {
259
+ try {
260
+ const raw = typeof value === "string" ? JSON.parse(value) : value;
261
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) throw new TypeError("expected a response object");
262
+ return raw;
263
+ } catch (error) {
264
+ throw withRaw(new ImageBuildError({ code: "service" /* SERVICE */, message: `Invalid image-build response: ${String(error)}` }), { response: value });
265
+ }
266
+ }
267
+ function parseBuildInfo(value) {
268
+ const raw = decodeResponse(value);
269
+ if (raw.status == null) {
270
+ throw withRaw(new ImageBuildError({ code: "service" /* SERVICE */, message: "Invalid image-build response: missing status" }), { response: value });
271
+ }
272
+ const attempt = raw.attempt_no ?? 0;
273
+ const attemptNo = Number(attempt);
274
+ if (typeof attempt !== "number" && typeof attempt !== "string" || typeof attempt === "string" && attempt.trim() === "" || !Number.isSafeInteger(attemptNo)) {
275
+ throw withRaw(new ImageBuildError({ code: "service" /* SERVICE */, message: "Invalid image-build attempt_no" }), { response: value });
276
+ }
234
277
  const camel = camelizeRecord(raw);
235
278
  const result = raw.result && typeof raw.result === "object" ? camelizeRecord(raw.result) : null;
236
- return {
279
+ return withRaw({
237
280
  buildId: String(raw.build_id ?? ""),
238
281
  clientRequestId: camel.clientRequestId ?? null,
239
- kind: String(raw.kind ?? ""),
282
+ kind: raw.kind ? enumValue(ImageBuildKind, raw.kind) : null,
240
283
  name: raw.name ?? null,
241
- status: String(raw.status ?? ""),
242
- phase: raw.phase ?? null,
243
- attemptNo: Number(raw.attempt_no ?? 0),
284
+ status: enumValue(ImageBuildStatus, raw.status),
285
+ phase: raw.phase ? enumValue(ImageBuildPhase, raw.phase) : null,
286
+ attemptNo,
244
287
  builderSandboxId: camel.builderSandboxId ?? null,
245
288
  error: raw.error ?? null,
246
289
  result,
247
290
  operationDeadlineMs: camel.operationDeadlineMs ?? null,
248
291
  createdAtMs: camel.createdAtMs ?? null,
249
- updatedAtMs: camel.updatedAtMs ?? null,
250
- raw
251
- };
292
+ updatedAtMs: camel.updatedAtMs ?? null
293
+ }, raw);
252
294
  }
253
295
  async function __runWithInterrupt(signal, run) {
254
296
  const binding = __imageBuildInternals.loadNativeBinding();
@@ -272,16 +314,68 @@ async function __runWithInterrupt(signal, run) {
272
314
  binding.releaseImageBuildInterrupt(interruptId);
273
315
  }
274
316
  }
275
- var import_node_path2, import_node_os, import_node_fs, ImageBuildError, ImageBuildNotFoundError, ImageBuildInProgressError, ImageBuildFailedError, ImageBuildCancelledError, ImageBuildTimeoutError, ImageBuildInterruptedError;
317
+ var import_node_path2, import_node_os, import_node_fs, ImageBuildStatus, ImageBuildPhase, ImageBuildKind, ImageBuildCancellationOutcome, ImageBuildErrorCode, ImageBuildError, ImageBuildNotFoundError, ImageBuildInProgressError, ImageBuildFailedError, ImageBuildCancelledError, ImageBuildTimeoutError, ImageBuildInterruptedError;
276
318
  var init_image_builds = __esm({
277
319
  "src/image-builds.ts"() {
278
320
  "use strict";
279
321
  init_cjs_shims();
280
322
  import_node_path2 = __toESM(require("path"), 1);
323
+ init_enum();
281
324
  import_node_os = __toESM(require("os"), 1);
282
325
  import_node_fs = require("fs");
283
326
  init_image();
284
327
  init_sandbox_image();
328
+ ImageBuildStatus = /* @__PURE__ */ ((ImageBuildStatus2) => {
329
+ ImageBuildStatus2["PENDING"] = "pending";
330
+ ImageBuildStatus2["RUNNING"] = "running";
331
+ ImageBuildStatus2["SUCCEEDED"] = "succeeded";
332
+ ImageBuildStatus2["FAILED"] = "failed";
333
+ ImageBuildStatus2["CANCELLED"] = "cancelled";
334
+ ImageBuildStatus2["UNKNOWN"] = "unknown";
335
+ return ImageBuildStatus2;
336
+ })(ImageBuildStatus || {});
337
+ ImageBuildPhase = /* @__PURE__ */ ((ImageBuildPhase2) => {
338
+ ImageBuildPhase2["AWAITING_CONTEXT"] = "awaiting_context";
339
+ ImageBuildPhase2["STARTING_BUILDER"] = "starting_builder";
340
+ ImageBuildPhase2["EXECUTING"] = "executing";
341
+ ImageBuildPhase2["SNAPSHOTTING"] = "snapshotting";
342
+ ImageBuildPhase2["PUBLISHING"] = "publishing";
343
+ ImageBuildPhase2["FINISHED"] = "finished";
344
+ ImageBuildPhase2["UNKNOWN"] = "unknown";
345
+ return ImageBuildPhase2;
346
+ })(ImageBuildPhase || {});
347
+ ImageBuildKind = /* @__PURE__ */ ((ImageBuildKind2) => {
348
+ ImageBuildKind2["DOCKERFILE"] = "dockerfile";
349
+ ImageBuildKind2["IMPORT"] = "import";
350
+ ImageBuildKind2["DIRECT"] = "direct";
351
+ ImageBuildKind2["UNKNOWN"] = "unknown";
352
+ return ImageBuildKind2;
353
+ })(ImageBuildKind || {});
354
+ ImageBuildCancellationOutcome = /* @__PURE__ */ ((ImageBuildCancellationOutcome2) => {
355
+ ImageBuildCancellationOutcome2["CANCELLED"] = "cancelled";
356
+ ImageBuildCancellationOutcome2["ALREADY_CANCELLED"] = "already_cancelled";
357
+ ImageBuildCancellationOutcome2["ALREADY_COMPLETED"] = "already_completed";
358
+ ImageBuildCancellationOutcome2["ALREADY_FAILED"] = "already_failed";
359
+ ImageBuildCancellationOutcome2["NOT_ADMITTED"] = "not_admitted";
360
+ ImageBuildCancellationOutcome2["UNCONFIRMED"] = "unconfirmed";
361
+ ImageBuildCancellationOutcome2["UNKNOWN"] = "unknown";
362
+ return ImageBuildCancellationOutcome2;
363
+ })(ImageBuildCancellationOutcome || {});
364
+ ImageBuildErrorCode = /* @__PURE__ */ ((ImageBuildErrorCode2) => {
365
+ ImageBuildErrorCode2["USAGE"] = "usage";
366
+ ImageBuildErrorCode2["AUTH"] = "auth";
367
+ ImageBuildErrorCode2["NOT_FOUND"] = "not_found";
368
+ ImageBuildErrorCode2["IMAGE_BUILD_IN_PROGRESS"] = "image_build_in_progress";
369
+ ImageBuildErrorCode2["CLIENT_REQUEST_ID_MISMATCH"] = "client_request_id_mismatch";
370
+ ImageBuildErrorCode2["FAILED"] = "failed";
371
+ ImageBuildErrorCode2["CANCELLED"] = "cancelled";
372
+ ImageBuildErrorCode2["TIMEOUT"] = "timeout";
373
+ ImageBuildErrorCode2["INTERRUPTED"] = "interrupted";
374
+ ImageBuildErrorCode2["SERVICE"] = "service";
375
+ ImageBuildErrorCode2["INTERNAL"] = "internal";
376
+ ImageBuildErrorCode2["UNKNOWN"] = "unknown";
377
+ return ImageBuildErrorCode2;
378
+ })(ImageBuildErrorCode || {});
285
379
  ImageBuildError = class extends Error {
286
380
  code;
287
381
  buildId;
@@ -291,7 +385,11 @@ var init_image_builds = __esm({
291
385
  super(details.message);
292
386
  this.name = "ImageBuildError";
293
387
  this.code = details.code;
294
- this.details = details;
388
+ this.details = { ...details };
389
+ withRaw(this, {});
390
+ if ("confirmed" in details) {
391
+ this.details.confirmed = details.confirmed === true && isConfirmedCancellation(details.outcome);
392
+ }
295
393
  if (details.buildId) this.buildId = details.buildId;
296
394
  if (details.clientRequestId) this.clientRequestId = details.clientRequestId;
297
395
  }
@@ -323,7 +421,7 @@ var init_image_builds = __esm({
323
421
  super(details);
324
422
  this.name = "ImageBuildFailedError";
325
423
  this.error = details.error ?? "no error recorded";
326
- if (details.info) this.info = parseBuildInfo(details.info);
424
+ if (details.info) this.info = details.info;
327
425
  }
328
426
  };
329
427
  ImageBuildCancelledError = class extends ImageBuildError {
@@ -331,7 +429,7 @@ var init_image_builds = __esm({
331
429
  constructor(details) {
332
430
  super(details);
333
431
  this.name = "ImageBuildCancelledError";
334
- if (details.info) this.info = parseBuildInfo(details.info);
432
+ if (details.info) this.info = details.info;
335
433
  }
336
434
  };
337
435
  ImageBuildTimeoutError = class extends ImageBuildError {
@@ -347,8 +445,8 @@ var init_image_builds = __esm({
347
445
  constructor(details) {
348
446
  super(details);
349
447
  this.name = "ImageBuildInterruptedError";
350
- this.outcome = details.outcome ?? "unconfirmed";
351
- this.confirmed = details.confirmed === true;
448
+ this.outcome = details.outcome ?? "unconfirmed" /* UNCONFIRMED */;
449
+ this.confirmed = this.details.confirmed === true;
352
450
  if (details.result) this.result = details.result;
353
451
  }
354
452
  };
@@ -407,16 +505,58 @@ function defaultRegisteredName(dockerfilePath) {
407
505
  const parsed = import_node_path3.default.parse(dockerfilePath);
408
506
  if (parsed.name.toLowerCase() === "dockerfile") {
409
507
  const parentName = import_node_path3.default.basename(import_node_path3.default.dirname(dockerfilePath)).trim();
410
- return parentName || "sandbox-image";
508
+ return parentName || DEFAULT_SANDBOX_IMAGE_NAME;
509
+ }
510
+ return parsed.name || DEFAULT_SANDBOX_IMAGE_NAME;
511
+ }
512
+ function registeredImageName(explicit, generated, cas, fallback = DEFAULT_SANDBOX_IMAGE_NAME) {
513
+ if (explicit || generated === void 0) {
514
+ const name = explicit ?? "";
515
+ return cas ? canonicalCasImageName(name) : name;
411
516
  }
412
- return parsed.name || "sandbox-image";
517
+ return cas ? casImageNameFrom(generated, fallback) : generated;
518
+ }
519
+ function canonicalCasImageName(name) {
520
+ return name.replace(/[A-Z]/g, (c) => c.toLowerCase());
521
+ }
522
+ function casImageNameFrom(raw, fallback) {
523
+ const lowered = canonicalCasImageName(raw);
524
+ if (isAddressableCasImageName(lowered)) {
525
+ return lowered;
526
+ }
527
+ let name = "";
528
+ for (const original of lowered) {
529
+ const ch = /^[a-z0-9._-]$/.test(original) ? original : "-";
530
+ const previous = name[name.length - 1];
531
+ if (CAS_NAME_SEPARATORS.includes(ch) && previous !== void 0 && CAS_NAME_SEPARATORS.includes(previous)) {
532
+ continue;
533
+ }
534
+ name += ch;
535
+ }
536
+ name = name.replace(/^[._-]+|[._-]+$/g, "").slice(0, MAX_CAS_IMAGE_NAME_LENGTH).replace(/[._-]+$/, "");
537
+ return isAddressableCasImageName(name) ? name : fallback;
538
+ }
539
+ function isAddressableCasImageName(name) {
540
+ if (name.length === 0 || name.length > MAX_CAS_IMAGE_NAME_LENGTH || RESERVED_IMAGE_NAME_PREFIXES.some((prefix) => name.startsWith(prefix)) || /^[0-9a-f]{64}$/.test(name)) {
541
+ return false;
542
+ }
543
+ const colon = name.indexOf(":");
544
+ const repository = colon === -1 ? name : name.slice(0, colon);
545
+ if (!repository.split("/").every((component) => /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(component))) {
546
+ return false;
547
+ }
548
+ if (colon === -1) {
549
+ return true;
550
+ }
551
+ const tag = name.slice(colon + 1);
552
+ return tag.length > 0 && tag.length <= 128 && /^[a-z0-9._-]+$/.test(tag) && !tag.startsWith(".") && !tag.startsWith("-");
413
553
  }
414
554
  function defaultRegisteredNameFromImage(imageReference) {
415
555
  const withoutDigest = imageReference.split("@", 1)[0] ?? imageReference;
416
556
  const lastSegment = withoutDigest.split("/").pop() ?? withoutDigest;
417
557
  const colonIndex = lastSegment.lastIndexOf(":");
418
558
  const name = colonIndex > 0 && colonIndex < lastSegment.length - 1 ? lastSegment.slice(0, colonIndex) : lastSegment;
419
- return name || "imported-image";
559
+ return name || DEFAULT_IMPORTED_IMAGE_NAME;
420
560
  }
421
561
  function noopEmit(_event) {
422
562
  }
@@ -519,7 +659,11 @@ async function createSandboxImage(source, options = {}, deps = {}) {
519
659
  if (!text.endsWith("\n")) text += "\n";
520
660
  dockerfileText = text;
521
661
  nativeContextDir = resolvedContext;
522
- effectiveName = options.registeredName ?? source.name;
662
+ effectiveName = registeredImageName(
663
+ options.registeredName ?? source.name,
664
+ void 0,
665
+ options.cas ?? true
666
+ );
523
667
  } else if (typeof source === "string") {
524
668
  const resolvedPath = import_node_path3.default.resolve(source);
525
669
  if (!(0, import_node_fs2.existsSync)(resolvedPath)) {
@@ -528,7 +672,11 @@ async function createSandboxImage(source, options = {}, deps = {}) {
528
672
  dockerfilePath = resolvedPath;
529
673
  dockerfileText = void 0;
530
674
  nativeContextDir = void 0;
531
- effectiveName = options.registeredName ?? defaultRegisteredName(resolvedPath);
675
+ effectiveName = registeredImageName(
676
+ options.registeredName,
677
+ defaultRegisteredName(resolvedPath),
678
+ options.cas ?? true
679
+ );
532
680
  } else {
533
681
  throw new TypeError(
534
682
  `source must be an Image or a Dockerfile path, got ${typeof source}`
@@ -552,12 +700,16 @@ async function createSandboxImage(source, options = {}, deps = {}) {
552
700
  deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
553
701
  );
554
702
  }
555
- if (options.signal !== void 0 && !options.cas) {
703
+ const cas = options.cas ?? true;
704
+ if (options.signal !== void 0 && !cas) {
556
705
  throw new Error(
557
- "signal is only supported for CAS image builds (cas: true); a legacy build has no Image Service build operation to cancel"
706
+ "signal is not supported for legacy image builds (cas: false): a legacy image build has no build operation to cancel"
558
707
  );
559
708
  }
560
- emit({ type: "status", message: `Building image '${effectiveName}'...` });
709
+ emit({
710
+ type: "status",
711
+ message: `Building ${cas ? "CAS" : "legacy"} image '${effectiveName}'...`
712
+ });
561
713
  const binding = loadNativeBinding();
562
714
  let emitError;
563
715
  const nativeOptions = {
@@ -579,7 +731,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
579
731
  dockerConfigJson: options.dockerConfigJson,
580
732
  dockerfileText,
581
733
  contextDir: nativeContextDir,
582
- cas: options.cas ?? false,
734
+ cas,
583
735
  buildArgs: options.buildArgs
584
736
  };
585
737
  const forward = (event) => {
@@ -589,7 +741,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
589
741
  emitError ??= error;
590
742
  }
591
743
  };
592
- const resultJson = options.cas ? await __runWithInterrupt(
744
+ const resultJson = cas ? await __runWithInterrupt(
593
745
  options.signal,
594
746
  (interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
595
747
  ) : await binding.buildSandboxImage(nativeOptions, forward);
@@ -620,7 +772,12 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
620
772
  }
621
773
  const reference = imageReference.trim();
622
774
  const context = buildContextFromEnv();
623
- const effectiveName = options.registeredName ?? defaultRegisteredNameFromImage(reference);
775
+ const effectiveName = registeredImageName(
776
+ options.registeredName,
777
+ defaultRegisteredNameFromImage(reference),
778
+ options.cas ?? true,
779
+ DEFAULT_IMPORTED_IMAGE_NAME
780
+ );
624
781
  if (effectiveName === DEFAULT_IMAGE_NAME) {
625
782
  console.warn(
626
783
  `Importing sandbox image with the default name "${DEFAULT_IMAGE_NAME}". Pass \`registeredName\` to avoid collisions with other default-named images in this project.`
@@ -638,14 +795,15 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
638
795
  deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
639
796
  );
640
797
  }
641
- if (options.signal !== void 0 && !options.cas) {
798
+ const cas = options.cas ?? true;
799
+ if (options.signal !== void 0 && !cas) {
642
800
  throw new Error(
643
- "signal is only supported for CAS image imports (cas: true); a legacy import has no Image Service build operation to cancel"
801
+ "signal is not supported for legacy image imports (cas: false): a legacy image import has no build operation to cancel"
644
802
  );
645
803
  }
646
804
  emit({
647
805
  type: "status",
648
- message: `Importing image '${reference}' as '${effectiveName}'...`
806
+ message: `Importing '${reference}' as ${cas ? "CAS" : "legacy"} image '${effectiveName}'...`
649
807
  });
650
808
  const binding = loadNativeBinding();
651
809
  let emitError;
@@ -666,7 +824,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
666
824
  userAgent: void 0,
667
825
  dockerCompat: options.dockerCompat ?? false,
668
826
  dockerConfigJson: options.dockerConfigJson,
669
- cas: options.cas ?? false
827
+ cas
670
828
  };
671
829
  const forward = (event) => {
672
830
  try {
@@ -675,7 +833,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
675
833
  emitError ??= error;
676
834
  }
677
835
  };
678
- const resultJson = options.cas ? await __runWithInterrupt(
836
+ const resultJson = cas ? await __runWithInterrupt(
679
837
  options.signal,
680
838
  (interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
681
839
  ) : await binding.importSandboxImage(nativeOptions, forward);
@@ -732,15 +890,29 @@ async function deleteSandboxImage(imageName) {
732
890
  if (typeof imageName !== "string" || imageName.length === 0) {
733
891
  throw new TypeError("imageName must be a non-empty string");
734
892
  }
735
- await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
893
+ warnIncompleteLegacyCleanup(
894
+ await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName)
895
+ );
736
896
  }
737
897
  async function deleteSandboxImageWithCredentials(credentials, imageName) {
738
898
  if (typeof imageName !== "string" || imageName.length === 0) {
739
899
  throw new TypeError("imageName must be a non-empty string");
740
900
  }
741
- await loadNativeBinding().deleteSandboxImage(
742
- catalogOptionsFromCredentials(credentials),
743
- imageName
901
+ warnIncompleteLegacyCleanup(
902
+ await loadNativeBinding().deleteSandboxImage(
903
+ catalogOptionsFromCredentials(credentials),
904
+ imageName
905
+ )
906
+ );
907
+ }
908
+ function warnIncompleteLegacyCleanup(failure) {
909
+ if (failure == null) {
910
+ return;
911
+ }
912
+ const legacyImageId = failure.legacyImageId ?? void 0;
913
+ const label = legacyImageId ? ` (${legacyImageId})` : "";
914
+ console.warn(
915
+ `Deleted CAS image '${failure.legacyImageName}', but could not delete the legacy image of the same name${label}, which can no longer start sandboxes: ${failure.error}. Delete it with deleteSandboxImage("${legacyImageId ?? failure.legacyImageName}").`
744
916
  );
745
917
  }
746
918
  async function findSandboxImageByName(imageName) {
@@ -784,13 +956,14 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
784
956
  disk_mb: { type: "string" },
785
957
  builder_disk_mb: { type: "string" },
786
958
  docker_compat: { type: "boolean", default: false },
787
- public: { type: "boolean", default: false }
959
+ public: { type: "boolean", default: false },
960
+ "no-cas": { type: "boolean", default: false }
788
961
  }
789
962
  });
790
963
  const dockerfilePath = parsed.positionals[0];
791
964
  if (!dockerfilePath) {
792
965
  throw new Error(
793
- "Usage: tensorlake-create-sandbox-image <dockerfile_path> [--name NAME] [--cpus N] [--memory MiB] [--disk_mb MiB] [--builder_disk_mb MiB] [--docker_compat] [--public]"
966
+ "Usage: tensorlake-create-sandbox-image <dockerfile_path> [--name NAME] [--cpus N] [--memory MiB] [--disk_mb MiB] [--builder_disk_mb MiB] [--docker_compat] [--public] [--no-cas]"
794
967
  );
795
968
  }
796
969
  const cpus = parsed.values.cpus != null ? Number(parsed.values.cpus) : void 0;
@@ -822,7 +995,8 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
822
995
  diskMb,
823
996
  builderDiskMb,
824
997
  dockerCompat: parsed.values.docker_compat,
825
- isPublic: parsed.values.public
998
+ isPublic: parsed.values.public,
999
+ cas: !parsed.values["no-cas"]
826
1000
  },
827
1001
  { emit: ndjsonStdoutEmit, _allowPat: true }
828
1002
  );
@@ -838,13 +1012,14 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
838
1012
  disk_mb: { type: "string" },
839
1013
  builder_disk_mb: { type: "string" },
840
1014
  docker_compat: { type: "boolean", default: false },
841
- public: { type: "boolean", default: false }
1015
+ public: { type: "boolean", default: false },
1016
+ "no-cas": { type: "boolean", default: false }
842
1017
  }
843
1018
  });
844
1019
  const imageReference = parsed.positionals[0];
845
1020
  if (!imageReference) {
846
1021
  throw new Error(
847
- "Usage: tensorlake-import-sandbox-image <image_reference> [--name NAME] [--cpus N] [--memory MiB] [--disk_mb MiB] [--builder_disk_mb MiB] [--docker_compat] [--public]"
1022
+ "Usage: tensorlake-import-sandbox-image <image_reference> [--name NAME] [--cpus N] [--memory MiB] [--disk_mb MiB] [--builder_disk_mb MiB] [--docker_compat] [--public] [--no-cas]"
848
1023
  );
849
1024
  }
850
1025
  const cpus = parsed.values.cpus != null ? Number(parsed.values.cpus) : void 0;
@@ -876,12 +1051,13 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
876
1051
  diskMb,
877
1052
  builderDiskMb,
878
1053
  dockerCompat: parsed.values.docker_compat,
879
- isPublic: parsed.values.public
1054
+ isPublic: parsed.values.public,
1055
+ cas: !parsed.values["no-cas"]
880
1056
  },
881
1057
  { emit: ndjsonStdoutEmit, _allowPat: true }
882
1058
  );
883
1059
  }
884
- var import_node_path3, import_node_os2, import_node_fs2, import_node_util, cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME, __imageBuildInternals;
1060
+ var import_node_path3, import_node_os2, import_node_fs2, import_node_util, cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME, DEFAULT_SANDBOX_IMAGE_NAME, DEFAULT_IMPORTED_IMAGE_NAME, CAS_NAME_SEPARATORS, RESERVED_IMAGE_NAME_PREFIXES, MAX_CAS_IMAGE_NAME_LENGTH, __imageBuildInternals;
885
1061
  var init_sandbox_image = __esm({
886
1062
  "src/sandbox-image.ts"() {
887
1063
  "use strict";
@@ -894,6 +1070,11 @@ var init_sandbox_image = __esm({
894
1070
  init_native_binding();
895
1071
  init_image_builds();
896
1072
  DEFAULT_IMAGE_NAME = "default";
1073
+ DEFAULT_SANDBOX_IMAGE_NAME = "sandbox-image";
1074
+ DEFAULT_IMPORTED_IMAGE_NAME = "imported-image";
1075
+ CAS_NAME_SEPARATORS = "._-";
1076
+ RESERVED_IMAGE_NAME_PREFIXES = ["sandbox_template_", "image_", "cas-v1:"];
1077
+ MAX_CAS_IMAGE_NAME_LENGTH = 255;
897
1078
  __imageBuildInternals = {
898
1079
  loadNativeBinding: () => loadNativeBinding(),
899
1080
  buildContextFromEnv: () => buildContextFromEnv(),
@@ -902,7 +1083,12 @@ var init_sandbox_image = __esm({
902
1083
  eventToEmitDict: (event) => eventToEmitDict(event),
903
1084
  imageRequiresContext: (image) => imageRequiresContext(image),
904
1085
  defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
905
- defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference)
1086
+ defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference),
1087
+ registeredImageName: (explicit, generated, cas, fallback) => registeredImageName(explicit, generated, cas, fallback),
1088
+ casImageNameFrom: (raw, fallback) => casImageNameFrom(raw, fallback),
1089
+ canonicalCasImageName: (name) => canonicalCasImageName(name),
1090
+ isAddressableCasImageName: (name) => isAddressableCasImageName(name),
1091
+ defaultImportedImageName: DEFAULT_IMPORTED_IMAGE_NAME
906
1092
  };
907
1093
  }
908
1094
  });
@@ -1015,10 +1201,11 @@ var init_image = __esm({
1015
1201
  });
1016
1202
  }
1017
1203
  /**
1018
- * Build this image as a sandbox template and register it.
1204
+ * Build this image and register it as a CAS sandbox image (the default) or,
1205
+ * with `cas: false`, a legacy sandbox image.
1019
1206
  *
1020
1207
  * Materializes the image in a build sandbox, snapshots the filesystem,
1021
- * and registers the snapshot as a named sandbox template.
1208
+ * and registers the snapshot under the image's name.
1022
1209
  */
1023
1210
  async build(options = {}) {
1024
1211
  const { createSandboxImage: createSandboxImage2 } = await Promise.resolve().then(() => (init_sandbox_image(), sandbox_image_exports));
@@ -2437,7 +2624,7 @@ init_image();
2437
2624
 
2438
2625
  // src/defaults.ts
2439
2626
  init_cjs_shims();
2440
- var SDK_VERSION = "0.5.153";
2627
+ var SDK_VERSION = "0.5.156";
2441
2628
  var API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
2442
2629
  var API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
2443
2630
  var NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -3245,7 +3432,7 @@ function createWorkerBinding(runtime) {
3245
3432
  };
3246
3433
  }
3247
3434
  var runtimeKey = /* @__PURE__ */ Symbol.for(
3248
- `tensorlake.native.worker.${false ? "source" : "0.5.153"}.v1`
3435
+ `tensorlake.native.worker.${false ? "source" : "0.5.156"}.v1`
3249
3436
  );
3250
3437
  var runtimes = globalThis;
3251
3438
  function workerBinding() {
@@ -3521,10 +3708,12 @@ var CloudClient = class _CloudClient {
3521
3708
  );
3522
3709
  }
3523
3710
  /**
3524
- * Delete a registered sandbox image by name or id through the merged
3525
- * catalog, with this client's credentials: an `image_` id or a name the
3526
- * Image Service knows deletes a CAS image, a `sandbox_template_` id or a
3527
- * name registered only in the platform registry deletes a legacy image.
3711
+ * Delete a registered CAS or legacy sandbox image by name or id through the
3712
+ * merged catalog, with this client's credentials: an `image_` id or a name
3713
+ * the CAS image registry knows deletes a CAS image, a `sandbox_template_` id
3714
+ * or a name registered only in the legacy image registry deletes a legacy
3715
+ * image.
3716
+ * A name is deleted from both the CAS and the legacy image registries.
3528
3717
  * Rejects when neither catalog knows the reference. The same semantics
3529
3718
  * and accepted differences as the module-level `deleteSandboxImage`.
3530
3719
  */
@@ -3532,10 +3721,10 @@ var CloudClient = class _CloudClient {
3532
3721
  await deleteSandboxImageWithCredentials(this.catalogCredentials(), imageName);
3533
3722
  }
3534
3723
  /**
3535
- * Look up a registered sandbox image by name or id through the merged
3536
- * catalog, with this client's credentials. Returns the image in the
3537
- * sandbox-template shape, or `null` when neither the Image Service nor the
3538
- * platform registry knows the reference. An explicit organization/project
3724
+ * Look up a registered CAS or legacy sandbox image by name or id through
3725
+ * the merged catalog, with this client's credentials. Returns the image in
3726
+ * the sandbox-template shape, or `null` when neither the CAS nor the legacy
3727
+ * image registry knows the reference. An explicit organization/project
3539
3728
  * scope (the client's, or the call's override) addresses that project's
3540
3729
  * routes directly, as before; without one the key's own scope applies.
3541
3730
  */