@lobehub/lobehub 2.0.0-next.155 → 2.0.0-next.157

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 (35) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/package.json +4 -4
  4. package/packages/model-bank/src/aiModels/cerebras.ts +22 -48
  5. package/packages/model-bank/src/aiModels/infiniai.ts +62 -0
  6. package/packages/model-bank/src/aiModels/minimax.ts +23 -11
  7. package/packages/model-bank/src/aiModels/moonshot.ts +3 -24
  8. package/packages/model-bank/src/aiModels/openai.ts +0 -23
  9. package/packages/model-bank/src/aiModels/qwen.ts +26 -27
  10. package/packages/model-bank/src/aiModels/siliconcloud.ts +46 -0
  11. package/packages/model-bank/src/aiModels/spark.ts +17 -16
  12. package/packages/model-bank/src/aiModels/volcengine.ts +53 -0
  13. package/packages/model-bank/src/aiModels/wenxin.ts +49 -1
  14. package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +2 -2
  15. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +44 -2
  16. package/packages/model-runtime/src/providers/minimax/index.ts +1 -11
  17. package/packages/model-runtime/src/providers/spark/index.test.ts +12 -11
  18. package/packages/model-runtime/src/providers/spark/index.ts +19 -4
  19. package/packages/model-runtime/src/providers/volcengine/index.test.ts +0 -14
  20. package/packages/model-runtime/src/providers/volcengine/index.ts +1 -24
  21. package/packages/types/src/tool/builtin.ts +6 -6
  22. package/scripts/migrateServerDB/index.ts +10 -3
  23. package/src/config/modelProviders/spark.ts +0 -3
  24. package/src/config/modelProviders/volcengine.ts +2 -1
  25. package/src/store/aiInfra/store.ts +2 -2
  26. package/src/store/chat/store.ts +2 -2
  27. package/src/store/discover/store.ts +2 -2
  28. package/src/store/electron/store.ts +2 -2
  29. package/src/store/file/store.ts +2 -2
  30. package/src/store/global/store.ts +2 -2
  31. package/src/store/knowledgeBase/store.ts +2 -2
  32. package/src/store/serverConfig/store.ts +2 -2
  33. package/src/store/session/store.ts +2 -2
  34. package/src/store/tool/store.ts +2 -2
  35. package/src/store/user/store.ts +2 -2
@@ -3,22 +3,25 @@ import { AIChatModelCard } from '../types/aiModel';
3
3
  const sparkChatModels: AIChatModelCard[] = [
4
4
  {
5
5
  abilities: {
6
+ functionCall: true,
6
7
  reasoning: true,
7
8
  search: true,
8
9
  },
9
- contextWindowTokens: 32_768,
10
+ contextWindowTokens: 65_535,
10
11
  description:
11
- 'Spark X1 模型将进一步升级,在原来数学任务国内领先基础上,推理、文本生成、语言理解等通用任务实现效果对标 OpenAI o1 和 DeepSeek R1。',
12
- displayName: 'Spark X1',
13
- id: 'x1',
14
- maxOutput: 32_768,
12
+ 'X1.5能力介绍:(1)新增动态调整思考模式,通过thinking 字段控制;(2)上下文长度增大:输入、输出各64K;(3)支持FunctionCall功能。',
13
+ displayName: 'Spark X1.5',
14
+ enabled: true,
15
+ id: 'spark-x',
16
+ maxOutput: 65_535,
15
17
  settings: {
18
+ extendParams: ['thinking'],
16
19
  searchImpl: 'params',
17
20
  },
18
21
  type: 'chat',
19
22
  },
20
23
  {
21
- contextWindowTokens: 8192,
24
+ contextWindowTokens: 8192 + 4096,
22
25
  description:
23
26
  'Spark Lite 是一款轻量级大语言模型,具备极低的延迟与高效的处理能力,完全免费开放,支持实时在线搜索功能。其快速响应的特性使其在低算力设备上的推理应用和模型微调中表现出色,为用户带来出色的成本效益和智能体验,尤其在知识问答、内容生成及搜索场景下表现不俗。',
24
27
  displayName: 'Spark Lite',
@@ -31,11 +34,10 @@ const sparkChatModels: AIChatModelCard[] = [
31
34
  abilities: {
32
35
  search: true,
33
36
  },
34
- contextWindowTokens: 8192,
37
+ contextWindowTokens: 8192 + 8192,
35
38
  description:
36
39
  'Spark Pro 是一款为专业领域优化的高性能大语言模型,专注数学、编程、医疗、教育等多个领域,并支持联网搜索及内置天气、日期等插件。其优化后模型在复杂知识问答、语言理解及高层次文本创作中展现出色表现和高效性能,是适合专业应用场景的理想选择。',
37
40
  displayName: 'Spark Pro',
38
- enabled: true,
39
41
  id: 'generalv3',
40
42
  maxOutput: 8192,
41
43
  settings: {
@@ -49,7 +51,7 @@ const sparkChatModels: AIChatModelCard[] = [
49
51
  'Spark Pro 128K 配置了特大上下文处理能力,能够处理多达128K的上下文信息,特别适合需通篇分析和长期逻辑关联处理的长文内容,可在复杂文本沟通中提供流畅一致的逻辑与多样的引用支持。',
50
52
  displayName: 'Spark Pro 128K',
51
53
  id: 'pro-128k',
52
- maxOutput: 4096,
54
+ maxOutput: 131_072,
53
55
  type: 'chat',
54
56
  },
55
57
  {
@@ -57,11 +59,10 @@ const sparkChatModels: AIChatModelCard[] = [
57
59
  functionCall: true,
58
60
  search: true,
59
61
  },
60
- contextWindowTokens: 8192,
62
+ contextWindowTokens: 8192 + 8192,
61
63
  description:
62
64
  'Spark Max 为功能最为全面的版本,支持联网搜索及众多内置插件。其全面优化的核心能力以及系统角色设定和函数调用功能,使其在各种复杂应用场景中的表现极为优异和出色。',
63
65
  displayName: 'Spark Max',
64
- enabled: true,
65
66
  id: 'generalv3.5',
66
67
  maxOutput: 8192,
67
68
  settings: {
@@ -74,12 +75,12 @@ const sparkChatModels: AIChatModelCard[] = [
74
75
  functionCall: true,
75
76
  search: true,
76
77
  },
77
- contextWindowTokens: 32_768,
78
+ contextWindowTokens: 32_768 + 32_768,
78
79
  description:
79
80
  'Spark Max 32K 配置了大上下文处理能力,更强的上下文理解和逻辑推理能力,支持32K tokens的文本输入,适用于长文档阅读、私有知识问答等场景',
80
81
  displayName: 'Spark Max 32K',
81
82
  id: 'max-32k',
82
- maxOutput: 8192,
83
+ maxOutput: 32_768,
83
84
  settings: {
84
85
  searchImpl: 'internal',
85
86
  },
@@ -88,15 +89,15 @@ const sparkChatModels: AIChatModelCard[] = [
88
89
  {
89
90
  abilities: {
90
91
  functionCall: true,
92
+ reasoning: true,
91
93
  search: true,
92
94
  },
93
- contextWindowTokens: 8192,
95
+ contextWindowTokens: 32_768 + 32_768,
94
96
  description:
95
97
  'Spark Ultra 是星火大模型系列中最为强大的版本,在升级联网搜索链路同时,提升对文本内容的理解和总结能力。它是用于提升办公生产力和准确响应需求的全方位解决方案,是引领行业的智能产品。',
96
98
  displayName: 'Spark 4.0 Ultra',
97
- enabled: true,
98
99
  id: '4.0Ultra',
99
- maxOutput: 8192,
100
+ maxOutput: 32_768,
100
101
  settings: {
101
102
  searchImpl: 'params',
102
103
  },
@@ -3,6 +3,59 @@ import { AIChatModelCard, AIImageModelCard } from '../types/aiModel';
3
3
  // https://www.volcengine.com/docs/82379/1330310
4
4
 
5
5
  const doubaoChatModels: AIChatModelCard[] = [
6
+ {
7
+ abilities: {
8
+ functionCall: true,
9
+ reasoning: true,
10
+ vision: true,
11
+ },
12
+ config: {
13
+ deploymentName: 'doubao-seed-code-preview-251028',
14
+ },
15
+ contextWindowTokens: 256_000,
16
+ description:
17
+ 'Doubao-Seed-Code 面向 Agentic 编程任务进行了深度优化,支持多模态(文字/图片/视频)与 256k 长上下文,兼容 Anthropic API,适用于编程、视觉理解与 Agent 场景。',
18
+ displayName: 'Doubao Seed Code',
19
+ id: 'doubao-seed-code',
20
+ maxOutput: 32_000,
21
+ pricing: {
22
+ currency: 'CNY',
23
+ units: [
24
+ {
25
+ lookup: {
26
+ prices: {
27
+ '[0, 0.032]': 1.2,
28
+ '[0.032, 0.128]': 1.4,
29
+ '[0.128, 0.256]': 2.8,
30
+ },
31
+ pricingParams: ['textInputRange'],
32
+ },
33
+ name: 'textInput',
34
+ strategy: 'lookup',
35
+ unit: 'millionTokens',
36
+ },
37
+ {
38
+ lookup: {
39
+ prices: {
40
+ '[0, 0.032]': 8,
41
+ '[0.032, 0.128]': 12,
42
+ '[0.128, 0.256]': 16,
43
+ },
44
+ pricingParams: ['textInputRange'],
45
+ },
46
+ name: 'textOutput',
47
+ strategy: 'lookup',
48
+ unit: 'millionTokens',
49
+ },
50
+ { name: 'textInput_cacheRead', rate: 0.24, strategy: 'fixed', unit: 'millionTokens' },
51
+ { name: 'textInput_cacheWrite', rate: 0.017, strategy: 'fixed', unit: 'millionTokens' },
52
+ ],
53
+ },
54
+ settings: {
55
+ extendParams: ['enableReasoning'],
56
+ },
57
+ type: 'chat',
58
+ },
6
59
  {
7
60
  abilities: {
8
61
  functionCall: true,
@@ -3,6 +3,55 @@ import { AIChatModelCard, AIImageModelCard } from '../types/aiModel';
3
3
  // https://cloud.baidu.com/doc/qianfan/s/rmh4stp0j
4
4
 
5
5
  const wenxinChatModels: AIChatModelCard[] = [
6
+ {
7
+ abilities: {
8
+ functionCall: true,
9
+ reasoning: true,
10
+ search: true,
11
+ vision: true,
12
+ },
13
+ contextWindowTokens: 131_072,
14
+ description:
15
+ '文心5.0 Thinking,原生全模态旗舰模型,支持文本、图像、音频、视频统一建模,综合能力全面升级,适用于复杂问答、创作与智能体场景。',
16
+ displayName: 'ERNIE 5.0 Thinking',
17
+ enabled: true,
18
+ id: 'ernie-5.0-thinking-latest',
19
+ maxOutput: 65_536,
20
+ pricing: {
21
+ currency: 'CNY',
22
+ units: [
23
+ {
24
+ lookup: {
25
+ prices: {
26
+ '[0, 0.032]': 6,
27
+ '[0.032, 0.128]': 10,
28
+ },
29
+ pricingParams: ['textInput'],
30
+ },
31
+ name: 'textInput',
32
+ strategy: 'lookup',
33
+ unit: 'millionTokens',
34
+ },
35
+ {
36
+ lookup: {
37
+ prices: {
38
+ '[0, 0.032]': 24,
39
+ '[0.032, 0.128]': 40,
40
+ },
41
+ pricingParams: ['textInput'],
42
+ },
43
+ name: 'textOutput',
44
+ strategy: 'lookup',
45
+ unit: 'millionTokens',
46
+ },
47
+ ],
48
+ },
49
+ releasedAt: '2025-11-12',
50
+ settings: {
51
+ searchImpl: 'params',
52
+ },
53
+ type: 'chat',
54
+ },
6
55
  {
7
56
  abilities: {
8
57
  functionCall: true,
@@ -14,7 +63,6 @@ const wenxinChatModels: AIChatModelCard[] = [
14
63
  description:
15
64
  '文心5.0 Thinking 预览版,原生全模态旗舰模型,支持文本、图像、音频、视频统一建模,综合能力全面升级,适用于复杂问答、创作与智能体场景。',
16
65
  displayName: 'ERNIE 5.0 Thinking Preview',
17
- enabled: true,
18
66
  id: 'ernie-5.0-thinking-preview',
19
67
  maxOutput: 65_536,
20
68
  pricing: {
@@ -124,7 +124,7 @@ export interface CreateRouterRuntimeOptions<T extends Record<string, any> = any>
124
124
  export const createRouterRuntime = ({
125
125
  id,
126
126
  routers,
127
- apiKey: DEFAULT_API_LEY,
127
+ apiKey: DEFAULT_API_KEY,
128
128
  models: modelsOption,
129
129
  ...params
130
130
  }: CreateRouterRuntimeOptions) => {
@@ -137,7 +137,7 @@ export const createRouterRuntime = ({
137
137
  constructor(options: ClientOptions & Record<string, any> = {}) {
138
138
  this._options = {
139
139
  ...options,
140
- apiKey: options.apiKey?.trim() || DEFAULT_API_LEY,
140
+ apiKey: options.apiKey?.trim() || DEFAULT_API_KEY,
141
141
  baseURL: options.baseURL?.trim(),
142
142
  };
143
143
 
@@ -154,7 +154,7 @@ export interface OpenAICompatibleFactoryOptions<T extends Record<string, any> =
154
154
  export const createOpenAICompatibleRuntime = <T extends Record<string, any> = any>({
155
155
  provider,
156
156
  baseURL: DEFAULT_BASE_URL,
157
- apiKey: DEFAULT_API_LEY,
157
+ apiKey: DEFAULT_API_KEY,
158
158
  errorType,
159
159
  debug: debugParams,
160
160
  constructorOptions,
@@ -182,7 +182,7 @@ export const createOpenAICompatibleRuntime = <T extends Record<string, any> = an
182
182
  constructor(options: ClientOptions & Record<string, any> = {}) {
183
183
  const _options = {
184
184
  ...options,
185
- apiKey: options.apiKey?.trim() || DEFAULT_API_LEY,
185
+ apiKey: options.apiKey?.trim() || DEFAULT_API_KEY,
186
186
  baseURL: options.baseURL?.trim() || DEFAULT_BASE_URL,
187
187
  };
188
188
  const { apiKey, baseURL = DEFAULT_BASE_URL, ...res } = _options;
@@ -346,6 +346,48 @@ export const createOpenAICompatibleRuntime = <T extends Record<string, any> = an
346
346
  return this.handleResponseAPIMode(processedPayload, options);
347
347
  }
348
348
 
349
+ const computedBaseURL =
350
+ typeof this._options.baseURL === 'string' && this._options.baseURL
351
+ ? this._options.baseURL.trim()
352
+ : typeof DEFAULT_BASE_URL === 'string'
353
+ ? DEFAULT_BASE_URL
354
+ : undefined;
355
+ const targetBaseURL = computedBaseURL || this.baseURL;
356
+
357
+ if (targetBaseURL !== this.baseURL) {
358
+ const restOptions = {
359
+ ...(this._options as ConstructorOptions<T> & Record<string, any>),
360
+ } as Record<string, any>;
361
+ const optionApiKey = restOptions.apiKey;
362
+ delete restOptions.apiKey;
363
+ delete restOptions.baseURL;
364
+
365
+ const sanitizedApiKey = optionApiKey?.toString().trim() || DEFAULT_API_KEY;
366
+
367
+ const nextOptions = {
368
+ ...restOptions,
369
+ apiKey: sanitizedApiKey,
370
+ baseURL: targetBaseURL,
371
+ } as ConstructorOptions<T>;
372
+
373
+ const initOptions = {
374
+ apiKey: sanitizedApiKey,
375
+ baseURL: targetBaseURL,
376
+ ...constructorOptions,
377
+ ...restOptions,
378
+ } as ConstructorOptions<T> & Record<string, any>;
379
+
380
+ this._options = nextOptions;
381
+
382
+ if (customClient?.createClient) {
383
+ this.client = customClient.createClient(initOptions);
384
+ } else {
385
+ this.client = new OpenAI(initOptions);
386
+ }
387
+
388
+ this.baseURL = targetBaseURL;
389
+ }
390
+
349
391
  const messages = await convertOpenAIMessages(postPayload.messages);
350
392
 
351
393
  let response: Stream<OpenAI.Chat.Completions.ChatCompletionChunk>;
@@ -13,16 +13,7 @@ export const LobeMinimaxAI = createOpenAICompatibleRuntime({
13
13
  baseURL: 'https://api.minimaxi.com/v1',
14
14
  chatCompletion: {
15
15
  handlePayload: (payload) => {
16
- const { enabledSearch, max_tokens, messages, temperature, tools, top_p, ...params } = payload;
17
-
18
- const minimaxTools = enabledSearch
19
- ? [
20
- ...(tools || []),
21
- {
22
- type: 'web_search',
23
- },
24
- ]
25
- : tools;
16
+ const { enabledSearch, max_tokens, messages, temperature, top_p, ...params } = payload;
26
17
 
27
18
  // Interleaved thinking
28
19
  const processedMessages = messages.map((message: any) => {
@@ -77,7 +68,6 @@ export const LobeMinimaxAI = createOpenAICompatibleRuntime({
77
68
  messages: processedMessages,
78
69
  reasoning_split: true,
79
70
  temperature: finalTemperature,
80
- tools: minimaxTools,
81
71
  top_p: resolvedParams.top_p,
82
72
  } as any;
83
73
  },
@@ -16,6 +16,7 @@ testProvider({
16
16
  chatModel: 'spark',
17
17
  test: {
18
18
  skipAPICall: true,
19
+ skipErrorHandle: true,
19
20
  },
20
21
  });
21
22
 
@@ -69,7 +70,7 @@ describe('LobeSparkAI - custom features', () => {
69
70
  enabledSearch: false,
70
71
  };
71
72
 
72
- const result = handlePayload(payload);
73
+ const result = handlePayload(payload, {});
73
74
 
74
75
  expect(result.tools).toBeUndefined();
75
76
  expect(result.enabledSearch).toBeUndefined();
@@ -81,7 +82,7 @@ describe('LobeSparkAI - custom features', () => {
81
82
  messages: [{ role: 'user' as const, content: 'Hello' }],
82
83
  };
83
84
 
84
- const result = handlePayload(payload);
85
+ const result = handlePayload(payload, {});
85
86
 
86
87
  expect(result.tools).toBeUndefined();
87
88
  });
@@ -93,7 +94,7 @@ describe('LobeSparkAI - custom features', () => {
93
94
  enabledSearch: true,
94
95
  };
95
96
 
96
- const result = handlePayload(payload);
97
+ const result = handlePayload(payload, {});
97
98
 
98
99
  expect(result.tools).toBeDefined();
99
100
  expect(result.tools).toHaveLength(1);
@@ -115,7 +116,7 @@ describe('LobeSparkAI - custom features', () => {
115
116
  enabledSearch: true,
116
117
  };
117
118
 
118
- const result = handlePayload(payload);
119
+ const result = handlePayload(payload, {});
119
120
 
120
121
  expect(result.tools[0].web_search.search_mode).toBe('normal');
121
122
  });
@@ -129,7 +130,7 @@ describe('LobeSparkAI - custom features', () => {
129
130
  enabledSearch: true,
130
131
  };
131
132
 
132
- const result = handlePayload(payload);
133
+ const result = handlePayload(payload, {});
133
134
 
134
135
  expect(result.tools[0].web_search.search_mode).toBe('deep');
135
136
  delete process.env.SPARK_SEARCH_MODE;
@@ -154,7 +155,7 @@ describe('LobeSparkAI - custom features', () => {
154
155
  tools: existingTools,
155
156
  };
156
157
 
157
- const result = handlePayload(payload);
158
+ const result = handlePayload(payload, {});
158
159
 
159
160
  expect(result.tools).toHaveLength(2);
160
161
  expect(result.tools[0]).toEqual(existingTools[0]);
@@ -180,7 +181,7 @@ describe('LobeSparkAI - custom features', () => {
180
181
  tools: existingTools,
181
182
  };
182
183
 
183
- const result = handlePayload(payload);
184
+ const result = handlePayload(payload, {});
184
185
 
185
186
  expect(result.tools).toEqual(existingTools);
186
187
  });
@@ -192,7 +193,7 @@ describe('LobeSparkAI - custom features', () => {
192
193
  enabledSearch: true,
193
194
  };
194
195
 
195
- const result = handlePayload(payload);
196
+ const result = handlePayload(payload, {});
196
197
 
197
198
  expect(result.enabledSearch).toBeUndefined();
198
199
  });
@@ -207,7 +208,7 @@ describe('LobeSparkAI - custom features', () => {
207
208
  enabledSearch: true,
208
209
  };
209
210
 
210
- const result = handlePayload(payload);
211
+ const result = handlePayload(payload, {});
211
212
 
212
213
  expect(result.model).toBe('spark');
213
214
  expect(result.messages).toEqual(payload.messages);
@@ -224,7 +225,7 @@ describe('LobeSparkAI - custom features', () => {
224
225
  tools: [],
225
226
  };
226
227
 
227
- const result = handlePayload(payload);
228
+ const result = handlePayload(payload, {});
228
229
 
229
230
  expect(result.tools).toHaveLength(1);
230
231
  expect(result.tools[0].type).toBe('web_search');
@@ -257,7 +258,7 @@ describe('LobeSparkAI - custom features', () => {
257
258
  tools: existingTools,
258
259
  };
259
260
 
260
- const result = handlePayload(payload);
261
+ const result = handlePayload(payload, {});
261
262
 
262
263
  expect(result.tools).toHaveLength(3);
263
264
  expect(result.tools[0]).toEqual(existingTools[0]);
@@ -7,11 +7,25 @@ import {
7
7
  import { SparkAIStream, transformSparkResponseToStream } from '../../core/streams';
8
8
  import { ChatStreamPayload } from '../../types';
9
9
 
10
+ const getBaseURLByModel = (model: string): string => {
11
+ if (model.includes('x1-preview')) {
12
+ return 'https://spark-api-open-preview.xf-yun.com/v2';
13
+ }
14
+ if (model.includes('spark-x')) {
15
+ return 'https://spark-api-open.xf-yun.com/v2';
16
+ }
17
+
18
+ return 'https://spark-api-open.xf-yun.com/v1';
19
+ };
20
+
10
21
  export const params = {
11
22
  baseURL: 'https://spark-api-open.xf-yun.com/v1',
12
23
  chatCompletion: {
13
- handlePayload: (payload: ChatStreamPayload) => {
14
- const { enabledSearch, tools, ...rest } = payload;
24
+ handlePayload: (payload: ChatStreamPayload, options) => {
25
+ const { enabledSearch, thinking, tools, ...rest } = payload;
26
+
27
+ const baseURL = getBaseURLByModel(payload.model);
28
+ if (options) options.baseURL = baseURL;
15
29
 
16
30
  const sparkTools = enabledSearch
17
31
  ? [
@@ -22,8 +36,8 @@ export const params = {
22
36
  enable: true,
23
37
  search_mode: process.env.SPARK_SEARCH_MODE || 'normal', // normal or deep
24
38
  /*
25
- show_ref_label: true,
26
- */
39
+ show_ref_label: true,
40
+ */
27
41
  },
28
42
  },
29
43
  ]
@@ -31,6 +45,7 @@ export const params = {
31
45
 
32
46
  return {
33
47
  ...rest,
48
+ thinking: { type: thinking?.type },
34
49
  tools: sparkTools,
35
50
  } as any;
36
51
  },
@@ -57,19 +57,5 @@ describe('LobeVolcengineAI - custom features', () => {
57
57
  const calledPayload = (instance['client'].chat.completions.create as any).mock.calls[0][0];
58
58
  expect(calledPayload.thinking).toEqual({ type: 'enabled' });
59
59
  });
60
-
61
- it('should not add thinking for non-thinking models', async () => {
62
- await instance.chat({
63
- messages: [{ content: 'Hello', role: 'user' }],
64
- model: 'doubao-pro-32k',
65
- thinking: {
66
- type: 'enabled',
67
- budget_tokens: 1000,
68
- },
69
- });
70
-
71
- const calledPayload = (instance['client'].chat.completions.create as any).mock.calls[0][0];
72
- expect(calledPayload.thinking).toBeUndefined();
73
- });
74
60
  });
75
61
  });
@@ -1,21 +1,8 @@
1
1
  import { ModelProvider } from 'model-bank';
2
2
 
3
3
  import { createOpenAICompatibleRuntime } from '../../core/openaiCompatibleFactory';
4
- import { MODEL_LIST_CONFIGS, processModelList } from '../../utils/modelParse';
5
4
  import { createVolcengineImage } from './createImage';
6
5
 
7
- const THINKING_MODELS = [
8
- 'thinking-vision-pro',
9
- 'thinking-pro-m',
10
- 'doubao-seed-1-6',
11
- 'doubao-1-5-ui-tars',
12
- 'deepseek-v3-1',
13
- ];
14
-
15
- export interface VolcengineModelCard {
16
- id: string;
17
- }
18
-
19
6
  export const LobeVolcengineAI = createOpenAICompatibleRuntime({
20
7
  baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
21
8
  chatCompletion: {
@@ -25,11 +12,7 @@ export const LobeVolcengineAI = createOpenAICompatibleRuntime({
25
12
  return {
26
13
  ...rest,
27
14
  model,
28
- ...(THINKING_MODELS.some((keyword) => model.toLowerCase().includes(keyword))
29
- ? {
30
- thinking: { type: thinking?.type },
31
- }
32
- : {}),
15
+ ...(thinking?.type && { thinking: { type: thinking.type } }),
33
16
  } as any;
34
17
  },
35
18
  },
@@ -37,11 +20,5 @@ export const LobeVolcengineAI = createOpenAICompatibleRuntime({
37
20
  debug: {
38
21
  chatCompletion: () => process.env.DEBUG_VOLCENGINE_CHAT_COMPLETION === '1',
39
22
  },
40
- models: async ({ client }) => {
41
- const modelsPage = (await client.models.list()) as any;
42
- const modelList: VolcengineModelCard[] = modelsPage.data;
43
-
44
- return processModelList(modelList, MODEL_LIST_CONFIGS.volcengine, 'volcengine');
45
- },
46
23
  provider: ModelProvider.Volcengine,
47
24
  });
@@ -8,22 +8,22 @@ interface Meta {
8
8
  /**
9
9
  * avatar
10
10
  * @desc Avatar of the plugin
11
- * @nameCN 头像
12
- * @descCN 插件的头像
11
+ * @nameEN Avatar
12
+ * @descEN Plugin avatar
13
13
  */
14
14
  avatar?: string;
15
15
  /**
16
16
  * description
17
17
  * @desc Description of the plugin
18
- * @nameCN 描述
19
- * @descCN 插件的描述
18
+ * @nameEN Description
19
+ * @descEN Plugin description
20
20
  */
21
21
  description?: string;
22
22
  /**
23
23
  * tags
24
24
  * @desc Tags of the plugin
25
- * @nameCN 标签
26
- * @descCN 插件的标签
25
+ * @nameEN Tags
26
+ * @descEN Plugin tags
27
27
  */
28
28
  tags?: string[];
29
29
  title: string;
@@ -1,4 +1,5 @@
1
1
  import * as dotenv from 'dotenv';
2
+ import dotenvExpand from 'dotenv-expand';
2
3
  import { migrate as neonMigrate } from 'drizzle-orm/neon-serverless/migrator';
3
4
  import { migrate as nodeMigrate } from 'drizzle-orm/node-postgres/migrator';
4
5
  import { join } from 'node:path';
@@ -6,9 +7,15 @@ import { join } from 'node:path';
6
7
  // @ts-ignore tsgo handle esm import cjs and compatibility issues
7
8
  import { DB_FAIL_INIT_HINT, DUPLICATE_EMAIL_HINT, PGVECTOR_HINT } from './errorHint';
8
9
 
9
- // Read the `.env` file if it exists, or a file specified by the
10
- // dotenv_config_path parameter that's passed to Node.js
11
- dotenv.config();
10
+ // Load environment variables in priority order:
11
+ // 1. .env (lowest priority)
12
+ // 2. .env.[env] (medium priority, overrides .env)
13
+ // 3. .env.[env].local (highest priority, overrides previous)
14
+ // Use dotenv-expand to support ${var} variable expansion
15
+ const env = process.env.NODE_ENV || 'development';
16
+ dotenvExpand.expand(dotenv.config()); // Load .env
17
+ dotenvExpand.expand(dotenv.config({ override: true, path: `.env.${env}` })); // Load .env.[env] and override
18
+ dotenvExpand.expand(dotenv.config({ override: true, path: `.env.${env}.local` })); // Load .env.[env].local and override
12
19
 
13
20
  const migrationsFolder = join(__dirname, '../../packages/database/migrations');
14
21
 
@@ -12,9 +12,6 @@ const Spark: ModelProviderCard = {
12
12
  name: 'Spark',
13
13
  settings: {
14
14
  disableBrowserRequest: true,
15
- proxyUrl: {
16
- placeholder: 'https://spark-api-open.xf-yun.com/v1',
17
- },
18
15
  responseAnimation: {
19
16
  speed: 2,
20
17
  text: 'smooth',
@@ -3,7 +3,7 @@ import { ModelProviderCard } from '@/types/llm';
3
3
  // ref https://www.volcengine.com/docs/82379/1330310
4
4
  const Doubao: ModelProviderCard = {
5
5
  chatModels: [],
6
- checkModel: 'doubao-1-5-lite-32k-250115',
6
+ checkModel: 'doubao-seed-1-6-flash-250828',
7
7
  description:
8
8
  '字节跳动推出的大模型服务的开发平台,提供功能丰富、安全以及具备价格竞争力的模型调用服务,同时提供模型数据、精调、推理、评测等端到端功能,全方位保障您的 AI 应用开发落地。',
9
9
  id: 'volcengine',
@@ -20,6 +20,7 @@ const Doubao: ModelProviderCard = {
20
20
  },
21
21
  sdkType: 'openai',
22
22
  showDeployName: true,
23
+ showModelFetcher: false,
23
24
  },
24
25
  url: 'https://www.volcengine.com/product/ark',
25
26
  };
@@ -7,7 +7,7 @@ import { AIProviderStoreState, initialState } from './initialState';
7
7
  import { AiModelAction, createAiModelSlice } from './slices/aiModel';
8
8
  import { AiProviderAction, createAiProviderSlice } from './slices/aiProvider';
9
9
 
10
- // =============== 聚合 createStoreFn ============ //
10
+ // =============== Aggregate createStoreFn ============ //
11
11
 
12
12
  export interface AiInfraStore extends AIProviderStoreState, AiProviderAction, AiModelAction {
13
13
  /* empty */
@@ -19,7 +19,7 @@ const createStore: StateCreator<AiInfraStore, [['zustand/devtools', never]]> = (
19
19
  ...createAiProviderSlice(...parameters),
20
20
  });
21
21
 
22
- // =============== 实装 useStore ============ //
22
+ // =============== Implement useStore ============ //
23
23
  const devtools = createDevtools('aiInfra');
24
24
 
25
25
  export const useAiInfraStore = createWithEqualityFn<AiInfraStore>()(devtools(createStore), shallow);
@@ -33,7 +33,7 @@ export interface ChatStoreAction
33
33
 
34
34
  export type ChatStore = ChatStoreAction & ChatStoreState;
35
35
 
36
- // =============== 聚合 createStoreFn ============ //
36
+ // =============== Aggregate createStoreFn ============ //
37
37
 
38
38
  const createStore: StateCreator<ChatStore, [['zustand/devtools', never]]> = (...params) => ({
39
39
  ...initialState,
@@ -53,7 +53,7 @@ const createStore: StateCreator<ChatStore, [['zustand/devtools', never]]> = (...
53
53
  // cloud
54
54
  });
55
55
 
56
- // =============== 实装 useStore ============ //
56
+ // =============== Implement useStore ============ //
57
57
  const devtools = createDevtools('chat');
58
58
 
59
59
  export const useChatStore = createWithEqualityFn<ChatStore>()(