Release Notes for NVIDIA NeMo Relay

View as Markdown

This page contains the release notes for NVIDIA NeMo Relay.

For the full release history, including individual pull requests, refer to GitHub Releases.

Release 0.9.0

Highlights

This release adds the following features and changes:

  • A shared daemon routes coding-agent requests to separate workers. Each user on each computer gets a worker with its own plugins and runtime state.
  • The CLI adds Pi support. You can install its extension, record session activity, check tool calls against policy, and route supported model requests.
  • All language bindings use the same plugin host to start, check, and stop plugins. Reports show the combined settings from files and application code.
  • Related work stays in the same trace by default. OpenTelemetry tool spans include more details about tool execution and sanitized tool content.
Breaking Changes

Update plugin-host calls and tool execution intercepts before upgrading. Review trace boundaries and policies for removing personally identifiable information (PII). Change remote plaintext trace endpoints to HTTPS. OTLP/HTTP trace exporters no longer follow redirects. For required steps, refer to the Migration Guides.

Managed Daemon Deployments

Daemon mode supports the following shared-service features:

  • nemo-relay daemon routes requests from authenticated Model Context Protocol (MCP) clients to workers. It supports coding-agent bundles that administrators manage for Codex, Claude Code, and Pi. Workers load system settings.
  • MCP clients and workers keep WebSocket control connections open. These connections carry route updates, readiness checks, shutdown requests, and recovery messages. Model and hook traffic uses separate HTTP connections. Responses stream back as data arrives.
  • Local deployments support Windows, macOS, and Linux. Remote deployments use HTTPS. Clients must reach the daemon, and the daemon must reach each client worker. Proxies must support WebSocket upgrades, keep those connections open, and forward frames in both directions. For setup, service management, upgrades, and troubleshooting, refer to Daemon.
  • A managed gateway has up to 20 seconds after Relay starts it to resolve its persistent configuration, bind its listener, and report readiness. This gives slow configuration discovery time to finish.

Coding-Agent and Framework Support

The following updates extend support for coding agents and frameworks:

  • Use nemo-relay install pi, nemo-relay pi, and nemo-relay doctor pi to install, launch, and check the Pi extension. This proof of concept is tested with Pi 0.84.x. It records sessions, turns, tools, and shell commands entered in Pi. It checks policy through supported hooks.
  • When Relay launches Pi, model requests can select named upstreams automatically. Relay skips models that use unsupported APIs. It also skips providers whose models have incompatible endpoint settings. For routing details, refer to Pi.
  • Use create_tool_node to run standalone LangGraph ToolNode calls through Relay’s tool pipeline. LangGraph still supplies state, store, and runtime arguments. Add NemoRelayCallbackHandler to record graph lifecycle scopes. For details, refer to Managed ToolNode Calls.
  • The OpenClaw plugin now targets OpenClaw 2026.9.3. Its minimum gateway version is also 2026.9.3. For details, refer to OpenClaw Plugin.

Plugin Configuration and Caching

Plugin settings and response caching include the following updates:

  • initialize and validate use the same plugin settings, version checks, and trust policy. Exact validation checks only the static document you pass in. Initialization returns a PluginHostActivation handle that controls plugin lifetime. For details, refer to Configure and Initialize Plugins.
  • Host reports include config_paths and resolved_config. These fields show which files contributed settings and how Relay combined them with application settings. Reports redact literal credentials and values in dynamic-plugin settings whose meaning Relay does not know.
  • Dynamic plugin declarations now layer by manifest plugin ID. When a higher-precedence file declares the same ID, its complete record replaces the lower-precedence record instead of blocking startup with a duplicate-ID error. For details, refer to Plugin Configuration Files.
  • Response caching adds key_strategy = "logical". It ignores changes to tool descriptions and tool order. Other tool-definition changes still affect the key. exact_request remains the default. Each strategy has its own set of cache keys. For details, refer to Key Strategies.

Observability and Redaction

Trace exports and PII redaction include the following changes:

  • Forking a scope stack or capturing propagation context keeps the Relay root when one is available. This root links related work to the same OpenTelemetry trace, even across processes. You can still capture a rootless context to start a separate trace.
  • ATIF uses the propagated root as the exported session_id when one is present. The trajectory_id, filenames, storage keys, and remote session headers still use the individual trajectory scope UUID.
  • Claude Code, Codex, and Pi provide consistent tool types and executing-agent names, including known subagent names. The gen_ai output format now includes sanitized tool arguments and successful results when they are JSON objects. It also includes tool-definition identities. The full and openinference formats receive the added tool metadata. For details, refer to OpenTelemetry.
  • Direct trace, log, and metric subscribers can read exporter headers from environment variables. Use header_env, or headerEnv in Node.js. Relay reads the values when it creates the subscriber. Missing or invalid values prevent creation without exposing the secret.
  • Observability exporters can also read a header from a local file with header_file. This supports credentials that another process rotates. Relay reads the file for each HTTP delivery. An ATOF WebSocket reads it when it connects or reconnects, and an NDJSON sink reads it when it starts. Relay does not write the header value to diagnostics.
  • OpenTelemetry trace, log, and metric exports add their standard SDK resource fields automatically. Do not set the reserved telemetry.sdk.* fields yourself.
  • The PII trajectory_context preset removes unknown fields and opaque payloads, whose structure Relay cannot safely interpret. It keeps approved analytics fields and trace links. Typed metric attributes must match allowed string names and values. The preset drops numeric, boolean, and unlisted attributes. Python, Node.js, and Go configuration helpers expose the preset and its typed settings. For details, refer to PII Redaction Configuration.

Operational Diagnostics

The CLI and daemon now provide more privacy-safe operational logs:

  • Daemon logs show worker, route, MCP session, and upstream lifecycle events. CLI logs also show hook delivery and upstream request events, including slow or stalled streams. These records use random operation IDs and do not include prompts, tool data, model names, URLs, headers, or credentials.
  • Failure records use short, fixed reason codes. These codes help operators identify a failed MCP session, gateway recovery, or worker startup without placing private error text in structured logs.
  • nemo-relay doctor now includes the redacted plugin-host preflight. It shows static settings and dynamic-plugin trust or configuration problems without starting plugins.

For the event names, fields, and logging setup, refer to Operational Logging.

Support Matrix and Compatibility Updates

For supported platforms, architectures, worker runtimes, coding agents, and integrations, refer to the Support Matrix. Go and the raw C FFI remain experimental, with source-first support.

For steps to upgrade from 0.8.x to 0.9, refer to the Migration Guides.

Breaking Changes

Review each of the following changes before upgrading.

Tool Execution Intercepts

Breaking Change

Tool execution intercepts now receive (ToolExecutionContext, next) because Relay needs to pass the provider tool-call ID with the name and arguments. Update every callback and plugin SDK that you use. Native plugins use ABI v5, and native or worker plugins that register this callback cannot support Relay 0.8. Follow the Migration Guides before you upgrade.

Plugin Host Lifecycle and Trust

Breaking Change

Global plugin clear and report functions and explicit dynamic activation-spec APIs are removed because one activation handle now owns the plugin host. Keep the handle, read its report, and close it during shutdown. The host also checks dynamic-plugin trust through every embedding API, so an unsigned plugin that previously started can now fail. Follow the Migration Guides before you upgrade.

Layered Dynamic Plugin Records

Breaking Change

A higher-precedence [[plugins.dynamic]] record with the same manifest ID now replaces the full lower-precedence record. This avoids duplicate-ID failures, but it also means that the lower record’s config is not kept. Copy all needed settings to the higher-precedence record. Follow the Migration Guides before you upgrade.

Python Plugin Errors

Breaking Change

Python plugin initialization and activation now raise ValueError for invalid static settings and FileNotFoundError for unavailable files or resources. These errors replace RuntimeError for those cases, so existing exception handlers can miss them. Follow the Migration Guides before you upgrade.

Trace Boundaries

Breaking Change

Default propagation can now join traces that were separate. In ATIF, session_id identifies a run and trajectory_id identifies one trajectory in that run. This preserves the parent trace across related work. Follow the Migration Guides before you upgrade.

GenAI Tool Content

Breaking Change

GenAI exports now include sanitized tool content by default. Review redaction and data-access rules because your collector can receive content that it did not receive before. Follow the Migration Guides before you upgrade.

Secure Trace Transport

Breaking Change

Remote trace collectors must use HTTPS. Plain HTTP is limited to localhost and loopback IP addresses, and OTLP/HTTP trace exporters reject redirects. This prevents trace data from being sent to an unexpected or insecure destination. Follow the Migration Guides before you upgrade.

File-Based Exporter Headers

Breaking Change

Rust observability struct literals must set the new header_file field, and Go code that uses unkeyed composite literals must switch to keyed fields. Also, when any exporter header source is set, remote ATOF, ATIF, log, and metric destinations require secure HTTPS or WSS transport. These rules protect rotated credentials. Follow the Migration Guides before you upgrade.

PII Redaction

Breaking Change

The stricter trajectory_context preset removes opaque fields and metric attributes that it previously kept, so analytics that use them need updates. Follow the Migration Guides before you upgrade.

Rust Response Cache API

Breaking Change

Rust ResponseCacheConfig.key_strategy now uses ResponseCacheKeyStrategy instead of String, and KEY_STRATEGY_EXACT_REQUEST is removed. Update source code that configures a response cache. Follow the Migration Guides before you upgrade.

Fixed Known Issues in 0.9

This release fixes the following issues that also affect earlier releases:

  • Coding-agent LLM events keep the provider’s conversation ID when one is given. Otherwise, they use the coding agent’s session ID to link events.
  • LangChain keeps message boundaries, tool-call IDs, and provider-specific content blocks when middleware processes messages. Relay omits its headers for models whose SDK rejects extra_headers, so those calls can proceed.
  • Anthropic token usage is kept when a stream reports it across several events. Gateway routing handles upstream URLs that already end in /v1. Collected streams also keep content and encrypted content from Anthropic compaction_delta events.
  • OpenAI Responses decoding keeps Codex automation tool outputs. Codex routing overrides also stay in the launched command’s execution scope.
  • Codex installation handles marketplace entries that point to missing files. Use nemo-relay install codex --force to repair stale entries owned by Relay.
  • Generated Codex and Claude Code hook commands use private files.
  • PII URL masking no longer keeps credentials. Overlapping PII path selectors no longer remove unrelated request content.
  • Gateway streams can run for more than five minutes when data keeps arriving. Relay still stops a stream that stays idle for five minutes.
  • nemo-relay doctor gives a slow coding-agent CLI up to 10 seconds to report its version. Network health checks keep their shorter timeout.
  • nemo-relay gateway stop recognizes the published pinned CLI process and can stop the Relay-owned gateway it started.
  • OpenTelemetry flush and shutdown drain accepted trace, log, and metric data more reliably before they finish.

Other Improvements

This release also includes the following updates:

  • Unix and PowerShell uninstall scripts remove a CLI installed by a script. They keep settings and integrations. They check active processes and refuse removal while managed daemon processes use the binary. For details, refer to Remove a Script-Installed CLI.
  • ATIF documentation explains how metadata placeholders become safe path components. Slashes in metadata values do not create nested directories. For details, refer to Metadata-Based Paths.

Known Issues in 0.9

The following limitations still apply in this release:

  • OTLP collectors can return a successful response while rejecting individual spans, log records, or metric data points. Relay does not report these partial successes in runtime diagnostics, and flush or shutdown can still succeed. Monitor collector-side rejection metrics and logs. Refer to OpenTelemetry.
  • Go and the raw C FFI remain experimental and source-first. Generated API pages focus on Rust, Python, and Node.js.
  • Local coding-agent observability depends on host hooks and provider traffic reaching the local gateway. Relay cannot fully capture remote or cloud execution that bypasses the local host.
  • Persistent Codex and Claude Code integrations use user-scoped configuration and a shared loopback gateway. Use nemo-relay run when a launch must retain project-specific configuration.
  • On Windows, a restrictive host Job Object can limit gateway reuse or prevent persistent bootstrap. Codex can also make a cold-start /models request before required MCP servers start; Relay retries the request.
  • Codex 0.143 does not expose SessionEnd, and Codex multi-agent v2 encrypts delegated-task payloads that Relay cannot decrypt or reliably link.
  • Pi support is a proof of concept tested with 0.84.x. By default, its personal extension lets work continue if the gateway is unavailable. Later extensions can change arguments after Relay checks them. Unsupported provider routes produce no LLM spans. This includes Google’s native Gemini and Vertex APIs. To route Gemini model traffic through Relay, use a provider or proxy that accepts an OpenAI- or Anthropic-compatible API. Nested Pi processes appear as separate sessions. SIGINT in headless mode can stop Pi before queued events are sent. For details, refer to Pi Limitations.
  • If a managed daemon worker fails to start, its authenticated route can enter pass-through mode. This mode forwards model requests without worker plugins until all MCP clients leave the route. MCP readiness alone does not prove that policy checks or exporters are active. For details, refer to Daemon Operations.
  • Remote daemons and client workers must be able to reach each other. Proxies must support WebSockets. Loopback control connections do not send periodic pings. An idle hung process can go undetected until an operation times out.
  • The Node.js binding and package workflows require Node.js 24 or later.
  • OpenClaw has public hook-backed telemetry. Its security and optimization coverage is partial because it does not own a managed execution path.
  • The built-in nemo_guardrails plugin is deprecated and scheduled for removal in NeMo Relay 0.9. No replacement is included. Until removal, the remote backend inherits its configured service’s availability, latency, and policy behavior, and the local backend requires Python 3.11 or later and nemoguardrails==0.22.0. Removal will include the built-in component kind, the public nemo_relay::plugins::nemo_guardrails Rust module, its CLI editor entry, and the guardrails-remote Cargo feature.
  • The PII redaction plugin currently supports its deterministic local backend; local-model backend configuration is reserved for future work.
  • Pricing and optimization estimates depend on model names, token data, pricing sources, and freshness evidence. Missing or inconsistent evidence produces partial or absent cost fields rather than zero values.
  • ATOF stream sinks and remote ATIF storage require reachable, correctly configured destinations. A failed stream sink does not stop file output or other active sinks.
  • ATIF omits point-in-time marks. Use ATOF for the canonical mark stream; the gen_ai OpenTelemetry projection also omits marks. The full and openinference projections retain their fixed native mark handling.
  • Native dynamic plugins run in the Relay process and are not sandboxed. A grpc-v1 worker runs in a separate process, but that process is not a security sandbox.
  • Treat Python LLMRequest objects as immutable. Request middleware that changes content must return a new request object.
  • Native subscriber callbacks arrive asynchronously. Flush subscribers before depending on their side effects, captured events, files, or exporter output.
  • OpenTelemetry endpoints use finite batch queues. A burst that fills an endpoint queue drops completed spans without applying backpressure and can leave an incomplete trace, including a missing root span. The SDK warns on the first drop and reports the exact dropped-span count during graceful shutdown. Configure max_queue_size, max_export_batch_size, and scheduled_delay_millis independently on each endpoint, or use the standard OTEL_BSP_* environment variables as process-wide fallbacks. A larger finite queue does not guarantee lossless telemetry.
  • Operational logging covers Relay-managed hooks, gateway requests, the daemon, and workers. It does not yet cover every CLI command.

Previous Releases

For previous release notes, release artifacts, and the complete PR-by-PR history, refer to GitHub Releases.

For more information, refer to the following pages: