Skip to content

feat(codec): add Gemini generateContent codec - #723

Open
sbulusu31 wants to merge 10 commits into
NVIDIA:mainfrom
sbulusu31:feat/gemini-codec
Open

feat(codec): add Gemini generateContent codec#723
sbulusu31 wants to merge 10 commits into
NVIDIA:mainfrom
sbulusu31:feat/gemini-codec

Conversation

@sbulusu31

@sbulusu31 sbulusu31 commented Aug 5, 2026

Copy link
Copy Markdown

Overview

Adds a built-in Gemini generateContent codec to NeMo Relay, covering request normalization, response normalization, streaming decode/replay, PII redaction overlays, response-cache integration, bindings, and docs.

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

Details

  • Adds GeminiGenerateContentCodec request decode/encode support for the Gemini generateContent API, including system instructions, contents, generation config, tools, function calls, function responses, usage, finish reasons, and provider-specific fields.
  • Adds Gemini generateContent response and streaming decode support, including response IDs, model versions, usage metadata, thought-token accounting, candidate metadata, thought signatures, and tool calls.
  • Wires the gemini_generate_content built-in codec ID across Rust runtime, FFI, Python, Node.js, Go, worker, plugin, PII redaction, adaptive response-cache, and NeMo Guardrails surfaces.
  • Accepts gemini as a compatibility alias at codec-ID parsing/config boundaries while keeping gemini_generate_content as the canonical codec spelling.
  • Adds Gemini generateContent PII overlay support while preserving provider metadata and fail-closed behavior for ambiguous multi-candidate responses.
  • Updates documentation and type surfaces so Gemini generateContent is listed with the other built-in provider codecs.
  • Keeps Gemini ACG request editing intentionally disabled; this PR covers Gemini generateContent response-cache keying/replay and sanitizer paths.

Validation:

  • cargo test -p nemo-relay -- codec::gemini_generate_content (148 passed)
  • cargo test -p nemo-relay -- codec::resolve (41 passed)
  • cargo test -p nemo-relay-pii-redaction -- --test-threads=1 (122 passed)
  • cargo test -p nemo-relay-adaptive response_cache (50 passed)
  • cargo test -p nemo-relay-ffi -- test_annotated_event_accessors_and_codec_handles (unit + integration targets passed)
  • just build-python
  • uv run pytest python/tests/test_builtin_codecs.py (31 passed)
  • just test-go
  • cargo clippy --workspace --all-targets -- -D warnings
  • Rust formatting check over changed Rust files
  • git diff --check upstream/main...HEAD
  • node --check crates/node/tests/types_tests.mjs
  • Old-name residue check for removed GeminiCodec / ProviderSurface::Gemini / BuiltinLlmCodec::Gemini style symbols
  • Node package tests were not run locally because this machine has Node v22.22.2 and nemo-relay-node requires Node >=24; PR CI should cover the Node 24 path.
  • Prior review-loop validation also included live Gemini smoke coverage before the final squash/upstream-sync rewrite: decode -> encode -> provider generateContent call -> decode_response.

Where should the reviewer start?

Start with crates/core/src/codec/gemini_generate_content.rs for the codec implementation and crates/core/tests/unit/codec/gemini_generate_content_tests.rs for the behavioral contract. Then review crates/pii-redaction/src/overlay.rs and the adaptive response-cache changes for integration behavior.

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

  • Relates to: none

Summary by CodeRabbit

  • New Features
    • Added support for Google Gemini generateContent requests and responses, including streaming, tool calls, usage, safety metadata, and provider-specific fields.
    • Added Gemini codecs across Python, Node.js, Go, C, NeMo Guardrails, and PII redaction integrations.
    • Added Gemini support to codec configuration, validation, and type definitions.
  • Bug Fixes
    • Improved Gemini response caching and replay, including safer handling of unsupported fields.
    • Safely handles unsupported provider surfaces and multi-candidate responses.
  • Documentation
    • Updated codec, integration, and configuration documentation with Gemini support.

Add Gemini generateContent request, response, and streaming codecs across the runtime and language bindings.

Wire Gemini into built-in codec resolution, PII redaction overlays, adaptive response cache paths, NeMo Guardrails codec configuration, FFI, Python, Node.js, Go, and docs.

Add focused Gemini codec, PII, adaptive cache, binding, and documentation coverage.

Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>
@sbulusu31
sbulusu31 requested review from a team as code owners August 5, 2026 23:16
@copy-pr-bot

copy-pr-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added size:XXL PR is very large Feature a new feature lang:go PR changes/introduces Go code lang:js PR changes/introduces Javascript/Typescript code lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code labels Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Gemini generateContent support now spans the built-in codec, provider detection, streaming, response caching, PII redaction, NeMo Guardrails, FFI, Node.js, Python, Go, tests, and documentation.

Changes

Gemini codec integration

Layer / File(s) Summary
Provider contracts and resolution
crates/types/..., crates/core/src/codec/..., crates/adaptive/..., crates/plugin/..., crates/worker/...
Registers Gemini provider surfaces, codec identities, response metadata, canonical names, detection rules, and unsupported-surface handling.
Gemini codec and streaming behavior
crates/core/src/codec/gemini_generate_content.rs
Adds Gemini request and response normalization, encoding, validation, metadata preservation, tool handling, and streaming aggregation.
Gemini codec validation and regression coverage
crates/core/tests/unit/codec/gemini_generate_content_tests.rs, crates/core/tests/unit/codec/response_tests.rs, crates/core/tests/unit/codec/parity_tests.rs
Adds coverage for decoding, encoding, streaming, tool calls, provider-native parts, metadata preservation, malformed payloads, and unsupported normalized fields.
Response-cache keying and replay
crates/adaptive/src/response_cache/*, crates/adaptive/tests/unit/response_cache/*
Treats supported Gemini request decoding as non-lossy for cache keys, rejects lossy fallback cases, and replays valid aggregates as single native Gemini events.
PII redaction and response overlay
crates/pii-redaction/src/*, crates/pii-redaction/tests/*
Adds Gemini codec selection, candidate targeting, sanitized response overlays, native metadata preservation, function-call handling, and fail-closed multi-candidate behavior.
NeMo Guardrails integration
crates/core/src/plugins/nemo_guardrails/*, crates/core/tests/unit/plugins/nemo_guardrails/*
Adds Gemini to local codec configuration and maps Gemini streaming parts to visible text while excluding thought parts and empty fragments.
FFI, Node.js, Python, and Go bindings
crates/ffi/..., crates/node/..., crates/python/..., go/..., python/...
Exposes Gemini codec construction, request encoding and decoding, response decoding, codec identities, type declarations, and binding tests.
Documentation and support metadata
docs/..., crates/pii-redaction/README.md, crates/core/tests/fixtures/native_plugin/.gitignore
Documents Gemini codec identifiers, provider schemas, response usage, plugin support, framework integration, and fixture metadata.

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

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title follows Conventional Commits format, uses an allowed type and lowercase scope, states the change clearly, and is under 72 characters.
Description check ✅ Passed The description includes all required sections, checklist confirmations, implementation details, reviewer guidance, related-issue information, and validation results.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 19

🤖 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/adaptive/src/acg/request_surfaces/mod.rs`:
- Around line 46-51: Update from_provider_surface to match
ProviderSurface::Gemini explicitly alongside the other unsupported surfaces,
removing the wildcard so new ProviderSurface variants trigger exhaustiveness
errors. Also revise the error path around the request-shape resolution message
to distinguish Gemini’s successfully resolved shape from the absence of an ACG
applier, producing accurate diagnostics for Gemini requests.

In `@crates/adaptive/src/response_cache/key.rs`:
- Line 340: Update the ProviderSurface::Gemini handling in lossy_request_shape
to detect unmodeled generationConfig fields, non-text or otherwise non-lossless
systemInstruction.parts, and extra function-call-part fields; return true to
force raw-body cache keys whenever these shapes cannot round-trip through
GeminiCodec::decode, while preserving normalized keying only for lossless
requests.

In `@crates/adaptive/tests/unit/response_cache/replay_tests.rs`:
- Around line 81-107: Update gemini_replay_uses_a_valid_native_stream_event to
include a single candidate containing functionCall, thoughtSignature, and
candidate metadata, then retain the exact aggregate round-trip and non-lossy
assertions. Add a separate recognized lossy replay case with multiple candidates
or a nonzero candidate index, asserting replay_is_lossy rejects it because
GeminiStreamingState only preserves candidate index 0; keep functionResponse
outside response candidates.

In `@crates/core/src/codec/gemini.rs`:
- Around line 361-366: Update gemini_function_response_to_message_content to
retrieve response without unwrap and return an appropriate error when the field
is missing; preserve the existing JSON serialization and text fallback behavior
when response is present.
- Around line 2731-2803: The observe/finalize streaming flow incorrectly assumes
every Gemini chunk belongs to candidate index 0, causing different candidates to
be merged and others discarded. Update the state around observe to track the
candidate.index and either preserve separate per-index candidate state through
finalize or reject the stream with an InvalidArgument error when the index is
missing, nonzero, or changes; ensure emitted responses retain the validated
candidate index instead of always using 0.

In `@crates/core/src/plugins/nemo_guardrails/python.rs`:
- Around line 1353-1372: Update the Gemini streaming handling around
LocalGuardrailsCodec::Gemini to explicitly define the multi-candidate contract:
either document and test that only candidates.first() is processed and the
emitted result uses index 0, or retain candidates by their response index and
define how Guardrails processes them. Ensure the implementation, finalization
behavior, and tests consistently enforce the selected contract.

In `@crates/core/tests/unit/plugins/nemo_guardrails/component_tests.rs`:
- Around line 402-407: Extend the remote-mode tests in the relevant component
test to include a configuration using codec "gemini", and assert the existing
openai_chat-only diagnostic for that configuration. Keep the new codec covered
as local-only while preserving the current openai_responses and
anthropic_messages cases.
- Around line 647-652: Strengthen the assertion for the bad_codec diagnostic by
requiring its message to contain the expected supported codec names, including
gemini, rather than only the generic “codec must be one of:” prefix. Update the
predicate in the diagnostic iteration while preserving the existing assertion
structure.

In `@crates/pii-redaction/src/builtin.rs`:
- Around line 475-486: Replace the duplicated
targets_normalized_gemini_candidate and targets_normalized_openai_chat_choice
predicates with one shared targets_normalized_single_candidate_field method
containing the existing normalized field-name checks, then update both guard
call sites to invoke it. Preserve the current fail-closed matching behavior.

In `@crates/pii-redaction/src/component.rs`:
- Around line 503-508: Update the codec schema definition near the listed codec
names to pass a reference to supported_codec_names() into string_enum_schema,
ensuring the schema uses the shared codec registry source of truth. Leave the
editor_config! codec values as literal static metadata.

In `@crates/pii-redaction/src/overlay.rs`:
- Around line 157-174: Update the function-call overlay logic in the
parts.retain_mut closure to preserve an absent original functionCall.id: only
call set_optional_string_field for "id" when fc already contains that field,
while continuing to update "name" and "args" from the sanitized call.
- Around line 118-153: Update the overlay logic in the non-thought text-part
loop to preserve newlines: assign the complete message_text to the first
non-thought text part, then remove all subsequent non-thought text parts from
parts instead of splitting on newline or assigning partial chunks. Keep thought
parts and unrelated parts unchanged.

In `@crates/pii-redaction/tests/coverage/overlay_tests.rs`:
- Around line 136-314: Extend the Gemini overlay tests around
overlay_gemini_response to cover multi-text-part splitting with a newline,
removal of responseId/modelVersion when annotated id and model are absent,
deletion of surplus raw functionCall parts when sanitized tool calls are fewer,
and preservation of thought parts unchanged. Add focused cases using
BuiltinCodecName::Gemini.overlay_response_payload and assert each resulting
payload branch explicitly.

In `@crates/pii-redaction/tests/unit/component_tests.rs`:
- Around line 5463-5535: The existing multi-candidate Gemini test only verifies
fail-closed behavior for normalized targeting; add a complementary test using a
raw target path such as /candidates/1/content/parts/0/text. Configure the
builtin redactor with that path, execute a multi-candidate response, and assert
the selected secret is redacted in the returned payload and captured event while
preserving the other candidate content, proving the guard is limited to
targets_normalized_gemini_candidate().

In `@crates/types/src/codec/response.rs`:
- Around line 334-353: Update the Gemini variant’s extra-field population to
reject or remove the reserved "api" key before serialization, preventing it from
colliding with the enum discriminator while preserving other fields. Add
round-trip tests covering empty extra data, non-empty extra data, and an extra
map containing "api".

In `@crates/worker/src/lib.rs`:
- Around line 2681-2704: Move
test_gemini_codec_identity_decoded_as_builtin_not_opaque out of the inline
#[cfg(test)] mod tests in lib.rs into
crates/worker/tests/unit/codec_identity_tests.rs. Add a #[path] module
declaration in lib.rs following the crates/core/src/codec/gemini.rs pattern so
the relocated test can still access private codec_identity_from_proto and
related symbols; remove the inline test body.

In `@docs/about-nemo-relay/concepts/codecs.mdx`:
- Around line 123-125: Update the provider-surface list sentence to format only
the Gemini method name as inline code, changing the plain-text generateContent
reference to Gemini `generateContent` while preserving the surrounding provider
names and wording.

In `@docs/integrate-into-frameworks/provider-codecs.mdx`:
- Line 94: Format generateContent as inline code in all four provider
references: update docs/integrate-into-frameworks/provider-codecs.mdx lines
94-94, docs/about-nemo-relay/concepts/codecs.mdx lines 123-125,
docs/integrate-into-frameworks/provider-response-codecs.mdx lines 445-448, and
docs/integrate-into-frameworks/using-codecs.mdx lines 41-41, without changing
the surrounding descriptions.

In `@docs/integrate-into-frameworks/provider-response-codecs.mdx`:
- Around line 364-372: Update the provider response codec table formatting:
rename the “Normalized field” header to “Normalized Field” and format the Gemini
generateContent identifier as inline code wherever it appears in the codec list.
Leave the already correctly formatted Gemini usage field names unchanged.
🪄 Autofix

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: 0a570dae-3799-465e-b93c-a954693f1cf8

📥 Commits

Reviewing files that changed from the base of the PR and between faf6e2c and 2c7dda6.

📒 Files selected for processing (54)
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/src/response_cache/replay.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/core/src/api/runtime/callbacks.rs
  • crates/core/src/codec/gemini.rs
  • crates/core/src/codec/mod.rs
  • crates/core/src/codec/resolve.rs
  • crates/core/src/plugins/nemo_guardrails/component.rs
  • crates/core/src/plugins/nemo_guardrails/python.rs
  • crates/core/tests/fixtures/native_plugin/.gitignore
  • crates/core/tests/unit/codec/gemini_tests.rs
  • crates/core/tests/unit/codec/parity_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/core/tests/unit/plugins/nemo_guardrails/component_tests.rs
  • crates/core/tests/unit/plugins/nemo_guardrails/local_python_tests.rs
  • crates/ffi/nemo_relay.h
  • crates/ffi/src/api/llm.rs
  • crates/ffi/tests/unit/types_tests.rs
  • crates/node/pii_redaction.d.ts
  • crates/node/plugin.d.ts
  • crates/node/src/types/mod.rs
  • crates/node/tests/types_tests.mjs
  • crates/pii-redaction/README.md
  • crates/pii-redaction/src/builtin.rs
  • crates/pii-redaction/src/component.rs
  • crates/pii-redaction/src/overlay.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/plugin/src/lib.rs
  • crates/python/src/py_api/mod.rs
  • crates/python/src/py_types/codecs.rs
  • crates/python/src/py_types/mod.rs
  • crates/types/src/codec/response.rs
  • crates/worker/src/lib.rs
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/about-nemo-relay/concepts/middleware.mdx
  • docs/build-plugins/dynamic-plugins/native-dynamic/about.mdx
  • docs/configure-plugins/nemo-guardrails/configuration.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/using-codecs.mdx
  • go/nemo_relay/callbacks_test.go
  • go/nemo_relay/coverage_gap_test.go
  • go/nemo_relay/nemo_relay.go
  • python/nemo_relay/_native.pyi
  • python/nemo_relay/codecs.py
  • python/nemo_relay/codecs.pyi
  • python/nemo_relay/pii_redaction.py
  • python/nemo_relay/pii_redaction.pyi
  • python/tests/plugin/test_worker_sdk.py
  • python/tests/test_builtin_codecs.py

Comment thread crates/adaptive/src/acg/request_surfaces/mod.rs Outdated
Comment thread crates/adaptive/src/response_cache/key.rs Outdated
Comment thread crates/adaptive/tests/unit/response_cache/replay_tests.rs
Comment thread crates/core/src/codec/gemini_generate_content.rs
Comment thread crates/core/src/codec/gemini_generate_content.rs
Comment thread crates/types/src/codec/response.rs
Comment thread crates/worker/src/lib.rs Outdated
Comment thread docs/about-nemo-relay/concepts/codecs.mdx
Comment thread docs/integrate-into-frameworks/provider-codecs.mdx Outdated
Comment thread docs/integrate-into-frameworks/provider-response-codecs.mdx Outdated

@willkill07 willkill07 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Before I do a comprehensive deep dive, I am requesting naming changes.

Gemini offers two APIs: generateContent and interaction.

For the sake of future compatibility, I think all instances must be clarified as GeminiGenerateContent to be explicit and reduce a breaking rename in the future. This suggestion also aligns with the existing naming of OpenAIResponses, OpenAIChat, and AnthropicMessages

Additionally:

  • ProviderSurface: Gemini --> GeminiGenerateContent
  • BuiltinLlmCodec: Gemini --> GeminiGenerateContent

I may have missed a few places, but that's definitely gating a comprehensive review.

The initial first pass is really great though! I'm looking forward to this being merged in :)

Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>

Copy link
Copy Markdown
Author

Addressed the requested naming change in d9faaaf.

  • Renamed the public codec/API surface to GeminiGenerateContent* (GeminiGenerateContentCodec, ProviderSurface::GeminiGenerateContent, BuiltinLlmCodec::GeminiGenerateContent, etc.).
  • Renamed the built-in codec ID to gemini_generate_content across Rust, Python, Node.js, Go, FFI, worker/plugin, PII redaction, NeMo Guardrails, adaptive cache/replay, and docs.
  • Renamed the core implementation/test files to gemini_generate_content.rs and gemini_generate_content_tests.rs.
  • Preserved provider/model/native-provider strings as gemini where they refer to the Google Gemini provider family rather than the NeMo Relay codec surface.

Validation after the rename: cargo test -p nemo-relay -- codec::gemini_generate_content (148 passed), cargo test -p nemo-relay -- codec::resolve (40 passed), PII (115 passed), adaptive response_cache (49 passed), FFI codec handle test, just build-python, Python built-in codec tests (31 passed), just test-go, and cargo clippy --workspace --all-targets -- -D warnings.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (3)
crates/adaptive/tests/unit/response_cache/key_tests.rs (1)

603-608: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Exercise cache-key behavior, not only codec resolution.

The test calls resolved_body and checks effective_codec, but it does not execute lossy_request_shape or key_of. It cannot detect a regression where an unmodeled Gemini field is dropped and two distinct requests receive the same cache key.

Add a request pair that differs in one unmodeled Gemini field. Assert raw-body fallback or distinct keys, while keeping this lossless case.

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

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

In `@crates/adaptive/tests/unit/response_cache/key_tests.rs` around lines 603 -
608, Extend the Gemini test around resolved_body with two requests that differ
only in an unmodeled Gemini field, then run them through lossy_request_shape and
key_of to verify raw-body fallback or distinct cache keys. Keep the existing
lossless normalized-body and effective_codec assertions unchanged.

Source: Path instructions

crates/adaptive/src/response_cache/replay.rs (1)

82-86: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Add a Gemini replay round-trip test.

The new branch emits one GenerateContentResponse as the replay sequence. The existing replay test covers Anthropic, OpenAI Chat, and OpenAI Responses only. Add a separate Gemini case with candidates, usage metadata, finish reasons, and tool-call parts. Assert that collection and finalization reproduce the stored aggregate. Do not add Gemini to the existing chunks.len() > 1 assertion.

🤖 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/adaptive/src/response_cache/replay.rs` around lines 82 - 86, Add a
separate Gemini replay round-trip test covering
ProviderSurface::GeminiGenerateContent, including candidates, usage metadata,
finish reasons, and tool-call parts; assert collection and finalization
reproduce the stored aggregate. Keep Gemini out of the existing multi-chunk
chunks.len() > 1 assertion and follow the existing replay test patterns.
crates/node/tests/types_tests.mjs (1)

91-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add error-path coverage for GeminiGenerateContentCodec.

The new wrapper converts malformed requests, annotated requests, responses, and codec failures into N-API errors in crates/node/src/types/mod.rs Lines 507-541. The added tests cover successful payloads only. Add assertions that invalid decode, encode, and decodeResponse calls throw.

As per path instructions, tests for binding changes must cover the changed API's error paths.

🤖 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/node/tests/types_tests.mjs` around lines 91 - 182, Extend the
GeminiGenerateContentCodec tests to cover error paths for decode, encode, and
decodeResponse. Add malformed request, annotated request, response, and
codec-failure inputs that cause each method to throw through the N-API wrapper,
and assert the calls throw while preserving the existing successful-payload
coverage.

Source: Path instructions

♻️ Duplicate comments (6)
crates/pii-redaction/src/builtin.rs (1)

476-488: 📐 Maintainability & Code Quality | 🟠 Major

Collapse the duplicated normalized-target predicate.

targets_normalized_gemini_candidate duplicates targets_normalized_openai_chat_choice. Both predicates feed fail-closed response guards. If one list changes, the two providers can enforce different redaction guarantees.

Use one shared predicate and call it from both guard branches.

🤖 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/pii-redaction/src/builtin.rs` around lines 476 - 488, Replace the
duplicated logic in targets_normalized_gemini_candidate and
targets_normalized_openai_chat_choice with one shared normalized-target
predicate, then invoke that predicate from both response guard branches.
Preserve the existing fail-closed behavior and the current recognized target
segments.
crates/pii-redaction/src/overlay.rs (2)

118-154: 🎯 Functional Correctness | 🟠 Major

Preserve multiline text parts during fallback overlay.

annotated_message_text joins visible text parts with "\n" at Line 468. Splitting that value again in Lines 118-154 cannot distinguish an embedded newline from a part boundary.

For raw parts containing "a\nb" and "c", reconstruction can assign the wrong text and drop "c". Store the complete sanitized text in the first non-thought text part. Remove only later non-thought text parts. Preserve thought and provider-native parts.

This repeats the previously identified overlay defect; confirm the current implementation still has this path.

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

In `@crates/pii-redaction/src/overlay.rs` around lines 118 - 154, The fallback
overlay logic in the loop over parts incorrectly splits annotated_message_text
on newlines and can lose multiline content. Preserve the complete sanitized
message_text in the first non-thought text part, remove subsequent non-thought
text parts, and leave thought and provider-native parts unchanged; update the
surrounding text_part_count/non_thought_text_count handling accordingly.

156-185: 🗄️ Data Integrity & Integration | 🟡 Minor

Do not synthesize a missing Gemini function-call ID.

When the raw functionCall has no id, the normalized ResponseToolCall.id can fall back to the function name. Writing that fallback back into the provider payload changes the native response and can make repeated calls with the same name ambiguous.

Update id only when the raw function call already contains it. Continue updating name and args.

This repeats the previously identified provider-payload defect; confirm the current implementation still has this path.

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

In `@crates/pii-redaction/src/overlay.rs` around lines 156 - 185, In the
functionCall overlay block, update the id field only when the raw function-call
object already contains an id, instead of always writing ResponseToolCall.id and
synthesizing a name fallback. Preserve the existing name and args updates, and
locate the change in the retain_mut closure handling fc and sc.
crates/pii-redaction/src/component.rs (1)

503-508: 📐 Maintainability & Code Quality | 🔵 Trivial

Derive codec_schema from the shared codec registry.

codec_schema hardcodes four values, while validation now uses supported_codec_names(). These lists can diverge. A new codec can pass validation but be absent from the generated schema.

Pass &supported_codec_names() to string_enum_schema. Keep the editor_config! list at Line 277 literal because it requires static metadata.

Based on learnings: keep static editor metadata literal, but use the shared registry for the generated schema.

🤖 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/pii-redaction/src/component.rs` around lines 503 - 508, Update the
generated schema construction in the surrounding component code to pass
&supported_codec_names() to string_enum_schema instead of maintaining a separate
hardcoded codec list. Leave the editor_config! codec list literal unchanged,
since it requires static metadata.

Source: Learnings

crates/pii-redaction/tests/unit/component_tests.rs (1)

5464-5535: 📐 Maintainability & Code Quality | 🔵 Trivial

Test the non-normalized multi-candidate path.

The current test targets /message, so it proves fail-closed behavior for normalized candidate targeting. Add a complementary case with a raw target such as /candidates/1/content/parts/0/text.

That case must redact candidate 1, preserve candidate 0, and avoid triggering the normalized multi-candidate omission guard.

As per path instructions: tests must 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/pii-redaction/tests/unit/component_tests.rs` around lines 5464 - 5535,
The test builtin_backend_omits_multi_candidate_gemini_normalized_response only
covers normalized targeting and does not verify raw multi-candidate redaction.
Add a complementary test using a target path such as
/candidates/1/content/parts/0/text, asserting candidate 1 is redacted, candidate
0 remains unchanged, and the response is not omitted by the normalized
multi-candidate guard.

Source: Path instructions

crates/pii-redaction/tests/coverage/overlay_tests.rs (1)

157-319: 📐 Maintainability & Code Quality | 🔵 Trivial

Add regression cases for the remaining Gemini overlay branches.

The current tests cover only happy paths. Add cases for:

  • A text part that contains an embedded newline.
  • An absent responseId or modelVersion.
  • A raw function call without id.
  • Fewer sanitized calls than raw function-call parts.
  • Preservation of thought parts.

These branches can drop or rewrite provider response data.

As per path instructions: tests must 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/pii-redaction/tests/coverage/overlay_tests.rs` around lines 157 - 319,
Extend the Gemini overlay regression tests around overlay_response_payload to
cover an embedded-newline text part, absent responseId/modelVersion, raw
functionCall parts without ids, fewer sanitized tool calls than raw
function-call parts, and preservation of thought parts. Assert that each case
retains or updates provider payload data correctly without dropping unmatched
calls or thought content, and include error-path behavior where applicable.

Source: Path instructions

🤖 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/pii-redaction/src/component.rs`:
- Line 277: Preserve the legacy "gemini" codec throughout the PII schema and
backend activation flow. Update ProviderSurface::from_codec_name and the
relevant validation or CompiledBuiltinBackend::new path to accept "gemini" as an
alias for "gemini_generate_content", and add compatibility coverage for schema
parsing, validation, and activation.

---

Outside diff comments:
In `@crates/adaptive/src/response_cache/replay.rs`:
- Around line 82-86: Add a separate Gemini replay round-trip test covering
ProviderSurface::GeminiGenerateContent, including candidates, usage metadata,
finish reasons, and tool-call parts; assert collection and finalization
reproduce the stored aggregate. Keep Gemini out of the existing multi-chunk
chunks.len() > 1 assertion and follow the existing replay test patterns.

In `@crates/adaptive/tests/unit/response_cache/key_tests.rs`:
- Around line 603-608: Extend the Gemini test around resolved_body with two
requests that differ only in an unmodeled Gemini field, then run them through
lossy_request_shape and key_of to verify raw-body fallback or distinct cache
keys. Keep the existing lossless normalized-body and effective_codec assertions
unchanged.

In `@crates/node/tests/types_tests.mjs`:
- Around line 91-182: Extend the GeminiGenerateContentCodec tests to cover error
paths for decode, encode, and decodeResponse. Add malformed request, annotated
request, response, and codec-failure inputs that cause each method to throw
through the N-API wrapper, and assert the calls throw while preserving the
existing successful-payload coverage.

---

Duplicate comments:
In `@crates/pii-redaction/src/builtin.rs`:
- Around line 476-488: Replace the duplicated logic in
targets_normalized_gemini_candidate and targets_normalized_openai_chat_choice
with one shared normalized-target predicate, then invoke that predicate from
both response guard branches. Preserve the existing fail-closed behavior and the
current recognized target segments.

In `@crates/pii-redaction/src/component.rs`:
- Around line 503-508: Update the generated schema construction in the
surrounding component code to pass &supported_codec_names() to
string_enum_schema instead of maintaining a separate hardcoded codec list. Leave
the editor_config! codec list literal unchanged, since it requires static
metadata.

In `@crates/pii-redaction/src/overlay.rs`:
- Around line 118-154: The fallback overlay logic in the loop over parts
incorrectly splits annotated_message_text on newlines and can lose multiline
content. Preserve the complete sanitized message_text in the first non-thought
text part, remove subsequent non-thought text parts, and leave thought and
provider-native parts unchanged; update the surrounding
text_part_count/non_thought_text_count handling accordingly.
- Around line 156-185: In the functionCall overlay block, update the id field
only when the raw function-call object already contains an id, instead of always
writing ResponseToolCall.id and synthesizing a name fallback. Preserve the
existing name and args updates, and locate the change in the retain_mut closure
handling fc and sc.

In `@crates/pii-redaction/tests/coverage/overlay_tests.rs`:
- Around line 157-319: Extend the Gemini overlay regression tests around
overlay_response_payload to cover an embedded-newline text part, absent
responseId/modelVersion, raw functionCall parts without ids, fewer sanitized
tool calls than raw function-call parts, and preservation of thought parts.
Assert that each case retains or updates provider payload data correctly without
dropping unmatched calls or thought content, and include error-path behavior
where applicable.

In `@crates/pii-redaction/tests/unit/component_tests.rs`:
- Around line 5464-5535: The test
builtin_backend_omits_multi_candidate_gemini_normalized_response only covers
normalized targeting and does not verify raw multi-candidate redaction. Add a
complementary test using a target path such as
/candidates/1/content/parts/0/text, asserting candidate 1 is redacted, candidate
0 remains unchanged, and the response is not omitted by the normalized
multi-candidate guard.
🪄 Autofix

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: 63d31741-2c7c-4fc9-b533-deb18e8a3ddb

📥 Commits

Reviewing files that changed from the base of the PR and between 2c7dda6 and d9faaaf.

📒 Files selected for processing (50)
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/src/response_cache/replay.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/api/runtime/callbacks.rs
  • crates/core/src/codec/gemini_generate_content.rs
  • crates/core/src/codec/mod.rs
  • crates/core/src/codec/resolve.rs
  • crates/core/src/plugins/nemo_guardrails/component.rs
  • crates/core/src/plugins/nemo_guardrails/python.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/tests/unit/codec/parity_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/core/tests/unit/plugins/nemo_guardrails/component_tests.rs
  • crates/core/tests/unit/plugins/nemo_guardrails/local_python_tests.rs
  • crates/ffi/nemo_relay.h
  • crates/ffi/src/api/llm.rs
  • crates/ffi/tests/unit/types_tests.rs
  • crates/node/pii_redaction.d.ts
  • crates/node/plugin.d.ts
  • crates/node/src/types/mod.rs
  • crates/node/tests/types_tests.mjs
  • crates/pii-redaction/README.md
  • crates/pii-redaction/src/builtin.rs
  • crates/pii-redaction/src/component.rs
  • crates/pii-redaction/src/overlay.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/plugin/src/lib.rs
  • crates/python/src/py_api/mod.rs
  • crates/python/src/py_types/codecs.rs
  • crates/python/src/py_types/mod.rs
  • crates/types/src/codec/response.rs
  • crates/worker/src/lib.rs
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/about-nemo-relay/concepts/middleware.mdx
  • docs/build-plugins/dynamic-plugins/native-dynamic/about.mdx
  • docs/configure-plugins/nemo-guardrails/configuration.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • go/nemo_relay/callbacks_test.go
  • go/nemo_relay/coverage_gap_test.go
  • go/nemo_relay/nemo_relay.go
  • python/nemo_relay/_native.pyi
  • python/nemo_relay/codecs.py
  • python/nemo_relay/codecs.pyi
  • python/nemo_relay/pii_redaction.py
  • python/nemo_relay/pii_redaction.pyi
  • python/tests/plugin/test_worker_sdk.py
  • python/tests/test_builtin_codecs.py

Comment thread crates/pii-redaction/src/component.rs
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>

Copy link
Copy Markdown
Author

Addressed the CodeRabbit follow-ups in 57ab92e.

  • Added gemini as a compatibility alias for ProviderSurface::GeminiGenerateContent while keeping gemini_generate_content canonical.
  • Updated PII validation/schema generation to use the shared accepted codec-name list and added alias validation + activation coverage.
  • Fixed Gemini PII overlay fallback so embedded newlines stay in one text part, thought parts are preserved, and missing raw functionCall.id is not synthesized.
  • Collapsed the duplicated normalized-response target predicate used by OpenAI Chat and Gemini multi-candidate fail-closed guards.
  • Added adaptive cache-key coverage for unmodeled Gemini generationConfig fields and expanded Gemini replay round-trip coverage with tool calls.
  • Added raw multi-candidate PII coverage and Node GeminiGenerateContentCodec error-path tests.

Validation: resolver 41 passed, Gemini codec 148 passed, adaptive response_cache 50 passed, PII 122 passed, full workspace clippy -D warnings clean, Rust format/diff checks clean, and node --check crates/node/tests/types_tests.mjs clean. Full Node tests still need Node >=24 in CI.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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/resolve.rs (1)

162-176: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the public method documentation for the compatibility alias.

from_codec_name now accepts "gemini", but the comments still describe canonical names only and call codec_name() the inverse. Document the canonical spelling and the accepted compatibility alias.

Proposed documentation fix
-    /// The canonical codec name for this surface (e.g. `"openai_chat"`), the
-    /// inverse of [`Self::from_codec_name`].
+    /// The canonical codec name for this surface (e.g. `"openai_chat"`).
...
-    /// Resolves a canonical codec name to its surface, or `None` when `name` is
-    /// not a built-in provider codec.
+    /// Resolves a canonical codec name or compatibility alias to its surface,
+    /// or `None` when `name` is not a built-in provider codec.
🤖 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/resolve.rs` around lines 162 - 176, Update the public
documentation for ProviderSurface::codec_name and
ProviderSurface::from_codec_name to distinguish canonical codec names from the
accepted "gemini" compatibility alias. Remove the claim that codec_name() and
from_codec_name() are exact inverses, and state that from_codec_name accepts
both canonical names and the alias.
♻️ Duplicate comments (1)
crates/adaptive/tests/unit/response_cache/replay_tests.rs (1)

82-112: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Cover the remaining Gemini replay shapes.

The fixture verifies functionCall, but it omits thoughtSignature and candidate metadata. Add an exact round-trip assertion for those fields. Add a multi-candidate or nonzero-index aggregate and assert that replay_is_lossy rejects it.

As per path instructions, “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/adaptive/tests/unit/response_cache/replay_tests.rs` around lines 82 -
112, Extend gemini_replay_uses_a_valid_native_stream_event and related replay
tests to include a thoughtSignature and candidate-level metadata, then assert
synthesize_replay_chunks preserves the aggregate exactly. Add a separate
aggregate with multiple candidates or a nonzero candidate index and assert
replay_is_lossy returns true for that unsupported shape.

Source: Path instructions

🤖 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/adaptive/src/response_cache/key.rs`:
- Around line 341-351: Update the GeminiGenerateContent lossiness guard to
return true when generationConfig exists but is not a JSON object, while
preserving detection of unsupported object keys. Also guard non-lossless
systemInstruction.parts and extra functionCall part fields, then add
distinct-key tests covering each guarded shape.

In `@crates/node/tests/types_tests.mjs`:
- Line 186: Update the request arguments in the codec tests around codec.decode
and codec.encode to use plain JSON-shaped objects containing own enumerable
headers and content properties instead of LlmRequest instances. Apply this
consistently to every decode/encode request argument, including the original
argument.

---

Outside diff comments:
In `@crates/core/src/codec/resolve.rs`:
- Around line 162-176: Update the public documentation for
ProviderSurface::codec_name and ProviderSurface::from_codec_name to distinguish
canonical codec names from the accepted "gemini" compatibility alias. Remove the
claim that codec_name() and from_codec_name() are exact inverses, and state that
from_codec_name accepts both canonical names and the alias.

---

Duplicate comments:
In `@crates/adaptive/tests/unit/response_cache/replay_tests.rs`:
- Around line 82-112: Extend gemini_replay_uses_a_valid_native_stream_event and
related replay tests to include a thoughtSignature and candidate-level metadata,
then assert synthesize_replay_chunks preserves the aggregate exactly. Add a
separate aggregate with multiple candidates or a nonzero candidate index and
assert replay_is_lossy returns true for that unsupported shape.
🪄 Autofix

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: 9594e358-2991-4378-abcd-b0036f146acb

📥 Commits

Reviewing files that changed from the base of the PR and between d9faaaf and 57ab92e.

📒 Files selected for processing (11)
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/pii-redaction/src/builtin.rs
  • crates/pii-redaction/src/component.rs
  • crates/pii-redaction/src/overlay.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (21)
**/*.rs

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

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

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

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

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

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

**/*.rs: Format Rust code with rustfmt defaults using cargo fmt.
Run cargo clippy -- -D warnings; all Rust warnings must be treated as errors.
Use Rust snake_case naming conventions.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
{crates/core,crates/adaptive}/**/*

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

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

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/core/src/codec/resolve.rs
crates/adaptive/**

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

Keep crates/adaptive aligned with the canonical adaptive config schema, built-in section helpers, plugin lifecycle, and validation/report behavior.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
**/*

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

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

**/*: Use release tags in raw Rust-compatible SemVer without a leading v; tags such as v0.1.0 are prohibited.
Use branch prefixes feat/, fix/, docs/, test/, or refactor/ according to the change purpose.
Every commit in a pull request must include a DCO Signed-off-by: sign-off.
Before submitting a pull request, ensure pre-commit hooks, relevant tests, target-specific builds, documentation updates, and a rebase on the latest main are complete.
Use commit messages in the form type: short description, with a valid type and a first line under 72 characters.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
crates/{core,adaptive}/**/*

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

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

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/core/src/codec/resolve.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.

**/*.{rs,py,go,js,ts}: When observability configuration or lifecycle is exposed, keep FFI and Python, Go, and Node.js binding-native config objects and subscriber/exporter methods aligned in logical knobs and semantics.
Require every OpenTelemetry endpoint to have a type and nonblank destination; resolve header_env values at activation and reject missing, blank, or duplicate headers.
Concatenate layered ATOF sink, ATIF storage, and OpenTelemetry endpoint lists with higher-precedence entries first.
Preserve correct handling of mark events, start/end events, orphan cases, and span or trajectory fields derived from intended event data.
Run affected Rust tests and just test-rust when event fields change; run just test-python, just test-go, and just test-node when binding-native configuration or lifecycle changes.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.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/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
**/*.{rs,py,js,jsx,ts,tsx,go,c,h,cc,cpp,md,toml,yml,yaml,sh}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, documentation, scripts, and configuration files; the project is Apache-2.0.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Use snake_case naming in Rust and Python.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Use Json = serde_json::Value in Rust-facing runtime APIs where existing code expects JSON payloads.
Treat Rust as the source of truth for runtime behavior; binding APIs should mirror Rust semantics unless a language-specific wrapper intentionally improves ergonomics.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
**/*.{rs,py,js,mjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Preserve the existing Tokio-based asynchronous model and callback/future lifetimes; do not unexpectedly block or hide async work in bindings.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
**/*.{rs,py,go,js,jsx,ts,tsx,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{rs,py,go,js,jsx,ts,tsx,c,h}: Run tests for every language affected by a change; changes to the core Rust crate require tests across all bindings.
Use SONAR_IGNORE_START / SONAR_IGNORE_END only for documented false positives, keep ignored blocks minimal, explain them with a comment, and obtain reviewer sign-off.
Preserve the layered architecture in which Rust provides the core runtime and C FFI, PyO3, and NAPI provide bindings that mirror the full API surface.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
**/{test,tests}/**/*

📄 CodeRabbit inference engine (CONTRIBUTING.md)

When adding functionality, include tests in the appropriate test files for each affected language binding.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
**/*.{rs,py,go,js,jsx,ts,tsx,c,h,html,md,mdx,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include the appropriate SPDX copyright and Apache-2.0 license header in every source file.

Files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.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/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/core/src/codec/resolve.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/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
{crates/**/src/**/*.rs,python/**/*.py}

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

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

Files:

  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/src/overlay.rs
crates/node/**/*.{js,mjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use camelCase naming for Node.js APIs.

Files:

  • crates/node/tests/types_tests.mjs
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/node/tests/types_tests.mjs
crates/core/**/*.rs

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

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

Use Result<T> with FlowError in core runtime paths, keeping wrapper-layer errors explicit and binding-appropriate.

Files:

  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/core/src/codec/resolve.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 as crates/core/src/api/runtime/, crates/core/src/codec/, and crates/core/src/json.rs.

Files:

  • crates/core/src/codec/resolve.rs
🧠 Learnings (4)
📚 Learning: 2026-08-03T19:55:03.931Z
Learnt from: afourniernv
Repo: NVIDIA/NeMo-Relay PR: 558
File: crates/pii-redaction/src/rampart/mod.rs:265-274
Timestamp: 2026-08-03T19:55:03.931Z
Learning: In NeMo Relay first-party plugin registration helpers, treat the documented duplicate-registration `PluginError::RegistrationFailed` result from `register_plugin` as success when registration is intended to be idempotent. Do not locally reclassify this as `PluginError::Conflict`; changing the classification requires a core-wide review of the public API and FFI behavior.

Applied to files:

  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/pii-redaction/src/component.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/pii-redaction/tests/coverage/overlay_tests.rs
  • crates/core/tests/unit/codec/resolve_tests.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/core/src/codec/resolve.rs
  • crates/pii-redaction/tests/unit/component_tests.rs
  • crates/pii-redaction/src/overlay.rs
📚 Learning: 2026-08-03T19:54:17.292Z
Learnt from: afourniernv
Repo: NVIDIA/NeMo-Relay PR: 558
File: crates/pii-redaction/src/rampart/mod.rs:486-492
Timestamp: 2026-08-03T19:54:17.292Z
Learning: In the Rust plugin configuration editor, use literal enum values for codec lists because `nemo_relay::editor_config!` generates static editor metadata. Do not replace these literals with a shared source such as `supported_codec_names()` unless the core editor-metadata API is first changed to support dynamic values.

Applied to files:

  • crates/pii-redaction/src/component.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/pii-redaction/src/overlay.rs
📚 Learning: 2026-08-03T19:54:44.552Z
Learnt from: afourniernv
Repo: NVIDIA/NeMo-Relay PR: 558
File: crates/pii-redaction/src/rampart/mod.rs:670-792
Timestamp: 2026-08-03T19:54:44.552Z
Learning: In the Rust `crates/pii-redaction` crate, treat `pii_rampart` as a first-party built-in component. Preserve private `#[cfg(test)]` unit-test modules under `src`, including Rampart tests, according to the crate’s existing convention. Do not request moving these tests to `tests/` when doing so would require widening implementation visibility solely for test access.

Applied to files:

  • crates/pii-redaction/src/component.rs
  • crates/pii-redaction/src/builtin.rs
  • crates/pii-redaction/src/overlay.rs
📚 Learning: 2026-07-28T20:07:29.880Z
Learnt from: willkill07
Repo: NVIDIA/NeMo-Relay PR: 571
File: crates/core/src/api/runtime/state.rs:996-1020
Timestamp: 2026-07-28T20:07:29.880Z
Learning: In NeMo Relay (RELAY-509), sanitizer callback failures must be treated as intentional fail-open behavior. When an event/tool (request/response) or LLM (request/response) sanitizer callback fails, the sanitizer chain should retain and publish the last valid event/payload snapshot (rather than dropping/invalidating the data) and log the failure including callback context (e.g., which sanitizer/callback failed and relevant identifiers). Apply this consistently across all sanitizer chains mentioned in the RELAY-509 documentation/migration guide.

Applied to files:

  • crates/core/src/codec/resolve.rs
🔇 Additional comments (12)
crates/pii-redaction/src/builtin.rs (1)

307-309: LGTM!

Also applies to: 402-417, 464-475

crates/pii-redaction/src/component.rs (1)

10-10: LGTM!

Also applies to: 500-502, 1130-1139

crates/pii-redaction/src/overlay.rs (1)

118-140: LGTM!

Also applies to: 157-159

crates/pii-redaction/tests/coverage/overlay_tests.rs (1)

180-225: LGTM!

Also applies to: 308-382

crates/pii-redaction/tests/unit/component_tests.rs (1)

1797-1816: LGTM!

Also applies to: 4371-4424, 4679-4679, 5613-5690

crates/adaptive/tests/unit/response_cache/key_tests.rs (1)

611-642: 📐 Maintainability & Code Quality

Record required validation for the adaptive Rust change.

Before handoff, run and record cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, just test-rust, and the required Rust, Python, Go, and Node.js validation matrix for crates/adaptive.

As per coding guidelines, “If crates/core or crates/adaptive changed, run the full validation matrix across Rust, Python, Go, and Node.js.”

Source: Coding guidelines

crates/core/src/codec/resolve.rs (4)

17-17: LGTM!


28-29: 🗄️ Data Integrity & Integration

Confirm the source-compatibility impact of this public enum addition.

ProviderSurface is public. Adding GeminiGenerateContent can make downstream exhaustive match expressions fail to compile. Confirm that the crate version and release policy allow this source-compatibility break. If not, provide the documented migration path before merge.

As per path instructions, public API changes should preserve existing behavior unless tests and docs show the intended migration path.

Source: Path instructions


72-81: LGTM!

Also applies to: 158-158


194-201: LGTM!

crates/core/tests/unit/codec/resolve_tests.rs (1)

29-29: LGTM!

Also applies to: 88-138, 401-401, 450-454, 479-500, 509-530, 568-578, 618-629

crates/node/tests/types_tests.mjs (1)

209-220: LGTM!

Comment thread crates/adaptive/src/response_cache/key.rs Outdated
Comment thread crates/node/tests/types_tests.mjs Outdated
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
crates/core/src/codec/gemini_generate_content.rs (1)

1315-1324: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the reserved key before testing candidate metadata.

Line 1316 treats a candidate with only "api" as metadata. Line 1324 then removes the only field. The decoder returns an empty Gemini api_specific variant instead of None.

Remove "api" before calculating has_candidate_data. Add a test for a candidate that contains only the reserved key.

Proposed fix
-            let cand_extra = candidate.map(|c| c.extra.clone()).unwrap_or_default();
-            let has_candidate_data = !cand_extra.is_empty() || thoughts_tokens.is_some();
+            let mut extra = candidate.map(|c| c.extra.clone()).unwrap_or_default();
+            extra.remove("api");
+            let has_candidate_data = !extra.is_empty() || thoughts_tokens.is_some();
             if !has_candidate_data {
                 None
             } else {
-                let mut extra = cand_extra;
                 let safety_ratings = extra.remove("safetyRatings");
                 let grounding_metadata = extra.remove("groundingMetadata");
                 let citation_metadata = extra.remove("citationMetadata");
-                extra.remove("api");
🤖 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/gemini_generate_content.rs` around lines 1315 - 1324,
Update the candidate metadata handling around cand_extra so the reserved "api"
key is removed before computing has_candidate_data, ensuring candidates
containing only that key return None rather than an empty api_specific variant.
Add a test covering a candidate whose metadata contains only "api".
🤖 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 `@docs/integrate-into-frameworks/provider-codecs.mdx`:
- Line 94: Clarify the provider-codecs documentation so
GeminiGenerateContentCodec is not implied to be auto-selected by the gateway
routes listed in the surrounding section. Either explicitly describe it as
directly usable or restrict the auto-selection wording to codecs supported on
/v1/messages, /v1/chat/completions, and /v1/responses, and keep the
corresponding codecs documentation consistent.

---

Outside diff comments:
In `@crates/core/src/codec/gemini_generate_content.rs`:
- Around line 1315-1324: Update the candidate metadata handling around
cand_extra so the reserved "api" key is removed before computing
has_candidate_data, ensuring candidates containing only that key return None
rather than an empty api_specific variant. Add a test covering a candidate whose
metadata contains only "api".
🪄 Autofix

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: b80f59b1-ac75-457c-95e4-cc2df7cda944

📥 Commits

Reviewing files that changed from the base of the PR and between 57ab92e and 3a0dd60.

📒 Files selected for processing (18)
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
  • crates/core/src/codec/resolve.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/types/src/codec/response.rs
  • crates/worker/src/lib.rs
  • crates/worker/tests/unit/codec_identity_tests.rs
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/using-codecs.mdx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (35)
**/*.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)

**/*.mdx: In MDX files, top-of-file comments must use JSX comment delimiters ({/* and */}); do not use HTML comments for MDX SPDX headers.
New or regenerated MDX files must use {/* ... */} for top-of-file SPDX comments.

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
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/using-codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
{docs,examples}/**/*

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

Update docs and examples.

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/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, use maintain-dynamic-plugins and include the native SDK, worker protocol, Python SDK, docs, packaging, and Codecov surfaces in the validation plan.
If code changes alter APIs, bindings, commands, paths, packaging behavior, observability/adaptive semantics, or documented best practices, update any dependent maintainer or consumer skills in the same branch.
During iteration, prefer uv run pre-commit run --files <changed files...>.
Before review or handoff, run uv run pre-commit run --all-files.

**/*: Use release tags in raw Rust-compatible SemVer without a leading v; tags such as v0.1.0 are prohibited.
Use branch prefixes feat/, fix/, docs/, test/, or refactor/ according to the change purpose.
Every commit in a pull request must include a DCO Signed-off-by: sign-off.
Before submitting a pull request, ensure pre-commit hooks, relevant tests, target-specific builds, documentation updates, and a rebase on the latest main are complete.
Use commit messages in the form type: short description, with a valid type and a first line under 72 characters.

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • crates/worker/src/lib.rs
  • docs/about-nemo-relay/concepts/codecs.mdx
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/node/tests/types_tests.mjs
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • docs/integrate-into-frameworks/provider-codecs.mdx
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
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/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
**/*.{md,mdx}

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

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

Use documented public APIs and stable wrapper commands in examples and user-facing documentation; do not rely on internal helpers.

**/*.{md,mdx}: Prefer the documented public API over internal shortcuts in documentation and examples.
Keep package names, repository references, and build commands current.
Contribution workflow documentation must require an issue before external contribution pull requests and note that NVIDIA contributors may use a GitHub or Linear issue.
Update entry-point documentation when examples or reading paths change.
Keep release-process and release-notes guidance in maintainer documentation such as RELEASING.md, rather than user-facing documentation pages or CHANGELOG.md.
Use stable user-facing wrappers at the scripts/ root in documentation and examples; reference namespaced helper paths only for internal maintenance documentation.
When detailed dynamic plugin guides exist, keep Rust native plugin examples, Python worker plugin examples, and grpc-v1 protocol details on separate pages.
Dynamic plugin manifests in documentation and examples should use compat.relay = ">=0.5,<1.0" unless deliberately narrower.
Render images, diagrams, tables, and other visual content at representative page widths, ensuring legibility and complete access without clipping; use responsive scaling, reflow, or overflow as appropriate and scope visual styling narrowly.
Dynamic plugin entry pages should link to native, worker, Rust example, Python example, and protocol pages when those pages exist.
Images, diagrams, tables, and custom visual content must remain legible and fully accessible at representative desktop and narrow page widths.
Release-policy documentation must point to GitHub Releases as the only release-history source of truth.
Run just docs when the documentation site changes; retain ./scripts/build-docs.sh html as the compatibility wrapper.

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
**/*.{md,mdx,py,go,js,ts}

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

Examples and documentation must use each exporter's documented flush/deregister order before shutdown.

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant reference documentation when public behavior or APIs change.

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
**/*.{rs,py,go,js,jsx,ts,tsx,c,h,html,md,mdx,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Include the appropriate SPDX copyright and Apache-2.0 license header in every source file.

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • crates/worker/src/lib.rs
  • docs/about-nemo-relay/concepts/codecs.mdx
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • docs/integrate-into-frameworks/provider-codecs.mdx
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
**/*.{md,mdx,rst}

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

**/*.{md,mdx,rst}: Use title case consistently for technical documentation headings and table headers; avoid quotation marks, ampersands, and exclamation marks in headings, while preserving official product, event, research, and whitepaper title case.
Format code elements, commands, parameters, package names, expressions, directories, file names, and paths in monospace; represent path placeholders with angle brackets inside monospace.
Format UI buttons, menus, fields, and labels in bold, and separate consecutive UI navigation labels with >.
Use quotation marks for error messages and strings when appropriate, italics for newly introduced terms and publication titles, and plain text for keyboard shortcuts.
Represent GitHub repositories with owner/repository link text, such as [NVIDIA/NeMo](link), rather than generic repository wording.
Introduce every code block with a complete sentence; do not let a code block complete or interrupt the grammar of surrounding prose; use syntax highlighting when supported.
Keep inline method, function, and class references consistent with nearby documentation; omit empty parentheses in prose when no call is shown.
Use descriptive link text matching the destination title when possible; avoid raw URLs, generic anchors, long-sentence links, and unnecessary links that distract from procedures.
Ensure lists have a complete lead-in sentence, more than one item, no more than two levels, parallel construction, one idea or action per item, and appropriate punctuation; use bullets for unordered items and numbers for ordered tasks.
Format definition lists with a bold term followed by a complete, parallel, punctuated definition.
Use tables for reference information, decision support, compatibility matrices, and comparable choices; flag one-row tables, missing captions or lead-ins, sentence-case headers where title case is expected, unexplained empty cells, and code or links that would be clearer as prose.
Write procedure steps as imperative ...

Files:

  • docs/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/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/integrate-into-frameworks/using-codecs.mdx
  • docs/configure-plugins/pii-redaction/configuration.mdx
  • docs/about-nemo-relay/concepts/codecs.mdx
  • docs/integrate-into-frameworks/provider-response-codecs.mdx
  • docs/integrate-into-frameworks/provider-codecs.mdx
**/*.rs

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

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

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

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

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

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

**/*.rs: Format Rust code with rustfmt defaults using cargo fmt.
Run cargo clippy -- -D warnings; all Rust warnings must be treated as errors.
Use Rust snake_case naming conventions.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
{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:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/worker/src/lib.rs
  • crates/types/src/codec/response.rs
{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/tests/unit/codec_identity_tests.rs
  • crates/worker/src/lib.rs
{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:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/worker/src/lib.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/tests/unit/codec_identity_tests.rs
  • crates/worker/src/lib.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.

**/*.{rs,py,go,js,ts}: When observability configuration or lifecycle is exposed, keep FFI and Python, Go, and Node.js binding-native config objects and subscriber/exporter methods aligned in logical knobs and semantics.
Require every OpenTelemetry endpoint to have a type and nonblank destination; resolve header_env values at activation and reject missing, blank, or duplicate headers.
Concatenate layered ATOF sink, ATIF storage, and OpenTelemetry endpoint lists with higher-precedence entries first.
Preserve correct handling of mark events, start/end events, orphan cases, and span or trajectory fields derived from intended event data.
Run affected Rust tests and just test-rust when event fields change; run just test-python, just test-go, and just test-node when binding-native configuration or lifecycle changes.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.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/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
**/*.{rs,py,js,jsx,ts,tsx,go,c,h,cc,cpp,md,toml,yml,yaml,sh}

📄 CodeRabbit inference engine (AGENTS.md)

Keep SPDX headers on source, documentation, scripts, and configuration files; the project is Apache-2.0.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Use snake_case naming in Rust and Python.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

crates/**/*.rs: Use Json = serde_json::Value in Rust-facing runtime APIs where existing code expects JSON payloads.
Treat Rust as the source of truth for runtime behavior; binding APIs should mirror Rust semantics unless a language-specific wrapper intentionally improves ergonomics.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
**/*.{rs,py,js,mjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Preserve the existing Tokio-based asynchronous model and callback/future lifetimes; do not unexpectedly block or hide async work in bindings.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
**/*.{rs,py,go,js,jsx,ts,tsx,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{rs,py,go,js,jsx,ts,tsx,c,h}: Run tests for every language affected by a change; changes to the core Rust crate require tests across all bindings.
Use SONAR_IGNORE_START / SONAR_IGNORE_END only for documented false positives, keep ignored blocks minimal, explain them with a comment, and obtain reviewer sign-off.
Preserve the layered architecture in which Rust provides the core runtime and C FFI, PyO3, and NAPI provide bindings that mirror the full API surface.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
**/{test,tests}/**/*

📄 CodeRabbit inference engine (CONTRIBUTING.md)

When adding functionality, include tests in the appropriate test files for each affected language binding.

Files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/tests/unit/codec/gemini_generate_content_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/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/node/tests/types_tests.mjs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
{crates/core,crates/adaptive}/**/*

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

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

Files:

  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
crates/adaptive/**

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

Keep crates/adaptive aligned with the canonical adaptive config schema, built-in section helpers, plugin lifecycle, and validation/report behavior.

Files:

  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/adaptive/src/response_cache/key.rs
crates/{core,adaptive}/**/*

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

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

Files:

  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.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/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
crates/core/**/*.rs

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

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

Use Result<T> with FlowError in core runtime paths, keeping wrapper-layer errors explicit and binding-appropriate.

Files:

  • crates/core/tests/unit/codec/response_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
{crates/**/src/**/*.rs,python/**/*.py}

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

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

Files:

  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/src/codec/gemini_generate_content.rs
crates/node/**/*.{js,mjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use camelCase naming for Node.js APIs.

Files:

  • crates/node/tests/types_tests.mjs
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/node/tests/types_tests.mjs
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 as crates/core/src/api/runtime/, crates/core/src/codec/, and crates/core/src/json.rs.

Files:

  • crates/core/src/codec/resolve.rs
  • crates/core/src/codec/gemini_generate_content.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/codec/response.rs
🧠 Learnings (2)
📚 Learning: 2026-08-03T19:55:03.931Z
Learnt from: afourniernv
Repo: NVIDIA/NeMo-Relay PR: 558
File: crates/pii-redaction/src/rampart/mod.rs:265-274
Timestamp: 2026-08-03T19:55:03.931Z
Learning: In NeMo Relay first-party plugin registration helpers, treat the documented duplicate-registration `PluginError::RegistrationFailed` result from `register_plugin` as success when registration is intended to be idempotent. Do not locally reclassify this as `PluginError::Conflict`; changing the classification requires a core-wide review of the public API and FFI behavior.

Applied to files:

  • crates/worker/tests/unit/codec_identity_tests.rs
  • crates/adaptive/tests/unit/acg/request_surface_tests.rs
  • crates/core/tests/unit/codec/response_tests.rs
  • crates/worker/src/lib.rs
  • crates/adaptive/src/acg/request_surfaces/mod.rs
  • crates/adaptive/tests/unit/response_cache/replay_tests.rs
  • crates/adaptive/tests/unit/response_cache/key_tests.rs
  • crates/core/src/codec/resolve.rs
  • crates/types/src/codec/response.rs
  • crates/adaptive/src/response_cache/key.rs
  • crates/core/tests/unit/codec/gemini_generate_content_tests.rs
  • crates/core/src/codec/gemini_generate_content.rs
📚 Learning: 2026-07-28T20:07:29.880Z
Learnt from: willkill07
Repo: NVIDIA/NeMo-Relay PR: 571
File: crates/core/src/api/runtime/state.rs:996-1020
Timestamp: 2026-07-28T20:07:29.880Z
Learning: In NeMo Relay (RELAY-509), sanitizer callback failures must be treated as intentional fail-open behavior. When an event/tool (request/response) or LLM (request/response) sanitizer callback fails, the sanitizer chain should retain and publish the last valid event/payload snapshot (rather than dropping/invalidating the data) and log the failure including callback context (e.g., which sanitizer/callback failed and relevant identifiers). Apply this consistently across all sanitizer chains mentioned in the RELAY-509 documentation/migration guide.

Applied to files:

  • crates/core/src/codec/resolve.rs
  • crates/core/src/codec/gemini_generate_content.rs
🔇 Additional comments (20)
crates/node/tests/types_tests.mjs (1)

98-107: LGTM!

Also applies to: 118-124, 134-140, 195-207

docs/about-nemo-relay/concepts/codecs.mdx (1)

91-93: LGTM!

Also applies to: 123-125

docs/configure-plugins/pii-redaction/configuration.mdx (1)

97-98: LGTM!

Also applies to: 137-137

docs/integrate-into-frameworks/provider-codecs.mdx (1)

110-110: LGTM!

docs/integrate-into-frameworks/provider-response-codecs.mdx (2)

364-372: LGTM!


445-448: LGTM!

docs/integrate-into-frameworks/using-codecs.mdx (1)

41-41: LGTM!

crates/types/src/codec/response.rs (1)

9-10: LGTM!

Also applies to: 351-357, 371-394

crates/core/src/codec/resolve.rs (1)

163-180: LGTM!

crates/core/tests/unit/codec/gemini_generate_content_tests.rs (1)

339-359: LGTM!

Also applies to: 3558-3561

crates/adaptive/src/acg/request_surfaces/mod.rs (1)

46-52: LGTM!

Also applies to: 95-104

crates/adaptive/tests/unit/acg/request_surface_tests.rs (1)

304-315: LGTM!

crates/worker/tests/unit/codec_identity_tests.rs (1)

1-21: LGTM!

crates/core/src/codec/gemini_generate_content.rs (1)

364-371: LGTM!

crates/core/tests/unit/codec/response_tests.rs (1)

1598-1654: LGTM!

crates/worker/src/lib.rs (1)

2162-2164: 🎯 Functional Correctness

Keep the canonical Gemini codec ID.

The worker-protocol producer serializes BuiltinLlmCodec::id(), which returns "gemini_generate_content". The "gemini" value is a provider-surface alias, not a worker-protocol codec identity.

			> Likely an incorrect or invalid review comment.
crates/adaptive/src/response_cache/key.rs (2)

341-362: 📐 Maintainability & Code Quality

Complete the required validation before merge.

This PR changes crates/adaptive. Provide successful results for cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, just test-rust, and the required Rust, Python, Go, and Node.js validation matrix. Do not leave the Node.js 24 package tests deferred after CI completes.

As per coding guidelines, “If any Rust code changed, always run just test-rust,” and changes to crates/adaptive “must run the full language matrix.”

Source: Coding guidelines


359-361: 🗄️ Data Integrity & Integration

No change required for these shapes. GeminiGenerateContentCodec::decode rejects non-array contents and invalid content-item roles, so decode_surface uses the raw-body fallback. No normalized-key collision occurs.

			> Likely an incorrect or invalid review comment.
crates/adaptive/tests/unit/response_cache/key_tests.rs (1)

644-744: LGTM!

crates/adaptive/tests/unit/response_cache/replay_tests.rs (1)

82-124: LGTM!

Also applies to: 126-146

Comment thread docs/integrate-into-frameworks/provider-codecs.mdx
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>
Signed-off-by: Sahiti Bulusu <sbulusu@nvidia.com>
@willkill07 willkill07 added this to the 0.8 milestone Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature a new feature lang:go PR changes/introduces Go code lang:js PR changes/introduces Javascript/Typescript code lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code size:XXL PR is very large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants