UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

187 lines (169 loc) 5.24 kB
import type { ChatModelCard } from '@/types/llm'; export interface ModelProcessorConfig { excludeKeywords?: readonly string[]; // 对符合的模型不添加标签 functionCallKeywords?: readonly string[]; reasoningKeywords?: readonly string[]; visionKeywords?: readonly string[]; } // 模型标签关键词配置 export const MODEL_LIST_CONFIGS = { anthropic: { functionCallKeywords: ['claude'], reasoningKeywords: ['-3-7', '3.7', '-4'], visionKeywords: ['claude'], }, deepseek: { functionCallKeywords: ['v3', 'r1'], reasoningKeywords: ['r1'], }, google: { functionCallKeywords: ['gemini'], reasoningKeywords: ['thinking', '-2.5-'], visionKeywords: ['gemini', 'learnlm'], }, llama: { functionCallKeywords: ['llama-3.2', 'llama-3.3', 'llama-4'], reasoningKeywords: [], visionKeywords: [], }, openai: { excludeKeywords: ['audio'], functionCallKeywords: ['4o', '4.1', 'o3', 'o4'], reasoningKeywords: ['o1', 'o3', 'o4'], visionKeywords: ['4o', '4.1', 'o4'], }, qwen: { functionCallKeywords: [ 'qwen-max', 'qwen-plus', 'qwen-turbo', 'qwen-long', 'qwen1.5', 'qwen2', 'qwen2.5', 'qwen3', ], reasoningKeywords: ['qvq', 'qwq', 'qwen3'], visionKeywords: ['qvq', 'vl'], }, volcengine: { functionCallKeywords: ['doubao-1.5'], reasoningKeywords: ['thinking', '-r1'], visionKeywords: ['vision', '-m'], }, zeroone: { functionCallKeywords: ['fc'], visionKeywords: ['vision'], }, zhipu: { functionCallKeywords: ['glm-4', 'glm-z1'], reasoningKeywords: ['glm-zero', 'glm-z1'], visionKeywords: ['glm-4v'], }, } as const; // 模型提供商关键词配置 export const PROVIDER_DETECTION_CONFIG = { anthropic: ['claude'], deepseek: ['deepseek'], google: ['gemini'], llama: ['llama'], openai: ['o1', 'o3', 'o4', 'gpt-'], qwen: ['qwen', 'qwq', 'qvq'], volcengine: ['doubao'], zeroone: ['yi-'], zhipu: ['glm'], } as const; /** * 检测单个模型的提供商类型 * @param modelId 模型ID * @returns 检测到的提供商配置键名,默认为 'openai' */ export const detectModelProvider = (modelId: string): keyof typeof MODEL_LIST_CONFIGS => { const lowerModelId = modelId.toLowerCase(); for (const [provider, keywords] of Object.entries(PROVIDER_DETECTION_CONFIG)) { const hasKeyword = keywords.some((keyword) => lowerModelId.includes(keyword)); if (hasKeyword && provider in MODEL_LIST_CONFIGS) { return provider as keyof typeof MODEL_LIST_CONFIGS; } } return 'openai'; }; /** * 处理模型卡片的通用逻辑 */ const processModelCard = ( model: { [key: string]: any; id: string }, config: ModelProcessorConfig, knownModel?: any, ): ChatModelCard => { const { functionCallKeywords = [], visionKeywords = [], reasoningKeywords = [], excludeKeywords = [], } = config; const isExcludedModel = excludeKeywords.some((keyword) => model.id.toLowerCase().includes(keyword), ); return { contextWindowTokens: model.contextWindowTokens ?? knownModel?.contextWindowTokens ?? undefined, displayName: model.displayName ?? knownModel?.displayName ?? model.id, enabled: knownModel?.enabled || false, functionCall: (functionCallKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) && !isExcludedModel) || knownModel?.abilities?.functionCall || false, id: model.id, maxOutput: model.maxOutput ?? knownModel?.maxOutput ?? undefined, reasoning: reasoningKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) || knownModel?.abilities?.reasoning || false, vision: (visionKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) && !isExcludedModel) || knownModel?.abilities?.vision || false, }; }; /** * 处理单一提供商的模型列表 * @param modelList 模型列表 * @param config 提供商配置 * @returns 处理后的模型卡片列表 */ export const processModelList = async ( modelList: Array<{ id: string }>, config: ModelProcessorConfig, ): Promise<ChatModelCard[]> => { const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); return modelList .map((model) => { const knownModel = LOBE_DEFAULT_MODEL_LIST.find( (m) => model.id.toLowerCase() === m.id.toLowerCase(), ); return processModelCard(model, config, knownModel); }) .filter(Boolean); }; /** * 处理混合提供商的模型列表 * @param modelList 模型列表 * @returns 处理后的模型卡片列表 */ export const processMultiProviderModelList = async ( modelList: Array<{ id: string }>, ): Promise<ChatModelCard[]> => { const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); return modelList .map((model) => { const detectedProvider = detectModelProvider(model.id); const config = MODEL_LIST_CONFIGS[detectedProvider]; const knownModel = LOBE_DEFAULT_MODEL_LIST.find( (m) => model.id.toLowerCase() === m.id.toLowerCase(), ); return processModelCard(model, config, knownModel); }) .filter(Boolean); };