({ run, task, publish, logger, jobToken }: RunTaskOptions)
| 23 | import { MessageLogDeduper } from "./messageLogDeduper" |
| 24 | |
| 25 | export const runTaskInVscode = async ({ run, task, publish, logger, jobToken }: RunTaskOptions) => { |
| 26 | const { language, exercise } = task |
| 27 | const prompt = fs.readFileSync(path.resolve(EVALS_REPO_PATH, `prompts/${language}.md`), "utf-8") |
| 28 | const workspacePath = path.resolve(EVALS_REPO_PATH, language, exercise) |
| 29 | const ipcSocketPath = path.resolve(os.tmpdir(), `evals-${run.id}-${task.id}.sock`) |
| 30 | const env = { ROO_CODE_IPC_SOCKET_PATH: ipcSocketPath } |
| 31 | const controller = new AbortController() |
| 32 | const cancelSignal = controller.signal |
| 33 | const containerized = isDockerContainer() |
| 34 | const logDir = containerized ? `/var/log/evals/runs/${run.id}` : `/tmp/evals/runs/${run.id}` |
| 35 | |
| 36 | let codeCommand = containerized |
| 37 | ? `xvfb-run --auto-servernum --server-num=1 code --wait --log trace --disable-workspace-trust --disable-gpu --disable-lcd-text --no-sandbox --user-data-dir /roo/.vscode --password-store="basic" -n ${workspacePath}` |
| 38 | : `code --disable-workspace-trust -n ${workspacePath}` |
| 39 | |
| 40 | if (jobToken) { |
| 41 | codeCommand = `ROO_CODE_CLOUD_TOKEN=${jobToken} ${codeCommand}` |
| 42 | } |
| 43 | |
| 44 | logger.info(codeCommand) |
| 45 | |
| 46 | // Sleep for a random amount of time between 5 and 10 seconds, unless we're |
| 47 | // running in a container, in which case there are no issues with flooding |
| 48 | // VSCode with new windows. |
| 49 | if (!containerized) { |
| 50 | await new Promise((resolve) => setTimeout(resolve, Math.random() * 5_000 + 5_000)) |
| 51 | } |
| 52 | |
| 53 | const subprocess = execa({ env, shell: "/bin/bash", cancelSignal })`${codeCommand}` |
| 54 | |
| 55 | // If debugging, add `--verbose` to `command` and uncomment the following line. |
| 56 | // subprocess.stdout.pipe(process.stdout) |
| 57 | |
| 58 | // Give VSCode some time to spawn before connecting to its unix socket. |
| 59 | await new Promise((resolve) => setTimeout(resolve, 3_000)) |
| 60 | let client: IpcClient | undefined = undefined |
| 61 | let attempts = 5 |
| 62 | |
| 63 | while (true) { |
| 64 | try { |
| 65 | client = new IpcClient(ipcSocketPath) |
| 66 | await pWaitFor(() => client!.isReady, { interval: 250, timeout: 1_000 }) |
| 67 | break |
| 68 | } catch (_error) { |
| 69 | client?.disconnect() |
| 70 | attempts-- |
| 71 | |
| 72 | if (attempts <= 0) { |
| 73 | logger.error(`unable to connect to IPC socket -> ${ipcSocketPath}`) |
| 74 | throw new Error("Unable to connect.") |
| 75 | } |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | let taskStartedAt = Date.now() |
| 80 | let taskFinishedAt: number | undefined |
| 81 | let taskAbortedAt: number | undefined |
| 82 | let taskTimedOut: boolean = false |
no test coverage detected