@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.
Files changed (71) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/docs/self-hosting/environment-variables/model-provider.mdx +7 -0
  4. package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +7 -0
  5. package/docs/self-hosting/server-database/dokploy.zh-CN.mdx +12 -12
  6. package/package.json +1 -1
  7. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/Content.tsx +3 -9
  8. package/src/app/(main)/chat/(workspace)/@conversation/features/ThreadHydration.tsx +2 -4
  9. package/src/app/(main)/chat/@session/features/SessionListContent/DefaultMode.tsx +2 -5
  10. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InstallPlugin.tsx +10 -15
  11. package/src/database/repositories/dataImporter/__tests__/index.test.ts +11 -18
  12. package/src/database/repositories/dataImporter/index.ts +31 -46
  13. package/src/database/server/models/__tests__/_test_template.ts +1 -1
  14. package/src/database/server/models/__tests__/agent.test.ts +1 -1
  15. package/src/database/server/models/__tests__/asyncTask.test.ts +1 -1
  16. package/src/database/server/models/__tests__/chunk.test.ts +1 -1
  17. package/src/database/server/models/__tests__/file.test.ts +1 -1
  18. package/src/database/server/models/__tests__/knowledgeBase.test.ts +1 -2
  19. package/src/database/server/models/__tests__/message.test.ts +35 -72
  20. package/src/database/server/models/__tests__/nextauth.test.ts +1 -1
  21. package/src/database/server/models/__tests__/session.test.ts +1 -1
  22. package/src/database/server/models/__tests__/sessionGroup.test.ts +1 -2
  23. package/src/database/server/models/__tests__/topic.test.ts +1 -1
  24. package/src/database/server/models/__tests__/user.test.ts +1 -1
  25. package/src/database/server/models/_template.ts +2 -2
  26. package/src/database/server/models/agent.ts +17 -25
  27. package/src/database/server/models/asyncTask.ts +2 -2
  28. package/src/database/server/models/chunk.ts +14 -14
  29. package/src/database/server/models/embedding.ts +1 -1
  30. package/src/database/server/models/file.ts +8 -10
  31. package/src/database/server/models/knowledgeBase.ts +4 -6
  32. package/src/database/server/models/message.ts +54 -65
  33. package/src/database/server/models/plugin.ts +6 -2
  34. package/src/database/server/models/ragEval/dataset.ts +2 -2
  35. package/src/database/server/models/ragEval/datasetRecord.ts +3 -8
  36. package/src/database/server/models/ragEval/evaluation.ts +3 -2
  37. package/src/database/server/models/ragEval/evaluationRecord.ts +2 -2
  38. package/src/database/server/models/session.ts +40 -35
  39. package/src/database/server/models/sessionGroup.ts +4 -4
  40. package/src/database/server/models/thread.ts +2 -2
  41. package/src/database/server/models/topic.ts +48 -53
  42. package/src/database/server/models/user.ts +12 -12
  43. package/src/features/AgentSetting/AgentPlugin/index.tsx +1 -1
  44. package/src/features/ChatInput/ActionBar/Tools/Dropdown.tsx +4 -4
  45. package/src/features/Portal/Thread/Chat/ChatList.tsx +1 -2
  46. package/src/hooks/useCheckPluginsIsInstalled.ts +10 -0
  47. package/src/hooks/useFetchInstalledPlugins.ts +10 -0
  48. package/src/hooks/useFetchMessages.ts +15 -0
  49. package/src/hooks/useFetchSessions.ts +13 -0
  50. package/src/hooks/useFetchThreads.ts +11 -0
  51. package/src/hooks/useFetchTopics.ts +6 -6
  52. package/src/layout/GlobalProvider/StoreInitialization.tsx +3 -1
  53. package/src/libs/agent-runtime/utils/streams/azureOpenai.test.ts +0 -1
  54. package/src/libs/next-auth/adapter/index.ts +1 -1
  55. package/src/server/routers/lambda/chunk.ts +2 -2
  56. package/src/services/user/client.ts +2 -2
  57. package/src/store/agent/slices/chat/action.test.ts +21 -10
  58. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +10 -0
  59. package/src/store/chat/slices/builtinTool/action.ts +0 -1
  60. package/src/store/chat/slices/message/action.test.ts +3 -1
  61. package/src/store/chat/slices/message/action.ts +7 -3
  62. package/src/store/chat/slices/thread/action.ts +3 -3
  63. package/src/store/chat/slices/topic/action.test.ts +1 -1
  64. package/src/store/chat/slices/topic/action.ts +3 -3
  65. package/src/store/global/selectors.ts +6 -0
  66. package/src/store/session/slices/session/action.ts +6 -3
  67. package/src/store/session/slices/sessionGroup/action.test.ts +8 -6
  68. package/src/store/tool/slices/plugin/action.ts +5 -3
  69. package/src/store/tool/slices/store/action.ts +4 -3
  70. package/src/store/user/slices/common/action.test.ts +3 -1
  71. 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')).execute();
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')).execute();
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')).execute();
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')).execute();
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')).execute();
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')).execute();
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')).execute();
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')).execute();
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')).execute();
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
- .select()
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
- .select()
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
- .select()
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
- .select()
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
- .execute();
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
- .execute();
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
- .select()
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
- .select()
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
- .execute();
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,4 +1,4 @@
1
- import { and, eq, inArray } from 'drizzle-orm';
1
+ import { and, eq, inArray } from 'drizzle-orm/expressions';
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
3
 
4
4
  import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
@@ -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';
@@ -1,4 +1,4 @@
1
- import { eq, inArray } from 'drizzle-orm';
1
+ import { eq, inArray } 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';
@@ -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 { INBOX_SESSION_ID } from '@/const/session';
@@ -45,10 +45,10 @@ export class TemplateModel {
45
45
  });
46
46
  };
47
47
 
48
- async update(id: string, value: Partial<SessionGroupItem>) {
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 getAgentConfigById(id: string) {
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 getAgentAssignedKnowledge(id: string) {
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 findBySessionId(sessionId: string) {
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
- .insert(agentsKnowledgeBases)
78
- .values({
79
- agentId,
80
- enabled,
81
- knowledgeBaseId,
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 checkTimeoutTasks(ids: string[]) {
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 findByFileId(id: string, page = 0) {
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 getChunksTextByFileId(id: string): Promise<{ id: string; text: string }[]> {
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 countByFileIds(ids: string[]) {
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 countByFileId(ids: string) {
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 semanticSearch({
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 semanticSearchForChat({
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;
@@ -50,7 +50,7 @@ export class EmbeddingModel {
50
50
  });
51
51
  };
52
52
 
53
- countUsage = async () => {
53
+ countUsage = async (): Promise<number> => {
54
54
  const result = await this.db
55
55
  .select({
56
56
  count: count(),
@@ -1,5 +1,5 @@
1
- import { asc, count, eq, ilike, inArray, notExists, or, sum } from 'drizzle-orm';
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 update(id: string, value: Partial<FileItem>) {
280
- return this.db
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 findByNames(fileNames: string[]) {
310
- return this.db.query.files.findMany({
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 deleteFileChunks(trx: PgTransaction<any>, fileIds: string[]) {
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 update(id: string, value: Partial<KnowledgeBaseItem>) {
84
- return this.db
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 findById(db: LobeChatDatabase, id: string) {
91
- return db.query.knowledgeBases.findFirst({
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
  }