@tensorlakeai/tensorlake 0.5.158 → 0.5.159

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.
@@ -402,7 +402,7 @@ var NativeWorkerClient = class {
402
402
  }
403
403
  };
404
404
  var runtimeKey = /* @__PURE__ */ Symbol.for(
405
- `tensorlake.native.worker.${false ? "source" : "0.5.158"}.v1`
405
+ `tensorlake.native.worker.${false ? "source" : "0.5.159"}.v1`
406
406
  );
407
407
  var runtimes = globalThis;
408
408
  function configureNativeWorker(workerPath) {
@@ -390,7 +390,7 @@ var NativeWorkerClient = class {
390
390
  }
391
391
  };
392
392
  var runtimeKey = /* @__PURE__ */ Symbol.for(
393
- `tensorlake.native.worker.${false ? "source" : "0.5.158"}.v1`
393
+ `tensorlake.native.worker.${false ? "source" : "0.5.159"}.v1`
394
394
  );
395
395
  var runtimes = globalThis;
396
396
  function configureNativeWorker(workerPath) {
@@ -51,7 +51,7 @@ var cancelNativeCall = /* @__PURE__ */ Symbol.for("tensorlake.native.cancel.v1")
51
51
  var closeNativeHandle = /* @__PURE__ */ Symbol.for("tensorlake.native.close.v1");
52
52
 
53
53
  // src/defaults.ts
54
- var SDK_VERSION = "0.5.158";
54
+ var SDK_VERSION = "0.5.159";
55
55
  var API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
56
56
  var API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
57
57
  var NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -247,7 +247,7 @@ var NativeWorkerClient = class {
247
247
  }
248
248
  };
249
249
  var runtimeKey = /* @__PURE__ */ Symbol.for(
250
- `tensorlake.native.worker.${false ? "source" : "0.5.158"}.v1`
250
+ `tensorlake.native.worker.${false ? "source" : "0.5.159"}.v1`
251
251
  );
252
252
  var runtimes = globalThis;
253
253
  function configureNativeWorker(workerPath) {
@@ -10,7 +10,7 @@ var cancelNativeCall = /* @__PURE__ */ Symbol.for("tensorlake.native.cancel.v1")
10
10
  var closeNativeHandle = /* @__PURE__ */ Symbol.for("tensorlake.native.close.v1");
11
11
 
12
12
  // src/defaults.ts
13
- var SDK_VERSION = "0.5.158";
13
+ var SDK_VERSION = "0.5.159";
14
14
  var API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
15
15
  var API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
16
16
  var NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -206,7 +206,7 @@ var NativeWorkerClient = class {
206
206
  }
207
207
  };
208
208
  var runtimeKey = /* @__PURE__ */ Symbol.for(
209
- `tensorlake.native.worker.${false ? "source" : "0.5.158"}.v1`
209
+ `tensorlake.native.worker.${false ? "source" : "0.5.159"}.v1`
210
210
  );
211
211
  var runtimes = globalThis;
212
212
  function configureNativeWorker(workerPath) {
package/dist/index.cjs CHANGED
@@ -49,7 +49,7 @@ var init_defaults = __esm({
49
49
  "src/defaults.ts"() {
50
50
  "use strict";
51
51
  init_cjs_shims();
52
- SDK_VERSION = "0.5.158";
52
+ SDK_VERSION = "0.5.159";
53
53
  API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
54
54
  API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
55
55
  NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -184,13 +184,17 @@ var init_errors = __esm({
184
184
  statusCode;
185
185
  /** Original response body, retained for compatibility and diagnostics. */
186
186
  responseMessage;
187
+ /** Machine-readable API error code, including proxy policy failures. */
188
+ code;
187
189
  errorDetails;
188
190
  constructor(statusCode, message) {
189
191
  let failure;
192
+ let code;
190
193
  try {
191
194
  const payload = JSON.parse(message);
192
195
  if (payload && typeof payload === "object" && !Array.isArray(payload)) {
193
196
  const record = payload;
197
+ if (typeof record.code === "string") code = record.code;
194
198
  if (typeof record.sandbox_id === "string" && record.sandbox_id.trim() && (record.status === "failed" || record.status === "terminated"))
195
199
  failure = record;
196
200
  }
@@ -216,6 +220,7 @@ var init_errors = __esm({
216
220
  this.name = "RemoteAPIError";
217
221
  this.statusCode = statusCode;
218
222
  this.responseMessage = message;
223
+ this.code = code;
219
224
  }
220
225
  };
221
226
  RequestNotFinishedError = class extends Error {
@@ -512,7 +517,7 @@ var init_native_worker_client = __esm({
512
517
  }
513
518
  };
514
519
  runtimeKey = /* @__PURE__ */ Symbol.for(
515
- `tensorlake.native.worker.${false ? "source" : "0.5.158"}.v1`
520
+ `tensorlake.native.worker.${false ? "source" : "0.5.159"}.v1`
516
521
  );
517
522
  runtimes = globalThis;
518
523
  }
@@ -4933,6 +4938,12 @@ var init_client = __esm({
4933
4938
  if (options?.timeoutSecs != null) body.timeout_secs = options.timeoutSecs;
4934
4939
  if (options?.entrypoint != null) body.entrypoint = options.entrypoint;
4935
4940
  if (options?.snapshotId != null) body.snapshot_id = options.snapshotId;
4941
+ if (options?.allowUnauthenticatedAccess != null) {
4942
+ body.allow_unauthenticated_access = options.allowUnauthenticatedAccess;
4943
+ }
4944
+ if (options?.exposedPorts != null) {
4945
+ body.exposed_ports = normalizeUserPorts(options.exposedPorts);
4946
+ }
4936
4947
  if (options?.name != null) body.name = options.name;
4937
4948
  if (options?.fileSystems != null && options.fileSystems.length > 0) {
4938
4949
  body.file_systems = options.fileSystems.map(fileSystemMountToWire);
@@ -4944,6 +4955,7 @@ var init_client = __esm({
4944
4955
  deny_out: options?.denyOut ?? []
4945
4956
  };
4946
4957
  }
4958
+ if (options?.autoResume != null) body.auto_resume = options.autoResume;
4947
4959
  if (options?.maxPendingSecs != null) {
4948
4960
  if (!Number.isInteger(options.maxPendingSecs) || options.maxPendingSecs < 0) {
4949
4961
  throw new SandboxError("maxPendingSecs must be a non-negative integer");
@@ -5060,13 +5072,14 @@ var init_client = __esm({
5060
5072
  const resizing = Object.keys(resources).length > 0;
5061
5073
  if (resizing) {
5062
5074
  validateResizeWait(options);
5063
- if (options.name != null || options.allowUnauthenticatedAccess != null || options.exposedPorts != null || options.network !== void 0) {
5075
+ if (options.name != null || options.allowUnauthenticatedAccess != null || options.exposedPorts != null || options.autoResume != null || options.network !== void 0) {
5064
5076
  throw new SandboxError(
5065
5077
  "resources cannot be combined with other sandbox update fields"
5066
5078
  );
5067
5079
  }
5068
5080
  body.resources = resources;
5069
5081
  }
5082
+ if (options.autoResume != null) body.auto_resume = options.autoResume;
5070
5083
  if (options.name != null) body.name = options.name;
5071
5084
  if (options.allowUnauthenticatedAccess != null) {
5072
5085
  body.allow_unauthenticated_access = options.allowUnauthenticatedAccess;
@@ -5161,28 +5174,19 @@ var init_client = __esm({
5161
5174
  * cannot. By default blocks until the sandbox is fully `Suspended`. Pass
5162
5175
  * `{ wait: false }` to return immediately after the request is sent
5163
5176
  * (fire-and-return); the server processes the suspend asynchronously.
5177
+ *
5178
+ * The server answers as soon as the suspend completes. When its wait runs
5179
+ * out first, or the server does not support waiting, the rest of `timeout`
5180
+ * is spent polling every `pollInterval` seconds.
5164
5181
  */
5165
5182
  async suspend(sandboxId, options) {
5166
- await callNative(() => this.native.suspendSandbox(sandboxId), {
5183
+ await this.changeLifecycle(
5167
5184
  sandboxId,
5168
- notFoundKind: "sandbox"
5169
- });
5170
- if (options?.wait === false) return;
5171
- const timeout = options?.timeout ?? 300;
5172
- const pollInterval = options?.pollInterval ?? 1;
5173
- const deadline = Date.now() + timeout * 1e3;
5174
- while (Date.now() < deadline) {
5175
- const info = await this.get(sandboxId);
5176
- if (info.status === "suspended" /* SUSPENDED */) return;
5177
- if (info.status === "terminated" /* TERMINATED */) {
5178
- throw new SandboxError(
5179
- `Sandbox ${sandboxId} terminated while waiting for suspend`
5180
- );
5181
- }
5182
- await sleep2(pollInterval * 1e3);
5183
- }
5184
- throw new SandboxError(
5185
- `Sandbox ${sandboxId} did not suspend within ${timeout}s`
5185
+ "suspend",
5186
+ "suspended" /* SUSPENDED */,
5187
+ () => this.native.suspendSandbox(sandboxId),
5188
+ (waitSec) => this.native.suspendSandboxAndWait(sandboxId, waitSec),
5189
+ options
5186
5190
  );
5187
5191
  }
5188
5192
  /**
@@ -5191,28 +5195,58 @@ var init_client = __esm({
5191
5195
  * By default blocks until the sandbox is `Running` and routable. Pass
5192
5196
  * `{ wait: false }` to return immediately after the request is sent
5193
5197
  * (fire-and-return); the server processes the resume asynchronously.
5198
+ *
5199
+ * The server answers as soon as the sandbox runs. When its wait runs out
5200
+ * first, or the server does not support waiting, the rest of `timeout` is
5201
+ * spent polling every `pollInterval` seconds.
5194
5202
  */
5195
5203
  async resume(sandboxId, options) {
5196
- await callNative(() => this.native.resumeSandbox(sandboxId), {
5204
+ await this.changeLifecycle(
5197
5205
  sandboxId,
5198
- notFoundKind: "sandbox"
5199
- });
5200
- if (options?.wait === false) return;
5206
+ "resume",
5207
+ "running" /* RUNNING */,
5208
+ () => this.native.resumeSandbox(sandboxId),
5209
+ (waitSec) => this.native.resumeSandboxAndWait(sandboxId, waitSec),
5210
+ options
5211
+ );
5212
+ }
5213
+ /**
5214
+ * Send a suspend or resume. With `wait`, the server waits for `target` and
5215
+ * answers whether it was reached; when its wait runs out first, the rest of
5216
+ * the timeout is spent polling.
5217
+ */
5218
+ async changeLifecycle(sandboxId, action, target, send, sendAndWait, options) {
5219
+ const context = { sandboxId, notFoundKind: "sandbox" };
5220
+ if (options?.wait === false) {
5221
+ await callNative(send, context);
5222
+ return;
5223
+ }
5201
5224
  const timeout = options?.timeout ?? 300;
5202
5225
  const pollInterval = options?.pollInterval ?? 1;
5203
5226
  const deadline = Date.now() + timeout * 1e3;
5227
+ let settled;
5228
+ try {
5229
+ settled = await callNative(() => sendAndWait(timeout), context);
5230
+ } catch (error) {
5231
+ if (!(error instanceof RemoteAPIError) || error.statusCode !== 409) {
5232
+ throw error;
5233
+ }
5234
+ if ((await this.get(sandboxId)).status === target) return;
5235
+ throw error;
5236
+ }
5237
+ if (settled) return;
5204
5238
  while (Date.now() < deadline) {
5205
5239
  const info = await this.get(sandboxId);
5206
- if (info.status === "running" /* RUNNING */) return;
5240
+ if (info.status === target) return;
5207
5241
  if (info.status === "terminated" /* TERMINATED */) {
5208
5242
  throw new SandboxError(
5209
- `Sandbox ${sandboxId} terminated while waiting for resume`
5243
+ `Sandbox ${sandboxId} terminated while waiting for ${action}`
5210
5244
  );
5211
5245
  }
5212
5246
  await sleep2(pollInterval * 1e3);
5213
5247
  }
5214
5248
  throw new SandboxError(
5215
- `Sandbox ${sandboxId} did not resume within ${timeout}s`
5249
+ `Sandbox ${sandboxId} did not ${action} within ${timeout}s`
5216
5250
  );
5217
5251
  }
5218
5252
  /**
@@ -5489,6 +5523,11 @@ var init_client = __esm({
5489
5523
  * claim that is still starting is then waited on the same way.
5490
5524
  */
5491
5525
  async createAndConnect(options) {
5526
+ if (options?.poolId != null && (options.allowUnauthenticatedAccess != null || options.exposedPorts != null)) {
5527
+ throw new SandboxError(
5528
+ "allowUnauthenticatedAccess and exposedPorts cannot be combined with poolId: pool claims inherit access settings from the pool."
5529
+ );
5530
+ }
5492
5531
  const opStart = nowMs();
5493
5532
  const requestTimeout = options?.requestTimeout ?? options?.startupTimeout ?? this.requestTimeoutMs / 1e3;
5494
5533
  const requestClient = this.withRequestTimeout(requestTimeout);
@@ -5501,6 +5540,9 @@ var init_client = __esm({
5501
5540
  const requestedName = options?.poolId != null ? null : options?.name ?? null;
5502
5541
  const createStart = nowMs();
5503
5542
  let result;
5543
+ if (options?.poolId != null && options.autoResume != null) {
5544
+ throw new SandboxError("autoResume cannot be set when claiming from a pool");
5545
+ }
5504
5546
  if (options?.poolId != null) {
5505
5547
  result = await requestClient.claim(options.poolId, {
5506
5548
  fileSystems: options.fileSystems