fix(core): add DeepSeek V4 Flash Vision to model metadata - #3605
fix(core): add DeepSeek V4 Flash Vision to model metadata#3605yunaremaia wants to merge 9 commits into
Conversation
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed at exact head d74bb28c0af711063db5c77084fdd06962a279e2. No [P0]–[P2]. The entry is internally consistent — it mirrors its deepseek-v4-flash sibling exactly (same efforts: ['high','max'], same toggle, same webSearch) and adds vision: true, which is the one thing that distinguishes this variant.
Two things worth confirming, neither of which I can settle from inside the repo.
The model ID has to be exactly what the API accepts. Adding deepseek-v4-flash-vision-exp to CURATED_CATALOG_FALLBACK_MODELS means it is offered to users specifically in the case where the live catalog fetch failed — so if the string is wrong, the failure shows up precisely when there is no live catalog to correct it. Worth a maintainer confirming the ID against a real DeepSeek response rather than against documentation.
vision: true is a hard declaration here. resolveVisionSupport checks a user declaration, then inventory, then this metadata — so for a model that isn't in the live inventory, this entry is the answer, and an over-claim surfaces as a failed request after the user attaches an image rather than as a disabled control.
[P3] No lastUpdated
The neighbouring deepseek-v4-pro carries lastUpdated: '2026-08-13' while both flash entries omit it. Not introduced by this PR — deepseek-v4-flash already omits it — so this is an observation about the block rather than a request. Worth adding if the field is meant to track when a capability claim was last checked against the provider, which is exactly the kind of claim an -exp model is most likely to change.
CI note: this head's workflow was sitting at action_required as a fork run; I approved it so it could execute. Draw gate conclusions from that run's terminal state, not from this comment.
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed at exact head 9287cdfe781bbac1f1673ccf23f0d62bbf7f8745 (biome-formatting follow-up to d74bb28c0a; delta is line-wrapping only). One [P3] inline; no [P0]–[P2].
This pass also settles the two external confirmations the earlier review left open, checked against the current official DeepSeek API docs:
- Model ID:
deepseek-v4-flash-vision-expis exactly the id listed on the Models & Pricing and Your First API Call pages (model versionDeepSeek-V4-Flash-Vision-Exp), so the fallback-catalog entry matches what the API accepts even in the no-live-catalog case. vision: true: the Vision guide documents image input for this model (JPEG/PNG/GIF/WebP via base64 / external URL / Files API) and the pricing page bills images as input tokens, so the capability claim is backed by upstream.
Two more spot-checks that pass: webSearch: true matches the Responses API guide's server-side web_search tool (with web_search_call passthrough explicitly covered for this model), and toggle: true matches "supports both non-thinking and thinking (default) modes" on the pricing page.
Gate: test is the only path-filtered check this change can trigger and it is terminal green on this exact head.
| }, | ||
| 'deepseek-v4-flash-vision-exp': { | ||
| capabilities: { vision: true, ...REASONING_FUNCTION_CALLING, webSearch: true }, | ||
| thinkingOptions: { efforts: ['high', 'max'], toggle: true }, |
There was a problem hiding this comment.
[P3] efforts here is ['high', 'max'] but every current upstream source lists low for this model, so the menu will be missing the cheapest effort option.
- models.dev lists
deepseek-v4-flash-vision-expwith toggle + effort values['low', 'high', 'max'](last updated 2026-08-21, the release date). - The official Thinking Mode guide accepts
reasoning_effort: low/high/max. - The
deepseek-v4-proentry just below already pins['low', 'high', 'max'](lastUpdated 2026-08-13).
The value looks copied from the deepseek-v4-flash sibling above, whose pinned set predates its 0731 refresh (models.dev now lists flash as low/high/max too). Suggested fix: efforts: ['low', 'high', 'max'].
(Separate observation, not for this PR: the deepseek-v4-flash static entry has the same staleness and might deserve its own follow-up so the next model doesn't inherit it.)
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed on exact head 9287cdfe781bbac1f1673ccf23f0d62bbf7f8745. Holding off on approval for one finding, inline below.
Everything else checks out. The model ID matches the official pricing and First API Call pages verbatim; vision is backed by the official Vision guide and by images being billed as input tokens; webSearch (Responses API web_search) and toggle (thinking on by default, can be turned off) both verified. Two items left open by an earlier review round are now closed.
Gating: only test is triggered here — no package.json/lockfile or sandbox paths — and it is terminal success on this exact head. So the sole thing standing between this and approval is the effort list.
| }, | ||
| 'deepseek-v4-flash-vision-exp': { | ||
| capabilities: { vision: true, ...REASONING_FUNCTION_CALLING, webSearch: true }, | ||
| thinkingOptions: { efforts: ['high', 'max'], toggle: true }, |
There was a problem hiding this comment.
[P2] efforts: ['high', 'max'] is missing 'low'.
Three independent sources agree this model exposes low/high/max: the models.dev entry (refreshed 2026-08-21, toggle plus low/high/max), the official Thinking Mode docs (reasoning_effort accepts low/high/max), and deepseek-v4-pro two entries below, which already pins ['low', 'high', 'max'].
The likely origin is visible in the file: the sibling deepseek-v4-flash entry directly above carries the same ['high', 'max'], which is a stale high-water mark from before the 07-31 refresh. This entry appears to have inherited it.
I am grading this P2 rather than P3, and I want to be explicit that I am raising a colleague's grade. The reasoning: this PR's entire purpose is to add correct metadata for one model. A wrong effort list is not a peripheral nitpick here — it is a defect in the single thing being added, and it is user-visible, since the effort menu simply will not offer low for this model. Merging as-is would ship the exact error the change set out to prevent, and the fix is one array element.
Separately, and explicitly not part of this PR: deepseek-v4-flash above looks stale for the same reason. Worth a follow-up, but please do not widen this PR to cover it.
There was a problem hiding this comment.
Fixed in 32dd6a4 - efforts is now ['low', 'high', 'max'], matching the three sources you cited (models.dev refreshed 2026-08-21, the Thinking Mode guide's reasoning_effort, and the deepseek-v4-pro pin). Good catch on the inheritance path: the value did come from copying the sibling deepseek-v4-flash entry above.
On that note - your [P3] analysis implies deepseek-v4-flash itself is also carrying a stale pre-refresh pin (['high','max']). I kept this PR scoped to the new entry, but I'm happy to open a separate PR correcting the sibling if you'd rather review that evidence independently.
Astro-Han
left a comment
There was a problem hiding this comment.
#3605 9287cdf — review (bind exact head)
Gate: CI test success (run 32642126723). No unaddressed threads.
Scope: Adds deepseek-v4-flash-vision-exp with vision:true + REASONING_FUNCTION_CALLING + webSearch and inserts into fallback catalog.
Checks: Model ID spelling follows existing deepseek-v4-flash convention; capabilities include vision as expected for vision exp. No context window / pricing fields in this metadata shape — not applicable. Placement in CURATED_CATALOG_FALLBACK_MODELS correct.
Limitation: No public DeepSeek doc fetched in this pass to independently confirm context window / capability bits — marked as sampled external verification. No P0-P2 observed on diff.
Verdict: COMMENT (content GO subject to external doc check — no blockers found in repo).
中文
命名与能力位符合既有风格,未见阻断问题。|
This does the same thing as #3420 — registering Before closing it I compared the metadata on both sides, and there are two factual disagreements. Could you confirm them against DeepSeek's official documentation?
Also, #3420 carried 简体中文这条和 #3420 在做同一件事(注册 关掉之前对比了两边的元数据,有两处事实上的分歧,麻烦你按 DeepSeek 官方文档确认一下:
另外 #3420 带了 |
|
Thanks for consolidating this work in #3605. I checked the two metadata differences against the current official DeepSeek documentation:
Regarding tests, the tests from #3420 should not be cherry-picked verbatim because they also assert richer metadata that #3605 does not currently add. I suggest adapting them into a focused regression test that verifies:
To support the modalities assertion, the metadata entry should explicitly add: modalities: { input: ['text', 'image'], output: ['text'] },One remaining scope question: #3420 also included a friendly display name and description, while #3605 currently leaves those out. Should those fields be retained in this PR or handled separately? I would be happy to prepare an adapted test patch if that would be helpful. 简体中文感谢将相关工作统一放到 #3605 中推进。 我对照 DeepSeek 当前的官方文档,检查了两处存在差异的模型元数据:
关于测试,#3420 中的测试不适合原样复制,因为它们还验证了 #3605 当前没有添加的、更完整的模型元数据。我建议将这些测试调整为有针对性的回归测试,用来验证:
为了支持输入模态相关的断言,模型元数据中应当明确添加: modalities: { input: ['text', 'image'], output: ['text'] },还有一个需要确认的范围问题:#3420 中还添加了友好的模型显示名称和模型说明,而 #3605 当前没有包含这些字段。这些字段应该保留在本 PR 中,还是另外处理? 如果有帮助,我愿意准备一份经过适配的测试补丁。 |
|
Thanks for the thorough doc check, @sunrioa — this is exactly the verification this PR needed.
On the scope question: my preference is to keep And thanks for offering the test patch — de54642 already includes an adapted version of it, so nothing more needed from you unless you spot a gap. |
ca7bcd2 to
a1d1366
Compare
deepseek-v4-flash-vision-exp is returned by the first-party /models endpoint but was absent from STATIC_MODEL_METADATA, causing Maka to classify it as text-only and filter image attachments before the request reaches the provider. Add the model ID with vision capability to both STATIC_MODEL_METADATA and CURATED_CATALOG_FALLBACK_MODELS so the existing DeepSeek adapter passes image content through. Fixes: apache#3417 Signed-off-by: Yunare Maia <yunare@gmail.com>
Per review: models.dev (refreshed 2026-08-21), the official Thinking Mode guide, and the deepseek-v4-pro entry all confirm low/high/max. The pinned ['high','max'] was inherited from the stale pre-0731 sibling entry.
…-exp Add the explicit modalities entry suggested in review so attachment routing sees image input without relying on generated snapshots, and add a focused regression test covering vision resolution, input modalities, and fallback-catalog presence for the bare model id. Co-authored-by: Yunare Maia <yunare@gmail.com>
a1d1366 to
a19e124
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Registers deepseek-v4-flash-vision-exp in STATIC_MODEL_METADATA.deepseek with vision: true and modalities.input: ['text','image'], adds it to CURATED_CATALOG_FALLBACK_MODELS.deepseek, and pins all three facts with a regression test (#3417).
The mechanism is right, and I verified it rather than taking the body's word for it:
resolveModelVisionSupport(model-metadata.ts:163-178) falls through the stored inventory tolookupModelMetadata, and returnsmetadata.capabilities?.vision === true. With no entry it returnedfalse, which is exactly the filtering the issue describes. The new entry flips it.STATIC_MODEL_METADATAis the override layer applied over the generated models.dev snapshot inlookupModelMetadata(:79-98), so it is the correct seam for a model models.dev does not carry yet. This extends an existing authority instead of adding a second one.modalities.inputis a genuinely separate authority here, not a restatement ofvision—resolveModelPdfSupport(:198-202) reads it independently. Listing['text','image']without'pdf'therefore leaves PDF supportfalse, which was also the behavior before this change. No accidental widening.
Two things before I approve.
P2 — this does not actually close #3417, but it says it does. The issue asks for three things, and its "expected behavior" names the third explicitly: recognize image input, send the attachment, and display a friendly model name and description instead of the raw ID. This PR delivers the first two. The picker will keep showing the bare deepseek-v4-flash-vision-exp string, because the generated models.dev snapshot does not carry this model — that absence is the entire reason this entry has to be hand-written in the first place. Fixes #3417 will auto-close the issue on merge with a third of it still broken, and the reporter will have to reopen it.
ModelMetadata already has displayName and description (model-metadata.ts:28-29), and six entries in this same table already use them, so the fix is two more lines in the object you are already adding. Please add them. If you would rather scope this PR to the vision capability alone, that is fine too — then change the body to Refs #3417 so the issue stays open.
P3 — lastUpdated is omitted. Both sibling entries, deepseek-v4-flash and deepseek-v4-pro, carry it. Not load-bearing, but this is a hand-maintained table whose staleness is otherwise invisible, which is precisely what that field exists to make visible.
One thing I could not verify and am not treating as a finding: I have no way to confirm from this repository that DeepSeek's /models really returns this ID with image input. I am taking the issue reporter's first-hand reproduction for that, which seems reasonable — flagging it only so it is on the record that the model's existence is sourced from the issue, not from our own code.
Leaving this as a comment. Happy to approve as soon as the display name and description are in, or the body is retargeted to Refs.
AI use: Claude Code (Opus) traced resolveModelVisionSupport, resolveModelInputModalities, resolveModelPdfSupport, and lookupModelMetadata in packages/core/src/model-metadata.ts, and checked the sibling entries and the displayName precedent in the same table. The reviewer of record reviewed and accepted that reasoning.
简体中文
在 STATIC_MODEL_METADATA.deepseek 中登记 deepseek-v4-flash-vision-exp(vision: true 与 modalities.input: ['text','image']),加入 CURATED_CATALOG_FALLBACK_MODELS.deepseek,并用回归测试钉住三项事实(#3417)。
机制是对的,我按代码核实而非采信正文:
resolveModelVisionSupport(model-metadata.ts:163-178)在库存查不到时回落到lookupModelMetadata,返回metadata.capabilities?.vision === true。没有条目时返回false,正是 issue 描述的过滤行为;新条目把它翻转过来。STATIC_MODEL_METADATA是在lookupModelMetadata(:79-98)中叠加于 models.dev 生成快照之上的覆盖层,因此对于 models.dev 尚未收录的模型,这是正确的接缝。属于扩展既有权威,而非新增第二个。modalities.input在这里确实是独立权威,不是vision的复述——resolveModelPdfSupport(:198-202)独立读取它。列['text','image']而不含'pdf',因此 PDF 支持仍为false,与改动前一致,没有意外放宽。
Approve 之前有两点。
P2 —— 它实际上没有关闭 #3417,但正文声称关闭了。 issue 要求三件事,"预期行为"明确点出第三件:识别图片输入、发送附件、以及显示友好的模型名称和说明而非原始 ID。本 PR 交付了前两件。模型选择器仍会显示裸的 deepseek-v4-flash-vision-exp,因为 models.dev 生成快照里没有这个模型——而这份缺失正是这个条目必须手写的全部原因。Fixes #3417 会在合并时自动关闭 issue,而三分之一仍未修复,报告者还得重开。
ModelMetadata 已有 displayName 和 description(model-metadata.ts:28-29),同一张表里已有六个条目在用,所以补齐只是你正在添加的这个对象里再加两行。请补上。若你更想把本 PR 收窄到只做视觉能力,也可以——那就把正文改成 Refs #3417,让 issue 保持打开。
P3 —— 缺 lastUpdated。 兄弟条目 deepseek-v4-flash 和 deepseek-v4-pro 都有。它不承重,但这是一张手工维护的表,其陈旧程度本来不可见,而这个字段的存在正是为了让它可见。
有一点我无法核实,也不作为 finding:我没法从本仓库确认 DeepSeek 的 /models 确实返回该 ID 且支持图片输入。这一点我采信 issue 报告者的第一手复现,看起来是合理的——写出来只是留档说明该模型的存在性来自 issue,而非来自我们自己的代码。
先留 comment。补上显示名与说明,或把正文改为 Refs,我即可 Approve。
…flash-vision-exp Addresses reviewer feedback on apache#3605: adds displayName, description, and lastUpdated fields to the STATIC_MODEL_METADATA entry so the model picker shows a friendly name instead of the bare model ID. Co-authored-by: Astro-Han <Astro-Han@users.noreply.github.com>
- Added tests to verify vision support, modalities, and metadata lookup - Added catalog test for V4 vision model display metadata - Fixes reviewer feedback on apache#3605
…l-metadata.test.ts The function is exported from model-catalog.ts, not model-metadata.ts. Local vitest runs pass because it compiles differently than tsc.
Summary
Registers
deepseek-v4-flash-vision-expin the model metadata so Maka correctly recognizes its image input capability and passes attachments through to the DeepSeek adapter.Fixes #3417
What changed
STATIC_MODEL_METADATA.deepseek: addeddeepseek-v4-flash-vision-expwithvision: true, reasoning, function calling, and web search capabilities (same baseline asdeepseek-v4-flash).CURATED_CATALOG_FALLBACK_MODELS.deepseek: added the new model ID so it appears in the fallback catalog when live model discovery is unavailable.How it fixes the bug
resolveModelVisionSupport()checksSTATIC_MODEL_METADATAwhen the model ID is not in the stored inventory. Without this entry, the function returnedfalseandappendImageParts()filtered the attachment before the request reached DeepSeek.Testing
deepseek-v4-flashentry, withvision: trueadded.resolveModelVisionSupporttests exercise the metadata lookup path, and the new entry is structurally identical to existing entries.npm installlocally (blocked by@xterm/xtermregistry fetch on this host).AI disclosure
OpenAI Codex assisted with codebase analysis. I reviewed the diff and take responsibility for the contribution.
Signed-off-by: Yunare Maia yunare@gmail.com