tensorlake 0.5.0 → 0.5.1

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.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/dist/index.cjs CHANGED
@@ -3182,8 +3182,11 @@ var init_sandbox = __esm({
3182
3182
  wsHeaders;
3183
3183
  ownsSandbox = false;
3184
3184
  lifecycleClient = null;
3185
+ lifecycleIdentifier;
3186
+ sandboxName = null;
3185
3187
  constructor(options) {
3186
3188
  this.sandboxId = options.sandboxId;
3189
+ this.lifecycleIdentifier = options.sandboxId;
3187
3190
  const proxyUrl = options.proxyUrl ?? SANDBOX_PROXY_URL;
3188
3191
  const { baseUrl, hostHeader } = resolveProxyTarget(proxyUrl, options.sandboxId);
3189
3192
  this.baseUrl = baseUrl;
@@ -3209,6 +3212,17 @@ var init_sandbox = __esm({
3209
3212
  routingHint: options.routingHint
3210
3213
  });
3211
3214
  }
3215
+ get name() {
3216
+ return this.sandboxName;
3217
+ }
3218
+ /** @internal Used by client wiring to keep locally cached name in sync. */
3219
+ _setName(name) {
3220
+ this.sandboxName = name;
3221
+ }
3222
+ /** @internal Used by lifecycle operations to pin to canonical sandbox ID. */
3223
+ _setLifecycleIdentifier(identifier) {
3224
+ this.lifecycleIdentifier = identifier;
3225
+ }
3212
3226
  /** @internal Used by SandboxClient.createAndConnect to set ownership. */
3213
3227
  _setOwner(client) {
3214
3228
  this.ownsSandbox = true;
@@ -3246,9 +3260,15 @@ var init_sandbox = __esm({
3246
3260
  /* _internal */
3247
3261
  true
3248
3262
  );
3249
- await client.get(options.sandboxId);
3250
- const sandbox = client.connect(options.sandboxId, options.proxyUrl, options.routingHint);
3263
+ const info = await client.get(options.sandboxId);
3264
+ const sandbox = client.connect(
3265
+ info.sandboxId,
3266
+ options.proxyUrl,
3267
+ options.routingHint ?? info.routingHint
3268
+ );
3251
3269
  sandbox.lifecycleClient = client;
3270
+ sandbox._setLifecycleIdentifier(info.sandboxId);
3271
+ sandbox._setName(info.name ?? null);
3252
3272
  return sandbox;
3253
3273
  }
3254
3274
  // --- Static snapshot management ---
@@ -3281,6 +3301,32 @@ var init_sandbox = __esm({
3281
3301
  }
3282
3302
  return this.lifecycleClient;
3283
3303
  }
3304
+ /**
3305
+ * Fetch the current sandbox status from the server.
3306
+ *
3307
+ * Always hits the network — the value is not cached locally because the
3308
+ * status changes over the sandbox's lifecycle.
3309
+ */
3310
+ async status() {
3311
+ const client = this.requireLifecycleClient("read_status");
3312
+ const info = await client.get(this.lifecycleIdentifier);
3313
+ this._setLifecycleIdentifier(info.sandboxId);
3314
+ this._setName(info.name ?? null);
3315
+ return info.status;
3316
+ }
3317
+ /**
3318
+ * Update this sandbox's properties (name, exposed ports, proxy auth).
3319
+ *
3320
+ * Naming an ephemeral sandbox makes it non-ephemeral and enables
3321
+ * suspend/resume.
3322
+ */
3323
+ async update(options) {
3324
+ const client = this.requireLifecycleClient("update");
3325
+ const info = await client.update(this.lifecycleIdentifier, options);
3326
+ this._setLifecycleIdentifier(info.sandboxId);
3327
+ this._setName(info.name ?? null);
3328
+ return info;
3329
+ }
3284
3330
  /**
3285
3331
  * Suspend this sandbox.
3286
3332
  *
@@ -3289,7 +3335,7 @@ var init_sandbox = __esm({
3289
3335
  */
3290
3336
  async suspend(options) {
3291
3337
  const client = this.requireLifecycleClient("suspend");
3292
- await client.suspend(this.sandboxId, options);
3338
+ await client.suspend(this.lifecycleIdentifier, options);
3293
3339
  }
3294
3340
  /**
3295
3341
  * Resume this sandbox.
@@ -3299,7 +3345,7 @@ var init_sandbox = __esm({
3299
3345
  */
3300
3346
  async resume(options) {
3301
3347
  const client = this.requireLifecycleClient("resume");
3302
- await client.resume(this.sandboxId, options);
3348
+ await client.resume(this.lifecycleIdentifier, options);
3303
3349
  }
3304
3350
  /**
3305
3351
  * Create a snapshot of this sandbox's filesystem and wait for it to
@@ -3312,10 +3358,10 @@ var init_sandbox = __esm({
3312
3358
  async checkpoint(options) {
3313
3359
  const client = this.requireLifecycleClient("checkpoint");
3314
3360
  if (options?.wait === false) {
3315
- await client.snapshot(this.sandboxId, { contentMode: options.contentMode });
3361
+ await client.snapshot(this.lifecycleIdentifier, { contentMode: options.contentMode });
3316
3362
  return void 0;
3317
3363
  }
3318
- return client.snapshotAndWait(this.sandboxId, {
3364
+ return client.snapshotAndWait(this.lifecycleIdentifier, {
3319
3365
  timeout: options?.timeout,
3320
3366
  pollInterval: options?.pollInterval,
3321
3367
  contentMode: options?.contentMode
@@ -3327,7 +3373,8 @@ var init_sandbox = __esm({
3327
3373
  async listSnapshots() {
3328
3374
  const client = this.requireLifecycleClient("listSnapshots");
3329
3375
  const all = await client.listSnapshots();
3330
- return all.filter((s) => s.sandboxId === this.sandboxId);
3376
+ const filtered = all.filter((s) => s.sandboxId === this.lifecycleIdentifier);
3377
+ return Object.assign(filtered, { traceId: all.traceId });
3331
3378
  }
3332
3379
  /** Close the HTTP client. The sandbox keeps running. */
3333
3380
  close() {
@@ -3340,7 +3387,7 @@ var init_sandbox = __esm({
3340
3387
  this.lifecycleClient = null;
3341
3388
  this.close();
3342
3389
  if (client) {
3343
- await client.delete(this.sandboxId);
3390
+ await client.delete(this.lifecycleIdentifier);
3344
3391
  }
3345
3392
  }
3346
3393
  // --- High-level convenience ---
@@ -3421,7 +3468,8 @@ var init_sandbox = __esm({
3421
3468
  "GET",
3422
3469
  "/api/v1/processes"
3423
3470
  );
3424
- return (raw.processes ?? []).map((p) => fromSnakeKeys(p));
3471
+ const processes = (raw.processes ?? []).map((p) => fromSnakeKeys(p));
3472
+ return Object.assign(processes, { traceId: raw.traceId });
3425
3473
  }
3426
3474
  /** Get current status and metadata for a process by PID. */
3427
3475
  async getProcess(pid) {
@@ -3758,7 +3806,7 @@ var init_client = __esm({
3758
3806
  resources: {
3759
3807
  cpus: options?.cpus ?? 1,
3760
3808
  memory_mb: options?.memoryMb ?? 1024,
3761
- ephemeral_disk_mb: options?.ephemeralDiskMb ?? 1024
3809
+ ...options?.diskMb != null ? { disk_mb: options.diskMb } : {}
3762
3810
  }
3763
3811
  };
3764
3812
  if (options?.image != null) body.image = options.image;
@@ -3796,9 +3844,10 @@ var init_client = __esm({
3796
3844
  "GET",
3797
3845
  this.path("sandboxes")
3798
3846
  );
3799
- return (raw.sandboxes ?? []).map(
3847
+ const sandboxes = (raw.sandboxes ?? []).map(
3800
3848
  (s) => fromSnakeKeys(s, "sandboxId")
3801
3849
  );
3850
+ return Object.assign(sandboxes, { traceId: raw.traceId });
3802
3851
  }
3803
3852
  /** Update sandbox properties such as name, exposed ports, and proxy auth settings. */
3804
3853
  async update(sandboxId, options) {
@@ -3968,9 +4017,10 @@ var init_client = __esm({
3968
4017
  "GET",
3969
4018
  this.path("snapshots")
3970
4019
  );
3971
- return (raw.snapshots ?? []).map(
4020
+ const snapshots = (raw.snapshots ?? []).map(
3972
4021
  (s) => fromSnakeKeys(s, "snapshotId")
3973
4022
  );
4023
+ return Object.assign(snapshots, { traceId: raw.traceId });
3974
4024
  }
3975
4025
  /** Delete a snapshot by ID. */
3976
4026
  async deleteSnapshot(snapshotId) {
@@ -4050,9 +4100,10 @@ var init_client = __esm({
4050
4100
  "GET",
4051
4101
  this.path("sandbox-pools")
4052
4102
  );
4053
- return (raw.pools ?? []).map(
4103
+ const pools = (raw.pools ?? []).map(
4054
4104
  (p) => fromSnakeKeys(p, "poolId")
4055
4105
  );
4106
+ return Object.assign(pools, { traceId: raw.traceId });
4056
4107
  }
4057
4108
  /** Replace the configuration of an existing sandbox pool. */
4058
4109
  async updatePool(poolId, options) {
@@ -4107,26 +4158,24 @@ var init_client = __esm({
4107
4158
  */
4108
4159
  async createAndConnect(options) {
4109
4160
  const startupTimeout = options?.startupTimeout ?? 60;
4110
- let result;
4111
- if (options?.poolId != null) {
4112
- result = await this.claim(options.poolId);
4113
- } else {
4114
- result = await this.create(options);
4115
- }
4116
- if (result.status === "running" /* RUNNING */) {
4117
- const sandbox = this.connect(result.sandboxId, options?.proxyUrl, result.routingHint);
4161
+ const result = options?.poolId != null ? await this.claim(options.poolId) : await this.create(options);
4162
+ const requestedName = options?.poolId != null ? null : options?.name ?? null;
4163
+ const finishConnect = (routingHint, name) => {
4164
+ const sandbox = this.connect(result.sandboxId, options?.proxyUrl, routingHint);
4118
4165
  sandbox._setOwner(this);
4119
4166
  sandbox.traceId = result.traceId;
4167
+ sandbox._setLifecycleIdentifier(result.sandboxId);
4168
+ sandbox._setName(name ?? requestedName);
4120
4169
  return sandbox;
4170
+ };
4171
+ if (result.status === "running" /* RUNNING */) {
4172
+ return finishConnect(result.routingHint, result.name);
4121
4173
  }
4122
4174
  const deadline = Date.now() + startupTimeout * 1e3;
4123
4175
  while (Date.now() < deadline) {
4124
4176
  const info = await this.get(result.sandboxId);
4125
4177
  if (info.status === "running" /* RUNNING */) {
4126
- const sandbox = this.connect(result.sandboxId, options?.proxyUrl, info.routingHint);
4127
- sandbox._setOwner(this);
4128
- sandbox.traceId = result.traceId;
4129
- return sandbox;
4178
+ return finishConnect(info.routingHint, info.name);
4130
4179
  }
4131
4180
  if (info.status === "terminated" /* TERMINATED */) {
4132
4181
  throw new SandboxError(
@@ -4965,7 +5014,8 @@ async function createSandboxImage(source, options = {}, deps = {}) {
4965
5014
  sandbox = await client.createAndConnect({
4966
5015
  ...plan.baseImage == null ? {} : { image: plan.baseImage },
4967
5016
  cpus: options.cpus ?? 2,
4968
- memoryMb: options.memoryMb ?? 4096
5017
+ memoryMb: options.memoryMb ?? 4096,
5018
+ ...options.diskMb != null ? { diskMb: options.diskMb } : {}
4969
5019
  });
4970
5020
  emit({
4971
5021
  type: "status",
@@ -4978,8 +5028,7 @@ async function createSandboxImage(source, options = {}, deps = {}) {
4978
5028
  });
4979
5029
  emit({
4980
5030
  type: "snapshot_created",
4981
- snapshot_id: snapshot.snapshotId,
4982
- snapshot_uri: snapshot.snapshotUri ?? null
5031
+ snapshot_id: snapshot.snapshotId
4983
5032
  });
4984
5033
  if (!snapshot.snapshotUri) {
4985
5034
  throw new Error(
@@ -5023,27 +5072,33 @@ async function runCreateSandboxImageCli(argv = process.argv.slice(2)) {
5023
5072
  name: { type: "string", short: "n" },
5024
5073
  cpus: { type: "string" },
5025
5074
  memory: { type: "string" },
5075
+ disk: { type: "string" },
5026
5076
  public: { type: "boolean", default: false }
5027
5077
  }
5028
5078
  });
5029
5079
  const dockerfilePath = parsed.positionals[0];
5030
5080
  if (!dockerfilePath) {
5031
- throw new Error("Usage: tensorlake-create-sandbox-image <dockerfile_path> [--name NAME] [--cpus N] [--memory MB] [--public]");
5081
+ throw new Error("Usage: tensorlake-create-sandbox-image <dockerfile_path> [--name NAME] [--cpus N] [--memory MB] [--disk GB] [--public]");
5032
5082
  }
5033
5083
  const cpus = parsed.values.cpus != null ? Number(parsed.values.cpus) : void 0;
5034
5084
  const memoryMb = parsed.values.memory != null ? Number(parsed.values.memory) : void 0;
5085
+ const diskGb = parsed.values.disk != null ? Number(parsed.values.disk) : void 0;
5035
5086
  if (cpus != null && !Number.isFinite(cpus)) {
5036
5087
  throw new Error(`Invalid --cpus value: ${parsed.values.cpus}`);
5037
5088
  }
5038
5089
  if (memoryMb != null && !Number.isInteger(memoryMb)) {
5039
5090
  throw new Error(`Invalid --memory value: ${parsed.values.memory}`);
5040
5091
  }
5092
+ if (diskGb != null && !Number.isInteger(diskGb)) {
5093
+ throw new Error(`Invalid --disk value: ${parsed.values.disk}`);
5094
+ }
5041
5095
  await createSandboxImage(
5042
5096
  dockerfilePath,
5043
5097
  {
5044
5098
  registeredName: parsed.values.name,
5045
5099
  cpus,
5046
5100
  memoryMb,
5101
+ diskMb: diskGb != null ? diskGb * 1024 : void 0,
5047
5102
  isPublic: parsed.values.public
5048
5103
  },
5049
5104
  { emit: ndjsonStdoutEmit }