Files
sim/apps/sim/lib/execution/e2b.ts
Waleed d707d18ee6 fix(build): update dockerfile to contain testing package deps (#2591)
* fix(build): update dockerfile to contain testing package deps

* added logger package
2025-12-26 12:20:38 -08:00

95 lines
2.4 KiB
TypeScript

import { Sandbox } from '@e2b/code-interpreter'
import { createLogger } from '@sim/logger'
import { env } from '@/lib/core/config/env'
import { CodeLanguage } from '@/lib/execution/languages'
export interface E2BExecutionRequest {
code: string
language: CodeLanguage
timeoutMs: number
}
export interface E2BExecutionResult {
result: unknown
stdout: string
sandboxId?: string
error?: string
}
const logger = createLogger('E2BExecution')
export async function executeInE2B(req: E2BExecutionRequest): Promise<E2BExecutionResult> {
const { code, language, timeoutMs } = req
const apiKey = env.E2B_API_KEY
if (!apiKey) {
throw new Error('E2B_API_KEY is required when E2B is enabled')
}
const sandbox = await Sandbox.create({ apiKey })
const sandboxId = sandbox.sandboxId
const stdoutChunks = []
try {
const execution = await sandbox.runCode(code, {
language: language === CodeLanguage.Python ? 'python' : 'javascript',
timeoutMs,
})
if (execution.error) {
const errorMessage = `${execution.error.name}: ${execution.error.value}`
logger.error(`E2B execution error`, {
sandboxId,
error: execution.error,
errorMessage,
})
const errorOutput = execution.error.traceback || errorMessage
return {
result: null,
stdout: errorOutput,
error: errorMessage,
sandboxId,
}
}
if (execution.text) {
stdoutChunks.push(execution.text)
}
if (execution.logs?.stdout) {
stdoutChunks.push(...execution.logs.stdout)
}
if (execution.logs?.stderr) {
stdoutChunks.push(...execution.logs.stderr)
}
const stdout = stdoutChunks.join('\n')
let result: unknown = null
const prefix = '__SIM_RESULT__='
const lines = stdout.split('\n')
const marker = lines.find((l) => l.startsWith(prefix))
let cleanedStdout = stdout
if (marker) {
const jsonPart = marker.slice(prefix.length)
try {
result = JSON.parse(jsonPart)
} catch {
result = jsonPart
}
const filteredLines = lines.filter((l) => !l.startsWith(prefix))
if (filteredLines.length > 0 && filteredLines[filteredLines.length - 1] === '') {
filteredLines.pop()
}
cleanedStdout = filteredLines.join('\n')
}
return { result, stdout: cleanedStdout, sandboxId }
} finally {
try {
await sandbox.kill()
} catch {}
}
}