Skip to content

fix: map FlowError to OpenTelemetry error types - #612

Merged
willkill07 merged 11 commits into
NVIDIA:release/0.7from
yczhang-nv:fix/otel-error-type
Aug 1, 2026
Merged

fix: map FlowError to OpenTelemetry error types#612
willkill07 merged 11 commits into
NVIDIA:release/0.7from
yczhang-nv:fix/otel-error-type

Conversation

@yczhang-nv

@yczhang-nv yczhang-nv commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Overview

Populate OpenTelemetry error.type for failed managed LLM, tool, and stream executions by mapping Relay's structured FlowError values instead of leaving the GenAI projection on _OTHER. The fix deliberately does not infer language exception classes from error messages.

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

Details

  • Map Relay-owned FlowError variants and upstream failure classes to bounded snake_case OpenTelemetry error types.
  • Classify FlowError::Internal as internal_error without scraping exception names from message strings.
  • Attach the mapped type to managed LLM, tool, stream setup, upstream stream, and collector failure end events while preserving caller-provided error.type metadata.
  • Verify the GenAI projection exports an explicit error.type instead of falling back to _OTHER.
  • Keep Python scopes, LangChain callbacks, Node.js scope callbacks, and other language-specific exception handling unchanged.
  • Keep _OTHER where no structured FlowError is available, such as cancellation/drop paths.
  • Document the complete FlowError mapping and the internal_error limitation for external application and callback exceptions.
  • Preserve the existing public API and caller-visible error messages.
  • Keep exception span events out of scope; exception messages and stacktraces need a separate privacy and sanitization design.

Validation:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • Focused Rust FlowError, managed LLM/tool/stream, metadata, and GenAI projection tests
  • just docs — passed with zero errors; the unauthenticated redirect check was skipped
  • just test-python — 614 passed on the final rebased tree
  • Node debug build plus focused LLM/tool suites — 128 passed on the final rebased tree
  • just test-rust — all workspace unit and integration test binaries passed; the recipe ends on an unrelated existing doctest failure where scope_stack.rs references the unexported nemo_relay::Result
  • Full just test-node is locally blocked by Node 23 (the repository requires Node 24) and sandboxed collector ports; the affected LLM/tool suites pass
  • just test-go was not run because the Go toolchain is not installed locally
  • uv run pre-commit run --all-files — every available hook passed; only unavailable local tools (cargo-deny, go, and gofmt) failed

Where should the reviewer start?

Start with FlowError::otel_error_type in crates/core/src/error.rs, then review metadata_with_otel_error in crates/core/src/api/shared.rs and the GenAI projection regression in crates/core/tests/unit/observability/otel_tests.rs.

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

  • Relates to: none

@coderabbitai

coderabbitai Bot commented Jul 31, 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

The change adds structured OpenTelemetry error metadata across Rust, Node.js, and Python paths. Lifecycle, stream, callback, scope, and LangChain failures now emit stable error.type values with error status descriptions.

Changes

Structured OTel Error Metadata

Layer / File(s) Summary
Error classification and shared metadata
crates/core/src/error.rs, crates/core/src/api/shared.rs, crates/core/tests/coverage/error_tests.rs, crates/core/tests/unit/shared_tests.rs
FlowError and unknown errors map to stable types. Shared helpers emit error status, descriptions, and error.type.
Rust API and stream lifecycle metadata
crates/core/src/api/llm.rs, crates/core/src/api/tool.rs, crates/core/src/stream.rs, crates/core/tests/unit/*, crates/core/tests/integration/*
LLM, tool, and stream paths use structured success, error, and unknown-error metadata. Cancellation and failure tests verify the emitted fields.
Node.js callback error propagation
crates/node/src/api/mod.rs, crates/node/src/callback_factory.rs, crates/node/src/promise_call.rs, crates/node/tests/*.mjs
Promise callbacks preserve error messages and JavaScript error types through detailed callback results and OpenTelemetry metadata.
Python scope and integration metadata
python/nemo_relay/scope.py, python/nemo_relay/integrations/langchain/callbacks.py, python/tests/*
Scopes and LangChain callbacks classify exceptions and include error.type in failed metadata.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Execution
  participant ErrorClassifier
  participant MetadataHelper
  participant EndEvent
  Execution->>ErrorClassifier: report failure
  ErrorClassifier->>MetadataHelper: provide error type
  MetadataHelper->>EndEvent: attach ERROR status, description, and error.type
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title uses the required Conventional Commits format, states the main change, stays under 72 characters, and has no trailing period.
Description check ✅ Passed The description covers the required sections, explains the changes, identifies review starting points, lists validation, and notes test limitations.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@yczhang-nv yczhang-nv self-assigned this Jul 31, 2026
@github-actions github-actions Bot added size:M PR is medium Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code labels Jul 31, 2026
@yczhang-nv
yczhang-nv force-pushed the fix/otel-error-type branch from ac05dbf to db734e7 Compare July 31, 2026 21:00
@yczhang-nv
yczhang-nv marked this pull request as ready for review July 31, 2026 21:02
@yczhang-nv
yczhang-nv requested a review from a team as a code owner July 31, 2026 21:02
@yczhang-nv

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions github-actions Bot added the lang:python PR changes/introduces Python code label Jul 31, 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: 3

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

Inline comments:
In `@crates/core/src/api/shared.rs`:
- Around line 209-218: Extend the shared metadata/error handling around
metadata_with_otel_error with a fallback helper that produces ERROR metadata
with error.type set to _OTHER when no concrete FlowError exists. Update
LlmStreamWrapper::finish and ManagedToolCompletion::drop cancellation/drop paths
to use this fallback, while preserving metadata_with_otel_error for paths with
an actual error and ensuring all such paths retain _OTHER.

In `@python/nemo_relay/scope.py`:
- Around line 256-264: Restrict the message-derived override in the error-type
extraction logic to a bounded, stable Relay/Python error taxonomy, or remove the
override and retain type(e).__name__ as the default. Update the loop around
status_message parsing so dynamic identifiers such as tenant_123Error cannot
replace error_type, and add a regression case covering that token.

In `@python/tests/test_scope.py`:
- Around line 110-123: Update test_scope_ctx_mgr_records_exception_type by
annotating the nested capture_pop callback with -> None to satisfy ANN202, and
combine the pytest.raises and scope.scope context managers into one with
statement, keeping pytest.raises first to satisfy SIM117.
🪄 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: e3a73248-cf40-4370-b065-6be39c0c42b7

📥 Commits

Reviewing files that changed from the base of the PR and between b671256 and db734e7.

📒 Files selected for processing (11)
  • crates/core/src/api/llm.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/error.rs
  • crates/core/src/stream.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • python/nemo_relay/scope.py
  • python/tests/test_scope.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (24)
**/*.rs

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

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

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

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

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

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

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

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.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/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.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/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
  • python/nemo_relay/scope.py
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: 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, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
  • python/nemo_relay/scope.py
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
  • python/nemo_relay/scope.py
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
**/*

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

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

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
  • python/nemo_relay/scope.py
crates/{core,adaptive}/**/*

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

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

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
**/*.{rs,py,go,js,ts}

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

If a language surface changed, always run that language's test target even when Rust core did not change.

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

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
  • python/nemo_relay/scope.py
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}

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

Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
  • python/nemo_relay/scope.py
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/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

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

Files:

  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
**/*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.py: When changing the Python wrapper package, tests, or docs tooling, lint with Ruff (E, F, W, I), format with Ruff formatter (120-character lines, double quotes), and pass ty type checking.
Add the SPDX license header to all Python source files using the # comment form.

Files:

  • python/tests/test_scope.py
  • python/nemo_relay/scope.py
{crates/**/src/**/*.rs,python/**/*.py}

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

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

Files:

  • python/tests/test_scope.py
  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
  • python/nemo_relay/scope.py
python/tests/**/*.py

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

python/tests/**/*.py: Pytest is used to run tests.
Do not add @pytest.mark.asyncio to any test; async tests are automatically detected and run by the async runner.
Do not add a -> None return type annotation to test functions.
When mocking a class, do not define a new class; use unittest.mock.MagicMock or unittest.mock.AsyncMock, with the spec constructor argument when necessary.
Name mocked classes with the mock prefix, not fake.
Prefer pytest fixtures over helper methods.
Do not repeat fixtures; if a fixture is needed in multiple test files, place it in a conftest.py file.
When creating a fixture, use @pytest.fixture(name="<fixture_name>"[, scope="<scope>"]) and define the fixture function as def <fixture_name>_fixture() -> <return_type>:; only specify scope when it is not function.
Prefer pytest.mark.parametrize over creating individual tests for different input types.

Files:

  • python/tests/test_scope.py
**/*.{md,mdx,py,go,js,ts}

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

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

Files:

  • python/tests/test_scope.py
  • python/nemo_relay/scope.py
crates/core/src/{api/**/*.rs,api/runtime/**/*.rs,codec/**/*.rs,json.rs}

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

Implement the new or changed public runtime behavior first in the Rust core, especially under crates/core/src/api/ and related core modules such as crates/core/src/api/runtime/, crates/core/src/codec/, and crates/core/src/json.rs.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/shared.rs
crates/core/src/api/{tool,llm,shared,scope}.rs

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

Wire the new middleware chain into the appropriate lifecycle owner and pipeline stage: tool and LLM execution paths use tool.rs or llm.rs; shared mark and scope event sanitization uses shared.rs and is called from scope.rs.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/shared.rs
crates/core/src/api/**/*.rs

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

Preserve the documented pipeline order: conditional guardrails, request intercepts, request sanitization, execution intercepts, and response sanitization for tool and LLM execution; specialized sanitization, event creation, and dispatch for mark and scope events.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/shared.rs
python/nemo_relay/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • python/nemo_relay/scope.py
{crates/python/src/py_api/mod.rs,python/nemo_relay/**/*.py,python/nemo_relay/**/*.pyi,go/nemo_relay/**/*.go,crates/node/src/api/**/*.rs}

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

Update the language-native bindings for every exposed surface in Python, Go, and Node.js.

Files:

  • python/nemo_relay/scope.py
{python/nemo_relay/**/*.py,python/nemo_relay/**/*.pyi,go/nemo_relay/**/*.go}

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

Update language wrapper helpers such as Python wrapper modules, Python type stubs, and Go shorthand packages when the new behavior belongs in those helper layers.

Files:

  • python/nemo_relay/scope.py
python/nemo_relay/**/*

⚙️ CodeRabbit configuration file

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

Files:

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

Applied to files:

  • crates/core/src/error.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/shared.rs
🪛 Ruff (0.16.0)
python/tests/test_scope.py

[warning] 114-114: Missing return type annotation for private function capture_pop

Add return type annotation: None

(ANN202)


[warning] 121-122: Use a single with statement with multiple contexts instead of nested with statements

(SIM117)

🔇 Additional comments (10)
crates/core/src/error.rs (1)

137-172: LGTM!

crates/core/tests/coverage/error_tests.rs (1)

57-76: LGTM!

crates/core/tests/unit/shared_tests.rs (1)

123-137: LGTM!

crates/core/src/api/llm.rs (1)

37-39: LGTM!

Also applies to: 1520-1520, 1726-1726

crates/core/src/api/tool.rs (1)

20-20: LGTM!

Also applies to: 809-809

crates/core/src/stream.rs (1)

47-49: LGTM!

Also applies to: 217-225, 456-464

crates/core/tests/unit/llm_api_tests.rs (1)

1691-1693: LGTM!

Also applies to: 1723-1723, 1821-1821, 1849-1851, 1883-1886, 1900-1900

crates/core/tests/unit/tool_api_tests.rs (1)

72-76: LGTM!

Also applies to: 106-109

python/nemo_relay/scope.py (1)

239-239: LGTM!

Also applies to: 271-272

python/tests/test_scope.py (1)

103-109: LGTM!

Also applies to: 125-130

Comment thread crates/core/src/api/shared.rs
Comment thread python/nemo_relay/scope.py Outdated
Comment thread python/tests/test_scope.py Outdated
@github-actions

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@crates/core/src/api/shared.rs`:
- Line 177: Before handoff, validate the change around metadata_with_otel_status
with just test-rust, cargo fmt --all, cargo clippy --workspace --all-targets --
-D warnings, validate-change, just test-go, cargo deny check, the required
Rust/Python/Go/Node language checks, and uv run pre-commit run --all-files;
record the exact blocker for any command that cannot run.
🪄 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: 0b9c3d3b-4198-40f2-98dd-620268ea3a00

📥 Commits

Reviewing files that changed from the base of the PR and between 4f9792a and ef92dad.

📒 Files selected for processing (5)
  • crates/core/src/api/llm.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (17)
**/*.rs

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

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

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

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

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

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

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

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.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/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.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/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: 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, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
crates/core/src/{api/**/*.rs,api/runtime/**/*.rs,codec/**/*.rs,json.rs}

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

Implement the new or changed public runtime behavior first in the Rust core, especially under crates/core/src/api/ and related core modules such as crates/core/src/api/runtime/, crates/core/src/codec/, and crates/core/src/json.rs.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/api/llm.rs
{crates/**/src/**/*.rs,python/**/*.py}

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

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

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/llm.rs
**/*

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

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

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
crates/{core,adaptive}/**/*

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

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

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
**/*.{rs,py,go,js,ts}

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

If a language surface changed, always run that language's test target even when Rust core did not change.

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

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
crates/core/src/api/{tool,llm,shared,scope}.rs

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

Wire the new middleware chain into the appropriate lifecycle owner and pipeline stage: tool and LLM execution paths use tool.rs or llm.rs; shared mark and scope event sanitization uses shared.rs and is called from scope.rs.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/api/llm.rs
crates/core/src/api/**/*.rs

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

Preserve the documented pipeline order: conditional guardrails, request intercepts, request sanitization, execution intercepts, and response sanitization for tool and LLM execution; specialized sanitization, event creation, and dispatch for mark and scope events.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/api/llm.rs
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}

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

Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
crates/{core,adaptive}/**/*.rs

⚙️ CodeRabbit configuration file

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

Files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
{crates/**/tests/**,python/tests/**,go/nemo_relay/**/*_test.go}

⚙️ CodeRabbit configuration file

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

Files:

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

Applied to files:

  • crates/core/src/api/tool.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/llm.rs
🔇 Additional comments (6)
crates/core/src/api/shared.rs (1)

209-222: LGTM!

Also applies to: 224-238

crates/core/tests/unit/shared_tests.rs (1)

93-103: LGTM!

Also applies to: 105-119, 121-136

crates/core/src/api/llm.rs (2)

37-39: LGTM!

Also applies to: 1011-1011, 1247-1249, 1520-1520, 1726-1726


1080-1080: 🎯 Functional Correctness

No issue found. All production callers set response_codec_errors_fatal to false, so the fatal codec-error path is unreachable.

			> Likely an incorrect or invalid review comment.
crates/core/src/api/tool.rs (1)

20-22: LGTM!

Also applies to: 633-635, 793-793, 809-809

crates/core/src/stream.rs (1)

47-50: LGTM!

Also applies to: 188-190, 201-218, 450-462

Comment thread crates/core/src/api/shared.rs Outdated
@yczhang-nv
yczhang-nv marked this pull request as draft July 31, 2026 21:44
@github-actions github-actions Bot added size:L PR is large lang:js PR changes/introduces Javascript/Typescript code and removed size:M PR is medium labels Jul 31, 2026
@yczhang-nv
yczhang-nv force-pushed the fix/otel-error-type branch from 14a153c to f5932f0 Compare July 31, 2026 23:05
@yczhang-nv
yczhang-nv marked this pull request as ready for review July 31, 2026 23:10
@yczhang-nv

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@crates/core/src/api/llm.rs`:
- Around line 1247-1249: Update the managed lifecycle tests
dropping_pending_llm_execution_closes_the_managed_lifecycle in
crates/core/src/api/llm.rs:1247-1249 and
dropping_pending_tool_execution_closes_the_managed_lifecycle in
crates/core/src/api/tool.rs:633-635 to assert that each cancellation End event
includes otel.status_code set to "ERROR" and error.type set to "_OTHER", while
preserving the existing Start and End event assertions.

In `@crates/core/src/api/shared.rs`:
- Around line 225-230: The metadata_with_otel_error_type helper must preserve a
caller-provided error.type: insert the derived error_type only when that key is
absent, while retaining the existing fallback behavior otherwise. In
crates/core/tests/unit/shared_tests.rs lines 123-154, extend the helper tests
with metadata containing an explicit error.type and assert that the explicit
value remains unchanged.
🪄 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: 618bdad1-863f-4bf0-83b8-b45821d5ee89

📥 Commits

Reviewing files that changed from the base of the PR and between ef92dad and 33b9db5.

📒 Files selected for processing (21)
  • crates/core/src/api/llm.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/api/tool.rs
  • crates/core/src/error.rs
  • crates/core/src/stream.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/node/src/api/mod.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/promise_call.rs
  • crates/node/tests/llm_tests.mjs
  • crates/node/tests/scope_tests.mjs
  • crates/node/tests/tools_tests.mjs
  • python/nemo_relay/integrations/langchain/callbacks.py
  • python/nemo_relay/scope.py
  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/tests/test_scope.py
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Check / Run
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (26)
crates/node/**/*.{js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use camelCase for Node.js public APIs.

Files:

  • crates/node/tests/llm_tests.mjs
  • crates/node/tests/tools_tests.mjs
  • crates/node/tests/scope_tests.mjs
**/*.{rs,py,js,mjs,cjs,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,py,js,mjs,cjs,ts,tsx}: 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, and keep errors explicit and binding-appropriate at the wrapper layer.
Keep async behavior on the existing tokio-based model; bindings should preserve callback and future lifetimes rather than blocking or hiding async work unexpectedly.

Files:

  • crates/node/tests/llm_tests.mjs
  • python/tests/integrations/langchain_tests/test_callbacks.py
  • crates/node/tests/tools_tests.mjs
  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/node/tests/scope_tests.mjs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • python/nemo_relay/scope.py
  • crates/node/src/promise_call.rs
**/*

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

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

Files:

  • crates/node/tests/llm_tests.mjs
  • python/tests/integrations/langchain_tests/test_callbacks.py
  • crates/node/tests/tools_tests.mjs
  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/node/tests/scope_tests.mjs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • python/nemo_relay/scope.py
  • crates/node/src/promise_call.rs
crates/{python,ffi,node}/**/*

⚙️ CodeRabbit configuration file

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

Files:

  • crates/node/tests/llm_tests.mjs
  • crates/node/tests/tools_tests.mjs
  • crates/node/tests/scope_tests.mjs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/node/src/promise_call.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/llm_tests.mjs
  • python/tests/integrations/langchain_tests/test_callbacks.py
  • crates/node/tests/tools_tests.mjs
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/node/tests/scope_tests.mjs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/core/tests/unit/shared_tests.rs
**/*.{rs,py}

📄 CodeRabbit inference engine (AGENTS.md)

Follow binding naming conventions in Rust and Python: use snake_case.

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • python/nemo_relay/scope.py
  • crates/node/src/promise_call.rs
**/*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.py: When changing the Python wrapper package, tests, or docs tooling, lint with Ruff (E, F, W, I), format with Ruff formatter (120-character lines, double quotes), and pass ty type checking.
Add the SPDX license header to all Python source files using the # comment form.

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/nemo_relay/integrations/langchain/callbacks.py
  • python/tests/test_scope.py
  • python/nemo_relay/scope.py
**/*.{rs,py,go,js,ts,c,h}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use language-appropriate naming conventions: Rust snake_case, C FFI exports prefixed nemo_relay_, Go PascalCase, Node.js camelCase, and Python snake_case.

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • python/nemo_relay/scope.py
  • crates/node/src/promise_call.rs
{crates/**/src/**/*.rs,python/**/*.py}

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

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

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/core/src/error.rs
  • python/tests/test_scope.py
  • crates/core/src/api/shared.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • python/nemo_relay/scope.py
  • crates/node/src/promise_call.rs
python/tests/**/*.py

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

python/tests/**/*.py: Pytest is used to run tests.
Do not add @pytest.mark.asyncio to any test; async tests are automatically detected and run by the async runner.
Do not add a -> None return type annotation to test functions.
When mocking a class, do not define a new class; use unittest.mock.MagicMock or unittest.mock.AsyncMock, with the spec constructor argument when necessary.
Name mocked classes with the mock prefix, not fake.
Prefer pytest fixtures over helper methods.
Do not repeat fixtures; if a fixture is needed in multiple test files, place it in a conftest.py file.
When creating a fixture, use @pytest.fixture(name="<fixture_name>"[, scope="<scope>"]) and define the fixture function as def <fixture_name>_fixture() -> <return_type>:; only specify scope when it is not function.
Prefer pytest.mark.parametrize over creating individual tests for different input types.

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/tests/test_scope.py
**/*.{rs,py,go,js,ts}

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

If a language surface changed, always run that language's test target even when Rust core did not change.

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

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • python/nemo_relay/scope.py
  • crates/node/src/promise_call.rs
**/*.{rs,py,js,ts,tsx,go,java,kt,swift}

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

Add tests covering registration and duplicate names, deregistration and missing names, priority ordering, callback failure policy, scope-local inheritance and cleanup, event payload semantics, immutable mark and scope fields, and parity across affected bindings.

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • python/tests/test_scope.py
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • python/nemo_relay/scope.py
  • crates/node/src/promise_call.rs
**/*.{md,mdx,py,go,js,ts}

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

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

Files:

  • python/tests/integrations/langchain_tests/test_callbacks.py
  • python/nemo_relay/integrations/langchain/callbacks.py
  • python/tests/test_scope.py
  • python/nemo_relay/scope.py
python/nemo_relay/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • python/nemo_relay/integrations/langchain/callbacks.py
  • python/nemo_relay/scope.py
{crates/python/src/py_api/mod.rs,python/nemo_relay/**/*.py,python/nemo_relay/**/*.pyi,go/nemo_relay/**/*.go,crates/node/src/api/**/*.rs}

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

Update the language-native bindings for every exposed surface in Python, Go, and Node.js.

Files:

  • python/nemo_relay/integrations/langchain/callbacks.py
  • crates/node/src/api/mod.rs
  • python/nemo_relay/scope.py
{python/nemo_relay/**/*.py,python/nemo_relay/**/*.pyi,go/nemo_relay/**/*.go}

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

Update language wrapper helpers such as Python wrapper modules, Python type stubs, and Go shorthand packages when the new behavior belongs in those helper layers.

Files:

  • python/nemo_relay/integrations/langchain/callbacks.py
  • python/nemo_relay/scope.py
python/nemo_relay/**/*

⚙️ CodeRabbit configuration file

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

Files:

  • python/nemo_relay/integrations/langchain/callbacks.py
  • python/nemo_relay/scope.py
**/*.rs

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

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

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

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

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

When changing the core Rust runtime or Rust-facing API surface, format Rust code with cargo fmt (rustfmt defaults), keep cargo clippy -- -D warnings clean, and satisfy cargo deny check per deny.toml.

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

Files:

  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • crates/node/src/promise_call.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/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.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/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
**/*.{rs,go,js,ts}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add the SPDX license header to all Rust, Go, JavaScript, and TypeScript source files using the corresponding // comment form.

Files:

  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/node/src/callback_factory.rs
  • crates/node/src/api/mod.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
  • crates/node/src/promise_call.rs
crates/{core,adaptive}/**/*

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

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

Files:

  • crates/core/tests/unit/observability/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.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/otel_tests.rs
  • crates/core/tests/unit/tool_api_tests.rs
  • crates/core/src/error.rs
  • crates/core/tests/coverage/error_tests.rs
  • crates/core/src/api/shared.rs
  • crates/core/tests/unit/llm_api_tests.rs
  • crates/core/tests/integration/stream_tests.rs
  • crates/core/src/stream.rs
  • crates/core/tests/unit/shared_tests.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
crates/core/src/{api/**/*.rs,api/runtime/**/*.rs,codec/**/*.rs,json.rs}

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

Implement the new or changed public runtime behavior first in the Rust core, especially under crates/core/src/api/ and related core modules such as crates/core/src/api/runtime/, crates/core/src/codec/, and crates/core/src/json.rs.

Files:

  • crates/core/src/api/shared.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
crates/core/src/api/{tool,llm,shared,scope}.rs

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

Wire the new middleware chain into the appropriate lifecycle owner and pipeline stage: tool and LLM execution paths use tool.rs or llm.rs; shared mark and scope event sanitization uses shared.rs and is called from scope.rs.

Files:

  • crates/core/src/api/shared.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
crates/core/src/api/**/*.rs

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

Preserve the documented pipeline order: conditional guardrails, request intercepts, request sanitization, execution intercepts, and response sanitization for tool and LLM execution; specialized sanitization, event creation, and dispatch for mark and scope events.

Files:

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

Applied to files:

  • crates/core/src/error.rs
  • crates/core/src/api/shared.rs
  • crates/core/src/stream.rs
  • crates/core/src/api/llm.rs
  • crates/core/src/api/tool.rs
📚 Learning: 2026-07-28T23:57:11.641Z
Learnt from: willkill07
Repo: NVIDIA/NeMo-Relay PR: 570
File: crates/node/src/api/mod.rs:3265-3282
Timestamp: 2026-07-28T23:57:11.641Z
Learning: In the Node.js binding, `flushSubscribers()` is Promise-based/async and must be awaited. Any session-close or teardown path (e.g., the OpenClaw live smoke session-close flow) must await `flushSubscribers()` before continuing to live ATIF export assertions and before teardown, so queued subscriber delivery fully completes and tests/assertions observe the final state.

Applied to files:

  • crates/node/src/api/mod.rs
🪛 Ruff (0.16.0)
python/tests/test_scope.py

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

(TRY003)

🔇 Additional comments (19)
crates/core/tests/unit/observability/otel_tests.rs (2)

12-14: LGTM!

Also applies to: 376-426, 1461-1485


376-426: 📐 Maintainability & Code Quality

Confirm the required core validation before handoff.

This change is under crates/core. Confirm just test-rust, cargo fmt --all, cargo clippy --workspace --all-targets -- -D warnings, validate-change, the Python, Go, and Node.js test targets, and uv run pre-commit run --all-files completed. The PR objectives note a local Go validation limitation; verify the Go check in CI.

As per coding guidelines, changes under crates/core require the listed Rust checks and the full language matrix.

Source: Coding guidelines

crates/node/src/promise_call.rs (1)

123-155: LGTM!

Also applies to: 338-340, 353-357, 474-476

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

324-324: LGTM!

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

252-266: LGTM!

Also applies to: 276-282

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

418-418: LGTM!

crates/node/src/callback_factory.rs (1)

103-149: 📐 Maintainability & Code Quality

Run the required binding validation in separate commands.

The combined validation timed out before producing results. Run each command separately, including cargo deny check for the Rust-facing API changes.

python/nemo_relay/scope.py (1)

19-19: LGTM!

Also applies to: 44-108, 306-335

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

15-15: LGTM!

Also applies to: 99-103

python/tests/test_scope.py (1)

6-15: LGTM!

Also applies to: 106-192

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

136-140: LGTM!

crates/core/src/error.rs (1)

137-229: LGTM!

crates/core/tests/coverage/error_tests.rs (1)

57-133: LGTM!

crates/core/src/api/llm.rs (1)

37-39: LGTM!

Also applies to: 1520-1520, 1726-1726

crates/core/src/api/tool.rs (1)

20-21: LGTM!

Also applies to: 809-809

crates/core/src/stream.rs (1)

47-49: LGTM!

Also applies to: 188-190, 217-225, 456-464

crates/core/tests/unit/llm_api_tests.rs (1)

1691-1693: LGTM!

Also applies to: 1723-1723, 1821-1821, 1849-1851, 1883-1886, 1900-1900

crates/core/tests/unit/tool_api_tests.rs (1)

72-76: LGTM!

Also applies to: 106-109

crates/core/tests/integration/stream_tests.rs (1)

466-466: LGTM!

Comment thread crates/core/src/api/llm.rs Outdated
Comment thread crates/core/src/api/shared.rs Outdated
Comment thread crates/core/src/error.rs Outdated
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
This reverts commit ef92dad.

Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
@yczhang-nv
yczhang-nv force-pushed the fix/otel-error-type branch from 47fc055 to e0c8bec Compare August 1, 2026 00:20
@github-actions github-actions Bot added size:M PR is medium and removed size:L PR is large lang:python PR changes/introduces Python code labels Aug 1, 2026
@yczhang-nv yczhang-nv changed the title fix: preserve OpenTelemetry error types fix: map FlowError to OpenTelemetry error types Aug 1, 2026
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
@yczhang-nv
yczhang-nv requested a review from a team as a code owner August 1, 2026 00:30
@willkill07

Copy link
Copy Markdown
Member

/merge

@willkill07
willkill07 merged commit 97c5bc7 into NVIDIA:release/0.7 Aug 1, 2026
74 of 76 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug issue describes bug; PR fixes bug lang:js PR changes/introduces Javascript/Typescript code lang:rust PR changes/introduces Rust code size:M PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants