UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

75 lines (51 loc) 4.08 kB
--- title: "Reporters" description: "Ship eval results to Braintrust experiments or JUnit XML. eve runs and scores everything itself." --- eve runs and grades everything itself; reporters ship the results out. The CLI prints a console summary by default (one line per eval, with failed assertions and their messages), and reporters from `eve/evals/reporters` add destinations on top. You are responsible for ensuring any observability or eval provider is approved for the data exported to it. Reporters attach in two places. Declare them in `evals.config.ts` to observe **every** eval in the run, the usual choice for a shared destination like one Braintrust experiment, so you don't repeat the reporter in each file. Or list them on an individual eval's `reporters` to scope a destination to that eval (or to a group of evals that share one instance). ## Braintrust `Braintrust(...)` uploads eval results to Braintrust experiments. Put one instance in the config so it covers the whole run: ```ts title="evals/evals.config.ts" import { defineEvalConfig } from "eve/evals"; import { Braintrust } from "eve/evals/reporters"; export default defineEvalConfig({ judge: { model: "openai/gpt-5.4-mini" }, reporters: [Braintrust({ projectName: "weather-agent" })], }); ``` Need a destination for only some evals? Attach it per eval instead: ```ts title="evals/brooklyn-forecast.eval.ts" import { defineEval } from "eve/evals"; import { Braintrust } from "eve/evals/reporters"; export default defineEval({ reporters: [Braintrust({ projectName: "weather-agent" })], async test(t) { await t.send("What is the weather in Brooklyn?"); t.succeeded(); }, }); ``` The reporter config takes an optional `projectName` and `experimentName`, plus a base experiment (by name or id) to diff against. Gate assertions log as binary scores under a `gate:` prefix so experiments diff gate regressions the same way they diff soft-score regressions. Eval `metadata` rides along to reporters. A reporter instance observes the evals that reference it. Share one instance across several evals (the config, a `shared.ts` export, or every entry of a dataset array) and their results land in a single experiment. Listing the same config reporter on an eval too does not double-report it. Braintrust needs its SDK installed in the app and credentials in the environment: install the `braintrust` package (`npm install braintrust`) and set `BRAINTRUST_API_KEY`. Pass `--skip-report` to run the eval without shipping results, which also suppresses config reporters and is useful locally when iterating. ## JUnit `JUnit({ filePath })` writes JUnit XML for CI annotations. The `--junit <path>` CLI flag does the same thing without touching the eval file, usually the better fit because CI owns the output path, not the eval: ```bash eve eval --strict --junit .eve/junit.xml ``` Each eval becomes one `<testcase>` named by its path-derived id; failed gates and execution errors become failures, while `t.skip(reason)` produces a JUnit `<skipped>` result. ## Custom reporters A reporter implements the `EvalReporter` interface from `eve/evals/reporters` and receives the same structured results the built-ins do. The runner calls three lifecycle methods, each of which may return a promise for async work like a remote upload: ```ts interface EvalReporter { onRunStart(evaluations: readonly EveEval[], target: EveEvalTarget): void | Promise<void>; onEvalComplete(result: EveEvalResult): void | Promise<void>; onRunComplete(summary: EveEvalRunSummary): void | Promise<void>; } ``` `onRunStart` fires once before any eval runs, `onEvalComplete` fires after each observed eval with its checks, scores, and verdict, and `onRunComplete` fires once with the aggregated summary. Reach for a custom reporter only when a destination isn't covered. The per-run artifacts under `.eve/evals/` already capture everything for ad-hoc inspection. ## What to read next - [Running evals](./running): console output, `--json`, and artifacts - [Judge](./judge): what the reported numbers mean