Skip to content

Commit 7a8e667

Browse files
authored
🤖 fix: enable xhigh reasoning for gpt-5.2 (#1117)
Enable `xhigh` thinking for `openai:gpt-5.2` by updating the per-model thinking policy. - Root cause: `gpt-5.2` was falling back to the default policy (`off/low/medium/high`), so any `xhigh` selection got clamped before building OpenAI provider options. - Fix: allow `xhigh` in `getThinkingPolicyForModel()` for `gpt-5.2` (including version-suffixed and mux-gateway forms) and add tests. Validation: - `bun test src/browser/utils/thinking/policy.test.ts` - `make typecheck` - `make static-check` --- <details> <summary>📋 Implementation Plan</summary> # Enable xhigh reasoning for `openai:gpt-5.2` ## Context / Problem The newly released `openai:gpt-5.2` model supports OpenAI’s `reasoningEffort: "xhigh"`, but mux currently **cannot actually request xhigh** for this model. ### Root cause (code-level) Mux clamps the requested “thinking level” to a per-model capability subset via: - `src/browser/utils/thinking/policy.ts` → `getThinkingPolicyForModel()` / `enforceThinkingPolicy()` - This policy is used both: - in the **UI** (Thinking slider/options), and - in the **backend request builder** (via `buildProviderOptions()` which calls `enforceThinkingPolicy()`). Right now `gpt-5.2` is not special-cased, so it falls into the **default policy**: - Default: `["off", "low", "medium", "high"]` - Result: any attempt to set `xhigh` gets clamped (typically to `"medium"`), so OpenAI never receives `reasoningEffort: "xhigh"`. OpenAI request construction is already correct once `xhigh` is allowed: - `src/common/utils/ai/providerOptions.ts` maps `ThinkingLevel` → OpenAI `reasoningEffort`. - `src/common/types/thinking.ts` includes `xhigh: "xhigh"` in `OPENAI_REASONING_EFFORT`. ## Recommended approach (minimal change) — **Update thinking policy for `gpt-5.2`** **Net LoC estimate (product code only): ~+10–25 LoC** (policy + comments; tests separate) ### What to change 1. **Allow `xhigh` for `gpt-5.2`** in `getThinkingPolicyForModel()`: - File: `src/browser/utils/thinking/policy.ts` - Add a special case similar to `gpt-5.2-pro` and `gpt-5.1-codex-max`. Suggested policy: - `openai:gpt-5.2` → `["off", "low", "medium", "high", "xhigh"]` Notes: - Keep the `gpt-5.2-pro` branch *above* the new `gpt-5.2` branch. - Use the same “version suffix tolerant” regex style already used elsewhere. - Example: `^gpt-5\.2(?!-[a-z])` so it matches `gpt-5.2` and `gpt-5.2-2025-12-11` but not `gpt-5.2-pro`. 2. **Update comments to match reality** - File: `src/browser/utils/thinking/policy.ts` - Update the “default policy” comment that currently implies `xhigh` is only for codex-max. - File: `src/common/types/thinking.ts` - Update the comment on `OPENAI_REASONING_EFFORT.xhigh` (currently says only `gpt-5.1-codex-max`). - Optional (nice-to-have): `src/common/utils/tokens/models-extra.ts` - The `gpt-5.2` comment block doesn’t mention xhigh. Add a short note for consistency. ### Why this works Once the policy allows `xhigh`, the normal request path already does the right thing: - UI can select/store `xhigh`. - Backend uses `buildProviderOptions(modelString, thinkingLevel, ...)`. - `buildProviderOptions()` will: - preserve `xhigh` (no clamping), - set `openai.reasoningEffort = "xhigh"`, and - include `reasoning.encrypted_content` so tool-use works correctly for reasoning models. ## Tests / Validation 1. Update/add unit tests for the policy: - File: `src/browser/utils/thinking/policy.test.ts` - Add cases: - `getThinkingPolicyForModel("openai:gpt-5.2")` returns 5 levels including `xhigh`. - `getThinkingPolicyForModel("mux-gateway:openai/gpt-5.2")` returns same. - `getThinkingPolicyForModel("openai:gpt-5.2-2025-12-11")` returns same. - `enforceThinkingPolicy("openai:gpt-5.2", "xhigh") === "xhigh"`. 2. Run targeted tests: - `bun test src/browser/utils/thinking/policy.test.ts` 3. Run repo-wide correctness gates (expected in CI): - `make typecheck` - `make lint` (or `make lint-fix` if needed) ## Rollout notes / UX impact - The Thinking slider will show an extra step for `gpt-5.2` once selected. - Command palette already offers `xhigh`; after this change, choosing `xhigh` on `gpt-5.2` will no longer silently clamp back to `medium`. - No changes required in provider config (`knownModels.ts` etc.). ## Alternative approach (more scalable, higher scope) **Drive thinking policy from model metadata** (e.g., a single authoritative model capabilities table that includes supported thinking levels). **Net LoC estimate (product code only): ~+80–200 LoC** This would reduce future “forgot to special-case model X” issues, but requires designing a shared model-capabilities schema and updating multiple call sites (policy derivation, UI, provider options clamping). ## Execution checklist (when switching to Exec mode) - [ ] Edit `src/browser/utils/thinking/policy.ts` to add `gpt-5.2` xhigh support. - [ ] Update relevant comments (policy + thinking mapping). - [ ] Update `src/browser/utils/thinking/policy.test.ts` with new assertions. - [ ] Run `bun test ...policy.test.ts`. - [ ] Run `make typecheck`. </details> --- _Generated with `mux`_ Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent 3594896 commit 7a8e667

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

src/browser/utils/thinking/policy.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,36 @@ describe("getThinkingPolicyForModel", () => {
6464
]);
6565
});
6666

67+
test("returns 5 levels including xhigh for gpt-5.2", () => {
68+
expect(getThinkingPolicyForModel("openai:gpt-5.2")).toEqual([
69+
"off",
70+
"low",
71+
"medium",
72+
"high",
73+
"xhigh",
74+
]);
75+
});
76+
77+
test("returns 5 levels including xhigh for gpt-5.2 behind mux-gateway", () => {
78+
expect(getThinkingPolicyForModel("mux-gateway:openai/gpt-5.2")).toEqual([
79+
"off",
80+
"low",
81+
"medium",
82+
"high",
83+
"xhigh",
84+
]);
85+
});
86+
87+
test("returns 5 levels including xhigh for gpt-5.2 with version suffix", () => {
88+
expect(getThinkingPolicyForModel("openai:gpt-5.2-2025-12-11")).toEqual([
89+
"off",
90+
"low",
91+
"medium",
92+
"high",
93+
"xhigh",
94+
]);
95+
});
96+
6797
test("returns 5 levels including xhigh for gpt-5.1-codex-max behind mux-gateway", () => {
6898
expect(getThinkingPolicyForModel("mux-gateway:openai/gpt-5.1-codex-max")).toEqual([
6999
"off",
@@ -205,6 +235,20 @@ describe("enforceThinkingPolicy", () => {
205235
});
206236
});
207237

238+
describe("GPT-5.2 (5 levels including xhigh)", () => {
239+
test("allows xhigh for base model", () => {
240+
expect(enforceThinkingPolicy("openai:gpt-5.2", "xhigh")).toBe("xhigh");
241+
});
242+
243+
test("allows xhigh behind mux-gateway", () => {
244+
expect(enforceThinkingPolicy("mux-gateway:openai/gpt-5.2", "xhigh")).toBe("xhigh");
245+
});
246+
247+
test("allows xhigh for versioned model", () => {
248+
expect(enforceThinkingPolicy("openai:gpt-5.2-2025-12-11", "xhigh")).toBe("xhigh");
249+
});
250+
});
251+
208252
describe("xhigh fallback for non-codex-max models", () => {
209253
test("falls back to medium when xhigh requested on standard model", () => {
210254
// Standard models don't support xhigh, so fall back to medium (preferred fallback)

src/browser/utils/thinking/policy.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ export type ThinkingPolicy = readonly ThinkingLevel[];
2525
*
2626
* Rules:
2727
* - openai:gpt-5.1-codex-max → ["off", "low", "medium", "high", "xhigh"] (5 levels including xhigh)
28+
* - openai:gpt-5.2 → ["off", "low", "medium", "high", "xhigh"] (5 levels including xhigh)
2829
* - openai:gpt-5.2-pro → ["medium", "high", "xhigh"] (3 levels)
2930
* - openai:gpt-5-pro → ["high"] (only supported level, legacy)
3031
* - gemini-3 → ["low", "high"] (thinking level only)
31-
* - default → ["off", "low", "medium", "high"] (standard 4 levels)
32+
* - default → ["off", "low", "medium", "high"] (standard 4 levels; xhigh is opt-in per model)
3233
*
3334
* Tolerates version suffixes (e.g., gpt-5-pro-2025-10-06).
3435
* Does NOT match gpt-5-pro-mini (uses negative lookahead).
@@ -55,6 +56,11 @@ export function getThinkingPolicyForModel(modelString: string): ThinkingPolicy {
5556
return ["medium", "high", "xhigh"];
5657
}
5758

59+
// gpt-5.2 supports 5 reasoning levels including xhigh (Extra High)
60+
if (/^gpt-5\.2(?!-[a-z])/.test(withoutProviderNamespace)) {
61+
return ["off", "low", "medium", "high", "xhigh"];
62+
}
63+
5864
// gpt-5-pro (legacy) only supports high
5965
if (/^gpt-5-pro(?!-[a-z])/.test(withoutProviderNamespace)) {
6066
return ["high"];
@@ -65,7 +71,7 @@ export function getThinkingPolicyForModel(modelString: string): ThinkingPolicy {
6571
return ["low", "high"];
6672
}
6773

68-
// Default policy: standard 4 levels (xhigh only for codex-max)
74+
// Default policy: standard 4 levels (off/low/medium/high). Models with xhigh must opt in above.
6975
return ["off", "low", "medium", "high"];
7076
}
7177

src/common/types/thinking.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export const OPENAI_REASONING_EFFORT: Record<ThinkingLevel, string | undefined>
6868
low: "low",
6969
medium: "medium",
7070
high: "high",
71-
xhigh: "xhigh", // Extra High - only supported by gpt-5.1-codex-max
71+
xhigh: "xhigh", // Extra High - supported by models that expose xhigh (e.g., gpt-5.1-codex-max, gpt-5.2)
7272
};
7373

7474
/**

src/common/utils/tokens/models-extra.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const modelsExtra: Record<string, ModelData> = {
4343
// GPT-5.2 - Released December 11, 2025
4444
// $1.75/M input, $14/M output
4545
// Cached input: $0.175/M
46+
// Supports off, low, medium, high, xhigh reasoning levels
4647
"gpt-5.2": {
4748
max_input_tokens: 400000,
4849
max_output_tokens: 128000,

0 commit comments

Comments
 (0)