fix(ai): replace qwen3.8-max-preview with qwen3.8-max on token plan (#7670)

GA qwen3.8-max is on models.dev for alibaba-token-plan[-cn]. Point the
Qwen3.8 effort map at the GA id and exclude the retired preview so
regenerate does not revive it.
This commit is contained in:
QuintinShaw 2026-08-06 04:16:20 +08:00 • committed by GitHub
parent 14cc26e86d
commit 2f7f75a20e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 7 deletions

View file

@ -293,6 +293,8 @@ const QWEN_TOKEN_PLAN_REASONING_EFFORT_UNSUPPORTED_MODEL_IDS = new Set([
"qwen3.7-max",
"qwen3.7-plus",
]);
// Retired preview id — models.dev may still list it after GA ships.
const QWEN_TOKEN_PLAN_EXCLUDED_MODEL_IDS = new Set(["qwen3.8-max-preview"]);
const KIMI_K3_MAX_TOKENS = 131072;
const KIMI_K3_COST = {
@ -2132,6 +2134,7 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
for (const [modelId, model] of Object.entries(providerModels)) {
const m = model as ModelsDevModel;
if (m.tool_call !== true) continue;
if (QWEN_TOKEN_PLAN_EXCLUDED_MODEL_IDS.has(modelId)) continue;
const supportsReasoningEffort = !QWEN_TOKEN_PLAN_REASONING_EFFORT_UNSUPPORTED_MODEL_IDS.has(modelId);
models.push({
@ -2146,7 +2149,7 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
...(supportsReasoningEffort
? {
thinkingLevelMap:
modelId === "qwen3.8-max-preview"
modelId === "qwen3.8-max"
? QWEN_TOKEN_PLAN_QWEN38_THINKING_LEVEL_MAP
: QWEN_TOKEN_PLAN_HIGH_MAX_THINKING_LEVEL_MAP,
}

View file

@ -53,7 +53,7 @@ const TEXT_MODELS = [
"qwen3.6-plus",
"qwen3.7-max",
"qwen3.7-plus",
"qwen3.8-max-preview",
"qwen3.8-max",
];
const IMAGE_MODELS = ["qwen-image-2.0", "qwen-image-2.0-pro", "wan2.7-image", "wan2.7-image-pro"];
@ -72,7 +72,7 @@ const QWEN_THINKING_MODELS = [
"qwen3.6-plus",
"qwen3.7-max",
"qwen3.7-plus",
"qwen3.8-max-preview",
"qwen3.8-max",
] as const;
const QWEN_THINKING_MODEL_CASES = (["qwen-token-plan", "qwen-token-plan-cn"] as const).flatMap((provider) =>
@ -155,9 +155,9 @@ describe("Qwen Token Plan models", () => {
it.each(["qwen-token-plan", "qwen-token-plan-cn"] as const)(
"exposes qwen3.8 reasoning_effort levels on %s",
(provider) => {
const model = getModels(provider).find((candidate) => candidate.id === "qwen3.8-max-preview");
const model = getModels(provider).find((candidate) => candidate.id === "qwen3.8-max");
expect(model).toBeDefined();
if (!model) throw new Error(`Missing model: ${provider}/qwen3.8-max-preview`);
if (!model) throw new Error(`Missing model: ${provider}/qwen3.8-max`);
expect(model.thinkingLevelMap).toMatchObject({
minimal: null,
@ -170,6 +170,14 @@ describe("Qwen Token Plan models", () => {
},
);
it.each(["qwen-token-plan", "qwen-token-plan-cn"] as const)(
"omits retired qwen3.8-max-preview on %s",
(provider) => {
const modelIds = getModels(provider).map((model) => model.id);
expect(modelIds).not.toContain("qwen3.8-max-preview");
},
);
it.each(QWEN_REASONING_EFFORT_MODEL_CASES)(
"sends Qwen reasoning_effort for $provider/$modelId",
async ({ provider, modelId }) => {
@ -205,9 +213,9 @@ describe("Qwen Token Plan models", () => {
it.each(["qwen-token-plan", "qwen-token-plan-cn"] as const)(
"sends qwen3.8 max reasoning_effort on %s",
async (provider) => {
const model = getModels(provider).find((candidate) => candidate.id === "qwen3.8-max-preview");
const model = getModels(provider).find((candidate) => candidate.id === "qwen3.8-max");
expect(model).toBeDefined();
if (!model) throw new Error(`Missing model: ${provider}/qwen3.8-max-preview`);
if (!model) throw new Error(`Missing model: ${provider}/qwen3.8-max`);
let payload: unknown;
await streamSimple(