Skip to content

Commit 062657a

Browse files
author
Zeph Gillen
committed
feat(openrouter): mirror static OpenAI effort arrays + add gpt-5.5 defs
OpenRouter-routed OpenAI models reported supportsReasoningEffort as boolean true, which collapses the UI to the legacy ["low","medium","high"] fallback and hides xhigh — even though the direct openai-native provider declares the full ["none","low","medium","high","xhigh"] array for the same model. For OR ids of shape "openai/<X>" where openAiNativeModels[X] declares an array capability, mirror that array (and reasoningEffort default) onto the dynamic ModelInfo so the dropdown surfaces the same effort levels via both providers. Adds gpt-5.5 and gpt-5.5-pro to the static OpenAI defs (1.05M context, xhigh supported) so the mirror covers them; without static entries the mirror has nothing to copy. Two new tests verify mirror behavior for openai/gpt-5.5 and that boolean true is preserved for openai/* ids without static defs.
1 parent 0426ef4 commit 062657a

3 files changed

Lines changed: 90 additions & 0 deletions

File tree

packages/types/src/providers/openai.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,38 @@ export const openAiNativeModels = {
2424
description:
2525
"GPT-5.1 Codex Max: Our most intelligent coding model optimized for long-horizon, agentic coding tasks",
2626
},
27+
"gpt-5.5": {
28+
maxTokens: 128000,
29+
contextWindow: 1_050_000,
30+
includedTools: ["apply_patch"],
31+
excludedTools: ["apply_diff", "write_to_file"],
32+
supportsImages: true,
33+
supportsPromptCache: true,
34+
supportsReasoningEffort: ["none", "low", "medium", "high", "xhigh"],
35+
reasoningEffort: "none",
36+
inputPrice: 5.0,
37+
outputPrice: 30.0,
38+
cacheReadsPrice: 0.5,
39+
supportsVerbosity: true,
40+
supportsTemperature: false,
41+
description: "GPT-5.5: OpenAI's frontier model for complex professional workloads, building on GPT-5.4",
42+
},
43+
"gpt-5.5-pro": {
44+
maxTokens: 128000,
45+
contextWindow: 1_050_000,
46+
includedTools: ["apply_patch"],
47+
excludedTools: ["apply_diff", "write_to_file"],
48+
supportsImages: true,
49+
supportsPromptCache: true,
50+
supportsReasoningEffort: ["none", "low", "medium", "high", "xhigh"],
51+
reasoningEffort: "none",
52+
inputPrice: 30.0,
53+
outputPrice: 180.0,
54+
supportsVerbosity: true,
55+
supportsTemperature: false,
56+
description:
57+
"GPT-5.5 Pro: High-capability model optimized for deep reasoning on complex, high-stakes workloads",
58+
},
2759
"gpt-5.4": {
2860
maxTokens: 128000,
2961
contextWindow: 1_050_000,

src/api/providers/fetchers/__tests__/openrouter.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,48 @@ describe("OpenRouter API", () => {
362362
expect(result.contextWindow).toBe(128000)
363363
})
364364

365+
it("mirrors reasoning-effort capability array from static openAiNativeModels for openai/* ids", () => {
366+
const mockModel = {
367+
name: "GPT-5.5",
368+
description: "Test model",
369+
context_length: 1_050_000,
370+
max_completion_tokens: 128000,
371+
pricing: { prompt: "0.000005", completion: "0.00003", input_cache_read: "0.0000005" },
372+
}
373+
374+
const result = parseOpenRouterModel({
375+
id: "openai/gpt-5.5",
376+
model: mockModel,
377+
inputModality: ["text", "image"],
378+
outputModality: ["text"],
379+
maxTokens: 128000,
380+
supportedParameters: ["reasoning", "max_tokens", "tools"],
381+
})
382+
383+
expect(result.supportsReasoningEffort).toEqual(["none", "low", "medium", "high", "xhigh"])
384+
})
385+
386+
it("leaves supportsReasoningEffort as boolean for openai ids not in static defs", () => {
387+
const mockModel = {
388+
name: "GPT-5.5 Future",
389+
description: "Test model",
390+
context_length: 1_050_000,
391+
max_completion_tokens: 128000,
392+
pricing: { prompt: "0.000005", completion: "0.00003" },
393+
}
394+
395+
const result = parseOpenRouterModel({
396+
id: "openai/gpt-5.99-imaginary",
397+
model: mockModel,
398+
inputModality: ["text"],
399+
outputModality: ["text"],
400+
maxTokens: 128000,
401+
supportedParameters: ["reasoning"],
402+
})
403+
404+
expect(result.supportsReasoningEffort).toBe(true)
405+
})
406+
365407
it("filters out image generation models", () => {
366408
const mockImageModel = {
367409
name: "Image Model",

src/api/providers/fetchers/openrouter.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
OPEN_ROUTER_REASONING_BUDGET_MODELS,
88
OPEN_ROUTER_REQUIRED_REASONING_BUDGET_MODELS,
99
anthropicModels,
10+
openAiNativeModels,
1011
} from "@roo-code/types"
1112

1213
import type { ApiHandlerOptions } from "../../../shared/api"
@@ -229,6 +230,21 @@ export const parseOpenRouterModel = ({
229230
modelInfo.requiredReasoningBudget = true
230231
}
231232

233+
// Mirror reasoning-effort capability arrays from static OpenAI defs so that
234+
// OpenRouter-routed OpenAI models surface the same effort levels (e.g. xhigh)
235+
// as the direct openai-native provider, instead of falling back to the legacy
236+
// short list. Anthropic-specific overrides below can still disable as needed.
237+
if (id.startsWith("openai/")) {
238+
const localId = id.slice("openai/".length) as keyof typeof openAiNativeModels
239+
const staticDef = openAiNativeModels[localId] as ModelInfo | undefined
240+
if (staticDef && Array.isArray(staticDef.supportsReasoningEffort)) {
241+
modelInfo.supportsReasoningEffort = staticDef.supportsReasoningEffort
242+
if (staticDef.reasoningEffort && !modelInfo.reasoningEffort) {
243+
modelInfo.reasoningEffort = staticDef.reasoningEffort
244+
}
245+
}
246+
}
247+
232248
// For backwards compatibility with the old model definitions we will
233249
// continue to disable extending thinking for anthropic/claude-3.7-sonnet
234250
// and force it for anthropic/claude-3.7-sonnet:thinking.

0 commit comments

Comments
 (0)