Skip to content

feat: Improve Hermes Relay hook injection and event alignment#205

Merged
rapids-bot[bot] merged 11 commits into
NVIDIA:mainfrom
yczhang-nv:codex/nat-294-relay-telemetry
Jun 3, 2026
Merged

feat: Improve Hermes Relay hook injection and event alignment#205
rapids-bot[bot] merged 11 commits into
NVIDIA:mainfrom
yczhang-nv:codex/nat-294-relay-telemetry

Conversation

@yczhang-nv

@yczhang-nv yczhang-nv commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Overview

Adds Relay-side support needed for NVIDIA NeMo Agent Toolkit to consume Hermes Relay telemetry.

This change:

  • Updates transparent Hermes Relay runs to temporarily patch Hermes hook config, route events to the local Relay gateway, and restore the original config afterward.
  • Improves Hermes session alignment by correlating task-scoped tool events back to the owning Hermes session.
  • Handles Hermes pre/post tool hook ID mismatches by matching active tools by name and arguments when provider tool IDs differ.

Why

Hermes invokes hooks from its own config and can execute through a different process boundary than the caller. For NeMo Agent Toolkit integration, Relay needs to capture Hermes lifecycle events reliably and make them available as replayable ATOF JSONL so the toolkit can import them into its telemetry stream.

Details

Where should the reviewer start?

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

  • Closes #

Summary by CodeRabbit

  • New Features

    • Hermes hook lifecycle: backup, patch, restore (dry-run supported); restores on failed runs/health checks.
    • Improved tool tracking retains tool name, arguments, and owner context for better correlation.
    • Better LLM/response parsing and span de-duplication for observability exports.
  • Bug Fixes

    • Hermes task→session routing and lifecycle cleanup corrected to avoid duplicate sessions and stale mappings.
    • More robust tool-end resolution with owner-context matching.
  • Tests

    • New unit/integration tests covering Hermes hooks, routing, tool correlation, and observability dedupe.
  • Documentation

    • Readme, CLI, Hermes, Cursor, integrations, and release notes updated; Node/WebAssembly/Python examples call out subscriber flush and Node.js 24+ requirement.

@yczhang-nv yczhang-nv requested a review from a team as a code owner June 3, 2026 01:05
@yczhang-nv yczhang-nv self-assigned this Jun 3, 2026
@github-actions github-actions Bot added size:L PR is large lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code labels Jun 3, 2026
@coderabbitai

coderabbitai Bot commented Jun 3, 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

Adds Hermes task→session correlation and routing, per-tool ActiveTool tracking for robust end-event matching, Hermes hook backup/merge/restore in launcher runs, LLM span de-duplication and metric merging in ATIF, Node API main-thread Arg0 builders, many tests, and documentation/workflow updates.

Changes

Hermes Task-Session Correlation and Tool-ID Resilience

Layer / File(s) Summary
Hermes Task-Session State and Extraction Utilities
crates/cli/src/alignment/mod.rs
SessionAlignmentState adds hermes_task_sessions HashMap for task-to-session mappings; extraction helpers parse task ids and optional session scope from Hermes provider payloads/metadata and JSON paths.
Hermes Routing Integration into Event Flow
crates/cli/src/alignment/mod.rs
route_event records Hermes task-session mappings and rewrites Hermes ToolStarted/ToolEnded events via task lookup before continuing alias-based routing; lifecycle pruning removes mappings on agent/subagent end.
Hermes adapter correlatability guard
crates/cli/src/adapters/hermes.rs
Adapter emits nothing and returns empty response for uncorrelatable Hermes pre_tool_call payloads; helper functions validate required session/tool identifiers.
Active Tool State with Name and Arguments
crates/cli/src/session.rs
Session.tools now stores ActiveTool { handle, name, arguments, owner_subagent_id }. start_tool records resolved args and owner; end_tool uses remove_tool_handle_for_event fallback matching by tool_call_id or unique (tool_name, exact_arguments) within owner context.
Hermes Hook Lifecycle Management
crates/cli/src/launcher.rs
Launcher adds HermesRestore and hermes_restore in PreparedRun; prepare_hermes backs up and merges .hermes/config.yaml (via merge_hermes_config), sets HERMES_ACCEPT_HOOKS, and records restore state; PreparedRun::restore restores Cursor and Hermes hooks with shared helper.
Hermes Integration and Tool-Matching Tests
crates/cli/tests/coverage/*
Adds/updates tests validating Hermes hook patching and restoration, uncorrelatable pre_tool_call suppression, Hermes task-session routing with/without explicit parent session, tool-id mismatch handling, and launcher restore on gateway health failure.

Observability: ATIF & OpenInference

Layer / File(s) Summary
LLM span de-duplication & metric merging
crates/core/src/observability/atif.rs, crates/core/tests/*
New LLM dedupe subsystem collects span candidates, computes signatures, suppresses lower-fidelity overlapping spans, merges supplemental metrics into canonical spans, and skips suppressed events during step conversion; multiple unit tests added to validate dedupe behavior.
Anthropic messages & tool promotion
crates/core/src/observability/atif.rs, crates/core/tests/unit/atif_tests.rs
Detect Anthropic messages payloads, aggregate content blocks, promote tool_use blocks into tool_calls, and accept args/input alt fields; update tool_call_extra recognized keys.
OpenInference display & cache-read handling
crates/core/src/observability/openinference.rs, tests
Cache-read token extraction extended to nested *_details.cached_tokens; prefer OpenAI Responses-style output parsing and synthesize “Requested tools” from function calls; tests added/updated accordingly.

Node API: main-thread Arg0 and with_scope

Layer / File(s) Summary
PrimaryArg / Arg0Builder plumbing
crates/node/src/promise_call.rs
Introduce Arg0Builder type and PrimaryArg to allow building the first JS callback argument on the main thread; add call_with_arg0 public API and update TSFN payload shape.
with_scope forwarding real ScopeHandle
crates/node/src/api/mod.rs, crates/node/tests/scope_tests.mjs
with_scope now passes a real ScopeHandle via call_with_arg0; tests validate the received handle works as event target, parent for child scopes, and execution scope for tool/LLM calls.
JS/WASM examples
crates/node/README.md, crates/wasm/README.md
Examples updated to include flushSubscribers and call it after scope usage to flush async subscriber delivery.

OpenClaw integration & replay tests

Layer / File(s) Summary
Provider usage normalization
integrations/openclaw/src/hook-replay/llm.ts, tests
mapUsage accepts more alias keys and nested cached-token paths; adds nestedNumberField; tests added for Anthropic/OpenAI replay normalization.

Docs, workflows, and scripts

Layer / File(s) Summary
Fern docs workflow & sync script
.github/workflows/fern-docs.yml, scripts/docs/sync_fern_docs_branch.py
Increase release job timeout; checkout workflow tools separately; pin source checkout to release tag; add Rust/Python/setup steps and source API generation; run sync script from workflow-checkout; sync_fern_docs_branch.py now accepts --source-root and snapshots source_root/docs.
Release notes, MDX docs, READMEs, redirects
docs/**, README.md, AGENTS.md, fern/docs.yml
Major release-notes content added, support matrix updates, small wording changes across many docs, README updates (Node.js requirement, ATIF v1.7), CODE_OF_CONDUCT header update, and a fern redirects entry.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • NVIDIA/NeMo-Relay#195: Shares related fern docs workflow checkout and running sync flow from workflow-checkout.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@yczhang-nv yczhang-nv added Improvement improvement to existing functionality and removed lang:rust PR changes/introduces Rust code lang:python PR changes/introduces Python code labels Jun 3, 2026
@github-actions github-actions Bot added lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code and removed Improvement improvement to existing functionality labels Jun 3, 2026
@yczhang-nv yczhang-nv changed the title Add NAT telemetry export support for Hermes Relay runs feat: Add NAT telemetry export support for Hermes Relay runs Jun 3, 2026
@github-actions github-actions Bot added the Feature a new feature label Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 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: 5

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

Inline comments:
In `@crates/cli/src/alignment/mod.rs`:
- Line 113: hermes_task_sessions is keyed only by task_id, so
record_hermes_task_session and route_hermes_task_event can collide across
sessions; change the storage to be collision-resistant by including session
scope in the key (e.g., use a composite key session_id + task_id or make
hermes_task_sessions a HashMap<session_id, HashMap<task_id, session_id_or_meta>>
/ nested map) and update record_hermes_task_session and route_hermes_task_event
to read/write using that composite/session-scoped key so entries cannot be
overwritten when different sessions reuse the same task_id.

In `@crates/cli/src/launcher.rs`:
- Around line 466-483: prepare_hermes currently mutates the user's Hermes config
during PreparedRun::new which can leave config.yaml patched if execute_live_run
returns early on failed health checks; update the flow so we either defer
calling prepare_hermes (or the write_merged_hermes_hooks step) until after
wait_for_health succeeds in execute_live_run, or ensure PreparedRun::restore is
always invoked on every early-return path from execute_live_run (add
try/finally-like cleanup or explicit restore on error paths). Refer to
prepare_hermes, write_merged_hermes_hooks, execute_live_run, wait_for_health,
and PreparedRun::restore to locate and implement the change.

In `@crates/cli/src/session.rs`:
- Around line 129-134: ActiveTool currently only stores handle, name, and
arguments so identical name+args from different subagents get conflated; add a
resolved owner/subagent identity field (e.g., owner or subagent_id) to the
ActiveTool struct and populate it wherever ActiveTool instances are created (the
synthetic start path and any start_tool constructors), update derives as needed,
and change the fallback/matching logic in end_tool (and the analogous code at
the other referenced range) to require the owner/subagent to match before
considering a name+args fallback so the real handle for a different subagent is
not left open.

In `@crates/cli/tests/coverage/session_tests.rs`:
- Around line 1615-1634: The pre/post tool-call test is vacuous because the
pre_tool_call JSON uses an empty session_id and can be filtered out, so the
subsequent assertion on session.tools.is_empty() doesn't prove mismatched
tool_call_id handling; update the test to make the pre_tool_call and
post_tool_call belong to a real session (non-empty session_id) and split the
test into phases: after injecting the pre_tool_call assert
!session.tools.is_empty() (e.g., session.tools.len() > 0), then inject the
post_tool_call with a different tool_call_id and assert session.tools.is_empty()
to verify the mismatch causes the tool to be removed; apply the same change
pattern to the other occurrence referenced (the block around the second instance
at the later lines).

In `@python/nemo_relay/nat_exporter.py`:
- Around line 40-47: The subscriber() currently reopens the file on every event
causing syscall overhead; instead open a single append handle in __init__ (e.g.
self._output = self._path.open("a")) and reuse it in subscriber() to write
_event_to_json(event) + "\n", calling self._output.flush() after each write for
durability; keep the existing self._lock and self._closed checks in
subscriber(), and close/cleanup the handle in shutdown() (and guard against
double-close) so the file is only opened once and closed on shutdown.
🪄 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: 539e1bb4-0a60-4cd1-880a-82c4de95efd0

📥 Commits

Reviewing files that changed from the base of the PR and between b85bd24 and 49893ec.

📒 Files selected for processing (9)
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • python/nemo_relay/README.md
  • python/nemo_relay/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/tests/test_nat_exporter.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (29)
**/*.rs

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

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

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

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

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

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

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

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

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

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

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/launcher.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/src/alignment/mod.rs
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • python/tests/test_nat_exporter.py
  • crates/cli/tests/coverage/launcher_tests.rs
**/{Cargo.toml,**/*.rs}

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

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

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/launcher.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/src/alignment/mod.rs
**/*.{h,hpp,c,cpp,rs}

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

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

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/launcher.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/src/alignment/mod.rs
**/*.{rs,toml}

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

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/launcher.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/src/alignment/mod.rs
**/*.{rs,py,js,ts,tsx,jsx,go,sh,toml,yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • python/nemo_relay/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/tests/test_nat_exporter.py
  • python/nemo_relay/README.md
  • crates/cli/src/launcher.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/src/alignment/mod.rs
**/*.{rs,py,go,js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • python/nemo_relay/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/tests/test_nat_exporter.py
  • crates/cli/src/launcher.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/src/alignment/mod.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • crates/cli/src/launcher.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/session.rs
  • crates/cli/src/alignment/mod.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}: Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.
Prefer assertions on lifecycle events, scope stacks, middleware ordering, and binding parity over shallow smoke tests.

Files:

  • crates/cli/tests/coverage/session_tests.rs
  • python/tests/test_nat_exporter.py
  • crates/cli/tests/coverage/launcher_tests.rs
{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/__init__.py
  • python/nemo_relay/nat_exporter.py
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/__init__.py
  • python/nemo_relay/nat_exporter.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/nemo_relay/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/tests/test_nat_exporter.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/nemo_relay/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/tests/test_nat_exporter.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/nemo_relay/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/tests/test_nat_exporter.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/nemo_relay/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/tests/test_nat_exporter.py
  • python/nemo_relay/README.md
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/__init__.py
  • python/nemo_relay/nat_exporter.py
  • python/nemo_relay/README.md
**/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_nat_exporter.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_nat_exporter.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_nat_exporter.py
**/*.{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:

  • python/nemo_relay/README.md
**/*.{md,rst,html}

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

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

Files:

  • python/nemo_relay/README.md
**/*.md

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

Documentation must be updated if activation or usage changed

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

Files:

  • python/nemo_relay/README.md
**/{docs,examples,**/*.md,*.patch,*.diff,.github,*.sh,*.yaml,*.yml}

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

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

Files:

  • python/nemo_relay/README.md
**/*.{md,rst,txt}

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

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

Files:

  • python/nemo_relay/README.md
**/*.{md,rst}

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

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

Files:

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

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

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

Files:

  • python/nemo_relay/README.md
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

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

Files:

  • python/nemo_relay/README.md
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • python/nemo_relay/README.md
**/README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant crate or package README when that surface changed

Files:

  • python/nemo_relay/README.md
🪛 Ruff (0.15.15)
python/nemo_relay/nat_exporter.py

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

(TRY003)

python/tests/test_nat_exporter.py

[warning] 41-41: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)

🔇 Additional comments (7)
python/nemo_relay/nat_exporter.py (3)

23-33: LGTM!


49-68: LGTM!


71-76: LGTM!

python/nemo_relay/__init__.py (1)

27-28: LGTM!

Also applies to: 192-201, 431-464

python/nemo_relay/README.md (1)

188-210: LGTM!

python/tests/test_nat_exporter.py (2)

40-41: LGTM!


14-37: ⚡ Quick win

Confirm scope_category end discriminant — Canonical ScopeEvent JSON includes a scope_category field and emits "scope_category": "end" for the pop/end event (e.g., crates/core/tests/unit/types_tests.rs and crates/ffi/tests/integration/api_tests.rs assert "scope_category" == "end"), so assert lines[2]["scope_category"] == "end" matches the real serialization.

Comment thread crates/cli/src/alignment/mod.rs Outdated
Comment thread crates/cli/src/launcher.rs
Comment thread crates/cli/src/session.rs
Comment thread crates/cli/tests/coverage/session_tests.rs
Comment thread python/nemo_relay/nat_exporter.py Outdated
willkill07
willkill07 previously approved these changes Jun 3, 2026

@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.

The improvements are more representative than the added exporter. Could the PR title be updated accordingly?

Otherwise, my only feedback is related to the added exporter and what value it adds over the existing AtofExporter.

Conditionally approving.

Comment thread python/nemo_relay/nat_exporter.py Outdated
@github-actions github-actions Bot removed the lang:python PR changes/introduces Python code label Jun 3, 2026
@yczhang-nv yczhang-nv changed the title feat: Add NAT telemetry export support for Hermes Relay runs feat: Improve Hermes Relay hook injection and event alignment Jun 3, 2026
@yczhang-nv yczhang-nv force-pushed the codex/nat-294-relay-telemetry branch from 73d3761 to b1df460 Compare June 3, 2026 04:10
@github-actions github-actions Bot added size:XL PR is extra large lang:js PR changes/introduces Javascript/Typescript code lang:python PR changes/introduces Python code and removed size:L PR is large labels Jun 3, 2026

@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: 5

🤖 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 @.github/workflows/fern-docs.yml:
- Around line 377-378: Add an explanatory comment above the job-level
permissions block so reviewers know why contents: write is required;
specifically, update the permissions block that contains "permissions:" and
"contents: write" to include a short comment explaining the reason (e.g., token
usage for pushing docs or updating releases) and any security scope constraints.

In `@crates/cli/src/session.rs`:
- Around line 1605-1633: The matcher currently restricts to root-owned tools
when owner resolution returns None, causing a root-biased fallback; modify
matching_active_tool_key so the owner check only applies when owner_subagent_id
is Some: in matching_active_tool_key (used by remove_tool_handle_for_event)
change the filter closure to require active.owner_subagent_id ==
owner_subagent_id only when owner_subagent_id.is_some(), otherwise ignore
owner_subagent_id and match on name and arguments across all owners, then keep
the existing uniqueness check (matches.len() == 1) to return a single global
match.

In `@crates/cli/tests/coverage/adapters_tests.rs`:
- Around line 312-320: The test drops_uncorrelatable_hermes_pre_tool_call
currently omits both session_id and tool_call_id so it can pass when only one
correlatability gate exists; change the test input passed to hermes::adapt to
include a valid tool_call_id (e.g. "tool_call_id": "toolcall-1") while keeping
session_id omitted so the test isolates the missing-session correlatability
check and still expects the adapter to drop the event.

In `@crates/core/src/observability/atif.rs`:
- Around line 1327-1329: The current llm_response_signature function reduces the
signature to only the extracted message text (via extract_llm_response_message),
which causes different tool-call/raw-response structures — including tool-only
Anthropic responses that become empty strings — to be treated as identical;
update llm_response_signature to include the full promoted tool-call/raw
response structure (or a stable request correlation key when available) in the
returned signature so that tool invocations and raw response metadata are part
of the uniqueness check used by same_physical_llm_request; locate
llm_response_signature and include either the promoted tool call fields or a
correlation id from the response (and apply the same change to the other
occurrences noted around the commented ranges) so signature-only suppression no
longer collapses distinct calls.

In `@integrations/openclaw/src/hook-replay/llm.ts`:
- Around line 1197-1202: The cacheRead normalization currently misses top-level
fields named cached_tokens (and camelCase cachedTokens), causing cache-read
metrics to be dropped; update the cacheRead resolution in the llm replay
normalization to check for numberField(usage, 'cached_tokens') and
numberField(usage, 'cachedTokens') (prior to or alongside the other fallbacks)
so that usage objects already using the canonical NeMo Relay name or camelCase
variant are preserved; locate the cacheRead variable assignment and add those
checks to the existing chain that uses numberField(...) and
nestedNumberField(...).
🪄 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: 862a7d2a-a412-4c2a-8780-757a946da69f

📥 Commits

Reviewing files that changed from the base of the PR and between d53e2ca and b1df460.

📒 Files selected for processing (53)
  • .github/CODE_OF_CONDUCT.md
  • .github/nightly-alpha-branches.yaml
  • .github/workflows/fern-docs.yml
  • AGENTS.md
  • README.md
  • crates/cli/src/adapters/hermes.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/src/doctor.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/node/README.md
  • crates/node/src/api/mod.rs
  • crates/node/src/promise_call.rs
  • crates/node/tests/scope_tests.mjs
  • crates/wasm/README.md
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/about-nemo-relay/release-notes/related-topics.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/build-plugins/validate-configuration.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/reference/performance.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/supported-integrations/about.mdx
  • docs/supported-integrations/openclaw-plugin.mdx
  • fern/docs.yml
  • go/nemo_relay/README.md
  • integrations/coding-agents/README.md
  • integrations/coding-agents/cursor/README.md
  • integrations/openclaw/README.md
  • integrations/openclaw/src/hook-replay/llm.ts
  • integrations/openclaw/test/llm-replay.test.ts
  • python/nemo_relay/README.md
  • scripts/docs/sync_fern_docs_branch.py
💤 Files with no reviewable changes (3)
  • docs/about-nemo-relay/release-notes/related-topics.mdx
  • .github/nightly-alpha-branches.yaml
  • integrations/coding-agents/README.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (54)
{docs/**,README.md,CONTRIBUTING.md}

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

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
{docs/**,README.md,CONTRIBUTING.md,**/*.md}

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

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • integrations/coding-agents/cursor/README.md
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • crates/node/README.md
  • crates/wasm/README.md
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
{docs/**,README.md}

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

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
{docs/**,examples/**,README.md}

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

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
{docs/**,README.md,**/Cargo.toml,**/package.json,**/*.md}

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

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • integrations/coding-agents/cursor/README.md
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • crates/node/README.md
  • crates/wasm/README.md
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
**/*.{md,mdx,py,sh,yaml,yml,toml,json}

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

Keep package names, repo references, and build commands current

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • integrations/coding-agents/cursor/README.md
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • crates/node/README.md
  • crates/wasm/README.md
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • integrations/openclaw/README.md
  • AGENTS.md
  • fern/docs.yml
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • scripts/docs/sync_fern_docs_branch.py
  • docs/about-nemo-relay/release-notes/index.mdx
**/*.mdx

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

In MDX files, top-of-file comments must use JSX comment delimiters: {/* to open and */} to close. Do not use HTML comments for MDX SPDX headers.

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
**/*.{html,md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • integrations/coding-agents/cursor/README.md
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • crates/node/README.md
  • crates/wasm/README.md
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
docs/**/*.{md,mdx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
docs/**

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
{docs/**,README.md,CONTRIBUTING.md,RELEASING.md,SECURITY.md}

⚙️ CodeRabbit configuration file

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

Files:

  • docs/build-plugins/validate-configuration.mdx
  • docs/nemo-relay-cli/about.mdx
  • docs/supported-integrations/about.mdx
  • docs/nemo-relay-cli/hermes.mdx
  • docs/about-nemo-relay/ecosystem.mdx
  • docs/getting-started/quick-start/index.mdx
  • docs/reference/performance.mdx
  • docs/integrate-into-frameworks/non-serializable-data.mdx
  • docs/about-nemo-relay/release-notes/highlights.mdx
  • docs/integrate-into-frameworks/about.mdx
  • docs/resources/support-and-faqs.mdx
  • docs/nemo-relay-cli/cursor.mdx
  • docs/about-nemo-relay/concepts/subscribers.mdx
  • README.md
  • docs/supported-integrations/openclaw-plugin.mdx
  • docs/about-nemo-relay/release-notes/known-issues.mdx
  • docs/build-plugins/register-behavior.mdx
  • docs/about-nemo-relay/release-notes/index.mdx
**/*.{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:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
**/*.{md,rst,html}

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

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

Files:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
**/*.md

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

Documentation must be updated if activation or usage changed

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

Files:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
**/{docs,examples,**/*.md,*.patch,*.diff,.github,*.sh,*.yaml,*.yml}

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

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

Files:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • AGENTS.md
  • fern/docs.yml
  • README.md
**/*.{md,rst,txt}

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

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

Files:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
**/*.{md,rst}

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

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

Files:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • AGENTS.md
  • README.md
**/README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant crate or package README when that surface changed

Files:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • README.md
**/*.{rs,py,js,ts,tsx,jsx,go,toml,yaml,yml,md,sh,bash,json}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • python/nemo_relay/README.md
  • go/nemo_relay/README.md
  • integrations/coding-agents/cursor/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • integrations/openclaw/README.md
  • AGENTS.md
  • crates/cli/src/doctor.rs
  • fern/docs.yml
  • crates/cli/tests/coverage/doctor_tests.rs
  • README.md
  • crates/cli/src/adapters/hermes.rs
  • integrations/openclaw/src/hook-replay/llm.ts
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • integrations/openclaw/test/llm-replay.test.ts
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/cli/src/launcher.rs
  • scripts/docs/sync_fern_docs_branch.py
  • crates/cli/src/session.rs
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/README.md
{crates/adaptive/**,python/nemo_relay/plugin.py,go/nemo_relay/**,**/node/**,**/wasm/**}

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

{crates/adaptive/**,python/nemo_relay/plugin.py,go/nemo_relay/**,**/node/**,**/wasm/**}: Maintain consistent plugin lifecycle across all language bindings (Python, Go, Node/WebAssembly, and Rust)
Keep plugin context surfaces aligned across all language implementations

Files:

  • go/nemo_relay/README.md
  • crates/node/README.md
  • crates/wasm/README.md
  • crates/node/tests/scope_tests.mjs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
go/nemo_relay/**/*

⚙️ CodeRabbit configuration file

go/nemo_relay/**/*: Review Go binding changes for cgo memory ownership, race safety, callback cleanup, idiomatic exported APIs, and parity with Rust/FFI behavior.
Any API change should include focused Go tests and consider race-test behavior.

Files:

  • go/nemo_relay/README.md
docs/reference/**

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update relevant reference documentation for any public API changes

Files:

  • docs/reference/performance.mdx
{crates/adaptive/**,python/nemo_relay/adaptive.py,python/nemo_relay/plugin.py,go/nemo_relay/adaptive/**,go/nemo_relay/!(adaptive)/**,**/node/**,**/wasm/**}

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

Keep adaptive surface in sync across crates/adaptive, shared plugin behavior in core and bindings, Python adaptive/plugin wrappers in python/nemo_relay/adaptive.py and python/nemo_relay/plugin.py, Go adaptive helpers under go/nemo_relay/adaptive plus shared plugin helpers in go/nemo_relay, and Node/WebAssembly adaptive helpers and plugin wrappers

Files:

  • crates/node/README.md
  • crates/wasm/README.md
  • crates/node/tests/scope_tests.mjs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.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/node/README.md
  • crates/wasm/README.md
  • crates/node/tests/scope_tests.mjs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
AGENTS.md

📄 CodeRabbit inference engine (CLAUDE.md)

Document agent implementations in AGENTS.md with clear descriptions of functionality and usage

Files:

  • AGENTS.md
{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}

⚙️ CodeRabbit configuration file

{.github/**,.gitlab-ci.yml,.pre-commit-config.yaml,justfile,scripts/**}: Review automation changes for reproducibility, pinned versions where appropriate, secret handling, and consistency with the documented validation matrix.
Pay attention to commands that need generated native artifacts, FFI libraries, or platform-specific environment variables.

Files:

  • .github/CODE_OF_CONDUCT.md
  • .github/workflows/fern-docs.yml
  • scripts/docs/sync_fern_docs_branch.py
**/{crates/**/*.rs,python/**/*.py,crates/ffi/**/*.{h,c},go/**/*.go,crates/node/**/*.{js,ts,mjs}}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • crates/node/tests/scope_tests.mjs
  • crates/cli/src/doctor.rs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/src/adapters/hermes.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.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/node/tests/scope_tests.mjs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/alignment_tests.rs
**/*.rs

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

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

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

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

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

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

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

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

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

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

Files:

  • crates/cli/src/doctor.rs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/src/adapters/hermes.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.rs
**/{Cargo.toml,**/*.rs}

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

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

Files:

  • crates/cli/src/doctor.rs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/src/adapters/hermes.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.rs
**/*.{h,hpp,c,cpp,rs}

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

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

Files:

  • crates/cli/src/doctor.rs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/src/adapters/hermes.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.rs
**/*.{rs,toml}

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

Update Rust crate names and module prefixes during coordinated rename operations

Files:

  • crates/cli/src/doctor.rs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/src/adapters/hermes.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.rs
crates/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Use Json = serde_json::Value in Rust-facing runtime APIs where the existing code expects JSON payloads.

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

Keep async behavior on the existing tokio-based model. Bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/cli/src/doctor.rs
  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/src/adapters/hermes.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/src/alignment/mod.rs
  • crates/cli/tests/coverage/alignment_tests.rs
  • crates/core/src/observability/atif.rs
  • crates/cli/src/launcher.rs
  • crates/cli/src/session.rs
**/*.{py,txt,toml,cfg,yaml,yml}

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

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

Files:

  • fern/docs.yml
  • scripts/docs/sync_fern_docs_branch.py
{README.md,docs/**/*.{md,rst,txt},fern/**/*}

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

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

Files:

  • fern/docs.yml
  • README.md
{crates/adaptive/**/*.rs,**/*test*.{rs,py,go,ts,js},**/*adaptive*test*.{rs,py,go,ts,js},docs/plugins/adaptive/**}

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

Maintain documented and tested validation and report behavior for adaptive surfaces

Files:

  • crates/cli/tests/coverage/doctor_tests.rs
  • crates/cli/tests/coverage/adapters_tests.rs
  • crates/cli/tests/coverage/gateway_tests.rs
  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/cli/tests/coverage/session_tests.rs
  • integrations/openclaw/test/llm-replay.test.ts
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/cli/tests/coverage/launcher_tests.rs
  • crates/cli/tests/coverage/alignment_tests.rs
{README.md,docs/getting-started/**/*.md}

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

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

Files:

  • README.md
README.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • README.md
**/*.{wasm,js,ts}{,x}

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

Ensure WebAssembly package naming conventions are consistent with generated package expectations and downstream consumption

Files:

  • integrations/openclaw/src/hook-replay/llm.ts
  • integrations/openclaw/test/llm-replay.test.ts
**/*.{js,ts,jsx,tsx}

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

Run Node.js formatting with npm run format --workspace=nemo-relay-node

Include SPDX license header in all JavaScript and TypeScript source files using double-slash comment syntax

Files:

  • integrations/openclaw/src/hook-replay/llm.ts
  • integrations/openclaw/test/llm-replay.test.ts
crates/node/src/**/*.rs

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

Use camelCase naming convention for Node.js identifiers (e.g., toolCall)

Files:

  • crates/node/src/promise_call.rs
  • crates/node/src/api/mod.rs
crates/node/src/api/**/*.rs

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

Update Node.js binding in crates/node/src/api/mod.rs for language-native bindings

Files:

  • crates/node/src/api/mod.rs
{crates/core,crates/adaptive}/**/*

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

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

Files:

  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/core/src/observability/atif.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

Files:

  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/core/src/observability/atif.rs
crates/{core,adaptive}/**

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

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

Files:

  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/core/src/observability/atif.rs
crates/{core,adaptive}/**/*.rs

⚙️ CodeRabbit configuration file

crates/{core,adaptive}/**/*.rs: Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.
Pay close attention to task-local/thread-local scope propagation, callback lifetimes, stream finalization, and root_uuid isolation.
Public API changes should preserve existing behavior unless tests and docs show the intended migration path.

Files:

  • crates/core/tests/unit/observability/openinference_tests.rs
  • crates/core/tests/unit/observability/atof_tests.rs
  • crates/core/src/observability/openinference.rs
  • crates/core/tests/unit/atif_tests.rs
  • crates/core/src/observability/atif.rs
**/*{test,spec,smoke}.{js,ts,py}

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

Relevant integration tests or smoke path must pass

Files:

  • integrations/openclaw/test/llm-replay.test.ts
crates/core/src/observability/{atif,otel,openinference}.rs

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

When changing event fields in ATIF, OpenTelemetry, or OpenInference observability surfaces, keep the core event model in crates/core/src/observability/atif.rs, crates/core/src/observability/otel.rs, and crates/core/src/observability/openinference.rs in sync

Files:

  • crates/core/src/observability/openinference.rs
  • crates/core/src/observability/atif.rs
.github/workflows/*.{yml,yaml}

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

.github/workflows/*.{yml,yaml}: Put permissions: on each job that needs token access in GitHub Actions workflows
Avoid workflow-level permissions unless the repository intentionally centralizes them and the inheritance tradeoff is documented
Keep third-party actions pinned to full commit SHAs and preserve the readable version comment after the SHA
Prefer action-native or ecosystem-native caching over generic actions/cache
Use lockfiles or dependency manifests to drive cache invalidation in GitHub Actions workflows
Keep deploy and publish permissions isolated to the jobs that need them in GitHub Actions
Read both caller and callee when a workflow uses workflow_call in GitHub Actions
Put release-tag validation in the earliest practical caller job when the pipeline has tag-based publish behavior
Keep release-tag policy aligned with RELEASING.md: raw SemVer tags only, no leading v
contents: read is the default minimum permission for checkout-based build, test, docs, and packaging jobs
pull-requests: read is required for PR metadata lookup jobs in GitHub Actions workflows
pages: write and id-token: write should be limited to Pages deployment jobs and callers that invoke them through reusable workflows
For reusable workflows, the caller must grant every permission the called jobs require; the callee cannot elevate beyond what the caller provides
Prefer astral-sh/setup-uv cache support with cache-dependency-glob anchored to uv.lock
Prefer Swatinem/rust-cache with explicit shared-key and workspaces instead of ad hoc target-directory caching
Avoid caching generated outputs that can hide stale behavior unless the repo already relies on them deliberately

Files:

  • .github/workflows/fern-docs.yml
.{github/workflows/*.{yml,yaml},gitlab-ci.yml}

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

Ensure CI workflows reference the same package names, install commands, and build commands as local development workflows

Files:

  • .github/workflows/fern-docs.yml
{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:

  • scripts/docs/sync_fern_docs_branch.py
{scripts/**,third-party/**}

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

{scripts/**,third-party/**}: For third-party integration or patch changes, run patch validation with ./scripts/apply-patches.sh --check and relevant integration tests. Keep root ./scripts/*.sh wrappers for third-party flows
Run third-party patch bootstrap with ./scripts/bootstrap-third-party.sh
Run third-party patch validation with ./scripts/apply-patches.sh --check

Files:

  • scripts/docs/sync_fern_docs_branch.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:

  • scripts/docs/sync_fern_docs_branch.py
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Do not hand-edit generated or packaged outputs unless the repository workflow expects them to be checked in. Regenerate through the documented recipe or script.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Prefer the repository `just` recipes over raw tool commands. Use raw `cargo`, `pytest`, `go test`, `npm`, or `wasm-pack` commands only for focused debugging or targeted single-test reruns.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Run tests for every language affected by a change. If you touch the Rust core runtime, middleware semantics, event shape, scope behavior, typed codecs, plugins, or observability, validate every affected binding.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Before review, prefer `uv run pre-commit run --all-files` when the change crosses languages or tooling.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Preserve the shared runtime model across bindings. Do not add behavior to one primary binding without considering Rust, Python, and Node.js parity.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Prefer documented public APIs and stable wrapper commands. Do not rely on internal helpers in examples or user-facing docs.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Keep primary documentation focused on Rust, Python, and Node.js. Treat Go, WebAssembly, and raw FFI as experimental and source-first unless binding-support guidance changes.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Update `README.md`, `fern/`, package READMEs, and binding-support notes when public behavior, package names, examples, or supported bindings change.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Keep release-process details in maintainer docs such as `RELEASING.md`. Do not move release-history policy into user-facing docs or `CHANGELOG.md`.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Keep stable public wrappers at the `scripts/` root in docs and examples. Reference namespaced helper paths only when documenting internal maintenance work.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Use branch prefixes from the contributor docs: `feat/`, `fix/`, `docs/`, `test/`, or `refactor/`.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Use signed-off commits for PR work: `git commit -s`.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: Before creating, opening, publishing, or editing a pull request, read `.github/pull_request_template.md` and use it as the PR body skeleton. Preserve its visible headings, checklist items, and related-issue guidance.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: PR descriptions should include what changed, why, how it was tested, and any breaking changes within the repository template format.
Learnt from: CR
Repo: NVIDIA/NeMo-Relay

Timestamp: 2026-06-03T04:11:40.730Z
Learning: If repo-local PR guidance conflicts with generic GitHub connector or plugin guidance, follow the repo-local PR guidance for PR body format and review handoff details.
📚 Learning: 2026-05-07T18:04:44.387Z
Learnt from: mnajafian-nv
Repo: NVIDIA/NeMo-Flow PR: 67
File: integrations/openclaw/src/modules.ts:1-2
Timestamp: 2026-05-07T18:04:44.387Z
Learning: In NVIDIA/NeMo-Flow, TypeScript source files should use `//` line comments for SPDX headers (e.g., `// SPDX-FileCopyrightText: ...` and `// SPDX-License-Identifier: ...`) rather than C-style block comments (`/* ... */`). The repo’s copyright checker enforces this mapping, so `//` SPDX headers in `.ts` files should not be flagged as a style violation.

Applied to files:

  • integrations/openclaw/src/hook-replay/llm.ts
  • integrations/openclaw/test/llm-replay.test.ts
📚 Learning: 2026-05-03T04:23:07.497Z
Learnt from: willkill07
Repo: NVIDIA/NeMo-Flow PR: 46
File: .github/workflows/ci_rust.yml:31-64
Timestamp: 2026-05-03T04:23:07.497Z
Learning: In GitHub Actions workflow YAML, it’s valid to conditionally disable a service container by setting the service container’s `image` to an empty string (`''`) via a matrix variable (e.g., `redis_service_image: ''`). This intentionally makes the runner skip service initialization for that matrix entry rather than failing the job. When reviewing workflows, don’t flag this as an error if the workflow uses an empty `image` to disable the service on specific matrix entries (e.g., OS-specific setups); verify the `image` is sourced from the matrix variable and that the service is only expected to be available when a non-empty image is provided.

Applied to files:

  • .github/workflows/fern-docs.yml
🪛 LanguageTool
docs/about-nemo-relay/release-notes/highlights.mdx

[style] ~37-~37: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... for guardrails plugin configuration. - Added guardrail scopes for conditional guardr...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~71-~71: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...t-in guardrails plugin documentation. - Added CI path filters, CLI draft release asse...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🪛 markdownlint-cli2 (0.22.1)
.github/CODE_OF_CONDUCT.md

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

(MD022, blanks-around-headings)

🪛 Ruff (0.15.15)
scripts/docs/sync_fern_docs_branch.py

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

(TRY003)

🪛 zizmor (1.25.2)
.github/workflows/fern-docs.yml

[warning] 378-378: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment

(undocumented-permissions)


[info] 451-451: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 439-439: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default

(cache-poisoning)

Comment thread .github/workflows/fern-docs.yml
Comment thread crates/cli/src/session.rs
Comment thread crates/cli/tests/coverage/adapters_tests.rs
Comment thread crates/core/src/observability/atif.rs
Comment thread integrations/openclaw/src/hook-replay/llm.ts
@willkill07 willkill07 added this to the 0.4 milestone Jun 3, 2026

@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.

The commit history and changes with your rebase are causing issues that should not be present. Please rewrite the history to only contain your commits. There are changes which are out-of-scope and/or outdated.

@github-actions github-actions Bot added size:XL PR is extra large lang:js PR changes/introduces Javascript/Typescript code labels Jun 3, 2026
@github-actions github-actions Bot added the lang:python PR changes/introduces Python code label Jun 3, 2026
@yczhang-nv yczhang-nv force-pushed the codex/nat-294-relay-telemetry branch from 8eecf56 to ea87222 Compare June 3, 2026 16:33
@github-actions github-actions Bot removed the lang:python PR changes/introduces Python code label Jun 3, 2026
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
@github-actions github-actions Bot removed the lang:js PR changes/introduces Javascript/Typescript code label Jun 3, 2026
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
@github-actions github-actions Bot added the lang:python PR changes/introduces Python code label Jun 3, 2026
@yczhang-nv

Copy link
Copy Markdown
Contributor Author

The commit history and changes with your rebase are causing issues that should not be present. Please rewrite the history to only contain your commits. There are changes which are out-of-scope and/or outdated.

Thanks Will! Just cleaned up the PR and I'll appreciate another review

willkill07
willkill07 previously approved these changes Jun 3, 2026

@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.

logic looks good! let's just relax the naming a bit to be more generic.

Comment thread crates/cli/src/alignment/mod.rs Outdated
Comment thread crates/cli/src/alignment/mod.rs
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
@github-actions github-actions Bot added size:L PR is large and removed size:XL PR is extra large labels Jun 3, 2026
@yczhang-nv

Copy link
Copy Markdown
Contributor Author

The naming has been generalized. @willkill07 could you re-approve when you get a chance?

@willkill07

Copy link
Copy Markdown
Member

/merge

@rapids-bot rapids-bot Bot merged commit d1001be into NVIDIA:main Jun 3, 2026
70 checks passed
@yczhang-nv yczhang-nv deleted the codex/nat-294-relay-telemetry branch June 3, 2026 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature a new feature lang:python PR changes/introduces Python code lang:rust PR changes/introduces Rust code size:L PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants