Repository navigation
0.10.0
·
378 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
We are proud to release NeMo Relay 0.10.0!
This release includes the changes since 0.9.0, including the fixes shipped in 0.9.1 through 0.9.4. The highlights below emphasize additions beyond those patch releases; previously shipped changes are identified where relevant.
Notable New Features
- 📊 Configurable resource metrics: The built-in
resource_metricsplugin collects CPU, memory, process, disk, network, and GPU measurements on Linux, macOS, and Windows. Applications can request current measurements or enable polling to emit ATOF metric marks and OpenTelemetry measurements. Polling is off by default, and available measurements depend on the platform and driver. - 🔌 Automatic OpenTelemetry configuration: Standard OTLP endpoint environment variables can enable
gen_aitraces, logs, and metrics automatically, alongside configured destinations. Signal-specific variables enable individual signals; a generic endpoint enables all three. Endpoint credentials remain subject to Relay's transport and header-isolation rules. - 💾 Local OpenTelemetry trace files: Export spans as OTLP JSON Lines or length-delimited protobuf, with file sinks available alongside remote collectors.
- 📦 Dynamic plugins from GitHub releases:
nemo-relay plugins installdownloads a bundle from a specific release tag, checks its metadata and integrity, and registers it in user or system configuration under the existing trust policy.plugins uninstallremoves the managed bundle and its Python environment. - 🧩 Codec-aware LLM execution policies: Execution intercepts receive Relay's selected codec context to inspect or rewrite provider requests and decode completed responses. Streaming intercepts receive request codec access. Native and worker SDKs also support captured timestamps for replayed scopes.
- 🛰️ Managed daemon startup and credential recovery: Workers start asynchronously after MCP authentication and registration, retry failed starts, and recover launch activation across daemon restarts. Per-user token files support clients started before login setup; rotated tokens can share an identity's existing route and worker. Use
--require-workerwhen every request must wait for worker policies. - 🎙️ Codex voice and auxiliary API passthrough: Standalone gateways and managed daemons forward voice call creation, Responses compaction, image editing, memory summarization, experimental search, and Live/Realtime WebSocket connections. These auxiliary routes bypass LLM lifecycle events and payload interception. ChatGPT voice call creation retains the caller's ChatGPT credential; Live and Realtime connections retain caller credentials and use the configured OpenAI upstream. WebRTC audio remains direct. Managed ChatGPT deployments must set
experimental_realtime_webrtc_call_base_urlto their Relay URL ending in/backend-api/codex. - 🔗 W3C trace continuity: Captured propagation contexts preserve imported
traceparent, sampling flags, andtracestateacross scope stacks, processes, managed calls, and asynchronous plugin callbacks. Provider request headers stay aligned with exported LLM spans. - 🛡️ Permission policy visibility: Matched Claude Code and Codex permission requests emit
nemo_relay.permission.policy_decisionmarks linked to the tool call. Apassmeans Relay did not block the request; it does not establish user approval or execution. Tool correlation builds on fixes shipped in 0.9.3. - 🌐 Served LangGraph agents: Python applications can use
configure_graph()withNemoRelayMiddlewareto record graph and node lifecycles for agents served throughlanggraph devorlanggraph up, while preserving human-approval interrupts and callback scope ownership. - 📋 Structured operational logging: Python and Node.js applications, Rust native plugins, and Rust and Python workers can send structured records to Relay's operational logs. File-sink overflow diagnostics identify the affected sink and limit repeated warnings.
Breaking Changes
- LLM execution intercepts and plugin ABI: Every execution-intercept callback gains codec context. Python streaming callbacks and public C callbacks also gain the logical LLM name. Rebuild every native plugin for ABI v7 and regenerate/rebuild workers that register LLM execution intercepts. Affected manifests must exclude Relay 0.9; compatibility labels remain
native_api = "1"andgrpc-v1. Raw native asynchronous non-streaming execution uses the dedicated LLM execution registration API. - Observability configuration and automatic export: Observability configuration requires
version = 4, including trace-only configurations. Existing OTLP endpoint variables can activate additional exporters. Move global OTLP headers into endpoint-specific settings for explicitly configured destinations; Relay skips those destinations when global header variables prevent credential isolation. OTLP/HTTP log and metric exporters now reject redirects, extending the trace-export restriction from 0.9. - Daemon logging: The primary daemon reads TOML logging settings only from
[daemon.logging], with no fallback to[logging]. Move daemon service settings; CLI and environment overrides still apply. This change already shipped in 0.9.1. - Managed daemon enforcement: Requests without a resolvable credential, with an unbound token, or without a live MCP session can pass through without worker plugins. Credentialless hooks pass through even with
--fail-closed. Authenticated requests also pass through during worker startup and recovery by default. Provision credentials withnemo-relay daemon token ensure; use--require-workerto require enforcement and handle401or503while credentials or workers are unavailable. - Trace boundaries: A valid imported W3C parent takes precedence over Relay-derived trace IDs, including an explicit root. Rootless capture retains an imported W3C parent; remove
traceparentandtracestatewhen a new trace is required. Managed LLM execution replaces propagation headers with its active context. - Codex trajectory exports: Each
codex-tasknow produces its own ATIF file and trace instead of a cumulative session file. Update default file lookups to use the task-scope ID and group related tasks withextra.nemo_relay.session_id. Refresh personal integrations and restart Codex to preserve its built-in OpenAI provider identity and apply updated hooks and routing. - Python callback exceptions: Managed LLM and tool calls and intercepts re-raise the original callback exception instead of wrapping it in
RuntimeError. Update handlers that catch onlyRuntimeError; cancellation is preserved during callbacks and stream iteration. Worker plugins retain their existing behavior. - Telemetry consumers: Replace
gen_ai.usage.cache_creation.input_tokenswithgen_ai.usage.cache_write.input_tokens. Metrics no longer includenemo_relay.session.instance_id. Sanitized GenAI tool content preserves all non-null JSON values, including scalars and arrays; these projection changes already shipped in 0.9.1. Codex and Claude completion hooks without a matching start produce partial-observation marks rather than invented lifecycles. The reservedtool_end_without_startmark requires a nonemptydata.tool_nameand applies tool sanitizers. - Rust, Go, and custom workers: Update exhaustive Rust struct literals for new observability, propagation, event, timing, usage, and callback-error fields; use keyed Go configuration literals. Resource metadata promotion for OTLP logs and metrics already shipped in 0.9.1. Regenerate custom worker protocol bindings for codec context and scope timestamps, and implement the new
RelayHostRuntime.LogRPC where applicable. - Linux musl binaries and shared Python workers: Musl CLI binaries require host musl 1.2 or newer; the Unix installer selects GNU binaries on glibc systems. Older shared Python worker environments without an environment-local verification key require the original installer's bootstrap key. Recreate them from trusted sources if that key is unavailable; shared-worker validation support already shipped in 0.9.3.
Non-Exhaustive Fixes
- Daemon and gateway reliability: Preserve routes on request timeouts, avoid compaction deadlocks, permit long provider execution without a default deadline, serialize shared TLS identity creation, and retain active requests and streams across worker transitions. Health and worker-status routes introduced in 0.9.2 remain available for operational checks.
- Windows coding-agent support: Repair Codex hook trust paths and PowerShell commands, shorten launch commands, preserve Claude Code paths under Git Bash, normalize executable paths, handle detached-worker stderr, and support workers confined by host Job Objects. Create private directories with explicit user ownership, including for LocalSystem daemons. Refresh installed hooks after upgrading.
- Python and Node.js reliability: Reduce Python streaming bridge scheduling overhead, preserve callback exceptions and cancellation, and prevent Node.js worker teardown crashes while streams finish on Windows.
- Coding-agent lifecycle accuracy: Preserve Codex delegated-task ancestry, retain unmatched completion hooks as sanitized marks, avoid closing parent turns for unclassified Claude internal-agent stops, correlate tool lifecycle logs with tool spans, and allow ten seconds for agent version probes.
- Anthropic compaction and caching: Preserve response metadata and compaction usage, including provider-reported uncached input tokens, and omit model-based cost estimates for mixed-model usage. Validated paused-threshold and on-demand compaction responses and continuations can now be cached; unsupported or malformed cases run live. This extends the blanket compaction-cache bypass shipped in 0.9.1.
- Telemetry correctness: Preserve trace parents across forks and callbacks, reject malformed
tracestatewithout discarding validtraceparent, drop out-of-range OTLP timestamps, preserve automatic export, and improve trace-file diagnostics. GenAI enrichment and log-provider delivery accounting include fixes already shipped in 0.9.1 and 0.9.2. - Framework and plugin compatibility: Preserve LangGraph interrupts and graph-scope parentage, flush OpenClaw's final telemetry during shutdown, isolate native and worker asynchronous callback contexts, support musl native plugins, preserve Linux Python
lib64aliases, and accept compatible plugin ranges on prerelease hosts. - Included patch-release fixes and maintenance: Retain Codex OAuth routing and permission handling from 0.9.1–0.9.2, normalized MCP tool metadata and shared Python worker support from 0.9.3, and the small-thread-stack fix from 0.9.4. Additional dependency updates, consolidated workspace lockfiles, security audits, and expanded regression coverage are included.
What's Changed
💥 Breaking Changes
- enhancement!: propagate W3C trace context by @willkill07 in #1130
- feat(observability)!: promote resource metadata across OTLP signals by @bbednarski9 in #1134
- feat(observability)!: export OTLP traces to a local file by @SandyChapman in #1042
- feat!: pass codec context to LLM execution intercepts by @afourniernv in #1133
✨ New Features
- feat: add OTLP environment autoconfiguration by @willkill07 in #1118
- feat: install dynamic plugins from GitHub releases by @willkill07 in #1147
- feat: cache safe Anthropic paused-threshold compaction responses by @mnajafian-nv in #1163
- feat: add safe cache support for Anthropic on-demand compaction by @mnajafian-nv in #1164
- feat: emit permission policy decision marks by @rissingh23 in #1154
- feat: add configurable resource metrics plugin by @willkill07 in #1171
- feat(plugin): add timestamped scope guards by @afourniernv in #1166
- feat(daemon): support client token files and credential recovery by @bbednarski9 in #1189
- feat: add Codex passthrough APIs and voice sidebands by @willkill07 in #1273
⚡ Improvements
- enhancement: separate daemon operational logging by @willkill07 in #1123
- enhancement: add structured operational logging by @willkill07 in #1128
- enhancement: default automatic OTLP traces to gen_ai by @willkill07 in #1140
- enhancement: expose daemon health and worker status routes by @bbednarski9 in #1142
- enhancement: normalize MCP tool metadata in harness adapters by @bbednarski9 in #1158
- refactor: resolve Sonar findings on main by @willkill07 in #1169
- refactor: resolve resource metrics Sonar findings by @willkill07 in #1173
- refactor: address all open Sonar findings by @willkill07 in #1179
- perf: reduce Python streaming bridge scheduling overhead by @willkill07 in #1265
🐛 Bug Fixes
- fix: accept Codex permission requests without call IDs by @willkill07 in #1112
- fix: preserve GenAI tool span content by @willkill07 in #1119
- fix: bypass response cache for Anthropic compaction by @mnajafian-nv in #1127
- fix: route managed Codex OAuth traffic by @willkill07 in #1135
- fix(observability): enrich GenAI and harness telemetry by @bbednarski9 in #1121
- fix: isolate resource log provider delivery accounting by @bbednarski9 in #1141
- fix: return native Codex permission denials and ignore approval descriptions by @elookpotts-nvidia in #1143
- fix(codex): preserve OpenAI session identity when routing through Relay by @bbednarski9 in #967
- fix(cli): preserve Linux venv lib64 aliases by @afourniernv in #1110
- fix: support shared system Python worker plugins by @willkill07 in #1146
- fix(cli): correlate permission decisions with tool spans by @bbednarski9 in #1148
- fix: serialize shared gateway TLS identity creation by @fernandol-nvidia in #1151
- fix: preserve Anthropic response metadata and compaction usage by @mnajafian-nv in #1152
- fix: preserve trace context across scopes and callbacks by @yczhang-nv in #1145
- fix: clarify public API expectations and regression coverage by @willkill07 in #1174
- fix(plugin): isolate async callback scope context by @afourniernv in #1167
- fix: harden worker lifecycle and enable asynchronous startup by @willkill07 in #1176
- fix: preserve worker launch activation across daemon restart by @mnajafian-nv in #1178
- fix: preserve daemon worker routes on request timeouts by @willkill07 in #1181
- fix: prevent compaction deadlocks and allow long execution by @willkill07 in #1182
- fix: avoid stack overflow on small thread stacks by @willkill07 in #1185
- fix: correct macOS memory metrics with sysinfo 0.39.6 by @willkill07 in #1193
- fix: match pre-release relay builds against plugin compat ranges by @greysonlalonde in #1195
- fix: preserve automatic OTLP export and reject malformed headers by @willkill07 in #1192
- fix(logging): attribute async sink overflow errors by @afourniernv in #1201
- fix(daemon): let one identity hold several route tokens by @bbednarski9 in #1190
- fix: backport OpenTelemetry file sink diagnostics to 0.10 by @mnajafian-nv in #1206
- fix: support Relay scope hierarchy for served LangGraph agents by @mnajafian-nv in #1205
- fix: preserve Codex delegated task ancestry by @yczhang-nv in #1200
- fix: log bound daemon requests that bypass unavailable workers by @willkill07 in #1220
- fix: reject malformed tracestate without dropping traceparent by @willkill07 in #1219
- fix: create private coding-agent hook directories by @willkill07 in #1218
- fix: preserve LangGraph interrupts in agent middleware by @willkill07 in #1216
- fix: close LangGraph scopes in their owning callback context by @willkill07 in #1215
- fix: drop OTLP events with out-of-range timestamps by @willkill07 in #1217
- fix: preserve OpenClaw telemetry during shutdown by @willkill07 in #1228
- fix: select the Linux CLI binary by host libc by @willkill07 in #1242
- fix: trust Codex session hooks on Windows by @willkill07 in #1244
- fix: handle console stderr in detached Windows workers by @willkill07 in #1245
- fix: parent LangGraph lifecycle marks to their graph scope by @willkill07 in #1247
- fix: normalize Windows agent executable paths by @willkill07 in #1248
- fix: preserve Claude hook paths under Windows Git Bash by @willkill07 in #1246
- fix: support musl plugins and safe Node worker teardown by @willkill07 in #1243
- fix(python): re-raise exceptions from managed calls and intercepts by @greysonlalonde in #1241
- fix: support host-confined Windows workers and private state ownership by @bbednarski9 in #1257
- fix: run Windows Codex hooks through PowerShell by @willkill07 in #1258
- fix: shorten Windows Codex launch commands by @willkill07 in #1266
- fix: create Windows private directories with explicit ownership by @willkill07 in #1267
- fix: allow ten seconds for agent version probes by @willkill07 in #1271
- fix(claude): preserve unclassified agent stops by @bbednarski9 in #1274
- fix: correlate tool lifecycle logs with tool spans by @bbednarski9 in #1275
✅ Tests
- test: align Claude and Codex plugin E2E gateways by @willkill07 in #1041
- test: cover the worker SDK registration mapping and response decoding by @SandyChapman in #1157
- test: expand coverage for plugins, telemetry, and bindings by @willkill07 in #1183
🧰 Maintenance
- chore: bump version to 0.10.0 by @willkill07 in #1107
- chore: constrain soupsieve to patched release by @willkill07 in #1114
- chore: constrain anyio to patched release by @willkill07 in #1122
- chore: update vulnerable LangChain NVIDIA dependency by @willkill07 in #1156
- chore: update vulnerable npm development dependencies by @willkill07 in #1165
- chore: update vulnerable Python audit dependencies by @willkill07 in #1170
- chore: align release/0.9 dependencies with main by @willkill07 in #1187
- ci: exclude Codecov links from lychee checks by @willkill07 in #1191
- chore: upgrade xxhash-rust to 0.8.16 by @willkill07 in #1209
- chore: update dependencies based on
uv auditandnpm auditby @willkill07 in #1212 - ci: disable unused ops-bot features by @willkill07 in #1227
- build: consolidate workspace lockfiles and enforce security audits by @willkill07 in #1233
- build: inherit example SDK versions for prerelease packaging by @willkill07 in #1236
- build: allow version locking with a cold uv cache by @willkill07 in #1238
📝 Documentation Updates
- docs: document 0.9.1 release changes by @willkill07 in #1139
- docs: add 0.9.2 and 0.9.3 release notes by @bbednarski9 in #1161
- docs: fix preempting typo by @greysonlalonde in #1175
- docs: update 0.10.0 release notes and migration guide by @willkill07 in #1177
- docs: update 0.10 release notes and migration guidance by @willkill07 in #1230
- docs: update 0.10 release notes and migration guidance by @willkill07 in #1261
- docs: update 0.10 release notes for latest fixes by @willkill07 in #1269
🧩 Skills Updates
- skills: add release workflow automation by @dagardner-nv in #1138
New Contributors
- @elookpotts-nvidia made their first contribution in #1143
- @fernandol-nvidia made their first contribution in #1151
- @rissingh23 made their first contribution in #1154
- @greysonlalonde made their first contribution in #1175
Full Changelog: 0.9.0...0.10.0