feat(eval): wire defaults.grader as a config-level grader fallback - #1703
Merged
Conversation
Promptfoo research (this session) confirmed grading providers there are a single layered override (assertion > test > suite default > env-detected default), fully decoupled from the providers-under-test list — never a per-provider field. AgentV's own design principles already state config-level grader selection through `defaults.grader` should be preferred over target-level `grader_target`, but `defaults.grader` was dead: validated at config-parse time, never consumed at eval-run time. Agent-provider targets (copilot-cli, codex, claude-cli, etc.) hard-required an explicit `grader_target` on every single target definition with no global fallback. - orchestrator.ts: thread a new `defaultGraderTarget` option through `RunEvaluationOptions` / `EvaluationRuntimeOptions`, inserted into the existing grader-resolution chain between a target's own `grader_target` and self-grading (`target.graderTarget ?? defaultGraderTarget ?? target.name`), and into the agent-provider guard so `defaults.grader` alone satisfies the "agent providers need a grader" requirement. - run-eval.ts: thread `.agentv/config.yaml`'s `defaults.grader` into the new option. - config-graph.ts: `defaults.target`/`defaults.grader` validation incorrectly required a match against this same config document's inline `targets:`/ `graders:` arrays — always empty in the common case where targets live in a separately-discovered `.agentv/targets.yaml`. Only validate when those arrays are non-empty; otherwise resolution (and its errors) happens lazily at eval-run time, same as CLI `--grader-target` already does. Verified live: a real copilot-cli agent target with no `grader_target`, `defaults.grader` set to a separate real Azure LLM target — previously threw "agent provider ... with no grader_target", now runs and grades correctly (grading.json shows `"target": "grader-llm"`). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Entire-Checkpoint: 639d5c677078
Deploying agentv with
|
| Latest commit: |
c43888b
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://710e237a.agentv.pages.dev |
| Branch Preview URL: | https://feat-defaults-grader-fallbac.agentv.pages.dev |
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promptfoo research this session confirmed their grading-provider selection is a single layered override (assertion → test → suite default → env-detected default), fully decoupled from the providers-under-test list — never a per-provider field. This repo's own
.agents/product-boundary.mddesign principles already list "config-level grader targets selected throughdefaults.graderor assertion-level target selection, not target-level grader configuration" as a preferred extension point, and.agents/verification.mdtells engineers configuring codex dogfood to "select it withdefaults.grader... do not put a grader selector on the system-under-test target." Butdefaults.graderwas dead:config-graph.tsvalidated it at config-parse time but nothing consumed it at eval-run time, andorchestrator.tshard-required an explicitgrader_targeton every single agent-provider target with no global fallback — contradicting the framework's own documented guidance.orchestrator.ts: newdefaultGraderTargetoption threaded throughRunEvaluationOptions/EvaluationRuntimeOptions, inserted into the grader-resolution chain between a target's owngrader_targetand self-grading:target.graderTarget ?? defaultGraderTarget ?? target.name. Also satisfies the agent-provider "needs a grader" hard-requirement guard.run-eval.ts: threads.agentv/config.yaml'sdefaults.graderinto the new option.config-graph.ts:defaults.target/defaults.gradervalidation incorrectly required a match against this same config document's inlinetargets:/graders:arrays — always empty in the common case where targets live in a separately-discovered.agentv/targets.yaml(true of this repo and every downstream consumer checked this session). Now only validates when those arrays are non-empty; otherwise resolution (and its "not found" errors) happens lazily at eval-run time, the same way CLI--grader-targetalready works.Priority order is unchanged/additive: CLI
--grader-target> target's owngrader_target>defaults.grader(new) > self-grade (LLM-capable providers only).Test plan
defaultGraderTargetused as fallback when target has none; target's owngrader_targetstill wins overdefaultGraderTarget(priority ordering).defaults.target/defaults.graderno longer throws when no inlinetargets:/graders:block exists in.agentv/config.yaml.bun test packages/core/test/evaluation/orchestrator.test.ts packages/core/test/evaluation/loaders/config-loader.test.ts— 191/191 pass.bun run typecheck(core + cli) — clean.bunx biome checkon touched files — clean..agentv/config.yamlwithdefaults: {target: agent-under-test, grader: grader-llm}, a realcopilot-cliagent target with nograder_target, and a real Azure LLMgrader-llmtarget. Before this change: hard error"... is an agent provider ... with no grader_target". After: runs and passes, andgrading.json's assertion metadata shows"target": "grader-llm", confirming the config-level fallback actually routed grading to the separate LLM target rather than silently no-op'ing or erroring.Note on naming
grader_target/defaults.grader/graders:all use the word "grader" to mean which provider judges, distinct from an assertion'stype(the grading method, e.g.llm-rubric) and a rubric'scriteria/value(the grading prompt). This PR doesn't rename anything — flagging the overload for a possible future naming pass now thatdefaults.graderis the primary path and per-targetgrader_targetbecomes the rarer override.🤖 Generated with Claude Code