Cases against your Agents and Teams in one pass. Each case sends one input to one agent or team, then applies a judge check (criteria), a reliability check (expected_tool_calls), or both. The built-in CLI adds case selection, a summary table, a machine-readable JSON report, and exit codes for CI.
evals.py
criteria runs an Agent as Judge eval on the response. Setting expected_tool_calls runs a Reliability eval on the tool calls. A case passes when every configured check passes and no error occurred.
Case
Case is a frozen dataclass. Construction raises ValueError unless exactly one of agent or team is set and at least one check (criteria or expected_tool_calls) is configured.
setup and teardown may be sync or async callables. A teardown failure is recorded on the case result instead of being swallowed.
Judge modes
Running Programmatically
cli() is built on the same runner as run_cases(). To run a suite from code, call run_cases() (or await arun_cases() inside an event loop) and read the SuiteResult.
Cases run sequentially on a single event loop. The runner performs no console I/O; all presentation flows through the hooks, which must be sync callables. A hook that raises is recorded on the case as a
hook: error without aborting the suite.
An empty selection (for example a mistyped tag) yields status == "FAIL", so a CI gate never passes a run that executed zero cases. A cancelled run aborts the suite; the unrun cases are recorded as failed with skipped=True so the payload accounts for every selected case.
With
db= set, results log to storage through the same path as standalone evals. A failed write logs a warning without failing the case, and a hung write cannot stall a case past its timeout. Each case runs in a dedicated eval session (the payload’s session_id), so eval traffic stays out of the agent or team’s history.CLI
cli(CASES) parses sys.argv, runs the selected cases with a progress display, prints a summary table, and returns an exit code. Wire it into __main__ with sys.exit(cli(CASES)). Inside an already-running event loop (a server or notebook), use await acli(CASES) instead.
Both accept db=, judge_model=, and default_timeout= keyword arguments, which set the runner defaults behind the flags.
Exit codes
JSON report
--json-output writes SuiteResult.to_dict(). The shape is a stable contract for CI consumers.
evals.json
judge_passed and reliability_passed are null when the check is not configured. judge_score carries the 1-10 score in numeric mode. error joins every error recorded for the case: run, judge, reliability, setup/teardown, and hooks.
CI usage
The exit code gates the job, and the JSON report is the artifact you keep.Teams
Passteam= instead of agent=. Reliability sees the members’ tool calls, so expected_tool_calls can name the tool a member fires rather than only the leader’s delegation.
team_evals.py