@lobehub/chat 0.105.2 → 0.107.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.
Files changed (224) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +18 -0
  3. package/README.zh-CN.md +18 -0
  4. package/docs/Environment-Variable.md +4 -2
  5. package/docs/Environment-Variable.zh-CN.md +4 -2
  6. package/locales/en_US/common.json +19 -0
  7. package/locales/en_US/migration.json +45 -0
  8. package/locales/en_US/setting.json +7 -7
  9. package/locales/ja_JP/common.json +19 -0
  10. package/locales/ja_JP/migration.json +45 -0
  11. package/locales/ja_JP/setting.json +2 -2
  12. package/locales/ko_KR/common.json +19 -0
  13. package/locales/ko_KR/migration.json +45 -0
  14. package/locales/ko_KR/setting.json +2 -2
  15. package/locales/ru_RU/common.json +19 -0
  16. package/locales/ru_RU/migration.json +45 -0
  17. package/locales/ru_RU/setting.json +2 -2
  18. package/locales/zh_CN/common.json +19 -0
  19. package/locales/zh_CN/migration.json +45 -0
  20. package/locales/zh_CN/setting.json +1 -1
  21. package/locales/zh_TW/common.json +19 -0
  22. package/locales/zh_TW/migration.json +45 -0
  23. package/locales/zh_TW/setting.json +2 -2
  24. package/package.json +2 -1
  25. package/src/app/api/openai/chat/createChatCompletion.test.ts +4 -4
  26. package/src/app/api/openai/chat/createChatCompletion.ts +4 -10
  27. package/src/app/api/openai/createBizOpenAI/index.ts +1 -1
  28. package/src/app/api/openai/errorResponse.test.ts +1 -1
  29. package/src/app/chat/(desktop)/features/ChatInput/Footer/index.tsx +2 -1
  30. package/src/app/chat/(mobile)/features/ChatInput/SendButton.tsx +2 -2
  31. package/src/app/chat/features/ChatHeader/ShareButton/Inner.tsx +2 -5
  32. package/src/app/chat/features/ChatHeader/ShareButton/index.tsx +2 -2
  33. package/src/app/chat/features/ChatInput/ActionBar/Clear.tsx +2 -2
  34. package/src/app/chat/features/ChatInput/ActionBar/ModelSwitch.tsx +1 -1
  35. package/src/app/chat/features/ChatInput/ActionBar/Token/TokenTag.tsx +8 -2
  36. package/src/app/chat/features/ChatInput/InputAreaInner/index.tsx +2 -2
  37. package/src/app/chat/features/ChatInput/STT/index.tsx +2 -2
  38. package/src/app/chat/features/ChatInput/Topic/index.tsx +2 -2
  39. package/src/app/chat/features/ChatInput/useSend.ts +3 -3
  40. package/src/app/chat/features/Conversation/ChatList/Actions/index.ts +2 -2
  41. package/src/app/chat/features/Conversation/ChatList/Error/ApiKeyForm.tsx +2 -2
  42. package/src/app/chat/features/Conversation/ChatList/Error/InvalidAccess.tsx +2 -2
  43. package/src/app/chat/features/Conversation/ChatList/Error/Plugin/PluginSettings.tsx +2 -2
  44. package/src/app/chat/features/Conversation/ChatList/Extras/Assistant.test.tsx +4 -4
  45. package/src/app/chat/features/Conversation/ChatList/Extras/Assistant.tsx +30 -31
  46. package/src/app/chat/features/Conversation/ChatList/Extras/TTS.tsx +2 -2
  47. package/src/app/chat/features/Conversation/ChatList/Extras/Translate.tsx +2 -2
  48. package/src/app/chat/features/Conversation/ChatList/Extras/User.tsx +8 -5
  49. package/src/app/chat/features/Conversation/ChatList/Extras/index.ts +3 -3
  50. package/src/app/chat/features/Conversation/ChatList/Extras/type.ts +5 -0
  51. package/src/app/chat/features/Conversation/ChatList/Messages/Assistant.tsx +10 -6
  52. package/src/app/chat/features/Conversation/ChatList/Messages/Default.tsx +7 -3
  53. package/src/app/chat/features/Conversation/ChatList/Messages/Function.tsx +7 -6
  54. package/src/app/chat/features/Conversation/ChatList/Messages/index.ts +7 -7
  55. package/src/app/chat/features/Conversation/ChatList/Plugins/Render/StandaloneType/Iframe.tsx +6 -6
  56. package/src/app/chat/features/Conversation/ChatList/index.tsx +16 -24
  57. package/src/app/chat/features/Conversation/ScrollAnchor/index.tsx +2 -2
  58. package/src/app/chat/features/Conversation/index.tsx +3 -3
  59. package/src/app/chat/features/Conversation/useInitConversation.ts +43 -0
  60. package/src/app/chat/features/Migration/ExportConfigButton.tsx +33 -0
  61. package/src/app/chat/features/Migration/Failed.tsx +115 -0
  62. package/src/app/chat/features/Migration/Modal.tsx +80 -0
  63. package/src/app/chat/features/Migration/Start.tsx +106 -0
  64. package/src/app/chat/features/Migration/UpgradeButton.tsx +74 -0
  65. package/src/app/chat/features/Migration/const.ts +15 -0
  66. package/src/app/chat/features/Migration/index.tsx +44 -0
  67. package/src/app/chat/features/SessionListContent/DefaultMode.tsx +54 -0
  68. package/src/app/chat/features/SessionListContent/List/Item/Actions.tsx +5 -4
  69. package/src/app/chat/features/SessionListContent/List/Item/index.tsx +22 -28
  70. package/src/app/chat/features/SessionListContent/SearchMode.tsx +15 -0
  71. package/src/app/chat/features/SessionListContent/index.tsx +4 -44
  72. package/src/app/chat/features/SessionSearchBar/index.tsx +11 -3
  73. package/src/app/chat/features/TopicListContent/Header.tsx +4 -4
  74. package/src/app/chat/features/TopicListContent/Topic/TopicContent.tsx +11 -9
  75. package/src/app/chat/features/TopicListContent/Topic/TopicItem.tsx +15 -13
  76. package/src/app/chat/features/TopicListContent/Topic/index.tsx +9 -16
  77. package/src/app/chat/features/TopicListContent/TopicSearchBar/index.tsx +13 -4
  78. package/src/app/chat/features/TopicListContent/index.tsx +1 -2
  79. package/src/app/chat/page.tsx +6 -1
  80. package/src/app/chat/settings/features/HeaderContent.tsx +3 -3
  81. package/src/app/home/Redirect.tsx +13 -7
  82. package/src/app/settings/(mobile)/features/ExtraList.tsx +12 -4
  83. package/src/app/settings/common/Common.tsx +16 -4
  84. package/src/app/welcome/features/Banner/index.tsx +9 -10
  85. package/src/chains/summaryTitle.ts +5 -2
  86. package/src/components/DataStyleModal/index.tsx +64 -0
  87. package/src/config/client.ts +5 -0
  88. package/src/const/session.ts +21 -0
  89. package/src/const/settings.ts +1 -1
  90. package/src/database/core/__tests__/db.test.ts +8 -5
  91. package/src/database/core/__tests__/model.test.ts +3 -3
  92. package/src/database/core/db.ts +38 -10
  93. package/src/database/core/index.ts +1 -0
  94. package/src/database/core/model.ts +121 -10
  95. package/src/database/core/schemas.ts +22 -0
  96. package/src/database/core/types/db.ts +13 -0
  97. package/src/database/models/__DEBUG.ts +119 -0
  98. package/src/database/models/{file.test.ts → __tests__/file.test.ts} +19 -6
  99. package/src/database/models/__tests__/message.test.ts +314 -0
  100. package/src/database/models/__tests__/session.test.ts +117 -0
  101. package/src/database/models/__tests__/topic.test.ts +250 -0
  102. package/src/database/models/file.ts +9 -5
  103. package/src/database/models/message.ts +186 -0
  104. package/src/database/models/session.ts +160 -0
  105. package/src/database/models/topic.ts +196 -0
  106. package/src/{types/database → database/schemas}/files.ts +2 -2
  107. package/src/database/schemas/message.ts +37 -0
  108. package/src/database/schemas/session.ts +56 -0
  109. package/src/database/schemas/topic.ts +12 -0
  110. package/src/features/AgentSetting/AgentConfig/index.tsx +8 -1
  111. package/src/features/AgentSetting/AgentTTS/SelectWithTTSPreview.tsx +1 -1
  112. package/src/features/AgentSetting/store/action.ts +1 -1
  113. package/src/features/AgentSetting/store/initialState.ts +1 -1
  114. package/src/features/AgentSetting/store/reducers/config.ts +1 -1
  115. package/src/features/DataImporter/index.tsx +240 -0
  116. package/src/features/DebugUI/index.tsx +34 -0
  117. package/src/features/SideBar/BottomActions.tsx +8 -14
  118. package/src/hooks/useImportConfig.ts +13 -30
  119. package/src/hooks/useTTS.ts +1 -1
  120. package/src/layout/GlobalLayout/index.tsx +16 -1
  121. package/src/locales/default/common.ts +19 -0
  122. package/src/locales/default/migration.ts +47 -0
  123. package/src/locales/default/setting.ts +1 -1
  124. package/src/locales/resources/en_US.ts +2 -0
  125. package/src/locales/resources/ja_JP.ts +2 -0
  126. package/src/locales/resources/ko_KR.ts +2 -0
  127. package/src/locales/resources/ru_RU.ts +2 -0
  128. package/src/locales/resources/zh_CN.ts +2 -0
  129. package/src/locales/resources/zh_TW.ts +2 -0
  130. package/src/migrations/FromV0ToV1.ts +2 -4
  131. package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +191 -0
  132. package/src/migrations/FromV1ToV2/fixtures/output-v2.json +202 -0
  133. package/src/migrations/FromV1ToV2/index.ts +82 -0
  134. package/src/migrations/FromV1ToV2/migrations.test.ts +224 -0
  135. package/src/migrations/FromV1ToV2/types/v1.ts +78 -0
  136. package/src/migrations/FromV1ToV2/types/v2.ts +52 -0
  137. package/src/{utils → migrations}/VersionController.test.ts +1 -3
  138. package/src/{utils → migrations}/VersionController.ts +5 -2
  139. package/src/migrations/index.ts +17 -3
  140. package/src/services/__tests__/file.test.ts +3 -3
  141. package/src/services/chat.ts +66 -5
  142. package/src/services/config.ts +184 -0
  143. package/src/services/debug.ts +13 -0
  144. package/src/services/file.ts +6 -2
  145. package/src/services/github.ts +25 -0
  146. package/src/services/message.ts +79 -0
  147. package/src/services/session.ts +63 -0
  148. package/src/services/topic.ts +56 -0
  149. package/src/store/chat/actions/enhance.ts +95 -0
  150. package/src/store/{session/slices/chat → chat}/actions/message.ts +225 -247
  151. package/src/store/{session/slices/chat → chat}/actions/plugin.ts +29 -34
  152. package/src/store/{session/slices/chat → chat}/actions/share.ts +9 -13
  153. package/src/store/chat/actions/topic.ts +197 -0
  154. package/src/store/chat/helpers.ts +23 -0
  155. package/src/store/chat/index.ts +3 -0
  156. package/src/store/chat/initialState.ts +48 -0
  157. package/src/store/chat/reducers/message.test.ts +83 -0
  158. package/src/store/chat/reducers/message.ts +83 -0
  159. package/src/store/chat/selectors/__tests__/topic.test.ts +43 -0
  160. package/src/store/chat/selectors/chat.ts +119 -0
  161. package/src/store/chat/selectors/index.ts +2 -0
  162. package/src/store/chat/selectors/topic.ts +28 -0
  163. package/src/store/chat/store.ts +63 -0
  164. package/src/store/files/slices/images/action.ts +6 -4
  165. package/src/store/global/selectors/__snapshots__/settings.test.ts.snap +99 -0
  166. package/src/store/global/selectors/settings.test.ts +51 -0
  167. package/src/store/global/selectors/settings.ts +36 -5
  168. package/src/store/global/store.ts +1 -1
  169. package/src/store/middleware/createHyperStorage/index.ts +40 -24
  170. package/src/store/middleware/createHyperStorage/keyMapper.ts +8 -2
  171. package/src/store/middleware/createHyperStorage/type.ts +10 -8
  172. package/src/store/plugin/slices/plugin/action.ts +1 -1
  173. package/src/store/plugin/store.ts +2 -4
  174. package/src/store/session/helpers.ts +1 -1
  175. package/src/store/session/hooks/useSessionHydrated.ts +6 -10
  176. package/src/store/session/initialState.ts +26 -7
  177. package/src/store/session/selectors.ts +1 -2
  178. package/src/store/session/slices/agent/action.ts +26 -35
  179. package/src/store/session/slices/agent/selectors.ts +32 -37
  180. package/src/store/session/slices/session/action.ts +81 -88
  181. package/src/store/session/slices/session/helpers.ts +19 -0
  182. package/src/store/session/slices/session/initialState.ts +7 -10
  183. package/src/store/session/slices/session/selectors/export.ts +12 -9
  184. package/src/store/session/slices/session/selectors/index.ts +2 -35
  185. package/src/store/session/slices/session/selectors/list.test.ts +25 -203
  186. package/src/store/session/slices/session/selectors/list.ts +40 -78
  187. package/src/store/session/store.ts +11 -17
  188. package/src/types/agent/index.ts +61 -0
  189. package/src/types/chatMessage.ts +11 -20
  190. package/src/types/exportConfig.ts +7 -2
  191. package/src/types/files.ts +2 -2
  192. package/src/types/llm.ts +1 -1
  193. package/src/types/meta.ts +24 -12
  194. package/src/types/openai/chat.ts +9 -1
  195. package/src/types/openai/functionCall.ts +4 -0
  196. package/src/types/session.ts +10 -94
  197. package/src/types/settings.ts +2 -0
  198. package/src/types/translate.ts +2 -1
  199. package/src/utils/config.ts +5 -11
  200. package/src/utils/fetch.ts +8 -2
  201. package/src/app/chat/features/Conversation/usePluginsInit.ts +0 -14
  202. package/src/database/core/schema.ts +0 -9
  203. package/src/helpers/export.ts +0 -69
  204. package/src/hooks/useExportConfig.ts +0 -6
  205. package/src/store/session/slices/chat/actions/index.ts +0 -32
  206. package/src/store/session/slices/chat/actions/topic.ts +0 -171
  207. package/src/store/session/slices/chat/actions/translate.ts +0 -113
  208. package/src/store/session/slices/chat/helpers.ts +0 -9
  209. package/src/store/session/slices/chat/initialState.ts +0 -13
  210. package/src/store/session/slices/chat/reducers/message.test.ts +0 -319
  211. package/src/store/session/slices/chat/reducers/message.ts +0 -156
  212. package/src/store/session/slices/chat/reducers/topic.test.ts +0 -179
  213. package/src/store/session/slices/chat/reducers/topic.ts +0 -81
  214. package/src/store/session/slices/chat/selectors/chat.ts +0 -111
  215. package/src/store/session/slices/chat/selectors/index.ts +0 -26
  216. package/src/store/session/slices/chat/selectors/topic.ts +0 -30
  217. package/src/store/session/slices/chat/selectors/utils.test.ts +0 -385
  218. package/src/store/session/slices/chat/selectors/utils.ts +0 -91
  219. package/src/store/session/slices/chat/utils.ts +0 -13
  220. package/src/store/session/slices/session/reducers/session.test.ts +0 -577
  221. package/src/store/session/slices/session/reducers/session.ts +0 -182
  222. package/src/types/database/db.ts +0 -4
  223. /package/src/store/{session/slices/chat → chat}/reducers/files.test.ts +0 -0
  224. /package/src/store/{session/slices/chat → chat}/reducers/files.ts +0 -0
@@ -1,385 +0,0 @@
1
- import { beforeEach, describe } from 'vitest';
2
-
3
- import { ChatMessage } from '@/types/chatMessage';
4
- import { LobeAgentSession } from '@/types/session';
5
-
6
- import { organizeChats } from './utils';
7
-
8
- let session: LobeAgentSession;
9
-
10
- beforeEach(() => {
11
- session = {
12
- chats: {
13
- '1': {
14
- id: '1',
15
- createAt: 1639440000000,
16
- updateAt: 1639440000000,
17
- meta: {},
18
- content: 'Message 1',
19
- role: 'assistant',
20
- },
21
- '2': {
22
- id: '2',
23
- createAt: 1639450000000,
24
- updateAt: 1639450000000,
25
- meta: {},
26
- content: 'Message 2',
27
- role: 'user',
28
- },
29
- '3': {
30
- id: '3',
31
- createAt: 1639460000000,
32
- updateAt: 1639460000000,
33
- meta: {},
34
- content: 'Message 3',
35
- role: 'assistant',
36
- },
37
- },
38
- config: {
39
- model: 'gpt-4',
40
- params: {
41
- temperature: 0.6,
42
- },
43
- autoCreateTopicThreshold: 2,
44
- enableAutoCreateTopic: true,
45
- systemRole: '',
46
- tts: {
47
- ttsService: 'openai',
48
- sttLocale: 'auto',
49
- showAllLocaleVoice: false,
50
- voice: {
51
- openai: 'alloy',
52
- },
53
- },
54
- },
55
- type: 'agent',
56
- createAt: 1690110700808,
57
- id: 'abc',
58
- meta: {},
59
- updateAt: 1690110700808,
60
- } as LobeAgentSession;
61
- });
62
-
63
- describe('organizeChats', () => {
64
- it('should return an array of chat messages', () => {
65
- const result = organizeChats(session);
66
- expect(Array.isArray(result)).toBe(true);
67
- expect(result.length).toBe(3);
68
- expect(result[0].id).toBe('1');
69
- expect(result[1].id).toBe('2');
70
- expect(result[2].id).toBe('3');
71
- });
72
-
73
- it('should sort chat messages in ascending order of createAt', () => {
74
- const result = organizeChats(session);
75
- expect(result[0].id).toBe('1');
76
- expect(result[1].id).toBe('2');
77
- expect(result[2].id).toBe('3');
78
- });
79
-
80
- it('should filter out archived messages', () => {
81
- session.chats['2'].topicId = '123';
82
- const result = organizeChats(session);
83
- expect(result.length).toBe(2);
84
- expect(result[0].id).toBe('1');
85
- expect(result[1].id).toBe('3');
86
- });
87
-
88
- it('should map avatars correctly', () => {
89
- const avatar = 'https://example.com/avatar.png';
90
- const settings = {
91
- avatar: 'https://example.com/user-avatar.png',
92
- };
93
-
94
- const result = organizeChats(session, {
95
- meta: {
96
- user: { avatar: settings.avatar },
97
- assistant: { avatar },
98
- },
99
- });
100
-
101
- expect(result[0].meta.avatar).toBe(avatar);
102
- expect(result[1].meta.avatar).toBe(settings.avatar);
103
- expect(result[2].meta.avatar).toBe(avatar);
104
- });
105
-
106
- it('should reorder messages based on parent-child relationship', () => {
107
- session.chats['2'].parentId = '1';
108
- session.chats['3'].parentId = '2';
109
- const result = organizeChats(session);
110
- expect(result.length).toBe(3);
111
- expect(result[0].id).toBe('1');
112
- expect(result[1].id).toBe('2');
113
- expect(result[2].id).toBe('3');
114
- });
115
-
116
- it('should remove duplicate messages', () => {
117
- session.chats['2'].parentId = '1';
118
- session.chats['3'].parentId = '2';
119
- session.chats['3'].id = '2';
120
- const result = organizeChats(session);
121
- expect(result.length).toBe(2);
122
- expect(result[0].id).toBe('1');
123
- expect(result[1].id).toBe('2');
124
- });
125
-
126
- it('should return an empty array for empty session', () => {
127
- const emptySession = {
128
- chats: {},
129
- config: {},
130
- type: 'agent',
131
- } as LobeAgentSession;
132
- const result = organizeChats(emptySession);
133
- expect(Array.isArray(result)).toBe(true);
134
- expect(result.length).toBe(0);
135
- });
136
-
137
- it('should handle large number of chat messages', () => {
138
- const largeSession = {
139
- chats: {},
140
- config: {},
141
- type: 'agent',
142
- meta: {},
143
- } as LobeAgentSession;
144
-
145
- const numMessages = 1000;
146
-
147
- for (let i = 1; i <= numMessages; i++) {
148
- largeSession.chats[i.toString()] = {
149
- id: i.toString(),
150
- createAt: i,
151
- updateAt: i,
152
- meta: {},
153
- content: `Message ${i}`,
154
- role: 'assistant',
155
- };
156
- }
157
-
158
- const result = organizeChats(largeSession);
159
- expect(result.length).toBe(numMessages);
160
- expect(result[0].id).toBe('1');
161
- expect(result[numMessages - 1].id).toBe(numMessages.toString());
162
- });
163
-
164
- it('按照预期进行排序', () => {
165
- const realSession = {
166
- chats: {
167
- 'Ftei28dF': {
168
- content: '鲁迅为何暴打周树人',
169
- createAt: 1690111354731,
170
- id: 'Ftei28dF',
171
- meta: {},
172
- role: 'user',
173
- updateAt: 1690111354731,
174
- },
175
- '9bQW9hTs': {
176
- content:
177
- '这是一种误解。鲁迅和周树人是同一人,指的都是现代文学家周樟寿。"鲁迅"是他的笔名,"周树人"则是他的原名。所以,鲁迅并没有暴打周树人,这只是一种说法上的误解。',
178
- createAt: 1690111354734,
179
- id: '9bQW9hTs',
180
- meta: {},
181
- parentId: 'Ftei28dF',
182
- role: 'assistant',
183
- updateAt: 1690111361514,
184
- extra: {
185
- fromModel: 'gpt-4',
186
- },
187
- },
188
- 'HRQGSszU': {
189
- content:
190
- '这个问题基于一个误解。实际上,鲁迅和周树人是同一个人,这是中国现代文学的开山鼻祖周树人的笔名。他的本名是周树人,鲁迅则是他在30岁时开始使用的笔名。因此,鲁迅不能暴打周树人,因为他们是同一个人。',
191
- createAt: 1690111364344,
192
- id: 'HRQGSszU',
193
- meta: {},
194
- parentId: 'Ftei28dF',
195
- role: 'assistant',
196
- updateAt: 1690111369519,
197
- extra: {
198
- fromModel: 'gpt-4',
199
- },
200
- },
201
- '981qr9n0': {
202
- content:
203
- '这是一个误解。鲁迅和周树人是同一个人,是中国现代文学的奠基人。鲁迅是他的笔名,周树人是他的本名。所以,鲁迅不可能暴打周树人。这种说法可能是源于一些误解或误传。',
204
- createAt: 1690111375456,
205
- id: '981qr9n0',
206
- meta: {},
207
- parentId: 'Ftei28dF',
208
- role: 'assistant',
209
- updateAt: 1690111381458,
210
- extra: {
211
- fromModel: 'gpt-4',
212
- },
213
- },
214
- 'ddd': {
215
- content: '鲁迅是谁',
216
- createAt: 1690211354731,
217
- id: 'ddd',
218
- meta: {},
219
- role: 'user',
220
- updateAt: 1690211354731,
221
- },
222
- },
223
- config: {
224
- autoCreateTopicThreshold: 2,
225
- enableAutoCreateTopic: true,
226
- model: 'gpt-4',
227
- params: {
228
- temperature: 0.6,
229
- },
230
- tts: {
231
- ttsService: 'openai',
232
- sttLocale: 'auto',
233
- showAllLocaleVoice: false,
234
- voice: {
235
- openai: 'alloy',
236
- },
237
- },
238
- systemRole: '',
239
- },
240
- createAt: 1690110700808,
241
- id: '1515e861-0c64-49a3-bb85-2b24d65a19d6',
242
- meta: {},
243
- type: 'agent',
244
- updateAt: 1690110700808,
245
- } as LobeAgentSession;
246
-
247
- const result = organizeChats(realSession);
248
-
249
- expect(
250
- result.map((i) => ({ id: i.id, content: i.content, role: i.role, createAt: i.createAt })),
251
- ).toEqual([
252
- {
253
- content: '鲁迅为何暴打周树人',
254
- createAt: 1690111354731,
255
- id: 'Ftei28dF',
256
- role: 'user',
257
- },
258
- {
259
- content:
260
- '这是一种误解。鲁迅和周树人是同一人,指的都是现代文学家周樟寿。"鲁迅"是他的笔名,"周树人"则是他的原名。所以,鲁迅并没有暴打周树人,这只是一种说法上的误解。',
261
- createAt: 1690111354734,
262
- id: '9bQW9hTs',
263
- role: 'assistant',
264
- },
265
- {
266
- content:
267
- '这个问题基于一个误解。实际上,鲁迅和周树人是同一个人,这是中国现代文学的开山鼻祖周树人的笔名。他的本名是周树人,鲁迅则是他在30岁时开始使用的笔名。因此,鲁迅不能暴打周树人,因为他们是同一个人。',
268
- createAt: 1690111364344,
269
- id: 'HRQGSszU',
270
- role: 'assistant',
271
- },
272
- {
273
- content:
274
- '这是一个误解。鲁迅和周树人是同一个人,是中国现代文学的奠基人。鲁迅是他的笔名,周树人是他的本名。所以,鲁迅不可能暴打周树人。这种说法可能是源于一些误解或误传。',
275
- createAt: 1690111375456,
276
- id: '981qr9n0',
277
- role: 'assistant',
278
- },
279
- {
280
- content: '鲁迅是谁',
281
- createAt: 1690211354731,
282
- id: 'ddd',
283
- role: 'user',
284
- },
285
- ]);
286
- });
287
-
288
- const params = {
289
- meta: {
290
- user: { avatar: 'user-avatar' },
291
- assistant: { avatar: 'assistant-avatar' },
292
- },
293
- };
294
-
295
- it('should organize chats in chronological order when topicId is not provided', () => {
296
- const result = organizeChats(session, params);
297
-
298
- expect(result.length).toBe(3);
299
- expect(result[0].id).toBe('1');
300
- expect(result[1].id).toBe('2');
301
- expect(result[2].id).toBe('3');
302
- });
303
-
304
- it('should only return chats with specified topicId when topicId is provided', () => {
305
- const result = organizeChats(session, { ...params, topicId: 'topic-id' });
306
-
307
- expect(result.length).toBe(0);
308
- });
309
-
310
- describe('user Meta', () => {
311
- it('should return correct meta for user role', () => {
312
- const result = organizeChats(session, params);
313
- const meta = result[1].meta;
314
-
315
- expect(meta.avatar).toBe(params.meta.user.avatar);
316
- });
317
-
318
- it('should return correct meta for assistant role', () => {
319
- const result = organizeChats(session, params);
320
- const meta = result[0].meta;
321
-
322
- expect(meta.avatar).toBe('assistant-avatar');
323
- expect(meta.title).toBeUndefined();
324
- });
325
-
326
- describe('should return correct meta for function role', () => {
327
- it('找不到插件', () => {
328
- const message = {
329
- id: '4',
330
- createAt: 1927785600004,
331
- updateAt: 1927785600004,
332
- role: 'function',
333
- function_call: {
334
- name: 'plugin-name',
335
- },
336
- } as ChatMessage;
337
-
338
- session.chats[message.id] = message;
339
-
340
- const result = organizeChats(session, params);
341
- const meta = result[3].meta;
342
-
343
- expect(meta.avatar).toBe('🧩');
344
- expect(meta.title).toBe('plugin-unknown');
345
- });
346
-
347
- it('找到的插件', () => {
348
- const message = {
349
- id: '4',
350
- createAt: 1927785600004,
351
- updateAt: 1927785600004,
352
- role: 'function',
353
- function_call: {
354
- name: 'realtimeWeather',
355
- },
356
- name: 'realtimeWeather',
357
- } as ChatMessage;
358
-
359
- session.chats[message.id] = message;
360
-
361
- const result = organizeChats(session, {
362
- ...params,
363
- pluginList: [
364
- {
365
- identifier: 'realtimeWeather',
366
- author: '123',
367
- meta: {
368
- avatar: '🧩',
369
- title: '天气预报',
370
- },
371
- createAt: 'abc',
372
- manifest: '',
373
- homepage: '',
374
- schemaVersion: 1,
375
- },
376
- ],
377
- });
378
- const meta = result[3].meta;
379
-
380
- expect(meta.avatar).toBe('🧩');
381
- expect(meta.title).toBe('realtimeWeather');
382
- });
383
- });
384
- });
385
- });
@@ -1,91 +0,0 @@
1
- import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
2
-
3
- import { ChatMessage } from '@/types/chatMessage';
4
- import { MetaData } from '@/types/meta';
5
- import { LobeAgentSession } from '@/types/session';
6
-
7
- interface OrganizeParams {
8
- meta?: {
9
- assistant?: MetaData;
10
- user?: MetaData;
11
- };
12
- pluginList?: LobeChatPluginMeta[];
13
- topicId?: string;
14
- }
15
-
16
- export const organizeChats = (
17
- session: LobeAgentSession,
18
- { topicId, meta, pluginList }: OrganizeParams = {},
19
- ) => {
20
- const getMeta = (message: ChatMessage) => {
21
- switch (message.role) {
22
- case 'user': {
23
- return {
24
- avatar: meta?.user?.avatar,
25
- };
26
- }
27
-
28
- case 'system': {
29
- return message.meta;
30
- }
31
-
32
- case 'assistant': {
33
- return {
34
- avatar: meta?.assistant?.avatar,
35
- backgroundColor: meta?.assistant?.backgroundColor,
36
- title: meta?.assistant?.title || session.meta.title,
37
- };
38
- }
39
-
40
- case 'function': {
41
- const plugin = (pluginList || []).find((m) => m.identifier === message.name);
42
-
43
- return {
44
- avatar: '🧩',
45
- title: plugin?.identifier || 'plugin-unknown',
46
- };
47
- }
48
- }
49
- };
50
-
51
- const basic = Object.values<ChatMessage>(session.chats)
52
- // 首先按照时间顺序排序,越早的在越前面
53
- .sort((pre, next) => pre.createAt - next.createAt)
54
- .filter((m) => {
55
- // 过滤掉包含 topicId 的消息,有主题的消息不应该出现在聊天框中
56
- if (!topicId) return !m.topicId;
57
-
58
- // 或者当话题 id 一致时,再展示话题
59
- return m.topicId === topicId;
60
- })
61
- // 映射头像关系
62
- .map((m) => {
63
- return {
64
- ...m,
65
- meta: getMeta(m),
66
- };
67
- });
68
-
69
- const finalList: ChatMessage[] = [];
70
-
71
- const addItem = (item: ChatMessage) => {
72
- const isExist = finalList.findIndex((i) => item.id === i.id) > -1;
73
- if (!isExist) {
74
- finalList.push(item);
75
- }
76
- };
77
-
78
- // 基于添加逻辑进行重排序
79
- for (const item of basic) {
80
- // 先判存在与否,不存在就加入
81
- addItem(item);
82
-
83
- for (const another of basic) {
84
- if (another.parentId === item.id) {
85
- addItem(another);
86
- }
87
- }
88
- }
89
-
90
- return finalList;
91
- };
@@ -1,13 +0,0 @@
1
- import { ChatMessage } from '@/types/chatMessage';
2
- import { LobeAgentConfig } from '@/types/session';
3
-
4
- export const getSlicedMessagesWithConfig = (
5
- messages: ChatMessage[],
6
- config: LobeAgentConfig,
7
- ): ChatMessage[] => {
8
- // 如果没有开启历史消息数限制,或者限制为 0,则直接返回
9
- if (!config.enableHistoryCount || !config.historyCount) return messages;
10
-
11
- // 如果开启了,则返回尾部的N条消息
12
- return messages.reverse().slice(0, config.historyCount).reverse();
13
- };