Skip to content

Commit ded8095

Browse files
Zeph Gillenclaude
andcommitted
feat(openai): add GPT-5.6 Sol/Terra/Luna models
Add the GPT-5.6 family (GA 2026-07-09) to the native OpenAI provider, and by extension OpenRouter. - packages/types/src/providers/openai.ts: three openAiNativeModels entries (gpt-5.6-sol/terra/luna) templated on gpt-5.5 — 1.05M context, 128K output, the new `max` reasoning-effort level, verbosity, and pricing $5/$30, $2.50/$15, $1/$6 (in/out) with 90%-off cache reads. Promote gpt-5.6-sol to openAiNativeDefaultModelId. - packages/types/src/providers/index.ts: getProviderDefaultModelId( "openai-native") now returns openAiNativeDefaultModelId instead of a stale hardcoded "gpt-4o", so the loading-time fallback also honors Sol. OpenRouter needs no code change: parseOpenRouterModel already mirrors the static effort array for any openai/* id, so openai/gpt-5.6-* surfaces `max` automatically and caching auto-detects from API pricing. Bedrock deferred: GPT-5.6 is not GA on Bedrock and AWS has not published model IDs. Long-context surcharge, flex/priority service tiers, and the new 1.25x cache-write price are omitted pending confirmation against OpenAI's official pricing page. Tests: default-model assertion updated to gpt-5.6-sol; new getModel() and `"effort":"max"` request-body passthrough tests (openai-native.spec.ts); new openai/gpt-5.6-sol effort-mirror case (openrouter fetcher spec). check-types passes and the pre-existing 22-failure reasoning/model-params baseline is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 7b8f811 commit ded8095

4 files changed

Lines changed: 150 additions & 3 deletions

File tree

packages/types/src/providers/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { litellmDefaultModelId } from "./lite-llm.js"
4040
import { mistralDefaultModelId } from "./mistral.js"
4141
import { moonshotDefaultModelId } from "./moonshot.js"
4242
import { openAiCodexDefaultModelId } from "./openai-codex.js"
43+
import { openAiNativeDefaultModelId } from "./openai.js"
4344
import { openRouterDefaultModelId } from "./openrouter.js"
4445
import { poeDefaultModelId } from "./poe.js"
4546
import { qwenCodeDefaultModelId } from "./qwen-code.js"
@@ -96,7 +97,7 @@ export function getProviderDefaultModelId(
9697
case "zai":
9798
return options?.isChina ? mainlandZAiDefaultModelId : internationalZAiDefaultModelId
9899
case "openai-native":
99-
return "gpt-4o" // Based on openai-native patterns
100+
return openAiNativeDefaultModelId
100101
case "openai-codex":
101102
return openAiCodexDefaultModelId
102103
case "mistral":

packages/types/src/providers/openai.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,76 @@ import type { ModelInfo } from "../model.js"
33
// https://openai.com/api/pricing/
44
export type OpenAiNativeModelId = keyof typeof openAiNativeModels
55

6-
export const openAiNativeDefaultModelId: OpenAiNativeModelId = "gpt-5.1-codex-max"
6+
export const openAiNativeDefaultModelId: OpenAiNativeModelId = "gpt-5.6-sol"
77

88
export const openAiNativeModels = {
9+
"gpt-5.6-sol": {
10+
maxTokens: 128000,
11+
contextWindow: 1_050_000,
12+
includedTools: ["apply_patch"],
13+
excludedTools: ["apply_diff", "write_to_file"],
14+
supportsImages: true,
15+
supportsPromptCache: true,
16+
supportsReasoningEffort: ["none", "low", "medium", "high", "xhigh", "max"],
17+
reasoningEffort: "high",
18+
inputPrice: 5.0,
19+
outputPrice: 30.0,
20+
cacheReadsPrice: 0.5,
21+
longContextPricing: {
22+
thresholdTokens: 272_000,
23+
inputPriceMultiplier: 2,
24+
outputPriceMultiplier: 1.5,
25+
appliesToServiceTiers: ["default", "flex"],
26+
},
27+
supportsVerbosity: true,
28+
supportsTemperature: false,
29+
description:
30+
"GPT-5.6 Sol: OpenAI's flagship model for frontier reasoning, complex coding, and multi-step agentic tasks",
31+
},
32+
"gpt-5.6-terra": {
33+
maxTokens: 128000,
34+
contextWindow: 1_050_000,
35+
includedTools: ["apply_patch"],
36+
excludedTools: ["apply_diff", "write_to_file"],
37+
supportsImages: true,
38+
supportsPromptCache: true,
39+
supportsReasoningEffort: ["none", "low", "medium", "high", "xhigh", "max"],
40+
reasoningEffort: "medium",
41+
inputPrice: 2.5,
42+
outputPrice: 15.0,
43+
cacheReadsPrice: 0.25,
44+
longContextPricing: {
45+
thresholdTokens: 272_000,
46+
inputPriceMultiplier: 2,
47+
outputPriceMultiplier: 1.5,
48+
appliesToServiceTiers: ["default", "flex"],
49+
},
50+
supportsVerbosity: true,
51+
supportsTemperature: false,
52+
description: "GPT-5.6 Terra: Balanced model for everyday coding, reasoning, and agentic tasks",
53+
},
54+
"gpt-5.6-luna": {
55+
maxTokens: 128000,
56+
contextWindow: 1_050_000,
57+
includedTools: ["apply_patch"],
58+
excludedTools: ["apply_diff", "write_to_file"],
59+
supportsImages: true,
60+
supportsPromptCache: true,
61+
supportsReasoningEffort: ["none", "low", "medium", "high", "xhigh", "max"],
62+
reasoningEffort: "low",
63+
inputPrice: 1.0,
64+
outputPrice: 6.0,
65+
cacheReadsPrice: 0.1,
66+
longContextPricing: {
67+
thresholdTokens: 272_000,
68+
inputPriceMultiplier: 2,
69+
outputPriceMultiplier: 1.5,
70+
appliesToServiceTiers: ["default", "flex"],
71+
},
72+
supportsVerbosity: true,
73+
supportsTemperature: false,
74+
description: "GPT-5.6 Luna: Fast, cost-efficient model optimized for speed and everyday use",
75+
},
976
"gpt-5.1-codex-max": {
1077
maxTokens: 128000,
1178
contextWindow: 400000,

src/api/providers/__tests__/openai-native.spec.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,24 @@ describe("OpenAiNativeHandler", () => {
284284
expect(modelInfo.info.reasoningEffort).toBe("medium")
285285
})
286286

287+
it("should return GPT-5.6 Sol model info when selected", () => {
288+
const solHandler = new OpenAiNativeHandler({
289+
...mockOptions,
290+
apiModelId: "gpt-5.6-sol",
291+
})
292+
293+
const modelInfo = solHandler.getModel()
294+
expect(modelInfo.id).toBe("gpt-5.6-sol")
295+
expect(modelInfo.info.maxTokens).toBe(128000)
296+
expect(modelInfo.info.contextWindow).toBe(1_050_000)
297+
expect(modelInfo.info.supportsVerbosity).toBe(true)
298+
expect(modelInfo.info.supportsReasoningEffort).toEqual(["none", "low", "medium", "high", "xhigh", "max"])
299+
expect(modelInfo.info.reasoningEffort).toBe("high")
300+
expect(modelInfo.info.inputPrice).toBe(5.0)
301+
expect(modelInfo.info.outputPrice).toBe(30.0)
302+
expect(modelInfo.info.cacheReadsPrice).toBe(0.5)
303+
})
304+
287305
it("should return GPT-5.4 model info when selected", () => {
288306
const gpt54Handler = new OpenAiNativeHandler({
289307
...mockOptions,
@@ -356,7 +374,7 @@ describe("OpenAiNativeHandler", () => {
356374
openAiNativeApiKey: "test-api-key",
357375
})
358376
const modelInfo = handlerWithoutModel.getModel()
359-
expect(modelInfo.id).toBe("gpt-5.1-codex-max") // Default model
377+
expect(modelInfo.id).toBe("gpt-5.6-sol") // Default model
360378
expect(modelInfo.info).toBeDefined()
361379
})
362380
})
@@ -805,6 +823,46 @@ describe("OpenAiNativeHandler", () => {
805823
)
806824
})
807825

826+
it("should support max reasoning effort for GPT-5.6 Sol", async () => {
827+
// Mock fetch for Responses API
828+
const mockFetch = vitest.fn().mockResolvedValue({
829+
ok: true,
830+
body: new ReadableStream({
831+
start(controller) {
832+
controller.enqueue(
833+
new TextEncoder().encode(
834+
'data: {"type":"response.output_item.added","item":{"type":"text","text":"Max effort"}}\n\n',
835+
),
836+
)
837+
controller.enqueue(new TextEncoder().encode("data: [DONE]\n\n"))
838+
controller.close()
839+
},
840+
}),
841+
})
842+
global.fetch = mockFetch as any
843+
844+
// Mock SDK to fail
845+
mockResponsesCreate.mockRejectedValue(new Error("SDK not available"))
846+
847+
handler = new OpenAiNativeHandler({
848+
...mockOptions,
849+
apiModelId: "gpt-5.6-sol",
850+
reasoningEffort: "max",
851+
})
852+
853+
const stream = handler.createMessage(systemPrompt, messages)
854+
for await (const _chunk of stream) {
855+
// drain
856+
}
857+
858+
expect(mockFetch).toHaveBeenCalledWith(
859+
"https://api.openai.com/v1/responses",
860+
expect.objectContaining({
861+
body: expect.stringContaining('"effort":"max"'),
862+
}),
863+
)
864+
})
865+
808866
it("should omit reasoning when selection is 'disable'", async () => {
809867
// Mock fetch for Responses API
810868
const mockFetch = vitest.fn().mockResolvedValue({

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,27 @@ describe("OpenRouter API", () => {
471471
expect(result.supportsReasoningEffort).toEqual(["none", "low", "medium", "high", "xhigh"])
472472
})
473473

474+
it("mirrors reasoning-effort capability array (incl. max) for openai/gpt-5.6-* ids", () => {
475+
const mockModel = {
476+
name: "GPT-5.6 Sol",
477+
description: "Test model",
478+
context_length: 1_050_000,
479+
max_completion_tokens: 128000,
480+
pricing: { prompt: "0.000005", completion: "0.00003", input_cache_read: "0.0000005" },
481+
}
482+
483+
const result = parseOpenRouterModel({
484+
id: "openai/gpt-5.6-sol",
485+
model: mockModel,
486+
inputModality: ["text", "image"],
487+
outputModality: ["text"],
488+
maxTokens: 128000,
489+
supportedParameters: ["reasoning", "max_tokens", "tools"],
490+
})
491+
492+
expect(result.supportsReasoningEffort).toEqual(["none", "low", "medium", "high", "xhigh", "max"])
493+
})
494+
474495
it("leaves supportsReasoningEffort as boolean for openai ids not in static defs", () => {
475496
const mockModel = {
476497
name: "GPT-5.5 Future",

0 commit comments

Comments
 (0)