agentv 5.3.0-next.1 → 5.3.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +22 -20
  2. package/dist/{artifact-writer-JFNIPMKW.js → artifact-writer-7NBCOAYC.js} +4 -4
  3. package/dist/{chunk-T32NL3E6.js → chunk-ASIGJIOJ.js} +50 -30
  4. package/dist/chunk-ASIGJIOJ.js.map +1 -0
  5. package/dist/{chunk-6ZZCDZPD.js → chunk-ELCJ23K4.js} +12766 -12478
  6. package/dist/chunk-ELCJ23K4.js.map +1 -0
  7. package/dist/{chunk-FVR4RQFK.js → chunk-LKGARI3W.js} +333 -24
  8. package/dist/chunk-LKGARI3W.js.map +1 -0
  9. package/dist/{chunk-V52ATPTT.js → chunk-LXBI3SPX.js} +142 -14
  10. package/dist/chunk-LXBI3SPX.js.map +1 -0
  11. package/dist/{chunk-BHKQHG26.js → chunk-RKE7SSET.js} +2 -2
  12. package/dist/cli.js +5 -5
  13. package/dist/dashboard/assets/{index-DNgf3qJ2.js → index-CbEMiJSb.js} +1 -1
  14. package/dist/dashboard/assets/{index-r_jSJmlw.js → index-DTA6-l7q.js} +3 -3
  15. package/dist/dashboard/index.html +1 -1
  16. package/dist/{dist-6Z7U473R.js → dist-NMXMI5SK.js} +17 -5
  17. package/dist/index.js +5 -5
  18. package/dist/{interactive-RUY3OCBI.js → interactive-BN527UV3.js} +5 -5
  19. package/dist/skills/agentv-bench/SKILL.md +14 -13
  20. package/dist/skills/agentv-bench/agents/analyzer.md +1 -1
  21. package/dist/skills/agentv-bench/agents/executor.md +1 -1
  22. package/dist/skills/agentv-bench/references/autoresearch.md +9 -9
  23. package/dist/skills/agentv-bench/references/environment-adaptation.md +4 -4
  24. package/dist/skills/agentv-bench/references/eval-yaml-spec.md +30 -47
  25. package/dist/skills/agentv-bench/references/schemas.md +44 -60
  26. package/dist/skills/agentv-bench/references/subagent-pipeline.md +20 -18
  27. package/dist/skills/agentv-eval-migrations/SKILL.md +13 -0
  28. package/dist/skills/agentv-eval-migrations/references/breaking-changes.md +39 -21
  29. package/dist/skills/agentv-eval-writer/SKILL.md +75 -46
  30. package/dist/skills/agentv-eval-writer/references/custom-evaluators.md +10 -5
  31. package/dist/skills/agentv-eval-writer/references/eval.schema.json +749 -2158
  32. package/dist/skills/agentv-eval-writer/references/rubric-evaluator.md +1 -1
  33. package/dist/{ts-eval-loader-DQDYRULE-V3377FOL.js → ts-eval-loader-2RFVZHCT-7CZ3DCDD.js} +8 -4
  34. package/package.json +1 -1
  35. package/dist/chunk-6ZZCDZPD.js.map +0 -1
  36. package/dist/chunk-FVR4RQFK.js.map +0 -1
  37. package/dist/chunk-T32NL3E6.js.map +0 -1
  38. package/dist/chunk-V52ATPTT.js.map +0 -1
  39. /package/dist/{artifact-writer-JFNIPMKW.js.map → artifact-writer-7NBCOAYC.js.map} +0 -0
  40. /package/dist/{chunk-BHKQHG26.js.map → chunk-RKE7SSET.js.map} +0 -0
  41. /package/dist/{dist-6Z7U473R.js.map → dist-NMXMI5SK.js.map} +0 -0
  42. /package/dist/{interactive-RUY3OCBI.js.map → interactive-BN527UV3.js.map} +0 -0
  43. /package/dist/{ts-eval-loader-DQDYRULE-V3377FOL.js.map → ts-eval-loader-2RFVZHCT-7CZ3DCDD.js.map} +0 -0
@@ -30,10 +30,12 @@ specific target, set `subagent_mode_allowed: false` in `.agentv/targets.yaml`:
30
30
  ```yaml
31
31
  # .agentv/targets.yaml
32
32
  targets:
33
- - name: my-target
33
+ - id: my-target
34
34
  provider: openai
35
- model: ${{ OPENAI_MODEL }}
36
- api_key: ${{ OPENAI_API_KEY }}
35
+ runtime: host
36
+ config:
37
+ model: "{{ env.OPENAI_MODEL }}"
38
+ api_key: "{{ env.OPENAI_API_KEY }}"
37
39
  subagent_mode_allowed: false # forces CLI invocation instead of executor subagent
38
40
  ```
39
41
 
@@ -43,8 +45,8 @@ even in subagent mode.
43
45
  ## CLI Targets: Single Command
44
46
 
45
47
  For evals with CLI targets, `pipeline run` handles input extraction, target invocation, and
46
- code grading in one step. When `--out` is omitted, the output directory defaults to
47
- `.agentv/results/default/<timestamp>` (same convention as `agentv eval`):
48
+ code grading in one step. When `--out` is omitted, the output directory uses the
49
+ canonical `.agentv/results/<run_id>` convention:
48
50
 
49
51
  ```bash
50
52
  # Extract inputs and invoke all CLI targets in parallel:
@@ -70,7 +72,7 @@ opted out via `subagent_mode_allowed: false` in `.agentv/targets.yaml`), fall ba
70
72
  ### Step 1: Extract inputs
71
73
 
72
74
  ```bash
73
- # Defaults to .agentv/results/default/<timestamp>
75
+ # Defaults to .agentv/results/<run_id>
74
76
  agentv pipeline input evals/repro.eval.yaml
75
77
  ```
76
78
 
@@ -117,7 +119,7 @@ LLM grading → merge and validate).
117
119
  Use individual commands when you need control over each step with CLI targets:
118
120
 
119
121
  ```bash
120
- # Step 1: Extract inputs (defaults to .agentv/results/default/<timestamp>)
122
+ # Step 1: Extract inputs (defaults to .agentv/results/<run_id>)
121
123
  agentv pipeline input evals/repro.eval.yaml
122
124
 
123
125
  # Step 2: run_tests.py invokes CLI targets (or use pipeline run instead)
@@ -127,7 +129,7 @@ agentv pipeline grade <run-dir>
127
129
 
128
130
  # Step 4: Subagent does LLM grading, writes results to llm_grader_results/<name>.json per test
129
131
 
130
- # Step 5: Merge scores (writes index.jsonl with full scores[] for dashboard)
132
+ # Step 5: Merge scores into the canonical run bundle
131
133
  agentv pipeline bench <run-dir>
132
134
 
133
135
  # Step 6: Validate
@@ -152,22 +154,22 @@ The agent reads `llm_graders/<name>.json` for each test, grades the response usi
152
154
 
153
155
  ## Pipeline Bench and Dashboard
154
156
 
155
- `pipeline bench` merges LLM scores into `index.jsonl` with a full `scores[]` array per entry,
156
- matching the CLI-mode schema. The web dashboard (`agentv results serve`) reads this format
157
- directly no separate conversion script is needed. Run `agentv results validate <run-dir>`
158
- to verify compatibility.
157
+ `pipeline bench` merges LLM scores into the canonical run bundle, including
158
+ `.internal/index.jsonl`, `summary.json`, and per-attempt `grading.json` with
159
+ `component_results`. The web dashboard reads this format directly no separate
160
+ conversion script is needed. Run `agentv results validate <run-dir>` to verify
161
+ compatibility.
159
162
 
160
163
  ## Output Structure
161
164
 
162
- The path hierarchy mirrors the CLI mode: `<evalset-name>` comes from the `name` field in
163
- the eval.yaml. The target is recorded in `manifest.json` — one run = one target.
165
+ The path hierarchy mirrors CLI mode. The target is recorded in run metadata.
164
166
 
165
167
  ```
166
- .agentv/results/<experiment>/<timestamp>/
168
+ .agentv/results/<run_id>/
167
169
  ├── manifest.json ← eval metadata, target, test_ids
168
- ├── index.jsonlper-test scores
169
- ├── summary.json aggregate statistics
170
- └── <evalset-name>/ ← eval.yaml "name" field, or eval file basename if absent (same as CLI mode)
170
+ ├── summary.jsonaggregate statistics
171
+ ├── .internal/index.jsonl canonical row index
172
+ └── <result-dir>/sample-1/grading.json
171
173
  └── <test-id>/ ← test case id
172
174
  ├── input.json ← test input text + messages
173
175
  ├── invoke.json ← target command or agent instructions
@@ -16,6 +16,19 @@ v4.42.4-era shape, current shape, migration steps, verification commands, and
16
16
  compatibility notes for each major breaking authoring change. Then compare the
17
17
  eval file against the current portable contract:
18
18
 
19
+ - Treat migrations as rule-based rewrites first. Do not rely on a manual
20
+ "looks current" pass when the old field has a direct current replacement.
21
+ - Rewrite authored prompt data into top-level `prompts` plus `tests[].vars`;
22
+ keep `input` only for documented raw-case import compatibility.
23
+ - Move sibling `expected_output` to `vars.expected_output`, then add or keep an
24
+ explicit assertion that consumes it, usually `llm-rubric` with
25
+ `{{ expected_output }}`.
26
+ - Rewrite target identity to `id`, keep `provider` for the backend/adapter kind,
27
+ put provider settings under `config`, and rewrite env references to
28
+ `{{ env.NAME }}`.
29
+ - Remove `use_target`, `eval_cases`, `evalcases`, `providerPromptMap`, and
30
+ `provider_prompt_map` from authored eval/config YAML. Current AgentV rejects
31
+ these fields, so do not preserve them as compatibility aliases.
19
32
  - Keep committed eval YAML portable: prompts, cases, assertions, workspace
20
33
  templates, repos, hooks, env checks, Docker preflight/container config, and
21
34
  `workspace.scope`.
@@ -23,7 +23,7 @@ For a v4.42.4-era eval:
23
23
 
24
24
  1. Move top-level `execution.target` to top-level `target`.
25
25
  2. Move top-level `execution.targets` to top-level `targets`, and rename target
26
- object `name` to `label`.
26
+ object `name` to `id`.
27
27
  3. Rename suite/test/turn `assertions` to `assert`.
28
28
  4. If a test uses `tests[].execution.assertions` or
29
29
  `tests[].execution.evaluators`, rename that nested list to
@@ -56,7 +56,14 @@ For a v4.42.4-era eval:
56
56
  assertions where there is a direct mapping.
57
57
  18. Keep raw cases under `tests` / `tests: file://...`; run full eval suites
58
58
  directly with CLI multi-file selection and tags.
59
- 19. Validate with `bun apps/cli/src/cli.ts validate <eval-file>`.
59
+ 19. Move authored prompt input from top-level or `tests[].input` into
60
+ `prompts` plus `tests[].vars.input`.
61
+ 20. Move authored reference answers from sibling `expected_output` into
62
+ `vars.expected_output`; add or keep an explicit assertion that consumes it.
63
+ 21. Rewrite target env interpolation from `${{ NAME }}` to `{{ env.NAME }}`.
64
+ 22. Remove `use_target`, `eval_cases`, `evalcases`, `providerPromptMap`, and
65
+ `provider_prompt_map`; current AgentV rejects them.
66
+ 23. Validate with `bun apps/cli/src/cli.ts validate <eval-file>`.
60
67
 
61
68
  ## Assertions Renamed To `assert`
62
69
 
@@ -844,42 +851,50 @@ targets:
844
851
  ### Current Shape
845
852
 
846
853
  Current eval YAML uses top-level `target` or `targets`. Target references use
847
- `label`; `id` is reserved for provider/backend identity when needed:
854
+ the target `id`; `provider` names the backend or adapter kind:
848
855
 
849
856
  ```yaml
850
857
  target: azure-base
851
858
 
852
859
  targets:
853
- - label: with-skills
854
- use_target: default
860
+ - id: with-skills
861
+ provider: codex-cli
862
+ runtime: host
863
+ config:
864
+ command: ["codex", "exec", "--json"]
855
865
  hooks:
856
866
  before_each:
857
867
  command: ["setup-plugins.sh", "skills"]
858
868
  ```
859
869
 
860
- Current `.agentv/targets.yaml` uses `label` and nests provider settings under
870
+ Current `.agentv/targets.yaml` uses `id` and nests provider settings under
861
871
  `config`:
862
872
 
863
873
  ```yaml
864
874
  targets:
865
- - label: azure-base
875
+ - id: azure-base
866
876
  provider: azure
877
+ runtime: host
867
878
  config:
868
- endpoint: ${{ AZURE_OPENAI_ENDPOINT }}
869
- api_key: ${{ AZURE_OPENAI_API_KEY }}
870
- model: ${{ AZURE_DEPLOYMENT_NAME }}
879
+ endpoint: "{{ env.AZURE_OPENAI_ENDPOINT }}"
880
+ api_key: "{{ env.AZURE_OPENAI_API_KEY }}"
881
+ model: "{{ env.AZURE_DEPLOYMENT_NAME }}"
871
882
  ```
872
883
 
873
884
  ### Migration Steps
874
885
 
875
886
  - Eval YAML: `execution.target` -> top-level `target`.
876
887
  - Eval YAML: `execution.targets` -> top-level `targets`.
877
- - Eval target object `name` -> `label`.
878
- - If an eval-local target object has provider configuration, include a
879
- `label`; use `extends` to derive from a base target.
880
- - Targets file: rename `name` to `label` and move provider-specific settings
881
- into `config`.
882
- - Keep AgentV target extensions such as `grader_target`, `use_target`,
888
+ - Eval target object `name` -> `id`.
889
+ - If an eval-local target object has provider configuration, include a concrete
890
+ `provider`; `id` is AgentV's stable target identity and `provider` names the
891
+ backend or adapter kind.
892
+ - Targets file: rename `name` to `id`, move provider-specific settings into
893
+ `config`, and rewrite environment references from `${{ NAME }}` to
894
+ `{{ env.NAME }}`.
895
+ - Remove `use_target`; current authored target definitions must resolve to
896
+ concrete provider objects.
897
+ - Keep supported AgentV target extensions such as `grader_target`,
883
898
  `fallback_targets`, `workers`, and `batch_requests` as top-level fields on
884
899
  target objects.
885
900
 
@@ -888,10 +903,12 @@ targets:
888
903
  ```bash
889
904
  bun apps/cli/src/cli.ts validate path/to/eval.eval.yaml
890
905
  bun apps/cli/src/cli.ts validate .agentv/targets.yaml
891
- rg -n "execution:|name:|endpoint:|api_key:|model:" path/to/evals .agentv/targets.yaml
906
+ rg -n "execution:|name:|use_target:|\\$\\{\\{|endpoint:|api_key:|model:" path/to/evals .agentv/targets.yaml
892
907
  ```
893
908
 
894
- Inspect `name:` matches manually because grader names still exist.
909
+ Inspect `name:`, top-level provider fields, and `${{ ... }}` matches manually
910
+ because grader names, non-target YAML, and historical examples can still use
911
+ similar strings legitimately.
895
912
 
896
913
  ### Compatibility Notes
897
914
 
@@ -1082,9 +1099,10 @@ rg -n "include:|tests:" path/to/evals
1082
1099
 
1083
1100
  ### Compatibility Notes
1084
1101
 
1085
- `eval_cases` remains a deprecated alias in the current schema, but migrated
1086
- YAML should use `tests`. The current convention is that runnable suites use
1087
- `*.eval.yaml`; reusable raw case files commonly use `*.cases.yaml` or JSONL.
1102
+ `eval_cases` and `evalcases` have been removed from authored eval YAML. Migrate
1103
+ them to `tests` before validating or running the suite. The current convention is
1104
+ that runnable suites use `*.eval.yaml`; reusable raw case files commonly use
1105
+ `*.cases.yaml` or JSONL.
1088
1106
 
1089
1107
  ## Result Artifact Path Changes Are Not Eval YAML Migrations
1090
1108
 
@@ -40,7 +40,7 @@ Use `@agentv/sdk` for TypeScript helper imports. Do not use `@agentv/eval` for n
40
40
 
41
41
  - Put grading criteria in `assert`, not in test-level `criteria`. Plain assertion strings become an `llm-rubric` grader.
42
42
  - Prefer plain assertion strings for semantic checks when the default rubric grader can judge them. Use `type: llm-rubric` for structured criteria, custom prompts, custom grader targets, or assertion-level transforms, and `type: script` when grading must execute code.
43
- - Write `expected_output` as a golden/reference answer the target could have produced. Do not write criteria, scoring instructions, or "the agent should..." rubric prose there.
43
+ - Put reference answers in `tests[].vars.expected_output` or `default_test.vars.expected_output`, and consume them with an explicit assertion such as `type: llm-rubric` with `value: "Matches the reference answer: {{ expected_output }}"`. Do not write criteria, scoring instructions, or "the agent should..." rubric prose as the reference answer.
44
44
  - For historical or repo-state evals, materialize the repo through a pinned `environment` setup recipe. Mentioning a SHA only in prompt prose is not enough because the agent needs an actual checkout to inspect.
45
45
 
46
46
  ## Evaluation Types
@@ -61,7 +61,12 @@ agentv convert evals.json
61
61
  agentv eval evals.json
62
62
  ```
63
63
 
64
- The converter maps `prompt` → `input`, `expected_output` → `expected_output`, and Agent Skills `assertions` AgentV `assert` (`llm-rubric` checks), and resolves `files[]` paths. The generated YAML includes TODO comments for AgentV features to add (environment setup, script graders, rubrics, required gates).
64
+ The converter maps Agent Skills prompt text into AgentV prompt/vars data,
65
+ promotes Agent Skills `expected_output` into explicit `llm-rubric` criteria or
66
+ `vars.expected_output` when it is true reference data, and maps Agent Skills
67
+ `assertions` to AgentV `assert` (`llm-rubric` checks). The generated YAML
68
+ includes TODO comments for AgentV features to add (environment setup, script
69
+ graders, rubrics, required gates).
65
70
 
66
71
  After converting, enhance the YAML with AgentV-specific capabilities shown below.
67
72
 
@@ -103,12 +108,15 @@ prompts:
103
108
 
104
109
  tests:
105
110
  - id: multi-turn-context
106
- expected_output: "Your name is Alice."
111
+ vars:
112
+ expected_output: "Your name is Alice."
107
113
  assert:
114
+ - type: llm-rubric
115
+ value: "Matches the reference answer: {{ expected_output }}"
108
116
  - Correctly recalls the user's name from earlier in the conversation
109
117
  ```
110
118
 
111
- **Guidelines:** preserve exact wording in `expected_output`; aim for 5–15 tests per transcript; pick exchanges that test different capabilities.
119
+ **Guidelines:** preserve exact wording in `vars.expected_output`; aim for 5–15 tests per transcript; pick exchanges that test different capabilities.
112
120
 
113
121
  ## Quick Start
114
122
 
@@ -123,8 +131,10 @@ tests:
123
131
  - id: greeting
124
132
  vars:
125
133
  prompt: "Say hello"
126
- expected_output: "Hello! How can I help you?"
134
+ expected_output: "Hello! How can I help you?"
127
135
  assert:
136
+ - type: llm-rubric
137
+ value: "Matches the reference answer: {{ expected_output }}"
128
138
  - Greeting is friendly and warm
129
139
  - Offers to help
130
140
  ```
@@ -140,7 +150,7 @@ tests:
140
150
  |-------|----------|-------------|
141
151
  | `id` | yes | Unique identifier |
142
152
  | `vars` | yes when the prompt needs row data | Prompt-template variables for this row |
143
- | `expected_output` | no | Gold-standard reference answer (string shorthand or full message array) |
153
+ | `vars.expected_output` | no | Conventional reference-answer var consumed by explicit graders |
144
154
  | `assert` | yes | Graders: deterministic checks, `llm-rubric` checks, script graders, or plain string rubric criteria |
145
155
  | `execution` | no | Per-case grader/default overrides such as `skip_defaults`; target selection belongs in top-level `target` or CLI `--target` |
146
156
  | `environment` | no | Per-case coding-agent testbed config (overrides suite-level) |
@@ -153,7 +163,7 @@ Use top-level `prompts` plus `tests[].vars` for the Promptfoo-compatible canonic
153
163
  input shape. Shared data defaults belong in `default_test.vars`; per-test
154
164
  `vars` override those defaults by key. AgentV renders every prompt with each
155
165
  test's merged vars, then expands the run across prompts, targets, tests, and
156
- repeat attempts.
166
+ repeat samples.
157
167
 
158
168
  ```yaml
159
169
  description: Prompt matrix example
@@ -176,15 +186,19 @@ tests:
176
186
  - id: password-reset
177
187
  vars:
178
188
  question: How do I reset my password?
179
- expected_output: Password reset guidance
189
+ expected_output: Password reset guidance
180
190
  assert:
191
+ - type: llm-rubric
192
+ value: "Matches the reference answer: {{ expected_output }}"
181
193
  - Gives correct password reset guidance
182
194
  - id: admin-access
183
195
  vars:
184
196
  audience: admins
185
197
  question: How do I revoke a user's access?
186
- expected_output: Access revocation guidance
198
+ expected_output: Access revocation guidance
187
199
  assert:
200
+ - type: llm-rubric
201
+ value: "Matches the reference answer: {{ expected_output }}"
188
202
  - Gives safe access revocation guidance
189
203
  ```
190
204
 
@@ -204,7 +218,7 @@ then render those vars from the prompt template next to the input.
204
218
  **Shorthand forms:**
205
219
  - Prompt entries can be strings, message arrays, file references, or prompt objects.
206
220
  - Put chat/system/user messages in `prompts`, not in `tests[].input`.
207
- - `expected_output` (string/object) expands to `[{role: "assistant", content: ...}]`
221
+ - `vars.expected_output` is a conventional reference-answer variable; explicit assertions decide how to grade it
208
222
  - Use these canonical field names on disk; keep the wire format `snake_case`
209
223
 
210
224
  **Message format:** `{role, content}` where role is `system`, `user`, `assistant`, or `tool`
@@ -356,12 +370,14 @@ tests:
356
370
  verification guidance was added.
357
371
 
358
372
  Decide what durable repo change should be made and explain why.
359
- expected_output: |
360
- The durable repo change is to update .agents/verification.md with the
361
- reusable verification workflow lessons. AGENTS.md already routes this
362
- class of work to .agents/verification.md, so no extra AGENTS.md edit is
363
- needed unless that routing is missing.
373
+ expected_output: |
374
+ The durable repo change is to update .agents/verification.md with the
375
+ reusable verification workflow lessons. AGENTS.md already routes this
376
+ class of work to .agents/verification.md, so no extra AGENTS.md edit is
377
+ needed unless that routing is missing.
364
378
  assert:
379
+ - type: llm-rubric
380
+ value: "Matches the reference answer: {{ expected_output }}"
365
381
  - The answer recommends updating .agents/verification.md rather than leaving the learning only in PR comments or private evidence.
366
382
  - The answer uses the pinned ./agentv checkout to verify the AGENTS.md routing.
367
383
  - The answer preserves the historical commit SHA as context.
@@ -387,9 +403,9 @@ tests:
387
403
  value: "fix"
388
404
  ```
389
405
 
390
- `expected_output` is passive reference data. It is available to graders through
391
- `{{expected_output}}` and the script stdin payload, but it does not create an
392
- implicit LLM grading call by itself.
406
+ `vars.expected_output` is passive reference data. It is available to graders
407
+ through `{{ expected_output }}` and the script stdin payload, but it does not
408
+ create an implicit LLM grading call by itself.
393
409
 
394
410
  **Common mistake:** putting rubric prose in `expected_output` instead of an
395
411
  assertion:
@@ -402,7 +418,7 @@ tests:
402
418
  - id: bad-example
403
419
  vars:
404
420
  prompt: "What is 2+2?"
405
- expected_output: The assistant should explain why the answer is 4. # reference answer field, not a grader
421
+ expected_output: The assistant should explain why the answer is 4. # reference answer var, not a grader
406
422
  ```
407
423
 
408
424
  Write this as:
@@ -415,8 +431,10 @@ tests:
415
431
  - id: good-example
416
432
  vars:
417
433
  prompt: "What is 2+2?"
418
- expected_output: "4"
434
+ expected_output: "4"
419
435
  assert:
436
+ - type: llm-rubric
437
+ value: "Matches the reference answer: {{ expected_output }}"
420
438
  - The answer is 4 and explains the arithmetic briefly
421
439
  ```
422
440
 
@@ -438,7 +456,7 @@ assert:
438
456
  weight: 5.0
439
457
  ```
440
458
 
441
- If a required grader scores below its threshold, the overall verdict is forced to `fail`.
459
+ If a required grader scores below its threshold, the overall case status is forced to `fail`.
442
460
 
443
461
  ## Environment Setup/Teardown
444
462
 
@@ -523,9 +541,10 @@ Configure via the `assert` array. Multiple graders produce a weighted average sc
523
541
  cwd: ./scripts # optional working directory
524
542
  target: {} # optional: enable LLM target proxy (max_calls: 50)
525
543
  ```
526
- Contract: stdin JSON -> stdout JSON `{score, assertions: [{text, passed, evidence?}], reasoning}`
544
+ Contract: stdin JSON -> stdout JSON `{pass, score, reason, checks?: [{text, pass, score?, reason}]}`
527
545
  Raw stdin uses snake_case and includes: `input`, `expected_output`, `output` (final answer string), `messages`, `trace`, `trace_summary`, `token_usage`, `cost_usd`, `duration_ms`, `start_time`, `end_time`, `file_changes`, `workspace_path`, `config`
528
546
  SDK handlers receive the same payload in camelCase: `expectedOutput`, `traceSummary`, `tokenUsage`, `costUsd`, `durationMs`, `startTime`, `endTime`, `fileChanges`, `workspacePath`.
547
+ `checks` is an SDK/script convenience shape; public `grading.json` artifacts normalize checks into recursive `component_results`.
529
548
  When an environment prepares a workspace directory, `workspace_path` is the absolute path to that directory (also available as `AGENTV_WORKSPACE_PATH` env var). Use this for functional grading (e.g., running `npm test` in the prepared workdir).
530
549
  For deterministic workspace checks that fit normal Vitest `expect(...)` tests, prefer a plain verifier file and the built-in adapter:
531
550
  ```yaml
@@ -567,7 +586,7 @@ Variables: `{{criteria}}`, `{{input}}`, `{{expected_output}}`, `{{output}}`, `{{
567
586
  type: llm-rubric
568
587
  weight: 0.7
569
588
  ```
570
- Use `assert-set` for Promptfoo-aligned assertion grouping. Without `threshold`, the set passes only when every nonzero-weight child assertion passes. With `threshold`, the weighted aggregate score determines the set verdict. Parent `config` is inherited by children, and child `config` keys override parent keys. Do not use `type: composite`; AgentV rejects it.
589
+ Use `assert-set` for Promptfoo-aligned assertion grouping. Without `threshold`, the set passes only when every nonzero-weight child assertion passes. With `threshold`, the weighted aggregate score determines the set pass/fail result. Parent `config` is inherited by children, and child `config` keys override parent keys. Do not use `type: composite`; AgentV rejects it.
571
590
 
572
591
  ### Skill And Trajectory Assertions
573
592
  ```yaml
@@ -722,24 +741,24 @@ agentv eval assert <grader-name> --agent-output "..." --agent-input "..."
722
741
  agentv import claude --session-id <uuid>
723
742
 
724
743
  # Re-run only execution errors from a previous run
725
- agentv eval <file.yaml> --retry-errors .agentv/results/default/<timestamp>/index.jsonl
744
+ agentv eval <file.yaml> --retry-errors .agentv/results/<run_id>/.internal/index.jsonl
726
745
 
727
746
  # Validate eval file
728
747
  agentv validate <file.yaml>
729
748
 
730
749
  # Compare completed runs
731
750
  agentv results compare \
732
- .agentv/results/default/<baseline-timestamp>/index.jsonl \
733
- .agentv/results/default/<candidate-timestamp>/index.jsonl
751
+ .agentv/results/<baseline-run-id>/.internal/index.jsonl \
752
+ .agentv/results/<candidate-run-id>/.internal/index.jsonl
734
753
  agentv results combine \
735
- .agentv/results/default/<baseline-timestamp> \
736
- .agentv/results/default/<candidate-timestamp> \
737
- .agentv/results/default/<third-target-timestamp> \
738
- --output .agentv/results/default/combined
739
- agentv results compare .agentv/results/default/combined/index.jsonl
754
+ .agentv/results/<baseline-run-id> \
755
+ .agentv/results/<candidate-run-id> \
756
+ .agentv/results/<third-target-run-id> \
757
+ --output .agentv/results/combined
758
+ agentv results compare .agentv/results/combined/.internal/index.jsonl
740
759
  agentv results compare \
741
- .agentv/results/default/<baseline-timestamp>/index.jsonl \
742
- .agentv/results/default/<candidate-timestamp>/index.jsonl \
760
+ .agentv/results/<baseline-run-id>/.internal/index.jsonl \
761
+ .agentv/results/<candidate-run-id>/.internal/index.jsonl \
743
762
  --json
744
763
 
745
764
  # Author assertions directly in the eval file
@@ -755,32 +774,36 @@ Use `@agentv/sdk` as the public lightweight SDK package for TypeScript/JavaScrip
755
774
 
756
775
  ### YAML-aligned eval authoring
757
776
  ```typescript
758
- import { defineEval, graders } from '@agentv/sdk';
777
+ // evals/helper-suite.eval.ts
778
+ import { graders, type EvalConfig } from '@agentv/sdk';
759
779
 
760
- export default defineEval({
780
+ const config: EvalConfig = {
761
781
  name: 'helper-suite',
762
782
  target: 'default',
763
- // The SDK helper lowers this to evaluate_options.repeat in generated YAML.
783
+ // TypeScript config loading lowers this to evaluate_options.repeat.
764
784
  repeat: {
765
785
  count: 3,
766
786
  strategy: 'pass_any',
767
787
  earlyExit: false,
768
788
  },
769
789
  threshold: 0.8,
790
+ prompts: ['{{ task }}'],
770
791
  tests: [
771
792
  {
772
793
  id: 'json-answer',
773
- input: 'Return a JSON answer with a status field.',
794
+ vars: { task: 'Return a JSON answer with a status field.' },
774
795
  assert: [
775
796
  graders.json({ name: 'valid-json', required: true }),
776
797
  graders.regex(/"status"\s*:/, { name: 'status-key' }),
777
798
  ],
778
799
  },
779
800
  ],
780
- });
801
+ };
802
+
803
+ export default config;
781
804
  ```
782
805
 
783
- The `graders` catalog returns ordinary `assert` entries such as `type: is-json`, `type: regex`, `type: llm-rubric`, and `type: script`. `defineEval()` lowers camelCase TypeScript fields such as `expectedOutput`, `inputFiles`, and `maxSteps` to canonical snake_case YAML/runtime keys.
806
+ The `graders` catalog returns ordinary `assert` entries such as `type: is-json`, `type: regex`, `type: llm-rubric`, and `type: script`. Explicit `*.eval.ts` and `*.eval.mts` files should default-export an `EvalConfig`; `defineEval(config)` is only an optional thin helper over that same shape. TypeScript config loading lowers camelCase fields such as `expectedOutput`, `inputFiles`, and `maxSteps` to canonical snake_case YAML/runtime keys.
784
807
 
785
808
  If adapting Braintrust `scores` or DeepEval metrics, write small AgentV helper factories that return `graders.*` configs:
786
809
 
@@ -805,9 +828,11 @@ import { defineAssertion } from '@agentv/sdk';
805
828
 
806
829
  export default defineAssertion(({ output, trace }) => {
807
830
  const finalOutput = output ?? '';
831
+ const pass = finalOutput.length > 0 && (trace?.eventCount ?? 0) <= 10;
808
832
  return {
809
- pass: finalOutput.length > 0 && (trace?.eventCount ?? 0) <= 10,
810
- reasoning: 'Checks content exists and is efficient',
833
+ pass,
834
+ score: pass ? 1 : 0,
835
+ reason: 'Checks content exists and is efficient',
811
836
  };
812
837
  });
813
838
  ```
@@ -823,17 +848,21 @@ import { defineScriptGrader } from '@agentv/sdk';
823
848
 
824
849
  export default defineScriptGrader(({ output, trace }) => {
825
850
  const finalOutput = output ?? '';
851
+ const hasOutput = finalOutput.length > 0;
852
+ const efficient = (trace?.eventCount ?? 0) <= 5;
826
853
  return {
827
- score: finalOutput.length > 0 && (trace?.eventCount ?? 0) <= 5 ? 1.0 : 0.5,
828
- assert: [
829
- { text: 'Output is not empty', passed: finalOutput.length > 0 },
830
- { text: 'Efficient tool usage', passed: (trace?.eventCount ?? 0) <= 5 },
854
+ pass: hasOutput && efficient,
855
+ score: hasOutput && efficient ? 1.0 : 0.5,
856
+ reason: 'Checks content exists and tool usage is bounded',
857
+ checks: [
858
+ { text: 'Output is not empty', pass: hasOutput, reason: hasOutput ? 'Output text is present' : 'Output is empty' },
859
+ { text: 'Efficient tool usage', pass: efficient, reason: efficient ? 'Trace event count is within limit' : 'Trace event count is too high' },
831
860
  ],
832
861
  };
833
862
  });
834
863
  ```
835
864
 
836
- Use `defineScriptGrader()` when the custom component is a command-backed grader with explicit score control, custom assertion-result arrays, workspace commands, or LLM calls through a grader target. `defineScriptGrader()` scripts are referenced in YAML with `type: script` and `command: [bun, run, grader.ts]`. Plain Vitest workspace verifier files can use `command: [agentv, eval, graders/check.test.ts]`.
865
+ Use `defineScriptGrader()` when the custom component is a command-backed grader with explicit score control, check arrays, workspace commands, or LLM calls through a grader target. `defineScriptGrader()` scripts are referenced in YAML with `type: script` and `command: [bun, run, grader.ts]`. Plain Vitest workspace verifier files can use `command: [agentv, eval, graders/check.test.ts]`.
837
866
 
838
867
  ### Convention-Based Discovery
839
868
 
@@ -59,13 +59,15 @@ import {
59
59
  createTargetClient,
60
60
  defineScriptGrader,
61
61
  defineEval,
62
+ type EvalConfig,
62
63
  definePromptTemplate,
63
64
  graders,
64
65
  } from '@agentv/sdk';
65
66
  ```
66
67
 
67
68
  - `defineScriptGrader(fn)` - Wraps evaluation function with stdin/stdout handling
68
- - `defineEval(definition)` - Defines a YAML-aligned `.eval.ts` suite
69
+ - `EvalConfig` - Public TypeScript eval authoring type for default-exported `*.eval.ts` and `*.eval.mts` files
70
+ - `defineEval(definition)` - Optional thin helper over the same `EvalConfig` shape
69
71
  - `graders` - Helper catalog that returns ordinary AgentV `assert` entries
70
72
  - `createTargetClient()` - Returns LLM proxy client (when `target: {}` configured)
71
73
  - `.invoke({question, systemPrompt})` - Single LLM call
@@ -81,7 +83,7 @@ For Python, the repo-local helper example in `examples/features/sdk-python/` kee
81
83
  Use helper factories for reusable Braintrust/DeepEval-inspired checks, but keep the result as AgentV `assert` entries:
82
84
 
83
85
  ```typescript
84
- import { defineEval, graders } from '@agentv/sdk';
86
+ import { graders, type EvalConfig } from '@agentv/sdk';
85
87
 
86
88
  function ragFaithfulness() {
87
89
  return graders.llmRubric(undefined, {
@@ -91,19 +93,22 @@ function ragFaithfulness() {
91
93
  });
92
94
  }
93
95
 
94
- export default defineEval({
96
+ const config: EvalConfig = {
95
97
  name: 'rag-suite',
98
+ prompts: ['{{ task }}'],
96
99
  tests: [
97
100
  {
98
101
  id: 'grounded-answer',
99
- input: 'Answer using the retrieved context.',
102
+ vars: { task: 'Answer using the retrieved context.' },
100
103
  assert: [
101
104
  graders.contains('source', { name: 'mentions-source' }),
102
105
  ragFaithfulness(),
103
106
  ],
104
107
  },
105
108
  ],
106
- });
109
+ };
110
+
111
+ export default config;
107
112
  ```
108
113
 
109
114
  The helper lowers to ordinary YAML: