Skip to content

fix(openai-chat): strip the Responses-only encrypted tool annotation - #1779

Merged
lidge-jun merged 1 commit into
devfrom
fix/openai-chat-encrypted-tool-schema
Aug 15, 2026
Merged

lidge-jun merged 1 commit into
devfrom
fix/openai-chat-encrypted-tool-schema

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Aug 15, 2026 •

Copy link
Copy Markdown
Owner

Summary

Codex multi-agent v2 stamps a Responses-only encrypted: true marker on collaboration tool schemas. Forwarded verbatim to a generic openai-chat upstream, the provider returned spawn_agent calls with the required message argument empty.

This lands @ZHJay's #1776 with one blocking fix. The marker is stripped at the protocol boundary rather than per provider name, sharing one implementation with the Anthropic path. Properties and definitions literally named encrypted survive, and literal payloads under const, default, enum, and examples are untouched.

The traversal is now iterative over an explicit stack. Tool schemas are caller-supplied, so nesting depth is attacker-influenced, and the recursive version in #1776 would have answered a deep schema with a stack overflow on the request path.

Closes #1774

Verification

Run on the Linux validation host against this exact head:

bun test tests/openai-chat-hardening.test.ts tests/anthropic-tool-schema.test.ts tests/openai-responses-passthrough.test.ts
129 pass, 0 fail, 100326 expect() calls

bun x tsc --noEmit clean. The expect() count reflects a new 50,000-deep schema regression that walks every level to prove the strip is both correct and bounded.

Checklist

  • Focused tests for the changed subsystem pass
  • bun x tsc --noEmit clean
  • Preserves native Responses passthrough behavior
  • No request bodies or schema values logged

Summary by CodeRabbit

  • Bug Fixes

    • Improved compatibility when using tool schemas across different OpenAI and Anthropic request formats.
    • Responses-only encryption markers are now removed safely from nested schemas without altering property names or literal values.
    • Deeply nested schemas are handled reliably, and original input schemas remain unchanged.
  • Tests

    • Added coverage for nested schemas, preserved values, input immutability, and deeply nested tool definitions.

Codex multi-agent v2 stamps a Responses-only 'encrypted: true' marker on
collaboration tool schemas. Forwarded verbatim to a generic openai-chat
upstream, the provider returned spawn_agent calls with the required message
argument empty.

Strip the marker at the protocol boundary rather than per provider name, and
share one implementation with the Anthropic path. Properties and definitions
literally named 'encrypted' survive, and literal payloads under const, default,
enum, and examples are left untouched.

The walk is iterative over an explicit stack. Schemas are caller-supplied, so
depth is attacker-influenced and a recursive walk would answer a deep schema
with a stack overflow on the request path; a 50k-deep regression covers it.

Closes #1774
Co-authored-by: ZHJay <ZHJay@users.noreply.github.com>
@lidge-jun
lidge-jun merged commit 02728d2 into dev Aug 15, 2026
6 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c0b0df6a-283c-4b22-b79b-f1ae93961a40

📥 Commits

Reviewing files that changed from the base of the PR and between 53130de and 5d90299.

📒 Files selected for processing (4)
  • src/adapters/anthropic.ts
  • src/adapters/openai-chat.ts
  • src/adapters/responses-tool-schema.ts
  • tests/openai-chat-hardening.test.ts

📝 Walkthrough

Walkthrough

The change adds a shared, iterative sanitizer for Responses-only encrypted schema markers. Anthropic and OpenAI Chat adapters use it before tool-schema serialization. Tests cover preservation, immutability, recursion, and deeply nested schemas.

Changes

Encrypted marker sanitization

Layer / File(s) Summary
Shared schema sanitizer
src/adapters/responses-tool-schema.ts
Adds stripResponsesOnlyEncryptedMarker, which removes schema-level encrypted markers without recursion. It preserves literal values, names, nested structure, and __proto__ keys.
Adapter integration
src/adapters/anthropic.ts, src/adapters/openai-chat.ts
Anthropic normalization and OpenAI Chat tool formatting use the shared sanitizer before serialization.
Regression coverage
tests/openai-chat-hardening.test.ts
Tests verify marker removal, preservation of required fields and literal data, input immutability, and processing of 50,000 nested schema levels.

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

Sequence Diagram(s)

sequenceDiagram
  participant OpenAIChatAdapter
  participant SchemaSanitizer
  participant ChatCompletionsSerializer
  OpenAIChatAdapter->>SchemaSanitizer: sanitize tool parameter schema
  SchemaSanitizer-->>OpenAIChatAdapter: return schema without Responses-only markers
  OpenAIChatAdapter->>ChatCompletionsSerializer: serialize normalized tool schema
Loading

Possibly related PRs

Suggested labels: review-ready

Suggested reviewers: wibias, ingwannu

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/openai-chat-encrypted-tool-schema

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added the bug Something isn't working label Aug 15, 2026
@Wibias
Wibias deleted the fix/openai-chat-encrypted-tool-schema branch August 15, 2026 19:57
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
…idge-jun#1779)

Codex multi-agent v2 stamps a Responses-only 'encrypted: true' marker on
collaboration tool schemas. Forwarded verbatim to a generic openai-chat
upstream, the provider returned spawn_agent calls with the required message
argument empty.

Strip the marker at the protocol boundary rather than per provider name, and
share one implementation with the Anthropic path. Properties and definitions
literally named 'encrypted' survive, and literal payloads under const, default,
enum, and examples are left untouched.

The walk is iterative over an explicit stack. Schemas are caller-supplied, so
depth is attacker-influenced and a recursive walk would answer a deep schema
with a stack overflow on the request path; a 50k-deep regression covers it.

Closes lidge-jun#1774

Co-authored-by: ZHJay <ZHJay@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant