# Coder Eval — full documentation > The complete text of every page published under https://coder-eval.com/docs, > concatenated in navigation order for LLM consumption. This is the llms-full.txt > companion to the link index at https://coder-eval.com/llms.txt. Source: https://github.com/UiPath/coder_eval @ v0.11.5 — 25 pages. Each section below is preceded by an HTML comment naming its source file and canonical URL. --- # Evaluate AI coding agents & Claude Code skills — Coder Eval **Coder Eval** (`pip install coder-eval` / `uv tool install coder-eval`) is an open-source framework for **evaluating AI coding agents and their skills** — built for CLI and skill builders — with sandboxing, reproducibility, and data-driven analysis. It is not an "agentic coding" benchmark: it measures how effective *your* CLI and skills are when used by coding agents such as **Claude Code**, **Codex**, **Google Antigravity (Gemini)**, and **OpenCode**. If you have ever asked *"how do I test whether my Claude Code skill actually triggers?"*, *"how do I benchmark Claude Code vs. Codex on my own tasks?"*, or *"how do I gate CI on coding-agent quality?"* — this is the framework for that.

Coder Eval running a sandboxed coding-agent evaluation from a YAML task and browsing the scored result in evalboard

## What Coder Eval does - **Declarative YAML tasks** with pinned dependencies and clear success criteria - **Sandboxed execution** in isolated environments with resource limits - **Weighted, continuous scoring** (0.0–1.0) with fractional credit and thresholds - **Many criterion types** — from file checks to code similarity and LLM-graded rubrics - **Agent abstraction** — Claude Code, Codex, Antigravity (Gemini), and OpenCode today, extensible via a plugin SPI - **Experiment layer** — A/B agent configs (models, tools, prompts) side-by-side - **Full telemetry** — every tool call, token counts, and cost, with real-time streaming ## Use cases - **Benchmark coding agents** — score an agent across a suite of tasks with weighted pass/fail thresholds - **Compare models & configs** — A/B-test Claude Code vs. Codex vs. Gemini vs. OpenCode, model vs. model, tool-on vs. tool-off, prompt vs. prompt - **Test whether a Claude Code skill triggers** — verify an agent actually engages a target skill (`skill_triggered`) and score skill-driven suites (SkillsBench-style) - **Keep skills fresh in CI** — re-validate skills on every change or on a schedule; catch silent regressions when models, prompts, or the skills themselves drift - **Gate CI on agent quality** — run the suite in GitHub Actions and fail the build on regressions - **Bring your own dataset** — fan one task out over many rows for larger benchmark suites ## Quick start ```bash # 1. Install the coder-eval CLI on your PATH (isolated environment) uv tool install coder-eval # 2. Grab the runnable example tasks git clone https://github.com/UiPath/coder_eval.git cd coder_eval # 3. Credentials — optional if you're already logged in to Claude Code # (`claude login`, reused automatically); otherwise set ANTHROPIC_API_KEY cp .env.example .env # 4. Validate, run, and read your first evaluation coder-eval plan tasks/hello_date.yaml # validate (no tokens spent) coder-eval run tasks/hello_date.yaml # run your first evaluation coder-eval report runs/latest # view the result ``` Prefer Coder Eval as a project dependency instead of a CLI tool? `uv add coder-eval` or `pip install coder-eval`. Hacking on Coder Eval itself? Clone, `uv sync --extra dev`, and prefix commands with `uv run`. New here? Start with **[Tutorial 01 — Your First Evaluation](https://coder-eval.com/docs/tutorials/01-first-evaluation)**. ## Where to go next | Guide | What's in it | | --- | --- | | [Tutorials](https://coder-eval.com/docs/tutorials) | Step-by-step walkthroughs — start here | | [User Guide](https://coder-eval.com/docs/user-guide) | Full CLI, configuration, output, and environment-variable reference | | [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide) | The task-file schema — all criterion types, scoring, templates | | [Claude Code](https://coder-eval.com/docs/agents/claude-code) | Configuring and running the default Claude Code agent | | [Codex](https://coder-eval.com/docs/agents/codex) | Running the OpenAI Codex agent | | [Antigravity (Gemini)](https://coder-eval.com/docs/agents/antigravity) | Running the Google Antigravity / Gemini agent | | [OpenCode](https://coder-eval.com/docs/agents/opencode) | Running the OpenCode agent on open-weight models | | [Run-Limit Parity](https://coder-eval.com/docs/agents/harness-parity) | What each run_limits field means on every harness | | [A/B Experiments](https://coder-eval.com/docs/ab-experiments) | Compare models / tools / prompts across the same tasks | | [Bring Your Own Dataset](https://coder-eval.com/docs/datasets) | Fan a single task out over a dataset | | [Dialog Mode](https://coder-eval.com/docs/dialog-mode) | Evaluate agents in multi-turn conversation via a simulated user | | [Docker Isolation](https://coder-eval.com/docs/docker-isolation) | The container sandbox driver, with custom images | | [CI Gate & GitHub Action](https://coder-eval.com/docs/ci-gate) | Run Coder Eval as a CI gate — the Marketplace Action, JUnit output, score floor | | [Claude Code Plugin](https://coder-eval.com/docs/plugin) | Install the Claude Code plugin — author, run, and analyze suites from inside the agent | | [Extending Coder Eval](https://coder-eval.com/docs/extending) | Author a custom agent, criterion, or model pricing via the plugin SPI | | [Report Schema](https://coder-eval.com/docs/report-schema) | Field-level reference for run.json / variant.json / task.json | | [How It Compares](https://coder-eval.com/docs/comparison) | vs. SWE-bench, SkillsBench, Harbor, OpenAI Evals, hand-rolled scripts | ## How Coder Eval compares - **vs. SWE-bench and fixed benchmarks** — SWE-bench is a fixed dataset; Coder Eval is a *framework* for authoring your own tasks in YAML, so you evaluate the skills and workflows you care about (and can still wrap a fixed dataset via [Bring Your Own Dataset](https://coder-eval.com/docs/datasets)). - **vs. other agent-eval frameworks (e.g. Harbor) and LLM-eval tools (OpenAI Evals)** — OpenAI Evals grades model text; Harbor targets large-scale agent eval and RL optimization. Coder Eval is purpose-built for coding-agent/skill suites — weighted 0.0–1.0 file/command scoring, a `skill_triggered` activation check, an experiment layer for A/Bs, and evalboard. See the full comparison. - **vs. hand-rolled scripts** — reproducible sandboxes, weighted criteria, cost/token telemetry, A/B experiments, and CI-ready pass/fail gates out of the box. See the full [comparison](https://coder-eval.com/docs/comparison) for details. --- # Tutorials Step-by-step, task-oriented walkthroughs. Start here if you're new; for the complete command/config reference see the [User Guide](https://coder-eval.com/docs/user-guide), and for the task-file schema see the [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide). | # | Tutorial | You'll learn | | - | --- | --- | | 01 | [Your first evaluation](https://coder-eval.com/docs/tutorials/01-first-evaluation) | Install, configure a key, and run + read your first eval | | 02 | [Running Coder Eval in CI](https://coder-eval.com/docs/tutorials/02-ci-pipeline) | Wire the suite into GitHub Actions with a pass/fail gate | | 03 | [Browsing results with evalboard](https://coder-eval.com/docs/tutorials/03-evalboard-local) | Explore runs in a local web UI — pass rates, timelines, artifacts | | 04 | [Writing a task](https://coder-eval.com/docs/tutorials/04-writing-a-task) | Author a task YAML with success criteria from scratch | | 05 | [Comparing two models](https://coder-eval.com/docs/tutorials/05-comparing-models) | Use the experiment layer to A/B two configurations | | 06 | [Running tasks in Docker isolation](https://coder-eval.com/docs/tutorials/06-use-docker-isolation) | Run each task in a fresh container; add task-specific dependencies | | 07 | [Driving Coder Eval from Claude Code](https://coder-eval.com/docs/tutorials/07-plugin-in-claude-code) | Install the plugin and drive the whole loop — scaffold, author, review, run, analyze — from slash commands | > Contributions welcome — add a numbered `NN-title.md` file and link it in the > table above. Keep tutorials short, copy-pasteable, and outcome-focused. --- # Tutorial 01 — Your First Evaluation By the end you'll have installed `coder-eval`, pointed it at an API key, run a built-in task, and read the result. ~5 minutes. ## Prerequisites - **Python 3.13+** - **[uv](https://docs.astral.sh/uv/)** — `brew install uv` (macOS) or `pip install uv` - **Claude CLI** — `brew install claude` ([install guide](https://docs.anthropic.com/claude/docs/claude-code)) - An **Anthropic API key** ## 1. Install ```bash git clone https://github.com/UiPath/coder_eval.git cd coder_eval uv sync --extra dev ``` > **Just want the CLI?** `uv tool install coder-eval` installs the released > `coder-eval` command on your PATH in its own isolated environment — then run > every command below without the `uv run` prefix. Keep the clone anyway: the > example `tasks/` used in this tutorial live in the repo. `uv sync` creates a `.venv/`. **Activate it** to run `coder-eval` directly and drop the `uv run` prefix used throughout this tutorial: ```bash source .venv/bin/activate # now `coder-eval ...` works on its own; e.g. `coder-eval run tasks/hello_date.yaml` ``` The `uv run coder-eval ...` form below works with or without activating — `uv run` resolves the same `.venv` — so use whichever you prefer. ## 2. Configure your API key ```bash cp .env.example .env # Edit .env and set ANTHROPIC_API_KEY=sk-ant-... ``` > **Heads up:** usage telemetry is **on by default**. To turn it off, add > `TELEMETRY_ENABLED=false` to your `.env`. See the > [User Guide](https://coder-eval.com/docs/user-guide#usage-telemetry). ## 3. Validate before running ```bash uv run coder-eval plan tasks/hello_date.yaml ``` `plan` checks the task's syntax, required tools, and API keys without spending any tokens — a good habit before every run. ## 4. Run your first task ```bash uv run coder-eval run tasks/hello_date.yaml ``` This spins up an isolated sandbox, sends the task prompt to the agent, records every tool call, and scores the result against the task's success criteria. Add `--stream full` to watch the agent work in real time: ```bash uv run coder-eval run tasks/hello_date.yaml --stream full ``` ## 5. Read the result ```bash uv run coder-eval report runs/latest ``` `runs/latest` is a symlink to the newest `runs//`. The per-task result lives at `runs/latest////task.json` (with `task.log` and `artifacts/` beside it); the run-level `run.json`/`run.md` sit at the run root. See the [Output Structure](https://coder-eval.com/docs/user-guide#output-structure) reference for the full layout. ## Next steps - **Write your own task** → [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide) - **Compare configurations** → [A/B Experiments](https://coder-eval.com/docs/ab-experiments) - **Full CLI & config reference** → [User Guide](https://coder-eval.com/docs/user-guide) --- # Tutorial 02 — Running Coder Eval in CI Run your evaluation suite automatically in GitHub Actions: on demand, on a schedule, or as a merge gate. By the end you'll have a workflow that installs `coder-eval`, runs a set of tasks, turns the results into a pass/fail verdict, and uploads the reports as artifacts. This mirrors how the [UiPath skills repo](https://github.com/UiPath/skills) drives its task tree under [`tests/tasks/`](https://github.com/UiPath/skills/tree/main/tests/tasks) — a task directory checked into the repo, a pinned `coder-eval` version, and a `task.json`-based verdict — distilled to the parts that transfer to any project. ## The shape of a Coder Eval CI job Every CI setup, however elaborate, is the same five steps: 1. **Install** a pinned `coder-eval` and set up Python/uv. 2. **Provide credentials** via repository secrets (never hard-code keys). 3. **Run** `coder-eval` over a glob of task files into a known run directory. 4. **Gate** — parse the per-task `task.json` files into a pass/fail exit code. 5. **Upload** the run directory as an artifact for later inspection. ## 1. Lay out your tasks Keep your task YAMLs in the repo — e.g. a `tests/tasks/` tree grouped by area: ``` tests/ └── tasks/ ├── group-a/ │ ├── task-one.yaml │ └── task-two.yaml └── group-b/ └── task-three.yaml ``` ## 2. Add the workflow Create `.github/workflows/coder-eval.yml`: ```yaml name: Coder Eval on: workflow_dispatch: inputs: task_globs: description: 'Space-separated globs, e.g. tests/tasks/group-a/**/*.yaml' type: string required: true default: 'tests/tasks/**/*.yaml' parallelism: description: 'Parallel tasks (-j). Keep ≤ runner vCPUs (ubuntu-latest = 4).' type: string default: '4' # Or run on a schedule to keep skills up to date as models change — a skill # that quietly stops triggering shows up as a failing task before users hit it: # schedule: # - cron: '0 6 * * *' # 06:00 UTC daily # Or gate merges: # pull_request: # paths: ['tests/tasks/**'] concurrency: group: coder-eval-${{ github.ref }} cancel-in-progress: false jobs: eval: runs-on: ubuntu-latest timeout-minutes: 120 env: # Usage telemetry is on by default — turn it off in CI. TELEMETRY_ENABLED: 'false' steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.13' - uses: astral-sh/setup-uv@v4 - name: Install coder-eval # Install the published package. In a real gate, pin an exact released # version (coder-eval==X.Y.Z) so a harness upgrade can't move your results. run: uv pip install --system coder-eval - name: Run evaluations env: # Provide exactly the credentials your tasks need. ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} TASK_GLOBS: ${{ inputs.task_globs }} PARALLELISM: ${{ inputs.parallelism }} run: | # TASK_GLOBS is intentionally unquoted so the shell expands the globs. coder-eval run $TASK_GLOBS -j "${PARALLELISM:-4}" -v - name: Verdict (fail the job if any task didn't pass) if: always() run: | set -uo pipefail run_dir=$(ls -td runs/*/ 2>/dev/null | head -n 1 || true) if [ -z "$run_dir" ]; then echo "FAIL — no run directory produced" | tee -a "$GITHUB_STEP_SUMMARY" exit 1 fi python - "$run_dir" <<'PY' | tee -a "$GITHUB_STEP_SUMMARY" import json, pathlib, sys rows = [json.loads(p.read_text(encoding="utf-8")) for p in sorted(pathlib.Path(sys.argv[1]).rglob("task.json"))] for r in rows: print(f"- {r.get('task_id','?')}: {r.get('final_status','?')}") ok = sum(1 for r in rows if r.get("final_status") == "SUCCESS") print(f"\n**{ok}/{len(rows)} PASS**") sys.exit(0 if rows and ok == len(rows) else 1) PY - name: Upload run reports if: always() uses: actions/upload-artifact@v4 with: name: coder-eval-${{ github.run_id }} # `**` matches the replicate-index segment coder_eval adds # (runs/////). path: | runs/*/run.json runs/*/run.md runs/**/task.json runs/**/task.log if-no-files-found: warn retention-days: 14 ``` ## How the pieces work - **Telemetry off in CI.** `TELEMETRY_ENABLED: 'false'` at the job level keeps CI runs out of the usage stream. (See the [User Guide](https://coder-eval.com/docs/user-guide#usage-telemetry).) - **Pin the version.** Pinning an exact release (`coder-eval==X.Y.Z`) makes runs reproducible; bump it deliberately. A single source of truth (a `tests/.coder-eval-version` file read in a resolve step) scales better than hard-coding it in the YAML. - **Run directory.** Omitting `--run-dir` lets the harness create `runs//` (and a `runs/latest` symlink); the verdict step finds the newest via `ls -td runs/*/` and the upload globs match `runs/*/run.json`. The per-task result is `runs/////task.json` — see [Output Structure](https://coder-eval.com/docs/user-guide#output-structure). - **The verdict is just `task.json` parsing.** `final_status == "SUCCESS"` is the pass condition. `sys.exit(1)` on any non-pass fails the job; writing to `$GITHUB_STEP_SUMMARY` puts the table on the run's summary page. - **`if: always()`** on the verdict and upload steps means you still get results even when a task fails. ## Shortcut: the packaged action The five steps above spell out the mechanics, but Coder Eval also ships a composite action — on the Marketplace as [**coder_eval**](https://github.com/marketplace/actions/coder_eval) — that bundles install + run + JUnit report + job-summary + fail-on-failure into one step: ```yaml - uses: actions/setup-node@v4 # the claude-code agent needs the Claude CLI… with: { node-version: '20' } - run: npm install -g @anthropic-ai/claude-code - uses: UiPath/coder_eval@v0 # …then run the gate (pin @vX.Y.Z in production) with: tasks: tests/tasks/*.yaml tests/tasks/*/*.yaml model: claude-sonnet-5 env: | ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }} ``` The action is agent-agnostic — it installs `coder-eval` but not the agent runtime, so provide the `claude` CLI (or your agent's runtime) in the job first. See the [CI Gate reference](https://coder-eval.com/docs/ci-gate) for the full inputs table, JUnit output, the score-floor gate, and the fork/`pull_request_target` security caveat. The rest of this tutorial's hand-rolled workflow is still useful when you need finer control than the action's inputs expose. ## Publishing test results (JUnit) The verdict step above parses `task.json` by hand. If your CI already ingests JUnit XML — for the per-test annotations, history, and flake tracking most CI systems render from it — let `coder-eval` emit it directly instead. Add `--junit-xml` to the run: ```yaml - name: Run evaluations run: coder-eval run $TASK_GLOBS -j 4 --junit-xml coder-eval-junit.xml ``` The file is written **before** the exit-code decision, so a failing run still produces a report. You can also regenerate it from any existing run directory without re-running the suite: ```bash coder-eval report runs/latest -f junit # writes runs/latest/junit.xml coder-eval report runs/latest -f junit -o out.xml # custom path ``` The mapping: one `` per task row (grouped into a `` per variant), failed/errored rows carry a ``/`` with the per-criterion breakdown, skipped tasks and failing suite gates get their own synthetic suites. Feed the file to whatever your platform uses to render test results. On GitHub Actions, [`mikepenz/action-junit-report`](https://github.com/mikepenz/action-junit-report): ```yaml - name: Publish test report if: always() uses: mikepenz/action-junit-report@v5 with: report_paths: coder-eval-junit.xml ``` On Azure DevOps, `PublishTestResults@2`: ```yaml - task: PublishTestResults@2 condition: always() inputs: testResultsFormat: 'JUnit' testResultsFiles: 'coder-eval-junit.xml' ``` ## Secrets Add these under **Settings → Secrets and variables → Actions**: | Secret | For | | --- | --- | | `ANTHROPIC_API_KEY` | Direct Anthropic API (default backend) | | `AWS_BEARER_TOKEN_BEDROCK`, `AWS_REGION`, `BEDROCK_MODEL` | Only if you run `--backend bedrock` | ## Next steps The five steps above are the whole core. As a suite grows you'll layer on cost guardrails, matrix partitioning, scheduled sweeps, and artifact hygiene — the `coder-eval run` call stays the same, only the wrapper grows: - **Full CLI & config reference** → [User Guide](https://coder-eval.com/docs/user-guide) - **Pin CI agent/model via an experiment** → [A/B Experiments](https://coder-eval.com/docs/ab-experiments) - **A worked, scaled-up pipeline** → the [UiPath skills repo](https://github.com/UiPath/skills) workflow (cost guardrail, matrix partitioning, nightly schedule). --- # Tutorial 03 — Browsing Results Locally with evalboard `coder-eval` writes results as JSON, markdown, and logs under `runs/`. **evalboard** is a small local web UI that renders those runs — pass rates, per-task detail, tool and message timelines, artifact downloads — so you can explore a run in a browser instead of reading raw files. It reads straight from your filesystem: no database, no backend, nothing leaves your machine. ## Prerequisites - A completed run (do [Tutorial 01](https://coder-eval.com/docs/tutorials/01-first-evaluation) first — you need a `runs//` directory with a `run.json`). - **Node.js 20+** and **pnpm**. The repo pins pnpm via `packageManager`, so the simplest way is Corepack: ```bash corepack enable # provides the pinned pnpm ``` ## 1. Install dependencies ```bash cd evalboard pnpm install ``` ## 2. Point evalboard at your runs and start it ```bash # Use coder_eval's own ./runs directory (shortcut): pnpm dev:local # ...or point at any runs directory (absolute path): EVALBOARD_LOCAL_RUNS_DIR=/absolute/path/to/runs pnpm dev ``` Then open **http://localhost:3030**. > Only directories that contain a `run.json` appear in the index — empty shells > and the `latest` symlink are filtered out. If your run list is empty, confirm > the run actually completed and that `EVALBOARD_LOCAL_RUNS_DIR` points at the > parent `runs/` folder (not a single run). ## 3. Explore | Page | What it shows | | --- | --- | | `/` | The 20 most recent runs, one clickable row each | | `/runs/latest` | Redirects to the newest run | | `/runs/` | Run summary — pass rate, cost, duration — plus one row per task (green = pass, red = fail). "Download run (.zip)" bundles the whole folder | | `/runs//` | Per-task detail: success-criteria cards, the tool timeline, the message timeline (per-message tokens, expandable into thinking/tool/text), artifact downloads, and the tail of `task.log` | | `/trends` | Per-task pass rate and average duration/cost/turns across recent runs | `` matches the `task_id` in the results and the subdirectory name under `//` — the same layout described in the [Output Structure](https://coder-eval.com/docs/user-guide#output-structure) reference. ## How it works (and why it's safe to run locally) - **Filesystem-only in local mode.** Setting `EVALBOARD_LOCAL_RUNS_DIR` makes evalboard read runs from that directory and never reach out to any remote storage. - **OSS edition by default.** evalboard runs in its open-source edition with no configuration; UiPath-internal surfaces are opt-in via `EVALBOARD_EDITION=internal`. - **No database.** Run listings and detail pages are rendered on the fly from the files Coder Eval already wrote. ## Next steps - **Produce more runs to compare** → [A/B Experiments](https://coder-eval.com/docs/ab-experiments) - **Automate runs in CI, then download the artifact and open it here** → [Running Coder Eval in CI](https://coder-eval.com/docs/tutorials/02-ci-pipeline) --- # Tutorial 04 — Writing a Task By the end you'll have authored a task YAML from scratch — a prompt, an isolated sandbox, a soft turn budget, and three success criteria — validated it without spending tokens, run it, and read the score. ~10 minutes. ## Prerequisites - A working `coder-eval` checkout with an API key configured — see [Tutorial 01](https://coder-eval.com/docs/tutorials/01-first-evaluation). ## 1. Create the task file A task is a single YAML file: the prompt sent to the agent, the agent configuration, and the criteria that score whatever the agent leaves behind in the sandbox. Create `tasks/fizzbuzz.yaml`: ```yaml task_id: "fizzbuzz" description: "Write and run a classic FizzBuzz script." initial_prompt: > Create a Python file named fizzbuzz.py in the current working directory that prints the numbers 1 to 15, one per line, replacing multiples of 3 with 'Fizz', multiples of 5 with 'Buzz', and multiples of both with 'FizzBuzz'. Then run it with: python fizzbuzz.py agent: type: "claude-code" model: "claude-sonnet-5" permission_mode: "acceptEdits" setting_sources: [] # isolate the sandbox from your own CLAUDE.md/settings run_limits: expected_turns: 5 # soft target — warns when exceeded, never aborts success_criteria: - type: "file_exists" path: "fizzbuzz.py" description: "The script must be created." - type: "file_contains" path: "fizzbuzz.py" includes: ["FizzBuzz"] description: "The script must produce the combined FizzBuzz case." - type: "run_command" command: "python fizzbuzz.py" timeout: 10 description: "The script must run successfully." ``` What each block does: - **`initial_prompt`** — delivered to the agent inside a fresh sandbox directory; all file paths in the criteria are relative to that sandbox. - **`agent.setting_sources: []`** — keeps your own `CLAUDE.md` and local settings out of the sandbox. Without it, a large host `CLAUDE.md` is injected into every API call, inflating cache-creation tokens and cost. Leave it out only when the task needs your MCP servers. - **`run_limits.expected_turns`** — an efficiency target, not a cap: exceeding it logs a warning and adds a report badge but never aborts (use `run_limits.max_turns` for a hard cap). - **`success_criteria`** — each criterion scores 0.0–1.0 and supports `weight` (default 1.0) and `pass_threshold` (default 0.9). `run_command` here only checks the exit code; it can also match stdout (`expected_stdout`) or read a continuous score from stdout — see the [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide) for all 14 criterion types and every field. ## 2. Validate without spending tokens ```bash uv run coder-eval plan tasks/fizzbuzz.yaml ``` `plan` checks the YAML schema, required tools, and API keys without calling the model. Typos in criterion fields fail here (task models reject unknown keys) instead of after a paid run. ## 3. Run it ```bash uv run coder-eval run tasks/fizzbuzz.yaml ``` ## 4. Read the result ```bash uv run coder-eval report runs/latest ``` The report shows one row per criterion — score, pass/fail against its threshold, and the weighted total. The agent's full transcript and the files it created are preserved under `runs/latest////` (`task.json`, `task.log`, `artifacts/`). ## Where to go deeper - **All 14 criterion types, weights, thresholds** → [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide) - **Stop a run early once the key criteria are decided** (an opt-in `stop_early:` block on a criterion; `run_limits.stop_early: false` is the run-level kill switch) → [Task Definition Guide → `stop_early`](https://coder-eval.com/docs/task-definition-guide#stop_early-opt-in-early-stop) - **Fan one task out over a dataset of rows** → [Bring Your Own Dataset](https://coder-eval.com/docs/datasets) - **Full CLI & config reference** → [User Guide](https://coder-eval.com/docs/user-guide) - **Compare two configurations on this task** → [Tutorial 05](https://coder-eval.com/docs/tutorials/05-comparing-models) --- # Tutorial 05 — Comparing Two Models By the end you'll have A/B-tested two Claude models on the same task through the experiment layer and read the cross-variant comparison report. Agents are stochastic, so eyeballing two separate runs is noise — the experiment layer runs both arms under identical conditions and scores them side by side. ~10 minutes. ## Prerequisites - A working `coder-eval` checkout with an API key configured — see [Tutorial 01](https://coder-eval.com/docs/tutorials/01-first-evaluation). This tutorial uses the built-in `tasks/hello_date.yaml`. ## 1. Define the experiment An experiment runs the same task once per **variant** and reports the arms side by side — one config file, no copy-pasted tasks. Create `experiments/haiku-vs-sonnet.yaml`: ```yaml experiment_id: haiku-vs-sonnet description: "Compare Haiku vs Sonnet on the same task" defaults: agent: type: claude-code permission_mode: bypassPermissions variants: - variant_id: haiku agent: model: claude-haiku-4-5-20251001 - variant_id: sonnet agent: model: claude-sonnet-5 ``` A variant declares only what differs — here just `agent.model`. Everything else merges in from `defaults` and the task itself, so both arms are identical except for the model. (The repo ships `experiments/model-comparison.yaml` as a Sonnet-vs-Opus version of the same shape.) ## 2. Run both arms ```bash uv run coder-eval run tasks/hello_date.yaml -e experiments/haiku-vs-sonnet.yaml ``` Bare names resolve too: `-e haiku-vs-sonnet` finds `experiments/haiku-vs-sonnet.yaml`. ## 3. Read the comparison The run writes the cross-variant report automatically when it finishes — there's no separate report command for experiments: ```bash cat runs/latest/experiment.md ``` It ranks the variants by weighted score and shows per-task results, durations, and token usage side by side. Drill down from there: - `runs/latest/experiment.json` — the full result data. - `runs/latest//variant.md` (e.g. `runs/latest/haiku/variant.md`) — per-variant aggregate detail. ## 4. Add statistical power (optional) Agents are stochastic — one run per arm is noise, not signal. Repeat each arm to see variance instead of a point estimate: ```bash uv run coder-eval run tasks/hello_date.yaml -e haiku-vs-sonnet --repeats 5 ``` (or set `repeats: 5` under `defaults:` in the experiment file). The report then aggregates per-replicate scores per variant. ## Where to go deeper - **Variants, prompt mutations, replicates, skill on/off comparisons** → [A/B Experiments](https://coder-eval.com/docs/ab-experiments) - **Write the task you're comparing on** → [Tutorial 04](https://coder-eval.com/docs/tutorials/04-writing-a-task) - **Full CLI & config reference** → [User Guide](https://coder-eval.com/docs/user-guide) --- # Tutorial 06 — Running Tasks in Docker Isolation By default a task runs in a temp-dir sandbox on your host. This tutorial switches that to a fresh **Docker container per task** — strong host isolation and a pinned, reproducible toolchain — then shows how to add task-specific dependencies. ~10 minutes. For the complete reference, see [Docker Isolation](https://coder-eval.com/docs/docker-isolation). ## Why - **Isolation** — agent-generated code can't touch files or the network outside the sandbox. - **Reproducibility** — the image bakes in Python 3.13, Node 22 LTS, the Claude CLI, `uv`, and the matching `coder_eval` version, so results don't drift with host upgrades. Aggregation (scores, reports, evalboard) still happens on the host — each container is a sealed "run one task → emit one `task.json`" worker. ## Prerequisites - You've done [Tutorial 01](https://coder-eval.com/docs/tutorials/01-first-evaluation) (installed + ran a task). - **Docker** installed and the daemon running — check with `docker info`. If that command errors, install Docker first (next section). ## Installing Docker Pick your OS. After installing, verify with: ```bash docker info # daemon reachable? (no error = good) docker run --rm hello-world # pulls a tiny image and runs it ``` ### Linux Install **Docker Engine** (the daemon runs natively — no VM needed). The official convenience script covers most distros (Ubuntu, Debian, Fedora, …): ```bash curl -fsSL https://get.docker.com | sh ``` Or use your distro's packages directly — e.g. Ubuntu/Debian: ```bash sudo apt-get update sudo apt-get install -y docker.io ``` Then start the daemon and allow your user to run Docker without `sudo`: ```bash sudo systemctl enable --now docker # start now + on boot sudo usermod -aG docker "$USER" # add yourself to the docker group newgrp docker # apply the group in this shell (or log out/in) ``` For the packaged Docker Engine (Docker CE with Compose/Buildx), follow the distro-specific apt/dnf repo steps at . ### macOS Install **Docker Desktop** (bundles the engine in a lightweight VM): - Download the installer for your chip (Apple Silicon vs Intel) from , **or** with Homebrew: ```bash brew install --cask docker ``` - Launch **Docker Desktop** once (from Applications) so it starts the daemon and installs the `docker` CLI. The whale icon in the menu bar means it's running. The `docker` commands then work from any terminal. ### Windows Install **Docker Desktop** with the **WSL 2** backend, and run coder-eval from inside a WSL 2 Linux distro (the framework targets Linux/macOS): 1. Enable WSL 2 and install a distro (e.g. Ubuntu): ```powershell wsl --install ``` 2. Install Docker Desktop from . During setup keep **"Use the WSL 2 based engine"** enabled, and under *Settings → Resources → WSL integration* enable your distro. 3. Open your **WSL 2 Ubuntu** terminal and run `docker info` there — you'll run all `coder-eval` commands from inside WSL, not PowerShell. ## 1. Build the framework image (one time) ```bash make docker-image ``` This builds `coder-eval-agent:` (also tagged `:latest`) with both built-in agents (claude-code + Codex) and **needs no credentials**. `` is your installed `coder_eval` version (find it with `coder-eval --version`). Rebuild only when you upgrade `coder_eval` or the pinned toolchain. It's all you need for the common case (steps 2–5 below). Related build targets: | Target | Builds | When you need it | | --- | --- | --- | | `make docker-image` | `coder-eval-agent` (rebase base) | The default — the base image from which task Dockerfile should inherit `FROM coder-eval-agent` (step 5). | | `make docker-images` | **both** `coder-eval-agent` **and** `coder-eval-runtime` | coder-eval-runtime is used when a task Dockerfile brings its own base image.| | `make docker-image-full` | `coder-eval-agent` **+ the `uipath` extra** | Tasks that shell out to the `uipath` CLI. The `uipath` SDK resolves from public PyPI — no credentials needed. | > `make docker-images` is just `make docker-image` + `make coder-eval-runtime`. > Both base images are independent and persistent — build once, run any mix of > rebase and inject tasks. See > [Docker Isolation](https://coder-eval.com/docs/docker-isolation#tasks-that-bring-their-own-base-image-the-runtime-kit-coder-eval-runtime) > for inject-mode details. ## 2. Run any task in a container Add `--driver docker` to the `run` command from Tutorial 01: ```bash uv run coder-eval run tasks/hello_date.yaml --driver docker ``` `--driver docker` is a thin alias for `-D sandbox.driver=docker`. Everything else (streaming, reports, exit codes) works exactly as before. ## 3. Confirm it ran in Docker The tell-tale sign is a **`docker.log`** in the task dir (the container's stdout/stderr) — the tempdir driver never produces one: ```bash find runs/latest -name docker.log ``` And if you `docker ps` *during* a run you'll see one `coder-eval--…` container per in-flight task; they're removed (`--rm`) when the task finishes. Scores and reports are still read the usual way (`coder-eval report runs/latest`) — the driver doesn't change how results are aggregated. ## 4. Make a task always use Docker Rather than passing the flag every time, set it in the task YAML: ```yaml sandbox: driver: docker docker: network: bridge # or "none" for a fully sealed run (no network) image: my-custom:tag # optional: override the default framework image ``` ## 5. Add task-specific dependencies with a Dockerfile When a task needs extra system packages or Python libs, ship a Dockerfile and have coder-eval build it before the run: ```yaml sandbox: driver: docker docker: dockerfile_path: ./environment/Dockerfile # relative to the task YAML ``` ```dockerfile # environment/Dockerfile FROM coder-eval-agent:latest # REQUIRED — inherits the runtime + entrypoint RUN apt-get update && apt-get install -y --no-install-recommends poppler-utils RUN pip install --no-cache-dir PyMuPDF==1.24.10 COPY input/ /root/input/ # build context = this Dockerfile's parent dir ``` - The built image is cached as `coder-eval-task-:built`, so repeat runs reuse Docker's layer cache — edit the Dockerfile and only changed layers rebuild. - `dockerfile_path` takes precedence over any `image:` value. > **⚠️ The `FROM coder-eval-agent:` line is mandatory.** The container > runs the coder-eval orchestrator via the framework image's `ENTRYPOINT`; a bare > base (e.g. `FROM ubuntu:24.04`) has no entrypoint and the run fails with > `exec: "--output": executable file not found in $PATH`. coder-eval detects this > after the build and aborts with a hint. (`:latest` and `:` are both > tagged by `make docker-image`, so either works in the `FROM`.) Tasks whose > Dockerfile brings its own base — e.g. Fedora/`dnf` — use > inject-mode instead; see > [Docker Isolation](https://coder-eval.com/docs/docker-isolation#tasks-that-bring-their-own-base-image-the-runtime-kit-coder-eval-runtime). ## Next steps - **Full Docker reference** (network modes, runtime kit, cleanup) → [Docker Isolation](https://coder-eval.com/docs/docker-isolation) - **Task-file schema** → [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide) - **Full CLI & config reference** → [User Guide](https://coder-eval.com/docs/user-guide) --- # Tutorial 07 — Driving Coder Eval from Claude Code By the end you'll have installed the Coder Eval plugin and driven a full loop from slash commands: scaffold, author, review, run, analyze. ~15 minutes. **Cost:** steps 1–2 are free; budget **one paid agent run** for steps 3–4. The optional step 5 is one run *per row* — 16 for an 8/8 suite — so budget it separately. ## Prerequisites - Claude Code installed and working. - The `coder-eval` CLI. **Installing the plugin does not install it** — a plugin ships skills, not packages. You can let the skills handle it (`init`, `task` and `check-skill` check for it and offer to install it, asking first), or do it now: ```bash uv tool install coder-eval # or: pip install coder-eval coder-eval --version ``` - An API key for whichever agent your tasks use (`ANTHROPIC_API_KEY` for the default `claude-code` agent). Steps 2 onward assume you are in **your own repository** — not the `coder_eval` clone used by Tutorials 01 and 04. ## 1. Install the plugin This repository is itself the marketplace. Both of these are typed at the Claude Code prompt, not in your shell: ``` /plugin marketplace add UiPath/coder_eval /plugin install coder-eval@coder-eval ``` Verify by typing `/coder-eval:`. You should see six commands: `init`, `check-skill`, `task`, `lint-tasks`, `analyze`, `ci`. Three of them — `init`, `check-skill` and `task` — drive the same `coder-eval` CLI you would type by hand, so what they write is a normal file you can commit, diff and run in CI. The other three never invoke it: `analyze` reads a finished run directory, `ci` writes a workflow, and `lint-tasks` only reads task files and reports. ## 2. Scaffold a suite ``` /coder-eval:init ``` It scans for what is worth evaluating (Claude Code skills, an MCP server, a CLI), reports what it found, then scaffolds a task directory with one runnable task. **Note the directory it reports** — the layout varies by repository (`tasks/`, `tests/tasks/`, …) and later steps need that path: ```bash ls tasks/ # or whichever path init reported cat tasks/*.yaml | head -40 ``` Read that task before moving on. It is the shape every later task here gets modeled on, and step 3 is easier to follow once you have seen one. ## 3. Author a task, then review it ``` /coder-eval:task a task that checks the CLI can list processes as JSON ``` It designs criteria against the bundled [task-quality rubric](https://github.com/UiPath/coder_eval/blob/main/plugins/coder-eval/reference/task-rubric.md), then re-checks the files it wrote against the rubric's framing question: *what is the cheapest thing an agent could do that scores full marks?* Then it validates with `coder-eval plan` and **offers to run the task, asking first**. Take the offer — step 4 needs a run. Read the score the way the skill does: a **1.000 on a first attempt means re-read the criteria**, not celebrate, and a failure is a question about *which layer* is wrong (the prompt, or the skill or tool it depends on) before it is a prompt edit. Now review what you already have. Point the read-only linter at the directory from step 2: ``` /coder-eval:lint-tasks tasks/ ``` Same rubric, applied to files on disk. Per task you get a severity, a line reference and a concrete fix, covering criteria that cannot fail, prompts that give away the answer, fixtures with no cleanup and near-duplicates. Gameability findings name the weight at risk, e.g. *"A single `--file` call satisfies 14.0 of 33.0 weight"*. It never edits a file, and it scores test design only, so it closes by suggesting `coder-eval plan` for the schema half. Watch for `⚠` notices there: an unknown top-level key warns rather than fails. ## 4. Read the result If you accepted the run in step 3, you already have a run directory: the skill invoked the CLI through Bash on your behalf. By hand it is the same command, which is the whole point of the plugin being a driver rather than a separate product: ```bash coder-eval run # discovers tasks recursively; or pass explicit paths ls runs/latest/ # the run that was just written ``` Hand it back to the agent: ``` /coder-eval:analyze runs/latest ``` It writes `analysis.md` **into** the run directory, containing: - a TL;DR and a score breakdown, - per-task findings with concrete fixes, ranked by estimated score recovery, - on suites over 20 tasks, failures clustered into systemic patterns instead of repeated per task. ## 5. Check whether your own skill triggers (optional) If this repository has Claude Code skills, the plugin can measure whether the model reaches for one at the right moment. **Export the skill location first** — the evaluated agent runs in a fresh sandbox holding none of your files, so it is offered no skills unless the task says where they live. Point at a **plugin root**: a directory holding a `skills/` subdirectory, so the skill sits at `/skills//SKILL.md`. For `.claude/skills/pdf-forms/SKILL.md` that root is `.claude`, not `.claude/skills` — one level too deep loads nothing at all: ```bash export SKILL_SOURCE_PATH="$(pwd)/.claude" ``` ``` /coder-eval:check-skill pdf-forms ``` You get recall, precision and F1 over a labeled suite of requests the skill should win plus distractors it should decline, gated by `suite_thresholds` on `recall.yes` / `precision.yes`. Each row is a full agent run, so the skill states the count and asks before starting. Low recall has three possible causes, not one: truncation and listing-budget eviction look identical to bad wording. [The plugin page](https://coder-eval.com/docs/plugin#a-low-recall-result-has-three-causes-not-one) covers telling them apart with `/doctor` and `/context`. ## If something goes wrong | Symptom | Cause | | --- | --- | | No `/coder-eval:` commands after installing | Check `/plugin`; re-run the install | | A skill offers to install the CLI, or Bash reports `command not found` | The CLI isn't installed or isn't on `PATH` — accept the offer, or install it yourself | | `coder-eval run` matches nothing | Wrong directory — use the path `init` reported in step 2 | | Every positive row in step 5 scores 0 | `SKILL_SOURCE_PATH` is unset, or points one level too deep (`.claude/skills` rather than the `.claude` plugin root), so the skill was never offered | To update after the marketplace moves, `/plugin marketplace update coder-eval`; to remove it, `/plugin uninstall`. ## Next steps - `/coder-eval:ci` emits the CI workflow from [Tutorial 02](https://coder-eval.com/docs/tutorials/02-ci-pipeline) for you — least-privilege by default, and it provides the agent runtime (Node plus the Claude CLI) that the Action deliberately does not install. - [Claude Code plugin](https://coder-eval.com/docs/plugin) — the reference page: every skill, what ships in the plugin, and the activation-budget mechanics in full. - [Writing a task](https://coder-eval.com/docs/tutorials/04-writing-a-task) — the same authoring loop by hand, worth doing once to see what the skill is producing. - [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide) — the complete task schema. --- # Coder Eval User Guide The full command, configuration, and output reference. For a gentle introduction start with the [tutorials](https://coder-eval.com/docs/tutorials); for the task-file schema see the [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide). ## Table of Contents - [CLI Commands](#cli-commands) - [API Routing & Benchmarking](#api-routing--benchmarking) - [Output Structure](#output-structure) - [Suite Thresholds & Classification Metrics](#suite-thresholds--classification-metrics) - [Environment Variables](#environment-variables) - [Troubleshooting](#troubleshooting) ## CLI Commands ### `coder-eval run` — execute evaluations ```bash coder-eval run # all tasks (discovers tasks/ recursively) coder-eval run tasks/hello_date.yaml # a single task coder-eval run tasks/*.yaml --max-parallel 3 # multiple, 3 concurrent coder-eval run tasks/hello_date.yaml --stream full # live LLM output ``` | Flag | Description | | --- | --- | | `--max-parallel, -j` | Concurrent tasks (default: 1) | | `--preservation-mode` | Sandbox persistence: `NONE` / `MOVE_ON_WRITE` / `DIRECT_WRITE`. Default is driver-derived (docker → `DIRECT_WRITE`, else `MOVE_ON_WRITE`); explicit value always wins. | | `--run-dir` | Custom run directory (default: timestamped in `runs/`) | | `-D path=value` / `--set` | Override any resolved task-config field (`agent`/`run_limits`/`sandbox` roots), e.g. `-D run_limits.max_turns=30 -D agent.permission_mode=plan -D agent.sdk_options.effort=high`. Repeatable; schema-validated. This is the way to set permission mode, turn/timeout limits, token/USD budget caps, tools, plugins, and SDK options. | | `--model, -m` | Shorthand alias for `-D agent.model=…` (e.g., `claude-sonnet-5`) | | `--driver` | Shorthand alias for `-D sandbox.driver=…` (`tempdir` or `docker`) | | `--type, -T` | Override agent type for all tasks (`claude-code`, `codex`, `antigravity`, `opencode`, or a plugin kind). | | `--repeats` | Run each `(task, variant)` N times (≥1); overrides experiment/variant `repeats:`. See [Replicates](#replicates). | | `--resume` | Resume an interrupted run: skip tasks already finalized in `--run-dir` and run the rest, folding prior results into `run.json`. Requires `--run-dir`. A task with *any* final status (incl. FAILED/ERROR) counts as finalized, so resume does **not** retry failures — delete a task's `task.json` to force a re-run. A config mismatch is warned, not refused. | | `--sample N` | For dataset-backed tasks, run a fixed-seed random N-row sample (reproducible; cheap smoke test). See [Bring Your Own Dataset](https://coder-eval.com/docs/datasets). | | `--sample-per-stratum N` | For dataset-backed tasks, keep up to N rows per stratum (`stratify_field`). Overridden by `--sample`. Nondeterministic unless `dataset.sample_seed` is set — see [Bring Your Own Dataset](https://coder-eval.com/docs/datasets). | | `--include-skipped` | Also run tasks marked `skip: true` in their YAML (off by default so CI keeps excluding them). | | `--exclude-tags` | Skip tasks matching any of these tags (comma-separated) | | `--tags, -t` | Only run tasks matching any of these tags (comma-separated) | | `--experiment, -e` | Experiment definition YAML for multi-variant comparison (default: `experiments/default.yaml`) | | `--log-file` | Write logs to file | | `--backend, -b` | API backend: `direct` or `bedrock` (default: from `API_BACKEND` env var) | | `--stream, -s` | Stream LLM events to terminal: `full` or `minimal` (disables progress bar) | | `--verbose, -v` | DEBUG-level logging | **Run-time caps** — turns, wall-clock timeouts, and cumulative token / USD budgets — are not CLI flags of their own. They live under `run_limits:` in the task YAML, or on the command line as `-D run_limits.=` (e.g. `-D run_limits.max_usd=2.50`). The complete field reference is in the [Task Definition Guide](https://coder-eval.com/docs/task-definition-guide#run-limits). ### `coder-eval plan` — validate tasks ```bash coder-eval plan # validate all tasks coder-eval plan tasks/*.yaml # validate specific tasks ``` Checks task syntax, required CLI tools, API keys, and schema validity without executing. | Flag | Description | | --- | --- | | `--experiment, -e` | Experiment definition YAML to resolve variants against (default: `experiments/default.yaml`). | ### `coder-eval evaluate` — test criteria without an agent ```bash coder-eval evaluate tasks/hello_date.yaml ./my_solution # evaluate a directory coder-eval evaluate tasks/hello_date.yaml ./my_solution --preserve # keep the sandbox ``` Runs a task's success criteria against a directory without an agent — useful for testing criterion definitions, validating task configs, or scoring code that was already written. | Flag | Description | | --- | --- | | `--preserve / --no-preserve` | Preserve sandbox after evaluation (default: preserve) | | `--run-dir` | Custom run directory (default: auto-generated timestamped dir in `runs/`). | | `--verbose, -v` | DEBUG-level logging | ### `coder-eval report` — view results ```bash coder-eval report runs/latest # view latest run (markdown to stdout) coder-eval report runs/latest -o summary.md # export markdown to a file coder-eval report runs/latest --format html # (re)render every task.json as task.html ``` The `run` command already writes reports during execution; `report` re-displays or re-exports them later. For the on-disk layout and field-level schema of the JSON it reads, see [Output Structure](#output-structure) and the [Report Schema](https://coder-eval.com/docs/report-schema). | Flag | Description | | --- | --- | | `--output, -o` | Write to a file instead of stdout (markdown). | | `--format, -f` | `md` (default) or `html`. `html` re-renders each `task.json` under the run dir to a `task.html` beside it (or to `-o` when exactly one task is found). | ### `coder-eval aggregate` — rebuild `run.json` from task results ```bash coder-eval aggregate runs/2026-06-22_14-32-27 # rebuild the summary in place coder-eval aggregate runs/combined -o runs/combined # aggregate a merged dir ``` Re-derives the run-level `run.json` + `run.md` from the finalized `task.json` files already on disk, using the same builder a live run uses. Use it when a run dir's top-level summary is missing or stale — e.g. after recovering an interrupted run or combining several run directories. It rebuilds the **run-level summary only**; per-suite rollups (`suite.json`/`suite.md`) and experiment reports (`experiment.json`/`experiment.md`) are *not* rebuilt, because the per-row suite/variant grouping they need is not recoverable from `task.json` alone. | Flag | Description | | --- | --- | | `--output, -o` | Write `run.json`/`run.md` into this directory instead of the run dir (e.g. a merged output dir). | ### Claude Code slash commands Authoring and analysis commands ship in the [Claude Code plugin](https://coder-eval.com/docs/plugin), so they work in **any** repository rather than only this one: ``` /plugin marketplace add UiPath/coder_eval ``` | Command | Description | | --- | --- | | `/coder-eval:task` | Create evaluation task YAML files from a natural language description. | | `/coder-eval:analyze ` | Analyze evaluation runs and suggest improvements to tasks, config, and prompts. Works at task, variant, or run scope. | See [Claude Code Plugin](https://coder-eval.com/docs/plugin) for the full set of six skills. The `.claude/commands/` directory in this repository holds contributor-only tooling (code review, planning) that is deliberately not shipped. ## API Routing & Benchmarking `coder-eval` supports two API routing modes, selected via `--backend` or the `API_BACKEND` env var: - **Direct API** (`--backend direct`, default) — calls the Anthropic API directly using your `ANTHROPIC_API_KEY`. Accurate token/cost reporting from the SDK. - **AWS Bedrock** (`--backend bedrock`) — routes through AWS Bedrock with bearer token auth. Useful for cross-region model access and org-managed AWS deployments. ```bash coder-eval run tasks/hello_date.yaml # direct (default) coder-eval run tasks/hello_date.yaml --backend bedrock # via Bedrock (set BEDROCK_* in .env) ``` > **For official benchmarking, use the direct API (`--backend direct`)** for accurate token/cost reporting. ## Output Structure ``` runs/ ├── 2026-02-26_14-30-00/ # Timestamped run directory │ ├── run.json # Run-level summary (tasks, durations, tokens) │ ├── run.md # Run-level markdown report │ ├── experiment.md / .json / .log # Cross-variant comparison + aggregated log │ ├── / # Per-variant directory │ │ ├── variant.md / variant.json # Variant aggregate report + data │ │ └── / │ │ └── 00/ # Replicate index — one dir per replicate │ │ ├── task.json # Evaluation result │ │ ├── task.log # Execution log │ │ └── artifacts/ # Preserved sandbox (unless --preservation-mode NONE) │ └── ... └── latest -> 2026-02-26_14-30-00/ # Symlink to most recent run ``` ### Replicates Run the same (task, variant) N times via `repeats:` in an experiment YAML or `--repeats N` on the CLI. Per-replicate results live in separate `NN/` directories; reports aggregate them with bootstrap confidence intervals and (for 2-variant experiments) a paired mean-difference test. Defaults to 1 (no repetition). For a field-level reference to `run.json`, `variant.json`, `task.json`, and the suite/experiment rollups, see the [Report Schema](https://coder-eval.com/docs/report-schema). ## Suite Thresholds & Classification Metrics Any criterion on a **dataset-backed** task (see [Bring Your Own Dataset](https://coder-eval.com/docs/datasets)) can gate the whole suite, not just individual rows. Each criterion's `aggregate()` emits `count / mean / median / std / min / max`, and classification-style criteria (`classification_match`, `skill_triggered`) additionally emit accuracy, per-label precision/recall/F1, and a confusion matrix. Add `suite_thresholds` to require a minimum for any of those metrics — the run exits non-zero if any gate fails: ```yaml success_criteria: - type: skill_triggered skill_name: uipath-agents expected_skill: "${row.expected_skill}" # "" for rows where it shouldn't fire suite_thresholds: recall.yes: 0.70 # fired on ≥70% of rows that needed it precision.yes: 0.80 # ≤20% false activations ``` Available metric keys: `accuracy`, `macro_f1`, `weighted_f1`, `micro_f1`, and per-label `precision.