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
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var SDK_VERSION, API_URL, API_KEY, NAMESPACE, SANDBOX_PROXY_URL, DEFAULT_HTTP_TI
|
|
|
19
19
|
var init_defaults = __esm({
|
|
20
20
|
"src/defaults.ts"() {
|
|
21
21
|
"use strict";
|
|
22
|
-
SDK_VERSION = "0.5.
|
|
22
|
+
SDK_VERSION = "0.5.33";
|
|
23
23
|
API_URL = process.env.TENSORLAKE_API_URL ?? "https://api.tensorlake.ai";
|
|
24
24
|
API_KEY = process.env.TENSORLAKE_API_KEY ?? void 0;
|
|
25
25
|
NAMESPACE = process.env.INDEXIFY_NAMESPACE ?? "default";
|
|
@@ -32,6 +32,28 @@ var init_defaults = __esm({
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
// src/errors.ts
|
|
35
|
+
function describeError(err) {
|
|
36
|
+
const parts = [];
|
|
37
|
+
const seen = /* @__PURE__ */ new Set();
|
|
38
|
+
let current = err;
|
|
39
|
+
for (let depth = 0; depth < 6; depth++) {
|
|
40
|
+
if (current == null || typeof current !== "object" || seen.has(current)) {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
seen.add(current);
|
|
44
|
+
const e = current;
|
|
45
|
+
const message = typeof e.message === "string" ? e.message.trim() : "";
|
|
46
|
+
const code = typeof e.code === "string" ? e.code : void 0;
|
|
47
|
+
let segment = message;
|
|
48
|
+
if (code && (!message || !message.includes(code))) {
|
|
49
|
+
segment = segment ? `${segment} (${code})` : code;
|
|
50
|
+
}
|
|
51
|
+
if (segment && !parts.includes(segment)) parts.push(segment);
|
|
52
|
+
current = e.cause;
|
|
53
|
+
}
|
|
54
|
+
if (parts.length > 0) return parts.join(": ");
|
|
55
|
+
return err instanceof Error ? err.message : String(err);
|
|
56
|
+
}
|
|
35
57
|
var SandboxException, SandboxError, SandboxConnectionError, SandboxNotFoundError, PoolNotFoundError, PoolInUseError, RemoteAPIError, RequestNotFinishedError, RequestFailedError, RequestExecutionError;
|
|
36
58
|
var init_errors = __esm({
|
|
37
59
|
"src/errors.ts"() {
|
|
@@ -49,9 +71,10 @@ var init_errors = __esm({
|
|
|
49
71
|
}
|
|
50
72
|
};
|
|
51
73
|
SandboxConnectionError = class extends SandboxError {
|
|
52
|
-
constructor(message) {
|
|
74
|
+
constructor(message, options) {
|
|
53
75
|
super(`Connection error: ${message}`);
|
|
54
76
|
this.name = "SandboxConnectionError";
|
|
77
|
+
if (options?.cause !== void 0) this.cause = options.cause;
|
|
55
78
|
}
|
|
56
79
|
};
|
|
57
80
|
SandboxNotFoundError = class extends SandboxError {
|
|
@@ -184,12 +207,13 @@ function anySignal(signals) {
|
|
|
184
207
|
function sleep(ms) {
|
|
185
208
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
186
209
|
}
|
|
187
|
-
var HttpClient;
|
|
210
|
+
var REQUEST_TIMEOUT_HEADER, HttpClient;
|
|
188
211
|
var init_http = __esm({
|
|
189
212
|
"src/http.ts"() {
|
|
190
213
|
"use strict";
|
|
191
214
|
init_defaults();
|
|
192
215
|
init_errors();
|
|
216
|
+
REQUEST_TIMEOUT_HEADER = "X-Tensorlake-Request-Timeout-Ms";
|
|
193
217
|
setGlobalDispatcher(
|
|
194
218
|
new Agent({
|
|
195
219
|
keepAliveTimeout: 6e4,
|
|
@@ -208,10 +232,13 @@ var init_http = __esm({
|
|
|
208
232
|
this.baseUrl = url.endsWith("/") ? url.slice(0, -1) : url;
|
|
209
233
|
this.maxRetries = options.maxRetries ?? MAX_RETRIES;
|
|
210
234
|
this.retryBackoffMs = options.retryBackoffMs ?? RETRY_BACKOFF_MS;
|
|
211
|
-
this.timeoutMs = options.timeoutMs
|
|
235
|
+
this.timeoutMs = options.timeoutMs === void 0 ? DEFAULT_HTTP_TIMEOUT_MS : options.timeoutMs;
|
|
212
236
|
this.headers = {
|
|
213
237
|
"User-Agent": `tensorlake-typescript-sdk/${SDK_VERSION}`
|
|
214
238
|
};
|
|
239
|
+
if (this.timeoutMs != null) {
|
|
240
|
+
this.headers[REQUEST_TIMEOUT_HEADER] = String(this.timeoutMs);
|
|
241
|
+
}
|
|
215
242
|
if (options.apiKey) {
|
|
216
243
|
this.headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
217
244
|
}
|
|
@@ -240,7 +267,10 @@ var init_http = __esm({
|
|
|
240
267
|
const response = await this.requestResponse(method, path2, {
|
|
241
268
|
json: options?.body,
|
|
242
269
|
headers: options?.headers,
|
|
243
|
-
signal: options?.signal
|
|
270
|
+
signal: options?.signal,
|
|
271
|
+
retryableStatusCodes: options?.retryableStatusCodes,
|
|
272
|
+
allowedErrorStatusCodes: options?.allowedErrorStatusCodes,
|
|
273
|
+
allowHttpErrors: options?.allowHttpErrors
|
|
244
274
|
});
|
|
245
275
|
const text = await response.text();
|
|
246
276
|
const data = text ? JSON.parse(text) : void 0;
|
|
@@ -292,7 +322,9 @@ var init_http = __esm({
|
|
|
292
322
|
body,
|
|
293
323
|
headers,
|
|
294
324
|
options?.signal,
|
|
295
|
-
options?.allowHttpErrors ?? false
|
|
325
|
+
options?.allowHttpErrors ?? false,
|
|
326
|
+
options?.retryableStatusCodes ?? RETRYABLE_STATUS_CODES,
|
|
327
|
+
options?.allowedErrorStatusCodes ?? /* @__PURE__ */ new Set()
|
|
296
328
|
);
|
|
297
329
|
return withTraceId(response, traceId);
|
|
298
330
|
}
|
|
@@ -302,7 +334,7 @@ var init_http = __esm({
|
|
|
302
334
|
const spanId = randomHex(8);
|
|
303
335
|
return { traceparent: `00-${traceId}-${spanId}-01`, traceId };
|
|
304
336
|
}
|
|
305
|
-
async doFetch(method, path2, body, headers, signal, allowHttpErrors = false) {
|
|
337
|
+
async doFetch(method, path2, body, headers, signal, allowHttpErrors = false, retryableStatusCodes = RETRYABLE_STATUS_CODES, allowedErrorStatusCodes = /* @__PURE__ */ new Set()) {
|
|
306
338
|
const url = `${this.baseUrl}${path2}`;
|
|
307
339
|
const { traceparent, traceId } = _HttpClient.makeTraceparent();
|
|
308
340
|
headers["traceparent"] = traceparent;
|
|
@@ -313,10 +345,11 @@ var init_http = __esm({
|
|
|
313
345
|
await sleep(delay);
|
|
314
346
|
}
|
|
315
347
|
this.abortController = new AbortController();
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
348
|
+
let timedOut = false;
|
|
349
|
+
const timeoutId = this.timeoutMs == null ? null : setTimeout(() => {
|
|
350
|
+
timedOut = true;
|
|
351
|
+
this.abortController?.abort();
|
|
352
|
+
}, this.timeoutMs);
|
|
320
353
|
const combinedSignal = signal ? anySignal([signal, this.abortController.signal]) : this.abortController.signal;
|
|
321
354
|
try {
|
|
322
355
|
const response = await undiciFetch(url, {
|
|
@@ -325,35 +358,41 @@ var init_http = __esm({
|
|
|
325
358
|
body,
|
|
326
359
|
signal: combinedSignal
|
|
327
360
|
});
|
|
328
|
-
clearTimeout(timeoutId);
|
|
361
|
+
if (timeoutId != null) clearTimeout(timeoutId);
|
|
329
362
|
if (response.ok) return { response, traceId };
|
|
330
|
-
if (
|
|
363
|
+
if (retryableStatusCodes.has(response.status) && attempt < this.maxRetries) {
|
|
331
364
|
lastError = new RemoteAPIError(
|
|
332
365
|
response.status,
|
|
333
366
|
await response.text().catch(() => "")
|
|
334
367
|
);
|
|
335
368
|
continue;
|
|
336
369
|
}
|
|
337
|
-
if (allowHttpErrors) {
|
|
370
|
+
if (allowHttpErrors || allowedErrorStatusCodes.has(response.status)) {
|
|
338
371
|
return { response, traceId };
|
|
339
372
|
}
|
|
340
373
|
const errorBody = await response.text().catch(() => "");
|
|
341
374
|
throwMappedError(response.status, errorBody, path2);
|
|
342
375
|
} catch (err) {
|
|
343
|
-
clearTimeout(timeoutId);
|
|
376
|
+
if (timeoutId != null) clearTimeout(timeoutId);
|
|
344
377
|
if (err instanceof RemoteAPIError || err instanceof SandboxNotFoundError || err instanceof PoolNotFoundError || err instanceof PoolInUseError) {
|
|
345
378
|
throw err;
|
|
346
379
|
}
|
|
347
|
-
if (signal?.aborted) {
|
|
348
|
-
throw new SandboxConnectionError("
|
|
380
|
+
if (signal?.aborted && !timedOut) {
|
|
381
|
+
throw new SandboxConnectionError("request aborted by caller", {
|
|
382
|
+
cause: err
|
|
383
|
+
});
|
|
349
384
|
}
|
|
350
385
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
351
386
|
if (attempt >= this.maxRetries) {
|
|
352
|
-
|
|
387
|
+
const detail = timedOut ? `request timed out after ${this.timeoutMs}ms` : describeError(err);
|
|
388
|
+
throw new SandboxConnectionError(detail, { cause: err });
|
|
353
389
|
}
|
|
354
390
|
}
|
|
355
391
|
}
|
|
356
|
-
throw new SandboxConnectionError(
|
|
392
|
+
throw new SandboxConnectionError(
|
|
393
|
+
lastError ? describeError(lastError) : "request failed",
|
|
394
|
+
{ cause: lastError }
|
|
395
|
+
);
|
|
357
396
|
}
|
|
358
397
|
};
|
|
359
398
|
}
|
|
@@ -412,6 +451,7 @@ var init_models = __esm({
|
|
|
412
451
|
SandboxStatus3["SUSPENDING"] = "suspending";
|
|
413
452
|
SandboxStatus3["SUSPENDED"] = "suspended";
|
|
414
453
|
SandboxStatus3["TERMINATED"] = "terminated";
|
|
454
|
+
SandboxStatus3["TIMEOUT"] = "timeout";
|
|
415
455
|
return SandboxStatus3;
|
|
416
456
|
})(SandboxStatus || {});
|
|
417
457
|
SnapshotStatus = /* @__PURE__ */ ((SnapshotStatus2) => {
|
|
@@ -3024,6 +3064,12 @@ function sendPtyFrame(socket, frame) {
|
|
|
3024
3064
|
socket.send(frame, (error) => error ? reject(error) : resolve());
|
|
3025
3065
|
});
|
|
3026
3066
|
}
|
|
3067
|
+
function secondsToMillis3(seconds) {
|
|
3068
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
3069
|
+
throw new SandboxError("requestTimeout must be a positive number of seconds");
|
|
3070
|
+
}
|
|
3071
|
+
return Math.ceil(seconds * 1e3);
|
|
3072
|
+
}
|
|
3027
3073
|
var DEFAULT_PROCESS_USER, SandboxProxyConnection, PTY_OP_DATA, PTY_OP_RESIZE, PTY_OP_READY, PTY_OP_EXIT, Pty, Sandbox;
|
|
3028
3074
|
var init_sandbox = __esm({
|
|
3029
3075
|
"src/sandbox.ts"() {
|
|
@@ -3125,7 +3171,8 @@ var init_sandbox = __esm({
|
|
|
3125
3171
|
projectId: this.options.projectId,
|
|
3126
3172
|
hostHeader,
|
|
3127
3173
|
sandboxIdHeader,
|
|
3128
|
-
routingHint
|
|
3174
|
+
routingHint,
|
|
3175
|
+
timeoutMs: this.options.requestTimeout != null ? secondsToMillis3(this.options.requestTimeout) : this.options.timeoutMs ?? null
|
|
3129
3176
|
});
|
|
3130
3177
|
}
|
|
3131
3178
|
};
|
|
@@ -3346,9 +3393,7 @@ var init_sandbox = __esm({
|
|
|
3346
3393
|
/* _internal */
|
|
3347
3394
|
true
|
|
3348
3395
|
);
|
|
3349
|
-
|
|
3350
|
-
sandbox.lifecycleClient = client;
|
|
3351
|
-
return sandbox;
|
|
3396
|
+
return client.createAndConnect(options);
|
|
3352
3397
|
}
|
|
3353
3398
|
/**
|
|
3354
3399
|
* Attach to an existing sandbox and return a connected handle.
|
|
@@ -3367,7 +3412,8 @@ var init_sandbox = __esm({
|
|
|
3367
3412
|
const sandbox = client.connect(
|
|
3368
3413
|
options.sandboxId,
|
|
3369
3414
|
options.proxyUrl,
|
|
3370
|
-
options.routingHint
|
|
3415
|
+
options.routingHint,
|
|
3416
|
+
options.requestTimeout
|
|
3371
3417
|
);
|
|
3372
3418
|
sandbox.lifecycleClient = client;
|
|
3373
3419
|
return sandbox;
|
|
@@ -3476,6 +3522,11 @@ var init_sandbox = __esm({
|
|
|
3476
3522
|
const client = this.requireLifecycleClient("resume");
|
|
3477
3523
|
await client.resume(this.lifecycleIdentifier, options);
|
|
3478
3524
|
}
|
|
3525
|
+
/** Live-copy this running sandbox. */
|
|
3526
|
+
async copy(options) {
|
|
3527
|
+
const client = this.requireLifecycleClient("copy");
|
|
3528
|
+
return client.copy(this.lifecycleIdentifier, options);
|
|
3529
|
+
}
|
|
3479
3530
|
/**
|
|
3480
3531
|
* Create a checkpoint of this sandbox and wait for it to be locally ready.
|
|
3481
3532
|
*
|
|
@@ -3892,6 +3943,27 @@ var client_exports = {};
|
|
|
3892
3943
|
__export(client_exports, {
|
|
3893
3944
|
SandboxClient: () => SandboxClient
|
|
3894
3945
|
});
|
|
3946
|
+
function resolveRequestTimeoutMs(options) {
|
|
3947
|
+
if (options?.requestTimeout != null) {
|
|
3948
|
+
return secondsToMillis4(options.requestTimeout);
|
|
3949
|
+
}
|
|
3950
|
+
if (options?.timeoutMs != null) {
|
|
3951
|
+
validateTimeoutMs(options.timeoutMs);
|
|
3952
|
+
return options.timeoutMs;
|
|
3953
|
+
}
|
|
3954
|
+
return DEFAULT_HTTP_TIMEOUT_MS;
|
|
3955
|
+
}
|
|
3956
|
+
function secondsToMillis4(seconds) {
|
|
3957
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
3958
|
+
throw new SandboxError("requestTimeout must be a positive number of seconds");
|
|
3959
|
+
}
|
|
3960
|
+
return Math.ceil(seconds * 1e3);
|
|
3961
|
+
}
|
|
3962
|
+
function validateTimeoutMs(timeoutMs) {
|
|
3963
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
3964
|
+
throw new SandboxError("timeoutMs must be a positive number of milliseconds");
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3895
3967
|
function sleep2(ms) {
|
|
3896
3968
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3897
3969
|
}
|
|
@@ -3948,7 +4020,7 @@ function validateUserPort(port) {
|
|
|
3948
4020
|
function dedupeAndSortPorts(ports) {
|
|
3949
4021
|
return [...new Set(ports)].sort((a, b) => a - b);
|
|
3950
4022
|
}
|
|
3951
|
-
var SandboxClient, RESERVED_SANDBOX_MANAGEMENT_PORT;
|
|
4023
|
+
var CREATE_SANDBOX_RETRYABLE_STATUS_CODES, CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES, COPY_SANDBOX_ALLOWED_ERROR_STATUS_CODES, SandboxClient, RESERVED_SANDBOX_MANAGEMENT_PORT;
|
|
3952
4024
|
var init_client = __esm({
|
|
3953
4025
|
"src/client.ts"() {
|
|
3954
4026
|
"use strict";
|
|
@@ -3958,6 +4030,9 @@ var init_client = __esm({
|
|
|
3958
4030
|
init_models();
|
|
3959
4031
|
init_sandbox();
|
|
3960
4032
|
init_url();
|
|
4033
|
+
CREATE_SANDBOX_RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([502, 503]);
|
|
4034
|
+
CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES = /* @__PURE__ */ new Set([504]);
|
|
4035
|
+
COPY_SANDBOX_ALLOWED_ERROR_STATUS_CODES = /* @__PURE__ */ new Set([422, 504]);
|
|
3961
4036
|
SandboxClient = class _SandboxClient {
|
|
3962
4037
|
http;
|
|
3963
4038
|
apiUrl;
|
|
@@ -3966,6 +4041,9 @@ var init_client = __esm({
|
|
|
3966
4041
|
projectId;
|
|
3967
4042
|
namespace;
|
|
3968
4043
|
local;
|
|
4044
|
+
maxRetries;
|
|
4045
|
+
retryBackoffMs;
|
|
4046
|
+
requestTimeoutMs;
|
|
3969
4047
|
/** @internal Pass `true` to suppress the deprecation warning when used by `Sandbox.create()` / `Sandbox.connect()`. */
|
|
3970
4048
|
constructor(options, _internal = false) {
|
|
3971
4049
|
if (!_internal) {
|
|
@@ -3979,13 +4057,17 @@ var init_client = __esm({
|
|
|
3979
4057
|
this.projectId = options?.projectId;
|
|
3980
4058
|
this.namespace = options?.namespace ?? NAMESPACE;
|
|
3981
4059
|
this.local = isLocalhost(this.apiUrl);
|
|
4060
|
+
this.maxRetries = options?.maxRetries ?? MAX_RETRIES;
|
|
4061
|
+
this.retryBackoffMs = options?.retryBackoffMs ?? RETRY_BACKOFF_MS;
|
|
4062
|
+
this.requestTimeoutMs = resolveRequestTimeoutMs(options);
|
|
3982
4063
|
this.http = new HttpClient({
|
|
3983
4064
|
baseUrl: resolveSandboxLifecycleUrl(this.apiUrl),
|
|
3984
4065
|
apiKey: this.apiKey,
|
|
3985
4066
|
organizationId: this.organizationId,
|
|
3986
4067
|
projectId: this.projectId,
|
|
3987
|
-
maxRetries:
|
|
3988
|
-
retryBackoffMs:
|
|
4068
|
+
maxRetries: this.maxRetries,
|
|
4069
|
+
retryBackoffMs: this.retryBackoffMs,
|
|
4070
|
+
timeoutMs: this.requestTimeoutMs
|
|
3989
4071
|
});
|
|
3990
4072
|
}
|
|
3991
4073
|
/** Create a client for the TensorLake cloud platform. */
|
|
@@ -3994,19 +4076,46 @@ var init_client = __esm({
|
|
|
3994
4076
|
apiUrl: options?.apiUrl ?? "https://api.tensorlake.ai",
|
|
3995
4077
|
apiKey: options?.apiKey,
|
|
3996
4078
|
organizationId: options?.organizationId,
|
|
3997
|
-
projectId: options?.projectId
|
|
4079
|
+
projectId: options?.projectId,
|
|
4080
|
+
requestTimeout: options?.requestTimeout,
|
|
4081
|
+
timeoutMs: options?.timeoutMs
|
|
3998
4082
|
});
|
|
3999
4083
|
}
|
|
4000
4084
|
/** Create a client for a local Indexify server. */
|
|
4001
4085
|
static forLocalhost(options) {
|
|
4002
4086
|
return new _SandboxClient({
|
|
4003
4087
|
apiUrl: options?.apiUrl ?? "http://localhost:8900",
|
|
4004
|
-
namespace: options?.namespace ?? "default"
|
|
4088
|
+
namespace: options?.namespace ?? "default",
|
|
4089
|
+
requestTimeout: options?.requestTimeout,
|
|
4090
|
+
timeoutMs: options?.timeoutMs
|
|
4005
4091
|
});
|
|
4006
4092
|
}
|
|
4007
4093
|
close() {
|
|
4008
4094
|
this.http.close();
|
|
4009
4095
|
}
|
|
4096
|
+
withRequestTimeout(requestTimeout) {
|
|
4097
|
+
if (requestTimeout == null) {
|
|
4098
|
+
return this;
|
|
4099
|
+
}
|
|
4100
|
+
const timeoutMs = secondsToMillis4(requestTimeout);
|
|
4101
|
+
if (timeoutMs === this.requestTimeoutMs) {
|
|
4102
|
+
return this;
|
|
4103
|
+
}
|
|
4104
|
+
return new _SandboxClient(
|
|
4105
|
+
{
|
|
4106
|
+
apiUrl: this.apiUrl,
|
|
4107
|
+
apiKey: this.apiKey,
|
|
4108
|
+
organizationId: this.organizationId,
|
|
4109
|
+
projectId: this.projectId,
|
|
4110
|
+
namespace: this.namespace,
|
|
4111
|
+
maxRetries: this.maxRetries,
|
|
4112
|
+
retryBackoffMs: this.retryBackoffMs,
|
|
4113
|
+
timeoutMs
|
|
4114
|
+
},
|
|
4115
|
+
/* _internal */
|
|
4116
|
+
true
|
|
4117
|
+
);
|
|
4118
|
+
}
|
|
4010
4119
|
// --- Path helper ---
|
|
4011
4120
|
path(subpath) {
|
|
4012
4121
|
return lifecyclePath(subpath, this.local, this.namespace);
|
|
@@ -4022,7 +4131,6 @@ var init_client = __esm({
|
|
|
4022
4131
|
}
|
|
4023
4132
|
};
|
|
4024
4133
|
if (options?.image != null) body.image = options.image;
|
|
4025
|
-
if (options?.secretNames != null) body.secret_names = options.secretNames;
|
|
4026
4134
|
if (options?.timeoutSecs != null) body.timeout_secs = options.timeoutSecs;
|
|
4027
4135
|
if (options?.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4028
4136
|
if (options?.snapshotId != null) body.snapshot_id = options.snapshotId;
|
|
@@ -4037,7 +4145,11 @@ var init_client = __esm({
|
|
|
4037
4145
|
const raw = await this.http.requestJson(
|
|
4038
4146
|
"POST",
|
|
4039
4147
|
this.path("sandboxes"),
|
|
4040
|
-
{
|
|
4148
|
+
{
|
|
4149
|
+
body,
|
|
4150
|
+
retryableStatusCodes: CREATE_SANDBOX_RETRYABLE_STATUS_CODES,
|
|
4151
|
+
allowedErrorStatusCodes: CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES
|
|
4152
|
+
}
|
|
4041
4153
|
);
|
|
4042
4154
|
const result = fromSnakeKeys(raw, "sandboxId");
|
|
4043
4155
|
return Object.assign(result, { traceId: raw.traceId });
|
|
@@ -4231,7 +4343,32 @@ var init_client = __esm({
|
|
|
4231
4343
|
async claim(poolId) {
|
|
4232
4344
|
const raw = await this.http.requestJson(
|
|
4233
4345
|
"POST",
|
|
4234
|
-
this.path(`sandbox-pools/${poolId}/sandboxes`)
|
|
4346
|
+
this.path(`sandbox-pools/${poolId}/sandboxes`),
|
|
4347
|
+
{
|
|
4348
|
+
retryableStatusCodes: CREATE_SANDBOX_RETRYABLE_STATUS_CODES,
|
|
4349
|
+
allowedErrorStatusCodes: CREATE_SANDBOX_ALLOWED_ERROR_STATUS_CODES
|
|
4350
|
+
}
|
|
4351
|
+
);
|
|
4352
|
+
const result = fromSnakeKeys(raw, "sandboxId");
|
|
4353
|
+
return Object.assign(result, { traceId: raw.traceId });
|
|
4354
|
+
}
|
|
4355
|
+
/**
|
|
4356
|
+
* Live-copy a running sandbox.
|
|
4357
|
+
*
|
|
4358
|
+
* The server creates `times` running copies from the source sandbox. Partial
|
|
4359
|
+
* responses can include failed copies; inspect each returned sandbox's
|
|
4360
|
+
* `status` and `reason`.
|
|
4361
|
+
*/
|
|
4362
|
+
async copy(sandboxId, options) {
|
|
4363
|
+
const times = options?.times ?? 1;
|
|
4364
|
+
if (!Number.isInteger(times) || times < 1) {
|
|
4365
|
+
throw new SandboxError("times must be a positive integer");
|
|
4366
|
+
}
|
|
4367
|
+
const client = this.withRequestTimeout(options?.requestTimeout);
|
|
4368
|
+
const raw = await client.http.requestJson(
|
|
4369
|
+
"POST",
|
|
4370
|
+
client.path(`sandbox/${sandboxId}/copy?times=${encodeURIComponent(String(times))}`),
|
|
4371
|
+
{ allowedErrorStatusCodes: COPY_SANDBOX_ALLOWED_ERROR_STATUS_CODES }
|
|
4235
4372
|
);
|
|
4236
4373
|
const result = fromSnakeKeys(raw, "sandboxId");
|
|
4237
4374
|
return Object.assign(result, { traceId: raw.traceId });
|
|
@@ -4332,7 +4469,6 @@ var init_client = __esm({
|
|
|
4332
4469
|
},
|
|
4333
4470
|
timeout_secs: options.timeoutSecs ?? 0
|
|
4334
4471
|
};
|
|
4335
|
-
if (options.secretNames != null) body.secret_names = options.secretNames;
|
|
4336
4472
|
if (options.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4337
4473
|
if (options.maxContainers != null) body.max_containers = options.maxContainers;
|
|
4338
4474
|
if (options.warmContainers != null) body.warm_containers = options.warmContainers;
|
|
@@ -4373,7 +4509,6 @@ var init_client = __esm({
|
|
|
4373
4509
|
},
|
|
4374
4510
|
timeout_secs: options.timeoutSecs ?? 0
|
|
4375
4511
|
};
|
|
4376
|
-
if (options.secretNames != null) body.secret_names = options.secretNames;
|
|
4377
4512
|
if (options.entrypoint != null) body.entrypoint = options.entrypoint;
|
|
4378
4513
|
if (options.maxContainers != null) body.max_containers = options.maxContainers;
|
|
4379
4514
|
if (options.warmContainers != null) body.warm_containers = options.warmContainers;
|
|
@@ -4393,7 +4528,7 @@ var init_client = __esm({
|
|
|
4393
4528
|
}
|
|
4394
4529
|
// --- Connect ---
|
|
4395
4530
|
/** Return a `Sandbox` handle for an existing running sandbox without verifying it exists. */
|
|
4396
|
-
connect(identifier, proxyUrl, routingHint) {
|
|
4531
|
+
connect(identifier, proxyUrl, routingHint, requestTimeout) {
|
|
4397
4532
|
const resolvedProxy = proxyUrl ?? resolveProxyUrl(this.apiUrl);
|
|
4398
4533
|
return new Sandbox({
|
|
4399
4534
|
sandboxId: identifier,
|
|
@@ -4402,29 +4537,33 @@ var init_client = __esm({
|
|
|
4402
4537
|
organizationId: this.organizationId,
|
|
4403
4538
|
projectId: this.projectId,
|
|
4404
4539
|
routingHint,
|
|
4405
|
-
resolveProxyInfo: proxyUrl == null ? async (currentIdentifier) => this.get(currentIdentifier) : void 0
|
|
4540
|
+
resolveProxyInfo: proxyUrl == null ? async (currentIdentifier) => this.get(currentIdentifier) : void 0,
|
|
4541
|
+
requestTimeout
|
|
4406
4542
|
});
|
|
4407
4543
|
}
|
|
4408
4544
|
/**
|
|
4409
4545
|
* Create a sandbox, wait for it to reach `Running`, and return a connected handle.
|
|
4410
4546
|
*
|
|
4411
|
-
* Blocks until the sandbox is ready or `
|
|
4547
|
+
* Blocks until the sandbox is ready or `requestTimeout` elapses. The returned
|
|
4412
4548
|
* `Sandbox` auto-terminates when `terminate()` is called.
|
|
4413
4549
|
*
|
|
4414
|
-
* @param options.
|
|
4550
|
+
* @param options.requestTimeout - Max seconds to wait for `Running` status (default: client requestTimeout).
|
|
4551
|
+
* @param options.startupTimeout - Deprecated alias for `requestTimeout`.
|
|
4415
4552
|
* @throws {SandboxError} If the sandbox terminates during startup or the timeout elapses.
|
|
4416
4553
|
*/
|
|
4417
4554
|
async createAndConnect(options) {
|
|
4418
|
-
const
|
|
4419
|
-
const
|
|
4555
|
+
const requestTimeout = options?.requestTimeout ?? options?.startupTimeout ?? this.requestTimeoutMs / 1e3;
|
|
4556
|
+
const requestClient = this.withRequestTimeout(requestTimeout);
|
|
4557
|
+
const result = options?.poolId != null ? await requestClient.claim(options.poolId) : await requestClient.create(options);
|
|
4420
4558
|
const requestedName = options?.poolId != null ? null : options?.name ?? null;
|
|
4421
4559
|
const finishConnect = (routingHint, name, ingressEndpoint) => {
|
|
4422
|
-
const sandbox =
|
|
4560
|
+
const sandbox = requestClient.connect(
|
|
4423
4561
|
result.sandboxId,
|
|
4424
4562
|
options?.proxyUrl ?? ingressEndpoint,
|
|
4425
|
-
routingHint
|
|
4563
|
+
routingHint,
|
|
4564
|
+
requestTimeout
|
|
4426
4565
|
);
|
|
4427
|
-
sandbox._setOwner(
|
|
4566
|
+
sandbox._setOwner(requestClient);
|
|
4428
4567
|
sandbox.traceId = result.traceId;
|
|
4429
4568
|
sandbox._setLifecycleIdentifier(result.sandboxId);
|
|
4430
4569
|
sandbox._setName(name ?? requestedName);
|
|
@@ -4441,9 +4580,18 @@ var init_client = __esm({
|
|
|
4441
4580
|
})
|
|
4442
4581
|
);
|
|
4443
4582
|
}
|
|
4444
|
-
|
|
4583
|
+
if (result.status === "timeout" /* TIMEOUT */) {
|
|
4584
|
+
try {
|
|
4585
|
+
await requestClient.delete(result.sandboxId);
|
|
4586
|
+
} catch {
|
|
4587
|
+
}
|
|
4588
|
+
throw new SandboxError(
|
|
4589
|
+
`Sandbox ${result.sandboxId} did not start within ${requestTimeout}s`
|
|
4590
|
+
);
|
|
4591
|
+
}
|
|
4592
|
+
const deadline = Date.now() + secondsToMillis4(requestTimeout);
|
|
4445
4593
|
while (Date.now() < deadline) {
|
|
4446
|
-
const info = await
|
|
4594
|
+
const info = await requestClient.get(result.sandboxId);
|
|
4447
4595
|
if (info.status === "running" /* RUNNING */) {
|
|
4448
4596
|
return finishConnect(info.routingHint, info.name, info.ingressEndpoint);
|
|
4449
4597
|
}
|
|
@@ -4458,11 +4606,11 @@ var init_client = __esm({
|
|
|
4458
4606
|
await sleep2(500);
|
|
4459
4607
|
}
|
|
4460
4608
|
try {
|
|
4461
|
-
await
|
|
4609
|
+
await requestClient.delete(result.sandboxId);
|
|
4462
4610
|
} catch {
|
|
4463
4611
|
}
|
|
4464
4612
|
throw new SandboxError(
|
|
4465
|
-
`Sandbox ${result.sandboxId} did not start within ${
|
|
4613
|
+
`Sandbox ${result.sandboxId} did not start within ${requestTimeout}s`
|
|
4466
4614
|
);
|
|
4467
4615
|
}
|
|
4468
4616
|
};
|