feat: layer code-driven plugin config over materialized file configs#211
feat: layer code-driven plugin config over materialized file configs#211zhongxuanwang-nv wants to merge 14 commits into
Conversation
Augment initialize_plugins so a code-driven plugin config layer, set via the new set_code_driven_plugin_config runtime API, is merged on top of the file/CLI-resolved config before validation and activation. The code-driven layer is the highest-precedence source and overrides discovered plugins.toml / [plugins].config / --plugin-config per-field; with no layer set, behavior is unchanged so file-only configs stay compatible. nemo-relay doctor now surfaces the effective plugin config source (code-driven layer vs file/CLI) and validates the merged effective config. Docs document the layering model, precedence, and conflict behavior. Additive and Rust-only: two new public functions in nemo_relay::plugin (set_code_driven_plugin_config, apply_code_driven_plugin_config). No existing API, struct/datatype, or language-binding changes. Relates to relay-183. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a JSON layering primitive for plugin configs, integrates file-based TOML discovery into core, exposes an exact initialization entrypoint, updates CLI/server callers to use core merging, expands tests for merge/precedence behavior, and documents configuration layering and precedence. ChangesPlugin Configuration Layering Helper
🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/core/src/plugin.rs`:
- Around line 924-954: The code-driven layer can change concurrently because you
only lock the PLUGIN_CONFIG_CODE_DRIVEN_LAYER in
apply_code_driven_plugin_config(), so a setter (set_code_driven_plugin_config)
may mutate/clear the layer after you compute the merge but before you activate
plugins or write active_plugin_report(), leaving runtime state and report
out-of-sync; fix by serializing the merge + activation/report storage under the
same mutex: modify initialize_plugins (and any activation/report write paths
that call apply_code_driven_plugin_config) to lock
PLUGIN_CONFIG_CODE_DRIVEN_LAYER, call merge_plugin_config_layers while holding
the lock, perform plugin activation and write active_plugin_report() (or store
any activation marker) before releasing the lock, or alternatively change
apply_code_driven_plugin_config to return a (merged_config, layer_token) while
retaining the lock via a scoped guard that the caller uses to perform
activation/reporting, ensuring set_code_driven_plugin_config cannot mutate the
layer until activation/report storage completes.
- Around line 980-993: merge_plugin_config_layers currently finds the first base
component with the same kind and always merges into it, which drops additional
base instances of the same kind; change the merge to perform a one-to-one match:
clone base.components into components, keep a matched flag array (or
remove/consume matched entries) and for each overlay.components try to find the
first unmatched component in components with the same kind; if found mark it
matched and merge (existing.enabled = overlay.enabled; merge_json_object(&mut
existing.config, overlay.config.clone())), otherwise push overlay.clone() so
additional overlay instances are appended and not lost.
🪄 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: 0e4486e5-d6fd-40cc-8d2b-1a65b79fd46f
📒 Files selected for processing (7)
crates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_tests.rscrates/core/Cargo.tomlcrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/tests/unit/plugin_tests.rsdocs/build-plugins/plugin-configuration-files.mdx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Check / Run
- GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (27)
**/{Cargo.toml,**/*.rs}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Maintain consistency between Rust package names in
Cargo.tomland their actual usage across the codebase
Files:
crates/core/Cargo.tomlcrates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_tests.rs
{crates/core,crates/adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
Changes to
crates/coreorcrates/adaptivemust run the full language matrix
Files:
crates/core/Cargo.tomlcrates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_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/Cargo.tomlcrates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_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:
crates/core/Cargo.toml
**/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 asrelease/<major>.<minor>.
Files:
crates/core/Cargo.toml
crates/{core,adaptive}/**
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, run the full matrix across Rust, Python, Go, Node.js, and WebAssembly
Files:
crates/core/Cargo.tomlcrates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rs
{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/core/Cargo.tomldocs/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:
crates/core/Cargo.tomldocs/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:
crates/core/Cargo.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:
crates/core/Cargo.tomlcrates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_tests.rs
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Use
snake_casenaming convention for Rust identifiers (e.g.,nemo_relay_tool_call)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node work
**/*.rs: Runcargo fmt --allto format all Rust code
Runcargo clippy --workspace --all-targets -- -D warningsto enforce all clippy lints as errors
**/*.rs: Runcargo fmt --allwhen Rust files changed as part of WebAssembly work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files changed as part of WebAssembly work
**/*.rs: If any Rust code changed, always runjust test-rust
If any Rust code changed, also runcargo fmt --all
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting withcargo fmt --all
Run Rust linting withcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Usecargo fmtfor Rust code formatting
Runcargo clippy -- -D warningsto 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 withuv run pre-commit run --all-filesto enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_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/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/tests/coverage/doctor_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/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_tests.rs
crates/core/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)
If the change touched
crates/coreor shared runtime semantics, also usevalidate-changefor broader validation
crates/core/**/*.rs: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin core runtime paths. Keep errors explicit and binding-appropriate at the wrapper layer.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_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 prefixednemo_relay_, Go usesPascalCasefor public APIs, Node.js usescamelCase.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_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.
UseJson = serde_json::Valuein Rust-facing runtime APIs for JSON payload handling.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/src/doctor.rscrates/cli/tests/coverage/doctor_tests.rs
crates/{core,adaptive}/**/*.rs
⚙️ CodeRabbit configuration file
crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}
⚙️ CodeRabbit configuration file
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/cli/tests/coverage/doctor_tests.rs
{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. Usejust docsfor docs-site builds andjust docs-linkcheckwhen links changed
Run docs site build withjust 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-linkcheckwhen 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
**/*.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 docsor./scripts/build-docs.sh htmlto regenerate ignored Fern API reference pages before validation for documentation site changes
Files:
docs/build-plugins/plugin-configuration-files.mdx
{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
🪛 LanguageTool
docs/build-plugins/plugin-configuration-files.mdx
[style] ~267-~267: Consider replacing this word to strengthen your wording.
Context: ... same process. It is a Rust runtime API and is not exposed to the Python, Node.js, ...
(AND_THAT)
🔇 Additional comments (9)
docs/build-plugins/plugin-configuration-files.mdx (1)
72-272: LGTM!crates/cli/src/doctor.rs (3)
17-19: LGTM!
575-587: LGTM!
589-698: LGTM!crates/cli/tests/coverage/doctor_tests.rs (2)
660-718: LGTM!
720-754: 💤 Low valueGlobal wiring is only covered indirectly.
collect_observability_layered(...)is exercised directly in these tests, but the process-global code-driven layer (set_code_driven_plugin_config) is only referenced in the core plugin layer tests, not incrates/cli/tests/coverage/doctor_tests.rs; the doctor tests that callcollect_observability(&gateway).awaitdon’t appear to set the global layer, so regressions incollect_observability’sbaseparsing +apply_code_driven_plugin_configmerge precedence could slip through.crates/core/tests/unit/plugin_tests.rs (1)
302-302: LGTM!Also applies to: 318-420
crates/core/Cargo.toml (1)
121-123: Please confirm the required Rust validation matrix ran for this new test target.This adds a dedicated integration binary, so please verify the PR ran
just test-rust,cargo fmt --all, andcargo clippy --workspace --all-targets -- -D warnings.As per coding guidelines,
**/*.rs: If any Rust code changed, always runjust test-rust; also runcargo fmt --all; also runcargo clippy --workspace --all-targets -- -D warnings.crates/core/tests/integration/plugin_layer_tests.rs (1)
1-105: LGTM!
merge_plugin_config_layers now pairs components by kind in order of appearance instead of always merging into the first match, so repeated kinds (multi-instance plugins) are no longer collapsed or dropped. Also slim the layer integration test to the apply path (merge correctness is covered by the unit tests) and tighten the new doc comments. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/core/tests/integration/plugin_layer_tests.rs (1)
13-34: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winCover
initialize_pluginsin the dedicated layer test binary.This test only exercises the pure accessor. The behavior that matters externally is
initialize_pluginsconsuming the layer, activating the merged config, and makingactive_plugin_report()reflect that effective config. Without that path here, regressions in the activation/reporting contract can slip through.As per coding guidelines,
{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.🤖 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/core/tests/integration/plugin_layer_tests.rs` around lines 13 - 34, The test currently only calls the accessor apply_code_driven_plugin_config and never goes through the activation path; update the test to call initialize_plugins (the real activation function) after setting set_code_driven_plugin_config(Some(...)) and then assert that active_plugin_report() reflects the merged/effective PluginConfig (including the relay183.example component), and finally call initialize_plugins or the appropriate teardown/cleanup to restore isolation and confirm active_plugin_report() becomes None after set_code_driven_plugin_config(None); use the existing symbols apply_code_driven_plugin_config, set_code_driven_plugin_config, initialize_plugins, and active_plugin_report to implement this activation/verification flow in the test binary.
♻️ Duplicate comments (1)
crates/core/src/plugin.rs (1)
919-926:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftSerialize the layer snapshot with activation/reporting.
Line 925 computes an effective config under the layer mutex, but
initialize_pluginsthen validates, activates, and storesactive_plugin_report()after that lock is gone. A concurrentset_code_driven_plugin_config(...)can change the process-global layer mid-initialization, leaving the active runtime state/report out of sync with the current layer.As per coding guidelines,
crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.🤖 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/core/src/plugin.rs` around lines 919 - 926, The code computes an effective config while holding the PLUGIN_CONFIG_CODE_DRIVEN_LAYER lock inside apply_code_driven_plugin_config but then initialize_plugins validates/activates and stores active_plugin_report after the lock is released, allowing a concurrent set_code_driven_plugin_config to change the global layer mid-initialization; fix by snapshotting the layer under the PLUGIN_CONFIG_CODE_DRIVEN_LAYER mutex (e.g., clone or serialize the layer value while inside the lock in apply_code_driven_plugin_config), return/propagate that immutable snapshot to initialize_plugins/merge_plugin_config_layers so that validation/activation/reporting (active_plugin_report) always operate on the exact serialized layer snapshot rather than a mutable global reference, ensuring consistency between activation and the stored report.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@crates/core/tests/integration/plugin_layer_tests.rs`:
- Around line 13-34: The test currently only calls the accessor
apply_code_driven_plugin_config and never goes through the activation path;
update the test to call initialize_plugins (the real activation function) after
setting set_code_driven_plugin_config(Some(...)) and then assert that
active_plugin_report() reflects the merged/effective PluginConfig (including the
relay183.example component), and finally call initialize_plugins or the
appropriate teardown/cleanup to restore isolation and confirm
active_plugin_report() becomes None after set_code_driven_plugin_config(None);
use the existing symbols apply_code_driven_plugin_config,
set_code_driven_plugin_config, initialize_plugins, and active_plugin_report to
implement this activation/verification flow in the test binary.
---
Duplicate comments:
In `@crates/core/src/plugin.rs`:
- Around line 919-926: The code computes an effective config while holding the
PLUGIN_CONFIG_CODE_DRIVEN_LAYER lock inside apply_code_driven_plugin_config but
then initialize_plugins validates/activates and stores active_plugin_report
after the lock is released, allowing a concurrent set_code_driven_plugin_config
to change the global layer mid-initialization; fix by snapshotting the layer
under the PLUGIN_CONFIG_CODE_DRIVEN_LAYER mutex (e.g., clone or serialize the
layer value while inside the lock in apply_code_driven_plugin_config),
return/propagate that immutable snapshot to
initialize_plugins/merge_plugin_config_layers so that
validation/activation/reporting (active_plugin_report) always operate on the
exact serialized layer snapshot rather than a mutable global reference, ensuring
consistency between activation and the stored report.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: f454ab03-ef87-4e13-8f84-a18a83081e6d
📒 Files selected for processing (4)
crates/core/src/plugin.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/tests/unit/plugin_tests.rsdocs/build-plugins/plugin-configuration-files.mdx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Python / Package (windows-arm64)
- GitHub Check: Python / Package (windows-amd64)
- GitHub Check: WebAssembly / Test (windows-arm64)
🧰 Additional context used
📓 Path-based instructions (24)
{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. Usejust docsfor docs-site builds andjust docs-linkcheckwhen links changed
Run docs site build withjust 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-linkcheckwhen 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 docsor./scripts/build-docs.sh htmlto regenerate ignored Fern API reference pages before validation for documentation site changes
Files:
docs/build-plugins/plugin-configuration-files.mdx
{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_casenaming convention for Rust identifiers (e.g.,nemo_relay_tool_call)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node work
**/*.rs: Runcargo fmt --allto format all Rust code
Runcargo clippy --workspace --all-targets -- -D warningsto enforce all clippy lints as errors
**/*.rs: Runcargo fmt --allwhen Rust files changed as part of WebAssembly work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files changed as part of WebAssembly work
**/*.rs: If any Rust code changed, always runjust test-rust
If any Rust code changed, also runcargo fmt --all
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting withcargo fmt --all
Run Rust linting withcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Usecargo fmtfor Rust code formatting
Runcargo clippy -- -D warningsto 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 withuv run pre-commit run --all-filesto enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.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/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rs
**/{Cargo.toml,**/*.rs}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Maintain consistency between Rust package names in
Cargo.tomland their actual usage across the codebase
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.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/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.rs
{crates/core,crates/adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
Changes to
crates/coreorcrates/adaptivemust run the full language matrix
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.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/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.rs
crates/core/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)
If the change touched
crates/coreor shared runtime semantics, also usevalidate-changefor broader validation
crates/core/**/*.rs: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin core runtime paths. Keep errors explicit and binding-appropriate at the wrapper layer.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.rs
crates/{core,adaptive}/**
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, run the full matrix across Rust, Python, Go, Node.js, and WebAssembly
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.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/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.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 prefixednemo_relay_, Go usesPascalCasefor public APIs, Node.js usescamelCase.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.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.
UseJson = serde_json::Valuein Rust-facing runtime APIs for JSON payload handling.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.rs
crates/{core,adaptive}/**/*.rs
⚙️ CodeRabbit configuration file
crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rscrates/core/src/plugin.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}
⚙️ CodeRabbit configuration file
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/tests/integration/plugin_layer_tests.rs
🔇 Additional comments (1)
docs/build-plugins/plugin-configuration-files.mdx (1)
229-231: LGTM!
| Arrays inside component config are replaced by the higher-precedence value. | ||
| Tables inside component config merge recursively. | ||
|
|
||
| ## Code-Driven Configuration Layer |
There was a problem hiding this comment.
This should NOT be exposed as a public API.
The layering should be described but it's not something that should be used invoked. Plugin initialize should be the only way it's done.
nemo-relay doctor runs in its own process and never sets a code-driven layer, so it can never observe one; the layer-aware reporting was unreachable in the shipped CLI (only the unit tests, which set the layer in-process, exercised it). Restore the original file-only collect_observability, remove the two layered doctor tests, and drop the doctor sentence from the docs. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
Add a single public core primitive, merge_plugin_config(&Value, &Value) -> Value: objects merge recursively, arrays and scalars are replaced by the overlay, and the top-level components array pairs entries by kind in order of appearance (so multi-instance kinds are not collapsed). The CLI's plugins.toml file-layer merging now calls it instead of the duplicate merge_plugin_toml/merge_plugin_components (merge_toml is kept for config.toml). This replaces the process-global code-driven layer (set/apply plus the auto-apply in initialize_plugins) with a caller-driven primitive; initialize_plugins is unchanged and the merge holds no global state. Tests and docs updated; the layer integration test is removed. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
Rename the public merge primitive merge_plugin_config -> layer_config (core, the CLI call site, tests, and docs), rename the docs section to "Configuration Layering", and trim the over-verbose doc comments on the merge helpers. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
…I merge layer_config / merge_plugin_components / merge_json_value now use the original in-place (&mut left, right) form, so they are faithful translations of the CLI's merge_plugin_toml / merge_plugin_components / merge_toml (on serde_json::Value, with the positional multi-instance pairing). Behavior is unchanged; the CLI call site, tests, and doc example are updated to match. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/cli/src/config.rs`:
- Around line 762-763: The current call to
validate_plugin_toml_component_kinds(&path, &parsed) prevents repeated component
kinds in a single plugins.toml file; remove or change that enforcement so
duplicate kinds are allowed per-file (since layer_config supports positional
same-kind pairing). Specifically, either delete the
validate_plugin_toml_component_kinds(&path, &parsed) invocation where files are
merged, or update validate_plugin_toml_component_kinds to only validate
component shape/existence (not uniqueness), ensuring functions that merge layers
(the code that converts each file to JSON and merges with the shared core
primitive) still rely on layer_config positional semantics to handle same-kind
instances correctly.
🪄 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: d23b22e4-d2ba-482b-b713-de5fdbfd87a0
📒 Files selected for processing (4)
crates/cli/src/config.rscrates/core/src/plugin.rscrates/core/tests/unit/plugin_tests.rsdocs/build-plugins/plugin-configuration-files.mdx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (25)
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Use
snake_casenaming convention for Rust identifiers (e.g.,nemo_relay_tool_call)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node work
**/*.rs: Runcargo fmt --allto format all Rust code
Runcargo clippy --workspace --all-targets -- -D warningsto enforce all clippy lints as errors
**/*.rs: Runcargo fmt --allwhen Rust files changed as part of WebAssembly work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files changed as part of WebAssembly work
**/*.rs: If any Rust code changed, always runjust test-rust
If any Rust code changed, also runcargo fmt --all
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting withcargo fmt --all
Run Rust linting withcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Usecargo fmtfor Rust code formatting
Runcargo clippy -- -D warningsto 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 withuv run pre-commit run --all-filesto enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/cli/src/config.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/core/tests/unit/plugin_tests.rs
**/{Cargo.toml,**/*.rs}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Maintain consistency between Rust package names in
Cargo.tomland their actual usage across the codebase
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/cli/src/config.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/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/cli/src/config.rs
{crates/core,crates/adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
Changes to
crates/coreorcrates/adaptivemust run the full language matrix
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.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/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/cli/src/config.rs
crates/core/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)
If the change touched
crates/coreor shared runtime semantics, also usevalidate-changefor broader validation
crates/core/**/*.rs: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin core runtime paths. Keep errors explicit and binding-appropriate at the wrapper layer.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rs
crates/{core,adaptive}/**
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, run the full matrix across Rust, Python, Go, Node.js, and WebAssembly
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.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/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/cli/src/config.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 prefixednemo_relay_, Go usesPascalCasefor public APIs, Node.js usescamelCase.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/cli/src/config.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.
UseJson = serde_json::Valuein Rust-facing runtime APIs for JSON payload handling.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rscrates/cli/src/config.rs
crates/{core,adaptive}/**/*.rs
⚙️ CodeRabbit configuration file
crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}
⚙️ CodeRabbit configuration file
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.
Files:
crates/core/tests/unit/plugin_tests.rs
{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. Usejust docsfor docs-site builds andjust docs-linkcheckwhen links changed
Run docs site build withjust 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-linkcheckwhen 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 docsor./scripts/build-docs.sh htmlto regenerate ignored Fern API reference pages before validation for documentation site changes
Files:
docs/build-plugins/plugin-configuration-files.mdx
{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
**/*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
🧠 Learnings (22)
📚 Learning: 2026-05-21T22:49:09.811Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/maintain-optimizer/SKILL.md:0-0
Timestamp: 2026-05-21T22:49:09.811Z
Learning: Applies to {crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**} : Maintain documented and tested validation and report behavior for adaptive surfaces
Applied to files:
crates/core/tests/unit/plugin_tests.rs
📚 Learning: 2026-05-21T22:51:04.073Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/test-go-binding/SKILL.md:0-0
Timestamp: 2026-05-21T22:51:04.073Z
Learning: Applies to crates/ffi/**/*.rs : If the change touched `crates/ffi`, also use `test-ffi-surface` for validation
Applied to files:
crates/core/tests/unit/plugin_tests.rs
📚 Learning: 2026-05-21T22:47:58.898Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/add-middleware/SKILL.md:0-0
Timestamp: 2026-05-21T22:47:58.898Z
Learning: Applies to crates/core/src/api/runtime/state.rs : Add chain execution helpers to `NemoRelayContextState` following the pattern of existing methods like `tool_sanitize_request_chain` or `tool_request_intercepts_chain`
Applied to files:
crates/core/tests/unit/plugin_tests.rs
📚 Learning: 2026-05-21T22:47:58.898Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/add-middleware/SKILL.md:0-0
Timestamp: 2026-05-21T22:47:58.898Z
Learning: Applies to crates/core/src/api/runtime/state.rs : Add registry fields as `SortedRegistry<GuardrailEntry<T>>` or `SortedRegistry<Intercept<T>>` to `NemoRelayContextState` in `crates/core/src/api/runtime/state.rs`
Applied to files:
crates/core/tests/unit/plugin_tests.rs
📚 Learning: 2026-05-29T21:25:49.977Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-29T21:25:49.977Z
Learning: Applies to crates/core/**/*.rs : Use `Json = serde_json::Value` in Rust-facing runtime APIs where the existing code expects JSON payloads.
Applied to files:
crates/core/src/plugin.rscrates/cli/src/config.rs
📚 Learning: 2026-05-29T21:25:49.977Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-29T21:25:49.977Z
Learning: Applies to crates/**/*.rs : Use `Json = serde_json::Value` in Rust-facing runtime APIs for JSON payload handling.
Applied to files:
crates/core/src/plugin.rscrates/cli/src/config.rs
📚 Learning: 2026-05-21T22:47:33.109Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/add-binding-feature/SKILL.md:0-0
Timestamp: 2026-05-21T22:47:33.109Z
Learning: Applies to crates/core/src/api/**/*.rs : Implement behavior first in Rust core API modules: `crates/core/src/api/` and related core modules such as `crates/core/src/api/runtime/`, `crates/core/src/codec/`, or `crates/core/src/json.rs`
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-21T22:49:09.811Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/maintain-optimizer/SKILL.md:0-0
Timestamp: 2026-05-21T22:49:09.811Z
Learning: Applies to {crates/adaptive/**,python/nemo_relay/plugin.py,go/nemo_relay/**,**/node/**,**/wasm/**} : Maintain consistent plugin lifecycle across all language bindings (Python, Go, Node/WebAssembly, and Rust)
Applied to files:
crates/core/src/plugin.rsdocs/build-plugins/plugin-configuration-files.mdx
📚 Learning: 2026-05-21T22:49:09.811Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/maintain-optimizer/SKILL.md:0-0
Timestamp: 2026-05-21T22:49:09.811Z
Learning: Applies to {crates/adaptive/**,python/nemo_relay/plugin.py,go/nemo_relay/**,**/node/**,**/wasm/**} : Keep plugin context surfaces aligned across all language implementations
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-21T22:50:43.254Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/small-fix/SKILL.md:0-0
Timestamp: 2026-05-21T22:50:43.254Z
Learning: Update documentation if public behavior changed
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-21T22:49:35.949Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/prepare-pr/SKILL.md:0-0
Timestamp: 2026-05-21T22:49:35.949Z
Learning: Docs and examples must be updated for any public behavior changes
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-21T22:47:33.109Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/add-binding-feature/SKILL.md:0-0
Timestamp: 2026-05-21T22:47:33.109Z
Learning: Do not use this skill for internal-only core refactors with no public API change
Applied to files:
crates/core/src/plugin.rsdocs/build-plugins/plugin-configuration-files.mdx
📚 Learning: 2026-05-21T22:48:05.982Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/contribute-api/SKILL.md:0-0
Timestamp: 2026-05-21T22:48:05.982Z
Learning: Include PR notes explaining the user-facing change for new API surfaces
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-27T02:34:30.939Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2026-05-27T02:34:30.939Z
Learning: Applies to docs/reference/** : Update relevant reference documentation for any public API changes
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-26T21:02:51.956Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/contribute-docs/SKILL.md:0-0
Timestamp: 2026-05-26T21:02:51.956Z
Learning: Prefer the documented public API, not internal shortcuts
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-21T22:48:05.982Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/contribute-api/SKILL.md:0-0
Timestamp: 2026-05-21T22:48:05.982Z
Learning: Update docs and examples in the same branch as public API changes
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-21T22:52:14.330Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/validate-change/SKILL.md:0-0
Timestamp: 2026-05-21T22:52:14.330Z
Learning: If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch
Applied to files:
crates/core/src/plugin.rs
📚 Learning: 2026-05-26T21:03:12.012Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/review-doc-style/SKILL.md:0-0
Timestamp: 2026-05-26T21:03:12.012Z
Learning: Applies to **/README.md|docs/index.md|python/nemo_relay/README.md|crates/*/README.md : Public behavior changes must be reflected in corresponding entry-point documentation (Must-Fix)
Applied to files:
docs/build-plugins/plugin-configuration-files.mdx
📚 Learning: 2026-05-26T21:03:12.012Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/review-doc-style/SKILL.md:0-0
Timestamp: 2026-05-26T21:03:12.012Z
Learning: Applies to **/README.md|docs/index.md|python/nemo_relay/README.md|crates/*/README.md : Update entry-point documentation (README.md, docs/index.md, package/crate READMEs, and binding-level source READMEs) whenever public behavior changes
Applied to files:
docs/build-plugins/plugin-configuration-files.mdx
📚 Learning: 2026-05-21T22:47:33.109Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/add-binding-feature/SKILL.md:0-0
Timestamp: 2026-05-21T22:47:33.109Z
Learning: Applies to crates/ffi/src/api/**/*.rs : Add or update FFI wrappers in relevant `crates/ffi/src/api/*.rs` modules, re-export through `crates/ffi/src/api/mod.rs`, and ensure generated `crates/ffi/nemo_relay.h` stays correct
Applied to files:
crates/cli/src/config.rs
📚 Learning: 2026-05-21T22:47:33.109Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/add-binding-feature/SKILL.md:0-0
Timestamp: 2026-05-21T22:47:33.109Z
Learning: Applies to crates/ffi/src/api/**/*.rs : Use `nemo_relay_` prefix for C FFI function names (e.g., `nemo_relay_tool_call`)
Applied to files:
crates/cli/src/config.rs
📚 Learning: 2026-05-21T22:49:46.956Z
Learnt from: CR
Repo: NVIDIA/NeMo-Relay PR: 0
File: .agents/skills/rename-surfaces/SKILL.md:0-0
Timestamp: 2026-05-21T22:49:46.956Z
Learning: Applies to **/*.{rs,toml} : Update Rust crate names and module prefixes during coordinated rename operations
Applied to files:
crates/cli/src/config.rs
🔇 Additional comments (5)
docs/build-plugins/plugin-configuration-files.mdx (3)
6-7: LGTM!
201-222: LGTM!
223-231: ⚡ Quick winUpdate “internal primitive” wording for
layer_configto match its actual Rust visibility
layer_configis declared aspub fnincrates/core/src/plugin.rsand is invoked bycrates/cli/src/config.rs.- Adjust the docs (lines 223-231) to describe it as an internal/unsupported gateway mechanism for direct callers, rather than implying it’s not something Rust users can access—unless you intentionally hide it from the public Rust API (module visibility/re-exports and/or
#[doc(hidden)]).crates/core/src/plugin.rs (1)
902-979: LGTM!crates/core/tests/unit/plugin_tests.rs (1)
318-393: LGTM!Also applies to: 396-419
|
This is the core required feature: Right now, if a user has direct integration and calls We already have existing configuration layering for the CLI through various Need: instead of the base configuration being empty, it should be resolved from pre-existing NeMo Relay plugin configuration layering. |
initialize_plugins now resolves the discovered plugins.toml layering as a base and layers the caller's config on top, so direct integrations (any binding) inherit the same file layering as the gateway instead of starting from an empty base. initialize_plugins_exact activates an already-materialized config without discovery; the CLI uses it so --config / --plugin-config source rules are unchanged. File discovery and TOML parsing sit behind an opt-in config-files core feature, keeping the default and wasm builds free of toml/filesystem; the CLI and native bindings enable it, and the CLI read/parse/merge is de-duplicated onto the shared core load_plugin_config_files primitive. The caller's config is layered as a typed document, so version/policy/enabled carry serde defaults while component config bodies merge field-by-field. Refs: RELAY-183 Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
The optional config-files feature gated plugins.toml discovery and the TOML parser out of core's default/wasm builds. Removing it makes toml a direct core dependency and discovery unconditional, dropping the feature flag, all #[cfg] gates, and the per-binding feature lines. Trade-off: toml and the filesystem discovery now compile into every core build, including wasm (where discovery finds no files, so the base is empty). Also trims the doc comments on the new plugin-init and discovery functions. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
Adds core unit tests for load_plugin_config_files (merge by precedence, per-file duplicate-kind rejection, absent-files case) and documents the code-driven layering model and its precedence in the plugin configuration docs. Restores the original initialize_plugins doc on initialize_plugins_exact. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
Internal gateway entry (no-discovery activation), not a documented public API — same treatment as load_plugin_config_files. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
Source Precedence And Conflicts duplicated the Discovery section (same source classes, mutual exclusivity, and precedence order); removed it. Tightened Configuration Layering to the code-driven model and precedence, dropping the internal layer_config note and the multi-instance aside. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
layer_config has no external callers — the CLI uses load_plugin_config_files and its tests are inline — so it drops pub and is fully internal to core's plugin module. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
Drops the duplicate-kind test (the CLI's plugins_toml_rejects_duplicate_component_kinds_per_file already covers that path through the shared loader) and the trivial absent-file test; adds a hermetic test pinning the code-vs-file typed-overlay precedence: a typed config's default version/policy/enabled override the file base, the config body merges, and an undeclared kind is inherited. Keeps the file-vs-file merge test. Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/core/src/plugin.rs`:
- Around line 1071-1099: load_plugin_config_files is performing blocking
filesystem and parse work (std::fs::read_to_string, toml::Table parsing,
serde_json::to_value) while being invoked from async initialize_plugins; offload
that work to the tokio blocking pool to avoid stalling the runtime by wrapping
the per-path blocking operations in tokio::task::spawn_blocking and awaiting the
JoinHandle inside load_plugin_config_files, or wrap the whole per-path block
(reading, parsing, validate_unique_component_kinds, layer_config) in
spawn_blocking so the function can remain synchronous for callers like
initialize_plugins; ensure errors are propagated back (map the JoinHandle result
and inner Result) and keep references to the same symbols
(load_plugin_config_files, validate_unique_component_kinds, layer_config,
initialize_plugins) so callers still compile.
🪄 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: db362eef-1db6-41b4-bd7a-cadf5f082488
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (6)
crates/cli/src/config.rscrates/cli/src/server.rscrates/core/Cargo.tomlcrates/core/src/plugin.rscrates/core/tests/unit/plugin_tests.rsdocs/build-plugins/plugin-configuration-files.mdx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Rust / Package (macos-arm64)
- GitHub Check: Rust / Package (linux-arm64)
- GitHub Check: Rust / Package (linux-amd64)
- GitHub Check: Rust / Package (windows-arm64)
- GitHub Check: Rust / Package (windows-amd64)
- GitHub Check: Node.js / Test (windows-arm64)
- GitHub Check: Python / Test (windows-arm64)
🧰 Additional context used
📓 Path-based instructions (29)
**/{Cargo.toml,**/*.rs}
📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)
Maintain consistency between Rust package names in
Cargo.tomland their actual usage across the codebase
Files:
crates/core/Cargo.tomlcrates/cli/src/server.rscrates/core/tests/unit/plugin_tests.rscrates/cli/src/config.rscrates/core/src/plugin.rs
{crates/core,crates/adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
Changes to
crates/coreorcrates/adaptivemust run the full language matrix
Files:
crates/core/Cargo.tomlcrates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.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/Cargo.tomlcrates/cli/src/server.rscrates/core/tests/unit/plugin_tests.rscrates/cli/src/config.rscrates/core/src/plugin.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:
crates/core/Cargo.toml
**/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 asrelease/<major>.<minor>.
Files:
crates/core/Cargo.toml
crates/{core,adaptive}/**
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, run the full matrix across Rust, Python, Go, Node.js, and WebAssembly
Files:
crates/core/Cargo.tomlcrates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rs
{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/core/Cargo.tomldocs/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:
crates/core/Cargo.tomldocs/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:
crates/core/Cargo.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:
crates/core/Cargo.tomlcrates/cli/src/server.rscrates/core/tests/unit/plugin_tests.rscrates/cli/src/config.rscrates/core/src/plugin.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:
- Scope stacks decide where work belongs and which scope-local behavior is visible.
- Middleware registries decide what guardrails and intercepts run around managed calls.
- Plugins install reusable runtime behavior from configuration.
- Events record runtime behavior in ATOF form.
- Subscribers and exporters consume events in-process or export them to ATIF, OpenTelemetry, OpenInference, or other backends.
Repository Structure
The repository layout separates the Rust runtime, language bindings, documentation,
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:
crates/core/Cargo.tomlcrates/cli/src/server.rscrates/core/tests/unit/plugin_tests.rsdocs/build-plugins/plugin-configuration-files.mdxcrates/cli/src/config.rscrates/core/src/plugin.rs
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Use
snake_casenaming convention for Rust identifiers (e.g.,nemo_relay_tool_call)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node work
**/*.rs: Runcargo fmt --allto format all Rust code
Runcargo clippy --workspace --all-targets -- -D warningsto enforce all clippy lints as errors
**/*.rs: Runcargo fmt --allwhen Rust files changed as part of WebAssembly work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files changed as part of WebAssembly work
**/*.rs: If any Rust code changed, always runjust test-rust
If any Rust code changed, also runcargo fmt --all
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings
Run Rust formatting withcargo fmt --all
Run Rust linting withcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Usecargo fmtfor Rust code formatting
Runcargo clippy -- -D warningsto 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 withuv run pre-commit run --all-filesto enforce cargo fmt formatting check, cargo clippy lints, and cargo deny aud...
Files:
crates/cli/src/server.rscrates/core/tests/unit/plugin_tests.rscrates/cli/src/config.rscrates/core/src/plugin.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/server.rscrates/core/tests/unit/plugin_tests.rscrates/cli/src/config.rscrates/core/src/plugin.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 prefixednemo_relay_, Go usesPascalCasefor public APIs, Node.js usescamelCase.
Files:
crates/cli/src/server.rscrates/core/tests/unit/plugin_tests.rscrates/cli/src/config.rscrates/core/src/plugin.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.
UseJson = serde_json::Valuein Rust-facing runtime APIs for JSON payload handling.
Files:
crates/cli/src/server.rscrates/core/tests/unit/plugin_tests.rscrates/cli/src/config.rscrates/core/src/plugin.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/core/tests/unit/plugin_tests.rs
crates/core/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)
If the change touched
crates/coreor shared runtime semantics, also usevalidate-changefor broader validation
crates/core/**/*.rs: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin core runtime paths. Keep errors explicit and binding-appropriate at the wrapper layer.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rs
crates/{core,adaptive}/**/*.rs
⚙️ CodeRabbit configuration file
crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.
Files:
crates/core/tests/unit/plugin_tests.rscrates/core/src/plugin.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}
⚙️ CodeRabbit configuration file
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.
Files:
crates/core/tests/unit/plugin_tests.rs
{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. Usejust docsfor docs-site builds andjust docs-linkcheckwhen links changed
Run docs site build withjust 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-linkcheckwhen 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
**/*.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 docsor./scripts/build-docs.sh htmlto regenerate ignored Fern API reference pages before validation for documentation site changes
Files:
docs/build-plugins/plugin-configuration-files.mdx
{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
**/*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
🔇 Additional comments (16)
crates/cli/src/config.rs (2)
743-753: Delegation to core's shared loader looks good.The error mapping correctly converts
PluginError::InvalidConfigtoCliError::Configwhile other variants fall back to.to_string().Note: The past review comment about allowing repeated component
kindvalues per file is still relevant—validate_unique_component_kindsin core still rejects duplicates within a single file. If multi-instance same-kind entries in oneplugins.tomlare intended, that validation needs adjustment in core.
4-13: LGTM!Clean import changes reflecting the delegation to core's shared loader.
crates/core/src/plugin.rs (7)
902-923: LGTM!
925-958: LGTM!The positional pairing via
base_slotsandconsumedcorrectly preserves multi-instance component kinds, addressing the earlier concern about collapsing duplicates.
960-979: LGTM!
1008-1061: LGTM!
initialize_plugins_exactcorrectly retains the rollback/restore semantics, andinitialize_pluginslayers code-driven config on top of discovered file config as intended.
1063-1069: LGTM!
1101-1125: LGTM!
1127-1159: LGTM!crates/core/tests/unit/plugin_tests.rs (2)
1422-1478: LGTM!Good coverage of file precedence merging behavior - verifies inheritance of lower-file keys, override of shared keys, and appending of higher-only component kinds.
1480-1533: LGTM!Solid test for the code-vs-file layering semantics, correctly verifying that typed defaults override file base while undeclared config fields merge.
crates/cli/src/server.rs (2)
10-10: LGTM!
160-165: LGTM!Correct use of
initialize_plugins_exactsince the gateway has already resolved config via CLI paths. The comment clearly documents the intent.crates/core/Cargo.toml (2)
89-89: LGTM!
tempfileis correctly placed in dev-dependencies for test filesystem isolation.
64-64: Keeptomlpin consistent withCargo.lock; confirm the MSRV/rationale for staying on 0.9.
crates/core/Cargo.tomlpinstoml = { version = "0.9" }, andCargo.lockresolves it totoml 0.9.12+spec-1.1.0(latest within the 0.9 major).crates/cli/Cargo.tomlalso usestoml = "0.9", so the pin is workspace-consistent.- crates.io latest is
1.1.2+spec-1.1.0; if moving to1.xis intentionally blocked for MSRV/behavior reasons, call that out—there’s norust-version = ...field found to substantiate the MSRV constraint.docs/build-plugins/plugin-configuration-files.mdx (1)
201-209: LGTM!Documentation correctly describes the layering behavior for direct integrations without exposing internal APIs. The precedence semantics (typed defaults override file, omitted keys inherited) are clearly stated.
|
@willkill07 , sorry it took so long — I spent most of the time trying to decide where the toml discovery should belong and decide on the general architecture — but I;m wondering what do you think of the new changes? I also updated the PR body for this :) |
Overview
Layer code-driven plugin config on top of the materialized file-based
plugins.tomlconfigs (RELAY-183). A direct integration that callsplugin.initialize(...)now resolves the sameplugins.tomllayering the gateway uses as its base instead of starting empty; the code-driven config is the authoritative top layer.Details
initialize_plugins(config)resolves the discoveredplugins.tomllayering (system → project → user) as a base and layersconfigon top, so every binding inherits the file layering with no binding code changes.initialize_plugins_exact(config)activates an already-materialized config without discovery; the gateway uses it so--config/--plugin-configsource rules are unchanged.tomlis a direct dependency andload_plugin_config_files(#[doc(hidden)]) is the shared read/parse/merge primitive the CLI delegates to.toml+ the filesystem discovery compile into every core build, including wasm (where discovery finds no files at runtime, so the base is empty).Precedence — code-vs-file differs from file-vs-file. File-vs-file uses
omit = inherit. Code-vs-file treats the code document as authoritative: you inherit any component kind orconfigkey you omit, but the typed fields (version,policy, and a declared component'senabled) always take the code value (serde defaults included) — because bindings deserialize to the typedPluginConfigbefore core sees it, so "set" vs "defaulted" is already lost.Constraints
Kept:
PluginConfig/PluginComponentSpec/ConfigPolicyuntouched.plugin.initialize(...)signatures unchanged across bindings.Relaxed (with reason):
pub fns added (initialize_plugins_exact,load_plugin_config_files), both#[doc(hidden)]for cross-crate gateway use; the gateway needs a no-discovery path distinct from the now-discoveringinitialize_plugins.Tests
Core unit tests for
load_plugin_config_files(merge precedence, per-file duplicate-kind rejection, absent files); existing CLI file-discovery tests exercise the same shared primitive.Where should the reviewer start?
crates/core/src/plugin.rs—initialize_plugins(base-layer + overlay),initialize_plugins_exact, and the discovery /load_plugin_config_files. The precedence decision is the key thing to confirm.Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)
Summary by CodeRabbit
Release Notes
New Features
Documentation