Repository navigation
refactor(arms): run arms from a typed ArmsRunConfig instead of the parsed Namespace - #270
Conversation
|
Ran: the full suite, lint and types on the head; the head merged into current main; old-vs-new CLI runs of arms run, matrix-run and subjects run.
|
antonwolfy
left a comment
There was a problem hiding this comment.
The refactor holds up, with two open points from @xaleryb that I confirm and that should be fixed before merge. I found nothing new.
I agree with @xaleryb that the head merged into current main fails test_answering_stack_parity.py, and that ArmsRunConfig keeps the Claude judge for a non-default judge_provider. New evidence: ArmsRunConfig(product="p", judge=True, judge_provider="openai").judge_model is claude-sonnet-5-5; the CLI paths are fine only because cli.py resolves the sentinel first.
What I ran, on a Linux review host at 4d7ca1d:
make ci-local: 25 passed, 3 failed, 7 skipped. 9302 tests passed; changed-line coverage 95% (232 lines measured).Fragment for package changesfails because the PR changesdokimi/dokimi/with no changelog fragment and noskip-changeloglabel, as @xaleryb noted; either one turns it green. The other two failures are not the PR's:pip-auditlistsfilelockadvisories in the lock files, which this PR does not touch.test_unbalanced_quote_in_hook_completes_quicklytook 1.04s against a 1s limit, and passes on its own (508 passed intest_repo_environment.py).- Mutation run: 119 single-point mutants of
arms_run.py,commands/arms.pyandcommands/subjects.py(fields dropped on the way toArmRunner,run_config_from_argsfields, defaults,cell_config, exit codes, error routing). The related test files kill all 119.
Checked, no issues
- Parity: every flag the base passed to
ArmRunner,JudgeandJudgePanelstill reaches them; exit codes and messages forLibraryIdError,MatrixCellErrorandEmptyQuestionErrormatch the base. - Description:
ArmsRunConfighas 24 fields named after thearms runflag dests, and the defaults match the flags apart from the judge model above. - Growth baseline: the removed entries and the new line counts match;
test_growth_ratchet.pypasses. - Leftovers: no references to the removed helpers remain in code, tests or docs. All five commits carry
Signed-off-by.
|
@xaleryb @antonwolfy thanks. I merged main into the branch, on top of your 4d7ca1d, and added three commits:
|
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #270 +/- ##
==========================================
+ Coverage 93.50% 93.53% +0.03%
==========================================
Files 273 274 +1
Lines 35569 35643 +74
Branches 6040 6041 +1
==========================================
+ Hits 33260 33340 +80
+ Misses 1492 1486 -6
Partials 817 817
🚀 New features to boost your workflow:
|
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 18 selected item(s). |
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 20 selected item(s). Review details
|
resolve_doc_library_id, validate_expected_skills, probe_sampling and validate_supported_matrix_harnesses read no parsed arguments, and judge_reliability imported the probe from another command. Move them, unchanged, into a new evaluation-layer module under public names; the commands and the tests import them from there. validate_expected_skills collects the offered skill names in a helper of its own, so the moved function stays under the complexity cap and its growth baseline entry goes. Refs intel#4 Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
_build_arms_output read the run configuration off the parsed Namespace, most fields with a getattr default, and matrix-run copied the Namespace per cell and mutated the copy. Add ArmsRunConfig to dokimi/eval/arms_run.py: frozen, the field names are the flags' dest names, and each default is what arms run runs with when the flag is left out. run_arms is the body of _build_arms_output, split under the complexity cap, and cell_config puts a matrix cell into a config with dataclasses.replace. run_config_from_args is the one place parsed flags become a config. A doc arm with no library id raises LibraryIdError instead of exiting inside the run; both commands print the same message and exit 1. The regex test over getattr(args, ...) goes with the getattr defaults. subjects run still hands matrix-run a Namespace; the next commit changes that. No flag changes; stdout, exit codes and arms.v1 are unchanged. Refs intel#4 Refs intel#229 Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
subjects run built a Namespace by hand from FORWARDED_RUN_CONFIG_FIELDS and called cmd_arms_matrix_run with it. Split the matrix run out of that handler into run_matrix(config, ...), which takes the config and the input and output paths, and have subjects run call it with run_config_from_args(args, product=..., baseline_arm=...). A field subjects run has no flag for takes the config's default, as before. FORWARDED_RUN_CONFIG_FIELDS and forwarded_run_config have no caller left and are removed. Refs intel#4 Refs intel#229 Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The loop over the cells still lived in the command. Move it into the run module: check_matrix checks every cell's harness and sampling, and run_matrix calls it before the first cell is paid for, then runs the cells in turn and hands each finished cell and its arms.v1 output to a callback, so a later cell's failure keeps the earlier ones. A failing cell raises MatrixCellError naming it; a bad question record and LibraryIdError pass through. The command keeps the files: it checks the matrix before it makes the output dir, makes the dirs before the first paid call, saves each cell from the callback, and writes the plugin deltas and the rollup. The messages and exit codes are unchanged; the cell-name collision check now runs before the harness check, ahead of the paid sampling probe. Refs intel#4 Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
run_matrix re-raises EmptyQuestionError past the MatrixCellError wrapper, so a blank question is bad input (exit 2), not a failed cell (exit 1). Nothing pinned it: dropping it from the tuple left the suite green. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
intel#253 came in from main with the old dokimi.commands.arms._resolve_doc_library_id, which this branch moved and renamed; the merge failed test_both_stacks_match_pinned_values with an ImportError. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
judge_model defaulted to the Claude judge whatever judge_provider said, so ArmsRunConfig(judge=True, judge_provider="openai") judged with claude-sonnet-5-5 on openai, while arms run --judge-provider openai runs gpt-6.1-sol. The CLI paths were right only because parse_args resolves the --judge-model sentinel first. The field now defaults to that sentinel and resolves it the way parse_args does; a provider with no default judge (openrouter) needs judge_model, as on the command line. Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
… were written against Signed-off-by: Vladislav Perevezentsev <vladislav.perevezentsev@intel.com> Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…to main check_growth.py --update, once the arms split is on top of main. Refs intel#4 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The Comment blocks check (intel#298, on main since the rebase) fails a block of three lines that a PR adds. The rest of the reason is in the PR. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
The docstring promises a ValueError naming the first bad cell, but a harness or sampling refusal did not say which cell it came from. Each cell's refusal now starts with its name. Harness checks still run for every cell before the first sampling probe is paid for. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
299f31b to
dc01659
Compare
antonwolfy
left a comment
There was a problem hiding this comment.
LGTM. Both points from my earlier review are fixed: ArmsRunConfig(product="p", judge=True, judge_provider="openai") now resolves its judge model through default_judge_model, and test_answering_stack_parity.py imports resolve_doc_library_id from dokimi.eval.arms_run. I found nothing new.
What I ran, on a Linux review host at dc01659:
make ci-local: 28 passed, 1 failed, 7 skipped. 10631 tests passed; changed-line coverage 97% (245 lines measured). The one failure isFragment for package changes; theskip-changeloglabel on the PR covers it.- Mutation run: 115 hand-picked single-point mutants of
arms_run.py,commands/arms.pyandcommands/subjects.py(fields dropped on the way toArmRunner,Judge,JudgePanel; defaults;cell_config; judge-model resolution; check order; caught exception classes; exit codes). The related test files kill all of them.
Checked, no issues
- Defaults: all 24
ArmsRunConfigfields compared with the argparse defaults ofarms run,matrix-runandsubjects run. The only difference isjudge_model, which is the--judge-modelsentinel resolved in__post_init__. - Parity: every argument the base passed to
ArmRunner,JudgeandJudgePanelstill reaches them. Exit codes and messages forLibraryIdError,MatrixCellErrorandEmptyQuestionErrormatch the base. The one stderr change is thematrix cell '<name>':prefix on amatrix-runsampling refusal, which the last commit adds on purpose and a test pins. - Leftovers: no reference to
FORWARDED_RUN_CONFIG_FIELDS,forwarded_run_config,_build_arms_output,_validate_expected_skills,_probe_samplingor_resolve_doc_library_idremains in code, tests, docs or scripts. The growth baseline matches the new line counts. - Repo rules: SPDX headers on the new files, docs build, docs-to-review check and comment-block check pass, no generated artifacts, and every non-merge commit carries
Signed-off-by.
Summary
arms run,arms matrix-runandsubjects runpass an arms run its configuration as anargparse.Namespace.matrix-runcopies the Namespace and mutates it for each cell.subjects runbuilds one by hand fromFORWARDED_RUN_CONFIG_FIELDS._build_arms_outputreads most fields withgetattr(args, ..., default), so when a caller drops a field, the run looks the same as if the user had chosen the default.This PR replaces that hand-off with one frozen dataclass and moves the run out of
commands/. It is the second half of the #4 Wave 5 item, as described in this #4 comment. No flag changes; stdout, exit codes andarms.v1stay the same.dokimi/eval/arms_run.py(new; no existingeval/*file changes):ArmsRunConfig: 24 fields, named after the flags' currentdest. Each default is whatarms runruns with when the flag is left out, so thegetattrdefaults are gone. A left-outjudge_modelis the default judge forjudge_provider, resolved asparse_argsdoes.run_armsis the body of_build_arms_output, split to stay under the complexity cap.cell_configbuilds a matrix cell's config withdataclasses.replace(...).run_matrix(config, cells, specs, questions, on_cell)checks every cell before the first paid call, then runs the cells in turn and hands each finished one toon_cell.probe_samplingis also used byjudge_reliability).commands/arms.pykeeps argument parsing, output paths, saving, printing and exit codes.run_config_from_argsis the one place where flags become a config. The commands'run_matrixwrites the cells, the plugin deltas and the rollup.subjects runbuilds the config directly.FORWARDED_RUN_CONFIG_FIELDS,forwarded_run_config()and the regex test overgetattr(args, ...)are removed.LibraryIdErrorreplaces aSystemExitraised inside_build_arms_output, andMatrixCellErrornames the failing cell. Both commands print the same messages and exit 1, as before.There is one order change in
matrix-run: the check that cell names give distinct file names now runs before the harness check, so both cheap checks come before the paid sampling probe.Commits: (1) move the shared checks to the new module; (2)
ArmsRunConfig+run_armsforarms runandmatrix-run; (3)subjects runbuilds the config; (4) the matrix loop moves to the module; (5) @xaleryb's pin of exit 2 on a blank question inmatrix-run. Then main is merged in, followed by (6) #253's test importing the renamed helper, (7) the config's judge model followingjudge_provider, and (8) #264's docstring. Commits 1-4 pass the tests on their own.#229, "the arms
Namespace" (not assessed yet). Three duplicates went away:FORWARDED_RUN_CONFIG_FIELDS, now the dataclass fields;getattrdefaults, now the dataclass defaults, which a test checks against thearms runflags;dataclasses.replace.The remaining duplicates are the flag definitions themselves (#94 F1a/F1b). F1b can now rename fields to the registry's
api_kwargin one place.#264 and #238
cmd_arms_matrix_run. Merging it gives 4 mechanical conflict hunks incommands/arms.py; I merge main in after it lands.Evidence
New
tests/test_arms_run_config.py(7 tests):arms runflag defaults, also with--judge-provider openai;Error: ...and exits 1, forarms runandmatrix-run;run_matrixrefuses a bad cell before any provider call.The three CLI tests also pass on
main.10 other test files change only their imports and monkeypatch targets (one of them, test(answers): characterize the two answering stacks (#228 step 1) #253's
test_answering_stack_parity.py, came in from main).Mutation sweep: 21 single edits (fields dropped on the way to the runner, defaults changed, the judge model not resolved for its provider, cells not applied, errors misrouted). Each one fails a test.
make ci-local: pytest 10133 passed, 57 skipped. The one failure besides the fragment step (green withskip-changelog) ispip-audit:filelockadvisories in the lock files, which this PR does not touch.Growth:
commands/arms.pygoes from 772 to 513 lines. The_build_arms_output(13) and_validate_expected_skills(11) baseline entries are removed.Merge Danger
Door: two-way. This is an internal refactor; the CLI, stdout, exit codes and artifacts do not change.
Blast Radius: the three commands that run arms, guarded by #264's parity tests.
Overlap: #238 (see above). #255 changes
--providerchoices in lines this PR does not touch.Not in this PR:
subjects runandmatrix-runlack today: adding them changes behaviour.plugins/judge_panel: they stay comma-separated strings, because tuples would change how a cell's plugin list is split.Checklist
pytestpassesruff,mypy, and schema checks pass (make ci-local)evaluating-treatments.mddepends_onand the architecture note name the new module. No changelog fragment (internal refactor):skip-changelogis setAGENTS.mdRefs #4
Refs #229