feat: Add unified CLI for run_guidance and fix missing args bug#207
feat: Add unified CLI for run_guidance and fix missing args bug#207Abdelsalam-Abbas merged 10 commits intomainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughReplaces many per-model per-strategy script entrypoints with a single unified CLI Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as "sampleworks-guidance\n(CLI)"
participant Config as "GuidanceConfig\n.from_cli()"
participant Model as "get_model_and_device"
participant Runner as "run_guidance"
User->>CLI: invoke sampleworks-guidance [--model ... --guidance-type ... + args]
CLI->>Config: GuidanceConfig.from_cli(argv)
Config-->>CLI: GuidanceConfig instance
CLI->>Model: get_model_and_device(config.device, getattr(config,'model_checkpoint',None), config.model, getattr(config,'method',None))
Model-->>CLI: model_wrapper, device
CLI->>Runner: run_guidance(config, config.guidance_type, model_wrapper, device)
Runner-->>CLI: result (exit_code)
CLI-->>User: process exit (exit_code)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/sampleworks/cli/guidance.py (1)
11-11: Add a NumPy-style docstring tomain().This new public CLI function is missing the required NumPy-style docstring.
As per coding guidelines "Always include NumPy-style docstrings for every function and class."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sampleworks/cli/guidance.py` at line 11, The public function main(argv: list[str] | None = None) lacks a NumPy-style docstring; add one directly above the def main(...) that briefly describes the function purpose, documents the parameters (argv: list[str] | None — what it represents), the return value (int — exit code), and any raised exceptions or side effects (e.g., calls to sys.exit or logging), following the NumPy docstring sections (Parameters, Returns, Raises) and using concise, clear prose so automated doc linters will accept it.scripts/boltz2_fk_steering.py (1)
7-7: Add a NumPy-style docstring tomain().This function is missing the required NumPy-style docstring.
As per coding guidelines "Always include NumPy-style docstrings for every function and class."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/boltz2_fk_steering.py` at line 7, Add a NumPy-style docstring to the main() function: insert a triple-quoted docstring immediately under the def main(): that follows NumPy conventions including a short summary line, a blank line, sections for Parameters (list any args or none), Returns (what main returns, e.g., None), and Examples if relevant; reference the function name main() when editing and ensure formatting matches other files (short summary, expanded description, sections titled "Parameters", "Returns", and optional "Examples") to satisfy the project's docstring guidelines.src/sampleworks/utils/guidance_script_arguments.py (1)
173-186: Documentfrom_cli()in the repo’s required docstring format.This is the new public parsing entrypoint, but its docstring still skips the NumPy-style
Parameters/Returns/Raisessections. That makes the CLI contract harder to consume than the rest of the config surface.As per coding guidelines,
**/*.py: "Always include NumPy-style docstrings for every function and class."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sampleworks/utils/guidance_script_arguments.py` around lines 173 - 186, The docstring for the classmethod from_cli (returning GuidanceConfig) is missing NumPy-style sections; update its docstring to include Parameters (describe argv: list[str]|None, model: str|None, guidance_type: str|None and their behavior), Returns (describe the GuidanceConfig returned) and Raises (list any exceptions raised during CLI parsing), keeping the existing summary and noting that model/guidance_type make CLI flags optional; ensure the sections follow the repo's NumPy-style formatting conventions so downstream docs and linters recognize them.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/boltz2_fk_steering.py`:
- Around line 15-19: The wrapper currently calls run_guidance(config, ...) but
ignores the returned JobResult and then unconditionally calls main(), causing
the process to always exit 0; update each wrapper entrypoint (the main()
function and the script-level invocation that calls main()) to capture the
JobResult from run_guidance (e.g., result = run_guidance(...)), return or
sys.exit(result.exit_code) from main, and propagate that exit_code back to the
process so CI sees failures; also add a NumPy-style docstring to each main()
describing parameters and return (including that it returns an int exit code) to
satisfy coding guidelines.
In `@src/sampleworks/utils/guidance_script_arguments.py`:
- Around line 211-236: The parser currently adds --model/--guidance-type with
preset defaults but then ignores any CLI overrides when building the config; fix
by validating CLI values after parsing: in the from_cli function (where parser
is built and args = parser.parse_args(argv) is called), compare args.model and
args.guidance_type to the preset model and guidance_type variables and call
parser.error(...) if they differ (reject conflicting CLI input), or
alternatively use args.model and args.guidance_type when constructing the config
(replace model=model, guidance_type=guidance_type with model=args.model,
guidance_type=args.guidance_type) so CLI values are honored — implement one of
these two approaches in guidance_script_arguments.py around the parser/args and
the cls(...) config construction.
---
Nitpick comments:
In `@scripts/boltz2_fk_steering.py`:
- Line 7: Add a NumPy-style docstring to the main() function: insert a
triple-quoted docstring immediately under the def main(): that follows NumPy
conventions including a short summary line, a blank line, sections for
Parameters (list any args or none), Returns (what main returns, e.g., None), and
Examples if relevant; reference the function name main() when editing and ensure
formatting matches other files (short summary, expanded description, sections
titled "Parameters", "Returns", and optional "Examples") to satisfy the
project's docstring guidelines.
In `@src/sampleworks/cli/guidance.py`:
- Line 11: The public function main(argv: list[str] | None = None) lacks a
NumPy-style docstring; add one directly above the def main(...) that briefly
describes the function purpose, documents the parameters (argv: list[str] | None
— what it represents), the return value (int — exit code), and any raised
exceptions or side effects (e.g., calls to sys.exit or logging), following the
NumPy docstring sections (Parameters, Returns, Raises) and using concise, clear
prose so automated doc linters will accept it.
In `@src/sampleworks/utils/guidance_script_arguments.py`:
- Around line 173-186: The docstring for the classmethod from_cli (returning
GuidanceConfig) is missing NumPy-style sections; update its docstring to include
Parameters (describe argv: list[str]|None, model: str|None, guidance_type:
str|None and their behavior), Returns (describe the GuidanceConfig returned) and
Raises (list any exceptions raised during CLI parsing), keeping the existing
summary and noting that model/guidance_type make CLI flags optional; ensure the
sections follow the repo's NumPy-style formatting conventions so downstream docs
and linters recognize them.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c43adbe7-7184-4d4a-98bb-5c3f4f361106
⛔ Files ignored due to path filters (1)
pixi.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
README.mdpyproject.tomlscripts/boltz1_fk_steering.pyscripts/boltz1_pure_guidance.pyscripts/boltz2_fk_steering.pyscripts/boltz2_pure_guidance.pyscripts/protenix_fk_steering.pyscripts/protenix_pure_guidance.pyscripts/rf3_fk_steering.pyscripts/rf3_pure_guidance.pysrc/sampleworks/cli/__init__.pysrc/sampleworks/cli/guidance.pysrc/sampleworks/utils/guidance_script_arguments.pytests/cli/__init__.pytests/cli/test_guidance_cli.py
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/sampleworks/utils/guidance_script_arguments.py (1)
176-182: Use a NumPy-style docstring forGuidanceConfig.from_cli.The new method docstring is clear, but it doesn’t follow the repository’s required NumPy docstring format (e.g.,
Parameters/Returnssections).As per coding guidelines: "Always include NumPy-style docstrings for every function and class."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sampleworks/utils/guidance_script_arguments.py` around lines 176 - 182, Update the docstring for GuidanceConfig.from_cli to use NumPy-style formatting: add a "Parameters" section detailing parameters (e.g., model, guidance_type and any CLI-related args or flags), and a "Returns" section describing the GuidanceConfig instance returned (including type). Keep the existing explanatory text but reorganize it into the NumPy sections and ensure parameter names and return type match the method signature in GuidanceConfig.from_cli.scripts/protenix_fk_steering.py (1)
9-9: Add a NumPy-style docstring tomain().Line 9 introduces/updates the function without the required NumPy-style docstring.
As per coding guidelines: "Always include NumPy-style docstrings for every function and class."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/protenix_fk_steering.py` at line 9, The function main() is missing a NumPy-style docstring; add a docstring immediately under the def main(): declaration following NumPy conventions that includes a short summary, Parameters (if any), Returns (if any), Raises (if any), and a brief Examples section when applicable; ensure the docstring uses triple quotes, proper section headers (Parameters, Returns, Raises, Examples) and concise descriptions so linters and docs tools recognize it for the main() function.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@scripts/protenix_fk_steering.py`:
- Line 9: The function main() is missing a NumPy-style docstring; add a
docstring immediately under the def main(): declaration following NumPy
conventions that includes a short summary, Parameters (if any), Returns (if
any), Raises (if any), and a brief Examples section when applicable; ensure the
docstring uses triple quotes, proper section headers (Parameters, Returns,
Raises, Examples) and concise descriptions so linters and docs tools recognize
it for the main() function.
In `@src/sampleworks/utils/guidance_script_arguments.py`:
- Around line 176-182: Update the docstring for GuidanceConfig.from_cli to use
NumPy-style formatting: add a "Parameters" section detailing parameters (e.g.,
model, guidance_type and any CLI-related args or flags), and a "Returns" section
describing the GuidanceConfig instance returned (including type). Keep the
existing explanatory text but reorganize it into the NumPy sections and ensure
parameter names and return type match the method signature in
GuidanceConfig.from_cli.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ae3bc552-cd58-43cb-bdf1-274d9a7620f7
📒 Files selected for processing (10)
scripts/boltz1_fk_steering.pyscripts/boltz1_pure_guidance.pyscripts/boltz2_fk_steering.pyscripts/boltz2_pure_guidance.pyscripts/protenix_fk_steering.pyscripts/protenix_pure_guidance.pyscripts/rf3_fk_steering.pyscripts/rf3_pure_guidance.pysrc/sampleworks/utils/guidance_script_arguments.pytests/cli/test_guidance_cli.py
🚧 Files skipped from review as they are similar to previous changes (8)
- scripts/rf3_pure_guidance.py
- scripts/boltz1_pure_guidance.py
- scripts/boltz2_fk_steering.py
- scripts/boltz1_fk_steering.py
- scripts/rf3_fk_steering.py
- scripts/boltz2_pure_guidance.py
- tests/cli/test_guidance_cli.py
- scripts/protenix_pure_guidance.py
Add GuidanceConfig.from_cli() classmethod that provides a single entrypoint for CLI argument parsing, replacing the 8 separate parse_*_args() functions. Register sampleworks-guidance console_scripts entrypoint in pyproject.toml. Simplify all 8 standalone scripts to thin wrappers calling from_cli() with pre-set model and guidance_type values. Fixes #181 (protein/model/guidance_type missing from argparse Namespace) Fixes #154 (unified CLI interface for run_guidance) Fixes #153 (CLI documentation in README)
Apply ruff format to guidance_script_arguments.py and test_guidance_cli.py. Propagate run_guidance exit code in all 8 wrapper scripts so failures are visible to CI. Stop registering --model/--guidance-type on the full parser when they are preset by wrapper scripts, preventing silent conflicts.
Remove lambda wrappers from _MODEL_ARG_ADDERS and _GUIDANCE_ARG_ADDERS, move dicts below function definitions. Replace __post_init__ if/elif chain with dispatch table lookups. Register --model/--guidance-type as hidden (SUPPRESS) args in preset mode and validate after parsing. Legacy scripts now error clearly on conflicting values instead of silently ignoring them. Add 5 tests for cross-model arg rejection: wrong model-specific args (--method on protenix/rf3, --msa-path on boltz1) and conflicting preset model/guidance_type.
Add 20 new tests covering cross-guidance-type arg rejection, preset value matching, arg passthrough for checkpoint/device/log-path/chiral features, and validation edge cases (empty args, missing resolution, invalid choices).
1296e9b to
b589947
Compare
Delete boltz1/boltz2/protenix/rf3 x pure_guidance/fk_steering wrapper scripts. The sampleworks-guidance CLI replaces all of them. Update README and AGENTS.md to remove references to deleted scripts.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/sampleworks/utils/guidance_script_arguments.py (1)
115-136: Avoid keeping_DYNAMIC_ATTRSin manual lockstep with every adder.This whitelist is easy to drift. If a new CLI option gets added in any
add_*_args()helper and_DYNAMIC_ATTRSis not updated, argparse will accept the flag butGuidanceConfigwill silently drop it here. Consider deriving the extra fields fromvars(args)minus the known base fields, or moving these fields onto the dataclass explicitly so the parser and config stay in sync.Also applies to: 273-279
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sampleworks/utils/guidance_script_arguments.py` around lines 115 - 136, The _DYNAMIC_ATTRS whitelist is brittle and can drift from the add_*_args helpers causing silently dropped flags; instead modify the code that copies parsed args onto GuidanceConfig (the logic that currently references _DYNAMIC_ATTRS) to compute dynamic fields at runtime by taking vars(args) and removing the known base fields (or by using GuidanceConfig's dataclass fields) so any new CLI options added via add_*_args are automatically included; update the copy logic to use set(vars(args).keys()) minus set(base_field_names) (or dataclass.__dataclass_fields__) rather than the hard-coded _DYNAMIC_ATTRS, and remove or deprecate the static _DYNAMIC_ATTRS list to avoid future maintenance drift.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/sampleworks/utils/guidance_script_arguments.py`:
- Around line 185-239: The code may index _MODEL_ARG_ADDERS and
_GUIDANCE_ARG_ADDERS with preset values and raise a raw KeyError for a typo; in
from_cli() validate the resolved/preset model and guidance_type against the
allowed enums (StructurePredictor and GuidanceType / model_choices and
guidance_choices) immediately after resolving them (after pre.parse_known_args
and before calling _MODEL_ARG_ADDERS[model] or
_GUIDANCE_ARG_ADDERS[guidance_type]); if a value is invalid raise a clear
ValueError mentioning the invalid value and the allowed choices so caller gets a
friendly error instead of KeyError.
In `@tests/cli/test_guidance_cli.py`:
- Around line 23-505: Add a smoke test that invokes the public entrypoint by
running the package module as a black-box process: spawn
subprocess.run([sys.executable, "-m", "sampleworks.cli.guidance", "--model",
"boltz1", "--guidance-type", "pure_guidance", "--protein", "1VME",
"--structure", "test.cif", "--density", "test.ccp4", "--resolution", "1.8"]) and
assert the process returncode is 0; place this new test alongside the
GuidanceConfig.from_cli tests (referencing GuidanceConfig.from_cli in the test
to mirror realistic args) so we verify the console entrypoint wiring without
mocking.
---
Nitpick comments:
In `@src/sampleworks/utils/guidance_script_arguments.py`:
- Around line 115-136: The _DYNAMIC_ATTRS whitelist is brittle and can drift
from the add_*_args helpers causing silently dropped flags; instead modify the
code that copies parsed args onto GuidanceConfig (the logic that currently
references _DYNAMIC_ATTRS) to compute dynamic fields at runtime by taking
vars(args) and removing the known base fields (or by using GuidanceConfig's
dataclass fields) so any new CLI options added via add_*_args are automatically
included; update the copy logic to use set(vars(args).keys()) minus
set(base_field_names) (or dataclass.__dataclass_fields__) rather than the
hard-coded _DYNAMIC_ATTRS, and remove or deprecate the static _DYNAMIC_ATTRS
list to avoid future maintenance drift.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0f4ebb27-3f83-4321-89a2-727e3bb0b70f
⛔ Files ignored due to path filters (1)
pixi.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
README.mdpyproject.tomlscripts/boltz1_fk_steering.pyscripts/boltz1_pure_guidance.pyscripts/boltz2_fk_steering.pyscripts/boltz2_pure_guidance.pyscripts/protenix_fk_steering.pyscripts/protenix_pure_guidance.pyscripts/rf3_fk_steering.pyscripts/rf3_pure_guidance.pysrc/sampleworks/cli/__init__.pysrc/sampleworks/cli/guidance.pysrc/sampleworks/utils/guidance_script_arguments.pytests/cli/__init__.pytests/cli/test_guidance_cli.py
✅ Files skipped from review due to trivial changes (1)
- README.md
🚧 Files skipped from review as they are similar to previous changes (8)
- pyproject.toml
- scripts/rf3_pure_guidance.py
- src/sampleworks/cli/guidance.py
- scripts/boltz2_pure_guidance.py
- scripts/protenix_fk_steering.py
- scripts/boltz1_fk_steering.py
- scripts/boltz2_fk_steering.py
- scripts/boltz1_pure_guidance.py
Validate preset model/guidance_type against allowed choices before dispatch map lookup, raising ValueError instead of raw KeyError. Add smoke test that invokes sampleworks.cli.guidance --help as a subprocess to verify the console_scripts wiring and import chain.
k-chrispens
left a comment
There was a problem hiding this comment.
I think the one remaining change to make is to expose the new arguments that Marcus enabled in #205 to the CLI, then it's good to go! It works on my dev node when I run things. I'll let @marcuscollins come back to approve if he things his comments were addressed fully
Add --recycling-steps and --num-diffusion-steps to add_generic_args() and _DYNAMIC_ATTRS so they are available via sampleworks-guidance. These were added in #205 but not wired to the CLI.
exposed both arguments |
marcuscollins
left a comment
There was a problem hiding this comment.
LGTM. Thanks for the changes @Abdelsalam-Abbas !
Summary
run_guidancescripts crash withAttributeError: 'Namespace' object has no attribute 'protein'becauseprotein,model, andguidance_typewere never added to the argparse parser. The error occurs inget_job_result()after guidance completes (or fails), making it impossible to get a clean exit from standalone scripts.sampleworks-guidanceas a unified CLI entrypoint (registered viaconsole_scripts) that replaces the need for 8 separate model+guidance scripts.run_guidancemethod in guidance_script_utils #153: Documents the new CLI in the README Quick Start section with a reference table of required arguments.What changed
GuidanceConfig.from_cli()classmethod that handles two-pass argument parsing: first resolves--modeland--guidance-type, then builds the full parser with model-specific and guidance-type-specific args dynamically.src/sampleworks/cli/guidance.pyas the unified entrypoint.from_cli()with pre-set model/guidance_type.parse_*_args()functions (replaced byfrom_cli()).--proteinas a required argument (must match naming used in grid search/evaluation).sampleworks-guidanceconsole_scripts inpyproject.toml.run_guidanceexit code in all 8 wrapper scripts viasys.exit(main())so CI and automation see non-zero exits on failure (previously always exited 0).--model/--guidance-typeon the argparse parser when preset by wrapper scripts, so conflicting CLI input (e.g.rf3_fk_steering.py --model boltz2) is rejected instead of silently ignored.Test plan
tests/cli/test_guidance_cli.pycovering unified CLI, legacy script pattern, validation errors, and defaultsAttributeError: 'Namespace' object has no attribute 'protein', EXIT CODE: 1)GuidanceConfigproperly populatingprotein,model,guidance_typeSummary by CodeRabbit
New Features
Refactor
Documentation
Tests