Skip to content

refactor: hoist provider schema handling for Responses, Messages, and Chat Completions#288

Draft
zhongxuanwang-nv wants to merge 1 commit into
NVIDIA:mainfrom
zhongxuanwang-nv:refactor/relay-325-hoist-provider-schema-handling
Draft

refactor: hoist provider schema handling for Responses, Messages, and Chat Completions#288
zhongxuanwang-nv wants to merge 1 commit into
NVIDIA:mainfrom
zhongxuanwang-nv:refactor/relay-325-hoist-provider-schema-handling

Conversation

@zhongxuanwang-nv

Copy link
Copy Markdown
Member

Overview

Hoist provider schema handling for OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages into a single codec-layer path, so exporters and plugins consume normalized provider data instead of re-implementing provider parsing from raw JSON. (RELAY-325)

Opened as a draft for review. Local validation: cargo fmt, cargo clippy --all-targets -D warnings, and the pre-commit hooks pass; targeted unit + integration tests are green (resolve, codec, observability::manual, otel, openinference, atif, types, adaptive request-surface, plus codec/pipeline integration). The full cross-language matrix is left to CI — no binding or public-API surfaces changed.

  • 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

  • codec::resolve (new) — the canonical detect-then-decode entry point. ProviderSurface + detect_request_surface (priority order hoisted verbatim from adaptive's resolver) / detect_response_surface (strict; ambiguous or empty payloads → None, avoiding the codecs' permissive {} decode) + fail-open normalize_request/normalize_response.
  • Event::normalized_llm_request/response — annotation-first Cow helpers over the detector; annotated_*() left unchanged.
  • OpenAIResponsesCodec — response-only extension to decode top-level output_text and item-level output[].type == "output_text" (structured output keeps precedence). Request input_text deliberately left out (strict request parse).
  • observability::manual (new) — the otel/openinference non-provider usage/cost fallback de-duplicated into one module, with the USD-only vs emit-any-currency policy parameterized. otel.rs and openinference.rs each shrink ~185 lines.
  • ATIF — reads normalized message text from annotations when present (multimodal falls back to the raw extractor); tool calls and metrics stay on the raw path so provider-specific extras (e.g. provider_data) are preserved.
  • adaptiveresolve_request_surface_from_request delegates to codec::resolve::detect_request_surface (function name, AcgError::Internal message, and priority order preserved).
  • Fixed the misleading "global codec registry" docstring in codec/traits.rs; added an annotation-vs-raw-fallback note to provider-response-codecs.mdx.

Where should the reviewer start?

crates/core/src/codec/resolve.rs (the new single path), then crates/core/src/observability/atif.rs — the annotation-first / raw-fallback consumer is the trickiest equivalence surface (the raw parser is intentionally retained where the normalized form would be lossy: tool-call extras and multimodal content).

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

  • Relates to RELAY-325

@copy-pr-bot

copy-pr-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 43784b3a-5c41-4fbb-b2b8-c098a62a7038

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions github-actions Bot added size:XL PR is extra large Improvement improvement to existing functionality lang:rust PR changes/introduces Rust code labels Jun 23, 2026
@zhongxuanwang-nv zhongxuanwang-nv self-assigned this Jun 23, 2026
@zhongxuanwang-nv zhongxuanwang-nv added the DO NOT MERGE PR should not be merged; see PR for details label Jun 23, 2026
@zhongxuanwang-nv zhongxuanwang-nv force-pushed the refactor/relay-325-hoist-provider-schema-handling branch from 2fa6ba4 to d60cc52 Compare June 23, 2026 00:25
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

@zhongxuanwang-nv zhongxuanwang-nv force-pushed the refactor/relay-325-hoist-provider-schema-handling branch from d60cc52 to 8055c45 Compare June 23, 2026 04:31
@willkill07 willkill07 added this to the 0.5 milestone Jun 23, 2026
… Chat Completions

Consolidate provider schema handling for OpenAI Chat Completions, OpenAI
Responses, and Anthropic Messages behind a single codec-layer path so exporters
and plugins consume normalized data instead of re-parsing raw provider JSON.

- Add codec::resolve: ProviderSurface detection + fail-open
  normalize_request/normalize_response as the canonical detect-then-decode entry.
- Add Event::normalized_llm_request/response annotation-first helpers and consume
  them in the OpenInference exporter (annotation -> OpenClaw replay -> codec
  detection), so un-annotated provider events emit structured attributes.
- Extend OpenAIResponsesCodec to decode top-level and item-level output_text.
- Dedupe the otel/openinference non-provider usage/cost fallback into
  observability::manual (currency policy parameterized).
- ATIF reads normalized message text from annotations (raw fallback for
  multimodal); tool calls and metrics stay on the raw path to preserve provider
  extras.
- adaptive delegates request-surface detection to codec::resolve.
- Fix the misleading "global codec registry" docstring and document the
  annotation-vs-raw-fallback rule.

Relates to RELAY-325.

Signed-off-by: Zhongxuan Wang <daniewang@nvidia.com>
@zhongxuanwang-nv zhongxuanwang-nv force-pushed the refactor/relay-325-hoist-provider-schema-handling branch from 8055c45 to 43d96d2 Compare June 23, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DO NOT MERGE PR should not be merged; see PR for details Improvement improvement to existing functionality lang:rust PR changes/introduces Rust code size:XL PR is extra large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants