> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instructorphp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent eval cases

## Overview

Generate many eval cases from typed dataset rows. This applies one safety contract to a growing
regression set without copy-pasting test bodies, while explicit case IDs keep failures actionable.

## Example

```php theme={null}
<?php
require 'examples/boot.php';

use Cognesy\Agents\Evals\AgentEval;
use Cognesy\Agents\Evals\AgentEvalSet;
use Cognesy\Agents\Evals\EvalRunner;
use Cognesy\Agents\Evals\EvalContext;
use Cognesy\Agents\Evals\EvalDataset;
use Cognesy\Agents\Evals\EvalDatasetRow;
use Cognesy\Agents\Evals\EvalVerdict;
use Cognesy\Agents\Evals\LocalAgentTarget;
use Cognesy\Agents\Builder\AgentBuilder;
use Cognesy\Agents\Capability\Core\UseDriver;
use Cognesy\Agents\Drivers\Testing\FakeAgentDriver;

$dataset = new EvalDataset(
    new EvalDatasetRow(['orderId' => 'A1049', 'prompt' => 'Refund A1049']),
    new EvalDatasetRow(['orderId' => 'B2050', 'prompt' => 'Refund B2050']),
);

// Expand every dataset row into an independently runnable eval case.
$cases = AgentEvalSet::fromDataset(
    $dataset,
    // Build the case definition now; its test closure captures this row and runs later.
    static fn(EvalDatasetRow $row): AgentEval => AgentEval::define(
        description: 'Refund request stays side-effect free.',
        test: static function (EvalContext $t) use ($row): void {
            // Execute the target with this row's prompt and retain the resulting trajectory.
            $t->send($row->string('prompt'));

            // Collect gates for completion, forbidden side effects, and the expected guidance.
            $t->succeeded();
            $t->notCalledTool('refunds_issue');
            $t->messageIncludes('Verification');
        },
        // Put the business identifier in reports so a failing dataset row is easy to find.
    )->withId('refund/' . $row->string('orderId')),
);

$target = LocalAgentTarget::fromFactory(static fn() => AgentBuilder::base()
    ->withCapability(new UseDriver(FakeAgentDriver::fromResponses(
        'Verification is required before any refund.',
    )))
    ->build());
$result = (new EvalRunner($target))->run($cases->evals());

echo "Dataset coverage:\n";
foreach ($result as $case) {
    echo "- {$case->id()}: " . strtoupper($case->verdict()->value) . "\n";
    if ($case->verdict() !== EvalVerdict::Passed) {
        throw new RuntimeException("Dataset case {$case->id()} did not pass.");
    }
}
echo "Result: {$result->count()} refund requests share one side-effect safety contract.\n";
?>
```
