@sandboxrouter/sdk 0.2.0 → 0.3.0
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/README.md +224 -48
- package/dist/bench.js +4 -4
- package/dist/catalog.d.ts +159 -0
- package/dist/catalog.js +448 -15
- package/dist/check.d.ts +28 -0
- package/dist/check.js +185 -0
- package/dist/cli.js +148 -11
- package/dist/computers.d.ts +55 -13
- package/dist/computers.js +132 -6
- package/dist/conformance.d.ts +46 -0
- package/dist/conformance.js +65 -0
- package/dist/cost.d.ts +67 -0
- package/dist/cost.js +153 -0
- package/dist/gc.d.ts +29 -0
- package/dist/gc.js +54 -0
- package/dist/index.d.ts +28 -2
- package/dist/index.js +28 -2
- package/dist/leaderboard.d.ts +6 -0
- package/dist/leaderboard.js +5 -4
- package/dist/ledger.d.ts +38 -0
- package/dist/ledger.js +89 -0
- package/dist/providers/agent37.d.ts +40 -0
- package/dist/providers/agent37.js +224 -0
- package/dist/providers/agentcore.d.ts +71 -0
- package/dist/providers/agentcore.js +446 -0
- package/dist/providers/alibaba.d.ts +18 -0
- package/dist/providers/alibaba.js +106 -0
- package/dist/providers/azure.d.ts +43 -0
- package/dist/providers/azure.js +330 -0
- package/dist/providers/beam.d.ts +11 -0
- package/dist/providers/beam.js +179 -0
- package/dist/providers/blaxel.d.ts +3 -1
- package/dist/providers/blaxel.js +32 -22
- package/dist/providers/boat.js +8 -3
- package/dist/providers/cloudflare.js +8 -3
- package/dist/providers/codesandbox.d.ts +59 -0
- package/dist/providers/codesandbox.js +287 -0
- package/dist/providers/daytona.d.ts +25 -4
- package/dist/providers/daytona.js +449 -28
- package/dist/providers/dedalus.d.ts +12 -0
- package/dist/providers/dedalus.js +244 -0
- package/dist/providers/deno.d.ts +50 -0
- package/dist/providers/deno.js +170 -0
- package/dist/providers/docker.js +11 -5
- package/dist/providers/e2b.d.ts +70 -3
- package/dist/providers/e2b.js +376 -8
- package/dist/providers/exedev.js +17 -5
- package/dist/providers/freestyle.d.ts +49 -0
- package/dist/providers/freestyle.js +261 -0
- package/dist/providers/hopx.js +27 -18
- package/dist/providers/instabox.d.ts +76 -0
- package/dist/providers/instabox.js +360 -0
- package/dist/providers/koyeb.d.ts +71 -0
- package/dist/providers/koyeb.js +379 -0
- package/dist/providers/lambda.d.ts +51 -0
- package/dist/providers/lambda.js +467 -0
- package/dist/providers/langsmith.d.ts +16 -0
- package/dist/providers/langsmith.js +149 -0
- package/dist/providers/limrun.d.ts +77 -0
- package/dist/providers/limrun.js +626 -0
- package/dist/providers/maritime.d.ts +5 -1
- package/dist/providers/maritime.js +39 -8
- package/dist/providers/mobilerun.d.ts +44 -0
- package/dist/providers/mobilerun.js +417 -0
- package/dist/providers/modal.js +12 -4
- package/dist/providers/morph.js +12 -4
- package/dist/providers/northflank.js +11 -13
- package/dist/providers/novita.d.ts +12 -0
- package/dist/providers/novita.js +81 -0
- package/dist/providers/openscale.d.ts +17 -0
- package/dist/providers/openscale.js +87 -0
- package/dist/providers/orgo.d.ts +45 -0
- package/dist/providers/orgo.js +414 -0
- package/dist/providers/sail.d.ts +32 -0
- package/dist/providers/sail.js +372 -0
- package/dist/providers/superserve.d.ts +25 -0
- package/dist/providers/superserve.js +337 -0
- package/dist/providers/tensorlake.js +17 -14
- package/dist/providers/upstash.d.ts +30 -0
- package/dist/providers/upstash.js +258 -0
- package/dist/providers/vercel.js +14 -3
- package/dist/providers/workspaces.d.ts +60 -0
- package/dist/providers/workspaces.js +662 -0
- package/dist/router.d.ts +36 -5
- package/dist/router.js +149 -19
- package/dist/server.d.ts +1 -1
- package/dist/server.js +22 -3
- package/dist/types.d.ts +13 -5
- package/dist/util.d.ts +28 -1
- package/dist/util.js +56 -7
- package/package.json +80 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import { DEFAULT_MEMORY_GB, DEFAULT_VCPU } from "../catalog.js";
|
|
3
3
|
import { ProviderError } from "../types.js";
|
|
4
|
-
import { dirname, optionalImport, shq, toBytes, wrapCommand } from "../util.js";
|
|
4
|
+
import { DEFAULT_EXEC_TIMEOUT_S, dirname, guardTimeout, killedByTimeout, optionalImport, shq, timeoutError, toBytes, wrapCommand } from "../util.js";
|
|
5
5
|
const DEFAULT_IMAGE = "ubuntu:22.04";
|
|
6
6
|
/** Northflank's createOptions.expiryTime bounds: 5 minutes to 7 days. */
|
|
7
7
|
const MIN_EXPIRY_SECONDS = 300;
|
|
@@ -128,19 +128,17 @@ class NorthflankBox {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
|
-
* Exec has no cwd/env/timeout, so cwd/env are wrapped into the command, the
|
|
132
|
-
*
|
|
131
|
+
* Exec has no cwd/env/timeout, so cwd/env are wrapped into the command, the sandbox kills the
|
|
132
|
+
* command at the deadline (`guardTimeout`), and this side gives up a little later as a fallback.
|
|
133
133
|
*/
|
|
134
134
|
async exec(cmd, opts = {}) {
|
|
135
135
|
const t0 = Date.now();
|
|
136
|
-
const secs = opts.timeoutSeconds ??
|
|
137
|
-
const
|
|
138
|
-
const
|
|
139
|
-
const r = await this.run(["/bin/sh", "-c", guarded], secs * 1000 + 10_000, opts);
|
|
136
|
+
const secs = opts.timeoutSeconds ?? DEFAULT_EXEC_TIMEOUT_S;
|
|
137
|
+
const guarded = guardTimeout(wrapCommand(cmd, { cwd: opts.cwd, env: opts.env }), secs);
|
|
138
|
+
const r = await this.run(["/bin/sh", "-c", guarded], secs * 1000 + 10_000, opts, undefined, () => timeoutError("northflank", secs));
|
|
140
139
|
const durationMs = Date.now() - t0;
|
|
141
|
-
if (
|
|
142
|
-
throw
|
|
143
|
-
}
|
|
140
|
+
if (killedByTimeout(r.exitCode, durationMs, secs))
|
|
141
|
+
throw timeoutError("northflank", secs);
|
|
144
142
|
return { ...r, durationMs };
|
|
145
143
|
}
|
|
146
144
|
/** Stream base64 over stdin and decode in the sandbox. */
|
|
@@ -159,8 +157,8 @@ class NorthflankBox {
|
|
|
159
157
|
async kill() {
|
|
160
158
|
await call(() => this.nf.delete.service({ parameters: this.params }));
|
|
161
159
|
}
|
|
162
|
-
/** One exec session: optional stdin, streamed stdout/stderr, exit code. */
|
|
163
|
-
async run(command, limitMs, opts = {}, stdin) {
|
|
160
|
+
/** One exec session: optional stdin, streamed stdout/stderr, exit code. `expired` is thrown when limitMs passes. */
|
|
161
|
+
async run(command, limitMs, opts = {}, stdin, expired = () => timeoutError("northflank", Math.round(limitMs / 1000))) {
|
|
164
162
|
const t0 = Date.now();
|
|
165
163
|
let session;
|
|
166
164
|
try {
|
|
@@ -197,7 +195,7 @@ class NorthflankBox {
|
|
|
197
195
|
try {
|
|
198
196
|
const res = await Promise.race([session.waitForCommandResult(), failed, timedOut]);
|
|
199
197
|
if (res === "timeout")
|
|
200
|
-
throw
|
|
198
|
+
throw expired();
|
|
201
199
|
return { exitCode: typeof res.exitCode === "number" ? res.exitCode : -1, stdout, stderr };
|
|
202
200
|
}
|
|
203
201
|
catch (err) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Provider, type ProviderSandbox, type SandboxSpec } from "../types.js";
|
|
2
|
+
export declare class NovitaProvider implements Provider {
|
|
3
|
+
private apiKey;
|
|
4
|
+
private domain;
|
|
5
|
+
readonly id: "novita";
|
|
6
|
+
constructor(apiKey?: string | undefined, domain?: string | undefined);
|
|
7
|
+
configured(): boolean;
|
|
8
|
+
private conn;
|
|
9
|
+
create(spec: SandboxSpec): Promise<ProviderSandbox>;
|
|
10
|
+
/** Reattach by sandbox id; a paused sandbox is resumed. */
|
|
11
|
+
connect(nativeId: string): Promise<ProviderSandbox>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ProviderError } from "../types.js";
|
|
2
|
+
import { optionalImport } from "../util.js";
|
|
3
|
+
import { E2BBox } from "./e2b.js";
|
|
4
|
+
/**
|
|
5
|
+
* Novita AI Agent Sandbox via the official `novita-sandbox` SDK (2.x), a fork of E2B's SDK with
|
|
6
|
+
* the same surface (Sandbox.create/connect, commands.run with onStdout/onStderr, files.read/write,
|
|
7
|
+
* pause, kill), so the E2B box wrapper is reused as-is.
|
|
8
|
+
*
|
|
9
|
+
* Why not the `e2b` SDK with Novita's domain: that was Novita's documented route for its v1
|
|
10
|
+
* cluster (sandbox.novita.ai), but since the 2026-06-08 SDK 2.0 release the E2B-compatible page
|
|
11
|
+
* is a "Legacy SDKs & CLI" page for the 1.x line, the default cluster moved to
|
|
12
|
+
* us-phx-1.sandbox.novita.ai, and the docs only describe `novita-sandbox` for it.
|
|
13
|
+
*
|
|
14
|
+
* Auth: NOVITA_API_KEY (sent as X-API-KEY by the SDK). NOVITA_DOMAIN optionally picks the cluster
|
|
15
|
+
* (default us-phx-1.sandbox.novita.ai; sandbox.novita.ai is the legacy v1 cluster). Resources are
|
|
16
|
+
* not shared between clusters.
|
|
17
|
+
* Size: vCPU and memory come from the template (set at template build time: cpuCount/memoryMB),
|
|
18
|
+
* not from the create call, exactly like E2B. image.novita = template name or ID (default "base").
|
|
19
|
+
* Pause keeps memory and disk; Sandbox.connect resumes it. Billing is per second for CPU and RAM
|
|
20
|
+
* while running; paused sandboxes pay only persistent storage beyond 60 GB free.
|
|
21
|
+
*
|
|
22
|
+
* Docs: https://docs.novita.ai/guides/sandbox-overview.md (regions/domains)
|
|
23
|
+
* https://docs.novita.ai/guides/sandbox-your-first-agent-sandbox.md (NOVITA_API_KEY, SDK)
|
|
24
|
+
* https://docs.novita.ai/guides/sandbox-metadata.md (create: template, timeoutMs, envs, metadata)
|
|
25
|
+
* https://docs.novita.ai/guides/sandbox-persistence.md (pause / connect resumes)
|
|
26
|
+
* https://docs.novita.ai/guides/sandbox-quota-limit.md (vCPU/memory/session limits)
|
|
27
|
+
* https://docs.novita.ai/guides/sandbox-pricing.md
|
|
28
|
+
* https://docs.novita.ai/changelog/08-06-26 (SDK 2.0, new default cluster)
|
|
29
|
+
* https://docs.novita.ai/guides/sandbox-legacy-e2b-compatible (legacy 1.x / E2B route)
|
|
30
|
+
*/
|
|
31
|
+
const ID = "novita";
|
|
32
|
+
export class NovitaProvider {
|
|
33
|
+
apiKey;
|
|
34
|
+
domain;
|
|
35
|
+
id = ID;
|
|
36
|
+
constructor(apiKey = process.env.NOVITA_API_KEY, domain = process.env.NOVITA_DOMAIN) {
|
|
37
|
+
this.apiKey = apiKey;
|
|
38
|
+
this.domain = domain;
|
|
39
|
+
}
|
|
40
|
+
configured() {
|
|
41
|
+
return !!this.apiKey;
|
|
42
|
+
}
|
|
43
|
+
conn() {
|
|
44
|
+
if (!this.apiKey)
|
|
45
|
+
throw new ProviderError(ID, "NOVITA_API_KEY is not set");
|
|
46
|
+
return { apiKey: this.apiKey, ...(this.domain ? { domain: this.domain } : {}) };
|
|
47
|
+
}
|
|
48
|
+
async create(spec) {
|
|
49
|
+
const { Sandbox } = await optionalImport("novita-sandbox", "novita");
|
|
50
|
+
const opts = {
|
|
51
|
+
...this.conn(),
|
|
52
|
+
timeoutMs: (spec.timeoutMinutes ?? 30) * 60_000,
|
|
53
|
+
envs: spec.env,
|
|
54
|
+
metadata: spec.metadata,
|
|
55
|
+
};
|
|
56
|
+
const template = spec.image?.novita;
|
|
57
|
+
try {
|
|
58
|
+
const sbx = template ? await Sandbox.create(template, opts) : await Sandbox.create(opts);
|
|
59
|
+
return new E2BBox(sbx, ID);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
throw wrap(err);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Reattach by sandbox id; a paused sandbox is resumed. */
|
|
66
|
+
async connect(nativeId) {
|
|
67
|
+
const { Sandbox } = await optionalImport("novita-sandbox", "novita");
|
|
68
|
+
try {
|
|
69
|
+
return new E2BBox(await Sandbox.connect(nativeId, this.conn()), ID);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
throw wrap(err);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function wrap(err) {
|
|
77
|
+
if (err instanceof ProviderError)
|
|
78
|
+
return err;
|
|
79
|
+
const status = err?.name === "SandboxNotFoundError" || err?.name === "NotFoundError" ? 404 : err?.name === "AuthenticationError" ? 401 : undefined;
|
|
80
|
+
return new ProviderError(ID, err?.message ?? String(err), status);
|
|
81
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Provider, type ProviderSandbox, type SandboxSpec } from "../types.js";
|
|
2
|
+
export declare const OPENSCALE_DOMAIN = "sandbox.openscale.so";
|
|
3
|
+
export declare class OpenScaleProvider implements Provider {
|
|
4
|
+
private apiKey;
|
|
5
|
+
readonly id: "openscale";
|
|
6
|
+
constructor(apiKey?: string | undefined);
|
|
7
|
+
configured(): boolean;
|
|
8
|
+
/** @internal Connection options for the e2b SDK. */
|
|
9
|
+
conn(): {
|
|
10
|
+
apiKey: string;
|
|
11
|
+
domain: string;
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
};
|
|
14
|
+
create(spec: SandboxSpec): Promise<ProviderSandbox>;
|
|
15
|
+
/** Reattach by sandbox id; a paused sandbox is resumed. */
|
|
16
|
+
connect(nativeId: string): Promise<ProviderSandbox>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ProviderError } from "../types.js";
|
|
2
|
+
import { optionalImport } from "../util.js";
|
|
3
|
+
import { E2BBox } from "./e2b.js";
|
|
4
|
+
/**
|
|
5
|
+
* OpenScale Sandboxes (YC S22) through their E2B-compatible API, driven with the official `e2b`
|
|
6
|
+
* SDK pointed at OpenScale's domain:
|
|
7
|
+
* API URL https://api.sandbox.openscale.so (the SDK's https://api.<domain> default)
|
|
8
|
+
* domain sandbox.openscale.so (data plane: <port>-<sandboxId>.<domain>)
|
|
9
|
+
* OpenScale's own instructions are E2B_DOMAIN=sandbox.openscale.so plus the OpenScale key as
|
|
10
|
+
* E2B_API_KEY. This adapter does not read E2B_API_KEY, so a real E2B key is never sent to
|
|
11
|
+
* OpenScale (and an OpenScale key never to E2B): it reads OPENSCALE_API_KEY (the name OpenScale's
|
|
12
|
+
* model docs use) and passes key, domain and apiUrl explicitly, so a stray E2B_DOMAIN or
|
|
13
|
+
* E2B_API_URL can't redirect calls. E2B_SANDBOX_URL would still override the data plane, so don't
|
|
14
|
+
* set it alongside this adapter.
|
|
15
|
+
*
|
|
16
|
+
* Auth: a pay-as-you-go OpenScale key (sk-openscale-...), the same account and credits as their
|
|
17
|
+
* model API. Plan (subscription) keys are refused: the API answers 401 "Use a pay-as-you-go
|
|
18
|
+
* OpenScale API key; plan keys don't run sandboxes". A new key can take ~30 s to start working.
|
|
19
|
+
* Region: Singapore only for now.
|
|
20
|
+
*
|
|
21
|
+
* Size: vCPU and memory come from the template, as with E2B (1-8 vCPU, up to 16 GB, 25 GB disk
|
|
22
|
+
* included, no GPU). image.openscale = template name or ID; default "base", the template the
|
|
23
|
+
* quick start says a sandbox starts from. Custom templates are built with the E2B template
|
|
24
|
+
* builder or CLI (Dockerfile) against the same domain.
|
|
25
|
+
* Lifetime: timeoutMs as given; OpenScale advertises no session time limit or 24 h cap, so no cap
|
|
26
|
+
* is applied here.
|
|
27
|
+
* Pause/resume is advertised as built in (memory and files kept, paused sandboxes are free), so
|
|
28
|
+
* the box offers pause(); Sandbox.connect resumes. Not supported yet per OpenScale: volumes,
|
|
29
|
+
* secrets, fork, snapshots API.
|
|
30
|
+
*
|
|
31
|
+
* Docs: https://openscale.so/sandboxes (setup, limits, pricing, FAQ)
|
|
32
|
+
* https://openscale.so/app/sandboxes (keys and quick start, signed in)
|
|
33
|
+
* https://openscale.so/docs (API keys: pay-as-you-go vs plan keys)
|
|
34
|
+
*/
|
|
35
|
+
const ID = "openscale";
|
|
36
|
+
export const OPENSCALE_DOMAIN = "sandbox.openscale.so";
|
|
37
|
+
const DEFAULT_TEMPLATE = "base";
|
|
38
|
+
export class OpenScaleProvider {
|
|
39
|
+
apiKey;
|
|
40
|
+
id = ID;
|
|
41
|
+
constructor(apiKey = process.env.OPENSCALE_API_KEY) {
|
|
42
|
+
this.apiKey = apiKey;
|
|
43
|
+
}
|
|
44
|
+
configured() {
|
|
45
|
+
return !!this.apiKey;
|
|
46
|
+
}
|
|
47
|
+
/** @internal Connection options for the e2b SDK. */
|
|
48
|
+
conn() {
|
|
49
|
+
if (!this.apiKey)
|
|
50
|
+
throw new ProviderError(ID, "OPENSCALE_API_KEY is not set");
|
|
51
|
+
return { apiKey: this.apiKey, domain: OPENSCALE_DOMAIN, apiUrl: `https://api.${OPENSCALE_DOMAIN}` };
|
|
52
|
+
}
|
|
53
|
+
async create(spec) {
|
|
54
|
+
const conn = this.conn();
|
|
55
|
+
const { Sandbox } = await optionalImport("e2b", "openscale");
|
|
56
|
+
const timeoutMs = Math.max(1, spec.timeoutMinutes ?? 30) * 60_000;
|
|
57
|
+
try {
|
|
58
|
+
const sbx = await Sandbox.create(spec.image?.openscale ?? DEFAULT_TEMPLATE, {
|
|
59
|
+
...conn,
|
|
60
|
+
timeoutMs,
|
|
61
|
+
envs: spec.env,
|
|
62
|
+
metadata: spec.metadata,
|
|
63
|
+
});
|
|
64
|
+
return new E2BBox(sbx, ID);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
throw wrap(err);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Reattach by sandbox id; a paused sandbox is resumed. */
|
|
71
|
+
async connect(nativeId) {
|
|
72
|
+
const conn = this.conn();
|
|
73
|
+
const { Sandbox } = await optionalImport("e2b", "openscale");
|
|
74
|
+
try {
|
|
75
|
+
return new E2BBox((await Sandbox.connect(nativeId, conn)), ID);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
throw wrap(err);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function wrap(err) {
|
|
83
|
+
if (err instanceof ProviderError)
|
|
84
|
+
return err;
|
|
85
|
+
const status = err?.name === "SandboxNotFoundError" || err?.name === "NotFoundError" ? 404 : err?.name === "AuthenticationError" ? 401 : undefined;
|
|
86
|
+
return new ProviderError(ID, err?.message ?? String(err), status);
|
|
87
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ComputerOs, ComputerProvider, ComputerSpec, ProviderComputer } from "../computers.js";
|
|
2
|
+
type Json = Record<string, any>;
|
|
3
|
+
export declare class OrgoProvider implements ComputerProvider {
|
|
4
|
+
private apiKey;
|
|
5
|
+
private baseUrl;
|
|
6
|
+
/** Workspace to create computers in. Unset: the first workspace this key can write to. */
|
|
7
|
+
private workspaceId;
|
|
8
|
+
readonly id: "orgo";
|
|
9
|
+
/**
|
|
10
|
+
* Linux on every account. Windows is created with `os: "windows"` but needs a Scale plan or a
|
|
11
|
+
* purchased Windows licence (else 403 WINDOWS_REQUIRES_SCALE) and is never offered by the hour.
|
|
12
|
+
* Android, macOS and iPhone are devices set up on request, not self-serve.
|
|
13
|
+
*/
|
|
14
|
+
readonly computerOs: ComputerOs[];
|
|
15
|
+
private workspace?;
|
|
16
|
+
constructor(apiKey?: string | undefined, baseUrl?: string,
|
|
17
|
+
/** Workspace to create computers in. Unset: the first workspace this key can write to. */
|
|
18
|
+
workspaceId?: string | undefined);
|
|
19
|
+
configured(): boolean;
|
|
20
|
+
/** @internal Authenticated call to the Orgo API. Throws ProviderError with the HTTP status. */
|
|
21
|
+
request(method: string, path: string, init?: {
|
|
22
|
+
json?: unknown;
|
|
23
|
+
form?: FormData;
|
|
24
|
+
query?: Record<string, string>;
|
|
25
|
+
}): Promise<Response>;
|
|
26
|
+
/** @internal */
|
|
27
|
+
json<T = Json>(method: string, path: string, init?: {
|
|
28
|
+
json?: unknown;
|
|
29
|
+
form?: FormData;
|
|
30
|
+
query?: Record<string, string>;
|
|
31
|
+
}): Promise<T>;
|
|
32
|
+
/** @internal The workspace new computers go in: ORGO_WORKSPACE_ID, else the first one the key can write to. */
|
|
33
|
+
resolveWorkspace(): Promise<string>;
|
|
34
|
+
createComputer(spec: ComputerSpec): Promise<ProviderComputer>;
|
|
35
|
+
/**
|
|
36
|
+
* Reattach to a computer. A stopped (frozen) one is started, a suspended one resumed. Both answer
|
|
37
|
+
* 202 while the computer comes back, so it is polled until it reports running.
|
|
38
|
+
*/
|
|
39
|
+
connectComputer(nativeId: string): Promise<ProviderComputer>;
|
|
40
|
+
/** Poll a computer until it is running; a computer that errored or was deleted meanwhile is reported. */
|
|
41
|
+
private waitRunning;
|
|
42
|
+
/** @internal wss:// origin for the computer's VNC WebSocket (same host as the API). */
|
|
43
|
+
wsOrigin(): string;
|
|
44
|
+
}
|
|
45
|
+
export {};
|