diff --git a/open-sse/config/freeModelCatalog.data.ts b/open-sse/config/freeModelCatalog.data.ts index 78047f5299..0ce4a04002 100644 --- a/open-sse/config/freeModelCatalog.data.ts +++ b/open-sse/config/freeModelCatalog.data.ts @@ -369,7 +369,7 @@ export const FREE_MODEL_BUDGETS: FreeModelBudget[] = [ { provider: "qoder", modelId: "deepseek-v4-pro", displayName: "DeepSeek-V4-Pro", monthlyTokens: 0, creditTokens: 1000000, freeType: "one-time-initial", poolKey: "qoder", tos: "caution" }, { provider: "qoder", modelId: "deepseek-v4-flash", displayName: "DeepSeek-V4-Flash", monthlyTokens: 0, creditTokens: 1000000, freeType: "one-time-initial", poolKey: "qoder", tos: "caution" }, { provider: "qoder", modelId: "minimax-m3", displayName: "MiniMax-M3", monthlyTokens: 0, creditTokens: 1000000, freeType: "one-time-initial", poolKey: "qoder", tos: "caution" }, - { provider: "qwen-web", modelId: "qwen3.8-max-preview", displayName: "Qwen3.8 Max Preview", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "qwen-web", tos: "avoid" }, + { provider: "qwen-web", modelId: "qwen3.8-max", displayName: "Qwen3.8 Max", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "qwen-web", tos: "avoid" }, { provider: "qwen-web", modelId: "qwen3.7-max", displayName: "Qwen3.7 Max", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "qwen-web", tos: "avoid" }, { provider: "qwen-web", modelId: "qwen3.7-plus", displayName: "Qwen3.7 Plus", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "qwen-web", tos: "avoid" }, { provider: "qwen-web", modelId: "qwen3.6-plus", displayName: "Qwen3.6 Plus", monthlyTokens: 0, creditTokens: 0, freeType: "keyless", poolKey: "qwen-web", tos: "avoid" }, diff --git a/open-sse/config/providers/registry/alibaba/index.ts b/open-sse/config/providers/registry/alibaba/index.ts index efe11a8a64..3f17f42720 100644 --- a/open-sse/config/providers/registry/alibaba/index.ts +++ b/open-sse/config/providers/registry/alibaba/index.ts @@ -1,6 +1,7 @@ import type { RegistryEntry, RegistryModel } from "../../shared.ts"; export const ALIBABA_MODEL_STUDIO_MODELS: RegistryModel[] = [ + { id: "qwen3.8-max", name: "Qwen3.8 Max" }, { id: "qwen3.7-max", name: "Qwen3.7 Max" }, { id: "qwen3.7-plus", name: "Qwen3.7 Plus" }, { id: "qwen3.6-plus", name: "Qwen3.6 Plus" }, diff --git a/open-sse/config/providers/registry/clinepass/index.ts b/open-sse/config/providers/registry/clinepass/index.ts index c6af5abad8..8a3e319080 100644 --- a/open-sse/config/providers/registry/clinepass/index.ts +++ b/open-sse/config/providers/registry/clinepass/index.ts @@ -32,7 +32,7 @@ export const clinepassProvider: RegistryEntry = { "HTTP-Referer": "https://cline.bot", "X-Title": "Cline", }, - // Offline fallback copied from Cline CLI 3.0.46's generated catalog. Live + // Offline fallback copied from Cline CLI 3.0.53's generated catalog. Live // discovery replaces it with the authored recommended-models order. models: [ { @@ -111,6 +111,15 @@ export const clinepassProvider: RegistryEntry = { maxInputTokens: 1048576, maxOutputTokens: 131072, }, + { + id: "cline-pass/qwen3.8-max", + name: "Qwen3.8 Max", + toolCalling: true, + supportsReasoning: true, + contextLength: 1000000, + maxInputTokens: 1000000, + maxOutputTokens: 65536, + }, { id: "cline-pass/qwen3.7-max", name: "Qwen3.7 Max", diff --git a/open-sse/config/providers/registry/qwen-cloud-token-plan/index.ts b/open-sse/config/providers/registry/qwen-cloud-token-plan/index.ts index 310f91ad86..591332e983 100644 --- a/open-sse/config/providers/registry/qwen-cloud-token-plan/index.ts +++ b/open-sse/config/providers/registry/qwen-cloud-token-plan/index.ts @@ -11,13 +11,13 @@ export const qwen_cloud_token_planProvider: RegistryEntry = { authHeader: "bearer", models: [ { - id: "qwen3.8-max-preview", - name: "Qwen3.8 Max Preview", + id: "qwen3.8-max", + name: "Qwen3.8 Max", supportsReasoning: true, supportsVision: true, toolCalling: true, contextLength: 1_000_000, - maxOutputTokens: 65_536, + maxOutputTokens: 131_072, }, { id: "qwen3.7-max", @@ -25,7 +25,7 @@ export const qwen_cloud_token_planProvider: RegistryEntry = { supportsReasoning: true, toolCalling: true, contextLength: 1_000_000, - maxOutputTokens: 65_536, + maxOutputTokens: 131_072, }, { id: "qwen3.7-plus", @@ -34,7 +34,7 @@ export const qwen_cloud_token_planProvider: RegistryEntry = { supportsVision: true, toolCalling: true, contextLength: 1_000_000, - maxOutputTokens: 65_536, + maxOutputTokens: 131_072, }, { id: "qwen3.6-flash", @@ -43,7 +43,7 @@ export const qwen_cloud_token_planProvider: RegistryEntry = { supportsVision: true, toolCalling: true, contextLength: 1_000_000, - maxOutputTokens: 32_768, + maxOutputTokens: 65_536, }, { id: "glm-5.2", @@ -51,15 +51,23 @@ export const qwen_cloud_token_planProvider: RegistryEntry = { supportsReasoning: true, toolCalling: true, contextLength: 1_000_000, - maxOutputTokens: 16_384, + maxOutputTokens: 131_072, }, { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true, toolCalling: true, - contextLength: 163_840, - maxOutputTokens: 32_768, + contextLength: 1_000_000, + maxOutputTokens: 393_216, + }, + { + id: "deepseek-v4-flash-0731", + name: "DeepSeek V4 Flash", + supportsReasoning: true, + toolCalling: true, + contextLength: 1_000_000, + maxOutputTokens: 393_216, }, ], }; diff --git a/open-sse/config/providers/registry/qwen-cloud/index.ts b/open-sse/config/providers/registry/qwen-cloud/index.ts index af13fc7f41..a72aa3bd4b 100644 --- a/open-sse/config/providers/registry/qwen-cloud/index.ts +++ b/open-sse/config/providers/registry/qwen-cloud/index.ts @@ -1,6 +1,7 @@ import type { RegistryEntry, RegistryModel } from "../../shared.ts"; export const QWEN_CLOUD_TEXT_MODELS: RegistryModel[] = [ + { id: "qwen3.8-max", name: "Qwen3.8 Max" }, { id: "qwen3.7-max-2026-06-08", name: "Qwen3.7 Max (2026-06-08)" }, { id: "qwen3.7-plus", name: "Qwen3.7 Plus" }, { id: "qwen3.6-plus", name: "Qwen3.6 Plus" }, diff --git a/open-sse/config/providers/registry/qwen/web/index.ts b/open-sse/config/providers/registry/qwen/web/index.ts index 8bc7b47ed1..531c4bf1e1 100644 --- a/open-sse/config/providers/registry/qwen/web/index.ts +++ b/open-sse/config/providers/registry/qwen/web/index.ts @@ -17,13 +17,13 @@ export const qwen_webProvider: RegistryEntry = { // MODEL_ALIASES map for backward compatibility. models: [ { - id: "qwen3.8-max-preview", - name: "Qwen3.8 Max Preview", + id: "qwen3.8-max", + name: "Qwen3.8 Max", toolCalling: false, supportsReasoning: true, supportsVision: true, contextLength: 1_000_000, - maxOutputTokens: 65_536, + maxOutputTokens: 131_072, }, { id: "qwen3.7-max", diff --git a/open-sse/executors/qwen-web.ts b/open-sse/executors/qwen-web.ts index 57036a3cbb..4a312d7003 100644 --- a/open-sse/executors/qwen-web.ts +++ b/open-sse/executors/qwen-web.ts @@ -58,6 +58,7 @@ const MODEL_ALIASES: Record = { "qwen3-plus": "qwen3.7-plus", "qwen3-max": "qwen3.7-max", "qwen3-flash": "qwen3.6-plus", + "qwen3.8-max-preview": "qwen3.8-max", // Note: `qwen3-coder-plus` is a real upstream model id (Qwen3-Coder) and // must NOT be aliased — the previous `"qwen3-coder-plus": "qwen3.7-max"` // entry silently rewrote valid coder requests to the wrong model. @@ -67,7 +68,7 @@ const MODEL_ALIASES: Record = { }; const DEFAULT_MODEL = "qwen3.7-max"; -const REQUIRED_THINKING_MODELS = new Set(["qwen3.8-max-preview"]); +const REQUIRED_THINKING_MODELS = new Set(["qwen3.8-max"]); function mapModel(modelId: string): string { return MODEL_ALIASES[modelId] || modelId; diff --git a/tests/unit/alibaba-provider-regions.test.ts b/tests/unit/alibaba-provider-regions.test.ts index 07f879ff5e..872b11de5e 100644 --- a/tests/unit/alibaba-provider-regions.test.ts +++ b/tests/unit/alibaba-provider-regions.test.ts @@ -208,6 +208,7 @@ test("Qwen Cloud is a first-class metered API-key provider", () => { assert.deepEqual( REGISTRY["qwen-cloud"].models.map((model) => model.id), [ + "qwen3.8-max", "qwen3.7-max-2026-06-08", "qwen3.7-plus", "qwen3.6-plus", @@ -227,6 +228,7 @@ test("Qwen Cloud is a first-class metered API-key provider", () => { test("Alibaba Model Studio exposes the curated modern text catalog", () => { const expectedModels = [ + "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-plus", @@ -276,19 +278,20 @@ test("Qwen Cloud Token Plan remains a flat-rate provider with chat models only", const modelIds = REGISTRY["qwen-cloud-token-plan"].models.map((model) => model.id); assert.deepEqual(modelIds, [ - "qwen3.8-max-preview", + "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-flash", "glm-5.2", "deepseek-v4-pro", + "deepseek-v4-flash-0731", ]); - const preview = REGISTRY["qwen-cloud-token-plan"].models[0]; - assert.equal(preview.supportsReasoning, true); - assert.equal(preview.supportsVision, true); - assert.equal(preview.contextLength, 1_000_000); - assert.equal(preview.maxOutputTokens, 65_536); + const qwen38 = REGISTRY["qwen-cloud-token-plan"].models[0]; + assert.equal(qwen38.supportsReasoning, true); + assert.equal(qwen38.supportsVision, true); + assert.equal(qwen38.contextLength, 1_000_000); + assert.equal(qwen38.maxOutputTokens, 131_072); }); test("dashboard folds legacy China connections into the unified Alibaba card", () => { diff --git a/tests/unit/clinepass-provider.test.ts b/tests/unit/clinepass-provider.test.ts index d7ccdf4eb5..d49957d305 100644 --- a/tests/unit/clinepass-provider.test.ts +++ b/tests/unit/clinepass-provider.test.ts @@ -68,6 +68,7 @@ test("ClinePass fallback is the official subscription-only catalog", () => { "cline-pass/kimi-k2.7-code", "cline-pass/mimo-v2.5-pro", "cline-pass/mimo-v2.5", + "cline-pass/qwen3.8-max", "cline-pass/qwen3.7-max", "cline-pass/qwen3.7-plus", ]); diff --git a/tests/unit/executor-qwen-web.test.ts b/tests/unit/executor-qwen-web.test.ts index 0d8278f770..5c8c709872 100644 --- a/tests/unit/executor-qwen-web.test.ts +++ b/tests/unit/executor-qwen-web.test.ts @@ -288,24 +288,17 @@ describe("QwenWebExecutor (v2 migration)", () => { "registry must use v2 endpoint" ); const ids = provider.models.map((m: any) => m.id); - assert.deepEqual(ids.sort(), [ - "qwen3.6-plus", - "qwen3.7-max", - "qwen3.7-plus", - "qwen3.8-max-preview", - ]); + assert.deepEqual(ids.sort(), ["qwen3.6-plus", "qwen3.7-max", "qwen3.7-plus", "qwen3.8-max"]); - const qwen38 = provider.models.find( - (model: RegistryModel) => model.id === "qwen3.8-max-preview" - ); + const qwen38 = provider.models.find((model: RegistryModel) => model.id === "qwen3.8-max"); assert.deepEqual(qwen38, { - id: "qwen3.8-max-preview", - name: "Qwen3.8 Max Preview", + id: "qwen3.8-max", + name: "Qwen3.8 Max", toolCalling: false, supportsReasoning: true, supportsVision: true, contextLength: 1_000_000, - maxOutputTokens: 65_536, + maxOutputTokens: 131_072, }); const qwen37Max = provider.models.find((model: RegistryModel) => model.id === "qwen3.7-max"); @@ -315,7 +308,7 @@ describe("QwenWebExecutor (v2 migration)", () => { it("free-model catalog lists the current qwen-web ids (not the retired ones)", () => { const qwenModels = (FREE_MODEL_BUDGETS as any[]).filter((m) => m.provider === "qwen-web"); const ids = qwenModels.map((m) => m.modelId); - assert.ok(ids.includes("qwen3.8-max-preview"), "catalog must list qwen3.8-max-preview"); + assert.ok(ids.includes("qwen3.8-max"), "catalog must list qwen3.8-max"); assert.ok(ids.includes("qwen3.7-max"), "catalog must list qwen3.7-max"); assert.ok(!ids.includes("qwen-plus"), "retired qwen-plus must be gone"); assert.ok( @@ -324,7 +317,7 @@ describe("QwenWebExecutor (v2 migration)", () => { ); }); - it("passes qwen3.8-max-preview through unchanged", async () => { + it("uses qwen3.8-max and maps its preview id for compatibility", async () => { globalThis.fetch = (async (url: string | URL | Request, init: RequestInit = {}) => { calls.push({ url: String(url), init }); if (String(url).includes("/api/v2/chats/new")) return chatCreatedResponse(); @@ -347,8 +340,8 @@ describe("QwenWebExecutor (v2 migration)", () => { const newBody = JSON.parse(calls[0].init.body); const completionBody = JSON.parse(calls[1].init.body); - assert.deepEqual(newBody.models, ["qwen3.8-max-preview"]); - assert.equal(completionBody.model, "qwen3.8-max-preview"); + assert.deepEqual(newBody.models, ["qwen3.8-max"]); + assert.equal(completionBody.model, "qwen3.8-max"); assert.equal(completionBody.messages[0].feature_config.thinking_enabled, true); assert.equal(completionBody.messages[0].feature_config.auto_thinking, true); });