fix: update selectedTypes logic in ModelEditContent for better handling (#5819)

refactor: improve model type checking logic in models.ts and ModelEditContent.tsx

* Refactor isFunctionCallingModel, isEmbeddingModel, isVisionModel, isReasoningModel, and isWebSearchModel functions for better readability and maintainability.
* Simplify type selection logic in ModelEditContent by directly using model.type or defaultTypes.
* Remove unnecessary conditional checks to streamline the code.

Co-authored-by: kanweiwei <kanweiwei@nutstore.net>
This commit is contained in:
Camol 2025-05-10 19:55:56 +08:00 committed by GitHub
parent a448fa1804
commit 14d013243c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 132 additions and 129 deletions

View File

@ -237,23 +237,24 @@ export const CLAUDE_SUPPORTED_WEBSEARCH_REGEX = new RegExp(
) )
export function isFunctionCallingModel(model: Model): boolean { export function isFunctionCallingModel(model: Model): boolean {
if (model.type?.includes('function_calling')) { if (!model) return false
return true if (model.type) {
} return model.type.includes('function_calling')
} else {
if (isEmbeddingModel(model)) {
return false
}
if (isEmbeddingModel(model)) { if (model.provider === 'qiniu') {
return false return ['deepseek-v3-tool', 'deepseek-v3-0324', 'qwq-32b', 'qwen2.5-72b-instruct'].includes(model.id)
} }
if (model.provider === 'qiniu') { if (['deepseek', 'anthropic'].includes(model.provider)) {
return ['deepseek-v3-tool', 'deepseek-v3-0324', 'qwq-32b', 'qwen2.5-72b-instruct'].includes(model.id) return true
} }
if (['deepseek', 'anthropic'].includes(model.provider)) { return FUNCTION_CALLING_REGEX.test(model.id)
return true
} }
return FUNCTION_CALLING_REGEX.test(model.id)
} }
export function getModelLogo(modelId: string) { export function getModelLogo(modelId: string) {
@ -2188,20 +2189,23 @@ export function isEmbeddingModel(model: Model): boolean {
if (!model) { if (!model) {
return false return false
} }
if (model.type) {
return model.type.includes('embedding')
} else {
if (['anthropic'].includes(model?.provider)) {
return false
}
if (['anthropic'].includes(model?.provider)) { if (model.provider === 'doubao') {
return false return EMBEDDING_REGEX.test(model.name)
}
if (isRerankModel(model)) {
return false
}
return EMBEDDING_REGEX.test(model.id)
} }
if (model.provider === 'doubao') {
return EMBEDDING_REGEX.test(model.name)
}
if (isRerankModel(model)) {
return false
}
return EMBEDDING_REGEX.test(model.id) || model.type?.includes('embedding') || false
} }
export function isRerankModel(model: Model): boolean { export function isRerankModel(model: Model): boolean {
@ -2212,16 +2216,20 @@ export function isVisionModel(model: Model): boolean {
if (!model) { if (!model) {
return false return false
} }
// 新添字段 copilot-vision-request 后可使用 vision if (model.type) {
// if (model.provider === 'copilot') { return model.type.includes('vision')
// return false } else {
// } // 新添字段 copilot-vision-request 后可使用 vision
// if (model.provider === 'copilot') {
// return false
// }
if (model.provider === 'doubao') { if (model.provider === 'doubao') {
return VISION_REGEX.test(model.name) || model.type?.includes('vision') || false return VISION_REGEX.test(model.name)
}
return VISION_REGEX.test(model.id)
} }
return VISION_REGEX.test(model.id) || model.type?.includes('vision') || false
} }
export function isOpenAIReasoningModel(model: Model): boolean { export function isOpenAIReasoningModel(model: Model): boolean {
@ -2355,23 +2363,26 @@ export function isReasoningModel(model?: Model): boolean {
if (!model) { if (!model) {
return false return false
} }
if (model.type) {
return model.type.includes('reasoning')
} else {
if (model.provider === 'doubao') {
return REASONING_REGEX.test(model.name)
}
if (model.provider === 'doubao') { if (
return REASONING_REGEX.test(model.name) || model.type?.includes('reasoning') || false isClaudeReasoningModel(model) ||
isOpenAIReasoningModel(model) ||
isGeminiReasoningModel(model) ||
isQwenReasoningModel(model) ||
isGrokReasoningModel(model) ||
model.id.includes('glm-z1')
) {
return true
}
return REASONING_REGEX.test(model.id)
} }
if (
isClaudeReasoningModel(model) ||
isOpenAIReasoningModel(model) ||
isGeminiReasoningModel(model) ||
isQwenReasoningModel(model) ||
isGrokReasoningModel(model) ||
model.id.includes('glm-z1')
) {
return true
}
return REASONING_REGEX.test(model.id) || model.type?.includes('reasoning') || false
} }
export function isSupportedModel(model: OpenAI.Models.Model): boolean { export function isSupportedModel(model: OpenAI.Models.Model): boolean {
@ -2386,89 +2397,86 @@ export function isWebSearchModel(model: Model): boolean {
if (!model) { if (!model) {
return false return false
} }
if (model.type) { if (model.type) {
if (model.type.includes('web_search')) { return model.type.includes('web_search')
return true } else {
const provider = getProviderByModel(model)
if (!provider) {
return false
} }
}
const provider = getProviderByModel(model) const isEmbedding = isEmbeddingModel(model)
if (!provider) { if (isEmbedding) {
return false return false
} }
const isEmbedding = isEmbeddingModel(model) if (model.id.includes('claude')) {
return CLAUDE_SUPPORTED_WEBSEARCH_REGEX.test(model.id)
}
if (isEmbedding) { if (provider.type === 'openai') {
return false if (
} isOpenAILLMModel(model) &&
!isTextToImageModel(model) &&
!isOpenAIReasoningModel(model) &&
!GENERATE_IMAGE_MODELS.includes(model.id)
) {
return true
}
if (model.id.includes('claude')) { return false
return CLAUDE_SUPPORTED_WEBSEARCH_REGEX.test(model.id) }
}
if (provider.type === 'openai') { if (provider.id === 'perplexity') {
if ( return PERPLEXITY_SEARCH_MODELS.includes(model?.id)
isOpenAILLMModel(model) && }
!isTextToImageModel(model) &&
!isOpenAIReasoningModel(model) && if (provider.id === 'aihubmix') {
!GENERATE_IMAGE_MODELS.includes(model.id) if (
) { isOpenAILLMModel(model) &&
!isTextToImageModel(model) &&
!isOpenAIReasoningModel(model) &&
!GENERATE_IMAGE_MODELS.includes(model.id)
) {
return true
}
const models = ['gemini-2.0-flash-search', 'gemini-2.0-flash-exp-search', 'gemini-2.0-pro-exp-02-05-search']
return models.includes(model?.id)
}
if (provider?.type === 'openai-compatible') {
if (GEMINI_SEARCH_MODELS.includes(model?.id) || isOpenAIWebSearch(model)) {
return true
}
}
if (provider.id === 'gemini' || provider?.type === 'gemini') {
return GEMINI_SEARCH_MODELS.includes(model?.id)
}
if (provider.id === 'hunyuan') {
return model?.id !== 'hunyuan-lite'
}
if (provider.id === 'zhipu') {
return model?.id?.startsWith('glm-4-')
}
if (provider.id === 'dashscope') {
const models = ['qwen-turbo', 'qwen-max', 'qwen-plus', 'qwq']
// matches id like qwen-max-0919, qwen-max-latest
return models.some((i) => model.id.startsWith(i))
}
if (provider.id === 'openrouter') {
return true return true
} }
return false return false
} }
if (provider.id === 'perplexity') {
return PERPLEXITY_SEARCH_MODELS.includes(model?.id)
}
if (provider.id === 'aihubmix') {
if (
isOpenAILLMModel(model) &&
!isTextToImageModel(model) &&
!isOpenAIReasoningModel(model) &&
!GENERATE_IMAGE_MODELS.includes(model.id)
) {
return true
}
const models = ['gemini-2.0-flash-search', 'gemini-2.0-flash-exp-search', 'gemini-2.0-pro-exp-02-05-search']
return models.includes(model?.id)
}
if (provider?.type === 'openai-compatible') {
if (GEMINI_SEARCH_MODELS.includes(model?.id) || isOpenAIWebSearch(model)) {
return true
}
}
if (provider.id === 'gemini' || provider?.type === 'gemini') {
return GEMINI_SEARCH_MODELS.includes(model?.id)
}
if (provider.id === 'hunyuan') {
return model?.id !== 'hunyuan-lite'
}
if (provider.id === 'zhipu') {
return model?.id?.startsWith('glm-4-')
}
if (provider.id === 'dashscope') {
const models = ['qwen-turbo', 'qwen-max', 'qwen-plus', 'qwq']
// matches id like qwen-max-0919, qwen-max-latest
return models.some((i) => model.id.startsWith(i))
}
if (provider.id === 'openrouter') {
return true
}
return false
} }
export function isGenerateImageModel(model: Model): boolean { export function isGenerateImageModel(model: Model): boolean {

View File

@ -132,7 +132,7 @@ const ModelEditContent: FC<ModelEditContentProps> = ({ model, onUpdateModel, ope
] as ModelType[] ] as ModelType[]
// 合并现有选择和默认类型 // 合并现有选择和默认类型
const selectedTypes = [...new Set([...(model.type || []), ...defaultTypes])] const selectedTypes = model.type ? model.type : defaultTypes
const showTypeConfirmModal = (type: string) => { const showTypeConfirmModal = (type: string) => {
window.modal.confirm({ window.modal.confirm({
@ -165,28 +165,23 @@ const ModelEditContent: FC<ModelEditContentProps> = ({ model, onUpdateModel, ope
options={[ options={[
{ {
label: t('models.type.vision'), label: t('models.type.vision'),
value: 'vision', value: 'vision'
disabled: isVisionModel(model) && !selectedTypes.includes('vision')
}, },
{ {
label: t('models.type.websearch'), label: t('models.type.websearch'),
value: 'web_search', value: 'web_search'
disabled: isWebSearchModel(model) && !selectedTypes.includes('web_search')
}, },
{ {
label: t('models.type.embedding'), label: t('models.type.embedding'),
value: 'embedding', value: 'embedding'
disabled: isEmbeddingModel(model) && !selectedTypes.includes('embedding')
}, },
{ {
label: t('models.type.reasoning'), label: t('models.type.reasoning'),
value: 'reasoning', value: 'reasoning'
disabled: isReasoningModel(model) && !selectedTypes.includes('reasoning')
}, },
{ {
label: t('models.type.function_calling'), label: t('models.type.function_calling'),
value: 'function_calling', value: 'function_calling'
disabled: isFunctionCallingModel(model) && !selectedTypes.includes('function_calling')
} }
]} ]}
/> />