feat(cli)!: add MCP-managed shared gateway for coding agents#395
Conversation
|
Caution Review failedAn error occurred during the review process. Please try again later. WalkthroughThis PR restructures the CLI into an ChangesCodex plugin_shim trust flow and MCP packaging
Estimated code review effort: 5 (Critical) | ~180 minutes Persistent agent integration platform
Test coverage for restructured CLI
Documentation and packaging assets
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
37d6608 to
d8740a1
Compare
There was a problem hiding this comment.
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
📒 Files selected for processing (11)
README.mdcrates/cli/src/plugin_shim/codex.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/tests/coverage/plugin_shim_tests.rscrates/cli/tests/coverage/server_tests.rsdocs/nemo-relay-cli/plugin-installation.mdxintegrations/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 spellNVIDIAin all caps. Do not useNvidia,nvidia,nVidia,nVIDIA, orNV.
Usean NVIDIAbefore a noun because the name starts with an 'en' sound.
Do not add a registered trademark symbol afterNVIDIAwhen 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 withNVIDIAon 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 withs, not an apostrophe, such asGPUs.
In headings, common acronyms can remain abbreviated. Spell out the term in the first or second sentence of the body.
Common terms such asCPU,GPU,PC,API, andUIusually do not need to be spelled out for developer audiences.
Files:
README.mdintegrations/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.mdintegrations/coding-agents/codex/README.md
**/*.{md,rst,txt}
📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)
Spell
NVIDIAin all caps. Do not useNvidia,nvidia, orNV.
Files:
README.mdintegrations/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.
Usecanfor possibility and reservemayfor permission.
Useafterfor temporal relationships instead ofonce.
Preferrefer tooverseewhen 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.mdintegrations/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.mdintegrations/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, andferndirectories, 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 asRELEASING.md, not as user-facing docs pages orCHANGELOG.md
Keep stable user-facing wrappers atscripts/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, andgrpc-v1protocol details on separate pagesIf links in documentation change, run
just docs-linkcheck.
Files:
README.mddocs/nemo-relay-cli/plugin-installation.mdxintegrations/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.mddocs/nemo-relay-cli/plugin-installation.mdxintegrations/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, usemaintain-dynamic-pluginsand 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, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
README.mdcrates/cli/tests/coverage/server_tests.rscrates/cli/src/server.rsdocs/nemo-relay-cli/plugin-installation.mdxintegrations/coding-agents/codex/README.mdcrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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.mdchange, 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:
- Scope stacks decide where work belongs and which scope-local behavior is visible.
- Middleware registries decide what guardrails and intercepts run around managed calls.
- Plugins install reusable runtime behavior from configuration.
- Events record runtime behavior in ATOF form.
- 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 patternsPrerequisites
Insta...
Files:
README.mdcrates/cli/tests/coverage/server_tests.rscrates/cli/src/server.rsdocs/nemo-relay-cli/plugin-installation.mdxintegrations/coding-agents/codex/README.mdcrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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.mddocs/nemo-relay-cli/plugin-installation.mdx
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/cli/tests/coverage/server_tests.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin 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.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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 prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/cli/tests/coverage/server_tests.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/cli/src/plugin_shim/codex.rscrates/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.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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 cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/cli/src/server.rscrates/cli/src/plugin_shim/mod.rscrates/cli/src/plugin_shim/shared.rscrates/cli/src/plugin_shim/codex_app_server.rscrates/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_readyis reachable fromserver_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 incodex_app_server.rsLines 158-160 applies here (&& let Some(client) = ...); resolve once by confirming the pinned toolchain is>= 1.88.
236-240: 🎯 Functional Correctness | ⚡ Quick winLexical path equality may reject legitimately-matching hooks.
Path::new(&hook.source_path) == hooks_pathcompares components lexically. If the app-server reports a canonicalized/symlink-resolved path (common on macOS, e.g./var→/private/var) whilehome_dir().join(".codex/hooks.json")is not resolved, this filter yields no hooks, andauto_trust_codex_hooksthen 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 & IntegrationNo rollback gap here
prepare_codex_configonly parses and validatesconfig.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 CorrectnessLet chains are supported by the pinned toolchain
rust-toolchain.tomlpins Rust1.93.0, soif let Some(errors) = ... && !errors.is_empty()is valid. The MSRV concern does not apply here. The same applies tocrates/cli/src/plugin_shim/codex.rs.> Likely an incorrect or invalid review comment.
18-30: 🗄️ Data Integrity & IntegrationNo change needed The
CodexHookMetadatafield 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!
License DiffCompared against Lockfile license changesLockfile License ChangesRustAdded
Removed
Updated/Changed
NodeAdded
Removed
Updated/Changed
PythonAdded
Removed
Updated/Changed
Status output |
There was a problem hiding this comment.
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
📒 Files selected for processing (21)
crates/cli/Cargo.tomlcrates/cli/src/config.rscrates/cli/src/main.rscrates/cli/src/mcp.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/plugin_install/state.rscrates/cli/src/plugin_shim/codex.rscrates/cli/src/server.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/installer_tests.rscrates/cli/tests/coverage/main_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/tests/coverage/plugin_install_tests.rsintegrations/coding-agents/README.mdintegrations/coding-agents/codex/.codex-plugin/plugin.jsonintegrations/coding-agents/codex/.mcp.jsonintegrations/coding-agents/codex/README.mdintegrations/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, usemaintain-dynamic-pluginsand 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, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
integrations/coding-agents/codex/hooks/hooks.jsoncrates/cli/Cargo.tomlcrates/cli/tests/coverage/main_tests.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rsintegrations/coding-agents/README.mdcrates/cli/src/plugin_install/marketplace.rsintegrations/coding-agents/codex/README.mdcrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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:
- Scope stacks decide where work belongs and which scope-local behavior is visible.
- Middleware registries decide what guardrails and intercepts run around managed calls.
- Plugins install reusable runtime behavior from configuration.
- Events record runtime behavior in ATOF form.
- 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 patternsPrerequisites
Insta...
Files:
integrations/coding-agents/codex/hooks/hooks.jsoncrates/cli/Cargo.tomlcrates/cli/tests/coverage/main_tests.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rsintegrations/coding-agents/README.mdcrates/cli/src/plugin_install/marketplace.rsintegrations/coding-agents/codex/README.mdcrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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 asrelease/<major>.<minor>.Keep Rust package names and workspace metadata in
Cargo.tomlinternally 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 runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/cli/tests/coverage/main_tests.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin 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.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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 prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/cli/tests/coverage/main_tests.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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.rscrates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/tests/coverage/installer_tests.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/cli/tests/coverage/plugin_install_tests.rscrates/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.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/mcp_tests.rscrates/cli/tests/coverage/installer_tests.rscrates/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 cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/cli/src/plugin_install/setup.rscrates/cli/src/main.rscrates/cli/src/config.rscrates/cli/src/plugin_install/host.rscrates/cli/src/plugin_install/state.rscrates/cli/src/plugin_install/marketplace.rscrates/cli/src/plugin_install/mod.rscrates/cli/src/mcp.rscrates/cli/src/server.rscrates/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 spellNVIDIAin all caps. Do not useNvidia,nvidia,nVidia,nVIDIA, orNV.
Usean NVIDIAbefore a noun because the name starts with an 'en' sound.
Do not add a registered trademark symbol afterNVIDIAwhen 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 withNVIDIAon 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 withs, not an apostrophe, such asGPUs.
In headings, common acronyms can remain abbreviated. Spell out the term in the first or second sentence of the body.
Common terms such asCPU,GPU,PC,API, andUIusually do not need to be spelled out for developer audiences.
Files:
integrations/coding-agents/README.mdintegrations/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.mdintegrations/coding-agents/codex/README.md
**/*.{md,rst,txt}
📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)
Spell
NVIDIAin all caps. Do not useNvidia,nvidia, orNV.
Files:
integrations/coding-agents/README.mdintegrations/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.
Usecanfor possibility and reservemayfor permission.
Useafterfor temporal relationships instead ofonce.
Preferrefer tooverseewhen 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.mdintegrations/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.mdintegrations/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 asRELEASING.md, not as user-facing docs pages orCHANGELOG.md
Keep stable user-facing wrappers atscripts/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, andgrpc-v1protocol details on separate pagesIf links in documentation change, run
just docs-linkcheck.
Files:
integrations/coding-agents/README.mdintegrations/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.mdintegrations/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 & AvailabilityReadiness 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 & IntegrationMCP stdio uses newline-delimited JSON, so
read_lineis 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 & AvailabilityNo issue — the workspace targets Rust 1.93.0 and edition 2024, so this
letchain is supported.
36-53: 🗄️ Data Integrity & IntegrationSnapshot order is fine
prepare_codex_configonly parsesconfig.tomland 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 existingvalidate_relay_plugin_shimpattern and matches the mocked-failure test expectations.crates/cli/src/plugin_install/marketplace.rs (2)
143-160: 🎯 Functional CorrectnessConfirm the hardcoded MCP bind address doesn't drift from a single source of truth, and how port conflicts are handled.
NEMO_RELAY_GATEWAY_BINDis 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, ifconfig.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 themcpsubcommand'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.jsoncontent, 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 behindvalidate_relay_mcp, matchingrelay_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
027d8ed to
f7779fc
Compare
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
There was a problem hiding this comment.
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 winDispatch-route override contract is incomplete and fails open instead of closed.
from_dispatch_overridedoesn't cover allProviderRoutevariants, andeffective_dispatch_requestsilently falls back to the original route on any parse failure while still applying an independently-suppliedoverride_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: whenINTERNAL_DISPATCH_ROUTE_HEADERis present but fails to parse viafrom_dispatch_override, dropoverride_urltoo (fail closed) instead of pairing the new URL with the stale route.crates/cli/src/gateway/routes.rs#L49-L63: addfrom_dispatch_overridematch arms forOpenAiModelsandAnthropicCountTokens(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::dropcan skip cleanup without a Tokio handle. If this destructor runs outside a Tokio runtime, bothrecord_gateway_response_hintsandfinish_gateway_callare skipped, leavingactive_gateway_callsstale 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
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (23)
ATTRIBUTIONS-Rust.mdcrates/cli/Cargo.tomlcrates/cli/src/agents/hermes/config.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/diagnostics/mod.rscrates/cli/src/gateway/mod.rscrates/cli/src/gateway/routes.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/plugins/mod.rscrates/cli/src/server/mod.rscrates/cli/src/sessions/mod.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/bootstrap_state_tests.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/shared/session_tests.rsscripts/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 spellNVIDIAin all caps. Do not useNvidia,nvidia,nVidia,nVIDIA, orNV.
Usean NVIDIAbefore a noun because the name starts with an 'en' sound.
Do not add a registered trademark symbol afterNVIDIAwhen 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 withNVIDIAon 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 withs, not an apostrophe, such asGPUs.
In headings, common acronyms can remain abbreviated. Spell out the term in the first or second sentence of the body.
Common terms such asCPU,GPU,PC,API, andUIusually do not need to be spelled out for developer audiences.
Files:
scripts/README.mdATTRIBUTIONS-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.mdATTRIBUTIONS-Rust.md
**/*.{md,rst,txt}
📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)
Spell
NVIDIAin all caps. Do not useNvidia,nvidia, orNV.
Files:
scripts/README.mdATTRIBUTIONS-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.
Usecanfor possibility and reservemayfor permission.
Useafterfor temporal relationships instead ofonce.
Preferrefer tooverseewhen 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.mdATTRIBUTIONS-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.mdATTRIBUTIONS-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 asRELEASING.md, not as user-facing docs pages orCHANGELOG.md
Keep stable user-facing wrappers atscripts/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, andgrpc-v1protocol details on separate pagesIf links in documentation change, run
just docs-linkcheck.
Files:
scripts/README.mdATTRIBUTIONS-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.mdATTRIBUTIONS-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, usemaintain-dynamic-pluginsand 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, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
scripts/README.mdcrates/cli/Cargo.tomlATTRIBUTIONS-Rust.mdcrates/cli/tests/coverage/shared/bootstrap_state_tests.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/src/plugins/mod.rscrates/cli/tests/cli_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/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 asrelease/<major>.<minor>.Keep Rust package names and workspace metadata in
Cargo.tomlinternally 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 runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/cli/tests/coverage/shared/bootstrap_state_tests.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/src/plugins/mod.rscrates/cli/tests/cli_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/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.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/src/plugins/mod.rscrates/cli/tests/cli_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/src/sessions/mod.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,py,js,mjs,cjs,ts,tsx}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin 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.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/src/plugins/mod.rscrates/cli/tests/cli_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/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 prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/cli/tests/coverage/shared/bootstrap_state_tests.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/src/plugins/mod.rscrates/cli/tests/cli_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/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.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/src/plugins/mod.rscrates/cli/tests/cli_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/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.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/src/plugins/mod.rscrates/cli/tests/cli_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/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.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/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 cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/agents/hermes/config.rscrates/cli/src/server/mod.rscrates/cli/src/diagnostics/mod.rscrates/cli/src/plugins/mod.rscrates/cli/src/gateway/mod.rscrates/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 QualityNo dependency-boundary issues here.
libcandwindows-sysare target-gated, andtokio’stest-util,shell-words, andsynstay in test-only usage.scripts/README.md (1)
21-28: 📐 Maintainability & Code QualityNo Change Needed For These Opt-In E2E Recipes. The
justfileentries 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 both2025-11-25and2025-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_URLderivation and overlay creation wiring look correct.Also applies to: 41-41
15-22: 🩺 Stability & AvailabilityNo issue: Hermes launch already receives
GATEWAY_URL_ENV.process/launcher.rsinjectscrate::configuration::GATEWAY_URL_ENVbeforecrate::agents::prepare_launch, andagents/mod.rsonly 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),ProviderForwardingthreading throughforward_upstream_request, and the newFlowError::Upstream→CliError::ProviderFailuremapping look correct and consistently applied across the buffered and streaming paths, with sensitive headers properly filtered infailure_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 CorrectnessNo issue here.
PluginsScopeArgsandPricingScopeArgsmap every multi-flag combination toConfigurationScope::Invalid, sotarget_scopestill 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 singleResetvariant 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 newprompt_valueguard 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 & PrivacyNo leak into
Check.details.header_envvalues are only applied to outbound requests; theCheck.detailsstrings 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 CorrectnessNo issue: this Hermes model rewrite matches the config format.
model.defaultis the expected key for the string shorthand, andprovider/base_urlare the right overrides here.> Likely an incorrect or invalid review comment.crates/cli/tests/cli_tests.rs (1)
122-168: 📐 Maintainability & Code QualityRun the required Rust validation before handoff.
crates/cli/tests/cli_tests.rs#L122-L168: Runcargo fmt --all,cargo clippy --workspace --all-targets -- -D warnings, andjust 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, andjust test-rust.Source: Coding guidelines
There was a problem hiding this comment.
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 winDispatch-route override contract is incomplete and fails open instead of closed.
from_dispatch_overridedoesn't cover allProviderRoutevariants, andeffective_dispatch_requestsilently falls back to the original route on any parse failure while still applying an independently-suppliedoverride_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: whenINTERNAL_DISPATCH_ROUTE_HEADERis present but fails to parse viafrom_dispatch_override, dropoverride_urltoo (fail closed) instead of pairing the new URL with the stale route.crates/cli/src/gateway/routes.rs#L49-L63: addfrom_dispatch_overridematch arms forOpenAiModelsandAnthropicCountTokens(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::dropcan skip cleanup without a Tokio handle. If this destructor runs outside a Tokio runtime, bothrecord_gateway_response_hintsandfinish_gateway_callare skipped, leavingactive_gateway_callsstale 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
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (23)
ATTRIBUTIONS-Rust.mdcrates/cli/Cargo.tomlcrates/cli/src/agents/hermes/config.rscrates/cli/src/agents/hermes/launch.rscrates/cli/src/diagnostics/mod.rscrates/cli/src/gateway/mod.rscrates/cli/src/gateway/routes.rscrates/cli/src/installation/operation_lock.rscrates/cli/src/mcp/protocol.rscrates/cli/src/plugins/config_io.rscrates/cli/src/plugins/mod.rscrates/cli/src/server/mod.rscrates/cli/src/sessions/mod.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/bootstrap_state_tests.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/mcp_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/shared/session_tests.rsscripts/README.md
📜 Review details
🔇 Additional comments (25)
crates/cli/Cargo.toml (1)
37-82: 📐 Maintainability & Code QualityNo dependency-boundary issues here.
libcandwindows-sysare target-gated, andtokio’stest-util,shell-words, andsynstay in test-only usage.scripts/README.md (1)
21-28: 📐 Maintainability & Code QualityNo Change Needed For These Opt-In E2E Recipes. The
justfileentries 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 both2025-11-25and2025-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_URLderivation and overlay creation wiring look correct.Also applies to: 41-41
15-22: 🩺 Stability & AvailabilityNo issue: Hermes launch already receives
GATEWAY_URL_ENV.process/launcher.rsinjectscrate::configuration::GATEWAY_URL_ENVbeforecrate::agents::prepare_launch, andagents/mod.rsonly 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),ProviderForwardingthreading throughforward_upstream_request, and the newFlowError::Upstream→CliError::ProviderFailuremapping look correct and consistently applied across the buffered and streaming paths, with sensitive headers properly filtered infailure_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 CorrectnessNo issue here.
PluginsScopeArgsandPricingScopeArgsmap every multi-flag combination toConfigurationScope::Invalid, sotarget_scopestill 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 singleResetvariant 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 newprompt_valueguard 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 & PrivacyNo leak into
Check.details.header_envvalues are only applied to outbound requests; theCheck.detailsstrings 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 CorrectnessNo issue: this Hermes model rewrite matches the config format.
model.defaultis the expected key for the string shorthand, andprovider/base_urlare the right overrides here.> Likely an incorrect or invalid review comment.crates/cli/tests/cli_tests.rs (1)
122-168: 📐 Maintainability & Code QualityRun the required Rust validation before handoff.
crates/cli/tests/cli_tests.rs#L122-L168: Runcargo fmt --all,cargo clippy --workspace --all-targets -- -D warnings, andjust 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, andjust 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 togateway::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_overridedoesn't cover allProviderRoutevariants.
OpenAiModelsandAnthropicCountTokenshave no override aliases, so any dispatch-override attempt targeting them returnsNone. Combined with the silent fallback ineffective_dispatch_request(gateway/mod.rs), an unparseable/incomplete route override can leaveoverride_urlapplied 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 sharedregister_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 inPluginActivation::initializewith the same shared helper.crates/cli/src/diagnostics/mod.rs#L482-L515: replace the inline registration/validation block incollect_observabilitywith the same shared helper.📍 Affects 2 files
crates/cli/src/server/mod.rs#L740-L776(this comment)crates/cli/src/server/mod.rs#L785-L917crates/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_ITEMtoeditor_item_label, but noListschema field references it. Add coverage that constructs a list field withlist_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
left a comment
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/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
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
crates/cli/src/diagnostics/mod.rscrates/cli/src/process/launcher.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/shared/session_tests.rscrates/core/tests/unit/plugin_tests.rsjustfile
📜 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 runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/core/tests/unit/plugin_tests.rscrates/cli/src/process/launcher.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rs
{crates/core,crates/adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
Changes to
crates/coreorcrates/adaptivemust 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/coreor shared runtime semantics, also usevalidate-changefor 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.rscrates/cli/src/process/launcher.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/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}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin 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.rscrates/cli/src/process/launcher.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/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 prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/core/tests/unit/plugin_tests.rscrates/cli/src/process/launcher.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/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.rscrates/cli/src/process/launcher.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/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, usemaintain-dynamic-pluginsand 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, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
crates/core/tests/unit/plugin_tests.rsjustfilecrates/cli/src/process/launcher.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rs
crates/{core,adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, 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.rscrates/cli/src/process/launcher.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/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.rscrates/cli/tests/coverage/shared/session_tests.rscrates/cli/tests/coverage/shared/doctor_tests.rscrates/cli/tests/cli_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/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
justfilebuild, 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 cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/cli/src/process/launcher.rscrates/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 & IntegrationConfirm the ATOF file-sink mode is intentionally omitted.
This v2 fixture’s file sink lacks
mode, whilecrates/cli/tests/cli_tests.rsexplicitly setsmode = "append". Verify that omission is valid and equivalent; otherwise this test may fail validation or exercise different behavior than intended. Addmode = "append"if it is required.justfile (3)
1059-1070: LGTM!
1126-1127: 🩺 Stability & AvailabilityVerify that CI preserves FFI test serialization.
The local path now runs
nemo-relay-ffiwith--test-threads=1, but CI still runs the entire workspace throughcargo nextest run --workspaceat Line 1117. If this split prevents shared-state or cleanup races, confirm that.config/nextest.tomlgives 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 & AvailabilityReview native Windows config isolation in the Python and Node test recipes.
XDG_CONFIG_HOMEalone may not isolate Windows config directories; align these recipes withtest-rustby settingAPPDATAandLOCALAPPDATAif 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 onPLUGIN_MUTATION_OWNERreturning toIdlecloses 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
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Salonijain27
left a comment
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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 winAvoid panicking inside
Drop.When no tokio runtime is current, this builds a throwaway runtime and
.expect()s onbuild(). IfDrop::dropruns 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
📒 Files selected for processing (12)
crates/cli/src/diagnostics/mod.rscrates/cli/src/gateway/mod.rscrates/cli/src/gateway/routes.rscrates/cli/src/plugins/config_io.rscrates/cli/src/process/launcher.rscrates/cli/src/server/mod.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/ffi/tests/integration/plugin_activation_tests.rsjustfile
📜 Review details
🧰 Additional context used
📓 Path-based instructions (15)
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/ffi/tests/integration/plugin_activation_tests.rscrates/cli/src/diagnostics/mod.rscrates/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.rscrates/cli/src/gateway/routes.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/ffi/tests/integration/plugin_activation_tests.rscrates/cli/src/diagnostics/mod.rscrates/cli/src/server/mod.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,py,js,mjs,cjs,ts,tsx}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin 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.rscrates/cli/src/gateway/routes.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/ffi/tests/integration/plugin_activation_tests.rscrates/cli/src/diagnostics/mod.rscrates/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 prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/ffi/tests/integration/plugin_activation_tests.rscrates/cli/src/diagnostics/mod.rscrates/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.rscrates/cli/src/gateway/routes.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/ffi/tests/integration/plugin_activation_tests.rscrates/cli/src/diagnostics/mod.rscrates/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 cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/cli/src/plugins/config_io.rscrates/cli/src/gateway/routes.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/cli/src/diagnostics/mod.rscrates/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, usemaintain-dynamic-pluginsand 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, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
crates/cli/src/plugins/config_io.rsjustfilecrates/cli/src/gateway/routes.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/ffi/tests/integration/plugin_activation_tests.rscrates/cli/src/diagnostics/mod.rscrates/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.rscrates/cli/src/gateway/routes.rscrates/cli/tests/coverage/agents/plugin_install_tests.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/src/process/launcher.rscrates/cli/src/gateway/mod.rscrates/ffi/tests/integration/plugin_activation_tests.rscrates/cli/src/diagnostics/mod.rscrates/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
justfilebuild, 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.rscrates/cli/tests/coverage/agents/launcher_tests.rscrates/cli/tests/coverage/shared/plugins_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/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 usetest-ffi-surfacefor validationUse 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 CorrectnessNo change needed for the FFI test command.
cargo test -p nemo-relay-ffi -- --test-threads=1already 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 QualityKeep the
TempDiralive with the cached library path
NativeFixturenow holds theTempDiralongside the cachedPathBuf, 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! Discardingoverride_urlwhen 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 throughsanitized_urllike the other exporter destinations.crates/cli/src/server/mod.rs (2)
815-839: LGTM!
861-875: LGTM! Merging dynamic components intoplugin_configbefore 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 onregister_and_validate_plugin_componentsincrates/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 sincevalidate_configonly needs a single pass/fail verdict for the config being installed.
Signed-off-by: Will Killian <wkillian@nvidia.com>
|
/merge |
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 andgeneration-fenced, and the shared gateway uses user-scoped configuration.
Run
nemo-relay install <agent> --forcefor each installed integration, ornemo-relay install all --force. Previously generated integration state isnot 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.
nemo-relay mcpeagerly 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.Details
Problems addressed
New behavior
nemo-relay mcpacquires the gateway before MCP initialization and advertises no tools.alwaysLoad; Hermes uses the same MCP lifecycle and canonical hooks.Component breakdown
crates/cli/src/commands/crates/cli/src/agents/crates/cli/src/mcp/gateway.rscrates/cli/src/server.rscrates/cli/src/bootstrap/crates/cli/src/gateway/client.rscrates/cli/src/process/detached.rssrc/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
/modelsbefore launching required MCP servers; captured turns and routed provider requests still wait for readiness.Validation
cargo fmt --allcargo clippy --workspace --all-targets -- -D warningsjust test-rust(992 CLI unit tests and 80 external CLI process tests, plus the complete Rust workspace)uv run pre-commit run --all-filescargo test -p nemo-relay-cli --test architecture_testsWhere should the reviewer start?
Review in four bounded passes:
crates/cli/src/commands/mod.rsand its thin executor modules to verify unchanged dispatch and exit behavior.crates/cli/src/agents/mod.rs, then one host directory at a time. Verify agent-specific adapters, alignment, hooks, trust, and setup are colocated.crates/cli/src/mcp/gateway.rs,bootstrap/mod.rs,gateway/client.rs,process/detached.rs, andserver/mod.rsfor eager acquisition, authenticated adoption, recovery, and idle shutdown.crates/cli/tests/architecture_tests.rsand 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)
Bugs addressed
Gateway bootstrap and lifecycle
nemo-relay mcpstarts, before waiting for MCP initialization.Hooks and event delivery
nemo-relay runsessions from also invoking persistent hooks and duplicating events.Codex correlation
client_metadata.session_idfor Codex root-session correlation.prompt_cache_keyas a compatibility fallback.client_metadata.thread_idas subagent ownership forcollab_spawn.Installation, trust, and rollback
alwaysLoadconfiguration and validates it during diagnosis.Filesystem and ownership safety
marketplaceRootorpluginRootvalues from granting recursive deletion authority over arbitrary directories.Process management
Environment propagation
NEMO_RELAY_,OTEL_, andAWS_.header_env, AWS secret-key, and session-token variables.New features
Adds the Rust-native
nemo-relay mcpcommand.Makes
nemo-relay mcpa lifecycle coordinator rather than a tool-serving MCP implementation.Advertises no MCP tools while keeping the MCP stdio session alive.
Supports the architecture:
Starts or adopts a detached Rust
nemo-relay --bind 127.0.0.1:47632gateway.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
/healthzwith 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.rsto the application entrypoint.Moves all Clap-derived types under
commands/.Makes
alla 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
Diagnostics and operator experience
Expands doctor checks for:
alwaysLoad;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-forwardflags 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:
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