From dc2a2470952dcd4d672f9d243710664bfb6d97e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Thu, 1 Oct 2026 23:23:46 +0800 Subject: [PATCH] feat(models): support GPT-6.1 Sol in desktop and Codex OAuth --- .../constants/openaiOfficialProvider.test.ts | 9 ++++++ .../src/constants/openaiOfficialProvider.ts | 8 +++++ src/server/__tests__/providers.test.ts | 1 + src/server/__tests__/settings.test.ts | 7 +++++ .../services/openaiOfficialProvider.test.ts | 1 + src/services/openaiAuth/fetch.test.ts | 30 +++++++++++++++++++ src/services/openaiAuth/models.test.ts | 17 ++++++++++- src/services/openaiAuth/models.ts | 13 +++++++- 8 files changed, 84 insertions(+), 2 deletions(-) diff --git a/desktop/src/constants/openaiOfficialProvider.test.ts b/desktop/src/constants/openaiOfficialProvider.test.ts index 2c81e378..63fe77a2 100644 --- a/desktop/src/constants/openaiOfficialProvider.test.ts +++ b/desktop/src/constants/openaiOfficialProvider.test.ts @@ -5,6 +5,15 @@ import { } from './openaiOfficialProvider' describe('ChatGPT Official fallback model catalog', () => { + it('offers GPT-6.1 Sol with OAuth context and reasoning metadata', () => { + expect(OPENAI_OFFICIAL_MODELS.find(model => model.id === 'gpt-6.1-sol')).toMatchObject({ + name: 'GPT-6.1-Sol', + context: '258400', + defaultReasoningEffort: 'low', + supportedReasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'], + }) + }) + it('exposes the current GPT-6 Codex tiers and effective context windows', () => { expect(OPENAI_OFFICIAL_DEFAULT_MODEL_ID).toBe('gpt-6-sol') expect(OPENAI_OFFICIAL_MODELS.slice(0, 3)).toMatchObject([ diff --git a/desktop/src/constants/openaiOfficialProvider.ts b/desktop/src/constants/openaiOfficialProvider.ts index e9513375..8c9145e2 100644 --- a/desktop/src/constants/openaiOfficialProvider.ts +++ b/desktop/src/constants/openaiOfficialProvider.ts @@ -36,6 +36,14 @@ export const OPENAI_OFFICIAL_MODELS: ModelInfo[] = [ defaultReasoningEffort: 'medium', supportedReasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'], }, + { + id: 'gpt-6.1-sol', + name: 'GPT-6.1-Sol', + description: 'Latest workhorse model for coding and everyday work', + context: '258400', + defaultReasoningEffort: 'low', + supportedReasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'], + }, { id: 'gpt-5.6-sol', name: 'GPT-5.6-Sol', diff --git a/src/server/__tests__/providers.test.ts b/src/server/__tests__/providers.test.ts index 465b0a5d..4d5cd51f 100644 --- a/src/server/__tests__/providers.test.ts +++ b/src/server/__tests__/providers.test.ts @@ -678,6 +678,7 @@ describe('ProviderService', () => { expect(typeof env.CLAUDE_CODE_MODEL_CONTEXT_WINDOWS).toBe('string') expect(JSON.parse(env.CLAUDE_CODE_MODEL_CONTEXT_WINDOWS)).toEqual({ 'gpt-6-sol': 258_400, + 'gpt-6.1-sol': 258_400, 'gpt-6-luna': 258_400, 'gpt-5.6-sol': 353_400, 'gpt-5.6-terra': 353_400, diff --git a/src/server/__tests__/settings.test.ts b/src/server/__tests__/settings.test.ts index 5f8b466c..518bc526 100644 --- a/src/server/__tests__/settings.test.ts +++ b/src/server/__tests__/settings.test.ts @@ -1397,6 +1397,7 @@ describe('Models API', () => { 'gpt-6-astra', 'gpt-6-sol', 'gpt-6-luna', + 'gpt-6.1-sol', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna', @@ -1410,6 +1411,12 @@ describe('Models API', () => { defaultReasoningEffort: 'low', supportedReasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'], }) + expect(body.models.find(model => model.id === 'gpt-6.1-sol')).toMatchObject({ + id: 'gpt-6.1-sol', + context: '258400', + defaultReasoningEffort: 'low', + supportedReasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'], + }) expect(body.models[1]).toMatchObject({ id: 'gpt-6-sol', defaultReasoningEffort: 'medium', diff --git a/src/server/services/openaiOfficialProvider.test.ts b/src/server/services/openaiOfficialProvider.test.ts index ef5cfc0a..92a30661 100644 --- a/src/server/services/openaiOfficialProvider.test.ts +++ b/src/server/services/openaiOfficialProvider.test.ts @@ -9,6 +9,7 @@ describe('ChatGPT Official runtime environment', () => { expect(windows['gpt-6-astra']).toBe(258_400) expect(windows['gpt-6-sol']).toBe(258_400) + expect(windows['gpt-6.1-sol']).toBe(258_400) expect(windows['gpt-6-luna']).toBe(258_400) expect(windows['gpt-5.6-sol']).toBe(353_400) expect(env.ANTHROPIC_MODEL).toBe('gpt-6-sol') diff --git a/src/services/openaiAuth/fetch.test.ts b/src/services/openaiAuth/fetch.test.ts index 88788367..97ecee32 100644 --- a/src/services/openaiAuth/fetch.test.ts +++ b/src/services/openaiAuth/fetch.test.ts @@ -164,6 +164,36 @@ describe('buildOpenAICodexFetch', () => { }) }) + test('routes GPT-6.1 Sol unchanged with its default low effort through Codex OAuth', async () => { + const calls: Array<{ url: string; body: Record }> = [] + const codexFetch = buildOpenAICodexFetch(async (input, init) => { + calls.push({ url: String(input), body: readWireBody(init) }) + return Response.json({ + id: 'resp_sol_61', + object: 'response', + model: 'gpt-6.1-sol', + status: 'completed', + output: [], + }) + }, 'test') + + const response = await codexFetch('https://api.anthropic.com/v1/messages', { + method: 'POST', + body: JSON.stringify({ + model: 'gpt-6.1-sol', + max_tokens: 64, + messages: [{ role: 'user', content: 'Say ok' }], + }), + }) + + expect(response.status).toBe(200) + await response.text() + expect(calls).toHaveLength(1) + expect(calls[0].url).toBe(OPENAI_CODEX_API_ENDPOINT) + expect(calls[0].body.model).toBe('gpt-6.1-sol') + expect(calls[0].body.reasoning).toEqual({ effort: 'low' }) + }) + test('preserves optional Computer Use parameters in the final Codex OAuth request', async () => { const computerTools = buildComputerUseTools().filter(tool => ['get_app_state', 'click'].includes(tool.name), diff --git a/src/services/openaiAuth/models.test.ts b/src/services/openaiAuth/models.test.ts index ee0200a8..69add668 100644 --- a/src/services/openaiAuth/models.test.ts +++ b/src/services/openaiAuth/models.test.ts @@ -18,6 +18,20 @@ import { } from './models.js' describe('openai auth model resolution', () => { + test('supports GPT-6.1 Sol selection, metadata and OAuth context budgeting', () => { + expect(OPENAI_CODEX_MODEL_CATALOG.find(model => model.value === 'gpt-6.1-sol')).toMatchObject({ + label: 'GPT-6.1-Sol', + defaultReasoningEffort: 'low', + supportedReasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'], + contextWindow: 258_400, + }) + expect(resolveOpenAICodexModel('gpt-6.1-sol')).toBe('gpt-6.1-sol') + expect(getOpenAIModelDisplayName('gpt-6.1-sol')).toBe('GPT-6.1-Sol') + expect(getOpenAICodexContextWindowForModel('gpt-6.1-sol')).toBe(258_400) + expect(resolveOpenAIReasoningEffort('gpt-6.1-sol', undefined)).toBe('low') + expect(resolveOpenAIReasoningEffort('gpt-6.1-sol', 'max')).toBe('max') + }) + test('provides Astra fallback metadata and effective Codex OAuth context', () => { const astra = OPENAI_CODEX_MODEL_CATALOG.find((model) => model.value === 'gpt-6-astra') expect(astra).toMatchObject({ @@ -87,10 +101,11 @@ describe('openai auth model resolution', () => { }) test('exposes GPT-6 Sol and Luna ahead of their GPT-5.6 predecessors', () => { - expect(OPENAI_CODEX_MODEL_CATALOG.slice(0, 6).map((model) => model.value)).toEqual([ + expect(OPENAI_CODEX_MODEL_CATALOG.slice(0, 7).map((model) => model.value)).toEqual([ 'gpt-6-astra', 'gpt-6-sol', 'gpt-6-luna', + 'gpt-6.1-sol', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna', diff --git a/src/services/openaiAuth/models.ts b/src/services/openaiAuth/models.ts index 18f41180..19fb3ee7 100644 --- a/src/services/openaiAuth/models.ts +++ b/src/services/openaiAuth/models.ts @@ -91,6 +91,15 @@ export const OPENAI_CODEX_MODEL_CATALOG: OpenAIModelCatalogEntry[] = [ supportedReasoningEfforts: GPT_5_6_REASONING_EFFORTS, contextWindow: OPENAI_CODEX_STANDARD_EFFECTIVE_CONTEXT_WINDOW, }, + { + value: 'gpt-6.1-sol', + label: 'GPT-6.1-Sol', + description: 'Latest workhorse model for coding and everyday work', + descriptionForModel: 'GPT-6.1-Sol - latest workhorse model for coding and everyday work', + defaultReasoningEffort: 'low', + supportedReasoningEfforts: GPT_5_6_REASONING_EFFORTS, + contextWindow: OPENAI_CODEX_STANDARD_EFFECTIVE_CONTEXT_WINDOW, + }, { value: 'gpt-5.6-sol', label: 'GPT-5.6-Sol', @@ -245,6 +254,8 @@ export function getOpenAIModelDisplayName(model: string): string | null { case 'gpt-6': case 'gpt-6-astra': return 'GPT-6 Astra' + case 'gpt-6.1-sol': + return 'GPT-6.1-Sol' case 'gpt-6-sol': return 'GPT-6-Sol' case 'gpt-6-luna': @@ -292,7 +303,7 @@ export function getOpenAICodexContextWindowForModel( return OPENAI_CODEX_STANDARD_EFFECTIVE_CONTEXT_WINDOW } - if (normalized === 'gpt-6-sol' || normalized === 'gpt-6-luna') { + if (normalized === 'gpt-6.1-sol' || normalized === 'gpt-6-sol' || normalized === 'gpt-6-luna') { return OPENAI_CODEX_STANDARD_EFFECTIVE_CONTEXT_WINDOW }