some ergonomic fixes for site level workflows#83
Conversation
Signed-off-by: Zoe Blevins <zblevins@nvidia.com>
📝 WalkthroughWalkthroughAdds ChangesManaged-only filtering, default statuses, optional tenant, MCP tool prompt, and invalid-filter handling
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/tests/mcp/test_workflows.py (1)
59-87: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider asserting site password rotation as well.
These tests cover
run_site_cable_validationandrun_cumulus_hardware_validationbut not the site password rotation workflow, which is also a site-level flow per the PR. Adding it would catch the field-name detection gap flagged inworkflows.py(_tool_prompt_for_input_class).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tests/mcp/test_workflows.py` around lines 59 - 87, The MCP workflow tests currently validate only run_site_cable_validation and run_cumulus_hardware_validation, but they should also cover the site password rotation workflow since it is another site-level flow. Update test_site_level_filter_workflows_include_mcp_targeting_prompt and test_site_level_filter_workflows_default_reachable_statuses in test_workflows.py to include the password rotation tool_name from discover_mcp_workflows(), asserting it gets SITE_LEVEL_DEVICE_FILTER_PROMPT and DEFAULT_SITE_LEVEL_DEVICE_STATUS where appropriate. This will exercise the field-name detection path in _tool_prompt_for_input_class and catch the missing site-level handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/nv_config_manager/mcp/workflows.py`:
- Around line 120-121: The status defaulting in workflows.py is treating an
explicitly provided empty status list as missing. Update the logic in the
workflow input normalization path around _tool_prompt_for_input_class and
normalized["status"] so it checks for key presence instead of truthiness if
empty list should mean “no status filter”; otherwise keep the current behavior
intentionally.
In `@src/nv_config_manager/temporal/ngc/workflows/cumulus_hardware_validation.py`:
- Around line 962-973: The top-level message in cumulus_hardware_validation’s
device validation flow is falling back to a generic “No devices matched” string
even when get_devices_to_validate already produced the correct Cumulus-specific
display. Update the branch that sets message to always use
devices_to_validate_output.display for the no-devices case, and only use the
generic fallback when needed for truly empty/invalid-filter scenarios; keep the
logic anchored around get_devices_to_validate and the invalid_filter check.
---
Nitpick comments:
In `@src/tests/mcp/test_workflows.py`:
- Around line 59-87: The MCP workflow tests currently validate only
run_site_cable_validation and run_cumulus_hardware_validation, but they should
also cover the site password rotation workflow since it is another site-level
flow. Update test_site_level_filter_workflows_include_mcp_targeting_prompt and
test_site_level_filter_workflows_default_reachable_statuses in test_workflows.py
to include the password rotation tool_name from discover_mcp_workflows(),
asserting it gets SITE_LEVEL_DEVICE_FILTER_PROMPT and
DEFAULT_SITE_LEVEL_DEVICE_STATUS where appropriate. This will exercise the
field-name detection path in _tool_prompt_for_input_class and catch the missing
site-level handling.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 061c1e85-4038-46f5-ac7c-a3fe08b5fc2d
📒 Files selected for processing (19)
src/nv_config_manager/mcp/tools.pysrc/nv_config_manager/mcp/workflows.pysrc/nv_config_manager/temporal/client/nautobot.pysrc/nv_config_manager/temporal/ngc/activities/nautobot.pysrc/nv_config_manager/temporal/ngc/workflows/cable_validation.pysrc/nv_config_manager/temporal/ngc/workflows/cumulus_hardware_validation.pysrc/nv_config_manager/temporal/ngc/workflows/site_password_rotation.pysrc/tests/mcp/test_tools.pysrc/tests/mcp/test_workflows.pysrc/tests/temporal/ngc/activities/test_nautobot.pysrc/tests/temporal/ngc/workflows/test_cumulus_hardware_validation_workflow.pyui/src/app/workflows/cumulushardwarevalidationworkflow/form/cumulus-hardware-validation-form.tsxui/src/app/workflows/sitecablevalidationworkflow/form/site-cable-validation-workflow-form.tsxui/src/app/workflows/sitepasswordrotationworkflow/form/site-password-rotation-workflow-form.tsxui/src/lib/workflow-defaults.tsui/src/mocks/data/formData.tsui/src/types/data-table.types.tsui/tests/e2e/cumulusHardwareValidationForm.spec.tsui/tests/e2e/siteCableValidationForm.spec.ts
| if _tool_prompt_for_input_class(workflow.input_class) and not normalized.get("status"): | ||
| normalized["status"] = DEFAULT_SITE_LEVEL_DEVICE_STATUS.copy() |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
status default skipped on explicit empty list.
not normalized.get("status") treats an explicitly supplied status=[] as missing and overrides it with DEFAULT_SITE_LEVEL_DEVICE_STATUS. If a caller intends "no status filter," that intent is lost. If empty-means-default is intended, this is fine; otherwise prefer a presence check ("status" not in normalized).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/nv_config_manager/mcp/workflows.py` around lines 120 - 121, The status
defaulting in workflows.py is treating an explicitly provided empty status list
as missing. Update the logic in the workflow input normalization path around
_tool_prompt_for_input_class and normalized["status"] so it checks for key
presence instead of truthiness if empty list should mean “no status filter”;
otherwise keep the current behavior intentionally.
| filter_summary = format_filter_summary( | ||
| workflow_input.site, | ||
| workflow_input.roles, | ||
| workflow_input.status, | ||
| workflow_input.tenant, | ||
| workflow_input.device_type_ids, | ||
| ) | ||
| message = ( | ||
| devices_to_validate_output.display | ||
| if devices_to_validate_output.invalid_filter | ||
| else f"No devices matched the hardware validation filter ({filter_summary})." | ||
| ) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Top-level message can be inaccurate when devices matched but none were Cumulus.
When result.devices is non-empty but no Cumulus devices match, get_devices_to_validate returns devices=[] with invalid_filter=False and a precise display ("No Cumulus Linux devices matched..."). Here that branch falls through to the generic "No devices matched the hardware validation filter", which is misleading since devices did match the filter. The stage output already holds the correct message in devices_to_validate_output.display.
Proposed fix
- message = (
- devices_to_validate_output.display
- if devices_to_validate_output.invalid_filter
- else f"No devices matched the hardware validation filter ({filter_summary})."
- )
+ message = devices_to_validate_output.display📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| filter_summary = format_filter_summary( | |
| workflow_input.site, | |
| workflow_input.roles, | |
| workflow_input.status, | |
| workflow_input.tenant, | |
| workflow_input.device_type_ids, | |
| ) | |
| message = ( | |
| devices_to_validate_output.display | |
| if devices_to_validate_output.invalid_filter | |
| else f"No devices matched the hardware validation filter ({filter_summary})." | |
| ) | |
| filter_summary = format_filter_summary( | |
| workflow_input.site, | |
| workflow_input.roles, | |
| workflow_input.status, | |
| workflow_input.tenant, | |
| workflow_input.device_type_ids, | |
| ) | |
| message = devices_to_validate_output.display |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/nv_config_manager/temporal/ngc/workflows/cumulus_hardware_validation.py`
around lines 962 - 973, The top-level message in cumulus_hardware_validation’s
device validation flow is falling back to a generic “No devices matched” string
even when get_devices_to_validate already produced the correct Cumulus-specific
display. Update the branch that sets message to always use
devices_to_validate_output.display for the no-devices case, and only use the
generic fallback when needed for truly empty/invalid-filter scenarios; keep the
logic anchored around get_devices_to_validate and the invalid_filter check.
Description
Slated for 1.3.1 release
Validation
The kind integration test is manual due to taking ~30 min to complete. When the PR is ready for review,
run Actions -> Kind Integration -> Run workflow against the copy-pr-bot generated
pull-request/<PR_NUMBER>branch. Use the defaulttest_pathfor the full suite,or narrow it only while debugging.
Passing Kind Integration run:
Checklist
CONTRIBUTING.md.docs screenshots, or Helm/rendered outputs.
Summary by CodeRabbit
New Features
Bug Fixes
UI