tensorlake 0.5.35 → 0.5.37

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
@@ -35,7 +35,7 @@ var SDK_VERSION, API_URL, API_KEY, NAMESPACE, SANDBOX_PROXY_URL, DEFAULT_HTTP_TI
35
35
  var init_defaults = __esm({
36
36
  "src/defaults.ts"() {
37
37
  "use strict";
38
- SDK_VERSION = "0.5.35";
38
+ SDK_VERSION = "0.5.37";
39
39
  API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
40
40
  API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
41
41
  NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
@@ -155,6 +155,56 @@ var init_errors = __esm({
155
155
  }
156
156
  });
157
157
 
158
+ // src/sdk-timings.ts
159
+ function sdkTimingsEnabled() {
160
+ const value = process.env[SDK_TIMINGS_ENV_VAR];
161
+ return value === "1" || value === "true" || value === "yes";
162
+ }
163
+ function sdkTimingPayloadsEnabled() {
164
+ const value = process.env[SDK_TIMING_PAYLOADS_ENV_VAR];
165
+ return value === "1" || value === "true" || value === "yes";
166
+ }
167
+ function nowMs() {
168
+ return performance.now();
169
+ }
170
+ function logSdkTiming(op, phase, startedAt, fields = {}) {
171
+ if (!sdkTimingsEnabled()) return;
172
+ logSdkTimingEvent(op, phase, {
173
+ ...fields,
174
+ duration_ms: Math.round((nowMs() - startedAt) * 100) / 100
175
+ });
176
+ }
177
+ function logSdkTimingEvent(op, phase, fields = {}) {
178
+ if (!sdkTimingsEnabled()) return;
179
+ const parts = [
180
+ "[tensorlake:sdk-timing]",
181
+ `op=${op}`,
182
+ `phase=${phase}`
183
+ ];
184
+ for (const [key, value] of Object.entries(fields)) {
185
+ if (value == null) continue;
186
+ parts.push(`${key}=${formatSdkTimingValue(value)}`);
187
+ }
188
+ console.error(parts.join(" "));
189
+ }
190
+ function formatSdkTimingValue(value) {
191
+ if (typeof value === "number" || typeof value === "boolean") {
192
+ return String(value);
193
+ }
194
+ if (/^[A-Za-z0-9_./:@-]+$/.test(value)) {
195
+ return value;
196
+ }
197
+ return JSON.stringify(value);
198
+ }
199
+ var SDK_TIMINGS_ENV_VAR, SDK_TIMING_PAYLOADS_ENV_VAR;
200
+ var init_sdk_timings = __esm({
201
+ "src/sdk-timings.ts"() {
202
+ "use strict";
203
+ SDK_TIMINGS_ENV_VAR = "TENSORLAKE_SDK_TIMINGS";
204
+ SDK_TIMING_PAYLOADS_ENV_VAR = "TENSORLAKE_SDK_TIMING_PAYLOADS";
205
+ }
206
+ });
207
+
158
208
  // src/http.ts
159
209
  function withTraceId(value, traceId) {
160
210
  if (value == null) {
@@ -175,6 +225,10 @@ function normalizeRequestBody(body) {
175
225
  }
176
226
  return body;
177
227
  }
228
+ function stripPathPayload(path2) {
229
+ const queryStart = path2.search(/[?#]/);
230
+ return queryStart === -1 ? path2 : path2.slice(0, queryStart);
231
+ }
178
232
  function throwMappedError(status, body, path2) {
179
233
  let message = body;
180
234
  try {
@@ -225,6 +279,7 @@ var init_http = __esm({
225
279
  import_undici = require("undici");
226
280
  init_defaults();
227
281
  init_errors();
282
+ init_sdk_timings();
228
283
  REQUEST_TIMEOUT_HEADER = "X-Tensorlake-Request-Timeout-Ms";
229
284
  (0, import_undici.setGlobalDispatcher)(
230
285
  new import_undici.Agent({
@@ -351,9 +406,18 @@ var init_http = __esm({
351
406
  const { traceparent, traceId } = _HttpClient.makeTraceparent();
352
407
  headers["traceparent"] = traceparent;
353
408
  let lastError;
409
+ const operationStart = nowMs();
410
+ const timingPath = sdkTimingPayloadsEnabled() ? path2 : stripPathPayload(path2);
354
411
  for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
355
412
  if (attempt > 0) {
356
413
  const delay = this.retryBackoffMs * Math.pow(2, attempt - 1);
414
+ logSdkTimingEvent("http.request", "retry_sleep_start", {
415
+ method,
416
+ path: timingPath,
417
+ attempt,
418
+ delay_ms: delay,
419
+ server_trace_id: traceId
420
+ });
357
421
  await sleep(delay);
358
422
  }
359
423
  this.abortController = new AbortController();
@@ -363,6 +427,7 @@ var init_http = __esm({
363
427
  this.abortController?.abort();
364
428
  }, this.timeoutMs);
365
429
  const combinedSignal = signal ? anySignal([signal, this.abortController.signal]) : this.abortController.signal;
430
+ const attemptStart = nowMs();
366
431
  try {
367
432
  const response = await (0, import_undici.fetch)(url, {
368
433
  method,
@@ -371,15 +436,45 @@ var init_http = __esm({
371
436
  signal: combinedSignal
372
437
  });
373
438
  if (timeoutId != null) clearTimeout(timeoutId);
374
- if (response.ok) return { response, traceId };
439
+ logSdkTiming("http.request", "headers", attemptStart, {
440
+ method,
441
+ path: timingPath,
442
+ status: response.status,
443
+ attempt,
444
+ server_trace_id: traceId
445
+ });
446
+ if (response.ok) {
447
+ logSdkTiming("http.request", "complete", operationStart, {
448
+ method,
449
+ path: timingPath,
450
+ status: response.status,
451
+ attempts: attempt + 1,
452
+ server_trace_id: traceId
453
+ });
454
+ return { response, traceId };
455
+ }
375
456
  if (retryableStatusCodes.has(response.status) && attempt < this.maxRetries) {
376
457
  lastError = new RemoteAPIError(
377
458
  response.status,
378
459
  await response.text().catch(() => "")
379
460
  );
461
+ logSdkTimingEvent("http.request", "retryable_status", {
462
+ method,
463
+ path: timingPath,
464
+ status: response.status,
465
+ attempt,
466
+ server_trace_id: traceId
467
+ });
380
468
  continue;
381
469
  }
382
470
  if (allowHttpErrors || allowedErrorStatusCodes.has(response.status)) {
471
+ logSdkTiming("http.request", "complete", operationStart, {
472
+ method,
473
+ path: timingPath,
474
+ status: response.status,
475
+ attempts: attempt + 1,
476
+ server_trace_id: traceId
477
+ });
383
478
  return { response, traceId };
384
479
  }
385
480
  const errorBody = await response.text().catch(() => "");
@@ -395,6 +490,13 @@ var init_http = __esm({
395
490
  });
396
491
  }
397
492
  lastError = err instanceof Error ? err : new Error(String(err));
493
+ logSdkTiming("http.request", "error", attemptStart, {
494
+ method,
495
+ path: timingPath,
496
+ attempt,
497
+ server_trace_id: traceId,
498
+ error: timedOut ? `request timed out after ${this.timeoutMs}ms` : describeError(err)
499
+ });
398
500
  if (attempt >= this.maxRetries) {
399
501
  const detail = timedOut ? `request timed out after ${this.timeoutMs}ms` : describeError(err);
400
502
  throw new SandboxConnectionError(detail, { cause: err });
@@ -3108,6 +3210,7 @@ var init_sandbox = __esm({
3108
3210
  init_models();
3109
3211
  init_tunnel();
3110
3212
  init_sse();
3213
+ init_sdk_timings();
3111
3214
  init_url();
3112
3215
  import_ws2 = __toESM(require("ws"), 1);
3113
3216
  DEFAULT_PROCESS_USER = "tl-user";
@@ -3136,7 +3239,12 @@ var init_sandbox = __esm({
3136
3239
  if (this.resolvePromise != null) {
3137
3240
  return this.resolvePromise;
3138
3241
  }
3139
- this.resolvePromise = this.resolveProxyInfo(this.sandbox._getLifecycleIdentifier()).then((info) => {
3242
+ const identifier = this.sandbox._getLifecycleIdentifier();
3243
+ const resolveStart = nowMs();
3244
+ logSdkTimingEvent("sandbox.proxy", "resolve_start", {
3245
+ sandbox_id: identifier
3246
+ });
3247
+ this.resolvePromise = this.resolveProxyInfo(identifier).then((info) => {
3140
3248
  this.resolveProxyInfo = void 0;
3141
3249
  this.sandbox.traceId = info.traceId;
3142
3250
  this.sandbox._setLifecycleIdentifier(info.sandboxId);
@@ -3146,6 +3254,12 @@ var init_sandbox = __esm({
3146
3254
  const nextHttp = this.configureProxy(proxyUrl, info.sandboxId, this.routingHint);
3147
3255
  this.http.close();
3148
3256
  this.http = nextHttp;
3257
+ logSdkTiming("sandbox.proxy", "resolve_complete", resolveStart, {
3258
+ sandbox_id: info.sandboxId,
3259
+ server_trace_id: info.traceId,
3260
+ routing_hint: this.routingHint,
3261
+ ingress_endpoint: info.ingressEndpoint
3262
+ });
3149
3263
  }).finally(() => {
3150
3264
  this.resolvePromise = null;
3151
3265
  });
@@ -3606,6 +3720,7 @@ var init_sandbox = __esm({
3606
3720
  * the process, streams output, and delivers the exit code over one connection.
3607
3721
  */
3608
3722
  async run(command, options) {
3723
+ const opStart = nowMs();
3609
3724
  const body = { command };
3610
3725
  if (options?.args) body.args = options.args;
3611
3726
  if (options?.env) body.env = options.env;
@@ -3613,15 +3728,28 @@ var init_sandbox = __esm({
3613
3728
  if (options?.timeout != null) body.timeout = options.timeout;
3614
3729
  const user = processUserPayload(options?.user);
3615
3730
  body.user = user;
3731
+ logSdkTimingEvent("sandbox.run", "start", {
3732
+ sandbox_id: this.sandboxId,
3733
+ command: sdkTimingPayloadsEnabled() ? command : void 0,
3734
+ command_length: command.length
3735
+ });
3736
+ const requestStart = nowMs();
3616
3737
  const sseStream = await this.http.requestStream(
3617
3738
  "POST",
3618
3739
  "/api/v1/processes/run",
3619
3740
  { json: body }
3620
3741
  );
3621
3742
  const traceId = sseStream.traceId;
3743
+ logSdkTiming("sandbox.run", "stream_headers", requestStart, {
3744
+ sandbox_id: this.sandboxId,
3745
+ server_trace_id: traceId,
3746
+ command: sdkTimingPayloadsEnabled() ? command : void 0,
3747
+ command_length: command.length
3748
+ });
3622
3749
  const stdoutLines = [];
3623
3750
  const stderrLines = [];
3624
3751
  let exitCode = -1;
3752
+ const streamStart = nowMs();
3625
3753
  for await (const raw of parseSSEStream(sseStream)) {
3626
3754
  if (typeof raw.line === "string") {
3627
3755
  if (raw.stream === "stderr") {
@@ -3637,6 +3765,20 @@ var init_sandbox = __esm({
3637
3765
  }
3638
3766
  }
3639
3767
  }
3768
+ logSdkTiming("sandbox.run", "stream_complete", streamStart, {
3769
+ sandbox_id: this.sandboxId,
3770
+ server_trace_id: traceId,
3771
+ command: sdkTimingPayloadsEnabled() ? command : void 0,
3772
+ command_length: command.length,
3773
+ exit_code: exitCode
3774
+ });
3775
+ logSdkTiming("sandbox.run", "complete", opStart, {
3776
+ sandbox_id: this.sandboxId,
3777
+ server_trace_id: traceId,
3778
+ command: sdkTimingPayloadsEnabled() ? command : void 0,
3779
+ command_length: command.length,
3780
+ exit_code: exitCode
3781
+ });
3640
3782
  return Object.assign(
3641
3783
  { exitCode, stdout: stdoutLines.join("\n"), stderr: stderrLines.join("\n") },
3642
3784
  { traceId }
@@ -4114,6 +4256,7 @@ var init_client = __esm({
4114
4256
  init_http();
4115
4257
  init_models();
4116
4258
  init_sandbox();
4259
+ init_sdk_timings();
4117
4260
  init_url();
4118
4261
  CREATE_SANDBOX_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([502, 503]);
4119
4262
  CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES = /* @__PURE__ */ new Set([504]);
@@ -4643,9 +4786,21 @@ var init_client = __esm({
4643
4786
  if (options?.poolId != null && options?.cloudInit != null) {
4644
4787
  throw new SandboxError("cloud-init cannot be used with poolId");
4645
4788
  }
4789
+ const opStart = nowMs();
4646
4790
  const requestTimeout = options?.requestTimeout ?? options?.startupTimeout ?? this.requestTimeoutMs / 1e3;
4647
4791
  const requestClient = this.withRequestTimeout(requestTimeout);
4792
+ logSdkTimingEvent("sandbox.create", "start", {
4793
+ request_timeout_s: requestTimeout,
4794
+ image: options?.image,
4795
+ pool_id: options?.poolId
4796
+ });
4797
+ const createStart = nowMs();
4648
4798
  const result = options?.poolId != null ? await requestClient.claim(options.poolId) : await requestClient.create(options);
4799
+ logSdkTiming("sandbox.create", options?.poolId != null ? "claim_response" : "create_response", createStart, {
4800
+ sandbox_id: result.sandboxId,
4801
+ status: result.status,
4802
+ server_trace_id: result.traceId
4803
+ });
4649
4804
  const requestedName = options?.poolId != null ? null : options?.name ?? null;
4650
4805
  const finishConnect = (routingHint, name, ingressEndpoint) => {
4651
4806
  const sandbox = requestClient.connect(
@@ -4658,6 +4813,13 @@ var init_client = __esm({
4658
4813
  sandbox.traceId = result.traceId;
4659
4814
  sandbox._setLifecycleIdentifier(result.sandboxId);
4660
4815
  sandbox._setName(name ?? requestedName);
4816
+ logSdkTiming("sandbox.create", "complete", opStart, {
4817
+ sandbox_id: result.sandboxId,
4818
+ status: "running" /* RUNNING */,
4819
+ server_trace_id: result.traceId,
4820
+ routing_hint: routingHint,
4821
+ ingress_endpoint: ingressEndpoint
4822
+ });
4661
4823
  return sandbox;
4662
4824
  };
4663
4825
  if (result.status === "running" /* RUNNING */) {
@@ -4682,7 +4844,13 @@ var init_client = __esm({
4682
4844
  }
4683
4845
  const deadline = Date.now() + secondsToMillis4(requestTimeout);
4684
4846
  while (Date.now() < deadline) {
4847
+ const pollStart = nowMs();
4685
4848
  const info = await requestClient.get(result.sandboxId);
4849
+ logSdkTiming("sandbox.create", "poll_response", pollStart, {
4850
+ sandbox_id: result.sandboxId,
4851
+ status: info.status,
4852
+ server_trace_id: info.traceId
4853
+ });
4686
4854
  if (info.status === "running" /* RUNNING */) {
4687
4855
  return finishConnect(info.routingHint, info.name, info.ingressEndpoint);
4688
4856
  }