Skip to content

Commit f0f768f

Browse files
authored
Complete hard-deprecation codemod migrations (#1654)
* Complete hard-deprecation codemod migrations * Fix manifest path codemod target * Fix rerun env fixture syntax
1 parent 7741f9d commit f0f768f

40 files changed

Lines changed: 1059 additions & 414 deletions

apps/cli/src/templates/.agentv/targets.yaml

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,25 @@
66
targets:
77
- id: default
88
provider: azure
9-
endpoint: ${{ AZURE_OPENAI_ENDPOINT }}
10-
api_key: ${{ AZURE_OPENAI_API_KEY }}
11-
model: ${{ AZURE_DEPLOYMENT_NAME }}
12-
# version: ${{ AZURE_OPENAI_API_VERSION }} # Optional: uncomment to override default (v1)
9+
endpoint: "{{ env.AZURE_OPENAI_ENDPOINT }}"
10+
api_key: "{{ env.AZURE_OPENAI_API_KEY }}"
11+
model: "{{ env.AZURE_DEPLOYMENT_NAME }}"
12+
# version: "{{ env.AZURE_OPENAI_API_VERSION }}" # Optional: uncomment to override default (v1)
1313

1414
- id: codex
1515
provider: codex
1616
grader_target: azure-llm
1717
# Uses the Codex CLI (defaults to `codex` on PATH)
18-
# executable: ${{ CODEX_CLI_PATH }} # Optional: override executable path
18+
# executable: "{{ env.CODEX_CLI_PATH }}" # Optional: override executable path
1919
# args: # Optional additional CLI arguments
2020
# - --profile
21-
# - ${{ CODEX_PROFILE }}
21+
# - "{{ env.CODEX_PROFILE }}"
2222
# - --model
23-
# - ${{ CODEX_MODEL }}
23+
# - "{{ env.CODEX_MODEL }}"
2424
# - --ask-for-approval
25-
# - ${{ CODEX_APPROVAL_PRESET }}
26-
cwd: ${{ CODEX_WORKSPACE_DIR }} # Where scratch workspaces are created
27-
log_dir: ${{ CODEX_LOG_DIR }} # Optional: where Codex CLI stream logs are stored (defaults to ./.agentv/logs/codex)
25+
# - "{{ env.CODEX_APPROVAL_PRESET }}"
26+
cwd: "{{ env.CODEX_WORKSPACE_DIR }}" # Where scratch workspaces are created
27+
log_dir: "{{ env.CODEX_LOG_DIR }}" # Optional: where Codex CLI stream logs are stored (defaults to ./.agentv/logs/codex)
2828
stream_log: raw # Optional: 'summary' for consolidated logs or 'raw' for per-event logs
2929

3030
# Claude - Anthropic's Claude Agent SDK
@@ -33,24 +33,24 @@ targets:
3333
grader_target: azure-llm
3434
# Uses the @anthropic-ai/claude-agent-sdk
3535
# model: claude-sonnet-4-20250514 # Optional: override model
36-
# cwd: ${{ CLAUDE_WORKSPACE_DIR }} # Optional: working directory (defaults to process.cwd())
36+
# cwd: "{{ env.CLAUDE_WORKSPACE_DIR }}" # Optional: working directory (defaults to process.cwd())
3737
# max_turns: 50 # Optional: max conversation turns
3838
# max_budget_usd: 5.0 # Optional: max cost budget in USD
39-
# log_dir: ${{ CLAUDE_LOG_DIR }} # Optional: where stream logs are stored (defaults to ./.agentv/logs/claude)
39+
# log_dir: "{{ env.CLAUDE_LOG_DIR }}" # Optional: where stream logs are stored (defaults to ./.agentv/logs/claude)
4040
stream_log: raw # Optional: 'summary' for consolidated logs or 'raw' for per-event logs
4141
# system_prompt: optional override (default instructs agent to include code in response)
4242

4343
- id: azure-llm
4444
provider: azure
45-
endpoint: ${{ AZURE_OPENAI_ENDPOINT }}
46-
api_key: ${{ AZURE_OPENAI_API_KEY }}
47-
model: ${{ AZURE_DEPLOYMENT_NAME }}
48-
version: ${{ AZURE_OPENAI_API_VERSION }}
45+
endpoint: "{{ env.AZURE_OPENAI_ENDPOINT }}"
46+
api_key: "{{ env.AZURE_OPENAI_API_KEY }}"
47+
model: "{{ env.AZURE_DEPLOYMENT_NAME }}"
48+
version: "{{ env.AZURE_OPENAI_API_VERSION }}"
4949

5050
- id: gemini-llm
5151
provider: gemini
52-
api_key: ${{ GOOGLE_GENERATIVE_AI_API_KEY }}
53-
model: ${{ GEMINI_MODEL_NAME }}
52+
api_key: "{{ env.GOOGLE_GENERATIVE_AI_API_KEY }}"
53+
model: "{{ env.GEMINI_MODEL_NAME }}"
5454

5555
- id: local_cli
5656
provider: cli
@@ -61,37 +61,37 @@ targets:
6161
# Format for each file in {FILES}. {path} and {basename} are automatically shell-escaped, so no quotes needed
6262
files_format: --file {path}
6363
# Optional working directory resolved from .env
64-
cwd: ${{ CLI_EVALS_DIR }}
64+
cwd: "{{ env.CLI_EVALS_DIR }}"
6565
healthcheck:
6666
command: uv run ./mock_cli.py --healthcheck
6767

68-
# ── MiMo (Xiaomi) via OpenRouter ───────────────────────────────────
68+
# -- MiMo (Xiaomi) via OpenRouter -----------------------------------
6969
# All MiMo models are available through OpenRouter with OpenAI-compatible API.
7070
# See https://openrouter.ai/xiaomi/mimo-v2.5-pro for pricing and limits.
7171
#
7272
# Models:
73-
# mimo-v2.5-pro 1M context, 131K output, flagship
74-
# mimo-v2-pro 1M context, ~131K output
75-
# mimo-v2.5 1M context, ~131K output, multimodal
76-
# mimo-v2-flash 262K context, 65K output, fast MoE (open-source)
77-
# mimo-v2-omni 262K context, 65K output, omni-modal
73+
# mimo-v2.5-pro - 1M context, 131K output, flagship
74+
# mimo-v2-pro - 1M context, ~131K output
75+
# mimo-v2.5 - 1M context, ~131K output, multimodal
76+
# mimo-v2-flash - 262K context, 65K output, fast MoE (open-source)
77+
# mimo-v2-omni - 262K context, 65K output, omni-modal
7878
- id: mimo
7979
provider: openrouter
80-
api_key: ${{ OPENROUTER_API_KEY }}
80+
api_key: "{{ env.OPENROUTER_API_KEY }}"
8181
model: xiaomi/mimo-v2.5-pro
8282

8383
- id: mimo-flash
8484
provider: openrouter
85-
api_key: ${{ OPENROUTER_API_KEY }}
85+
api_key: "{{ env.OPENROUTER_API_KEY }}"
8686
model: xiaomi/mimo-v2-flash
8787

88-
# ── Direct provider (not through OpenRouter) ───────────────────────
88+
# -- Direct provider (not through OpenRouter) -----------------------
8989
# For providers not in pi-ai's model registry, set max_output_tokens
9090
# to match your model's actual output limit. Without this, the default
9191
# is 16K which may cap output below the model's capability.
9292
# - name: mimo-direct
9393
# provider: openai
9494
# base_url: https://token-plan-sgp.xiaomimimo.com/v1
95-
# api_key: ${{ XIAOMI_MIMO_API_KEY }}
95+
# api_key: "{{ env.XIAOMI_MIMO_API_KEY }}"
9696
# model: xiaomi/mimo-v2.5-pro
9797
# max_output_tokens: 131072

apps/cli/test/commands/runs/rerun.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ describe('agentv runs rerun', () => {
280280
const created = await fixture(`targets:
281281
- id: captured
282282
provider: cli
283-
command: \${{ LOCAL_AGENT_COMMAND }}
283+
command: "{{ env.LOCAL_AGENT_COMMAND }}"
284284
`);
285285

286286
const missing = await runCli(created, [
@@ -292,7 +292,7 @@ describe('agentv runs rerun', () => {
292292
'--dry-run',
293293
]);
294294
expect(missing.exitCode).toBe(1);
295-
expect(missing.stderr).toContain('Missing environment variable(s)');
295+
expect(missing.stderr).toContain("Failed to resolve target 'captured'");
296296
expect(missing.stderr).toContain('LOCAL_AGENT_COMMAND');
297297

298298
const withAmbientEnv = await runCli(

apps/web/src/content/docs/docs/next/evaluation/eval-cases.mdx

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -404,17 +404,29 @@ tests:
404404
- Assistant correctly explains the bug and proposes a fix
405405
```
406406

407-
Suite-level `preprocessors` apply to explicit LLM graders. That matters when the
408-
agent output is a `ContentFile` block rather than plain text:
407+
Suite-level transforms apply before graders see the target output. That matters
408+
when the agent output is a `ContentFile` block rather than plain text:
409409

410410
```yaml
411-
preprocessors:
412-
- type: xlsx
413-
command: ["bun", "run", "scripts/preprocessors/xlsx-to-csv.ts"]
411+
default_test:
412+
options:
413+
transform: >-
414+
return (() => {
415+
const file = Array.isArray(output)
416+
? output.find((block) => block?.type === "file" && block.path?.endsWith(".xlsx"))
417+
: undefined;
418+
if (!file) return output;
419+
const result = Bun.spawnSync(["bun", "run", "scripts/preprocessors/xlsx-to-csv.ts"], {
420+
stdin: JSON.stringify({ path: file.path, media_type: file.media_type })
421+
});
422+
if (result.exitCode !== 0) throw new Error(new TextDecoder().decode(result.stderr).trim());
423+
return new TextDecoder().decode(result.stdout).trim();
424+
})()
414425
415426
tests:
416427
- id: spreadsheet-eval
417-
input: Generate the spreadsheet report
428+
vars:
429+
input: Generate the spreadsheet report
418430
assert:
419431
- Output includes the revenue rows
420432
```
@@ -466,22 +478,17 @@ tests:
466478
value: "fix"
467479
```
468480

469-
When you need a custom file conversion for only one grader, add `preprocessors` directly to that grader:
481+
When you need a custom output conversion for only one grader, add `transform` directly to that grader:
470482

471483
```yaml
472-
preprocessors:
473-
- type: xlsx
474-
command: ["bun", "run", "scripts/preprocessors/xlsx-to-csv.ts"]
475-
476484
tests:
477485
- id: mixed-eval
478-
input: "Debug this function..."
486+
vars:
487+
input: "Debug this function..."
479488
assert:
480489
- Response is helpful and mentions the fix
481-
- type: llm-rubric # use explicit form for custom preprocessors
482-
preprocessors:
483-
- type: xlsx
484-
command: ["bun", "run", "scripts/preprocessors/xlsx-to-json.ts"]
490+
- type: llm-rubric
491+
transform: file://scripts/transforms/xlsx-to-json.ts
485492
- type: contains
486493
value: "fix"
487494
```

apps/web/src/content/docs/docs/next/evaluation/examples.mdx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,22 +101,33 @@ tests:
101101
}
102102
```
103103
104-
## File Output Preprocessing
104+
## File Output Transform
105105
106106
Convert a binary file output into text before the `llm-rubric` sees it:
107107

108108
```yaml
109-
description: Grade spreadsheet output via a preprocessor
110-
111-
preprocessors:
112-
- type: xlsx
113-
command: ["bun", "run", "../scripts/preprocessors/xlsx-to-csv.ts"]
109+
description: Grade spreadsheet output via a transform
114110
115111
target: file_output
112+
default_test:
113+
options:
114+
transform: >-
115+
return (() => {
116+
const file = Array.isArray(output)
117+
? output.find((block) => block?.type === "file" && block.path?.endsWith(".xlsx"))
118+
: undefined;
119+
if (!file) return output;
120+
const result = Bun.spawnSync(["bun", "run", "../scripts/preprocessors/xlsx-to-csv.ts"], {
121+
stdin: JSON.stringify({ path: file.path, media_type: file.media_type })
122+
});
123+
if (result.exitCode !== 0) throw new Error(new TextDecoder().decode(result.stderr).trim());
124+
return new TextDecoder().decode(result.stdout).trim();
125+
})()
116126
117127
tests:
118128
- id: spreadsheet-output
119-
input: Generate the spreadsheet report
129+
vars:
130+
input: Generate the spreadsheet report
120131
criteria: The extracted spreadsheet content includes the revenue rows
121132
assert:
122133
- Output contains the transformed spreadsheet text including the revenue rows

apps/web/src/content/docs/docs/next/graders/llm-graders.mdx

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,32 @@ assert:
192192
193193
The `config` object is available as `ctx.config` inside the template function.
194194

195-
## Preprocessing File Outputs
195+
## Transforming File Outputs
196196

197-
If an agent returns a `ContentFile` block instead of plain text, you can preprocess that file into text before `llm-rubric` builds the candidate prompt.
197+
If an agent returns a `ContentFile` block instead of plain text, use `transform` to convert that file into text before `llm-rubric` builds the candidate prompt.
198198

199-
AgentV always tries a default UTF-8 text read first. That is enough for text-based formats such as CSV, JSON, SQL, Markdown, YAML, HTML, XML, and plain text. For binary formats such as `.xlsx`, `.pdf`, or `.docx`, add a preprocessor command:
199+
AgentV always tries a default UTF-8 text read first. That is enough for text-based formats such as CSV, JSON, SQL, Markdown, YAML, HTML, XML, and plain text. For binary formats such as `.xlsx`, `.pdf`, or `.docx`, add a transform:
200200

201201
```yaml
202-
preprocessors:
203-
- type: xlsx
204-
command: ["bun", "run", "scripts/preprocessors/xlsx-to-csv.ts"]
202+
default_test:
203+
options:
204+
transform: >-
205+
return (() => {
206+
const file = Array.isArray(output)
207+
? output.find((block) => block?.type === "file" && block.path?.endsWith(".xlsx"))
208+
: undefined;
209+
if (!file) return output;
210+
const result = Bun.spawnSync(["bun", "run", "scripts/preprocessors/xlsx-to-csv.ts"], {
211+
stdin: JSON.stringify({ path: file.path, media_type: file.media_type })
212+
});
213+
if (result.exitCode !== 0) throw new Error(new TextDecoder().decode(result.stderr).trim());
214+
return new TextDecoder().decode(result.stdout).trim();
215+
})()
205216
206217
tests:
207218
- id: spreadsheet-output
208-
input: Generate the spreadsheet report
219+
vars:
220+
input: Generate the spreadsheet report
209221
assert:
210222
- Output includes the revenue rows
211223
- name: spreadsheet-check
@@ -216,15 +228,14 @@ tests:
216228
{{ output }}
217229
```
218230

219-
`type` accepts either a short alias such as `xlsx` or a full MIME type such as `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`.
220-
221231
Resolution order:
222232

223-
- per-grader `preprocessors` override suite-level entries
224-
- if no preprocessor matches, AgentV falls back to a UTF-8 text read
233+
- `tests[].options.transform` overrides `default_test.options.transform`
234+
- assertion-level `transform` applies to that grader only
235+
- if no transform is configured, AgentV falls back to a UTF-8 text read
225236
- if the fallback read looks binary or invalid, the grader receives a warning note instead of failing the test run
226237

227-
See [`examples/features/preprocessors/`](../../../../../examples/features/preprocessors/) for a runnable example with a file-producing target and a custom preprocessor script.
238+
See [`examples/features/preprocessors/`](../../../../../examples/features/preprocessors/) for a runnable example with a file-producing target and a spreadsheet conversion script.
228239

229240
## Available Context Fields
230241

apps/web/src/content/docs/docs/next/targets/cli-provider.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ graders:
2525
- id: azure-grader
2626
provider: azure
2727
config:
28-
endpoint: ${{ AZURE_OPENAI_ENDPOINT }}
29-
api_key: ${{ AZURE_OPENAI_API_KEY }}
30-
model: ${{ AZURE_DEPLOYMENT_NAME }}
28+
endpoint: "{{ env.AZURE_OPENAI_ENDPOINT }}"
29+
api_key: "{{ env.AZURE_OPENAI_API_KEY }}"
30+
model: "{{ env.AZURE_DEPLOYMENT_NAME }}"
3131

3232
defaults:
3333
target: my-agent
@@ -137,9 +137,9 @@ graders:
137137
- id: azure-grader
138138
provider: azure
139139
config:
140-
endpoint: ${{ AZURE_OPENAI_ENDPOINT }}
141-
api_key: ${{ AZURE_OPENAI_API_KEY }}
142-
model: ${{ AZURE_DEPLOYMENT_NAME }}
140+
endpoint: "{{ env.AZURE_OPENAI_ENDPOINT }}"
141+
api_key: "{{ env.AZURE_OPENAI_API_KEY }}"
142+
model: "{{ env.AZURE_DEPLOYMENT_NAME }}"
143143
144144
defaults:
145145
grader: azure-grader

apps/web/src/content/docs/docs/next/targets/coding-agents.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ targets:
9090
target: /results
9191
access: rw
9292
secrets:
93-
OPENAI_API_KEY: ${{ OPENAI_API_KEY }}
93+
OPENAI_API_KEY: "{{ env.OPENAI_API_KEY }}"
9494
config:
9595
command: ["codex", "exec", "--json"]
9696
model: gpt-5-codex
@@ -144,7 +144,7 @@ targets:
144144
runtime: host
145145
config:
146146
command: ["codex-eng", "exec", "--json"]
147-
model: ${{ CODEX_MODEL }}
147+
model: "{{ env.CODEX_MODEL }}"
148148
```
149149

150150
Use `codex-sdk` only when you intentionally want the Codex SDK path:
@@ -190,8 +190,8 @@ targets:
190190
config:
191191
command: ["pi"]
192192
subprovider: openrouter
193-
model: ${{ OPENROUTER_MODEL }}
194-
api_key: ${{ OPENROUTER_API_KEY }}
193+
model: "{{ env.OPENROUTER_MODEL }}"
194+
api_key: "{{ env.OPENROUTER_API_KEY }}"
195195
```
196196

197197
Use `pi-sdk` only when you intentionally want the SDK path:
@@ -266,8 +266,8 @@ targets:
266266
config:
267267
command: ["copilot"]
268268
subprovider: openai
269-
base_url: ${{ OPENAI_ENDPOINT }}
270-
api_key: ${{ OPENAI_API_KEY }}
269+
base_url: "{{ env.OPENAI_ENDPOINT }}"
270+
api_key: "{{ env.OPENAI_API_KEY }}"
271271
api_format: responses
272272
```
273273

0 commit comments

Comments
 (0)