Repository navigation
fix(responses): resolve bidirectional tool namespace identity and custom tool payload for Codex - #12928
Closed
multi-forge wants to merge 4 commits into
Conversation
11 of 12 tasks
Collaborator
|
Thanks for tackling the Codex/Gemini namespace-delimiter mismatch — the core problem is
|
…tom tool payload for Codex
When downstream clients using the OpenAI Responses wire protocol (such as OpenAI
Codex CLI) submit namespaced tools (e.g. namespace: 'functions', name: 'exec'),
OmniRoute flattens the wire descriptor to 'functions__exec'. Providers like
Gemini, Antigravity, and Vertex AI normalize consecutive underscores to single
underscores ('functions_exec').
This commit addresses three interconnected issues in the translation pipeline:
1. Bidirectional Request Tool Identity Resolution:
- Enhance resolveRequestToolIdentity to resolve tool names against candidates
using delimiter variations (single underscore, double underscore, dot, hyphen)
and leaf names, ensuring the original {namespace, name} tuple is restored
even when the upstream provider alters the separator.
2. Gemini Tool Sanitizer De-duplication:
- Update isSanitizedNameTaken to compare normalized forms rather than raw
strings, preventing false collision detection when both 'functions_exec'
(from conversation history) and 'functions__exec' (from declaration) exist.
- Replace non-deterministic Date.now() collision suffixing with deterministic
hash digests.
3. Custom Tool Payload Classification:
- Ensure isCustomTool resolves the underlying tool identity before checking
state.customToolNames, allowing namespaced custom tools (such as Codex's
functions.exec) to correctly emit custom_tool_call events with raw input
rather than regular function_call arguments.
- Populate compound namespace variations in collectResponsesCustomToolNames.
multi-forge
force-pushed
the
fix/responses-codex-tool-namespace-resolution
branch
from
September 15, 2026 14:10
edd9fb4 to
a96510d
Compare
Author
|
Thanks for the review, @diegosouzapw! All items addressed:
Ready for re-review! |
…sification resolveRequestToolIdentity()'s suffix-match step matched a dotted tool name against any candidate's leaf regardless of namespace (e.g. "other.exec_command" resolved to the "exec" namespace's identity), breaking the pre-existing dotted-alias contract. Dot notation is now handled exclusively by the exact namespace.name check; the suffix step stays underscore-only for hash-prefixed wire names. The Codex-specific "exec" custom-tool carve-out in emitToolCall/closeToolCall matched ANY tool literally named "exec", including plain function tools with no namespace (e.g. Gemma), misclassifying them as custom_tool_call. Scope the carve-out to only fire when the name resolved through a namespace identity. Also extract the duplicated isCustomTool computation from emitToolCall and closeToolCall into a shared resolveToolCustomStatus() helper so the two call sites cannot drift apart, which brings openai-responses.ts back under its frozen file-size budget. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
restoreResponsesPassthroughFunctionCallIdentity() was switched from a raw Map.get() to resolveRequestToolIdentity() to pick up the same delimiter-variant resolution as the openai-responses translator, but the import was missing — a live TS2552 (undeclared reference) that would throw a ReferenceError on the first Responses passthrough function_call restore. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Resolves the conflict in nonStreamingClientTranslate.ts — both sides call resolveRequestToolIdentity on the same line; kept the base's explanatory comment (cheaper-inference#12370). Overlaps cheaper-inference#13128 in this area — whichever lands second needs a re-sync. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When downstream clients using the OpenAI Responses wire protocol (such as OpenAI Codex CLI) submit namespaced tools (e.g. namespace: "functions", name: "exec"), OmniRoute flattens the wire descriptor to "functions__exec". Providers like Gemini, Antigravity, and Vertex AI normalize consecutive underscores to single underscores ("functions_exec").
This change fixes three interrelated issues that previously prevented Codex CLI from executing tools through Gemini/Antigravity:
resolveRequestToolIdentityto resolve tool names against registered namespace candidates across delimiter variations (_,__,.,-) and bare leaf names, restoring the{namespace, name}tuple on response items.geminiToolsSanitizer.tswhen both flattened and normalized forms appear in context history.customToolNames, enabling namespaced custom tools (like Codex's JavaScript isolateexec) to emitcustom_tool_callwith rawinputrather thanfunction_callwith JSONarguments.Related Issues
mcp__prefix, breaking every namespace sub-tool (1mcp, ctx, multi_agent, etc.) #7936Validation
release/v3.8.51); focused checks rerun afterwardTests Added Or Updated
tests/unit/translator-resp-openai-responses-namespace-identity.test.tsfunctions_exec).functions.exec).Coverage Notes
tests/unit/translator-resp-openai-responses-namespace-identity.test.ts.antigravity/gemini-3.8-flash.Reviewer Notes
changelog.d/fixes/responses-codex-tool-namespace-resolution.md.