@lobehub/chat 1.36.30 → 1.36.32
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/changelog/v1.json +18 -0
- package/docs/self-hosting/environment-variables/model-provider.mdx +7 -0
- package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +7 -0
- package/docs/self-hosting/server-database/dokploy.zh-CN.mdx +12 -12
- package/package.json +1 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/Content.tsx +3 -9
- package/src/app/(main)/chat/(workspace)/@conversation/features/ThreadHydration.tsx +2 -4
- package/src/app/(main)/chat/@session/features/SessionListContent/DefaultMode.tsx +2 -5
- package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InstallPlugin.tsx +10 -15
- package/src/database/repositories/dataImporter/__tests__/index.test.ts +11 -18
- package/src/database/repositories/dataImporter/index.ts +31 -46
- package/src/database/server/models/__tests__/_test_template.ts +1 -1
- package/src/database/server/models/__tests__/agent.test.ts +1 -1
- package/src/database/server/models/__tests__/asyncTask.test.ts +1 -1
- package/src/database/server/models/__tests__/chunk.test.ts +1 -1
- package/src/database/server/models/__tests__/file.test.ts +1 -1
- package/src/database/server/models/__tests__/knowledgeBase.test.ts +1 -2
- package/src/database/server/models/__tests__/message.test.ts +35 -72
- package/src/database/server/models/__tests__/nextauth.test.ts +1 -1
- package/src/database/server/models/__tests__/session.test.ts +1 -1
- package/src/database/server/models/__tests__/sessionGroup.test.ts +1 -2
- package/src/database/server/models/__tests__/topic.test.ts +1 -1
- package/src/database/server/models/__tests__/user.test.ts +1 -1
- package/src/database/server/models/_template.ts +2 -2
- package/src/database/server/models/agent.ts +17 -25
- package/src/database/server/models/asyncTask.ts +2 -2
- package/src/database/server/models/chunk.ts +14 -14
- package/src/database/server/models/embedding.ts +1 -1
- package/src/database/server/models/file.ts +8 -10
- package/src/database/server/models/knowledgeBase.ts +4 -6
- package/src/database/server/models/message.ts +54 -65
- package/src/database/server/models/plugin.ts +6 -2
- package/src/database/server/models/ragEval/dataset.ts +2 -2
- package/src/database/server/models/ragEval/datasetRecord.ts +3 -8
- package/src/database/server/models/ragEval/evaluation.ts +3 -2
- package/src/database/server/models/ragEval/evaluationRecord.ts +2 -2
- package/src/database/server/models/session.ts +40 -35
- package/src/database/server/models/sessionGroup.ts +4 -4
- package/src/database/server/models/thread.ts +2 -2
- package/src/database/server/models/topic.ts +48 -53
- package/src/database/server/models/user.ts +12 -12
- package/src/features/AgentSetting/AgentPlugin/index.tsx +1 -1
- package/src/features/ChatInput/ActionBar/Tools/Dropdown.tsx +4 -4
- package/src/features/Portal/Thread/Chat/ChatList.tsx +1 -2
- package/src/hooks/useCheckPluginsIsInstalled.ts +10 -0
- package/src/hooks/useFetchInstalledPlugins.ts +10 -0
- package/src/hooks/useFetchMessages.ts +15 -0
- package/src/hooks/useFetchSessions.ts +13 -0
- package/src/hooks/useFetchThreads.ts +11 -0
- package/src/hooks/useFetchTopics.ts +6 -6
- package/src/layout/GlobalProvider/StoreInitialization.tsx +3 -1
- package/src/libs/agent-runtime/utils/streams/azureOpenai.test.ts +0 -1
- package/src/libs/next-auth/adapter/index.ts +1 -1
- package/src/server/routers/lambda/chunk.ts +2 -2
- package/src/services/user/client.ts +2 -2
- package/src/store/agent/slices/chat/action.test.ts +21 -10
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +10 -0
- package/src/store/chat/slices/builtinTool/action.ts +0 -1
- package/src/store/chat/slices/message/action.test.ts +3 -1
- package/src/store/chat/slices/message/action.ts +7 -3
- package/src/store/chat/slices/thread/action.ts +3 -3
- package/src/store/chat/slices/topic/action.test.ts +1 -1
- package/src/store/chat/slices/topic/action.ts +3 -3
- package/src/store/global/selectors.ts +6 -0
- package/src/store/session/slices/session/action.ts +6 -3
- package/src/store/session/slices/sessionGroup/action.test.ts +8 -6
- package/src/store/tool/slices/plugin/action.ts +5 -3
- package/src/store/tool/slices/store/action.ts +4 -3
- package/src/store/user/slices/common/action.test.ts +3 -1
- package/vercel.json +1 -1
@@ -1,4 +1,4 @@
|
|
1
|
-
import { eq } from 'drizzle-orm';
|
1
|
+
import { eq } from 'drizzle-orm/expressions';
|
2
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
3
3
|
|
4
4
|
import { getTestDBInstance } from '@/database/server/core/dbForTest';
|
@@ -514,11 +514,7 @@ describe('MessageModel', () => {
|
|
514
514
|
await messageModel.create({ role: 'user', content: 'new message', sessionId: '1' });
|
515
515
|
|
516
516
|
// 断言结果
|
517
|
-
const result = await serverDB
|
518
|
-
.select()
|
519
|
-
.from(messages)
|
520
|
-
.where(eq(messages.userId, userId))
|
521
|
-
.execute();
|
517
|
+
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
522
518
|
expect(result).toHaveLength(1);
|
523
519
|
expect(result[0].content).toBe('new message');
|
524
520
|
});
|
@@ -549,11 +545,7 @@ describe('MessageModel', () => {
|
|
549
545
|
});
|
550
546
|
|
551
547
|
// 断言结果
|
552
|
-
const result = await serverDB
|
553
|
-
.select()
|
554
|
-
.from(messages)
|
555
|
-
.where(eq(messages.userId, userId))
|
556
|
-
.execute();
|
548
|
+
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
557
549
|
expect(result[0].id).toBeDefined();
|
558
550
|
expect(result[0].id).toHaveLength(18);
|
559
551
|
});
|
@@ -582,8 +574,7 @@ describe('MessageModel', () => {
|
|
582
574
|
const pluginResult = await serverDB
|
583
575
|
.select()
|
584
576
|
.from(messagePlugins)
|
585
|
-
.where(eq(messagePlugins.id, result.id))
|
586
|
-
.execute();
|
577
|
+
.where(eq(messagePlugins.id, result.id));
|
587
578
|
expect(pluginResult).toHaveLength(1);
|
588
579
|
expect(pluginResult[0].identifier).toBe('plugin1');
|
589
580
|
});
|
@@ -650,8 +641,7 @@ describe('MessageModel', () => {
|
|
650
641
|
const pluginResult = await serverDB
|
651
642
|
.select()
|
652
643
|
.from(messagePlugins)
|
653
|
-
.where(eq(messagePlugins.id, result.id))
|
654
|
-
.execute();
|
644
|
+
.where(eq(messagePlugins.id, result.id));
|
655
645
|
expect(pluginResult).toHaveLength(1);
|
656
646
|
expect(pluginResult[0].identifier).toBe('lobe-web-browsing');
|
657
647
|
expect(pluginResult[0].state!).toMatchObject(state);
|
@@ -670,11 +660,7 @@ describe('MessageModel', () => {
|
|
670
660
|
await messageModel.batchCreate(newMessages);
|
671
661
|
|
672
662
|
// 断言结果
|
673
|
-
const result = await serverDB
|
674
|
-
.select()
|
675
|
-
.from(messages)
|
676
|
-
.where(eq(messages.userId, userId))
|
677
|
-
.execute();
|
663
|
+
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
678
664
|
expect(result).toHaveLength(2);
|
679
665
|
expect(result[0].content).toBe('message 1');
|
680
666
|
expect(result[1].content).toBe('message 2');
|
@@ -692,7 +678,7 @@ describe('MessageModel', () => {
|
|
692
678
|
await messageModel.update('1', { content: 'updated message' });
|
693
679
|
|
694
680
|
// 断言结果
|
695
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
681
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
696
682
|
expect(result[0].content).toBe('updated message');
|
697
683
|
});
|
698
684
|
|
@@ -706,7 +692,7 @@ describe('MessageModel', () => {
|
|
706
692
|
await messageModel.update('1', { content: 'updated message' });
|
707
693
|
|
708
694
|
// 断言结果
|
709
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
695
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
710
696
|
expect(result[0].content).toBe('message 1');
|
711
697
|
});
|
712
698
|
|
@@ -745,7 +731,7 @@ describe('MessageModel', () => {
|
|
745
731
|
});
|
746
732
|
|
747
733
|
// 断言结果
|
748
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
734
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
749
735
|
expect(result[0].tools[0].arguments).toBe(
|
750
736
|
'{"query":"2024 杭州暴雨","searchEngines":["duckduckgo","google","brave"]}',
|
751
737
|
);
|
@@ -763,7 +749,7 @@ describe('MessageModel', () => {
|
|
763
749
|
await messageModel.deleteMessage('1');
|
764
750
|
|
765
751
|
// 断言结果
|
766
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
752
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
767
753
|
expect(result).toHaveLength(0);
|
768
754
|
});
|
769
755
|
|
@@ -783,14 +769,13 @@ describe('MessageModel', () => {
|
|
783
769
|
await messageModel.deleteMessage('1');
|
784
770
|
|
785
771
|
// 断言结果
|
786
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
772
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
787
773
|
expect(result).toHaveLength(0);
|
788
774
|
|
789
775
|
const result2 = await serverDB
|
790
776
|
.select()
|
791
777
|
.from(messagePlugins)
|
792
|
-
.where(eq(messagePlugins.id, '2'))
|
793
|
-
.execute();
|
778
|
+
.where(eq(messagePlugins.id, '2'));
|
794
779
|
|
795
780
|
expect(result2).toHaveLength(0);
|
796
781
|
});
|
@@ -805,7 +790,7 @@ describe('MessageModel', () => {
|
|
805
790
|
await messageModel.deleteMessage('1');
|
806
791
|
|
807
792
|
// 断言结果
|
808
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
793
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
809
794
|
expect(result).toHaveLength(1);
|
810
795
|
});
|
811
796
|
});
|
@@ -822,9 +807,9 @@ describe('MessageModel', () => {
|
|
822
807
|
await messageModel.deleteMessages(['1', '2']);
|
823
808
|
|
824
809
|
// 断言结果
|
825
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
810
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
826
811
|
expect(result).toHaveLength(0);
|
827
|
-
const result2 = await serverDB.select().from(messages).where(eq(messages.id, '2'))
|
812
|
+
const result2 = await serverDB.select().from(messages).where(eq(messages.id, '2'));
|
828
813
|
expect(result2).toHaveLength(0);
|
829
814
|
});
|
830
815
|
|
@@ -839,7 +824,7 @@ describe('MessageModel', () => {
|
|
839
824
|
await messageModel.deleteMessages(['1', '2']);
|
840
825
|
|
841
826
|
// 断言结果
|
842
|
-
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'))
|
827
|
+
const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
|
843
828
|
expect(result).toHaveLength(1);
|
844
829
|
});
|
845
830
|
});
|
@@ -857,18 +842,12 @@ describe('MessageModel', () => {
|
|
857
842
|
await messageModel.deleteAllMessages();
|
858
843
|
|
859
844
|
// 断言结果
|
860
|
-
const result = await serverDB
|
861
|
-
|
862
|
-
.from(messages)
|
863
|
-
.where(eq(messages.userId, userId))
|
864
|
-
.execute();
|
845
|
+
const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
|
846
|
+
|
865
847
|
expect(result).toHaveLength(0);
|
866
848
|
|
867
|
-
const otherResult = await serverDB
|
868
|
-
|
869
|
-
.from(messages)
|
870
|
-
.where(eq(messages.userId, '456'))
|
871
|
-
.execute();
|
849
|
+
const otherResult = await serverDB.select().from(messages).where(eq(messages.userId, '456'));
|
850
|
+
|
872
851
|
expect(otherResult).toHaveLength(1);
|
873
852
|
});
|
874
853
|
});
|
@@ -887,11 +866,8 @@ describe('MessageModel', () => {
|
|
887
866
|
await messageModel.updatePluginState('1', { key2: 'value2' });
|
888
867
|
|
889
868
|
// 断言结果
|
890
|
-
const result = await serverDB
|
891
|
-
|
892
|
-
.from(messagePlugins)
|
893
|
-
.where(eq(messagePlugins.id, '1'))
|
894
|
-
.execute();
|
869
|
+
const result = await serverDB.select().from(messagePlugins).where(eq(messagePlugins.id, '1'));
|
870
|
+
|
895
871
|
expect(result[0].state).toEqual({ key1: 'value1', key2: 'value2' });
|
896
872
|
});
|
897
873
|
|
@@ -916,11 +892,8 @@ describe('MessageModel', () => {
|
|
916
892
|
await messageModel.updateMessagePlugin('1', { identifier: 'plugin2' });
|
917
893
|
|
918
894
|
// 断言结果
|
919
|
-
const result = await serverDB
|
920
|
-
|
921
|
-
.from(messagePlugins)
|
922
|
-
.where(eq(messagePlugins.id, '1'))
|
923
|
-
.execute();
|
895
|
+
const result = await serverDB.select().from(messagePlugins).where(eq(messagePlugins.id, '1'));
|
896
|
+
|
924
897
|
expect(result[0].identifier).toEqual('plugin2');
|
925
898
|
});
|
926
899
|
|
@@ -950,8 +923,8 @@ describe('MessageModel', () => {
|
|
950
923
|
const result = await serverDB
|
951
924
|
.select()
|
952
925
|
.from(messageTranslates)
|
953
|
-
.where(eq(messageTranslates.id, '1'))
|
954
|
-
|
926
|
+
.where(eq(messageTranslates.id, '1'));
|
927
|
+
|
955
928
|
expect(result).toHaveLength(1);
|
956
929
|
expect(result[0].content).toBe('translated message 1');
|
957
930
|
});
|
@@ -974,8 +947,8 @@ describe('MessageModel', () => {
|
|
974
947
|
const result = await serverDB
|
975
948
|
.select()
|
976
949
|
.from(messageTranslates)
|
977
|
-
.where(eq(messageTranslates.id, '1'))
|
978
|
-
|
950
|
+
.where(eq(messageTranslates.id, '1'));
|
951
|
+
|
979
952
|
expect(result[0].content).toBe('updated translated message 1');
|
980
953
|
});
|
981
954
|
});
|
@@ -991,11 +964,8 @@ describe('MessageModel', () => {
|
|
991
964
|
await messageModel.updateTTS('1', { contentMd5: 'md5', file: 'f1', voice: 'voice1' });
|
992
965
|
|
993
966
|
// 断言结果
|
994
|
-
const result = await serverDB
|
995
|
-
|
996
|
-
.from(messageTTS)
|
997
|
-
.where(eq(messageTTS.id, '1'))
|
998
|
-
.execute();
|
967
|
+
const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
|
968
|
+
|
999
969
|
expect(result).toHaveLength(1);
|
1000
970
|
expect(result[0].voice).toBe('voice1');
|
1001
971
|
});
|
@@ -1015,11 +985,8 @@ describe('MessageModel', () => {
|
|
1015
985
|
await messageModel.updateTTS('1', { voice: 'updated voice1' });
|
1016
986
|
|
1017
987
|
// 断言结果
|
1018
|
-
const result = await serverDB
|
1019
|
-
|
1020
|
-
.from(messageTTS)
|
1021
|
-
.where(eq(messageTTS.id, '1'))
|
1022
|
-
.execute();
|
988
|
+
const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
|
989
|
+
|
1023
990
|
expect(result[0].voice).toBe('updated voice1');
|
1024
991
|
});
|
1025
992
|
});
|
@@ -1037,8 +1004,8 @@ describe('MessageModel', () => {
|
|
1037
1004
|
const result = await serverDB
|
1038
1005
|
.select()
|
1039
1006
|
.from(messageTranslates)
|
1040
|
-
.where(eq(messageTranslates.id, '1'))
|
1041
|
-
|
1007
|
+
.where(eq(messageTranslates.id, '1'));
|
1008
|
+
|
1042
1009
|
expect(result).toHaveLength(0);
|
1043
1010
|
});
|
1044
1011
|
});
|
@@ -1053,11 +1020,7 @@ describe('MessageModel', () => {
|
|
1053
1020
|
await messageModel.deleteMessageTTS('1');
|
1054
1021
|
|
1055
1022
|
// 断言结果
|
1056
|
-
const result = await serverDB
|
1057
|
-
.select()
|
1058
|
-
.from(messageTTS)
|
1059
|
-
.where(eq(messageTTS.id, '1'))
|
1060
|
-
.execute();
|
1023
|
+
const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
|
1061
1024
|
expect(result).toHaveLength(0);
|
1062
1025
|
});
|
1063
1026
|
});
|
@@ -5,7 +5,7 @@ import type {
|
|
5
5
|
AdapterUser,
|
6
6
|
VerificationToken,
|
7
7
|
} from '@auth/core/adapters';
|
8
|
-
import { eq } from 'drizzle-orm';
|
8
|
+
import { eq } from 'drizzle-orm/expressions';
|
9
9
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
10
10
|
|
11
11
|
import {
|
@@ -1,6 +1,5 @@
|
|
1
1
|
// @vitest-environment node
|
2
|
-
import { eq } from 'drizzle-orm';
|
3
|
-
import { desc } from 'drizzle-orm/expressions';
|
2
|
+
import { eq } from 'drizzle-orm/expressions';
|
4
3
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
5
4
|
|
6
5
|
import { getTestDBInstance } from '@/database/server/core/dbForTest';
|
@@ -45,10 +45,10 @@ export class TemplateModel {
|
|
45
45
|
});
|
46
46
|
};
|
47
47
|
|
48
|
-
async
|
48
|
+
update = async (id: string, value: Partial<SessionGroupItem>) => {
|
49
49
|
return this.db
|
50
50
|
.update(sessionGroups)
|
51
51
|
.set({ ...value, updatedAt: new Date() })
|
52
52
|
.where(and(eq(sessionGroups.id, id), eq(sessionGroups.userId, this.userId)));
|
53
|
-
}
|
53
|
+
};
|
54
54
|
}
|
@@ -19,15 +19,15 @@ export class AgentModel {
|
|
19
19
|
this.db = db;
|
20
20
|
}
|
21
21
|
|
22
|
-
async
|
22
|
+
getAgentConfigById = async (id: string) => {
|
23
23
|
const agent = await this.db.query.agents.findFirst({ where: eq(agents.id, id) });
|
24
24
|
|
25
25
|
const knowledge = await this.getAgentAssignedKnowledge(id);
|
26
26
|
|
27
27
|
return { ...agent, ...knowledge };
|
28
|
-
}
|
28
|
+
};
|
29
29
|
|
30
|
-
async
|
30
|
+
getAgentAssignedKnowledge = async (id: string) => {
|
31
31
|
const knowledgeBaseResult = await this.db
|
32
32
|
.select({ enabled: agentsKnowledgeBases.enabled, knowledgeBases })
|
33
33
|
.from(agentsKnowledgeBases)
|
@@ -52,12 +52,12 @@ export class AgentModel {
|
|
52
52
|
enabled: item.enabled,
|
53
53
|
})),
|
54
54
|
};
|
55
|
-
}
|
55
|
+
};
|
56
56
|
|
57
57
|
/**
|
58
58
|
* Find agent by session id
|
59
59
|
*/
|
60
|
-
async
|
60
|
+
findBySessionId = async (sessionId: string) => {
|
61
61
|
const item = await this.db.query.agentsToSessions.findFirst({
|
62
62
|
where: eq(agentsToSessions.sessionId, sessionId),
|
63
63
|
});
|
@@ -66,22 +66,19 @@ export class AgentModel {
|
|
66
66
|
const agentId = item.agentId;
|
67
67
|
|
68
68
|
return this.getAgentConfigById(agentId);
|
69
|
-
}
|
69
|
+
};
|
70
70
|
|
71
71
|
createAgentKnowledgeBase = async (
|
72
72
|
agentId: string,
|
73
73
|
knowledgeBaseId: string,
|
74
74
|
enabled: boolean = true,
|
75
75
|
) => {
|
76
|
-
return this.db
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
userId: this.userId,
|
83
|
-
})
|
84
|
-
.execute();
|
76
|
+
return this.db.insert(agentsKnowledgeBases).values({
|
77
|
+
agentId,
|
78
|
+
enabled,
|
79
|
+
knowledgeBaseId,
|
80
|
+
userId: this.userId,
|
81
|
+
});
|
85
82
|
};
|
86
83
|
|
87
84
|
deleteAgentKnowledgeBase = async (agentId: string, knowledgeBaseId: string) => {
|
@@ -93,8 +90,7 @@ export class AgentModel {
|
|
93
90
|
eq(agentsKnowledgeBases.knowledgeBaseId, knowledgeBaseId),
|
94
91
|
eq(agentsKnowledgeBases.userId, this.userId),
|
95
92
|
),
|
96
|
-
)
|
97
|
-
.execute();
|
93
|
+
);
|
98
94
|
};
|
99
95
|
|
100
96
|
toggleKnowledgeBase = async (agentId: string, knowledgeBaseId: string, enabled?: boolean) => {
|
@@ -107,8 +103,7 @@ export class AgentModel {
|
|
107
103
|
eq(agentsKnowledgeBases.knowledgeBaseId, knowledgeBaseId),
|
108
104
|
eq(agentsKnowledgeBases.userId, this.userId),
|
109
105
|
),
|
110
|
-
)
|
111
|
-
.execute();
|
106
|
+
);
|
112
107
|
};
|
113
108
|
|
114
109
|
createAgentFiles = async (agentId: string, fileIds: string[], enabled: boolean = true) => {
|
@@ -134,8 +129,7 @@ export class AgentModel {
|
|
134
129
|
.insert(agentsFiles)
|
135
130
|
.values(
|
136
131
|
needToInsertFileIds.map((fileId) => ({ agentId, enabled, fileId, userId: this.userId })),
|
137
|
-
)
|
138
|
-
.execute();
|
132
|
+
);
|
139
133
|
};
|
140
134
|
|
141
135
|
deleteAgentFile = async (agentId: string, fileId: string) => {
|
@@ -147,8 +141,7 @@ export class AgentModel {
|
|
147
141
|
eq(agentsFiles.fileId, fileId),
|
148
142
|
eq(agentsFiles.userId, this.userId),
|
149
143
|
),
|
150
|
-
)
|
151
|
-
.execute();
|
144
|
+
);
|
152
145
|
};
|
153
146
|
|
154
147
|
toggleFile = async (agentId: string, fileId: string, enabled?: boolean) => {
|
@@ -161,7 +154,6 @@ export class AgentModel {
|
|
161
154
|
eq(agentsFiles.fileId, fileId),
|
162
155
|
eq(agentsFiles.userId, this.userId),
|
163
156
|
),
|
164
|
-
)
|
165
|
-
.execute();
|
157
|
+
);
|
166
158
|
};
|
167
159
|
}
|
@@ -64,7 +64,7 @@ export class AsyncTaskModel {
|
|
64
64
|
/**
|
65
65
|
* make the task status to be `error` if the task is not finished in 20 seconds
|
66
66
|
*/
|
67
|
-
async
|
67
|
+
checkTimeoutTasks = async (ids: string[]) => {
|
68
68
|
const tasks = await this.db
|
69
69
|
.select({ id: asyncTasks.id })
|
70
70
|
.from(asyncTasks)
|
@@ -93,5 +93,5 @@ export class AsyncTaskModel {
|
|
93
93
|
),
|
94
94
|
);
|
95
95
|
}
|
96
|
-
}
|
96
|
+
};
|
97
97
|
}
|
@@ -76,7 +76,7 @@ export class ChunkModel {
|
|
76
76
|
});
|
77
77
|
};
|
78
78
|
|
79
|
-
async
|
79
|
+
findByFileId = async (id: string, page = 0) => {
|
80
80
|
const data = await this.db
|
81
81
|
.select({
|
82
82
|
abstract: chunks.abstract,
|
@@ -100,9 +100,9 @@ export class ChunkModel {
|
|
100
100
|
|
101
101
|
return { ...item, metadata, pageNumber: metadata?.pageNumber } as FileChunk;
|
102
102
|
});
|
103
|
-
}
|
103
|
+
};
|
104
104
|
|
105
|
-
async
|
105
|
+
getChunksTextByFileId = async (id: string): Promise<{ id: string; text: string }[]> => {
|
106
106
|
const data = await this.db
|
107
107
|
.select()
|
108
108
|
.from(chunks)
|
@@ -113,9 +113,9 @@ export class ChunkModel {
|
|
113
113
|
.map((item) => item.chunks)
|
114
114
|
.map((chunk) => ({ id: chunk.id, text: this.mapChunkText(chunk) }))
|
115
115
|
.filter((chunk) => chunk.text) as { id: string; text: string }[];
|
116
|
-
}
|
116
|
+
};
|
117
117
|
|
118
|
-
async
|
118
|
+
countByFileIds = async (ids: string[]) => {
|
119
119
|
if (ids.length === 0) return [];
|
120
120
|
|
121
121
|
return this.db
|
@@ -126,9 +126,9 @@ export class ChunkModel {
|
|
126
126
|
.from(fileChunks)
|
127
127
|
.where(inArray(fileChunks.fileId, ids))
|
128
128
|
.groupBy(fileChunks.fileId);
|
129
|
-
}
|
129
|
+
};
|
130
130
|
|
131
|
-
async
|
131
|
+
countByFileId = async (ids: string) => {
|
132
132
|
const data = await this.db
|
133
133
|
.select({
|
134
134
|
count: count(fileChunks.chunkId),
|
@@ -139,16 +139,16 @@ export class ChunkModel {
|
|
139
139
|
.groupBy(fileChunks.fileId);
|
140
140
|
|
141
141
|
return data[0]?.count ?? 0;
|
142
|
-
}
|
142
|
+
};
|
143
143
|
|
144
|
-
async
|
144
|
+
semanticSearch = async ({
|
145
145
|
embedding,
|
146
146
|
fileIds,
|
147
147
|
}: {
|
148
148
|
embedding: number[];
|
149
149
|
fileIds: string[] | undefined;
|
150
150
|
query: string;
|
151
|
-
}) {
|
151
|
+
}) => {
|
152
152
|
const similarity = sql<number>`1 - (${cosineDistance(embeddings.embeddings, embedding)})`;
|
153
153
|
|
154
154
|
const data = await this.db
|
@@ -174,16 +174,16 @@ export class ChunkModel {
|
|
174
174
|
...item,
|
175
175
|
metadata: item.metadata as ChunkMetadata,
|
176
176
|
}));
|
177
|
-
}
|
177
|
+
};
|
178
178
|
|
179
|
-
async
|
179
|
+
semanticSearchForChat = async ({
|
180
180
|
embedding,
|
181
181
|
fileIds,
|
182
182
|
}: {
|
183
183
|
embedding: number[];
|
184
184
|
fileIds: string[] | undefined;
|
185
185
|
query: string;
|
186
|
-
}) {
|
186
|
+
}) => {
|
187
187
|
const similarity = sql<number>`1 - (${cosineDistance(embeddings.embeddings, embedding)})`;
|
188
188
|
|
189
189
|
const hasFiles = fileIds && fileIds.length > 0;
|
@@ -219,7 +219,7 @@ export class ChunkModel {
|
|
219
219
|
text: this.mapChunkText(item),
|
220
220
|
};
|
221
221
|
});
|
222
|
-
}
|
222
|
+
};
|
223
223
|
|
224
224
|
private mapChunkText = (chunk: { metadata: any; text: string | null; type: string | null }) => {
|
225
225
|
let text = chunk.text;
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
import { and, desc, like } from 'drizzle-orm/expressions';
|
1
|
+
import { count, sum } from 'drizzle-orm';
|
2
|
+
import { and, asc, desc, eq, ilike, inArray, like, notExists, or } from 'drizzle-orm/expressions';
|
3
3
|
import type { PgTransaction } from 'drizzle-orm/pg-core';
|
4
4
|
|
5
5
|
import { LobeChatDatabase } from '@/database/type';
|
@@ -276,12 +276,11 @@ export class FileModel {
|
|
276
276
|
return result[0].count;
|
277
277
|
};
|
278
278
|
|
279
|
-
async
|
280
|
-
|
279
|
+
update = async (id: string, value: Partial<FileItem>) =>
|
280
|
+
this.db
|
281
281
|
.update(files)
|
282
282
|
.set({ ...value, updatedAt: new Date() })
|
283
283
|
.where(and(eq(files.id, id), eq(files.userId, this.userId)));
|
284
|
-
}
|
285
284
|
|
286
285
|
/**
|
287
286
|
* get the corresponding file type prefix according to FilesTabs
|
@@ -306,17 +305,16 @@ export class FileModel {
|
|
306
305
|
}
|
307
306
|
};
|
308
307
|
|
309
|
-
async
|
310
|
-
|
308
|
+
findByNames = async (fileNames: string[]) =>
|
309
|
+
this.db.query.files.findMany({
|
311
310
|
where: and(
|
312
311
|
or(...fileNames.map((name) => like(files.name, `${name}%`))),
|
313
312
|
eq(files.userId, this.userId),
|
314
313
|
),
|
315
314
|
});
|
316
|
-
}
|
317
315
|
|
318
316
|
// 抽象出通用的删除 chunks 方法
|
319
|
-
private async
|
317
|
+
private deleteFileChunks = async (trx: PgTransaction<any>, fileIds: string[]) => {
|
320
318
|
const BATCH_SIZE = 1000; // 每批处理的数量
|
321
319
|
|
322
320
|
// 1. 获取所有关联的 chunk IDs
|
@@ -339,5 +337,5 @@ export class FileModel {
|
|
339
337
|
}
|
340
338
|
|
341
339
|
return chunkIds;
|
342
|
-
}
|
340
|
+
};
|
343
341
|
}
|
@@ -80,16 +80,14 @@ export class KnowledgeBaseModel {
|
|
80
80
|
};
|
81
81
|
|
82
82
|
// update
|
83
|
-
async
|
84
|
-
|
83
|
+
update = async (id: string, value: Partial<KnowledgeBaseItem>) =>
|
84
|
+
this.db
|
85
85
|
.update(knowledgeBases)
|
86
86
|
.set({ ...value, updatedAt: new Date() })
|
87
87
|
.where(and(eq(knowledgeBases.id, id), eq(knowledgeBases.userId, this.userId)));
|
88
|
-
}
|
89
88
|
|
90
|
-
static async
|
91
|
-
|
89
|
+
static findById = async (db: LobeChatDatabase, id: string) =>
|
90
|
+
db.query.knowledgeBases.findFirst({
|
92
91
|
where: eq(knowledgeBases.id, id),
|
93
92
|
});
|
94
|
-
}
|
95
93
|
}
|