Skip to content

Commit ad517b3

Browse files
committed
Test
1 parent 2b59dad commit ad517b3

1 file changed

Lines changed: 1 addition & 287 deletions

File tree

src/utils/models.js

Lines changed: 1 addition & 287 deletions
Original file line numberDiff line numberDiff line change
@@ -1,287 +1 @@
1-
import CUSTOM_MODEL_PRESET from '@src/components/Header/CustomModelDrawer/preset';
2-
import { getSecretKey } from '@src/store/storage';
3-
import { getJsonDataFromLocalStorage, setJsonDataToLocalStorage } from '@src/utils/helpers';
4-
import { LOCAL_STORAGE_KEY } from '@src/utils/types';
5-
import { checkModelLimit, openAiCompatibleChat } from "./utils";
6-
7-
const modules = import.meta.glob('../assets/img/models/*.*', { eager: true });
8-
9-
const _iconCache = {};
10-
11-
let customModels = null;
12-
let normalizedCustomModel = null;
13-
14-
// 辅助函数:解析模型ID,提取 series、name 和 isPro 标志
15-
function parseModelId (id) {
16-
let isPro = false;
17-
let isVendorA = false;
18-
let fullName = id;
19-
if (id.startsWith('Pro/')) {
20-
isPro = true;
21-
fullName = id.replace('Pro/', '');
22-
}
23-
if (id.startsWith('Vendor-A/')) {
24-
isVendorA = true;
25-
fullName = id.replace('Vendor-A/', '');
26-
}
27-
const [series, ...nameParts] = fullName.split('/');
28-
const name = nameParts.join('/');
29-
return { series, name, isPro, isVendorA };
30-
}
31-
32-
const keywordsMap = {
33-
'Qwen': '阿里云,aliyun,通义千问',
34-
'THUDM': '智谱AI,智谱清言,BigModel,清华大学',
35-
'google': '谷歌,Brad',
36-
'meta-llama': 'Facebook',
37-
'internlm': '书生浦语大模型书生大模型,上海AI实验室,商汤科技,上海人工智能实验室香港中文大学和复旦大学',
38-
'mistralai': '法国欧洲',
39-
'deepseek-ai': '私募巨头幻方量化深度求索',
40-
'01-ai': '01万物零一万物李开复',
41-
'AIDC-AI': 'AIDC-AI,阿里云,CoT',
42-
'baidu': '百度,文心一言',
43-
'tencent': '腾讯,Hunyuan',
44-
'moonshotai': '月之暗面,Kimi',
45-
};
46-
47-
// 修改后的 textModelOf 函数,统一处理 "Pro/" 前缀
48-
const textModelOf = (id, price, length, needVerify, vision) => {
49-
const { series, name, isPro, isVendorA } = parseModelId(id);
50-
const icon = getModelIcon(id); // 使用原始id获取图标
51-
let keywords = keywordsMap[series];
52-
if (vision) {
53-
keywords += ',多模态,视觉,图像,VL,vision,image'
54-
}
55-
if (isVendorA) {
56-
keywords += ',Vendor-A,国产算力芯片'
57-
}
58-
const displayName = isPro ? `Pro/${name}` : isVendorA ? `Vendor-A/${name}` : name; // 根据 isPro 添加前缀
59-
return { id, name: displayName, series, price, length, icon, keywords, needVerify, isPro, isVendorA, vision };
60-
};
61-
62-
/**
63-
* 获取内置的自定义模型解析函数
64-
*/
65-
function getCustomModelResolveFn (modelConfig) {
66-
const model = CUSTOM_MODEL_PRESET.find(item => modelConfig.isOpenAiCompatible ? item.isOpenAiCompatible : item.id === modelConfig.id);
67-
// 在标准的函数入参之外,添加上用户配置的数据(内含 apiKey 等东西)
68-
return (...args) => model.resolveFn(modelConfig, ...args);
69-
}
70-
71-
const VISION_CUSTOM_MODELS = ['grok-vision-beta'];
72-
73-
export function getCustomModels () {
74-
if (!customModels) {
75-
customModels = getJsonDataFromLocalStorage(LOCAL_STORAGE_KEY.USER_CUSTOM_MODELS, []);
76-
normalizedCustomModel = customModels.map(item => {
77-
const resolveFn = (item.paramsMode || item.isOpenAiCompatible)
78-
? getCustomModelResolveFn(item)
79-
: new Function(`return ${item.resolveFn}`)();
80-
81-
// 拆分多个模型ID,并处理每个ID
82-
return item.ids.split(',').map(id => {
83-
const { series, name, isPro } = parseModelId(id);
84-
const icon = item.icon || getModelIcon(id); // 使用原始id获取图标
85-
const displayName = isPro ? `Pro/${name}` : name; // 根据 isPro 添加前缀
86-
const vision = VISION_CUSTOM_MODELS.includes(name) || item.vision;
87-
return ({
88-
...item,
89-
vision,
90-
keywords: item.keywords || keywordsMap[series],
91-
ids: void 0, // 移除原始ids字段
92-
id,
93-
series,
94-
name: displayName,
95-
resolveFn,
96-
icon,
97-
isCustom: true,
98-
isPro
99-
});
100-
});
101-
}).reduce((acc, cur) => [...acc, ...cur], []);
102-
}
103-
return { raw: customModels, normalized: normalizedCustomModel };
104-
}
105-
106-
export function setCustomModels (models) {
107-
setJsonDataToLocalStorage(LOCAL_STORAGE_KEY.USER_CUSTOM_MODELS, models);
108-
getCustomModels();
109-
}
110-
111-
// 修改 getModelIcon 函数,确保使用正确的 fullName 获取图标
112-
export function getModelIcon (model) {
113-
if (!_iconCache[model]) {
114-
const { series } = parseModelId(model);
115-
_iconCache[model] = modules[Object.keys(modules).find(i => i.includes(series))]?.default;
116-
if (!_iconCache[model]) {
117-
_iconCache[model] = '/logo.svg';
118-
}
119-
}
120-
return _iconCache[model];
121-
}
122-
123-
/**
124-
* 关于模型顺序:
125-
* 1. 免费模型在前
126-
* 2. 免费模型中,尽量根据模型能力排序,最新最强的在前
127-
* 3. 中文模型应排在英文模型前面
128-
* 4. Pro 开头的模型为免费模型的付费版本,优先级最低
129-
* 5. 新增模型请参考上述规则
130-
*/
131-
const SILICON_MODELS = [
132-
textModelOf("baidu/ERNIE-4.5-300B-A47B", 8, 128, false),
133-
textModelOf("tencent/Hunyuan-A13B-Instruct", 4, 128, false),
134-
textModelOf("moonshotai/Kimi-Dev-72B", 8, 128, false),
135-
textModelOf("MiniMaxAI/MiniMax-M1-80k", 16, 128, false),
136-
textModelOf("Tongyi-Zhiwen/QwenLong-L1-32B", 4, 128, false),
137-
textModelOf("Qwen/Qwen3-235B-A22B", 10, 128, false),
138-
textModelOf("Qwen/Qwen3-30B-A3B", 2.8, 128, false),
139-
textModelOf("Qwen/Qwen3-32B", 4, 128, false),
140-
textModelOf("Qwen/Qwen3-14B", 2, 128, false),
141-
textModelOf("THUDM/GLM-Z1-32B-0414", 0.5, 32, false),
142-
textModelOf("THUDM/GLM-4-32B-0414", 0.5, 32, false),
143-
textModelOf("THUDM/GLM-Z1-9B-0414", 0, 32, false),
144-
textModelOf("THUDM/GLM-4.1V-9B-Thinking", 0, 64, false),
145-
textModelOf("THUDM/GLM-4-9B-0414", 0, 32, false),
146-
textModelOf("Qwen/Qwen2.5-7B-Instruct", 0, 32, false),
147-
textModelOf("deepseek-ai/DeepSeek-R1-Distill-Llama-8B", 0, 32, false, false),
148-
textModelOf("deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", 0, 32, false, false),
149-
textModelOf("deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B", 0, 32, false, false),
150-
// textModelOf("AIDC-AI/Marco-o1", 0, 32, false),
151-
textModelOf("THUDM/glm-4-9b-chat", 0, 128, false),
152-
textModelOf("internlm/internlm2_5-7b-chat", 0, 32, false),
153-
textModelOf("Qwen/Qwen2.5-Coder-7B-Instruct", 0, 32, false),
154-
textModelOf("Qwen/Qwen2-7B-Instruct", 0, 32, false),
155-
textModelOf("THUDM/chatglm3-6b", 0, 32, false),
156-
textModelOf("Qwen/Qwen2-1.5B-Instruct", 0, 32, false),
157-
textModelOf("meta-llama/Meta-Llama-3.1-8B-Instruct", 0, 32, true),
158-
// textModelOf("meta-llama/Meta-Llama-3-8B-Instruct", 0, 8, true),
159-
textModelOf("deepseek-ai/DeepSeek-R1", 16, 64, false, false),
160-
textModelOf("deepseek-ai/DeepSeek-V3", 8, 64, false, false),
161-
textModelOf("Pro/deepseek-ai/DeepSeek-R1", 16, 64, false, false),
162-
textModelOf("Pro/deepseek-ai/DeepSeek-V3", 8, 64, false, false),
163-
textModelOf("Pro/deepseek-ai/DeepSeek-R1-Distill-Llama-8B", 0.42, 32, false, false),
164-
textModelOf("Pro/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", 0.35, 32, false, false),
165-
textModelOf("Pro/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B", 0.14, 32, false, false),
166-
textModelOf("Qwen/QwQ-32B", 1.26, 32, false, false),
167-
textModelOf("Qwen/QVQ-72B-Preview", 9.9, 32, false, true),
168-
// textModelOf("Tencent/Hunyuan-A52B-Instruct", 21, 32, false),
169-
textModelOf("Qwen/Qwen2.5-14B-Instruct", 0.7, 32, false),
170-
textModelOf("internlm/internlm2_5-20b-chat", 1, 32, false),
171-
textModelOf("Qwen/Qwen2.5-Coder-32B-Instruct", 1.26, 32, false),
172-
textModelOf("Qwen/Qwen2.5-32B-Instruct", 1.26, 32, false),
173-
// textModelOf("Qwen/Qwen2-57B-A14B-Instruct", 1.26, 32, false),
174-
textModelOf("deepseek-ai/DeepSeek-R1-Distill-Llama-70B", 4.13, 32, false, false),
175-
textModelOf("deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", 1.26, 32, false, false),
176-
textModelOf("deepseek-ai/DeepSeek-R1-Distill-Qwen-14B", 0.7, 32, false, false),
177-
178-
textModelOf("deepseek-ai/DeepSeek-V2.5", 1.33, 32, false),
179-
textModelOf("deepseek-ai/deepseek-vl2", 0.99, 4, false, true),
180-
// textModelOf("deepseek-ai/DeepSeek-Coder-V2-Instruct", 1.33, 32, false),
181-
textModelOf("deepseek-ai/DeepSeek-V2-Chat", 1.33, 32, false),
182-
// textModelOf("Qwen/Qwen2.5-Math-72B-Instruct", 4.13, 4, false),
183-
textModelOf("Qwen/Qwen2.5-72B-Instruct-128K", 4.13, 128, false),
184-
textModelOf("Qwen/Qwen2.5-72B-Instruct", 4.13, 32, false),
185-
// textModelOf("Qwen/Qwen2-72B-Instruct", 4.13, 32, false),
186-
// textModelOf("Vendor-A/Qwen/Qwen2.5-72B-Instruct", 1, 32, false),
187-
// textModelOf("Vendor-A/Qwen/Qwen2-72B-Instruct", 1, 32, false),
188-
// textModelOf("nvidia/Llama-3.1-Nemotron-70B-Instruct", 4.13, 32, true),
189-
textModelOf("meta-llama/Llama-3.3-70B-Instruct", 4.13, 32, true),
190-
textModelOf("meta-llama/Meta-Llama-3.1-70B-Instruct", 4.13, 32, true),
191-
// textModelOf("meta-llama/Meta-Llama-3-70B-Instruct", 4.13, 8, true),
192-
textModelOf("meta-llama/Meta-Llama-3.1-405B-Instruct", 21, 32, true),
193-
textModelOf("Qwen/Qwen2.5-VL-72B-Instruct", 4.13, 32, false, true),
194-
// textModelOf("Qwen/Qwen2.5-VL-32B-Instruct", 1.26, 32, false, true),
195-
textModelOf("Pro/Qwen/Qwen2.5-VL-7B-Instruct", 0.35, 32, false, true),
196-
textModelOf("Qwen/Qwen2-VL-72B-Instruct", 4.13, 32, false, true),
197-
textModelOf("OpenGVLab/InternVL2-26B", 1, 32, false, true),
198-
textModelOf("Pro/OpenGVLab/InternVL2-8B", 0.35, 32, false, true),
199-
textModelOf("Pro/Qwen/Qwen2-VL-7B-Instruct", 0.35, 32, false, true),
200-
textModelOf("OpenGVLab/InternVL2-Llama3-76B", 4.13, 8, false, true),
201-
textModelOf("Pro/Qwen/Qwen2-1.5B-Instruct", 0.14, 32, false),
202-
textModelOf("Pro/Qwen/Qwen2.5-7B-Instruct", 0.35, 32, false),
203-
// textModelOf("Pro/internlm/internlm2_5-7b-chat", 0.35, 32, false),
204-
textModelOf("Pro/Qwen/Qwen2-7B-Instruct", 0.35, 32, false),
205-
// textModelOf("Pro/THUDM/chatglm3-6b", 0.35, 32, false),
206-
textModelOf("Pro/THUDM/glm-4-9b-chat", 0.6, 128, false),
207-
textModelOf("Pro/THUDM/GLM-4.1V-9B-Thinking", 1, 64, false),
208-
textModelOf("Pro/meta-llama/Meta-Llama-3.1-8B-Instruct", 0.42, 32, true),
209-
// textModelOf("Pro/meta-llama/Meta-Llama-3-8B-Instruct", 0.42, 8, true),
210-
];
211-
212-
export function isMixedThinkingModel (modelId) {
213-
return modelId.includes('Qwen/Qwen3')
214-
}
215-
216-
export const SILICON_MODELS_IDS = SILICON_MODELS.map(item => item.id)
217-
218-
export const isSiliconModel = (modelId) => {
219-
return SILICON_MODELS.some(item => modelId === item.id)
220-
}
221-
222-
export function getAllTextModels () {
223-
return [
224-
...getCustomModels().normalized,
225-
...SILICON_MODELS
226-
];
227-
}
228-
229-
const _visionModelIds = getAllTextModels().filter(item => item.vision).map(item => item.id);
230-
231-
export function isVisionModel (modelId) {
232-
return _visionModelIds.includes(modelId)
233-
}
234-
235-
236-
const customResolveFns = getAllTextModels().filter(item => item.resolveFn).reduce((acc, item) => {
237-
acc[item.id] = item.resolveFn;
238-
return acc;
239-
}, {});
240-
241-
/**
242-
* 获取聊天解析器,根据模型ID选择合适的解析函数
243-
*/
244-
export function getChatResolver (modelId) {
245-
if (customResolveFns[modelId]) return customResolveFns[modelId];
246-
return (...args) => {
247-
// 硅基模型校验模型限制
248-
checkModelLimit(modelId);
249-
return openAiCompatibleChat('https://api.siliconflow.cn/v1', getSecretKey(), modelId => modelId, ...args);
250-
};
251-
}
252-
253-
254-
const imageModelOf = (id, price) => {
255-
const { series, name, isPro } = parseModelId(id);
256-
const icon = getModelIcon(id);
257-
const displayName = isPro ? `Pro/${name}` : name;
258-
return { id, name: displayName, series, price, icon, isPro };
259-
};
260-
261-
const IMAGE_MODELS = [
262-
imageModelOf("black-forest-labs/FLUX.1-dev", 1),
263-
imageModelOf("black-forest-labs/FLUX.1-schnell", 1),
264-
imageModelOf("stabilityai/stable-diffusion-3-5-large", -1),
265-
imageModelOf("stabilityai/stable-diffusion-xl-base-1.0", -1),
266-
// imageModelOf("stabilityai/stable-diffusion-2-1", -1),
267-
// 已弃模型
268-
// imageModelOf("stabilityai/stable-diffusion-3-medium", -1),
269-
// imageModelOf("stabilityai/sd-turbo", -1),
270-
// imageModelOf("stabilityai/sdxl-turbo", -1),
271-
// imageModelOf("ByteDance/SDXL-Lightning", -1),
272-
imageModelOf('Pro/black-forest-labs/FLUX.1-schnell', 1)
273-
];
274-
275-
/**
276-
* 判断体验密钥是否可用
277-
*/
278-
export function isLimitedModel (modelId) {
279-
const IMAGE_LIMITED_MODELS = IMAGE_MODELS.filter(item => item.price > 0).map(item => item.id);
280-
const TEXT_LIMITED_MODELS = SILICON_MODELS.filter(item => item.price > 0).map(item => item.id);
281-
return IMAGE_LIMITED_MODELS.includes(modelId) || TEXT_LIMITED_MODELS.includes(modelId);
282-
}
283-
284-
export function getImageModels () {
285-
return [...IMAGE_MODELS];
286-
}
287-
1+
Hello

0 commit comments

Comments
 (0)