Skip to content

feat: add promptlens compare for run-over-run regression detection - #48

Open
brainsparker wants to merge 1 commit into
mainfrom
feature/2026-08-21-compare-runs
Open

feat: add promptlens compare for run-over-run regression detection#48
brainsparker wants to merge 1 commit into
mainfrom
feature/2026-08-21-compare-runs

Conversation

@brainsparker

Copy link
Copy Markdown
Owner

What this does

Adds a promptlens compare command that diffs two saved evaluation runs, a baseline and a candidate, case by case. It answers the question --fail-under cannot: did my prompt or model change make anything worse than it was before?

promptlens run config.yaml            # baseline (e.g. on main)
# ... change the prompt or model ...
promptlens run config.yaml
promptlens compare <baseline_run_id> latest --fail-on-regression

Behavior:

  • Matches test cases between the two runs per (test_case_id, model) and classifies each shared case as improved, regressed, or unchanged. Cases only in one run are reported as added or removed.
  • A case that succeeded in the baseline but errored in the candidate counts as a regression even without judge scores. Baseline error to candidate success counts as an improvement.
  • Reports average judge score delta, total cost delta, and average latency delta for shared cases.
  • --threshold N mutes score drops smaller than N judge points.
  • --fail-on-regression exits with code 2 if any case regressed (code 1 stays reserved for run errors, matching the existing --fail-under convention).
  • --format md --output comparison.md writes a Markdown diff with regressions first (including the judge's explanation for each regression), ready to post as a PR comment. --format json writes the full structured comparison.
  • --baseline-model X --candidate-model Y matches on test_case_id alone for cross-model comparisons (same golden set, model swap).
  • latest resolves through the existing latest symlink.

Why this feature, today

Run-over-run regression diffing is the core workflow of every major eval platform, and PromptLens had all the ingredients (persisted runs, judge scores, a CI gate) but no way to do it:

PromptLens positions as the local, no-cloud alternative in exactly that lane. compare closes the gap: absolute gates (--fail-under) catch bad quality, but only a baseline diff catches a change that makes things worse while staying above the bar.

Runner-up candidates considered today: new export targets for you.md (GitHub Copilot CLI personal instructions at ~/.copilot/copilot-instructions.md and OpenCode global rules), and an MCP-Profiles improvement. Both are real opportunities but incremental reach; this one upgrades the core workflow of the tool.

Implementation notes

  • New module promptlens/comparison.py: pure comparison logic (compare_runs) plus Markdown rendering (comparison_to_markdown), built on the existing pydantic RunResult models. No new dependencies.
  • promptlens/cli.py: new compare command following the existing click and rich conventions, plus a shared _load_run helper.
  • README: feature bullet, CLI reference entry, and a "Comparing Runs and Catching Regressions" section under CI/CD Integration with a GitHub Actions PR-comment recipe.

Test status

  • 21 new tests in tests/test_compare.py covering classification, error transitions, thresholds, per-model and cross-model matching, added and removed cases, aggregate deltas, Markdown output (including pipe escaping), and CLI exit codes.
  • Full suite: 79 passed, 0 failed.
  • Manual end-to-end smoke test: built two runs on disk, ran python -m promptlens compare base cand --format md --fail-on-regression, verified the terminal table, the Markdown file, and exit code 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant