withruntime 0.3.0 → 0.4.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/E2B.md +146 -0
- package/README.md +41 -5
- package/dist/cli.js +43 -7
- package/dist/client.d.ts +5 -0
- package/dist/e2b/client.d.ts +58 -0
- package/dist/e2b/client.js +66 -0
- package/dist/e2b/code-interpreter.d.ts +144 -0
- package/dist/e2b/code-interpreter.js +244 -0
- package/dist/e2b/commands.d.ts +100 -0
- package/dist/e2b/commands.js +268 -0
- package/dist/e2b/errors.d.ts +72 -0
- package/dist/e2b/errors.js +151 -0
- package/dist/e2b/filesystem.d.ts +82 -0
- package/dist/e2b/filesystem.js +143 -0
- package/dist/e2b/index.d.ts +28 -0
- package/dist/e2b/index.js +61 -0
- package/dist/e2b/sandbox.d.ts +183 -0
- package/dist/e2b/sandbox.js +458 -0
- package/dist/e2b/unsupported.d.ts +19 -0
- package/dist/e2b/unsupported.js +27 -0
- package/dist/index.d.ts +1 -0
- package/dist/login.js +13 -4
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +4 -3
- package/dist/products/index.d.ts +2 -0
- package/dist/products/index.js +2 -1
- package/dist/products/limits.d.ts +25 -0
- package/dist/products/limits.js +10 -0
- package/dist/products/previews.d.ts +3 -0
- package/dist/proxy.d.ts +30 -0
- package/dist/proxy.js +178 -0
- package/dist/sandbox.d.ts +4 -1
- package/dist/transport.d.ts +1 -1
- package/dist/transport.js +46 -13
- package/package.json +16 -3
|
@@ -18,6 +18,9 @@ export type Preview = {
|
|
|
18
18
|
/** Turned off by Runtime after a report. */
|
|
19
19
|
disabled: boolean;
|
|
20
20
|
createdAt: string;
|
|
21
|
+
/** On create only: how to share the address, and the referral link that
|
|
22
|
+
* pays you both when someone you share it with signs up. */
|
|
23
|
+
hint?: string;
|
|
21
24
|
};
|
|
22
25
|
export type CreatePreview = {
|
|
23
26
|
/** private (default): a token is needed. public: anyone with the address;
|
package/dist/proxy.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type Env = Record<string, string | undefined>;
|
|
2
|
+
/** How a call to an address leaves this machine. */
|
|
3
|
+
export type Route = {
|
|
4
|
+
/** The proxy's address, credentials included, to connect through. */
|
|
5
|
+
proxy?: string;
|
|
6
|
+
/** The proxy as it may be shown: no user name or password. */
|
|
7
|
+
shown?: string;
|
|
8
|
+
/** The variable the proxy or the exemption came from. */
|
|
9
|
+
variable?: string;
|
|
10
|
+
/** Set when NO_PROXY exempts the host: the entry that matched. */
|
|
11
|
+
exempt?: string;
|
|
12
|
+
/** HTTP_PROXY was set but HTTPS_PROXY was not, for an HTTPS address. */
|
|
13
|
+
httpOnly?: string;
|
|
14
|
+
};
|
|
15
|
+
/** Whether a NO_PROXY list names this host (and port). Returns the entry. */
|
|
16
|
+
export declare function exemption(list: string, hostname: string, port: string): string | undefined;
|
|
17
|
+
/** The route the SDK takes to `target`, read from the environment now. */
|
|
18
|
+
export declare function routeFor(target: string, env?: Env): Route;
|
|
19
|
+
/** Words for a failed connection: the route it took, and what to check.
|
|
20
|
+
* `cause` is the error fetch threw, or the status a proxy answered with (Bun's
|
|
21
|
+
* fetch hands a refused tunnel back as a response). */
|
|
22
|
+
export declare function describeRoute(target: string, cause: unknown, env?: Env): {
|
|
23
|
+
via: string;
|
|
24
|
+
hint?: string;
|
|
25
|
+
};
|
|
26
|
+
/** fetch, through the proxy the environment names for the address. */
|
|
27
|
+
export declare const envFetch: typeof fetch;
|
|
28
|
+
/** A WebSocket, through the proxy the environment names for the address. */
|
|
29
|
+
export declare function openWebSocket(url: string, headers: Record<string, string>): Promise<WebSocket>;
|
|
30
|
+
export {};
|
package/dist/proxy.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/* Proxies named by the environment: HTTPS_PROXY, HTTP_PROXY and NO_PROXY, in
|
|
2
|
+
lower or upper case, the lower winning when both are set (as curl reads
|
|
3
|
+
them). Bun's fetch reads them itself; its WebSocket and Node's fetch and
|
|
4
|
+
WebSocket do not unless NODE_USE_ENV_PROXY was set before the process
|
|
5
|
+
started, which a library cannot do for its host. So every call the SDK and
|
|
6
|
+
the CLI make goes through `envFetch` and `openWebSocket`, which route by the
|
|
7
|
+
same rule on every runtime:
|
|
8
|
+
|
|
9
|
+
- an https:// or wss:// address uses HTTPS_PROXY; an http:// or ws:// one
|
|
10
|
+
uses HTTP_PROXY. HTTP_PROXY is never used for HTTPS (curl, Bun, Python
|
|
11
|
+
and Go agree; Node's own env support would fall back to it). A connection
|
|
12
|
+
error says so when that is why nothing was tried.
|
|
13
|
+
- NO_PROXY is a list of host names split by commas or spaces. A name
|
|
14
|
+
covers its subdomains, a leading dot is allowed, host:port limits it to
|
|
15
|
+
one port, and `*` alone means every host.
|
|
16
|
+
- A proxy address without a scheme is http://. Only http:// and https://
|
|
17
|
+
proxies are spoken to.
|
|
18
|
+
|
|
19
|
+
On Node the proxy is undici's ProxyAgent: undici is Node's own HTTP client
|
|
20
|
+
(the code under its fetch and WebSocket), loaded only when a proxy applies.
|
|
21
|
+
On Bun the proxy is passed to fetch and WebSocket as their `proxy` option. */
|
|
22
|
+
import { RuntimeError } from "./errors.js";
|
|
23
|
+
const processEnv = () => (typeof process === "undefined" ? {} : process.env);
|
|
24
|
+
function variable(env, name) {
|
|
25
|
+
for (const candidate of [name.toLowerCase(), name.toUpperCase()]) {
|
|
26
|
+
const value = env[candidate]?.trim();
|
|
27
|
+
if (value)
|
|
28
|
+
return { value, name: candidate };
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
/** Whether a NO_PROXY list names this host (and port). Returns the entry. */
|
|
33
|
+
export function exemption(list, hostname, port) {
|
|
34
|
+
const host = hostname
|
|
35
|
+
.toLowerCase()
|
|
36
|
+
.replace(/^\[|\]$/g, "")
|
|
37
|
+
.replace(/\.$/, "");
|
|
38
|
+
for (const raw of list.split(/[\s,]+/)) {
|
|
39
|
+
const entry = raw.trim().toLowerCase();
|
|
40
|
+
if (!entry)
|
|
41
|
+
continue;
|
|
42
|
+
if (entry === "*")
|
|
43
|
+
return entry;
|
|
44
|
+
const match = /^(.*?)(?::(\d+))?$/.exec(entry.replace(/^\[(.*)\]/, "$1"));
|
|
45
|
+
const name = match[1].replace(/^\./, "").replace(/\.$/, "");
|
|
46
|
+
if (!name || (match[2] && match[2] !== port))
|
|
47
|
+
continue;
|
|
48
|
+
if (host === name || host.endsWith(`.${name}`))
|
|
49
|
+
return entry;
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
/** The route the SDK takes to `target`, read from the environment now. */
|
|
54
|
+
export function routeFor(target, env = processEnv()) {
|
|
55
|
+
const url = new URL(target);
|
|
56
|
+
const secure = url.protocol === "https:" || url.protocol === "wss:";
|
|
57
|
+
const port = url.port || (secure ? "443" : "80");
|
|
58
|
+
const found = variable(env, secure ? "https_proxy" : "http_proxy");
|
|
59
|
+
if (!found) {
|
|
60
|
+
const http = secure ? variable(env, "http_proxy") : undefined;
|
|
61
|
+
return http ? { httpOnly: http.name } : {};
|
|
62
|
+
}
|
|
63
|
+
const skip = variable(env, "no_proxy");
|
|
64
|
+
const exempt = skip && exemption(skip.value, url.hostname, port);
|
|
65
|
+
if (skip && exempt)
|
|
66
|
+
return { exempt, variable: skip.name };
|
|
67
|
+
const proxy = /^[a-z][a-z0-9+.-]*:\/\//i.test(found.value)
|
|
68
|
+
? found.value
|
|
69
|
+
: `http://${found.value}`;
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = new URL(proxy);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
throw invalidProxy(found.name, found.value, "is not an address");
|
|
76
|
+
}
|
|
77
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
|
|
78
|
+
throw invalidProxy(found.name, `${parsed.protocol}//${parsed.host}`, "is not an HTTP proxy");
|
|
79
|
+
return { proxy, shown: `${parsed.protocol}//${parsed.host}`, variable: found.name };
|
|
80
|
+
}
|
|
81
|
+
function invalidProxy(name, shown, problem) {
|
|
82
|
+
return new RuntimeError({
|
|
83
|
+
message: `${name} (${shown}) ${problem}; Runtime connects through http:// and https:// proxies.`,
|
|
84
|
+
code: "invalid_proxy",
|
|
85
|
+
status: 0,
|
|
86
|
+
hint: `Set ${name} to the proxy's address, for example http://proxy.example.com:3128, or unset it.`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** Words for a failed connection: the route it took, and what to check.
|
|
90
|
+
* `cause` is the error fetch threw, or the status a proxy answered with (Bun's
|
|
91
|
+
* fetch hands a refused tunnel back as a response). */
|
|
92
|
+
export function describeRoute(target, cause, env = processEnv()) {
|
|
93
|
+
let route;
|
|
94
|
+
try {
|
|
95
|
+
route = routeFor(target, env);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return { via: "" };
|
|
99
|
+
}
|
|
100
|
+
const url = new URL(target);
|
|
101
|
+
const port = url.port || (url.protocol === "https:" ? "443" : "80");
|
|
102
|
+
if (route.proxy) {
|
|
103
|
+
const status = typeof cause === "number" ? cause : proxyStatus(cause);
|
|
104
|
+
return {
|
|
105
|
+
via: ` through the proxy ${route.shown} (${route.variable})${status ? `, which answered HTTP ${status} to the tunnel request` : ""}`,
|
|
106
|
+
hint: status === 407
|
|
107
|
+
? `The proxy wants credentials: put them in ${route.variable}, as http://user:password@host:port.`
|
|
108
|
+
: `Check that the proxy is running and allows CONNECT to ${url.hostname}:${port}, or list ${url.hostname} in NO_PROXY to connect directly.`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (route.exempt)
|
|
112
|
+
return {
|
|
113
|
+
via: ` (directly: ${route.variable} lists ${route.exempt})`,
|
|
114
|
+
hint: `Check the network, or remove ${route.exempt} from ${route.variable} to go through the proxy.`,
|
|
115
|
+
};
|
|
116
|
+
if (route.httpOnly)
|
|
117
|
+
return {
|
|
118
|
+
via: " (directly: no HTTPS proxy is set)",
|
|
119
|
+
hint: `${route.httpOnly} is set but HTTPS_PROXY is not, and ${url.hostname} is HTTPS. Set HTTPS_PROXY to the proxy to use it.`,
|
|
120
|
+
};
|
|
121
|
+
return { via: "" };
|
|
122
|
+
}
|
|
123
|
+
/** The status a proxy refused a tunnel with, from undici's or Bun's error. */
|
|
124
|
+
function proxyStatus(cause) {
|
|
125
|
+
for (let error = cause, depth = 0; error && depth < 5; depth++) {
|
|
126
|
+
const message = error.message;
|
|
127
|
+
const text = typeof message === "string" ? message : "";
|
|
128
|
+
const found = /proxy response \((\d{3})\)|proxy.*?\b(40[37]|50[0-9])\b/i.exec(text);
|
|
129
|
+
if (found)
|
|
130
|
+
return Number(found[1] ?? found[2]);
|
|
131
|
+
error = error.cause;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
const isBun = () => typeof process !== "undefined" && !!process.versions?.bun;
|
|
136
|
+
const isNode = () => typeof process !== "undefined" &&
|
|
137
|
+
!!process.versions?.node &&
|
|
138
|
+
!process.versions.bun &&
|
|
139
|
+
!("Deno" in globalThis);
|
|
140
|
+
const agents = new Map();
|
|
141
|
+
/** One undici ProxyAgent per proxy address, so connections are reused. */
|
|
142
|
+
function undici(proxy) {
|
|
143
|
+
let agent = agents.get(proxy);
|
|
144
|
+
if (!agent) {
|
|
145
|
+
agent = import("undici").then((module) => ({
|
|
146
|
+
fetch: module.fetch,
|
|
147
|
+
WebSocket: module.WebSocket,
|
|
148
|
+
dispatcher: new module.ProxyAgent({ uri: proxy }),
|
|
149
|
+
}));
|
|
150
|
+
agent.catch(() => agents.delete(proxy));
|
|
151
|
+
agents.set(proxy, agent);
|
|
152
|
+
}
|
|
153
|
+
return agent;
|
|
154
|
+
}
|
|
155
|
+
/** fetch, through the proxy the environment names for the address. */
|
|
156
|
+
export const envFetch = (async (input, init) => {
|
|
157
|
+
const target = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
158
|
+
const { proxy } = routeFor(target);
|
|
159
|
+
if (proxy && isBun())
|
|
160
|
+
return fetch(input, { ...init, proxy });
|
|
161
|
+
if (proxy && isNode()) {
|
|
162
|
+
const { fetch: proxied, dispatcher } = await undici(proxy);
|
|
163
|
+
return (await proxied(target, { ...init, dispatcher }));
|
|
164
|
+
}
|
|
165
|
+
return fetch(input, init);
|
|
166
|
+
});
|
|
167
|
+
/** A WebSocket, through the proxy the environment names for the address. */
|
|
168
|
+
export async function openWebSocket(url, headers) {
|
|
169
|
+
const { proxy } = routeFor(url);
|
|
170
|
+
if (proxy && isNode()) {
|
|
171
|
+
const { WebSocket: Proxied, dispatcher } = await undici(proxy);
|
|
172
|
+
return new Proxied(url, { headers, dispatcher });
|
|
173
|
+
}
|
|
174
|
+
const Socket = globalThis.WebSocket;
|
|
175
|
+
if (!Socket)
|
|
176
|
+
throw new Error("This runtime has no WebSocket; use Node 22+ or Bun.");
|
|
177
|
+
return new Socket(url, proxy && isBun() ? { headers, proxy } : { headers });
|
|
178
|
+
}
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -74,17 +74,20 @@ export declare class Sandbox implements AsyncDisposable {
|
|
|
74
74
|
/** Copies of this sandbox as it is now (files, memory, running processes),
|
|
75
75
|
* each its own sandbox, answered once they run. A running sandbox is paused
|
|
76
76
|
* for the moment its snapshot takes, then woken. One without `count`; an
|
|
77
|
-
* array with it.
|
|
77
|
+
* array with it. `funding` is what the copies run on, as for a create;
|
|
78
|
+
* omitted, they keep this sandbox's. */
|
|
78
79
|
fork(options?: {
|
|
79
80
|
name?: string;
|
|
80
81
|
labels?: Record<string, string>;
|
|
81
82
|
keepSnapshot?: boolean;
|
|
83
|
+
funding?: "trial" | "paid";
|
|
82
84
|
} & RequestOptions): Promise<Sandbox>;
|
|
83
85
|
fork(options: {
|
|
84
86
|
count: number;
|
|
85
87
|
name?: string;
|
|
86
88
|
labels?: Record<string, string>;
|
|
87
89
|
keepSnapshot?: boolean;
|
|
90
|
+
funding?: "trial" | "paid";
|
|
88
91
|
} & RequestOptions): Promise<Sandbox[]>;
|
|
89
92
|
/** Starts a stopped persistent sandbox again from its disk (memory is not kept). */
|
|
90
93
|
restart(options?: RequestOptions & {
|
package/dist/transport.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RuntimeError } from "./errors.js";
|
|
2
|
-
export declare const VERSION = "0.
|
|
2
|
+
export declare const VERSION = "0.4.0";
|
|
3
3
|
export declare const DEFAULT_BASE_URL = "https://api.withruntime.com";
|
|
4
4
|
export type RequestOptions = {
|
|
5
5
|
/** Sent as Idempotency-Key. Omit it: the SDK makes one per call and keeps
|
package/dist/transport.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ConnectionError, errorFor, RuntimeError } from "./errors.js";
|
|
2
|
-
|
|
2
|
+
import { describeRoute, envFetch, openWebSocket } from "./proxy.js";
|
|
3
|
+
export const VERSION = "0.4.0";
|
|
3
4
|
export const DEFAULT_BASE_URL = "https://api.withruntime.com";
|
|
4
5
|
export function apiOrigin(value) {
|
|
5
6
|
const url = new URL(value);
|
|
@@ -83,6 +84,8 @@ export class Transport {
|
|
|
83
84
|
#apiKey;
|
|
84
85
|
#findKey;
|
|
85
86
|
#fetch;
|
|
87
|
+
/** Whether calls go through envFetch, so a failure can name its proxy. */
|
|
88
|
+
#routed;
|
|
86
89
|
#timeoutMs;
|
|
87
90
|
#maxRetries;
|
|
88
91
|
#client;
|
|
@@ -95,7 +98,10 @@ export class Transport {
|
|
|
95
98
|
else
|
|
96
99
|
this.#apiKey = options.apiKey;
|
|
97
100
|
this.baseUrl = apiOrigin(options.baseUrl ?? DEFAULT_BASE_URL);
|
|
98
|
-
|
|
101
|
+
// The environment's proxy (HTTPS_PROXY, NO_PROXY) on Node and Bun alike;
|
|
102
|
+
// a fetch passed in is used as it is.
|
|
103
|
+
this.#fetch = options.fetch ?? envFetch;
|
|
104
|
+
this.#routed = options.fetch === undefined;
|
|
99
105
|
this.#timeoutMs = options.timeoutMs ?? 300_000;
|
|
100
106
|
this.#maxRetries = options.maxRetries ?? 4;
|
|
101
107
|
this.#client = options.client ?? `sdk-js/${VERSION}`;
|
|
@@ -139,36 +145,65 @@ export class Transport {
|
|
|
139
145
|
const retry = call.retry ?? true;
|
|
140
146
|
for (let attempt = 0;; attempt++) {
|
|
141
147
|
let response;
|
|
148
|
+
// Called as a plain function: Cloudflare Workers' fetch throws "Illegal
|
|
149
|
+
// invocation" when called as a method of another object (this.#fetch()).
|
|
150
|
+
const send = this.#fetch;
|
|
142
151
|
try {
|
|
143
|
-
|
|
152
|
+
// "manual", not "error": Workers accept only "follow" and "manual".
|
|
153
|
+
// The API never redirects, so a redirect is refused here exactly as
|
|
154
|
+
// "error" refused it: thrown, retried, then a connection_error.
|
|
155
|
+
response = await send(url, {
|
|
144
156
|
method: call.method,
|
|
145
157
|
headers: this.#headers(call, key, apiKey),
|
|
146
|
-
redirect: "
|
|
158
|
+
redirect: "manual",
|
|
147
159
|
signal,
|
|
148
160
|
...(body === undefined ? {} : { body: body }),
|
|
149
161
|
});
|
|
162
|
+
if (response.type === "opaqueredirect" ||
|
|
163
|
+
(response.status >= 300 && response.status < 400)) {
|
|
164
|
+
await response.body?.cancel().catch(() => { });
|
|
165
|
+
throw new TypeError(`fetch failed: Runtime answered a redirect (${response.status}).`);
|
|
166
|
+
}
|
|
150
167
|
}
|
|
151
168
|
catch (cause) {
|
|
152
|
-
|
|
169
|
+
// A proxy variable the SDK cannot use: retrying cannot change it.
|
|
170
|
+
if (cause instanceof RuntimeError)
|
|
171
|
+
throw cause;
|
|
172
|
+
if (signal.aborted || !retry || attempt >= this.#maxRetries) {
|
|
173
|
+
const route = this.#routed && !signal.aborted ? describeRoute(url, cause) : { via: "" };
|
|
153
174
|
throw new ConnectionError({
|
|
154
175
|
message: signal.aborted
|
|
155
176
|
? "The call was cancelled or ran past its deadline."
|
|
156
177
|
: write
|
|
157
|
-
? `No answer from Runtime at ${this.baseUrl}. The change may have happened; retrying with the same idempotencyKey is safe.`
|
|
158
|
-
: `No answer from Runtime at ${this.baseUrl}.`,
|
|
178
|
+
? `No answer from Runtime at ${this.baseUrl}${route.via}. The change may have happened; retrying with the same idempotencyKey is safe.`
|
|
179
|
+
: `No answer from Runtime at ${this.baseUrl}${route.via}.`,
|
|
159
180
|
hint: signal.aborted
|
|
160
181
|
? "Raise timeoutMs for a long call, or retry with the same idempotencyKey."
|
|
161
|
-
: "Check the network, and RUNTIME_API_URL if you set it.",
|
|
182
|
+
: (route.hint ?? "Check the network, and RUNTIME_API_URL if you set it."),
|
|
162
183
|
code: signal.aborted ? "timeout" : "connection_error",
|
|
163
184
|
status: 0,
|
|
164
185
|
...(key ? { idempotencyKey: key } : {}),
|
|
165
186
|
cause,
|
|
166
187
|
});
|
|
188
|
+
}
|
|
167
189
|
await sleep(backoff(attempt), signal);
|
|
168
190
|
continue;
|
|
169
191
|
}
|
|
170
192
|
if (response.ok)
|
|
171
193
|
return response;
|
|
194
|
+
// Runtime never answers 407: it is a proxy refusing the tunnel, which
|
|
195
|
+
// Bun's fetch hands back as a response rather than an error.
|
|
196
|
+
if (response.status === 407 && this.#routed) {
|
|
197
|
+
await response.body?.cancel();
|
|
198
|
+
const route = describeRoute(url, 407);
|
|
199
|
+
throw new ConnectionError({
|
|
200
|
+
message: `No answer from Runtime at ${this.baseUrl}${route.via}.`,
|
|
201
|
+
code: "connection_error",
|
|
202
|
+
status: 0,
|
|
203
|
+
...(route.hint ? { hint: route.hint } : {}),
|
|
204
|
+
...(key ? { idempotencyKey: key } : {}),
|
|
205
|
+
});
|
|
206
|
+
}
|
|
172
207
|
const text = await response.text();
|
|
173
208
|
let parsed = null;
|
|
174
209
|
try {
|
|
@@ -239,11 +274,9 @@ export class Transport {
|
|
|
239
274
|
async websocket(path, query) {
|
|
240
275
|
const apiKey = await this.#key();
|
|
241
276
|
const url = `${this.baseUrl.replace(/^http/, "ws")}${path}${encodeQuery(query)}`;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return new Socket(url, {
|
|
246
|
-
headers: { authorization: `Bearer ${apiKey}`, "x-runtime-client": this.#client },
|
|
277
|
+
return openWebSocket(url, {
|
|
278
|
+
authorization: `Bearer ${apiKey}`,
|
|
279
|
+
"x-runtime-client": this.#client,
|
|
247
280
|
});
|
|
248
281
|
}
|
|
249
282
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "withruntime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"mcpName": "com.withruntime/runtime",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"exports": {
|
|
6
7
|
".": {
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"import": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./e2b": {
|
|
12
|
+
"types": "./dist/e2b/index.d.ts",
|
|
13
|
+
"import": "./dist/e2b/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./e2b/code-interpreter": {
|
|
16
|
+
"types": "./dist/e2b/code-interpreter.d.ts",
|
|
17
|
+
"import": "./dist/e2b/code-interpreter.js"
|
|
9
18
|
}
|
|
10
19
|
},
|
|
11
20
|
"bin": {
|
|
@@ -14,7 +23,8 @@
|
|
|
14
23
|
},
|
|
15
24
|
"files": [
|
|
16
25
|
"dist",
|
|
17
|
-
"README.md"
|
|
26
|
+
"README.md",
|
|
27
|
+
"E2B.md"
|
|
18
28
|
],
|
|
19
29
|
"engines": {
|
|
20
30
|
"node": ">=22"
|
|
@@ -53,5 +63,8 @@
|
|
|
53
63
|
"mcp",
|
|
54
64
|
"microvm",
|
|
55
65
|
"code-execution"
|
|
56
|
-
]
|
|
66
|
+
],
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"undici": "^7.29.1"
|
|
69
|
+
}
|
|
57
70
|
}
|