refactor(iorails): Migrate RailResult to use RailOutcome for rail responses - #2286
Conversation
…IORails-specific metadata
Greptile SummaryThe PR migrates IORails rail verdicts to a shared
|
| Filename | Overview |
|---|---|
| nemoguardrails/guardrails/guardrails_types.py | Reworks RailResult as an immutable wrapper around RailOutcome and separates client-facing reasons from diagnostic metadata. |
| nemoguardrails/guardrails/rails_manager.py | Converts compiled and tool-rail outcomes into aggregated RailResult instances while preserving sequential and parallel orchestration. |
| nemoguardrails/guardrails/tool_rail_action.py | Aligns tool-rail return and fail-closed exception behavior with the shared RailOutcome contract. |
| nemoguardrails/guardrails/actions/tool_call_action.py | Migrates tool-call validation results from RailResult to allow/block RailOutcome factories. |
| nemoguardrails/guardrails/actions/tool_result_action.py | Migrates tool-result linkage, naming, and content validation to shared outcomes without changing validation semantics. |
| nemoguardrails/guardrails/rail_guard.py | Consolidates compiled-rail and tool-rail exception conversion around rail_error_outcome. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Compiled or tool rail] --> B[RailOutcome]
B --> C[RailResult wrapper]
C --> D[Safety decision]
C --> E[Client block reason]
C --> F[RailCallRecord]
F --> G[GenerationLog]
Reviews (2): Last reviewed commit: "Address coderabbit feedback" | Re-trigger Greptile
📝 WalkthroughWalkthroughRail validation now returns ChangesRailOutcome migration
Estimated code review effort: 4 (Complex) | ~45 minutes Mergeability Score: 🟠 High · up to The migration changes how rail verdicts are recorded, but caller-provided metadata can overwrite the computed safety decision, allowing blocked outcomes to be recorded as allowed. This concrete correctness and safety risk should be fixed before merge; the remaining test cleanup is localized. Sequence Diagram(s)sequenceDiagram
participant ToolRailAction
participant RailsManager
participant RailResult
ToolRailAction->>RailsManager: return RailOutcome
RailsManager->>RailResult: wrap outcome and attach records
RailsManager-->>RailResult: return allow or block result
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@nemoguardrails/guardrails/guardrails_types.py`:
- Around line 104-106: Update RailOutcome.return_value so metadata cannot
overwrite the reserved _VERDICT_DECISION_KEY: expand self.outcome.metadata
first, then assign the verdict using self.is_safe as the final value. Preserve
all non-reserved metadata entries in the returned dictionary.
In `@tests/guardrails/test_guardrails_types.py`:
- Around line 233-238: Replace the credit-card-like sentinel in REGEX_VERDICT
with a non-card test value, and update the corresponding withheld value in the
related test case so both remain consistent. Preserve the test’s purpose of
verifying that metadata is excluded from client_reason.
- Around line 224-229: Resolve both RUF012 findings for the CROWDSTRIKE_VERDICT
and REGEX_VERDICT class attributes by annotating them as ClassVar or replacing
the shared mutable mappings with fresh mappings created through a helper,
preserving their existing contents and behavior.
🪄 Autofix
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: 1027bc26-a9cb-4835-80e4-8e331e527631
📒 Files selected for processing (23)
nemoguardrails/guardrails/actions/tool_call_action.pynemoguardrails/guardrails/actions/tool_result_action.pynemoguardrails/guardrails/guardrails_types.pynemoguardrails/guardrails/rail_guard.pynemoguardrails/guardrails/rails_manager.pynemoguardrails/guardrails/tool_rail_action.pytests/guardrails/test_guardrails_types.pytests/guardrails/test_iorails.pytests/guardrails/test_iorails_check.pytests/guardrails/test_iorails_generation_log.pytests/guardrails/test_iorails_generation_response.pytests/guardrails/test_iorails_reasoning.pytests/guardrails/test_iorails_streaming.pytests/guardrails/test_iorails_telemetry.pytests/guardrails/test_rail_guard.pytests/guardrails/test_rails_manager.pytests/guardrails/test_request_id.pytests/guardrails/test_speculative_generation.pytests/guardrails/test_tool_call_action.pytests/guardrails/test_tool_rail_action.pytests/guardrails/test_tool_rails_e2e.pytests/guardrails/test_tool_result_action.pytests/guardrails/tool_helpers.py
|
Have to merge myself since Pouyan is OOO |
Description
This PR migrates the IORails specific
RailResultto wrap theRailOutcomeobjects intended for use across both LLMRails and IORails.This PR is part of a stack shown below, but isn't implemented using Github's stacks feature since all preceeding PRs are already merged to develop.
PR 1 #2241
PR 2 #2246
PR 3a #2253
PR 3b #2261 . Builds on the #2253 and migrates from RailAction subclasses to CompiledRail implementations for all currently-supported actions.
PR 4 #2264 enable the 49 block-only input/output surfaces via catalog-derived gating
PR 4.5 THIS PR #2286 Use RailOutcome instead of RailResult
PR 5 transform surfaces (18): RailResult.transforms, rewrite threading, MODIFIED status
PR 6 model_caches response-cache parity with LLMRails
Related Issue(s)
Verification
Pre-commit
Unit-test
Integration test with Chat
AI Assistance
Checklist
Summary by CodeRabbit