mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-11 17:52:31 +03:00
fix(translator): keep Responses namespace identity across the hub-and-spoke pivot (#9783)
Step 1 of the pivot (openai-responses -> openai) flattens namespace sub-tools to a qualified wire name (#8295) and records the `{namespace, name}` pair on a non-enumerable `_toolNameMap`. Step 2 (openai -> target) returns a brand-new object, so the property was dropped for every non-OpenAI target. chatCore then handed `null` to the #7936 response seam and namespace sub-tool calls reached the client under their flattened name, which Codex rejects with `unsupported call: <name>` — the symptom #7936 was opened to fix. Copying `_toolNameMap` through is not viable: openai-to-claude and openai-to-gemini publish their own `Map<string, string>` alias map on that same property during step 2, so it carries two incompatible types. This adds a dedicated `_namespaceToolIdentityMap`, propagated by translateRequest across the pivot; chatCore prefers it and falls back to `_toolNameMap` for the non-pivot producers. Both keys are stripped from the cliproxyapi wire body. Fixes #9780
This commit is contained in:
1
changelog.d/fixes/9783-namespace-identity-pivot.md
Normal file
1
changelog.d/fixes/9783-namespace-identity-pivot.md
Normal file
@@ -0,0 +1 @@
|
||||
- **Translator**: keep the Responses namespace identity map across the hub-and-spoke pivot — namespace sub-tool calls routed to non-OpenAI targets (Kiro, Cursor) no longer come back flattened (`unsupported call: functions__exec` in Codex CLI) (#9783 — thanks @VXNCXNX)
|
||||
@@ -1,3 +1,4 @@
|
||||
import { extractRequestToolIdentityMap } from "./chatCore/requestToolIdentity.ts";
|
||||
import { injectMemoryAndSkills } from "./chatCore/memorySkillsInjection.ts";
|
||||
import { resolveChatCoreRequestSetup } from "./chatCore/requestSetup.ts";
|
||||
import { buildFailureUsageRecord } from "./chatCore/failureUsage.ts";
|
||||
@@ -2264,20 +2265,7 @@ export async function handleChatCore({
|
||||
// the latter is a Kiro/Claude passthrough alias channel with string values,
|
||||
// while namespace identities carry `{namespace, name}` for the #7936 response
|
||||
// seam. Extract first because Kiro merge may reuse `_toolNameMap` below.
|
||||
//
|
||||
// #9780 — prefer the dedicated channel: on a pivot the openai->claude/gemini
|
||||
// step publishes its own alias map on `_toolNameMap`, so that property alone
|
||||
// yields aliases here. The `_toolNameMap` read stays as the fallback for the
|
||||
// non-pivot producers (executors/base.ts, cliproxyapi.ts, antigravity).
|
||||
const namespaceIdentityMap = translatedBody._namespaceToolIdentityMap;
|
||||
const requestToolIdentityMap =
|
||||
namespaceIdentityMap instanceof Map
|
||||
? namespaceIdentityMap
|
||||
: translatedBody._toolNameMap instanceof Map
|
||||
? translatedBody._toolNameMap
|
||||
: null;
|
||||
delete translatedBody._namespaceToolIdentityMap;
|
||||
delete translatedBody._toolNameMap;
|
||||
const requestToolIdentityMap = extractRequestToolIdentityMap(translatedBody);
|
||||
|
||||
// Kiro: sanitize tool schemas before dispatch. Kiro returns 400 "Improperly
|
||||
// formed request" for unsupported JSON-Schema keywords (anyOf/$ref/if-then,
|
||||
|
||||
26
open-sse/handlers/chatCore/requestToolIdentity.ts
Normal file
26
open-sse/handlers/chatCore/requestToolIdentity.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
type NamespaceIdentity = { namespace: string; name: string };
|
||||
|
||||
/**
|
||||
* Extract the #7936 request-tool identity map from the translated body and
|
||||
* strip both side channels before dispatch.
|
||||
*
|
||||
* #9780 — prefer the dedicated `_namespaceToolIdentityMap`: on a pivot the
|
||||
* openai->claude/gemini step publishes its own alias `Map<string, string>` on
|
||||
* `_toolNameMap`, so that property alone can yield aliases instead of
|
||||
* identities. The `_toolNameMap` read stays as the fallback for the non-pivot
|
||||
* producers (executors/base.ts, cliproxyapi.ts, antigravity).
|
||||
*/
|
||||
export function extractRequestToolIdentityMap(
|
||||
translatedBody: Record<string, unknown>
|
||||
): Map<string, NamespaceIdentity> | null {
|
||||
const namespaceIdentityMap = translatedBody._namespaceToolIdentityMap;
|
||||
const requestToolIdentityMap =
|
||||
namespaceIdentityMap instanceof Map
|
||||
? namespaceIdentityMap
|
||||
: translatedBody._toolNameMap instanceof Map
|
||||
? translatedBody._toolNameMap
|
||||
: null;
|
||||
delete translatedBody._namespaceToolIdentityMap;
|
||||
delete translatedBody._toolNameMap;
|
||||
return requestToolIdentityMap as Map<string, NamespaceIdentity> | null;
|
||||
}
|
||||
Reference in New Issue
Block a user