Status: done
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Build a packaged benchmark CLI that runs deterministic mock or live OpenAI-compatible comparisons for both invocation modes and writes secret-safe JSON/Markdown reports.
Architecture: Add a benchmark application module for config, case catalog, run models, timing and aggregation; a reporting infrastructure module for redaction/rendering/atomic writes; and a thin presentation CLI. Each run uses DebugRuntime.start_session() with a temporary SQLite store and timing chat-client wrapper.
Tech Stack: Python 3.11+, asyncio, Pydantic, argparse, httpx-based existing OpenAI-compatible client, SQLite, pytest, uv.
Files:
src/agent_lab/application/benchmark.pytests/test_benchmark_config.pyModify: tests/test_tool_invocation_comparison.py
[x] Write failing tests for strict schema version, URL validation, known case/mode IDs, positive runs, and rejection of secret fields.
[x] Verify RED with uv run pytest tests/test_benchmark_config.py -q.
[x] Implement strict Pydantic models BenchmarkConfig, BenchmarkTarget, BenchmarkCase, BenchmarkExpectation, and immutable built-in case catalog.
[x] Implement build_benchmark_request(case, mode, model) using the existing DebugRunRequest, identical params, and built-in enabled tools.
[x] Expose deterministic mock rounds from the production case catalog and refactor the existing comparison test to reuse the catalog instead of duplicating prompts/expectations.
[x] Run config and comparison tests, then commit with feat: add benchmark case catalog.
Files:
src/agent_lab/application/benchmark.pyCreate: tests/test_benchmark_runner.py
[x] Write failing tests for provider TTFT versus visible TTFT, per-call elapsed/usage, persisted wall time, detected events/sources, tool/fallback counts, semantic failures, partial-failure continuation, and temporary-database isolation.
[x] Verify RED with uv run pytest tests/test_benchmark_runner.py -q.
[x] Implement TimingChatClient around the existing stream protocol, recording first item, first message delta, usage, elapsed, and fallback classification.
[x] Implement deterministic MockBenchmarkChatClient that never constructs HTTP transport and emits mode-correct streams for the six cases.
[x] Implement BenchmarkRunner.run() over case → mode → iteration, creating/closing one runtime, chat client, and temporary SQLite store per run.
[x] Implement semantic evaluation from output, audit, and usage ledgers and return ordered BenchmarkRunResult records without stopping after an individual failure.
[x] Run runner/config/comparison tests, then commit with feat: run isolated agent benchmarks.
Files:
src/agent_lab/infrastructure/benchmark_reporting.pysrc/agent_lab/presentation/benchmark_cli.pytests/test_benchmark_reporting.pytests/test_benchmark_cli.pyModify: pyproject.toml
[x] Write failing tests for linear-interpolated p50/p95, failed-sample exclusion, low-sample warnings, redaction, JSON/Markdown consistency, atomic writes, CLI overrides, mock/live API-key requirements, exit codes 0/1/2, and continued report writing after run failures.
[x] Verify RED with uv run pytest tests/test_benchmark_reporting.py tests/test_benchmark_cli.py -q.
[x] Implement aggregation into one typed BenchmarkReport model shared by JSON and Markdown.
[x] Implement centralized redaction and 2 KiB error truncation before any rendered output.
[x] Implement one atomically published report bundle containing matching report.json and report.md files.
[x] Implement argparse with --config, --base-url, --model, repeatable --case/--mode, --runs, --output-dir, and --mock; apply CLI > JSON and environment-only API key.
[x] Register agent-lab-benchmark = agent_lab.presentation.benchmark_cli:main and verify --help.
[x] Run reporting/CLI/runner tests, then commit with feat: add benchmark reports and cli.
Files:
benchmarks/single-target.example.json.gitignoreREADME.mddocs/plans/todo-52-agent-benchmark-runner.mdModify: docs/plans/todos.md
[x] Add a secret-free example covering both modes and all six cases; ignore outputs/benchmarks/.
[x] Document .env, config copy/edit, mock command, live command, output fields, exit codes, fairness controls, and the limits of scripted/mock adapters.
[x] Run agent-lab-benchmark --config benchmarks/single-target.example.json --mock --output-dir /tmp/agent-lab-benchmark and inspect both reports.
[x] Run focused benchmark tests, uv run pytest, CLI help, app import, node --check, and git diff --check.
[x] Perform specification review then code-quality review; add Todo 52.x rows for post-execution fixes.
[x] Record evidence and Workflow Evolution findings, mark Todo 52 done, and commit with docs: close benchmark runner todo.
Verified on 2026-07-14 (Asia/Shanghai):
196 passed in 1.19s;601 passed in 3.67s, with one existing Starlette/httpx deprecation warning;agent-lab-benchmark --help: exit 0;Agent Lab;node --check src/agent_lab/presentation/static/app.js: exit 0;git diff --check: exit 0;12 attempted / 12 passed / 0 failed;/tmp/agent-lab-benchmark-final-20260714/20260713T194850Z/report.json;/tmp/agent-lab-benchmark-final-20260714/20260713T194850Z/report.md;parallel_events_overlapped=true;Specification and code-quality reviews found no remaining Critical or Important issues after Todos 52.1-52.13. The remaining non-blocking risks are documented below.
mkdtemp() may leave an empty hidden bundle directory.
A close failure during a narrow consumer-pause cancellation window may be
logged as a secondary async-generator exception. Neither case changes the
primary cancellation result or exposes a mixed public report.The requirement loop exposed three durable workflow lessons:
These lessons are recorded in this task report and the benchmark design. No
AGENTS.md change was made because the repository's existing PAOU, todo-first,
TDD, per-todo commit, and post-review follow-up rules already caused the issues to
be found and corrected; adding more global workflow rules would duplicate the
current core process.