@lobehub/lobehub 2.0.0-next.26 → 2.0.0-next.28

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 (73) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/package.json +1 -1
  4. package/packages/types/src/discover/mcp.ts +6 -0
  5. package/packages/types/src/plugins/mcp.ts +4 -1
  6. package/packages/types/src/topic/topic.ts +14 -0
  7. package/renovate.json +4 -30
  8. package/src/features/MCP/utils.test.ts +91 -0
  9. package/src/features/MCP/utils.ts +20 -2
  10. package/src/features/PluginStore/Content.tsx +2 -3
  11. package/src/features/PluginStore/McpList/index.tsx +6 -2
  12. package/src/server/routers/lambda/market/index.ts +4 -2
  13. package/src/server/routers/lambda/topic.ts +7 -1
  14. package/src/services/aiModel/index.test.ts +3 -3
  15. package/src/services/aiModel/index.ts +56 -2
  16. package/src/services/aiProvider/index.test.ts +2 -2
  17. package/src/services/aiProvider/index.ts +48 -2
  18. package/src/services/chatGroup/index.ts +66 -2
  19. package/src/services/export/index.ts +10 -2
  20. package/src/services/file/index.ts +61 -2
  21. package/src/services/import/index.ts +133 -2
  22. package/src/services/mcp.ts +40 -6
  23. package/src/services/message/index.ts +176 -2
  24. package/src/services/message/{__tests__/server.test.ts → server.test.ts} +3 -3
  25. package/src/services/plugin/index.test.ts +8 -0
  26. package/src/services/plugin/index.ts +53 -2
  27. package/src/services/session/index.test.ts +8 -0
  28. package/src/services/session/index.ts +145 -2
  29. package/src/services/thread/index.test.ts +8 -0
  30. package/src/services/thread/index.ts +38 -2
  31. package/src/services/topic/index.test.ts +8 -0
  32. package/src/services/topic/index.ts +76 -2
  33. package/src/services/user/index.test.ts +8 -0
  34. package/src/services/user/index.ts +53 -2
  35. package/src/store/aiInfra/slices/aiModel/action.test.ts +17 -9
  36. package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +4 -2
  37. package/src/store/chat/slices/topic/action.test.ts +1 -1
  38. package/src/store/chat/slices/topic/action.ts +1 -2
  39. package/src/store/chat/slices/topic/reducer.ts +1 -2
  40. package/src/store/file/slices/chat/action.ts +1 -4
  41. package/src/store/file/slices/fileManager/action.ts +2 -3
  42. package/src/store/session/slices/sessionGroup/action.test.ts +5 -5
  43. package/src/store/tool/slices/mcpStore/action.test.ts +95 -3
  44. package/src/store/tool/slices/mcpStore/action.ts +177 -53
  45. package/src/store/tool/slices/oldStore/initialState.ts +1 -2
  46. package/src/store/user/slices/common/action.test.ts +1 -1
  47. package/src/services/aiModel/server.test.ts +0 -122
  48. package/src/services/aiModel/server.ts +0 -51
  49. package/src/services/aiModel/type.ts +0 -32
  50. package/src/services/aiProvider/server.ts +0 -43
  51. package/src/services/aiProvider/type.ts +0 -27
  52. package/src/services/chatGroup/server.ts +0 -67
  53. package/src/services/chatGroup/type.ts +0 -22
  54. package/src/services/export/server.ts +0 -9
  55. package/src/services/export/type.ts +0 -5
  56. package/src/services/file/server.ts +0 -53
  57. package/src/services/file/type.ts +0 -13
  58. package/src/services/import/server.ts +0 -133
  59. package/src/services/import/type.ts +0 -17
  60. package/src/services/message/server.ts +0 -151
  61. package/src/services/message/type.ts +0 -55
  62. package/src/services/plugin/server.ts +0 -42
  63. package/src/services/plugin/type.ts +0 -23
  64. package/src/services/session/server.test.ts +0 -260
  65. package/src/services/session/server.ts +0 -125
  66. package/src/services/session/type.ts +0 -82
  67. package/src/services/thread/server.ts +0 -32
  68. package/src/services/thread/type.ts +0 -21
  69. package/src/services/topic/server.ts +0 -57
  70. package/src/services/topic/type.ts +0 -40
  71. package/src/services/user/server.test.ts +0 -149
  72. package/src/services/user/server.ts +0 -47
  73. package/src/services/user/type.ts +0 -21
@@ -1,19 +1,21 @@
1
1
  import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
2
2
  import { PluginItem, PluginListResponse } from '@lobehub/market-sdk';
3
3
  import { TRPCClientError } from '@trpc/client';
4
+ import debug from 'debug';
4
5
  import { produce } from 'immer';
5
6
  import { uniqBy } from 'lodash-es';
6
7
  import { gt, valid } from 'semver';
7
8
  import useSWR, { SWRResponse } from 'swr';
8
9
  import { StateCreator } from 'zustand/vanilla';
9
10
 
10
- import { CURRENT_VERSION } from '@/const/version';
11
+ import { CURRENT_VERSION, isDesktop } from '@lobechat/const';
11
12
  import { MCPErrorData } from '@/libs/mcp/types';
12
13
  import { discoverService } from '@/services/discover';
13
14
  import { mcpService } from '@/services/mcp';
14
15
  import { pluginService } from '@/services/plugin';
15
16
  import { globalHelpers } from '@/store/global/helpers';
16
17
  import { mcpStoreSelectors } from '@/store/tool/selectors';
18
+ import { McpConnectionType } from '@/types/discover';
17
19
  import {
18
20
  CheckMcpInstallResult,
19
21
  MCPErrorInfo,
@@ -28,8 +30,41 @@ import { setNamespace } from '@/utils/storeDebug';
28
30
  import { ToolStore } from '../../store';
29
31
  import { MCPStoreState } from './initialState';
30
32
 
33
+ const log = debug('lobe-mcp:store:action');
34
+
31
35
  const n = setNamespace('mcpStore');
32
36
 
37
+ const doesConfigSchemaRequireInput = (configSchema?: any) => {
38
+ if (!configSchema) return false;
39
+
40
+ const hasRequiredArray =
41
+ Array.isArray(configSchema.required) && configSchema.required.some(Boolean);
42
+
43
+ const hasRequiredProperty =
44
+ !!configSchema.properties &&
45
+ Object.values(configSchema.properties).some(
46
+ (property: any) => property && property.required === true,
47
+ );
48
+
49
+ return hasRequiredArray || hasRequiredProperty;
50
+ };
51
+
52
+ const toNonEmptyStringRecord = (input?: Record<string, any>) => {
53
+ if (!input) return undefined;
54
+
55
+ const entries = Object.entries(input).filter(
56
+ ([, value]) => value !== undefined && value !== null,
57
+ );
58
+
59
+ if (entries.length === 0) return undefined;
60
+
61
+ return entries.reduce<Record<string, string>>((acc, [key, value]) => {
62
+ acc[key] = typeof value === 'string' ? value : String(value);
63
+
64
+ return acc;
65
+ }, {});
66
+ };
67
+
33
68
  // 测试连接结果类型
34
69
  export interface TestMcpConnectionResult {
35
70
  error?: string;
@@ -101,6 +136,7 @@ export const createMCPPluginStoreSlice: StateCreator<
101
136
 
102
137
  installMCPPlugin: async (identifier, options = {}) => {
103
138
  const { resume = false, config, skipDepsCheck } = options;
139
+ const normalizedConfig = toNonEmptyStringRecord(config);
104
140
  let plugin = mcpStoreSelectors.getPluginById(identifier)(get());
105
141
 
106
142
  if (!plugin || !plugin.manifestUrl) {
@@ -149,12 +185,8 @@ export const createMCPPluginStoreSlice: StateCreator<
149
185
  }
150
186
 
151
187
  data = configInfo.manifest;
152
- connection = {
153
- ...configInfo.connection,
154
- config, // 合并用户提供的配置
155
- };
188
+ connection = configInfo.connection ? { ...configInfo.connection } : undefined;
156
189
  result = configInfo.checkResult;
157
- connection = configInfo.connection;
158
190
  } else {
159
191
  // 正常模式:从头开始安装
160
192
 
@@ -175,59 +207,137 @@ export const createMCPPluginStoreSlice: StateCreator<
175
207
  install: true,
176
208
  });
177
209
 
178
- // 步骤 2: 检查安装环境
179
- updateMCPInstallProgress(identifier, {
180
- progress: 30,
181
- step: MCPInstallStep.CHECKING_INSTALLATION,
210
+ const deploymentOptions: any[] = Array.isArray(data.deploymentOptions)
211
+ ? data.deploymentOptions
212
+ : [];
213
+
214
+ const httpOption = deploymentOptions.find(
215
+ (option) => option?.connection?.url && option?.connection?.type === 'http',
216
+ ) ||
217
+ deploymentOptions.find(
218
+ (option) => option?.connection?.url && !option?.connection?.type,
219
+ );
220
+
221
+ const hasNonHttpDeployment = deploymentOptions.some((option) => {
222
+ const type = option?.connection?.type;
223
+ if (!type && option?.connection?.url) return false;
224
+
225
+ return type && type !== 'http';
182
226
  });
183
227
 
184
- // 检查是否已被取消
185
- if (abortController.signal.aborted) {
186
- return;
187
- }
228
+ const shouldUseHttpDeployment = !!httpOption && (!hasNonHttpDeployment || !isDesktop);
188
229
 
189
- result = await mcpService.checkInstallation(data, abortController.signal);
230
+ if (shouldUseHttpDeployment && httpOption) {
231
+ // ✅ HTTP 类型:跳过系统依赖检查,直接使用 URL
232
+ log('HTTP MCP detected, skipping system dependency check');
190
233
 
191
- if (!result.success) {
192
- updateMCPInstallProgress(identifier, undefined);
193
- return;
194
- }
234
+ connection = {
235
+ auth: httpOption.connection?.auth || { type: 'none' },
236
+ headers: httpOption.connection?.headers,
237
+ type: 'http',
238
+ url: httpOption.connection?.url,
239
+ };
240
+
241
+ log('Using HTTP connection: %O', { type: connection.type, url: connection.url });
195
242
 
196
- // 步骤 3: 检查系统依赖是否满足
197
- if (!skipDepsCheck && !result.allDependenciesMet) {
198
- // 依赖不满足,暂停安装流程并显示依赖安装引导
243
+ const configSchema = httpOption.connection?.configSchema;
244
+ const needsConfig = doesConfigSchemaRequireInput(configSchema);
245
+
246
+ if (needsConfig && !normalizedConfig) {
247
+ updateMCPInstallProgress(identifier, {
248
+ configSchema,
249
+ connection,
250
+ manifest: data,
251
+ needsConfig: true,
252
+ progress: 50,
253
+ step: MCPInstallStep.CONFIGURATION_REQUIRED,
254
+ });
255
+
256
+ updateInstallLoadingState(identifier, undefined);
257
+ return false;
258
+ }
259
+ } else {
260
+ // ❌ stdio 类型:需要完整的系统依赖检查流程
261
+
262
+ // 步骤 2: 检查安装环境
199
263
  updateMCPInstallProgress(identifier, {
200
- connection: result.connection,
201
- manifest: data,
202
- progress: 40,
203
- step: MCPInstallStep.DEPENDENCIES_REQUIRED,
204
- systemDependencies: result.systemDependencies,
264
+ progress: 30,
265
+ step: MCPInstallStep.CHECKING_INSTALLATION,
205
266
  });
206
267
 
207
- // 暂停安装流程,等待用户安装依赖
208
- updateInstallLoadingState(identifier, undefined);
209
- return false; // 返回 false 表示需要安装依赖
268
+ // 检查是否已被取消
269
+ if (abortController.signal.aborted) {
270
+ return;
271
+ }
272
+
273
+ result = await mcpService.checkInstallation(data, abortController.signal);
274
+
275
+ if (!result.success) {
276
+ updateMCPInstallProgress(identifier, undefined);
277
+ return;
278
+ }
279
+
280
+ // 步骤 3: 检查系统依赖是否满足
281
+ if (!skipDepsCheck && !result.allDependenciesMet) {
282
+ // 依赖不满足,暂停安装流程并显示依赖安装引导
283
+ updateMCPInstallProgress(identifier, {
284
+ connection: result.connection,
285
+ manifest: data,
286
+ progress: 40,
287
+ step: MCPInstallStep.DEPENDENCIES_REQUIRED,
288
+ systemDependencies: result.systemDependencies,
289
+ });
290
+
291
+ // 暂停安装流程,等待用户安装依赖
292
+ updateInstallLoadingState(identifier, undefined);
293
+ return false; // 返回 false 表示需要安装依赖
294
+ }
295
+
296
+ // 步骤 4: 检查是否需要配置
297
+ if (result.needsConfig) {
298
+ // 需要配置,暂停安装流程
299
+ updateMCPInstallProgress(identifier, {
300
+ checkResult: result,
301
+ configSchema: result.configSchema,
302
+ connection: result.connection,
303
+ manifest: data,
304
+ needsConfig: true,
305
+ progress: 50,
306
+ step: MCPInstallStep.CONFIGURATION_REQUIRED,
307
+ });
308
+
309
+ // 暂停安装流程,等待用户配置
310
+ updateInstallLoadingState(identifier, undefined);
311
+ return false; // 返回 false 表示需要配置
312
+ }
313
+
314
+ connection = result.connection;
210
315
  }
316
+ }
211
317
 
212
- // 步骤 4: 检查是否需要配置
213
- if (result.needsConfig) {
214
- // 需要配置,暂停安装流程
215
- updateMCPInstallProgress(identifier, {
216
- checkResult: result,
217
- configSchema: result.configSchema,
218
- connection: result.connection,
219
- manifest: data,
220
- needsConfig: true,
221
- progress: 50,
222
- step: MCPInstallStep.CONFIGURATION_REQUIRED,
223
- });
318
+ let mergedHttpHeaders: Record<string, string> | undefined;
319
+ let mergedStdioEnv: Record<string, string> | undefined;
320
+
321
+ if (connection?.type === 'http') {
322
+ const baseHeaders = toNonEmptyStringRecord(connection.headers);
224
323
 
225
- // 暂停安装流程,等待用户配置
226
- updateInstallLoadingState(identifier, undefined);
227
- return false; // 返回 false 表示需要配置
324
+ if (baseHeaders || normalizedConfig) {
325
+ mergedHttpHeaders = {
326
+ ...baseHeaders,
327
+ ...normalizedConfig,
328
+ };
228
329
  }
330
+ }
331
+
332
+ if (connection?.type === 'stdio') {
333
+ const baseEnv = toNonEmptyStringRecord(connection.env);
229
334
 
230
- connection = result.connection;
335
+ if (baseEnv || normalizedConfig) {
336
+ mergedStdioEnv = {
337
+ ...baseEnv,
338
+ ...normalizedConfig,
339
+ };
340
+ }
231
341
  }
232
342
 
233
343
  // 获取服务器清单逻辑
@@ -251,7 +361,7 @@ export const createMCPPluginStoreSlice: StateCreator<
251
361
  {
252
362
  args: connection.args,
253
363
  command: connection.command!,
254
- env: config,
364
+ env: mergedStdioEnv,
255
365
  name: identifier, // 将配置作为环境变量传递(resume 模式下)
256
366
  },
257
367
  { avatar: plugin.icon, description: plugin.description, name: data.name },
@@ -261,6 +371,8 @@ export const createMCPPluginStoreSlice: StateCreator<
261
371
  if (connection?.type === 'http') {
262
372
  manifest = await mcpService.getStreamableMcpServerManifest(
263
373
  {
374
+ auth: connection.auth,
375
+ headers: mergedHttpHeaders,
264
376
  identifier,
265
377
  metadata: {
266
378
  avatar: plugin.icon,
@@ -318,7 +430,7 @@ export const createMCPPluginStoreSlice: StateCreator<
318
430
  customParams: { mcp: connection },
319
431
  identifier: plugin.identifier,
320
432
  manifest: manifest,
321
- settings: config,
433
+ settings: normalizedConfig,
322
434
  type: 'plugin',
323
435
  });
324
436
 
@@ -347,7 +459,7 @@ export const createMCPPluginStoreSlice: StateCreator<
347
459
  resources: (manifest as any).resources,
348
460
  tools: (manifest as any).tools,
349
461
  },
350
- platform: result!.platform,
462
+ platform: result?.platform || process.platform,
351
463
  success: true,
352
464
  userAgent,
353
465
  version: manifest.version || data.version,
@@ -423,7 +535,7 @@ export const createMCPPluginStoreSlice: StateCreator<
423
535
  installDurationMs,
424
536
  installParams: connection,
425
537
  metadata: errorInfo.metadata,
426
- platform: result!.platform,
538
+ platform: result?.platform || process.platform,
427
539
  success: false,
428
540
  userAgent,
429
541
  version: data?.version,
@@ -581,10 +693,22 @@ export const createMCPPluginStoreSlice: StateCreator<
581
693
 
582
694
  useFetchMCPPluginList: (params) => {
583
695
  const locale = globalHelpers.getCurrentLanguage();
696
+ const requestParams = isDesktop ? params : { ...params, connectionType: McpConnectionType.http };
697
+ const swrKeyParts = [
698
+ 'useFetchMCPPluginList',
699
+ locale,
700
+ requestParams.page,
701
+ requestParams.pageSize,
702
+ requestParams.q,
703
+ requestParams.connectionType,
704
+ ];
705
+ const swrKey = swrKeyParts.filter((part) => part !== undefined && part !== null && part !== '')
706
+ .join('-');
707
+ const page = requestParams.page ?? 1;
584
708
 
585
709
  return useSWR<PluginListResponse>(
586
- ['useFetchMCPPluginList', locale, ...Object.values(params)].filter(Boolean).join('-'),
587
- () => discoverService.getMCPPluginList(params),
710
+ swrKey,
711
+ () => discoverService.getMCPPluginList(requestParams),
588
712
  {
589
713
  onSuccess(data) {
590
714
  set(
@@ -602,7 +726,7 @@ export const createMCPPluginStoreSlice: StateCreator<
602
726
  }
603
727
 
604
728
  // 累积数据逻辑
605
- if (params.page === 1) {
729
+ if (page === 1) {
606
730
  // 第一页,直接设置
607
731
  draft.mcpPluginItems = uniqBy(data.items, 'identifier');
608
732
  } else {
@@ -1,4 +1,3 @@
1
- import { isDesktop } from '@/const/version';
2
1
  import { DiscoverPluginItem } from '@/types/discover';
3
2
 
4
3
  export type PluginInstallLoadingMap = Record<string, boolean | undefined>;
@@ -47,7 +46,7 @@ export const initialPluginStoreState: PluginStoreState = {
47
46
  // Plugin list state management initial values
48
47
  currentPluginPage: 1,
49
48
  displayMode: 'grid',
50
- listType: isDesktop ? PluginStoreTabs.MCP : PluginStoreTabs.Plugin,
49
+ listType: PluginStoreTabs.MCP,
51
50
  oldPluginItems: [],
52
51
  pluginInstallLoading: {},
53
52
  pluginInstallProgress: {},
@@ -30,7 +30,7 @@ describe('createCommonSlice', () => {
30
30
  const avatar = 'data:image/png;base64,';
31
31
 
32
32
  const spyOn = vi.spyOn(result.current, 'refreshUserState');
33
- const updateAvatarSpy = vi.spyOn(userService, 'updateAvatar').mockResolvedValue(undefined);
33
+ const updateAvatarSpy = vi.spyOn(userService, 'updateAvatar').mockResolvedValue({} as any);
34
34
 
35
35
  await act(async () => {
36
36
  await result.current.updateAvatar(avatar);
@@ -1,122 +0,0 @@
1
- import { AiProviderModelListItem } from 'model-bank';
2
- import { describe, expect, it, vi } from 'vitest';
3
-
4
- import { lambdaClient } from '@/libs/trpc/client';
5
-
6
- import { ServerService } from './server';
7
-
8
- vi.mock('@/libs/trpc/client', () => ({
9
- lambdaClient: {
10
- aiModel: {
11
- createAiModel: { mutate: vi.fn() },
12
- getAiProviderModelList: { query: vi.fn() },
13
- getAiModelById: { query: vi.fn() },
14
- toggleModelEnabled: { mutate: vi.fn() },
15
- updateAiModel: { mutate: vi.fn() },
16
- batchUpdateAiModels: { mutate: vi.fn() },
17
- batchToggleAiModels: { mutate: vi.fn() },
18
- clearModelsByProvider: { mutate: vi.fn() },
19
- clearRemoteModels: { mutate: vi.fn() },
20
- updateAiModelOrder: { mutate: vi.fn() },
21
- removeAiModel: { mutate: vi.fn() },
22
- },
23
- },
24
- }));
25
-
26
- describe('ServerService', () => {
27
- const service = new ServerService();
28
-
29
- it('should create AI model', async () => {
30
- const params = {
31
- id: 'test-id',
32
- providerId: 'test-provider',
33
- displayName: 'Test Model',
34
- };
35
- await service.createAiModel(params);
36
- expect(vi.mocked(lambdaClient.aiModel.createAiModel.mutate)).toHaveBeenCalledWith(params);
37
- });
38
-
39
- it('should get AI provider model list', async () => {
40
- await service.getAiProviderModelList('123');
41
- expect(vi.mocked(lambdaClient.aiModel.getAiProviderModelList.query)).toHaveBeenCalledWith({
42
- id: '123',
43
- });
44
- });
45
-
46
- it('should get AI model by id', async () => {
47
- await service.getAiModelById('123');
48
- expect(vi.mocked(lambdaClient.aiModel.getAiModelById.query)).toHaveBeenCalledWith({
49
- id: '123',
50
- });
51
- });
52
-
53
- it('should toggle model enabled', async () => {
54
- const params = { id: '123', providerId: 'test', enabled: true };
55
- await service.toggleModelEnabled(params);
56
- expect(vi.mocked(lambdaClient.aiModel.toggleModelEnabled.mutate)).toHaveBeenCalledWith(params);
57
- });
58
-
59
- it('should update AI model', async () => {
60
- const value = { contextWindowTokens: 4000, displayName: 'Updated Model' };
61
- await service.updateAiModel('123', 'openai', value);
62
- expect(vi.mocked(lambdaClient.aiModel.updateAiModel.mutate)).toHaveBeenCalledWith({
63
- id: '123',
64
- providerId: 'openai',
65
- value,
66
- });
67
- });
68
-
69
- it('should batch update AI models', async () => {
70
- const models: AiProviderModelListItem[] = [
71
- {
72
- id: '123',
73
- enabled: true,
74
- type: 'chat',
75
- },
76
- ];
77
- await service.batchUpdateAiModels('provider1', models);
78
- expect(vi.mocked(lambdaClient.aiModel.batchUpdateAiModels.mutate)).toHaveBeenCalledWith({
79
- id: 'provider1',
80
- models,
81
- });
82
- });
83
-
84
- it('should batch toggle AI models', async () => {
85
- const models = ['123', '456'];
86
- await service.batchToggleAiModels('provider1', models, true);
87
- expect(vi.mocked(lambdaClient.aiModel.batchToggleAiModels.mutate)).toHaveBeenCalledWith({
88
- id: 'provider1',
89
- models,
90
- enabled: true,
91
- });
92
- });
93
-
94
- it('should clear models by provider', async () => {
95
- await service.clearModelsByProvider('provider1');
96
- expect(vi.mocked(lambdaClient.aiModel.clearModelsByProvider.mutate)).toHaveBeenCalledWith({
97
- providerId: 'provider1',
98
- });
99
- });
100
-
101
- it('should clear remote models', async () => {
102
- await service.clearRemoteModels('provider1');
103
- expect(vi.mocked(lambdaClient.aiModel.clearRemoteModels.mutate)).toHaveBeenCalledWith({
104
- providerId: 'provider1',
105
- });
106
- });
107
-
108
- it('should update AI model order', async () => {
109
- const items = [{ id: '123', sort: 1 }];
110
- await service.updateAiModelOrder('provider1', items);
111
- expect(vi.mocked(lambdaClient.aiModel.updateAiModelOrder.mutate)).toHaveBeenCalledWith({
112
- providerId: 'provider1',
113
- sortMap: items,
114
- });
115
- });
116
-
117
- it('should delete AI model', async () => {
118
- const params = { id: '123', providerId: 'openai' };
119
- await service.deleteAiModel(params);
120
- expect(vi.mocked(lambdaClient.aiModel.removeAiModel.mutate)).toHaveBeenCalledWith(params);
121
- });
122
- });
@@ -1,51 +0,0 @@
1
- import { lambdaClient } from '@/libs/trpc/client';
2
- import { IAiModelService } from '@/services/aiModel/type';
3
-
4
- export class ServerService implements IAiModelService {
5
- createAiModel: IAiModelService['createAiModel'] = async (params) => {
6
- return lambdaClient.aiModel.createAiModel.mutate(params);
7
- };
8
-
9
- getAiProviderModelList: IAiModelService['getAiProviderModelList'] = async (id) => {
10
- return lambdaClient.aiModel.getAiProviderModelList.query({ id });
11
- };
12
-
13
- getAiModelById: IAiModelService['getAiModelById'] = async (id) => {
14
- return lambdaClient.aiModel.getAiModelById.query({ id });
15
- };
16
-
17
- toggleModelEnabled: IAiModelService['toggleModelEnabled'] = async (params) => {
18
- return lambdaClient.aiModel.toggleModelEnabled.mutate(params);
19
- };
20
-
21
- updateAiModel: IAiModelService['updateAiModel'] = async (id, providerId, value) => {
22
- return lambdaClient.aiModel.updateAiModel.mutate({ id, providerId, value });
23
- };
24
-
25
- batchUpdateAiModels: IAiModelService['batchUpdateAiModels'] = async (id, models) => {
26
- return lambdaClient.aiModel.batchUpdateAiModels.mutate({ id, models });
27
- };
28
-
29
- batchToggleAiModels: IAiModelService['batchToggleAiModels'] = async (id, models, enabled) => {
30
- return lambdaClient.aiModel.batchToggleAiModels.mutate({ enabled, id, models });
31
- };
32
-
33
- clearModelsByProvider: IAiModelService['clearModelsByProvider'] = async (providerId) => {
34
- return lambdaClient.aiModel.clearModelsByProvider.mutate({ providerId });
35
- };
36
-
37
- clearRemoteModels: IAiModelService['clearRemoteModels'] = async (providerId) => {
38
- return lambdaClient.aiModel.clearRemoteModels.mutate({ providerId });
39
- };
40
-
41
- updateAiModelOrder: IAiModelService['updateAiModelOrder'] = async (providerId, items) => {
42
- return lambdaClient.aiModel.updateAiModelOrder.mutate({ providerId, sortMap: items });
43
- };
44
-
45
- deleteAiModel: IAiModelService['deleteAiModel'] = async (params: {
46
- id: string;
47
- providerId: string;
48
- }) => {
49
- return lambdaClient.aiModel.removeAiModel.mutate(params);
50
- };
51
- }
@@ -1,32 +0,0 @@
1
- /* eslint-disable typescript-sort-keys/interface */
2
- import {
3
- AiModelSortMap,
4
- AiProviderModelListItem,
5
- CreateAiModelParams,
6
- ToggleAiModelEnableParams,
7
- UpdateAiModelParams,
8
- } from 'model-bank';
9
-
10
- export interface IAiModelService {
11
- createAiModel: (params: CreateAiModelParams) => Promise<any>;
12
-
13
- getAiProviderModelList: (id: string) => Promise<AiProviderModelListItem[]>;
14
-
15
- getAiModelById: (id: string) => Promise<any>;
16
-
17
- toggleModelEnabled: (params: ToggleAiModelEnableParams) => Promise<any>;
18
-
19
- updateAiModel: (id: string, providerId: string, value: UpdateAiModelParams) => Promise<any>;
20
-
21
- batchUpdateAiModels: (id: string, models: AiProviderModelListItem[]) => Promise<any>;
22
-
23
- batchToggleAiModels: (id: string, models: string[], enabled: boolean) => Promise<any>;
24
-
25
- clearRemoteModels: (providerId: string) => Promise<any>;
26
-
27
- clearModelsByProvider: (providerId: string) => Promise<any>;
28
-
29
- updateAiModelOrder: (providerId: string, items: AiModelSortMap[]) => Promise<any>;
30
-
31
- deleteAiModel: (params: { id: string; providerId: string }) => Promise<any>;
32
- }
@@ -1,43 +0,0 @@
1
- import { lambdaClient } from '@/libs/trpc/client';
2
-
3
- import { IAiProviderService } from './type';
4
-
5
- export class ServerService implements IAiProviderService {
6
- createAiProvider: IAiProviderService['createAiProvider'] = async (params) => {
7
- return lambdaClient.aiProvider.createAiProvider.mutate(params);
8
- };
9
-
10
- getAiProviderList: IAiProviderService['getAiProviderList'] = async () => {
11
- return lambdaClient.aiProvider.getAiProviderList.query();
12
- };
13
-
14
- getAiProviderById: IAiProviderService['getAiProviderById'] = async (id) => {
15
- return lambdaClient.aiProvider.getAiProviderById.query({ id });
16
- };
17
-
18
- toggleProviderEnabled: IAiProviderService['toggleProviderEnabled'] = async (id, enabled) => {
19
- return lambdaClient.aiProvider.toggleProviderEnabled.mutate({ enabled, id });
20
- };
21
-
22
- updateAiProvider: IAiProviderService['updateAiProvider'] = async (id, value) => {
23
- return lambdaClient.aiProvider.updateAiProvider.mutate({ id, value });
24
- };
25
-
26
- updateAiProviderConfig: IAiProviderService['updateAiProviderConfig'] = async (id, value) => {
27
- return lambdaClient.aiProvider.updateAiProviderConfig.mutate({ id, value });
28
- };
29
-
30
- updateAiProviderOrder: IAiProviderService['updateAiProviderOrder'] = async (items) => {
31
- return lambdaClient.aiProvider.updateAiProviderOrder.mutate({ sortMap: items });
32
- };
33
-
34
- deleteAiProvider: IAiProviderService['deleteAiProvider'] = async (id) => {
35
- return lambdaClient.aiProvider.removeAiProvider.mutate({ id });
36
- };
37
-
38
- getAiProviderRuntimeState: IAiProviderService['getAiProviderRuntimeState'] = async (
39
- isLogin?: boolean,
40
- ) => {
41
- return lambdaClient.aiProvider.getAiProviderRuntimeState.query({ isLogin });
42
- };
43
- }
@@ -1,27 +0,0 @@
1
- import {
2
- AiProviderDetailItem,
3
- AiProviderRuntimeState,
4
- AiProviderSortMap,
5
- CreateAiProviderParams,
6
- UpdateAiProviderConfigParams,
7
- } from '@/types/aiProvider';
8
-
9
- export interface IAiProviderService {
10
- createAiProvider: (params: CreateAiProviderParams) => Promise<any>;
11
-
12
- deleteAiProvider: (id: string) => Promise<any>;
13
-
14
- getAiProviderById: (id: string) => Promise<AiProviderDetailItem | undefined>;
15
-
16
- getAiProviderList: () => Promise<any>;
17
-
18
- getAiProviderRuntimeState: (isLogin?: boolean) => Promise<AiProviderRuntimeState>;
19
-
20
- toggleProviderEnabled: (id: string, enabled: boolean) => Promise<any>;
21
-
22
- updateAiProvider: (id: string, value: any) => Promise<any>;
23
-
24
- updateAiProviderConfig: (id: string, value: UpdateAiProviderConfigParams) => Promise<any>;
25
-
26
- updateAiProviderOrder: (items: AiProviderSortMap[]) => Promise<any>;
27
- }