@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
@@ -148,10 +148,11 @@ var init_image = __esm({
148
148
  });
149
149
  }
150
150
  /**
151
- * Build this image as a sandbox template and register it.
151
+ * Build this image and register it as a CAS sandbox image (the default) or,
152
+ * with `cas: false`, a legacy sandbox image.
152
153
  *
153
154
  * Materializes the image in a build sandbox, snapshots the filesystem,
154
- * and registers the snapshot as a named sandbox template.
155
+ * and registers the snapshot under the image's name.
155
156
  */
156
157
  async build(options = {}) {
157
158
  const { createSandboxImage: createSandboxImage2 } = await Promise.resolve().then(() => (init_sandbox_image(), sandbox_image_exports));
@@ -631,16 +632,58 @@ function defaultRegisteredName(dockerfilePath) {
631
632
  const parsed = path4.parse(dockerfilePath);
632
633
  if (parsed.name.toLowerCase() === "dockerfile") {
633
634
  const parentName = path4.basename(path4.dirname(dockerfilePath)).trim();
634
- return parentName || "sandbox-image";
635
+ return parentName || DEFAULT_SANDBOX_IMAGE_NAME;
635
636
  }
636
- return parsed.name || "sandbox-image";
637
+ return parsed.name || DEFAULT_SANDBOX_IMAGE_NAME;
638
+ }
639
+ function registeredImageName(explicit, generated, cas, fallback = DEFAULT_SANDBOX_IMAGE_NAME) {
640
+ if (explicit || generated === void 0) {
641
+ const name = explicit ?? "";
642
+ return cas ? canonicalCasImageName(name) : name;
643
+ }
644
+ return cas ? casImageNameFrom(generated, fallback) : generated;
645
+ }
646
+ function canonicalCasImageName(name) {
647
+ return name.replace(/[A-Z]/g, (c) => c.toLowerCase());
648
+ }
649
+ function casImageNameFrom(raw, fallback) {
650
+ const lowered = canonicalCasImageName(raw);
651
+ if (isAddressableCasImageName(lowered)) {
652
+ return lowered;
653
+ }
654
+ let name = "";
655
+ for (const original of lowered) {
656
+ const ch = /^[a-z0-9._-]$/.test(original) ? original : "-";
657
+ const previous = name[name.length - 1];
658
+ if (CAS_NAME_SEPARATORS.includes(ch) && previous !== void 0 && CAS_NAME_SEPARATORS.includes(previous)) {
659
+ continue;
660
+ }
661
+ name += ch;
662
+ }
663
+ name = name.replace(/^[._-]+|[._-]+$/g, "").slice(0, MAX_CAS_IMAGE_NAME_LENGTH).replace(/[._-]+$/, "");
664
+ return isAddressableCasImageName(name) ? name : fallback;
665
+ }
666
+ function isAddressableCasImageName(name) {
667
+ 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)) {
668
+ return false;
669
+ }
670
+ const colon = name.indexOf(":");
671
+ const repository = colon === -1 ? name : name.slice(0, colon);
672
+ if (!repository.split("/").every((component) => /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(component))) {
673
+ return false;
674
+ }
675
+ if (colon === -1) {
676
+ return true;
677
+ }
678
+ const tag = name.slice(colon + 1);
679
+ return tag.length > 0 && tag.length <= 128 && /^[a-z0-9._-]+$/.test(tag) && !tag.startsWith(".") && !tag.startsWith("-");
637
680
  }
638
681
  function defaultRegisteredNameFromImage(imageReference) {
639
682
  const withoutDigest = imageReference.split("@", 1)[0] ?? imageReference;
640
683
  const lastSegment = withoutDigest.split("/").pop() ?? withoutDigest;
641
684
  const colonIndex = lastSegment.lastIndexOf(":");
642
685
  const name = colonIndex > 0 && colonIndex < lastSegment.length - 1 ? lastSegment.slice(0, colonIndex) : lastSegment;
643
- return name || "imported-image";
686
+ return name || DEFAULT_IMPORTED_IMAGE_NAME;
644
687
  }
645
688
  function noopEmit(_event) {
646
689
  }
@@ -743,7 +786,11 @@ async function createSandboxImage(source, options = {}, deps = {}) {
743
786
  if (!text.endsWith("\n")) text += "\n";
744
787
  dockerfileText = text;
745
788
  nativeContextDir = resolvedContext;
746
- effectiveName = options.registeredName ?? source.name;
789
+ effectiveName = registeredImageName(
790
+ options.registeredName ?? source.name,
791
+ void 0,
792
+ options.cas ?? true
793
+ );
747
794
  } else if (typeof source === "string") {
748
795
  const resolvedPath = path4.resolve(source);
749
796
  if (!existsSync3(resolvedPath)) {
@@ -752,7 +799,11 @@ async function createSandboxImage(source, options = {}, deps = {}) {
752
799
  dockerfilePath = resolvedPath;
753
800
  dockerfileText = void 0;
754
801
  nativeContextDir = void 0;
755
- effectiveName = options.registeredName ?? defaultRegisteredName(resolvedPath);
802
+ effectiveName = registeredImageName(
803
+ options.registeredName,
804
+ defaultRegisteredName(resolvedPath),
805
+ options.cas ?? true
806
+ );
756
807
  } else {
757
808
  throw new TypeError(
758
809
  `source must be an Image or a Dockerfile path, got ${typeof source}`
@@ -776,12 +827,16 @@ async function createSandboxImage(source, options = {}, deps = {}) {
776
827
  deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
777
828
  );
778
829
  }
779
- if (options.signal !== void 0 && !options.cas) {
830
+ const cas = options.cas ?? true;
831
+ if (options.signal !== void 0 && !cas) {
780
832
  throw new Error(
781
- "signal is only supported for CAS image builds (cas: true); a legacy build has no Image Service build operation to cancel"
833
+ "signal is not supported for legacy image builds (cas: false): a legacy image build has no build operation to cancel"
782
834
  );
783
835
  }
784
- emit({ type: "status", message: `Building image '${effectiveName}'...` });
836
+ emit({
837
+ type: "status",
838
+ message: `Building ${cas ? "CAS" : "legacy"} image '${effectiveName}'...`
839
+ });
785
840
  const binding = loadNativeBinding();
786
841
  let emitError;
787
842
  const nativeOptions = {
@@ -803,7 +858,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
803
858
  dockerConfigJson: options.dockerConfigJson,
804
859
  dockerfileText,
805
860
  contextDir: nativeContextDir,
806
- cas: options.cas ?? false,
861
+ cas,
807
862
  buildArgs: options.buildArgs
808
863
  };
809
864
  const forward = (event) => {
@@ -813,7 +868,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
813
868
  emitError ??= error;
814
869
  }
815
870
  };
816
- const resultJson = options.cas ? await __runWithInterrupt(
871
+ const resultJson = cas ? await __runWithInterrupt(
817
872
  options.signal,
818
873
  (interruptId) => binding.buildSandboxImage(nativeOptions, forward, interruptId)
819
874
  ) : await binding.buildSandboxImage(nativeOptions, forward);
@@ -844,7 +899,12 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
844
899
  }
845
900
  const reference = imageReference.trim();
846
901
  const context = buildContextFromEnv();
847
- const effectiveName = options.registeredName ?? defaultRegisteredNameFromImage(reference);
902
+ const effectiveName = registeredImageName(
903
+ options.registeredName,
904
+ defaultRegisteredNameFromImage(reference),
905
+ options.cas ?? true,
906
+ DEFAULT_IMPORTED_IMAGE_NAME
907
+ );
848
908
  if (effectiveName === DEFAULT_IMAGE_NAME2) {
849
909
  console.warn(
850
910
  `Importing sandbox image with the default name "${DEFAULT_IMAGE_NAME2}". Pass \`registeredName\` to avoid collisions with other default-named images in this project.`
@@ -862,14 +922,15 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
862
922
  deps._allowPat ? "Missing TENSORLAKE_API_KEY or TENSORLAKE_PAT credentials." : "Missing TENSORLAKE_API_KEY credentials."
863
923
  );
864
924
  }
865
- if (options.signal !== void 0 && !options.cas) {
925
+ const cas = options.cas ?? true;
926
+ if (options.signal !== void 0 && !cas) {
866
927
  throw new Error(
867
- "signal is only supported for CAS image imports (cas: true); a legacy import has no Image Service build operation to cancel"
928
+ "signal is not supported for legacy image imports (cas: false): a legacy image import has no build operation to cancel"
868
929
  );
869
930
  }
870
931
  emit({
871
932
  type: "status",
872
- message: `Importing image '${reference}' as '${effectiveName}'...`
933
+ message: `Importing '${reference}' as ${cas ? "CAS" : "legacy"} image '${effectiveName}'...`
873
934
  });
874
935
  const binding = loadNativeBinding();
875
936
  let emitError;
@@ -890,7 +951,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
890
951
  userAgent: void 0,
891
952
  dockerCompat: options.dockerCompat ?? false,
892
953
  dockerConfigJson: options.dockerConfigJson,
893
- cas: options.cas ?? false
954
+ cas
894
955
  };
895
956
  const forward = (event) => {
896
957
  try {
@@ -899,7 +960,7 @@ async function importSandboxImage(imageReference, options = {}, deps = {}) {
899
960
  emitError ??= error;
900
961
  }
901
962
  };
902
- const resultJson = options.cas ? await __runWithInterrupt(
963
+ const resultJson = cas ? await __runWithInterrupt(
903
964
  options.signal,
904
965
  (interruptId) => binding.importSandboxImage(nativeOptions, forward, interruptId)
905
966
  ) : await binding.importSandboxImage(nativeOptions, forward);
@@ -956,15 +1017,29 @@ async function deleteSandboxImage(imageName) {
956
1017
  if (typeof imageName !== "string" || imageName.length === 0) {
957
1018
  throw new TypeError("imageName must be a non-empty string");
958
1019
  }
959
- await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName);
1020
+ warnIncompleteLegacyCleanup(
1021
+ await loadNativeBinding().deleteSandboxImage(catalogOptionsFromEnv(), imageName)
1022
+ );
960
1023
  }
961
1024
  async function deleteSandboxImageWithCredentials(credentials, imageName) {
962
1025
  if (typeof imageName !== "string" || imageName.length === 0) {
963
1026
  throw new TypeError("imageName must be a non-empty string");
964
1027
  }
965
- await loadNativeBinding().deleteSandboxImage(
966
- catalogOptionsFromCredentials(credentials),
967
- imageName
1028
+ warnIncompleteLegacyCleanup(
1029
+ await loadNativeBinding().deleteSandboxImage(
1030
+ catalogOptionsFromCredentials(credentials),
1031
+ imageName
1032
+ )
1033
+ );
1034
+ }
1035
+ function warnIncompleteLegacyCleanup(failure) {
1036
+ if (failure == null) {
1037
+ return;
1038
+ }
1039
+ const legacyImageId = failure.legacyImageId ?? void 0;
1040
+ const label = legacyImageId ? ` (${legacyImageId})` : "";
1041
+ console.warn(
1042
+ `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}").`
968
1043
  );
969
1044
  }
970
1045
  async function findSandboxImageByName(imageName) {
@@ -1008,13 +1083,14 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
1008
1083
  disk_mb: { type: "string" },
1009
1084
  builder_disk_mb: { type: "string" },
1010
1085
  docker_compat: { type: "boolean", default: false },
1011
- public: { type: "boolean", default: false }
1086
+ public: { type: "boolean", default: false },
1087
+ "no-cas": { type: "boolean", default: false }
1012
1088
  }
1013
1089
  });
1014
1090
  const dockerfilePath = parsed.positionals[0];
1015
1091
  if (!dockerfilePath) {
1016
1092
  throw new Error(
1017
- "Usage: tensorlake-create-sandbox-image <dockerfile_path> [--name NAME] [--cpus N] [--memory MiB] [--disk_mb MiB] [--builder_disk_mb MiB] [--docker_compat] [--public]"
1093
+ "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]"
1018
1094
  );
1019
1095
  }
1020
1096
  const cpus = parsed.values.cpus != null ? Number(parsed.values.cpus) : void 0;
@@ -1046,7 +1122,8 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
1046
1122
  diskMb,
1047
1123
  builderDiskMb,
1048
1124
  dockerCompat: parsed.values.docker_compat,
1049
- isPublic: parsed.values.public
1125
+ isPublic: parsed.values.public,
1126
+ cas: !parsed.values["no-cas"]
1050
1127
  },
1051
1128
  { emit: ndjsonStdoutEmit, _allowPat: true }
1052
1129
  );
@@ -1062,13 +1139,14 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
1062
1139
  disk_mb: { type: "string" },
1063
1140
  builder_disk_mb: { type: "string" },
1064
1141
  docker_compat: { type: "boolean", default: false },
1065
- public: { type: "boolean", default: false }
1142
+ public: { type: "boolean", default: false },
1143
+ "no-cas": { type: "boolean", default: false }
1066
1144
  }
1067
1145
  });
1068
1146
  const imageReference = parsed.positionals[0];
1069
1147
  if (!imageReference) {
1070
1148
  throw new Error(
1071
- "Usage: tensorlake-import-sandbox-image <image_reference> [--name NAME] [--cpus N] [--memory MiB] [--disk_mb MiB] [--builder_disk_mb MiB] [--docker_compat] [--public]"
1149
+ "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]"
1072
1150
  );
1073
1151
  }
1074
1152
  const cpus = parsed.values.cpus != null ? Number(parsed.values.cpus) : void 0;
@@ -1100,12 +1178,13 @@ async function runImportSandboxImageCli(argv = process.argv.slice(2)) {
1100
1178
  diskMb,
1101
1179
  builderDiskMb,
1102
1180
  dockerCompat: parsed.values.docker_compat,
1103
- isPublic: parsed.values.public
1181
+ isPublic: parsed.values.public,
1182
+ cas: !parsed.values["no-cas"]
1104
1183
  },
1105
1184
  { emit: ndjsonStdoutEmit, _allowPat: true }
1106
1185
  );
1107
1186
  }
1108
- var cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2, __imageBuildInternals;
1187
+ var cachedNativeBinding, cachedNativeBindingError, DEFAULT_IMAGE_NAME2, DEFAULT_SANDBOX_IMAGE_NAME, DEFAULT_IMPORTED_IMAGE_NAME, CAS_NAME_SEPARATORS, RESERVED_IMAGE_NAME_PREFIXES, MAX_CAS_IMAGE_NAME_LENGTH, __imageBuildInternals;
1109
1188
  var init_sandbox_image = __esm({
1110
1189
  "src/sandbox-image.ts"() {
1111
1190
  init_esm_shims();
@@ -1113,6 +1192,11 @@ var init_sandbox_image = __esm({
1113
1192
  init_native_binding();
1114
1193
  init_image_builds();
1115
1194
  DEFAULT_IMAGE_NAME2 = "default";
1195
+ DEFAULT_SANDBOX_IMAGE_NAME = "sandbox-image";
1196
+ DEFAULT_IMPORTED_IMAGE_NAME = "imported-image";
1197
+ CAS_NAME_SEPARATORS = "._-";
1198
+ RESERVED_IMAGE_NAME_PREFIXES = ["sandbox_template_", "image_", "cas-v1:"];
1199
+ MAX_CAS_IMAGE_NAME_LENGTH = 255;
1116
1200
  __imageBuildInternals = {
1117
1201
  loadNativeBinding: () => loadNativeBinding(),
1118
1202
  buildContextFromEnv: () => buildContextFromEnv(),
@@ -1121,7 +1205,12 @@ var init_sandbox_image = __esm({
1121
1205
  eventToEmitDict: (event) => eventToEmitDict(event),
1122
1206
  imageRequiresContext: (image) => imageRequiresContext(image),
1123
1207
  defaultRegisteredName: (dockerfilePath) => defaultRegisteredName(dockerfilePath),
1124
- defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference)
1208
+ defaultRegisteredNameFromImage: (reference) => defaultRegisteredNameFromImage(reference),
1209
+ registeredImageName: (explicit, generated, cas, fallback) => registeredImageName(explicit, generated, cas, fallback),
1210
+ casImageNameFrom: (raw, fallback) => casImageNameFrom(raw, fallback),
1211
+ canonicalCasImageName: (name) => canonicalCasImageName(name),
1212
+ isAddressableCasImageName: (name) => isAddressableCasImageName(name),
1213
+ defaultImportedImageName: DEFAULT_IMPORTED_IMAGE_NAME
1125
1214
  };
1126
1215
  }
1127
1216
  });