fix(annotated)!: integrate lossless request codecs#509
Conversation
Signed-off-by: Will Killian <wkillian@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:
WalkthroughThe request annotation model now supports instructions, provider-specific fields, extended message/content variants, and provider-native tools. Provider codecs decode structured requests and apply baseline-aware patches, while gateway routing, compatibility validation, bindings, adaptive processing, tests, and documentation are updated. ChangesProvider-aware request annotation flow
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant Gateway
participant RequestCodec
participant Interceptor
participant Provider
Client->>Gateway: generation request
Gateway->>RequestCodec: decode provider JSON
RequestCodec->>Interceptor: normalized AnnotatedLlmRequest
Interceptor->>RequestCodec: edited instructions/messages/tools
RequestCodec->>Provider: baseline-patched provider JSON
Provider-->>Gateway: response
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Verified end-to-end successfully.
Commands:
Both used the real installed clients, temporary Relay plugin installations, codec-enabled gateways, and an isolated deterministic provider. Requests returned This verifies client/gateway/codec compatibility, not live Anthropic/OpenAI service availability. The PR branch remains clean and unchanged. |
|
One compatibility question before this lands: the PR adds new |
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
P2 verification: malformed modeled scalars are silently acceptedI reproduced this issue against the current PR head, commit Cases tested
For each case, the focused diagnostic test performed the same checks:
The focused command was: Result: These were diagnostic assertions of the current behavior, so the passing result confirms the bug rather than the desired contract. ImpactA present value of the wrong JSON type is treated the same as an absent value by the typed annotation. Because the baseline-aware encoder preserves untouched raw fields, the malformed value is still forwarded to the provider. Middleware therefore sees the control as absent while the provider receives invalid JSON. This conflicts with the PR's stated behavior of rejecting malformed recognized structures before invoking the provider callback and may defer errors to provider-specific validation. Expected behaviorFor recognized modeled fields, decoding should distinguish:
The latter should return Inline discussion: #509 (comment) |
Signed-off-by: Will Killian <wkillian@nvidia.com>
bbednarski9
left a comment
There was a problem hiding this comment.
Follow-up testing found one residual P2 in the new array-alignment fix.
Signed-off-by: Will Killian <wkillian@nvidia.com>
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/codec/mod.rs`:
- Around line 162-211: Remove the unconditional single-pair fallback in
align_changed_items that pairs one unmatched edited item with one unmatched
baseline item, since it can transfer provider fields between unrelated items.
Let ambiguous unmatched items remain unaligned so
patch_changed_json/patch_changed_array use their normal encode or edited-value
behavior; add a regression test in parity_tests.rs covering the reordered
deletion plus unrelated insertion case.
In `@crates/core/src/plugin/dynamic.rs`:
- Around line 96-109: Update validate_annotated_request_consumer_compatibility
to reject any VersionReq that admits a Relay 0.5.x version, including narrow
bounds and exact pins such as =0.5.3; do not rely on a single max-patch probe.
Inspect the parsed requirement’s comparators or otherwise perform comprehensive
0.5.x matching, while preserving the existing InvalidConfig error and allowing
ranges that exclude the entire 0.5 series.
🪄 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: bc8d8ce7-ff3c-48e0-ad02-3303a0afeff3
📒 Files selected for processing (46)
crates/adaptive/src/acg/ir_builder.rscrates/adaptive/src/acg_profile.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/src/gateway/mod.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/api/llm.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/core/src/observability/openinference.rscrates/core/src/plugin/dynamic.rscrates/core/src/plugin/dynamic/native.rscrates/core/src/plugin/dynamic/worker.rscrates/core/tests/integration/native_plugin_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/types/src/api/llm.rscrates/types/src/codec/request.rscrates/worker/src/lib.rscrates/worker/tests/worker_sdk_tests.rsdocs/about-nemo-relay/release-notes/known-issues.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxdocs/integrate-into-frameworks/provider-codecs.mdxdocs/reference/llm-request-intercept-outcomes.mdxexamples/rust-native-plugin/relay-plugin.tomlpython/nemo_relay/_native.pyipython/plugin/src/nemo_relay_plugin/_api.pypython/tests/plugin/test_worker_sdk.pypython/tests/test_codecs.py
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Check / Run
- GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (47)
**/*.toml
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add the SPDX license header to all TOML files using the
#comment form.
Files:
examples/rust-native-plugin/relay-plugin.toml
{crates/core/src/plugin/dynamic/**,crates/plugin/**,crates/worker/**,crates/worker-proto/**,crates/types/**,python/plugin/**,examples/rust-native-plugin/**,examples/python-grpc-worker-plugin/**,docs/build-plugins/**}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Keep the stable boundary explicit: native plugins cross a C ABI, and worker plugins cross
grpc-v1.
Files:
examples/rust-native-plugin/relay-plugin.tomldocs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxcrates/types/src/api/llm.rsdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxpython/plugin/src/nemo_relay_plugin/_api.pydocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxcrates/core/src/plugin/dynamic/native.rscrates/worker/src/lib.rscrates/core/src/plugin/dynamic/worker.rscrates/worker/tests/worker_sdk_tests.rscrates/types/src/codec/request.rs
**/relay-plugin.toml
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
**/relay-plugin.toml: Keeprelay-plugin.tomldynamic records separate from generic runtime components; enabled dynamic records may synthesize internal component specs, and disabled records should remain inspectable but unloaded.
Treat plugin Relay compatibility as normal SemVer; use>=0.5,<1.0in examples unless a plugin intentionally declares a narrower range.
Files:
examples/rust-native-plugin/relay-plugin.toml
{crates/core/src/plugin/dynamic/**,examples/rust-native-plugin/**,examples/python-grpc-worker-plugin/**,docs/build-plugins/**}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Native and worker plugins are trusted extensions; document that native plugins are in-process and unsandboxed, and worker plugins provide process isolation but not a security sandbox.
Files:
examples/rust-native-plugin/relay-plugin.tomldocs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxcrates/core/src/plugin/dynamic/native.rscrates/core/src/plugin/dynamic/worker.rs
{docs/build-plugins/**,examples/rust-native-plugin/**,examples/python-grpc-worker-plugin/**}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
When detailed dynamic plugin guides exist, keep Rust native, Python worker, and
grpc-v1protocol details on separate pages.
Files:
examples/rust-native-plugin/relay-plugin.tomldocs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdx
{docs,examples}/**/*
📄 CodeRabbit inference engine (.agents/skills/rename-surfaces/SKILL.md)
Update docs and examples.
Files:
examples/rust-native-plugin/relay-plugin.tomldocs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxdocs/reference/llm-request-intercept-outcomes.mdxdocs/about-nemo-relay/release-notes/known-issues.mdxdocs/integrate-into-frameworks/provider-codecs.mdx
**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, usemaintain-dynamic-pluginsand include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
examples/rust-native-plugin/relay-plugin.tomldocs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxcrates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rsdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxcrates/core/src/api/llm.rspython/plugin/src/nemo_relay_plugin/_api.pycrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rsdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxpython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/core/src/codec/mod.rsdocs/reference/llm-request-intercept-outcomes.mdxcrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rspython/nemo_relay/_native.pyidocs/about-nemo-relay/release-notes/known-issues.mdxcrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rsdocs/integrate-into-frameworks/provider-codecs.mdxcrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
**/*.mdx
📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)
MDX top-of-file SPDX comments must use {/* ... */} delimiters instead of HTML comment delimiters (Must-Fix)
In MDX files, top-of-file comments must use JSX comment delimiters (
{/*to open and*/}to close); do not use HTML comments for MDX SPDX headers
Files:
docs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxdocs/reference/llm-request-intercept-outcomes.mdxdocs/about-nemo-relay/release-notes/known-issues.mdxdocs/integrate-into-frameworks/provider-codecs.mdx
**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
Update
README.md,fern/, package READMEs, and binding-support notes when public behavior, package names, examples, or supported bindings change.
**/*.{md,mdx}: Prefer the documented public API, not internal shortcuts
Keep package names, repo references, and build commands current
Keep release-process and release-notes guidance in repo-maintainer docs such asRELEASING.md, not as user-facing docs pages orCHANGELOG.md
Keep stable user-facing wrappers atscripts/root in docs and examples; only point at namespaced helper paths when documenting internal maintenance work
When detailed dynamic plugin guides exist, keep Rust native plugin examples, Python worker plugin examples, andgrpc-v1protocol details on separate pagesIf links in documentation change, run
just docs-linkcheck.
Files:
docs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxdocs/reference/llm-request-intercept-outcomes.mdxdocs/about-nemo-relay/release-notes/known-issues.mdxdocs/integrate-into-frameworks/provider-codecs.mdx
**/*.{md,markdown,mdx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add the SPDX license header to all Markdown/MDX documentation files using the HTML comment block form.
Files:
docs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxdocs/reference/llm-request-intercept-outcomes.mdxdocs/about-nemo-relay/release-notes/known-issues.mdxdocs/integrate-into-frameworks/provider-codecs.mdx
docs/**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If documentation examples or commands under
docs/change, run the targeted docs checks appropriate to the change.
Files:
docs/build-plugins/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxdocs/reference/llm-request-intercept-outcomes.mdxdocs/about-nemo-relay/release-notes/known-issues.mdxdocs/integrate-into-frameworks/provider-codecs.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/dynamic-plugins/native-dynamic/about.mdxdocs/build-plugins/dynamic-plugins/about.mdxdocs/build-plugins/dynamic-plugins/grpc-worker/about.mdxdocs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdxdocs/reference/llm-request-intercept-outcomes.mdxdocs/about-nemo-relay/release-notes/known-issues.mdxdocs/integrate-into-frameworks/provider-codecs.mdx
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/core/src/api/llm.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rscrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
**/*.{rs,py}
📄 CodeRabbit inference engine (AGENTS.md)
Follow binding naming conventions in Rust and Python: use
snake_case.
Files:
crates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/core/src/api/llm.rspython/plugin/src/nemo_relay_plugin/_api.pycrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rspython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,py,js,mjs,cjs,ts,tsx}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Files:
crates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/core/src/api/llm.rspython/plugin/src/nemo_relay_plugin/_api.pycrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rspython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
**/*.{rs,py,go,js,ts,c,h}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Use language-appropriate naming conventions: Rust
snake_case, C FFI exports prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/core/src/api/llm.rspython/plugin/src/nemo_relay_plugin/_api.pycrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rspython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
**/*.{rs,go,js,ts}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding
//comment form.
Files:
crates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/core/src/api/llm.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rscrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
{crates/**/src/**/*.rs,python/**/*.py}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Do not add tests under
src; Rust tests belong in cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/types/src/api/llm.rscrates/core/src/api/llm.rspython/plugin/src/nemo_relay_plugin/_api.pycrates/core/src/plugin/dynamic.rscrates/pii-redaction/src/overlay.rspython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/worker/src/lib.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/adaptive/src/acg_profile.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rs
crates/types/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Runtime helpers must cover marks, scopes, continuations, and isolated scope stacks.
Files:
crates/types/src/api/llm.rscrates/types/src/codec/request.rs
**/*.{rs,py,go,js,ts}
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If a language surface changed, always run that language's test target even when Rust core did not change.
Files:
crates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/core/src/api/llm.rspython/plugin/src/nemo_relay_plugin/_api.pycrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rspython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}
📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)
Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.
Files:
crates/types/src/api/llm.rscrates/pii-redaction/tests/coverage/overlay_tests.rscrates/core/src/api/llm.rspython/plugin/src/nemo_relay_plugin/_api.pycrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/pii-redaction/src/overlay.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rspython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/worker/src/lib.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/cli/src/gateway/mod.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/worker/tests/worker_sdk_tests.rscrates/core/src/codec/anthropic.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/types/src/codec/request.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_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/pii-redaction/tests/coverage/overlay_tests.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rspython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.pycrates/adaptive/tests/unit/runtime_tests.rscrates/cli/tests/coverage/shared/gateway_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/python/tests/coverage/py_types_coverage_tests.rscrates/core/tests/unit/observability/openinference_tests.rscrates/worker/tests/worker_sdk_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/tests/unit/codec/anthropic_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/src/api/llm.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rscrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
crates/core/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)
If the change touched
crates/coreor shared runtime semantics, also usevalidate-changefor broader validation
Files:
crates/core/src/api/llm.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rscrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/core/tests/unit/observability/openinference_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
crates/core/src/{api/**/*.rs,api/runtime/**/*.rs,codec/**/*.rs,json.rs}
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Implement the new or changed public runtime behavior first in the Rust core, especially under
crates/core/src/api/and related core modules such ascrates/core/src/api/runtime/,crates/core/src/codec/, andcrates/core/src/json.rs.
Files:
crates/core/src/api/llm.rscrates/core/src/codec/mod.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rs
crates/{core,adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, run the full validation matrix across Rust, Python, Go, and Node.js.
Files:
crates/core/src/api/llm.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rscrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
crates/core/src/api/{tool,llm,shared,scope}.rs
📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)
Wire the new middleware chain into the appropriate lifecycle owner and pipeline stage: tool and LLM execution paths use
tool.rsorllm.rs; shared mark and scope event sanitization usesshared.rsand is called fromscope.rs.
Files:
crates/core/src/api/llm.rs
crates/core/src/api/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)
Preserve the documented pipeline order: conditional guardrails, request intercepts, request sanitization, execution intercepts, and response sanitization for tool and LLM execution; specialized sanitization, event creation, and dispatch for mark and scope events.
Files:
crates/core/src/api/llm.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/api/llm.rscrates/core/tests/unit/dynamic_worker_tests.rscrates/core/src/plugin/dynamic.rscrates/core/tests/unit/plugin_dynamic_tests.rscrates/core/tests/unit/codec/parity_tests.rscrates/core/tests/integration/worker_plugin_tests.rscrates/core/tests/integration/native_plugin_tests.rscrates/core/src/codec/mod.rscrates/core/src/plugin/dynamic/native.rscrates/adaptive/tests/unit/runtime_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/core/src/plugin/dynamic/worker.rscrates/core/src/observability/openinference.rscrates/adaptive/src/acg/ir_builder.rscrates/core/tests/unit/observability/openinference_tests.rscrates/adaptive/src/acg_profile.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rs
**/*.py
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.py: When changing the Python wrapper package, tests, or docs tooling, lint with Ruff (E,F,W,I), format with Ruff formatter (120-character lines, double quotes), and passtytype checking.
Add the SPDX license header to all Python source files using the#comment form.
Files:
python/plugin/src/nemo_relay_plugin/_api.pypython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.py
{crates/core/src/plugin/dynamic/**/*.rs,crates/plugin/**/*.rs,crates/worker/**/*.rs,crates/worker-proto/**/*.rs,python/plugin/**/*.py}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Manifest validation must cover kind, compatibility, load contract, integrity, capability mismatch, and disabled-plugin behavior.
Files:
python/plugin/src/nemo_relay_plugin/_api.pycrates/core/src/plugin/dynamic/native.rscrates/worker/src/lib.rscrates/core/src/plugin/dynamic/worker.rscrates/worker/tests/worker_sdk_tests.rs
{crates/plugin/**/*.rs,python/plugin/**/*.py}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Rust and Python SDKs must expose every supported registration surface.
Files:
python/plugin/src/nemo_relay_plugin/_api.py
**/*.{py,go,js,ts}
📄 CodeRabbit inference engine (.agents/skills/maintain-observability/SKILL.md)
Keep Python, Go, and Node.js config objects and subscriber/exporter methods aligned so all bindings expose the same logical knobs and semantics.
Files:
python/plugin/src/nemo_relay_plugin/_api.pypython/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.py
python/tests/**/*.py
📄 CodeRabbit inference engine (.agents/skills/test-python-binding/SKILL.md)
python/tests/**/*.py: Pytest is used to run tests.
Do not add@pytest.mark.asyncioto any test; async tests are automatically detected and run by the async runner.
Do not add a-> Nonereturn type annotation to test functions.
When mocking a class, do not define a new class; useunittest.mock.MagicMockorunittest.mock.AsyncMock, with thespecconstructor argument when necessary.
Name mocked classes with themockprefix, notfake.
Prefer pytest fixtures over helper methods.
Do not repeat fixtures; if a fixture is needed in multiple test files, place it in aconftest.pyfile.
When creating a fixture, use@pytest.fixture(name="<fixture_name>"[, scope="<scope>"])and define the fixture function asdef <fixture_name>_fixture() -> <return_type>:; only specifyscopewhen it is notfunction.
Preferpytest.mark.parametrizeover creating individual tests for different input types.
Files:
python/tests/test_codecs.pypython/tests/plugin/test_worker_sdk.py
{crates/core/src/plugin/dynamic/**/*.rs,examples/rust-native-plugin/**/*.rs}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Do not pass Rust runtime types, trait objects, futures, or allocator-owned strings across the native dynamic-library boundary.
Files:
crates/core/src/plugin/dynamic/native.rscrates/core/src/plugin/dynamic/worker.rs
crates/core/src/plugin/dynamic/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
The native loader must keep libraries alive until registered callbacks are cleared and must deregister plugin kinds before unload.
Files:
crates/core/src/plugin/dynamic/native.rscrates/core/src/plugin/dynamic/worker.rs
crates/adaptive/**
📄 CodeRabbit inference engine (.agents/skills/maintain-optimizer/SKILL.md)
Keep
crates/adaptivealigned with the canonical adaptive config schema, built-in section helpers, plugin lifecycle, and validation/report behavior.
Files:
crates/adaptive/tests/unit/runtime_tests.rscrates/adaptive/tests/integration/runtime_integration_tests.rscrates/adaptive/tests/unit/acg_profile_tests.rscrates/adaptive/tests/unit/acg/ir_builder_tests.rscrates/adaptive/src/acg/ir_builder.rscrates/adaptive/src/acg_profile.rs
{crates/python/src/py_api/mod.rs,python/nemo_relay/**/*.py,python/nemo_relay/**/*.pyi,go/nemo_relay/**/*.go,crates/node/src/api/**/*.rs}
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Update the language-native bindings for every exposed surface in Python, Go, and Node.js.
Files:
python/nemo_relay/_native.pyi
{python/nemo_relay/**/*.py,python/nemo_relay/**/*.pyi,go/nemo_relay/**/*.go}
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Update language wrapper helpers such as Python wrapper modules, Python type stubs, and Go shorthand packages when the new behavior belongs in those helper layers.
Files:
python/nemo_relay/_native.pyi
python/nemo_relay/**/*
⚙️ CodeRabbit configuration file
python/nemo_relay/**/*: Review Python wrapper changes for typed API consistency, contextvars-based scope isolation, async behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.
Files:
python/nemo_relay/_native.pyi
docs/about-nemo-relay/release-notes/{index,highlights,known-issues}.mdx
📄 CodeRabbit inference engine (.agents/skills/draft-release-notes/SKILL.md)
docs/about-nemo-relay/release-notes/{index,highlights,known-issues}.mdx: Update onlydocs/about-nemo-relay/release-notes/index.mdx,docs/about-nemo-relay/release-notes/highlights.mdx, anddocs/about-nemo-relay/release-notes/known-issues.mdxunless the release changes their route or entry points.
Preserve the existing MDX front matter and the JSX SPDX comment in the release-notes pages.
Files:
docs/about-nemo-relay/release-notes/known-issues.mdx
docs/about-nemo-relay/release-notes/known-issues.mdx
📄 CodeRabbit inference engine (.agents/skills/draft-release-notes/SKILL.md)
docs/about-nemo-relay/release-notes/known-issues.mdx: Inknown-issues.mdx, preserve every prior fixed-item bullet under release-labeled subsections; do not summarize, deduplicate, or omit it.
Inknown-issues.mdx, keep the complete fixed-item history recorded in earlier release-note pages.
Files:
docs/about-nemo-relay/release-notes/known-issues.mdx
{crates/worker-proto/**/*.{rs,proto},crates/worker/**/*.rs}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Keep worker protocol DTOs in
JsonEnvelope; protobuf should own control flow, not duplicated Relay data models.
Files:
crates/worker/src/lib.rscrates/worker/tests/worker_sdk_tests.rs
crates/worker/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Worker activation must cover process launch, token authentication, handshake, validation, declarative registration, proxy rollback, cancellation, and shutdown.
Files:
crates/worker/src/lib.rscrates/worker/tests/worker_sdk_tests.rs
crates/core/src/observability/{atif,otel,openinference}.rs
📄 CodeRabbit inference engine (.agents/skills/maintain-observability/SKILL.md)
When changing the core event model, emitted fields, exporter behavior, subscriber config, or lifecycle, keep the ATIF, OpenTelemetry, and OpenInference implementations in sync.
Files:
crates/core/src/observability/openinference.rs
crates/{python,ffi,node}/**/*
⚙️ CodeRabbit configuration file
crates/{python,ffi,node}/**/*: Treat binding changes as public API changes. Check for parity with the other language bindings, FFI ownership/lifetime safety,
callback error propagation, stable type conversion, and consistent async/stream semantics.
Flag changes that update one binding without corresponding tests or documentation for the same surface elsewhere.
Files:
crates/python/tests/coverage/py_types_coverage_tests.rs
docs/integrate-into-frameworks/**/*.mdx
📄 CodeRabbit inference engine (.agents/skills/contribute-integration/SKILL.md)
Update docs if activation or usage changes.
Files:
docs/integrate-into-frameworks/provider-codecs.mdx
🧠 Learnings (1)
📚 Learning: 2026-07-02T18:33:06.638Z
Learnt from: yczhang-nv
Repo: NVIDIA/NeMo-Relay PR: 355
File: crates/core/tests/unit/codec/parity_tests.rs:500-548
Timestamp: 2026-07-02T18:33:06.638Z
Learning: In Rust codec parity unit tests, when comparing a computed float/cost against a hand-derived literal (typically documented in a nearby comment), use a tolerance-based assertion rather than `assert_eq!` (e.g., `assert!((total - expected).abs() < 1e-9)`) to avoid harmless floating-point/rounding differences. Keep cross-codec parity assertions (e.g., `assert_eq!(chat_cost, anthropic_cost)`) exact with `assert_eq!` when the intention is a strict parity contract across codecs, since they are expected to share the same estimation path and produce bit-identical output across codecs.
Applied to files:
crates/core/tests/unit/codec/parity_tests.rs
🔇 Additional comments (49)
crates/adaptive/src/acg/ir_builder.rs (1)
79-87: LGTM!crates/adaptive/tests/unit/acg_profile_tests.rs (1)
135-189: LGTM!Also applies to: 339-455, 457-498
crates/core/tests/unit/observability/openinference_tests.rs (1)
18-19: LGTM!Also applies to: 101-102, 372-373, 391-402, 4235-4321
crates/core/tests/unit/plugin_dynamic_tests.rs (1)
1841-1852: LGTM!crates/pii-redaction/src/overlay.rs (1)
295-319: LGTM!crates/pii-redaction/tests/coverage/overlay_tests.rs (1)
60-85: LGTM!docs/build-plugins/dynamic-plugins/native-dynamic/rust-native-plugin-example.mdx (1)
32-32: LGTM!Also applies to: 73-73
docs/integrate-into-frameworks/provider-codecs.mdx (1)
55-59: LGTM!Also applies to: 62-86, 451-469
docs/reference/llm-request-intercept-outcomes.mdx (1)
46-62: LGTM!Also applies to: 101-101, 131-145
examples/rust-native-plugin/relay-plugin.toml (1)
11-11: LGTM!python/nemo_relay/_native.pyi (1)
33-33: LGTM!Also applies to: 467-485, 504-511, 544-557
python/tests/test_codecs.py (1)
171-195: LGTM!crates/adaptive/src/acg_profile.rs (1)
90-121: LGTM!Also applies to: 167-223, 270-272
crates/cli/src/gateway/mod.rs (1)
31-31: LGTM!Also applies to: 153-199
crates/core/src/api/llm.rs (1)
39-41: LGTM!crates/core/src/codec/openai_chat.rs (2)
561-609: LGTM!Also applies to: 713-796, 802-948, 949-1254
864-900: 🗄️ Data Integrity & IntegrationNo issue:
MODELED_REQUEST_KEYSalready includes the newly modeled request fields, soextraonly captures unmodeled keys here.> Likely an incorrect or invalid review comment.crates/core/src/plugin/dynamic/worker.rs (1)
56-56: LGTM!Also applies to: 66-66, 76-76, 451-456, 615-620, 1641-1641
crates/core/tests/integration/native_plugin_tests.rs (1)
847-879: LGTM!Also applies to: 1965-2015
crates/worker/src/lib.rs (1)
47-47: LGTM!Also applies to: 1518-1534, 1774-1787, 1817-1830
crates/worker/tests/worker_sdk_tests.rs (1)
22-25: LGTM!Also applies to: 1266-1275, 2339-2376
python/plugin/src/nemo_relay_plugin/_api.py (1)
109-110: LGTM!python/tests/plugin/test_worker_sdk.py (1)
1299-1299: LGTM!crates/adaptive/tests/integration/runtime_integration_tests.rs (1)
81-82: LGTM!Also applies to: 117-193, 528-532
crates/adaptive/tests/unit/acg/ir_builder_tests.rs (1)
15-28: LGTM!Also applies to: 46-61, 121-122, 168-169, 200-300
crates/adaptive/tests/unit/runtime_tests.rs (1)
40-41: LGTM!Also applies to: 75-76, 417-435, 513-514
crates/cli/tests/coverage/shared/gateway_tests.rs (1)
330-370: LGTM!Also applies to: 372-412
crates/core/src/codec/anthropic.rs (2)
132-139: LGTM!Also applies to: 169-179, 520-562, 706-821
823-1041: Both previously-flagged surgical-edit gaps look resolved. The(None, _)tool_choice arm now synthesizes anAutochoice carryingparallel_tool_callsinstead of silently dropping the edit, and thetools/tool_choice/messagespaths now patch against the original JSON (super::patch_changed_json/super::encode_changed_items) instead of fully reconstructing, preserving unknown nested fields and explicit nulls. Note: the shared array-alignment helper these paths delegate to (crates/core/src/codec/mod.rs) has a residual misattribution edge case for insert+delete pairs — see the corresponding comment on that file; it applies here too sincemessages(829-838) andtools(883-898) both usesuper::encode_changed_items.crates/core/src/codec/mod.rs (2)
28-100: LGTM!Also applies to: 102-121, 230-266
213-228: 🎯 Functional CorrectnessNo issue with this
let-chain syntax. The workspace is on Rust 2024 and pinned to toolchain 1.96.1, so this code is valid here.> Likely an incorrect or invalid review comment.crates/core/tests/unit/codec/parity_tests.rs (1)
683-695: LGTM!Also applies to: 729-784
crates/types/src/api/llm.rs (1)
14-18: LGTM!docs/about-nemo-relay/release-notes/known-issues.mdx (1)
84-113: LGTM!Also applies to: 310-313
docs/build-plugins/dynamic-plugins/about.mdx (1)
67-73: LGTM!docs/build-plugins/dynamic-plugins/grpc-worker/about.mdx (1)
67-72: LGTM!docs/build-plugins/dynamic-plugins/native-dynamic/about.mdx (1)
58-62: LGTM!crates/cli/tests/coverage/shared/server_tests.rs (1)
2650-2704: LGTM!crates/core/src/codec/openai_responses.rs (2)
671-796: LGTM! Wrapped-function-tool name edits now correctly patch the nestedfunctionobject (viapatch_responses_tool) instead of flattening into a conflicting top-levelname, resolving the previously flagged issue on this segment.
1130-1201: 🗄️ Data Integrity & IntegrationNo issue:
MODELED_REQUEST_KEYSalready covers every field read indecode(), soextrawon’t duplicate the typed fields.> Likely an incorrect or invalid review comment.crates/core/src/observability/openinference.rs (1)
1096-1131: LGTM! Function and ProviderNative message content are now correctly projected into span attributes, resolving the previously flagged content-loss issue.Also applies to: 1173-1183
crates/core/src/plugin/dynamic/native.rs (1)
260-266: LGTM!Also applies to: 290-400, 1347-1382
crates/core/tests/integration/worker_plugin_tests.rs (1)
938-959: LGTM!Also applies to: 1141-1165
crates/core/tests/unit/codec/anthropic_tests.rs (1)
776-834: LGTM!Also applies to: 894-910
crates/core/tests/unit/codec/openai_chat_tests.rs (1)
1365-1409: LGTM!Also applies to: 1432-1481
crates/core/tests/unit/codec/openai_responses_tests.rs (1)
815-844: LGTM!Also applies to: 871-910
crates/core/tests/unit/dynamic_worker_tests.rs (1)
402-402: LGTM!Also applies to: 418-418
crates/python/tests/coverage/py_types_coverage_tests.rs (1)
1075-1099: LGTM! Fully addresses the previously flagged coverage gap forinstructions/api_specific(round-trip, mutation, clearing, invalid input, and forced-serialization hooks all present).Also applies to: 1143-1152, 1190-1197, 1229-1239, 1248-1278, 1537-1566, 1647-1671
crates/types/src/codec/request.rs (1)
15-19: LGTM! Movinginstructionsout of themessagesarray (and prioritizing it insystem_prompt) is the correct structural fix for the issue#501corruption bug, and the schema bump to@2correctly reflects the new tagged variants.Also applies to: 591-601, 608-620, 626-644
Signed-off-by: Will Killian <wkillian@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/src/codec/mod.rs (1)
166-222: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftSingle-pair fallback still cross-wires unrelated insert/delete items.
The
>1 && >1guard (lines 204-209) only blocks ambiguity when both sides have multiple unmatched items. It does not stop the exact scenario flagged previously:baseline=[A,B,C],edited=[A,C,X](B deleted, C reordered, X inserted) →unmatched_edited=[X],unmatched_baseline=[B]→ theelse if let ([edited_index], [baseline_index]) = ...branch at lines 215-219 unconditionally pairs X with B.patch_changed_json/patch_changed_arraythen grafts B's original-only provider fields (id,cache_control, etc.) onto the unrelated new item X — silent cross-item field leakage, not an error, contradicting the PR's stated guarantee that unsupported/ambiguous edits must "remain intact... or produce an explicit error."This affects every provider codec that reuses
encode_changed_items/encode_changed_items_with_patch(Anthropicmessages/tools, OpenAI Chatmessages/tools, OpenAI Responsesinput/tools), so the fix belongs here once.🐛 Proposed fix: drop the ambiguous 1:1 fallback
- if !structurally_changed && edited.len() == baseline.len() { - for index in unmatched_edited { - alignment[index] = Some(index); - } - } else if let ([edited_index], [baseline_index]) = - (unmatched_edited.as_slice(), unmatched_baseline.as_slice()) - { - alignment[*edited_index] = Some(*baseline_index); - } + if !structurally_changed && edited.len() == baseline.len() { + for index in unmatched_edited { + alignment[index] = Some(index); + } + } + // Do not positionally pair a single unmatched edited item with a single + // unmatched baseline item: without a stable identity/discriminator this + // cannot distinguish "same item edited" from "unrelated insert+delete", + // and mispairing leaks baseline-only provider fields onto the wrong item. + // Leaving it unaligned falls through to `encode(item)` (safe: no reuse, + // no corruption).A regression test mirroring the coderabbitai example (baseline=[A,B,C], edited=[A,C,X]) belongs in
crates/core/tests/unit/codec/parity_tests.rs.🤖 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/codec/mod.rs` around lines 166 - 222, Remove the single-pair fallback in align_changed_items that unconditionally maps one unmatched edited item to one unmatched baseline item. For cases such as a deletion, reorder, and insertion, leave the unmatched entries unaligned so provider-only fields cannot be copied between unrelated items; preserve direct matches and existing safe ambiguity handling. Add a regression test in parity_tests.rs covering baseline [A,B,C] and edited [A,C,X].
🤖 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/src/codec/mod.rs`:
- Around line 166-222: Remove the single-pair fallback in align_changed_items
that unconditionally maps one unmatched edited item to one unmatched baseline
item. For cases such as a deletion, reorder, and insertion, leave the unmatched
entries unaligned so provider-only fields cannot be copied between unrelated
items; preserve direct matches and existing safe ambiguity handling. Add a
regression test in parity_tests.rs covering baseline [A,B,C] and edited [A,C,X].
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 3bb79caf-659c-41b4-bfc6-656cbe14a8e4
📒 Files selected for processing (6)
crates/core/src/codec/anthropic.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/tests/unit/codec/parity_tests.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Check / Run
- GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (15)
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.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/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
crates/core/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)
If the change touched
crates/coreor shared runtime semantics, also usevalidate-changefor broader validation
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
**/*.{rs,py}
📄 CodeRabbit inference engine (AGENTS.md)
Follow binding naming conventions in Rust and Python: use
snake_case.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,py,js,mjs,cjs,ts,tsx}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
**/*.{rs,py,go,js,ts,c,h}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Use language-appropriate naming conventions: Rust
snake_case, C FFI exports prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
**/*.{rs,go,js,ts}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding
//comment form.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, usemaintain-dynamic-pluginsand include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
crates/{core,adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, run the full validation matrix across Rust, Python, Go, and Node.js.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
**/*.{rs,py,go,js,ts}
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If a language surface changed, always run that language's test target even when Rust core did not change.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.rs
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}
📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)
Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.
Files:
crates/core/tests/unit/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.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/codec/parity_tests.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/src/codec/openai_responses.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/codec/parity_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
crates/core/src/{api/**/*.rs,api/runtime/**/*.rs,codec/**/*.rs,json.rs}
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Implement the new or changed public runtime behavior first in the Rust core, especially under
crates/core/src/api/and related core modules such ascrates/core/src/api/runtime/,crates/core/src/codec/, andcrates/core/src/json.rs.
Files:
crates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_responses.rs
{crates/**/src/**/*.rs,python/**/*.py}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Do not add tests under
src; Rust tests belong in cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_responses.rs
🧠 Learnings (1)
📚 Learning: 2026-07-02T18:33:06.638Z
Learnt from: yczhang-nv
Repo: NVIDIA/NeMo-Relay PR: 355
File: crates/core/tests/unit/codec/parity_tests.rs:500-548
Timestamp: 2026-07-02T18:33:06.638Z
Learning: In Rust codec parity unit tests, when comparing a computed float/cost against a hand-derived literal (typically documented in a nearby comment), use a tolerance-based assertion rather than `assert_eq!` (e.g., `assert!((total - expected).abs() < 1e-9)`) to avoid harmless floating-point/rounding differences. Keep cross-codec parity assertions (e.g., `assert_eq!(chat_cost, anthropic_cost)`) exact with `assert_eq!` when the intention is a strict parity contract across codecs, since they are expected to share the same estimation path and produce bit-identical output across codecs.
Applied to files:
crates/core/tests/unit/codec/parity_tests.rs
🔇 Additional comments (6)
crates/core/src/codec/mod.rs (1)
28-100: LGTM!Also applies to: 102-121, 123-164, 224-239, 241-277
crates/core/src/codec/anthropic.rs (1)
706-1041: LGTM!crates/core/src/codec/openai_chat.rs (1)
802-1254: LGTM!crates/core/src/codec/openai_responses.rs (1)
757-791: LGTM!Also applies to: 1077-1383
crates/core/tests/unit/codec/openai_chat_tests.rs (1)
1410-1452: LGTM!crates/core/tests/unit/codec/parity_tests.rs (1)
729-756: LGTM!Also applies to: 758-784, 785-807
P2: malformed modeled structured controls are still forwardedI reproduced this against the current PR head, commit The scalar validation added in the recent commits works, including Chat Cases tested
For all three cases, the diagnostic test confirmed that:
I also exercised the Chat case through the real gateway request-interceptor path. A request containing The focused results were: These passing tests assert the current behavior, so they confirm the gap rather than the desired contract. This conflicts with the PR description's guarantee that malformed recognized structures are rejected before the provider callback. Suggested fix and costThe decode paths currently use direct This should have negligible compute overhead. Relevant decode sites:
|
Signed-off-by: Will Killian <wkillian@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 (2)
crates/core/src/codec/openai_chat.rs (1)
896-953: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
function_callbypasses the new structured-field validation.Every other newly-added field here uses
super::optional_object(...), butfunction_call: obj.get("function_call").cloned()(Line 935) reads the raw value with no type check at all. Since the deprecated OpenAIfunction_callcontrol accepts"none"/"auto"(string) or{"name": ...}(object),optional_objectcan't be reused directly — but that's not a reason to skip validation entirely. A malformedfunction_call(e.g. a number or array) will decode successfully, get embedded inapi_specific, and be forwarded to the provider unchanged on encode — exactly the "malformed recognized structures forwarded unchanged" bug this PR's fix commit targets. The malformed-field test matrix atopenai_chat_tests.rsL1497-1511 confirms this gap: every other structured field is covered exceptfunction_call.🛡️ Proposed fix to validate function_call's union type
+ let function_call = match obj.get("function_call") { + Some(Json::Null) | None => None, + Some(value @ (Json::String(_) | Json::Object(_))) => Some(value.clone()), + Some(_) => { + return Err(FlowError::InvalidArgument( + "OpenAI Chat function_call must be a string, object, or null".into(), + )); + } + }; let metadata = super::optional_object(obj, "metadata", "OpenAI Chat")?;api_specific: Some(ApiSpecificRequest::OpenAIChat { audio, frequency_penalty, - function_call: obj.get("function_call").cloned(), + function_call, functions,🤖 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/codec/openai_chat.rs` around lines 896 - 953, Validate the `function_call` field in the request-decoding path before constructing `ApiSpecificRequest::OpenAIChat`: allow only the supported string values (`"none"` or `"auto"`) or the expected object form, while rejecting numbers, arrays, and other malformed values. Replace the raw `obj.get("function_call").cloned()` handling with this union-type validation and preserve the validated value for encoding.crates/core/src/codec/openai_responses.rs (1)
1157-1205: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
conversationhas the same unvalidated union-type gap asfunction_call.
conversation: obj.get("conversation").cloned()(Line 1196) is newly touched in this hunk but skips validation entirely, unlike the surroundingreasoning/include/metadata/etc. fields that now useoptional_object/optional_array. OpenAI Responsesconversationaccepts either a string ID or an object; a malformed value (number, array, bool) will decode without error and be forwarded to the provider unchanged on encode, which is the exact bug class this PR's fix commit is meant to close. The malformed-field matrix atopenai_responses_tests.rsL887-900 confirmsconversationisn't covered.🛡️ Proposed fix to validate conversation's union type
+ let conversation = match obj.get("conversation") { + Some(Json::Null) | None => None, + Some(value @ (Json::String(_) | Json::Object(_))) => Some(value.clone()), + Some(_) => { + return Err(FlowError::InvalidArgument( + "OpenAI Responses conversation must be a string, object, or null".into(), + )); + } + }; let text = super::optional_object(obj, "text", "OpenAI Responses")?;api_specific: Some(ApiSpecificRequest::OpenAIResponses { background, context_management, - conversation: obj.get("conversation").cloned(), + conversation, moderation,🤖 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/codec/openai_responses.rs` around lines 1157 - 1205, Validate the OpenAI Responses `conversation` field before constructing `ApiSpecificRequest::OpenAIResponses`, accepting only its supported string-ID or object forms and rejecting numbers, arrays, booleans, and other invalid values. Replace the direct `obj.get("conversation").cloned()` assignment in the request decoder with the appropriate validated parsing flow, and add `conversation` to the malformed-field coverage in `openai_responses_tests.rs`.
🤖 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/src/codec/openai_chat.rs`:
- Around line 896-953: Validate the `function_call` field in the
request-decoding path before constructing `ApiSpecificRequest::OpenAIChat`:
allow only the supported string values (`"none"` or `"auto"`) or the expected
object form, while rejecting numbers, arrays, and other malformed values.
Replace the raw `obj.get("function_call").cloned()` handling with this
union-type validation and preserve the validated value for encoding.
In `@crates/core/src/codec/openai_responses.rs`:
- Around line 1157-1205: Validate the OpenAI Responses `conversation` field
before constructing `ApiSpecificRequest::OpenAIResponses`, accepting only its
supported string-ID or object forms and rejecting numbers, arrays, booleans, and
other invalid values. Replace the direct `obj.get("conversation").cloned()`
assignment in the request decoder with the appropriate validated parsing flow,
and add `conversation` to the malformed-field coverage in
`openai_responses_tests.rs`.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 63505c70-55c0-4ef5-b52b-83324153e67b
📒 Files selected for processing (8)
crates/cli/tests/coverage/shared/server_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/mod.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rscrates/core/tests/unit/codec/openai_responses_tests.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Check / Run
- GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (15)
**/*.rs
📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)
**/*.rs: Any Rust change must runjust test-rust
Any Rust change must runcargo fmt --all
Any Rust change must runcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allfor all FFI work since it is Rust work
Runjust test-rustto validate FFI changes
Runcargo clippy --workspace --all-targets -- -D warningsto enforce strict linting on FFI workWhen Rust files changed as part of Go work, also run
cargo fmt --all,just test-rust, andcargo clippy --workspace --all-targets -- -D warnings
**/*.rs: Runcargo fmt --allwhen Rust files are changed as part of Node work
Runcargo clippy --workspace --all-targets -- -D warningswhen Rust files are changed as part of Node work
Runjust test-rustwhen Rust files are changed as part of Node workWhen changing the core Rust runtime or Rust-facing API surface, format Rust code with
cargo fmt(rustfmt defaults), keepcargo clippy -- -D warningsclean, and satisfycargo deny checkperdeny.toml.
**/*.rs: If any Rust code changed, always runjust test-rust.
If any Rust code changed, also runcargo fmt --all.
If any Rust code changed, also runcargo clippy --workspace --all-targets -- -D warnings.
For Rust changes headed for review, runcargo fmt --allandcargo clippy --workspace --all-targets -- -D warningseven if relying on pre-commit.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_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/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
crates/core/**/*.rs
📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)
If the change touched
crates/coreor shared runtime semantics, also usevalidate-changefor broader validation
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
**/*.{rs,py}
📄 CodeRabbit inference engine (AGENTS.md)
Follow binding naming conventions in Rust and Python: use
snake_case.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{rs,py,js,mjs,cjs,ts,tsx}: UseJson = serde_json::Valuein Rust-facing runtime APIs where the existing code expects JSON payloads.
UseResult<T>withFlowErrorin core runtime paths, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
**/*.{rs,py,go,js,ts,c,h}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Use language-appropriate naming conventions: Rust
snake_case, C FFI exports prefixednemo_relay_, GoPascalCase, Node.jscamelCase, and Pythonsnake_case.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
**/*.{rs,go,js,ts}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding
//comment form.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
crates/core/src/{api/**/*.rs,api/runtime/**/*.rs,codec/**/*.rs,json.rs}
📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)
Implement the new or changed public runtime behavior first in the Rust core, especially under
crates/core/src/api/and related core modules such ascrates/core/src/api/runtime/,crates/core/src/codec/, andcrates/core/src/json.rs.
Files:
crates/core/src/codec/mod.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rs
{crates/**/src/**/*.rs,python/**/*.py}
📄 CodeRabbit inference engine (.agents/skills/maintain-dynamic-plugins/SKILL.md)
Do not add tests under
src; Rust tests belong in cratetests/trees, and Python SDK tests belong underpython/tests.
Files:
crates/core/src/codec/mod.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rs
**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
**/*: Format changed files with the language-native formatter before the final lint/test pass.
If dynamic plugin behavior changed, usemaintain-dynamic-pluginsand include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, preferuv run pre-commit run --files <changed files...>.
Before review or handoff, runuv run pre-commit run --all-files.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
crates/{core,adaptive}/**/*
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If
crates/coreorcrates/adaptivechanged, run the full validation matrix across Rust, Python, Go, and Node.js.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
**/*.{rs,py,go,js,ts}
📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)
If a language surface changed, always run that language's test target even when Rust core did not change.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}
📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)
Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.
Files:
crates/core/src/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_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/codec/mod.rscrates/core/tests/unit/codec/openai_responses_tests.rscrates/core/src/codec/anthropic.rscrates/core/src/codec/openai_chat.rscrates/core/src/codec/openai_responses.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_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/codec/openai_responses_tests.rscrates/cli/tests/coverage/shared/server_tests.rscrates/core/tests/unit/codec/anthropic_tests.rscrates/core/tests/unit/codec/openai_chat_tests.rs
🔇 Additional comments (6)
crates/cli/tests/coverage/shared/server_tests.rs (1)
2650-2676: LGTM!crates/core/src/codec/mod.rs (1)
102-128: LGTM!crates/core/tests/unit/codec/anthropic_tests.rs (1)
802-823: LGTM!crates/core/tests/unit/codec/openai_chat_tests.rs (1)
1497-1520: LGTM!crates/core/tests/unit/codec/openai_responses_tests.rs (1)
887-909: LGTM!crates/core/src/codec/anthropic.rs (1)
785-822: 🗄️ Data Integrity & Integration
metadatais already modeled and excluded fromextra. It’s listed inMODELED_REQUEST_KEYS, so it won’t leak intoextrahere.> Likely an incorrect or invalid review comment.
|
/merge |
Overview
Warning
BREAKING CHANGE: [annotated request schema and plugin compatibility]
AnnotatedLlmRequestadds public fields and message, content, tool, and tool-choice variants. Rust exhaustive matches and direct struct literals must be updated. Request annotations and request-intercept outcomes now use the@2schema tags. Rust native plugins and Rustgrpc-v1workers that consume annotations must rebuild against NeMo Relay 0.6; Python workers must update to the 0.6 worker SDK. Dynamic plugins that register LLM request intercepts must declarecompat.relay = ">=0.6,<1.0"; the host rejects ranges that still admit Relay 0.5. Node.js, Go, and raw C FFI callback boundaries remain JSON-based and do not require new binding DTOs.Fix Issue 501 by making request-codec annotations lossless across Anthropic Messages, OpenAI Responses, and OpenAI Chat Completions, and by enabling those request codecs in the
nemo-relaygateway.Details
AnnotatedLlmRequestwith shared provider instructions, a tagged mutableapi_specificsurface, portable message/content/tool unions, component extras, and explicit provider-native fallbacks.encode(decode(original), original)calls by comparing edits with a decoded baseline and patching only changed fields. Unknown fields, nulls, alternate representations, item order, and untouched native values remain unchanged.stream_options.include_usageinjection./v1/messages,/v1/chat/completions, and/v1/responsesgateway calls. Count-token, model, probe, and non-LLM passthrough routes remain unannotated.@2, require the 0.6 SDK for Python workers, and enforce a Relay 0.6 compatibility floor for dynamic plugins that register request intercepts. Node, FFI, and Go callback boundaries continue carrying annotations as JSON.annotated_request; changing rawrequest.contentwhile a request codec is active remains an explicit runtime error.Validation:
just test-rustjust test-python(536 passed)just test-node(277 passed)just test-gojust test-python-pluginjust test-claude-plugin-e2ejust test-codex-plugin-e2ejust docsuv run pre-commit run --all-filesWhere should the reviewer start?
Start with
crates/types/src/codec/request.rsfor the public annotation contract, then review the baseline-diff helper and provider codecs undercrates/core/src/codec/. The gateway wiring and buffered/streaming matrix are incrates/cli/src/gateway/mod.rsandcrates/cli/tests/coverage/shared/server_tests.rs.Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)
Summary by CodeRabbit
instructionsandapi_specificthrough Python request objects.Summary by CodeRabbit
New Features
instructions,api_specific, developer/function/tool/provider-native variants, and richer tool schemas.instructionsandapi_specific; enhanced OpenInference message-role projection.Bug Fixes
Documentation
Tests