Skip to content

feat: configure dynamic plugins through CLI#325

Open
willkill07 wants to merge 6 commits into
NVIDIA:mainfrom
willkill07:wkk_dynamic-plugin-config-editor
Open

feat: configure dynamic plugins through CLI#325
willkill07 wants to merge 6 commits into
NVIDIA:mainfrom
willkill07:wkk_dynamic-plugin-config-editor

Conversation

@willkill07

@willkill07 willkill07 commented Jun 29, 2026

Copy link
Copy Markdown
Member

Overview

Add a static, manifest-declared JSON Schema boundary so dynamic plugins can be configured through nemo-relay plugins edit without loading native code or starting workers. The editor now presents one top-level row per built-in or dynamic plugin and remains usable in small terminals.

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

Details

  • Extend manifest v1 with an optional [config_schema] section and enforce its bidirectional relationship with the config_schema capability.
  • Load and validate JSON Schema Draft 7 and Draft 2020-12 documents using local same-document references only, map supported shapes to native controls, and retain raw JSON fallbacks with full schema validation.
  • Treat schema-declared writeOnly strings as secrets by masking menus and previews, using hidden input, and preserving existing values unless explicitly replaced or cleared.
  • Rework plugins edit into built-in and dynamic plugin submenus with per-field and whole-plugin reset behavior, plus terminal-height-aware scrolling, truncation, and Page Up/Down and Home/End navigation.
  • Preserve host policy, dynamic manifest references, unknown TOML fields and sections, TOML-native values, and absent-versus-empty dynamic configuration. Reuse the lossless document writer in pricing commands.
  • Add manifest, schema, persistence, editor, viewport, lifecycle, and pricing regression tests; update CLI help, documentation, the Rust native plugin example, and the plugin-building skill.
  • Keep the native ABI, worker protocol, SDK callbacks, runtime validation authority, and manifest version unchanged. Existing valid manifests remain compatible; the config_schema capability and section must now be declared together.

Validation performed:

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • just test-rust
  • just test-python (382 passed)
  • just test-go
  • just test-node (243 passed)
  • just test-wasm (Rust checks and 80 JavaScript tests passed)
  • just docs
  • just docs-linkcheck
  • cargo deny check
  • Commit-time pre-commit hooks passed. The all-files run passed every hook except ty, which traversed a local untracked generated python/plugin/ tree that is not part of this branch; the same type check excluding that directory exited successfully with two pre-existing warnings.

Where should the reviewer start?

Start with crates/cli/src/plugins/schema.rs for the schema boundary and control mapping, then crates/cli/src/plugins/dynamic_editor.rs for editing and secret semantics, and crates/cli/src/plugins/config_io.rs for lossless TOML patching.

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

  • Closes: RELAY-312

Summary by CodeRabbit

  • New Features

    • Added schema-backed editing for dynamic plugins with structured field prompts, secret-aware redaction, validation, and merged TOML preview/save.
    • Dynamic plugin manifests can declare a local config_schema capability; CLI operations load and enforce it.
    • Enhanced dynamic plugin editor and menu navigation (paging, keyboard shortcuts, viewport-aware rendering).
  • Bug Fixes

    • Preserves existing plugins.toml content when updating plugin configuration (including pricing).
    • Improved reset/clear messaging from the main plugins menu.
  • Documentation

    • Updated Quick Start and CLI/example docs for observability and schema-backed editing.
    • Added dynamic plugin authoring guidance and example config.schema.json.

Signed-off-by: Will Killian <wkillian@nvidia.com>
@willkill07 willkill07 requested review from a team and lvojtku as code owners June 29, 2026 14:37
@github-actions github-actions Bot added size:XXL PR is very large Feature a new feature lang:rust PR changes/introduces Rust code labels Jun 29, 2026
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 2959cfa3-f084-427a-9a15-e880ca2a99f6

📥 Commits

Reviewing files that changed from the base of the PR and between e83cbc7 and ac2e888.

📒 Files selected for processing (3)
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/relay-plugin.toml
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (24)
**/*.{rs,toml}

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

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{py,txt,toml,cfg,yaml,yml}

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

Update Python package names and top-level module imports during coordinated rename operations

Files:

  • examples/rust-native-plugin/relay-plugin.toml
{docs/**,examples/**,README.md}

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

Verify examples still run with documented commands for large or public-facing changes

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

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

Keep package names, repo references, and build commands current

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in TOML configuration files using hash comment syntax

Files:

  • examples/rust-native-plugin/relay-plugin.toml
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
  • crates/cli/tests/coverage/plugins_lifecycle_tests.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, WebAssembly, and the raw C FFI are experimental and source-first.

The shared runtime model is:

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

Repository Structure

The repository layout separates the Rust runtime, language bindings, documentation,
integration patches, 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
  wasm/       # wasm-bindgen WebAssembly binding and JS wrappers
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
third_party/  # P...

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{md,rst,html,txt}

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

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

Files:

  • examples/rust-native-plugin/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:

  • examples/rust-native-plugin/README.md
**/*.md

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

Documentation must be updated if activation or usage changed

**/*.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 ...

Files:

  • examples/rust-native-plugin/README.md
**/{docs,examples,**/*.md,*.patch,*.diff,.github,*.sh,*.yaml,*.yml}

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

Update documentation, examples, CI configuration, and patch artifacts when performing rename operations

Files:

  • examples/rust-native-plugin/README.md
**/*.{md,rst,txt}

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

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

Files:

  • examples/rust-native-plugin/README.md
**/*.{md,rst}

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

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

Files:

  • examples/rust-native-plugin/README.md
{docs/**,README.md,CONTRIBUTING.md,**/*.md}

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

Run docs link validation with just docs-linkcheck when links change

Files:

  • examples/rust-native-plugin/README.md
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

Ensure renamed public surfaces are reflected consistently in manifests and docs for large or public-facing changes

Files:

  • examples/rust-native-plugin/README.md
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in HTML and Markdown files using HTML comment syntax

Files:

  • examples/rust-native-plugin/README.md
**/README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant crate or package README when that surface changed

Files:

  • examples/rust-native-plugin/README.md
**/*.rs

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

Use snake_case naming convention for Rust identifiers (e.g., nemo_relay_tool_call)

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

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

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

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

**/*.rs: Run cargo fmt --all to format all Rust code
Run cargo clippy --workspace --all-targets -- -D warnings to enforce all clippy lints as errors

**/*.rs: Run cargo fmt --all when Rust files changed as part of WebAssembly work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files changed as part of WebAssembly work

**/*.rs: If any Rust code changed, always run just test-rust
If any Rust code changed, also run cargo fmt --all
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting with cargo fmt --all
Run Rust linting with cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Use cargo fmt for Rust code formatting
Run cargo clippy -- -D warnings to lint Rust code and treat all warnings as errors
Use Rust snake_case naming convention for Rust identifiers
Include SPDX license header in all Rust source files using double-slash comment syntax
Validate Rust code with uv run pre-commit run --all-files to enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/{Cargo.toml,**/*.rs}

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

Maintain consistency between Rust package names in Cargo.toml and their actual usage across the codebase

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{h,hpp,c,cpp,rs}

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

Ensure FFI header and library naming follows consistent conventions across platform-specific builds

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions: Rust and Python use snake_case, C FFI exports prefixed nemo_relay_, Go uses PascalCase for public APIs, Node.js uses camelCase.

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Keep async behavior on the existing tokio-based model. Bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Use Json = serde_json::Value in Rust-facing runtime APIs for JSON payload handling.

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_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/plugins_lifecycle_tests.rs
🛑 Comments failed to post (1)
crates/cli/tests/coverage/plugins_lifecycle_tests.rs (1)

404-413: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Copy the declared schema alongside the rendered example manifest.

Line 405 now reuses examples/rust-native-plugin/relay-plugin.toml, but Lines 412-413 only write relay-plugin.toml. That template now declares [config_schema] path = "config.schema.json", and plugins add loads the schema before the trust/integrity checks these tests are meant to exercise. As written, both tracked_native_plugin_example_* tests fail on schema loading instead of the intended lifecycle path.

Proposed fix
 fn materialize_native_example_manifest(dir: &Path) -> (PathBuf, PathBuf) {
@@
     let template = std::fs::read_to_string(
         repository_root.join("examples/rust-native-plugin/relay-plugin.toml"),
     )
     .unwrap();
+    let config_schema = std::fs::read(
+        repository_root.join("examples/rust-native-plugin/config.schema.json"),
+    )
+    .unwrap();
     let manifest = template
         .replace("<platform-library-file>", &artifact_name)
         .replace("<artifact-sha256>", &digest);
     let manifest_path = dir.join("relay-plugin.toml");
     std::fs::write(&manifest_path, manifest).unwrap();
+    std::fs::write(dir.join("config.schema.json"), config_schema).unwrap();
     (manifest_path, artifact_path)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    let repository_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
    let template = std::fs::read_to_string(
        repository_root.join("examples/rust-native-plugin/relay-plugin.toml"),
    )
    .unwrap();
    let config_schema = std::fs::read(
        repository_root.join("examples/rust-native-plugin/config.schema.json"),
    )
    .unwrap();
    let manifest = template
        .replace("<platform-library-file>", &artifact_name)
        .replace("<artifact-sha256>", &digest);
    let manifest_path = dir.join("relay-plugin.toml");
    std::fs::write(&manifest_path, manifest).unwrap();
    std::fs::write(dir.join("config.schema.json"), config_schema).unwrap();
🤖 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/plugins_lifecycle_tests.rs` around lines 404 - 413,
The tracked native plugin example tests are only writing the rendered
relay-plugin.toml, but the referenced example template now also expects
config.schema.json to exist alongside it. Update the test setup in the plugin
lifecycle test helper to copy or write the declared schema file into the same
temp directory before invoking plugins add, using the existing manifest
rendering flow around the relay-plugin.toml creation so schema loading succeeds
and the tests reach the intended lifecycle path.

Walkthrough

Adds JSON Schema-backed dynamic plugin editing and validation, introduces a document wrapper for merged TOML persistence, updates plugin menu navigation and viewport rendering, and extends docs, examples, dependencies, and tests to cover the new schema flow.

Changes

Dynamic Plugin Config Schema Editing

Layer / File(s) Summary
Manifest schema contract and path resolution
crates/core/src/plugin/dynamic/manifest.rs, crates/core/tests/unit/plugin_dynamic_tests.rs
DynamicPluginManifest gains optional config_schema metadata. Validation enforces capability coupling and local-path constraints, and resolve_config_schema_path resolves relative or absolute schema paths. Tests cover parsing, rejection, and resolution behavior.
Schema loading, field mapping, and secret redaction
crates/cli/src/plugins/schema.rs, crates/cli/Cargo.toml, crates/cli/src/config.rs
Adds PluginConfigSchema loading for Draft 7 and Draft 2020-12 schemas, including external ref rejection, editor field mapping, secret traversal, validation, and redaction/restoration. CLI dependencies and edit help text are updated to match schema-backed editing.
PluginConfigDocument overlay and TOML patching
crates/cli/src/plugins/config_io.rs, crates/cli/src/pricing.rs, crates/cli/tests/coverage/pricing_tests.rs
Introduces a document wrapper for merged TOML plus typed config, dynamic entry mutation helpers, selective patching, and preview rendering. Pricing updates switch to the shared document helper and are covered by a preservation test.
Dynamic plugin editor state and field prompting
crates/cli/src/plugins/dynamic_editor.rs
Adds dynamic editor state loading from manifests, schema-aware structured and raw editing, secret-aware prompts, per-field reset and clear handling, and JSON path utilities for dynamic configs.
Menu model for component and dynamic plugin navigation
crates/cli/src/plugins/editor_model.rs
Replaces inline field actions with two-level navigation actions and adds a component submenu builder for toggle, field edit, and back behavior.
Plugin edit flow and viewport menu rendering
crates/cli/src/plugins.rs
Reworks the edit loop around document-backed state and dynamic editors, updates preview/save/reset handling, and replaces fixed rendering with viewport paging, terminal resizing, and expanded navigation keys.
Lifecycle schema loading and validation
crates/cli/src/plugins/lifecycle.rs
Loads config schemas during add and validate flows, and validates resolved host config against a declared schema when validating by plugin id.
Tests, fixtures, docs, and example plugin updates
crates/cli/tests/coverage/plugins_tests.rs, crates/cli/tests/coverage/plugins_lifecycle_tests.rs, crates/cli/tests/coverage/launcher_tests.rs, README.md, crates/cli/README.md, examples/rust-native-plugin/*, skills/nemo-relay-build-plugin/SKILL.md, about.toml, deny.toml
Adds coverage for dynamic editor behavior, menu rendering, schema validation, TOML persistence, and CWD locking. Updates user docs, example plugin schema and manifest, build guidance, and license allowlists.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title follows Conventional Commits and accurately summarizes the PR's main change.
Description check ✅ Passed The description includes all required sections and provides detailed, relevant implementation and review guidance.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

Copy link
Copy Markdown

1 similar comment
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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/plugins/dynamic_editor.rs`:
- Around line 205-219: The remove_field and reset_field paths are eagerly
synthesizing an empty config map when the plugin config was originally absent,
which turns a no-op clear into config = {} and can make no-default resets fail
validation on save. Update remove_field to preserve None when there was no
existing config to mutate, and make reset_field avoid routing no-default fields
through remove_field unless there is an actual prior value to restore. Keep the
behavior tied to remove_value_at_path, DynamicConfigField::default, and
set_field so only real defaults or existing values are written back.

In `@crates/cli/src/plugins/schema.rs`:
- Around line 249-252: The restore path in
`restore_edit_secrets`/`restore_secret_tokens` is too permissive because it
replaces matching redaction tokens anywhere in the edited JSON. Update the raw
edit flow in `crates/cli/src/plugins/schema.rs` so tokens are only restored at
their original validated locations, or reject edits that duplicate/move a token
into a different field. Use the existing `restore_edit_secrets`,
`redact_for_edit`, and `SecretEditValues` symbols to locate the code and enforce
occurrence binding before reconstructing the final `Value`.
- Around line 311-314: The schema validation and resolution flow currently
accepts local $dynamicRef in reject_external_references, but resolve_schema only
follows $ref and ignores $dynamicAnchor, leaving Draft 2020-12 dynamic
references unresolved in the editor path. Update the schema handling in
schema.rs by either rejecting $dynamicRef and $dynamicAnchor alongside $ref in
the CLI subset, or extend resolve_schema and its related schema traversal
helpers to resolve dynamic anchors consistently so root typing, field synthesis,
and secret discovery see the resolved schema.

In `@crates/core/src/plugin/dynamic/manifest.rs`:
- Around line 521-524: The config_schema.path validation in the manifest parser
only rejects URI schemes, so UNC-style network paths can still be treated as
local paths and opened immediately. Update the validation logic around
required_trimmed_string, has_uri_scheme, and the config_schema.path checks to
also reject UNC and verbatim-UNC prefixes like backslash-backslash and
double-slash network shares before any filesystem access. Add a regression test
alongside the existing config_schema.path path cases to cover UNC and
verbatim-UNC inputs and verify they are rejected.
🪄 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: 5255c033-7727-435b-b27f-e9099648d008

📥 Commits

Reviewing files that changed from the base of the PR and between 19a537d and b87c616.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (26)
  • ATTRIBUTIONS-Rust.md
  • README.md
  • about.toml
  • crates/cli/Cargo.toml
  • crates/cli/README.md
  • crates/cli/src/config.rs
  • crates/cli/src/plugins.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/src/pricing.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • deny.toml
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/config.schema.json
  • examples/rust-native-plugin/relay-plugin.toml
  • skills/nemo-relay-build-plugin/SKILL.md
📜 Review details
🧰 Additional context used
📓 Path-based instructions (41)
**/*.{rs,toml}

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

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • about.toml
  • deny.toml
  • crates/cli/src/config.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/Cargo.toml
  • examples/rust-native-plugin/relay-plugin.toml
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.rs
**/*.{py,txt,toml,cfg,yaml,yml}

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

Update Python package names and top-level module imports during coordinated rename operations

Files:

  • about.toml
  • deny.toml
  • crates/cli/Cargo.toml
  • examples/rust-native-plugin/relay-plugin.toml
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

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

Keep package names, repo references, and build commands current

Files:

  • about.toml
  • deny.toml
  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/config.schema.json
  • crates/cli/Cargo.toml
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/relay-plugin.toml
  • skills/nemo-relay-build-plugin/SKILL.md
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in TOML configuration files using hash comment syntax

Files:

  • about.toml
  • deny.toml
  • crates/cli/Cargo.toml
  • examples/rust-native-plugin/relay-plugin.toml
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.

Files:

  • about.toml
  • deny.toml
  • crates/cli/README.md
  • crates/cli/src/config.rs
  • README.md
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/Cargo.toml
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/relay-plugin.toml
  • skills/nemo-relay-build-plugin/SKILL.md
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.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, WebAssembly, and the raw C FFI are experimental and source-first.

The shared runtime model is:

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

Repository Structure

The repository layout separates the Rust runtime, language bindings, documentation,
integration patches, 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
  wasm/       # wasm-bindgen WebAssembly binding and JS wrappers
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
third_party/  # P...

Files:

  • about.toml
  • deny.toml
  • crates/cli/README.md
  • crates/cli/src/config.rs
  • README.md
  • examples/rust-native-plugin/config.schema.json
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/Cargo.toml
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/relay-plugin.toml
  • skills/nemo-relay-build-plugin/SKILL.md
  • crates/cli/tests/coverage/pricing_tests.rs
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.rs
deny.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run cargo deny check for Rust dependency auditing as configured in deny.toml

Files:

  • deny.toml
**/*.{md,rst,html,txt}

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

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

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.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:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
**/*.md

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

Documentation must be updated if activation or usage changed

**/*.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 ...

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
**/{docs,examples,**/*.md,*.patch,*.diff,.github,*.sh,*.yaml,*.yml}

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

Update documentation, examples, CI configuration, and patch artifacts when performing rename operations

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
**/*.{md,rst,txt}

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

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

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
**/*.{md,rst}

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

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

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
{docs/**,README.md,CONTRIBUTING.md,**/*.md}

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

Run docs link validation with just docs-linkcheck when links change

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

Ensure renamed public surfaces are reflected consistently in manifests and docs for large or public-facing changes

Files:

  • crates/cli/README.md
  • README.md
  • crates/cli/Cargo.toml
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in HTML and Markdown files using HTML comment syntax

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
  • skills/nemo-relay-build-plugin/SKILL.md
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
**/README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant crate or package README when that surface changed

Files:

  • crates/cli/README.md
  • README.md
  • examples/rust-native-plugin/README.md
**/*.rs

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

Use snake_case naming convention for Rust identifiers (e.g., nemo_relay_tool_call)

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

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

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

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

**/*.rs: Run cargo fmt --all to format all Rust code
Run cargo clippy --workspace --all-targets -- -D warnings to enforce all clippy lints as errors

**/*.rs: Run cargo fmt --all when Rust files changed as part of WebAssembly work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files changed as part of WebAssembly work

**/*.rs: If any Rust code changed, always run just test-rust
If any Rust code changed, also run cargo fmt --all
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting with cargo fmt --all
Run Rust linting with cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Use cargo fmt for Rust code formatting
Run cargo clippy -- -D warnings to lint Rust code and treat all warnings as errors
Use Rust snake_case naming convention for Rust identifiers
Include SPDX license header in all Rust source files using double-slash comment syntax
Validate Rust code with uv run pre-commit run --all-files to enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...

Files:

  • crates/cli/src/config.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.rs
**/*config*.{rs,ts,py,go,js,json,yaml,yml}

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

Ensure dynamic config shape still matches the documented canonical model

Files:

  • crates/cli/src/config.rs
  • examples/rust-native-plugin/config.schema.json
  • crates/cli/src/plugins/config_io.rs
**/{Cargo.toml,**/*.rs}

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

Maintain consistency between Rust package names in Cargo.toml and their actual usage across the codebase

Files:

  • crates/cli/src/config.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/Cargo.toml
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.rs
**/*.{h,hpp,c,cpp,rs}

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

Ensure FFI header and library naming follows consistent conventions across platform-specific builds

Files:

  • crates/cli/src/config.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.rs
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions: Rust and Python use snake_case, C FFI exports prefixed nemo_relay_, Go uses PascalCase for public APIs, Node.js uses camelCase.

Files:

  • crates/cli/src/config.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Keep async behavior on the existing tokio-based model. Bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Use Json = serde_json::Value in Rust-facing runtime APIs for JSON payload handling.

Files:

  • crates/cli/src/config.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/src/pricing.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/src/plugins/lifecycle.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/editor_model.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/cli/src/plugins/config_io.rs
  • crates/cli/src/plugins.rs
{README.md,docs/getting-started/**/*.md}

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

Update README.md, docs/getting-started/, or binding-level READMEs if behavior differs by language or usage changed

Files:

  • README.md
{docs/**,README.md,CONTRIBUTING.md}

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

{docs/**,README.md,CONTRIBUTING.md}: For docs-only changes, run targeted checks only if commands, package names, or examples changed. Use just docs for docs-site builds and just docs-linkcheck when links changed
Run docs site build with just docs

Files:

  • README.md
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
{docs/**,README.md}

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

Verify README and docs entry points still match current package names and paths for large or public-facing changes

Files:

  • README.md
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
{docs/**,examples/**,README.md}

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

Verify examples still run with documented commands for large or public-facing changes

Files:

  • README.md
  • examples/rust-native-plugin/config.schema.json
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/relay-plugin.toml
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update README.md to reflect current workspace members and top-level documentation when workspace structure changes

Files:

  • README.md
{README.md,docs/**/*.{md,rst,txt},fern/**/*}

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

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

Files:

  • README.md
{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}

⚙️ CodeRabbit configuration file

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

Files:

  • README.md
  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/tests/coverage/plugins_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/launcher_tests.rs
  • crates/cli/tests/coverage/pricing_tests.rs
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/tests/coverage/plugins_tests.rs
**/Cargo.toml

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

Update WebAssembly crate names and generated package names during coordinated rename operations

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

**/Cargo.toml: Maintain Cargo.toml [workspace.package].version as the source of truth for the Rust workspace and Python build versioning
Keep Cargo.toml [workspace.dependencies] self-references aligned with the workspace version when the workspace version changes
After updating workspace package entries, run cargo check --workspace to refresh Cargo.lock

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

SKILL.md files are skill entrypoints and do not need SPDX headers, but they must always start with YAML frontmatter containing at least name and description.

Files:

  • skills/nemo-relay-build-plugin/SKILL.md

⚙️ CodeRabbit configuration file

**/SKILL.md: Do not flag SKILL.md files for missing SPDX headers. Skill entrypoints intentionally start with YAML frontmatter instead.
Verify that every SKILL.md keeps valid YAML frontmatter with at least name and description fields before the Markdown body.

Files:

  • skills/nemo-relay-build-plugin/SKILL.md
**/*.mdx

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

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.

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

Files:

  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update embedded documentation snippets, patch docs, and binding-support notes if examples or supported bindings changed

Files:

  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
docs/**

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run just docs or ./scripts/build-docs.sh html to regenerate ignored Fern API reference pages before validation for documentation site changes

Files:

  • docs/build-plugins/basic-guide.mdx
  • docs/build-plugins/plugin-configuration-files.mdx
{crates/core,crates/adaptive}/**/*

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

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

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
crates/core/**/*.rs

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

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

crates/core/**/*.rs: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths. Keep errors explicit and binding-appropriate at the wrapper layer.

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
crates/{core,adaptive}/**

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

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

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_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/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
🪛 LanguageTool
docs/build-plugins/plugin-configuration-files.mdx

[style] ~201-~201: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ptionsupplies field help. -defaultsupplies the reset value. -required` identifie...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (14)
README.md (1)

74-77: LGTM!

Also applies to: 89-89

about.toml (1)

14-14: LGTM!

deny.toml (1)

25-25: LGTM!

skills/nemo-relay-build-plugin/SKILL.md (1)

75-79: LGTM!

Also applies to: 147-148

examples/rust-native-plugin/relay-plugin.toml (1)

20-21: 🎯 Functional Correctness

Drop this comment: there is no duplicate [config_schema] table. The TOML in examples/rust-native-plugin/relay-plugin.toml parses as-is, so the file is not invalid.

			> Likely an incorrect or invalid review comment.
crates/cli/README.md (1)

114-117: LGTM!

docs/build-plugins/basic-guide.mdx (1)

47-47: LGTM!

Also applies to: 137-142

docs/build-plugins/plugin-configuration-files.mdx (1)

106-108: LGTM!

Also applies to: 148-149, 158-215

examples/rust-native-plugin/README.md (1)

57-60: 🎯 Functional Correctness | ⚡ Quick win

Verify --user is a supported flag.

The surrounding docs only show the implicit user target plus --project/--global, so this sentence may mislead users if plugins edit does not actually accept --user.

examples/rust-native-plugin/config.schema.json (1)

1-39: LGTM!

crates/core/src/plugin/dynamic/manifest.rs (1)

335-375: 📐 Maintainability & Code Quality

Please attach the full validation matrix for this crates/core contract change.

This changes shared manifest semantics, so the repo guidance calls for broader validation than a local Rust-only pass. As per path instructions, "If the change touched crates/core or shared runtime semantics, also use validate-change for broader validation" and "If crates/core or crates/adaptive changed, run the full matrix across Rust, Python, Go, Node.js, and WebAssembly." As per coding guidelines, "Run tests for every language affected by a change."

Sources: Coding guidelines, Path instructions

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

29-180: LGTM!

Also applies to: 204-251, 293-310, 456-690

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

20-20: LGTM!

Also applies to: 38-44, 61-74, 83-92

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

118-171: LGTM!

Comment thread crates/cli/src/plugins/dynamic_editor.rs
Comment thread crates/cli/src/plugins/schema.rs Outdated
Comment thread crates/cli/src/plugins/schema.rs Outdated
Comment thread crates/core/src/plugin/dynamic/manifest.rs
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
crates/cli/src/plugins/schema.rs (1)

105-114: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Bound schema reads to regular, reasonably-sized files.

config_schema.path can resolve to any local path, and fs::read_to_string eagerly reads it. A manifest pointing at a device, FIFO, or huge file can hang/OOM plugins add/validate before JSON parsing. Open the file, verify it is regular, and cap bytes read.

Proposed fix
+use std::io::Read;
+
+const MAX_CONFIG_SCHEMA_BYTES: u64 = 4 * 1024 * 1024;
+
-        let contents = fs::read_to_string(&path).map_err(|error| {
-            schema_error(&plugin_id, &path, format!("failed to read schema: {error}"))
-        })?;
-        let source: Value = serde_json::from_str(&contents).map_err(|error| {
+        let mut file = fs::File::open(&path).map_err(|error| {
+            schema_error(&plugin_id, &path, format!("failed to open schema: {error}"))
+        })?;
+        let metadata = file.metadata().map_err(|error| {
+            schema_error(&plugin_id, &path, format!("failed to stat schema: {error}"))
+        })?;
+        if !metadata.file_type().is_file() {
+            return Err(schema_error(&plugin_id, &path, "schema path must be a regular file"));
+        }
+
+        let mut contents = Vec::new();
+        file.take(MAX_CONFIG_SCHEMA_BYTES + 1)
+            .read_to_end(&mut contents)
+            .map_err(|error| {
+                schema_error(&plugin_id, &path, format!("failed to read schema: {error}"))
+            })?;
+        if contents.len() as u64 > MAX_CONFIG_SCHEMA_BYTES {
+            return Err(schema_error(
+                &plugin_id,
+                &path,
+                format!("schema exceeds {MAX_CONFIG_SCHEMA_BYTES} bytes"),
+            ));
+        }
+
+        let source: Value = serde_json::from_slice(&contents).map_err(|error| {
             schema_error(
                 &plugin_id,
                 &path,
🤖 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/plugins/schema.rs` around lines 105 - 114, The schema loading
in the plugin schema reader currently uses fs::read_to_string on
config_schema.path, which can block or exhaust memory on non-regular or very
large local paths. Update the schema loading path in the schema.rs flow that
builds the Value source to open the file first, verify it is a regular file, and
enforce a reasonable size limit before reading. Keep the existing schema_error
handling around the read/parse steps, but make the bounded file check part of
the same schema-loading logic.
🤖 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/plugins/dynamic_editor.rs`:
- Around line 575-578: The secret-restoration flow is losing the original field
path because `field_value_for_raw_edit` restores only the edited fragment
instead of the full config context. Update the restore logic in `dynamic_editor`
so the value passed through `Schema::restore_edit_secrets` is still associated
with the original field path, including nested paths like `/records/*/password`.
Apply the same fix in both restore sites around the `restore_edit_secrets` calls
so unchanged secrets are restored at their original location rather than as
moved values.

---

Outside diff comments:
In `@crates/cli/src/plugins/schema.rs`:
- Around line 105-114: The schema loading in the plugin schema reader currently
uses fs::read_to_string on config_schema.path, which can block or exhaust memory
on non-regular or very large local paths. Update the schema loading path in the
schema.rs flow that builds the Value source to open the file first, verify it is
a regular file, and enforce a reasonable size limit before reading. Keep the
existing schema_error handling around the read/parse steps, but make the bounded
file check part of the same schema-loading logic.
🪄 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: c3913c22-de80-41fa-a95d-5902f387e9ac

📥 Commits

Reviewing files that changed from the base of the PR and between b87c616 and a81d953.

📒 Files selected for processing (6)
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • docs/build-plugins/plugin-configuration-files.mdx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (25)
{docs/**,README.md,CONTRIBUTING.md}

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

{docs/**,README.md,CONTRIBUTING.md}: For docs-only changes, run targeted checks only if commands, package names, or examples changed. Use just docs for docs-site builds and just docs-linkcheck when links changed
Run docs site build with just docs

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
{docs/**,README.md,CONTRIBUTING.md,**/*.md}

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

Run docs link validation with just docs-linkcheck when links change

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
{docs/**,README.md}

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

Verify README and docs entry points still match current package names and paths for large or public-facing changes

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
{docs/**,examples/**,README.md}

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

Verify examples still run with documented commands for large or public-facing changes

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

Ensure renamed public surfaces are reflected consistently in manifests and docs for large or public-facing changes

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

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

Keep package names, repo references, and build commands current

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
**/*.mdx

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

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.

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

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in HTML and Markdown files using HTML comment syntax

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update embedded documentation snippets, patch docs, and binding-support notes if examples or supported bindings changed

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
docs/**

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run just docs or ./scripts/build-docs.sh html to regenerate ignored Fern API reference pages before validation for documentation site changes

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
**

⚙️ 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, WebAssembly, and the raw C FFI are experimental and source-first.

The shared runtime model is:

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

Repository Structure

The repository layout separates the Rust runtime, language bindings, documentation,
integration patches, 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
  wasm/       # wasm-bindgen WebAssembly binding and JS wrappers
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
third_party/  # P...

Files:

  • docs/build-plugins/plugin-configuration-files.mdx
  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.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:

  • docs/build-plugins/plugin-configuration-files.mdx
**/*.rs

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

Use snake_case naming convention for Rust identifiers (e.g., nemo_relay_tool_call)

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

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

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

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

**/*.rs: Run cargo fmt --all to format all Rust code
Run cargo clippy --workspace --all-targets -- -D warnings to enforce all clippy lints as errors

**/*.rs: Run cargo fmt --all when Rust files changed as part of WebAssembly work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files changed as part of WebAssembly work

**/*.rs: If any Rust code changed, always run just test-rust
If any Rust code changed, also run cargo fmt --all
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting with cargo fmt --all
Run Rust linting with cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Use cargo fmt for Rust code formatting
Run cargo clippy -- -D warnings to lint Rust code and treat all warnings as errors
Use Rust snake_case naming convention for Rust identifiers
Include SPDX license header in all Rust source files using double-slash comment syntax
Validate Rust code with uv run pre-commit run --all-files to enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
**/{Cargo.toml,**/*.rs}

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

Maintain consistency between Rust package names in Cargo.toml and their actual usage across the codebase

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
**/*.{h,hpp,c,cpp,rs}

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

Ensure FFI header and library naming follows consistent conventions across platform-specific builds

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
{crates/core,crates/adaptive}/**/*

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

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

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
**/*.{rs,toml}

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

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
crates/core/**/*.rs

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

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

crates/core/**/*.rs: Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.
Use Result<T> with FlowError in core runtime paths. Keep errors explicit and binding-appropriate at the wrapper layer.

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
crates/{core,adaptive}/**

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

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

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions: Rust and Python use snake_case, C FFI exports prefixed nemo_relay_, Go uses PascalCase for public APIs, Node.js uses camelCase.

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Keep async behavior on the existing tokio-based model. Bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Use Json = serde_json::Value in Rust-facing runtime APIs for JSON payload handling.

Files:

  • crates/core/src/plugin/dynamic/manifest.rs
  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
  • crates/cli/src/plugins/dynamic_editor.rs
  • crates/cli/src/plugins/schema.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/src/plugin/dynamic/manifest.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_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/plugins_tests.rs
  • crates/core/tests/unit/plugin_dynamic_tests.rs
🔇 Additional comments (8)
docs/build-plugins/plugin-configuration-files.mdx (1)

106-108: LGTM!

Also applies to: 148-149, 158-216

crates/core/src/plugin/dynamic/manifest.rs (2)

335-335: 📐 Maintainability & Code Quality

Confirm required Rust/core validation before merge.

This cohort changes crates/core, so please attach results for cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, just test-rust, and the affected binding matrix/validate-change run. As per coding guidelines, “Any Rust change must run just test-rust”, “cargo fmt --all”, and “cargo clippy --workspace --all-targets -- -D warnings.” As per path instructions, “Changes to crates/coreorcrates/adaptive` must run the full language matrix.”

Sources: Coding guidelines, Path instructions


40-40: LGTM!

Also applies to: 108-108, 349-375, 521-534

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

743-763: LGTM!

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

24-30: LGTM!

Also applies to: 116-153, 155-267, 270-310, 312-438, 845-950, 992-1033, 1210-1226, 1440-1480

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

205-208: LGTM!

Also applies to: 714-717


205-208: 📐 Maintainability & Code Quality

Confirm required Rust validation before merge.

Please confirm cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, and just test-rust were run for this Rust change. As per coding guidelines, **/*.rs: “Any Rust change must run just test-rust”, “Any Rust change must run cargo fmt --all”, and “Any Rust change must run cargo clippy --workspace --all-targets -- -D warnings”.

Also applies to: 575-578, 597-601, 714-717

Source: Coding guidelines

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

1498-1502: LGTM!

Also applies to: 1540-1542, 1561-1565

Comment thread crates/cli/src/plugins/dynamic_editor.rs Outdated
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

@willkill07 willkill07 removed the request for review from lvojtku June 29, 2026 15:56
@willkill07 willkill07 self-assigned this Jun 29, 2026
@willkill07 willkill07 added this to the 0.5 milestone Jun 29, 2026
Signed-off-by: Will Killian <wkillian@nvidia.com>
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cli/tests/coverage/plugins_lifecycle_tests.rs`:
- Around line 404-413: The tracked native plugin example tests are only writing
the rendered relay-plugin.toml, but the referenced example template now also
expects config.schema.json to exist alongside it. Update the test setup in the
plugin lifecycle test helper to copy or write the declared schema file into the
same temp directory before invoking plugins add, using the existing manifest
rendering flow around the relay-plugin.toml creation so schema loading succeeds
and the tests reach the intended lifecycle 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: 2959cfa3-f084-427a-9a15-e880ca2a99f6

📥 Commits

Reviewing files that changed from the base of the PR and between e83cbc7 and ac2e888.

📒 Files selected for processing (3)
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/relay-plugin.toml
📜 Review details
🧰 Additional context used
📓 Path-based instructions (24)
**/*.{rs,toml}

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

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{py,txt,toml,cfg,yaml,yml}

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

Update Python package names and top-level module imports during coordinated rename operations

Files:

  • examples/rust-native-plugin/relay-plugin.toml
{docs/**,examples/**,README.md}

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

Verify examples still run with documented commands for large or public-facing changes

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

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

Keep package names, repo references, and build commands current

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in TOML configuration files using hash comment syntax

Files:

  • examples/rust-native-plugin/relay-plugin.toml
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, docs, scripts, and configuration files. The project is Apache-2.0.

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
  • crates/cli/tests/coverage/plugins_lifecycle_tests.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, WebAssembly, and the raw C FFI are experimental and source-first.

The shared runtime model is:

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

Repository Structure

The repository layout separates the Rust runtime, language bindings, documentation,
integration patches, 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
  wasm/       # wasm-bindgen WebAssembly binding and JS wrappers
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
third_party/  # P...

Files:

  • examples/rust-native-plugin/relay-plugin.toml
  • examples/rust-native-plugin/README.md
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{md,rst,html,txt}

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

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

Files:

  • examples/rust-native-plugin/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:

  • examples/rust-native-plugin/README.md
**/*.md

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

Documentation must be updated if activation or usage changed

**/*.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 ...

Files:

  • examples/rust-native-plugin/README.md
**/{docs,examples,**/*.md,*.patch,*.diff,.github,*.sh,*.yaml,*.yml}

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

Update documentation, examples, CI configuration, and patch artifacts when performing rename operations

Files:

  • examples/rust-native-plugin/README.md
**/*.{md,rst,txt}

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

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

Files:

  • examples/rust-native-plugin/README.md
**/*.{md,rst}

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

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

Files:

  • examples/rust-native-plugin/README.md
{docs/**,README.md,CONTRIBUTING.md,**/*.md}

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

Run docs link validation with just docs-linkcheck when links change

Files:

  • examples/rust-native-plugin/README.md
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

Ensure renamed public surfaces are reflected consistently in manifests and docs for large or public-facing changes

Files:

  • examples/rust-native-plugin/README.md
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include SPDX license header in HTML and Markdown files using HTML comment syntax

Files:

  • examples/rust-native-plugin/README.md
**/README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant crate or package README when that surface changed

Files:

  • examples/rust-native-plugin/README.md
**/*.rs

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

Use snake_case naming convention for Rust identifiers (e.g., nemo_relay_tool_call)

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

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

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

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

**/*.rs: Run cargo fmt --all to format all Rust code
Run cargo clippy --workspace --all-targets -- -D warnings to enforce all clippy lints as errors

**/*.rs: Run cargo fmt --all when Rust files changed as part of WebAssembly work
Run cargo clippy --workspace --all-targets -- -D warnings when Rust files changed as part of WebAssembly work

**/*.rs: If any Rust code changed, always run just test-rust
If any Rust code changed, also run cargo fmt --all
If any Rust code changed, also run cargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting with cargo fmt --all
Run Rust linting with cargo clippy --workspace --all-targets -- -D warnings

**/*.rs: Use cargo fmt for Rust code formatting
Run cargo clippy -- -D warnings to lint Rust code and treat all warnings as errors
Use Rust snake_case naming convention for Rust identifiers
Include SPDX license header in all Rust source files using double-slash comment syntax
Validate Rust code with uv run pre-commit run --all-files to enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/{Cargo.toml,**/*.rs}

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

Maintain consistency between Rust package names in Cargo.toml and their actual usage across the codebase

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{h,hpp,c,cpp,rs}

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

Ensure FFI header and library naming follows consistent conventions across platform-specific builds

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions: Rust and Python use snake_case, C FFI exports prefixed nemo_relay_, Go uses PascalCase for public APIs, Node.js uses camelCase.

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Keep async behavior on the existing tokio-based model. Bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Use Json = serde_json::Value in Rust-facing runtime APIs for JSON payload handling.

Files:

  • crates/cli/tests/coverage/plugins_lifecycle_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/plugins_lifecycle_tests.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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: 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/tests/coverage/plugins_lifecycle_tests.rs`:
- Around line 404-413: The tracked native plugin example tests are only writing
the rendered relay-plugin.toml, but the referenced example template now also
expects config.schema.json to exist alongside it. Update the test setup in the
plugin lifecycle test helper to copy or write the declared schema file into the
same temp directory before invoking plugins add, using the existing manifest
rendering flow around the relay-plugin.toml creation so schema loading succeeds
and the tests reach the intended lifecycle 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: 2959cfa3-f084-427a-9a15-e880ca2a99f6

📥 Commits

Reviewing files that changed from the base of the PR and between e83cbc7 and ac2e888.

📒 Files selected for processing (3)
  • crates/cli/tests/coverage/plugins_lifecycle_tests.rs
  • examples/rust-native-plugin/README.md
  • examples/rust-native-plugin/relay-plugin.toml
🛑 Comments failed to post (1)
crates/cli/tests/coverage/plugins_lifecycle_tests.rs (1)

404-413: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Copy the declared schema alongside the rendered example manifest.

Line 405 now reuses examples/rust-native-plugin/relay-plugin.toml, but Lines 412-413 only write relay-plugin.toml. That template now declares [config_schema] path = "config.schema.json", and plugins add loads the schema before the trust/integrity checks these tests are meant to exercise. As written, both tracked_native_plugin_example_* tests fail on schema loading instead of the intended lifecycle path.

Proposed fix
 fn materialize_native_example_manifest(dir: &Path) -> (PathBuf, PathBuf) {
@@
     let template = std::fs::read_to_string(
         repository_root.join("examples/rust-native-plugin/relay-plugin.toml"),
     )
     .unwrap();
+    let config_schema = std::fs::read(
+        repository_root.join("examples/rust-native-plugin/config.schema.json"),
+    )
+    .unwrap();
     let manifest = template
         .replace("<platform-library-file>", &artifact_name)
         .replace("<artifact-sha256>", &digest);
     let manifest_path = dir.join("relay-plugin.toml");
     std::fs::write(&manifest_path, manifest).unwrap();
+    std::fs::write(dir.join("config.schema.json"), config_schema).unwrap();
     (manifest_path, artifact_path)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    let repository_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
    let template = std::fs::read_to_string(
        repository_root.join("examples/rust-native-plugin/relay-plugin.toml"),
    )
    .unwrap();
    let config_schema = std::fs::read(
        repository_root.join("examples/rust-native-plugin/config.schema.json"),
    )
    .unwrap();
    let manifest = template
        .replace("<platform-library-file>", &artifact_name)
        .replace("<artifact-sha256>", &digest);
    let manifest_path = dir.join("relay-plugin.toml");
    std::fs::write(&manifest_path, manifest).unwrap();
    std::fs::write(dir.join("config.schema.json"), config_schema).unwrap();
🤖 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/plugins_lifecycle_tests.rs` around lines 404 - 413,
The tracked native plugin example tests are only writing the rendered
relay-plugin.toml, but the referenced example template now also expects
config.schema.json to exist alongside it. Update the test setup in the plugin
lifecycle test helper to copy or write the declared schema file into the same
temp directory before invoking plugins add, using the existing manifest
rendering flow around the relay-plugin.toml creation so schema loading succeeds
and the tests reach the intended lifecycle path.

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants