feat(eval,cli): print why a gated metric failed, not just that it did - #3458
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Warning Review limit reached
Next review available in: 32 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: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe eval CLI now groups gate-failure explanations by metric, suppresses duplicate incomplete-record errors, limits displayed reasons, and prints unattached failures. A shared explanation constant is used across reports and JUnit output. Integration coverage verifies the output. ChangesEval gate output
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant EvalReport
participant EvalCLI
participant CLIOutput
EvalReport->>EvalCLI: Provide gate-failure summary
EvalCLI->>EvalCLI: Group reasons and suppress redundant incomplete-record errors
EvalCLI->>CLIOutput: Print metric and unattached failure explanations
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
bc3b3c5 to
4376b7a
Compare
4376b7a to
d8c90d4
Compare
d8c90d4 to
dda8c29
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cli/commands/eval/command.test.ts`:
- Around line 1268-1304: Update the test around runEvalCommand to save the
original values of VERYFRONT_API_TOKEN, VERYFRONT_PROJECT_SLUG,
VERYFRONT_EVAL_EXPORT, VERYFRONT_EVAL_EXPORTERS, and XDG_CONFIG_HOME before
modifying them, then restore each value in the finally block, deleting only
variables that were originally unset. Keep the existing temporary-directory
cleanup intact.
In `@cli/commands/eval/command.ts`:
- Around line 856-860: Update the derived duplicate-record calculation near
const derived so it includes only failures whose severity is "gate", while
retaining the exclusion of "record.error". Ensure the suppression logic at line
866 therefore removes record.error only when the record also has a gate failure,
and add a regression case covering a budget failure alongside an independent
record error.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 3b27b18e-21d3-4d37-b32a-95c23d2f161a
📒 Files selected for processing (2)
cli/commands/eval/command.test.tscli/commands/eval/command.ts
dda8c29 to
57112cf
Compare
57112cf to
5c5b51b
Compare
A failing metric line said that something failed but never why. For a judge rubric the verdict is the entire reason the eval failed, and reading it meant opening `summary.json` by hand. Gate failure explanations now print under the metric that produced them, capped at three per metric with a pointer to the written report beyond that. `record.error` is dropped only when it carries the stand-in explanation `RECORD_INCOMPLETE_EXPLANATION` and the record already reported a blocking failure. `isBlockingFailure` clears `completed` for both gate and budget severities, so either one produces that stand-in and printing it would restate the failure above it. A record error with text of its own, such as an adapter error, always prints, because no other line carries it. The stand-in string was written out at both sites that build it. It is a shared constant now, so the suppression rule cannot drift from the text it matches.
5c5b51b to
59325e3
Compare
A failing metric line said that something failed, never why:
Everything needed to act on that already existed in
summary.json, unprinted:For a judge rubric the verdict is the reason the eval failed. Reading it should not mean opening a JSON artifact.
After
Explanations print under the metric that produced them, three per metric, then
and N more, see the report. The cap keeps a large dataset from burying the summary; the pointer says where the rest live.Which record errors are suppressed
summary.gateFailuresalso carries arecord.errorentry whenever a record did not complete. Printing it unconditionally would restate the judge verdict directly above it as a second, independent problem.The rule keys on the explanation, not the severity:
isBlockingFailure(src/eval/runner.ts:232) clearscompletedfor bothgateandbudgetseverities, so either one yields the synthesizedRecord did not complete.stand-in. Both are suppressed when another failure already explains the record.record.errorcarrying text of its own — an adapter that threw, say — always prints. It is the only line explaining why the agent never answered, and nothing else reports it.The stand-in string was written out at both sites that build it (
report.ts,run-report.ts). It is now an exportedRECORD_INCOMPLETE_EXPLANATION, so the suppression rule cannot drift from the text it matches.Review follow-ups
derivedtoseverity === "gate". I did not take that: budget failures clearcompletedtoo, so it would have reintroduced the duplicate line for every budget metric. It did surface a real bug next door — a thrown adapter error being swallowed — which is what the explanation check fixes.Testing
src/eval/,cli/commands/eval/,src/extensions/eval/,extensions/ext-eval-report-mlflow/: 21 passed, 255 steps, 0 faileddeno lint,deno fmt --check(58 files): cleandeno checkon every touched file: cleanBoth new tests were verified failing against the previous code first:
prints why a gated metric failed, without restating it as a record errorkeeps a record error that carries detail of its own— drives a rejecting adapter plus a failing gate, asserts the upstream message survivesNot from this branch:
deno check src/eval/judges.test.tsreports threeTS18048 'call' is possibly 'undefined'errors. They reproduce unchanged onorigin/main.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation