@lobehub/chat 1.11.8 → 1.12.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 (440) hide show
  1. package/.github/workflows/release.yml +2 -1
  2. package/.github/workflows/test.yml +2 -1
  3. package/CHANGELOG.md +50 -0
  4. package/Dockerfile.database +2 -0
  5. package/docs/self-hosting/advanced/knowledge-base.zh-CN.mdx +65 -0
  6. package/locales/ar/chat.json +46 -3
  7. package/locales/ar/common.json +1 -0
  8. package/locales/ar/components.json +2 -0
  9. package/locales/ar/error.json +1 -0
  10. package/locales/ar/file.json +91 -0
  11. package/locales/ar/knowledgeBase.json +31 -0
  12. package/locales/ar/portal.json +1 -0
  13. package/locales/bg-BG/chat.json +46 -3
  14. package/locales/bg-BG/common.json +1 -0
  15. package/locales/bg-BG/components.json +2 -0
  16. package/locales/bg-BG/error.json +1 -0
  17. package/locales/bg-BG/file.json +91 -0
  18. package/locales/bg-BG/knowledgeBase.json +31 -0
  19. package/locales/bg-BG/portal.json +1 -0
  20. package/locales/de-DE/chat.json +46 -3
  21. package/locales/de-DE/common.json +1 -0
  22. package/locales/de-DE/components.json +2 -0
  23. package/locales/de-DE/error.json +1 -0
  24. package/locales/de-DE/file.json +91 -0
  25. package/locales/de-DE/knowledgeBase.json +31 -0
  26. package/locales/de-DE/portal.json +1 -0
  27. package/locales/en-US/chat.json +46 -3
  28. package/locales/en-US/common.json +1 -0
  29. package/locales/en-US/components.json +2 -0
  30. package/locales/en-US/error.json +1 -0
  31. package/locales/en-US/file.json +91 -0
  32. package/locales/en-US/knowledgeBase.json +31 -0
  33. package/locales/en-US/portal.json +1 -0
  34. package/locales/es-ES/chat.json +46 -3
  35. package/locales/es-ES/common.json +1 -0
  36. package/locales/es-ES/components.json +2 -0
  37. package/locales/es-ES/error.json +1 -0
  38. package/locales/es-ES/file.json +91 -0
  39. package/locales/es-ES/knowledgeBase.json +31 -0
  40. package/locales/es-ES/portal.json +1 -0
  41. package/locales/fr-FR/chat.json +46 -3
  42. package/locales/fr-FR/common.json +1 -0
  43. package/locales/fr-FR/components.json +2 -0
  44. package/locales/fr-FR/error.json +1 -0
  45. package/locales/fr-FR/file.json +91 -0
  46. package/locales/fr-FR/knowledgeBase.json +31 -0
  47. package/locales/fr-FR/portal.json +1 -0
  48. package/locales/it-IT/chat.json +46 -3
  49. package/locales/it-IT/common.json +1 -0
  50. package/locales/it-IT/components.json +2 -0
  51. package/locales/it-IT/error.json +1 -0
  52. package/locales/it-IT/file.json +91 -0
  53. package/locales/it-IT/knowledgeBase.json +31 -0
  54. package/locales/it-IT/portal.json +1 -0
  55. package/locales/ja-JP/chat.json +46 -3
  56. package/locales/ja-JP/common.json +1 -0
  57. package/locales/ja-JP/components.json +2 -0
  58. package/locales/ja-JP/error.json +1 -0
  59. package/locales/ja-JP/file.json +91 -0
  60. package/locales/ja-JP/knowledgeBase.json +31 -0
  61. package/locales/ja-JP/portal.json +1 -0
  62. package/locales/ko-KR/chat.json +46 -3
  63. package/locales/ko-KR/common.json +1 -0
  64. package/locales/ko-KR/components.json +2 -0
  65. package/locales/ko-KR/error.json +1 -0
  66. package/locales/ko-KR/file.json +91 -0
  67. package/locales/ko-KR/knowledgeBase.json +31 -0
  68. package/locales/ko-KR/portal.json +1 -0
  69. package/locales/nl-NL/chat.json +46 -3
  70. package/locales/nl-NL/common.json +1 -0
  71. package/locales/nl-NL/components.json +2 -0
  72. package/locales/nl-NL/error.json +1 -0
  73. package/locales/nl-NL/file.json +91 -0
  74. package/locales/nl-NL/knowledgeBase.json +31 -0
  75. package/locales/nl-NL/portal.json +1 -0
  76. package/locales/pl-PL/chat.json +46 -3
  77. package/locales/pl-PL/common.json +1 -0
  78. package/locales/pl-PL/components.json +2 -0
  79. package/locales/pl-PL/error.json +1 -0
  80. package/locales/pl-PL/file.json +91 -0
  81. package/locales/pl-PL/knowledgeBase.json +31 -0
  82. package/locales/pl-PL/portal.json +1 -0
  83. package/locales/pt-BR/chat.json +46 -3
  84. package/locales/pt-BR/common.json +1 -0
  85. package/locales/pt-BR/components.json +2 -0
  86. package/locales/pt-BR/error.json +1 -0
  87. package/locales/pt-BR/file.json +91 -0
  88. package/locales/pt-BR/knowledgeBase.json +31 -0
  89. package/locales/pt-BR/portal.json +1 -0
  90. package/locales/ru-RU/chat.json +46 -3
  91. package/locales/ru-RU/common.json +1 -0
  92. package/locales/ru-RU/components.json +2 -0
  93. package/locales/ru-RU/error.json +1 -0
  94. package/locales/ru-RU/file.json +91 -0
  95. package/locales/ru-RU/knowledgeBase.json +31 -0
  96. package/locales/ru-RU/portal.json +1 -0
  97. package/locales/tr-TR/chat.json +46 -3
  98. package/locales/tr-TR/common.json +1 -0
  99. package/locales/tr-TR/components.json +2 -0
  100. package/locales/tr-TR/error.json +1 -0
  101. package/locales/tr-TR/file.json +91 -0
  102. package/locales/tr-TR/knowledgeBase.json +31 -0
  103. package/locales/tr-TR/portal.json +1 -0
  104. package/locales/vi-VN/chat.json +46 -3
  105. package/locales/vi-VN/common.json +1 -0
  106. package/locales/vi-VN/components.json +2 -0
  107. package/locales/vi-VN/error.json +1 -0
  108. package/locales/vi-VN/file.json +91 -0
  109. package/locales/vi-VN/knowledgeBase.json +31 -0
  110. package/locales/vi-VN/portal.json +1 -0
  111. package/locales/zh-CN/chat.json +46 -3
  112. package/locales/zh-CN/common.json +1 -0
  113. package/locales/zh-CN/components.json +2 -0
  114. package/locales/zh-CN/error.json +1 -0
  115. package/locales/zh-CN/file.json +91 -0
  116. package/locales/zh-CN/knowledgeBase.json +31 -0
  117. package/locales/zh-CN/portal.json +1 -0
  118. package/locales/zh-TW/chat.json +46 -3
  119. package/locales/zh-TW/common.json +1 -0
  120. package/locales/zh-TW/components.json +2 -0
  121. package/locales/zh-TW/error.json +1 -0
  122. package/locales/zh-TW/file.json +91 -0
  123. package/locales/zh-TW/knowledgeBase.json +31 -0
  124. package/locales/zh-TW/portal.json +1 -0
  125. package/package.json +3 -2
  126. package/scripts/migrateServerDB/docker.cjs +6 -0
  127. package/scripts/migrateServerDB/errorHint.js +17 -0
  128. package/scripts/migrateServerDB/index.ts +6 -0
  129. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/FilePreview/FileItem/Content.tsx +37 -0
  130. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/FilePreview/FileItem/index.tsx +87 -0
  131. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/FilePreview/FileItem/style.ts +4 -0
  132. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/FilePreview/FileItem/utils.ts +28 -0
  133. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/FilePreview/FileList.tsx +41 -0
  134. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/FilePreview/index.tsx +40 -0
  135. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/SendMore.tsx +1 -1
  136. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/index.tsx +7 -22
  137. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/TextArea.tsx +1 -1
  138. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +2 -4
  139. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files/FileItem/File.tsx +72 -0
  140. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files/FileItem/Image.tsx +74 -0
  141. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files/FileItem/index.tsx +39 -0
  142. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files/FileItem/style.ts +1 -0
  143. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files/index.tsx +33 -0
  144. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/InputArea/Container.tsx +41 -0
  145. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/InputArea/index.tsx +154 -0
  146. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Send.tsx +34 -0
  147. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/index.tsx +24 -11
  148. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/components/UploadDetail/UploadStatus.tsx +71 -0
  149. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/components/UploadDetail/index.tsx +49 -0
  150. package/src/app/(main)/chat/(workspace)/@portal/FilePreview/index.tsx +26 -0
  151. package/src/app/(main)/chat/(workspace)/@portal/Home/Files/FileList/Item.tsx +53 -0
  152. package/src/app/(main)/chat/(workspace)/@portal/Home/Files/FileList/index.tsx +50 -0
  153. package/src/app/(main)/chat/(workspace)/@portal/Home/Files/index.tsx +21 -0
  154. package/src/app/(main)/chat/(workspace)/@portal/Home/index.tsx +2 -0
  155. package/src/app/(main)/chat/(workspace)/@portal/router.tsx +4 -0
  156. package/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/KnowledgeTag.tsx +41 -0
  157. package/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Tags.tsx +7 -2
  158. package/src/app/(main)/chat/(workspace)/_layout/Desktop/HotKeys.tsx +1 -1
  159. package/src/app/(main)/files/(content)/@menu/default.tsx +27 -0
  160. package/src/app/(main)/files/(content)/@menu/features/FileMenu/index.tsx +97 -0
  161. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/EmptyStatus.tsx +53 -0
  162. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/Item/Content.tsx +175 -0
  163. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/Item/index.tsx +69 -0
  164. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/KnowledgeBaseList.tsx +30 -0
  165. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/SkeletonList.tsx +57 -0
  166. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/index.tsx +54 -0
  167. package/src/app/(main)/files/(content)/@modal/(.)[id]/FileDetail.tsx +16 -0
  168. package/src/app/(main)/files/(content)/@modal/(.)[id]/FilePreview.tsx +15 -0
  169. package/src/app/(main)/files/(content)/@modal/(.)[id]/FullscreenModal.tsx +85 -0
  170. package/src/app/(main)/files/(content)/@modal/(.)[id]/page.tsx +19 -0
  171. package/src/app/(main)/files/(content)/@modal/default.tsx +3 -0
  172. package/src/app/(main)/files/(content)/NotSupportClient.tsx +152 -0
  173. package/src/app/(main)/files/(content)/_layout/Desktop/index.tsx +28 -0
  174. package/src/app/(main)/files/(content)/_layout/Mobile.tsx +47 -0
  175. package/src/app/(main)/files/(content)/_layout/type.ts +7 -0
  176. package/src/app/(main)/files/(content)/layout.tsx +18 -0
  177. package/src/app/(main)/files/(content)/page.tsx +14 -0
  178. package/src/app/(main)/files/[id]/Header.tsx +63 -0
  179. package/src/app/(main)/files/[id]/page.tsx +44 -0
  180. package/src/app/(main)/files/features/FileDetail.tsx +93 -0
  181. package/src/app/(main)/files/hooks/useFileCategory.ts +9 -0
  182. package/src/app/(main)/files/layout.tsx +12 -0
  183. package/src/app/(main)/files/loading.tsx +21 -0
  184. package/src/app/(main)/repos/[id]/@menu/Head/index.tsx +33 -0
  185. package/src/app/(main)/repos/[id]/@menu/Menu/index.tsx +56 -0
  186. package/src/app/(main)/repos/[id]/@menu/default.tsx +25 -0
  187. package/src/app/(main)/repos/[id]/_layout/Desktop/index.tsx +25 -0
  188. package/src/app/(main)/repos/[id]/_layout/Mobile.tsx +47 -0
  189. package/src/app/(main)/repos/[id]/_layout/type.ts +6 -0
  190. package/src/app/(main)/repos/[id]/hooks/useKnowledgeItem.ts +7 -0
  191. package/src/app/(main)/repos/[id]/layout.tsx +13 -0
  192. package/src/app/(main)/repos/[id]/page.tsx +18 -0
  193. package/src/app/(main)/repos/layout.tsx +13 -0
  194. package/src/app/(main)/repos/page.tsx +5 -0
  195. package/src/app/trpc/async/[trpc]/route.ts +28 -0
  196. package/src/chains/abstractChunk.ts +19 -0
  197. package/src/chains/answerWithContext.ts +34 -0
  198. package/src/chains/rewriteQuery.ts +22 -0
  199. package/src/components/DragUpload/index.tsx +6 -99
  200. package/src/components/DragUpload/useDragUpload.tsx +146 -0
  201. package/src/components/FeatureList/index.tsx +64 -0
  202. package/src/components/FileParsingStatus/index.tsx +230 -0
  203. package/src/components/ImageItem/index.tsx +10 -2
  204. package/src/components/KnowledgeIcon/index.tsx +28 -0
  205. package/src/config/app.ts +6 -1
  206. package/src/config/featureFlags/schema.ts +1 -1
  207. package/src/config/modelProviders/bedrock.ts +5 -5
  208. package/src/const/file.ts +1 -0
  209. package/src/const/url.ts +1 -0
  210. package/src/database/client/models/file.ts +8 -2
  211. package/src/database/server/migrations/0005_pgvector.sql +2 -0
  212. package/src/database/server/migrations/0006_add_knowledge_base.sql +307 -0
  213. package/src/database/server/migrations/meta/0005_snapshot.json +2119 -0
  214. package/src/database/server/migrations/meta/0006_snapshot.json +3006 -0
  215. package/src/database/server/migrations/meta/_journal.json +14 -0
  216. package/src/database/server/models/__tests__/_test_template.ts +155 -0
  217. package/src/database/server/models/__tests__/agent.test.ts +226 -0
  218. package/src/database/server/models/__tests__/asyncTask.test.ts +176 -0
  219. package/src/database/server/models/__tests__/chunk.test.ts +336 -0
  220. package/src/database/server/models/__tests__/file.test.ts +317 -29
  221. package/src/database/server/models/__tests__/fixtures/embedding.ts +568 -0
  222. package/src/database/server/models/__tests__/knowledgeBase.test.ts +132 -0
  223. package/src/database/server/models/__tests__/message.test.ts +7 -4
  224. package/src/database/server/models/_template.ts +10 -1
  225. package/src/database/server/models/agent.ts +165 -0
  226. package/src/database/server/models/asyncTask.ts +96 -0
  227. package/src/database/server/models/chunk.ts +203 -0
  228. package/src/database/server/models/embedding.ts +47 -0
  229. package/src/database/server/models/file.ts +231 -12
  230. package/src/database/server/models/knowledgeBase.ts +94 -0
  231. package/src/database/server/models/message.ts +156 -30
  232. package/src/database/server/models/user.ts +12 -1
  233. package/src/database/server/schemas/lobechat/agent.ts +93 -0
  234. package/src/database/server/schemas/lobechat/discover.ts +1 -1
  235. package/src/database/server/schemas/lobechat/file.ts +118 -1
  236. package/src/database/server/schemas/lobechat/index.ts +5 -1
  237. package/src/database/server/schemas/lobechat/message.ts +169 -0
  238. package/src/database/server/schemas/lobechat/rag.ts +51 -0
  239. package/src/database/server/schemas/lobechat/relations.ts +68 -48
  240. package/src/database/server/schemas/lobechat/session.ts +77 -0
  241. package/src/database/server/schemas/lobechat/topic.ts +32 -0
  242. package/src/database/server/schemas/lobechat/user.ts +40 -25
  243. package/src/database/server/utils/idGenerator.ts +1 -0
  244. package/src/features/ChatInput/ActionBar/Clear.tsx +1 -1
  245. package/src/features/ChatInput/ActionBar/Knowledge/Dropdown.tsx +160 -0
  246. package/src/features/ChatInput/ActionBar/Knowledge/ListItem.tsx +52 -0
  247. package/src/features/ChatInput/ActionBar/Knowledge/index.tsx +54 -0
  248. package/src/features/ChatInput/ActionBar/Tools/index.tsx +1 -1
  249. package/src/features/ChatInput/ActionBar/Upload/ClientMode.tsx +52 -0
  250. package/src/features/ChatInput/ActionBar/Upload/ServerMode.tsx +104 -0
  251. package/src/features/ChatInput/ActionBar/Upload/index.tsx +8 -0
  252. package/src/features/ChatInput/ActionBar/config.ts +14 -5
  253. package/src/features/ChatInput/useSend.ts +16 -7
  254. package/src/features/Conversation/Messages/Assistant/FileChunks/Item/index.tsx +51 -0
  255. package/src/features/Conversation/Messages/Assistant/FileChunks/Item/style.ts +38 -0
  256. package/src/features/Conversation/Messages/Assistant/FileChunks/index.tsx +76 -0
  257. package/src/features/Conversation/Messages/Assistant/index.tsx +13 -4
  258. package/src/features/Conversation/Messages/Default.tsx +4 -0
  259. package/src/features/Conversation/Messages/User/BelowMessage.tsx +78 -0
  260. package/src/features/Conversation/Messages/User/FileListViewer/Item.tsx +53 -0
  261. package/src/features/Conversation/Messages/User/FileListViewer/index.tsx +21 -0
  262. package/src/{components/FileList/FileListViewer.tsx → features/Conversation/Messages/User/ImageFileListViewer.tsx} +10 -2
  263. package/src/features/Conversation/Messages/{User.tsx → User/index.tsx} +11 -2
  264. package/src/features/Conversation/Messages/index.ts +8 -3
  265. package/src/features/Conversation/components/ChatItem/index.tsx +33 -10
  266. package/src/features/Conversation/components/InboxWelcome/QuestionSuggest.tsx +1 -1
  267. package/src/features/Conversation/types/index.tsx +1 -0
  268. package/src/features/FileManager/ChunkDrawer/ChunkList/ChunkItem.tsx +61 -0
  269. package/src/features/FileManager/ChunkDrawer/ChunkList/index.tsx +42 -0
  270. package/src/features/FileManager/ChunkDrawer/Content.tsx +38 -0
  271. package/src/features/FileManager/ChunkDrawer/Loading/index.tsx +16 -0
  272. package/src/features/FileManager/ChunkDrawer/SimilaritySearchList/Item.tsx +62 -0
  273. package/src/features/FileManager/ChunkDrawer/SimilaritySearchList/index.tsx +31 -0
  274. package/src/features/FileManager/ChunkDrawer/index.tsx +48 -0
  275. package/src/features/FileManager/FileList/EmptyStatus.tsx +153 -0
  276. package/src/features/FileManager/FileList/FileListItem/ChunkTag.tsx +35 -0
  277. package/src/features/FileManager/FileList/FileListItem/DropdownMenu.tsx +150 -0
  278. package/src/features/FileManager/FileList/FileListItem/index.tsx +211 -0
  279. package/src/features/FileManager/FileList/FileSkeleton.tsx +25 -0
  280. package/src/features/FileManager/FileList/ToolBar/Config.tsx +28 -0
  281. package/src/features/FileManager/FileList/ToolBar/MultiSelectActions.tsx +152 -0
  282. package/src/features/FileManager/FileList/ToolBar/index.tsx +114 -0
  283. package/src/features/FileManager/FileList/index.tsx +143 -0
  284. package/src/features/FileManager/FileList/useCheckTaskStatus.ts +27 -0
  285. package/src/features/FileManager/Header/FilesSearchBar.tsx +41 -0
  286. package/src/features/FileManager/Header/UploadFileButton.tsx +79 -0
  287. package/src/features/FileManager/Header/index.tsx +39 -0
  288. package/src/features/FileManager/UploadDock/Item.tsx +124 -0
  289. package/src/features/FileManager/UploadDock/index.tsx +183 -0
  290. package/src/features/FileManager/index.tsx +38 -0
  291. package/src/features/FileSidePanel/index.tsx +79 -0
  292. package/src/features/FileViewer/NotSupport/index.tsx +54 -0
  293. package/src/features/FileViewer/PDFViewer/HighlightLayer.tsx +81 -0
  294. package/src/features/FileViewer/PDFViewer/index.tsx +93 -0
  295. package/src/features/FileViewer/PDFViewer/style.ts +20 -0
  296. package/src/features/FileViewer/PDFViewer/useResizeObserver.ts +33 -0
  297. package/src/features/FileViewer/TXTViewer/index.tsx +41 -0
  298. package/src/features/FileViewer/index.tsx +45 -0
  299. package/src/features/KnowledgeBaseModal/AddFilesToKnowledgeBase/SelectForm.tsx +115 -0
  300. package/src/features/KnowledgeBaseModal/AddFilesToKnowledgeBase/index.tsx +43 -0
  301. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/Item/Action.tsx +103 -0
  302. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/Item/EditCustomPlugin.tsx +55 -0
  303. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/Item/PluginTag.tsx +58 -0
  304. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/Item/index.tsx +70 -0
  305. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/List.tsx +49 -0
  306. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/Loading.tsx +13 -0
  307. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/index.tsx +39 -0
  308. package/src/features/KnowledgeBaseModal/CreateNew/CreateForm.tsx +73 -0
  309. package/src/features/KnowledgeBaseModal/CreateNew/index.tsx +35 -0
  310. package/src/features/KnowledgeBaseModal/index.ts +3 -0
  311. package/src/libs/langchain/loaders/pdf/index.ts +2 -2
  312. package/src/libs/trpc/async/asyncAuth.ts +24 -0
  313. package/src/libs/trpc/async/index.ts +10 -0
  314. package/src/libs/trpc/async/init.ts +11 -0
  315. package/src/libs/trpc/client/async.ts +14 -0
  316. package/src/libs/trpc/client/index.ts +1 -0
  317. package/src/libs/trpc/client/lambda.ts +9 -0
  318. package/src/libs/trpc/middleware/keyVaults.ts +18 -0
  319. package/src/libs/unstructured/__tests__/index.test.ts +0 -10
  320. package/src/libs/unstructured/index.ts +6 -11
  321. package/src/locales/default/chat.ts +47 -3
  322. package/src/locales/default/common.ts +1 -0
  323. package/src/locales/default/components.ts +2 -0
  324. package/src/locales/default/error.ts +6 -1
  325. package/src/locales/default/file.ts +92 -0
  326. package/src/locales/default/index.ts +4 -0
  327. package/src/locales/default/knowledgeBase.ts +31 -0
  328. package/src/locales/default/portal.ts +1 -0
  329. package/src/middleware.ts +3 -0
  330. package/src/server/asyncContext.ts +40 -0
  331. package/src/server/modules/ContentChunk/index.ts +135 -0
  332. package/src/server/modules/S3/index.ts +30 -5
  333. package/src/server/routers/async/caller.ts +27 -0
  334. package/src/server/routers/async/file.ts +247 -0
  335. package/src/server/routers/async/index.ts +12 -0
  336. package/src/server/routers/lambda/_template.ts +77 -0
  337. package/src/server/routers/lambda/agent.ts +159 -0
  338. package/src/server/routers/lambda/chunk.ts +189 -0
  339. package/src/server/routers/lambda/file.ts +129 -5
  340. package/src/server/routers/lambda/index.ts +6 -0
  341. package/src/server/routers/lambda/knowledgeBase.ts +79 -0
  342. package/src/server/routers/lambda/message.ts +6 -0
  343. package/src/server/routers/lambda/session.ts +0 -25
  344. package/src/server/routers/lambda/user.ts +5 -1
  345. package/src/server/services/chunk/index.ts +74 -0
  346. package/src/server/utils/files.ts +9 -0
  347. package/src/services/__tests__/chat.test.ts +18 -20
  348. package/src/services/__tests__/{upload.test.ts → upload_legacy.test.ts} +1 -1
  349. package/src/services/agent.ts +45 -0
  350. package/src/services/chat.ts +17 -15
  351. package/src/services/file/client.test.ts +1 -50
  352. package/src/services/file/client.ts +12 -25
  353. package/src/services/file/server.ts +25 -3
  354. package/src/services/file/type.ts +7 -4
  355. package/src/services/knowledgeBase.ts +34 -0
  356. package/src/services/message/client.test.ts +1 -1
  357. package/src/services/message/client.ts +29 -3
  358. package/src/services/message/index.ts +0 -2
  359. package/src/services/message/server.ts +9 -3
  360. package/src/services/message/type.ts +1 -13
  361. package/src/services/rag.ts +29 -0
  362. package/src/services/session/server.ts +1 -1
  363. package/src/services/upload.ts +89 -84
  364. package/src/services/upload_legacy.ts +104 -0
  365. package/src/services/user/client.ts +7 -2
  366. package/src/services/user/server.ts +6 -2
  367. package/src/services/user/type.ts +3 -2
  368. package/src/store/agent/slices/chat/action.ts +90 -18
  369. package/src/store/agent/slices/chat/initialState.ts +1 -0
  370. package/src/store/agent/slices/chat/selectors.ts +58 -0
  371. package/src/store/chat/slices/builtinTool/action.test.ts +2 -2
  372. package/src/store/chat/slices/builtinTool/action.ts +2 -2
  373. package/src/store/chat/slices/message/action.test.ts +2 -1
  374. package/src/store/chat/slices/message/action.ts +102 -26
  375. package/src/store/chat/slices/message/actions/rag.ts +148 -0
  376. package/src/store/chat/slices/message/initialState.ts +7 -0
  377. package/src/store/chat/slices/message/reducer.ts +6 -2
  378. package/src/store/chat/slices/message/selectors.ts +38 -3
  379. package/src/store/chat/slices/plugin/action.ts +8 -2
  380. package/src/store/chat/slices/portal/action.ts +8 -0
  381. package/src/store/chat/slices/portal/initialState.ts +3 -0
  382. package/src/store/chat/slices/portal/selectors.ts +8 -2
  383. package/src/store/file/initialState.ts +5 -1
  384. package/src/store/file/reducers/uploadFileList.ts +133 -0
  385. package/src/store/file/selectors.ts +3 -0
  386. package/src/store/file/slices/chat/action.test.ts +90 -90
  387. package/src/store/file/slices/chat/action.ts +164 -109
  388. package/src/store/file/slices/chat/initialState.ts +7 -2
  389. package/src/store/file/slices/chat/selectors.test.ts +84 -61
  390. package/src/store/file/slices/chat/selectors.ts +22 -32
  391. package/src/store/file/slices/chunk/action.ts +36 -0
  392. package/src/store/file/slices/chunk/index.ts +3 -0
  393. package/src/store/file/slices/chunk/initialState.ts +15 -0
  394. package/src/store/file/slices/chunk/selectors.ts +10 -0
  395. package/src/store/file/slices/fileManager/action.ts +187 -0
  396. package/src/store/file/slices/fileManager/index.ts +3 -0
  397. package/src/store/file/slices/fileManager/initialState.ts +18 -0
  398. package/src/store/file/slices/fileManager/selectors.ts +58 -0
  399. package/src/store/file/slices/tts/action.test.ts +1 -1
  400. package/src/store/file/slices/tts/action.ts +2 -2
  401. package/src/store/file/slices/upload/action.ts +164 -0
  402. package/src/store/file/store.ts +12 -1
  403. package/src/store/knowledgeBase/index.ts +2 -0
  404. package/src/store/knowledgeBase/initialState.ts +7 -0
  405. package/src/store/knowledgeBase/selectors.ts +1 -0
  406. package/src/store/knowledgeBase/slices/content/action.ts +27 -0
  407. package/src/store/knowledgeBase/slices/content/index.ts +1 -0
  408. package/src/store/knowledgeBase/slices/crud/action.ts +78 -0
  409. package/src/store/knowledgeBase/slices/crud/index.ts +3 -0
  410. package/src/store/knowledgeBase/slices/crud/initialState.ts +12 -0
  411. package/src/store/knowledgeBase/slices/crud/selectors.ts +7 -0
  412. package/src/store/knowledgeBase/store.ts +30 -0
  413. package/src/store/serverConfig/selectors.test.ts +1 -1
  414. package/src/store/user/slices/preference/selectors.ts +8 -0
  415. package/src/store/user/slices/settings/selectors/systemAgent.ts +2 -0
  416. package/src/tools/dalle/Render/Item/ImageFileItem.tsx +3 -23
  417. package/src/types/agent/index.ts +9 -0
  418. package/src/types/asyncTask.ts +31 -0
  419. package/src/types/chunk/document.ts +9 -0
  420. package/src/types/chunk/index.ts +52 -0
  421. package/src/types/files/index.ts +35 -0
  422. package/src/types/files/list.ts +44 -0
  423. package/src/types/files/upload.ts +91 -0
  424. package/src/types/knowledgeBase/index.ts +45 -0
  425. package/src/types/message/index.ts +54 -5
  426. package/src/types/rag.ts +16 -0
  427. package/src/utils/filter.test.ts +2 -0
  428. package/src/utils/server/auth.ts +23 -0
  429. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/LocalFiles.tsx +0 -46
  430. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Mobile/Files.tsx +0 -19
  431. package/src/components/FileList/EditableFileList.tsx +0 -47
  432. package/src/components/FileList/index.ts +0 -2
  433. package/src/components/FileList/type.tsx +0 -7
  434. package/src/database/server/schemas/lobechat/chat.ts +0 -331
  435. package/src/features/ChatInput/ActionBar/FileUpload.tsx +0 -69
  436. package/src/features/ChatInput/useChatInput.ts +0 -45
  437. package/src/features/FileList/EditableFileList.tsx +0 -31
  438. package/src/features/FileList/FileListPreviewer.tsx +0 -17
  439. package/src/features/FileList/index.tsx +0 -2
  440. package/src/types/files.ts +0 -42
@@ -1,16 +1,18 @@
1
1
  import STT from '../STT';
2
2
  import Clear from './Clear';
3
- import FileUpload from './FileUpload';
4
3
  import History from './History';
4
+ import Knowledge from './Knowledge';
5
5
  import ModelSwitch from './ModelSwitch';
6
6
  import Temperature from './Temperature';
7
7
  import Token from './Token';
8
8
  import Tools from './Tools';
9
+ import Upload from './Upload';
9
10
 
10
11
  export const actionMap = {
11
12
  clear: Clear,
12
- fileUpload: FileUpload,
13
+ fileUpload: Upload,
13
14
  history: History,
15
+ knowledgeBase: Knowledge,
14
16
  model: ModelSwitch,
15
17
  stt: STT,
16
18
  temperature: Temperature,
@@ -26,8 +28,15 @@ type getActionList = (mobile?: boolean) => ActionKeys[];
26
28
 
27
29
  // we can make these action lists configurable in the future
28
30
  export const getLeftActionList: getActionList = (mobile) =>
29
- ['model', 'fileUpload', 'temperature', 'history', !mobile && 'stt', 'tools', 'token'].filter(
30
- Boolean,
31
- ) as ActionKeys[];
31
+ [
32
+ 'model',
33
+ 'fileUpload',
34
+ 'knowledgeBase',
35
+ 'temperature',
36
+ 'history',
37
+ !mobile && 'stt',
38
+ 'tools',
39
+ 'token',
40
+ ].filter(Boolean) as ActionKeys[];
32
41
 
33
42
  export const getRightActionList: getActionList = () => ['clear'].filter(Boolean) as ActionKeys[];
@@ -1,9 +1,9 @@
1
- import { useCallback } from 'react';
1
+ import { useCallback, useMemo } from 'react';
2
2
 
3
3
  import { useChatStore } from '@/store/chat';
4
4
  import { chatSelectors } from '@/store/chat/selectors';
5
5
  import { SendMessageParams } from '@/store/chat/slices/message/action';
6
- import { filesSelectors, useFileStore } from '@/store/file';
6
+ import { fileChatSelectors, useFileStore } from '@/store/file';
7
7
 
8
8
  export type UseSendMessageParams = Pick<
9
9
  SendMessageParams,
@@ -16,22 +16,24 @@ export const useSendMessage = () => {
16
16
  s.updateInputMessage,
17
17
  ]);
18
18
 
19
- return useCallback((params: UseSendMessageParams = {}) => {
19
+ const clearChatUploadFileList = useFileStore((s) => s.clearChatUploadFileList);
20
+
21
+ const send = useCallback((params: UseSendMessageParams = {}) => {
20
22
  const store = useChatStore.getState();
21
23
  if (chatSelectors.isAIGenerating(store)) return;
22
24
 
23
- const imageList = filesSelectors.imageUrlOrBase64List(useFileStore.getState());
25
+ const fileList = fileChatSelectors.chatUploadFileList(useFileStore.getState());
24
26
  // if there is no message and no image, then we should not send the message
25
- if (!store.inputMessage && imageList.length === 0) return;
27
+ if (!store.inputMessage && fileList.length === 0) return;
26
28
 
27
29
  sendMessage({
28
- files: imageList,
30
+ files: fileList,
29
31
  message: store.inputMessage,
30
32
  ...params,
31
33
  });
32
34
 
33
35
  updateInputMessage('');
34
- useFileStore.getState().clearImageList();
36
+ clearChatUploadFileList();
35
37
 
36
38
  // const hasSystemRole = agentSelectors.hasSystemRole(useAgentStore.getState());
37
39
  // const agentSetting = useAgentStore.getState().agentSettingInstance;
@@ -41,4 +43,11 @@ export const useSendMessage = () => {
41
43
  // agentSetting.autocompleteAllMeta();
42
44
  // }
43
45
  }, []);
46
+
47
+ const isUploadingFiles = useFileStore(fileChatSelectors.isUploadingFiles);
48
+ const isSendButtonDisabledByMessage = useChatStore(chatSelectors.isSendButtonDisabledByMessage);
49
+
50
+ const canSend = !isUploadingFiles && !isSendButtonDisabledByMessage;
51
+
52
+ return useMemo(() => ({ canSend, send }), [canSend]);
44
53
  };
@@ -0,0 +1,51 @@
1
+ import { Tooltip } from '@lobehub/ui';
2
+ import { Typography } from 'antd';
3
+ import { memo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import FileIcon from '@/components/FileIcon';
7
+ import { useIsMobile } from '@/hooks/useIsMobile';
8
+ import { useChatStore } from '@/store/chat';
9
+ import { ChatFileChunk } from '@/types/message';
10
+
11
+ import { useStyles } from './style';
12
+
13
+ export interface ChunkItemProps extends ChatFileChunk {
14
+ index: number;
15
+ }
16
+
17
+ const ChunkItem = memo<ChunkItemProps>(({ id, fileId, text, filename, fileType }) => {
18
+ const { styles, cx } = useStyles();
19
+ const openFilePreview = useChatStore((s) => s.openFilePreview);
20
+
21
+ const isMobile = useIsMobile();
22
+ return (
23
+ <Flexbox
24
+ align={'center'}
25
+ className={cx(styles.container, isMobile && styles.mobile)}
26
+ gap={4}
27
+ horizontal
28
+ key={id}
29
+ onClick={(e) => {
30
+ e.stopPropagation();
31
+ openFilePreview(fileId);
32
+ }}
33
+ >
34
+ <FileIcon fileName={filename} fileType={fileType} size={20} variant={'pure'} />
35
+ <Flexbox style={{ maxWidth: 200 }}>
36
+ <Tooltip title={text.slice(0, 100) + '...'}>
37
+ <Typography.Text ellipsis={{ tooltip: false }}>{filename}</Typography.Text>
38
+ </Tooltip>
39
+ {/*<Typography.Text*/}
40
+ {/* ellipsis={{ suffix: '...' }}*/}
41
+ {/* style={{ fontSize: 12, lineHeight: 1 }}*/}
42
+ {/* type={'secondary'}*/}
43
+ {/*>*/}
44
+ {/* {text}*/}
45
+ {/*</Typography.Text>*/}
46
+ </Flexbox>
47
+ </Flexbox>
48
+ );
49
+ });
50
+
51
+ export default ChunkItem;
@@ -0,0 +1,38 @@
1
+ import { createStyles } from 'antd-style';
2
+ import { lighten } from 'polished';
3
+
4
+ export const useStyles = createStyles(({ css, token, isDarkMode }) => ({
5
+ container: css`
6
+ cursor: pointer;
7
+
8
+ width: fit-content;
9
+ padding-block: 6px;
10
+ padding-inline: 8px;
11
+ padding-inline-end: 12px;
12
+
13
+ color: ${token.colorText};
14
+
15
+ background: ${lighten(0.1, token.colorBgElevated)};
16
+ border-radius: 8px;
17
+ box-shadow: ${token.boxShadowTertiary};
18
+
19
+ transition: all 0.2s;
20
+
21
+ &:hover {
22
+ background: ${isDarkMode ? lighten(0.15, token.colorBgElevated) : ''};
23
+ box-shadow: ${token.boxShadowSecondary};
24
+ }
25
+ `,
26
+ filename: css`
27
+ overflow: hidden;
28
+ display: -webkit-box;
29
+ -webkit-box-orient: vertical;
30
+ -webkit-line-clamp: 1;
31
+
32
+ font-size: 12px;
33
+ text-overflow: ellipsis;
34
+ `,
35
+ mobile: css`
36
+ width: 100%;
37
+ `,
38
+ }));
@@ -0,0 +1,76 @@
1
+ import { Icon } from '@lobehub/ui';
2
+ import { createStyles } from 'antd-style';
3
+ import { BookOpenTextIcon, ChevronDown, ChevronRight } from 'lucide-react';
4
+ import { memo, useState } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { Flexbox } from 'react-layout-kit';
7
+
8
+ import { ChatFileChunk } from '@/types/message';
9
+
10
+ import ChunkItem from './Item';
11
+
12
+ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
13
+ container: css`
14
+ cursor: pointer;
15
+
16
+ padding-block: 8px;
17
+ padding-inline: 12px;
18
+ padding-inline-end: 12px;
19
+
20
+ color: ${token.colorText};
21
+
22
+ background: ${token.colorFillTertiary};
23
+ border-radius: 8px;
24
+
25
+ &:hover {
26
+ background: ${isDarkMode ? '' : token.colorFillSecondary};
27
+ }
28
+ `,
29
+ title: css`
30
+ overflow: hidden;
31
+ display: -webkit-box;
32
+ -webkit-box-orient: vertical;
33
+ -webkit-line-clamp: 1;
34
+
35
+ font-size: 12px;
36
+ text-overflow: ellipsis;
37
+ `,
38
+ }));
39
+
40
+ interface FileChunksProps {
41
+ data: ChatFileChunk[];
42
+ }
43
+
44
+ const FileChunks = memo<FileChunksProps>(({ data }) => {
45
+ const { t } = useTranslation('chat');
46
+ const { styles, theme } = useStyles();
47
+
48
+ const [showDetail, setShowDetail] = useState(false);
49
+
50
+ return (
51
+ <Flexbox
52
+ className={styles.container}
53
+ gap={16}
54
+ onClick={() => {
55
+ setShowDetail(!showDetail);
56
+ }}
57
+ width={'100%'}
58
+ >
59
+ <Flexbox distribution={'space-between'} flex={1} horizontal>
60
+ <Flexbox gap={8} horizontal>
61
+ <Icon color={theme.geekblue} icon={BookOpenTextIcon} /> {t('rag.referenceChunks')}
62
+ </Flexbox>
63
+ <Icon icon={showDetail ? ChevronDown : ChevronRight} />
64
+ </Flexbox>
65
+ {showDetail && (
66
+ <Flexbox gap={8} horizontal wrap={'wrap'}>
67
+ {data.map((item, index) => {
68
+ return <ChunkItem index={index} key={item.id} {...item}></ChunkItem>;
69
+ })}
70
+ </Flexbox>
71
+ )}
72
+ </Flexbox>
73
+ );
74
+ });
75
+
76
+ export default FileChunks;
@@ -7,21 +7,30 @@ import { chatSelectors } from '@/store/chat/selectors';
7
7
  import { ChatMessage } from '@/types/message';
8
8
 
9
9
  import { DefaultMessage } from '../Default';
10
+ import FileChunks from './FileChunks';
10
11
  import ToolCall from './ToolCallItem';
11
12
 
12
13
  export const AssistantMessage = memo<
13
14
  ChatMessage & {
14
15
  editableContent: ReactNode;
15
16
  }
16
- >(({ id, tools, content, ...props }) => {
17
+ >(({ id, tools, content, chunksList, ...props }) => {
17
18
  const editing = useChatStore(chatSelectors.isMessageEditing(id));
18
19
  const generating = useChatStore(chatSelectors.isMessageGenerating(id));
19
20
 
20
21
  const isToolCallGenerating = generating && (content === LOADING_FLAT || !content) && !!tools;
21
22
 
22
- return (
23
+ return editing ? (
24
+ <DefaultMessage
25
+ content={content}
26
+ id={id}
27
+ isToolCallGenerating={isToolCallGenerating}
28
+ {...props}
29
+ />
30
+ ) : (
23
31
  <Flexbox gap={8} id={id}>
24
- {(content || editing) && (
32
+ {!!chunksList && chunksList.length > 0 && <FileChunks data={chunksList} />}
33
+ {content && (
25
34
  <DefaultMessage
26
35
  addIdOnDOM={false}
27
36
  content={content}
@@ -30,7 +39,7 @@ export const AssistantMessage = memo<
30
39
  {...props}
31
40
  />
32
41
  )}
33
- {!editing && tools && (
42
+ {tools && (
34
43
  <Flexbox gap={8}>
35
44
  {tools.map((toolCall, index) => (
36
45
  <ToolCall
@@ -21,3 +21,7 @@ export const DefaultMessage = memo<
21
21
 
22
22
  return <div id={addIdOnDOM ? id : undefined}>{editableContent}</div>;
23
23
  });
24
+
25
+ export const DefaultBelowMessage = memo<ChatMessage>(() => {
26
+ return null;
27
+ });
@@ -0,0 +1,78 @@
1
+ import { ActionIcon } from '@lobehub/ui';
2
+ import { Typography } from 'antd';
3
+ import { createStyles } from 'antd-style';
4
+ import isEqual from 'fast-deep-equal';
5
+ import { RotateCwIcon, Trash2 } from 'lucide-react';
6
+ import { memo } from 'react';
7
+ import { useTranslation } from 'react-i18next';
8
+ import { Flexbox } from 'react-layout-kit';
9
+
10
+ import { useChatStore } from '@/store/chat';
11
+ import { ChatMessage } from '@/types/message';
12
+
13
+ const useStyles = createStyles(({ css, cx }) => ({
14
+ action: cx(
15
+ css`
16
+ align-self: flex-end;
17
+ opacity: 0;
18
+ `,
19
+ 'rag-query-actions',
20
+ ),
21
+ container: css`
22
+ &:hover {
23
+ .rag-query-actions {
24
+ opacity: 1;
25
+ }
26
+ }
27
+ `,
28
+ content: css`
29
+ overflow-y: scroll;
30
+ flex-wrap: wrap;
31
+
32
+ width: 100%;
33
+ max-height: 54px;
34
+ margin-block-start: 6px;
35
+ `,
36
+ }));
37
+
38
+ export const UserBelowMessage = memo<ChatMessage>(({ ragQuery, content, id }) => {
39
+ const { styles } = useStyles();
40
+
41
+ const { t } = useTranslation('chat');
42
+
43
+ const [deleteUserMessageRagQuery, rewriteQuery] = useChatStore((s) => [
44
+ s.deleteUserMessageRagQuery,
45
+ s.rewriteQuery,
46
+ ]);
47
+
48
+ return (
49
+ !!ragQuery &&
50
+ !isEqual(ragQuery, content) && (
51
+ <Flexbox className={styles.container}>
52
+ <Flexbox align={'center'} className={styles.content} gap={4} horizontal>
53
+ <Typography.Text style={{ fontSize: 12 }} type={'secondary'}>
54
+ {ragQuery}
55
+ </Typography.Text>
56
+ </Flexbox>
57
+ <Flexbox className={styles.action} horizontal>
58
+ <ActionIcon
59
+ icon={Trash2}
60
+ onClick={() => {
61
+ deleteUserMessageRagQuery(id);
62
+ }}
63
+ size={'small'}
64
+ title={t('rag.userQuery.actions.delete')}
65
+ />
66
+ <ActionIcon
67
+ icon={RotateCwIcon}
68
+ onClick={() => {
69
+ rewriteQuery(id);
70
+ }}
71
+ size={'small'}
72
+ title={t('rag.userQuery.actions.regenerate')}
73
+ />
74
+ </Flexbox>
75
+ </Flexbox>
76
+ )
77
+ );
78
+ });
@@ -0,0 +1,53 @@
1
+ import { Typography } from 'antd';
2
+ import { createStyles } from 'antd-style';
3
+ import { memo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import FileIcon from '@/components/FileIcon';
7
+ import { useChatStore } from '@/store/chat';
8
+ import { ChatFileItem } from '@/types/message';
9
+ import { formatSize } from '@/utils/format';
10
+
11
+ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
12
+ container: css`
13
+ cursor: pointer;
14
+
15
+ overflow: hidden;
16
+
17
+ max-width: 420px;
18
+ padding-block: 8px;
19
+ padding-inline: 12px 32px;
20
+
21
+ border: 1px solid ${isDarkMode ? token.colorBorder : token.colorSplit};
22
+ border-radius: 8px;
23
+
24
+ &:hover {
25
+ background: ${token.colorFillTertiary};
26
+ }
27
+ `,
28
+ }));
29
+
30
+ const FileItem = memo<ChatFileItem>(({ id, fileType, size, name }) => {
31
+ const { styles } = useStyles();
32
+
33
+ const openFilePreview = useChatStore((s) => s.openFilePreview);
34
+
35
+ return (
36
+ <Flexbox
37
+ className={styles.container}
38
+ gap={12}
39
+ horizontal
40
+ key={id}
41
+ onClick={() => {
42
+ openFilePreview(id);
43
+ }}
44
+ >
45
+ <FileIcon fileName={name} fileType={fileType} />
46
+ <Flexbox style={{ overflow: 'hidden' }}>
47
+ <Typography.Text ellipsis>{name}</Typography.Text>
48
+ <Typography.Text type={'secondary'}>{formatSize(size)}</Typography.Text>
49
+ </Flexbox>
50
+ </Flexbox>
51
+ );
52
+ });
53
+ export default FileItem;
@@ -0,0 +1,21 @@
1
+ import { memo } from 'react';
2
+ import { Flexbox } from 'react-layout-kit';
3
+
4
+ import { ChatFileItem } from '@/types/message';
5
+
6
+ import FileItem from './Item';
7
+
8
+ interface FileListViewerProps {
9
+ items: ChatFileItem[];
10
+ }
11
+
12
+ const FileListViewer = memo<FileListViewerProps>(({ items }) => {
13
+ return (
14
+ <Flexbox gap={8}>
15
+ {items.map((item) => (
16
+ <FileItem key={item.id} {...item} />
17
+ ))}
18
+ </Flexbox>
19
+ );
20
+ });
21
+ export default FileListViewer;
@@ -4,16 +4,24 @@ import { memo } from 'react';
4
4
  import GalleyGrid from '@/components/GalleyGrid';
5
5
  import ImageItem from '@/components/ImageItem';
6
6
 
7
- import { ImageFileItem } from './type';
7
+ interface ImageFileItem {
8
+ alt?: string;
9
+ id: string;
10
+ loading?: boolean;
11
+ onRemove?: (id: string) => void;
12
+ url: string;
13
+ }
8
14
 
9
15
  interface FileListProps {
10
16
  items: ImageFileItem[];
11
17
  }
12
18
 
13
- export const ImageFileListViewer = memo<FileListProps>(({ items }) => {
19
+ const ImageFileListViewer = memo<FileListProps>(({ items }) => {
14
20
  return (
15
21
  <ImageGallery>
16
22
  <GalleyGrid items={items} renderItem={ImageItem} />
17
23
  </ImageGallery>
18
24
  );
19
25
  });
26
+
27
+ export default ImageFileListViewer;
@@ -3,9 +3,11 @@ import { Flexbox } from 'react-layout-kit';
3
3
 
4
4
  import BubblesLoading from '@/components/BubblesLoading';
5
5
  import { LOADING_FLAT } from '@/const/message';
6
- import { FileListPreviewer } from '@/features/FileList';
7
6
  import { ChatMessage } from '@/types/message';
8
7
 
8
+ import FileListViewer from './FileListViewer';
9
+ import ImageFileListViewer from './ImageFileListViewer';
10
+
9
11
  export const UserMessage = memo<
10
12
  ChatMessage & {
11
13
  editableContent: ReactNode;
@@ -16,7 +18,14 @@ export const UserMessage = memo<
16
18
  return (
17
19
  <Flexbox gap={8} id={id}>
18
20
  {editableContent}
19
- {res.files && res.files?.length > 0 && <FileListPreviewer items={res.files} />}
21
+ {res.imageList && res.imageList?.length > 0 && <ImageFileListViewer items={res.imageList} />}
22
+ {res.fileList && res.fileList?.length > 0 && (
23
+ <div style={{ marginTop: 8 }}>
24
+ <FileListViewer items={res.fileList} />
25
+ </div>
26
+ )}
20
27
  </Flexbox>
21
28
  );
22
29
  });
30
+
31
+ export * from './BelowMessage';
@@ -3,11 +3,11 @@ import { useGlobalStore } from '@/store/global';
3
3
  import { useSessionStore } from '@/store/session';
4
4
  import { sessionSelectors } from '@/store/session/selectors';
5
5
 
6
- import { OnAvatarsClick, RenderMessage } from '../types';
6
+ import { OnAvatarsClick, RenderBelowMessage, RenderMessage } from '../types';
7
7
  import { AssistantMessage } from './Assistant';
8
- import { DefaultMessage } from './Default';
8
+ import { DefaultBelowMessage, DefaultMessage } from './Default';
9
9
  import { ToolMessage } from './Tool';
10
- import { UserMessage } from './User';
10
+ import { UserBelowMessage, UserMessage } from './User';
11
11
 
12
12
  export const renderMessages: Record<string, RenderMessage> = {
13
13
  assistant: AssistantMessage,
@@ -17,6 +17,11 @@ export const renderMessages: Record<string, RenderMessage> = {
17
17
  user: UserMessage,
18
18
  };
19
19
 
20
+ export const renderBelowMessages: Record<string, RenderBelowMessage> = {
21
+ default: DefaultBelowMessage,
22
+ user: UserBelowMessage,
23
+ };
24
+
20
25
  export const useAvatarsClick = (): OnAvatarsClick => {
21
26
  const [isInbox] = useSessionStore((s) => [sessionSelectors.isInboxSession(s)]);
22
27
  const [toggleSystemRole] = useGlobalStore((s) => [s.toggleSystemRole]);
@@ -16,7 +16,7 @@ import { ChatMessage } from '@/types/message';
16
16
 
17
17
  import ErrorMessageExtra, { useErrorContent } from '../../Error';
18
18
  import { renderMessagesExtra } from '../../Extras';
19
- import { renderMessages, useAvatarsClick } from '../../Messages';
19
+ import { renderBelowMessages, renderMessages, useAvatarsClick } from '../../Messages';
20
20
  import ActionsBar from './ActionsBar';
21
21
  import HistoryDivider from './HistoryDivider';
22
22
 
@@ -57,14 +57,24 @@ const Item = memo<ChatListItemProps>(({ index, id }) => {
57
57
 
58
58
  const historyLength = useChatStore((s) => chatSelectors.currentChats(s).length);
59
59
 
60
- const [isMessageLoading, generating, editing, toggleMessageEditing, updateMessageContent] =
61
- useChatStore((s) => [
62
- chatSelectors.isMessageLoading(id)(s),
63
- chatSelectors.isMessageGenerating(id)(s),
64
- chatSelectors.isMessageEditing(id)(s),
65
- s.toggleMessageEditing,
66
- s.modifyMessageContent,
67
- ]);
60
+ const [
61
+ isMessageLoading,
62
+ generating,
63
+ isInRAGFlow,
64
+ editing,
65
+ toggleMessageEditing,
66
+ updateMessageContent,
67
+ ] = useChatStore((s) => [
68
+ chatSelectors.isMessageLoading(id)(s),
69
+ chatSelectors.isMessageGenerating(id)(s),
70
+ chatSelectors.isMessageInRAGFlow(id)(s),
71
+ chatSelectors.isMessageEditing(id)(s),
72
+ s.toggleMessageEditing,
73
+ s.modifyMessageContent,
74
+ ]);
75
+
76
+ // when the message is in RAG flow or the AI generating, it should be in loading state
77
+ const isProcessing = isInRAGFlow || generating;
68
78
 
69
79
  const onAvatarsClick = useAvatarsClick();
70
80
 
@@ -80,6 +90,18 @@ const Item = memo<ChatListItemProps>(({ index, id }) => {
80
90
  [item?.role],
81
91
  );
82
92
 
93
+ const BelowMessage = useCallback(
94
+ ({ data }: { data: ChatMessage }) => {
95
+ if (!item?.role) return;
96
+ const RenderFunction = renderBelowMessages[item.role] ?? renderBelowMessages['default'];
97
+
98
+ if (!RenderFunction) return;
99
+
100
+ return <RenderFunction {...data} />;
101
+ },
102
+ [item?.role],
103
+ );
104
+
83
105
  const MessageExtra = useCallback(
84
106
  ({ data }: { data: ChatMessage }) => {
85
107
  if (!renderMessagesExtra || !item?.role) return;
@@ -116,12 +138,13 @@ const Item = memo<ChatListItemProps>(({ index, id }) => {
116
138
  />
117
139
  }
118
140
  avatar={item.meta}
141
+ belowMessage={<BelowMessage data={item} />}
119
142
  className={cx(styles.message, isMessageLoading && styles.loading)}
120
143
  editing={editing}
121
144
  error={error}
122
145
  errorMessage={<ErrorMessageExtra data={item} />}
123
146
  fontSize={fontSize}
124
- loading={generating}
147
+ loading={isProcessing}
125
148
  message={item.content}
126
149
  messageExtra={<MessageExtra data={item} />}
127
150
  onAvatarClick={onAvatarsClick?.(item.role)}
@@ -65,7 +65,7 @@ const QuestionSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
65
65
 
66
66
  const { t } = useTranslation('welcome');
67
67
  const { styles } = useStyles();
68
- const sendMessage = useSendMessage();
68
+ const { send: sendMessage } = useSendMessage();
69
69
 
70
70
  return (
71
71
  <Flexbox gap={8} width={'100%'}>
@@ -11,6 +11,7 @@ export type OnActionsClick = (action: ActionEvent, message: ChatMessage) => void
11
11
  export type OnAvatarsClick = (role: RenderRole) => ChatItemProps['onAvatarClick'];
12
12
  export type RenderRole = LLMRoleType | 'default' | string;
13
13
  export type RenderMessage = FC<ChatMessage & { editableContent: ReactNode }>;
14
+ export type RenderBelowMessage = FC<ChatMessage>;
14
15
  export type RenderMessageExtra = FC<ChatMessage>;
15
16
 
16
17
  export type RenderAction = FC<ActionsBarProps & ChatMessage>;