From 12c416e1a6f4c673523c04aebc30827266485684 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 29 Sep 2026 19:43:27 +0200 Subject: [PATCH] feat(ai,coding-agent): add GPT-6.1 Sol and make it the Codex default Add gpt-6.1-sol to the OpenAI, Azure OpenAI Responses, and OpenAI Codex providers with official pricing ($2 input, $0.10 cached input, $2.50 cache writes, $10 output, long-context tier above 272k). The model rejects reasoning.effort "none", so off is unsupported and clamps to the lowest effort. --- packages/ai/CHANGELOG.md | 4 ++ packages/ai/scripts/generate-models.ts | 37 ++++++++++++++++++- packages/ai/test/max-thinking.test.ts | 2 +- packages/ai/test/supports-xhigh.test.ts | 17 +++++++++ packages/coding-agent/CHANGELOG.md | 4 ++ .../coding-agent/src/core/model-resolver.ts | 2 +- .../coding-agent/test/model-resolver.test.ts | 2 +- 7 files changed, 63 insertions(+), 5 deletions(-) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index b55b05577..63b82f87c 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- Added GPT-6.1 Sol (`gpt-6.1-sol`) to the OpenAI, Azure OpenAI Responses, and OpenAI Codex providers. + ## [0.99.0] - 2026-09-29 ### Breaking Changes diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index ce383484b..cddc04015 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -369,6 +369,7 @@ const OPENAI_TOOL_SEARCH_MODEL_IDS = new Set([ "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", + "gpt-6.1-sol", ]); const OPENAI_ADDITIONAL_TOOLS_MODEL_IDS = OPENAI_TOOL_SEARCH_MODEL_IDS; const OPENAI_MID_CONVO_SYSTEM_MESSAGE_MODEL_IDS = OPENAI_TOOL_SEARCH_MODEL_IDS; @@ -379,6 +380,7 @@ const OPENAI_CODEX_ADDITIONAL_TOOLS_MODEL_IDS = new Set([ "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", + "gpt-6.1-sol", ]); const OPENAI_LONG_CONTEXT_INPUT_THRESHOLD = 272000; const OPENAI_SHORT_CONTEXT_CAPPED_MODEL_IDS = new Set([ @@ -390,6 +392,7 @@ const OPENAI_SHORT_CONTEXT_CAPPED_MODEL_IDS = new Set([ "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", + "gpt-6.1-sol", ]); const OPENAI_LONG_CONTEXT_PRICING_MODEL_IDS = new Set([ "gpt-5.4", @@ -402,6 +405,7 @@ const OPENAI_LONG_CONTEXT_PRICING_MODEL_IDS = new Set([ "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", + "gpt-6.1-sol", ]); // Keep the generated default no less restrictive than coding-agent's historical @@ -439,6 +443,7 @@ const OPENAI_STANDARD_COSTS: Record = { "gpt-6-astra": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 }, "gpt-6-luna": { input: 0.1, output: 0.5, cacheRead: 0.01, cacheWrite: 0.125 }, "gpt-6-sol": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }, + "gpt-6.1-sol": { input: 2, output: 10, cacheRead: 0.1, cacheWrite: 2.5 }, }; const OPENAI_RESPONSES_NONE_REASONING_MODELS = new Set([ @@ -1028,13 +1033,17 @@ function applyThinkingLevelMetadata(model: Model): void { mergeThinkingLevelMap(model, { off: null }); } if ( - (model.id === "gpt-6-astra" || model.id === "gpt-6-sol" || model.id === "gpt-6-luna") && + (model.id === "gpt-6-astra" || + model.id === "gpt-6-sol" || + model.id === "gpt-6-luna" || + model.id === "gpt-6.1-sol") && (model.api === "openai-responses" || model.api === "azure-openai-responses" || model.api === "openai-codex-responses") ) { mergeThinkingLevelMap(model, { - off: model.id === "gpt-6-astra" ? null : "none", + // GPT-6 Astra and GPT-6.1 Sol reject reasoning.effort "none". + off: model.id === "gpt-6-astra" || model.id === "gpt-6.1-sol" ? null : "none", minimal: null, low: "low", medium: "medium", @@ -2951,6 +2960,18 @@ async function generateModels() { // Add missing gpt models const missingOpenAiModels: Model<"openai-responses">[] = [ + { + id: "gpt-6.1-sol", + name: "GPT-6.1 Sol", + api: "openai-responses", + baseUrl: "https://api.openai.com/v1", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: withOpenAiLongContextPricing(OPENAI_STANDARD_COSTS["gpt-6.1-sol"]), + contextWindow: OPENAI_LONG_CONTEXT_INPUT_THRESHOLD, + maxTokens: 128000, + }, { id: "gpt-6-astra", name: "GPT-6 Astra", @@ -3184,6 +3205,18 @@ async function generateModels() { const CODEX_SPARK_CONTEXT = 128000; const CODEX_MAX_TOKENS = 128000; const codexModels: Model<"openai-codex-responses">[] = [ + { + id: "gpt-6.1-sol", + name: "GPT-6.1 Sol", + api: "openai-codex-responses", + provider: "openai-codex", + baseUrl: CODEX_BASE_URL, + reasoning: true, + input: ["text", "image"], + cost: withOpenAiLongContextPricing(OPENAI_STANDARD_COSTS["gpt-6.1-sol"]), + contextWindow: CODEX_CONTEXT, + maxTokens: CODEX_MAX_TOKENS, + }, { id: "gpt-6-astra", name: "GPT-6 Astra", diff --git a/packages/ai/test/max-thinking.test.ts b/packages/ai/test/max-thinking.test.ts index efbc83efc..653d9a820 100644 --- a/packages/ai/test/max-thinking.test.ts +++ b/packages/ai/test/max-thinking.test.ts @@ -67,7 +67,7 @@ describe("max thinking level", () => { expect(clampThinkingLevel(model, "xhigh")).toBe("max"); }); - it.each(["gpt-5.6-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna"] as const)( + it.each(["gpt-5.6-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-6.1-sol"] as const)( "sends max to the Codex Responses API for %s", async (modelId) => { const model = getModel("openai-codex", modelId)!; diff --git a/packages/ai/test/supports-xhigh.test.ts b/packages/ai/test/supports-xhigh.test.ts index 5c3a61a21..31e381dee 100644 --- a/packages/ai/test/supports-xhigh.test.ts +++ b/packages/ai/test/supports-xhigh.test.ts @@ -93,6 +93,7 @@ describe("getSupportedThinkingLevels", () => { "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", + "gpt-6.1-sol", ] as const)("includes xhigh for openai-codex %s models", (modelId) => { const model = getModel("openai-codex", modelId); expect(model).toBeDefined(); @@ -108,9 +109,25 @@ describe("getSupportedThinkingLevels", () => { }, ); + // OpenAI and Codex reject reasoning.effort "none" for GPT-6.1 Sol. + it("does not support off for GPT-6.1 Sol", () => { + const expected = { + openai: ["low", "medium", "high", "xhigh", "max"], + "azure-openai-responses": ["low", "medium", "high", "xhigh", "max"], + "openai-codex": ["minimal", "low", "medium", "high", "xhigh", "max"], + } as const; + for (const [provider, levels] of Object.entries(expected)) { + const model = getModel(provider as keyof typeof expected, "gpt-6.1-sol"); + expect(model).toBeDefined(); + expect(getSupportedThinkingLevels(model!)).toEqual(levels); + expect(model!.thinkingLevelMap?.off).toBeNull(); + } + }); + it.each([ ["gpt-6-sol", { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 }], ["gpt-6-luna", { input: 0.1, output: 0.5, cacheRead: 0.01, cacheWrite: 0.125 }], + ["gpt-6.1-sol", { input: 2, output: 10, cacheRead: 0.1, cacheWrite: 2.5 }], ] as const)("includes official metadata for OpenAI and Codex %s", (modelId, cost) => { for (const provider of ["openai", "openai-codex"] as const) { const model = getModel(provider, modelId); diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 5c670e2db..a6295f0e8 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Changed + +- Changed the default OpenAI Codex model to GPT-6.1 Sol (`gpt-6.1-sol`). + ## [0.99.0] - 2026-09-29 ### New Features diff --git a/packages/coding-agent/src/core/model-resolver.ts b/packages/coding-agent/src/core/model-resolver.ts index 5eef3690f..45606699c 100644 --- a/packages/coding-agent/src/core/model-resolver.ts +++ b/packages/coding-agent/src/core/model-resolver.ts @@ -23,7 +23,7 @@ export const defaultModelPerProvider: Partial> = { anthropic: "claude-opus-4-8", openai: "gpt-5.5", "azure-openai-responses": "gpt-5.4", - "openai-codex": "gpt-5.5", + "openai-codex": "gpt-6.1-sol", radius: "balanced", nvidia: "nvidia/nemotron-3-super-120b-a12b", deepseek: "deepseek-v4-pro", diff --git a/packages/coding-agent/test/model-resolver.test.ts b/packages/coding-agent/test/model-resolver.test.ts index b9efcc4a4..20522c7f3 100644 --- a/packages/coding-agent/test/model-resolver.test.ts +++ b/packages/coding-agent/test/model-resolver.test.ts @@ -708,7 +708,7 @@ describe("resolveCliModel", () => { describe("default model selection", () => { test("openai defaults track current models", () => { expect(defaultModelPerProvider.openai).toBe("gpt-5.5"); - expect(defaultModelPerProvider["openai-codex"]).toBe("gpt-5.5"); + expect(defaultModelPerProvider["openai-codex"]).toBe("gpt-6.1-sol"); }); test("zai, minimax, cerebras, and ant-ling defaults track current models", () => {