Skip to content

feat(cli)!: add MCP-managed shared gateway for coding agents#395

Merged
rapids-bot[bot] merged 106 commits into
NVIDIA:mainfrom
willkill07:wkk_relay-447-codex-bootstrap
Jul 15, 2026
Merged

feat(cli)!: add MCP-managed shared gateway for coding agents#395
rapids-bot[bot] merged 106 commits into
NVIDIA:mainfrom
willkill07:wkk_relay-447-codex-bootstrap

Conversation

@willkill07

@willkill07 willkill07 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Warning

BREAKING CHANGE: [Plugin configuration and installation] Existing
Codex, Claude Code, and Hermes Relay integrations must be reinstalled. Generated
MCP entries now invoke nemo-relay mcp, persistent hooks are agent-owned and
generation-fenced, and the shared gateway uses user-scoped configuration.
Run nemo-relay install <agent> --force for each installed integration, or
nemo-relay install all --force. Previously generated integration state is
not compatible with the new lifecycle and may fail readiness or doctor checks.

Overview

Add an MCP-managed shared Relay gateway for Codex, Claude Code, and Hermes. The new lifecycle guarantees that Relay is ready before installed coding agents emit hooks or routed provider traffic, fixing RELAY-447.

Codex plugin ---------\
Claude Code plugin ----+--> Relay MCP --> Relay Gateway --> Model provider
Hermes user config ----/       stdio        127.0.0.1:47632

nemo-relay mcp eagerly starts or adopts the existing Rust gateway before reading MCP input, heartbeats it while stdio is open, and coordinates one recovery. Codex, Claude Code, and Hermes use the same lifecycle model.

  • I confirm this contribution is my own work, or I have the right to submit it under this project's license.
  • I searched existing issues and open pull requests, and this does not duplicate existing work.

Details

Problems addressed
  • Cold sessions could lose their first hook or provider request because Relay was not guaranteed to be listening.
  • Concurrent hosts could race startup, adopt a foreign listener, or perform independent recoveries.
  • Codex, Claude Code, and Hermes used inconsistent MCP, hook, trust, and environment-forwarding paths.
  • Persisted plugin state and generation markers needed explicit ownership boundaries before authorizing destructive cleanup.
  • Agent-specific CLI behavior was spread across top-level adapter, alignment, plugin-host, installer, and Hermes modules.
New behavior
  • nemo-relay mcp acquires the gateway before MCP initialization and advertises no tools.
  • Multiple MCP processes share one authenticated fixed-port gateway with readiness fencing, heartbeats, idle shutdown, and one coordinated recovery.
  • Persistent hooks are forward-only and use the MCP-owned gateway.
  • Codex uses plugin-owned hook discovery and transactional trust rollback; Claude Code uses alwaysLoad; Hermes uses the same MCP lifecycle and canonical hooks.
  • Generated MCP configuration forwards approved environment variable names, never values.
  • Launch-status observability destinations support ATOF v2 file and stream sinks while redacting stream URL credentials and query values.
  • Plugin cleanup accepts only the selected install layout and its canonical generation lock or constrained sibling legacy lock.
  • Child ownership is retained until the detached gateway waiter starts; thread-creation failure terminates and reaps the child.
Component breakdown
Component Responsibility Start here
Command layer Thin subcommand executors, dispatch, rendering, and exit codes crates/cli/src/commands/
Agent integrations Codex, Claude Code, and Hermes descriptors, adapters, alignment, hooks, trust, setup, and installation crates/cli/src/agents/
MCP coordinator Eager gateway acquisition, heartbeat, and one recovery crates/cli/src/mcp/gateway.rs
Existing gateway server Identity, readiness, activity, idle shutdown, and ownership cleanup crates/cli/src/server.rs
Bootstrap coordinator Startup locking, readiness, adoption, and recovery crates/cli/src/bootstrap/
Gateway client Authenticated health, shutdown, and verified delivery crates/cli/src/gateway/client.rs
Detached processes Cross-platform detach, termination, and reaping crates/cli/src/process/detached.rs
Acceptance evidence Behavior and dependency-boundary coverage outside src/ crates/cli/tests/

The CLI source now has two explicit ownership axes. commands/ owns command execution; agents/ owns agent vertical slices and shared installation transactions. Gateway, MCP transport, sessions, bootstrap lifecycle, and runtime configuration remain agent-neutral. Architecture tests prevent retired top-level agent trees from returning and prohibit shared-service-to-command and cross-agent dependencies.

Compatibility and limitations
  • Public CLI syntax, generated plugin artifacts, configuration paths, hook payloads, trust state, and runtime behavior are unchanged by the source-layout refactor.
  • Codex can request /models before launching required MCP servers; captured turns and routed provider requests still wait for readiness.
  • Hook delivery remains fail-open by default and is not crash-consistent exactly-once delivery after server acceptance.
  • Real-host E2Es remain opt-in so Rust CI does not require agent CLIs.
Validation
  • cargo fmt --all
  • cargo clippy --workspace --all-targets -- -D warnings
  • just test-rust (992 CLI unit tests and 80 external CLI process tests, plus the complete Rust workspace)
  • uv run pre-commit run --all-files
  • cargo test -p nemo-relay-cli --test architecture_tests
  • Existing opt-in results on this branch: 10 cold and 2 concurrent real Codex runs; 10 cold and 2 concurrent real Claude Code runs. Hermes was unavailable, with its Rust/install/platform coverage passing.

Where should the reviewer start?

Review in four bounded passes:

  1. Read crates/cli/src/commands/mod.rs and its thin executor modules to verify unchanged dispatch and exit behavior.
  2. Read crates/cli/src/agents/mod.rs, then one host directory at a time. Verify agent-specific adapters, alignment, hooks, trust, and setup are colocated.
  3. Read crates/cli/src/mcp/gateway.rs, bootstrap/mod.rs, gateway/client.rs, process/detached.rs, and server/mod.rs for eager acquisition, authenticated adoption, recovery, and idle shutdown.
  4. Use crates/cli/tests/architecture_tests.rs and the grouped coverage directories as the acceptance specification.

The key runtime boundary remains: hosts own MCP stdio, MCP coordinates liveness, and the existing Relay gateway owns server lifecycle.

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

  • Relates to RELAY-447

Bugs addressed

Gateway bootstrap and lifecycle

  • Prevents the first lifecycle hook or provider request from being lost during a cold agent launch.
  • Starts the Relay gateway when nemo-relay mcp starts, before waiting for MCP initialization.
  • Prevents concurrent MCP clients from racing to start separate gateways.
  • Prevents one MCP client exiting from terminating a gateway still used by other clients.
  • Serializes gateway recovery so multiple clients do not independently restart a failed gateway.
  • Limits recovery to one coordinated attempt and reports failure cleanly afterward.
  • Prevents adoption of an unrelated process that happens to return HTTP 200 on Relay’s port.
  • Rejects incompatible Relay versions or bootstrap protocols on the configured endpoint.
  • Detects stale gateway ownership and readiness records.
  • Eliminates the reserve/drop/bind port race through a readiness-file handshake.
  • Ensures port-zero servers can safely publish their actual bound address.
  • Retains the gateway for the configured idle period after the final MCP client exits.
  • Prevents ordinary health checks from incorrectly extending the managed gateway lifetime.
  • Cleans ownership records only when they belong to the terminating gateway.
  • Rejects non-loopback endpoints for persistent managed gateways.

Hooks and event delivery

  • Removes hook-only gateway startup, which could never guarantee readiness before the first hook.
  • Makes persistent hooks forward-only so hooks cannot unexpectedly create or recover services.
  • Prevents transparent nemo-relay run sessions from also invoking persistent hooks and duplicating events.
  • Prevents duplicate Relay hook handlers from user and plugin hook sources.
  • Removes legacy Relay user-hook groups during upgrades while preserving unrelated hooks.
  • Verifies that exactly one effective Relay handler exists for every expected event.
  • Uses canonical executable paths and platform-correct quoting for hook commands.
  • Correctly handles executable paths containing spaces and shell metacharacters.
  • Prevents hooks from accidentally using ambient HTTP proxy settings for loopback delivery.
  • Preserves fail-open and fail-closed behavior without retrying ambiguous accepted requests.
  • Bounds hook request and response payloads.
  • Ensures a forwarded hook cannot reconnect and redeliver after an authenticated connection closes.

Codex correlation

  • Prefers client_metadata.session_id for Codex root-session correlation.
  • Retains prompt_cache_key as a compatibility fallback.
  • Uses client_metadata.thread_id as subagent ownership for collab_spawn.
  • Keeps review, compaction, memory, and other internal calls under the root session.
  • Preserves explicit Relay session and subagent header precedence.
  • Prevents internal Codex operations from creating unmatched subagent scopes.
  • Correctly aligns concurrent root and child provider traffic with Codex hook sessions.

Installation, trust, and rollback

  • Prevents Codex installation from trusting unrelated user, project, or third-party plugin hooks.
  • Discovers and trusts only exact generated hooks from the Relay Codex plugin.
  • Verifies trust after writing it.
  • Restores every original Codex trust state if installation fails.
  • Preserves trusted, modified, disabled, and absent hook states exactly during rollback.
  • Aggregates rollback failures with the original installation error.
  • Performs trust cleanup while plugin metadata is still discoverable.
  • Preserves original configuration, hooks, backups, permissions, and trust after failed installation.
  • Prevents repeated installation from overwriting the original user backup.
  • Preserves user changes made after installation during uninstall or restoration.
  • Prevents stale or malformed backups from restoring managed Relay values incorrectly.
  • Enforces Claude Code alwaysLoad configuration and validates it during diagnosis.
  • Preserves user-owned Hermes MCP servers, hook entries, allowlists, and unrelated configuration.
  • Prevents Relay from claiming manually configured same-named Hermes integrations.
  • Restores Hermes configuration, trust, generation state, and permissions after failed installation.

Filesystem and ownership safety

  • Prevents a corrupted generation marker from selecting an arbitrary external file for deletion.
  • Requires generation locks to match the selected installation’s canonical layout or a constrained legacy sibling.
  • Prevents persisted marketplaceRoot or pluginRoot values from granting recursive deletion authority over arbitrary directories.
  • Canonicalizes persisted installation paths before using them for destructive operations.
  • Validates that installation state belongs to the selected agent and layout.
  • Preserves unrelated files and directories during force-install and uninstall.
  • Uses bounded reads for configuration, state, identity, and readiness files.
  • Applies private permissions to secret-bearing configuration and ownership state.
  • Serializes installation operations and generation transitions.

Process management

  • Prevents an unreaped gateway child if waiter-thread creation fails.
  • Retains child ownership until the waiter thread has successfully started.
  • Terminates and reaps the child when waiter creation fails.
  • Improves detached-process termination and reaping across Unix and Windows.
  • Preserves interactive terminal job control for transparent agent launches.
  • Forwards termination to the complete agent process tree.
  • Cleans temporary files and launch resources after success, failure, or interruption.

Environment propagation

  • Prevents provider credentials from disappearing when an agent launches Relay through MCP.
  • Forwards standard Relay, OTLP, AWS, proxy, and certificate environment variable names.
  • Includes approved installed variables under NEMO_RELAY_, OTEL_, and AWS_.
  • Includes configuration-referenced header_env, AWS secret-key, and session-token variables.
  • Excludes internal worker tokens, sockets, ownership variables, binary overrides, and readiness plumbing.
  • Stores only variable names in MCP configuration, never secret values.
  • Diagnoses stale generated environment lists and recommends forced reinstall.

New features

  • Adds the Rust-native nemo-relay mcp command.

  • Makes nemo-relay mcp a lifecycle coordinator rather than a tool-serving MCP implementation.

  • Advertises no MCP tools while keeping the MCP stdio session alive.

  • Supports the architecture:

    Codex / Claude Code / Hermes
                |
            Relay MCP
                |
          Relay Gateway
                |
          Model provider
    
  • Starts or adopts a detached Rust nemo-relay --bind 127.0.0.1:47632 gateway.

  • Allows multiple Codex, Claude Code, and Hermes MCP processes to share one gateway.

  • Starts gateway acquisition immediately when MCP stdio opens.

  • Heartbeats the gateway while MCP remains connected.

  • Performs one coordinated gateway recovery after failure.

  • Adds authenticated gateway health, shutdown, hook-delivery, and ownership operations.

  • Extends /healthz with Relay identity, version, protocol, and compatibility information.

  • Adds readiness-file reporting for automatically assigned ports.

  • Uses system and user Relay configuration for persistent plugin mode.

  • Keeps project-specific configuration available through transparent nemo-relay run.

  • Adds a consistent persistent MCP lifecycle for Codex, Claude Code, and Hermes.

  • Adds generated MCP environment-forwarding declarations for all three agents.

  • Adds plugin-owned Codex hooks with automatic, verified trust management.

  • Adds Claude Code plugin activation through alwaysLoad.

  • Adds Hermes MCP, hook, trust, generation, install, uninstall, and doctor integration.

  • Adds shared gateway idle shutdown after the final MCP client disconnects.

  • Adds generation-fenced hook and MCP identities to prevent stale installations from controlling a replacement gateway.

  • Adds opt-in cold-start and concurrency E2E suites for Codex, Claude Code, and Hermes.

Improvements

Architecture and readability

  • Reorganizes the CLI around two explicit ownership axes:

    • commands/ owns CLI syntax, validation, dispatch, rendering, and exit codes.
    • agents/ owns Codex, Claude Code, and Hermes behavior.
  • Adds an internal library root with a minimal process entrypoint.

  • Reduces main.rs to the application entrypoint.

  • Moves all Clap-derived types under commands/.

  • Makes all a command-only install target instead of a runtime agent identity.

  • Replaces command-shaped configuration DTOs with subsystem-owned runtime inputs.

  • Gives Codex, Claude, and Hermes complete vertical slices for launch, hooks, assets, trust, setup, installation, and diagnosis.

  • Removes obsolete horizontal adapter, alignment, host, installer, and plugin-shim facades.

  • Removes the production Node bootstrap path; gateway bootstrap is entirely Rust-native.

  • Separates launch preparation from shared process supervision.

  • Separates gateway startup coordination from gateway transport and server execution.

  • Separates detached process handling from bootstrap ownership.

  • Splits gateway routing, request preparation, response handling, and authenticated client transport.

  • Splits session routing, correlation, ownership, and idle shutdown.

  • Splits configuration, diagnostics, filesystem operations, hooks, installation transactions, and plugin services by responsibility.

  • Keeps agent-neutral installation primitives free of host selection.

  • Centralizes concrete agent dispatch in agents/mod.rs.

  • Makes relative persistent output paths deterministic by starting the gateway from the user configuration directory.

Security and transactional integrity

  • Adds authenticated client proofs for managed gateway operations.
  • Adds generation fencing around installation and runtime ownership.
  • Adds staging, promotion, snapshot, rollback, and verification boundaries.
  • Validates destructive paths before rename or recursive removal.
  • Preserves unrelated configuration and plugin state throughout migration.
  • Keeps environment values out of generated MCP manifests.
  • Tightens permissions on sensitive files.
  • Rejects malformed, oversized, stale, foreign, or ambiguous ownership records.

Diagnostics and operator experience

  • Expands doctor checks for:

    • agent versions;
    • generated MCP configuration;
    • expected environment variable names;
    • gateway compatibility;
    • plugin hook discovery;
    • hook trust;
    • generation identity;
    • canonical paths;
    • Claude alwaysLoad;
    • Hermes trust and allowlist state.
  • Provides actionable reinstall remediation when generated state is stale.

  • Distinguishes foreign listener conflicts from compatible Relay reuse.

  • Preserves existing CLI output, JSON schemas, aliases, paths, and exit behavior.

  • Documents operational hook-forward flags directly in CLI help without brittle prose-pinning tests.

Testing and quality

  • Keeps all tests outside the src/ tree.

  • Increases the CLI suite to 995 unit tests plus 80 process-level tests.

  • Adds architecture tests that enforce command, agent, and shared-service dependency boundaries.

  • Adds coverage for:

    • simultaneous MCP clients;
    • cold gateway startup;
    • compatible gateway adoption;
    • foreign listener rejection;
    • coordinated recovery;
    • idle shutdown;
    • readiness handshakes;
    • hook generation and quoting;
    • trust rollback;
    • hostile persisted state;
    • environment forwarding;
    • installation rollback;
    • process reaping;
    • Codex root and subagent metadata correlation;
    • Claude and Hermes lifecycle parity;
    • Unix and Windows behavior.
  • Adds real-agent opt-in E2Es without making Codex, Claude Code, or Hermes mandatory Rust CI dependencies.

  • Adds ten-cold-run and concurrent-session coverage for Codex and Claude Code.

  • Adds a Hermes MCP E2E target for environments where Hermes is installed.

  • Enforces CLI coverage through Codecov while avoiding artificial help-text or environment-name tests.

  • Adds test serialization for process-global environment and working-directory mutations.

  • Restores cross-platform compilation and coverage-module visibility after the CLI reorganization.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Added native MCP gateway support with stdio-based MCP handling, lifecycle management, and updated MCP protocol negotiation.
    • Enhanced Codex/Claude Code/Hermes install, run, and doctor flows with Codex MCP server/config generation.
    • Added hook-forwarding CLI support for transparent (run-local) and persistent (installed) delivery modes.
  • Bug Fixes
    • Improved hook-forwarding reliability (retry classification, fail-open/fail-closed handling) and safer rollback on failures.
    • Added Codex hook trust reporting and trust-aware uninstall cleanup.
  • Documentation
    • Updated marketplace/plugin descriptions and MCP metadata to match the new workflows.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

An error occurred during the review process. Please try again later.

Walkthrough

This PR restructures the CLI into an agents/ module (Claude Code, Codex, Hermes) with per-agent install/launch/trust logic, adds a native nemo-relay mcp gateway client with bootstrap/lifecycle management and a pinned per-user TLS identity for the authenticated bootstrap tunnel, reworks hook forwarding, gateway routing, and session correlation, adds Codex app-server trust verification and MCP packaging, and expands test coverage broadly.

Changes

Codex plugin_shim trust flow and MCP packaging

Layer / File(s) Summary
Hook forward retry rework
crates/cli/src/plugin_shim/mod.rs, crates/cli/src/plugin_shim/shared.rs
Reworks retry semantics via HookForwardError, sidecar lock/start timeouts, and Codex hook-trust doctor reporting.
Codex app-server trust client
crates/cli/src/plugin_shim/codex.rs
Adds install/uninstall trust snapshotting, CodexHookTrustReport, and auto_trust_codex_hooks verification.
Codex MCP config generation
crates/cli/src/plugin_install/marketplace.rs, crates/cli/src/plugin_install/mod.rs, crates/cli/src/plugin_install/setup.rs
Generates plugin_mcp_config, validates relay MCP support, updates Codex setup description.
Codex/MCP trust tests
crates/cli/tests/coverage/plugin_shim_tests.rs, crates/cli/tests/coverage/installer_tests.rs, crates/cli/tests/coverage/plugin_install_tests.rs
Adds/updates unit and integration tests for trust, MCP validation, install/uninstall.

Estimated code review effort: 5 (Critical) | ~180 minutes

Persistent agent integration platform

Layer / File(s) Summary
Agent abstraction
crates/cli/src/agents/mod.rs, crates/cli/src/agents/shared/*
Defines CodingAgent, MarketplaceHost, and shared adapter/alignment/host helpers plus events/json_path.rs.
Claude Code integration
crates/cli/src/agents/claude/*
Adds install/host/launch/adapter/alignment logic.
Codex integration
crates/cli/src/agents/codex/*
Adds app-server client, host trust reporting, hook-hash generation.
Hermes integration
crates/cli/src/agents/hermes/*
Adds config generation, filesystem locking, install/integration/launch/trust.
Hook forwarding and env forwarding
crates/cli/src/hooks/*, crates/cli/src/mcp_environment.rs
Adds delivery/destination/encoding/merging/response modules and forwarding rules.
Native MCP client, bootstrap, and TLS identity
crates/cli/src/mcp/*, crates/cli/src/bootstrap/*, crates/cli/src/gateway/tls.rs, crates/cli/src/gateway/client.rs
Adds stdio protocol/session/transport, gateway lease, bootstrap state, authenticated gateway client, and pinned self-signed TLS identity for the bootstrap tunnel.
Gateway and session management
crates/cli/src/gateway/*, crates/cli/src/sessions/*
Reworks request/response/routing and session correlation, including provider-forwarding/env-auth threading.
Server, process, and CLI wiring
crates/cli/src/server/*, crates/cli/src/process/*, crates/cli/src/commands/*, crates/cli/src/configuration/*, crates/cli/src/diagnostics/*, crates/cli/src/filesystem/*, crates/cli/src/installation/*, crates/cli/src/plugins/*
Adds server lifecycle, process supervision, CLI commands, config resolution, and plugin lifecycle/schema/pricing.

Test coverage for restructured CLI

Layer / File(s) Summary
Architecture and e2e tests
crates/cli/tests/architecture_tests.rs, crates/cli/tests/cli_tests.rs
Adds module boundary invariants and expands CLI integration tests.
Agents coverage
crates/cli/tests/coverage/agents/*
Adds adapter/alignment/coding-agent/hermes/launcher/plugin coverage.
Commands coverage
crates/cli/tests/coverage/commands/*
Adds tests for CLI dispatch and model-pricing commands.
Shared infrastructure coverage
crates/cli/tests/coverage/shared/*, crates/cli/tests/fixtures/*, crates/core/tests/unit/plugin_tests.rs, crates/ffi/tests/integration/plugin_activation_tests.rs
Adds broad coverage for process, gateway, hooks, mcp, plugins, server, session, config, TLS identity, and native FFI activation fixtures.

Documentation and packaging assets

Layer / File(s) Summary
Docs and package metadata
ATTRIBUTIONS-Rust.md, codecov.yml, crates/cli/Cargo.toml, .config/nextest.toml, justfile, integrations/coding-agents/*
Updates dependency attributions, coverage config, Cargo dependencies, CI overrides, packaged manifests/hooks, and e2e test targets.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 59.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title follows Conventional Commits and accurately summarizes the MCP-managed shared gateway change.
Description check ✅ Passed The description includes the required overview, details, reviewer start, and issue sections, though the related-issue format is slightly different.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:XL PR is extra large Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code labels Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

@willkill07
willkill07 force-pushed the wkk_relay-447-codex-bootstrap branch from 37d6608 to d8740a1 Compare July 9, 2026 02:05
@willkill07 willkill07 added this to the 0.6 milestone Jul 9, 2026
@willkill07 willkill07 self-assigned this Jul 9, 2026
@willkill07 willkill07 changed the title fix: harden Codex lazy bootstrap fix(codex): harden Codex lazy bootstrap Jul 9, 2026
@willkill07
willkill07 marked this pull request as ready for review July 9, 2026 14:06
@willkill07
willkill07 requested review from a team and lvojtku as code owners July 9, 2026 14:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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/cli/src/plugin_shim/shared.rs`:
- Around line 41-60: The sidecar lock acquisition loop in shared.rs can time out
before stale-lock recovery becomes eligible, so adjust the timing constants used
by ensure_sidecar and related lock handling: either increase
SIDECAR_LOCK_TIMEOUT to be at least as long as STALE_LOCK_AFTER, or reduce the
stale threshold so repair_stale_lock can reclaim an orphaned lock within the
same call. Keep the behavior around fs::create_dir, healthz, repair_stale_lock,
and sidecar_start_error consistent so retryable hook calls do not fail early
with “sidecar lock timed out”.

In `@README.md`:
- Around line 123-126: The README warning uses trust-state wording too broadly
and should match CodexHookTrustReport terminology. Update the text around the
install and doctor guidance so it distinguishes modified hooks from untrusted
hooks instead of collapsing them into one state, and make sure the wording
matches what nemo-relay doctor actually reports for generated, modified, and
manual/source-marketplace hooks.
🪄 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: ASSERTIVE

Plan: Enterprise

Run ID: f2e7bcd6-9e1a-48bf-93b6-e41075a2cd5d

📥 Commits

Reviewing files that changed from the base of the PR and between c83c8f2 and 1c9106d.

📒 Files selected for processing (11)
  • README.md
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
  • crates/cli/tests/coverage/server_tests.rs
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
📜 Review details
🧰 Additional context used
📓 Path-based instructions (25)
**/*.{md,rst,html,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

**/*.{md,rst,html,txt}: Always spell NVIDIA in all caps. Do not use Nvidia, nvidia, nVidia, nVIDIA, or NV.
Use an NVIDIA before a noun because the name starts with an 'en' sound.
Do not add a registered trademark symbol after NVIDIA when referring to the company.
Use trademark symbols with product names only when the document type or legal guidance requires them.
Verify official capitalization, spacing, and hyphenation for product names.
Precede NVIDIA product names with NVIDIA on first mention when it is natural and accurate.
Do not rewrite product names for grammar or title-case rules.
Preserve third-party product names according to the owner's spelling.
Include the company name and full model qualifier on first use when it helps identify the model.
Preserve the official capitalization and punctuation of model names.
Use shorter family names only after the full name is established.
Spell out a term on first use and put the acronym in parentheses unless the acronym is widely understood by the intended audience.
Use the acronym on later mentions after it has been defined.
For long documents, reintroduce the full term if readers might lose context.
Form plurals of acronyms with s, not an apostrophe, such as GPUs.
In headings, common acronyms can remain abbreviated. Spell out the term in the first or second sentence of the body.
Common terms such as CPU, GPU, PC, API, and UI usually do not need to be spelled out for developer audiences.

Files:

  • README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,rst,html}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

Link the first mention of a product name when the destination helps the reader.

Files:

  • README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,rst,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

Spell NVIDIA in all caps. Do not use Nvidia, nvidia, or NV.

Files:

  • README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,rst}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

**/*.{md,rst}: Format commands, code elements, expressions, package names, file names, and paths as inline code.
Use descriptive link text. Avoid raw URLs and weak anchors such as "here" or "read more."
Use title case consistently for technical documentation headings.
Introduce code blocks, lists, tables, and images with complete sentences.
Write procedures as imperative steps. Keep steps parallel and split long procedures into smaller tasks.
Prefer active voice, present tense, short sentences, contractions, and plain English.
Use can for possibility and reserve may for permission.
Use after for temporal relationships instead of once.
Prefer refer to over see when the wording points readers to another resource.
Avoid culture-specific idioms, unnecessary Latinisms, jokes, and marketing exaggeration in technical docs.
Spell out months in body text, avoid ordinal dates, and use clear time zones.
Spell out whole numbers from zero through nine unless they are technical values, parameters, versions, or UI values.
Use numerals for 10 or greater and include commas in thousands.
Do not add trademark symbols to learning-oriented docs unless the source, platform, or legal guidance explicitly requires them.

Files:

  • README.md
  • integrations/coding-agents/codex/README.md
**/*.md

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-technical-docs.md)

**/*.md: Use title case consistently in technical documentation headings
Avoid quotation marks, ampersands, and exclamation marks in headings
Keep product, event, research, and whitepaper names in their official title case
Use title case for table headers
Do not force social-media sentence case into technical docs
Format code elements, commands, parameters, package names, and expressions in monospace
Format directories, file names, and paths in monospace using backticks
Use angle brackets inside monospace for variables inside paths, such as /home/<username>/.login
Format error messages and strings in quotation marks, keeping literal code strings in code formatting when clearer
Format UI buttons, menus, fields, and labels in bold
Use angle brackets between UI labels for menu paths, such as File > Save As
Use italics for new terms on first use, sparingly and only when introducing the term
Use italics for publication titles
Format keyboard shortcuts in plain text, such as Press Ctrl+Alt+Delete
Use owner/repo link text for GitHub repositories, preferring [NVIDIA/NeMo](link) over prose references like 'the GitHub repo'
Introduce every code block with a complete sentence
Do not make a code block complete the grammar of the previous sentence
Do not continue a sentence after a code block
Use syntax highlighting when the format supports it for code blocks
Avoid the word 'snippet' unless the surrounding docs already use it as a term of art
Keep inline method, function, and class references consistent with nearby docs, omitting empty parentheses for prose readability when no call is shown
Use descriptive anchor text that matches the destination title when possible for links
Avoid raw URLs in running text
Avoid generic anchor text such as 'here,' 'this page,' and 'read more'
Include acronyms in link text when a linked term includes an acronym
Do not link long sentences or multiple sentences
Avoid links that pull readers away from a procedure unless the link is a p...

Files:

  • README.md
  • integrations/coding-agents/codex/README.md
{README.md,docs/**/*.{md,rst,txt},fern/**/*}

📄 CodeRabbit inference engine (.agents/skills/prepare-code-freeze/SKILL.md)

Search and update documentation source for references to the old version in README.md, docs, and fern directories, updating current-version install commands, package examples, and configuration examples to <next-version>

Files:

  • README.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

Update README.md, fern/, package READMEs, and binding-support notes when public behavior, package names, examples, or supported bindings change.

**/*.{md,mdx}: Prefer the documented public API, not internal shortcuts
Keep package names, repo references, and build commands current
Keep release-process and release-notes guidance in repo-maintainer docs such as RELEASING.md, not as user-facing docs pages or CHANGELOG.md
Keep stable user-facing wrappers at scripts/ root in docs and examples; only point at namespaced helper paths when documenting internal maintenance work
When detailed dynamic plugin guides exist, keep Rust native plugin examples, Python worker plugin examples, and grpc-v1 protocol details on separate pages

If links in documentation change, run just docs-linkcheck.

Files:

  • README.md
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
**/*.{md,markdown,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Markdown/MDX documentation files using the HTML comment block form.

Files:

  • README.md
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
{docs/**/*.md,README.md}

📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)

Update reference docs, language-binding docs, READMEs, and example documentation when the public surface or expected usage changes.

Files:

  • README.md
{README.md,docs/index.md}

📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)

Update entry-point docs when examples or reading paths change

Files:

  • README.md
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • README.md
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
README.md

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If documentation examples or commands in README.md change, run the targeted docs checks appropriate to the change.

Files:

  • README.md
**

⚙️ CodeRabbit configuration file

**:

AGENTS.md

This file provides guidance to agents, including Claude Code and OpenAI Codex, when working in this repository.

Project Overview

NeMo Relay is a multi-language agent runtime framework for execution scopes, lifecycle events, middleware, plugins, and observability around tool and LLM calls. The core runtime is Rust. Primary supported bindings are Rust, Python, and Node.js. Go and the raw C FFI are experimental and source-first.

The shared runtime model is:

  1. Scope stacks decide where work belongs and which scope-local behavior is visible.
  2. Middleware registries decide what guardrails and intercepts run around managed calls.
  3. Plugins install reusable runtime behavior from configuration.
  4. Events record runtime behavior in ATOF form.
  5. Subscribers and exporters consume events in-process or export them to ATIF, OpenTelemetry, OpenInference, or other backends.

Repository Structure

The repository layout separates the Rust runtime, language bindings,
documentation, integrations, and agent-facing skills.

crates/
  core/       # Rust core runtime crate, published as nemo-relay
  adaptive/   # Adaptive runtime primitives and plugin components
  python/     # PyO3 native extension for the Python package
  ffi/        # Raw C ABI layer used by downstream bindings such as Go
  node/       # NAPI Node.js binding and JavaScript/TypeScript entry points
python/
  nemo_relay/  # Python wrapper package: scopes, tools, LLM, middleware, typed helpers, plugins, adaptive helpers
  tests/      # Python tests
go/
  nemo_relay/  # Experimental Go CGo binding and tests
fern/         # Fern documentation site
scripts/      # Stable wrappers and helper scripts; build/test/docs entry points live in justfile
skills/       # Published Codex/agent skills for NeMo Relay usage patterns

Prerequisites

Insta...

Files:

  • README.md
  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • docs/nemo-relay-cli/plugin-installation.mdx
  • integrations/coding-agents/codex/README.md
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency across language bindings.
Flag stale examples, missing SPDX headers where required, and instructions that no longer match CI or pre-commit behavior.

Files:

  • README.md
  • docs/nemo-relay-cli/plugin-installation.mdx
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

**/*.rs: Any Rust change must run just test-rust
Any Rust change must run cargo fmt --all
Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all for all FFI work since it is Rust work
Run just test-rust to validate FFI changes
Run cargo clippy --workspace --all-targets -- -D warnings to enforce strict linting on FFI work

When Rust files changed as part of Go work, also run cargo fmt --all, just test-rust, and cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all when Rust files are changed as part of Node work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files are changed as part of Node work
Run just test-rust when Rust files are changed as part of Node work

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

**/*.rs: If any Rust code changed, always run just test-rust.
If any Rust code changed, also run cargo fmt --all.
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, run cargo fmt --all and cargo clippy --workspace --all-targets -- -D warnings even if relying on pre-commit.

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
**/*.{rs,py,go,js,ts}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If a language surface changed, always run that language's test target even when Rust core did not change.

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/cli/tests/coverage/server_tests.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/tests/coverage/plugin_shim_tests.rs
{crates/**/src/**/*.rs,python/**/*.py}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

Do not add tests under src; Rust tests belong in crate tests/ trees, and Python SDK tests belong under python/tests.

Files:

  • crates/cli/src/server.rs
  • crates/cli/src/plugin_shim/mod.rs
  • crates/cli/src/plugin_shim/shared.rs
  • crates/cli/src/plugin_shim/codex_app_server.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.mdx

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

MDX top-of-file SPDX comments must use {/* ... */} delimiters instead of HTML comment delimiters (Must-Fix)

In MDX files, top-of-file comments must use JSX comment delimiters ({/* to open and */} to close); do not use HTML comments for MDX SPDX headers

Files:

  • docs/nemo-relay-cli/plugin-installation.mdx
{docs,examples}/**/*

📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)

Update docs and examples.

Files:

  • docs/nemo-relay-cli/plugin-installation.mdx
docs/**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If documentation examples or commands under docs/ change, run the targeted docs checks appropriate to the change.

Files:

  • docs/nemo-relay-cli/plugin-installation.mdx
🔇 Additional comments (18)
crates/cli/src/server.rs (2)

300-314: LGTM!


316-335: 🩺 Stability & Availability

idle_shutdown_ready is reachable from server_tests.rs #[cfg(test)] #[path = "../tests/coverage/server_tests.rs"] mod tests; makes that file a child module, so the private helper is visible there.

			> Likely an incorrect or invalid review comment.
crates/cli/tests/coverage/server_tests.rs (1)

540-568: LGTM!

docs/nemo-relay-cli/plugin-installation.mdx (1)

81-99: LGTM!

Also applies to: 127-132, 165-167

integrations/coding-agents/codex/README.md (1)

46-63: LGTM!

Also applies to: 192-194, 292-304

crates/cli/src/plugin_shim/codex.rs (4)

117-122: Same let-chain / MSRV concern flagged in codex_app_server.rs Lines 158-160 applies here (&& let Some(client) = ...); resolve once by confirming the pinned toolchain is >= 1.88.


236-240: 🎯 Functional Correctness | ⚡ Quick win

Lexical path equality may reject legitimately-matching hooks.

Path::new(&hook.source_path) == hooks_path compares components lexically. If the app-server reports a canonicalized/symlink-resolved path (common on macOS, e.g. /var/private/var) while home_dir().join(".codex/hooks.json") is not resolved, this filter yields no hooks, and auto_trust_codex_hooks then fails with "missing required hooks". Consider comparing canonicalized paths (or file identity) when both exist.


22-59: LGTM!

Also applies to: 61-116, 123-135, 144-234, 245-302


42-43: 🗄️ Data Integrity & Integration

No rollback gap here
prepare_codex_config only parses and validates config.toml; it doesn’t mutate files, so taking snapshots afterward doesn’t miss any install-time changes.

			> Likely an incorrect or invalid review comment.
crates/cli/src/plugin_shim/codex_app_server.rs (3)

45-94: LGTM!

Also applies to: 96-122, 124-139, 141-147, 167-182, 184-197, 199-209, 211-225


158-160: 🎯 Functional Correctness

Let chains are supported by the pinned toolchain

rust-toolchain.toml pins Rust 1.93.0, so if let Some(errors) = ... && !errors.is_empty() is valid. The MSRV concern does not apply here. The same applies to crates/cli/src/plugin_shim/codex.rs.

			> Likely an incorrect or invalid review comment.

18-30: 🗄️ Data Integrity & Integration

No change needed The CodexHookMetadata field names are already mapped to the app-server’s camelCase schema by #[serde(rename_all = "camelCase")]; the snake_case Rust fields are correct here.

			> Likely an incorrect or invalid review comment.
crates/cli/src/plugin_shim/mod.rs (2)

101-110: LGTM!


202-223: LGTM!

Also applies to: 233-245

crates/cli/src/plugin_shim/shared.rs (1)

382-476: LGTM!

crates/cli/tests/coverage/plugin_shim_tests.rs (2)

17-140: LGTM!


311-403: LGTM!

Also applies to: 468-645, 985-1058

crates/cli/tests/coverage/plugin_install_tests.rs (1)

385-408: LGTM!

Comment thread crates/cli/src/plugin_shim/shared.rs Outdated
Comment thread README.md Outdated
@willkill07 willkill07 changed the title fix(codex): harden Codex lazy bootstrap fix(codex): launch native gateway from plugin MCP Jul 9, 2026
@willkill07
willkill07 marked this pull request as draft July 9, 2026 19:22
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

License Diff

Compared against origin/main.

Lockfile license changes

Lockfile License Changes

Rust

Added

  • deranged 0.5.8 (Apache-2.0)
  • fs2 0.4.3 (Apache-2.0)
  • num-conv 0.2.2 (Apache-2.0)
  • pem 3.0.6 (MIT)
  • powerfmt 0.2.0 (Apache-2.0)
  • rcgen 0.13.2 (Apache-2.0)
  • time 0.3.53 (Apache-2.0)
  • time-core 0.1.9 (Apache-2.0)
  • winapi 0.3.9 (Apache-2.0)
  • winapi-i686-pc-windows-gnu 0.4.0 (Apache-2.0)
  • winapi-x86_64-pc-windows-gnu 0.4.0 (Apache-2.0)
  • yasna 0.5.2 (Apache-2.0)

Removed

  • None

Updated/Changed

  • None

Node

Added

  • None

Removed

  • None

Updated/Changed

  • None

Python

Added

  • None

Removed

  • None

Updated/Changed

  • None
Status output
[license-diff] selected languages: rust, node, python
[license-diff] generating current inventory
[license-diff] current: generating Rust inventory
[license-diff] current: Rust inventory complete (391 packages)
[license-diff] current: generating Node inventory
[license-diff] current: Node inventory complete (363 packages)
[license-diff] current: generating Python inventory
[license-diff] current: Python inventory complete (105 packages)
[license-diff] current inventory complete
[license-diff] checking out base ref origin/main into a temporary worktree
[license-diff] base: generating Rust inventory
[license-diff] base: Rust inventory complete (379 packages)
[license-diff] base: generating Node inventory
[license-diff] base: Node inventory complete (363 packages)
[license-diff] base: generating Python inventory
[license-diff] base: Python inventory complete (105 packages)
[license-diff] base inventory complete
[license-diff] removing temporary base worktree
[license-diff] comparing inventories
[license-diff] rendering Markdown output
[license-diff] done

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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/cli/src/plugin_install/host.rs`:
- Around line 293-296: The relay executable path handling in resolve_executable
should keep canonicalization for matching, but avoid serializing a Windows \\?\
path into the MCP config command. Update the host.rs flow around RELAY_COMMAND
so the value written to .mcp.json is normalized to a Windows-friendly path while
preserving the canonicalized form only for comparison/lookup. Use the existing
executable resolution and config-writing logic in this area to ensure the
serialized MCP command remains executable on Windows.

In `@crates/cli/src/plugin_install/mod.rs`:
- Around line 594-605: The Generated MCP server check builds the MCP config path
inline with a literal ".mcp.json", which is inconsistent with the other manifest
path helpers and may drift from PluginLayout::new. Add a dedicated
mcp_config_path helper near the existing path helpers and use it in the
readiness.plugin branch instead of calling plugin.join directly, keeping the
path construction centralized alongside marketplace_manifest_path and
plugin_manifest_path.
🪄 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: ASSERTIVE

Plan: Enterprise

Run ID: 088df63e-c8eb-465a-9b69-608258e79bb2

📥 Commits

Reviewing files that changed from the base of the PR and between bc7e0a0 and 027d8ed.

📒 Files selected for processing (21)
  • crates/cli/Cargo.toml
  • crates/cli/src/config.rs
  • crates/cli/src/main.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/src/plugin_shim/codex.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/.codex-plugin/plugin.json
  • integrations/coding-agents/codex/.mcp.json
  • integrations/coding-agents/codex/README.md
  • integrations/coding-agents/codex/hooks/hooks.json
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (19)
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • integrations/coding-agents/codex/hooks/hooks.json
  • crates/cli/Cargo.toml
  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • integrations/coding-agents/README.md
  • crates/cli/src/plugin_install/marketplace.rs
  • integrations/coding-agents/codex/README.md
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**

⚙️ CodeRabbit configuration file

**:

AGENTS.md

This file provides guidance to agents, including Claude Code and OpenAI Codex, when working in this repository.

Project Overview

NeMo Relay is a multi-language agent runtime framework for execution scopes, lifecycle events, middleware, plugins, and observability around tool and LLM calls. The core runtime is Rust. Primary supported bindings are Rust, Python, and Node.js. Go and the raw C FFI are experimental and source-first.

The shared runtime model is:

  1. Scope stacks decide where work belongs and which scope-local behavior is visible.
  2. Middleware registries decide what guardrails and intercepts run around managed calls.
  3. Plugins install reusable runtime behavior from configuration.
  4. Events record runtime behavior in ATOF form.
  5. Subscribers and exporters consume events in-process or export them to ATIF, OpenTelemetry, OpenInference, or other backends.

Repository Structure

The repository layout separates the Rust runtime, language bindings,
documentation, integrations, and agent-facing skills.

crates/
  core/       # Rust core runtime crate, published as nemo-relay
  adaptive/   # Adaptive runtime primitives and plugin components
  python/     # PyO3 native extension for the Python package
  ffi/        # Raw C ABI layer used by downstream bindings such as Go
  node/       # NAPI Node.js binding and JavaScript/TypeScript entry points
python/
  nemo_relay/  # Python wrapper package: scopes, tools, LLM, middleware, typed helpers, plugins, adaptive helpers
  tests/      # Python tests
go/
  nemo_relay/  # Experimental Go CGo binding and tests
fern/         # Fern documentation site
scripts/      # Stable wrappers and helper scripts; build/test/docs entry points live in justfile
skills/       # Published Codex/agent skills for NeMo Relay usage patterns

Prerequisites

Insta...

Files:

  • integrations/coding-agents/codex/hooks/hooks.json
  • crates/cli/Cargo.toml
  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • integrations/coding-agents/README.md
  • crates/cli/src/plugin_install/marketplace.rs
  • integrations/coding-agents/codex/README.md
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/Cargo.toml

📄 CodeRabbit inference engine (.agents/skills/prepare-code-freeze/SKILL.md)

Confirm or infer the target release version from upstream/main:Cargo.toml. Derive the release branch as release/<major>.<minor>.

Keep Rust package names and workspace metadata in Cargo.toml internally consistent across the project.

Files:

  • crates/cli/Cargo.toml
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all TOML files using the # comment form.

Files:

  • crates/cli/Cargo.toml
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

**/*.rs: Any Rust change must run just test-rust
Any Rust change must run cargo fmt --all
Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all for all FFI work since it is Rust work
Run just test-rust to validate FFI changes
Run cargo clippy --workspace --all-targets -- -D warnings to enforce strict linting on FFI work

When Rust files changed as part of Go work, also run cargo fmt --all, just test-rust, and cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all when Rust files are changed as part of Node work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files are changed as part of Node work
Run just test-rust when Rust files are changed as part of Node work

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

**/*.rs: If any Rust code changed, always run just test-rust.
If any Rust code changed, also run cargo fmt --all.
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, run cargo fmt --all and cargo clippy --workspace --all-targets -- -D warnings even if relying on pre-commit.

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{rs,py,go,js,ts}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If a language surface changed, always run that language's test target even when Rust core did not change.

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
  • crates/cli/src/plugin_shim/codex.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/cli/tests/coverage/main_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/mcp_tests.rs
  • crates/cli/tests/coverage/installer_tests.rs
  • crates/cli/tests/coverage/plugin_install_tests.rs
{crates/**/src/**/*.rs,python/**/*.py}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

Do not add tests under src; Rust tests belong in crate tests/ trees, and Python SDK tests belong under python/tests.

Files:

  • crates/cli/src/plugin_install/setup.rs
  • crates/cli/src/main.rs
  • crates/cli/src/config.rs
  • crates/cli/src/plugin_install/host.rs
  • crates/cli/src/plugin_install/state.rs
  • crates/cli/src/plugin_install/marketplace.rs
  • crates/cli/src/plugin_install/mod.rs
  • crates/cli/src/mcp.rs
  • crates/cli/src/server.rs
  • crates/cli/src/plugin_shim/codex.rs
**/*.{md,rst,html,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

**/*.{md,rst,html,txt}: Always spell NVIDIA in all caps. Do not use Nvidia, nvidia, nVidia, nVIDIA, or NV.
Use an NVIDIA before a noun because the name starts with an 'en' sound.
Do not add a registered trademark symbol after NVIDIA when referring to the company.
Use trademark symbols with product names only when the document type or legal guidance requires them.
Verify official capitalization, spacing, and hyphenation for product names.
Precede NVIDIA product names with NVIDIA on first mention when it is natural and accurate.
Do not rewrite product names for grammar or title-case rules.
Preserve third-party product names according to the owner's spelling.
Include the company name and full model qualifier on first use when it helps identify the model.
Preserve the official capitalization and punctuation of model names.
Use shorter family names only after the full name is established.
Spell out a term on first use and put the acronym in parentheses unless the acronym is widely understood by the intended audience.
Use the acronym on later mentions after it has been defined.
For long documents, reintroduce the full term if readers might lose context.
Form plurals of acronyms with s, not an apostrophe, such as GPUs.
In headings, common acronyms can remain abbreviated. Spell out the term in the first or second sentence of the body.
Common terms such as CPU, GPU, PC, API, and UI usually do not need to be spelled out for developer audiences.

Files:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,rst,html}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

Link the first mention of a product name when the destination helps the reader.

Files:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,rst,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

Spell NVIDIA in all caps. Do not use Nvidia, nvidia, or NV.

Files:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,rst}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

**/*.{md,rst}: Format commands, code elements, expressions, package names, file names, and paths as inline code.
Use descriptive link text. Avoid raw URLs and weak anchors such as "here" or "read more."
Use title case consistently for technical documentation headings.
Introduce code blocks, lists, tables, and images with complete sentences.
Write procedures as imperative steps. Keep steps parallel and split long procedures into smaller tasks.
Prefer active voice, present tense, short sentences, contractions, and plain English.
Use can for possibility and reserve may for permission.
Use after for temporal relationships instead of once.
Prefer refer to over see when the wording points readers to another resource.
Avoid culture-specific idioms, unnecessary Latinisms, jokes, and marketing exaggeration in technical docs.
Spell out months in body text, avoid ordinal dates, and use clear time zones.
Spell out whole numbers from zero through nine unless they are technical values, parameters, versions, or UI values.
Use numerals for 10 or greater and include commas in thousands.
Do not add trademark symbols to learning-oriented docs unless the source, platform, or legal guidance explicitly requires them.

Files:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
**/*.md

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-technical-docs.md)

**/*.md: Use title case consistently in technical documentation headings
Avoid quotation marks, ampersands, and exclamation marks in headings
Keep product, event, research, and whitepaper names in their official title case
Use title case for table headers
Do not force social-media sentence case into technical docs
Format code elements, commands, parameters, package names, and expressions in monospace
Format directories, file names, and paths in monospace using backticks
Use angle brackets inside monospace for variables inside paths, such as /home/<username>/.login
Format error messages and strings in quotation marks, keeping literal code strings in code formatting when clearer
Format UI buttons, menus, fields, and labels in bold
Use angle brackets between UI labels for menu paths, such as File > Save As
Use italics for new terms on first use, sparingly and only when introducing the term
Use italics for publication titles
Format keyboard shortcuts in plain text, such as Press Ctrl+Alt+Delete
Use owner/repo link text for GitHub repositories, preferring [NVIDIA/NeMo](link) over prose references like 'the GitHub repo'
Introduce every code block with a complete sentence
Do not make a code block complete the grammar of the previous sentence
Do not continue a sentence after a code block
Use syntax highlighting when the format supports it for code blocks
Avoid the word 'snippet' unless the surrounding docs already use it as a term of art
Keep inline method, function, and class references consistent with nearby docs, omitting empty parentheses for prose readability when no call is shown
Use descriptive anchor text that matches the destination title when possible for links
Avoid raw URLs in running text
Avoid generic anchor text such as 'here,' 'this page,' and 'read more'
Include acronyms in link text when a linked term includes an acronym
Do not link long sentences or multiple sentences
Avoid links that pull readers away from a procedure unless the link is a p...

Files:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

Update README.md, fern/, package READMEs, and binding-support notes when public behavior, package names, examples, or supported bindings change.

**/*.{md,mdx}: Prefer the documented public API, not internal shortcuts
Keep package names, repo references, and build commands current
Keep release-process and release-notes guidance in repo-maintainer docs such as RELEASING.md, not as user-facing docs pages or CHANGELOG.md
Keep stable user-facing wrappers at scripts/ root in docs and examples; only point at namespaced helper paths when documenting internal maintenance work
When detailed dynamic plugin guides exist, keep Rust native plugin examples, Python worker plugin examples, and grpc-v1 protocol details on separate pages

If links in documentation change, run just docs-linkcheck.

Files:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
**/*.{md,markdown,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Markdown/MDX documentation files using the HTML comment block form.

Files:

  • integrations/coding-agents/README.md
  • integrations/coding-agents/codex/README.md
🔇 Additional comments (26)
crates/cli/src/server.rs (2)

53-63: LGTM!

Also applies to: 65-85, 87-91, 132-146, 178-188


148-164: 🩺 Stability & Availability

Readiness signal is correctly ordered. It fires after plugin/router setup and before axum::serve, and the MCP launcher only waits on it before starting stdio handling.

crates/cli/Cargo.toml (1)

53-53: LGTM!

crates/cli/src/config.rs (1)

72-83: LGTM!

crates/cli/src/main.rs (1)

17-17: LGTM!

Also applies to: 84-84

crates/cli/src/mcp.rs (2)

1-104: LGTM!

Also applies to: 131-187


105-129: 🗄️ Data Integrity & Integration

MCP stdio uses newline-delimited JSON, so read_line is the right framing here.

			> Likely an incorrect or invalid review comment.
integrations/coding-agents/codex/.mcp.json (1)

1-15: LGTM!

integrations/coding-agents/codex/README.md (1)

22-23: LGTM!

Also applies to: 48-68, 196-200, 227-227, 299-317, 338-342

integrations/coding-agents/codex/hooks/hooks.json (1)

2-151: LGTM!

crates/cli/tests/cli_tests.rs (1)

164-217: LGTM!

Also applies to: 1329-1329

crates/cli/tests/coverage/main_tests.rs (1)

86-96: LGTM!

crates/cli/tests/coverage/mcp_tests.rs (1)

1-201: LGTM!

Good coverage of readiness gating, EOF shutdown, and the plugin-activation error path — satisfies the path instruction to prefer lifecycle/error-path assertions over shallow smoke tests.

crates/cli/src/plugin_shim/codex.rs (3)

146-314: LGTM!

Trust classification, canonicalized path matching, missing-required computation, and the snapshot/rollback aggregation helpers all look correct and consistent with the PR's trust-hardening goals.


117-122: 🩺 Stability & Availability

No issue — the workspace targets Rust 1.93.0 and edition 2024, so this let chain is supported.


36-53: 🗄️ Data Integrity & Integration

Snapshot order is fine

prepare_codex_config only parses config.toml and returns an error on invalid TOML; it does not write to disk, so taking the snapshot afterward still captures the pre-install state.

			> Likely an incorrect or invalid review comment.
integrations/coding-agents/README.md (1)

25-36: LGTM!

Also applies to: 69-85

integrations/coding-agents/codex/.codex-plugin/plugin.json (1)

4-22: LGTM!

crates/cli/src/plugin_install/state.rs (1)

50-50: LGTM!

Also applies to: 74-83

crates/cli/src/plugin_install/host.rs (1)

319-338: LGTM! Mirrors the existing validate_relay_plugin_shim pattern and matches the mocked-failure test expectations.

crates/cli/src/plugin_install/marketplace.rs (2)

143-160: 🎯 Functional Correctness

Confirm the hardcoded MCP bind address doesn't drift from a single source of truth, and how port conflicts are handled.

NEMO_RELAY_GATEWAY_BIND is hardcoded here to a fixed port (127.0.0.1:47632), while docs describe the transparent-wrapper flow using a dynamic port. Since this config is marked "required": true, if config.rs/mcp.rs (default bind handling, not in this file set) ever changes the default bind or if the port is already in use (e.g., two installs, a leftover process), Codex startup could fail hard. Worth confirming this literal is sourced from (or kept in sync with) the same constant used by the mcp subcommand's default bind, and whether a bind failure is retried/surfaced gracefully.


20-28: LGTM! Consistent with updated tests (installer_tests.rs, plugin_install_tests.rs) confirming the generated .mcp.json content, manifest description/interface text, and the new Codex hooks-template behavior.

Also applies to: 49-51, 100-131, 176-176

crates/cli/src/plugin_install/mod.rs (1)

361-369: LGTM! Correctly gates Codex plugin generation behind validate_relay_mcp, matching relay_without_native_mcp_fails_codex_install_before_generating_plugin.

crates/cli/src/plugin_install/setup.rs (1)

58-58: LGTM!

crates/cli/tests/coverage/plugin_install_tests.rs (1)

287-293: LGTM! Good coverage of the new MCP validation gate, generated config content, and readiness failure modes (missing config, mismatched binary), consistent with the source changes.

Also applies to: 346-362, 474-474, 529-534, 847-870, 1045-1069, 1444-1487

crates/cli/tests/coverage/installer_tests.rs (1)

171-179: LGTM!

Also applies to: 228-245, 283-283

Comment thread crates/cli/src/plugin_install/host.rs Outdated
Comment thread crates/cli/src/plugin_install/mod.rs Outdated
@willkill07
willkill07 force-pushed the wkk_relay-447-codex-bootstrap branch from 027d8ed to f7779fc Compare July 9, 2026 21:47
@github-actions github-actions Bot added the lang:python PR changes/introduces Python code label Jul 9, 2026
@willkill07 willkill07 changed the title fix(codex): launch native gateway from plugin MCP fix(codex): stabilize plugin gateway bootstrap Jul 9, 2026
@github-actions github-actions Bot added size:XXL PR is very large and removed size:XL PR is extra large labels Jul 9, 2026
Signed-off-by: Will Killian <wkillian@nvidia.com>
Comment thread crates/cli/src/plugins/lifecycle/environment.rs Outdated
Comment thread crates/cli/src/plugins/lifecycle/mod.rs
Comment thread scripts/test-claude-plugin-e2e.sh
Comment thread crates/cli/src/mcp/protocol.rs Outdated
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/cli/src/gateway/mod.rs (2)

862-927: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Dispatch-route override contract is incomplete and fails open instead of closed. from_dispatch_override doesn't cover all ProviderRoute variants, and effective_dispatch_request silently falls back to the original route on any parse failure while still applying an independently-supplied override_url — the combination can forward a request to a new upstream URL under the wrong provider's auth-header semantics.

  • crates/cli/src/gateway/mod.rs#L862-L927: when INTERNAL_DISPATCH_ROUTE_HEADER is present but fails to parse via from_dispatch_override, drop override_url too (fail closed) instead of pairing the new URL with the stale route.
  • crates/cli/src/gateway/routes.rs#L49-L63: add from_dispatch_override match arms for OpenAiModels and AnthropicCountTokens (or document why they're intentionally excluded from override targeting).
🤖 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/cli/src/gateway/mod.rs` around lines 862 - 927, Update
effective_dispatch_request in crates/cli/src/gateway/mod.rs (lines 862-927) to
fail closed when INTERNAL_DISPATCH_ROUTE_HEADER is present but
from_dispatch_override cannot parse it: discard override_url rather than
applying it with the original route. Update from_dispatch_override in
crates/cli/src/gateway/routes.rs (lines 49-63) to handle OpenAiModels and
AnthropicCountTokens, unless those variants are explicitly documented as
unsupported override targets.

752-776: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

GatewayCallGuard::drop can skip cleanup without a Tokio handle. If this destructor runs outside a Tokio runtime, both record_gateway_response_hints and finish_gateway_call are skipped, leaving active_gateway_calls stale and blocking idle shutdown.

🤖 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/cli/src/gateway/mod.rs` around lines 752 - 776, Update
GatewayCallGuard::drop to always execute the response-hint recording and
finish_gateway_call cleanup, including when Handle::try_current() finds no Tokio
runtime. Preserve the existing async cleanup sequence and ensure it is run using
an appropriate runtime fallback rather than silently skipping cleanup.
🤖 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 `@ATTRIBUTIONS-Rust.md`:
- Around line 38435-38439: Update the switchyard-translation attribution entry
by adding blank lines around its headings and changing the license code fence to
include an explicit text language, while preserving the existing license
content.

In `@crates/cli/src/gateway/mod.rs`:
- Around line 81-205: Remove the commented-out pre-refactor code blocks
containing PreparedGatewayRequest and the former gateway route/response helpers,
including the block around prepare_gateway_request and its related functions and
the additional block noted in the review. Keep the active implementations in
gateway::request, gateway::routes, and gateway::response unchanged.

In `@crates/cli/src/gateway/routes.rs`:
- Around line 49-63: The from_dispatch_override method does not support the
OpenAiModels and AnthropicCountTokens ProviderRoute variants. Add the
appropriate dispatch-override aliases for both variants so valid overrides
resolve to their corresponding route classifications, and ensure
effective_dispatch_request does not silently apply an unparseable override to a
different route.

In `@crates/cli/src/server/mod.rs`:
- Around line 740-776: Extract the shared adaptive, PII, and feature-gated
switchyard registration plus switchyard ATOF validation into a
register_and_validate_plugin_components(&PluginConfig) helper. In
crates/cli/src/server/mod.rs lines 740-776, call it from
initialize_plugin_host’s static path; in crates/cli/src/server/mod.rs lines
785-917, replace PluginActivation::initialize’s inline registration and
validation; and in crates/cli/src/diagnostics/mod.rs lines 482-515, replace
collect_observability’s duplicated block with the helper.

In `@crates/cli/tests/coverage/shared/plugins_tests.rs`:
- Around line 2417-2430: Extend
tagged_unions_support_list_items_and_top_level_fields to construct a list schema
field whose list_item is Some(&TAGGED_LIST_ITEM), then invoke the relevant
editor item-label or variant-handling path through that field and assert the
expected tagged-union behavior. Retain the existing top-level field assertions
while ensuring the test no longer passes TAGGED_LIST_ITEM only as a direct
helper argument.

---

Outside diff comments:
In `@crates/cli/src/gateway/mod.rs`:
- Around line 862-927: Update effective_dispatch_request in
crates/cli/src/gateway/mod.rs (lines 862-927) to fail closed when
INTERNAL_DISPATCH_ROUTE_HEADER is present but from_dispatch_override cannot
parse it: discard override_url rather than applying it with the original route.
Update from_dispatch_override in crates/cli/src/gateway/routes.rs (lines 49-63)
to handle OpenAiModels and AnthropicCountTokens, unless those variants are
explicitly documented as unsupported override targets.
- Around line 752-776: Update GatewayCallGuard::drop to always execute the
response-hint recording and finish_gateway_call cleanup, including when
Handle::try_current() finds no Tokio runtime. Preserve the existing async
cleanup sequence and ensure it is run using an appropriate runtime fallback
rather than silently skipping cleanup.
🪄 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: ASSERTIVE

Plan: Enterprise

Run ID: 07434d67-647c-4734-8c4b-acf4ab15d595

📥 Commits

Reviewing files that changed from the base of the PR and between 2f640ce and ab7cf50.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • ATTRIBUTIONS-Rust.md
  • crates/cli/Cargo.toml
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/src/sessions/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • scripts/README.md
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
  • GitHub Check: Node.js / Test (windows-arm64)
  • GitHub Check: Python / Test (windows-arm64)
  • GitHub Check: Rust / Test (macos-arm64)
  • GitHub Check: Python / Test (macos-arm64)
  • GitHub Check: Rust / Test (windows-arm64)
  • GitHub Check: Rust / Test (windows-amd64)
🧰 Additional context used
📓 Path-based instructions (19)
**/*.{md,rst,html,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

**/*.{md,rst,html,txt}: Always spell NVIDIA in all caps. Do not use Nvidia, nvidia, nVidia, nVIDIA, or NV.
Use an NVIDIA before a noun because the name starts with an 'en' sound.
Do not add a registered trademark symbol after NVIDIA when referring to the company.
Use trademark symbols with product names only when the document type or legal guidance requires them.
Verify official capitalization, spacing, and hyphenation for product names.
Precede NVIDIA product names with NVIDIA on first mention when it is natural and accurate.
Do not rewrite product names for grammar or title-case rules.
Preserve third-party product names according to the owner's spelling.
Include the company name and full model qualifier on first use when it helps identify the model.
Preserve the official capitalization and punctuation of model names.
Use shorter family names only after the full name is established.
Spell out a term on first use and put the acronym in parentheses unless the acronym is widely understood by the intended audience.
Use the acronym on later mentions after it has been defined.
For long documents, reintroduce the full term if readers might lose context.
Form plurals of acronyms with s, not an apostrophe, such as GPUs.
In headings, common acronyms can remain abbreviated. Spell out the term in the first or second sentence of the body.
Common terms such as CPU, GPU, PC, API, and UI usually do not need to be spelled out for developer audiences.

Files:

  • scripts/README.md
  • ATTRIBUTIONS-Rust.md
**/*.{md,rst,html}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-brand-terminology.md)

Link the first mention of a product name when the destination helps the reader.

Files:

  • scripts/README.md
  • ATTRIBUTIONS-Rust.md
**/*.{md,rst,txt}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

Spell NVIDIA in all caps. Do not use Nvidia, nvidia, or NV.

Files:

  • scripts/README.md
  • ATTRIBUTIONS-Rust.md
**/*.{md,rst}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

**/*.{md,rst}: Format commands, code elements, expressions, package names, file names, and paths as inline code.
Use descriptive link text. Avoid raw URLs and weak anchors such as "here" or "read more."
Use title case consistently for technical documentation headings.
Introduce code blocks, lists, tables, and images with complete sentences.
Write procedures as imperative steps. Keep steps parallel and split long procedures into smaller tasks.
Prefer active voice, present tense, short sentences, contractions, and plain English.
Use can for possibility and reserve may for permission.
Use after for temporal relationships instead of once.
Prefer refer to over see when the wording points readers to another resource.
Avoid culture-specific idioms, unnecessary Latinisms, jokes, and marketing exaggeration in technical docs.
Spell out months in body text, avoid ordinal dates, and use clear time zones.
Spell out whole numbers from zero through nine unless they are technical values, parameters, versions, or UI values.
Use numerals for 10 or greater and include commas in thousands.
Do not add trademark symbols to learning-oriented docs unless the source, platform, or legal guidance explicitly requires them.

Files:

  • scripts/README.md
  • ATTRIBUTIONS-Rust.md
**/*.md

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-technical-docs.md)

**/*.md: Use title case consistently in technical documentation headings
Avoid quotation marks, ampersands, and exclamation marks in headings
Keep product, event, research, and whitepaper names in their official title case
Use title case for table headers
Do not force social-media sentence case into technical docs
Format code elements, commands, parameters, package names, and expressions in monospace
Format directories, file names, and paths in monospace using backticks
Use angle brackets inside monospace for variables inside paths, such as /home/<username>/.login
Format error messages and strings in quotation marks, keeping literal code strings in code formatting when clearer
Format UI buttons, menus, fields, and labels in bold
Use angle brackets between UI labels for menu paths, such as File > Save As
Use italics for new terms on first use, sparingly and only when introducing the term
Use italics for publication titles
Format keyboard shortcuts in plain text, such as Press Ctrl+Alt+Delete
Use owner/repo link text for GitHub repositories, preferring [NVIDIA/NeMo](link) over prose references like 'the GitHub repo'
Introduce every code block with a complete sentence
Do not make a code block complete the grammar of the previous sentence
Do not continue a sentence after a code block
Use syntax highlighting when the format supports it for code blocks
Avoid the word 'snippet' unless the surrounding docs already use it as a term of art
Keep inline method, function, and class references consistent with nearby docs, omitting empty parentheses for prose readability when no call is shown
Use descriptive anchor text that matches the destination title when possible for links
Avoid raw URLs in running text
Avoid generic anchor text such as 'here,' 'this page,' and 'read more'
Include acronyms in link text when a linked term includes an acronym
Do not link long sentences or multiple sentences
Avoid links that pull readers away from a procedure unless the link is a p...

Files:

  • scripts/README.md
  • ATTRIBUTIONS-Rust.md
**/*.{md,mdx}

📄 CodeRabbit inference engine (AGENTS.md)

Update README.md, fern/, package READMEs, and binding-support notes when public behavior, package names, examples, or supported bindings change.

**/*.{md,mdx}: Prefer the documented public API, not internal shortcuts
Keep package names, repo references, and build commands current
Keep release-process and release-notes guidance in repo-maintainer docs such as RELEASING.md, not as user-facing docs pages or CHANGELOG.md
Keep stable user-facing wrappers at scripts/ root in docs and examples; only point at namespaced helper paths when documenting internal maintenance work
When detailed dynamic plugin guides exist, keep Rust native plugin examples, Python worker plugin examples, and grpc-v1 protocol details on separate pages

If links in documentation change, run just docs-linkcheck.

Files:

  • scripts/README.md
  • ATTRIBUTIONS-Rust.md
**/*.{md,markdown,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Markdown/MDX documentation files using the HTML comment block form.

Files:

  • scripts/README.md
  • ATTRIBUTIONS-Rust.md
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • scripts/README.md
  • crates/cli/Cargo.toml
  • ATTRIBUTIONS-Rust.md
  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/src/sessions/mod.rs
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}

⚙️ CodeRabbit configuration file

{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}: Review automation changes for reproducibility, pinned versions where appropriate, secret handling, and consistency with the documented validation matrix.
Pay attention to commands that need generated native artifacts, FFI libraries, or platform-specific environment variables.

Files:

  • scripts/README.md
**/Cargo.toml

📄 CodeRabbit inference engine (.agents/skills/prepare-code-freeze/SKILL.md)

Confirm or infer the target release version from upstream/main:Cargo.toml. Derive the release branch as release/<major>.<minor>.

Keep Rust package names and workspace metadata in Cargo.toml internally consistent across the project.

Files:

  • crates/cli/Cargo.toml
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all TOML files using the # comment form.

Files:

  • crates/cli/Cargo.toml
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

**/*.rs: Any Rust change must run just test-rust
Any Rust change must run cargo fmt --all
Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all for all FFI work since it is Rust work
Run just test-rust to validate FFI changes
Run cargo clippy --workspace --all-targets -- -D warnings to enforce strict linting on FFI work

When Rust files changed as part of Go work, also run cargo fmt --all, just test-rust, and cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all when Rust files are changed as part of Node work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files are changed as part of Node work
Run just test-rust when Rust files are changed as part of Node work

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

**/*.rs: If any Rust code changed, always run just test-rust.
If any Rust code changed, also run cargo fmt --all.
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, run cargo fmt --all and cargo clippy --workspace --all-targets -- -D warnings even if relying on pre-commit.

Files:

  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/src/sessions/mod.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/src/sessions/mod.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/src/sessions/mod.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/src/sessions/mod.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/src/sessions/mod.rs
**/*.{rs,py,go,js,ts}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If a language surface changed, always run that language's test target even when Rust core did not change.

Files:

  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/src/sessions/mod.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
{crates/**/src/**/*.rs,python/**/*.py}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

Do not add tests under src; Rust tests belong in crate tests/ trees, and Python SDK tests belong under python/tests.

Files:

  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/src/sessions/mod.rs
🪛 markdownlint-cli2 (0.23.0)
ATTRIBUTIONS-Rust.md

[warning] 38435-38435: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38438-38438: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 38438-38438: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38439-38439: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 38439-38439: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (25)
crates/cli/Cargo.toml (1)

37-82: 📐 Maintainability & Code Quality

No dependency-boundary issues here. libc and windows-sys are target-gated, and tokio’s test-util, shell-words, and syn stay in test-only usage.

scripts/README.md (1)

21-28: 📐 Maintainability & Code Quality

No Change Needed For These Opt-In E2E Recipes. The justfile entries exist, stay out of the default test flow and CI, and call out the required local client.

crates/cli/src/mcp/protocol.rs (1)

8-9: LGTM! Version negotiation correctly supports both 2025-11-25 and 2025-06-18, resolving the prior review thread's request.

Also applies to: 53-58

crates/cli/src/agents/hermes/launch.rs (2)

23-27: LGTM! OPENAI_BASE_URL derivation and overlay creation wiring look correct.

Also applies to: 41-41


15-22: 🩺 Stability & Availability

No issue: Hermes launch already receives GATEWAY_URL_ENV. process/launcher.rs injects crate::configuration::GATEWAY_URL_ENV before crate::agents::prepare_launch, and agents/mod.rs only routes Hermes through that launch path.

			> Likely an incorrect or invalid review comment.
crates/cli/src/gateway/mod.rs (1)

393-443: LGTM! Retry-aware upstream failure classification (transport_failure/http_failure), ProviderForwarding threading through forward_upstream_request, and the new FlowError::UpstreamCliError::ProviderFailure mapping look correct and consistently applied across the buffered and streaming paths, with sensitive headers properly filtered in failure_headers.

Also applies to: 553-616, 800-836, 1067-1159

crates/cli/tests/coverage/agents/plugin_install_tests.rs (1)

1220-1242: LGTM! Matches the mutual-exclusion fix already confirmed resolved in the prior review thread (commit 4d6b464).

crates/cli/tests/coverage/shared/bootstrap_state_tests.rs (1)

210-215: LGTM!

crates/cli/src/plugins/config_io.rs (2)

12-15: LGTM!

Also applies to: 716-722, 422-422


276-284: 🎯 Functional Correctness

No issue here. PluginsScopeArgs and PricingScopeArgs map every multi-flag combination to ConfigurationScope::Invalid, so target_scope still rejects the same inputs.

			> Likely an incorrect or invalid review comment.
crates/cli/tests/coverage/shared/gateway_tests.rs (1)

15-15: LGTM! Solid coverage: internal dispatch-control stripping, upstream failure classification (retryability + sensitive-header scrubbing), and the retry-aware buffered-body structured-error regression are all correctly exercised.

Also applies to: 340-529

crates/cli/tests/coverage/shared/doctor_tests.rs (1)

1264-1290: LGTM!

crates/cli/src/plugins/mod.rs (4)

335-364: LGTM!


823-1050: LGTM! "Only write back if changed" is applied consistently, and Clear always sets an empty collection rather than removing the key, so required List/StringMap fields stay deserializable.


1052-1372: LGTM! Tagged-union Reset/Clear collapsing to a single Reset variant matches the existing scalar-field pattern in this file, and out-of-range variant/discriminator lookups fail gracefully rather than panicking.


1374-1479: LGTM! Struct-based and raw-Value-based editors mirror the section-based dispatch faithfully, and the new prompt_value guard cleanly rejects structured kinds instead of falling through.

Also applies to: 1644-1772, 1873-1963

crates/cli/src/installation/operation_lock.rs (1)

21-109: LGTM!

crates/cli/tests/coverage/shared/mcp_tests.rs (1)

16-16: LGTM!

Also applies to: 142-168

crates/cli/tests/coverage/shared/session_tests.rs (2)

24-96: LGTM!


5436-5444: LGTM!

crates/cli/tests/coverage/shared/server_tests.rs (1)

1976-2005: LGTM!

crates/cli/src/sessions/mod.rs (1)

50-152: LGTM!

Also applies to: 887-900, 1067-1081, 1493-1493, 1525-1568

crates/cli/src/diagnostics/mod.rs (1)

819-861: 🔒 Security & Privacy

No leak into Check.details. header_env values are only applied to outbound requests; the Check.details strings in this path include only the URL, transport, or static error text, not header contents.

			> Likely an incorrect or invalid review comment.
crates/cli/src/agents/hermes/config.rs (1)

43-67: 🎯 Functional Correctness

No issue: this Hermes model rewrite matches the config format. model.default is the expected key for the string shorthand, and provider/base_url are the right overrides here.

			> Likely an incorrect or invalid review comment.
crates/cli/tests/cli_tests.rs (1)

122-168: 📐 Maintainability & Code Quality

Run the required Rust validation before handoff.

  • crates/cli/tests/cli_tests.rs#L122-L168: Run cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, and just test-rust.
  • crates/cli/tests/coverage/shared/plugins_tests.rs#L9-L11: Include this changed test module in the same validation run.

As per coding guidelines, any Rust change must run cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, and just test-rust.

Source: Coding guidelines

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/cli/src/gateway/mod.rs (2)

862-927: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Dispatch-route override contract is incomplete and fails open instead of closed. from_dispatch_override doesn't cover all ProviderRoute variants, and effective_dispatch_request silently falls back to the original route on any parse failure while still applying an independently-supplied override_url — the combination can forward a request to a new upstream URL under the wrong provider's auth-header semantics.

  • crates/cli/src/gateway/mod.rs#L862-L927: when INTERNAL_DISPATCH_ROUTE_HEADER is present but fails to parse via from_dispatch_override, drop override_url too (fail closed) instead of pairing the new URL with the stale route.
  • crates/cli/src/gateway/routes.rs#L49-L63: add from_dispatch_override match arms for OpenAiModels and AnthropicCountTokens (or document why they're intentionally excluded from override targeting).
🤖 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/cli/src/gateway/mod.rs` around lines 862 - 927, Update
effective_dispatch_request in crates/cli/src/gateway/mod.rs (lines 862-927) to
fail closed when INTERNAL_DISPATCH_ROUTE_HEADER is present but
from_dispatch_override cannot parse it: discard override_url rather than
applying it with the original route. Update from_dispatch_override in
crates/cli/src/gateway/routes.rs (lines 49-63) to handle OpenAiModels and
AnthropicCountTokens, unless those variants are explicitly documented as
unsupported override targets.

752-776: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

GatewayCallGuard::drop can skip cleanup without a Tokio handle. If this destructor runs outside a Tokio runtime, both record_gateway_response_hints and finish_gateway_call are skipped, leaving active_gateway_calls stale and blocking idle shutdown.

🤖 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/cli/src/gateway/mod.rs` around lines 752 - 776, Update
GatewayCallGuard::drop to always execute the response-hint recording and
finish_gateway_call cleanup, including when Handle::try_current() finds no Tokio
runtime. Preserve the existing async cleanup sequence and ensure it is run using
an appropriate runtime fallback rather than silently skipping cleanup.
🤖 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 `@ATTRIBUTIONS-Rust.md`:
- Around line 38435-38439: Update the switchyard-translation attribution entry
by adding blank lines around its headings and changing the license code fence to
include an explicit text language, while preserving the existing license
content.

In `@crates/cli/src/gateway/mod.rs`:
- Around line 81-205: Remove the commented-out pre-refactor code blocks
containing PreparedGatewayRequest and the former gateway route/response helpers,
including the block around prepare_gateway_request and its related functions and
the additional block noted in the review. Keep the active implementations in
gateway::request, gateway::routes, and gateway::response unchanged.

In `@crates/cli/src/gateway/routes.rs`:
- Around line 49-63: The from_dispatch_override method does not support the
OpenAiModels and AnthropicCountTokens ProviderRoute variants. Add the
appropriate dispatch-override aliases for both variants so valid overrides
resolve to their corresponding route classifications, and ensure
effective_dispatch_request does not silently apply an unparseable override to a
different route.

In `@crates/cli/src/server/mod.rs`:
- Around line 740-776: Extract the shared adaptive, PII, and feature-gated
switchyard registration plus switchyard ATOF validation into a
register_and_validate_plugin_components(&PluginConfig) helper. In
crates/cli/src/server/mod.rs lines 740-776, call it from
initialize_plugin_host’s static path; in crates/cli/src/server/mod.rs lines
785-917, replace PluginActivation::initialize’s inline registration and
validation; and in crates/cli/src/diagnostics/mod.rs lines 482-515, replace
collect_observability’s duplicated block with the helper.

In `@crates/cli/tests/coverage/shared/plugins_tests.rs`:
- Around line 2417-2430: Extend
tagged_unions_support_list_items_and_top_level_fields to construct a list schema
field whose list_item is Some(&TAGGED_LIST_ITEM), then invoke the relevant
editor item-label or variant-handling path through that field and assert the
expected tagged-union behavior. Retain the existing top-level field assertions
while ensuring the test no longer passes TAGGED_LIST_ITEM only as a direct
helper argument.

---

Outside diff comments:
In `@crates/cli/src/gateway/mod.rs`:
- Around line 862-927: Update effective_dispatch_request in
crates/cli/src/gateway/mod.rs (lines 862-927) to fail closed when
INTERNAL_DISPATCH_ROUTE_HEADER is present but from_dispatch_override cannot
parse it: discard override_url rather than applying it with the original route.
Update from_dispatch_override in crates/cli/src/gateway/routes.rs (lines 49-63)
to handle OpenAiModels and AnthropicCountTokens, unless those variants are
explicitly documented as unsupported override targets.
- Around line 752-776: Update GatewayCallGuard::drop to always execute the
response-hint recording and finish_gateway_call cleanup, including when
Handle::try_current() finds no Tokio runtime. Preserve the existing async
cleanup sequence and ensure it is run using an appropriate runtime fallback
rather than silently skipping cleanup.
🪄 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: ASSERTIVE

Plan: Enterprise

Run ID: 07434d67-647c-4734-8c4b-acf4ab15d595

📥 Commits

Reviewing files that changed from the base of the PR and between 2f640ce and ab7cf50.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • ATTRIBUTIONS-Rust.md
  • crates/cli/Cargo.toml
  • crates/cli/src/agents/hermes/config.rs
  • crates/cli/src/agents/hermes/launch.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/installation/operation_lock.rs
  • crates/cli/src/mcp/protocol.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins/mod.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/src/sessions/mod.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/bootstrap_state_tests.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/mcp_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • scripts/README.md
📜 Review details
🔇 Additional comments (25)
crates/cli/Cargo.toml (1)

37-82: 📐 Maintainability & Code Quality

No dependency-boundary issues here. libc and windows-sys are target-gated, and tokio’s test-util, shell-words, and syn stay in test-only usage.

scripts/README.md (1)

21-28: 📐 Maintainability & Code Quality

No Change Needed For These Opt-In E2E Recipes. The justfile entries exist, stay out of the default test flow and CI, and call out the required local client.

crates/cli/src/mcp/protocol.rs (1)

8-9: LGTM! Version negotiation correctly supports both 2025-11-25 and 2025-06-18, resolving the prior review thread's request.

Also applies to: 53-58

crates/cli/src/agents/hermes/launch.rs (2)

23-27: LGTM! OPENAI_BASE_URL derivation and overlay creation wiring look correct.

Also applies to: 41-41


15-22: 🩺 Stability & Availability

No issue: Hermes launch already receives GATEWAY_URL_ENV. process/launcher.rs injects crate::configuration::GATEWAY_URL_ENV before crate::agents::prepare_launch, and agents/mod.rs only routes Hermes through that launch path.

			> Likely an incorrect or invalid review comment.
crates/cli/src/gateway/mod.rs (1)

393-443: LGTM! Retry-aware upstream failure classification (transport_failure/http_failure), ProviderForwarding threading through forward_upstream_request, and the new FlowError::UpstreamCliError::ProviderFailure mapping look correct and consistently applied across the buffered and streaming paths, with sensitive headers properly filtered in failure_headers.

Also applies to: 553-616, 800-836, 1067-1159

crates/cli/tests/coverage/agents/plugin_install_tests.rs (1)

1220-1242: LGTM! Matches the mutual-exclusion fix already confirmed resolved in the prior review thread (commit 4d6b464).

crates/cli/tests/coverage/shared/bootstrap_state_tests.rs (1)

210-215: LGTM!

crates/cli/src/plugins/config_io.rs (2)

12-15: LGTM!

Also applies to: 716-722, 422-422


276-284: 🎯 Functional Correctness

No issue here. PluginsScopeArgs and PricingScopeArgs map every multi-flag combination to ConfigurationScope::Invalid, so target_scope still rejects the same inputs.

			> Likely an incorrect or invalid review comment.
crates/cli/tests/coverage/shared/gateway_tests.rs (1)

15-15: LGTM! Solid coverage: internal dispatch-control stripping, upstream failure classification (retryability + sensitive-header scrubbing), and the retry-aware buffered-body structured-error regression are all correctly exercised.

Also applies to: 340-529

crates/cli/tests/coverage/shared/doctor_tests.rs (1)

1264-1290: LGTM!

crates/cli/src/plugins/mod.rs (4)

335-364: LGTM!


823-1050: LGTM! "Only write back if changed" is applied consistently, and Clear always sets an empty collection rather than removing the key, so required List/StringMap fields stay deserializable.


1052-1372: LGTM! Tagged-union Reset/Clear collapsing to a single Reset variant matches the existing scalar-field pattern in this file, and out-of-range variant/discriminator lookups fail gracefully rather than panicking.


1374-1479: LGTM! Struct-based and raw-Value-based editors mirror the section-based dispatch faithfully, and the new prompt_value guard cleanly rejects structured kinds instead of falling through.

Also applies to: 1644-1772, 1873-1963

crates/cli/src/installation/operation_lock.rs (1)

21-109: LGTM!

crates/cli/tests/coverage/shared/mcp_tests.rs (1)

16-16: LGTM!

Also applies to: 142-168

crates/cli/tests/coverage/shared/session_tests.rs (2)

24-96: LGTM!


5436-5444: LGTM!

crates/cli/tests/coverage/shared/server_tests.rs (1)

1976-2005: LGTM!

crates/cli/src/sessions/mod.rs (1)

50-152: LGTM!

Also applies to: 887-900, 1067-1081, 1493-1493, 1525-1568

crates/cli/src/diagnostics/mod.rs (1)

819-861: 🔒 Security & Privacy

No leak into Check.details. header_env values are only applied to outbound requests; the Check.details strings in this path include only the URL, transport, or static error text, not header contents.

			> Likely an incorrect or invalid review comment.
crates/cli/src/agents/hermes/config.rs (1)

43-67: 🎯 Functional Correctness

No issue: this Hermes model rewrite matches the config format. model.default is the expected key for the string shorthand, and provider/base_url are the right overrides here.

			> Likely an incorrect or invalid review comment.
crates/cli/tests/cli_tests.rs (1)

122-168: 📐 Maintainability & Code Quality

Run the required Rust validation before handoff.

  • crates/cli/tests/cli_tests.rs#L122-L168: Run cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, and just test-rust.
  • crates/cli/tests/coverage/shared/plugins_tests.rs#L9-L11: Include this changed test module in the same validation run.

As per coding guidelines, any Rust change must run cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, and just test-rust.

Source: Coding guidelines

🛑 Comments failed to post (5)
ATTRIBUTIONS-Rust.md (1)

38435-38439: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix Markdown spacing and fence metadata.

Add blank lines around the headings and specify a language for the license fence, such as text, to satisfy the reported Markdown lint rules.

Proposed fix
 ## switchyard-translation - 0.1.0
+
 **Repository URL**: https://github.com/NVIDIA-NeMo/Switchyard
 **License Type(s)**: Apache-2.0
+
 ### License: https://spdx.org/licenses/Apache-2.0.html
-```
+```text
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 38435-38435: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38438-38438: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


[warning] 38438-38438: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 38439-38439: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 38439-38439: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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 `@ATTRIBUTIONS-Rust.md` around lines 38435 - 38439, Update the
switchyard-translation attribution entry by adding blank lines around its
headings and changing the license code fence to include an explicit text
language, while preserving the existing license content.

Source: Linters/SAST tools

crates/cli/src/gateway/mod.rs (1)

81-205: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the large "pre-refactor" commented-out code blocks.

Two multi-hundred-line dead code blocks (former PreparedGatewayRequest/route/response helpers now moved to gateway::request/gateway::routes/gateway::response) are left commented out in this diff. They add significant noise and risk drifting out of sync with the real implementations.

Also applies to: 1215-1497

🤖 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/cli/src/gateway/mod.rs` around lines 81 - 205, Remove the
commented-out pre-refactor code blocks containing PreparedGatewayRequest and the
former gateway route/response helpers, including the block around
prepare_gateway_request and its related functions and the additional block noted
in the review. Keep the active implementations in gateway::request,
gateway::routes, and gateway::response unchanged.
crates/cli/src/gateway/routes.rs (1)

49-63: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

from_dispatch_override doesn't cover all ProviderRoute variants.

OpenAiModels and AnthropicCountTokens have no override aliases, so any dispatch-override attempt targeting them returns None. Combined with the silent fallback in effective_dispatch_request (gateway/mod.rs), an unparseable/incomplete route override can leave override_url applied against the wrong route classification. See the linked consolidated comment for the full-picture fix.

🤖 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/cli/src/gateway/routes.rs` around lines 49 - 63, The
from_dispatch_override method does not support the OpenAiModels and
AnthropicCountTokens ProviderRoute variants. Add the appropriate
dispatch-override aliases for both variants so valid overrides resolve to their
corresponding route classifications, and ensure effective_dispatch_request does
not silently apply an unparseable override to a different route.
crates/cli/src/server/mod.rs (1)

740-776: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Plugin component registration/validation is duplicated across three sites. The adaptive/PII/switchyard registration and switchyard ATOF validation sequence is copy-pasted rather than shared, creating drift risk if a future component is added to only one path.

  • crates/cli/src/server/mod.rs#L740-L776: extract a shared register_and_validate_plugin_components(&PluginConfig) helper and call it from the static fast path here.
  • crates/cli/src/server/mod.rs#L785-L917: replace the inline registration (798-807) and validation (904-907) calls in PluginActivation::initialize with the same shared helper.
  • crates/cli/src/diagnostics/mod.rs#L482-L515: replace the inline registration/validation block in collect_observability with the same shared helper.
📍 Affects 2 files
  • crates/cli/src/server/mod.rs#L740-L776 (this comment)
  • crates/cli/src/server/mod.rs#L785-L917
  • crates/cli/src/diagnostics/mod.rs#L482-L515
🤖 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/cli/src/server/mod.rs` around lines 740 - 776, Extract the shared
adaptive, PII, and feature-gated switchyard registration plus switchyard ATOF
validation into a register_and_validate_plugin_components(&PluginConfig) helper.
In crates/cli/src/server/mod.rs lines 740-776, call it from
initialize_plugin_host’s static path; in crates/cli/src/server/mod.rs lines
785-917, replace PluginActivation::initialize’s inline registration and
validation; and in crates/cli/src/diagnostics/mod.rs lines 482-515, replace
collect_observability’s duplicated block with the helper.
crates/cli/tests/coverage/shared/plugins_tests.rs (1)

2417-2430: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Cover the list-field metadata path.

This directly passes TAGGED_LIST_ITEM to editor_item_label, but no List schema field references it. Add coverage that constructs a list field with list_item: Some(&TAGGED_LIST_ITEM) and verifies rendering or variant handling through that schema path.

As per path instructions, tests should cover the behavior promised by the changed API surface.

🤖 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/cli/tests/coverage/shared/plugins_tests.rs` around lines 2417 - 2430,
Extend tagged_unions_support_list_items_and_top_level_fields to construct a list
schema field whose list_item is Some(&TAGGED_LIST_ITEM), then invoke the
relevant editor item-label or variant-handling path through that field and
assert the expected tagged-union behavior. Retain the existing top-level field
assertions while ensuring the test no longer passes TAGGED_LIST_ITEM only as a
direct helper argument.

Source: Path instructions

@Salonijain27 Salonijain27 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved from a dependency point of view

Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>

# Conflicts:
#	crates/cli/src/launcher.rs
#	crates/cli/tests/coverage/launcher_tests.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/cli/src/process/launcher.rs`:
- Around line 596-618: Update the AtofSinkSectionConfig::Stream branch in
observability_exporter_destinations to pass stream.url through the existing
sanitized_url helper before adding it to destinations, matching the credential
and query-parameter redaction used by other exporter destinations while
preserving the “ATOF ” label.
🪄 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: ASSERTIVE

Plan: Enterprise

Run ID: 746a7889-4df6-40df-9bb5-96978f0e4285

📥 Commits

Reviewing files that changed from the base of the PR and between ab7cf50 and 82c9e74.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/core/tests/unit/plugin_tests.rs
  • justfile
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (16)
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

**/*.rs: Any Rust change must run just test-rust
Any Rust change must run cargo fmt --all
Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all for all FFI work since it is Rust work
Run just test-rust to validate FFI changes
Run cargo clippy --workspace --all-targets -- -D warnings to enforce strict linting on FFI work

When Rust files changed as part of Go work, also run cargo fmt --all, just test-rust, and cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all when Rust files are changed as part of Node work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files are changed as part of Node work
Run just test-rust when Rust files are changed as part of Node work

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

**/*.rs: If any Rust code changed, always run just test-rust.
If any Rust code changed, also run cargo fmt --all.
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, run cargo fmt --all and cargo clippy --workspace --all-targets -- -D warnings even if relying on pre-commit.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
{crates/core,crates/adaptive}/**/*

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

Changes to crates/core or crates/adaptive must run the full language matrix

Files:

  • crates/core/tests/unit/plugin_tests.rs
crates/core/**/*.rs

📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)

If the change touched crates/core or shared runtime semantics, also use validate-change for broader validation

Files:

  • crates/core/tests/unit/plugin_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • justfile
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
crates/{core,adaptive}/**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If crates/core or crates/adaptive changed, run the full validation matrix across Rust, Python, Go, and Node.js.

Files:

  • crates/core/tests/unit/plugin_tests.rs
**/*.{rs,py,go,js,ts}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If a language surface changed, always run that language's test target even when Rust core did not change.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
crates/{core,adaptive}/**/*.rs

⚙️ CodeRabbit configuration file

crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.

Files:

  • crates/core/tests/unit/plugin_tests.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/core/tests/unit/plugin_tests.rs
  • crates/cli/tests/coverage/shared/session_tests.rs
  • crates/cli/tests/coverage/shared/doctor_tests.rs
  • crates/cli/tests/cli_tests.rs
  • crates/cli/tests/coverage/shared/server_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
{justfile,codecov.yml,codecov.yaml,.github/workflows/**/*.yml,.github/workflows/**/*.yaml}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

justfile, Codecov, and CI package/test workflows must include new plugin crates and packages.

Files:

  • justfile
justfile

📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)

Keep justfile build, test, clean, version, and package recipes for plugin crates and packages aligned with the current packaging layout.

Files:

  • justfile
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}

⚙️ CodeRabbit configuration file

{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}: Review automation changes for reproducibility, pinned versions where appropriate, secret handling, and consistency with the documented validation matrix.
Pay attention to commands that need generated native artifacts, FFI libraries, or platform-specific environment variables.

Files:

  • justfile
{crates/**/src/**/*.rs,python/**/*.py}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

Do not add tests under src; Rust tests belong in crate tests/ trees, and Python SDK tests belong under python/tests.

Files:

  • crates/cli/src/process/launcher.rs
  • crates/cli/src/diagnostics/mod.rs
🔇 Additional comments (11)
crates/cli/tests/cli_tests.rs (1)

3000-3009: LGTM!

crates/cli/tests/coverage/agents/launcher_tests.rs (1)

467-480: 🗄️ Data Integrity & Integration

Confirm the ATOF file-sink mode is intentionally omitted.

This v2 fixture’s file sink lacks mode, while crates/cli/tests/cli_tests.rs explicitly sets mode = "append". Verify that omission is valid and equivalent; otherwise this test may fail validation or exercise different behavior than intended. Add mode = "append" if it is required.

justfile (3)

1059-1070: LGTM!


1126-1127: 🩺 Stability & Availability

Verify that CI preserves FFI test serialization.

The local path now runs nemo-relay-ffi with --test-threads=1, but CI still runs the entire workspace through cargo nextest run --workspace at Line 1117. If this split prevents shared-state or cleanup races, confirm that .config/nextest.toml gives the FFI tests equivalent serialization; otherwise CI can reintroduce the failure this change is intended to prevent.

As per path instructions, review automation changes for reproducibility, pinned versions where appropriate, secret handling, and consistency with the documented validation matrix.

Source: Path instructions


1140-1142: 🩺 Stability & Availability

Review native Windows config isolation in the Python and Node test recipes. XDG_CONFIG_HOME alone may not isolate Windows config directories; align these recipes with test-rust by setting APPDATA and LOCALAPPDATA if they run on Windows. Same applies to the later recipe.

crates/cli/src/diagnostics/mod.rs (1)

552-612: LGTM!

Also applies to: 773-990, 944-961, 1098-1166

crates/cli/tests/coverage/shared/doctor_tests.rs (1)

788-815: LGTM!

Also applies to: 944-959, 1120-1168, 1206-1238

crates/cli/tests/coverage/shared/plugins_tests.rs (1)

176-208: LGTM!

Also applies to: 647-667, 763-790, 812-878, 1508-1536, 2015-2044, 2314-2327, 2606-2622

crates/cli/tests/coverage/shared/server_tests.rs (1)

842-933: LGTM!

Also applies to: 953-1039, 1042-1242, 1245-1391, 1394-1510, 1513-1805, 1808-1943, 2110-2142

crates/cli/tests/coverage/shared/session_tests.rs (1)

98-120: LGTM!

Also applies to: 3163-3251, 3299-3413, 3634-3697

crates/core/tests/unit/plugin_tests.rs (1)

1143-1169: LGTM! Good addition — waiting on PLUGIN_MUTATION_OWNER returning to Idle closes a race between diagnostic visibility and lease release. As per path instructions, "Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions."

Source: Path instructions

Comment thread crates/cli/src/process/launcher.rs
willkill07 and others added 3 commits July 14, 2026 15:55
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>

@Salonijain27 Salonijain27 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved from a dependency point of view

Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/cli/src/gateway/mod.rs (1)

639-669: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Avoid panicking inside Drop.

When no tokio runtime is current, this builds a throwaway runtime and .expect()s on build(). If Drop::drop runs here while the thread is already unwinding from a prior panic, an .expect() panic here triggers a double-panic abort of the whole process — a severe outcome for what should be a best-effort cleanup path. Runtime build failures are rare (thread/resource exhaustion), but the fallback exists precisely for the "unusual context" case, so it should degrade gracefully rather than assume success.

🛡️ Proposed fix: log and skip cleanup instead of panicking
         if let Ok(handle) = tokio::runtime::Handle::try_current() {
             handle.spawn(cleanup);
         } else {
-            tokio::runtime::Builder::new_current_thread()
-                .enable_all()
-                .build()
-                .expect("gateway cleanup runtime should build")
-                .block_on(cleanup);
+            match tokio::runtime::Builder::new_current_thread().enable_all().build() {
+                Ok(runtime) => runtime.block_on(cleanup),
+                Err(error) => {
+                    eprintln!("nemo-relay CLI gateway: failed to build cleanup runtime; skipping session finalize: {error}");
+                }
+            }
         }
🤖 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/cli/src/gateway/mod.rs` around lines 639 - 669, Update
GatewayCallGuard::drop so failure to build the fallback Tokio runtime is handled
without panicking: log the runtime-build error and skip cleanup when
Builder::build() fails. Preserve the existing spawned cleanup path when a
current runtime exists and the block_on fallback when runtime construction
succeeds.
🤖 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/cli/src/server/mod.rs`:
- Around line 799-813: Update register_and_validate_plugin_components to attempt
every component registration and Switchyard ATOF validation, collecting each
PluginComponentSetupError instead of returning on the first failure. Adjust
validate_config and initialize_plugin_host to preserve their pass/fail behavior
by checking the collected errors and using the first error where required.
Update diagnostics::collect_observability to render a separate diagnostic for
every collected component error.

---

Outside diff comments:
In `@crates/cli/src/gateway/mod.rs`:
- Around line 639-669: Update GatewayCallGuard::drop so failure to build the
fallback Tokio runtime is handled without panicking: log the runtime-build error
and skip cleanup when Builder::build() fails. Preserve the existing spawned
cleanup path when a current runtime exists and the block_on fallback when
runtime construction succeeds.
🪄 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: ASSERTIVE

Plan: Enterprise

Run ID: 26359134-ae3e-455a-a919-0356a38e406e

📥 Commits

Reviewing files that changed from the base of the PR and between 82c9e74 and 1a6a933.

📒 Files selected for processing (12)
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/server/mod.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • justfile
📜 Review details
🧰 Additional context used
📓 Path-based instructions (15)
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

**/*.rs: Any Rust change must run just test-rust
Any Rust change must run cargo fmt --all
Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all for all FFI work since it is Rust work
Run just test-rust to validate FFI changes
Run cargo clippy --workspace --all-targets -- -D warnings to enforce strict linting on FFI work

When Rust files changed as part of Go work, also run cargo fmt --all, just test-rust, and cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Run cargo fmt --all when Rust files are changed as part of Node work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files are changed as part of Node work
Run just test-rust when Rust files are changed as part of Node work

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

**/*.rs: If any Rust code changed, always run just test-rust.
If any Rust code changed, also run cargo fmt --all.
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, run cargo fmt --all and cargo clippy --workspace --all-targets -- -D warnings even if relying on pre-commit.

Files:

  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
{crates/**/src/**/*.rs,python/**/*.py}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

Do not add tests under src; Rust tests belong in crate tests/ trees, and Python SDK tests belong under python/tests.

Files:

  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
**/*

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

Files:

  • crates/cli/src/plugins/config_io.rs
  • justfile
  • crates/cli/src/gateway/routes.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
**/*.{rs,py,go,js,ts}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If a language surface changed, always run that language's test target even when Rust core did not change.

Files:

  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/gateway/routes.rs
  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/cli/src/process/launcher.rs
  • crates/cli/src/gateway/mod.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
  • crates/cli/src/diagnostics/mod.rs
  • crates/cli/src/server/mod.rs
{justfile,codecov.yml,codecov.yaml,.github/workflows/**/*.yml,.github/workflows/**/*.yaml}

📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)

justfile, Codecov, and CI package/test workflows must include new plugin crates and packages.

Files:

  • justfile
justfile

📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)

Keep justfile build, test, clean, version, and package recipes for plugin crates and packages aligned with the current packaging layout.

Files:

  • justfile
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}

⚙️ CodeRabbit configuration file

{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}: Review automation changes for reproducibility, pinned versions where appropriate, secret handling, and consistency with the documented validation matrix.
Pay attention to commands that need generated native artifacts, FFI libraries, or platform-specific environment variables.

Files:

  • justfile
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/cli/tests/coverage/agents/plugin_install_tests.rs
  • crates/cli/tests/coverage/agents/launcher_tests.rs
  • crates/cli/tests/coverage/shared/plugins_tests.rs
  • crates/cli/tests/coverage/shared/gateway_tests.rs
  • crates/ffi/tests/integration/plugin_activation_tests.rs
crates/ffi/**

📄 CodeRabbit inference engine (.agents/skills/test-ffi-surface/SKILL.md)

Rebuild the FFI crate in release mode so the shared library and header stay in sync when making changes to crates/ffi

Files:

  • crates/ffi/tests/integration/plugin_activation_tests.rs
crates/ffi/**/*.rs

📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)

If the change touched crates/ffi, also use test-ffi-surface for validation

Use C FFI export names prefixed with nemo_relay_ in the raw C FFI layer.

Files:

  • crates/ffi/tests/integration/plugin_activation_tests.rs
crates/{python,ffi,node}/**/*

⚙️ CodeRabbit configuration file

crates/{python,ffi,node}/**/*: Treat binding changes as public API changes. Check for parity with the other language bindings, FFI ownership/lifetime safety,
callback error propagation, stable type conversion, and consistent async/stream semantics.
Flag changes that update one binding without corresponding tests or documentation for the same surface elsewhere.

Files:

  • crates/ffi/tests/integration/plugin_activation_tests.rs
🔇 Additional comments (17)
crates/cli/tests/coverage/agents/plugin_install_tests.rs (1)

3180-3180: LGTM!

Also applies to: 3194-3194

crates/cli/tests/coverage/agents/launcher_tests.rs (1)

478-478: LGTM!

Also applies to: 510-510

justfile (2)

471-471: LGTM!

Also applies to: 1060-1071, 1258-1261, 1274-1278


1127-1128: 🎯 Functional Correctness

No change needed for the FFI test command. cargo test -p nemo-relay-ffi -- --test-threads=1 already includes the required -- separator.

			> Likely an incorrect or invalid review comment.
crates/cli/tests/coverage/shared/plugins_tests.rs (1)

2463-2490: LGTM!

crates/cli/tests/coverage/shared/gateway_tests.rs (1)

162-183: LGTM!

Also applies to: 416-478, 1252-1331

crates/ffi/tests/integration/plugin_activation_tests.rs (2)

20-24: LGTM!

Also applies to: 503-554


20-24: 📐 Maintainability & Code Quality

Keep the TempDir alive with the cached library path
NativeFixture now holds the TempDir alongside the cached PathBuf, so the fixture path stays valid for the lifetime of the cached library.

crates/cli/src/gateway/mod.rs (2)

583-637: LGTM!


731-825: LGTM! Discarding override_url when the paired route header failed to parse avoids pairing a mismatched URL with the fallback route.

crates/cli/src/gateway/routes.rs (2)

32-131: LGTM!


147-196: LGTM!

crates/cli/src/process/launcher.rs (1)

613-615: LGTM! This resolves the previously flagged credential-leak issue by routing the ATOF stream URL through sanitized_url like the other exporter destinations.

crates/cli/src/server/mod.rs (2)

815-839: LGTM!


861-875: LGTM! Merging dynamic components into plugin_config before calling the shared registration/validation helper correctly lets Switchyard ATOF validation see the full merged component set.

crates/cli/src/diagnostics/mod.rs (1)

476-483: Delegation to the shared helper is correctly wired (check_name()/diagnostic_details()Check). See the comment on register_and_validate_plugin_components in crates/cli/src/server/mod.rs (lines 799-813) regarding the fail-fast behavior's effect on this doctor check's ability to surface multiple simultaneous plugin-registration failures.

crates/cli/src/plugins/config_io.rs (1)

704-721: LGTM! Fail-fast is the right behavior here since validate_config only needs a single pass/fail verdict for the config being installed.

Comment thread crates/cli/src/server/mod.rs
Signed-off-by: Will Killian <wkillian@nvidia.com>
@willkill07

Copy link
Copy Markdown
Member Author

/merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking PR introduces a breaking change Feature a new feature lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code size:XXL PR is very large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants