UNPKG

@e2b/code-interpreter

Version:

E2B Code Interpreter - Stateful code execution

428 lines (421 loc) 13.4 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name); var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; var __await = function(promise, isYieldStar) { this[0] = promise; this[1] = isYieldStar; }; var __asyncGenerator = (__this, __arguments, generator) => { var resume = (k, v, yes, no) => { try { var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done; Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no)); } catch (e) { no(e); } }, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {}; return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it; }; var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it); // src/index.ts export * from "e2b"; // src/sandbox.ts import { Sandbox as BaseSandbox, InvalidArgumentError } from "e2b"; // src/messaging.ts import { NotFoundError, SandboxError, TimeoutError } from "e2b"; function extractError(res) { return __async(this, null, function* () { if (res.ok) { return; } switch (res.status) { case 502: return new TimeoutError( `${yield res.text()}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeoutMs' when starting the sandbox or calling '.setTimeout' on the sandbox with the desired timeout.` ); case 404: return new NotFoundError(yield res.text()); default: return new SandboxError(`${res.status} ${res.statusText}`); } }); } var ExecutionError = class { constructor(name, value, traceback) { this.name = name; this.value = value; this.traceback = traceback; } }; var Result = class { constructor(rawData, isMainResult) { this.isMainResult = isMainResult; const data = __spreadValues({}, rawData); delete data["type"]; delete data["is_main_result"]; this.text = data["text"]; this.html = data["html"]; this.markdown = data["markdown"]; this.svg = data["svg"]; this.png = data["png"]; this.jpeg = data["jpeg"]; this.pdf = data["pdf"]; this.latex = data["latex"]; this.json = data["json"]; this.javascript = data["javascript"]; this.isMainResult = isMainResult; this.raw = data; this.data = data["data"]; this.chart = data["chart"]; this.extra = {}; for (const key of Object.keys(data)) { if (![ "plain", "html", "markdown", "svg", "png", "jpeg", "pdf", "latex", "json", "javascript", "data", "chart", "extra", "text" ].includes(key)) { this.extra[key] = data[key]; } } } /** * Returns all the formats available for the result. * * @returns Array of strings representing the formats available for the result. */ formats() { const formats = []; if (this.html) { formats.push("html"); } if (this.markdown) { formats.push("markdown"); } if (this.svg) { formats.push("svg"); } if (this.png) { formats.push("png"); } if (this.jpeg) { formats.push("jpeg"); } if (this.pdf) { formats.push("pdf"); } if (this.latex) { formats.push("latex"); } if (this.json) { formats.push("json"); } if (this.javascript) { formats.push("javascript"); } if (this.data) { formats.push("data"); } for (const key of Object.keys(this.extra)) { formats.push(key); } return formats; } /** * Returns the serializable representation of the result. */ toJSON() { return __spreadValues({ text: this.text, html: this.html, markdown: this.markdown, svg: this.svg, png: this.png, jpeg: this.jpeg, pdf: this.pdf, latex: this.latex, json: this.json, javascript: this.javascript }, Object.keys(this.extra).length > 0 ? { extra: this.extra } : {}); } }; var Execution = class { constructor(results = [], logs = { stdout: [], stderr: [] }, error, executionCount) { this.results = results; this.logs = logs; this.error = error; this.executionCount = executionCount; } /** * Returns the text representation of the main result of the cell. */ get text() { for (const data of this.results) { if (data.isMainResult) { return data.text; } } } /** * Returns the serializable representation of the execution result. */ toJSON() { return { results: this.results, logs: this.logs, error: this.error }; } }; function parseOutput(execution, line, onStdout, onStderr, onResult, onError) { return __async(this, null, function* () { const msg = JSON.parse(line); switch (msg.type) { case "result": const result = new Result( __spreadProps(__spreadValues({}, msg), { type: void 0, is_main_result: void 0 }), msg.is_main_result ); execution.results.push(result); if (onResult) { yield onResult(result); } break; case "stdout": execution.logs.stdout.push(msg.text); if (onStdout) { yield onStdout({ error: false, line: msg.text, timestamp: (/* @__PURE__ */ new Date()).getTime() * 1e3 }); } break; case "stderr": execution.logs.stderr.push(msg.text); if (onStderr) { yield onStderr({ error: true, line: msg.text, timestamp: (/* @__PURE__ */ new Date()).getTime() * 1e3 }); } break; case "error": execution.error = new ExecutionError(msg.name, msg.value, msg.traceback); if (onError) { yield onError(execution.error); } break; case "number_of_executions": execution.executionCount = msg.execution_count; break; } }); } // src/utils.ts import { TimeoutError as TimeoutError2 } from "e2b"; function formatRequestTimeoutError(error) { if (error instanceof Error && error.name === "AbortError") { return new TimeoutError2("Request timed out \u2014 the 'requestTimeoutMs' option can be used to increase this timeout"); } return error; } function formatExecutionTimeoutError(error) { if (error instanceof Error && error.name === "AbortError") { return new TimeoutError2("Execution timed out \u2014 the 'timeoutMs' option can be used to increase this timeout"); } return error; } function readLines(stream) { return __asyncGenerator(this, null, function* () { const reader = stream.getReader(); let buffer = ""; try { while (true) { const { done, value } = yield new __await(reader.read()); if (value !== void 0) { buffer += new TextDecoder().decode(value); } if (done) { if (buffer.length > 0) { yield buffer; } break; } let newlineIdx = -1; do { newlineIdx = buffer.indexOf("\n"); if (newlineIdx !== -1) { yield buffer.slice(0, newlineIdx); buffer = buffer.slice(newlineIdx + 1); } } while (newlineIdx !== -1); } } finally { reader.releaseLock(); } }); } // src/consts.ts var DEFAULT_TIMEOUT_MS = 6e4; var JUPYTER_PORT = 49999; // src/sandbox.ts var Sandbox = class extends BaseSandbox { runCode(code, opts) { return __async(this, null, function* () { var _a, _b, _c; if ((opts == null ? void 0 : opts.context) && (opts == null ? void 0 : opts.language)) { throw new InvalidArgumentError("You can provide context or language, but not both at the same time."); } const controller = new AbortController(); const requestTimeout = (_a = opts == null ? void 0 : opts.requestTimeoutMs) != null ? _a : this.connectionConfig.requestTimeoutMs; const reqTimer = requestTimeout ? setTimeout(() => { controller.abort(); }, requestTimeout) : void 0; try { const res = yield fetch(`${this.jupyterUrl}/execute`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ code, context_id: (_b = opts == null ? void 0 : opts.context) == null ? void 0 : _b.id, language: opts == null ? void 0 : opts.language, env_vars: opts == null ? void 0 : opts.envs }), signal: controller.signal, keepalive: true }); const error2 = yield extractError(res); if (error2) { throw error2; } if (!res.body) { throw new Error(`Not response body: ${res.statusText} ${yield res == null ? void 0 : res.text()}`); } clearTimeout(reqTimer); const bodyTimeout = (_c = opts == null ? void 0 : opts.timeoutMs) != null ? _c : DEFAULT_TIMEOUT_MS; const bodyTimer = bodyTimeout ? setTimeout(() => { controller.abort(); }, bodyTimeout) : void 0; const execution = new Execution(); try { try { for (var iter = __forAwait(readLines(res.body)), more, temp, error; more = !(temp = yield iter.next()).done; more = false) { const chunk = temp.value; yield parseOutput(execution, chunk, opts == null ? void 0 : opts.onStdout, opts == null ? void 0 : opts.onStderr, opts == null ? void 0 : opts.onResult, opts == null ? void 0 : opts.onError); } } catch (temp) { error = [temp]; } finally { try { more && (temp = iter.return) && (yield temp.call(iter)); } finally { if (error) throw error[0]; } } } catch (error3) { throw formatExecutionTimeoutError(error3); } finally { clearTimeout(bodyTimer); } return execution; } catch (error2) { throw formatRequestTimeoutError(error2); } }); } /** * Creates a new context to run code in. * * @param opts options for creating the context. * * @returns context object. */ createCodeContext(opts) { return __async(this, null, function* () { try { const res = yield fetch(`${this.jupyterUrl}/contexts`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ language: opts == null ? void 0 : opts.language, cwd: opts == null ? void 0 : opts.cwd }), keepalive: true, signal: this.connectionConfig.getSignal(opts == null ? void 0 : opts.requestTimeoutMs) }); const error = yield extractError(res); if (error) { throw error; } return yield res.json(); } catch (error) { throw formatRequestTimeoutError(error); } }); } get jupyterUrl() { return `${this.connectionConfig.debug ? "http" : "https"}://${this.getHost(JUPYTER_PORT)}`; } }; Sandbox.defaultTemplate = "code-interpreter-v1"; // src/index.ts var src_default = Sandbox; export { Sandbox, src_default as default }; //# sourceMappingURL=index.mjs.map