Skip to main content
The eval suite runner executes declared Cases sequentially and returns a SuiteResult. Each case runs one input against one agent or team, then applies an optional judge check (AgentAsJudgeEval via criteria) and an optional reliability check (ReliabilityEval via expected_tool_calls).
from agno.eval import Case, CaseResult, JudgeMode, SuiteResult, run_cases, arun_cases, cli, acli

Case

A Case describes a single input and its checks. It’s 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.
ParameterTypeDefaultDescription
namestrRequiredCase name. Used by the --name selector and in results.
inputstrRequiredInput sent to the agent or team.
agentOptional[Agent]NoneAgent under test. Provide exactly one of agent or team.
teamOptional[Team]NoneTeam under test. Provide exactly one of agent or team.
tagsTuple[str, ...]()Tags used by the --tag selector.
timeout_secondsOptional[int]NonePer-case timeout in seconds. Falls back to the runner’s default_timeout.
criteriaOptional[str]NoneJudge criteria. Setting this enables an AgentAsJudgeEval check on the response.
judge_modelOptional[Model]NonePer-case judge model. Falls back to the runner’s judge_model, then the AgentAsJudgeEval default.
judge_modeJudgeModeJudgeMode.BINARYJudge scoring mode. BINARY is a pass/fail verdict; NUMERIC grades 1-10 and passes when the score meets judge_threshold.
judge_thresholdint7Pass bar for numeric scoring, from 1 to 10. Read only when judge_mode is NUMERIC.
expected_tool_callsOptional[Tuple[str, ...]]NoneTool names that must fire during the run. Setting this enables a ReliabilityEval check.
allow_additional_tool_callsboolTrueAllow tool calls outside expected_tool_calls (subset matching).
setupOptional[Callable[[], Any]]NoneRuns before the case, outside the timeout. Its return value is passed to teardown as context. Sync callables run in a thread; async callables are awaited.
teardownOptional[Callable[[Any, CaseResult], Any]]NoneRuns after the case whenever setup completed, including on failure, error, and timeout. Receives (context, result).

JudgeMode

JudgeMode is a string enum whose values match AgentAsJudgeEval.scoring_strategy. The plain strings "binary" and "numeric" work anywhere a JudgeMode does.
MemberValueDescription
JudgeMode.BINARY"binary"The judge returns a pass/fail verdict.
JudgeMode.NUMERIC"numeric"The judge returns a 1-10 score. The case passes when the score meets judge_threshold.

run_cases and arun_cases

def run_cases(
    cases: Sequence[Case],
    *,
    tag: Optional[str] = None,
    name: Optional[str] = None,
    default_timeout: int = 120,
    judge_model: Optional[Model] = None,
    db: Optional[Union[BaseDb, AsyncBaseDb]] = None,
    on_case_start: Optional[Callable[[Case], None]] = None,
    on_case_end: Optional[Callable[[Case, CaseResult], None]] = None,
    on_run_event: Optional[Callable[[Case, RunOutputEvent], None]] = None,
) -> SuiteResult
arun_cases takes the same arguments and is awaited. run_cases is a sync wrapper that runs the whole suite on a single event loop via asyncio.run.
ArgumentTypeDefaultDescription
casesSequence[Case]RequiredCases to select from.
tagOptional[str]NoneKeep only cases with this tag.
nameOptional[str]NoneKeep only the case with this name.
default_timeoutint120Per-case timeout in seconds when Case.timeout_seconds is None.
judge_modelOptional[Model]NoneSuite-wide default judge model. Case.judge_model overrides it.
dbOptional[Union[BaseDb, AsyncBaseDb]]NonePassed to the judge and reliability evals so results log to storage.
on_case_startOptional[Callable[[Case], None]]NonePresentation hook called before each case runs.
on_case_endOptional[Callable[[Case, CaseResult], None]]NonePresentation hook called with each case and its CaseResult, including skipped cases after an abort.
on_run_eventOptional[Callable[[Case, RunOutputEvent], None]]NonePresentation hook called with every streamed run event.
The runner performs no console I/O; all presentation flows through the hooks. Hooks must be sync callables invoked on the event loop. A hook that raises, or an async hook, is recorded as a hook: error on the case without aborting the suite. A cancelled run aborts the suite; the unrun cases are appended as failed with skipped=True so the payload accounts for every selected case.

CaseResult

FieldTypeDescription
namestrCase name.
tagsTuple[str, ...]Case tags.
agent_idOptional[str]Agent ID for an agent case. None for a team case.
team_idOptional[str]Team ID for a team case. None for an agent case.
session_idstrGenerated eval session ID linking the case to its stored session and trace. Empty for skipped cases.
duration_secondsfloatWall-clock duration of the case, including setup and teardown.
judge_passedOptional[bool]Judge verdict. None when no criteria was configured.
judge_reasonOptional[str]The judge’s stated reason, when available.
judge_scoreOptional[int]Numeric-mode score from 1 to 10. None in binary mode.
reliability_passedOptional[bool]Reliability verdict. None when no expected_tool_calls was configured.
outputOptional[str]Response text the judge graded.
tools_calledTuple[str, ...]Tool names fired during the run, in order, including team member tools.
timed_outboolWhether the case exceeded its timeout.
skippedboolTrue for cases the suite never ran after a cancelled-run abort.
errorOptional[str]Run, judge, reliability, hook, and teardown errors, joined with "; ".
responseOptional[Union[RunOutput, TeamRunOutput]]Raw run output for programmatic access. Excluded from to_dict().
passedbool (property)True when there is no error and every configured check passed. False when no check ran.

SuiteResult

MemberTypeDescription
resultsList[CaseResult]One entry per selected case, including skipped cases.
totalint (property)Number of case results.
passedint (property)Number of passing cases.
failedint (property)Number of failing cases.
statusstr (property)"PASS" when all cases passed. An empty suite is "FAIL", so a typo’d selector cannot green-light CI.
to_dict()Dict[str, Any]Machine-readable payload with a summary block and per-case entries. This shape is a stable contract for CI consumers.

cli and acli

def cli(
    cases: Sequence[Case],
    *,
    db: Optional[Union[BaseDb, AsyncBaseDb]] = None,
    judge_model: Optional[Model] = None,
    default_timeout: int = 120,
    argv: Optional[Sequence[str]] = None,
) -> int
cli runs an argparse CLI over the given cases and returns the exit code. Call it from a script’s __main__ block with sys.exit(cli(CASES)). acli takes the same arguments and is the awaitable variant for callers already inside an event loop. When argv is None, arguments are read from sys.argv.

Flags

FlagDescription
--name NAMERun only the case with this name.
--tag TAGRun only cases with this tag.
--timeout SECONDSDefault per-case timeout in seconds. Defaults to the default_timeout argument.
--json-output PATHWrite the machine-readable JSON results to this path.
--listList the selected cases without running them. With --json-output, writes the case list instead of results.
-v, --verboseRender the full run panels (Message, Tool Calls, Response) after each case.

Exit codes

CodeMeaning
0All selected cases passed.
1Any case failed, or the --json-output write failed.
2No cases matched the selector, or an argparse usage error.