tensorlake 0.5.30 → 0.5.33
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.
- package/dist/bin/darwin-arm64/tensorlake +0 -0
- package/dist/bin/darwin-arm64/tl +0 -0
- package/dist/bin/linux-x64/tensorlake +0 -0
- package/dist/bin/linux-x64/tl +0 -0
- package/dist/bin/win32-x64/tensorlake.exe +0 -0
- package/dist/bin/win32-x64/tl.exe +0 -0
- package/dist/index.cjs +195 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +72 -12
- package/dist/index.d.ts +72 -12
- package/dist/index.js +195 -47
- package/dist/index.js.map +1 -1
- package/dist/native/darwin-arm64/tensorlake-node.node +0 -0
- package/dist/native/linux-x64/tensorlake-node.node +0 -0
- package/dist/native/win32-x64/tensorlake-node.node +0 -0
- package/package.json +2 -2
|
Binary file
|
package/dist/bin/darwin-arm64/tl
CHANGED
|
Binary file
|
|
Binary file
|
package/dist/bin/linux-x64/tl
CHANGED
|
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.
|
|
38
|
+
SDK_VERSION = "0.5.33";
|
|
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";
|
|
@@ -48,6 +48,28 @@ var init_defaults = __esm({
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
// src/errors.ts
|
|
51
|
+
function describeError(err) {
|
|
52
|
+
const parts = [];
|
|
53
|
+
const seen = /* @__PURE__ */ new Set();
|
|
54
|
+
let current = err;
|
|
55
|
+
for (let depth = 0; depth < 6; depth++) {
|
|
56
|
+
if (current == null || typeof current !== "object" || seen.has(current)) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
seen.add(current);
|
|
60
|
+
const e = current;
|
|
61
|
+
const message = typeof e.message === "string" ? e.message.trim() : "";
|
|
62
|
+
const code = typeof e.code === "string" ? e.code : void 0;
|
|
63
|
+
let segment = message;
|
|
64
|
+
if (code && (!message || !message.includes(code))) {
|
|
65
|
+
segment = segment ? `${segment} (${code})` : code;
|
|
66
|
+
}
|
|
67
|
+
if (segment && !parts.includes(segment)) parts.push(segment);
|
|
68
|
+
current = e.cause;
|
|
69
|
+
}
|
|
70
|
+
if (parts.length > 0) return parts.join(": ");
|
|
71
|
+
return err instanceof Error ? err.message : String(err);
|
|
72
|
+
}
|
|
51
73
|
var SandboxException, SandboxError, SandboxConnectionError, SandboxNotFoundError, PoolNotFoundError, PoolInUseError, RemoteAPIError, RequestNotFinishedError, RequestFailedError, RequestExecutionError;
|
|
52
74
|
var init_errors = __esm({
|
|
53
75
|
"src/errors.ts"() {
|
|
@@ -65,9 +87,10 @@ var init_errors = __esm({
|
|
|
65
87
|
}
|
|
66
88
|
};
|
|
67
89
|
SandboxConnectionError = class extends SandboxError {
|
|
68
|
-
constructor(message) {
|
|
90
|
+
constructor(message, options) {
|
|
69
91
|
super(`Connection error: ${message}`);
|
|
70
92
|
this.name = "SandboxConnectionError";
|
|
93
|
+
if (options?.cause !== void 0) this.cause = options.cause;
|
|
71
94
|
}
|
|
72
95
|
};
|
|
73
96
|
SandboxNotFoundError = class extends SandboxError {
|
|
@@ -195,13 +218,14 @@ function anySignal(signals) {
|
|
|
195
218
|
function sleep(ms) {
|
|
196
219
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
197
220
|
}
|
|
198
|
-
var import_undici, HttpClient;
|
|
221
|
+
var import_undici, REQUEST_TIMEOUT_HEADER, HttpClient;
|
|
199
222
|
var init_http = __esm({
|
|
200
223
|
"src/http.ts"() {
|
|
201
224
|
"use strict";
|
|
202
225
|
import_undici = require("undici");
|
|
203
226
|
init_defaults();
|
|
204
227
|
init_errors();
|
|
228
|
+
REQUEST_TIMEOUT_HEADER = "X-Tensorlake-Request-Timeout-Ms";
|
|
205
229
|
(0, import_undici.setGlobalDispatcher)(
|
|
206
230
|
new import_undici.Agent({
|
|
207
231
|
keepAliveTimeout: 6e4,
|
|
@@ -220,10 +244,13 @@ var init_http = __esm({
|
|
|
220
244
|
this.baseUrl = url.endsWith("/") ? url.slice(0, -1) : url;
|
|
221
245
|
this.maxRetries = options.maxRetries ?? MAX_RETRIES;
|
|
222
246
|
this.retryBackoffMs = options.retryBackoffMs ?? RETRY_BACKOFF_MS;
|
|
223
|
-
this.timeoutMs = options.timeoutMs
|
|
247
|
+
this.timeoutMs = options.timeoutMs === void 0 ? DEFAULT_HTTP_TIMEOUT_MS : options.timeoutMs;
|
|
224
248
|
this.headers = {
|
|
225
249
|
"User-Agent": `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
226
250
|
};
|
|
251
|
+
if (this.timeoutMs != null) {
|
|
252
|
+
this.headers[REQUEST_TIMEOUT_HEADER] = String(this.timeoutMs);
|
|
253
|
+
}
|
|
227
254
|
if (options.apiKey) {
|
|
228
255
|
this.headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
229
256
|
}
|
|
@@ -252,7 +279,10 @@ var init_http = __esm({
|
|
|
252
279
|
const response = await this.requestResponse(method, path2, {
|
|
253
280
|
json: options?.body,
|
|
254
281
|
headers: options?.headers,
|
|
255
|
-
signal: options?.signal
|
|
282
|
+
signal: options?.signal,
|
|
283
|
+
retryableStatusCodes: options?.retryableStatusCodes,
|
|
284
|
+
allowedErrorStatusCodes: options?.allowedErrorStatusCodes,
|
|
285
|
+
allowHttpErrors: options?.allowHttpErrors
|
|
256
286
|
});
|
|
257
287
|
const text = await response.text();
|
|
258
288
|
const data = text ? JSON.parse(text) : void 0;
|
|
@@ -304,7 +334,9 @@ var init_http = __esm({
|
|
|
304
334
|
body,
|
|
305
335
|
headers,
|
|
306
336
|
options?.signal,
|
|
307
|
-
options?.allowHttpErrors ?? false
|
|
337
|
+
options?.allowHttpErrors ?? false,
|
|
338
|
+
options?.retryableStatusCodes ?? RETRYABLE_STATUS_CODES,
|
|
339
|
+
options?.allowedErrorStatusCodes ?? /* @__PURE__ */ new Set()
|
|
308
340
|
);
|
|
309
341
|
return withTraceId(response, traceId);
|
|
310
342
|
}
|
|
@@ -314,7 +346,7 @@ var init_http = __esm({
|
|
|
314
346
|
const spanId = randomHex(8);
|
|
315
347
|
return { traceparent: `00-${traceId}-${spanId}-01`, traceId };
|
|
316
348
|
}
|
|
317
|
-
async doFetch(method, path2, body, headers, signal, allowHttpErrors = false) {
|
|
349
|
+
async doFetch(method, path2, body, headers, signal, allowHttpErrors = false, retryableStatusCodes = RETRYABLE_STATUS_CODES, allowedErrorStatusCodes = /* @__PURE__ */ new Set()) {
|
|
318
350
|
const url = `${this.baseUrl}${path2}`;
|
|
319
351
|
const { traceparent, traceId } = _HttpClient.makeTraceparent();
|
|
320
352
|
headers["traceparent"] = traceparent;
|
|
@@ -325,10 +357,11 @@ var init_http = __esm({
|
|
|
325
357
|
await sleep(delay);
|
|
326
358
|
}
|
|
327
359
|
this.abortController = new AbortController();
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
360
|
+
let timedOut = false;
|
|
361
|
+
const timeoutId = this.timeoutMs == null ? null : setTimeout(() => {
|
|
362
|
+
timedOut = true;
|
|
363
|
+
this.abortController?.abort();
|
|
364
|
+
}, this.timeoutMs);
|
|
332
365
|
const combinedSignal = signal ? anySignal([signal, this.abortController.signal]) : this.abortController.signal;
|
|
333
366
|
try {
|
|
334
367
|
const response = await (0, import_undici.fetch)(url, {
|
|
@@ -337,35 +370,41 @@ var init_http = __esm({
|
|
|
337
370
|
body,
|
|
338
371
|
signal: combinedSignal
|
|
339
372
|
});
|
|
340
|
-
clearTimeout(timeoutId);
|
|
373
|
+
if (timeoutId != null) clearTimeout(timeoutId);
|
|
341
374
|
if (response.ok) return { response, traceId };
|
|
342
|
-
if (
|
|
375
|
+
if (retryableStatusCodes.has(response.status) && attempt < this.maxRetries) {
|
|
343
376
|
lastError = new RemoteAPIError(
|
|
344
377
|
response.status,
|
|
345
378
|
await response.text().catch(() => "")
|
|
346
379
|
);
|
|
347
380
|
continue;
|
|
348
381
|
}
|
|
349
|
-
if (allowHttpErrors) {
|
|
382
|
+
if (allowHttpErrors || allowedErrorStatusCodes.has(response.status)) {
|
|
350
383
|
return { response, traceId };
|
|
351
384
|
}
|
|
352
385
|
const errorBody = await response.text().catch(() => "");
|
|
353
386
|
throwMappedError(response.status, errorBody, path2);
|
|
354
387
|
} catch (err) {
|
|
355
|
-
clearTimeout(timeoutId);
|
|
388
|
+
if (timeoutId != null) clearTimeout(timeoutId);
|
|
356
389
|
if (err instanceof RemoteAPIError || err instanceof SandboxNotFoundError || err instanceof PoolNotFoundError || err instanceof PoolInUseError) {
|
|
357
390
|
throw err;
|
|
358
391
|
}
|
|
359
|
-
if (signal?.aborted) {
|
|
360
|
-
throw new SandboxConnectionError("
|
|
392
|
+
if (signal?.aborted && !timedOut) {
|
|
393
|
+
throw new SandboxConnectionError("request aborted by caller", {
|
|
394
|
+
cause: err
|
|
395
|
+
});
|
|
361
396
|
}
|
|
362
397
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
363
398
|
if (attempt >= this.maxRetries) {
|
|
364
|
-
|
|
399
|
+
const detail = timedOut ? `request timed out after ${this.timeoutMs}ms` : describeError(err);
|
|
400
|
+
throw new SandboxConnectionError(detail, { cause: err });
|
|
365
401
|
}
|
|
366
402
|
}
|
|
367
403
|
}
|
|
368
|
-
throw new SandboxConnectionError(
|
|
404
|
+
throw new SandboxConnectionError(
|
|
405
|
+
lastError ? describeError(lastError) : "request failed",
|
|
406
|
+
{ cause: lastError }
|
|
407
|
+
);
|
|
369
408
|
}
|
|
370
409
|
};
|
|
371
410
|
}
|
|
@@ -424,6 +463,7 @@ var init_models = __esm({
|
|
|
424
463
|
SandboxStatus3["SUSPENDING"] = "suspending";
|
|
425
464
|
SandboxStatus3["SUSPENDED"] = "suspended";
|
|
426
465
|
SandboxStatus3["TERMINATED"] = "terminated";
|
|
466
|
+
SandboxStatus3["TIMEOUT"] = "timeout";
|
|
427
467
|
return SandboxStatus3;
|
|
428
468
|
})(SandboxStatus || {});
|
|
429
469
|
SnapshotStatus = /* @__PURE__ */ ((SnapshotStatus2) => {
|
|
@@ -3035,6 +3075,12 @@ function sendPtyFrame(socket, frame) {
|
|
|
3035
3075
|
socket.send(frame, (error) => error ? reject(error) : resolve());
|
|
3036
3076
|
});
|
|
3037
3077
|
}
|
|
3078
|
+
function secondsToMillis3(seconds) {
|
|
3079
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
3080
|
+
throw new SandboxError("requestTimeout must be a positive number of seconds");
|
|
3081
|
+
}
|
|
3082
|
+
return Math.ceil(seconds * 1e3);
|
|
3083
|
+
}
|
|
3038
3084
|
var import_ws2, DEFAULT_PROCESS_USER, SandboxProxyConnection, PTY_OP_DATA, PTY_OP_RESIZE, PTY_OP_READY, PTY_OP_EXIT, Pty, Sandbox;
|
|
3039
3085
|
var init_sandbox = __esm({
|
|
3040
3086
|
"src/sandbox.ts"() {
|
|
@@ -3137,7 +3183,8 @@ var init_sandbox = __esm({
|
|
|
3137
3183
|
projectId: this.options.projectId,
|
|
3138
3184
|
hostHeader,
|
|
3139
3185
|
sandboxIdHeader,
|
|
3140
|
-
routingHint
|
|
3186
|
+
routingHint,
|
|
3187
|
+
timeoutMs: this.options.requestTimeout != null ? secondsToMillis3(this.options.requestTimeout) : this.options.timeoutMs ?? null
|
|
3141
3188
|
});
|
|
3142
3189
|
}
|
|
3143
3190
|
};
|
|
@@ -3358,9 +3405,7 @@ var init_sandbox = __esm({
|
|
|
3358
3405
|
/* _internal */
|
|
3359
3406
|
true
|
|
3360
3407
|
);
|
|
3361
|
-
|
|
3362
|
-
sandbox.lifecycleClient = client;
|
|
3363
|
-
return sandbox;
|
|
3408
|
+
return client.createAndConnect(options);
|
|
3364
3409
|
}
|
|
3365
3410
|
/**
|
|
3366
3411
|
* Attach to an existing sandbox and return a connected handle.
|
|
@@ -3379,7 +3424,8 @@ var init_sandbox = __esm({
|
|
|
3379
3424
|
const sandbox = client.connect(
|
|
3380
3425
|
options.sandboxId,
|
|
3381
3426
|
options.proxyUrl,
|
|
3382
|
-
options.routingHint
|
|
3427
|
+
options.routingHint,
|
|
3428
|
+
options.requestTimeout
|
|
3383
3429
|
);
|
|
3384
3430
|
sandbox.lifecycleClient = client;
|
|
3385
3431
|
return sandbox;
|
|
@@ -3488,6 +3534,11 @@ var init_sandbox = __esm({
|
|
|
3488
3534
|
const client = this.requireLifecycleClient("resume");
|
|
3489
3535
|
await client.resume(this.lifecycleIdentifier, options);
|
|
3490
3536
|
}
|
|
3537
|
+
/** Live-copy this running sandbox. */
|
|
3538
|
+
async copy(options) {
|
|
3539
|
+
const client = this.requireLifecycleClient("copy");
|
|
3540
|
+
return client.copy(this.lifecycleIdentifier, options);
|
|
3541
|
+
}
|
|
3491
3542
|
/**
|
|
3492
3543
|
* Create a checkpoint of this sandbox and wait for it to be locally ready.
|
|
3493
3544
|
*
|
|
@@ -3904,6 +3955,27 @@ var client_exports = {};
|
|
|
3904
3955
|
__export(client_exports, {
|
|
3905
3956
|
SandboxClient: () => SandboxClient
|
|
3906
3957
|
});
|
|
3958
|
+
function resolveRequestTimeoutMs(options) {
|
|
3959
|
+
if (options?.requestTimeout != null) {
|
|
3960
|
+
return secondsToMillis4(options.requestTimeout);
|
|
3961
|
+
}
|
|
3962
|
+
if (options?.timeoutMs != null) {
|
|
3963
|
+
validateTimeoutMs(options.timeoutMs);
|
|
3964
|
+
return options.timeoutMs;
|
|
3965
|
+
}
|
|
3966
|
+
return DEFAULT_HTTP_TIMEOUT_MS;
|
|
3967
|
+
}
|
|
3968
|
+
function secondsToMillis4(seconds) {
|
|
3969
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
3970
|
+
throw new SandboxError("requestTimeout must be a positive number of seconds");
|
|
3971
|
+
}
|
|
3972
|
+
return Math.ceil(seconds * 1e3);
|
|
3973
|
+
}
|
|
3974
|
+
function validateTimeoutMs(timeoutMs) {
|
|
3975
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
3976
|
+
throw new SandboxError("timeoutMs must be a positive number of milliseconds");
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3907
3979
|
function sleep2(ms) {
|
|
3908
3980
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3909
3981
|
}
|
|
@@ -3960,7 +4032,7 @@ function validateUserPort(port) {
|
|
|
3960
4032
|
function dedupeAndSortPorts(ports) {
|
|
3961
4033
|
return [...new Set(ports)].sort((a, b) => a - b);
|
|
3962
4034
|
}
|
|
3963
|
-
var SandboxClient, RESERVED_SANDBOX_MANAGEMENT_PORT;
|
|
4035
|
+
var CREATE_SANDBOX_RETRYABLE_STATUS_CODES, CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES, COPY_SANDBOX_ALLOWED_ERROR_STATUS_CODES, SandboxClient, RESERVED_SANDBOX_MANAGEMENT_PORT;
|
|
3964
4036
|
var init_client = __esm({
|
|
3965
4037
|
"src/client.ts"() {
|
|
3966
4038
|
"use strict";
|
|
@@ -3970,6 +4042,9 @@ var init_client = __esm({
|
|
|
3970
4042
|
init_models();
|
|
3971
4043
|
init_sandbox();
|
|
3972
4044
|
init_url();
|
|
4045
|
+
CREATE_SANDBOX_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([502, 503]);
|
|
4046
|
+
CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES = /* @__PURE__ */ new Set([504]);
|
|
4047
|
+
COPY_SANDBOX_ALLOWED_ERROR_STATUS_CODES = /* @__PURE__ */ new Set([422, 504]);
|
|
3973
4048
|
SandboxClient = class _SandboxClient {
|
|
3974
4049
|
http;
|
|
3975
4050
|
apiUrl;
|
|
@@ -3978,6 +4053,9 @@ var init_client = __esm({
|
|
|
3978
4053
|
projectId;
|
|
3979
4054
|
namespace;
|
|
3980
4055
|
local;
|
|
4056
|
+
maxRetries;
|
|
4057
|
+
retryBackoffMs;
|
|
4058
|
+
requestTimeoutMs;
|
|
3981
4059
|
/** @internal Pass `true` to suppress the deprecation warning when used by `Sandbox.create()` / `Sandbox.connect()`. */
|
|
3982
4060
|
constructor(options, _internal = false) {
|
|
3983
4061
|
if (!_internal) {
|
|
@@ -3991,13 +4069,17 @@ var init_client = __esm({
|
|
|
3991
4069
|
this.projectId = options?.projectId;
|
|
3992
4070
|
this.namespace = options?.namespace ?? NAMESPACE;
|
|
3993
4071
|
this.local = isLocalhost(this.apiUrl);
|
|
4072
|
+
this.maxRetries = options?.maxRetries ?? MAX_RETRIES;
|
|
4073
|
+
this.retryBackoffMs = options?.retryBackoffMs ?? RETRY_BACKOFF_MS;
|
|
4074
|
+
this.requestTimeoutMs = resolveRequestTimeoutMs(options);
|
|
3994
4075
|
this.http = new HttpClient({
|
|
3995
4076
|
baseUrl: resolveSandboxLifecycleUrl(this.apiUrl),
|
|
3996
4077
|
apiKey: this.apiKey,
|
|
3997
4078
|
organizationId: this.organizationId,
|
|
3998
4079
|
projectId: this.projectId,
|
|
3999
|
-
maxRetries:
|
|
4000
|
-
retryBackoffMs:
|
|
4080
|
+
maxRetries: this.maxRetries,
|
|
4081
|
+
retryBackoffMs: this.retryBackoffMs,
|
|
4082
|
+
timeoutMs: this.requestTimeoutMs
|
|
4001
4083
|
});
|
|
4002
4084
|
}
|
|
4003
4085
|
/** Create a client for the TensorLake cloud platform. */
|
|
@@ -4006,19 +4088,46 @@ var init_client = __esm({
|
|
|
4006
4088
|
apiUrl: options?.apiUrl ?? "https://api.tensorlake.ai",
|
|
4007
4089
|
apiKey: options?.apiKey,
|
|
4008
4090
|
organizationId: options?.organizationId,
|
|
4009
|
-
projectId: options?.projectId
|
|
4091
|
+
projectId: options?.projectId,
|
|
4092
|
+
requestTimeout: options?.requestTimeout,
|
|
4093
|
+
timeoutMs: options?.timeoutMs
|
|
4010
4094
|
});
|
|
4011
4095
|
}
|
|
4012
4096
|
/** Create a client for a local Indexify server. */
|
|
4013
4097
|
static forLocalhost(options) {
|
|
4014
4098
|
return new _SandboxClient({
|
|
4015
4099
|
apiUrl: options?.apiUrl ?? "http://localhost:8900",
|
|
4016
|
-
namespace: options?.namespace ?? "default"
|
|
4100
|
+
namespace: options?.namespace ?? "default",
|
|
4101
|
+
requestTimeout: options?.requestTimeout,
|
|
4102
|
+
timeoutMs: options?.timeoutMs
|
|
4017
4103
|
});
|
|
4018
4104
|
}
|
|
4019
4105
|
close() {
|
|
4020
4106
|
this.http.close();
|
|
4021
4107
|
}
|
|
4108
|
+
withRequestTimeout(requestTimeout) {
|
|
4109
|
+
if (requestTimeout == null) {
|
|
4110
|
+
return this;
|
|
4111
|
+
}
|
|
4112
|
+
const timeoutMs = secondsToMillis4(requestTimeout);
|
|
4113
|
+
if (timeoutMs === this.requestTimeoutMs) {
|
|
4114
|
+
return this;
|
|
4115
|
+
}
|
|
4116
|
+
return new _SandboxClient(
|
|
4117
|
+
{
|
|
4118
|
+
apiUrl: this.apiUrl,
|
|
4119
|
+
apiKey: this.apiKey,
|
|
4120
|
+
organizationId: this.organizationId,
|
|
4121
|
+
projectId: this.projectId,
|
|
4122
|
+
namespace: this.namespace,
|
|
4123
|
+
maxRetries: this.maxRetries,
|
|
4124
|
+
retryBackoffMs: this.retryBackoffMs,
|
|
4125
|
+
timeoutMs
|
|
4126
|
+
},
|
|
4127
|
+
/* _internal */
|
|
4128
|
+
true
|
|
4129
|
+
);
|
|
4130
|
+
}
|
|
4022
4131
|
// --- Path helper ---
|
|
4023
4132
|
path(subpath) {
|
|
4024
4133
|
return lifecyclePath(subpath, this.local, this.namespace);
|
|
@@ -4034,7 +4143,6 @@ var init_client = __esm({
|
|
|
4034
4143
|
}
|
|
4035
4144
|
};
|
|
4036
4145
|
if (options?.image != null) body.image = options.image;
|
|
4037
|
-
if (options?.secretNames != null) body.secret_names = options.secretNames;
|
|
4038
4146
|
if (options?.timeoutSecs != null) body.timeout_secs = options.timeoutSecs;
|
|
4039
4147
|
if (options?.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4040
4148
|
if (options?.snapshotId != null) body.snapshot_id = options.snapshotId;
|
|
@@ -4049,7 +4157,11 @@ var init_client = __esm({
|
|
|
4049
4157
|
const raw = await this.http.requestJson(
|
|
4050
4158
|
"POST",
|
|
4051
4159
|
this.path("sandboxes"),
|
|
4052
|
-
{
|
|
4160
|
+
{
|
|
4161
|
+
body,
|
|
4162
|
+
retryableStatusCodes: CREATE_SANDBOX_RETRYABLE_STATUS_CODES,
|
|
4163
|
+
allowedErrorStatusCodes: CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES
|
|
4164
|
+
}
|
|
4053
4165
|
);
|
|
4054
4166
|
const result = fromSnakeKeys(raw, "sandboxId");
|
|
4055
4167
|
return Object.assign(result, { traceId: raw.traceId });
|
|
@@ -4243,7 +4355,32 @@ var init_client = __esm({
|
|
|
4243
4355
|
async claim(poolId) {
|
|
4244
4356
|
const raw = await this.http.requestJson(
|
|
4245
4357
|
"POST",
|
|
4246
|
-
this.path(`sandbox-pools/${poolId}/sandboxes`)
|
|
4358
|
+
this.path(`sandbox-pools/${poolId}/sandboxes`),
|
|
4359
|
+
{
|
|
4360
|
+
retryableStatusCodes: CREATE_SANDBOX_RETRYABLE_STATUS_CODES,
|
|
4361
|
+
allowedErrorStatusCodes: CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES
|
|
4362
|
+
}
|
|
4363
|
+
);
|
|
4364
|
+
const result = fromSnakeKeys(raw, "sandboxId");
|
|
4365
|
+
return Object.assign(result, { traceId: raw.traceId });
|
|
4366
|
+
}
|
|
4367
|
+
/**
|
|
4368
|
+
* Live-copy a running sandbox.
|
|
4369
|
+
*
|
|
4370
|
+
* The server creates `times` running copies from the source sandbox. Partial
|
|
4371
|
+
* responses can include failed copies; inspect each returned sandbox's
|
|
4372
|
+
* `status` and `reason`.
|
|
4373
|
+
*/
|
|
4374
|
+
async copy(sandboxId, options) {
|
|
4375
|
+
const times = options?.times ?? 1;
|
|
4376
|
+
if (!Number.isInteger(times) || times < 1) {
|
|
4377
|
+
throw new SandboxError("times must be a positive integer");
|
|
4378
|
+
}
|
|
4379
|
+
const client = this.withRequestTimeout(options?.requestTimeout);
|
|
4380
|
+
const raw = await client.http.requestJson(
|
|
4381
|
+
"POST",
|
|
4382
|
+
client.path(`sandbox/${sandboxId}/copy?times=${encodeURIComponent(String(times))}`),
|
|
4383
|
+
{ allowedErrorStatusCodes: COPY_SANDBOX_ALLOWED_ERROR_STATUS_CODES }
|
|
4247
4384
|
);
|
|
4248
4385
|
const result = fromSnakeKeys(raw, "sandboxId");
|
|
4249
4386
|
return Object.assign(result, { traceId: raw.traceId });
|
|
@@ -4344,7 +4481,6 @@ var init_client = __esm({
|
|
|
4344
4481
|
},
|
|
4345
4482
|
timeout_secs: options.timeoutSecs ?? 0
|
|
4346
4483
|
};
|
|
4347
|
-
if (options.secretNames != null) body.secret_names = options.secretNames;
|
|
4348
4484
|
if (options.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4349
4485
|
if (options.maxContainers != null) body.max_containers = options.maxContainers;
|
|
4350
4486
|
if (options.warmContainers != null) body.warm_containers = options.warmContainers;
|
|
@@ -4385,7 +4521,6 @@ var init_client = __esm({
|
|
|
4385
4521
|
},
|
|
4386
4522
|
timeout_secs: options.timeoutSecs ?? 0
|
|
4387
4523
|
};
|
|
4388
|
-
if (options.secretNames != null) body.secret_names = options.secretNames;
|
|
4389
4524
|
if (options.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4390
4525
|
if (options.maxContainers != null) body.max_containers = options.maxContainers;
|
|
4391
4526
|
if (options.warmContainers != null) body.warm_containers = options.warmContainers;
|
|
@@ -4405,7 +4540,7 @@ var init_client = __esm({
|
|
|
4405
4540
|
}
|
|
4406
4541
|
// --- Connect ---
|
|
4407
4542
|
/** Return a `Sandbox` handle for an existing running sandbox without verifying it exists. */
|
|
4408
|
-
connect(identifier, proxyUrl, routingHint) {
|
|
4543
|
+
connect(identifier, proxyUrl, routingHint, requestTimeout) {
|
|
4409
4544
|
const resolvedProxy = proxyUrl ?? resolveProxyUrl(this.apiUrl);
|
|
4410
4545
|
return new Sandbox({
|
|
4411
4546
|
sandboxId: identifier,
|
|
@@ -4414,29 +4549,33 @@ var init_client = __esm({
|
|
|
4414
4549
|
organizationId: this.organizationId,
|
|
4415
4550
|
projectId: this.projectId,
|
|
4416
4551
|
routingHint,
|
|
4417
|
-
resolveProxyInfo: proxyUrl == null ? async (currentIdentifier) => this.get(currentIdentifier) : void 0
|
|
4552
|
+
resolveProxyInfo: proxyUrl == null ? async (currentIdentifier) => this.get(currentIdentifier) : void 0,
|
|
4553
|
+
requestTimeout
|
|
4418
4554
|
});
|
|
4419
4555
|
}
|
|
4420
4556
|
/**
|
|
4421
4557
|
* Create a sandbox, wait for it to reach `Running`, and return a connected handle.
|
|
4422
4558
|
*
|
|
4423
|
-
* Blocks until the sandbox is ready or `
|
|
4559
|
+
* Blocks until the sandbox is ready or `requestTimeout` elapses. The returned
|
|
4424
4560
|
* `Sandbox` auto-terminates when `terminate()` is called.
|
|
4425
4561
|
*
|
|
4426
|
-
* @param options.
|
|
4562
|
+
* @param options.requestTimeout - Max seconds to wait for `Running` status (default: client requestTimeout).
|
|
4563
|
+
* @param options.startupTimeout - Deprecated alias for `requestTimeout`.
|
|
4427
4564
|
* @throws {SandboxError} If the sandbox terminates during startup or the timeout elapses.
|
|
4428
4565
|
*/
|
|
4429
4566
|
async createAndConnect(options) {
|
|
4430
|
-
const
|
|
4431
|
-
const
|
|
4567
|
+
const requestTimeout = options?.requestTimeout ?? options?.startupTimeout ?? this.requestTimeoutMs / 1e3;
|
|
4568
|
+
const requestClient = this.withRequestTimeout(requestTimeout);
|
|
4569
|
+
const result = options?.poolId != null ? await requestClient.claim(options.poolId) : await requestClient.create(options);
|
|
4432
4570
|
const requestedName = options?.poolId != null ? null : options?.name ?? null;
|
|
4433
4571
|
const finishConnect = (routingHint, name, ingressEndpoint) => {
|
|
4434
|
-
const sandbox =
|
|
4572
|
+
const sandbox = requestClient.connect(
|
|
4435
4573
|
result.sandboxId,
|
|
4436
4574
|
options?.proxyUrl ?? ingressEndpoint,
|
|
4437
|
-
routingHint
|
|
4575
|
+
routingHint,
|
|
4576
|
+
requestTimeout
|
|
4438
4577
|
);
|
|
4439
|
-
sandbox._setOwner(
|
|
4578
|
+
sandbox._setOwner(requestClient);
|
|
4440
4579
|
sandbox.traceId = result.traceId;
|
|
4441
4580
|
sandbox._setLifecycleIdentifier(result.sandboxId);
|
|
4442
4581
|
sandbox._setName(name ?? requestedName);
|
|
@@ -4453,9 +4592,18 @@ var init_client = __esm({
|
|
|
4453
4592
|
})
|
|
4454
4593
|
);
|
|
4455
4594
|
}
|
|
4456
|
-
|
|
4595
|
+
if (result.status === "timeout" /* TIMEOUT */) {
|
|
4596
|
+
try {
|
|
4597
|
+
await requestClient.delete(result.sandboxId);
|
|
4598
|
+
} catch {
|
|
4599
|
+
}
|
|
4600
|
+
throw new SandboxError(
|
|
4601
|
+
`Sandbox ${result.sandboxId} did not start within ${requestTimeout}s`
|
|
4602
|
+
);
|
|
4603
|
+
}
|
|
4604
|
+
const deadline = Date.now() + secondsToMillis4(requestTimeout);
|
|
4457
4605
|
while (Date.now() < deadline) {
|
|
4458
|
-
const info = await
|
|
4606
|
+
const info = await requestClient.get(result.sandboxId);
|
|
4459
4607
|
if (info.status === "running" /* RUNNING */) {
|
|
4460
4608
|
return finishConnect(info.routingHint, info.name, info.ingressEndpoint);
|
|
4461
4609
|
}
|
|
@@ -4470,11 +4618,11 @@ var init_client = __esm({
|
|
|
4470
4618
|
await sleep2(500);
|
|
4471
4619
|
}
|
|
4472
4620
|
try {
|
|
4473
|
-
await
|
|
4621
|
+
await requestClient.delete(result.sandboxId);
|
|
4474
4622
|
} catch {
|
|
4475
4623
|
}
|
|
4476
4624
|
throw new SandboxError(
|
|
4477
|
-
`Sandbox ${result.sandboxId} did not start within ${
|
|
4625
|
+
`Sandbox ${result.sandboxId} did not start within ${requestTimeout}s`
|
|
4478
4626
|
);
|
|
4479
4627
|
}
|
|
4480
4628
|
};
|