Skip to content

fix(codex): preserve native Responses passthrough tools and history - #3107

Merged
diegosouzapw merged 3 commits into
diegosouzapw:release/v3.8.9from
yinaoxiong:fix/codex-tool-search-v388
Jun 3, 2026
Merged

diegosouzapw merged 3 commits into
diegosouzapw:release/v3.8.9from
yinaoxiong:fix/codex-tool-search-v388

Conversation

@yinaoxiong

@yinaoxiong yinaoxiong commented Jun 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR fixes several Codex native Responses passthrough regressions where OmniRoute was dropping protocol-native tools or history items before forwarding requests to the Codex backend.

Changes:

  • Preserve the Responses API tool_search hosted tool in normalizeCodexTools().
  • Preserve native Codex custom tools such as apply_patch, including their freeform grammar format.
  • Preserve function tool strict values when normalizing Codex tools.
  • Preserve native assistant history messages with phase: "commentary" and output_text content in Codex native passthrough mode.
  • Keep the previous sanitizer behavior for non-native / translated paths, so assistant commentary is still stripped outside Codex native passthrough.

Background

Recent Codex CLI versions send richer native Responses API payloads through /v1/responses. These payloads include protocol-native items that are not plain OpenAI-compatible function tools:

  • Codex CLI 0.136 multi-agent v1 discovery can expose subagent tools through the hosted { "type": "tool_search" } tool.
  • Native apply_patch is sent as a Responses API custom/freeform tool:
    { "type": "custom", "name": "apply_patch", "format": ... }.
  • Codex conversation history can include assistant messages with:
    { "role": "assistant", "phase": "commentary", "content": [{ "type": "output_text", ... }] }.

The official Codex client treats these as valid Responses API protocol items. It also sets store=false for the ChatGPT Codex backend, so follow-up turns rely on replaying necessary history through input.

Problem

OmniRoute previously normalized Codex requests too aggressively:

  • Unknown hosted tools were dropped, including tool_search.
  • Native custom tools were dropped unless they looked like function tools.
  • Assistant phase: "commentary" history was treated as an internal runtime frame and removed, even in native Codex passthrough mode.

As a result, the upstream Codex backend could receive an incomplete version of the native client request.

Impact

Affected scenarios include:

  • Codex CLI 0.136 multi-agent v1 tool discovery.
  • Native Codex apply_patch / freeform custom tool calls.
  • Multi-turn Codex workflows where assistant commentary/history is replayed through /v1/responses.
  • Long-running agent flows where prior visible assistant progress messages help preserve execution context.

Without this fix, the model may be unable to discover subagent tools, unable to call native custom tools, or lose part of the assistant history between turns.

Fix

This PR keeps the behavior scoped by path:

  • In Codex native passthrough mode, preserve native Responses API tools and assistant commentary history.
  • Outside native passthrough, keep the existing stricter cleanup behavior to avoid forwarding commentary from translated/non-native clients.

Validation

  • npm run lint
  • npm run test:unit
  • npm run test:coverage
  • Coverage is still >= 60% for statements, lines, functions, and branches
  • SonarQube PR analysis is green or any remaining issues are explicitly documented below

Targeted validation:

node --import tsx/esm --test tests/unit/executor-codex.test.ts
node --import tsx/esm --test tests/unit/responses-input-sanitizer-name.test.ts

Results:

  • tests/unit/executor-codex.test.ts: 39 passed, 0 failed
  • tests/unit/responses-input-sanitizer-name.test.ts: 8 passed, 0 failed

Manual integration validation:

  • Deployed the patched OmniRoute build locally with Docker Compose.
  • Confirmed the running container includes the patched Codex executor and sanitizer files.
  • Confirmed the service starts healthy.
  • Confirmed custom Docker Compose mounts were preserved during local deployment.
  • Previously validated Codex CLI 0.136 with:
    • features.multi_agent=true
    • features.multi_agent_v2=false
    • Responses API provider
  • Confirmed tool_search returns:
    • multi_agent_v1.spawn_agent
    • multi_agent_v1.resume_agent
    • multi_agent_v1.close_agent
    • multi_agent_v1.wait_agent
    • multi_agent_v1.send_input
  • Confirmed a v1 subagent can be spawned and waited successfully.

Tests Added Or Updated

  • Updated tests/unit/executor-codex.test.ts
    • Covers preserving { type: "tool_search" }.
    • Covers preserving native Codex custom tools.
    • Covers preserving function tool strict.
    • Covers preserving native assistant phase: "commentary" history.
    • Covers continuing to strip assistant commentary outside native passthrough.

Coverage Notes

The production change is limited to Codex request normalization and Responses input sanitization behavior. No migrations, UI changes, or broad routing changes are included.

Reviewer Notes

  • This PR now contains three focused commits:
    • fix(codex): preserve tool_search hosted tool
    • fix(codex): preserve native custom tools
    • fix(codex): preserve native assistant commentary history
  • The second and third commits are follow-up fixes discovered while testing the same Codex native Responses passthrough path.
  • The sanitizer change is intentionally opt-in for native passthrough; default behavior remains unchanged.

@yinaoxiong
yinaoxiong requested a review from diegosouzapw as a code owner June 3, 2026 13:15

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds "tool_search" to the set of hosted tool types (CODEX_HOSTED_TOOL_TYPES) in open-sse/executors/codex.ts and updates the corresponding unit tests in tests/unit/executor-codex.test.ts to verify that the tool is preserved during request transformation. There are no review comments, and I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

// `{ type: "namespace", name: "mcp__atlassian__", tools: [...] }` for MCP tool groups.
// Keep them through `normalizeCodexTools` so upstream can execute them.
const CODEX_HOSTED_TOOL_TYPES: ReadonlySet<string> = new Set([
"tool_search",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Adding "tool_search" to the CODEX_HOSTED_TOOL_TYPES set is appropriate. This hosted tool type should be preserved through normalizeCodexTools like other hosted tools.

],
},
{ type: "image_generation", output_format: "png" },
{ type: "tool_search" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Adding the tool_search tool type to the test input is correct. This verifies the new hosted tool type is handled properly.

assert.deepEqual(types, [
"function",
"namespace",
"image_generation",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Adding "tool_search" to the expected output types array is correct. This completes the test verification for the new hosted tool type.

@kilo-code-bot

kilo-code-bot Bot commented Jun 3, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (3 files)
  • open-sse/executors/codex.ts - 0 issues
  • open-sse/services/responsesInputSanitizer.ts - 0 issues
  • tests/unit/executor-codex.test.ts - 0 issues

Notes on Incremental Changes

This PR was previously reviewed at commit 18e6a0844cae7b8bc06533216984af623aa19e83. The incremental changes since then:

  1. open-sse/executors/codex.ts (lines 451-452, 479-489, 547-562, 1237-1239, 1307):

    • Added preserveCustomTools option to normalizeCodexTools signature
    • Added logic to preserve { type: "custom", name, format } tools when preserveCustomTools === true
    • Added strict property preservation for function tools during normalization
    • Passes nativeCodexPassthrough flag to sanitizeResponsesInputItems and normalizeCodexTools
    • All changes follow existing code patterns and conventions
  2. open-sse/services/responsesInputSanitizer.ts (lines 2-4, 73-77, 83):

    • Added SanitizeResponsesInputOptions type with dropInternalAssistantMessages option
    • Added conditional check using the new option (defaults to true for backward compatibility)
    • Clean API extension with proper defaults
  3. tests/unit/executor-codex.test.ts (lines 453-541, 543-581, 1046-1114):

    • Updated test name from "strips raw internal assistant commentary" to "preserves native assistant commentary history"
    • Changed assertion from false to true for commentary preservation (native passthrough)
    • Added new test "still strips assistant commentary outside native passthrough" for non-passthrough path
    • Added tests for native Codex custom tools preservation and dropping outside passthrough

All changes are well-tested and follow the existing codebase patterns. The previous review suggestions regarding tool_search have been addressed in the test assertions.


Reviewed by laguna-m.1-20260312:free · 921,973 tokens

@yinaoxiong yinaoxiong changed the title fix(codex): preserve tool_search hosted tool fix(codex): preserve native Responses passthrough tools and history Jun 3, 2026
@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks for the careful work, @yinaoxiong! 🙌 Preserving native Codex Responses passthrough tools (tool_search, custom tools like apply_patch) and the assistant commentary history on the native path is exactly the right scoping — gated on _nativeCodexPassthrough so the translated path and other executors are untouched. The tests covering both the positive (native) and negative (non-native) cases made this easy to verify. Merged into release/v3.8.9 — it'll ship in the next release (v3.8.9).

@diegosouzapw
diegosouzapw merged commit 261a910 into diegosouzapw:release/v3.8.9 Jun 3, 2026
2 checks passed
@diegosouzapw diegosouzapw mentioned this pull request Jun 3, 2026
diegosouzapw added a commit that referenced this pull request Jun 3, 2026
…ors hall

Adds entries for #3097, #3101 (deepseek-web #2942/#2820), #3104, #3105, #3107,
#3109, #3111, #3113, #3115, #3122, #3125, #3127, #3129, plus a Contributors
section crediting all v3.8.9 contributors. Stamps the 3.8.9 release date.
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…iegosouzapw#3107)

* fix(codex): preserve tool_search hosted tool

* fix(codex): preserve native custom tools

* fix(codex): preserve native assistant commentary history
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…iegosouzapw#3107)

* fix(codex): preserve tool_search hosted tool

* fix(codex): preserve native custom tools

* fix(codex): preserve native assistant commentary history
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…iegosouzapw#3107)

* fix(codex): preserve tool_search hosted tool

* fix(codex): preserve native custom tools

* fix(codex): preserve native assistant commentary history
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants