@lobehub/chat 0.162.25 → 0.163.0
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/.github/workflows/release.yml +21 -2
- package/.github/workflows/sync.yml +1 -1
- package/.github/workflows/test.yml +35 -4
- package/CHANGELOG.md +25 -0
- package/LICENSE +38 -21
- package/codecov.yml +11 -0
- package/drizzle.config.ts +29 -0
- package/next.config.mjs +3 -0
- package/package.json +24 -4
- package/scripts/migrateServerDB/index.ts +30 -0
- package/src/app/(main)/(mobile)/me/(home)/features/useCategory.tsx +2 -1
- package/src/app/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +95 -88
- package/src/app/(main)/chat/settings/features/HeaderContent.tsx +37 -31
- package/src/app/api/webhooks/clerk/__tests__/fixtures/createUser.json +73 -0
- package/src/app/api/webhooks/clerk/route.ts +159 -0
- package/src/app/api/webhooks/clerk/validateRequest.ts +22 -0
- package/src/app/trpc/edge/[trpc]/route.ts +1 -1
- package/src/app/trpc/lambda/[trpc]/route.ts +26 -0
- package/src/config/auth.ts +2 -0
- package/src/config/db.ts +13 -1
- package/src/database/server/core/db.ts +44 -0
- package/src/database/server/core/dbForTest.ts +45 -0
- package/src/database/server/index.ts +1 -0
- package/src/database/server/migrations/0000_init.sql +439 -0
- package/src/database/server/migrations/0001_add_client_id.sql +9 -0
- package/src/database/server/migrations/0002_amusing_puma.sql +9 -0
- package/src/database/server/migrations/meta/0000_snapshot.json +1583 -0
- package/src/database/server/migrations/meta/0001_snapshot.json +1636 -0
- package/src/database/server/migrations/meta/0002_snapshot.json +1630 -0
- package/src/database/server/migrations/meta/_journal.json +27 -0
- package/src/database/server/models/__tests__/file.test.ts +140 -0
- package/src/database/server/models/__tests__/message.test.ts +847 -0
- package/src/database/server/models/__tests__/plugin.test.ts +172 -0
- package/src/database/server/models/__tests__/session.test.ts +595 -0
- package/src/database/server/models/__tests__/topic.test.ts +623 -0
- package/src/database/server/models/__tests__/user.test.ts +173 -0
- package/src/database/server/models/_template.ts +44 -0
- package/src/database/server/models/file.ts +51 -0
- package/src/database/server/models/message.ts +378 -0
- package/src/database/server/models/plugin.ts +63 -0
- package/src/database/server/models/session.ts +290 -0
- package/src/database/server/models/sessionGroup.ts +69 -0
- package/src/database/server/models/topic.ts +265 -0
- package/src/database/server/models/user.ts +138 -0
- package/src/database/server/modules/DataImporter/__tests__/fixtures/messages.json +1101 -0
- package/src/database/server/modules/DataImporter/__tests__/index.test.ts +954 -0
- package/src/database/server/modules/DataImporter/index.ts +333 -0
- package/src/database/server/schemas/_id.ts +15 -0
- package/src/database/server/schemas/lobechat.ts +601 -0
- package/src/database/server/utils/idGenerator.test.ts +39 -0
- package/src/database/server/utils/idGenerator.ts +26 -0
- package/src/features/User/UserPanel/useMenu.tsx +43 -37
- package/src/libs/trpc/client.ts +52 -3
- package/src/server/files/s3.ts +21 -1
- package/src/server/keyVaultsEncrypt/index.test.ts +62 -0
- package/src/server/keyVaultsEncrypt/index.ts +93 -0
- package/src/server/mock.ts +1 -1
- package/src/server/routers/{index.ts → edge/index.ts} +3 -3
- package/src/server/routers/lambda/file.ts +49 -0
- package/src/server/routers/lambda/importer.ts +54 -0
- package/src/server/routers/lambda/index.ts +28 -0
- package/src/server/routers/lambda/message.ts +165 -0
- package/src/server/routers/lambda/plugin.ts +100 -0
- package/src/server/routers/lambda/session.ts +194 -0
- package/src/server/routers/lambda/sessionGroup.ts +77 -0
- package/src/server/routers/lambda/topic.ts +134 -0
- package/src/server/routers/lambda/user.ts +57 -0
- package/src/services/file/index.ts +4 -7
- package/src/services/file/server.ts +45 -0
- package/src/services/import/index.ts +4 -1
- package/src/services/import/server.ts +115 -0
- package/src/services/message/index.ts +4 -8
- package/src/services/message/server.ts +93 -0
- package/src/services/plugin/index.ts +4 -9
- package/src/services/plugin/server.ts +46 -0
- package/src/services/session/index.ts +4 -8
- package/src/services/session/server.ts +148 -0
- package/src/services/topic/index.ts +4 -9
- package/src/services/topic/server.ts +68 -0
- package/src/services/user/index.ts +4 -9
- package/src/services/user/server.ts +28 -0
- package/tests/setup-db.ts +7 -0
- package/vitest.config.ts +2 -1
- package/vitest.server.config.ts +23 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { DefaultErrorShape } from '@trpc/server/unstable-core-do-not-import';
|
|
2
|
+
|
|
3
|
+
import { edgeClient, lambdaClient } from '@/libs/trpc/client';
|
|
4
|
+
import { useUserStore } from '@/store/user';
|
|
5
|
+
import { ImportStage, ImporterEntryData, OnImportCallbacks } from '@/types/importer';
|
|
6
|
+
import { UserSettings } from '@/types/user/settings';
|
|
7
|
+
import { uuid } from '@/utils/uuid';
|
|
8
|
+
|
|
9
|
+
export class ServerService {
|
|
10
|
+
importSettings = async (settings: UserSettings) => {
|
|
11
|
+
await useUserStore.getState().importAppSettings(settings);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
importData = async (data: ImporterEntryData, callbacks?: OnImportCallbacks): Promise<void> => {
|
|
15
|
+
const handleError = (e: unknown) => {
|
|
16
|
+
callbacks?.onStageChange?.(ImportStage.Error);
|
|
17
|
+
const error = e as DefaultErrorShape;
|
|
18
|
+
|
|
19
|
+
callbacks?.onError?.({
|
|
20
|
+
code: error.data.code,
|
|
21
|
+
httpStatus: error.data.httpStatus,
|
|
22
|
+
message: error.message,
|
|
23
|
+
path: error.data.path,
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const totalLength =
|
|
28
|
+
(data.messages?.length || 0) +
|
|
29
|
+
(data.sessionGroups?.length || 0) +
|
|
30
|
+
(data.sessions?.length || 0) +
|
|
31
|
+
(data.topics?.length || 0);
|
|
32
|
+
|
|
33
|
+
if (totalLength < 500) {
|
|
34
|
+
callbacks?.onStageChange?.(ImportStage.Importing);
|
|
35
|
+
const time = Date.now();
|
|
36
|
+
try {
|
|
37
|
+
const result = await lambdaClient.importer.importByPost.mutate({ data });
|
|
38
|
+
const duration = Date.now() - time;
|
|
39
|
+
|
|
40
|
+
callbacks?.onStageChange?.(ImportStage.Success);
|
|
41
|
+
callbacks?.onSuccess?.(result, duration);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
handleError(e);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// if the data is too large, upload it to S3 and upload by file
|
|
50
|
+
const filename = `${uuid()}.json`;
|
|
51
|
+
|
|
52
|
+
const pathname = `import_config/${filename}`;
|
|
53
|
+
|
|
54
|
+
const url = await edgeClient.upload.createS3PreSignedUrl.mutate({ pathname });
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
callbacks?.onStageChange?.(ImportStage.Uploading);
|
|
58
|
+
await this.uploadWithProgress(url, data, callbacks?.onFileUploading);
|
|
59
|
+
} catch {
|
|
60
|
+
throw new Error('Upload Error');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
callbacks?.onStageChange?.(ImportStage.Importing);
|
|
64
|
+
const time = Date.now();
|
|
65
|
+
try {
|
|
66
|
+
const result = await lambdaClient.importer.importByFile.mutate({ pathname });
|
|
67
|
+
const duration = Date.now() - time;
|
|
68
|
+
callbacks?.onStageChange?.(ImportStage.Success);
|
|
69
|
+
callbacks?.onSuccess?.(result, duration);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
handleError(e);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
private uploadWithProgress = async (
|
|
76
|
+
url: string,
|
|
77
|
+
data: object,
|
|
78
|
+
onProgress: OnImportCallbacks['onFileUploading'],
|
|
79
|
+
) => {
|
|
80
|
+
const xhr = new XMLHttpRequest();
|
|
81
|
+
|
|
82
|
+
let startTime = Date.now();
|
|
83
|
+
xhr.upload.addEventListener('progress', (event) => {
|
|
84
|
+
if (event.lengthComputable) {
|
|
85
|
+
const progress = Number(((event.loaded / event.total) * 100).toFixed(1));
|
|
86
|
+
|
|
87
|
+
const speedInByte = event.loaded / ((Date.now() - startTime) / 1000);
|
|
88
|
+
|
|
89
|
+
onProgress?.({
|
|
90
|
+
// if the progress is 100, it means the file is uploaded
|
|
91
|
+
// but the server is still processing it
|
|
92
|
+
// so make it as 99.5 and let users think it's still uploading
|
|
93
|
+
progress: progress === 100 ? 99.5 : progress,
|
|
94
|
+
restTime: (event.total - event.loaded) / speedInByte,
|
|
95
|
+
speed: speedInByte / 1024,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
xhr.open('PUT', url);
|
|
101
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
102
|
+
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
xhr.addEventListener('load', () => {
|
|
105
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
106
|
+
resolve(xhr.response);
|
|
107
|
+
} else {
|
|
108
|
+
reject(xhr.statusText);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
xhr.addEventListener('error', () => reject(xhr.statusText));
|
|
112
|
+
xhr.send(JSON.stringify(data));
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// import { ClientService } from './client';
|
|
4
|
-
//
|
|
5
|
-
// const { ENABLED_SERVER_SERVICE } = getClientConfig();
|
|
6
|
-
//
|
|
7
|
-
// export const messageService = ENABLED_SERVER_SERVICE ? new ServerService() : new ClientService();
|
|
1
|
+
import { isServerMode } from '@/const/version';
|
|
2
|
+
|
|
8
3
|
import { ClientService } from './client';
|
|
4
|
+
import { ServerService } from './server';
|
|
9
5
|
|
|
10
6
|
export type { CreateMessageParams } from './type';
|
|
11
7
|
|
|
12
|
-
export const messageService = new ClientService();
|
|
8
|
+
export const messageService = isServerMode ? new ServerService() : new ClientService();
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import { INBOX_SESSION_ID } from '@/const/session';
|
|
3
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
4
|
+
import { ChatMessage, ChatMessageError, ChatTTS, ChatTranslate } from '@/types/message';
|
|
5
|
+
|
|
6
|
+
import { CreateMessageParams, IMessageService } from './type';
|
|
7
|
+
|
|
8
|
+
export class ServerService implements IMessageService {
|
|
9
|
+
createMessage({ sessionId, ...params }: CreateMessageParams): Promise<string> {
|
|
10
|
+
return lambdaClient.message.createMessage.mutate({
|
|
11
|
+
...params,
|
|
12
|
+
sessionId: this.toDbSessionId(sessionId),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
batchCreateMessages(messages: ChatMessage[]): Promise<any> {
|
|
17
|
+
return lambdaClient.message.batchCreateMessages.mutate(messages);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getMessages(sessionId?: string, topicId?: string | undefined): Promise<ChatMessage[]> {
|
|
21
|
+
return lambdaClient.message.getMessages.query({
|
|
22
|
+
sessionId: this.toDbSessionId(sessionId),
|
|
23
|
+
topicId,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getAllMessages(): Promise<ChatMessage[]> {
|
|
28
|
+
return lambdaClient.message.getAllMessages.query();
|
|
29
|
+
}
|
|
30
|
+
getAllMessagesInSession(sessionId: string): Promise<ChatMessage[]> {
|
|
31
|
+
return lambdaClient.message.getAllMessagesInSession.query({
|
|
32
|
+
sessionId: this.toDbSessionId(sessionId),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
countMessages(): Promise<number> {
|
|
37
|
+
return lambdaClient.message.count.query();
|
|
38
|
+
}
|
|
39
|
+
countTodayMessages(): Promise<number> {
|
|
40
|
+
return lambdaClient.message.countToday.query();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
updateMessageError(id: string, error: ChatMessageError): Promise<any> {
|
|
44
|
+
return lambdaClient.message.update.mutate({ id, value: { error } });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
updateMessage(id: string, message: Partial<ChatMessage>): Promise<any> {
|
|
48
|
+
return lambdaClient.message.update.mutate({ id, value: message });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
updateMessageTranslate(id: string, translate: Partial<ChatTranslate> | false): Promise<any> {
|
|
52
|
+
return lambdaClient.message.updateTranslate.mutate({ id, value: translate as ChatTranslate });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
updateMessageTTS(id: string, tts: Partial<ChatTTS> | false): Promise<any> {
|
|
56
|
+
return lambdaClient.message.updateTTS.mutate({ id, value: tts });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
updateMessagePluginState(id: string, value: any): Promise<any> {
|
|
60
|
+
return lambdaClient.message.updatePluginState.mutate({ id, value });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
bindMessagesToTopic(topicId: string, messageIds: string[]): Promise<any> {
|
|
64
|
+
throw new Error('Method not implemented.');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
removeMessage(id: string): Promise<any> {
|
|
68
|
+
return lambdaClient.message.removeMessage.mutate({ id });
|
|
69
|
+
}
|
|
70
|
+
removeMessages(sessionId: string, topicId?: string | undefined): Promise<any> {
|
|
71
|
+
return lambdaClient.message.removeMessages.mutate({
|
|
72
|
+
sessionId: this.toDbSessionId(sessionId),
|
|
73
|
+
topicId,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
removeAllMessages(): Promise<any> {
|
|
77
|
+
return lambdaClient.message.removeAllMessages.mutate();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private toDbSessionId(sessionId: string | undefined) {
|
|
81
|
+
return sessionId === INBOX_SESSION_ID ? null : sessionId;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async hasMessages() {
|
|
85
|
+
const number = await this.countMessages();
|
|
86
|
+
return number > 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async messageCountToCheckTrace() {
|
|
90
|
+
const number = await this.countMessages();
|
|
91
|
+
return number >= 4;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { ClientService } from './client';
|
|
1
|
+
import { isServerMode } from '@/const/version';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// export type { InstallPluginParams } from './client';
|
|
7
|
-
//
|
|
8
|
-
// const { ENABLED_SERVER_SERVICE } = getClientConfig();
|
|
3
|
+
import { ClientService } from './client';
|
|
4
|
+
import { ServerService } from './server';
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
export const pluginService = new ClientService();
|
|
6
|
+
export const pluginService = isServerMode ? new ServerService() : new ClientService();
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
|
|
3
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
4
|
+
import { LobeTool } from '@/types/tool';
|
|
5
|
+
import { LobeToolCustomPlugin } from '@/types/tool/plugin';
|
|
6
|
+
|
|
7
|
+
import { IPluginService, InstallPluginParams } from './type';
|
|
8
|
+
|
|
9
|
+
export class ServerService implements IPluginService {
|
|
10
|
+
installPlugin = async (plugin: InstallPluginParams) => {
|
|
11
|
+
await lambdaClient.plugin.createOrInstallPlugin.mutate(plugin);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
getInstalledPlugins = (): Promise<LobeTool[]> => {
|
|
15
|
+
return lambdaClient.plugin.getPlugins.query();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
async uninstallPlugin(identifier: string) {
|
|
19
|
+
await lambdaClient.plugin.removePlugin.mutate({ id: identifier });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async createCustomPlugin(customPlugin: LobeToolCustomPlugin) {
|
|
23
|
+
await lambdaClient.plugin.createPlugin.mutate({ ...customPlugin, type: 'customPlugin' });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async updatePlugin(id: string, value: LobeToolCustomPlugin) {
|
|
27
|
+
await lambdaClient.plugin.updatePlugin.mutate({
|
|
28
|
+
customParams: value.customParams,
|
|
29
|
+
id,
|
|
30
|
+
manifest: value.manifest,
|
|
31
|
+
settings: value.settings,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async updatePluginManifest(id: string, manifest: LobeChatPluginManifest) {
|
|
36
|
+
await lambdaClient.plugin.updatePlugin.mutate({ id, manifest });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async removeAllPlugins() {
|
|
40
|
+
await lambdaClient.plugin.removeAllPlugins.mutate();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async updatePluginSettings(id: string, settings: any, signal?: AbortSignal) {
|
|
44
|
+
await lambdaClient.plugin.updatePlugin.mutate({ id, settings }, { signal });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
import { ClientService } from './client';
|
|
4
|
-
|
|
5
|
-
// import { ServerService } from './server';
|
|
1
|
+
import { isServerMode } from '@/const/version';
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
import { ClientService } from './client';
|
|
4
|
+
import { ServerService } from './server';
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
export const sessionService = new ClientService();
|
|
6
|
+
export const sessionService = isServerMode ? new ServerService() : new ClientService();
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import { DeepPartial } from 'utility-types';
|
|
3
|
+
|
|
4
|
+
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
|
5
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
6
|
+
import { useUserStore } from '@/store/user';
|
|
7
|
+
import { authSelectors } from '@/store/user/selectors';
|
|
8
|
+
import { LobeAgentChatConfig, LobeAgentConfig } from '@/types/agent';
|
|
9
|
+
import { MetaData } from '@/types/meta';
|
|
10
|
+
import { BatchTaskResult } from '@/types/service';
|
|
11
|
+
import {
|
|
12
|
+
ChatSessionList,
|
|
13
|
+
LobeAgentSession,
|
|
14
|
+
LobeSessionType,
|
|
15
|
+
LobeSessions,
|
|
16
|
+
SessionGroupId,
|
|
17
|
+
SessionGroupItem,
|
|
18
|
+
SessionGroups,
|
|
19
|
+
} from '@/types/session';
|
|
20
|
+
|
|
21
|
+
import { ISessionService } from './type';
|
|
22
|
+
|
|
23
|
+
export class ServerService implements ISessionService {
|
|
24
|
+
async hasSessions() {
|
|
25
|
+
return (await this.countSessions()) === 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
createSession(type: LobeSessionType, data: Partial<LobeAgentSession>): Promise<string> {
|
|
29
|
+
const { config, group, meta, ...session } = data;
|
|
30
|
+
|
|
31
|
+
return lambdaClient.session.createSession.mutate({
|
|
32
|
+
config: { ...config, ...meta } as any,
|
|
33
|
+
session: { ...session, groupId: group },
|
|
34
|
+
type,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async batchCreateSessions(importSessions: LobeSessions): Promise<BatchTaskResult> {
|
|
39
|
+
// TODO: remove any
|
|
40
|
+
const data = await lambdaClient.session.batchCreateSessions.mutate(importSessions as any);
|
|
41
|
+
console.log(data);
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
cloneSession(id: string, newTitle: string): Promise<string | undefined> {
|
|
46
|
+
return lambdaClient.session.cloneSession.mutate({ id, newTitle });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getGroupedSessions(): Promise<ChatSessionList> {
|
|
50
|
+
return lambdaClient.session.getGroupedSessions.query();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
countSessions(): Promise<number> {
|
|
54
|
+
return lambdaClient.session.countSessions.query();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
updateSession(
|
|
58
|
+
id: string,
|
|
59
|
+
data: Partial<{ group?: SessionGroupId; meta?: any; pinned?: boolean }>,
|
|
60
|
+
): Promise<any> {
|
|
61
|
+
const { group, pinned, meta } = data;
|
|
62
|
+
return lambdaClient.session.updateSession.mutate({
|
|
63
|
+
id,
|
|
64
|
+
value: { groupId: group === 'default' ? null : group, pinned, ...meta },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async getSessionConfig(id: string): Promise<LobeAgentConfig> {
|
|
69
|
+
const isLogin = authSelectors.isLogin(useUserStore.getState());
|
|
70
|
+
if (!isLogin) return DEFAULT_AGENT_CONFIG;
|
|
71
|
+
|
|
72
|
+
// TODO: Need to be fixed
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
return lambdaClient.session.getSessionConfig.query({ id });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
updateSessionConfig(
|
|
78
|
+
id: string,
|
|
79
|
+
config: DeepPartial<LobeAgentConfig>,
|
|
80
|
+
signal?: AbortSignal,
|
|
81
|
+
): Promise<any> {
|
|
82
|
+
return lambdaClient.session.updateSessionConfig.mutate({ id, value: config }, { signal });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
updateSessionMeta(id: string, meta: Partial<MetaData>, signal?: AbortSignal): Promise<any> {
|
|
86
|
+
return lambdaClient.session.updateSessionConfig.mutate({ id, value: meta }, { signal });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
updateSessionChatConfig(
|
|
90
|
+
id: string,
|
|
91
|
+
value: DeepPartial<LobeAgentChatConfig>,
|
|
92
|
+
signal?: AbortSignal,
|
|
93
|
+
): Promise<any> {
|
|
94
|
+
return lambdaClient.session.updateSessionChatConfig.mutate({ id, value }, { signal });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
getSessionsByType(type: 'agent' | 'group' | 'all' = 'all'): Promise<LobeSessions> {
|
|
98
|
+
// TODO: need be fixed
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
return lambdaClient.session.getSessions.query({});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
searchSessions(keywords: string): Promise<LobeSessions> {
|
|
104
|
+
return lambdaClient.session.searchSessions.query({ keywords });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
removeSession(id: string): Promise<any> {
|
|
108
|
+
return lambdaClient.session.removeSession.mutate({ id });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
removeAllSessions(): Promise<any> {
|
|
112
|
+
return lambdaClient.session.removeAllSessions.mutate();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ************************************** //
|
|
116
|
+
// *********** SessionGroup *********** //
|
|
117
|
+
// ************************************** //
|
|
118
|
+
|
|
119
|
+
createSessionGroup(name: string, sort?: number): Promise<string> {
|
|
120
|
+
return lambdaClient.sessionGroup.createSessionGroup.mutate({ name, sort });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
getSessionGroups(): Promise<SessionGroupItem[]> {
|
|
124
|
+
return lambdaClient.sessionGroup.getSessionGroup.query();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
batchCreateSessionGroups(groups: SessionGroups): Promise<BatchTaskResult> {
|
|
128
|
+
return Promise.resolve({ added: 0, ids: [], skips: [], success: true });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
removeSessionGroup(id: string, removeChildren?: boolean): Promise<any> {
|
|
132
|
+
return lambdaClient.sessionGroup.removeSessionGroup.mutate({ id, removeChildren });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
removeSessionGroups(): Promise<any> {
|
|
136
|
+
return lambdaClient.sessionGroup.removeAllSessionGroups.mutate();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
updateSessionGroup(id: string, value: Partial<SessionGroupItem>): Promise<any> {
|
|
140
|
+
// TODO: need be fixed
|
|
141
|
+
// @ts-ignore
|
|
142
|
+
return lambdaClient.sessionGroup.updateSessionGroup.mutate({ id, value });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
updateSessionGroupOrder(sortMap: { id: string; sort: number }[]): Promise<any> {
|
|
146
|
+
return lambdaClient.sessionGroup.updateSessionGroupOrder.mutate({ sortMap });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// import { ClientService } from './client';
|
|
4
|
-
// import { ServerService } from './server';
|
|
5
|
-
//
|
|
6
|
-
// const { ENABLED_SERVER_SERVICE } = getClientConfig();
|
|
7
|
-
//
|
|
8
|
-
// export const topicService = ENABLED_SERVER_SERVICE ? new ServerService() : new ClientService();
|
|
1
|
+
import { isServerMode } from '@/const/version';
|
|
2
|
+
|
|
9
3
|
import { ClientService } from './client';
|
|
4
|
+
import { ServerService } from './server';
|
|
10
5
|
|
|
11
|
-
export const topicService = new ClientService();
|
|
6
|
+
export const topicService = isServerMode ? new ServerService() : new ClientService();
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { INBOX_SESSION_ID } from '@/const/session';
|
|
2
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
3
|
+
import { CreateTopicParams, ITopicService, QueryTopicParams } from '@/services/topic/type';
|
|
4
|
+
import { BatchTaskResult } from '@/types/service';
|
|
5
|
+
import { ChatTopic } from '@/types/topic';
|
|
6
|
+
|
|
7
|
+
export class ServerService implements ITopicService {
|
|
8
|
+
createTopic(params: CreateTopicParams): Promise<string> {
|
|
9
|
+
return lambdaClient.topic.createTopic.mutate({
|
|
10
|
+
...params,
|
|
11
|
+
sessionId: this.toDbSessionId(params.sessionId),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
batchCreateTopics(importTopics: ChatTopic[]): Promise<BatchTaskResult> {
|
|
16
|
+
return lambdaClient.topic.batchCreateTopics.mutate(importTopics);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
cloneTopic(id: string, newTitle?: string | undefined): Promise<string> {
|
|
20
|
+
return lambdaClient.topic.cloneTopic.mutate({ id, newTitle });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getTopics(params: QueryTopicParams): Promise<ChatTopic[]> {
|
|
24
|
+
return lambdaClient.topic.getTopics.query({
|
|
25
|
+
...params,
|
|
26
|
+
sessionId: this.toDbSessionId(params.sessionId),
|
|
27
|
+
}) as any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getAllTopics(): Promise<ChatTopic[]> {
|
|
31
|
+
return lambdaClient.topic.getAllTopics.query() as any;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async countTopics() {
|
|
35
|
+
return lambdaClient.topic.countTopics.query();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
searchTopics(keywords: string, sessionId?: string | undefined): Promise<ChatTopic[]> {
|
|
39
|
+
return lambdaClient.topic.searchTopics.query({
|
|
40
|
+
keywords,
|
|
41
|
+
sessionId: this.toDbSessionId(sessionId),
|
|
42
|
+
}) as any;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
updateTopic(id: string, data: Partial<ChatTopic>): Promise<any> {
|
|
46
|
+
return lambdaClient.topic.updateTopic.mutate({ id, value: data });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
removeTopic(id: string): Promise<any> {
|
|
50
|
+
return lambdaClient.topic.removeTopic.mutate({ id });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
removeTopics(sessionId: string): Promise<any> {
|
|
54
|
+
return lambdaClient.topic.batchDeleteBySessionId.mutate({ id: this.toDbSessionId(sessionId) });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
batchRemoveTopics(topics: string[]): Promise<any> {
|
|
58
|
+
return lambdaClient.topic.batchDelete.mutate({ ids: topics });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
removeAllTopic(): Promise<any> {
|
|
62
|
+
return lambdaClient.topic.removeAllTopics.mutate();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private toDbSessionId(sessionId?: string | null) {
|
|
66
|
+
return sessionId === INBOX_SESSION_ID ? null : sessionId;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// import { ClientService } from './client';
|
|
4
|
-
// import { ServerService } from './server';
|
|
5
|
-
//
|
|
6
|
-
// const { ENABLED_SERVER_SERVICE } = getClientConfig();
|
|
7
|
-
//
|
|
8
|
-
// export const userService = ENABLED_SERVER_SERVICE ? new ServerService() : new ClientService();
|
|
1
|
+
import { isServerMode } from '@/const/version';
|
|
2
|
+
|
|
9
3
|
import { ClientService } from './client';
|
|
4
|
+
import { ServerService } from './server';
|
|
10
5
|
|
|
11
|
-
export const userService = new ClientService();
|
|
6
|
+
export const userService = isServerMode ? new ServerService() : new ClientService();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DeepPartial } from 'utility-types';
|
|
2
|
+
|
|
3
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
4
|
+
import { IUserService } from '@/services/user/type';
|
|
5
|
+
import { UserInitializationState, UserPreference } from '@/types/user';
|
|
6
|
+
import { UserSettings } from '@/types/user/settings';
|
|
7
|
+
|
|
8
|
+
export class ServerService implements IUserService {
|
|
9
|
+
getUserState = async (): Promise<UserInitializationState> => {
|
|
10
|
+
return lambdaClient.user.getUserState.query();
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
async makeUserOnboarded() {
|
|
14
|
+
return lambdaClient.user.makeUserOnboarded.mutate();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async updatePreference(preference: UserPreference) {
|
|
18
|
+
return lambdaClient.user.updatePreference.mutate(preference);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
updateUserSettings = async (value: DeepPartial<UserSettings>, signal?: AbortSignal) => {
|
|
22
|
+
return lambdaClient.user.updateSettings.mutate(value, { signal });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
resetUserSettings = async () => {
|
|
26
|
+
return lambdaClient.user.resetSettings.mutate();
|
|
27
|
+
};
|
|
28
|
+
}
|
package/vitest.config.ts
CHANGED
|
@@ -22,12 +22,13 @@ export default defineConfig({
|
|
|
22
22
|
],
|
|
23
23
|
provider: 'v8',
|
|
24
24
|
reporter: ['text', 'json', 'lcov', 'text-summary'],
|
|
25
|
+
reportsDirectory: './coverage/app',
|
|
25
26
|
},
|
|
26
27
|
deps: {
|
|
27
28
|
inline: ['vitest-canvas-mock'],
|
|
28
29
|
},
|
|
29
|
-
// threads: false,
|
|
30
30
|
environment: 'happy-dom',
|
|
31
|
+
exclude: ['**/node_modules/**', '**/dist/**', '**/build/**', 'src/database/server/**/**'],
|
|
31
32
|
globals: true,
|
|
32
33
|
setupFiles: './tests/setup.ts',
|
|
33
34
|
},
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { defineConfig } from 'vitest/config';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
test: {
|
|
6
|
+
alias: {
|
|
7
|
+
'@': resolve(__dirname, './src'),
|
|
8
|
+
},
|
|
9
|
+
coverage: {
|
|
10
|
+
all: false,
|
|
11
|
+
exclude: ['src/database/server/core/dbForTest.ts'],
|
|
12
|
+
provider: 'v8',
|
|
13
|
+
reporter: ['text', 'json', 'lcov', 'text-summary'],
|
|
14
|
+
reportsDirectory: './coverage/server',
|
|
15
|
+
},
|
|
16
|
+
environment: 'node',
|
|
17
|
+
include: ['src/database/server/**/**/*.test.ts'],
|
|
18
|
+
poolOptions: {
|
|
19
|
+
threads: { singleThread: true },
|
|
20
|
+
},
|
|
21
|
+
setupFiles: './tests/setup-db.ts',
|
|
22
|
+
},
|
|
23
|
+
});
|