Skip to content

fix(providers): sync Token Plan model list with the Bailian catalog - #8651

Open
yibudak wants to merge 4 commits into
QwenLM:mainfrom
yibudak:fix/token-plan-qwen38-max
Open

fix(providers): sync Token Plan model list with the Bailian catalog#8651
yibudak wants to merge 4 commits into
QwenLM:mainfrom
yibudak:fix/token-plan-qwen38-max

Conversation

@yibudak

@yibudak yibudak commented Aug 6, 2026

Copy link
Copy Markdown

What this PR does

Adds qwen3.8-max to the Bailian Token Plan model list and adds the dated DeepSeek flash ID the catalog publishes (deepseek-v4-flash-0731) alongside the existing bare alias. It also declares video input on the qwen3.8-max family in the modality default table, which had it as image-only. The same two edits are mirrored in the VS Code companion's duplicate copy of that list, and both pinned ID lists in the tests are updated alongside.

The new entry declares a 1M context window, thinking enabled, and image + video input. It deliberately does not carry thinkingMandatory. The preview sibling has that flag because it answers enable_thinking: false with a 400, but the GA model accepts the disable on the wire, and pinning it would keep thinking switched on for the side queries that turn it off on purpose. A short comment on the entry records that asymmetry so it does not get "fixed" later by copying the preview.

Nothing is removed. Models that appear in the list but not in the reporter's console are left in place — see Risk & Scope for why the evidence does not support removing them yet.

Why it's needed

The Token Plan selector is backed by a static list, so a newly released model only becomes selectable once someone updates that list by hand. qwen3.8-max went GA but only the preview was ever added, so the model is unreachable through /auth even though the subscription includes it, and Singapore's catalog publishes only the dated DeepSeek flash ID, which the list never carried. Users are left editing settings.json by hand to reach a model their plan already covers.

Reviewer Test Plan

How to verify

Run /auth, choose Alibaba ModelStudio → Token Plan, and confirm qwen3.8-max now appears in the model selector between qwen3.7-max and qwen3.8-max-preview, and that deepseek-v4-flash-0731 now appears next to deepseek-v4-flash. The first entry is still qwen3.7-plus, so the model auto-selected after setup does not change. Selecting qwen3.8-max and sending a prompt should stream normally, and attaching an image should work rather than being replaced by a text placeholder.

Unit tests covering the two lists:

cd packages/core && npx vitest run src/providers/__tests__/presets/alibaba-token-plan.test.ts
cd packages/vscode-ide-companion && npx vitest run src/services/subscriptionPlanDefinitions.test.ts

The metadata on the new entry was verified against the live Token Plan endpoint rather than inferred. All of the following ran against the Singapore endpoint with a Token Plan key; the same key returns 401 on the Beijing endpoint, so the Beijing side rests on the console listing in the linked issue.

The catalog is reachable over the API. GET /models answers on the Token Plan endpoint and returns 11 entries: qwen3.8-max, qwen3.7-max, qwen3.7-plus, qwen3.6-flash, deepseek-v4-pro, deepseek-v4-flash-0731, glm-5.2, two audio models and two image-generation models. qwen3.8-max is there; the bare deepseek-v4-flash is not.

The GA model is not thinking-mandatory. A request carrying enable_thinking: false returns 200 with no reasoning_content and no reasoning_tokens in the usage block, and reasoning_effort: "none" behaves the same. With neither field the response carries 21 reasoning tokens, so thinking is genuinely on by default and genuinely switchable off.

Image and video input both work. A solid-colour PNG passed as a data URI came back correctly identified, and an MP4 passed as video_url came back described accurately. An earlier video attempt returned 400 "The provided URL does not appear to be valid", but a control run put the same URL through qwen3.7-plus, which the list already declares as image + video, and it failed identically — the URL was dead, not the modality.

An unavailable model is distinguishable from a retired one. A nonsense model ID returns 404 model_not_found / "Model not exist.", while deepseek-v4-flash returns 403 AccessDenied.Unpurchased. The two are different answers, which is why the bare alias is kept rather than replaced: it is an entitlement gap, not a retirement.

The preview now resolves to the GA model. A request naming qwen3.8-max-preview comes back with "model": "qwen3.8-max" in the response body, and the preview no longer appears in /models even though it still answers. That is the argument for adding the GA ID rather than leaving users on the preview alias.

Evidence (Before & After)

Before: the Token Plan selector offers qwen3.8-max-preview but no qwen3.8-max, and offers deepseek-v4-flash, which a Token Plan key cannot call. After: the selector offers qwen3.8-max, and deepseek-v4-flash-0731 alongside the alias.

Tested on

OS Status
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

Environment (optional)

Unit tests plus direct HTTP calls against the Singapore Token Plan endpoint with a Token Plan subscription key.

Risk & Scope

  • Main risk or tradeoff: editing the list changes the computed model-list version, so existing Token Plan users see the provider-update prompt on next launch and the preset-owned models are replaced. That is the intended path for picking up the new entries. No model is removed, so no existing selection breaks.
  • Not validated / out of scope: the 1M context window on the new entry is not directly measured — it matches qwen3.7-max and is what the model-name rules already resolve to for this family, so the declared value only makes the existing default explicit. The Beijing endpoint could not be exercised with the key available. Removing the models that no longer appear in the reporter's console is deliberately left out: the endpoint answers an unentitled model with an access error rather than a not-found, so their absence from one subscription's catalog is not evidence that the ID is retired, and one static list serves both regions. Pruning should follow a check against an entitled key in each region. The image and video generation models discussed in the linked issue are a separate protocol limitation and are untouched here.
  • Breaking changes / migration notes: none beyond the provider-update prompt described above.

Two things surfaced while verifying that are worth separate issues rather than widening this PR. The family default for input modalities declares image only for qwen3.8-max, but the endpoint accepts video as shown above, so anyone reaching the model without this preset entry silently loses video. And the preview entry's thinking-mandatory pin now looks stale on the Singapore endpoint, since the preview resolves to the GA model there — though it may still hold in Beijing, so it should not be dropped without checking. Happy to file both, or fold either in if you would rather have it here.

The model-listing API the maintainer wondered about in the issue thread does exist on this endpoint, which makes syncing this list from the platform viable rather than hypothetical.

Linked Issues

Addresses #8432 (the model-list half; the generation-model findings in that thread are untouched).

中文说明

本 PR 做了什么

在百炼 Token Plan 模型列表中加入 qwen3.8-max,并在原有裸 ID 之外新增目录发布的带日期 DeepSeek flash ID(deepseek-v4-flash-0731)。同时在 modality 默认表中为 qwen3.8-max 系列声明视频输入(此前被标为仅图像)。同样的两处改动同步到 VS Code 插件中那份重复的列表,测试里固定的两份 ID 列表也一并更新。

新条目声明 100 万上下文窗口、开启思考、支持图像与视频输入。它刻意不带 thinkingMandatory。预览版之所以有该标记,是因为它对 enable_thinking: false 返回 400,而 GA 模型在协议层接受该关闭指令;若给它打上该标记,那些特意关闭思考的侧查询就会一直开着思考。条目上有一行注释记录这一差异,以免日后有人照搬预览版的配置把它"修"回去。

没有删除任何模型。列表中存在、但未出现在报告者控制台里的模型保持原样——原因见"风险与范围"。

为什么需要

Token Plan 选择器由静态列表驱动,因此新发布的模型只有在有人手动更新该列表后才可选。qwen3.8-max 已经 GA,但当初只加入了预览版,导致订阅明明包含该模型却无法通过 /auth 选到;同时新加坡目录只发布带日期的 DeepSeek flash ID,而列表中一直没有该 ID。用户只能手改 settings.json 才能用上自己套餐已覆盖的模型。

评审验证方案

如何验证

运行 /auth,选择 Alibaba ModelStudio → Token Plan,确认模型选择器中 qwen3.8-max 出现在 qwen3.7-maxqwen3.8-max-preview 之间,且 deepseek-v4-flash-0731 出现在 deepseek-v4-flash 旁边。首项仍是 qwen3.7-plus,因此配置完成后自动选中的模型不变。选择 qwen3.8-max 并发送提示词应正常流式返回,附带图片时应能正常处理,而不是被替换成文本占位符。

覆盖这两份列表的单元测试:

cd packages/core && npx vitest run src/providers/__tests__/presets/alibaba-token-plan.test.ts
cd packages/vscode-ide-companion && npx vitest run src/services/subscriptionPlanDefinitions.test.ts

新条目的元数据是对着线上 Token Plan 端点验证的,而非推测得出。以下全部针对新加坡端点、使用 Token Plan 密钥执行;同一密钥在北京端点返回 401,因此北京侧依据的是关联 issue 中的控制台列表。

目录可通过 API 获取。 GET /models 在 Token Plan 端点上可用,返回 11 个条目:qwen3.8-maxqwen3.7-maxqwen3.7-plusqwen3.6-flashdeepseek-v4-prodeepseek-v4-flash-0731glm-5.2,以及两个音频模型和两个图像生成模型。qwen3.8-max 在其中;不带日期的 deepseek-v4-flash 不在。

GA 模型并非强制思考。enable_thinking: false 的请求返回 200,响应中没有 reasoning_content,usage 中也没有 reasoning_tokensreasoning_effort: "none" 表现相同。两个字段都不带时,响应包含 21 个思考 token,说明默认确实开启思考,且确实可以关闭。

图像与视频输入均可用。 以 data URI 传入的纯色 PNG 被正确识别;以 video_url 传入的 MP4 被准确描述。此前一次视频尝试返回 400 "The provided URL does not appear to be valid",但对照实验把同一 URL 发给列表中已声明支持图像+视频的 qwen3.7-plus,报错完全相同——是那个 URL 失效,而非模态不支持。

"无权限"与"已下线"可以区分。 一个不存在的模型 ID 返回 404 model_not_found / "Model not exist.",而 deepseek-v4-flash 返回 403 AccessDenied.Unpurchased。两者是不同的响应,这正是保留裸 ID 而非替换它的原因:这是权益缺失,不是模型下线。

预览版现已指向 GA 模型。 请求 qwen3.8-max-preview 时,响应体中返回的是 "model": "qwen3.8-max";同时预览版虽仍可调用,却已不出现在 /models 中。这正是应当加入 GA ID、而非让用户继续停留在预览别名上的理由。

证据(前后对比)

之前:Token Plan 选择器提供 qwen3.8-max-preview 但没有 qwen3.8-max,并提供 Token Plan 密钥无法调用的 deepseek-v4-flash。之后:选择器提供 qwen3.8-max,并在裸 ID 之外提供 deepseek-v4-flash-0731

测试平台

系统 状态
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

环境(可选)

单元测试,以及使用 Token Plan 订阅密钥对新加坡 Token Plan 端点发起的直接 HTTP 调用。

风险与范围

  • 主要风险或权衡:修改列表会改变计算出的模型列表版本号,因此现有 Token Plan 用户下次启动时会看到 provider 更新提示,预设拥有的模型会被替换。这正是获取新条目的预期路径。本次没有删除任何模型,因此不会破坏已有的模型选择。
  • 未验证 / 范围之外:新条目的 100 万上下文窗口未直接实测——它与 qwen3.7-max 一致,也是该系列在现有模型名规则下已经解析出的值,因此这里的显式声明只是把既有默认值写明。手头的密钥无法访问北京端点。删除那些不再出现在报告者控制台中的模型被刻意排除在外:该端点对无权限模型返回的是访问错误而非未找到,因此它们在某一份订阅目录中缺席并不能证明该 ID 已下线,而且同一份静态列表服务于两个区域。剪枝应当在每个区域用有权限的密钥核实之后再做。关联 issue 中讨论的图像与视频生成模型属于另一个协议层面的限制,本 PR 未涉及。
  • 破坏性变更 / 迁移说明:除上述 provider 更新提示外没有其他影响。

验证过程中还浮现两件事,更适合另开 issue 而不是扩大本 PR。其一,输入模态的系列默认值对 qwen3.8-max 只声明了图像,但如上所示该端点接受视频,因此未经此预设条目而使用该模型的路径会静默丢失视频能力。其二,预览版条目上的强制思考标记在新加坡端点看来已经过时,因为预览版在那里会指向 GA 模型——但北京端点可能仍然成立,因此不宜未经核实就移除。两件事我都乐意去提 issue,或者你们更希望的话也可以并入本 PR。

维护者在 issue 讨论中提到的模型列表 API 在该端点上确实存在,因此从平台侧同步这份列表是可行的,而不只是设想。

关联 issue

Addresses #8432(模型列表这一半;该讨论串中关于生成类模型的发现未涉及)。

The Token Plan model selector is a static list, so a newly released model
only appears once someone updates it. qwen3.8-max reached GA but only the
preview ever made it into the list, and the DeepSeek flash entry still uses
an ID the plan no longer exposes.

Add qwen3.8-max and switch the DeepSeek flash entry to the dated ID the
catalog now publishes. Verified against the live Token Plan endpoint: the GA
model accepts enable_thinking: false, so unlike the preview it is not pinned
as thinking-mandatory, and it accepts both image and video input.

Models absent from the reporter's console but still present in the list are
left alone — the same list serves both regions, and the endpoint answers an
unentitled model with an access error rather than a not-found, so absence
from one subscription's catalog is not evidence the ID is retired.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread packages/core/src/providers/presets/alibaba-token-plan.ts
Comment thread packages/vscode-ide-companion/src/services/subscriptionPlanDefinitions.ts Outdated
Comment thread packages/vscode-ide-companion/src/services/subscriptionPlanDefinitions.test.ts Outdated
yibudak and others added 2 commits August 7, 2026 08:30
…k flash ids

Review follow-up on two points.

The qwen3.8-max family reached the modality default table as image-only, so
every config that carries no explicit modalities — the VS Code companion
template, which ships none for any model, plus manually typed model ids and
installs predating the preset entry — silently dropped video input the model
accepts. Declaring video on the family pattern fixes all of those paths at
once instead of widening the companion's duplicate spec, and lines the
default up with the preset, which already declared video for the preview.

Swapping deepseek-v4-flash for the dated snapshot removed a still-live id.
The bare alias answers Singapore's Token Plan endpoint with 403 Unpurchased,
not 404, so it is missing from that plan's entitlement rather than retired,
and it remains a built-in of the DeepSeek, Alibaba standard and IdeaLab
presets. Shipping both ids strands neither region's users and drops the need
to migrate installed model selections.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed. Not reviewed: reverse audit — stopped before round 2 by the review time budget.

中文说明

已审查。 未审查:反向审计——评审时间预算不足,未能开始第 2 轮。

— qwen3.8-max via Qwen Code /review (v0.21.7)

@wenshao

wenshao commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /resolve

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code attempted to resolve merge conflicts but the run did not complete successfully.

Check the workflow run for full logs.

…-max

Resolve five conflicts; main had superseded most of this branch:
- modalityDefaults.ts (+ its test): keep main's newer classification —
  qwen3.8-max is image-only there (QwenLM#10195/QwenLM#10278), not image+video.
- alibaba-token-plan.ts: keep this branch's deepseek-v4-flash entry (the
  part main never landed) and drop its duplicate qwen3.8-max record;
  main's later QwenLM#9383 entry, with thinkingMandatory, is authoritative.
  The matching branch assertion is dropped with it.
- vscode-ide-companion subscriptionPlanDefinitions.{ts,test.ts}: take
  main's version, which now derives the plan list from the shared preset
  instead of the hand-kept copy this branch was updating.

core: alibaba-token-plan + modalityDefaults 62 passed;
vscode-ide-companion subscriptionPlanDefinitions 3 passed.

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially reviewed — gaps disclosed.

Not reviewed: reverse audit — stopped before round 1 by the review time budget.

Deferred under the convergence posture (round 2, not a blocker) — recorded, not requested in this round:

  • packages/core/src/providers/__tests__/presets/alibaba-token-plan.test.ts:47 — [probe] new entry's contextWindowSize is not pinned by any test
中文说明

仅完成部分审查,审查缺口已披露。

未审查:反向审计——评审时间预算不足,未能开始第 1 轮。

收敛姿态下延后(第 2 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.22.3)

Comment on lines +162 to +163
expect(m.pdf).toBeUndefined();
expect(m.audio).toBeUndefined();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Critical] R2-1: [certifies-falsely] The final merge with main dropped this PR's own accepted R1-2 fix (video: true on /^qwen3\.8-max/ in defaultModalities), and these added assertions pin the reverted image-only state. The PR description still says it declares video input on the qwen3.8-max family in the modality default table, but after this diff the test locks in the opposite. A user who reaches qwen3.8-max through any path without explicit modalities — an env-var-only Token Plan setup, or a manually typed model id (modelsEditable: true) — falls back to defaultModalities (modelConfigResolver.ts:430), gets { image: true }, and when they attach a video, converter.ts:931/:986 silently replaces the attachment with the unsupportedModalityPlaceholder text stub. This happens even though the endpoint accepts video (this PR's own evidence: an MP4 passed as video_url came back described accurately) and the preset entries for qwen3.8-max/qwen3.8-max-preview in the same codebase declare modalities: { image: true, video: true }.

Witness:

probe at 847ec81c (intact PR):
  expected: {"max":{"image":true,"video":true},"previewPrefixed":{"image":true,"video":true}}
  received: {"max":{"image":true},"previewPrefixed":{"image":true}}
  probe red while the pinned suite passes 58/58
with [/^qwen3\.8-max/, { image: true, video: true }] applied:
  probe green; pinned test fails at modalityDefaults.test.ts:161
  AssertionError: expected true to be undefined
  the added lines actively lock the pre-fix behavior

Restore the merge-dropped fix: in packages/core/src/core/modalityDefaults.ts, change the pattern back to [/^qwen3\.8-max/, { image: true, video: true }] (updating the adjacent "max supports image only" comment), and in this test restore it('returns image + video for qwen3.8-max', ...) with expect(m.video).toBe(true), plus the provider-prefixed preview expectation expect(m.video).toBe(true) that dce1ea7 carried. The VS Code companion path itself no longer depends on this — main's derive-from-preset restructuring carries the preset's modalities — but env-var-only setups and manually typed ids still fall through this table.

After the fix, expect(m.video).toBe(true) in this test must hold — remove video: true from the /^qwen3\.8-max/ pattern (the exact mutation the merge already performed once) and confirm the test goes red.

中文说明

问题: 与 main 的最后一次合并丢掉了本 PR 自己已被接受的 R1-2 修复(defaultModalities/^qwen3\.8-max/video: true),而这里新增的断言把回退后的"仅图像"状态固定了下来。PR 描述仍声称在 modality 默认表中为 qwen3.8-max 系列声明了视频输入,但合入本 diff 后,测试锁定的恰恰是相反的行为。

失败场景: 用户通过任何不带显式 modalities 的路径使用 qwen3.8-max——仅环境变量的 Token Plan 配置,或手动输入的模型 ID(modelsEditable: true)——会回退到 defaultModalitiesmodelConfigResolver.ts:430),得到 { image: true };此时附带视频,converter.ts:931/:986 会把视频附件静默替换为 unsupportedModalityPlaceholder 文本占位符。尽管端点接受视频(本 PR 自己的证据:以 video_url 传入的 MP4 被准确描述),且同一代码库中 qwen3.8-max/qwen3.8-max-preview 的 preset 条目声明了 modalities: { image: true, video: true }

见证:

在 847ec81c 上用探针验证(PR 原样):
  期望: {"max":{"image":true,"video":true},"previewPrefixed":{"image":true,"video":true}}
  实际: {"max":{"image":true},"previewPrefixed":{"image":true}}
  探针失败,而现有测试套件 58/58 全绿
应用 [/^qwen3\.8-max/, { image: true, video: true }] 后:
  探针通过;固定测试在 modalityDefaults.test.ts:161 失败
  AssertionError: expected true to be undefined
  说明新增断言主动锁定了修复前的行为

建议修复: 恢复被合并丢失的修复:在 packages/core/src/core/modalityDefaults.ts 中把模式改回 [/^qwen3\.8-max/, { image: true, video: true }](同步更新相邻的 "max supports image only" 注释),并在本测试中恢复 it('returns image + video for qwen3.8-max', ...)expect(m.video).toBe(true),以及 dce1ea7 中带上的 provider 前缀预览版断言 expect(m.video).toBe(true)。VS Code companion 路径本身已不再依赖此修复——main 上 companion 已改为从 core preset 派生、会携带 preset 的 modalities——但仅环境变量配置和手动输入 ID 的路径仍会落到这张表。

修复见证: 修复后本测试必须满足 expect(m.video).toBe(true)——把 /^qwen3\.8-max/ 模式中的 video: true 去掉(即本次合并已经发生过一次的突变)并运行该测试,确认其变红。

— qwen3.8-max via Qwen Code /review (v0.22.3)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants