11---
2- title : " Codecs"
3- description : " "
2+ title : " Provider Codecs"
3+ description : " Understand how provider codecs normalize requests and responses, preserve unknown fields, and expose supported fields. "
44position : 7
55---
6+ import { MermaidStyles } from " @/components/MermaidStyles" ;
7+
68{ /* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
79SPDX-License-Identifier: Apache-2.0 */ }
810
911This page explains how codecs fit into the shared NeMo Relay runtime contract.
1012
1113## Overview
1214
13- A codec is a boundary translator. It converts one runtime-facing data shape into
14- another without changing who owns execution.
15+ A provider codec translates provider-native LLM request and response payloads
16+ into annotated Relay data. Middleware and observability can then work with
17+ consistent fields without taking control of provider execution. Refer to
18+ [ Provider Payload Normalization] ( /integrate-into-frameworks/provider-codecs ) for
19+ implementation guidance.
1520
16- NeMo Relay uses codecs when runtime behavior needs stable, JSON-compatible, or
17- annotated data but the application or provider surface starts from a different
18- shape .
21+ NeMo Relay also supports
22+ [ typed value codecs ] ( /integrate-into-frameworks/using-codecs ) , which translate
23+ application objects at a public wrapper API .
1924
2025## Key Features
2126
22- Codecs let NeMo Relay preserve one execution model across different boundaries:
23-
24- - Application-owned typed values
25- - Framework-owned callback payloads
26- - Provider-native LLM request and response shapes
27- - Exporter or subscriber consumers that need normalized data
28-
29- Without codecs, request-side middleware and observability would need to reason
30- about every framework or provider shape directly.
31-
32- ## Two Main Codec Roles
33-
34- NeMo Relay documentation uses the word ` codec ` in two ways: typed value codecs
35- and provider codecs. They are related, but they differ in the ways described
36- below.
37-
38- ### Typed Value Codecs
27+ Provider codecs handle:
3928
40- Typed value codecs translate application-facing values to and from JSON-friendly
41- shapes at the public wrapper boundary.
29+ - Provider-native LLM request and response payloads
30+ - Request middleware that needs normalized instructions, messages, tools, or
31+ generation controls
32+ - Events, subscribers, and exporters that need normalized response facts
4233
43- Typed value codecs are suitable for:
34+ Without provider codecs, request middleware and observability would need to
35+ parse every provider payload directly.
4436
45- - Application code wants native objects
46- - Framework callbacks expect typed values
47- - Runtime events and JSON-based middleware still need stable serialized payloads
48-
49- ### Provider Codecs
37+ ## Provider Request and Response Codecs
5038
5139Provider codecs translate provider-native LLM payloads in the request and
5240response halves of a provider call. First, request codecs decode provider
5341requests into annotated request data for request intercepts and request-side
54- middleware, then encode edits back into the provider shape when execution
55- continues. Later, after the provider returns, response codecs decode provider
42+ middleware, then encode edits back into the provider payload when execution
43+ continues. Later, after the provider returns,
44+ [ response codecs] ( /integrate-into-frameworks/provider-response-codecs ) decode provider
5645responses into annotated response data for LLM end events, subscribers,
5746exporters, and diagnostics.
5847
59- Provider codecs are suitable for :
48+ Use provider codecs when :
6049
61- - Provider payloads differ structurally
62- - Request intercepts need normalized request meaning
50+ - Provider payloads differ structurally.
51+ - Request intercepts need consistent request fields.
6352- Response annotations such as usage, model names, or tool calls should be
64- exposed in one stable shape for downstream consumers
53+ exposed through consistent fields for downstream consumers.
54+
55+ <MermaidStyles />
56+
57+ ### Request Path
58+
59+ The following diagram shows the request path.
60+
61+ ``` mermaid
62+ flowchart LR
63+ native["Provider-native request"] --> decode["Request codec decodes"]
64+ decode --> annotated["Annotated request"]
65+ annotated --> middleware["Request middleware reads or edits"]
66+ middleware --> encode["Request codec patches original"]
67+ encode --> provider["Provider call"]
68+ ```
69+
70+ ### Response Path
71+
72+ The following diagram shows the response path.
73+
74+ ``` mermaid
75+ flowchart LR
76+ provider["Provider response"] --> decode["Response codec decodes"]
77+ decode --> annotated["Annotated response"]
78+ annotated --> event["LLM end event"]
79+ event --> consumers["Subscribers and exporters"]
80+ ```
6581
6682Response decoding improves observability and downstream consistency. It does not
6783automatically change the value returned to the application unless a separate
68- typed value boundary also does so.
84+ typed value codec also does so.
6985
7086The built-in request codecs are lossless patch codecs. For an unchanged
7187annotation, the following identity holds at the JSON-value level:
@@ -86,50 +102,71 @@ changing a key overlays it.
86102- ` instructions ` represents Anthropic ` system ` and OpenAI Responses
87103 ` instructions ` .
88104- ` messages ` , content parts, function calls and results, tools, and tool choice
89- expose portable components when the shapes have shared semantics .
90- - ` api_specific ` is a tagged, mutable surface for modeled Anthropic Messages,
105+ expose portable components when the provider formats have equivalent meaning .
106+ - ` api_specific ` is a tagged, mutable field for modeled Anthropic Messages,
91107 OpenAI Chat Completions, or OpenAI Responses controls.
92108- Provider-only messages, content blocks, input items, tools, and tool choices
93109 use ` { provider, kind, value } ` , where ` value ` is the exact native JSON.
94- - Top-level ` extra ` is reserved for unknown future fields.
110+ - Top-level ` extra ` preserves unknown or unmodeled fields.
95111
96- A provider-native component can only be encoded by the provider surface named
112+ A provider-native component can only be encoded by the provider API named
97113in its ` provider ` field. Provider mismatches and portable edits that the target
98114API cannot represent fail before the provider callback.
99115
100- ## Normalized Data Consumption
116+ ### Preservation Is Not Semantic Support
117+
118+ Provider APIs can add fields or change semantics before Relay's built-in codecs
119+ are updated. The lossless patch contract preserves unknown fields and
120+ provider-native components when they are unchanged, which keeps newer payloads
121+ from being discarded. That pass-through behavior does not mean Relay
122+ understands, validates, or can portably edit those fields.
101123
102- Normalized codec output is applicable to several runtime layers:
124+ Semantic support is limited to the provider fields modeled by the current codec
125+ implementation. New provider behavior requires a codec and test update before
126+ middleware or exporters should rely on its normalized meaning.
103127
104- - Request intercepts or request-side middleware that need stable request meaning
128+ ## Typed Value Codecs
129+
130+ Typed value codecs serve a different purpose. They translate
131+ application-facing objects to and from JSON-compatible values when application
132+ code or framework callbacks need native types but Relay events and middleware
133+ need a stable serialized payload. Refer to
134+ [ Using Codecs] ( /integrate-into-frameworks/using-codecs ) for implementation
135+ guidance.
136+
137+ ## Where Normalized Data Is Used
138+
139+ Several parts of Relay use normalized codec output:
140+
141+ - Request intercepts or request-side middleware that need consistent request fields
105142- Lifecycle events that should expose consistent semantic payloads
106143- Subscribers that inspect runtime activity in process
107144- Exporters that write raw ATOF events or project them into ATIF or typed
108145 OpenTelemetry output
109146
110147Codecs do not replace scopes, middleware, subscribers, or plugins. They make
111- those layers easier to apply consistently across heterogeneous inputs.
148+ those layers easier to apply consistently across provider-specific inputs.
112149
113- ## Extraction Strategy Boundaries
150+ ## Extraction Responsibilities
114151
115- NeMo Relay keeps extraction responsibilities separated so refactors can reuse
116- normalization logic without changing runtime ownership or public binding APIs.
152+ NeMo Relay separates extraction responsibilities so normalization logic can be
153+ reused without changing public binding APIs.
117154
118155### Provider Schema Extraction
119156
120- Provider schema extraction is codec-owned. Built -in provider surfaces, such as
121- OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages, each own the
122- logic that recognizes their request and response shapes and maps them into
123- ` AnnotatedLlmRequest ` or ` AnnotatedLlmResponse ` .
157+ Provider codecs extract provider schema fields. The built -in codecs for OpenAI
158+ Chat Completions, OpenAI Responses, and Anthropic Messages recognize their
159+ request and response payloads and map them into ` AnnotatedLlmRequest ` or
160+ ` AnnotatedLlmResponse ` .
124161
125162When a managed LLM event already has an annotation, subscribers and exporters
126163consume that annotation. When an event has only raw provider JSON, best-effort
127- normalization may detect a built-in provider surface and decode it. This
164+ normalization can detect a built-in provider codec and decode it. This
128165fallback is fail-open: unrecognized, ambiguous, missing, sparse, or invalid
129166payloads remain observable as raw lifecycle data. A recognized provider hint can
130- disambiguate an otherwise identical request shape , such as an Anthropic Messages
167+ disambiguate an otherwise identical request payload , such as an Anthropic Messages
131168request without a top-level ` system ` field, but no provider annotation is
132- invented without either a matching provider surface or a recognized hint.
169+ invented without either a matching provider codec or a recognized hint.
133170
134171Provider extraction covers model names, instructions, messages, generation
135172parameters, tool definitions, tool calls, finish reasons, usage, cost,
@@ -145,24 +182,24 @@ usage, cost, provider-specific, and preserved `extra` fields. Cost parsing and
145182estimation helpers are codec implementation details behind that interface, not a
146183separate provider-response API.
147184
148- ### Provider Request Extraction
185+ ### Gateway Request Extraction
149186
150- Provider request extraction is gateway-owned . It uses the selected gateway route,
187+ The gateway extracts route-specific request facts . It uses the selected route,
151188such as OpenAI Responses, OpenAI Chat Completions, OpenAI Models, Anthropic
152189Messages, or Anthropic Count Tokens, to extract request facts that are not codec
153190schema annotations.
154191
155192Route-specific request extractors resolve gateway session IDs, request-affinity
156193keys, and fallback turn input for provider calls that arrive before the matching
157- agent prompt hook. This keeps correlation and ownership hints near gateway
158- alignment , while provider codecs stay focused on decoding request and response
194+ agent prompt hook. This keeps correlation and routing hints in the gateway
195+ routing logic , while provider codecs stay focused on request and response
159196schemas.
160197
161198Provider request extraction can also pass a narrow provider hint into codec
162199normalization. For example, the recognized ` anthropic ` and ` anthropic.messages `
163200hints let Anthropic Messages requests without a top-level ` system ` field decode
164- through the Anthropic provider surface instead of being treated as shape-only
165- OpenAI Chat payloads .
201+ through the Anthropic codec instead of being inferred as OpenAI Chat payloads
202+ from their fields alone .
166203
167204The ` nemo-relay ` gateway always enables matching request codecs for
168205` /v1/messages ` , ` /v1/chat/completions ` , and ` /v1/responses ` , for both buffered
@@ -176,16 +213,16 @@ remains writable on routes without a request codec.
176213Agent payload extraction is separate from provider codecs. Coding agents,
177214harnesses, and framework hooks can expose session IDs, event names, subagent
178215relationships, tool IDs, tool names, tool arguments, tool results, LLM hints,
179- and status fields through host-specific payload shapes . These facts help NeMo
216+ and status fields through host-specific payload formats . These facts help NeMo
180217Relay attach lifecycle events to the right scope, but they do not decode
181218provider schemas or build request-affinity keys from provider requests.
182219
183220Agent extraction may be partial. Missing identifiers use compatibility
184- fallbacks at the adapter boundary , such as synthetic session IDs, synthetic tool
221+ fallbacks in the adapter, such as synthetic session IDs, synthetic tool
185222call IDs, an explicit ` unknown_tool ` name, or a generic subagent ID. Lossy,
186223summary-only, or truncated payloads should keep their original payload and
187- metadata available for debugging instead of pretending to be reconstruction
188- grade provider data.
224+ metadata available for debugging instead of presenting them as complete provider
225+ data.
189226
190227### Exporter Projection
191228
@@ -199,22 +236,10 @@ semantic attributes remain exporter-local.
199236
200237Codecs do not decide:
201238
202- - Ownership boundaries
239+ - Which scope owns the call
203240- Middleware ordering
204241- Whether execution is allowed to continue
205242- Which exporter is active
206243
207244Those responsibilities belong to scopes, middleware, plugins, and exporter or
208245subscriber registration.
209-
210- ## Read Next
211-
212- - Use [ Using Codecs] ( /integrate-into-frameworks/using-codecs ) for typed value
213- codecs at framework-facing boundaries.
214- - Use [ Provider Codecs] ( /integrate-into-frameworks/provider-codecs ) for
215- provider-native request and response normalization.
216- - Use [ Provider Response
217- Codecs] ( /integrate-into-frameworks/provider-response-codecs ) when the main
218- need is response-side annotations for subscribers or exporters.
219- - Refer to the [ Glossary] ( /resources/glossary ) for the stable terminology used
220- across codecs, providers, and observability surfaces.
0 commit comments