From c363f65f19a341b99d6dbfb492480e00ba2a4bec Mon Sep 17 00:00:00 2001 From: "jinjing.zzj" Date: Thu, 27 Aug 2026 18:35:50 +0800 Subject: [PATCH] fix(core): recognize new DeepSeek/GLM vision models in modality auto-detection Add targeted entries to MODALITY_PATTERNS so name-based modality detection grants image input to the vision models reported in #10270: - deepseek-v4-flash-vision-exp (and any DeepSeek -vision variant) previously matched the family-wide [/^deepseek/, {}] text-only entry. - glm-4.6v / glm-5v-turbo belong to the same v-suffix vision family as the already-recognized glm-4.5v; generalize that entry to [/^glm-[0-9.]+v/, { image: true }]. - glm-5.3-flash natively integrates vision input but has no v suffix, so it gets its own precise entry ahead of the text-only GLM patterns. Without these entries the models fall through to the text-only default, so createMediaContentPart() silently replaces attached images with a text placeholder and isImageCapable() excludes the models from vision-bridge candidates. Explicit modalities overrides were already honored and are untouched. Co-authored-by: Qwen-Coder --- .../core/src/core/modalityDefaults.test.ts | 34 +++++++++++++++++++ packages/core/src/core/modalityDefaults.ts | 11 ++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/core/src/core/modalityDefaults.test.ts b/packages/core/src/core/modalityDefaults.test.ts index 8406363d901..82b00d3e5c9 100644 --- a/packages/core/src/core/modalityDefaults.test.ts +++ b/packages/core/src/core/modalityDefaults.test.ts @@ -202,6 +202,17 @@ describe('defaultModalities', () => { it('returns text-only for deepseek-reasoner', () => { expect(defaultModalities('deepseek-reasoner')).toEqual({}); }); + + // (QwenLM/qwen-code#10270) + it('returns text-only for non-vision deepseek-v4-flash', () => { + expect(defaultModalities('deepseek-v4-flash')).toEqual({}); + }); + + it('returns image for deepseek-v4-flash-vision-exp', () => { + const m = defaultModalities('deepseek-v4-flash-vision-exp'); + expect(m.image).toBe(true); + expect(m.pdf).toBeUndefined(); + }); }); describe('Zhipu GLM', () => { @@ -211,6 +222,25 @@ describe('defaultModalities', () => { expect(m.pdf).toBeUndefined(); }); + // (QwenLM/qwen-code#10270) + it('returns image for glm-4.6v', () => { + const m = defaultModalities('glm-4.6v'); + expect(m.image).toBe(true); + expect(m.pdf).toBeUndefined(); + }); + + it('returns image for glm-5v-turbo', () => { + const m = defaultModalities('glm-5v-turbo'); + expect(m.image).toBe(true); + expect(m.pdf).toBeUndefined(); + }); + + it('returns image for glm-5.3-flash', () => { + const m = defaultModalities('glm-5.3-flash'); + expect(m.image).toBe(true); + expect(m.pdf).toBeUndefined(); + }); + it('returns text-only for glm-5', () => { expect(defaultModalities('glm-5')).toEqual({}); }); @@ -218,6 +248,10 @@ describe('defaultModalities', () => { it('returns text-only for glm-4.7', () => { expect(defaultModalities('glm-4.7')).toEqual({}); }); + + it('returns text-only for glm-4.6 (no v suffix)', () => { + expect(defaultModalities('glm-4.6')).toEqual({}); + }); }); describe('MiniMax', () => { diff --git a/packages/core/src/core/modalityDefaults.ts b/packages/core/src/core/modalityDefaults.ts index d8adce67bb6..e70728688bc 100644 --- a/packages/core/src/core/modalityDefaults.ts +++ b/packages/core/src/core/modalityDefaults.ts @@ -61,14 +61,19 @@ const MODALITY_PATTERNS: Array<[RegExp, InputModalities]> = [ [/^qwen/, {}], // ------------------- - // DeepSeek — text-only + // DeepSeek — text-only, except explicit vision variants + // (QwenLM/qwen-code#10270) // ------------------- + [/^deepseek-.*vision/, { image: true }], [/^deepseek/, {}], // ------------------- - // Zhipu GLM + // Zhipu GLM — v-suffix ids are vision models; others are text-only + // (QwenLM/qwen-code#10270) // ------------------- - [/^glm-4\.5v/, { image: true }], + [/^glm-[0-9.]+v/, { image: true }], + // glm-5.3-flash natively integrates vision input (no v suffix) + [/^glm-5\.3-flash/, { image: true }], [/^glm-5(?:-|$)/, {}], [/^glm-/, {}],