Skip to content

fix: annotate Deep Agents model responses#246

Merged
rapids-bot[bot] merged 3 commits into
NVIDIA:mainfrom
willkill07:fix/relay-198-199
Jun 10, 2026
Merged

fix: annotate Deep Agents model responses#246
rapids-bot[bot] merged 3 commits into
NVIDIA:mainfrom
willkill07:fix/relay-198-199

Conversation

@willkill07

@willkill07 willkill07 commented Jun 9, 2026

Copy link
Copy Markdown
Member

Overview

Adds Deep Agents/LangChain model response annotations so managed LangChain model calls emit provider-neutral AnnotatedLLMResponse data and OpenInference output spans match the shared contract.

  • 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

  • Add a Python constructor for AnnotatedLLMResponse, including public support for unknown finish-reason strings from custom codecs.
  • Decode serialized LangChain ModelResponse values directly into normalized Relay response annotations without using an OpenAI-specific codec as a factory.
  • Extend Deep Agents coverage for sync and async model/tool middleware routing, end-to-end execution, and exact OpenInference span attributes.
  • Add opentelemetry-proto as a test-only dependency for decoding OTLP test payloads and refresh Python attributions.

Validation run:

  • cargo test -p nemo-relay-python --lib
  • just test-python-langchain
  • uv run pre-commit run --files pyproject.toml uv.lock ATTRIBUTIONS-Python.md python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • Earlier full local validation also included just test-python, RUST_TEST_THREADS=1 just test-rust, and all-files pre-commit before the final test-only dependency cleanup.

Where should the reviewer start?

Start with python/nemo_relay/integrations/langchain/_serialization.py for the response annotation behavior, then python/tests/integrations/deepagents_tests/test_deepagents_integration.py for the Deep Agents execution and OpenInference contract coverage.

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

  • Closes RELAY-198
  • Closes RELAY-199

Summary by CodeRabbit

  • New Features

    • LangChain response decoding to convert model responses into annotated format.
    • Explicit constructor support for annotated LLM responses for easier programmatic creation.
    • Enhanced observability: OpenTelemetry/OpenInference tracing support and local OTLP test collector for verification.
  • Documentation

    • Added license attributions for new dependencies (opentelemetry-proto, protobuf).
  • Tests

    • New and expanded tests covering LangChain decoding, finish-reason mapping, tool-call extraction, OTLP tracing, and improved test cleanup/flush semantics.

Signed-off-by: Will Killian <wkillian@nvidia.com>
@willkill07 willkill07 requested review from a team as code owners June 9, 2026 17:28
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 10775c8f-22d9-4a15-86e4-157bb73dee17

📥 Commits

Reviewing files that changed from the base of the PR and between bf48a20 and a366daf.

📒 Files selected for processing (3)
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
  • python/tests/test_tools.py
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (12)
**/test_*.{py,py}

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

Relevant integration tests or smoke coverage must exist for the integration path

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
{pyproject.toml,**/*.py}

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

Maintain consistency between Python package names in pyproject.toml and import paths used throughout the codebase

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
**/*.{py,txt,toml,cfg,yaml,yml}

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

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

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
python/**/*test*.py

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

python/**/*test*.py: Do not add @pytest.mark.asyncio to any test in Python test files
Do not add a -> None return type annotation to test functions
When mocking a class, use unittest.mock.MagicMock or unittest.mock.AsyncMock with the spec constructor argument when necessary, rather than defining a new class
Prefix mocked class names with mock, not fake
Prefer pytest fixtures over helper methods in Python tests
Prefer pytest.mark.parametrize over creating individual tests for different input types

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
python/**/{conftest.py,*test*.py}

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

When creating a fixture follow the pattern: @pytest.fixture(name="<fixture_name>"[, scope="<scope>"]) def <fixture_name>_fixture() -> <return_type>: and only specify the scope argument when the value is something other than "function"

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
**/*.py

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

**/*.py: Run Python formatting with uv run ruff format python
Run Python testing with uv run pytest -k "<pattern>"

**/*.py: Use Ruff with rule sets E, F, W, I for Python linting
Use Ruff formatter with line length 120 and double quotes for Python code formatting
Run ty for Python type checking
Use Python snake_case naming convention for Python identifiers
Include SPDX license header in all Python source files using hash comment syntax
Validate Python code with uv run pre-commit run --all-files to enforce Ruff linting and formatting, and ty type checking

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

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

Keep package names, repo references, and build commands current

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
{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:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
**

⚙️ CodeRabbit configuration file

**:

AGENTS.md

This file provides guidance to agents, including Claude Code and OpenAI Codex, when working in this repository.

Project Overview

NeMo Relay is a multi-language agent runtime framework for execution scopes, lifecycle events, middleware, plugins, and observability around tool and LLM calls. The core runtime is Rust. Primary supported bindings are Rust, Python, and Node.js. Go, WebAssembly, and the raw C FFI are experimental and source-first.

The shared runtime model is:

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

Repository Structure

The repository layout separates the Rust runtime, language bindings, documentation,
integration patches, and agent-facing skills.

crates/
  core/       # Rust core runtime crate, published as nemo-relay
  adaptive/   # Adaptive runtime primitives and plugin components
  python/     # PyO3 native extension for the Python package
  ffi/        # Raw C ABI layer used by downstream bindings such as Go
  node/       # NAPI Node.js binding and JavaScript/TypeScript entry points
  wasm/       # wasm-bindgen WebAssembly binding and JS wrappers
python/
  nemo_relay/  # Python wrapper package: scopes, tools, LLM, middleware, typed helpers, plugins, adaptive helpers
  tests/      # Python tests
go/
  nemo_relay/  # Experimental Go CGo binding and tests
fern/         # Fern documentation site
scripts/      # Stable wrappers and helper scripts; build/test/docs entry points live in justfile
third_party/  # P...

Files:

  • python/tests/test_tools.py
  • python/tests/test_llm.py
  • python/tests/test_scope_local.py
🪛 Ruff (0.15.15)
python/tests/test_scope_local.py

[warning] 441-441: Lambda may be unnecessary; consider inlining inner function

Inline function call

(PLW0108)

🔇 Additional comments (3)
python/tests/test_llm.py (1)

644-647: LGTM!

Also applies to: 675-678

python/tests/test_scope_local.py (1)

73-73: LGTM!

Also applies to: 99-99, 133-133, 144-147, 309-309, 437-437, 443-443, 551-551, 563-563, 638-638

python/tests/test_tools.py (1)

136-139: LGTM!


Walkthrough

Adds Rust/Python bindings for constructing AnnotatedLLMResponse, implements LangChainCodec.decode_response to map LangChain ModelResponse into AnnotatedLLMResponse (including finish_reason mapping and tool-call extraction), and expands tests with OTLP collector and end-to-end OpenInference span assertions.

Changes

LangChain Response Decoding and Observability

Layer / File(s) Summary
AnnotatedLLMResponse constructor bindings and test reliability fixes
crates/python/src/py_types/codecs.rs, python/nemo_relay/_native.pyi, python/tests/test_builtin_codecs.py, python/tests/test_llm.py, python/tests/test_scope_local.py, python/tests/test_tools.py
Rust adds optional_py_json() and optional_finish_reason() helpers; PyAnnotatedLLMResponse::new uses them and stores FinishReason; getter maps enum variants to strings. Python stub documents AnnotatedLLMResponse.__init__. Tests validate normalized fields, unknown-finish-reason preservation, and add subscribers.flush()/try/finally cleanup for reliability.
LangChain response codec implementation
python/nemo_relay/integrations/langchain/_serialization.py, python/tests/integrations/langchain_tests/test_middleware.py
Adds LangChainCodec.decode_response() and helpers: _FINISH_REASON_MAP, _model_response_payload_from_json(), content/finish/usage/model/tool-call extractors, and _model_response_to_annotated() to produce AnnotatedLLMResponse. Integration test verifies decoding, finish-reason mapping, usage tokens, and tool-call structure.
Middleware routing and observability validation
python/tests/integrations/deepagents_tests/test_deepagents_integration.py
Introduces local OTLP HTTP collector and span-decoding utilities; adds parametrized middleware routing tests for model/tool execution (sync/async); updates e2e agent invocation (async param) and adds test_e2e_agent_exports_openinference_output_contract asserting OTLP span counts and OpenInference attributes.
Dependencies and attributions
pyproject.toml, ATTRIBUTIONS-Python.md
Adds opentelemetry-proto>=1.39,<2 to test deps; updates ATTRIBUTIONS-Python.md with opentelemetry-proto and protobuf license sections.

Sequence Diagram

sequenceDiagram
  participant DeepAgents
  participant NemoRelayMiddleware
  participant LangChainCodec
  participant AnnotatedLLMResponse
  participant OTLPCollector
  DeepAgents->>NemoRelayMiddleware: invoke(agent request)
  NemoRelayMiddleware->>LangChainCodec: decode_response(ModelResponse JSON)
  LangChainCodec->>LangChainCodec: extract AIMessage, finish_reason, tool_calls, usage
  LangChainCodec->>AnnotatedLLMResponse: new(id, model, message, tool_calls, finish_reason, usage)
  LangChainCodec-->>NemoRelayMiddleware: AnnotatedLLMResponse
  NemoRelayMiddleware->>OTLPCollector: export spans (AGENT/LLM/TOOL with OpenInference attrs)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • NVIDIA/NeMo-Relay#165: Related LangChain codec changes and finish-reason handling in _serialization.py.
  • NVIDIA/NeMo-Relay#207: Related work flattening AnnotatedLLMResponse fields into OpenInference llm.* trace attributes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title follows Conventional Commits format with 'fix' type and concise imperative summary well under 72 characters.
Description check ✅ Passed Description includes all required template sections: Overview with confirmation checkboxes, Details with specific changes, Where to start guidance, and Related Issues with action keywords.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions github-actions Bot added size:L PR is large Bug issue describes bug; PR fixes bug lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code labels Jun 9, 2026
@willkill07 willkill07 self-assigned this Jun 9, 2026
@willkill07 willkill07 added this to the 0.4 milestone Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@ATTRIBUTIONS-Python.md`:
- Around line 3340-3344: Update the attribution generator/template to emit blank
lines before and after headings and fenced code blocks and include a fenced code
language (e.g., use ```text) for LICENSE/code blocks; specifically adjust the
template that renders the `opentelemetry-proto` and `protobuf` sections (and
other similar blocks like the ones at 4508-4512) so each heading is separated by
a blank line, each code fence is preceded by a complete introductory sentence,
and each fence includes a language token (text) to satisfy MD022/MD031/MD040.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 86a4c64c-1684-44a4-bd4d-9bab68fd66fc

📥 Commits

Reviewing files that changed from the base of the PR and between 7d9323c and 641bbee.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • ATTRIBUTIONS-Python.md
  • crates/python/src/py_types/codecs.rs
  • pyproject.toml
  • python/nemo_relay/_native.pyi
  • python/nemo_relay/integrations/langchain/_serialization.py
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/integrations/langchain_tests/test_middleware.py
  • python/tests/test_builtin_codecs.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (32)
**/test_*.{py,py}

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

Relevant integration tests or smoke coverage must exist for the integration path

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
{pyproject.toml,**/*.py}

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

Maintain consistency between Python package names in pyproject.toml and import paths used throughout the codebase

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • pyproject.toml
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
  • python/nemo_relay/integrations/langchain/_serialization.py
**/*.{py,txt,toml,cfg,yaml,yml}

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

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

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • pyproject.toml
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
  • python/nemo_relay/integrations/langchain/_serialization.py
python/**/*test*.py

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

python/**/*test*.py: Do not add @pytest.mark.asyncio to any test in Python test files
Do not add a -> None return type annotation to test functions
When mocking a class, use unittest.mock.MagicMock or unittest.mock.AsyncMock with the spec constructor argument when necessary, rather than defining a new class
Prefix mocked class names with mock, not fake
Prefer pytest fixtures over helper methods in Python tests
Prefer pytest.mark.parametrize over creating individual tests for different input types

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
python/**/{conftest.py,*test*.py}

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

When creating a fixture follow the pattern: @pytest.fixture(name="<fixture_name>"[, scope="<scope>"]) def <fixture_name>_fixture() -> <return_type>: and only specify the scope argument when the value is something other than "function"

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
**/*.py

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

**/*.py: Run Python formatting with uv run ruff format python
Run Python testing with uv run pytest -k "<pattern>"

**/*.py: Use Ruff with rule sets E, F, W, I for Python linting
Use Ruff formatter with line length 120 and double quotes for Python code formatting
Run ty for Python type checking
Use Python snake_case naming convention for Python identifiers
Include SPDX license header in all Python source files using hash comment syntax
Validate Python code with uv run pre-commit run --all-files to enforce Ruff linting and formatting, and ty type checking

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
  • python/nemo_relay/integrations/langchain/_serialization.py
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

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

Keep package names, repo references, and build commands current

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • pyproject.toml
  • ATTRIBUTIONS-Python.md
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
  • python/nemo_relay/integrations/langchain/_serialization.py
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • pyproject.toml
  • crates/python/src/py_types/codecs.rs
  • ATTRIBUTIONS-Python.md
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
  • python/nemo_relay/integrations/langchain/_serialization.py
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • crates/python/src/py_types/codecs.rs
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
  • python/nemo_relay/integrations/langchain/_serialization.py
{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:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
**

⚙️ CodeRabbit configuration file

**:

AGENTS.md

This file provides guidance to agents, including Claude Code and OpenAI Codex, when working in this repository.

Project Overview

NeMo Relay is a multi-language agent runtime framework for execution scopes, lifecycle events, middleware, plugins, and observability around tool and LLM calls. The core runtime is Rust. Primary supported bindings are Rust, Python, and Node.js. Go, WebAssembly, and the raw C FFI are experimental and source-first.

The shared runtime model is:

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

Repository Structure

The repository layout separates the Rust runtime, language bindings, documentation,
integration patches, and agent-facing skills.

crates/
  core/       # Rust core runtime crate, published as nemo-relay
  adaptive/   # Adaptive runtime primitives and plugin components
  python/     # PyO3 native extension for the Python package
  ffi/        # Raw C ABI layer used by downstream bindings such as Go
  node/       # NAPI Node.js binding and JavaScript/TypeScript entry points
  wasm/       # wasm-bindgen WebAssembly binding and JS wrappers
python/
  nemo_relay/  # Python wrapper package: scopes, tools, LLM, middleware, typed helpers, plugins, adaptive helpers
  tests/      # Python tests
go/
  nemo_relay/  # Experimental Go CGo binding and tests
fern/         # Fern documentation site
scripts/      # Stable wrappers and helper scripts; build/test/docs entry points live in justfile
third_party/  # P...

Files:

  • python/tests/integrations/langchain_tests/test_middleware.py
  • pyproject.toml
  • python/nemo_relay/_native.pyi
  • crates/python/src/py_types/codecs.rs
  • ATTRIBUTIONS-Python.md
  • python/tests/integrations/deepagents_tests/test_deepagents_integration.py
  • python/tests/test_builtin_codecs.py
  • python/nemo_relay/integrations/langchain/_serialization.py
**/*.{rs,toml}

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

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • pyproject.toml
  • crates/python/src/py_types/codecs.rs
**/*.toml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • pyproject.toml
{crates/python/src/py_api/**/*.rs,python/nemo_relay/**/*.py,python/nemo_relay/**/*.pyi}

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

Update Python native binding in crates/python/src/py_api/mod.rs with Python wrapper docstring in python/nemo_relay/<module>.py and type stubs in python/nemo_relay/*.pyi modules

Files:

  • python/nemo_relay/_native.pyi
  • python/nemo_relay/integrations/langchain/_serialization.py
python/nemo_relay/**/*

⚙️ CodeRabbit configuration file

python/nemo_relay/**/*: Review Python wrapper changes for typed API consistency, contextvars-based scope isolation, async behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.

Files:

  • python/nemo_relay/_native.pyi
  • python/nemo_relay/integrations/langchain/_serialization.py
**/*.rs

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

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

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

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

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

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

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

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

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

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

Files:

  • crates/python/src/py_types/codecs.rs
**/{Cargo.toml,**/*.rs}

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

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

Files:

  • crates/python/src/py_types/codecs.rs
**/*.{h,hpp,c,cpp,rs}

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

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

Files:

  • crates/python/src/py_types/codecs.rs
crates/python/**/*.rs

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

If the native Rust bridge changed, add the Rust crate tests for nemo-relay-python

Files:

  • crates/python/src/py_types/codecs.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/python/src/py_types/codecs.rs
crates/{python,ffi,node,wasm}/**/*

⚙️ CodeRabbit configuration file

crates/{python,ffi,node,wasm}/**/*: Treat binding changes as public API changes. Check for parity with the other language bindings, FFI ownership/lifetime safety,
callback error propagation, stable type conversion, and consistent async/stream semantics.
Flag changes that update one binding without corresponding tests or documentation for the same surface elsewhere.

Files:

  • crates/python/src/py_types/codecs.rs
**/*.{md,rst,html,txt}

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

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

Files:

  • ATTRIBUTIONS-Python.md
**/*.{md,rst,html}

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

Link the first mention of a product name when the destination helps the reader.

Files:

  • ATTRIBUTIONS-Python.md
**/*.md

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

Documentation must be updated if activation or usage changed

**/*.md: Use title case consistently in technical documentation headings
Avoid quotation marks, ampersands, and exclamation marks in headings
Keep product, event, research, and whitepaper names in their official title case
Use title case for table headers
Do not force social-media sentence case into technical docs
Format code elements, commands, parameters, package names, and expressions in monospace
Format directories, file names, and paths in monospace using backticks
Use angle brackets inside monospace for variables inside paths, such as /home/<username>/.login
Format error messages and strings in quotation marks, keeping literal code strings in code formatting when clearer
Format UI buttons, menus, fields, and labels in bold
Use angle brackets between UI labels for menu paths, such as File > Save As
Use italics for new terms on first use, sparingly and only when introducing the term
Use italics for publication titles
Format keyboard shortcuts in plain text, such as Press Ctrl+Alt+Delete
Use owner/repo link text for GitHub repositories, preferring [NVIDIA/NeMo](link) over prose references like 'the GitHub repo'
Introduce every code block with a complete sentence
Do not make a code block complete the grammar of the previous sentence
Do not continue a sentence after a code block
Use syntax highlighting when the format supports it for code blocks
Avoid the word 'snippet' unless the surrounding docs already use it as a term of art
Keep inline method, function, and class references consistent with nearby docs, omitting empty parentheses for prose readability when no call is shown
Use descriptive anchor text that matches the destination title when possible for links
Avoid raw URLs in running text
Avoid generic anchor text such as 'here,' 'this page,' and 'read more'
Include acronyms in link text when a linked term includes an acronym
Do not link long sentences or multiple sentences
Avoid links ...

Files:

  • ATTRIBUTIONS-Python.md
**/{docs,examples,**/*.md,*.patch,*.diff,.github,*.sh,*.yaml,*.yml}

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

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

Files:

  • ATTRIBUTIONS-Python.md
**/*.{md,rst,txt}

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

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

Files:

  • ATTRIBUTIONS-Python.md
**/*.{md,rst}

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

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

Files:

  • ATTRIBUTIONS-Python.md
{docs/**,README.md,CONTRIBUTING.md,**/*.md}

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

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

Files:

  • ATTRIBUTIONS-Python.md
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

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

Files:

  • ATTRIBUTIONS-Python.md
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • ATTRIBUTIONS-Python.md
python/nemo_relay/**/*.py

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

Use snake_case naming convention for Python identifiers (e.g., nemo_relay.tools.call)

Format changed Python wrapper and test files with uv run ruff format python

Python wrapper modules live under python/nemo_relay/; the native extension is built from crates/python with maturin.

Files:

  • python/nemo_relay/integrations/langchain/_serialization.py
🪛 markdownlint-cli2 (0.22.1)
ATTRIBUTIONS-Python.md

[warning] 3340-3340: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 3344-3344: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 3344-3344: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


[warning] 4508-4508: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 4512-4512: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 4512-4512: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 Ruff (0.15.15)
python/tests/integrations/deepagents_tests/test_deepagents_integration.py

[error] 79-79: Function argument format is shadowing a Python builtin

(A002)


[warning] 84-84: Remove quotes from type annotation

Remove quotes

(UP037)


[warning] 86-86: Remove quotes from type annotation

Remove quotes

(UP037)


[warning] 118-118: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 126-126: Dynamically typed expressions (typing.Any) are disallowed in value

(ANN401)


[warning] 126-126: Dynamically typed expressions (typing.Any) are disallowed in _any_value_to_python

(ANN401)


[warning] 214-214: Boolean-typed positional argument in function definition

(FBT001)


[warning] 223-223: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


[warning] 231-231: Dynamically typed expressions (typing.Any) are disallowed in codec

(ANN401)


[warning] 232-232: Dynamically typed expressions (typing.Any) are disallowed in response_codec

(ANN401)


[warning] 233-233: Dynamically typed expressions (typing.Any) are disallowed in func

(ANN401)


[warning] 234-234: Dynamically typed expressions (typing.Any) are disallowed in _llm_execute

(ANN401)


[warning] 281-281: Boolean-typed positional argument in function definition

(FBT001)


[warning] 291-291: Dynamically typed expressions (typing.Any) are disallowed in func

(ANN401)


[warning] 291-291: Dynamically typed expressions (typing.Any) are disallowed in **_kwargs

(ANN401)


[warning] 444-444: Boolean-typed positional argument in function definition

(FBT001)


[warning] 553-553: Too many statements (56 > 50)

(PLR0915)

python/nemo_relay/integrations/langchain/_serialization.py

[warning] 206-206: Dynamically typed expressions (typing.Any) are disallowed in response

(ANN401)


[warning] 285-285: Dynamically typed expressions (typing.Any) are disallowed in payload

(ANN401)


[warning] 287-287: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 291-291: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 399-399: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (7)
crates/python/src/py_types/codecs.rs (1)

5-5: LGTM!

Also applies to: 24-24, 462-546, 595-601

python/nemo_relay/_native.pyi (1)

495-525: LGTM!

python/tests/test_builtin_codecs.py (1)

125-172: LGTM!

python/nemo_relay/integrations/langchain/_serialization.py (1)

23-23: LGTM!

Also applies to: 35-43, 206-210, 285-294, 320-416

python/tests/integrations/langchain_tests/test_middleware.py (1)

247-299: LGTM!

python/tests/integrations/deepagents_tests/test_deepagents_integration.py (1)

8-173: LGTM!

Also applies to: 212-331, 442-551, 553-651

pyproject.toml (1)

58-58: Confirm opentelemetry-proto constraint is compatible with ExportTraceServiceRequest

pyproject.toml (line 58) adds:

"opentelemetry-proto>=1.39,<2",

The test imports ExportTraceServiceRequest from opentelemetry.proto.collector.trace.v1.trace_service_pb2, and opentelemetry-proto==1.39.1 includes class ExportTraceServiceRequest in that module path—so >=1.39,<2 is compatible.

Comment thread ATTRIBUTIONS-Python.md
Signed-off-by: Will Killian <wkillian@nvidia.com>
Signed-off-by: Will Killian <wkillian@nvidia.com>
@github-actions github-actions Bot added size:XL PR is extra large and removed size:L PR is large labels Jun 9, 2026

@Salonijain27 Salonijain27 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved from a dependency point of view

@willkill07

Copy link
Copy Markdown
Member Author

/merge

@rapids-bot rapids-bot Bot merged commit 39bfd5f into NVIDIA:main Jun 10, 2026
40 checks passed
@willkill07 willkill07 deleted the fix/relay-198-199 branch June 15, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug issue describes bug; PR fixes bug lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code size:XL PR is extra large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants