1.0.0-rc.5) so your agents interoperate with any EvalPort-compatible tool.
Run an Agent through a suite, then export both the suite and results as spec-conformant EvalPort documents:
Agent produces an EvalReport; one line exports it as an EvalPort ResultSet:
Quick Start
1
Export a suite
Build an
EvalPackage and export it as an EvalPort suite dict:2
Import a suite from another tool
Load an EvalPort suite dict from any compatible tool, then run it.
from_evalport prefers spec-shaped test_cases but also accepts legacy cases:3
Export a run report
Run a suite to get an
EvalReport, then persist it as an EvalPort ResultSet:4
Pin run_id / started_at for CI
Pass explicit
run_id and started_at so CI runs produce stable, diffable output:How It Works
The adapter maps native dataclasses to plain EvalPort dicts and back, so PraisonAI and external harnesses trade suites over the shared spec.The exporter (
to_evalport, report_to_evalport) now emits the spec-conformant 1.0.0-rc.5 shape. Downstream code that parsed the old fields (kind, suite_name, case_id, latency_ms, top-level score, grader_scores, top-level thresholds/seed, timeout_seconds) must be updated to the new keys. The importer (from_evalport) stays backward-compatible — it still reads legacy suites (cases, evalport_version, top-level thresholds/seed/timeout_seconds) and spec-shaped external suites with inline grader objects.
A round trip is lossless —
from_evalport(to_evalport(pkg)) reproduces the original package’s to_dict().
Spec Mapping
Native models map 1:1 onto EvalPort concepts.
Each
grader_result carries a clamped [0,1] score:
to_evalport looks like this:
report_to_evalport looks like this:
Configuration Options
The adapter is dependency-free and exposes three functions — no config classes.Full Python API for the eval package, including
to_evalport, from_evalport, and report_to_evalportCommon Patterns
Round-trip a suite locally to prove fidelity:HarnessEvaluator:
openeval package:
Best Practices
Timeouts export as timeout_ms (integer, >= 1)
Timeouts export as timeout_ms (integer, >= 1)
to_evalport writes a positive timeout_seconds as timeout_ms (integer milliseconds, max(1, round(sec*1000))) because the spec requires timeout_ms >= 1. A nonpositive timeout_seconds cannot be represented, so it is preserved under test_case.metadata.praisonai.timeout_seconds — the importer restores the original value, keeping round trips lossless.Every test case references praisonai_verdict first
Every test case references praisonai_verdict first
The exported
graders list on each test case always starts with "praisonai_verdict" (the spec requires at least one grader per case) followed by any criterion names, deduplicated in order. On import the adapter strips "praisonai_verdict" before returning criteria, so a round trip reproduces the original criteria exactly.Pin run_id / started_at for deterministic CI
Pin run_id / started_at for deterministic CI
report_to_evalport accepts keyword-only run_id and started_at. Left unset, run_id defaults to a random UUID and started_at to the current UTC time — pass explicit values in CI so output stays stable and diffable.Scores are clamped to [0, 1]
Scores are clamped to [0, 1]
Any raw score outside
[0, 1] is clamped; the pre-clamp value survives under grader_result.metadata["openeval.raw_score"]. When clamping changes the summary average, the raw value is kept under metadata.praisonai.average_score. A non-numeric or NaN score becomes null and forces passed: false (“not verified”).Keep the core SDK dependency-free
Keep the core SDK dependency-free
The adapter never imports
evalport-sdk or openeval. Install validation packages only where you run validate_suite() / validate_result_set(), so the core SDK stays lightweight everywhere else.Related
Evaluation Suite
Run every evaluator as one CI gate
Harness Evaluator
Score Interactive Test Harness traces
Judge
LLM-as-judge for evaluating outputs
Evaluation
Evaluators, suites, and reports

