@tensorlakeai/tensorlake 0.5.157 → 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.157"}.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.157"}.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.157";
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.157"}.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.157";
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.157"}.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.157";
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.157"}.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
  /**
@@ -5475,10 +5509,9 @@ var init_client = __esm({
5475
5509
  /**
5476
5510
  * Create a sandbox, wait for it to reach `Running`, and return a connected handle.
5477
5511
  *
5478
- * This is `create({ wait: false })` followed by `PendingSandbox.ready()`
5479
- * polling every `pollInterval` seconds, with `requestTimeout` as the wait
5480
- * budget, in one call. The returned `Sandbox` auto-terminates when
5481
- * `terminate()` is called.
5512
+ * The create waits on the server, which answers as soon as the sandbox
5513
+ * runs, with `requestTimeout` as the wait budget. The returned `Sandbox`
5514
+ * auto-terminates when `terminate()` is called.
5482
5515
  *
5483
5516
  * **When the wait runs out the sandbox is not deleted.** A `SandboxPending`
5484
5517
  * is thrown with the sandbox id, and the sandbox keeps its place in the
@@ -5490,6 +5523,11 @@ var init_client = __esm({
5490
5523
  * claim that is still starting is then waited on the same way.
5491
5524
  */
5492
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
+ }
5493
5531
  const opStart = nowMs();
5494
5532
  const requestTimeout = options?.requestTimeout ?? options?.startupTimeout ?? this.requestTimeoutMs / 1e3;
5495
5533
  const requestClient = this.withRequestTimeout(requestTimeout);
@@ -5500,11 +5538,13 @@ var init_client = __esm({
5500
5538
  pool_id: options?.poolId
5501
5539
  });
5502
5540
  const requestedName = options?.poolId != null ? null : options?.name ?? null;
5503
- let sandboxId;
5504
- let traceId;
5505
5541
  const createStart = nowMs();
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
+ }
5506
5546
  if (options?.poolId != null) {
5507
- const result = await requestClient.claim(options.poolId, {
5547
+ result = await requestClient.claim(options.poolId, {
5508
5548
  fileSystems: options.fileSystems
5509
5549
  });
5510
5550
  logSdkTiming("sandbox.create", "claim_response", createStart, {
@@ -5512,84 +5552,55 @@ var init_client = __esm({
5512
5552
  status: result.status,
5513
5553
  server_trace_id: result.traceId
5514
5554
  });
5515
- if (result.status === "running" /* RUNNING */) {
5516
- const explicitProxyUrl = options?.proxyUrl ?? explicitProxyUrlOverride() ?? void 0;
5517
- const selectedProxyUrl = await this.native.selectSandboxProxyUrl(
5518
- result.sandboxId,
5519
- result.sandboxUrl ?? null,
5520
- result.ingressEndpoint ?? null,
5521
- explicitProxyUrl ?? null
5522
- );
5523
- const sandbox2 = requestClient.connect(
5524
- result.sandboxId,
5525
- selectedProxyUrl,
5526
- result.routingHint,
5527
- requestTimeout,
5528
- explicitProxyUrl
5529
- );
5530
- sandbox2._setOwner(requestClient);
5531
- sandbox2.traceId = result.traceId;
5532
- sandbox2._setLifecycleIdentifier(result.sandboxId);
5533
- sandbox2._setName(result.name ?? requestedName);
5534
- logSdkTiming("sandbox.create", "complete", opStart, {
5535
- sandbox_id: result.sandboxId,
5536
- status: "running" /* RUNNING */,
5537
- server_trace_id: result.traceId
5538
- });
5539
- return sandbox2;
5540
- }
5541
- if (result.status === "suspended" /* SUSPENDED */ || result.status === "terminated" /* TERMINATED */ || result.status === "failed" /* FAILED */) {
5542
- throw startupFailure(result.sandboxId, result.status, {
5543
- errorDetails: result.errorDetails,
5544
- terminationReason: result.terminationReason ?? result.reason
5545
- });
5546
- }
5547
- sandboxId = result.sandboxId;
5548
- traceId = result.traceId;
5549
5555
  } else {
5550
- const pending = await requestClient.requestPending(options, {
5551
- ownsSandbox: true
5556
+ const body = _SandboxClient.buildCreateRequestBody({
5557
+ ...options,
5558
+ wait: void 0
5552
5559
  });
5560
+ result = await requestClient.tracedJson(
5561
+ () => requestClient.native.createSandboxAndWait(JSON.stringify(body)),
5562
+ "sandboxId"
5563
+ );
5553
5564
  logSdkTiming("sandbox.create", "create_response", createStart, {
5554
- sandbox_id: pending.sandboxId,
5555
- status: pending.state,
5556
- server_trace_id: pending.traceId
5565
+ sandbox_id: result.sandboxId,
5566
+ status: result.status,
5567
+ server_trace_id: result.traceId
5568
+ });
5569
+ }
5570
+ if (result.status === "running" /* RUNNING */) {
5571
+ const explicitProxyUrl = options?.proxyUrl ?? explicitProxyUrlOverride() ?? void 0;
5572
+ const selectedProxyUrl = await this.native.selectSandboxProxyUrl(
5573
+ result.sandboxId,
5574
+ result.sandboxUrl ?? null,
5575
+ result.ingressEndpoint ?? null,
5576
+ explicitProxyUrl ?? null
5577
+ );
5578
+ const sandbox2 = requestClient.connect(
5579
+ result.sandboxId,
5580
+ selectedProxyUrl,
5581
+ result.routingHint,
5582
+ requestTimeout,
5583
+ explicitProxyUrl
5584
+ );
5585
+ sandbox2._setOwner(requestClient);
5586
+ sandbox2.traceId = result.traceId;
5587
+ sandbox2._setLifecycleIdentifier(result.sandboxId);
5588
+ sandbox2._setName(result.name ?? requestedName);
5589
+ logSdkTiming("sandbox.create", "complete", opStart, {
5590
+ sandbox_id: result.sandboxId,
5591
+ status: "running" /* RUNNING */,
5592
+ server_trace_id: result.traceId
5593
+ });
5594
+ return sandbox2;
5595
+ }
5596
+ if (result.status === "suspended" /* SUSPENDED */ || result.status === "terminated" /* TERMINATED */ || result.status === "failed" /* FAILED */) {
5597
+ throw startupFailure(result.sandboxId, result.status, {
5598
+ errorDetails: result.errorDetails,
5599
+ terminationReason: result.terminationReason ?? result.reason
5557
5600
  });
5558
- sandboxId = pending.sandboxId;
5559
- traceId = pending.traceId;
5560
- if (pending.state === "running" /* RUNNING */) {
5561
- const explicitProxyUrl = options?.proxyUrl ?? explicitProxyUrlOverride() ?? void 0;
5562
- const selectedProxyUrl = await this.native.selectSandboxProxyUrl(
5563
- sandboxId,
5564
- pending.sandboxUrl ?? null,
5565
- pending.ingressEndpoint ?? null,
5566
- explicitProxyUrl ?? null
5567
- );
5568
- const sandbox2 = requestClient.connect(
5569
- sandboxId,
5570
- selectedProxyUrl,
5571
- pending.routingHint,
5572
- requestTimeout,
5573
- explicitProxyUrl
5574
- );
5575
- sandbox2._setOwner(requestClient);
5576
- sandbox2.traceId = traceId;
5577
- sandbox2._setLifecycleIdentifier(sandboxId);
5578
- sandbox2._setName(pending.name ?? requestedName);
5579
- logSdkTiming("sandbox.create", "complete", opStart, {
5580
- sandbox_id: sandboxId,
5581
- status: "running" /* RUNNING */,
5582
- server_trace_id: traceId
5583
- });
5584
- return sandbox2;
5585
- }
5586
- if (pending.state === "terminated" /* TERMINATED */ || pending.state === "failed" /* FAILED */) {
5587
- throw startupFailure(sandboxId, pending.state, {
5588
- errorDetails: pending.errorDetails,
5589
- terminationReason: pending.terminationReason ?? pending.reason
5590
- });
5591
- }
5592
5601
  }
5602
+ const sandboxId = result.sandboxId;
5603
+ const traceId = result.traceId;
5593
5604
  const remaining = Math.max(0, (deadline - Date.now()) / 1e3);
5594
5605
  const observed = await requestClient.waitForSandbox(
5595
5606
  sandboxId,