From 2ba3353ae515650629e8f2905b6f9af757e9a4b6 Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 7 Nov 2026 21:10:33 +0900 Subject: [PATCH 1/2] fix(chat): honor max omission before native ultra clamping A dual-control thinking wire with a low/high ladder rewrote native ultra to high before either the effort mapper or shared omission policy could see max:__omit__. Translated Chat already omitted the strength correctly. Retain max for an explicitly omitted independent effort before ladder clamping, so the existing policy omits strength and selects thinking. Keep explicitly declared native ultra ahead of the omission lookup, and leave other aliases, clamping and legacy discriminator behavior unchanged. Add plain/gateway native/translated regressions with all thinking override states and a short ladder. Preserve no-alias clamping and expand declared native ultra coverage. Clarify the existing structure contract; public provider docs already describe the intended behavior and need no change. Verification (Bun 1.4.4; each invocation used env -i with fresh HOME, OPENCODEX_HOME, CODEX_HOME, CLAUDE_CONFIG_DIR and TMPDIR): - Before the runtime edit: bun test tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts -> 59 pass, 6 fail: native high / gateway effort:high leaks. - Same focused command after the fix -> 65 pass, 0 fail. - bun test tests/codex-integration/reasoning-effort.test.ts tests/providers/mistral-reasoning-efforts.test.ts tests/ci-workflows/file-size-ratchet.test.ts -> 61 pass, 0 fail. - bun run test:changed -> 26175 pass, 42 skip, 0 fail; 1070 files; comparison origin/dev, merge base 66e5b12e024e512082a47b6bc66a61db4227223c. - bun run typecheck -> No type errors in 2,333 files. - bun run structure:check -> structure/ SSOT checks passed. - bun run privacy:scan -> Privacy scan passed. - git diff --check and staged diff check -> exit 0. Initial typecheck stopped because dependency install skipped Bun's postinstall. Running the package-declared trusted Bun installer resolved the shim setup; the fresh typecheck above passed without source changes. Exact expanded commands, complete stdout/stderr, exit codes, diagnosis, binary hash and patch are preserved in /tmp/ocx-omit-clamp.NpeCDv/. NOT RUN: full bun run test (bounded implementation worker; import-connected coverage used), hosted CI, independent review, real-provider smoke. No remote mutation; PR, review and merge remain coordinator-owned. --- src/adapters/openai-chat/reasoning-wire.ts | 7 ++- structure/providers/chat-compat.md | 2 +- .../openai-chat-reasoning-wire-policy.test.ts | 46 +++++++++++++++++-- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/adapters/openai-chat/reasoning-wire.ts b/src/adapters/openai-chat/reasoning-wire.ts index eb1f0afd3c9..cd92ba3bc77 100644 --- a/src/adapters/openai-chat/reasoning-wire.ts +++ b/src/adapters/openai-chat/reasoning-wire.ts @@ -44,7 +44,12 @@ export function declaresIndependentChatReasoningControls(provider: OcxProviderCo export function nativeChatUltraWireEffort(provider: OcxProviderConfig, modelId: string): string | undefined { const ladder = configuredReasoningEfforts(provider, modelId); if (ladder?.includes("ultra")) return "ultra"; - if (declaresThinkingToggleWire(provider, modelId)) return ladder ? resolveEffortAtOrBelow("max", ladder) ?? "max" : "max"; + if (declaresThinkingToggleWire(provider, modelId)) { + // Keep the original alias for the independent policy to omit effort and select thinking. + if (declaresIndependentChatReasoningEffort(provider, modelId) + && isReasoningEffortOmitted(reasoningEffortMapFor(provider, modelId)?.max)) return "max"; + return ladder ? resolveEffortAtOrBelow("max", ladder) ?? "max" : "max"; + } return mapReasoningEffort(provider, modelId, "ultra"); } diff --git a/structure/providers/chat-compat.md b/structure/providers/chat-compat.md index ad45d9b8cc9..9978e04874f 100644 --- a/structure/providers/chat-compat.md +++ b/structure/providers/chat-compat.md @@ -112,7 +112,7 @@ Passthrough and routed-compaction raw-body repairs emit it as a user turn (`exte Stateful developer-guidance injection reuses that validator for its raw insertion boundary, so parsed messages and stored raw history retain the same task/guidance order. -Native Chat passthrough and translated Chat share `src/adapters/openai-chat/reasoning-wire.ts` after provider resolution. Explicit reasoning/effort false declarations and empty strength ladders remove unsupported effort; toggle false removes the switch without declaring an unknown strength axis unsupported. A declared toggle wire serializes the independent thinking choice without treating enabled/disabled/adaptive discriminators as strengths. On a dual-control wire, an explicit `__omit__` effort alias removes the strength while the caller's effort still selects the thinking switch. Dual-control requests still pass through gateway-object projection and tool-bearing effort omission; a legacy toggle configuration gains a second serialized control only with explicit effort support; unknown declarations preserve legacy raw forwarding. Native passthrough also sanitizes routed reasoning history so `reasoning` input items do not send +Native Chat passthrough and translated Chat share `src/adapters/openai-chat/reasoning-wire.ts` after provider resolution. Explicit reasoning/effort false declarations and empty strength ladders remove unsupported effort; toggle false removes the switch without declaring an unknown strength axis unsupported. A declared toggle wire serializes the independent thinking choice without treating enabled/disabled/adaptive discriminators as strengths. On a dual-control wire, an explicit `__omit__` effort alias removes the strength while the caller's effort still selects the thinking switch. Native `ultra` honors the `max` omission alias before ladder clamping, unless the declared ladder supports native `ultra` itself. Dual-control requests still pass through gateway-object projection and tool-bearing effort omission; a legacy toggle configuration gains a second serialized control only with explicit effort support; unknown declarations preserve legacy raw forwarding. Native passthrough also sanitizes routed reasoning history so `reasoning` input items do not send non-empty `content` arrays to upstream models that reject them. Chat Completions bridging repairs orphan `toolResult` messages by inserting a synthetic assistant `tool_call` before tool messages. It also repairs the opposite direction (260718): an assistant `tool_calls` round left dangling — diff --git a/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts b/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts index 0a0b17c8f64..30f04d79865 100644 --- a/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts +++ b/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts @@ -316,6 +316,40 @@ describe("toggle-only Chat reasoning capability", () => { } }); + test.each([ + [undefined, undefined], [undefined, false], [undefined, true], + ["gateway-object", undefined], ["gateway-object", false], ["gateway-object", true], + ] as const)("dual-axis %s omits ultra before ladder clamping with thinking override %s", (reasoningWireFormat, thinkingEnabled) => { + const target: OcxProviderConfig = { + ...toggleProvider, reasoningWireFormat, + modelCapabilities: { [toggleModel]: { supportsThinkingToggle: true, supportsReasoningEffort: true } }, + modelReasoningEfforts: { [toggleModel]: ["low", "high"] }, + modelReasoningEffortMap: { [toggleModel]: { max: "__omit__" } }, + }; + for (const effort of ["max", "ultra"]) { + for (const body of Object.values(finalToggleBodies(request(effort), target, toggleModel, thinkingEnabled))) { + expect(body.thinking).toEqual({ type: thinkingEnabled === false ? "disabled" : "enabled" }); + expect(body.reasoning_effort).toBeUndefined(); + expect(body.reasoning).toBeUndefined(); + } + } + }); + + test.each([undefined, "gateway-object"] as const)("dual-axis %s still clamps ultra when max has no omission alias", reasoningWireFormat => { + const target: OcxProviderConfig = { + ...toggleProvider, reasoningWireFormat, + modelCapabilities: { [toggleModel]: { supportsThinkingToggle: true, supportsReasoningEffort: true } }, + modelReasoningEfforts: { [toggleModel]: ["low", "high"] }, + }; + for (const thinkingEnabled of [undefined, false, true]) { + for (const body of Object.values(finalToggleBodies(request("ultra"), target, toggleModel, thinkingEnabled))) { + expect(body.thinking).toEqual({ type: thinkingEnabled === false ? "disabled" : "enabled" }); + expect(body.reasoning_effort).toBe(reasoningWireFormat ? undefined : "high"); + expect(body.reasoning).toEqual(reasoningWireFormat ? { enabled: thinkingEnabled !== false, effort: "high" } : undefined); + } + } + }); + test("native dual-axis wire preserves explicitly supported ultra despite the max omission alias", () => { const target: OcxProviderConfig = { ...toggleProvider, @@ -323,9 +357,15 @@ describe("toggle-only Chat reasoning capability", () => { modelReasoningEfforts: { [toggleModel]: ["high", "max", "ultra"] }, modelReasoningEffortMap: { [toggleModel]: { max: "__omit__" } }, }; - const body = JSON.parse(buildOpenAIChatPassthroughRequest(target, request("ultra"), toggleModel, false).body); - expect(body.reasoning_effort).toBe("ultra"); - expect(body.thinking).toEqual({ type: "enabled" }); + for (const thinkingEnabled of [undefined, false, true]) { + const bodies = finalToggleBodies(request("ultra"), target, toggleModel, thinkingEnabled); + expect(bodies.native.reasoning_effort).toBe("ultra"); + expect(bodies.translated.reasoning_effort).toBeUndefined(); + for (const body of Object.values(bodies)) { + expect(body.thinking).toEqual({ type: thinkingEnabled === false ? "disabled" : "enabled" }); + expect(body.reasoning).toBeUndefined(); + } + } }); test.each([ From 471709b13f9906ffa83249fd0d75797838bbc26a Mon Sep 17 00:00:00 2001 From: JUN Date: Sat, 7 Nov 2026 21:27:09 +0900 Subject: [PATCH 2/2] Cover omission with disabled thinking toggle --- .../openai-chat-reasoning-wire-policy.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts b/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts index 30f04d79865..597b32f54ac 100644 --- a/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts +++ b/tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts @@ -350,6 +350,22 @@ describe("toggle-only Chat reasoning capability", () => { } }); + test.each([undefined, "gateway-object"] as const)("disabled toggle omits aliased ultra on %s", reasoningWireFormat => { + const target: OcxProviderConfig = { + ...toggleProvider, reasoningWireFormat, + modelCapabilities: { [toggleModel]: { supportsThinkingToggle: false, supportsReasoningEffort: true } }, + modelReasoningEfforts: { [toggleModel]: ["low", "high"] }, + modelReasoningEffortMap: { [toggleModel]: { max: "__omit__" } }, + }; + for (const thinkingEnabled of [undefined, false, true]) { + for (const body of Object.values(finalToggleBodies(request("ultra"), target, toggleModel, thinkingEnabled))) { + expect(body.thinking).toBeUndefined(); + expect(body.reasoning_effort).toBeUndefined(); + expect(body.reasoning).toBeUndefined(); + } + } + }); + test("native dual-axis wire preserves explicitly supported ultra despite the max omission alias", () => { const target: OcxProviderConfig = { ...toggleProvider,