agentv 5.1.0-next.1 → 5.2.0-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 (38) hide show
  1. package/README.md +16 -12
  2. package/dist/{artifact-writer-IORG7CW5.js → artifact-writer-SN6UNL5G.js} +5 -5
  3. package/dist/{chunk-ZGPCX334.js → chunk-3S6A2RKR.js} +2803 -959
  4. package/dist/chunk-3S6A2RKR.js.map +1 -0
  5. package/dist/{chunk-GIRUNQGP.js → chunk-3X357HS4.js} +205 -153
  6. package/dist/chunk-3X357HS4.js.map +1 -0
  7. package/dist/{chunk-CBBBRTQ3.js → chunk-46K2OET3.js} +64 -3
  8. package/dist/chunk-46K2OET3.js.map +1 -0
  9. package/dist/{chunk-GJWPQXHN.js → chunk-ALVZQUZP.js} +104 -188
  10. package/dist/chunk-ALVZQUZP.js.map +1 -0
  11. package/dist/{chunk-AM2IPHKS.js → chunk-T4AD3H3Y.js} +236 -154
  12. package/dist/chunk-T4AD3H3Y.js.map +1 -0
  13. package/dist/cli.js +6 -6
  14. package/dist/dashboard/assets/{index-BSHoWrdr.js → index-DNgf3qJ2.js} +1 -1
  15. package/dist/dashboard/assets/{index-zvUKAkKn.css → index-D_bokML8.css} +1 -1
  16. package/dist/dashboard/assets/index-r_jSJmlw.js +121 -0
  17. package/dist/dashboard/index.html +2 -2
  18. package/dist/{dist-2D2GBHZV.js → dist-DEPJOMCA.js} +6 -8
  19. package/dist/index.js +6 -6
  20. package/dist/{interactive-V4SEHLNY.js → interactive-36ZNMQB2.js} +6 -6
  21. package/dist/skills/agentv-bench/SKILL.md +16 -12
  22. package/dist/skills/agentv-bench/references/eval-yaml-spec.md +15 -10
  23. package/dist/skills/agentv-bench/references/migrating-from-skill-creator.md +1 -1
  24. package/dist/skills/agentv-eval-migrations/references/breaking-changes.md +26 -27
  25. package/dist/skills/agentv-eval-writer/SKILL.md +86 -71
  26. package/dist/skills/agentv-eval-writer/references/eval.schema.json +772 -1367
  27. package/dist/{ts-eval-loader-SSPJVEHD-AL2A3V5Z.js → ts-eval-loader-OMG2JBHP-OP5RR7A3.js} +3 -2
  28. package/package.json +8 -2
  29. package/dist/chunk-AM2IPHKS.js.map +0 -1
  30. package/dist/chunk-CBBBRTQ3.js.map +0 -1
  31. package/dist/chunk-GIRUNQGP.js.map +0 -1
  32. package/dist/chunk-GJWPQXHN.js.map +0 -1
  33. package/dist/chunk-ZGPCX334.js.map +0 -1
  34. package/dist/dashboard/assets/index-BaLLxmVO.js +0 -121
  35. /package/dist/{artifact-writer-IORG7CW5.js.map → artifact-writer-SN6UNL5G.js.map} +0 -0
  36. /package/dist/{dist-2D2GBHZV.js.map → dist-DEPJOMCA.js.map} +0 -0
  37. /package/dist/{interactive-V4SEHLNY.js.map → interactive-36ZNMQB2.js.map} +0 -0
  38. /package/dist/{ts-eval-loader-SSPJVEHD-AL2A3V5Z.js.map → ts-eval-loader-OMG2JBHP-OP5RR7A3.js.map} +0 -0
@@ -4,8 +4,8 @@
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-BaLLxmVO.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-zvUKAkKn.css">
7
+ <script type="module" crossorigin src="/assets/index-r_jSJmlw.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-D_bokML8.css">
9
9
  </head>
10
10
  <body class="bg-gray-950 text-gray-100">
11
11
  <div id="root"></div>
@@ -44,7 +44,6 @@ import {
44
44
  resolveResultsRepoRunsDir,
45
45
  resolveResultsRepoUrl,
46
46
  runBeforeSessionHook,
47
- scanRepoDeps,
48
47
  setupWipWorktree,
49
48
  stageResultsArtifacts,
50
49
  syncProject,
@@ -55,10 +54,7 @@ import {
55
54
  transpileEvalYaml,
56
55
  transpileEvalYamlFile,
57
56
  trimBaselineResult
58
- } from "./chunk-GJWPQXHN.js";
59
- import {
60
- DockerWorkspaceProvider
61
- } from "./chunk-PEUTJS7B.js";
57
+ } from "./chunk-ALVZQUZP.js";
62
58
  import {
63
59
  AGENTV_CONFIG_FILE_NAME,
64
60
  AGENTV_CONFIG_YML_FILE_NAME,
@@ -377,8 +373,11 @@ import {
377
373
  writeArtifactsFromResults,
378
374
  writeInitialRunSummaryArtifact,
379
375
  writePerTestArtifacts
380
- } from "./chunk-ZGPCX334.js";
376
+ } from "./chunk-3S6A2RKR.js";
381
377
  import "./chunk-7BGERE6L.js";
378
+ import {
379
+ DockerWorkspaceProvider
380
+ } from "./chunk-PEUTJS7B.js";
382
381
  import "./chunk-M7BUKBAF.js";
383
382
  import "./chunk-QMRVH5ZP.js";
384
383
  export {
@@ -700,7 +699,6 @@ export {
700
699
  sameReplayEvalPath,
701
700
  sanitizeExternalTraceMetadata,
702
701
  saveProjectRegistry,
703
- scanRepoDeps,
704
702
  scoreRangeEvaluationSchema,
705
703
  scoreToVerdict,
706
704
  serializeEvaluationResultWire,
@@ -756,4 +754,4 @@ export {
756
754
  writeInitialRunSummaryArtifact,
757
755
  writePerTestArtifacts
758
756
  };
759
- //# sourceMappingURL=dist-2D2GBHZV.js.map
757
+ //# sourceMappingURL=dist-DEPJOMCA.js.map
package/dist/index.js CHANGED
@@ -6,13 +6,13 @@ import {
6
6
  runCli,
7
7
  shouldRunBeforeSessionHook,
8
8
  usesDeprecatedStudioAlias
9
- } from "./chunk-GIRUNQGP.js";
10
- import "./chunk-AM2IPHKS.js";
11
- import "./chunk-CBBBRTQ3.js";
12
- import "./chunk-GJWPQXHN.js";
13
- import "./chunk-PEUTJS7B.js";
14
- import "./chunk-ZGPCX334.js";
9
+ } from "./chunk-3X357HS4.js";
10
+ import "./chunk-T4AD3H3Y.js";
11
+ import "./chunk-46K2OET3.js";
12
+ import "./chunk-ALVZQUZP.js";
13
+ import "./chunk-3S6A2RKR.js";
15
14
  import "./chunk-7BGERE6L.js";
15
+ import "./chunk-PEUTJS7B.js";
16
16
  import "./chunk-M7BUKBAF.js";
17
17
  import "./chunk-QMRVH5ZP.js";
18
18
  export {
@@ -8,16 +8,16 @@ import {
8
8
  getCategories,
9
9
  resolveExistingRunPrimaryPath,
10
10
  runEvalCommand
11
- } from "./chunk-AM2IPHKS.js";
12
- import "./chunk-CBBBRTQ3.js";
13
- import "./chunk-GJWPQXHN.js";
14
- import "./chunk-PEUTJS7B.js";
11
+ } from "./chunk-T4AD3H3Y.js";
12
+ import "./chunk-46K2OET3.js";
13
+ import "./chunk-ALVZQUZP.js";
15
14
  import {
16
15
  getAgentvConfigDir,
17
16
  listTargetNames,
18
17
  readTargetDefinitions
19
- } from "./chunk-ZGPCX334.js";
18
+ } from "./chunk-3S6A2RKR.js";
20
19
  import "./chunk-7BGERE6L.js";
20
+ import "./chunk-PEUTJS7B.js";
21
21
  import "./chunk-M7BUKBAF.js";
22
22
  import "./chunk-QMRVH5ZP.js";
23
23
 
@@ -344,4 +344,4 @@ ${ANSI_DIM}Retrying execution errors...${ANSI_RESET}
344
344
  export {
345
345
  launchInteractiveWizard
346
346
  };
347
- //# sourceMappingURL=interactive-V4SEHLNY.js.map
347
+ //# sourceMappingURL=interactive-36ZNMQB2.js.map
@@ -65,24 +65,28 @@ 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 workspaces, script graders, multi-turn conversations, tool trajectory scoring, workspace file tracking, multi-provider targets. Use this for agent evaluation.
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.
69
69
 
70
70
  ```yaml
71
71
  # example.eval.yaml
72
+ prompts:
73
+ - "{{ task }}"
74
+
75
+ environment:
76
+ type: host
77
+ workdir: ./workspace-template
78
+ setup:
79
+ command: ["bash", "-lc", "bun install && bun run build"]
80
+ cwd: "."
81
+
72
82
  tests:
73
83
  - id: basic-code-review
74
- input: "Review this TypeScript file for bugs and suggest improvements"
75
- criteria: "Identifies the null pointer bug on line 12 and suggests a fix"
84
+ vars:
85
+ task: "Review this TypeScript file for bugs and suggest improvements"
76
86
  assert:
77
87
  - type: contains
78
88
  value: "null"
79
89
  - Review identifies the null pointer bug and suggests a concrete fix
80
-
81
- workspace:
82
- template: ./workspace-template
83
- hooks:
84
- before_each:
85
- reset: fast
86
90
  ```
87
91
 
88
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.
@@ -255,11 +259,11 @@ All artifacts use established schemas — see `references/schemas.md` for the fu
255
259
 
256
260
  Write artifacts to `.agentv/artifacts/` or the iteration directory.
257
261
 
258
- ### Workspace features (EVAL.yaml only)
262
+ ### Environment features (EVAL.yaml only)
259
263
 
260
- - **Workspace scope** — clone repos, run setup/teardown hooks (before_all, before_each, after_each, after_all), and choose `suite` or `attempt` lifetime
264
+ - **Environment recipes** — prepare host or Docker testbeds with `type`, `workdir`, and argv-only `setup.command`
261
265
  - **Static local override** — use `--workspace-path` only when an existing local directory should be reused as-is
262
- - **Multi-repo** — clone multiple repos with sparse checkout and shallow clone support
266
+ - **Multi-repo** — materialize repos from setup scripts when a task needs several checkouts
263
267
  - **File change tracking** — grade by diffing workspace files before/after agent execution
264
268
 
265
269
  ---
@@ -9,32 +9,37 @@ The grader agent uses this to evaluate assertions without the CLI.
9
9
 
10
10
  - `name` (string, optional) — eval name
11
11
  - `description` (string, optional) — description
12
- - `execution` (object, optional) — `target`, `model`, etc.
13
- - `workspace` (object, optional) — workspace config (template, repos, hooks)
14
- - `input` (string | object | Message | Message[], optional) — suite-level input prepended to each test. String/block shorthand expands to a user message.
12
+ - `target` or `targets` (string | object | object[], optional) — system under test selection
13
+ - `environment` (object | `file://...`, optional) — AgentV coding-agent testbed recipe
14
+ - `env` (object, optional) — provider/eval environment variable overrides and template inputs
15
+ - `extensions` (array, optional) — lifecycle hooks such as `beforeAll`, `beforeEach`, `afterEach`, `afterAll`
16
+ - `prompts` (array, optional) — Promptfoo-compatible prompt matrix entries
15
17
  - `tests` (array, required) — test cases
16
18
 
17
19
  ### Per-test fields
18
20
 
19
21
  - `id` (string, required) — unique test identifier
20
- - `input` (string | object | Message | Message[], required) — task input. String shorthand expands to `[{role: user, content: "..."}]`; object shorthand preserves structured user content when the object has no top-level `role`. Top-level `role` is reserved for message objects.
22
+ - `vars` (object, required when prompts need row data) prompt-template variables for this row
21
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.
22
24
  - `criteria` (string, optional) — human-readable success criteria
23
- - `assertions` (array, optional) — grader assertions
25
+ - `assert` (array, optional) — grader assertions
26
+ - `environment` (object | `file://...`, optional) — per-case testbed override
24
27
  - `conversation_id` (string, optional) — groups related tests
25
28
  - `execution` (object, optional) — per-test execution override
26
29
 
27
- If `assertions` already state the grading contract, omit `criteria` instead of
30
+ If `assert` already states the grading contract, omit `criteria` instead of
28
31
  duplicating the same rubric. Prefer plain assertion strings for semantic checks
29
32
  when the default LLM rubric grader can judge them; use multiple named
30
33
  `type: llm-rubric` blocks only for custom prompts, custom grader targets, or
31
34
  intentional grader panels. Write `expected_output` as a golden/reference answer,
32
35
  not as criteria or scoring instructions.
33
36
 
34
- For historical or repo-state evals, materialize the repository under
35
- `workspace.repos[]` and pin `commit` to the commit under test. A SHA in prompt
36
- prose or metadata is context only; it does not give the agent an actual
37
- checkout.
37
+ For historical or repo-state evals, materialize the repository through
38
+ `environment.setup.command` and pass the repo/ref as argv inputs. A SHA in
39
+ prompt prose or metadata is context only; it does not give the agent an actual
40
+ checkout. `setup.command` is a non-empty string array. Put the executable at
41
+ `command[0]`, put CLI arguments in the remaining array entries, and use
42
+ `timeout_ms` for setup timeout.
38
43
 
39
44
  ## 2. Assertion Types and Grading Recipes
40
45
 
@@ -64,7 +64,7 @@ When evals.json becomes limiting, convert to EVAL.yaml for the full feature set:
64
64
  # Convert evals.json to EVAL.yaml
65
65
  agentv convert evals.json
66
66
 
67
- # Edit the generated YAML to add workspace config, script graders, etc.
67
+ # Edit the generated YAML to add environment setup, script graders, etc.
68
68
  # Then run with the full lifecycle
69
69
  agentv eval eval.yaml
70
70
  ```
@@ -40,19 +40,19 @@ For a v4.42.4-era eval:
40
40
  `execution.max_concurrency` to `evaluate_options.max_concurrency`, or leave
41
41
  it to `--workers` / project config if it is operator policy.
42
42
  10. Remove top-level `execution`; current eval YAML rejects it.
43
- 11. Replace `workspace.isolation: shared|per_test` with
44
- `workspace.scope: suite|attempt`.
43
+ 11. Move authored coding-agent testbed setup from public `workspace` fields to
44
+ `environment`.
45
45
  12. Remove `workspace.mode` and `workspace.path` from committed eval YAML.
46
46
  Use `--workspace-path` or `.agentv/config.local.yaml` for local static
47
47
  directories.
48
- 13. Replace workspace hook `script:` with `command:`.
49
- 14. For executable setup, prefer top-level `extensions`; keep
50
- `workspace.hooks.after_each.reset` for reset policy.
48
+ 13. Move lifecycle hooks to top-level `extensions`.
49
+ 14. Put reset policy and portable testbed setup under `environment`; keep
50
+ provider environment overrides under top-level `env`.
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` or `imports.tests`; import full eval suites
55
- with `imports.suites`.
54
+ 16. Keep raw cases under `tests` / `tests: file://...`; run full eval suites
55
+ directly with CLI multi-file selection and tags.
56
56
  17. Validate with `bun apps/cli/src/cli.ts validate <eval-file>`.
57
57
 
58
58
  ## Assertions Renamed To `assert`
@@ -266,7 +266,7 @@ tests:
266
266
  contains `{type: file, value: "{{ file_path }}"}` and a text block. Store file
267
267
  paths in `default_test.vars` or `tests[].vars`.
268
268
  - Keep `input` only in external raw-case files imported through
269
- `tests: file://...` or `imports.tests` when preserving existing raw datasets.
269
+ `tests: file://...` when preserving existing raw datasets.
270
270
  Do not copy that compatibility shape back into normal eval YAML.
271
271
 
272
272
  ### Verification
@@ -945,19 +945,18 @@ The external file contained raw case rows.
945
945
 
946
946
  ### Current Shape
947
947
 
948
- Current eval YAML still accepts inline `tests` and `tests: ./cases.yaml`, but
949
- adds explicit imports for composition:
948
+ Current eval YAML accepts inline `tests`, `tests: ./cases.yaml`, and field-local
949
+ file refs for raw case data. Run multiple full eval suites directly with CLI
950
+ selection and tags:
950
951
 
951
952
  ```yaml
952
- imports:
953
- suites:
954
- - path: ../suites/refunds.eval.yaml
955
- tests:
956
- - path: ../cases/refund-smoke.cases.yaml
957
-
953
+ prompts: file://../prompts/refund.yaml
954
+ default_test: file://../defaults/refund.yaml
958
955
  tests:
956
+ - file://../cases/refund-smoke.cases.yaml
959
957
  - id: local-edge-case
960
- input: Can a final-sale item be refunded after damage in transit?
958
+ vars:
959
+ question: Can a final-sale item be refunded after damage in transit?
961
960
  assert:
962
961
  - Explains the final-sale exception
963
962
  ```
@@ -966,21 +965,21 @@ tests:
966
965
 
967
966
  - Keep `tests: ./cases.yaml` when the file is a raw case array, JSONL, CSV,
968
967
  directory, glob, or script-backed dataset.
969
- - Use `imports.tests` when importing raw rows into the parent suite context.
970
- - Use `imports.suites` when importing full child eval suites that own their
971
- own `workspace`, input, assertions, and task environment.
972
- - Do not define a parent `workspace` in a wrapper eval that imports child
973
- suites through `imports.suites`; child suites own their environments.
974
- - Replace legacy `tests[].include` entries with `imports.suites` or
975
- `imports.tests` where possible.
976
- - Use `run:` on import entries only for scoped overrides:
977
- `threshold`, `repeat`, `timeout_seconds`, and `budget_usd`.
968
+ - Use `tests: file://...` or string entries inside `tests` for raw rows that run
969
+ in the parent suite context.
970
+ - Run full eval suites directly with CLI multi-file selection and tags. Do not
971
+ add wrapper-suite import semantics.
972
+ - Use `prompts: file://...`, `default_test: file://...`, and
973
+ `environment: file://...` to share reusable config locally at the field that
974
+ consumes it.
975
+ - Use `run:` on individual tests only for scoped overrides: `threshold`,
976
+ `repeat`, `timeout_seconds`, and `budget_usd`.
978
977
 
979
978
  ### Verification
980
979
 
981
980
  ```bash
982
981
  bun apps/cli/src/cli.ts validate path/to/eval.eval.yaml
983
- rg -n "include:|imports:|tests:" path/to/evals
982
+ rg -n "include:|tests:" path/to/evals
984
983
  ```
985
984
 
986
985
  ### Compatibility Notes
@@ -20,20 +20,19 @@ Promptfoo parity matrix: https://agentv.dev/docs/reference/promptfoo-parity/
20
20
  Treat YAML as the canonical portable model. Prefer authoring `.eval.yaml` / `EVAL.yaml` first, then use TypeScript helpers, Python scripts, or executable graders only when they lower to the same fields or when the evaluation logic must actually run code.
21
21
 
22
22
  Eval files define what is tested and how it runs: prompts, datasets, assertions,
23
- task fixtures, top-level `target`, and suite run controls. Use `imports.suites`
24
- for full child suites that preserve their workspace, shared input, `assert`,
25
- fixtures, and graders. Use `imports.tests` for raw case rows that should run in
26
- the parent file's context. Inline `tests` are also parent-owned raw cases.
27
- String-valued `tests` and string entries inside `tests[]` are raw-case import
28
- shorthand for direct paths, directories, and globs. Legacy `tests[].include`
29
- entries still load with a migration warning, but new evals should use
30
- `imports.suites` or `imports.tests`. Use scoped `run:` on import entries or
31
- individual tests only for `threshold`, `repeat`, `timeout_seconds`, and
32
- legacy `budget_usd`; keep target selection at top-level `target` or CLI `--target`,
33
- put suite budget caps under `evaluate_options.budget_usd`, authored concurrency
34
- under `evaluate_options.max_concurrency`, suite repeat policy under
35
- `evaluate_options.repeat`,
36
- and keep setup and workspace mutation under `workspace`.
23
+ task fixtures, top-level `target`, and suite run controls. Use field-local file
24
+ refs such as `tests: file://...`, `prompts: file://...`, `default_test:
25
+ file://...`, and `environment: file://...`. String-valued `tests` and string
26
+ entries inside `tests[]` are raw-case refs for direct paths, directories, and
27
+ globs. Run several full eval suites directly with CLI multi-file selection and
28
+ tags. Use scoped `run:` on individual tests only for `threshold`, `repeat`,
29
+ `timeout_seconds`, and legacy `budget_usd`; keep target selection at top-level
30
+ `target` or CLI `--target`, put suite budget caps under
31
+ `evaluate_options.budget_usd`, authored concurrency under
32
+ `evaluate_options.max_concurrency`, suite repeat policy under
33
+ `evaluate_options.repeat`, coding-agent testbed setup under `environment`,
34
+ provider environment overrides under `env`, and lifecycle hooks under
35
+ `extensions`.
37
36
 
38
37
  Use `@agentv/sdk` for TypeScript helper imports. Do not use `@agentv/eval` for new evals, examples, scaffolds, or skill guidance; it was a deprecated compatibility package and has been removed from this repository.
39
38
 
@@ -42,7 +41,7 @@ Use `@agentv/sdk` for TypeScript helper imports. Do not use `@agentv/eval` for n
42
41
  - Put grading criteria in `assert`, not in test-level `criteria`. Plain assertion strings become an `llm-rubric` grader.
43
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.
44
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.
45
- - For historical or repo-state evals, materialize the repo under `workspace.repos[]` pinned to the commit under test. Mentioning a SHA only in prompt prose is not enough because the agent needs an actual checkout to inspect.
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.
46
45
 
47
46
  ## Evaluation Types
48
47
 
@@ -62,7 +61,7 @@ agentv convert evals.json
62
61
  agentv eval evals.json
63
62
  ```
64
63
 
65
- 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 (workspace setup, script graders, rubrics, required gates).
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).
66
65
 
67
66
  After converting, enhance the YAML with AgentV-specific capabilities shown below.
68
67
 
@@ -132,8 +131,8 @@ tests:
132
131
 
133
132
  ## Eval File Structure
134
133
 
135
- **Required:** `tests` (array or string raw-case path) or `imports`
136
- **Optional:** `name`, `description`, `experiment`, `version`, `author`, `tags`, `license`, `requires`, `target`, `targets`, `prompts`, `default_test`, `timeout_seconds`, `evaluate_options`, `threshold`, `suite`, `workspace`, `assert`
134
+ **Required:** `tests` (array or string raw-case path) or `scenarios`
135
+ **Optional:** `name`, `description`, `experiment`, `version`, `author`, `tags`, `license`, `requires`, `target`, `targets`, `prompts`, `default_test`, `timeout_seconds`, `evaluate_options`, `threshold`, `suite`, `environment`, `env`, `extensions`, `assert`
137
136
 
138
137
  **Test fields:**
139
138
 
@@ -144,7 +143,7 @@ tests:
144
143
  | `expected_output` | no | Gold-standard reference answer (string shorthand or full message array) |
145
144
  | `assert` | yes | Graders: deterministic checks, `llm-rubric` checks, script graders, or plain string rubric criteria |
146
145
  | `execution` | no | Per-case grader/default overrides such as `skip_defaults`; target selection belongs in top-level `target` or CLI `--target` |
147
- | `workspace` | no | Per-case workspace config (overrides suite-level) |
146
+ | `environment` | no | Per-case coding-agent testbed config (overrides suite-level) |
148
147
  | `metadata` | no | Arbitrary key-value pairs passed to setup/teardown scripts |
149
148
  | `conversation_id` | no | Thread grouping |
150
149
 
@@ -215,7 +214,7 @@ then render those vars from the prompt template next to the input.
215
214
 
216
215
  **JSONL format:** One test per line as JSON. Optional `.yaml` sidecar for shared defaults. See `examples/features/basic-jsonl/`.
217
216
 
218
- **Environment variables:** Use `{{ env.VAR }}` templates in authored config. Missing vars resolve to empty string. Works in eval files, external case files, and workspace configs. `.env` files are loaded automatically.
217
+ **Environment variables:** Use `{{ env.VAR }}` templates in authored config. Missing vars resolve to empty string. Works in eval files, external case files, and environment configs. `.env` files are loaded automatically.
219
218
 
220
219
  ## Output Transforms
221
220
 
@@ -334,19 +333,29 @@ For repo-state evals, combine a pinned checkout, a golden answer, and assertion
334
333
  shorthand:
335
334
 
336
335
  ```yaml
337
- workspace:
338
- repos:
339
- - path: ./agentv
340
- repo: https://github.com/EntityProcess/agentv.git
341
- commit: 5e3c8f46d80fe66b1a75659e4fd94e38a7e09215
336
+ environment:
337
+ type: host
338
+ workdir: ./agentv
339
+ setup:
340
+ command:
341
+ - bash
342
+ - ./scripts/materialize-repo.sh
343
+ - ./agentv
344
+ - https://github.com/EntityProcess/agentv.git
345
+ - 5e3c8f46d80fe66b1a75659e4fd94e38a7e09215
346
+ cwd: "."
347
+
348
+ prompts:
349
+ - "{{ task }}"
342
350
 
343
351
  tests:
344
352
  - id: verification-learning-capture
345
- input: |
346
- The eval harness has prepared ./agentv at the commit before the
347
- verification guidance was added.
353
+ vars:
354
+ task: |
355
+ The eval harness has prepared ./agentv at the commit before the
356
+ verification guidance was added.
348
357
 
349
- Decide what durable repo change should be made and explain why.
358
+ Decide what durable repo change should be made and explain why.
350
359
  expected_output: |
351
360
  The durable repo change is to update .agents/verification.md with the
352
361
  reusable verification workflow lessons. AGENTS.md already routes this
@@ -431,25 +440,20 @@ assert:
431
440
 
432
441
  If a required grader scores below its threshold, the overall verdict is forced to `fail`.
433
442
 
434
- ## Workspace Setup/Teardown
443
+ ## Environment Setup/Teardown
435
444
 
436
445
  Run scripts before/after each test. Define at suite level or override per case:
437
446
 
438
447
  ```yaml
439
- workspace:
440
- template: ./workspace-templates/my-project
441
- repos:
442
- - path: ./repo
443
- repo: sympy/sympy
444
- commit: "abc123"
445
- hooks:
446
- before_all:
447
- command: ["bun", "run", "setup.ts"]
448
- timeout_ms: 120000
449
- after_each:
450
- reset: fast
451
- after_all:
452
- command: ["bun", "run", "teardown.ts"]
448
+ environment:
449
+ type: host
450
+ workdir: ./repo
451
+ setup:
452
+ command: ["bun", "run", "setup.ts", "sympy/sympy", "abc123"]
453
+ cwd: "."
454
+ timeout_ms: 120000
455
+ extensions:
456
+ - file://scripts/teardown.mjs:afterAll
453
457
 
454
458
  tests:
455
459
  - id: case-1
@@ -459,42 +463,53 @@ tests:
459
463
  source_commit: "abc123"
460
464
  ```
461
465
 
462
- **Lifecycle:** template copyrepo materializationworkspace before_all → target before_allgit baseline → before_each hooks → agent → file changes after_each hooksafter_all hooks → cleanup
463
- **Merge:** Case-level fields replace suite-level fields.
464
- **Commands receive stdin JSON:** `{workspace_path, test_id, eval_run_id, case_input, case_metadata}`
466
+ **Lifecycle:** environment setuplifecycle extensions → target setup → agent → gradingteardown extensions → cleanup
467
+ **Merge:** Case-level environment fields replace suite-level fields.
468
+ **Setup commands:** `setup.command` is an argv command. `command[0]` is the executable and `command[1...]` are CLI arguments. Use `["bash", "-lc", "..."]` when shell behavior is required.
469
+ **Setup stdin:** AgentV sends environment metadata JSON on stdin for setup commands.
465
470
  **Setup failure:** aborts case. **Teardown failure:** non-fatal (warning).
466
471
  For SWE-bench-style evals, put operational checkout state under
467
- `workspace.repos[].commit`; treat `metadata.source_commit` as informational
468
- only. A SHA in the prompt or metadata without a matching workspace repo pin is
472
+ `environment.setup.command` CLI arguments; treat `metadata.source_commit` as informational only.
473
+ A SHA in the prompt or metadata without a matching environment setup recipe is
469
474
  not an operational checkout.
470
475
 
471
- ### Repository Lifecycle
476
+ ### Environment Lifecycle
472
477
 
473
- Materialize repos into the eval workspace automatically. Repo entries declare identity and checkout pins only; AgentV resolves acquisition from configured `repo_resolvers`, then registered projects, `git_cache.mirrors`, its mirror cache, and remote clone. `repo_resolvers` and `git_cache.mirrors` may be defined in `$AGENTV_HOME/config.yaml`, the project's committed `.agentv/config.yaml`, or a gitignored `.agentv/config.override.yaml` (highest precedence) — use the override for machine-specific local bindings without editing tracked or user-global config. Shared repo workspaces use fresh temp materialization by default:
478
+ Describe coding-agent testbeds with `environment`. Reusable recipes should live
479
+ in field-local files and be loaded with `environment: file://...`:
474
480
 
475
481
  ```yaml
476
- workspace:
477
- repos:
478
- - path: ./repo
479
- repo: https://github.com/org/repo.git
480
- commit: main
481
- ancestor: 1 # parent commit
482
- hooks:
483
- after_each:
484
- reset: fast # none | fast | strict
485
- scope: suite # suite | attempt
482
+ environment: file://.agentv/environments/repo.yaml
486
483
  ```
487
484
 
488
- - `repo`: full clone URL or GitHub `org/name` shorthand
489
- - `commit`: branch, tag, or SHA to check out
490
- - `ancestor`: walk N commits back from the checked-out ref
491
- - `sparse`: sparse checkout paths array
492
- - Harness-managed repo workspaces use temp materialization by default; use `workspace.scope: suite | attempt` for portable lifetime
493
- - Existing local workspace directories are machine-local bindings; use `--workspace-path` or `.agentv/config.local.yaml` with `execution.workspace_path`
494
- - `hooks.enabled`: boolean (default `true`); set `false` to skip all lifecycle hooks
495
- - `agentv workspace deps <eval-paths>` scans eval files and outputs a JSON manifest of required git repos (useful for CI pre-cloning)
485
+ ```yaml
486
+ # .agentv/environments/repo.yaml
487
+ type: host
488
+ workdir: ./repo
489
+ setup:
490
+ command: ["bash", "./scripts/materialize-repo.sh", "https://github.com/org/repo.git", "main", "1"]
491
+ cwd: "."
492
+ timeout_ms: 120000
493
+ ```
496
494
 
497
- See https://agentv.dev/targets/configuration/#repository-lifecycle
495
+ ```yaml
496
+ # .agentv/environments/docker-repo.yaml
497
+ type: docker
498
+ context: ./environment
499
+ dockerfile: Dockerfile
500
+ workdir: /app
501
+ setup:
502
+ command: ["bash", "-lc", "bun install && bun run build"]
503
+ cwd: "."
504
+ timeout_ms: 120000
505
+ ```
506
+
507
+ - `type`: `host` or `docker`
508
+ - `workdir`: path the target and graders should use
509
+ - `setup`: argv command, optional `cwd`, and optional `timeout_ms` for repository/testbed materialization
510
+ - Top-level `env`: provider/eval environment overrides
511
+ - `environment.env`: recipe-scoped process environment, distinct from top-level `env`
512
+ - `extensions`: lifecycle hooks such as `beforeAll`, `beforeEach`, `afterEach`, and `afterAll`
498
513
 
499
514
  ## Grader Types
500
515
 
@@ -511,7 +526,7 @@ Configure via the `assert` array. Multiple graders produce a weighted average sc
511
526
  Contract: stdin JSON -> stdout JSON `{score, assertions: [{text, passed, evidence?}], reasoning}`
512
527
  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`
513
528
  SDK handlers receive the same payload in camelCase: `expectedOutput`, `traceSummary`, `tokenUsage`, `costUsd`, `durationMs`, `startTime`, `endTime`, `fileChanges`, `workspacePath`.
514
- When a workspace is configured, `workspace_path` is the absolute path to the workspace dir (also available as `AGENTV_WORKSPACE_PATH` env var). Use this for functional grading (e.g., running `npm test` in the workspace).
529
+ 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).
515
530
  For deterministic workspace checks that fit normal Vitest `expect(...)` tests, prefer a plain verifier file and the built-in adapter:
516
531
  ```yaml
517
532
  - name: welcome_banner