Skip to content

0.10.0

Choose a tag to compare

@willkill07 willkill07 released this 08 Oct 22:25
· 378 commits to main since this release
Immutable release. Only release title and notes can be modified.
0.10.0
494018a

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_metrics plugin 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_ai traces, 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 install downloads 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 uninstall removes 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-worker when 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_url to their Relay URL ending in /backend-api/codex.
  • 🔗 W3C trace continuity: Captured propagation contexts preserve imported traceparent, sampling flags, and tracestate across 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_decision marks linked to the tool call. A pass means 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() with NemoRelayMiddleware to record graph and node lifecycles for agents served through langgraph dev or langgraph 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" and grpc-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 with nemo-relay daemon token ensure; use --require-worker to require enforcement and handle 401 or 503 while 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 traceparent and tracestate when a new trace is required. Managed LLM execution replaces propagation headers with its active context.
  • Codex trajectory exports: Each codex-task now 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 with extra.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 only RuntimeError; cancellation is preserved during callbacks and stream iteration. Worker plugins retain their existing behavior.
  • Telemetry consumers: Replace gen_ai.usage.cache_creation.input_tokens with gen_ai.usage.cache_write.input_tokens. Metrics no longer include nemo_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 reserved tool_end_without_start mark requires a nonempty data.tool_name and 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.Log RPC 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 tracestate without discarding valid traceparent, 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 lib64 aliases, 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

✨ New Features

⚡ Improvements

🐛 Bug Fixes

✅ 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

📝 Documentation Updates

🧩 Skills Updates

New Contributors

Full Changelog: 0.9.0...0.10.0