@lobehub/lobehub 2.0.0-next.156 → 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 (34) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/package.json +1 -1
  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/src/config/modelProviders/spark.ts +0 -3
  23. package/src/config/modelProviders/volcengine.ts +2 -1
  24. package/src/store/aiInfra/store.ts +2 -2
  25. package/src/store/chat/store.ts +2 -2
  26. package/src/store/discover/store.ts +2 -2
  27. package/src/store/electron/store.ts +2 -2
  28. package/src/store/file/store.ts +2 -2
  29. package/src/store/global/store.ts +2 -2
  30. package/src/store/knowledgeBase/store.ts +2 -2
  31. package/src/store/serverConfig/store.ts +2 -2
  32. package/src/store/session/store.ts +2 -2
  33. package/src/store/tool/store.ts +2 -2
  34. package/src/store/user/store.ts +2 -2
@@ -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;
@@ -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>()(
@@ -9,7 +9,7 @@ import { ModelAction, createModelSlice } from './slices/model/action';
9
9
  import { PluginAction, createPluginSlice } from './slices/plugin/action';
10
10
  import { ProviderAction, createProviderSlice } from './slices/provider/action';
11
11
 
12
- // =============== 聚合 createStoreFn ============ //
12
+ // =============== Aggregate createStoreFn ============ //
13
13
 
14
14
  export type DiscoverStore = MCPAction &
15
15
  AssistantAction &
@@ -27,7 +27,7 @@ const createStore: StateCreator<DiscoverStore, [['zustand/devtools', never]]> =
27
27
  ...createPluginSlice(...parameters),
28
28
  });
29
29
 
30
- // =============== 实装 useStore ============ //
30
+ // =============== Implement useStore ============ //
31
31
 
32
32
  const devtools = createDevtools('discover');
33
33
 
@@ -8,7 +8,7 @@ import { type ElectronSettingsAction, settingsSlice } from './actions/settings';
8
8
  import { type ElectronRemoteServerAction, remoteSyncSlice } from './actions/sync';
9
9
  import { type ElectronState, initialState } from './initialState';
10
10
 
11
- // =============== 聚合 createStoreFn ============ //
11
+ // =============== Aggregate createStoreFn ============ //
12
12
 
13
13
  export interface ElectronStore
14
14
  extends ElectronState,
@@ -27,7 +27,7 @@ const createStore: StateCreator<ElectronStore, [['zustand/devtools', never]]> =
27
27
  ...settingsSlice(...parameters),
28
28
  });
29
29
 
30
- // =============== 实装 useStore ============ //
30
+ // =============== Implement useStore ============ //
31
31
 
32
32
  const devtools = createDevtools('electron');
33
33
 
@@ -11,7 +11,7 @@ import { FileManageAction, createFileManageSlice } from './slices/fileManager';
11
11
  import { TTSFileAction, createTTSFileSlice } from './slices/tts';
12
12
  import { FileUploadAction, createFileUploadSlice } from './slices/upload/action';
13
13
 
14
- // =============== 聚合 createStoreFn ============ //
14
+ // =============== Aggregate createStoreFn ============ //
15
15
 
16
16
  export type FileStore = FilesStoreState &
17
17
  FileAction &
@@ -31,7 +31,7 @@ const createStore: StateCreator<FileStore, [['zustand/devtools', never]]> = (...
31
31
  ...createFileUploadSlice(...parameters),
32
32
  });
33
33
 
34
- // =============== 实装 useStore ============ //
34
+ // =============== Implement useStore ============ //
35
35
  const devtools = createDevtools('file');
36
36
 
37
37
  export const useFileStore = createWithEqualityFn<FileStore>()(devtools(createStore), shallow);
@@ -8,7 +8,7 @@ import { type GlobalGeneralAction, generalActionSlice } from './actions/general'
8
8
  import { type GlobalWorkspacePaneAction, globalWorkspaceSlice } from './actions/workspacePane';
9
9
  import { type GlobalState, initialState } from './initialState';
10
10
 
11
- // =============== 聚合 createStoreFn ============ //
11
+ // =============== Aggregate createStoreFn ============ //
12
12
 
13
13
  export interface GlobalStore extends GlobalState, GlobalWorkspacePaneAction, GlobalGeneralAction {
14
14
  /* empty */
@@ -20,7 +20,7 @@ const createStore: StateCreator<GlobalStore, [['zustand/devtools', never]]> = (.
20
20
  ...generalActionSlice(...parameters),
21
21
  });
22
22
 
23
- // =============== 实装 useStore ============ //
23
+ // =============== Implement useStore ============ //
24
24
 
25
25
  const devtools = createDevtools('global');
26
26
 
@@ -8,7 +8,7 @@ import { KnowledgeBaseContentAction, createContentSlice } from './slices/content
8
8
  import { KnowledgeBaseCrudAction, createCrudSlice } from './slices/crud';
9
9
  import { RAGEvalAction, createRagEvalSlice } from './slices/ragEval';
10
10
 
11
- // =============== 聚合 createStoreFn ============ //
11
+ // =============== Aggregate createStoreFn ============ //
12
12
 
13
13
  export interface KnowledgeBaseStore
14
14
  extends KnowledgeBaseStoreState,
@@ -27,7 +27,7 @@ const createStore: StateCreator<KnowledgeBaseStore, [['zustand/devtools', never]
27
27
  ...createRagEvalSlice(...parameters),
28
28
  });
29
29
 
30
- // =============== 实装 useStore ============ //
30
+ // =============== Implement useStore ============ //
31
31
  const devtools = createDevtools('knowledgeBase');
32
32
 
33
33
  export const useKnowledgeBaseStore = createWithEqualityFn<KnowledgeBaseStore>()(
@@ -31,7 +31,7 @@ const initialState: ServerConfigState = {
31
31
  serverConfigInit: false,
32
32
  };
33
33
 
34
- // =============== 聚合 createStoreFn ============ //
34
+ // =============== Aggregate createStoreFn ============ //
35
35
 
36
36
  export interface ServerConfigStore extends ServerConfigState, ServerConfigAction {}
37
37
 
@@ -46,7 +46,7 @@ const createStore: CreateStore =
46
46
  ...createServerConfigSlice(...params),
47
47
  });
48
48
 
49
- // =============== 实装 useStore ============ //
49
+ // =============== Implement useStore ============ //
50
50
 
51
51
  let store: StoreApi<ServerConfigStore>;
52
52