Skip to main content
Pest 5 ships its own evals plugin (pestphp/pest-plugin-evals), and the obvious question is how the two relate. Short answer: different layers, happy coexistence — both are “just expectations,” they share the --evals flag, and they can live in the same file.
tests/Evals/SupportBotTest.php
Both are skipped without --evals. This is worth understanding rather than trusting, because the two plugins genuinely fight over that flag: each one pops --evals out of the argument list, so only one of them ever sees it. They coexist because both set PEST_EVALS=1 in the environment before popping, and both read that variable in isEvalMode(). Whichever runs first enables the other. Verified with both installed side by side: without the flag both skip, with it both run.
pest-plugin-evals requires Pest 5 and pins laravel/ai to a narrow range — currently >=0.10.2 <0.11.0. Running the two together therefore means Laravel 13, and a laravel/ai upgrade may block one until the other catches up.

When to reach for which

The structural difference

pest-plugin-evals operates on response text: its scorers receive strings, its repeat(n) requires every sample to pass (a consistency gate), and results exist only in the terminal. That’s exactly right for its job — fast, ergonomic checks. Vizra Evals operates on the response object and time: sampled score distributions rather than all-or-nothing, assertions against real tool calls and usage, multi-turn context, and every run persisted — which is what makes baselines, regression gates, trend charts, and the dashboard possible.
A perfectly good setup: pest-plugin-evals expectations as cheap per-prompt smoke checks, and one toPassEval() per agent as the recorded, baseline-gated measurement. They’ll never conflict.