kanros migrate
Translate an existing declarative eval configuration — the common YAML shape used by earlier-generation Node.js eval CLIs — into a kanros configuration.
kanros migrate <INPUT> [--output <PATH> | --stdout]
| Flag / arg | Default | Meaning |
|---|---|---|
<INPUT> | required | Path to the legacy config to migrate. |
-o, --output | ./kanros.yaml | Write to this path. |
--stdout | off | Print to stdout (mutually exclusive with --output). |
What it does
kanros migrate reads the input file, parses the legacy schema, and
emits an equivalent kanros YAML. The translator:
- Maps
providers:1:1, preserving inlineconfig:blocks. - Maps
prompts:1:1, converting anyfile:///https://URIs as-is. - Walks every
tests[i].assert[j]and translates the assertion'stype:to its kanros equivalent, normalising to kebab-case. - Translates
defaultTest→default_test, including itsvars:and appendedassert:list. - Inserts
# TODO:comments wherever a legacy construct has no direct kanros equivalent.
The command prints a summary line on success:
✓ migrated → kanros.yaml (3 providers, 5 prompts, 24 tests)
If TODOs were inserted, the line also notes the count:
✓ migrated → kanros.yaml (3 providers, 5 prompts, 24 tests) (2 TODO comment(s) — review before running)
Examples
kanros migrate legacy-config.yaml
kanros migrate legacy-config.yaml --output configs/regression.yaml
kanros migrate legacy-config.yaml --stdout | less
What survives translation
| Source concept | kanros equivalent |
|---|---|
providers: list | providers: list (id passed through) |
prompts: list (string) | prompts: list (string) |
prompts: list (file URI) | prompts: list (string, URI preserved) |
tests: list | tests: list |
vars: per test | vars: per test |
defaultTest | default_test |
assert: type: equals | assert: type: equals |
assert: type: contains | assert: type: contains |
assert: type: regex | assert: type: regex |
assert: type: javascript | assert: type: javascript (runs in boa_engine) |
assert: type: llm-rubric | assert: type: llm-rubric with provider: block |
assert: type: factuality | assert: type: factuality |
assert: type: model-graded-* | model-graded-closedqa / answer-relevance |
weight: on assertions | assert-set with op: weighted and threshold: |
What needs human review
The migrator inserts a # TODO: comment above any construct that does
not have a clean kanros equivalent. Look for these markers and resolve
them before piping the file into kanros run:
- Inline JavaScript graders that depend on Node.js built-ins
(
fs,path,http). kanros runs JS via embeddedboa_engine, which exposes no Node APIs. Rewrite the grader as a pure function or port it to a WASM plugin (see WASM plugins). - Custom dataset loaders. kanros supports CSV, JSONL, and Hugging
Face datasets via the
kanros-datasetscrate. Other loaders need afile://URI plus a short pre-processing script. - Cloud-only features — team mode, remote run history. kanros does
not have a server side; for run comparisons see
kanros diff, for sharing seekanros share. - Cost / latency assertions with units other than USD / ms. kanros is strict on units.
Sanity workflow after migration
kanros migrate legacy-config.yaml
grep -n 'TODO:' kanros.yaml # resolve all TODOs
kanros validate --config kanros.yaml # check shape
kanros run --config kanros.yaml --no-cache # smoke test
Then start iterating.
Notes
- The migrator is one-shot. It does not watch the source for changes; re-run it after any meaningful edit to the source config.
- The output is deterministic given a fixed input. Diff-friendly.
- If the input file cannot be read or the YAML parser rejects it,
migrateexits with code2and prints the underlying error.