@lobehub/chat 0.147.11 → 0.147.13

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 (71) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/contributing/Basic/Feature-Development.md +2 -2
  3. package/contributing/Basic/Feature-Development.zh-CN.md +2 -2
  4. package/package.json +1 -1
  5. package/src/database/{core → client/core}/__tests__/db-upgrade.test.ts +2 -2
  6. package/src/database/{core → client/core}/__tests__/db.test.ts +5 -6
  7. package/src/database/{core → client/core}/db.ts +18 -18
  8. package/src/database/{core → client/core}/index.ts +1 -1
  9. package/src/database/{core → client/core}/migrations/migrateSettingsToUser/index.ts +1 -1
  10. package/src/database/{core → client/core}/model.ts +7 -7
  11. package/src/database/{core → client/core}/sync.ts +3 -3
  12. package/src/database/{models → client/models}/__DEBUG.ts +3 -3
  13. package/src/database/{models → client/models}/__tests__/file.test.ts +3 -4
  14. package/src/database/{models → client/models}/__tests__/session.test.ts +3 -3
  15. package/src/database/{models → client/models}/__tests__/sessionGroup.test.ts +1 -1
  16. package/src/database/{models → client/models}/__tests__/topic.test.ts +4 -4
  17. package/src/database/{models → client/models}/file.ts +1 -1
  18. package/src/database/{models → client/models}/message.ts +3 -3
  19. package/src/database/{models → client/models}/plugin.ts +1 -1
  20. package/src/database/{models → client/models}/session.ts +3 -3
  21. package/src/database/{models → client/models}/sessionGroup.ts +2 -2
  22. package/src/database/{models → client/models}/topic.ts +4 -4
  23. package/src/database/{models → client/models}/user.ts +1 -1
  24. package/src/database/{schemas → client/schemas}/user.ts +1 -1
  25. package/src/features/PluginDevModal/UrlManifestForm.tsx +2 -2
  26. package/src/services/__tests__/__snapshots__/{plugin.test.ts.snap → tool.test.ts.snap} +2 -2
  27. package/src/services/__tests__/chat.test.ts +0 -1
  28. package/src/services/__tests__/{plugin.test.ts → tool.test.ts} +13 -160
  29. package/src/services/debug.ts +1 -1
  30. package/src/services/{file.ts → file/client.ts} +4 -6
  31. package/src/services/{__tests__ → file}/file.test.ts +6 -4
  32. package/src/services/file/index.ts +3 -0
  33. package/src/services/global.ts +1 -1
  34. package/src/services/{__tests__/message.test.ts → message/client.test.ts} +6 -10
  35. package/src/services/{message.ts → message/client.ts} +11 -4
  36. package/src/services/message/index.ts +4 -0
  37. package/src/services/plugin/client.ts +44 -0
  38. package/src/services/plugin/index.ts +5 -0
  39. package/src/services/plugin/plugin.test.ts +162 -0
  40. package/src/services/{session.ts → session/client.ts} +3 -5
  41. package/src/services/session/index.ts +3 -0
  42. package/src/services/{__tests__ → session}/session.test.ts +7 -5
  43. package/src/services/{plugin.ts → tool.ts} +2 -41
  44. package/src/services/{topic.ts → topic/client.ts} +2 -4
  45. package/src/services/topic/index.ts +3 -0
  46. package/src/services/{__tests__ → topic}/topic.test.ts +4 -3
  47. package/src/services/{user.ts → user/client.ts} +2 -4
  48. package/src/services/user/index.ts +5 -0
  49. package/src/store/chat/slices/message/action.ts +1 -2
  50. package/src/store/chat/slices/plugin/action.ts +1 -2
  51. package/src/store/tool/slices/customPlugin/action.test.ts +7 -1
  52. package/src/store/tool/slices/customPlugin/action.ts +2 -1
  53. package/src/store/tool/slices/store/action.test.ts +16 -10
  54. package/src/store/tool/slices/store/action.ts +3 -2
  55. package/src/types/sync.ts +1 -1
  56. /package/src/database/{core → client/core}/__tests__/model.test.ts +0 -0
  57. /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/fixtures/input.json +0 -0
  58. /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/fixtures/output.json +0 -0
  59. /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/index.test.ts +0 -0
  60. /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/type.ts +0 -0
  61. /package/src/database/{core → client/core}/schemas.ts +0 -0
  62. /package/src/database/{core → client/core}/types/db.ts +0 -0
  63. /package/src/database/{models → client/models}/__tests__/message.test.ts +0 -0
  64. /package/src/database/{models → client/models}/__tests__/plugin.test.ts +0 -0
  65. /package/src/database/{models → client/models}/__tests__/user.test.ts +0 -0
  66. /package/src/database/{schemas → client/schemas}/files.ts +0 -0
  67. /package/src/database/{schemas → client/schemas}/message.ts +0 -0
  68. /package/src/database/{schemas → client/schemas}/plugin.ts +0 -0
  69. /package/src/database/{schemas → client/schemas}/session.ts +0 -0
  70. /package/src/database/{schemas → client/schemas}/sessionGroup.ts +0 -0
  71. /package/src/database/{schemas → client/schemas}/topic.ts +0 -0
@@ -4,20 +4,12 @@ import {
4
4
  pluginManifestSchema,
5
5
  } from '@lobehub/chat-plugin-sdk';
6
6
 
7
- import { PluginModel } from '@/database/models/plugin';
8
7
  import { globalHelpers } from '@/store/global/helpers';
9
8
  import { OpenAIPluginManifest } from '@/types/openai/plugin';
10
- import { LobeTool } from '@/types/tool';
11
- import { LobeToolCustomPlugin } from '@/types/tool/plugin';
12
9
 
13
10
  import { API_ENDPOINTS } from './_url';
14
11
 
15
- export interface InstallPluginParams {
16
- identifier: string;
17
- manifest: LobeChatPluginManifest;
18
- type: 'plugin' | 'customPlugin';
19
- }
20
- class PluginService {
12
+ class ToolService {
21
13
  private _fetchJSON = async <T = any>(url: string, proxy = false): Promise<T> => {
22
14
  // 2. 发送请求
23
15
  let res: Response;
@@ -107,37 +99,6 @@ class PluginService {
107
99
  return data;
108
100
  };
109
101
 
110
- installPlugin = async (plugin: InstallPluginParams) => {
111
- return PluginModel.create(plugin);
112
- };
113
-
114
- getInstalledPlugins = () => {
115
- return PluginModel.getList() as Promise<LobeTool[]>;
116
- };
117
-
118
- uninstallPlugin(identifier: string) {
119
- return PluginModel.delete(identifier);
120
- }
121
-
122
- async createCustomPlugin(customPlugin: LobeToolCustomPlugin) {
123
- return PluginModel.create({ ...customPlugin, type: 'customPlugin' });
124
- }
125
-
126
- async updatePlugin(id: string, value: LobeToolCustomPlugin) {
127
- return PluginModel.update(id, value);
128
- }
129
- async updatePluginManifest(id: string, manifest: LobeChatPluginManifest) {
130
- return PluginModel.update(id, { manifest });
131
- }
132
-
133
- async removeAllPlugins() {
134
- return PluginModel.clear();
135
- }
136
-
137
- async updatePluginSettings(id: string, settings: any) {
138
- return PluginModel.update(id, { settings });
139
- }
140
-
141
102
  private convertOpenAIManifestToLobeManifest = (
142
103
  data: OpenAIPluginManifest,
143
104
  ): LobeChatPluginManifest => {
@@ -180,4 +141,4 @@ class PluginService {
180
141
  };
181
142
  }
182
143
 
183
- export const pluginService = new PluginService();
144
+ export const toolService = new ToolService();
@@ -1,7 +1,7 @@
1
- import { CreateTopicParams, QueryTopicParams, TopicModel } from '@/database/models/topic';
1
+ import { CreateTopicParams, QueryTopicParams, TopicModel } from '@/database/client/models/topic';
2
2
  import { ChatTopic } from '@/types/topic';
3
3
 
4
- class TopicService {
4
+ export class TopicService {
5
5
  async createTopic(params: CreateTopicParams): Promise<string> {
6
6
  const item = await TopicModel.create(params);
7
7
 
@@ -56,5 +56,3 @@ class TopicService {
56
56
  return TopicModel.duplicateTopic(id, newTitle);
57
57
  }
58
58
  }
59
-
60
- export const topicService = new TopicService();
@@ -0,0 +1,3 @@
1
+ import { TopicService } from './client';
2
+
3
+ export const topicService = new TopicService();
@@ -1,12 +1,13 @@
1
1
  import { Mock, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
2
2
 
3
- import { CreateTopicParams, TopicModel } from '@/database/models/topic';
3
+ import { CreateTopicParams, TopicModel } from '@/database/client/models/topic';
4
4
  import { ChatTopic } from '@/types/topic';
5
5
 
6
- import { topicService } from '../topic';
6
+ import { TopicService } from './client';
7
7
 
8
+ const topicService = new TopicService();
8
9
  // Mock the TopicModel
9
- vi.mock('@/database/models/topic', () => {
10
+ vi.mock('@/database/client/models/topic', () => {
10
11
  return {
11
12
  TopicModel: {
12
13
  create: vi.fn(),
@@ -1,6 +1,6 @@
1
1
  import { DeepPartial } from 'utility-types';
2
2
 
3
- import { UserModel } from '@/database/models/user';
3
+ import { UserModel } from '@/database/client/models/user';
4
4
  import { GlobalSettings } from '@/types/settings';
5
5
 
6
6
  export interface UserConfig {
@@ -9,7 +9,7 @@ export interface UserConfig {
9
9
  uuid: string;
10
10
  }
11
11
 
12
- class UserService {
12
+ export class UserService {
13
13
  getUserConfig = async () => {
14
14
  const user = await UserModel.getUser();
15
15
  return user as unknown as UserConfig;
@@ -27,5 +27,3 @@ class UserService {
27
27
  return UserModel.updateAvatar(avatar);
28
28
  }
29
29
  }
30
-
31
- export const userService = new UserService();
@@ -0,0 +1,5 @@
1
+ import { UserService } from './client';
2
+
3
+ export type { UserConfig } from './client';
4
+
5
+ export const userService = new UserService();
@@ -7,10 +7,9 @@ import { StateCreator } from 'zustand/vanilla';
7
7
 
8
8
  import { LOADING_FLAT, isFunctionMessageAtStart, testFunctionMessageAtEnd } from '@/const/message';
9
9
  import { TraceEventType, TraceNameMap } from '@/const/trace';
10
- import { CreateMessageParams } from '@/database/models/message';
11
10
  import { useClientDataSWR } from '@/libs/swr';
12
11
  import { chatService } from '@/services/chat';
13
- import { messageService } from '@/services/message';
12
+ import { CreateMessageParams, messageService } from '@/services/message';
14
13
  import { topicService } from '@/services/topic';
15
14
  import { traceService } from '@/services/trace';
16
15
  import { chatHelpers } from '@/store/chat/helpers';
@@ -4,9 +4,8 @@ import { Md5 } from 'ts-md5';
4
4
  import { StateCreator } from 'zustand/vanilla';
5
5
 
6
6
  import { PLUGIN_SCHEMA_API_MD5_PREFIX, PLUGIN_SCHEMA_SEPARATOR } from '@/const/plugin';
7
- import { CreateMessageParams } from '@/database/models/message';
8
7
  import { chatService } from '@/services/chat';
9
- import { messageService } from '@/services/message';
8
+ import { CreateMessageParams, messageService } from '@/services/message';
10
9
  import { ChatStore } from '@/store/chat/store';
11
10
  import { useToolStore } from '@/store/tool';
12
11
  import { pluginSelectors } from '@/store/tool/selectors';
@@ -12,13 +12,19 @@ beforeEach(() => {
12
12
  });
13
13
  vi.mock('@/services/plugin', () => ({
14
14
  pluginService: {
15
- getPluginManifest: vi.fn(),
16
15
  updatePlugin: vi.fn(),
17
16
  createCustomPlugin: vi.fn(),
18
17
  uninstallPlugin: vi.fn(),
19
18
  updatePluginManifest: vi.fn(),
20
19
  },
21
20
  }));
21
+
22
+ vi.mock('@/services/tool', () => ({
23
+ toolService: {
24
+ getPluginManifest: vi.fn(),
25
+ },
26
+ }));
27
+
22
28
  describe('useToolStore:customPlugin', () => {
23
29
  describe('deleteCustomPlugin', () => {
24
30
  it('should delete custom plugin and related settings', async () => {
@@ -4,6 +4,7 @@ import { StateCreator } from 'zustand/vanilla';
4
4
 
5
5
  import { notification } from '@/components/AntdStaticMethods';
6
6
  import { pluginService } from '@/services/plugin';
7
+ import { toolService } from '@/services/tool';
7
8
  import { pluginHelpers } from '@/store/tool/helpers';
8
9
  import { LobeToolCustomPlugin, PluginInstallError } from '@/types/tool/plugin';
9
10
  import { setNamespace } from '@/utils/storeDebug';
@@ -41,7 +42,7 @@ export const createCustomPluginSlice: StateCreator<
41
42
  const { refreshPlugins, updateInstallLoadingState } = get();
42
43
  try {
43
44
  updateInstallLoadingState(id, true);
44
- const manifest = await pluginService.getPluginManifest(
45
+ const manifest = await toolService.getPluginManifest(
45
46
  plugin.customParams?.manifestUrl,
46
47
  plugin.customParams?.useProxy,
47
48
  );
@@ -5,6 +5,7 @@ import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
5
 
6
6
  import { notification } from '@/components/AntdStaticMethods';
7
7
  import { pluginService } from '@/services/plugin';
8
+ import { toolService } from '@/services/tool';
8
9
 
9
10
  import { useToolStore } from '../../store';
10
11
 
@@ -17,13 +18,18 @@ vi.mock('@/components/AntdStaticMethods', () => ({
17
18
  // Mock the pluginService.getPluginList method
18
19
  vi.mock('@/services/plugin', () => ({
19
20
  pluginService: {
20
- getPluginManifest: vi.fn(),
21
- getPluginList: vi.fn(),
22
21
  uninstallPlugin: vi.fn(),
23
22
  installPlugin: vi.fn(),
24
23
  },
25
24
  }));
26
25
 
26
+ vi.mock('@/services/tool', () => ({
27
+ toolService: {
28
+ getPluginManifest: vi.fn(),
29
+ getPluginList: vi.fn(),
30
+ },
31
+ }));
32
+
27
33
  // Mock i18next
28
34
  vi.mock('i18next', () => ({
29
35
  t: vi.fn((key) => key),
@@ -97,7 +103,7 @@ describe('useToolStore:pluginStore', () => {
97
103
  it('should load plugin list and update state', async () => {
98
104
  // Given
99
105
  const pluginListMock = { plugins: [{ identifier: 'plugin1' }, { identifier: 'plugin2' }] };
100
- (pluginService.getPluginList as Mock).mockResolvedValue(pluginListMock);
106
+ (toolService.getPluginList as Mock).mockResolvedValue(pluginListMock);
101
107
 
102
108
  // When
103
109
  let pluginList;
@@ -106,7 +112,7 @@ describe('useToolStore:pluginStore', () => {
106
112
  });
107
113
 
108
114
  // Then
109
- expect(pluginService.getPluginList).toHaveBeenCalled();
115
+ expect(toolService.getPluginList).toHaveBeenCalled();
110
116
  expect(pluginList).toEqual(pluginListMock);
111
117
  expect(useToolStore.getState().pluginStoreList).toEqual(pluginListMock.plugins);
112
118
  });
@@ -114,7 +120,7 @@ describe('useToolStore:pluginStore', () => {
114
120
  it('should handle errors when loading plugin list', async () => {
115
121
  // Given
116
122
  const error = new Error('Failed to load plugin list');
117
- (pluginService.getPluginList as Mock).mockRejectedValue(error);
123
+ (toolService.getPluginList as Mock).mockRejectedValue(error);
118
124
 
119
125
  // When
120
126
  let pluginList;
@@ -128,7 +134,7 @@ describe('useToolStore:pluginStore', () => {
128
134
  }
129
135
 
130
136
  // Then
131
- expect(pluginService.getPluginList).toHaveBeenCalled();
137
+ expect(toolService.getPluginList).toHaveBeenCalled();
132
138
  expect(errorOccurred).toBe(true);
133
139
  expect(pluginList).toBeUndefined();
134
140
  // Ensure the state is not updated with an undefined value
@@ -224,14 +230,14 @@ describe('useToolStore:pluginStore', () => {
224
230
  },
225
231
  version: '1',
226
232
  };
227
- (pluginService.getPluginManifest as Mock).mockResolvedValue(pluginManifestMock);
233
+ (toolService.getPluginManifest as Mock).mockResolvedValue(pluginManifestMock);
228
234
 
229
235
  await act(async () => {
230
236
  await useToolStore.getState().installPlugin(pluginIdentifier);
231
237
  });
232
238
 
233
239
  // Then
234
- expect(pluginService.getPluginManifest).toHaveBeenCalled();
240
+ expect(toolService.getPluginManifest).toHaveBeenCalled();
235
241
  expect(notification.error).not.toHaveBeenCalled();
236
242
  expect(updateInstallLoadingStateMock).toHaveBeenCalledTimes(2);
237
243
  expect(pluginService.installPlugin).toHaveBeenCalledWith({
@@ -253,7 +259,7 @@ describe('useToolStore:pluginStore', () => {
253
259
  const error = new TypeError('noManifest');
254
260
 
255
261
  // Mock necessary modules and functions
256
- (pluginService.getPluginManifest as Mock).mockRejectedValue(error);
262
+ (toolService.getPluginManifest as Mock).mockRejectedValue(error);
257
263
 
258
264
  useToolStore.setState({
259
265
  pluginStoreList: [
@@ -297,7 +303,7 @@ describe('useToolStore:pluginStore', () => {
297
303
 
298
304
  const plugins = ['plugin1', 'plugin2'];
299
305
 
300
- (pluginService.getPluginManifest as Mock).mockResolvedValue(pluginManifestMock);
306
+ (toolService.getPluginManifest as Mock).mockResolvedValue(pluginManifestMock);
301
307
 
302
308
  // When
303
309
  await act(async () => {
@@ -6,6 +6,7 @@ import { StateCreator } from 'zustand/vanilla';
6
6
 
7
7
  import { notification } from '@/components/AntdStaticMethods';
8
8
  import { pluginService } from '@/services/plugin';
9
+ import { toolService } from '@/services/tool';
9
10
  import { pluginStoreSelectors } from '@/store/tool/selectors';
10
11
  import { LobeTool } from '@/types/tool';
11
12
  import { PluginInstallError } from '@/types/tool/plugin';
@@ -43,7 +44,7 @@ export const createPluginStoreSlice: StateCreator<
43
44
  const { updateInstallLoadingState, refreshPlugins } = get();
44
45
  try {
45
46
  updateInstallLoadingState(name, true);
46
- const data = await pluginService.getPluginManifest(plugin.manifest);
47
+ const data = await toolService.getPluginManifest(plugin.manifest);
47
48
  updateInstallLoadingState(name, undefined);
48
49
 
49
50
  // 4. 存储 manifest 信息
@@ -66,7 +67,7 @@ export const createPluginStoreSlice: StateCreator<
66
67
  await Promise.all(plugins.map((identifier) => installPlugin(identifier)));
67
68
  },
68
69
  loadPluginStore: async () => {
69
- const pluginMarketIndex = await pluginService.getPluginList();
70
+ const pluginMarketIndex = await toolService.getPluginList();
70
71
 
71
72
  set({ pluginStoreList: pluginMarketIndex.plugins }, false, n('loadPluginList'));
72
73
 
package/src/types/sync.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { LobeDBSchemaMap } from '@/database/core/db';
1
+ import { LobeDBSchemaMap } from '@/database/client/core/db';
2
2
 
3
3
  export type OnSyncEvent = (tableKey: keyof LobeDBSchemaMap) => void;
4
4
  export type OnSyncStatusChange = (status: PeerSyncStatus) => void;
File without changes
File without changes