mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-03 19:24:57 -05:00
95 lines
2.4 KiB
TypeScript
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 {}
|
|
}
|
|
}
|