Skip to content

Commit b352a9b

Browse files
committed
fix(eval): migrate remaining assert fixtures
1 parent 88dcb3b commit b352a9b

26 files changed

Lines changed: 122 additions & 121 deletions

README.md

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,10 @@ Test AI targets on real repo tasks and measure what actually works.
1818
- **Category** is derived from where the eval lives, such as folder path and file name. Use paths to organize the corpus instead of repeating category labels in every eval.
1919
- **Workspace / fixtures / graders** are task-owned context: repos, setup scripts, files, fixtures, isolation, deterministic checks, and LLM grading prompts.
2020
- **Target** is the system under test: an agent, provider, gateway, replay target, CLI wrapper, transcript provider, or future app/service wrapper. Each eval selects one `target`, either by label from `targets.yaml` or with an eval-local target object.
21-
- **Experiment** is the run/result grouping label being measured over that corpus, such as `with-skills` or `without-skills`. Keep suite/category and target/model names out of this label.
21+
- **Tags** are run/result grouping labels. `tags.experiment` is the default experiment namespace, such as `with-skills` or `without-skills`; keep suite/category and target/model names out of that tag.
2222
- **Evaluate options** configure runner-level behavior such as repeat policy, optional timeouts, and `max_concurrency` under `evaluate_options`.
2323
- **Default test** configures inherited per-test defaults such as score `threshold`.
24-
- **Run** is one concrete execution of an experiment against a resolved target that writes portable artifacts for readers such as Dashboard, compare, and trend.
25-
26-
```mermaid
27-
flowchart LR
28-
corpus["Eval suite / imports / tests<br/>task corpus"]
29-
category["Category<br/>path-derived grouping"]
30-
context["Workspace / fixtures / graders<br/>task-owned context"]
31-
experiment["Experiment<br/>named run condition"]
32-
target["Target<br/>system under test"]
33-
controls["Run controls<br/>execution + gates"]
34-
run["Run<br/>concrete execution"]
35-
artifacts["Run artifacts<br/>summary.json + index.jsonl + sidecars"]
36-
readers["Dashboard / compare / trend<br/>derived readers"]
37-
38-
corpus --> category
39-
corpus --> run
40-
context --> run
41-
category --> run
42-
experiment --> run
43-
target --> run
44-
controls --> run
45-
run --> artifacts
46-
artifacts --> readers
47-
```
24+
- **Run** is one concrete execution of a tagged eval against a resolved target that writes portable artifacts for readers such as Dashboard, compare, and trend.
4825

4926
## Quick start
5027

apps/cli/src/commands/eval/task-bundle.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,23 @@ function parseSourceTestCase(test: EvalTest): Record<string, unknown> {
494494
}
495495

496496
function withoutLegacyAssertionKeys(testCase: Record<string, unknown>): Record<string, unknown> {
497-
return Object.fromEntries(Object.entries(testCase).filter(([key]) => key !== 'assert'));
497+
return Object.fromEntries(
498+
Object.entries(testCase).filter(([key]) => key !== 'assert' && key !== 'assertions'),
499+
);
500+
}
501+
502+
function serializeGraderDefinition(
503+
definition: Record<string, unknown>,
504+
rewrites: ReadonlyMap<string, string>,
505+
): unknown {
506+
const serialized = rewritePathsDeep(toSnakeCaseDeep(definition), rewrites);
507+
if (!isRecord(serialized)) {
508+
return serialized;
509+
}
510+
const { name, metric, ...rest } = serialized;
511+
return typeof name === 'string' && metric === undefined
512+
? { metric: name, ...rest }
513+
: serialized;
498514
}
499515

500516
function buildEvalCase(
@@ -506,8 +522,8 @@ function buildEvalCase(
506522
if (graderDefinitions.length > 0) {
507523
return {
508524
...withoutLegacyAssertionKeys(testCase),
509-
assertions: graderDefinitions.map((grader) =>
510-
rewritePathsDeep(toSnakeCaseDeep(grader.definition), rewrites),
525+
assert: graderDefinitions.map((grader) =>
526+
serializeGraderDefinition(grader.definition, rewrites),
511527
),
512528
};
513529
}

apps/cli/test/commands/eval/artifact-writer.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2404,7 +2404,7 @@ describe('writeArtifactsFromResults', () => {
24042404

24052405
const parsedEval = parseYamlValue(taskEval) as Record<string, unknown>;
24062406
const [testCase] = parsedEval.tests as Record<string, unknown>[];
2407-
const [assertion] = testCase.assertions as Record<string, unknown>[];
2407+
const [assertion] = testCase.assert as Record<string, unknown>[];
24082408
expect(parsedEval.target).toBe('gpt-4o');
24092409
expect(testCase.input).toBe('file://files/src/input.txt');
24102410
expect(assertion.prompt).toBe('file://graders/src/grader.md');

apps/cli/test/commands/eval/bundle.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ describe('agentv eval bundle', () => {
7575
value: ../data/input.txt
7676
- type: text
7777
value: Answer using the fixture.
78-
assertions:
78+
assert:
7979
- type: contains
8080
value: Mock
8181
`,
@@ -184,7 +184,7 @@ tests: ../data/cases.yaml
184184
tests:
185185
- id: inline-case
186186
input: hello
187-
assertions:
187+
assert:
188188
- type: contains
189189
value: inline
190190
`,
@@ -226,7 +226,7 @@ tests:
226226
tests:
227227
- id: missing-template
228228
input: hello
229-
assertions:
229+
assert:
230230
- type: contains
231231
value: Mock
232232
`,

apps/cli/test/commands/eval/pipeline/fixtures/builtin-test.eval.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ tests:
33
- id: test-01
44
input: hello world
55
criteria: Response echoes the input
6-
assertions:
7-
- name: has_hello
6+
assert:
7+
- metric: has_hello
88
type: contains
99
value: hello
10-
- name: matches_pattern
10+
- metric: matches_pattern
1111
type: regex
1212
value: "h[aeiou]llo"
13-
- name: is_valid_json
13+
- metric: is_valid_json
1414
type: is-json

apps/cli/test/commands/eval/pipeline/fixtures/input-test.eval.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ tests:
33
- id: test-01
44
input: hello world
55
criteria: Response echoes the input
6-
assertions:
7-
- name: contains_hello
6+
assert:
7+
- metric: contains_hello
88
type: script
99
command: node grader-score-1.js
1010
weight: 1.0
11-
- name: relevance
11+
- metric: relevance
1212
type: llm-grader
1313
prompt: Did the response echo the input?
1414
weight: 2.0

apps/cli/test/commands/eval/pipeline/fixtures/no-name.eval.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ tests:
22
- id: test-01
33
input: hello world
44
criteria: Response echoes the input
5-
assertions:
6-
- name: contains_hello
5+
assert:
6+
- metric: contains_hello
77
type: contains
88
value: hello

apps/cli/test/commands/eval/task-bundle.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ describe('materializeTaskBundle', () => {
121121
const taskTargets = await readFile(paths?.targetsPath ?? '', 'utf8');
122122
const parsedEval = parseYamlValue(taskEval) as Record<string, unknown>;
123123
const [testCase] = parsedEval.tests as Record<string, unknown>[];
124-
const [assertion] = testCase.assertions as Record<string, unknown>[];
124+
const [assertion] = testCase.assert as Record<string, unknown>[];
125125

126126
expect(parsedEval.target).toBe('selected');
127127
expect(parsedEval.execution).toBeUndefined();

apps/cli/test/commands/grade/grade-prepared.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ targets:
9494
`
9595
workspace:
9696
template: ../template
97-
assertions:
97+
assert:
9898
${assertionYaml
9999
.trim()
100100
.split('\n')
@@ -126,7 +126,7 @@ describe('agentv grade prepared attempts', () => {
126126
const { evalPath, targetMarker, graderPayloadPath } = await writeFixtureProject(
127127
tempDir,
128128
`
129-
- name: workspace-check
129+
- metric: workspace-check
130130
type: script
131131
command: ["bun", "../scripts/workspace-grader.ts"]
132132
`,
@@ -247,7 +247,7 @@ describe('agentv grade prepared attempts', () => {
247247
const { evalPath, targetMarker } = await writeFixtureProject(
248248
tempDir,
249249
`
250-
- name: expected-tool-sequence
250+
- metric: expected-tool-sequence
251251
type: tool-trajectory
252252
mode: exact
253253
expected:
@@ -292,7 +292,7 @@ describe('agentv grade prepared attempts', () => {
292292
const { evalPath, targetMarker } = await writeFixtureProject(
293293
tempDir,
294294
`
295-
- name: expected-tool-sequence
295+
- metric: expected-tool-sequence
296296
type: tool-trajectory
297297
mode: in_order
298298
expected:
@@ -400,7 +400,7 @@ describe('agentv grade prepared attempts', () => {
400400
const { evalPath } = await writeFixtureProject(
401401
tempDir,
402402
`
403-
- name: expected-tool-sequence
403+
- metric: expected-tool-sequence
404404
type: tool-trajectory
405405
mode: in_order
406406
expected:
@@ -443,7 +443,7 @@ describe('agentv grade prepared attempts', () => {
443443
const { evalPath } = await writeFixtureProject(
444444
tempDir,
445445
`
446-
- name: expected-tool-sequence
446+
- metric: expected-tool-sequence
447447
type: tool-trajectory
448448
mode: in_order
449449
expected:

examples/features/agent-skills-evals/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ tests:
6262
value: evals/files/sales.csv
6363
- type: text
6464
value: "Find the top 3 months by revenue."
65-
assertions:
65+
assert:
6666
- type: skill-trigger
6767
skill: csv-analyzer
6868
should_trigger: true
69-
- type: rubrics
70-
criteria: "Output identifies November as the highest revenue month"
69+
- type: llm-rubric
70+
value: "Output identifies November as the highest revenue month"
7171
- type: contains
7272
value: "$22,500"
7373
```

0 commit comments

Comments
 (0)