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
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>AgentV</title>
7
- <script type="module" crossorigin src="/assets/index-r_jSJmlw.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-DTA6-l7q.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-D_bokML8.css">
9
9
  </head>
10
10
  <body class="bg-gray-950 text-gray-100">
@@ -26,6 +26,7 @@ import {
26
26
  getResultsRepoSyncStatus,
27
27
  listGitRuns,
28
28
  listGitRunsCached,
29
+ loadEnvPathFiles,
29
30
  loadTsConfig,
30
31
  materializeGitRun,
31
32
  normalizeResultsConfig,
@@ -34,6 +35,8 @@ import {
34
35
  parseCodexSession,
35
36
  parseCopilotEvents,
36
37
  parseEnvOutput,
38
+ parseJsonEnv,
39
+ parseShellExportsEnv,
37
40
  prepareEvalWorkspace,
38
41
  prepareResultsRepoBranch,
39
42
  pushResultsRepoBranch,
@@ -44,6 +47,7 @@ import {
44
47
  resolveResultsRepoRunsDir,
45
48
  resolveResultsRepoUrl,
46
49
  runBeforeSessionHook,
50
+ runEnvFromEntries,
47
51
  setupWipWorktree,
48
52
  stageResultsArtifacts,
49
53
  syncProject,
@@ -54,7 +58,7 @@ import {
54
58
  transpileEvalYaml,
55
59
  transpileEvalYamlFile,
56
60
  trimBaselineResult
57
- } from "./chunk-V52ATPTT.js";
61
+ } from "./chunk-LXBI3SPX.js";
58
62
  import {
59
63
  AGENTV_CONFIG_FILE_NAME,
60
64
  AGENTV_CONFIG_YML_FILE_NAME,
@@ -219,7 +223,7 @@ import {
219
223
  extractFailOnError,
220
224
  extractImageBlocks,
221
225
  extractJsonBlob,
222
- extractLastAssistantContent,
226
+ extractLastAssistantContent2,
223
227
  extractTargetFromSuite,
224
228
  extractTargetRefsFromSuite,
225
229
  extractTargetsFromSuite,
@@ -266,6 +270,7 @@ import {
266
270
  isPlainConfigObject,
267
271
  isTestMessage,
268
272
  isTestMessageRole,
273
+ isTypeScriptEvalConfigFileName,
269
274
  killAllTrackedChildren,
270
275
  listTargetNames,
271
276
  loadConfig,
@@ -373,11 +378,12 @@ import {
373
378
  trackChild,
374
379
  trackedChildCount,
375
380
  transcriptReplayRecordToProviderResponse,
381
+ typeScriptEvalConfigGlob,
376
382
  writeArtifacts,
377
383
  writeArtifactsFromResults,
378
384
  writeInitialRunSummaryArtifact,
379
385
  writePerTestArtifacts
380
- } from "./chunk-6ZZCDZPD.js";
386
+ } from "./chunk-ELCJ23K4.js";
381
387
  import "./chunk-7BGERE6L.js";
382
388
  import {
383
389
  DockerWorkspaceProvider
@@ -568,7 +574,7 @@ export {
568
574
  extractFailOnError,
569
575
  extractImageBlocks,
570
576
  extractJsonBlob,
571
- extractLastAssistantContent,
577
+ extractLastAssistantContent2 as extractLastAssistantContent,
572
578
  extractTargetFromSuite,
573
579
  extractTargetRefsFromSuite,
574
580
  extractTargetsFromSuite,
@@ -620,11 +626,13 @@ export {
620
626
  isPlainConfigObject,
621
627
  isTestMessage,
622
628
  isTestMessageRole,
629
+ isTypeScriptEvalConfigFileName,
623
630
  killAllTrackedChildren,
624
631
  listGitRuns,
625
632
  listGitRunsCached,
626
633
  listTargetNames,
627
634
  loadConfig,
635
+ loadEnvPathFiles,
628
636
  loadEvalCaseById,
629
637
  loadEvalCases,
630
638
  loadEvalSuite,
@@ -654,9 +662,11 @@ export {
654
662
  parseCopilotEvents,
655
663
  parseEnvOutput,
656
664
  parseEvaluationResultBoundary,
665
+ parseJsonEnv,
657
666
  parseJsonFromText,
658
667
  parseJsonSafe,
659
668
  parseJsonlResults,
669
+ parseShellExportsEnv,
660
670
  parseTraceBoundary,
661
671
  parseTraceSummaryBoundary,
662
672
  parseYamlValue,
@@ -695,6 +705,7 @@ export {
695
705
  runContainsAnyAssertion,
696
706
  runContainsAssertion,
697
707
  runEndsWithAssertion,
708
+ runEnvFromEntries,
698
709
  runEqualsAssertion,
699
710
  runEvalCase,
700
711
  runEvaluation,
@@ -757,9 +768,10 @@ export {
757
768
  transpileEvalYaml,
758
769
  transpileEvalYamlFile,
759
770
  trimBaselineResult,
771
+ typeScriptEvalConfigGlob,
760
772
  writeArtifacts,
761
773
  writeArtifactsFromResults,
762
774
  writeInitialRunSummaryArtifact,
763
775
  writePerTestArtifacts
764
776
  };
765
- //# sourceMappingURL=dist-6Z7U473R.js.map
777
+ //# sourceMappingURL=dist-NMXMI5SK.js.map
package/dist/index.js CHANGED
@@ -6,11 +6,11 @@ import {
6
6
  runCli,
7
7
  shouldRunBeforeSessionHook,
8
8
  usesDeprecatedStudioAlias
9
- } from "./chunk-T32NL3E6.js";
10
- import "./chunk-FVR4RQFK.js";
11
- import "./chunk-BHKQHG26.js";
12
- import "./chunk-V52ATPTT.js";
13
- import "./chunk-6ZZCDZPD.js";
9
+ } from "./chunk-ASIGJIOJ.js";
10
+ import "./chunk-LKGARI3W.js";
11
+ import "./chunk-RKE7SSET.js";
12
+ import "./chunk-LXBI3SPX.js";
13
+ import "./chunk-ELCJ23K4.js";
14
14
  import "./chunk-7BGERE6L.js";
15
15
  import "./chunk-PEUTJS7B.js";
16
16
  import "./chunk-M7BUKBAF.js";
@@ -8,14 +8,14 @@ import {
8
8
  getCategories,
9
9
  resolveExistingRunPrimaryPath,
10
10
  runEvalCommand
11
- } from "./chunk-FVR4RQFK.js";
12
- import "./chunk-BHKQHG26.js";
13
- import "./chunk-V52ATPTT.js";
11
+ } from "./chunk-LKGARI3W.js";
12
+ import "./chunk-RKE7SSET.js";
13
+ import "./chunk-LXBI3SPX.js";
14
14
  import {
15
15
  getAgentvConfigDir,
16
16
  listTargetNames,
17
17
  readTargetDefinitions
18
- } from "./chunk-6ZZCDZPD.js";
18
+ } from "./chunk-ELCJ23K4.js";
19
19
  import "./chunk-7BGERE6L.js";
20
20
  import "./chunk-PEUTJS7B.js";
21
21
  import "./chunk-M7BUKBAF.js";
@@ -344,4 +344,4 @@ ${ANSI_DIM}Retrying execution errors...${ANSI_RESET}
344
344
  export {
345
345
  launchInteractiveWizard
346
346
  };
347
- //# sourceMappingURL=interactive-RUY3OCBI.js.map
347
+ //# sourceMappingURL=interactive-BN527UV3.js.map
@@ -49,7 +49,7 @@ Before running or optimizing, understand what you're working with.
49
49
 
50
50
  2. **Identify success criteria** — what does "good" look like for this agent? What are the edge cases? What would a failure look like? Talk to the user if this isn't clear from the artifacts alone.
51
51
 
52
- 3. **Understand the target harness** — which provider runs the agent (Claude, GPT, Copilot CLI, Gemini, custom CLI)? This affects what grader types are available and how to run tests. Targets are configured in `.agentv/targets.yaml` (canonical location, searched from the eval file directory upward). Sensitive values like `api_key` must use `${{ ENV_VAR }}` syntax — literal secrets are rejected as a security guardrail.
52
+ 3. **Understand the target harness** — which provider runs the agent (Claude, GPT, Copilot CLI, Gemini, custom CLI)? This affects what grader types are available and how to run tests. Targets are configured in `.agentv/targets.yaml` (canonical location, searched from the eval file directory upward). Sensitive values like `api_key` must use `{{ env.ENV_VAR }}` references — literal secrets are rejected as a security guardrail.
53
53
 
54
54
  4. **Challenge assumptions** — if evals already exist, review their quality before running:
55
55
  - Are the test cases testing the right things?
@@ -65,7 +65,7 @@ Before running or optimizing, understand what you're working with.
65
65
 
66
66
  AgentV supports two evaluation formats:
67
67
 
68
- **EVAL.yaml** (native, full features) — supports environment recipes, script graders, multi-turn conversations, tool trajectory scoring, workspace file tracking, and multi-provider targets. Use this for agent evaluation.
68
+ **EVAL.yaml** (native, full features) — supports prompt matrices, environment recipes, script graders, multi-turn conversations, tool trajectory scoring, workspace file tracking, and multi-provider targets. Use this for agent evaluation.
69
69
 
70
70
  ```yaml
71
71
  # example.eval.yaml
@@ -89,7 +89,7 @@ tests:
89
89
  - Review identifies the null pointer bug and suggests a concrete fix
90
90
  ```
91
91
 
92
- Multi-skill evaluation is handled naturally via input messages — describe the task in the test input, and the agent uses whatever skills it needs.
92
+ Multi-skill evaluation is handled naturally via prompt messages — describe the task in `prompts`, put row-specific data in `tests[].vars`, and the agent uses whatever skills it needs.
93
93
 
94
94
  **evals.json** (skill-creator compatible) — auto-promoted to EVAL-equivalent format:
95
95
  - `prompt` → input messages
@@ -127,7 +127,7 @@ Prefer deterministic graders over LLM graders whenever possible. If an assertion
127
127
 
128
128
  This section is one continuous sequence — don't stop partway through.
129
129
 
130
- Each run produces a new `.agentv/results/default/<timestamp>/` directory automatically. Use timestamps to identify iterations when comparing runs.
130
+ Each run produces a new canonical `.agentv/results/<run_id>/` directory automatically. Use the printed run id and `.internal/index.jsonl` when comparing runs.
131
131
 
132
132
  ### Choosing a run mode
133
133
 
@@ -228,11 +228,11 @@ Each grader subagent (operating under `agents/grader.md` instructions):
228
228
  2. Reads `<test-id>/response.md` for the candidate output
229
229
  3. Grades the response against the prompt criteria
230
230
  4. **Writes its result to disk**: `<run-dir>/<evalset>/<test-id>/llm_grader_results/<name>.json`
231
- 5. Returns score (0.0–1.0) and per-assertion evidence to the orchestrator
231
+ 5. Returns score (0.0–1.0) and per-assertion notes to the orchestrator
232
232
 
233
- **Writing to disk is critical.** Assertion arrays are lost if accumulated only in the orchestrator's context across multiple batches (context summarization drops detail). Writing per-test results to `llm_grader_results/<name>.json` makes grading resumable and assertion evidence durable.
233
+ **Writing to disk is critical.** Intermediate assertion arrays are lost if accumulated only in the orchestrator's context across multiple batches (context summarization drops detail). Writing per-test results to `llm_grader_results/<name>.json` makes grading resumable. Public `grading.json` artifacts normalize these details into recursive `component_results`.
234
234
 
235
- The result file format is:
235
+ The intermediate subagent result file format is:
236
236
  ```json
237
237
  { "score": 0.85, "assertions": [{"text": "...", "passed": true, "evidence": "..."}] }
238
238
  ```
@@ -246,18 +246,19 @@ agentv pipeline bench <run-dir>
246
246
  agentv results validate <run-dir>
247
247
  ```
248
248
 
249
- `pipeline bench` reads LLM grader results from `llm_grader_results/<name>.json` per test automatically, merges with script-grader scores, computes weighted pass_rate, and writes `grading.json` + `index.jsonl` + `summary.json`.
249
+ `pipeline bench` reads LLM grader results from `llm_grader_results/<name>.json` per test automatically, merges with script-grader scores, computes aggregate scores, and writes the canonical run bundle with `.internal/index.jsonl`, `summary.json`, and per-attempt `grading.json`.
250
250
 
251
251
  > **Diagnosing `pass_rate=0`:** If `pipeline bench` reports `pass_rate=0` across the board, do **not** assume the tests genuinely failed. First verify the grading pipeline ran correctly: check that `<test-id>/llm_grader_results/<name>.json` exists and is non-empty for each test. If these files are absent or empty, the grader subagents failed to produce output (most common cause: `agents/grader.md` was not embedded in the subagent prompts — see Phase 2). Treat `pass_rate=0` as a real signal only after confirming grader results exist.
252
252
 
253
253
  ### Artifacts
254
254
 
255
255
  All artifacts use established schemas — see `references/schemas.md` for the full definitions. Do not modify the structure. Key artifacts per run:
256
- - **grading.json**: per-test assertions with `{text, passed, evidence}`, plus summary
257
- - **timing.json**: `{total_tokens, duration_ms, total_duration_seconds}`
258
- - **summary.json**: per-target aggregate `{pass_rate, time_seconds, tokens}`
256
+ - **.internal/index.jsonl**: canonical row index for compare, Dashboard, rerun, and artifact discovery
257
+ - **grading.json**: aggregate `pass`, `score`, `reason`, recursive `component_results`, and optional `assertion`, `named_scores`, and `metadata`
258
+ - **metrics.json**: token, cost, timing, tool, and transcript metrics for the attempt
259
+ - **summary.json**: run-level aggregate metadata and pass/score rollups
259
260
 
260
- Write artifacts to `.agentv/artifacts/` or the iteration directory.
261
+ Write artifacts to `.agentv/results/<run_id>/` through the CLI unless a task explicitly needs a fixed output path.
261
262
 
262
263
  ### Environment features (EVAL.yaml only)
263
264
 
@@ -350,7 +351,7 @@ If a prompt file is referenced in both task input and grader configs, optimize f
350
351
  After improving:
351
352
 
352
353
  1. Apply your changes to the agent's prompts/skills/config
353
- 2. Re-run all test cases (agentv creates a new `.agentv/results/default/<timestamp>/` directory automatically)
354
+ 2. Re-run all test cases (agentv creates a new `.agentv/results/<run_id>/` directory automatically)
354
355
  3. Compare against the previous iteration (Step 4). If running in automated mode, use the **automated keep/discard** logic below instead of manual judgment — it will decide whether to keep or revert the change for you.
355
356
  4. Present results to the user (or log the decision if running automated keep/discard)
356
357
  5. Stop when ANY of:
@@ -22,7 +22,7 @@ You are an eval-quality analyst for AgentV. Your job is to read JSONL evaluation
22
22
 
23
23
  Read every line of the JSONL results file. Each line is a JSON object with:
24
24
  - `test_id`, `suite`, `score`, `assertions`, `reasoning`, `target`
25
- - `scores` (optional): Array of per-grader breakdowns with `name`, `type`, `score`, `weight`, `verdict`, `assertions`, `reasoning`
25
+ - `scores` (optional): Array of per-grader breakdowns with `name`, `type`, `score`, `weight`, `pass`, `assertions`, `reasoning`
26
26
 
27
27
  If `eval-path` is provided, also read the EVAL.yaml to understand grader configurations.
28
28
 
@@ -14,7 +14,7 @@ You are the executor for an AgentV evaluation test case. Your job is to **perfor
14
14
  You are the target agent being evaluated. Do the task to the best of your ability — your output will be graded by a separate grader agent.
15
15
 
16
16
  **You will receive these parameters:**
17
- - `test-dir`: Path to the test case directory (e.g., `.agentv/results/default/<timestamp>/<test-id>/`)
17
+ - `test-dir`: Path to the prepared test case directory inside the run bundle (for example `.agentv/results/<run_id>/<result-dir>/`)
18
18
 
19
19
  ## Process
20
20
 
@@ -56,14 +56,14 @@ Before proceeding to the next iteration, log the decision and rationale so the u
56
56
  Iteration 2: KEEP
57
57
  wins=3, losses=1, ties=6, meanDelta=+0.05
58
58
  Rationale: candidate wins outweigh losses (3 > 1)
59
- Baseline promoted: .agentv/results/default/20250101-120000/index.jsonl
59
+ Baseline promoted: .agentv/results/2025-01-01T12-00-00-000Z/.internal/index.jsonl
60
60
  ```
61
61
 
62
62
  ```
63
63
  Iteration 3: DISCARD
64
64
  wins=1, losses=2, ties=7, meanDelta=-0.03
65
65
  Rationale: candidate losses outweigh wins (2 > 1)
66
- Reverted to baseline: .agentv/results/default/20250101-110000/index.jsonl
66
+ Reverted to baseline: .agentv/results/2025-01-01T11-00-00-000Z/.internal/index.jsonl
67
67
  Next: try a different mutation
68
68
  ```
69
69
 
@@ -210,20 +210,20 @@ agentv eval <eval-path> --experiment autoresearch-<name>
210
210
 
211
211
  **b. Extract scores (bash only — do NOT read result files into your context)**
212
212
 
213
- Find the latest timestamped directory in the experiment folder. Use bash/jq to extract small structured values:
213
+ Find the latest run directory. Use bash/jq to extract small structured values:
214
214
 
215
215
  ```bash
216
216
  # Find latest run dir
217
- RUN_DIR=$(ls -td <experiment-dir>/20*/ | head -1)
217
+ RUN_DIR=$(ls -td .agentv/results/20*/ | head -1)
218
218
 
219
219
  # Overall score (mean of all scores in index.jsonl)
220
- SCORE=$(jq -sr '[.[].scores[].score] | add / length' "$RUN_DIR/index.jsonl")
220
+ SCORE=$(jq -sr '[.[].score] | add / length' "$RUN_DIR/.internal/index.jsonl")
221
221
 
222
- # Per-assertion pass rates as JSON object
223
- PASS_RATES=$(jq -sr '[.[].scores[]] | group_by(.type) | map({key: .[0].type, value: (map(.score) | add / length)}) | from_entries' "$RUN_DIR/index.jsonl")
222
+ # Per-target mean scores as JSON object
223
+ TARGET_SCORES=$(jq -sr 'group_by(.target) | map({key: .[0].target, value: (map(.score) | add / length)}) | from_entries' "$RUN_DIR/.internal/index.jsonl")
224
224
 
225
- # Cost (if timing.json exists)
226
- COST=$(jq -r '.cost_usd // 0' "$RUN_DIR/timing.json" 2>/dev/null || echo 0)
225
+ # Cost (if present in summary.json)
226
+ COST=$(jq -r '.cost_usd // .total_cost_usd // 0' "$RUN_DIR/summary.json" 2>/dev/null || echo 0)
227
227
  ```
228
228
 
229
229
  Capture only these small outputs (`SCORE`, `PASS_RATES`, `COST`) — never read the full JSONL into context.
@@ -21,7 +21,7 @@ for each test case, show the prompt and output. Ask for feedback inline. Skip be
21
21
  - **Codex**: Supports skills via `.agents/` or `.codex/` folders. Emits `command_execution`
22
22
  and `file_change` tool calls.
23
23
  - **Custom CLI**: Needs `command` and output file pattern in target config
24
- - **Target config**: Uses `${{ ENV_VAR }}` syntax (not `${ENV_VAR}`) for API keys
24
+ - **Target config**: Uses `{{ env.ENV_VAR }}` references for API keys
25
25
 
26
26
  **Note**: "Description Optimization" (see `references/description-optimization.md`) applies
27
27
  to any platform with skill-discovery mechanisms. All listed providers support skills.
@@ -39,15 +39,15 @@ tool calls; reserve `output` for final-answer text checks.
39
39
  ```yaml
40
40
  # Example: script-grader for Codex skill-use detection
41
41
  tests:
42
- - id: should-trigger-codex
42
+ - id: codex-skill-use
43
43
  input: "Analyze this CSV file"
44
44
  assert:
45
45
  - type: script
46
- command: [bun, run, ./judges/codex-skill-trigger.ts]
46
+ command: [bun, run, ./judges/codex-skill-use.ts]
47
47
  ```
48
48
 
49
49
  ```typescript
50
- // judges/codex-skill-trigger.ts
50
+ // judges/codex-skill-use.ts
51
51
  import { defineScriptGrader } from '@agentv/sdk';
52
52
 
53
53
  export default defineScriptGrader(({ messages }) => {
@@ -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
@@ -211,18 +212,20 @@ Same as contains variants but explicitly case-insensitive.
211
212
 
212
213
  ### Script-based assertions
213
214
 
214
- #### `script-grader`
215
+ #### `script`
215
216
 
216
- - **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`
217
218
  - **Script SDK:** Use `defineScriptGrader` from `@agentv/sdk`:
218
219
  ```typescript
219
220
  import { defineScriptGrader } from '@agentv/sdk';
220
221
  export default defineScriptGrader(({ output, trace }) => ({
222
+ pass: (output ?? '').includes('expected'),
221
223
  score: (output ?? '').includes('expected') ? 1 : 0,
222
- 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' }],
223
226
  }));
224
227
  ```
225
- - **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`.
226
229
  - **PASS:** score >= 0.5 (or as configured).
227
230
 
228
231
  ### Assertion groups
@@ -252,42 +255,22 @@ All assertion types support:
252
255
  - `negate` (boolean, optional) — invert result
253
256
  - `threshold` (number, optional) — minimum score to pass (for LLM types)
254
257
 
255
- ## 5. AgentV JSONL Output Format
258
+ ## 5. AgentV Run Bundle Output
256
259
 
257
- Each line in the results JSONL file is an `EvaluationResult` object. In JSONL, field names use snake_case (applied by `toSnakeCaseDeep()`).
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.
258
263
 
259
- ### Required fields
264
+ Key artifacts:
260
265
 
261
- - `timestamp` (string, ISO-8601)
262
- - `test_id` (string)
263
- - `score` (number, 0.0-1.0, weighted average of all assertion scores)
264
- - `assertions` (array of `{text, passed, evidence?}`)
265
- - `output` (string) final answer/scored result; transcript evidence is available through captured trace/messages when present
266
- - `execution_status` (string: `ok` | `quality_failure` | `execution_error`)
267
-
268
- ### Optional fields
269
-
270
- - `scores` (array of EvaluatorResult) — per-grader breakdown
271
- - `input` (Message[]) — input messages
272
- - `token_usage` (object: `{prompt_tokens, completion_tokens, total_tokens}`)
273
- - `cost_usd` (number)
274
- - `duration_ms` (number)
275
- - `target` (string)
276
- - `eval_set` (string)
277
- - `error` (string)
278
- - `file_changes` (string — unified diff)
279
- - `mode` (string — `agent` for agent mode)
280
-
281
- ### `scores[]` entries (EvaluatorResult)
282
-
283
- - `name` (string) — grader name
284
- - `type` (string) — grader kind (kebab-case)
285
- - `score` (number, 0.0-1.0)
286
- - `assertions` (array of `{text, passed, evidence?}`)
287
- - `weight` (number, optional)
288
- - `verdict` (string: `pass` | `fail` | `skip`)
289
- - `details` (object, optional — structured data from script graders)
290
- - `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.
291
274
 
292
275
  ## 6. Eval Set Support
293
276
 
@@ -366,9 +349,9 @@ LLM grader results are read from disk at `<test-id>/llm_grader_results/<name>.js
366
349
  ```
367
350
 
368
351
  **Output:**
369
- - `<test-id>/run-1/grading.json` — merged grading with `graders`, `assertions`, `summary.pass_rate`
370
- - `index.jsonl` — one JSON line per test: `{test_id, score, pass, graders: [...]}`
371
- - `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`
372
355
 
373
356
  ### Agent-Mode Workflow
374
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