Repository navigation
fix(loop-host): repair unavailable capability calls without aborting runs - #7551
Conversation
|
🚅 Deployed to the ironclaw-pr-7551 environment in ironclaw-ci-preview
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe model gateway no longer suppresses provider calls because a named capability is unavailable. It validates calls against advertised or resolvable capabilities and treats outside-surface tool results as repairable. Tests cover discovery ordering, valid calls, decimal prose, and repair retries. ChangesProvider tool validation and repair
Estimated code review effort: 3 (Moderate) | ~20 minutes Mergeability Score: ⚪ Minimal · up to The change repairs unavailable capability calls while preserving atomic rejection of invalid batches; no actionable merge-blocking risk remains beyond normal checks and review. Sequence Diagram(s)sequenceDiagram
participant Model
participant ModelGateway
participant CapabilityPort
Model->>ModelGateway: submit provider tool call
ModelGateway->>CapabilityPort: validate advertised or resolvable capability
CapabilityPort-->>ModelGateway: return validation result
ModelGateway-->>Model: return repairable tool-output error
Model->>ModelGateway: submit recovered capability call
ModelGateway-->>Model: register recovered call
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
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: 1
🤖 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 `@crates/loop/ironclaw_loop_host/src/model_gateway.rs`:
- Around line 1427-1430: Complete the Track C review record for the
capability-admission change around unavailable_requested_capability_guard and
requested_capability_is_resolvable: document the rollback plan, confirm two
required approvals, and confirm green CI before merge.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 0fb070d4-cfb4-43ac-b224-880e690279cb
📒 Files selected for processing (2)
crates/loop/ironclaw_loop_host/src/model_gateway.rscrates/loop/ironclaw_loop_host/tests/llm_gateway.rs
🧭 IronLoop Run · ReviewThis comment updates in place as the Run moves through its stages. 🟩 Final result · Completed
Automatic trigger · attempt 1 of 3 · completed in 5m 46s IronLoop completed the review and posted it to GitHub. 🔗 Result |
There was a problem hiding this comment.
🔍 IronLoop review
One medium-severity regression found in mixed deferred/unknown capability requests.
Findings: 🟠 Medium 1
🟠 Medium · Retain suppression for later unresolved named capabilities
Inline on crates/loop/ironclaw_loop_host/src/model_gateway.rs:1430. See the inline comment for details.
Validation
- ✅ Diff integrity — No whitespace errors found in the reviewed change.
- ⚪ Focused regression test — Not run. The run-local Rust build did not complete during the review.
Review details
- Run:
5fdfec82-d82b-405a-829e-dca11b6bfeb7 - Workflow: Review
- Attempts: 1
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/loop/ironclaw_loop_host/src/model_gateway.rs (1)
2005-2033: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winAdd caller coverage for malformed capability probes.
The failed port-resolution path is covered. Add a
stream_model_with_capabilitiestest for a validCapabilityIdwhose encoded provider name exceedsProviderToolName::MAX_BYTES. Assert that the probe stays unresolved and no substitute call is registered. This preserves the “Everything Goes Through Tools” and “Test through the caller” invariants.🤖 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 `@crates/loop/ironclaw_loop_host/src/model_gateway.rs` around lines 2005 - 2033, Add caller-level coverage in stream_model_with_capabilities for a valid CapabilityId whose encoded provider name exceeds ProviderToolName::MAX_BYTES. Assert the malformed availability probe remains unresolved and verify that no substitute call is registered, preserving the existing “Everything Goes Through Tools” behavior through the caller rather than testing requested_capability_is_resolvable directly.Source: Path instructions
🤖 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.
Outside diff comments:
In `@crates/loop/ironclaw_loop_host/src/model_gateway.rs`:
- Around line 2005-2033: Add caller-level coverage in
stream_model_with_capabilities for a valid CapabilityId whose encoded provider
name exceeds ProviderToolName::MAX_BYTES. Assert the malformed availability
probe remains unresolved and verify that no substitute call is registered,
preserving the existing “Everything Goes Through Tools” behavior through the
caller rather than testing requested_capability_is_resolvable directly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 6f864fd8-6815-4a1c-86fa-c507aadce586
📒 Files selected for processing (2)
crates/loop/ironclaw_loop_host/src/model_gateway.rscrates/loop/ironclaw_loop_host/tests/llm_gateway.rs
Railway preview QA — BLOCKED
Given / When / Then matrix
Status derivation
Regression result and diagnosticsThis QA run is scoped only to PR #7551 and the capabilities configured in its own preview. The earlier The live behavior was user-friendly: the explicitly requested valid operations completed, and the assistant clearly reported that No persistence or refresh case was relevant. No external extension setup was performed; CleanupComplete. Removed all three |
|
Corrected the runtime contract in 93ae624 based on the clarified expected behavior. The prompt-text suppression guard has been removed: mentioning an unavailable capability no longer suppresses valid calls. An actual provider call outside the capability surface remains fail-closed before registration, but now enters the existing one-shot repair loop so the model can retry with an available capability or answer directly. This supersedes the earlier mixed-request suppression expectation; the replacement caller-path regressions pass along with the full |
Railway preview QA — BLOCKED
PromptsRequired natural-language journey:
Supplemental natural-language repeat:
Given / When / Then matrix
Status derivation
Regression resultThe preview did not reproduce the original run-aborting behavior. A request combining a valid operation with an unavailable email function completed normally, returned the valid result, and gave a clear user-facing explanation. However, all observed provider calls were valid, so this live run cannot prove that an actual unknown provider call receives the new one-shot repair feedback. The deterministic gateway regression tests remain the evidence for that internal seam. Skipped and remaining risk
Cleanup
|
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
…runs (nearai#7551) * fix(loop-host): resolve deferred capabilities before guard * fix(loop-host): retain mixed-request suppression (nearai#7551) * fix(loop-host): repair unavailable capability calls * test(loop-host): assert gateway repair feedback
Summary
Change Type
Linked Issue
Related #7163
Validation
cargo fmt --all -- --checkcargo clippy -p ironclaw_loop_host --all-targets --all-features -- -D warningscargo build(covered by the crate test and clippy builds)cargo test -p ironclaw_loop_hostOutsideCapabilitySurfacepath and reproduced it deterministically at the provider-to-capability registration seamTest Strategy
User behavior: naming a capability that is not available does not abort the run. Valid provider calls may continue. If the provider actually calls an unavailable capability, IronClaw rejects the batch before registration, gives the model repair feedback, and accepts a valid retry or direct answer.
Risk areas:
Tests added or updated:
What the tests prove:
Commands run:
Security Impact
Capability availability remains enforced by the decorated capability port against the provider's actual tool calls. Unknown calls remain fail-closed and are never registered or executed. The change removes heuristic policy decisions based on untrusted natural-language parsing and converts the resulting model-correctable failure into bounded repair feedback.
Reborn Trust-Boundary Checklist
InvalidOutputReason::OutsideCapabilitySurfaceclassification is reused.Database Impact
None.
Blast Radius
Limited to model-gateway handling of provider tool output. The existing one-shot repair path now also covers outside-surface calls. A rejected batch remains atomic, and a failed repair retains the existing terminal error behavior.
Rollback Plan
Revert commit
93ae624e80(or the eventual PR merge commit). This restores the prompt-text suppression guard and removes outside-surface repair. No data migration or compatibility action is required.Review Follow-Through
Track C still requires two approvals and green CI before merge. The separate NEAR AI streaming-header timeout observed in the original Railway logs is outside this fix.
Review track: C (security/runtime guard behavior)