mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-31 08:29:07 +08:00
fix(models): qwen-mt-flash supports text delta (#11448)
refactor(models): improve text delta support check for qwen-mt models Replace direct qwen-mt model check with regex pattern matching Add comprehensive test cases for isNotSupportTextDeltaModel Update all references to use new function name
This commit is contained in:
parent
fd3b7f717d
commit
69d31a1e2b
@ -24,9 +24,9 @@ import {
|
||||
isGemmaModel,
|
||||
isGenerateImageModels,
|
||||
isMaxTemperatureOneModel,
|
||||
isNotSupportedTextDelta,
|
||||
isNotSupportSystemMessageModel,
|
||||
isNotSupportTemperatureAndTopP,
|
||||
isNotSupportTextDeltaModel,
|
||||
isSupportedFlexServiceTier,
|
||||
isSupportedModel,
|
||||
isSupportFlexServiceTierModel,
|
||||
@ -215,12 +215,51 @@ describe('model utils', () => {
|
||||
|
||||
it('aggregates boolean helpers based on regex rules', () => {
|
||||
expect(isAnthropicModel(createModel({ id: 'claude-3.5' }))).toBe(true)
|
||||
expect(isQwenMTModel(createModel({ id: 'qwen-mt-large' }))).toBe(true)
|
||||
expect(isNotSupportedTextDelta(createModel({ id: 'qwen-mt-large' }))).toBe(true)
|
||||
expect(isQwenMTModel(createModel({ id: 'qwen-mt-plus' }))).toBe(true)
|
||||
expect(isNotSupportSystemMessageModel(createModel({ id: 'gemma-moe' }))).toBe(true)
|
||||
expect(isOpenAIOpenWeightModel(createModel({ id: 'gpt-oss-free' }))).toBe(true)
|
||||
})
|
||||
|
||||
describe('isNotSupportedTextDelta', () => {
|
||||
it('returns true for qwen-mt-turbo and qwen-mt-plus models', () => {
|
||||
// qwen-mt series that don't support text delta
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-mt-turbo' }))).toBe(true)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-mt-plus' }))).toBe(true)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'Qwen-MT-Turbo' }))).toBe(true)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'QWEN-MT-PLUS' }))).toBe(true)
|
||||
})
|
||||
|
||||
it('returns false for qwen-mt-flash and other models', () => {
|
||||
// qwen-mt-flash supports text delta
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-mt-flash' }))).toBe(false)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'Qwen-MT-Flash' }))).toBe(false)
|
||||
|
||||
// Legacy qwen models without mt prefix (support text delta)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-turbo' }))).toBe(false)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-plus' }))).toBe(false)
|
||||
|
||||
// Other qwen models
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-max' }))).toBe(false)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen2.5-72b' }))).toBe(false)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-vl-plus' }))).toBe(false)
|
||||
|
||||
// Non-qwen models
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'gpt-4o' }))).toBe(false)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'claude-3.5' }))).toBe(false)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'glm-4-plus' }))).toBe(false)
|
||||
})
|
||||
|
||||
it('handles models with version suffixes', () => {
|
||||
// qwen-mt models with version suffixes
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-mt-turbo-1201' }))).toBe(true)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-mt-plus-0828' }))).toBe(true)
|
||||
|
||||
// Legacy qwen models with version suffixes (support text delta)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-turbo-0828' }))).toBe(false)
|
||||
expect(isNotSupportTextDeltaModel(createModel({ id: 'qwen-plus-latest' }))).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
it('evaluates GPT-5 family helpers', () => {
|
||||
expect(isGPT5SeriesModel(createModel({ id: 'gpt-5-preview' }))).toBe(true)
|
||||
expect(isGPT5SeriesModel(createModel({ id: 'gpt-5.1-preview' }))).toBe(false)
|
||||
|
||||
@ -111,8 +111,11 @@ export const isAnthropicModel = (model?: Model): boolean => {
|
||||
return modelId.startsWith('claude')
|
||||
}
|
||||
|
||||
export const isNotSupportedTextDelta = (model: Model): boolean => {
|
||||
return isQwenMTModel(model)
|
||||
const NOT_SUPPORT_TEXT_DELTA_MODEL_REGEX = new RegExp('qwen-mt-(?:turbo|plus)')
|
||||
|
||||
export const isNotSupportTextDeltaModel = (model: Model): boolean => {
|
||||
const modelId = getLowerBaseModelName(model.id)
|
||||
return NOT_SUPPORT_TEXT_DELTA_MODEL_REGEX.test(modelId)
|
||||
}
|
||||
|
||||
export const isNotSupportSystemMessageModel = (model: Model): boolean => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { TopView } from '@renderer/components/TopView'
|
||||
import { isNotSupportedTextDelta } from '@renderer/config/models'
|
||||
import { isNotSupportTextDeltaModel } from '@renderer/config/models'
|
||||
import { useProvider } from '@renderer/hooks/useProvider'
|
||||
import type { Model, Provider } from '@renderer/types'
|
||||
import { getDefaultGroupName } from '@renderer/utils'
|
||||
@ -58,7 +58,7 @@ const PopupContainer: React.FC<Props> = ({ title, provider, resolve }) => {
|
||||
group: values.group ?? getDefaultGroupName(id)
|
||||
}
|
||||
|
||||
addModel({ ...model, supported_text_delta: !isNotSupportedTextDelta(model) })
|
||||
addModel({ ...model, supported_text_delta: !isNotSupportTextDeltaModel(model) })
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
groupQwenModels,
|
||||
isEmbeddingModel,
|
||||
isFunctionCallingModel,
|
||||
isNotSupportedTextDelta,
|
||||
isNotSupportTextDeltaModel,
|
||||
isReasoningModel,
|
||||
isRerankModel,
|
||||
isVisionModel,
|
||||
@ -136,13 +136,13 @@ const PopupContainer: React.FC<Props> = ({ providerId, resolve }) => {
|
||||
addModel({
|
||||
...model,
|
||||
endpoint_type: endpointTypes.includes('image-generation') ? 'image-generation' : endpointTypes[0],
|
||||
supported_text_delta: !isNotSupportedTextDelta(model)
|
||||
supported_text_delta: !isNotSupportTextDeltaModel(model)
|
||||
})
|
||||
} else {
|
||||
NewApiAddModelPopup.show({ title: t('settings.models.add.add_model'), provider, model })
|
||||
}
|
||||
} else {
|
||||
addModel({ ...model, supported_text_delta: !isNotSupportedTextDelta(model) })
|
||||
addModel({ ...model, supported_text_delta: !isNotSupportTextDeltaModel(model) })
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { TopView } from '@renderer/components/TopView'
|
||||
import { endpointTypeOptions } from '@renderer/config/endpointTypes'
|
||||
import { isNotSupportedTextDelta } from '@renderer/config/models'
|
||||
import { isNotSupportTextDeltaModel } from '@renderer/config/models'
|
||||
import { useDynamicLabelWidth } from '@renderer/hooks/useDynamicLabelWidth'
|
||||
import { useProvider } from '@renderer/hooks/useProvider'
|
||||
import type { EndpointType, Model, Provider } from '@renderer/types'
|
||||
@ -65,7 +65,7 @@ const PopupContainer: React.FC<Props> = ({ title, provider, resolve, model, endp
|
||||
endpoint_type: isNewApiProvider(provider) ? values.endpointType : undefined
|
||||
}
|
||||
|
||||
addModel({ ...model, supported_text_delta: !isNotSupportedTextDelta(model) })
|
||||
addModel({ ...model, supported_text_delta: !isNotSupportTextDeltaModel(model) })
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { TopView } from '@renderer/components/TopView'
|
||||
import { endpointTypeOptions } from '@renderer/config/endpointTypes'
|
||||
import { isNotSupportedTextDelta } from '@renderer/config/models'
|
||||
import { isNotSupportTextDeltaModel } from '@renderer/config/models'
|
||||
import { useDynamicLabelWidth } from '@renderer/hooks/useDynamicLabelWidth'
|
||||
import { useProvider } from '@renderer/hooks/useProvider'
|
||||
import type { EndpointType, Model, Provider } from '@renderer/types'
|
||||
@ -48,7 +48,7 @@ const PopupContainer: React.FC<Props> = ({ title, provider, resolve, batchModels
|
||||
addModel({
|
||||
...model,
|
||||
endpoint_type: values.endpointType,
|
||||
supported_text_delta: !isNotSupportedTextDelta(model)
|
||||
supported_text_delta: !isNotSupportTextDeltaModel(model)
|
||||
})
|
||||
})
|
||||
return true
|
||||
|
||||
@ -5,7 +5,7 @@ import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
|
||||
import {
|
||||
glm45FlashModel,
|
||||
isFunctionCallingModel,
|
||||
isNotSupportedTextDelta,
|
||||
isNotSupportTextDeltaModel,
|
||||
SYSTEM_MODELS
|
||||
} from '@renderer/config/models'
|
||||
import { BUILTIN_OCR_PROVIDERS, BUILTIN_OCR_PROVIDERS_MAP, DEFAULT_OCR_PROVIDER } from '@renderer/config/ocr'
|
||||
@ -1988,7 +1988,7 @@ const migrateConfig = {
|
||||
const updateModelTextDelta = (model?: Model) => {
|
||||
if (model) {
|
||||
model.supported_text_delta = true
|
||||
if (isNotSupportedTextDelta(model)) {
|
||||
if (isNotSupportTextDeltaModel(model)) {
|
||||
model.supported_text_delta = false
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user