Skip to content

fix: preserve Codex automation tool outputs - #1016

Merged
rapids-bot[bot] merged 2 commits into
NVIDIA:mainfrom
willkill07:wkillian/relay-840-codex-scheduled-tasks-failing-with-nemo-relay
Sep 10, 2026
Merged

fix: preserve Codex automation tool outputs#1016
rapids-bot[bot] merged 2 commits into
NVIDIA:mainfrom
willkill07:wkillian/relay-840-codex-scheduled-tasks-failing-with-nemo-relay

Conversation

@willkill07

@willkill07 willkill07 commented Sep 10, 2026

Copy link
Copy Markdown
Member

Overview

Allow Codex scheduled and automation tasks to pass through Relay when Codex persists a namespaced app-tool result without the public Responses API call ID. The compatibility path is restricted to requests carrying Codex installation metadata and preserves the native item losslessly.

  • I confirm this contribution is my own work, or I have the right to submit it under this project license.
  • I searched existing issues and open pull requests, and this does not duplicate existing work.

Details

  • Detect the Codex Responses dialect from non-empty client_metadata.x-codex-installation-id.
  • Preserve namespaced function_call_output items as provider-native only when call_id is absent or null and valid name, namespace, and output fields are present.
  • Keep strict validation for standard Responses requests and malformed Codex items.
  • Add regression coverage for absent and null call IDs, exact round trips, surgical edits, and strict negative cases.

Validation:

  • cargo fmt --all -- --check
  • cargo test -p nemo-relay openai_responses --lib (57 passed)
  • cargo test -p nemo-relay --lib (1,599 passed)
  • Commit hooks passed except workspace-wide cargo clippy and cargo check, which are blocked by existing unresolved initialize_plugins and clear_plugin_configuration references in nemo-relay-pii-redaction tests.
  • just test-rust is blocked by the same unrelated nemo-relay-pii-redaction compilation errors.

Breaking changes: none.

Where should the reviewer start?

Start with decode_responses_input_item in crates/core/src/codec/openai_responses.rs, then review codex_namespaced_function_output_without_call_id_round_trips_losslessly in the corresponding codec tests.

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

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility with Codex-formatted OpenAI Responses.
    • Preserves valid Codex function-call output messages even when standard call identifiers are absent.
    • Maintains unknown fields and explicit null values during request processing.
    • Continues rejecting malformed or incomplete metadata and invalid tool results.

Signed-off-by: Will Killian <wkillian@nvidia.com>
@willkill07
willkill07 requested a review from a team as a code owner September 10, 2026 00:23
@github-actions github-actions Bot added size:S PR is small Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code labels Sep 10, 2026
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 1b385991-7d54-4605-b88a-b1a9507e8608

📥 Commits

Reviewing files that changed from the base of the PR and between eb3d1a0 and 0873894.

📒 Files selected for processing (2)
  • crates/core/src/codec/openai_responses.rs
  • crates/core/tests/unit/codec/openai_responses_tests.rs

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (44)
  • GitHub Check: Node.js / Test (linux-arm64)
  • GitHub Check: Node.js / Package (linux-musl-arm64)
  • GitHub Check: Rust / Package (linux-musl-arm64)
  • GitHub Check: Node.js / Package (linux-musl-amd64)
  • GitHub Check: Rust / Package (windows-amd64)
  • GitHub Check: Node.js / Package (windows-amd64)
  • GitHub Check: Rust / Package (windows-arm64)
  • GitHub Check: Node.js / Package (linux-amd64)
  • GitHub Check: Node.js / Package (windows-arm64)
  • GitHub Check: Rust / Package (linux-amd64)
  • GitHub Check: Rust / Package (macos-arm64)
  • GitHub Check: Rust / Package (linux-arm64)
  • GitHub Check: Node.js / Package (macos-arm64)
  • GitHub Check: Python / Test (windows-arm64)
  • GitHub Check: Node.js / Package (linux-arm64)
  • GitHub Check: Node.js / Test (windows-amd64)
  • GitHub Check: Rust / Package (linux-musl-amd64)
  • GitHub Check: Node.js / Test (windows-arm64)
  • GitHub Check: Node.js / Test (macos-arm64)
  • GitHub Check: Python / Package (windows-arm64)
  • GitHub Check: Rust / Test (linux-amd64)
  • GitHub Check: Python / Package (linux-musl-amd64)
  • GitHub Check: Python / Package (macos-arm64)
  • GitHub Check: Rust / Test (macos-arm64)
  • GitHub Check: Python / Package (linux-musl-arm64)
  • GitHub Check: Python / Package (windows-amd64)
  • GitHub Check: Node.js / Test (linux-amd64)
  • GitHub Check: Go / Test (macos-arm64)
  • GitHub Check: Rust / Test (linux-arm64)
  • GitHub Check: Python / Test (linux-arm64)
  • GitHub Check: Python / Package (linux-amd64)
  • GitHub Check: Python / Test (linux-amd64)
  • GitHub Check: Python / Package (linux-arm64)
  • GitHub Check: Python / Test (windows-amd64)
  • GitHub Check: Rust / Test (windows-arm64)
  • GitHub Check: Go / Test (windows-amd64)
  • GitHub Check: Rust / Test (windows-amd64)
  • GitHub Check: Go / Test (linux-amd64)
  • GitHub Check: Python / Test (macos-arm64)
  • GitHub Check: Go / Test (linux-arm64)
  • GitHub Check: Go / Test (windows-arm64)
  • GitHub Check: Check / Run
  • GitHub Check: Node.js / Package OpenClaw plugin
  • GitHub Check: Preview docs
🧰 Additional context used
📓 Path-based instructions (29)
Tests should cover the behavior promised by the changed API surface, including error paths and cross-request isolation where relevant.

⚙️ CodeRabbit configuration file

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
Review the Rust runtime for async correctness, scope isolation, middleware ordering, and event lifecycle regressions.

⚙️ CodeRabbit configuration file

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
For changes affecting `crates/core`, `crates/adaptive`, or shared Rust runtime semantics, expand validation to the full binding matrix with `validate-change`.

📄 CodeRabbit inference engine (.agents/skills/test-rust-core/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
If a language surface changed, always run that language's test target even when Rust core did not change.

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Keep async behavior on the existing tokio-based model.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
[ ] Do all bindings expose the same logical knobs and semantics?

📄 CodeRabbit inference engine (.agents/skills/maintain-observability/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
If any Rust code changed, always run `just test-rust`.

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
**Formatting**: `cargo fmt` (rustfmt defaults) **Linting**: `cargo clippy -- -D warnings` -- all warnings are treated as errors

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
If any Rust code changed, also run `cargo fmt --all`.

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Use `Json = serde_json::Value` in Rust-facing runtime APIs where the existing code expects JSON payloads.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
[ ] Branch scope is coherent and reviewable [ ] Relevant tests passed under `validate-change` [ ] Docs and examples updated for any public behavior changes [ ] Pull request title follows Conventional Commit style and uses the correct type U...

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Format changed files with the language-native formatter before the final lint/test pass.

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Keep NeMo Relay optional Use stable, documented framework or plugin APIs Wrap tool and LLM paths at the correct framework boundary Preserve the framework's original behavior when NeMo Relay is absent Integration uses public framework or plu...

📄 CodeRabbit inference engine (.agents/skills/contribute-integration/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Tool execution callbacks and each execution-intercept `next` continuation return the canonical `ToolExecutionResult { result, annotation }`.

📄 CodeRabbit inference engine (.agents/skills/add-middleware/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
For changes in the Rust core, adaptive, dynamic plugin, worker, worker-proto, or types crates, run `cargo fmt --all`, `just test-rust`, and `cargo clippy --workspace --all-targets -- -D warnings` as the default validation sequence.

📄 CodeRabbit inference engine (.agents/skills/test-rust-core/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
[ ] `crates/core` or `crates/adaptive` changes ran the full language matrix

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
For shared-semantics or broad runtime changes in the core or adaptive crates, run `just ci=true test-rust`.

📄 CodeRabbit inference engine (.agents/skills/test-rust-core/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
**Core Rust** Implement the behavior first in `crates/core/src/api/` and related core modules such as `crates/core/src/api/runtime/`, `crates/core/src/codec/`, or `crates/core/src/json.rs`.

📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)

Files:

  • crates/core/src/codec/openai_responses.rs
Keep SPDX headers on source, docs, scripts, and configuration files.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
**Validation** Run the validation matrix from the `validate-change` skill for the affected surfaces.

📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Use `test-ffi-surface`.

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
[ ] Any Rust change ran `just test-rust` [ ] Any Rust change ran `cargo fmt --all` [ ] Any Rust change ran `cargo clippy --workspace --all-targets -- -D warnings`

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Follow binding naming conventions: Rust and Python `snake_case`, C FFI exports prefixed `nemo_relay_`, Go `PascalCase` for public APIs, Node.js `camelCase`.

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
[ ] SPDX license header on any new files

📄 CodeRabbit inference engine (.agents/skills/add-binding-feature/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Update docs and examples in the same branch.

📄 CodeRabbit inference engine (.agents/skills/maintain-observability/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
If the change touched `crates/core` or shared runtime semantics, also use `validate-change` for broader validation

📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Run `cargo fmt --all` for all FFI work since it is Rust work Run `just test-rust` to validate FFI changes Run `cargo clippy --workspace --all-targets -- -D warnings` to enforce strict linting on FFI work

📄 CodeRabbit inference engine (.agents/skills/test-ffi-surface/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
Run `cargo fmt --all` when Rust files are changed as part of Node work Run `cargo clippy --workspace --all-targets -- -D warnings` when Rust files are changed as part of Node work Run `just test-rust` when Rust files are changed as part of...

📄 CodeRabbit inference engine (.agents/skills/test-node-binding/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
When Rust files changed as part of Go work, also run `cargo fmt --all`, `just test-rust`, and `cargo clippy --workspace --all-targets -- -D warnings`

📄 CodeRabbit inference engine (.agents/skills/test-go-binding/SKILL.md)

Files:

  • crates/core/tests/unit/codec/openai_responses_tests.rs
  • crates/core/src/codec/openai_responses.rs
🔇 Additional comments (2)
crates/core/src/codec/openai_responses.rs (1)

399-399: LGTM!

Also applies to: 486-506, 1316-1321, 1336-1336

crates/core/tests/unit/codec/openai_responses_tests.rs (1)

780-930: LGTM!

Also applies to: 1343-1343, 1354-1354, 1364-1364


Walkthrough

The decoder detects Codex metadata, passes the dialect context to input-item decoding, and preserves valid Codex function_call_output items without call_id. Tests cover lossless round trips and invalid cases.

Changes

Codex input decoding

Layer / File(s) Summary
Codex dialect detection and propagation
crates/core/src/codec/openai_responses.rs, crates/core/tests/unit/codec/openai_responses_tests.rs
Request decoding derives the Codex dialect from client_metadata.x-codex-installation-id and passes it to input-item decoding. Existing malformed, portable, and native test branches provide the new context argument.
Codex-native output preservation and validation
crates/core/src/codec/openai_responses.rs, crates/core/tests/unit/codec/openai_responses_tests.rs
Valid Codex-namespaced function_call_output items without call_id retain their complete native JSON representation. Invalid metadata and incomplete items remain rejected. Tests cover null fields, unknown data, and round-trip behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 624c0

This change preserves valid Codex tool outputs that omit public call IDs while retaining strict validation for standard and malformed requests. The covered decoding and round-trip behavior presents no remaining merge-blocking risk.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title follows Conventional Commits format with the allowed lowercase type "fix". It provides a concise, imperative summary of preserving Codex automation tool outputs, uses no trailing period, and…
Description check ✅ Passed The description includes all required sections. It explains the change, records validation results and known unrelated workspace blockers, identifies review starting points, confirms no breaking chang…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@willkill07 willkill07 self-assigned this Sep 10, 2026
@willkill07 willkill07 added this to the 0.9 milestone Sep 10, 2026
@github-actions

Copy link
Copy Markdown

@mnajafian-nv mnajafian-nv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mnajafian-nv

Copy link
Copy Markdown
Contributor

/merge

@rapids-bot
rapids-bot Bot merged commit aa1e5be into NVIDIA:main Sep 10, 2026
97 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug issue describes bug; PR fixes bug lang:rust PR changes/introduces Rust code size:S PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants