(targetPath, options = {})
| 488 | } |
| 489 | |
| 490 | export async function runBenchmark(targetPath, options = {}) { |
| 491 | const target = await resolveTarget(targetPath); |
| 492 | const { config, configPath, source } = await loadBenchmarkConfig(target, options); |
| 493 | const scenarios = (config.scenarios || []).map(normalizeScenario).filter((scenario) => scenario.userInput); |
| 494 | if (scenarios.length === 0) { |
| 495 | throw new Error("Benchmark config does not contain any runnable scenarios."); |
| 496 | } |
| 497 | if (options.dryRun) { |
| 498 | throw new Error("CLI-only benchmarking no longer supports --dry-run. Edit the benchmark config, then run `plugin-eval benchmark` for a real Codex execution."); |
| 499 | } |
| 500 | |
| 501 | const processRunner = options.processRunner || runProcessCapture; |
| 502 | const codexExecutable = options.codexExecutable || process.env.PLUGIN_EVAL_CODEX_EXECUTABLE || "codex"; |
| 503 | const runId = createRunId(); |
| 504 | const runDirectory = path.join(benchmarkRunsDirectoryForTarget(target), runId); |
| 505 | await fs.mkdir(runDirectory, { recursive: true }); |
| 506 | |
| 507 | let codexVersion = "unknown"; |
| 508 | try { |
| 509 | const versionResult = await processRunner({ |
| 510 | kind: "codex-version", |
| 511 | command: codexExecutable, |
| 512 | args: ["--version"], |
| 513 | cwd: process.cwd(), |
| 514 | env: process.env, |
| 515 | stdoutPath: path.join(runDirectory, "codex-version.stdout.log"), |
| 516 | stderrPath: path.join(runDirectory, "codex-version.stderr.log"), |
| 517 | }); |
| 518 | codexVersion = (versionResult.stdoutText || versionResult.stderrText || "unknown").trim().split(/\r?\n/).pop() || "unknown"; |
| 519 | } catch { |
| 520 | codexVersion = "unknown"; |
| 521 | } |
| 522 | |
| 523 | const usageLines = []; |
| 524 | const runScenarios = []; |
| 525 | |
| 526 | for (let index = 0; index < scenarios.length; index += 1) { |
| 527 | const scenario = scenarios[index]; |
| 528 | const scenarioDirectory = path.join(runDirectory, `${String(index + 1).padStart(2, "0")}-${scenario.id}`); |
| 529 | await fs.mkdir(scenarioDirectory, { recursive: true }); |
| 530 | |
| 531 | const provisioned = await provisionBenchmarkWorkspace({ |
| 532 | target, |
| 533 | config, |
| 534 | scenarioId: scenario.id, |
| 535 | }); |
| 536 | const beforeSnapshot = await snapshotWorkspace(provisioned.workspacePath); |
| 537 | const stdoutPath = path.join(scenarioDirectory, "codex.stdout.jsonl"); |
| 538 | const stderrPath = path.join(scenarioDirectory, "codex.stderr.log"); |
| 539 | const finalMessagePath = path.join(scenarioDirectory, "final-message.txt"); |
| 540 | |
| 541 | const args = buildCodexExecArgs({ |
| 542 | config, |
| 543 | model: options.model || config.runner.model || defaultModelForTarget(target), |
| 544 | workspacePath: provisioned.workspacePath, |
| 545 | finalMessagePath, |
| 546 | prompt: scenario.userInput, |
| 547 | }); |
no test coverage detected