agentv 5.2.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 (46) hide show
  1. package/README.md +22 -20
  2. package/dist/{artifact-writer-SN6UNL5G.js → artifact-writer-7NBCOAYC.js} +4 -4
  3. package/dist/{chunk-3X357HS4.js → chunk-ASIGJIOJ.js} +107 -31
  4. package/dist/chunk-ASIGJIOJ.js.map +1 -0
  5. package/dist/{chunk-3S6A2RKR.js → chunk-ELCJ23K4.js} +18879 -17538
  6. package/dist/chunk-ELCJ23K4.js.map +1 -0
  7. package/dist/{chunk-T4AD3H3Y.js → chunk-LKGARI3W.js} +399 -32
  8. package/dist/chunk-LKGARI3W.js.map +1 -0
  9. package/dist/{chunk-ALVZQUZP.js → chunk-LXBI3SPX.js} +142 -14
  10. package/dist/chunk-LXBI3SPX.js.map +1 -0
  11. package/dist/{chunk-46K2OET3.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-DEPJOMCA.js → dist-NMXMI5SK.js} +25 -5
  17. package/dist/index.js +5 -5
  18. package/dist/{interactive-36ZNMQB2.js → interactive-BN527UV3.js} +5 -5
  19. package/dist/skills/agentv-bench/SKILL.md +15 -14
  20. package/dist/skills/agentv-bench/agents/analyzer.md +2 -2
  21. package/dist/skills/agentv-bench/agents/comparator.md +3 -3
  22. package/dist/skills/agentv-bench/agents/executor.md +1 -1
  23. package/dist/skills/agentv-bench/agents/grader.md +4 -2
  24. package/dist/skills/agentv-bench/references/autoresearch.md +9 -9
  25. package/dist/skills/agentv-bench/references/description-optimization.md +5 -6
  26. package/dist/skills/agentv-bench/references/environment-adaptation.md +6 -6
  27. package/dist/skills/agentv-bench/references/eval-yaml-spec.md +50 -56
  28. package/dist/skills/agentv-bench/references/schemas.md +44 -60
  29. package/dist/skills/agentv-bench/references/subagent-pipeline.md +20 -18
  30. package/dist/skills/agentv-eval-migrations/SKILL.md +13 -0
  31. package/dist/skills/agentv-eval-migrations/references/breaking-changes.md +138 -22
  32. package/dist/skills/agentv-eval-writer/SKILL.md +103 -63
  33. package/dist/skills/agentv-eval-writer/references/custom-evaluators.md +10 -5
  34. package/dist/skills/agentv-eval-writer/references/eval.schema.json +749 -2158
  35. package/dist/skills/agentv-eval-writer/references/rubric-evaluator.md +1 -1
  36. package/dist/{ts-eval-loader-OMG2JBHP-OP5RR7A3.js → ts-eval-loader-2RFVZHCT-7CZ3DCDD.js} +8 -4
  37. package/package.json +1 -1
  38. package/dist/chunk-3S6A2RKR.js.map +0 -1
  39. package/dist/chunk-3X357HS4.js.map +0 -1
  40. package/dist/chunk-ALVZQUZP.js.map +0 -1
  41. package/dist/chunk-T4AD3H3Y.js.map +0 -1
  42. /package/dist/{artifact-writer-SN6UNL5G.js.map → artifact-writer-7NBCOAYC.js.map} +0 -0
  43. /package/dist/{chunk-46K2OET3.js.map → chunk-RKE7SSET.js.map} +0 -0
  44. /package/dist/{dist-DEPJOMCA.js.map → dist-NMXMI5SK.js.map} +0 -0
  45. /package/dist/{interactive-36ZNMQB2.js.map → interactive-BN527UV3.js.map} +0 -0
  46. /package/dist/{ts-eval-loader-OMG2JBHP-OP5RR7A3.js.map → ts-eval-loader-2RFVZHCT-7CZ3DCDD.js.map} +0 -0
@@ -20,7 +20,7 @@ The grader agent uses this to evaluate assertions without the CLI.
20
20
 
21
21
  - `id` (string, required) — unique test identifier
22
22
  - `vars` (object, required when prompts need row data) — prompt-template variables for this row
23
- - `expected_output` (string | Message[], optional) — passive reference answer. String shorthand expands to `[{role: assistant, content: "..."}]`. It is available to declared graders, but does not add an implicit grader when `assertions` is present.
23
+ - `vars.expected_output` (string | Message[], optional) — passive reference answer data. It is available to declared graders, but does not add an implicit grader when `assert` is present.
24
24
  - `criteria` (string, optional) — human-readable success criteria
25
25
  - `assert` (array, optional) — grader assertions
26
26
  - `environment` (object | `file://...`, optional) — per-case testbed override
@@ -31,8 +31,8 @@ If `assert` already states the grading contract, omit `criteria` instead of
31
31
  duplicating the same rubric. Prefer plain assertion strings for semantic checks
32
32
  when the default LLM rubric grader can judge them; use multiple named
33
33
  `type: llm-rubric` blocks only for custom prompts, custom grader targets, or
34
- intentional grader panels. Write `expected_output` as a golden/reference answer,
35
- not as criteria or scoring instructions.
34
+ intentional grader panels. Write `vars.expected_output` as a golden/reference
35
+ answer, not as criteria or scoring instructions.
36
36
 
37
37
  For historical or repo-state evals, materialize the repository through
38
38
  `environment.setup.command` and pass the repo/ref as argv inputs. A SHA in
@@ -45,11 +45,12 @@ checkout. `setup.command` is a non-empty string array. Put the executable at
45
45
 
46
46
  ### Default grader contract
47
47
 
48
- When a test has no `assertions`, AgentV uses the default `llm-rubric` with the case context,
49
- including `criteria` and `expected_output` when present.
48
+ When a test has no `assert`, AgentV can use configured suite/default graders
49
+ with the case context, including `criteria` and `vars.expected_output` when
50
+ present.
50
51
 
51
- When `assertions` is present, the list is explicit: run only the declared
52
- assertions/graders. `expected_output` remains reference data for graders that consume it,
52
+ When `assert` is present, the list is explicit: run only the declared
53
+ assertions/graders. `vars.expected_output` remains reference data for graders that consume it,
53
54
  such as `llm-rubric`, `script`, or `field-accuracy`; it does not trigger an additional
54
55
  default `llm-rubric`.
55
56
  When the declared assertion strings fully express the semantic contract, do not
@@ -171,18 +172,29 @@ Same as contains variants but explicitly case-insensitive.
171
172
 
172
173
  ### Tool inspection assertions
173
174
 
174
- #### `tool-trajectory`
175
+ #### `trajectory:tool-used`
175
176
 
176
- - **Fields:** `expected` (array of expected tool calls), `mode` (string: `any_order` | `in_order` | `exact` | `subset` | `superset`)
177
- - **Recipe:** Inspect AgentV-normalized transcript/tool-call data. Match against expected based on mode.
178
- - **PASS:** tool calls match expected pattern per mode.
179
- - **Boundary:** This is an AgentV extension. Promptfoo `trajectory:*`, `tool-call-f1`, `skill-used`, and `trace-*` assertion names are rejected until implemented directly.
177
+ - **Fields:** `value.name` (string, required), `value.min` (number, optional)
178
+ - **Recipe:** Inspect AgentV-normalized transcript/tool-call data and count matching tool calls.
179
+ - **PASS:** matching calls meet the requested minimum.
180
180
 
181
- #### `skill-trigger`
181
+ #### `trajectory:tool-sequence`
182
182
 
183
- - **Fields:** `skill_name` (string, required)
184
- - **Recipe:** Check if the agent invoked the named skill in its tool calls.
185
- - **PASS:** skill was triggered.
183
+ - **Fields:** `value.steps` (array of tool names, required), `value.mode` (`in_order` | `exact`)
184
+ - **Recipe:** Inspect AgentV-normalized transcript/tool-call data and compare the observed sequence.
185
+ - **PASS:** tool calls match the expected sequence for the selected mode.
186
+
187
+ #### `trajectory:tool-args-match`
188
+
189
+ - **Fields:** `value.name` (string, required), `value.args` (object, required), `value.mode` (`partial` | `exact`)
190
+ - **Recipe:** Inspect matching tool calls and compare arguments.
191
+ - **PASS:** at least one matching call has the expected arguments.
192
+
193
+ #### `skill-used` / `not-skill-used`
194
+
195
+ - **Fields:** `value` (skill name string or pattern object, required)
196
+ - **Recipe:** Check whether the agent invoked the named skill in its tool calls.
197
+ - **PASS:** `skill-used` finds the skill; `not-skill-used` confirms it is absent.
186
198
 
187
199
  ### LLM-judged assertions (require Claude reasoning)
188
200
 
@@ -200,18 +212,20 @@ Same as contains variants but explicitly case-insensitive.
200
212
 
201
213
  ### Script-based assertions
202
214
 
203
- #### `script-grader`
215
+ #### `script`
204
216
 
205
- - **Fields:** `path` (string, required — path to script), `command` (string[], optional — custom command)
217
+ - **Fields:** `command` (string[], required — command to execute), optional `cwd`, `config`, and `target`
206
218
  - **Script SDK:** Use `defineScriptGrader` from `@agentv/sdk`:
207
219
  ```typescript
208
220
  import { defineScriptGrader } from '@agentv/sdk';
209
221
  export default defineScriptGrader(({ output, trace }) => ({
222
+ pass: (output ?? '').includes('expected'),
210
223
  score: (output ?? '').includes('expected') ? 1 : 0,
211
- assert: [{ text: 'Contains expected', passed: (output ?? '').includes('expected') }],
224
+ reason: 'Checks for the expected token',
225
+ checks: [{ text: 'Contains expected', pass: (output ?? '').includes('expected'), reason: 'Substring check' }],
212
226
  }));
213
227
  ```
214
- - **Recipe:** The CLI runs the script, passing canonical JSON on stdin (`{output, input, expected_output, ...}`). Script returns `{"score": N, "assertions": [...]}`
228
+ - **Recipe:** The CLI runs the script, passing canonical JSON on stdin (`{output, input, expected_output, ...}`). Script returns `{pass, score, reason, checks?}`; public artifacts normalize `checks` into recursive `component_results`.
215
229
  - **PASS:** score >= 0.5 (or as configured).
216
230
 
217
231
  ### Assertion groups
@@ -241,42 +255,22 @@ All assertion types support:
241
255
  - `negate` (boolean, optional) — invert result
242
256
  - `threshold` (number, optional) — minimum score to pass (for LLM types)
243
257
 
244
- ## 5. AgentV JSONL Output Format
245
-
246
- Each line in the results JSONL file is an `EvaluationResult` object. In JSONL, field names use snake_case (applied by `toSnakeCaseDeep()`).
247
-
248
- ### Required fields
249
-
250
- - `timestamp` (string, ISO-8601)
251
- - `test_id` (string)
252
- - `score` (number, 0.0-1.0, weighted average of all assertion scores)
253
- - `assertions` (array of `{text, passed, evidence?}`)
254
- - `output` (string) — final answer/scored result; transcript evidence is available through captured trace/messages when present
255
- - `execution_status` (string: `ok` | `quality_failure` | `execution_error`)
256
-
257
- ### Optional fields
258
+ ## 5. AgentV Run Bundle Output
258
259
 
259
- - `scores` (array of EvaluatorResult) per-grader breakdown
260
- - `input` (Message[]) input messages
261
- - `token_usage` (object: `{prompt_tokens, completion_tokens, total_tokens}`)
262
- - `cost_usd` (number)
263
- - `duration_ms` (number)
264
- - `target` (string)
265
- - `eval_set` (string)
266
- - `error` (string)
267
- - `file_changes` (string — unified diff)
268
- - `mode` (string — `agent` for agent mode)
260
+ Each run writes `.agentv/results/<run_id>/`. Public persisted fields use
261
+ snake_case. The canonical discovery file is `.internal/index.jsonl`; per-attempt
262
+ sidecars live under each result directory.
269
263
 
270
- ### `scores[]` entries (EvaluatorResult)
264
+ Key artifacts:
271
265
 
272
- - `name` (string) grader name
273
- - `type` (string) grader kind (kebab-case)
274
- - `score` (number, 0.0-1.0)
275
- - `assertions` (array of `{text, passed, evidence?}`)
276
- - `weight` (number, optional)
277
- - `verdict` (string: `pass` | `fail` | `skip`)
278
- - `details` (object, optionalstructured data from script graders)
279
- - `reasoning` (string, optional)
266
+ - `.internal/index.jsonl` — one row per result aggregate with identity fields,
267
+ status, score, target metadata, and explicit paths to sidecars.
268
+ - `summary.json` run-level metadata and aggregate pass/score rollups.
269
+ - `sample-N/grading.json` aggregate `pass`, `score`, `reason`, recursive
270
+ `component_results`, and optional `assertion`, `named_scores`, and `metadata`.
271
+ - `sample-N/metrics.json` token, cost, timing, tool, and transcript metrics.
272
+ - `sample-N/transcript.json` and `sample-N/transcript-raw.jsonl`normalized
273
+ and raw transcript data when available.
280
274
 
281
275
  ## 6. Eval Set Support
282
276
 
@@ -355,9 +349,9 @@ LLM grader results are read from disk at `<test-id>/llm_grader_results/<name>.js
355
349
  ```
356
350
 
357
351
  **Output:**
358
- - `<test-id>/run-1/grading.json` — merged grading with `graders`, `assertions`, `summary.pass_rate`
359
- - `index.jsonl` — one JSON line per test: `{test_id, score, pass, graders: [...]}`
360
- - `summary.json` — aggregate stats: `{metadata: {targets}, run_summary: {<target>: {mean, stddev, n}}}`
352
+ - `.internal/index.jsonl` — canonical row index
353
+ - `summary.json` — aggregate run summary
354
+ - per-attempt `grading.json` — aggregate `pass`, `score`, `reason`, and recursive `component_results`
361
355
 
362
356
  ### Agent-Mode Workflow
363
357
 
@@ -85,80 +85,64 @@ Tracks version progression in Improve mode. Located at workspace root.
85
85
 
86
86
  ## grading.json
87
87
 
88
- Output from the grader agent. Located at `<case-dir>/run-N/grading.json`.
88
+ Public per-attempt grading output. Located at
89
+ `.agentv/results/<run_id>/<result_dir>/sample-N/grading.json`.
89
90
 
90
- **Important:** The `assertions` array must use the fields `text`, `passed`, and `evidence` downstream tooling depends on these exact field names.
91
+ `checks` and other SDK/script convenience shapes are normalized into recursive
92
+ `component_results`. Do not document `assertions`, `passed`, `graders`, or
93
+ `evidence` as public grading artifact fields.
91
94
 
92
95
  ```json
93
96
  {
94
- "assertions": [
97
+ "pass": false,
98
+ "score": 0.67,
99
+ "reason": "One required spreadsheet check failed.",
100
+ "component_results": [
95
101
  {
96
- "text": "The output includes the name 'John Smith'",
97
- "passed": true,
98
- "evidence": "Found in transcript Step 3: 'Extracted names: John Smith, Sarah Johnson'"
102
+ "name": "name-check",
103
+ "type": "llm-rubric",
104
+ "pass": true,
105
+ "score": 1,
106
+ "reason": "The answer includes the expected name.",
107
+ "assertion": {
108
+ "text": "The output includes the expected name."
109
+ }
99
110
  },
100
111
  {
101
- "text": "The spreadsheet has a SUM formula in cell B10",
102
- "passed": false,
103
- "evidence": "No spreadsheet was created. The output was a text file."
104
- }
105
- ],
106
- "summary": {
107
- "passed": 2,
108
- "failed": 1,
109
- "total": 3,
110
- "pass_rate": 0.67
111
- },
112
- "execution_metrics": {
113
- "tool_calls": {
114
- "Read": 5,
115
- "Write": 2,
116
- "Bash": 8
117
- },
118
- "total_tool_calls": 15,
119
- "total_steps": 6,
120
- "errors_encountered": 0,
121
- "output_chars": 12450,
122
- "transcript_chars": 3200
123
- },
124
- "timing": {
125
- "executor_duration_seconds": 165.0,
126
- "grader_duration_seconds": 26.0,
127
- "total_duration_seconds": 191.0
128
- },
129
- "claims": [
130
- {
131
- "claim": "The form has 12 fillable fields",
132
- "type": "factual",
133
- "verified": true,
134
- "evidence": "Counted 12 fields in field_info.json"
112
+ "name": "spreadsheet-check",
113
+ "type": "script",
114
+ "pass": false,
115
+ "score": 0,
116
+ "reason": "No spreadsheet was created.",
117
+ "component_results": [
118
+ {
119
+ "pass": false,
120
+ "score": 0,
121
+ "reason": "Cell B10 did not contain a SUM formula.",
122
+ "assertion": {
123
+ "text": "Spreadsheet has SUM formula in B10"
124
+ }
125
+ }
126
+ ]
135
127
  }
136
128
  ],
137
- "user_notes_summary": {
138
- "uncertainties": ["Used 2023 data, may be stale"],
139
- "needs_review": [],
140
- "workarounds": ["Fell back to text overlay for non-fillable fields"]
129
+ "named_scores": {
130
+ "spreadsheet": 0
141
131
  },
142
- "eval_feedback": {
143
- "suggestions": [
144
- {
145
- "assertion": "The output includes the name 'John Smith'",
146
- "reason": "A hallucinated document that mentions the name would also pass"
147
- }
148
- ],
149
- "overall": "Assertions check presence but not correctness."
132
+ "metadata": {
133
+ "grader_target": "local-openai-grader"
150
134
  }
151
135
  }
152
136
  ```
153
137
 
154
138
  **Fields:**
155
- - `assertions[]`: Graded assertion results with evidence
156
- - `summary`: Aggregate pass/fail counts
157
- - `execution_metrics`: Tool usage and output size (from executor's metrics.json)
158
- - `timing`: Wall clock timing (from timing.json)
159
- - `claims`: Extracted and verified claims from the output
160
- - `user_notes_summary`: Issues flagged by the executor
161
- - `eval_feedback`: (optional) Improvement suggestions for the evals, only present when the grader identifies issues worth raising
139
+ - `pass`: Aggregate pass/fail for the grading component
140
+ - `score`: Aggregate score from 0 to 1
141
+ - `reason`: Human-readable explanation for the aggregate result
142
+ - `component_results`: Recursive child grading components
143
+ - `assertion`: Optional assertion metadata for a leaf component
144
+ - `named_scores`: Optional metric-name to score map
145
+ - `metadata`: Optional grader/runtime metadata
162
146
 
163
147
  ---
164
148
 
@@ -198,7 +182,7 @@ Output from the executor agent. Located at `<case-dir>/run-N/metrics.json`.
198
182
 
199
183
  ## timing.json
200
184
 
201
- Wall clock timing for a run attempt. Located at `<case-dir>/run-N/timing.json`.
185
+ Wall clock timing for a run sample. Located at `<case-dir>/sample-N/timing.json`.
202
186
 
203
187
  **How to capture:** When a subagent task completes, the task notification includes `total_tokens` and `duration_ms`. Save these immediately — they are not persisted anywhere else and cannot be recovered after the fact.
204
188
 
@@ -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
@@ -51,9 +51,19 @@ For a v4.42.4-era eval:
51
51
  15. Replace authored `preprocessors` and deprecated Promptfoo `postprocess`
52
52
  with `transform` at `default_test.options`, `tests[].options`, or the
53
53
  assertion that needs the shaped output.
54
- 16. Keep raw cases under `tests` / `tests: file://...`; run full eval suites
54
+ 16. Replace `type: skill-trigger` with `skill-used` or `not-skill-used`.
55
+ 17. Replace `type: tool-trajectory` with Promptfoo-compatible `trajectory:*`
56
+ assertions where there is a direct mapping.
57
+ 18. Keep raw cases under `tests` / `tests: file://...`; run full eval suites
55
58
  directly with CLI multi-file selection and tags.
56
- 17. 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>`.
57
67
 
58
68
  ## Assertions Renamed To `assert`
59
69
 
@@ -211,6 +221,101 @@ templates and custom graders can consume it. The breaking authoring change is
211
221
  that workers should not depend on missing `assert` plus `criteria` to define
212
222
  the whole grading contract for new migrated YAML.
213
223
 
224
+ ## `skill-trigger` And `tool-trajectory` Replaced By Promptfoo Assertions
225
+
226
+ ### v4.42.4 Shape
227
+
228
+ Older AgentV YAML used AgentV-specific skill and tool trajectory assertions:
229
+
230
+ ```yaml
231
+ assert:
232
+ - type: skill-trigger
233
+ skill: csv-analyzer
234
+ should_trigger: true
235
+ - type: tool-trajectory
236
+ mode: any_order
237
+ minimums:
238
+ search: 2
239
+ - type: tool-trajectory
240
+ mode: exact
241
+ expected:
242
+ - tool: search
243
+ args:
244
+ q: agentv
245
+ - tool: fetch
246
+ ```
247
+
248
+ ### Current Shape
249
+
250
+ Current authored eval YAML uses Promptfoo-compatible assertions:
251
+
252
+ ```yaml
253
+ assert:
254
+ - type: skill-used
255
+ value: csv-analyzer
256
+ - type: trajectory:tool-used
257
+ value:
258
+ name: search
259
+ min: 2
260
+ - type: trajectory:tool-sequence
261
+ value:
262
+ mode: exact
263
+ steps: [search, fetch]
264
+ - type: trajectory:tool-args-match
265
+ value:
266
+ name: search
267
+ args:
268
+ q: agentv
269
+ mode: partial
270
+ ```
271
+
272
+ ### Migration Steps
273
+
274
+ - Replace `type: skill-trigger`, `skill: X`, `should_trigger: true` with
275
+ `type: skill-used`, `value: X`.
276
+ - Replace `type: skill-trigger`, `skill: X`, `should_trigger: false` with
277
+ `type: not-skill-used`, `value: X`.
278
+ - Replace `type: tool-trajectory`, `mode: any_order`, and `minimums: { Tool: N }`
279
+ with one `trajectory:tool-used` assertion per tool:
280
+
281
+ ```yaml
282
+ - type: trajectory:tool-used
283
+ value:
284
+ name: Tool
285
+ min: N
286
+ ```
287
+
288
+ - Replace `mode: in_order` or `mode: exact` plus `expected` tool steps with
289
+ `trajectory:tool-sequence`:
290
+
291
+ ```yaml
292
+ - type: trajectory:tool-sequence
293
+ value:
294
+ mode: exact
295
+ steps: [search, fetch]
296
+ ```
297
+
298
+ - Move old `expected[].args` checks to `trajectory:tool-args-match`. Use
299
+ `mode: exact` only for exact argument equality; otherwise use Promptfoo's
300
+ partial argument matching.
301
+ - Do not carry old `max_duration_ms` per-tool latency checks under
302
+ `trajectory:*`. There is no Promptfoo-compatible equivalent in AgentV yet;
303
+ use a `script` assertion or track the behavior as future scope.
304
+
305
+ ### Verification
306
+
307
+ ```bash
308
+ bun apps/cli/src/cli.ts validate path/to/eval.eval.yaml
309
+ rg -n "skill-trigger|tool-trajectory" path/to/evals path/to/.agentv/templates
310
+ ```
311
+
312
+ ### Compatibility Notes
313
+
314
+ The runtime still has private compatibility classes and tests for older
315
+ helpers. That does not make `skill-trigger` or `tool-trajectory` valid authored
316
+ eval YAML. Normal Promptfoo-aligned eval files fail validation and parsing with
317
+ the replacement guidance above.
318
+
214
319
  ## Authored `input` Moved To `prompts` Plus Vars
215
320
 
216
321
  ### v4.42.4 Shape
@@ -746,42 +851,50 @@ targets:
746
851
  ### Current Shape
747
852
 
748
853
  Current eval YAML uses top-level `target` or `targets`. Target references use
749
- `label`; `id` is reserved for provider/backend identity when needed:
854
+ the target `id`; `provider` names the backend or adapter kind:
750
855
 
751
856
  ```yaml
752
857
  target: azure-base
753
858
 
754
859
  targets:
755
- - label: with-skills
756
- use_target: default
860
+ - id: with-skills
861
+ provider: codex-cli
862
+ runtime: host
863
+ config:
864
+ command: ["codex", "exec", "--json"]
757
865
  hooks:
758
866
  before_each:
759
867
  command: ["setup-plugins.sh", "skills"]
760
868
  ```
761
869
 
762
- Current `.agentv/targets.yaml` uses `label` and nests provider settings under
870
+ Current `.agentv/targets.yaml` uses `id` and nests provider settings under
763
871
  `config`:
764
872
 
765
873
  ```yaml
766
874
  targets:
767
- - label: azure-base
875
+ - id: azure-base
768
876
  provider: azure
877
+ runtime: host
769
878
  config:
770
- endpoint: ${{ AZURE_OPENAI_ENDPOINT }}
771
- api_key: ${{ AZURE_OPENAI_API_KEY }}
772
- model: ${{ AZURE_DEPLOYMENT_NAME }}
879
+ endpoint: "{{ env.AZURE_OPENAI_ENDPOINT }}"
880
+ api_key: "{{ env.AZURE_OPENAI_API_KEY }}"
881
+ model: "{{ env.AZURE_DEPLOYMENT_NAME }}"
773
882
  ```
774
883
 
775
884
  ### Migration Steps
776
885
 
777
886
  - Eval YAML: `execution.target` -> top-level `target`.
778
887
  - Eval YAML: `execution.targets` -> top-level `targets`.
779
- - Eval target object `name` -> `label`.
780
- - If an eval-local target object has provider configuration, include a
781
- `label`; use `extends` to derive from a base target.
782
- - Targets file: rename `name` to `label` and move provider-specific settings
783
- into `config`.
784
- - 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`,
785
898
  `fallback_targets`, `workers`, and `batch_requests` as top-level fields on
786
899
  target objects.
787
900
 
@@ -790,10 +903,12 @@ targets:
790
903
  ```bash
791
904
  bun apps/cli/src/cli.ts validate path/to/eval.eval.yaml
792
905
  bun apps/cli/src/cli.ts validate .agentv/targets.yaml
793
- 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
794
907
  ```
795
908
 
796
- 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.
797
912
 
798
913
  ### Compatibility Notes
799
914
 
@@ -984,9 +1099,10 @@ rg -n "include:|tests:" path/to/evals
984
1099
 
985
1100
  ### Compatibility Notes
986
1101
 
987
- `eval_cases` remains a deprecated alias in the current schema, but migrated
988
- YAML should use `tests`. The current convention is that runnable suites use
989
- `*.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.
990
1106
 
991
1107
  ## Result Artifact Path Changes Are Not Eval YAML Migrations
992
1108