@tensorlakeai/tensorlake 0.5.154 → 0.5.157

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 +131 -40
  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 +131 -40
  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 +175 -62
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +31 -23
  14. package/dist/index.d.ts +31 -23
  15. package/dist/index.js +175 -62
  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 +119 -30
  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 +119 -30
  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
@@ -505,16 +505,58 @@ function defaultRegisteredName(dockerfilePath) {
505
505
  const parsed = import_node_path3.default.parse(dockerfilePath);
506
506
  if (parsed.name.toLowerCase() === "dockerfile") {
507
507
  const parentName = import_node_path3.default.basename(import_node_path3.default.dirname(dockerfilePath)).trim();
508
- return parentName || "sandbox-image";
508
+ return parentName || DEFAULT_SANDBOX_IMAGE_NAME;
509
509
  }
510
- return parsed.name || "sandbox-image";
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;
516
+ }
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("-");
511
553
  }
512
554
  function defaultRegisteredNameFromImage(imageReference) {
513
555
  const withoutDigest = imageReference.split("@", 1)[0] ?? imageReference;
514
556
  const lastSegment = withoutDigest.split("/").pop() ?? withoutDigest;
515
557
  const colonIndex = lastSegment.lastIndexOf(":");
516
558
  const name = colonIndex > 0 && colonIndex < lastSegment.length - 1 ? lastSegment.slice(0, colonIndex) : lastSegment;
517
- return name || "imported-image";
559
+ return name || DEFAULT_IMPORTED_IMAGE_NAME;
518
560
  }
519
561
  function noopEmit(_event) {
520
562
  }
@@ -617,7 +659,11 @@ async function createSandboxImage(source, options = {}, deps = {}) {
617
659
  if (!text.endsWith("\n")) text += "\n";
618
660
  dockerfileText = text;
619
661
  nativeContextDir = resolvedContext;
620
- effectiveName = options.registeredName ?? source.name;
662
+ effectiveName = registeredImageName(
663
+ options.registeredName ?? source.name,
664
+ void 0,
665
+ options.cas ?? true
666
+ );
621
667
  } else if (typeof source === "string") {
622
668
  const resolvedPath = import_node_path3.default.resolve(source);
623
669
  if (!(0, import_node_fs2.existsSync)(resolvedPath)) {
@@ -626,7 +672,11 @@ async function createSandboxImage(source, options = {}, deps = {}) {
626
672
  dockerfilePath = resolvedPath;
627
673
  dockerfileText = void 0;
628
674
  nativeContextDir = void 0;
629
- effectiveName = options.registeredName ?? defaultRegisteredName(resolvedPath);
675
+ effectiveName = registeredImageName(
676
+ options.registeredName,
677
+ defaultRegisteredName(resolvedPath),
678
+ options.cas ?? true
679
+ );
630
680
  } else {
631
681
  throw new TypeError(
632
682
  `source must be an Image or a Dockerfile path, got ${typeof source}`
@@ -650,12 +700,16 @@ async function createSandboxImage(source, options = {}, deps = {}) {
650
700
  deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
651
701
  );
652
702
  }
653
- if (options.signal !== void 0 && !options.cas) {
703
+ const cas = options.cas ?? true;
704
+ if (options.signal !== void 0 && !cas) {
654
705
  throw new Error(
655
- "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"
656
707
  );
657
708
  }
658
- emit({ type: "status", message: `Building image '${effectiveName}'...` });
709
+ emit({
710
+ type: "status",
711
+ message: `Building ${cas ? "CAS" : "legacy"} image '${effectiveName}'...`
712
+ });
659
713
  const binding = loadNativeBinding();
660
714
  let emitError;
661
715
  const nativeOptions = {
@@ -677,7 +731,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
677
731
  dockerConfigJson: options.dockerConfigJson,
678
732
  dockerfileText,
679
733
  contextDir: nativeContextDir,
680
- cas: options.cas ?? false,
734
+ cas,
681
735
  buildArgs: options.buildArgs
682
736
  };
683
737
  const forward = (event) => {
@@ -687,7 +741,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
687
741
  emitError ??= error;
688
742
  }
689
743
  };
690
- const resultJson = options.cas ? await __runWithInterrupt(
744
+ const resultJson = cas ? await __runWithInterrupt(
691
745
  options.signal,
692
746
  (interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
693
747
  ) : await binding.buildSandboxImage(nativeOptions, forward);
@@ -718,7 +772,12 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
718
772
  }
719
773
  const reference = imageReference.trim();
720
774
  const context = buildContextFromEnv();
721
- 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
+ );
722
781
  if (effectiveName === DEFAULT_IMAGE_NAME) {
723
782
  console.warn(
724
783
  `Importing sandbox image with the default name "${DEFAULT_IMAGE_NAME}". Pass \`registeredName\` to avoid collisions with other default-named images in this project.`
@@ -736,14 +795,15 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
736
795
  deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
737
796
  );
738
797
  }
739
- if (options.signal !== void 0 && !options.cas) {
798
+ const cas = options.cas ?? true;
799
+ if (options.signal !== void 0 && !cas) {
740
800
  throw new Error(
741
- "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"
742
802
  );
743
803
  }
744
804
  emit({
745
805
  type: "status",
746
- message: `Importing image '${reference}' as '${effectiveName}'...`
806
+ message: `Importing '${reference}' as ${cas ? "CAS" : "legacy"} image '${effectiveName}'...`
747
807
  });
748
808
  const binding = loadNativeBinding();
749
809
  let emitError;
@@ -764,7 +824,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
764
824
  userAgent: void 0,
765
825
  dockerCompat: options.dockerCompat ?? false,
766
826
  dockerConfigJson: options.dockerConfigJson,
767
- cas: options.cas ?? false
827
+ cas
768
828
  };
769
829
  const forward = (event) => {
770
830
  try {
@@ -773,7 +833,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
773
833
  emitError ??= error;
774
834
  }
775
835
  };
776
- const resultJson = options.cas ? await __runWithInterrupt(
836
+ const resultJson = cas ? await __runWithInterrupt(
777
837
  options.signal,
778
838
  (interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
779
839
  ) : await binding.importSandboxImage(nativeOptions, forward);
@@ -830,15 +890,29 @@ async function deleteSandboxImage(imageName) {
830
890
  if (typeof imageName !== "string" || imageName.length === 0) {
831
891
  throw new TypeError("imageName must be a non-empty string");
832
892
  }
833
- await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
893
+ warnIncompleteLegacyCleanup(
894
+ await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName)
895
+ );
834
896
  }
835
897
  async function deleteSandboxImageWithCredentials(credentials, imageName) {
836
898
  if (typeof imageName !== "string" || imageName.length === 0) {
837
899
  throw new TypeError("imageName must be a non-empty string");
838
900
  }
839
- await loadNativeBinding().deleteSandboxImage(
840
- catalogOptionsFromCredentials(credentials),
841
- 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}").`
842
916
  );
843
917
  }
844
918
  async function findSandboxImageByName(imageName) {
@@ -882,13 +956,14 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
882
956
  disk_mb: { type: "string" },
883
957
  builder_disk_mb: { type: "string" },
884
958
  docker_compat: { type: "boolean", default: false },
885
- public: { type: "boolean", default: false }
959
+ public: { type: "boolean", default: false },
960
+ "no-cas": { type: "boolean", default: false }
886
961
  }
887
962
  });
888
963
  const dockerfilePath = parsed.positionals[0];
889
964
  if (!dockerfilePath) {
890
965
  throw new Error(
891
- "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]"
892
967
  );
893
968
  }
894
969
  const cpus = parsed.values.cpus != null ? Number(parsed.values.cpus) : void 0;
@@ -920,7 +995,8 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
920
995
  diskMb,
921
996
  builderDiskMb,
922
997
  dockerCompat: parsed.values.docker_compat,
923
- isPublic: parsed.values.public
998
+ isPublic: parsed.values.public,
999
+ cas: !parsed.values["no-cas"]
924
1000
  },
925
1001
  { emit: ndjsonStdoutEmit, _allowPat: true }
926
1002
  );
@@ -936,13 +1012,14 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
936
1012
  disk_mb: { type: "string" },
937
1013
  builder_disk_mb: { type: "string" },
938
1014
  docker_compat: { type: "boolean", default: false },
939
- public: { type: "boolean", default: false }
1015
+ public: { type: "boolean", default: false },
1016
+ "no-cas": { type: "boolean", default: false }
940
1017
  }
941
1018
  });
942
1019
  const imageReference = parsed.positionals[0];
943
1020
  if (!imageReference) {
944
1021
  throw new Error(
945
- "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]"
946
1023
  );
947
1024
  }
948
1025
  const cpus = parsed.values.cpus != null ? Number(parsed.values.cpus) : void 0;
@@ -974,12 +1051,13 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
974
1051
  diskMb,
975
1052
  builderDiskMb,
976
1053
  dockerCompat: parsed.values.docker_compat,
977
- isPublic: parsed.values.public
1054
+ isPublic: parsed.values.public,
1055
+ cas: !parsed.values["no-cas"]
978
1056
  },
979
1057
  { emit: ndjsonStdoutEmit, _allowPat: true }
980
1058
  );
981
1059
  }
982
- 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;
983
1061
  var init_sandbox_image = __esm({
984
1062
  "src/sandbox-image.ts"() {
985
1063
  "use strict";
@@ -992,6 +1070,11 @@ var init_sandbox_image = __esm({
992
1070
  init_native_binding();
993
1071
  init_image_builds();
994
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;
995
1078
  __imageBuildInternals = {
996
1079
  loadNativeBinding: () => loadNativeBinding(),
997
1080
  buildContextFromEnv: () => buildContextFromEnv(),
@@ -1000,7 +1083,12 @@ var init_sandbox_image = __esm({
1000
1083
  eventToEmitDict: (event) => eventToEmitDict(event),
1001
1084
  imageRequiresContext: (image) => imageRequiresContext(image),
1002
1085
  defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
1003
- 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
1004
1092
  };
1005
1093
  }
1006
1094
  });
@@ -1113,10 +1201,11 @@ var init_image = __esm({
1113
1201
  });
1114
1202
  }
1115
1203
  /**
1116
- * 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.
1117
1206
  *
1118
1207
  * Materializes the image in a build sandbox, snapshots the filesystem,
1119
- * and registers the snapshot as a named sandbox template.
1208
+ * and registers the snapshot under the image's name.
1120
1209
  */
1121
1210
  async build(options = {}) {
1122
1211
  const { createSandboxImage: createSandboxImage2 } = await Promise.resolve().then(() => (init_sandbox_image(), sandbox_image_exports));
@@ -2535,7 +2624,7 @@ init_image();
2535
2624
 
2536
2625
  // src/defaults.ts
2537
2626
  init_cjs_shims();
2538
- var SDK_VERSION = "0.5.154";
2627
+ var SDK_VERSION = "0.5.157";
2539
2628
  var API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
2540
2629
  var API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
2541
2630
  var NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -3343,7 +3432,7 @@ function createWorkerBinding(runtime) {
3343
3432
  };
3344
3433
  }
3345
3434
  var runtimeKey = /* @__PURE__ */ Symbol.for(
3346
- `tensorlake.native.worker.${false ? "source" : "0.5.154"}.v1`
3435
+ `tensorlake.native.worker.${false ? "source" : "0.5.157"}.v1`
3347
3436
  );
3348
3437
  var runtimes = globalThis;
3349
3438
  function workerBinding() {
@@ -3619,10 +3708,12 @@ var CloudClient = class _CloudClient {
3619
3708
  );
3620
3709
  }
3621
3710
  /**
3622
- * Delete a registered sandbox image by name or id through the merged
3623
- * catalog, with this client's credentials: an `image_` id or a name the
3624
- * Image Service knows deletes a CAS image, a `sandbox_template_` id or a
3625
- * 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.
3626
3717
  * Rejects when neither catalog knows the reference. The same semantics
3627
3718
  * and accepted differences as the module-level `deleteSandboxImage`.
3628
3719
  */
@@ -3630,10 +3721,10 @@ var CloudClient = class _CloudClient {
3630
3721
  await deleteSandboxImageWithCredentials(this.catalogCredentials(), imageName);
3631
3722
  }
3632
3723
  /**
3633
- * Look up a registered sandbox image by name or id through the merged
3634
- * catalog, with this client's credentials. Returns the image in the
3635
- * sandbox-template shape, or `null` when neither the Image Service nor the
3636
- * 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
3637
3728
  * scope (the client's, or the call's override) addresses that project's
3638
3729
  * routes directly, as before; without one the key's own scope applies.
3639
3730
  */