@lobehub/chat 1.111.10 → 1.111.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.github/workflows/claude-code-review.yml +12 -12
  2. package/.github/workflows/claude.yml +9 -9
  3. package/.vscode/extensions.json +13 -0
  4. package/.vscode/settings.json +89 -0
  5. package/CHANGELOG.md +42 -0
  6. package/CLAUDE.md +117 -0
  7. package/changelog/v1.json +14 -0
  8. package/docs/development/state-management/state-management-intro.mdx +2 -2
  9. package/docs/development/state-management/state-management-intro.zh-CN.mdx +2 -2
  10. package/package.json +1 -1
  11. package/packages/model-runtime/src/RouterRuntime/createRuntime.ts +9 -1
  12. package/packages/model-runtime/src/ai302/index.ts +1 -1
  13. package/packages/model-runtime/src/aihubmix/index.ts +28 -71
  14. package/packages/model-runtime/src/anthropic/index.ts +6 -26
  15. package/packages/model-runtime/src/giteeai/index.ts +2 -37
  16. package/packages/model-runtime/src/github/index.ts +33 -44
  17. package/packages/model-runtime/src/modelscope/index.ts +2 -38
  18. package/packages/model-runtime/src/moonshot/index.ts +2 -36
  19. package/packages/model-runtime/src/novita/__snapshots__/index.test.ts.snap +40 -22
  20. package/packages/model-runtime/src/novita/index.ts +1 -32
  21. package/packages/model-runtime/src/nvidia/index.ts +1 -1
  22. package/packages/model-runtime/src/openai/__snapshots__/index.test.ts.snap +63 -7
  23. package/packages/model-runtime/src/openai/index.ts +1 -1
  24. package/packages/model-runtime/src/openrouter/__snapshots__/index.test.ts.snap +6 -21
  25. package/packages/model-runtime/src/openrouter/index.ts +29 -37
  26. package/packages/model-runtime/src/qiniu/index.ts +3 -27
  27. package/packages/model-runtime/src/qwen/index.ts +1 -1
  28. package/packages/model-runtime/src/siliconcloud/index.ts +1 -1
  29. package/packages/model-runtime/src/utils/modelParse.test.ts +6 -6
  30. package/packages/model-runtime/src/utils/modelParse.ts +238 -40
  31. package/packages/model-runtime/src/utils/openaiCompatibleFactory/index.test.ts +18 -0
  32. package/packages/model-runtime/src/utils/streams/openai/openai.ts +12 -0
  33. package/packages/model-runtime/src/v0/index.ts +2 -2
  34. package/packages/model-runtime/src/volcengine/index.ts +1 -1
  35. package/packages/model-runtime/src/xai/index.ts +2 -24
  36. package/packages/model-runtime/src/zhipu/index.ts +1 -1
  37. package/src/config/aiModels/aihubmix.ts +1 -9
  38. package/src/config/aiModels/anthropic.ts +24 -4
  39. package/src/config/aiModels/fal.ts +20 -3
  40. package/src/config/aiModels/google.ts +60 -6
  41. package/src/config/aiModels/groq.ts +4 -21
  42. package/src/config/aiModels/hunyuan.ts +1 -1
  43. package/src/config/aiModels/mistral.ts +22 -5
  44. package/src/config/aiModels/moonshot.ts +20 -0
  45. package/src/config/aiModels/openai.ts +0 -45
  46. package/src/config/aiModels/qwen.ts +113 -3
  47. package/src/config/aiModels/sensenova.ts +6 -6
  48. package/src/config/aiModels/siliconcloud.ts +80 -0
  49. package/src/config/aiModels/stepfun.ts +38 -4
  50. package/src/config/aiModels/zhipu.ts +33 -8
  51. package/src/config/modelProviders/aihubmix.ts +1 -1
  52. package/src/config/modelProviders/mistral.ts +1 -0
  53. package/src/config/modelProviders/openai.ts +1 -1
  54. package/src/config/modelProviders/qwen.ts +1 -1
  55. package/src/config/modelProviders/v0.ts +1 -0
  56. package/src/config/modelProviders/volcengine.ts +1 -0
  57. package/src/server/routers/async/image.ts +1 -0
  58. package/src/services/file/_deprecated.ts +1 -1
  59. package/src/store/file/slices/upload/action.ts +1 -1
@@ -4,309 +4,365 @@ exports[`LobeOpenAI > models > should get models 1`] = `
4
4
  [
5
5
  {
6
6
  "contextWindowTokens": undefined,
7
+ "description": "通用语音识别模型,支持多语言语音识别、语音翻译和语言识别。",
7
8
  "displayName": "Whisper",
8
9
  "enabled": false,
9
10
  "functionCall": false,
10
11
  "id": "whisper-1",
11
12
  "maxOutput": undefined,
12
13
  "reasoning": false,
14
+ "releasedAt": "2023-02-27",
13
15
  "type": "stt",
14
16
  "vision": false,
15
17
  },
16
18
  {
17
19
  "contextWindowTokens": undefined,
20
+ "description": "",
18
21
  "displayName": "davinci-002",
19
22
  "enabled": false,
20
23
  "functionCall": false,
21
24
  "id": "davinci-002",
22
25
  "maxOutput": undefined,
23
26
  "reasoning": false,
27
+ "releasedAt": "2023-08-21",
24
28
  "type": "chat",
25
29
  "vision": false,
26
30
  },
27
31
  {
28
- "contextWindowTokens": 16385,
32
+ "contextWindowTokens": 16384,
33
+ "description": "GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125",
29
34
  "displayName": "GPT-3.5 Turbo",
30
35
  "enabled": false,
31
36
  "functionCall": true,
32
37
  "id": "gpt-3.5-turbo",
33
38
  "maxOutput": undefined,
34
39
  "reasoning": false,
40
+ "releasedAt": "2023-02-28",
35
41
  "type": "chat",
36
42
  "vision": false,
37
43
  },
38
44
  {
39
45
  "contextWindowTokens": undefined,
46
+ "description": "第二代 DALL·E 模型,支持更真实、准确的图像生成,分辨率是第一代的4倍",
40
47
  "displayName": "DALL·E 2",
41
48
  "enabled": false,
42
49
  "functionCall": false,
43
50
  "id": "dall-e-2",
44
51
  "maxOutput": undefined,
45
52
  "reasoning": false,
53
+ "releasedAt": "2023-11-01",
46
54
  "type": "image",
47
55
  "vision": false,
48
56
  },
49
57
  {
50
58
  "contextWindowTokens": undefined,
59
+ "description": "",
51
60
  "displayName": "gpt-3.5-turbo-16k",
52
61
  "enabled": false,
53
62
  "functionCall": false,
54
63
  "id": "gpt-3.5-turbo-16k",
55
64
  "maxOutput": undefined,
56
65
  "reasoning": false,
66
+ "releasedAt": "2023-05-10",
57
67
  "type": "chat",
58
68
  "vision": false,
59
69
  },
60
70
  {
61
71
  "contextWindowTokens": undefined,
72
+ "description": "",
62
73
  "displayName": "tts-1-hd-1106",
63
74
  "enabled": false,
64
75
  "functionCall": false,
65
76
  "id": "tts-1-hd-1106",
66
77
  "maxOutput": undefined,
67
78
  "reasoning": false,
79
+ "releasedAt": "2023-11-03",
68
80
  "type": "chat",
69
81
  "vision": false,
70
82
  },
71
83
  {
72
84
  "contextWindowTokens": undefined,
85
+ "description": "最新的文本转语音模型,针对质量进行优化",
73
86
  "displayName": "TTS-1 HD",
74
87
  "enabled": false,
75
88
  "functionCall": false,
76
89
  "id": "tts-1-hd",
77
90
  "maxOutput": undefined,
78
91
  "reasoning": false,
92
+ "releasedAt": "2023-11-03",
79
93
  "type": "tts",
80
94
  "vision": false,
81
95
  },
82
96
  {
83
97
  "contextWindowTokens": undefined,
98
+ "description": "",
84
99
  "displayName": "gpt-3.5-turbo-16k-0613",
85
100
  "enabled": false,
86
101
  "functionCall": false,
87
102
  "id": "gpt-3.5-turbo-16k-0613",
88
103
  "maxOutput": undefined,
89
104
  "reasoning": false,
105
+ "releasedAt": "2023-05-30",
90
106
  "type": "chat",
91
107
  "vision": false,
92
108
  },
93
109
  {
94
110
  "contextWindowTokens": 8192,
111
+ "description": "最强大的向量化模型,适用于英文和非英文任务",
95
112
  "displayName": "Text Embedding 3 Large",
96
113
  "enabled": false,
97
114
  "functionCall": false,
98
115
  "id": "text-embedding-3-large",
99
116
  "maxOutput": undefined,
100
117
  "reasoning": false,
118
+ "releasedAt": "2024-01-22",
101
119
  "type": "embedding",
102
120
  "vision": false,
103
121
  },
104
122
  {
105
123
  "contextWindowTokens": undefined,
124
+ "description": "",
106
125
  "displayName": "gpt-4-1106-vision-preview",
107
126
  "enabled": false,
108
127
  "functionCall": false,
109
128
  "id": "gpt-4-1106-vision-preview",
110
129
  "maxOutput": undefined,
111
130
  "reasoning": false,
131
+ "releasedAt": "2024-03-26",
112
132
  "type": "chat",
113
133
  "vision": false,
114
134
  },
115
135
  {
116
136
  "contextWindowTokens": undefined,
137
+ "description": "",
117
138
  "displayName": "gpt-3.5-turbo-instruct-0914",
118
139
  "enabled": false,
119
140
  "functionCall": false,
120
141
  "id": "gpt-3.5-turbo-instruct-0914",
121
142
  "maxOutput": undefined,
122
143
  "reasoning": false,
144
+ "releasedAt": "2023-09-07",
123
145
  "type": "chat",
124
146
  "vision": false,
125
147
  },
126
148
  {
127
149
  "contextWindowTokens": 128000,
150
+ "description": "最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。",
128
151
  "displayName": "GPT-4 Turbo Preview 0125",
129
152
  "enabled": false,
130
153
  "functionCall": true,
131
154
  "id": "gpt-4-0125-preview",
132
155
  "maxOutput": undefined,
133
156
  "reasoning": false,
157
+ "releasedAt": "2024-01-23",
134
158
  "type": "chat",
135
159
  "vision": false,
136
160
  },
137
161
  {
138
162
  "contextWindowTokens": 128000,
163
+ "description": "最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。",
139
164
  "displayName": "GPT-4 Turbo Preview",
140
165
  "enabled": false,
141
166
  "functionCall": true,
142
167
  "id": "gpt-4-turbo-preview",
143
168
  "maxOutput": undefined,
144
169
  "reasoning": false,
170
+ "releasedAt": "2024-01-23",
145
171
  "type": "chat",
146
172
  "vision": false,
147
173
  },
148
174
  {
149
175
  "contextWindowTokens": 4096,
176
+ "description": "GPT 3.5 Turbo,适用于各种文本生成和理解任务,对指令遵循的优化",
150
177
  "displayName": "GPT-3.5 Turbo Instruct",
151
178
  "enabled": false,
152
179
  "functionCall": false,
153
180
  "id": "gpt-3.5-turbo-instruct",
154
181
  "maxOutput": undefined,
155
182
  "reasoning": false,
183
+ "releasedAt": "2023-08-24",
156
184
  "type": "chat",
157
185
  "vision": false,
158
186
  },
159
187
  {
160
188
  "contextWindowTokens": undefined,
189
+ "description": "",
161
190
  "displayName": "gpt-3.5-turbo-0301",
162
191
  "enabled": false,
163
192
  "functionCall": false,
164
193
  "id": "gpt-3.5-turbo-0301",
165
194
  "maxOutput": undefined,
166
195
  "reasoning": false,
196
+ "releasedAt": "2023-03-01",
167
197
  "type": "chat",
168
198
  "vision": false,
169
199
  },
170
200
  {
171
201
  "contextWindowTokens": undefined,
202
+ "description": "",
172
203
  "displayName": "gpt-3.5-turbo-0613",
173
204
  "enabled": false,
174
205
  "functionCall": false,
175
206
  "id": "gpt-3.5-turbo-0613",
176
207
  "maxOutput": undefined,
177
208
  "reasoning": false,
209
+ "releasedAt": "2023-06-12",
178
210
  "type": "chat",
179
211
  "vision": false,
180
212
  },
181
213
  {
182
214
  "contextWindowTokens": undefined,
215
+ "description": "最新的文本转语音模型,针对实时场景优化速度",
183
216
  "displayName": "TTS-1",
184
217
  "enabled": false,
185
218
  "functionCall": false,
186
219
  "id": "tts-1",
187
220
  "maxOutput": undefined,
188
221
  "reasoning": false,
222
+ "releasedAt": "2023-04-19",
189
223
  "type": "tts",
190
224
  "vision": false,
191
225
  },
192
226
  {
193
227
  "contextWindowTokens": undefined,
228
+ "description": "最新的 DALL·E 模型,于2023年11月发布。支持更真实、准确的图像生成,具有更强的细节表现力",
194
229
  "displayName": "DALL·E 3",
195
230
  "enabled": false,
196
231
  "functionCall": false,
197
232
  "id": "dall-e-3",
198
233
  "maxOutput": undefined,
199
234
  "reasoning": false,
235
+ "releasedAt": "2023-10-31",
200
236
  "type": "image",
201
237
  "vision": false,
202
238
  },
203
239
  {
204
- "contextWindowTokens": 16385,
240
+ "contextWindowTokens": 16384,
241
+ "description": "GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125",
205
242
  "displayName": "GPT-3.5 Turbo 1106",
206
243
  "enabled": false,
207
244
  "functionCall": true,
208
245
  "id": "gpt-3.5-turbo-1106",
209
246
  "maxOutput": undefined,
210
247
  "reasoning": false,
248
+ "releasedAt": "2023-11-02",
211
249
  "type": "chat",
212
250
  "vision": false,
213
251
  },
214
252
  {
215
253
  "contextWindowTokens": 128000,
254
+ "description": "最新的 GPT-4 Turbo 模型具备视觉功能。现在,视觉请求可以使用 JSON 模式和函数调用。 GPT-4 Turbo 是一个增强版本,为多模态任务提供成本效益高的支持。它在准确性和效率之间找到平衡,适合需要进行实时交互的应用程序场景。",
216
255
  "displayName": "GPT-4 Turbo Preview 1106",
217
256
  "enabled": false,
218
257
  "functionCall": true,
219
258
  "id": "gpt-4-1106-preview",
220
259
  "maxOutput": undefined,
221
260
  "reasoning": false,
261
+ "releasedAt": "2023-11-02",
222
262
  "type": "chat",
223
263
  "vision": false,
224
264
  },
225
265
  {
226
266
  "contextWindowTokens": undefined,
267
+ "description": "",
227
268
  "displayName": "babbage-002",
228
269
  "enabled": false,
229
270
  "functionCall": false,
230
271
  "id": "babbage-002",
231
272
  "maxOutput": undefined,
232
273
  "reasoning": false,
274
+ "releasedAt": "2023-08-21",
233
275
  "type": "chat",
234
276
  "vision": false,
235
277
  },
236
278
  {
237
279
  "contextWindowTokens": undefined,
280
+ "description": "",
238
281
  "displayName": "tts-1-1106",
239
282
  "enabled": false,
240
283
  "functionCall": false,
241
284
  "id": "tts-1-1106",
242
285
  "maxOutput": undefined,
243
286
  "reasoning": false,
287
+ "releasedAt": "2023-11-03",
244
288
  "type": "chat",
245
289
  "vision": false,
246
290
  },
247
291
  {
248
292
  "contextWindowTokens": 128000,
293
+ "description": "GPT-4 视觉预览版,专为图像分析和处理任务设计。",
249
294
  "displayName": "GPT 4 Turbo with Vision Preview",
250
295
  "enabled": false,
251
296
  "functionCall": false,
252
297
  "id": "gpt-4-vision-preview",
253
298
  "maxOutput": undefined,
254
299
  "reasoning": false,
300
+ "releasedAt": "2023-11-02",
255
301
  "type": "chat",
256
302
  "vision": true,
257
303
  },
258
304
  {
259
305
  "contextWindowTokens": 8192,
306
+ "description": "高效且经济的新一代 Embedding 模型,适用于知识检索、RAG 应用等场景",
260
307
  "displayName": "Text Embedding 3 Small",
261
308
  "enabled": false,
262
309
  "functionCall": false,
263
310
  "id": "text-embedding-3-small",
264
311
  "maxOutput": undefined,
265
312
  "reasoning": false,
313
+ "releasedAt": "2024-01-22",
266
314
  "type": "embedding",
267
315
  "vision": false,
268
316
  },
269
317
  {
270
- "contextWindowTokens": 128000,
271
- "displayName": "GPT 4 Turbo",
318
+ "contextWindowTokens": 8192,
319
+ "description": "GPT-4 提供了一个更大的上下文窗口,能够处理更长的文本输入,适用于需要广泛信息整合和数据分析的场景。",
320
+ "displayName": "GPT-4",
272
321
  "enabled": false,
273
322
  "functionCall": true,
274
323
  "id": "gpt-4",
275
- "maxOutput": 4096,
324
+ "maxOutput": undefined,
276
325
  "reasoning": false,
326
+ "releasedAt": "2023-06-27",
277
327
  "type": "chat",
278
- "vision": true,
328
+ "vision": false,
279
329
  },
280
330
  {
281
331
  "contextWindowTokens": undefined,
332
+ "description": "",
282
333
  "displayName": "text-embedding-ada-002",
283
334
  "enabled": false,
284
335
  "functionCall": false,
285
336
  "id": "text-embedding-ada-002",
286
337
  "maxOutput": undefined,
287
338
  "reasoning": false,
339
+ "releasedAt": "2022-12-16",
288
340
  "type": "chat",
289
341
  "vision": false,
290
342
  },
291
343
  {
292
- "contextWindowTokens": 16385,
344
+ "contextWindowTokens": 16384,
345
+ "description": "GPT 3.5 Turbo,适用于各种文本生成和理解任务,Currently points to gpt-3.5-turbo-0125",
293
346
  "displayName": "GPT-3.5 Turbo 0125",
294
347
  "enabled": false,
295
348
  "functionCall": true,
296
349
  "id": "gpt-3.5-turbo-0125",
297
350
  "maxOutput": undefined,
298
351
  "reasoning": false,
352
+ "releasedAt": "2024-01-23",
299
353
  "type": "chat",
300
354
  "vision": false,
301
355
  },
302
356
  {
303
357
  "contextWindowTokens": 8192,
358
+ "description": "GPT-4 提供了一个更大的上下文窗口,能够处理更长的文本输入,适用于需要广泛信息整合和数据分析的场景。",
304
359
  "displayName": "GPT-4 0613",
305
360
  "enabled": false,
306
361
  "functionCall": true,
307
362
  "id": "gpt-4-0613",
308
363
  "maxOutput": undefined,
309
364
  "reasoning": false,
365
+ "releasedAt": "2023-06-12",
310
366
  "type": "chat",
311
367
  "vision": false,
312
368
  },
@@ -55,7 +55,7 @@ export const LobeOpenAI = createOpenAICompatibleRuntime({
55
55
  const modelList: OpenAIModelCard[] = modelsPage.data;
56
56
 
57
57
  // 自动检测模型提供商并选择相应配置
58
- return processMultiProviderModelList(modelList);
58
+ return processMultiProviderModelList(modelList, 'openai');
59
59
  },
60
60
  provider: ModelProvider.OpenAI,
61
61
  responses: {
@@ -9,16 +9,11 @@ exports[`LobeOpenRouterAI > models > should get models with frontend models data
9
9
  The model was trained on synthetic data.
10
10
 
11
11
  _These are free, rate-limited endpoints for [Reflection 70B](/models/mattshumer/reflection-70b). Outputs may be cached. Read about rate limits [here](/docs/limits)._",
12
- "displayName": "Reflection 70B (free)",
12
+ "displayName": "Reflection 70B",
13
13
  "enabled": false,
14
14
  "functionCall": true,
15
15
  "id": "mattshumer/reflection-70b:free",
16
- "maxOutput": undefined,
17
- "maxTokens": 4096,
18
- "pricing": {
19
- "input": 0,
20
- "output": 0,
21
- },
16
+ "maxOutput": 4096,
22
17
  "reasoning": true,
23
18
  "releasedAt": "2024-09-06",
24
19
  "type": "chat",
@@ -36,16 +31,11 @@ exports[`LobeOpenRouterAI > models > should handle fetch error gracefully 1`] =
36
31
  The model was trained on synthetic data.
37
32
 
38
33
  _These are free, rate-limited endpoints for [Reflection 70B](/models/mattshumer/reflection-70b). Outputs may be cached. Read about rate limits [here](/docs/limits)._",
39
- "displayName": "Reflection 70B (free)",
34
+ "displayName": "Reflection 70B",
40
35
  "enabled": false,
41
36
  "functionCall": false,
42
37
  "id": "mattshumer/reflection-70b:free",
43
- "maxOutput": undefined,
44
- "maxTokens": 4096,
45
- "pricing": {
46
- "input": 0,
47
- "output": 0,
48
- },
38
+ "maxOutput": 4096,
49
39
  "reasoning": false,
50
40
  "releasedAt": "2024-09-06",
51
41
  "type": "chat",
@@ -63,16 +53,11 @@ exports[`LobeOpenRouterAI > models > should handle fetch failure gracefully 1`]
63
53
  The model was trained on synthetic data.
64
54
 
65
55
  _These are free, rate-limited endpoints for [Reflection 70B](/models/mattshumer/reflection-70b). Outputs may be cached. Read about rate limits [here](/docs/limits)._",
66
- "displayName": "Reflection 70B (free)",
56
+ "displayName": "Reflection 70B",
67
57
  "enabled": false,
68
58
  "functionCall": false,
69
59
  "id": "mattshumer/reflection-70b:free",
70
- "maxOutput": undefined,
71
- "maxTokens": 4096,
72
- "pricing": {
73
- "input": 0,
74
- "output": 0,
75
- },
60
+ "maxOutput": 4096,
76
61
  "reasoning": false,
77
62
  "releasedAt": "2024-09-06",
78
63
  "type": "chat",
@@ -1,5 +1,4 @@
1
1
  import OpenRouterModels from '@/config/aiModels/openrouter';
2
- import type { ChatModelCard } from '@/types/llm';
3
2
 
4
3
  import { ModelProvider } from '../types';
5
4
  import { processMultiProviderModelList } from '../utils/modelParse';
@@ -71,44 +70,37 @@ export const LobeOpenRouterAI = createOpenAICompatibleRuntime({
71
70
  console.error('Failed to fetch OpenRouter frontend models:', error);
72
71
  }
73
72
 
74
- // 解析模型能力
75
- const baseModels = await processMultiProviderModelList(modelList);
73
+ // 先处理抓取的模型信息,转换为标准格式
74
+ const formattedModels = modelList.map((model) => {
75
+ const extraInfo = modelsExtraInfo.find(
76
+ (m) => m.slug.toLowerCase() === model.id.toLowerCase(),
77
+ );
76
78
 
77
- // 合并 OpenRouter 获取的模型信息
78
- return baseModels
79
- .map((baseModel) => {
80
- const model = modelList.find((m) => m.id === baseModel.id);
81
- const extraInfo = modelsExtraInfo.find(
82
- (m) => m.slug.toLowerCase() === baseModel.id.toLowerCase(),
83
- );
84
-
85
- if (!model) return baseModel;
79
+ return {
80
+ contextWindowTokens: model.context_length,
81
+ description: model.description,
82
+ displayName: model.name,
83
+ functionCall:
84
+ model.description.includes('function calling') ||
85
+ model.description.includes('tools') ||
86
+ extraInfo?.endpoint?.supports_tool_parameters ||
87
+ false,
88
+ id: model.id,
89
+ maxOutput:
90
+ typeof model.top_provider.max_completion_tokens === 'number'
91
+ ? model.top_provider.max_completion_tokens
92
+ : undefined,
93
+ pricing: {
94
+ input: formatPrice(model.pricing.prompt),
95
+ output: formatPrice(model.pricing.completion),
96
+ },
97
+ reasoning: extraInfo?.endpoint?.supports_reasoning || false,
98
+ releasedAt: new Date(model.created * 1000).toISOString().split('T')[0],
99
+ vision: model.architecture.modality.includes('image') || false,
100
+ };
101
+ });
86
102
 
87
- return {
88
- ...baseModel,
89
- contextWindowTokens: model.context_length,
90
- description: model.description,
91
- displayName: model.name,
92
- functionCall:
93
- baseModel.functionCall ||
94
- model.description.includes('function calling') ||
95
- model.description.includes('tools') ||
96
- extraInfo?.endpoint?.supports_tool_parameters ||
97
- false,
98
- maxTokens:
99
- typeof model.top_provider.max_completion_tokens === 'number'
100
- ? model.top_provider.max_completion_tokens
101
- : undefined,
102
- pricing: {
103
- input: formatPrice(model.pricing.prompt),
104
- output: formatPrice(model.pricing.completion),
105
- },
106
- reasoning: baseModel.reasoning || extraInfo?.endpoint?.supports_reasoning || false,
107
- releasedAt: new Date(model.created * 1000).toISOString().split('T')[0],
108
- vision: baseModel.vision || model.architecture.modality.includes('image') || false,
109
- };
110
- })
111
- .filter(Boolean) as ChatModelCard[];
103
+ return await processMultiProviderModelList(formattedModels, 'openrouter');
112
104
  },
113
105
  provider: ModelProvider.OpenRouter,
114
106
  });
@@ -1,6 +1,5 @@
1
- import type { ChatModelCard } from '@/types/llm';
2
-
3
1
  import { ModelProvider } from '../types';
2
+ import { processMultiProviderModelList } from '../utils/modelParse';
4
3
  import { createOpenAICompatibleRuntime } from '../utils/openaiCompatibleFactory';
5
4
 
6
5
  export interface QiniuModelCard {
@@ -14,34 +13,11 @@ export const LobeQiniuAI = createOpenAICompatibleRuntime({
14
13
  chatCompletion: () => process.env.DEBUG_QINIU_CHAT_COMPLETION === '1',
15
14
  },
16
15
  models: async ({ client }) => {
17
- const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
18
- const { DEFAULT_MODEL_PROVIDER_LIST } = await import('@/config/modelProviders');
19
-
20
16
  const modelsPage = (await client.models.list()) as any;
21
17
  const modelList: QiniuModelCard[] = modelsPage.data;
22
18
 
23
- return modelList
24
- .map((model) => {
25
- const knownModelProvlder = DEFAULT_MODEL_PROVIDER_LIST.find(
26
- (mp) => mp.id.toLowerCase() === ModelProvider.Qiniu.toLowerCase(),
27
- );
28
-
29
- const knownModel = (knownModelProvlder?.chatModels ?? LOBE_DEFAULT_MODEL_LIST).find(
30
- (m) => model.id.toLowerCase() === m.id.toLowerCase(),
31
- );
32
-
33
- const abilities = knownModel && 'abilities' in knownModel ? knownModel.abilities : {};
34
- return {
35
- contextWindowTokens: knownModel?.contextWindowTokens ?? undefined,
36
- displayName: knownModel?.displayName ?? undefined,
37
- enabled: knownModel?.enabled || false,
38
- functionCall: abilities?.functionCall || false,
39
- id: model.id,
40
- reasoning: abilities?.reasoning || false,
41
- vision: abilities?.vision || false,
42
- };
43
- })
44
- .filter(Boolean) as ChatModelCard[];
19
+ // 自动检测模型提供商并选择相应配置
20
+ return processMultiProviderModelList(modelList, 'qiniu');
45
21
  },
46
22
  provider: ModelProvider.Qiniu,
47
23
  });
@@ -88,7 +88,7 @@ export const LobeQwenAI = createOpenAICompatibleRuntime({
88
88
  const modelsPage = (await client.models.list()) as any;
89
89
  const modelList: QwenModelCard[] = modelsPage.data;
90
90
 
91
- return processMultiProviderModelList(modelList);
91
+ return processMultiProviderModelList(modelList, 'qwen');
92
92
  },
93
93
  provider: ModelProvider.Qwen,
94
94
  });
@@ -71,7 +71,7 @@ export const LobeSiliconCloudAI = createOpenAICompatibleRuntime({
71
71
  const modelsPage = (await client.models.list()) as any;
72
72
  const modelList: SiliconCloudModelCard[] = modelsPage.data;
73
73
 
74
- return processMultiProviderModelList(modelList);
74
+ return processMultiProviderModelList(modelList, 'siliconcloud');
75
75
  },
76
76
  provider: ModelProvider.SiliconCloud,
77
77
  });
@@ -181,7 +181,7 @@ describe('modelParse', () => {
181
181
 
182
182
  const gpt4Result = result.find((m) => m.id === 'gpt-4')!;
183
183
  expect(gpt4Result.displayName).toBe('GPT-4');
184
- expect(gpt4Result.enabled).toBe(true);
184
+ expect(gpt4Result.enabled).toBe(false);
185
185
  expect(gpt4Result.contextWindowTokens).toBe(8192);
186
186
  expect(gpt4Result.maxOutput).toBe(4096);
187
187
  expect(gpt4Result.functionCall).toBe(false); // From knownModel.abilities
@@ -287,7 +287,7 @@ describe('modelParse', () => {
287
287
  { id: 'unknown-model-for-enabled-test' }, // unknown
288
288
  ];
289
289
  const result = await processModelList(modelList, config);
290
- expect(result.find((m) => m.id === 'gpt-4')!.enabled).toBe(true);
290
+ expect(result.find((m) => m.id === 'gpt-4')!.enabled).toBe(false);
291
291
  expect(result.find((m) => m.id === 'model-known-disabled')!.enabled).toBe(false);
292
292
  expect(result.find((m) => m.id === 'unknown-model-for-enabled-test')!.enabled).toBe(false);
293
293
  });
@@ -406,9 +406,9 @@ describe('modelParse', () => {
406
406
  expect(model.displayName).toBe('Test Claude Known Abilities');
407
407
  // 虽然 'claude' 是 anthropic 的 functionCall 和 vision 关键词,
408
408
  // 但是 knownModel.abilities.functionCall 和 knownModel.abilities.vision 是 false
409
- // 关键词匹配优先,所以应该是 true
410
- expect(model.functionCall).toBe(true); // 关键词 'claude' 匹配
411
- expect(model.vision).toBe(true); // 关键词 'claude' 匹配
409
+ // 本地模型配置优先,所以应该是 false
410
+ expect(model.functionCall).toBe(false); // knownModel.abilities.functionCall
411
+ expect(model.vision).toBe(false); // knownModel.abilities.vision
412
412
  expect(model.reasoning).toBe(true); // 从 knownModel.abilities.reasoning
413
413
  });
414
414
 
@@ -490,7 +490,7 @@ describe('modelParse', () => {
490
490
  expect(result[0].displayName).toBe('Direct Special Model'); // From model (priority)
491
491
  expect(result[0].contextWindowTokens).toBe(5000); // From model (priority)
492
492
  expect(result[0].maxOutput).toBe(2000); // From knownModel
493
- expect(result[0].enabled).toBe(true); // From knownModel
493
+ expect(result[0].enabled).toBe(false);
494
494
  });
495
495
 
496
496
  it('should correctly process reasoning capabilities based on keywords', async () => {