@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.
- package/CHANGELOG.md +50 -0
- package/contributing/Basic/Feature-Development.md +2 -2
- package/contributing/Basic/Feature-Development.zh-CN.md +2 -2
- package/package.json +1 -1
- package/src/database/{core → client/core}/__tests__/db-upgrade.test.ts +2 -2
- package/src/database/{core → client/core}/__tests__/db.test.ts +5 -6
- package/src/database/{core → client/core}/db.ts +18 -18
- package/src/database/{core → client/core}/index.ts +1 -1
- package/src/database/{core → client/core}/migrations/migrateSettingsToUser/index.ts +1 -1
- package/src/database/{core → client/core}/model.ts +7 -7
- package/src/database/{core → client/core}/sync.ts +3 -3
- package/src/database/{models → client/models}/__DEBUG.ts +3 -3
- package/src/database/{models → client/models}/__tests__/file.test.ts +3 -4
- package/src/database/{models → client/models}/__tests__/session.test.ts +3 -3
- package/src/database/{models → client/models}/__tests__/sessionGroup.test.ts +1 -1
- package/src/database/{models → client/models}/__tests__/topic.test.ts +4 -4
- package/src/database/{models → client/models}/file.ts +1 -1
- package/src/database/{models → client/models}/message.ts +3 -3
- package/src/database/{models → client/models}/plugin.ts +1 -1
- package/src/database/{models → client/models}/session.ts +3 -3
- package/src/database/{models → client/models}/sessionGroup.ts +2 -2
- package/src/database/{models → client/models}/topic.ts +4 -4
- package/src/database/{models → client/models}/user.ts +1 -1
- package/src/database/{schemas → client/schemas}/user.ts +1 -1
- package/src/features/PluginDevModal/UrlManifestForm.tsx +2 -2
- package/src/services/__tests__/__snapshots__/{plugin.test.ts.snap → tool.test.ts.snap} +2 -2
- package/src/services/__tests__/chat.test.ts +0 -1
- package/src/services/__tests__/{plugin.test.ts → tool.test.ts} +13 -160
- package/src/services/debug.ts +1 -1
- package/src/services/{file.ts → file/client.ts} +4 -6
- package/src/services/{__tests__ → file}/file.test.ts +6 -4
- package/src/services/file/index.ts +3 -0
- package/src/services/global.ts +1 -1
- package/src/services/{__tests__/message.test.ts → message/client.test.ts} +6 -10
- package/src/services/{message.ts → message/client.ts} +11 -4
- package/src/services/message/index.ts +4 -0
- package/src/services/plugin/client.ts +44 -0
- package/src/services/plugin/index.ts +5 -0
- package/src/services/plugin/plugin.test.ts +162 -0
- package/src/services/{session.ts → session/client.ts} +3 -5
- package/src/services/session/index.ts +3 -0
- package/src/services/{__tests__ → session}/session.test.ts +7 -5
- package/src/services/{plugin.ts → tool.ts} +2 -41
- package/src/services/{topic.ts → topic/client.ts} +2 -4
- package/src/services/topic/index.ts +3 -0
- package/src/services/{__tests__ → topic}/topic.test.ts +4 -3
- package/src/services/{user.ts → user/client.ts} +2 -4
- package/src/services/user/index.ts +5 -0
- package/src/store/chat/slices/message/action.ts +1 -2
- package/src/store/chat/slices/plugin/action.ts +1 -2
- package/src/store/tool/slices/customPlugin/action.test.ts +7 -1
- package/src/store/tool/slices/customPlugin/action.ts +2 -1
- package/src/store/tool/slices/store/action.test.ts +16 -10
- package/src/store/tool/slices/store/action.ts +3 -2
- package/src/types/sync.ts +1 -1
- /package/src/database/{core → client/core}/__tests__/model.test.ts +0 -0
- /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/fixtures/input.json +0 -0
- /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/fixtures/output.json +0 -0
- /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/index.test.ts +0 -0
- /package/src/database/{core → client/core}/migrations/migrateSettingsToUser/type.ts +0 -0
- /package/src/database/{core → client/core}/schemas.ts +0 -0
- /package/src/database/{core → client/core}/types/db.ts +0 -0
- /package/src/database/{models → client/models}/__tests__/message.test.ts +0 -0
- /package/src/database/{models → client/models}/__tests__/plugin.test.ts +0 -0
- /package/src/database/{models → client/models}/__tests__/user.test.ts +0 -0
- /package/src/database/{schemas → client/schemas}/files.ts +0 -0
- /package/src/database/{schemas → client/schemas}/message.ts +0 -0
- /package/src/database/{schemas → client/schemas}/plugin.ts +0 -0
- /package/src/database/{schemas → client/schemas}/session.ts +0 -0
- /package/src/database/{schemas → client/schemas}/sessionGroup.ts +0 -0
- /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
|
-
|
|
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
|
|
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();
|
|
@@ -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 {
|
|
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();
|
|
@@ -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
|
|
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
|
-
(
|
|
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(
|
|
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
|
-
(
|
|
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(
|
|
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
|
-
(
|
|
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(
|
|
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
|
-
(
|
|
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
|
-
(
|
|
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
|
|
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
|
|
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
|
File without changes
|
/package/src/database/{core → client/core}/migrations/migrateSettingsToUser/fixtures/input.json
RENAMED
|
File without changes
|
/package/src/database/{core → client/core}/migrations/migrateSettingsToUser/fixtures/output.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|