feat(evaluation) 6/15: eval_datasets and eval_runs persistence - #817
feat(evaluation) 6/15: eval_datasets and eval_runs persistence#817Ahmath-Gadji wants to merge 1 commit into
Conversation
|
Warning Review limit reached
Next review available in: 59 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
7faed53 to
1f7dc63
Compare
ac18d7c to
9c927e8
Compare
|
@coderabbitai full review |
✅ Action performedFull review finished. Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 57 minutes. |
1f7dc63 to
6fc3735
Compare
9c927e8 to
b7efc52
Compare
6fc3735 to
dc532d0
Compare
b7efc52 to
f8a8257
Compare
dc532d0 to
367fc99
Compare
f8a8257 to
d04cd51
Compare
The `EvaluationRepository` port, its asyncpg implementation, the two tables, and the idempotent migration that creates them. `eval_runs` carries the metric payloads as JSONB rather than columns: the metric set is expected to grow, and the dataclasses in `core.models.evaluation` already define their shape. The store is what enforces one run at a time. The partial unique index `ux_eval_runs_single_active` admits a single row in an active status, so `create_run` raises `ConflictError` on the loser of a race rather than the orchestrator reading and then inserting. That matters because starting a run regenerates a shared service user's token: two racing starts that both passed a read check would revoke each other's credentials. The migration is idempotent per this repo's alembic rules — `Base.metadata.create_all()` runs at startup, so a freshly bootstrapped database already has these tables before alembic sees them.
367fc99 to
35e2f62
Compare
d04cd51 to
37d4787
Compare
Part 6 of 15 of the split of #811. Targets
eval/05-promptfoo-config(#816).What
core/ports/evaluation_repo.pyEvaluationRepositorycontractservices/persistence/evaluation_repo.pyservices/persistence/schema.pyeval_datasets,eval_runsmigrations/.../a7c9e1f2b3d4_add_evaluation_tables.pypostgres_store.py,catalog_store.py,di/container.pyNotable
ux_eval_runs_single_activeis a partial unique index over an always-true expression, so it admits exactly one row inQUEUED/INDEXING/EVALUATING;create_runmaps the resultingUniqueViolationErrortoConflictError. A read-then-insert in the service would be a race, and not a harmless one — starting a run regenerates a shared service user's token (part 8), so two racing starts that both passed a read check would revoke each other's credentials mid-indexing.core/models/evaluation.pyalready define the shape._row_to_runreconstructs them, including liftingsamplesback out of the indexing payload._loadexists because asyncpg returns JSONB asstrunless a codec is registered on the pool; the repo does not own the pool, so it decodes defensively instead.created_byisON DELETE SET NULL, matching howfiles.created_bybehaves — deleting an admin should not cascade away the run history they produced.eval_runs.dataset_idisON DELETE CASCADE: a run without its dataset is not meaningful.CLAUDE.md):Base.metadata.create_all()runs at startup, so a freshly bootstrapped database already has these tables before alembic sees them. Every op is guarded bytable_exists/index_exists, in both directions.Testing
ruff, format check, the layer-import guard, and the full unit suite (2258 passed) — including the container and catalog-store wiring tests, which the new abstract property could have broken. The one failure,test_content_deduplication_can_be_disabled_by_env, reproduces ondevelop.