From e5fe9777b965b67bc0c448a14f769bab6a802c1c Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 21 Oct 2026 10:10:55 +0200 Subject: [PATCH] fix(ai,coding-agent): drop models retired upstream models.dev deprecated several Baseten, GitHub Copilot, and Together models, which broke type checks and the default-model test. - Default GitHub Copilot model: gpt-5.4 -> gpt-6.1-sol - Move Copilot live tests to gpt-6-luna/gpt-6-sol - Remove tests and generator entries for retired models, including the Together reasoning-only model list --- packages/ai/scripts/generate-models.ts | 20 +--------- packages/ai/test/baseten-models.test.ts | 38 ------------------- .../ai/test/github-copilot-anthropic.test.ts | 5 --- packages/ai/test/image-tool-result.test.ts | 13 ------- .../ai/test/openai-responses-compat.test.ts | 3 +- ...penai-responses-tool-result-images.test.ts | 4 +- packages/ai/test/stream.test.ts | 10 ++--- packages/ai/test/together-models.test.ts | 5 --- .../test/tool-call-id-normalization.test.ts | 6 +-- packages/coding-agent/CHANGELOG.md | 1 + .../coding-agent/src/core/model-resolver.ts | 2 +- 11 files changed, 14 insertions(+), 93 deletions(-) diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index 6072e138c..e6527b4b7 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -189,18 +189,8 @@ const TOGETHER_TOGGLE_REASONING_EFFORT_COMPAT: OpenAICompletionsCompat = { ...TOGETHER_TOGGLE_REASONING_COMPAT, supportsReasoningEffort: true, }; -const TOGETHER_REASONING_ONLY_MODELS = new Set([ - "deepseek-ai/DeepSeek-R1", - "MiniMaxAI/MiniMax-M2.7", -]); const TOGETHER_REASONING_EFFORT_MODELS = new Set(["openai/gpt-oss-20b", "openai/gpt-oss-120b"]); const TOGETHER_TOGGLE_REASONING_EFFORT_MODELS = new Set(["deepseek-ai/DeepSeek-V4-Pro-0813"]); -const TOGETHER_FIXED_REASONING_LEVEL_MAP = { - off: null, - minimal: null, - low: null, - medium: null, -} as const; const TOGETHER_REASONING_EFFORT_LEVEL_MAP = { off: null, minimal: null, @@ -502,16 +492,12 @@ const OPENCODE_OPENAI_COMPLETIONS_LONG_CACHE_RETENTION_UNSUPPORTED_MODELS = new // the extended 1 million token context window. const GITHUB_COPILOT_EXTENDED_CONTEXT_MODELS = new Set([ "claude-fable-5", - "claude-opus-4.6", - "claude-opus-4.7", "claude-opus-4.8", "claude-opus-5", "claude-opus-5.5", "claude-sonnet-4.6", "claude-sonnet-5", "gpt-5.3-codex", - "gpt-5.4", - "gpt-5.5", "gpt-6-astra", "gpt-6-luna", "gpt-6-sol", @@ -520,7 +506,6 @@ const GITHUB_COPILOT_EXTENDED_CONTEXT_MODELS = new Set([ // Checked manually against the authenticated GitHub Copilot /models endpoint on 2026-06-15. // Keep this to narrow corrections over models.dev metadata instead of snapshotting Copilot's catalog. const GITHUB_COPILOT_THINKING_LEVEL_OVERRIDES = { - "claude-opus-4.7": { minimal: "low" }, "claude-opus-4.8": { minimal: "low" }, "claude-opus-5": { minimal: "low" }, "claude-sonnet-4.6": { minimal: "low", max: "max" }, @@ -571,7 +556,6 @@ function getTogetherCompat(modelId: string, reasoning: boolean): OpenAICompletio if (!reasoning) return TOGETHER_BASE_COMPAT; if (TOGETHER_REASONING_EFFORT_MODELS.has(modelId)) return TOGETHER_REASONING_EFFORT_COMPAT; if (TOGETHER_TOGGLE_REASONING_EFFORT_MODELS.has(modelId)) return TOGETHER_TOGGLE_REASONING_EFFORT_COMPAT; - if (TOGETHER_REASONING_ONLY_MODELS.has(modelId)) return TOGETHER_BASE_COMPAT; return TOGETHER_TOGGLE_REASONING_COMPAT; } @@ -582,7 +566,6 @@ function getTogetherThinkingLevelMap( if (!reasoning) return undefined; if (TOGETHER_REASONING_EFFORT_MODELS.has(modelId)) return { ...TOGETHER_REASONING_EFFORT_LEVEL_MAP }; if (TOGETHER_TOGGLE_REASONING_EFFORT_MODELS.has(modelId)) return { ...TOGETHER_DEEPSEEK_V4_THINKING_LEVEL_MAP }; - if (TOGETHER_REASONING_ONLY_MODELS.has(modelId)) return { ...TOGETHER_FIXED_REASONING_LEVEL_MAP }; return { ...TOGETHER_TOGGLE_REASONING_LEVEL_MAP }; } @@ -739,7 +722,6 @@ function detectOpenAICompletionsCompat(model: Model<"openai-completions">): Open const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com"); const isAntLing = provider === "ant-ling" || baseUrl.includes("api.ant-ling.com"); const isCerebras = provider === "cerebras" || baseUrl.includes("cerebras.ai"); - const isTogetherReasoningOnly = isTogether && TOGETHER_REASONING_ONLY_MODELS.has(model.id); const isDeepSeek = provider === "deepseek" || baseUrl.toLowerCase().includes("deepseek.com"); const isNonStandard = @@ -790,7 +772,7 @@ function detectOpenAICompletionsCompat(model: Model<"openai-completions">): Open ? "deepseek" : isZai ? "zai" - : isTogether && !isTogetherReasoningOnly + : isTogether ? "together" : isAntLing ? "ant-ling" diff --git a/packages/ai/test/baseten-models.test.ts b/packages/ai/test/baseten-models.test.ts index 97fcc2e24..483fc7050 100644 --- a/packages/ai/test/baseten-models.test.ts +++ b/packages/ai/test/baseten-models.test.ts @@ -1,7 +1,6 @@ import { afterEach, describe, expect, it } from "vitest"; import { getModel, streamSimple } from "../src/compat.ts"; import { findEnvKeys, getEnvApiKey } from "../src/env-api-keys.ts"; -import { getSupportedThinkingLevels } from "../src/models.ts"; const originalBasetenApiKey = process.env.BASETEN_API_KEY; @@ -19,43 +18,6 @@ describe("Baseten models", () => { expect(getModel("baseten", "zai-org/GLM-5.2-Fast").input).toEqual(["text"]); }); - it("models Kimi K2.6 reasoning as an explicit off/on toggle", async () => { - const model = getModel("baseten", "moonshotai/Kimi-K2.6"); - let payload: Record | undefined; - - expect(model.thinkingLevelMap).toEqual({ - off: "off", - minimal: null, - low: null, - medium: null, - high: "high", - xhigh: null, - max: null, - }); - expect(model.compat).toMatchObject({ - supportsReasoningEffort: false, - thinkingFormat: "baseten", - chatTemplateArgs: { enable_thinking: { $var: "thinking.enabled" } }, - }); - expect(getSupportedThinkingLevels(model)).toEqual(["off", "high"]); - - await streamSimple( - model, - { messages: [{ role: "user", content: "test", timestamp: 0 }] }, - { - apiKey: "test-baseten-key", - reasoning: "high", - onPayload: (value) => { - payload = value as Record; - throw new Error("payload captured"); - }, - }, - ).result(); - - expect(payload?.chat_template_args).toEqual({ enable_thinking: true }); - expect(payload?.reasoning_effort).toBeUndefined(); - }); - it("sends Baseten chat_template_args with reasoning effort", async () => { const model = getModel("baseten", "zai-org/GLM-5.2"); let payload: Record | undefined; diff --git a/packages/ai/test/github-copilot-anthropic.test.ts b/packages/ai/test/github-copilot-anthropic.test.ts index 9a5a28d6f..e1bde9161 100644 --- a/packages/ai/test/github-copilot-anthropic.test.ts +++ b/packages/ai/test/github-copilot-anthropic.test.ts @@ -57,11 +57,6 @@ describe("Copilot Claude via Anthropic Messages", () => { }); it("applies Copilot-specific adaptive thinking effort overrides", () => { - const opus47 = getModel("github-copilot", "claude-opus-4.7"); - expect(opus47.thinkingLevelMap).toMatchObject({ minimal: "low", xhigh: "xhigh", max: "max" }); - expect(getSupportedThinkingLevels(opus47)).toContain("xhigh"); - expect(getSupportedThinkingLevels(opus47)).toContain("max"); - const opus5 = getModel("github-copilot", "claude-opus-5"); expect(opus5.api).toBe("anthropic-messages"); expect(opus5.contextWindow).toBe(1000000); diff --git a/packages/ai/test/image-tool-result.test.ts b/packages/ai/test/image-tool-result.test.ts index 4ef8eaf98..853a02f88 100644 --- a/packages/ai/test/image-tool-result.test.ts +++ b/packages/ai/test/image-tool-result.test.ts @@ -311,19 +311,6 @@ describe("Tool Results with Images", () => { }); }); - describe.skipIf(!process.env.BASETEN_API_KEY)("Baseten Provider (Kimi-K2.6)", () => { - const llm = getModel("baseten", "moonshotai/Kimi-K2.6"); - const options = { reasoningEffort: "high" } satisfies StreamOptionsWithExtras; - - it("should handle tool result with only image", { retry: 3, timeout: 30000 }, async () => { - await handleToolWithImageResult(llm, options); - }); - - it("should handle tool result with text and image", { retry: 3, timeout: 30000 }, async () => { - await handleToolWithTextAndImageResult(llm, options); - }); - }); - describe.skipIf(!process.env.XIAOMI_API_KEY)("Xiaomi MiMo (API billing) Provider (mimo-v2.6-pro)", () => { const llm = getModel("xiaomi", "mimo-v2.6-pro"); diff --git a/packages/ai/test/openai-responses-compat.test.ts b/packages/ai/test/openai-responses-compat.test.ts index 8295cb7a8..3b61686e8 100644 --- a/packages/ai/test/openai-responses-compat.test.ts +++ b/packages/ai/test/openai-responses-compat.test.ts @@ -72,8 +72,9 @@ describe("openai-responses provider defaults", () => { vi.restoreAllMocks(); }); + // #2567: Copilot rejected reasoning.effort "none". gpt-6-sol has off: "none", so this exercises the Copilot exception. it("omits reasoning when no reasoning is requested", async () => { - const model = getModel("github-copilot", "gpt-5-mini"); + const model = getModel("github-copilot", "gpt-6-sol"); let capturedPayload: unknown; vi.spyOn(globalThis, "fetch").mockResolvedValue( diff --git a/packages/ai/test/openai-responses-tool-result-images.test.ts b/packages/ai/test/openai-responses-tool-result-images.test.ts index 8668746a5..efa3a87fa 100644 --- a/packages/ai/test/openai-responses-tool-result-images.test.ts +++ b/packages/ai/test/openai-responses-tool-result-images.test.ts @@ -162,8 +162,8 @@ describe("Responses API tool result images", () => { }); }); - describe("GitHub Copilot Responses Provider (gpt-5-mini)", () => { - const model = getModel("github-copilot", "gpt-5-mini"); + describe("GitHub Copilot Responses Provider (gpt-6-luna)", () => { + const model = getModel("github-copilot", "gpt-6-luna"); it.skipIf(!githubCopilotToken)( "should send tool result images in function_call_output", diff --git a/packages/ai/test/stream.test.ts b/packages/ai/test/stream.test.ts index df77742c4..6cac98a15 100644 --- a/packages/ai/test/stream.test.ts +++ b/packages/ai/test/stream.test.ts @@ -1395,8 +1395,8 @@ describe("Generate E2E Tests", () => { }); }); - describe("GitHub Copilot Provider (gpt-5.3-codex via OpenAI Completions)", () => { - const llm = getModel("github-copilot", "gpt-5.3-codex"); + describe("GitHub Copilot Provider (gpt-6-luna via OpenAI Responses)", () => { + const llm = getModel("github-copilot", "gpt-6-luna"); it.skipIf(!githubCopilotToken)("should complete basic text generation", { retry: 3 }, async () => { await basicTextGeneration(llm, { apiKey: githubCopilotToken }); @@ -1411,13 +1411,11 @@ describe("Generate E2E Tests", () => { }); it.skipIf(!githubCopilotToken)("should handle thinking", { retry: 2 }, async () => { - const thinkingModel = getModel("github-copilot", "gpt-5-mini"); - await handleThinking(thinkingModel, { apiKey: githubCopilotToken, reasoningEffort: "high" }); + await handleThinking(llm, { apiKey: githubCopilotToken, reasoningEffort: "high" }); }); it.skipIf(!githubCopilotToken)("should handle multi-turn with thinking and tools", { retry: 3 }, async () => { - const thinkingModel = getModel("github-copilot", "gpt-5-mini"); - await multiTurn(thinkingModel, { apiKey: githubCopilotToken, reasoningEffort: "high" }); + await multiTurn(llm, { apiKey: githubCopilotToken, reasoningEffort: "high" }); }); it.skipIf(!githubCopilotToken)("should handle image input", { retry: 3 }, async () => { diff --git a/packages/ai/test/together-models.test.ts b/packages/ai/test/together-models.test.ts index a3c3df919..daa3e6371 100644 --- a/packages/ai/test/together-models.test.ts +++ b/packages/ai/test/together-models.test.ts @@ -70,11 +70,6 @@ describe("Together models", () => { supportsReasoningEffort: true, thinkingFormat: "together", }); - - const minimax = getModel("together", "MiniMaxAI/MiniMax-M2.7"); - expect(minimax.thinkingLevelMap).toEqual({ off: null, minimal: null, low: null, medium: null }); - expect(minimax.compat?.thinkingFormat).toBeUndefined(); - expect(minimax.compat?.supportsReasoningEffort).toBe(false); }); it("resolves TOGETHER_API_KEY from the environment", () => { diff --git a/packages/ai/test/tool-call-id-normalization.test.ts b/packages/ai/test/tool-call-id-normalization.test.ts index b4c8936bf..bf9d21c64 100644 --- a/packages/ai/test/tool-call-id-normalization.test.ts +++ b/packages/ai/test/tool-call-id-normalization.test.ts @@ -35,7 +35,7 @@ const echoTool: Tool = { /** * Test 1: Live cross-provider handoff * - * 1. Use github-copilot gpt-5.5 to generate a tool call + * 1. Use github-copilot gpt-6-luna to generate a tool call * 2. Switch to openrouter openai/gpt-5.5 and complete * 3. Switch to openai-codex gpt-6.1-sol and complete * @@ -45,7 +45,7 @@ describe("Tool Call ID Normalization - Live Handoff", () => { it.skipIf(!copilotToken || !openrouterKey)( "github-copilot -> openrouter should normalize pipe-separated IDs", async () => { - const copilotModel = getModel("github-copilot", "gpt-5.5"); + const copilotModel = getModel("github-copilot", "gpt-6-luna"); const openrouterModel = getModel("openrouter", "openai/gpt-5.5"); // Step 1: Generate tool call with github-copilot @@ -115,7 +115,7 @@ describe("Tool Call ID Normalization - Live Handoff", () => { it.skipIf(!copilotToken || !codexToken)( "github-copilot -> openai-codex should normalize pipe-separated IDs", async () => { - const copilotModel = getModel("github-copilot", "gpt-5.5"); + const copilotModel = getModel("github-copilot", "gpt-6-luna"); const codexModel = getModel("openai-codex", "gpt-6.1-sol"); // Step 1: Generate tool call with github-copilot diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 8945d4bab..1a36040a6 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -9,6 +9,7 @@ ### Changed - `generateSummary()` and `generateSummaryWithUsage()` now ignore their `reserveTokens` parameter. Summary requests use the model's output limit instead. +- Changed the default GitHub Copilot model from `gpt-5.4`, which Copilot retired, to `gpt-6.1-sol`. ### Fixed diff --git a/packages/coding-agent/src/core/model-resolver.ts b/packages/coding-agent/src/core/model-resolver.ts index f48f93717..e6657e9eb 100644 --- a/packages/coding-agent/src/core/model-resolver.ts +++ b/packages/coding-agent/src/core/model-resolver.ts @@ -29,7 +29,7 @@ export const defaultModelPerProvider: Partial> = { deepseek: "deepseek-v4-pro", google: "gemini-3.1-pro-preview", "google-vertex": "gemini-3.1-pro-preview", - "github-copilot": "gpt-5.4", + "github-copilot": "gpt-6.1-sol", openrouter: "moonshotai/kimi-k2.6", "vercel-ai-gateway": "zai/glm-5.1", xai: "grok-4.7",