toPassEval() is an expectation like any other, and the recording, baselines, and dashboard happen behind it.
tests/Evals/SupportBotTest.php
The subject
expect(...) accepts a Laravel AI agent class-string, an agent instance, or a Closure(Row $row): AgentResponse — the closure escape hatch lets you evaluate anything that can produce an AgentResponse.
The $eval builder
Skip semantics
Evals call real models, so they never run by accident:Terminal
The
--evals flag and PEST_EVALS variable are the same contract used by pestphp/pest-plugin-evals, so the two plugins coexist cleanly in one suite — whichever consumes the flag, both see eval mode. See Vizra Evals vs pest-plugin-evals.What failure looks like
A failed gate fails the test with the receipts — aggregate score and pass rate, the run id (look it up in the dashboard), regressed rows with before → after scores, and the worst failing rows with sample counts. A run where every sample errored always fails, whatever the gate says.Suites and recording
EachtoPassEval test records under a suite named after the test (e.g. pest: answers support questions from documented policy) — that’s the identity baselines and history attach to. Rename the test and you start a fresh history, so pin it with ->suite('support-quality') if you expect descriptions to churn.