@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
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.28](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.27...v2.0.0-next.28)
6
+
7
+ <sup>Released on **2025-11-04**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: Support install sreamable http mcp server on web.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: Support install sreamable http mcp server on web, closes [#10044](https://github.com/lobehub/lobe-chat/issues/10044) [#9916](https://github.com/lobehub/lobe-chat/issues/9916) ([85454c5](https://github.com/lobehub/lobe-chat/commit/85454c5))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ## [Version 2.0.0-next.27](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.26...v2.0.0-next.27)
31
+
32
+ <sup>Released on **2025-11-04**</sup>
33
+
34
+ #### ♻ Code Refactoring
35
+
36
+ - **misc**: Refactor services to a more clean structure.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Code refactoring
44
+
45
+ - **misc**: Refactor services to a more clean structure, closes [#10050](https://github.com/lobehub/lobe-chat/issues/10050) ([de61dfa](https://github.com/lobehub/lobe-chat/commit/de61dfa))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ## [Version 2.0.0-next.26](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.25...v2.0.0-next.26)
6
56
 
7
57
  <sup>Released on **2025-11-04**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "features": [
5
+ "Support install sreamable http mcp server on web."
6
+ ]
7
+ },
8
+ "date": "2025-11-04",
9
+ "version": "2.0.0-next.28"
10
+ },
11
+ {
12
+ "children": {
13
+ "improvements": [
14
+ "Refactor services to a more clean structure."
15
+ ]
16
+ },
17
+ "date": "2025-11-04",
18
+ "version": "2.0.0-next.27"
19
+ },
2
20
  {
3
21
  "children": {
4
22
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.26",
3
+ "version": "2.0.0-next.28",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -39,10 +39,16 @@ export enum McpNavKey {
39
39
  Version = 'version',
40
40
  }
41
41
 
42
+ export enum McpConnectionType {
43
+ http = 'http',
44
+ stdio = 'stdio'
45
+ }
46
+
42
47
  export type DiscoverMcpItem = PluginItem;
43
48
 
44
49
  export interface McpQueryParams {
45
50
  category?: string;
51
+ connectionType?: McpConnectionType;
46
52
  locale?: string;
47
53
  order?: 'asc' | 'desc';
48
54
  page?: number;
@@ -3,6 +3,7 @@ import { z } from 'zod';
3
3
 
4
4
  import { MCPErrorType } from '@/libs/mcp';
5
5
 
6
+ import { McpConnectionType } from '../discover/mcp';
6
7
  import { CustomPluginMetadata } from '../tool/plugin';
7
8
 
8
9
  /* eslint-disable typescript-sort-keys/string-enum */
@@ -110,7 +111,9 @@ export interface CheckMcpInstallResult {
110
111
  }>;
111
112
  }
112
113
 
113
- export type MCPPluginListParams = Pick<PluginQueryParams, 'locale' | 'pageSize' | 'page' | 'q'>;
114
+ export type MCPPluginListParams = Pick<PluginQueryParams, 'locale' | 'pageSize' | 'page' | 'q'> & {
115
+ connectionType?: McpConnectionType;
116
+ };
114
117
 
115
118
  export interface MCPErrorInfoMetadata {
116
119
  errorLog?: string;
@@ -51,3 +51,17 @@ export interface TopicRankItem {
51
51
  sessionId: string | null;
52
52
  title: string | null;
53
53
  }
54
+
55
+ export interface CreateTopicParams {
56
+ favorite?: boolean;
57
+ groupId?: string | null;
58
+ messages?: string[];
59
+ sessionId?: string | null;
60
+ title: string;
61
+ }
62
+
63
+ export interface QueryTopicParams {
64
+ containerId?: string | null; // sessionId or groupId
65
+ current?: number;
66
+ pageSize?: number;
67
+ }
package/renovate.json CHANGED
@@ -21,44 +21,18 @@
21
21
  {
22
22
  "description": "Isolate PRs for pinned deps (exact x.y.z)",
23
23
  "matchManagers": ["npm", "pnpm", "yarn", "bun"],
24
- "matchDepTypes": [
25
- "dependencies",
26
- "devDependencies",
27
- "optionalDependencies",
28
- "peerDependencies"
29
- ],
30
24
  "matchCurrentValue": "^\\d+\\.\\d+\\.\\d+([+-][0-9A-Za-z.-]+)?$",
31
25
  "groupName": null,
32
26
  "separateMinorPatch": true,
33
27
  "separateMajorMinor": true
34
28
  },
35
- // 2a) Non-pinned deps: override splitting so patch+minor can be combined
29
+ // 2) Non-pinned deps: Patch versions, grouped together
36
30
  {
37
- "description": "Non-pinned deps: allow patch+minor to group; keep majors separate",
31
+ "description": "Group patch versions together for non-pinned deps",
38
32
  "matchManagers": ["npm", "pnpm", "yarn", "bun"],
39
- "matchDepTypes": [
40
- "dependencies",
41
- "devDependencies",
42
- "optionalDependencies",
43
- "peerDependencies"
44
- ],
45
33
  "matchCurrentValue": "/(^[~^]|[<>=| -])/", // anything that looks like a range
46
- "separateMinorPatch": false,
47
- "separateMajorMinor": true
48
- },
49
- // 2b) Non-pinned deps: actually group patch+minor together
50
- {
51
- "description": "Non-pinned deps: group non-major updates",
52
- "matchManagers": ["npm", "pnpm", "yarn", "bun"],
53
- "matchDepTypes": [
54
- "dependencies",
55
- "devDependencies",
56
- "optionalDependencies",
57
- "peerDependencies"
58
- ],
59
- "matchCurrentValue": "/(^[~^]|[<>=| -])/",
60
- "matchUpdateTypes": ["minor", "patch"], // only non-majors
61
- "groupName": "deps (non-major)"
34
+ "groupName": "patch dependencies",
35
+ "matchUpdateTypes": ["patch"]
62
36
  }
63
37
  ],
64
38
  "postUpdateOptions": ["yarnDedupeHighest"],
@@ -0,0 +1,91 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { genServerConfig } from './utils';
4
+
5
+ describe('genServerConfig', () => {
6
+ it('should generate HTTP MCP server config with url', () => {
7
+ const result = genServerConfig('context7', {
8
+ type: 'http',
9
+ url: 'https://mcp.context7.com/mcp',
10
+ } as any);
11
+
12
+ const config = JSON.parse(result);
13
+
14
+ expect(config).toEqual({
15
+ mcpServers: {
16
+ context7: {
17
+ url: 'https://mcp.context7.com/mcp',
18
+ },
19
+ },
20
+ });
21
+ });
22
+
23
+ it('should generate stdio MCP server config with command and args', () => {
24
+ const result = genServerConfig('github', {
25
+ args: ['-y', '@modelcontextprotocol/server-github'],
26
+ command: 'npx',
27
+ type: 'stdio',
28
+ } as any);
29
+
30
+ const config = JSON.parse(result);
31
+
32
+ expect(config).toEqual({
33
+ mcpServers: {
34
+ github: {
35
+ args: ['-y', '@modelcontextprotocol/server-github'],
36
+ command: 'npx',
37
+ },
38
+ },
39
+ });
40
+ });
41
+
42
+ it('should handle empty connection config', () => {
43
+ const result = genServerConfig('test-plugin', {} as any);
44
+
45
+ const config = JSON.parse(result);
46
+
47
+ expect(config).toEqual({
48
+ mcpServers: {
49
+ 'test-plugin': {
50
+ args: [],
51
+ command: {},
52
+ },
53
+ },
54
+ });
55
+ });
56
+
57
+ it('should handle undefined connection', () => {
58
+ const result = genServerConfig('test-plugin', undefined);
59
+
60
+ const config = JSON.parse(result);
61
+
62
+ expect(config).toEqual({
63
+ mcpServers: {
64
+ 'test-plugin': {
65
+ args: [],
66
+ command: {},
67
+ },
68
+ },
69
+ });
70
+ });
71
+
72
+ it('should prioritize url over command/args when both exist', () => {
73
+ const result = genServerConfig('hybrid', {
74
+ args: ['arg1'],
75
+ command: 'cmd',
76
+ type: 'http',
77
+ url: 'https://example.com/mcp',
78
+ } as any);
79
+
80
+ const config = JSON.parse(result);
81
+
82
+ // Should only include url, not command/args
83
+ expect(config).toEqual({
84
+ mcpServers: {
85
+ hybrid: {
86
+ url: 'https://example.com/mcp',
87
+ },
88
+ },
89
+ });
90
+ });
91
+ });
@@ -1,7 +1,24 @@
1
1
  import { ConnectionConfig, DeploymentOption } from '@lobehub/market-types';
2
2
 
3
- export const genServerConfig = (identifier?: string, connection?: ConnectionConfig) =>
4
- JSON.stringify(
3
+ export const genServerConfig = (identifier?: string, connection?: ConnectionConfig) => {
4
+ // 检查是否为 HTTP 类型
5
+ if (connection?.url) {
6
+ // HTTP 类型配置
7
+ return JSON.stringify(
8
+ {
9
+ mcpServers: {
10
+ [String(identifier)]: {
11
+ url: connection.url,
12
+ },
13
+ },
14
+ },
15
+ null,
16
+ 2,
17
+ );
18
+ }
19
+
20
+ // stdio 类型配置
21
+ return JSON.stringify(
5
22
  {
6
23
  mcpServers: {
7
24
  [String(identifier)]: {
@@ -13,6 +30,7 @@ export const genServerConfig = (identifier?: string, connection?: ConnectionConf
13
30
  null,
14
31
  2,
15
32
  );
33
+ };
16
34
 
17
35
  export const getRecommendedDeployment = (deploymentOptions: DeploymentOption[]) =>
18
36
  deploymentOptions?.find((item) => item.isRecommended) || deploymentOptions?.[0];
@@ -4,7 +4,6 @@ import { memo, useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { Flexbox } from 'react-layout-kit';
6
6
 
7
- import { isDesktop } from '@/const/version';
8
7
  import { useServerConfigStore } from '@/store/serverConfig';
9
8
  import { useToolStore } from '@/store/tool';
10
9
  import { PluginStoreTabs } from '@/store/tool/slices/oldStore';
@@ -22,7 +21,7 @@ export const Content = memo(() => {
22
21
  const [keywords] = useState<string>();
23
22
 
24
23
  const options = [
25
- isDesktop ? { label: t('store.tabs.mcp'), value: PluginStoreTabs.MCP } : undefined,
24
+ { label: t('store.tabs.mcp'), value: PluginStoreTabs.MCP },
26
25
  { label: t('store.tabs.old'), value: PluginStoreTabs.Plugin },
27
26
  { label: t('store.tabs.installed'), value: PluginStoreTabs.Installed },
28
27
  ].filter(Boolean) as SegmentedOptions;
@@ -45,7 +44,7 @@ export const Content = memo(() => {
45
44
  value={listType}
46
45
  variant={'filled'}
47
46
  />
48
- <AddPluginButton />
47
+ {mobile ? null : <AddPluginButton />}
49
48
  </Flexbox>
50
49
  <Search />
51
50
  </Flexbox>
@@ -5,7 +5,7 @@ import { memo, useRef } from 'react';
5
5
  import { Flexbox } from 'react-layout-kit';
6
6
 
7
7
  import { useToolStore } from '@/store/tool';
8
-
8
+ import { useServerConfigStore } from '@/store/serverConfig';
9
9
  import DetailLoading from './Detail/Loading';
10
10
  import List from './List';
11
11
 
@@ -15,6 +15,8 @@ export const MCPPluginList = memo(() => {
15
15
  const ref = useRef<HTMLDivElement>(null);
16
16
  const theme = useTheme();
17
17
 
18
+ const mobile = useServerConfigStore((s) => s.isMobile);
19
+
18
20
  return (
19
21
  <Flexbox
20
22
  height={'75vh'}
@@ -26,7 +28,9 @@ export const MCPPluginList = memo(() => {
26
28
  }}
27
29
  width={'100%'}
28
30
  >
29
- <DraggablePanel maxWidth={1024} minWidth={420} placement={'left'}>
31
+ {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
32
+ {/* @ts-ignore */}
33
+ <DraggablePanel maxWidth={1024} minWidth={mobile ? '100vw' : 420} placement={'left'}>
30
34
  <List
31
35
  setIdentifier={(identifier) => {
32
36
  useToolStore.setState({ activeMCPIdentifier: identifier });
@@ -3,10 +3,10 @@ import { serialize } from 'cookie';
3
3
  import debug from 'debug';
4
4
  import { z } from 'zod';
5
5
 
6
- import { isDesktop } from '@/const/version';
6
+ import { isDesktop } from '@lobechat/const';
7
7
  import { publicProcedure, router } from '@/libs/trpc/lambda';
8
8
  import { DiscoverService } from '@/server/services/discover';
9
- import { AssistantSorts, McpSorts, ModelSorts, PluginSorts, ProviderSorts } from '@/types/discover';
9
+ import { AssistantSorts, McpConnectionType, McpSorts, ModelSorts, PluginSorts, ProviderSorts } from '@/types/discover';
10
10
 
11
11
  const log = debug('lambda-router:market');
12
12
 
@@ -83,6 +83,7 @@ export const marketRouter = router({
83
83
  z
84
84
  .object({
85
85
  category: z.string().optional(),
86
+ connectionType: z.nativeEnum(McpConnectionType).optional(),
86
87
  locale: z.string().optional(),
87
88
  order: z.enum(['asc', 'desc']).optional(),
88
89
  page: z.number().optional(),
@@ -178,6 +179,7 @@ export const marketRouter = router({
178
179
  z
179
180
  .object({
180
181
  category: z.string().optional(),
182
+ connectionType: z.nativeEnum(McpConnectionType).optional(),
181
183
  locale: z.string().optional(),
182
184
  order: z.enum(['asc', 'desc']).optional(),
183
185
  page: z.number().optional(),
@@ -128,7 +128,13 @@ export const topicRouter = router({
128
128
  }),
129
129
 
130
130
  searchTopics: topicProcedure
131
- .input(z.object({ keywords: z.string(), sessionId: z.string().nullable().optional() }))
131
+ .input(
132
+ z.object({
133
+ groupId: z.string().nullable().optional(),
134
+ keywords: z.string(),
135
+ sessionId: z.string().nullable().optional(),
136
+ }),
137
+ )
132
138
  .query(async ({ input, ctx }) => {
133
139
  return ctx.topicModel.queryByKeyword(input.keywords, input.sessionId);
134
140
  }),
@@ -1,7 +1,7 @@
1
1
  import { testService } from '~test-utils';
2
2
 
3
- import { ServerService } from './server';
3
+ import { AiModelService } from './index';
4
4
 
5
- describe('aiModelService', () => {
6
- testService(ServerService);
5
+ describe('AiModelService', () => {
6
+ testService(AiModelService);
7
7
  });
@@ -1,3 +1,57 @@
1
- import { ServerService } from './server';
1
+ import {
2
+ AiModelSortMap,
3
+ AiProviderModelListItem,
4
+ CreateAiModelParams,
5
+ ToggleAiModelEnableParams,
6
+ UpdateAiModelParams,
7
+ } from 'model-bank';
2
8
 
3
- export const aiModelService = new ServerService();
9
+ import { lambdaClient } from '@/libs/trpc/client';
10
+
11
+ export class AiModelService {
12
+ createAiModel = async (params: CreateAiModelParams) => {
13
+ return lambdaClient.aiModel.createAiModel.mutate(params);
14
+ };
15
+
16
+ getAiProviderModelList = async (id: string): Promise<AiProviderModelListItem[]> => {
17
+ return lambdaClient.aiModel.getAiProviderModelList.query({ id });
18
+ };
19
+
20
+ getAiModelById = async (id: string) => {
21
+ return lambdaClient.aiModel.getAiModelById.query({ id });
22
+ };
23
+
24
+ toggleModelEnabled = async (params: ToggleAiModelEnableParams) => {
25
+ return lambdaClient.aiModel.toggleModelEnabled.mutate(params);
26
+ };
27
+
28
+ updateAiModel = async (id: string, providerId: string, value: UpdateAiModelParams) => {
29
+ return lambdaClient.aiModel.updateAiModel.mutate({ id, providerId, value });
30
+ };
31
+
32
+ batchUpdateAiModels = async (id: string, models: AiProviderModelListItem[]) => {
33
+ return lambdaClient.aiModel.batchUpdateAiModels.mutate({ id, models });
34
+ };
35
+
36
+ batchToggleAiModels = async (id: string, models: string[], enabled: boolean) => {
37
+ return lambdaClient.aiModel.batchToggleAiModels.mutate({ enabled, id, models });
38
+ };
39
+
40
+ clearModelsByProvider = async (providerId: string) => {
41
+ return lambdaClient.aiModel.clearModelsByProvider.mutate({ providerId });
42
+ };
43
+
44
+ clearRemoteModels = async (providerId: string) => {
45
+ return lambdaClient.aiModel.clearRemoteModels.mutate({ providerId });
46
+ };
47
+
48
+ updateAiModelOrder = async (providerId: string, items: AiModelSortMap[]) => {
49
+ return lambdaClient.aiModel.updateAiModelOrder.mutate({ providerId, sortMap: items });
50
+ };
51
+
52
+ deleteAiModel = async (params: { id: string; providerId: string }) => {
53
+ return lambdaClient.aiModel.removeAiModel.mutate(params);
54
+ };
55
+ }
56
+
57
+ export const aiModelService = new AiModelService();
@@ -1,7 +1,7 @@
1
1
  import { testService } from '~test-utils';
2
2
 
3
- import { ServerService } from './server';
3
+ import { AiProviderService } from './index';
4
4
 
5
5
  describe('aiProviderService', () => {
6
- testService(ServerService);
6
+ testService(AiProviderService);
7
7
  });
@@ -1,3 +1,49 @@
1
- import { ServerService } from './server';
1
+ import {
2
+ AiProviderDetailItem,
3
+ AiProviderRuntimeState,
4
+ AiProviderSortMap,
5
+ CreateAiProviderParams,
6
+ UpdateAiProviderConfigParams,
7
+ } from '@/types/aiProvider';
2
8
 
3
- export const aiProviderService = new ServerService();
9
+ import { lambdaClient } from '@/libs/trpc/client';
10
+
11
+ export class AiProviderService {
12
+ createAiProvider = async (params: CreateAiProviderParams) => {
13
+ return lambdaClient.aiProvider.createAiProvider.mutate(params);
14
+ };
15
+
16
+ getAiProviderList = async () => {
17
+ return lambdaClient.aiProvider.getAiProviderList.query();
18
+ };
19
+
20
+ getAiProviderById = async (id: string): Promise<AiProviderDetailItem | undefined> => {
21
+ return lambdaClient.aiProvider.getAiProviderById.query({ id });
22
+ };
23
+
24
+ toggleProviderEnabled = async (id: string, enabled: boolean) => {
25
+ return lambdaClient.aiProvider.toggleProviderEnabled.mutate({ enabled, id });
26
+ };
27
+
28
+ updateAiProvider = async (id: string, value: any) => {
29
+ return lambdaClient.aiProvider.updateAiProvider.mutate({ id, value });
30
+ };
31
+
32
+ updateAiProviderConfig = async (id: string, value: UpdateAiProviderConfigParams) => {
33
+ return lambdaClient.aiProvider.updateAiProviderConfig.mutate({ id, value });
34
+ };
35
+
36
+ updateAiProviderOrder = async (items: AiProviderSortMap[]) => {
37
+ return lambdaClient.aiProvider.updateAiProviderOrder.mutate({ sortMap: items });
38
+ };
39
+
40
+ deleteAiProvider = async (id: string) => {
41
+ return lambdaClient.aiProvider.removeAiProvider.mutate({ id });
42
+ };
43
+
44
+ getAiProviderRuntimeState = async (isLogin?: boolean): Promise<AiProviderRuntimeState> => {
45
+ return lambdaClient.aiProvider.getAiProviderRuntimeState.query({ isLogin });
46
+ };
47
+ }
48
+
49
+ export const aiProviderService = new AiProviderService();
@@ -1,3 +1,67 @@
1
- import { ServerService } from './server';
1
+ import {
2
+ ChatGroupAgentItem,
3
+ ChatGroupItem,
4
+ NewChatGroup,
5
+ NewChatGroupAgent,
6
+ } from '@/database/schemas';
7
+ import { lambdaClient } from '@/libs/trpc/client';
2
8
 
3
- export const chatGroupService = new ServerService();
9
+ class ChatGroupService {
10
+ createGroup = (params: Omit<NewChatGroup, 'userId'>): Promise<ChatGroupItem> => {
11
+ return lambdaClient.group.createGroup.mutate({
12
+ ...params,
13
+ config: params.config as any,
14
+ });
15
+ };
16
+
17
+ updateGroup = (id: string, value: Partial<ChatGroupItem>): Promise<ChatGroupItem> => {
18
+ return lambdaClient.group.updateGroup.mutate({
19
+ id,
20
+ value: {
21
+ ...value,
22
+ config: value.config as any,
23
+ },
24
+ });
25
+ };
26
+
27
+ deleteGroup = (id: string) => {
28
+ return lambdaClient.group.deleteGroup.mutate({ id });
29
+ };
30
+
31
+ getGroup = (id: string): Promise<ChatGroupItem | undefined> => {
32
+ return lambdaClient.group.getGroup.query({ id });
33
+ };
34
+
35
+ getGroups = (): Promise<ChatGroupItem[]> => {
36
+ return lambdaClient.group.getGroups.query();
37
+ };
38
+
39
+ addAgentsToGroup = (groupId: string, agentIds: string[]): Promise<ChatGroupAgentItem[]> => {
40
+ return lambdaClient.group.addAgentsToGroup.mutate({ agentIds, groupId });
41
+ };
42
+
43
+ removeAgentsFromGroup = (groupId: string, agentIds: string[]) => {
44
+ return lambdaClient.group.removeAgentsFromGroup.mutate({ agentIds, groupId });
45
+ };
46
+
47
+ updateAgentInGroup = (
48
+ groupId: string,
49
+ agentId: string,
50
+ updates: Partial<Pick<NewChatGroupAgent, 'order' | 'role'>>,
51
+ ): Promise<ChatGroupAgentItem> => {
52
+ return lambdaClient.group.updateAgentInGroup.mutate({
53
+ agentId,
54
+ groupId,
55
+ updates: {
56
+ order: updates.order === null ? undefined : updates.order,
57
+ role: updates.role === null ? undefined : updates.role,
58
+ },
59
+ });
60
+ };
61
+
62
+ getGroupAgents = (groupId: string): Promise<ChatGroupAgentItem[]> => {
63
+ return lambdaClient.group.getGroupAgents.query({ groupId });
64
+ };
65
+ }
66
+
67
+ export const chatGroupService = new ChatGroupService();
@@ -1,3 +1,11 @@
1
- import { ServerService } from './server';
1
+ import { ExportDatabaseData } from '@/types/export';
2
2
 
3
- export const exportService = new ServerService();
3
+ import { lambdaClient } from '@/libs/trpc/client';
4
+
5
+ class ExportService {
6
+ exportData = async (): Promise<ExportDatabaseData> => {
7
+ return await lambdaClient.exporter.exportData.mutate();
8
+ };
9
+ }
10
+
11
+ export const exportService = new ExportService();