/** E2B process/worker implementation of the harness code-runtime seam. */ import { posix } from 'node:path' import { stripTypeScriptTypes } from 'node:module' import type { Context } from 'cordis' import z from 'schemastery' import { CodeRuntime } from '@deepseek-ai/dsh-code-runtime' import type { CodeBindingNamespace, CodeJsonValue, CodeRunFailure, CodeRunRequest, CodeRunResult, } from '@deepseek-ai/dsh-code-runtime' import { E2BFrameDecoder, encodeE2BFrame, quoteE2BShellArg, resolveE2BExecutable, } from '@deepseek-ai/dsh-e2b' import { decodeWorkerJson, encodeWorkerJson, OutputLedger, } from '@deepseek-ai/dsh-code-runtime-worker' import type { WorkerJsonWire } from '@deepseek-ai/dsh-code-runtime-worker' import { snapshotJsonValue } from '@deepseek-ai/dsh-session' import E2BSubprocessService from '@deepseek-ai/dsh-subprocess-e2b' import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout' import { CODE_RUNNER_SOURCE } from './runner-source.ts' /** Runtime configuration; every execution and bridge bound is deployment-tunable. */ export interface Config { /** Remote worker measured event-loop busy-time budget. */ computeMs?: number /** Host-observed wall-clock ceiling. */ maxWallMs?: number /** Combined serialized outer logs/value/diagnostic cap. */ maxOutputBytes?: number /** Remote worker old-generation heap cap in MiB. */ maxOldGenerationSizeMb?: number /** Largest decoded bridge frame, including binding traffic. */ maxFrameBytes?: number /** Remote process-group TERM-to-KILL grace. */ killGraceMs?: number } type ResolvedConfig = Required interface LiveRun { settle(failure: CodeRunFailure): void finished: Promise } interface CallMessage { type: 'call' id: number global: string name: string args: WorkerJsonWire } interface LogMessage { type: 'log' text: string } interface DoneMessage { type: 'done' value?: WorkerJsonWire error?: CodeRunFailure } type RunnerMessage = CallMessage | LogMessage | DoneMessage | { type: 'output-limit' } const STRIP_WRAP = { prefix: 'async function __dsh_program__() {\n', suffix: '\n}' } as const const MIN_OUTPUT_BYTES = 4 const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/ /* jscpd:ignore-start -- Backends enforce the same injected-global vocabulary without coupling lifecycle implementations. */ const RESERVED_WORDS = new Set([ 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'null', 'return', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield', 'let', 'static', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'arguments', 'eval', ]) const RESERVED_ERROR_PROPERTIES = new Set(['name', 'message', 'stack']) /* jscpd:ignore-end */ const FAILURE_KINDS = new Set([ 'exception', 'timeout', 'abort', 'worker-exit', 'invalid-output', 'output-limit', ]) function messageOf(error: unknown): string { return error instanceof Error ? error.message : String(error) } function parseRunnerMessage(raw: unknown): RunnerMessage | undefined { if (typeof raw !== 'object' || raw === null) return undefined const record = raw as Record if (record.type === 'output-limit') return { type: 'output-limit' } if (record.type === 'log') return typeof record.text === 'string' ? { type: 'log', text: record.text } : undefined if (record.type === 'call') { if (!Number.isSafeInteger(record.id) || (record.id as number) < 1 || typeof record.global !== 'string' || typeof record.name !== 'string' || !Array.isArray(record.args)) return undefined return { type: 'call', id: record.id as number, global: record.global, name: record.name, args: record.args as WorkerJsonWire } } if (record.type !== 'done') return undefined if (record.error === undefined) { return { type: 'done', ...record.value === undefined ? {} : { value: record.value as WorkerJsonWire } } } if (typeof record.error !== 'object' || record.error === null) return undefined const error = record.error as Record if (typeof error.kind !== 'string' || !FAILURE_KINDS.has(error.kind as CodeRunFailure['kind']) || typeof error.message !== 'string') return undefined return { type: 'done', error: { kind: error.kind as CodeRunFailure['kind'], message: error.message } } } /** E2B-backed runtime: host-side type stripping, remote worker execution, host binding dispatch. */ export class E2BCodeRuntime extends CodeRuntime { static inject = ['e2b', 'subprocess'] static Config: z = z.object({ computeMs: z.number().default(60_000), maxWallMs: z.number().default(600_000), maxOutputBytes: z.number().default(67_108_864), maxOldGenerationSizeMb: z.number().default(512), maxFrameBytes: z.number().default(268_435_456), killGraceMs: z.number().default(2_000), }) readonly language = 'typescript' readonly isolation = 'container' private readonly config: ResolvedConfig private readonly ready: Promise<{ node: string; runner: string }> private readonly live = new Set() private readonly subprocess: E2BSubprocessService private disposed = false constructor(ctx: Context, config: Config) { super(ctx) if (!(ctx.subprocess instanceof E2BSubprocessService)) { throw new Error('code-runtime-e2b requires @deepseek-ai/dsh-subprocess-e2b as ctx.subprocess') } this.subprocess = ctx.subprocess this.config = config as ResolvedConfig for (const [key, value] of Object.entries(this.config)) { if (!Number.isSafeInteger(value) || value <= 0) { throw new Error(`code-runtime-e2b: config.${key} must be a positive safe integer`) } } if (this.config.maxOutputBytes < MIN_OUTPUT_BYTES) { throw new Error(`code-runtime-e2b: config.maxOutputBytes must be at least ${MIN_OUTPUT_BYTES}`) } if (this.config.maxWallMs > MAX_TIMER_DELAY_MS) { throw new Error(`code-runtime-e2b: config.maxWallMs must be at most ${MAX_TIMER_DELAY_MS}`) } if (this.config.maxFrameBytes < this.config.maxOutputBytes) { throw new Error('code-runtime-e2b: config.maxFrameBytes must be at least maxOutputBytes') } this.ready = this.prepare() void this.ready.catch(() => {}) ctx.effect(() => () => this.teardown(), 'E2B code-runtime teardown') } /* jscpd:ignore-start -- Seam-level abort and type-strip results remain identical across execution substrates. */ /** Execute one type-stripped program in a fresh E2B worker process. */ async run(request: CodeRunRequest): Promise { if (this.disposed) throw new Error('code-runtime-e2b: run() after disposal') const bindings = this.validateBindings(request) if (request.signal?.aborted === true) { return this.failure({ kind: 'abort', message: String(request.signal.reason) }) } let code: string try { const stripped = stripTypeScriptTypes(STRIP_WRAP.prefix + request.program + STRIP_WRAP.suffix) code = stripped.slice(STRIP_WRAP.prefix.length, stripped.length - STRIP_WRAP.suffix.length) } catch (error: unknown) { return this.failure({ kind: 'exception', message: messageOf(error) }) } let runtime: Awaited try { runtime = await this.ready } catch (error: unknown) { return this.failure({ kind: 'worker-exit', message: `E2B runtime setup failed: ${messageOf(error)}` }) } // Disposal can race the awaited remote setup after the pre-await check. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (this.disposed) return this.failure({ kind: 'abort', message: 'runtime disposed' }) return await this.execute(request, code, bindings, runtime) } /* jscpd:ignore-end */ private async prepare(): Promise<{ node: string; runner: string }> { const sandbox = await this.ctx.e2b.getSandbox() const runner = posix.join(this.ctx.e2b.runtimeRoot, 'code-runtime-runner.mjs') await sandbox.files.write([{ path: runner, data: CODE_RUNNER_SOURCE }]) await sandbox.commands.run(`chmod 600 -- ${quoteE2BShellArg(runner)}`) const node = await resolveE2BExecutable(sandbox, 'node') return { node, runner } } private failure(error: CodeRunFailure): CodeRunResult { return new OutputLedger(this.config.maxOutputBytes).failure([], error) } /* jscpd:ignore-start -- Binding names have one seam contract while dispatch and teardown remain backend-owned. */ private validateBindings(request: CodeRunRequest): Map { const bindings = new Map() for (const namespace of request.bindings) { if (!IDENTIFIER.test(namespace.global) || RESERVED_WORDS.has(namespace.global)) { throw new Error(`code-runtime-e2b: binding global ${JSON.stringify(namespace.global)} is not a usable identifier`) } if (namespace.global === 'console' || bindings.has(namespace.global)) { throw new Error(`code-runtime-e2b: duplicate binding global ${JSON.stringify(namespace.global)}`) } bindings.set(namespace.global, namespace) } const errorClassNames = new Set() for (const namespace of request.bindings) { const descriptor = namespace.errorClass if (descriptor === undefined) continue if (!IDENTIFIER.test(descriptor.name) || RESERVED_WORDS.has(descriptor.name)) { throw new Error(`code-runtime-e2b: binding error class ${JSON.stringify(descriptor.name)} is not a usable identifier`) } if (descriptor.name === 'console' || bindings.has(descriptor.name) || errorClassNames.has(descriptor.name)) { throw new Error(`code-runtime-e2b: duplicate injected global ${JSON.stringify(descriptor.name)}`) } if (descriptor.memberNameProperty.length === 0 || RESERVED_ERROR_PROPERTIES.has(descriptor.memberNameProperty)) { throw new Error(`code-runtime-e2b: binding error member property ${JSON.stringify(descriptor.memberNameProperty)} is not usable`) } errorClassNames.add(descriptor.name) } return bindings } /* jscpd:ignore-end */ private async execute( request: CodeRunRequest, code: string, bindings: Map, runtime: { node: string; runner: string }, ): Promise { const handle = this.subprocess.spawn({ argv: [runtime.node, runtime.runner], cwd: this.ctx.e2b.cwd, stdio: { stdin: 'pipe', stdout: 'pipe', stderr: { maxBytes: this.config.maxOutputBytes } }, graceMs: this.config.killGraceMs, ...request.signal === undefined ? {} : { signal: request.signal }, env: {}, }) if (handle.stdin === undefined || handle.stdout === undefined) { handle.terminate() await Promise.allSettled([handle.done]) try { await handle.waitForExit() } catch (error: unknown) { return this.failure({ kind: 'worker-exit', message: `E2B runtime cleanup failed: ${messageOf(error)}` }) } return this.failure({ kind: 'worker-exit', message: 'E2B subprocess dropped a piped runtime stream' }) } const stdin = handle.stdin const stdout = handle.stdout return new Promise((resolve) => { const output = new OutputLedger(this.config.maxOutputBytes) const logs: string[] = [] const answered = new Set() const decoder = new E2BFrameDecoder(this.config.maxFrameBytes) let settled = false let finishResolve!: () => void const finished = new Promise((done) => { finishResolve = done }) const wallTimer: { current: NodeJS.Timeout | undefined } = { current: undefined } const live: LiveRun = { finished, settle: (failure) => { finish(() => output.failure(logs, failure)) }, } const finish = (result: CodeRunResult | (() => CodeRunResult)): void => { if (settled) return settled = true clearTimeout(wallTimer.current) request.signal?.removeEventListener('abort', onAbort) this.live.delete(live) void new Promise((resume) => { setImmediate(resume) }).then(async () => { handle.terminate() await handle.done.catch(() => {}) let cleanupError: unknown try { await handle.waitForExit() } catch (error: unknown) { cleanupError = error } try { decoder.finish() } catch (error: unknown) { result = output.failure(logs, { kind: 'worker-exit', message: messageOf(error) }) } if (cleanupError !== undefined) { result = output.failure(logs, { kind: 'worker-exit', message: `E2B runtime cleanup failed: ${messageOf(cleanupError)}` }) } const final = typeof result === 'function' ? result() : result finishResolve() resolve(final) }) } const sendReply = (message: unknown): void => { if (settled) return stdin.write(encodeE2BFrame(message), (error?: Error | null) => { if (error !== undefined && error !== null) { finish(() => output.failure(logs, { kind: 'worker-exit', message: `E2B runtime bridge write failed: ${error.message}` })) } }) } /* jscpd:ignore-start -- Host binding resolution mirrors worker semantics over a different transport. */ const onCall = (message: CallMessage): void => { if (answered.has(message.id)) return answered.add(message.id) const functions = bindings.get(message.global)?.functions const fn = functions !== undefined && Object.hasOwn(functions, message.name) ? functions[message.name] : undefined if (typeof fn !== 'function') { sendReply({ type: 'reply', id: message.id, ok: false, message: `unknown binding ${JSON.stringify(`${message.global}.${message.name}`)}` }) return } const args = decodeWorkerJson(message.args) if (args === undefined) { sendReply({ type: 'reply', id: message.id, ok: false, message: 'binding arguments must be lossless JSON' }) return } void (async () => { try { const resolved = await fn(args) let value: CodeJsonValue | undefined try { value = snapshotJsonValue(resolved) } catch { value = undefined } if (value === undefined) { sendReply({ type: 'reply', id: message.id, ok: false, message: 'binding resolution must be lossless JSON' }) } else { sendReply({ type: 'reply', id: message.id, ok: true, value: encodeWorkerJson(value) }) } } catch (error: unknown) { sendReply({ type: 'reply', id: message.id, ok: false, message: messageOf(error) }) } })() } /* jscpd:ignore-end */ const onMessage = (raw: unknown): void => { if (settled) return const message = parseRunnerMessage(raw) if (message === undefined) return if (message.type === 'log') { if (!output.admit(message.text, logs)) finish(output.limit([...logs, message.text])) return } if (message.type === 'output-limit') { finish(output.limit(logs)) return } if (message.type === 'call') { onCall(message) return } if (message.error !== undefined) { finish(() => output.failure(logs, message.error as CodeRunFailure)) } else if (message.value === undefined) { finish(() => output.success(logs)) } else { const value = decodeWorkerJson(message.value) if (value === undefined) finish(() => output.failure(logs, { kind: 'invalid-output', message: 'program completion must be lossless JSON' })) else finish(() => output.success(logs, value)) } } stdout.on('data', (chunk: Buffer) => { if (settled) return try { for (const frame of decoder.push(chunk.toString('utf8'))) onMessage(frame) } catch (error: unknown) { finish(() => output.failure(logs, { kind: 'worker-exit', message: `E2B runtime bridge failed: ${messageOf(error)}` })) } }) stdout.on('error', (error: Error) => { finish(() => output.failure(logs, { kind: 'worker-exit', message: `E2B runtime stdout failed: ${error.message}` })) }) stdin.on('error', (error: Error) => { finish(() => output.failure(logs, { kind: 'worker-exit', message: `E2B runtime stdin failed: ${error.message}` })) }) void handle.done.then( () => { if (!settled) { const stderr = handle.collected.stderr?.readFrom(0).text.trim() finish(() => output.failure(logs, { kind: 'worker-exit', message: stderr === undefined || stderr === '' ? 'E2B runtime exited before completing' : `E2B runtime exited before completing: ${stderr}` })) } }, (error: unknown) => { finish(() => output.failure(logs, { kind: 'worker-exit', message: `E2B runtime spawn failed: ${messageOf(error)}` })) }, ) const onAbort = (): void => { finish(() => output.failure(logs, { kind: 'abort', message: String(request.signal?.reason) })) } request.signal?.addEventListener('abort', onAbort, { once: true }) wallTimer.current = setTimeout(() => { finish(() => output.failure(logs, { kind: 'timeout', message: `wall-clock ceiling reached (${this.config.maxWallMs}ms)` })) }, this.config.maxWallMs) this.live.add(live) if (request.signal?.aborted === true) { onAbort() return } sendReply({ type: 'boot', code, namespaces: [...bindings].map(([global, namespace]) => ({ global, names: Object.keys(namespace.functions), ...namespace.errorClass === undefined ? {} : { errorClass: namespace.errorClass }, })), computeMs: this.config.computeMs, maxOutputBytes: this.config.maxOutputBytes, maxOldGenerationSizeMb: this.config.maxOldGenerationSizeMb, }) }) } /* jscpd:ignore-start -- Code-runtime backends share the service lifecycle but own different child identities. */ private async teardown(): Promise { this.disposed = true const runs = [...this.live] for (const run of runs) run.settle({ kind: 'abort', message: 'runtime disposed' }) await Promise.all(runs.map(run => run.finished)) } /* jscpd:ignore-end */ } export default E2BCodeRuntime