@lobehub/lobehub 2.0.0-next.26 → 2.0.0-next.27
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 +25 -0
- package/changelog/v1.json +9 -0
- package/package.json +1 -1
- package/packages/types/src/topic/topic.ts +14 -0
- package/src/server/routers/lambda/topic.ts +7 -1
- package/src/services/aiModel/index.test.ts +3 -3
- package/src/services/aiModel/index.ts +56 -2
- package/src/services/aiProvider/index.test.ts +2 -2
- package/src/services/aiProvider/index.ts +48 -2
- package/src/services/chatGroup/index.ts +66 -2
- package/src/services/export/index.ts +10 -2
- package/src/services/file/index.ts +61 -2
- package/src/services/import/index.ts +133 -2
- package/src/services/message/index.ts +176 -2
- package/src/services/message/{__tests__/server.test.ts → server.test.ts} +3 -3
- package/src/services/plugin/index.test.ts +8 -0
- package/src/services/plugin/index.ts +53 -2
- package/src/services/session/index.test.ts +8 -0
- package/src/services/session/index.ts +145 -2
- package/src/services/thread/index.test.ts +8 -0
- package/src/services/thread/index.ts +38 -2
- package/src/services/topic/index.test.ts +8 -0
- package/src/services/topic/index.ts +76 -2
- package/src/services/user/index.test.ts +8 -0
- package/src/services/user/index.ts +53 -2
- package/src/store/aiInfra/slices/aiModel/action.test.ts +17 -9
- package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +4 -2
- package/src/store/chat/slices/topic/action.test.ts +1 -1
- package/src/store/chat/slices/topic/action.ts +1 -2
- package/src/store/chat/slices/topic/reducer.ts +1 -2
- package/src/store/file/slices/chat/action.ts +1 -4
- package/src/store/file/slices/fileManager/action.ts +2 -3
- package/src/store/session/slices/sessionGroup/action.test.ts +5 -5
- package/src/store/user/slices/common/action.test.ts +1 -1
- package/src/services/aiModel/server.test.ts +0 -122
- package/src/services/aiModel/server.ts +0 -51
- package/src/services/aiModel/type.ts +0 -32
- package/src/services/aiProvider/server.ts +0 -43
- package/src/services/aiProvider/type.ts +0 -27
- package/src/services/chatGroup/server.ts +0 -67
- package/src/services/chatGroup/type.ts +0 -22
- package/src/services/export/server.ts +0 -9
- package/src/services/export/type.ts +0 -5
- package/src/services/file/server.ts +0 -53
- package/src/services/file/type.ts +0 -13
- package/src/services/import/server.ts +0 -133
- package/src/services/import/type.ts +0 -17
- package/src/services/message/server.ts +0 -151
- package/src/services/message/type.ts +0 -55
- package/src/services/plugin/server.ts +0 -42
- package/src/services/plugin/type.ts +0 -23
- package/src/services/session/server.test.ts +0 -260
- package/src/services/session/server.ts +0 -125
- package/src/services/session/type.ts +0 -82
- package/src/services/thread/server.ts +0 -32
- package/src/services/thread/type.ts +0 -21
- package/src/services/topic/server.ts +0 -57
- package/src/services/topic/type.ts +0 -40
- package/src/services/user/server.test.ts +0 -149
- package/src/services/user/server.ts +0 -47
- package/src/services/user/type.ts +0 -21
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.27](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.26...v2.0.0-next.27)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-11-04**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Refactor services to a more clean structure.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Code refactoring
|
|
19
|
+
|
|
20
|
+
- **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))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
## [Version 2.0.0-next.26](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.25...v2.0.0-next.26)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2025-11-04**</sup>
|
package/changelog/v1.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.27",
|
|
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",
|
|
@@ -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
|
+
}
|
|
@@ -128,7 +128,13 @@ export const topicRouter = router({
|
|
|
128
128
|
}),
|
|
129
129
|
|
|
130
130
|
searchTopics: topicProcedure
|
|
131
|
-
.input(
|
|
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 {
|
|
3
|
+
import { AiModelService } from './index';
|
|
4
4
|
|
|
5
|
-
describe('
|
|
6
|
-
testService(
|
|
5
|
+
describe('AiModelService', () => {
|
|
6
|
+
testService(AiModelService);
|
|
7
7
|
});
|
|
@@ -1,3 +1,57 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AiModelSortMap,
|
|
3
|
+
AiProviderModelListItem,
|
|
4
|
+
CreateAiModelParams,
|
|
5
|
+
ToggleAiModelEnableParams,
|
|
6
|
+
UpdateAiModelParams,
|
|
7
|
+
} from 'model-bank';
|
|
2
8
|
|
|
3
|
-
|
|
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,3 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AiProviderDetailItem,
|
|
3
|
+
AiProviderRuntimeState,
|
|
4
|
+
AiProviderSortMap,
|
|
5
|
+
CreateAiProviderParams,
|
|
6
|
+
UpdateAiProviderConfigParams,
|
|
7
|
+
} from '@/types/aiProvider';
|
|
2
8
|
|
|
3
|
-
|
|
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 {
|
|
1
|
+
import {
|
|
2
|
+
ChatGroupAgentItem,
|
|
3
|
+
ChatGroupItem,
|
|
4
|
+
NewChatGroup,
|
|
5
|
+
NewChatGroupAgent,
|
|
6
|
+
} from '@/database/schemas';
|
|
7
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
2
8
|
|
|
3
|
-
|
|
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 {
|
|
1
|
+
import { ExportDatabaseData } from '@/types/export';
|
|
2
2
|
|
|
3
|
-
|
|
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();
|
|
@@ -1,3 +1,62 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
2
|
+
import {
|
|
3
|
+
CheckFileHashResult,
|
|
4
|
+
FileItem,
|
|
5
|
+
QueryFileListParams,
|
|
6
|
+
QueryFileListSchemaType,
|
|
7
|
+
UploadFileParams,
|
|
8
|
+
} from '@/types/files';
|
|
2
9
|
|
|
3
|
-
|
|
10
|
+
interface CreateFileParams extends Omit<UploadFileParams, 'url'> {
|
|
11
|
+
knowledgeBaseId?: string;
|
|
12
|
+
url: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class FileService {
|
|
16
|
+
createFile = async (
|
|
17
|
+
params: UploadFileParams,
|
|
18
|
+
knowledgeBaseId?: string,
|
|
19
|
+
): Promise<{ id: string; url: string }> => {
|
|
20
|
+
return lambdaClient.file.createFile.mutate({ ...params, knowledgeBaseId } as CreateFileParams);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
getFile = async (id: string): Promise<FileItem> => {
|
|
24
|
+
const item = await lambdaClient.file.findById.query({ id });
|
|
25
|
+
|
|
26
|
+
if (!item) {
|
|
27
|
+
throw new Error('file not found');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return { ...item, type: item.fileType };
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
removeFile = async (id: string): Promise<void> => {
|
|
34
|
+
await lambdaClient.file.removeFile.mutate({ id });
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
removeFiles = async (ids: string[]): Promise<void> => {
|
|
38
|
+
await lambdaClient.file.removeFiles.mutate({ ids });
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
removeAllFiles = async () => {
|
|
42
|
+
await lambdaClient.file.removeAllFiles.mutate();
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
getFiles = async (params: QueryFileListParams) => {
|
|
46
|
+
return lambdaClient.file.getFiles.query(params as QueryFileListSchemaType);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
getFileItem = async (id: string) => {
|
|
50
|
+
return lambdaClient.file.getFileItemById.query({ id });
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
checkFileHash = async (hash: string): Promise<CheckFileHashResult> => {
|
|
54
|
+
return lambdaClient.file.checkFileHash.mutate({ hash });
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
removeFileAsyncTask = async (id: string, type: 'embedding' | 'chunk') => {
|
|
58
|
+
return lambdaClient.file.removeFileAsyncTask.mutate({ id, type });
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const fileService = new FileService();
|
|
@@ -1,3 +1,134 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DefaultErrorShape } from '@trpc/server/unstable-core-do-not-import';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
4
|
+
import { uploadService } from '@/services/upload';
|
|
5
|
+
import { useUserStore } from '@/store/user';
|
|
6
|
+
import { ImportPgDataStructure } from '@/types/export';
|
|
7
|
+
import { ImporterEntryData, ImportStage, OnImportCallbacks } from '@/types/importer';
|
|
8
|
+
import { UserSettings } from '@/types/user/settings';
|
|
9
|
+
import { uuid } from '@/utils/uuid';
|
|
10
|
+
|
|
11
|
+
class ImportService {
|
|
12
|
+
importSettings = async (settings: UserSettings): Promise<void> => {
|
|
13
|
+
await useUserStore.getState().importAppSettings(settings);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
importData = async (data: ImporterEntryData, callbacks?: OnImportCallbacks): Promise<void> => {
|
|
17
|
+
const handleError = (e: unknown) => {
|
|
18
|
+
callbacks?.onStageChange?.(ImportStage.Error);
|
|
19
|
+
const error = e as DefaultErrorShape;
|
|
20
|
+
|
|
21
|
+
callbacks?.onError?.({
|
|
22
|
+
code: error.data.code,
|
|
23
|
+
httpStatus: error.data.httpStatus,
|
|
24
|
+
message: error.message,
|
|
25
|
+
path: error.data.path,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const totalLength =
|
|
30
|
+
(data.messages?.length || 0) +
|
|
31
|
+
(data.sessionGroups?.length || 0) +
|
|
32
|
+
(data.sessions?.length || 0) +
|
|
33
|
+
(data.topics?.length || 0);
|
|
34
|
+
|
|
35
|
+
if (totalLength < 500) {
|
|
36
|
+
callbacks?.onStageChange?.(ImportStage.Importing);
|
|
37
|
+
const time = Date.now();
|
|
38
|
+
try {
|
|
39
|
+
const result = await lambdaClient.importer.importByPost.mutate({ data });
|
|
40
|
+
const duration = Date.now() - time;
|
|
41
|
+
|
|
42
|
+
callbacks?.onStageChange?.(ImportStage.Success);
|
|
43
|
+
callbacks?.onSuccess?.(result.results, duration);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
handleError(e);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await this.uploadData(data, { callbacks, handleError });
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
importPgData = async (
|
|
55
|
+
data: ImportPgDataStructure,
|
|
56
|
+
options?: {
|
|
57
|
+
callbacks?: OnImportCallbacks;
|
|
58
|
+
overwriteExisting?: boolean;
|
|
59
|
+
},
|
|
60
|
+
): Promise<void> => {
|
|
61
|
+
const { callbacks } = options || {};
|
|
62
|
+
|
|
63
|
+
const handleError = (e: unknown) => {
|
|
64
|
+
callbacks?.onStageChange?.(ImportStage.Error);
|
|
65
|
+
const error = e as DefaultErrorShape;
|
|
66
|
+
|
|
67
|
+
callbacks?.onError?.({
|
|
68
|
+
code: error.data.code,
|
|
69
|
+
httpStatus: error.data.httpStatus,
|
|
70
|
+
message: error.message,
|
|
71
|
+
path: error.data.path,
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const totalLength = Object.values(data.data)
|
|
76
|
+
.map((d) => d.length)
|
|
77
|
+
.reduce((a, b) => a + b, 0);
|
|
78
|
+
|
|
79
|
+
if (totalLength < 500) {
|
|
80
|
+
callbacks?.onStageChange?.(ImportStage.Importing);
|
|
81
|
+
const time = Date.now();
|
|
82
|
+
try {
|
|
83
|
+
const result = await lambdaClient.importer.importPgByPost.mutate(data);
|
|
84
|
+
const duration = Date.now() - time;
|
|
85
|
+
|
|
86
|
+
callbacks?.onStageChange?.(ImportStage.Success);
|
|
87
|
+
callbacks?.onSuccess?.(result.results, duration);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
handleError(e);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
await this.uploadData(data, { callbacks, handleError });
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
private uploadData = async (
|
|
99
|
+
data: object,
|
|
100
|
+
{ callbacks, handleError }: { callbacks?: OnImportCallbacks; handleError: (e: unknown) => any },
|
|
101
|
+
) => {
|
|
102
|
+
// if the data is too large, upload it to S3 and upload by file
|
|
103
|
+
const filename = `${uuid()}.json`;
|
|
104
|
+
|
|
105
|
+
let pathname;
|
|
106
|
+
try {
|
|
107
|
+
callbacks?.onStageChange?.(ImportStage.Uploading);
|
|
108
|
+
const result = await uploadService.uploadDataToS3(data, {
|
|
109
|
+
filename,
|
|
110
|
+
onProgress: (status, state) => {
|
|
111
|
+
callbacks?.onFileUploading?.(state);
|
|
112
|
+
},
|
|
113
|
+
pathname: `import_config/${filename}`,
|
|
114
|
+
});
|
|
115
|
+
pathname = result.data.path;
|
|
116
|
+
console.log(pathname);
|
|
117
|
+
} catch {
|
|
118
|
+
throw new Error('Upload Error');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
callbacks?.onStageChange?.(ImportStage.Importing);
|
|
122
|
+
const time = Date.now();
|
|
123
|
+
try {
|
|
124
|
+
const result = await lambdaClient.importer.importByFile.mutate({ pathname });
|
|
125
|
+
const duration = Date.now() - time;
|
|
126
|
+
callbacks?.onStageChange?.(ImportStage.Success);
|
|
127
|
+
callbacks?.onSuccess?.(result.results, duration);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
handleError(e);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const importService = new ImportService();
|
|
@@ -1,3 +1,177 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
+
import {
|
|
3
|
+
ChatMessageError,
|
|
4
|
+
ChatMessagePluginError,
|
|
5
|
+
ChatTranslate,
|
|
6
|
+
ChatTTS,
|
|
7
|
+
CreateMessageParams,
|
|
8
|
+
CreateMessageResult,
|
|
9
|
+
ModelRankItem,
|
|
10
|
+
UIChatMessage,
|
|
11
|
+
UpdateMessageParams,
|
|
12
|
+
UpdateMessageRAGParams,
|
|
13
|
+
UpdateMessageResult,
|
|
14
|
+
} from '@lobechat/types';
|
|
15
|
+
import type { HeatmapsProps } from '@lobehub/charts';
|
|
2
16
|
|
|
3
|
-
|
|
17
|
+
import { INBOX_SESSION_ID } from '@/const/session';
|
|
18
|
+
import { lambdaClient } from '@/libs/trpc/client';
|
|
19
|
+
import { useUserStore } from '@/store/user';
|
|
20
|
+
import { labPreferSelectors } from '@/store/user/selectors';
|
|
21
|
+
|
|
22
|
+
export class MessageService {
|
|
23
|
+
createMessage = async ({ sessionId, ...params }: CreateMessageParams): Promise<string> => {
|
|
24
|
+
return lambdaClient.message.createMessage.mutate({
|
|
25
|
+
...params,
|
|
26
|
+
sessionId: sessionId ? this.toDbSessionId(sessionId) : undefined,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
createNewMessage = async ({
|
|
31
|
+
sessionId,
|
|
32
|
+
...params
|
|
33
|
+
}: CreateMessageParams): Promise<CreateMessageResult> => {
|
|
34
|
+
return lambdaClient.message.createNewMessage.mutate({
|
|
35
|
+
...params,
|
|
36
|
+
sessionId: sessionId ? this.toDbSessionId(sessionId) : undefined,
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
getMessages = async (
|
|
41
|
+
sessionId: string,
|
|
42
|
+
topicId?: string,
|
|
43
|
+
groupId?: string,
|
|
44
|
+
): Promise<UIChatMessage[]> => {
|
|
45
|
+
// Get user lab preference for message grouping
|
|
46
|
+
const useGroup = labPreferSelectors.enableAssistantMessageGroup(useUserStore.getState());
|
|
47
|
+
|
|
48
|
+
const data = await lambdaClient.message.getMessages.query({
|
|
49
|
+
groupId,
|
|
50
|
+
sessionId: this.toDbSessionId(sessionId),
|
|
51
|
+
topicId,
|
|
52
|
+
useGroup,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return data as unknown as UIChatMessage[];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
getGroupMessages = async (groupId: string, topicId?: string): Promise<UIChatMessage[]> => {
|
|
59
|
+
// Get user lab preference for message grouping
|
|
60
|
+
const useGroup = labPreferSelectors.enableAssistantMessageGroup(useUserStore.getState());
|
|
61
|
+
|
|
62
|
+
const data = await lambdaClient.message.getMessages.query({
|
|
63
|
+
groupId,
|
|
64
|
+
topicId,
|
|
65
|
+
useGroup,
|
|
66
|
+
});
|
|
67
|
+
return data as unknown as UIChatMessage[];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
countMessages = async (params?: {
|
|
71
|
+
endDate?: string;
|
|
72
|
+
range?: [string, string];
|
|
73
|
+
startDate?: string;
|
|
74
|
+
}): Promise<number> => {
|
|
75
|
+
return lambdaClient.message.count.query(params);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
countWords = async (params?: {
|
|
79
|
+
endDate?: string;
|
|
80
|
+
range?: [string, string];
|
|
81
|
+
startDate?: string;
|
|
82
|
+
}): Promise<number> => {
|
|
83
|
+
return lambdaClient.message.countWords.query(params);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
rankModels = async (): Promise<ModelRankItem[]> => {
|
|
87
|
+
return lambdaClient.message.rankModels.query();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
getHeatmaps = async (): Promise<HeatmapsProps['data']> => {
|
|
91
|
+
return lambdaClient.message.getHeatmaps.query();
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
updateMessageError = async (id: string, error: ChatMessageError) => {
|
|
95
|
+
return lambdaClient.message.update.mutate({ id, value: { error } });
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
updateMessagePluginArguments = async (id: string, value: string | Record<string, any>) => {
|
|
99
|
+
const args = typeof value === 'string' ? value : JSON.stringify(value);
|
|
100
|
+
return lambdaClient.message.updateMessagePlugin.mutate({ id, value: { arguments: args } });
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
updateMessage = async (
|
|
104
|
+
id: string,
|
|
105
|
+
value: Partial<UpdateMessageParams>,
|
|
106
|
+
options?: { sessionId?: string | null; topicId?: string | null },
|
|
107
|
+
): Promise<UpdateMessageResult> => {
|
|
108
|
+
return lambdaClient.message.update.mutate({
|
|
109
|
+
id,
|
|
110
|
+
sessionId: options?.sessionId,
|
|
111
|
+
topicId: options?.topicId,
|
|
112
|
+
value,
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
updateMessageTranslate = async (id: string, translate: Partial<ChatTranslate> | false) => {
|
|
117
|
+
return lambdaClient.message.updateTranslate.mutate({ id, value: translate as ChatTranslate });
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
updateMessageTTS = async (id: string, tts: Partial<ChatTTS> | false) => {
|
|
121
|
+
return lambdaClient.message.updateTTS.mutate({ id, value: tts });
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
updateMessagePluginState = async (id: string, value: Record<string, any>) => {
|
|
125
|
+
return lambdaClient.message.updatePluginState.mutate({ id, value });
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
updateMessagePluginError = async (id: string, error: ChatMessagePluginError | null) => {
|
|
129
|
+
return lambdaClient.message.updatePluginError.mutate({ id, value: error as any });
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
updateMessageRAG = async (id: string, data: UpdateMessageRAGParams): Promise<void> => {
|
|
133
|
+
return lambdaClient.message.updateMessageRAG.mutate({ id, value: data });
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
removeMessage = async (id: string) => {
|
|
137
|
+
return lambdaClient.message.removeMessage.mutate({ id });
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
removeMessages = async (ids: string[]) => {
|
|
141
|
+
return lambdaClient.message.removeMessages.mutate({ ids });
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
removeMessagesByAssistant = async (sessionId: string, topicId?: string) => {
|
|
145
|
+
return lambdaClient.message.removeMessagesByAssistant.mutate({
|
|
146
|
+
sessionId: this.toDbSessionId(sessionId),
|
|
147
|
+
topicId,
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
removeMessagesByGroup = async (groupId: string, topicId?: string) => {
|
|
152
|
+
return lambdaClient.message.removeMessagesByGroup.mutate({
|
|
153
|
+
groupId,
|
|
154
|
+
topicId,
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
removeAllMessages = async () => {
|
|
159
|
+
return lambdaClient.message.removeAllMessages.mutate();
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
private toDbSessionId = (sessionId: string | undefined) => {
|
|
163
|
+
return sessionId === INBOX_SESSION_ID ? null : sessionId;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
hasMessages = async (): Promise<boolean> => {
|
|
167
|
+
const number = await this.countMessages();
|
|
168
|
+
return number > 0;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
messageCountToCheckTrace = async (): Promise<boolean> => {
|
|
172
|
+
const number = await this.countMessages();
|
|
173
|
+
return number >= 4;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export const messageService = new MessageService();
|