Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/adapters/openai-chat/reasoning-wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
2 changes: 1 addition & 1 deletion structure/providers/chat-compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 —
Expand Down
62 changes: 59 additions & 3 deletions tests/adapters/openai/openai-chat-reasoning-wire-policy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,16 +316,72 @@ 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();
}
}
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

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.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,
modelCapabilities: { [toggleModel]: { supportsThinkingToggle: true, supportsReasoningEffort: true } },
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([
Expand Down
Loading