@lobehub/chat 0.147.15 → 0.147.17

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/contributing/Basic/Feature-Development.md +7 -7
  3. package/contributing/Basic/Feature-Development.zh-CN.md +7 -7
  4. package/next.config.mjs +61 -13
  5. package/package.json +2 -1
  6. package/sentry.client.config.ts +30 -0
  7. package/sentry.edge.config.ts +17 -0
  8. package/sentry.server.config.ts +19 -0
  9. package/src/app/api/auth/[...nextauth]/route.ts +1 -1
  10. package/src/app/chat/(desktop)/features/ChatInput/Footer/index.tsx +7 -1
  11. package/src/app/chat/(desktop)/features/ChatInput/TextArea.tsx +7 -1
  12. package/src/app/home/Redirect.tsx +2 -2
  13. package/src/app/layout.tsx +2 -2
  14. package/src/config/server/app.ts +0 -18
  15. package/src/config/server/auth.ts +71 -0
  16. package/src/config/server/index.ts +3 -1
  17. package/src/database/client/models/__tests__/session.test.ts +1 -3
  18. package/src/database/client/models/session.ts +4 -4
  19. package/src/layout/AuthProvider/NextAuth/index.tsx +10 -0
  20. package/src/layout/AuthProvider/index.tsx +3 -7
  21. package/src/layout/DefaultLayout/Desktop/SideBar/Avatar.tsx +11 -0
  22. package/src/layout/{GlobalLayout → DefaultLayout}/Desktop/SideBar/index.tsx +2 -2
  23. package/src/layout/{GlobalLayout/Mobile/Client.tsx → DefaultLayout/Mobile/index.tsx} +2 -0
  24. package/src/layout/DefaultLayout/index.ts +2 -0
  25. package/src/layout/{GlobalLayout/Desktop/index.tsx → routes/Desktop.tsx} +5 -3
  26. package/src/layout/{GlobalLayout/Mobile/index.tsx → routes/Mobile.tsx} +3 -4
  27. package/src/layout/{GlobalLayout → routes}/index.tsx +2 -2
  28. package/src/{app/api/auth/next-auth.ts → libs/next-auth/index.ts} +1 -1
  29. package/src/middleware.ts +1 -1
  30. package/src/services/config.ts +4 -4
  31. package/src/services/file/client.test.ts +2 -2
  32. package/src/services/file/client.ts +35 -33
  33. package/src/services/file/index.ts +8 -2
  34. package/src/services/file/type.ts +11 -0
  35. package/src/services/message/client.test.ts +6 -32
  36. package/src/services/message/client.ts +24 -37
  37. package/src/services/message/index.test.ts +48 -0
  38. package/src/services/message/index.ts +22 -2
  39. package/src/services/message/type.ts +33 -0
  40. package/src/services/plugin/client.test.ts +2 -2
  41. package/src/services/plugin/client.ts +1 -1
  42. package/src/services/plugin/index.ts +9 -3
  43. package/src/services/session/client.test.ts +37 -44
  44. package/src/services/session/client.ts +30 -22
  45. package/src/services/session/index.ts +9 -2
  46. package/src/services/session/type.ts +44 -0
  47. package/src/services/topic/client.test.ts +18 -22
  48. package/src/services/topic/client.ts +31 -23
  49. package/src/services/topic/index.ts +10 -2
  50. package/src/services/topic/type.ts +32 -0
  51. package/src/services/user/client.ts +1 -1
  52. package/src/services/user/index.ts +10 -2
  53. package/src/store/chat/slices/message/action.test.ts +12 -12
  54. package/src/store/chat/slices/message/action.ts +4 -4
  55. package/src/store/chat/slices/plugin/action.test.ts +5 -6
  56. package/src/store/chat/slices/plugin/action.ts +1 -1
  57. package/src/store/chat/slices/topic/action.test.ts +11 -6
  58. package/src/store/chat/slices/topic/action.ts +7 -5
  59. package/src/store/session/slices/agent/action.test.ts +175 -0
  60. package/src/store/session/slices/agent/action.ts +1 -1
  61. package/src/store/session/slices/session/action.test.ts +14 -15
  62. package/src/store/session/slices/session/action.ts +4 -4
  63. package/src/store/session/slices/sessionGroup/action.test.ts +6 -4
  64. package/src/store/session/slices/sessionGroup/action.ts +3 -3
  65. /package/src/layout/{GlobalLayout → DefaultLayout}/Desktop/SideBar/BottomActions.tsx +0 -0
  66. /package/src/layout/{GlobalLayout → DefaultLayout}/Desktop/SideBar/TopActions.tsx +0 -0
  67. /package/src/layout/{GlobalLayout/Desktop/Client.tsx → DefaultLayout/Desktop/index.tsx} +0 -0
  68. /package/src/{app/api/auth → libs/next-auth}/sso-providers/auth0.ts +0 -0
  69. /package/src/{app/api/auth → libs/next-auth}/sso-providers/authentik.ts +0 -0
  70. /package/src/{app/api/auth → libs/next-auth}/sso-providers/azure-ad.ts +0 -0
  71. /package/src/{app/api/auth → libs/next-auth}/sso-providers/github.ts +0 -0
  72. /package/src/{app/api/auth → libs/next-auth}/sso-providers/index.ts +0 -0
  73. /package/src/{app/api/auth → libs/next-auth}/sso-providers/zitadel.ts +0 -0
@@ -3,14 +3,16 @@
3
3
  import { usePathname } from 'next/navigation';
4
4
  import { PropsWithChildren, memo } from 'react';
5
5
 
6
- import Client from './Client';
6
+ import { DefaultLayoutDesktop } from '@/layout/DefaultLayout';
7
+
8
+ const defaultLayoutRoutes = new Set(['/']);
7
9
 
8
10
  const DesktopLayout = memo<PropsWithChildren>(({ children }) => {
9
11
  const pathname = usePathname();
10
12
 
11
- if (pathname === '/') return children;
13
+ if (defaultLayoutRoutes.has(pathname)) return children;
12
14
 
13
- return <Client>{children}</Client>;
15
+ return <DefaultLayoutDesktop>{children}</DefaultLayoutDesktop>;
14
16
  });
15
17
 
16
18
  export default DesktopLayout;
@@ -5,8 +5,7 @@ import { PropsWithChildren, memo } from 'react';
5
5
 
6
6
  import { useActiveTabKey } from '@/hooks/useActiveTabKey';
7
7
  import { useIsSubSlug } from '@/hooks/useIsSubSlug';
8
-
9
- import Layout from './Client';
8
+ import { DefaultLayoutMobile } from '@/layout/DefaultLayout';
10
9
 
11
10
  const MobileLayout = memo<PropsWithChildren>(({ children }) => {
12
11
  const pathname = usePathname();
@@ -16,9 +15,9 @@ const MobileLayout = memo<PropsWithChildren>(({ children }) => {
16
15
  if (pathname === '/') return children;
17
16
 
18
17
  return (
19
- <Layout showTabBar={!isSubPath} tabBarKey={tabBarKey}>
18
+ <DefaultLayoutMobile showTabBar={!isSubPath} tabBarKey={tabBarKey}>
20
19
  {children}
21
- </Layout>
20
+ </DefaultLayoutMobile>
22
21
  );
23
22
  });
24
23
 
@@ -3,6 +3,6 @@ import ServerLayout from '@/components/server/ServerLayout';
3
3
  import Desktop from './Desktop';
4
4
  import Mobile from './Mobile';
5
5
 
6
- const GlobalLayout = ServerLayout({ Desktop, Mobile });
6
+ const LayoutRoutes = ServerLayout({ Desktop, Mobile });
7
7
 
8
- export default GlobalLayout;
8
+ export default LayoutRoutes;
@@ -32,7 +32,7 @@ const nextAuth = NextAuth({
32
32
  async session({ session, token }) {
33
33
  // Pick userid from token
34
34
  if (session.user) {
35
- session.user.id = token.userId ?? session.user.id;
35
+ session.user.id = (token.userId ?? session.user.id) as string;
36
36
  }
37
37
  return session;
38
38
  },
package/src/middleware.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { NextResponse } from 'next/server';
2
2
 
3
3
  import { getServerConfig } from '@/config/server';
4
+ import { auth } from '@/libs/next-auth';
4
5
 
5
- import { auth } from './app/api/auth/next-auth';
6
6
  import { OAUTH_AUTHORIZED } from './const/auth';
7
7
 
8
8
  export const config = {
@@ -33,7 +33,7 @@ class ConfigService {
33
33
  return await sessionService.batchCreateSessions(sessions);
34
34
  };
35
35
  importMessages = async (messages: ChatMessage[]) => {
36
- return messageService.batchCreate(messages);
36
+ return messageService.batchCreateMessages(messages);
37
37
  };
38
38
  importSettings = async (settings: GlobalSettings) => {
39
39
  useGlobalStore.getState().importAppSettings(settings);
@@ -105,7 +105,7 @@ class ConfigService {
105
105
  * export all agents
106
106
  */
107
107
  exportAgents = async () => {
108
- const agents = await sessionService.getAllAgents();
108
+ const agents = await sessionService.getSessionsByType('agent');
109
109
  const sessionGroups = await sessionService.getSessionGroups();
110
110
 
111
111
  const config = createConfigFile('agents', { sessionGroups, sessions: agents });
@@ -117,7 +117,7 @@ class ConfigService {
117
117
  * export all sessions
118
118
  */
119
119
  exportSessions = async () => {
120
- const sessions = await sessionService.getSessions();
120
+ const sessions = await sessionService.getSessionsByType();
121
121
  const sessionGroups = await sessionService.getSessionGroups();
122
122
  const messages = await messageService.getAllMessages();
123
123
  const topics = await topicService.getAllTopics();
@@ -188,7 +188,7 @@ class ConfigService {
188
188
  * export all data
189
189
  */
190
190
  exportAll = async () => {
191
- const sessions = await sessionService.getSessions();
191
+ const sessions = await sessionService.getSessionsByType();
192
192
  const sessionGroups = await sessionService.getSessionGroups();
193
193
  const messages = await messageService.getAllMessages();
194
194
  const topics = await topicService.getAllTopics();
@@ -3,9 +3,9 @@ import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
3
3
  import { FileModel } from '@/database/client/models/file';
4
4
  import { DB_File } from '@/database/client/schemas/files';
5
5
 
6
- import { FileService } from './client';
6
+ import { ClientService } from './client';
7
7
 
8
- const fileService = new FileService();
8
+ const fileService = new ClientService();
9
9
 
10
10
  // Mocks for the FileModel
11
11
  vi.mock('@/database/client/models/file', () => ({
@@ -4,12 +4,9 @@ import { FilePreview } from '@/types/files';
4
4
  import compressImage from '@/utils/compressImage';
5
5
 
6
6
  import { API_ENDPOINTS } from '../_url';
7
+ import { IFileService } from './type';
7
8
 
8
- export class FileService {
9
- private isImage(fileType: string) {
10
- const imageRegex = /^image\//;
11
- return imageRegex.test(fileType);
12
- }
9
+ export class ClientService implements IFileService {
13
10
  async uploadFile(file: DB_File) {
14
11
  // 跳过图片上传测试
15
12
  const isTestData = file.size === 1;
@@ -22,26 +19,6 @@ export class FileService {
22
19
  return FileModel.create(file);
23
20
  }
24
21
 
25
- async uploadImageFile(file: DB_File) {
26
- // 加载图片
27
- const url = file.url || URL.createObjectURL(new Blob([file.data]));
28
-
29
- const img = new Image();
30
- img.src = url;
31
- await (() =>
32
- new Promise((resolve) => {
33
- img.addEventListener('load', resolve);
34
- }))();
35
-
36
- // 压缩图片
37
- const base64String = compressImage({ img, type: file.fileType });
38
- const binaryString = atob(base64String.split('base64,')[1]);
39
- const uint8Array = Uint8Array.from(binaryString, (char) => char.charCodeAt(0));
40
- file.data = uint8Array.buffer;
41
-
42
- return FileModel.create(file);
43
- }
44
-
45
22
  async uploadImageByUrl(url: string, file: Pick<DB_File, 'name' | 'metadata'>) {
46
23
  const res = await fetch(API_ENDPOINTS.proxy, { body: url, method: 'POST' });
47
24
  const data = await res.arrayBuffer();
@@ -57,14 +34,6 @@ export class FileService {
57
34
  });
58
35
  }
59
36
 
60
- async removeFile(id: string) {
61
- return FileModel.delete(id);
62
- }
63
-
64
- async removeAllFiles() {
65
- return FileModel.clear();
66
- }
67
-
68
37
  async getFile(id: string): Promise<FilePreview> {
69
38
  const item = await FileModel.findById(id);
70
39
  if (!item) {
@@ -83,4 +52,37 @@ export class FileService {
83
52
  url,
84
53
  };
85
54
  }
55
+
56
+ async removeFile(id: string) {
57
+ return FileModel.delete(id);
58
+ }
59
+
60
+ async removeAllFiles() {
61
+ return FileModel.clear();
62
+ }
63
+
64
+ private isImage(fileType: string) {
65
+ const imageRegex = /^image\//;
66
+ return imageRegex.test(fileType);
67
+ }
68
+
69
+ private async uploadImageFile(file: DB_File) {
70
+ // 加载图片
71
+ const url = file.url || URL.createObjectURL(new Blob([file.data]));
72
+
73
+ const img = new Image();
74
+ img.src = url;
75
+ await (() =>
76
+ new Promise((resolve) => {
77
+ img.addEventListener('load', resolve);
78
+ }))();
79
+
80
+ // 压缩图片
81
+ const base64String = compressImage({ img, type: file.fileType });
82
+ const binaryString = atob(base64String.split('base64,')[1]);
83
+ const uint8Array = Uint8Array.from(binaryString, (char) => char.charCodeAt(0));
84
+ file.data = uint8Array.buffer;
85
+
86
+ return FileModel.create(file);
87
+ }
86
88
  }
@@ -1,3 +1,9 @@
1
- import { FileService } from './client';
1
+ // import { getClientConfig } from '@/config/client';
2
+ import { ClientService } from './client';
2
3
 
3
- export const fileService = new FileService();
4
+ // import { ServerService } from './server';
5
+ //
6
+ // const { ENABLED_SERVER_SERVICE } = getClientConfig();
7
+ //
8
+ // export const fileService = ENABLED_SERVER_SERVICE ? new ServerService() : new ClientService();
9
+ export const fileService = new ClientService();
@@ -0,0 +1,11 @@
1
+ /* eslint-disable typescript-sort-keys/interface */
2
+ import { DB_File } from '@/database/client/schemas/files';
3
+ import { FilePreview } from '@/types/files';
4
+
5
+ export interface IFileService {
6
+ uploadFile(file: DB_File): Promise<any>;
7
+ uploadImageByUrl(url: string, file: Pick<DB_File, 'name' | 'metadata'>): Promise<any>;
8
+ removeFile(id: string): Promise<any>;
9
+ removeAllFiles(): Promise<any>;
10
+ getFile(id: string): Promise<FilePreview>;
11
+ }
@@ -3,9 +3,9 @@ import { Mock, describe, expect, it, vi } from 'vitest';
3
3
  import { CreateMessageParams, MessageModel } from '@/database/client/models/message';
4
4
  import { ChatMessage, ChatMessageError, ChatPluginPayload } from '@/types/message';
5
5
 
6
- import { MessageService } from './client';
6
+ import { ClientService } from './client';
7
7
 
8
- const messageService = new MessageService();
8
+ const messageService = new ClientService();
9
9
 
10
10
  // Mock the MessageModel
11
11
  vi.mock('@/database/client/models/message', () => {
@@ -27,7 +27,7 @@ vi.mock('@/database/client/models/message', () => {
27
27
  };
28
28
  });
29
29
 
30
- describe('MessageService', () => {
30
+ describe('MessageClientService', () => {
31
31
  // Mock data
32
32
  const mockMessageId = 'mock-message-id';
33
33
  const mockMessage = {
@@ -57,7 +57,7 @@ describe('MessageService', () => {
57
57
  (MessageModel.create as Mock).mockResolvedValue({ id: mockMessageId });
58
58
 
59
59
  // Execute
60
- const messageId = await messageService.create(createParams);
60
+ const messageId = await messageService.createMessage(createParams);
61
61
 
62
62
  // Assert
63
63
  expect(MessageModel.create).toHaveBeenCalledWith(createParams);
@@ -71,7 +71,7 @@ describe('MessageService', () => {
71
71
  (MessageModel.batchCreate as Mock).mockResolvedValue(mockMessages);
72
72
 
73
73
  // Execute
74
- const result = await messageService.batchCreate(mockMessages);
74
+ const result = await messageService.batchCreateMessages(mockMessages);
75
75
 
76
76
  // Assert
77
77
  expect(MessageModel.batchCreate).toHaveBeenCalledWith(mockMessages);
@@ -79,32 +79,6 @@ describe('MessageService', () => {
79
79
  });
80
80
  });
81
81
 
82
- describe('hasMessages', () => {
83
- it('should return true if there are messages', async () => {
84
- // Setup
85
- (MessageModel.count as Mock).mockResolvedValue(1);
86
-
87
- // Execute
88
- const hasMessages = await messageService.hasMessages();
89
-
90
- // Assert
91
- expect(MessageModel.count).toHaveBeenCalled();
92
- expect(hasMessages).toBe(true);
93
- });
94
-
95
- it('should return false if there are no messages', async () => {
96
- // Setup
97
- (MessageModel.count as Mock).mockResolvedValue(0);
98
-
99
- // Execute
100
- const hasMessages = await messageService.hasMessages();
101
-
102
- // Assert
103
- expect(MessageModel.count).toHaveBeenCalled();
104
- expect(hasMessages).toBe(false);
105
- });
106
- });
107
-
108
82
  describe('removeMessage', () => {
109
83
  it('should remove a message by id', async () => {
110
84
  // Setup
@@ -172,7 +146,7 @@ describe('MessageService', () => {
172
146
  (MessageModel.clearTable as Mock).mockResolvedValue(true);
173
147
 
174
148
  // Execute
175
- const result = await messageService.clearAllMessage();
149
+ const result = await messageService.removeAllMessages();
176
150
 
177
151
  // Assert
178
152
  expect(MessageModel.clearTable).toHaveBeenCalled();
@@ -2,42 +2,29 @@ import { MessageModel } from '@/database/client/models/message';
2
2
  import { DB_Message } from '@/database/client/schemas/message';
3
3
  import { ChatMessage, ChatMessageError, ChatPluginPayload } from '@/types/message';
4
4
 
5
- export interface CreateMessageParams
6
- extends Partial<Omit<ChatMessage, 'content' | 'role'>>,
7
- Pick<ChatMessage, 'content' | 'role'> {
8
- fromModel?: string;
9
- fromProvider?: string;
10
- sessionId: string;
11
- traceId?: string;
12
- }
5
+ import { CreateMessageParams, IMessageService } from './type';
13
6
 
14
- export class MessageService {
15
- async create(data: CreateMessageParams) {
7
+ export class ClientService implements IMessageService {
8
+ async createMessage(data: CreateMessageParams) {
16
9
  const { id } = await MessageModel.create(data);
17
10
 
18
11
  return id;
19
12
  }
20
13
 
21
- async batchCreate(messages: ChatMessage[]) {
14
+ async batchCreateMessages(messages: ChatMessage[]) {
22
15
  return MessageModel.batchCreate(messages);
23
16
  }
24
17
 
25
- async hasMessages() {
26
- const number = await MessageModel.count();
27
- return number > 0;
28
- }
29
-
30
- async messageCountToCheckTrace() {
31
- const number = await MessageModel.count();
32
- return number >= 4;
33
- }
34
-
35
18
  async getMessages(sessionId: string, topicId?: string): Promise<ChatMessage[]> {
36
19
  return MessageModel.query({ sessionId, topicId });
37
20
  }
38
21
 
39
- async removeMessage(id: string) {
40
- return MessageModel.delete(id);
22
+ async getAllMessages() {
23
+ return MessageModel.queryAll();
24
+ }
25
+
26
+ async countMessages() {
27
+ return MessageModel.count();
41
28
  }
42
29
 
43
30
  async getAllMessagesInSession(sessionId: string) {
@@ -48,18 +35,6 @@ export class MessageService {
48
35
  return MessageModel.update(id, { error });
49
36
  }
50
37
 
51
- async removeMessages(assistantId: string, topicId?: string) {
52
- return MessageModel.batchDelete(assistantId, topicId);
53
- }
54
-
55
- async clearAllMessage() {
56
- return MessageModel.clearTable();
57
- }
58
-
59
- async bindMessagesToTopic(topicId: string, messageIds: string[]) {
60
- return MessageModel.batchUpdate(messageIds, { topicId });
61
- }
62
-
63
38
  async updateMessage(id: string, message: Partial<DB_Message>) {
64
39
  return MessageModel.update(id, message);
65
40
  }
@@ -72,7 +47,19 @@ export class MessageService {
72
47
  return MessageModel.updatePluginState(id, key, value);
73
48
  }
74
49
 
75
- async getAllMessages() {
76
- return MessageModel.queryAll();
50
+ async bindMessagesToTopic(topicId: string, messageIds: string[]) {
51
+ return MessageModel.batchUpdate(messageIds, { topicId });
52
+ }
53
+
54
+ async removeMessage(id: string) {
55
+ return MessageModel.delete(id);
56
+ }
57
+
58
+ async removeMessages(assistantId: string, topicId?: string) {
59
+ return MessageModel.batchDelete(assistantId, topicId);
60
+ }
61
+
62
+ async removeAllMessages() {
63
+ return MessageModel.clearTable();
77
64
  }
78
65
  }
@@ -0,0 +1,48 @@
1
+ import { Mock, describe, expect, it, vi } from 'vitest';
2
+
3
+ import { CreateMessageParams, MessageModel } from '@/database/client/models/message';
4
+ import { ChatMessage, ChatMessageError, ChatPluginPayload } from '@/types/message';
5
+
6
+ import { messageService } from './index';
7
+
8
+ // Mock the MessageModel
9
+ vi.mock('@/database/client/models/message', () => {
10
+ return {
11
+ MessageModel: {
12
+ count: vi.fn(),
13
+ },
14
+ };
15
+ });
16
+
17
+ describe('MessageService', () => {
18
+ beforeEach(() => {
19
+ // Reset all mocks before running each test case
20
+ vi.resetAllMocks();
21
+ });
22
+
23
+ describe('hasMessages', () => {
24
+ it('should return true if there are messages', async () => {
25
+ // Setup
26
+ (MessageModel.count as Mock).mockResolvedValue(1);
27
+
28
+ // Execute
29
+ const hasMessages = await messageService.hasMessages();
30
+
31
+ // Assert
32
+ expect(MessageModel.count).toHaveBeenCalled();
33
+ expect(hasMessages).toBe(true);
34
+ });
35
+
36
+ it('should return false if there are no messages', async () => {
37
+ // Setup
38
+ (MessageModel.count as Mock).mockResolvedValue(0);
39
+
40
+ // Execute
41
+ const hasMessages = await messageService.hasMessages();
42
+
43
+ // Assert
44
+ expect(MessageModel.count).toHaveBeenCalled();
45
+ expect(hasMessages).toBe(false);
46
+ });
47
+ });
48
+ });
@@ -1,4 +1,24 @@
1
- import { MessageService } from './client';
1
+ // import { getClientConfig } from '@/config/client';
2
+ // import { ServerService } from './server';
3
+ // import { ClientService } from './client';
4
+ //
5
+ // const { ENABLED_SERVER_SERVICE } = getClientConfig();
6
+ //
7
+ // export const messageService = ENABLED_SERVER_SERVICE ? new ServerService() : new ClientService();
8
+ import { ClientService } from './client';
9
+
10
+ export type { CreateMessageParams } from './type';
11
+
12
+ class MessageService extends ClientService {
13
+ async hasMessages() {
14
+ const number = await this.countMessages();
15
+ return number > 0;
16
+ }
17
+
18
+ async messageCountToCheckTrace() {
19
+ const number = await this.countMessages();
20
+ return number >= 4;
21
+ }
22
+ }
2
23
 
3
24
  export const messageService = new MessageService();
4
- export type { CreateMessageParams } from './client';
@@ -0,0 +1,33 @@
1
+ import { DB_Message } from '@/database/client/schemas/message';
2
+ import { ChatMessage, ChatMessageError, ChatPluginPayload } from '@/types/message';
3
+
4
+ /* eslint-disable typescript-sort-keys/interface */
5
+
6
+ export interface CreateMessageParams
7
+ extends Partial<Omit<ChatMessage, 'content' | 'role'>>,
8
+ Pick<ChatMessage, 'content' | 'role'> {
9
+ fromModel?: string;
10
+ fromProvider?: string;
11
+ sessionId: string;
12
+ traceId?: string;
13
+ }
14
+
15
+ export interface IMessageService {
16
+ createMessage(data: CreateMessageParams): Promise<string>;
17
+ batchCreateMessages(messages: ChatMessage[]): Promise<any>;
18
+
19
+ getMessages(sessionId: string, topicId?: string): Promise<ChatMessage[]>;
20
+ getAllMessages(): Promise<ChatMessage[]>;
21
+ getAllMessagesInSession(sessionId: string): Promise<ChatMessage[]>;
22
+ countMessages(): Promise<number>;
23
+
24
+ updateMessageError(id: string, error: ChatMessageError): Promise<any>;
25
+ updateMessage(id: string, message: Partial<DB_Message>): Promise<any>;
26
+ updateMessagePlugin(id: string, plugin: ChatPluginPayload): Promise<any>;
27
+ updateMessagePluginState(id: string, key: string, value: any): Promise<any>;
28
+ bindMessagesToTopic(topicId: string, messageIds: string[]): Promise<any>;
29
+
30
+ removeMessage(id: string): Promise<any>;
31
+ removeMessages(assistantId: string, topicId?: string): Promise<any>;
32
+ removeAllMessages(): Promise<any>;
33
+ }
@@ -6,9 +6,9 @@ import { DB_Plugin } from '@/database/client/schemas/plugin';
6
6
  import { LobeTool } from '@/types/tool';
7
7
  import { LobeToolCustomPlugin } from '@/types/tool/plugin';
8
8
 
9
- import { InstallPluginParams, PluginService } from './client';
9
+ import { ClientService, InstallPluginParams } from './client';
10
10
 
11
- const pluginService = new PluginService();
11
+ const pluginService = new ClientService();
12
12
 
13
13
  // Mocking modules and functions
14
14
 
@@ -10,7 +10,7 @@ export interface InstallPluginParams {
10
10
  type: 'plugin' | 'customPlugin';
11
11
  }
12
12
 
13
- export class PluginService {
13
+ export class ClientService {
14
14
  installPlugin = async (plugin: InstallPluginParams) => {
15
15
  return PluginModel.create(plugin);
16
16
  };
@@ -1,5 +1,11 @@
1
- import { PluginService } from './client';
1
+ // import { getClientConfig } from '@/config/client';
2
+ import { ClientService } from './client';
2
3
 
3
- export type { InstallPluginParams } from './client';
4
+ // import { ServerService } from './server';
5
+ //
6
+ // export type { InstallPluginParams } from './client';
7
+ //
8
+ // const { ENABLED_SERVER_SERVICE } = getClientConfig();
4
9
 
5
- export const pluginService = new PluginService();
10
+ // export const pluginService = ENABLED_SERVER_SERVICE ? new ServerService() : new ClientService();
11
+ export const pluginService = new ClientService();