@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
@@ -0,0 +1,31 @@
1
+ {
2
+ "addToKnowledgeBase": {
3
+ "addSuccess": "文件添加成功,<1>立即查看</1>",
4
+ "confirm": "添加",
5
+ "id": {
6
+ "placeholder": "请选择要添加的知识库",
7
+ "required": "请选择知识库",
8
+ "title": "目标知识库"
9
+ },
10
+ "title": "添加到知识库",
11
+ "totalFiles": "已选择 {{count}} 个文件"
12
+ },
13
+ "createNew": {
14
+ "confirm": "新建",
15
+ "description": {
16
+ "placeholder": "知识库简介(选填)"
17
+ },
18
+ "formTitle": "基本信息",
19
+ "name": {
20
+ "placeholder": "知识库名称",
21
+ "required": "请填写知识库名称"
22
+ },
23
+ "title": "新建知识库"
24
+ },
25
+ "tab": {
26
+ "files": "文档",
27
+ "settings": "设置",
28
+ "testing": "召回测试"
29
+ },
30
+ "title": "知识库"
31
+ }
@@ -6,5 +6,6 @@
6
6
  "summaryTooltip": "总结当前内容"
7
7
  },
8
8
  "emptyArtifactList": "当前 Artifacts 列表为空,请在会话中按需使用插件后再查看",
9
+ "files": "文件",
9
10
  "title": "工作区"
10
11
  }
@@ -36,6 +36,24 @@
36
36
  "stop": "停止",
37
37
  "warp": "換行"
38
38
  },
39
+ "knowledgeBase": {
40
+ "all": "所有內容",
41
+ "allFiles": "所有檔案",
42
+ "allKnowledgeBases": "所有知識庫",
43
+ "disabled": "當前部署模式不支持知識庫對話,如需使用,請切換到伺服器端資料庫部署或使用 LobeChat Cloud 服務",
44
+ "library": {
45
+ "action": {
46
+ "add": "添加",
47
+ "detail": "詳情",
48
+ "remove": "移除"
49
+ },
50
+ "title": "檔案/知識庫"
51
+ },
52
+ "relativeFilesOrKnowledgeBases": "關聯檔案/知識庫",
53
+ "title": "知識庫",
54
+ "uploadGuide": "上傳過的檔案可以在「知識庫」中查看哦",
55
+ "viewMore": "查看更多"
56
+ },
39
57
  "messageAction": {
40
58
  "delAndRegenerate": "刪除並重新生成",
41
59
  "regenerate": "重新生成"
@@ -43,6 +61,15 @@
43
61
  "newAgent": "新建助手",
44
62
  "pin": "置頂",
45
63
  "pinOff": "取消置頂",
64
+ "rag": {
65
+ "referenceChunks": "引用來源",
66
+ "userQuery": {
67
+ "actions": {
68
+ "delete": "刪除 Query 重寫",
69
+ "regenerate": "重新生成 Query"
70
+ }
71
+ }
72
+ },
46
73
  "regenerate": "重新生成",
47
74
  "roleAndArchive": "角色與記錄",
48
75
  "searchAgentPlaceholder": "搜索助手和對話...",
@@ -129,8 +156,24 @@
129
156
  },
130
157
  "updateAgent": "更新助理信息",
131
158
  "upload": {
132
- "actionFiletip": "上傳文件",
133
- "actionTooltip": "上傳圖片",
134
- "disabled": "當前模型不支援視覺識別,請切換模型後使用"
159
+ "action": {
160
+ "fileUpload": "上傳檔案",
161
+ "folderUpload": "上傳資料夾",
162
+ "imageDisabled": "當前模型不支援視覺識別,請切換模型後使用",
163
+ "imageUpload": "上傳圖片",
164
+ "tooltip": "上傳"
165
+ },
166
+ "clientMode": {
167
+ "actionFiletip": "上傳檔案",
168
+ "actionTooltip": "上傳",
169
+ "disabled": "當前模型不支援視覺識別和檔案分析,請切換模型後使用"
170
+ },
171
+ "preview": {
172
+ "prepareTasks": "準備分塊...",
173
+ "status": {
174
+ "pending": "準備上傳...",
175
+ "processing": "檔案處理中..."
176
+ }
177
+ }
135
178
  }
136
179
  }
@@ -13,6 +13,7 @@
13
13
  "autoGenerate": "自動生成",
14
14
  "autoGenerateTooltip": "基於提示詞自動生成助手描述",
15
15
  "autoGenerateTooltipDisabled": "請填寫提示詞後使用自動補全功能",
16
+ "back": "返回",
16
17
  "batchDelete": "批次刪除",
17
18
  "blog": "產品部落格",
18
19
  "cancel": "取消",
@@ -50,6 +50,8 @@
50
50
  "chunks": {
51
51
  "embeddingStatus": {
52
52
  "empty": "文本塊尚未完全向量化,將導致語義檢索功能不可用,為提升檢索質量,請對文本塊向量化",
53
+ "error": "向量化失敗",
54
+ "errorResult": "向量化失敗,請檢查後重試。失敗原因:",
53
55
  "processing": "文本塊正在向量化,請耐心等待",
54
56
  "success": "當前文本塊均已向量化"
55
57
  },
@@ -115,6 +115,7 @@
115
115
  },
116
116
  "upload": {
117
117
  "desc": "詳情: {{detail}}",
118
+ "fileOnlySupportInServerMode": "當前部署模式不支持上傳非圖片文件,如需上傳 {{ext}} 格式,請切換到伺服器端資料庫部署或使用 LobeChat Cloud 服務",
118
119
  "title": "檔案上傳失敗,請檢查網路連線或稍後再試"
119
120
  }
120
121
  }
@@ -0,0 +1,91 @@
1
+ {
2
+ "desc": "管理你的文件與知識庫",
3
+ "detail": {
4
+ "basic": {
5
+ "createdAt": "創建時間",
6
+ "filename": "檔案名稱",
7
+ "size": "檔案大小",
8
+ "title": "基本資訊",
9
+ "type": "格式",
10
+ "updatedAt": "更新時間"
11
+ },
12
+ "data": {
13
+ "chunkCount": "分塊數",
14
+ "embedding": {
15
+ "default": "暫未向量化",
16
+ "error": "失敗",
17
+ "pending": "待啟動",
18
+ "processing": "進行中",
19
+ "success": "已完成"
20
+ },
21
+ "embeddingStatus": "向量化"
22
+ }
23
+ },
24
+ "header": {
25
+ "actions": {
26
+ "newFolder": "新建資料夾",
27
+ "uploadFile": "上傳檔案",
28
+ "uploadFolder": "上傳資料夾"
29
+ },
30
+ "uploadButton": "上傳"
31
+ },
32
+ "knowledgeBase": {
33
+ "list": {
34
+ "confirmRemoveKnowledgeBase": "即將刪除該知識庫,其中的檔案不會刪除,將移入全部檔案中。知識庫刪除後將不可恢復,請謹慎操作。",
35
+ "empty": "點擊 <1>+</1> 開始創建知識庫"
36
+ },
37
+ "new": "新建知識庫",
38
+ "title": "知識庫"
39
+ },
40
+ "notSupportGuide": {
41
+ "desc": "當前部署實例為客戶端資料庫模式,無法使用檔案管理功能。請切換到<1>伺服器端資料庫部署模式</1>,或直接使用 <3>LobeChat Cloud</3>",
42
+ "features": {
43
+ "allKind": {
44
+ "desc": "支持主流檔案類型,包括 Word、PPT、Excel、PDF、TXT 等常見文檔格式,以及JS、Python 等主流程式碼檔案",
45
+ "title": "多種檔案類型解析"
46
+ },
47
+ "embeddings": {
48
+ "desc": "使用高性能向量模型,對文本分塊進行向量化,實現檔案內容的語義化檢索",
49
+ "title": "向量語義化"
50
+ },
51
+ "repos": {
52
+ "desc": "支持創建知識庫,並允許添加不同類型的檔案,構建屬於你的領域知識",
53
+ "title": "知識庫"
54
+ }
55
+ },
56
+ "title": "當前部署模式不支持檔案管理"
57
+ },
58
+ "preview": {
59
+ "unsupportedFile": "此檔案格式不支持在線預覽"
60
+ },
61
+ "searchFilePlaceholder": "搜索檔案",
62
+ "tab": {
63
+ "all": "全部檔案",
64
+ "audios": "語音",
65
+ "documents": "文檔",
66
+ "images": "圖片",
67
+ "videos": "視頻",
68
+ "websites": "網頁"
69
+ },
70
+ "title": "檔案",
71
+ "uploadDock": {
72
+ "body": {
73
+ "collapse": "收起",
74
+ "item": {
75
+ "done": "已上傳",
76
+ "error": "上傳失敗,請重試",
77
+ "pending": "準備上傳...",
78
+ "processing": "檔案處理中...",
79
+ "restTime": "剩餘 {{time}}"
80
+ }
81
+ },
82
+ "totalCount": "共 {{count}} 項",
83
+ "uploadStatus": {
84
+ "error": "上傳出錯",
85
+ "pending": "等待上傳",
86
+ "processing": "正在上傳",
87
+ "success": "上傳完成",
88
+ "uploading": "正在上傳"
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "addToKnowledgeBase": {
3
+ "addSuccess": "文件添加成功,<1>立即查看</1>",
4
+ "confirm": "添加",
5
+ "id": {
6
+ "placeholder": "請選擇要添加的知識庫",
7
+ "required": "請選擇知識庫",
8
+ "title": "目標知識庫"
9
+ },
10
+ "title": "添加到知識庫",
11
+ "totalFiles": "已選擇 {{count}} 個文件"
12
+ },
13
+ "createNew": {
14
+ "confirm": "新建",
15
+ "description": {
16
+ "placeholder": "知識庫簡介(選填)"
17
+ },
18
+ "formTitle": "基本信息",
19
+ "name": {
20
+ "placeholder": "知識庫名稱",
21
+ "required": "請填寫知識庫名稱"
22
+ },
23
+ "title": "新建知識庫"
24
+ },
25
+ "tab": {
26
+ "files": "文檔",
27
+ "settings": "設置",
28
+ "testing": "召回測試"
29
+ },
30
+ "title": "知識庫"
31
+ }
@@ -6,5 +6,6 @@
6
6
  "summaryTooltip": "總結目前內容"
7
7
  },
8
8
  "emptyArtifactList": "當前文物列表為空,請在會話中按需使用插件後再查看",
9
+ "files": "檔案",
9
10
  "title": "擴展視窗"
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.11.8",
3
+ "version": "1.12.0",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -53,7 +53,8 @@
53
53
  "pull": "git pull",
54
54
  "release": "semantic-release",
55
55
  "self-hosting:docker": "docker build -t lobe-chat:local .",
56
- "self-hosting:docker-cn": "docker build -t lobe-chat:local --build-arg USE_CN_MIRROR=true .",
56
+ "self-hosting:docker-cn": "docker build -t lobe-chat-local --build-arg USE_CN_MIRROR=true .",
57
+ "self-hosting:docker-cn@database": "docker build -t lobe-chat-database-local -f Dockerfile.database --build-arg USE_CN_MIRROR=true .",
57
58
  "start": "next start -p 3210",
58
59
  "stylelint": "stylelint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
59
60
  "test": "npm run test-app && npm run test-server",
@@ -2,6 +2,7 @@ const { join } = require('node:path');
2
2
  const { Pool } = require('pg');
3
3
  const { drizzle } = require('drizzle-orm/node-postgres');
4
4
  const migrator = require('drizzle-orm/node-postgres/migrator');
5
+ const { PGVECTOR_HINT } = require('./errorHint');
5
6
 
6
7
  if (!process.env.DATABASE_URL) {
7
8
  throw new Error('DATABASE_URL is not set, please set it in your environment variables.');
@@ -29,6 +30,11 @@ runMigrations().catch((err) => {
29
30
  '❌ Database migrate failed. Please check your database is valid and DATABASE_URL is set correctly. The error detail is below:',
30
31
  );
31
32
  console.error(err);
33
+
34
+ if (err.message.includes('extension "vector" is not available')) {
35
+ console.info(PGVECTOR_HINT);
36
+ }
37
+
32
38
  // eslint-disable-next-line unicorn/no-process-exit
33
39
  process.exit(1);
34
40
  });
@@ -0,0 +1,17 @@
1
+ const PGVECTOR_HINT = `⚠️ Database migrate failed due to \`pgvector\` extension not found. Please install the \`pgvector\` extension on your postgres instance.
2
+
3
+ 1) if you are using docker postgres image:
4
+ you can just use \`pgvector/pgvector:pg16\` image instead of \`postgres\`, e.g:
5
+
6
+ \`\`\`
7
+ docker run -p 5432:5432 -d --name pg -e POSTGRES_PASSWORD=mysecretpassword pgvector/pgvector:pg16
8
+ \`\`\`
9
+
10
+ 2) if you are using cloud postgres instance, please contact your cloud provider for help.
11
+
12
+ if you have any other question, please open issue here: https://github.com/lobehub/lobe-chat/issues
13
+ `;
14
+
15
+ module.exports = {
16
+ PGVECTOR_HINT,
17
+ };
@@ -3,6 +3,7 @@ import * as migrator from 'drizzle-orm/neon-serverless/migrator';
3
3
  import { join } from 'node:path';
4
4
 
5
5
  import { serverDB } from '../../src/database/server/core/db';
6
+ import { PGVECTOR_HINT } from './errorHint';
6
7
 
7
8
  // Read the `.env` file if it exists, or a file specified by the
8
9
  // dotenv_config_path parameter that's passed to Node.js
@@ -24,6 +25,11 @@ if (connectionString) {
24
25
  // eslint-disable-next-line unicorn/prefer-top-level-await
25
26
  runMigrations().catch((err) => {
26
27
  console.error('❌ Database migrate failed:', err);
28
+
29
+ if ((err.message as string).includes('extension "vector" is not available')) {
30
+ console.info(PGVECTOR_HINT);
31
+ }
32
+
27
33
  // eslint-disable-next-line unicorn/no-process-exit
28
34
  process.exit(1);
29
35
  });
@@ -0,0 +1,37 @@
1
+ import { Image } from '@lobehub/ui';
2
+ import { createStyles } from 'antd-style';
3
+ import { memo } from 'react';
4
+
5
+ import FileIcon from '@/components/FileIcon';
6
+ import { UploadFileItem } from '@/types/files/upload';
7
+
8
+ const useStyles = createStyles(({ css }) => ({
9
+ image: css`
10
+ margin-block: 0 !important;
11
+ box-shadow: none;
12
+
13
+ img {
14
+ object-fit: contain;
15
+ }
16
+ `,
17
+ video: css`
18
+ overflow: hidden;
19
+ border-radius: 8px;
20
+ `,
21
+ }));
22
+
23
+ const Content = memo<UploadFileItem>(({ file, previewUrl }) => {
24
+ const { styles } = useStyles();
25
+
26
+ if (file.type.startsWith('image')) {
27
+ return <Image alt={file.name} src={previewUrl} wrapperClassName={styles.image} />;
28
+ }
29
+
30
+ if (file.type.startsWith('video')) {
31
+ return <video className={styles.video} src={previewUrl} width={'100%'} />;
32
+ }
33
+
34
+ return <FileIcon fileName={file.name} fileType={file.type} size={100} />;
35
+ });
36
+
37
+ export default Content;
@@ -0,0 +1,87 @@
1
+ import { ActionIcon } from '@lobehub/ui';
2
+ import { Typography } from 'antd';
3
+ import { createStyles } from 'antd-style';
4
+ import { Trash2Icon } from 'lucide-react';
5
+ import { memo } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+ import { Center, Flexbox } from 'react-layout-kit';
8
+
9
+ import { useFileStore } from '@/store/file';
10
+ import { UploadFileItem } from '@/types/files/upload';
11
+
12
+ import UploadDetail from '../../../components/UploadDetail';
13
+ import Content from './Content';
14
+ import { FILE_ITEM_SIZE } from './style';
15
+
16
+ const useStyles = createStyles(({ css, token }) => ({
17
+ actions: css`
18
+ position: absolute;
19
+ z-index: 10;
20
+ inset-block-start: -4px;
21
+ inset-inline-end: -4px;
22
+
23
+ background: ${token.colorBgElevated};
24
+ border-radius: 5px;
25
+ box-shadow:
26
+ 0 0 0 0.5px ${token.colorFillSecondary} inset,
27
+ ${token.boxShadowTertiary};
28
+ `,
29
+ container: css`
30
+ position: relative;
31
+
32
+ width: ${FILE_ITEM_SIZE}px;
33
+ min-width: ${FILE_ITEM_SIZE}px;
34
+ height: ${FILE_ITEM_SIZE}px;
35
+
36
+ background: ${token.colorBgContainer};
37
+ border-radius: 8px;
38
+ `,
39
+ image: css`
40
+ margin-block: 0 !important;
41
+ `,
42
+ status: css`
43
+ &.ant-tag {
44
+ padding-inline: 0;
45
+ background: none;
46
+ }
47
+ `,
48
+ }));
49
+
50
+ type FileItemProps = UploadFileItem;
51
+
52
+ const spacing = 8;
53
+
54
+ const FileItem = memo<FileItemProps>((props) => {
55
+ const { file, uploadState, status, id, tasks } = props;
56
+ const { t } = useTranslation(['chat', 'common']);
57
+ const { styles } = useStyles();
58
+ const [removeChatUploadFile] = useFileStore((s) => [s.removeChatUploadFile]);
59
+
60
+ return (
61
+ <Flexbox className={styles.container} distribution={'space-between'}>
62
+ <Center flex={1} height={FILE_ITEM_SIZE - 46} padding={spacing}>
63
+ <Content {...props} />
64
+ </Center>
65
+ <Flexbox gap={4} style={{ paddingBottom: 4, paddingInline: spacing }}>
66
+ <Typography.Text ellipsis={{ tooltip: true }} style={{ fontSize: 12 }}>
67
+ {file.name}
68
+ </Typography.Text>
69
+
70
+ <UploadDetail size={file.size} status={status} tasks={tasks} uploadState={uploadState} />
71
+ </Flexbox>
72
+ <Flexbox className={styles.actions}>
73
+ <ActionIcon
74
+ color={'red'}
75
+ icon={Trash2Icon}
76
+ onClick={() => {
77
+ removeChatUploadFile(id);
78
+ }}
79
+ size={'small'}
80
+ title={t('delete', { ns: 'common' })}
81
+ />
82
+ </Flexbox>
83
+ </Flexbox>
84
+ );
85
+ });
86
+
87
+ export default FileItem;
@@ -0,0 +1,4 @@
1
+ export const FILE_ITEM_SIZE = 200;
2
+
3
+ // 8px on each side
4
+ export const IMAGE_FILE_SIZE = 200 - 2 * 8;
@@ -0,0 +1,28 @@
1
+ export const getHarmoniousSize = (
2
+ inputWidth: number,
3
+ inputHeight: number,
4
+ {
5
+ spacing = 24,
6
+ containerWidth,
7
+ containerHeight,
8
+ }: { containerHeight: number; containerWidth: number; spacing: number },
9
+ ) => {
10
+ let width = String(inputWidth);
11
+ let height = String(inputHeight);
12
+
13
+ const maxWidth = containerWidth - spacing;
14
+ const maxHeight = containerHeight - spacing;
15
+
16
+ if (inputHeight >= inputWidth && inputHeight >= maxHeight) {
17
+ height = maxHeight + 'px';
18
+ width = 'auto';
19
+ } else if (inputWidth >= inputHeight && inputWidth >= maxWidth) {
20
+ height = 'auto';
21
+ width = maxWidth + 'px';
22
+ } else {
23
+ width = width + 'px';
24
+ height = height + 'px';
25
+ }
26
+
27
+ return { height, width };
28
+ };
@@ -0,0 +1,41 @@
1
+ import { createStyles } from 'antd-style';
2
+ import { lighten } from 'polished';
3
+ import { memo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import { fileChatSelectors, useFileStore } from '@/store/file';
7
+
8
+ import FileItem from './FileItem';
9
+
10
+ const useStyles = createStyles(({ css, token }) => ({
11
+ container: css`
12
+ overflow-x: scroll;
13
+
14
+ width: 100%;
15
+
16
+ background: ${lighten(0.01, token.colorBgLayout)};
17
+ border-start-start-radius: 8px;
18
+ border-start-end-radius: 8px;
19
+ `,
20
+ }));
21
+
22
+ const FileList = memo(() => {
23
+ const inputFilesList = useFileStore(fileChatSelectors.chatUploadFileList);
24
+ const showFileList = useFileStore(fileChatSelectors.chatUploadFileListHasItem);
25
+ const { styles } = useStyles();
26
+
27
+ return (
28
+ <Flexbox
29
+ className={styles.container}
30
+ gap={6}
31
+ horizontal
32
+ padding={showFileList ? '16px 16px 12px' : 0}
33
+ >
34
+ {inputFilesList.map((item) => (
35
+ <FileItem key={item.id} {...item} />
36
+ ))}
37
+ </Flexbox>
38
+ );
39
+ });
40
+
41
+ export default FileList;
@@ -0,0 +1,40 @@
1
+ import { memo } from 'react';
2
+
3
+ import DragUpload from '@/components/DragUpload';
4
+ import { useAgentStore } from '@/store/agent';
5
+ import { agentSelectors } from '@/store/agent/slices/chat';
6
+ import { useFileStore } from '@/store/file';
7
+ import { useUserStore } from '@/store/user';
8
+ import { modelProviderSelectors } from '@/store/user/selectors';
9
+
10
+ import FileItemList from './FileList';
11
+
12
+ const FilePreview = memo(() => {
13
+ const model = useAgentStore(agentSelectors.currentAgentModel);
14
+
15
+ const canUploadImage = useUserStore(modelProviderSelectors.isModelEnabledUpload(model));
16
+
17
+ const [uploadFiles] = useFileStore((s) => [s.uploadChatFiles]);
18
+
19
+ const upload = async (fileList: FileList | File[] | undefined) => {
20
+ if (!fileList || fileList.length === 0) return;
21
+
22
+ // Filter out files that are not images if the model does not support image uploads
23
+ const files = Array.from(fileList).filter((file) => {
24
+ if (canUploadImage) return true;
25
+
26
+ return !file.type.startsWith('image');
27
+ });
28
+
29
+ uploadFiles(files);
30
+ };
31
+
32
+ return (
33
+ <>
34
+ <DragUpload onUploadFiles={upload} />
35
+ <FileItemList />
36
+ </>
37
+ );
38
+ });
39
+
40
+ export default FilePreview;
@@ -40,7 +40,7 @@ const SendMore = memo<SendMoreProps>(({ disabled, isMac }) => {
40
40
  ]);
41
41
  const addAIMessage = useChatStore((s) => s.addAIMessage);
42
42
 
43
- const sendMessage = useSendMessage();
43
+ const { send: sendMessage } = useSendMessage();
44
44
 
45
45
  const hotKey = [ALT_KEY, 'enter'].join('+');
46
46
  useHotkeys(
@@ -11,13 +11,12 @@ import StopLoadingIcon from '@/components/StopLoading';
11
11
  import SaveTopic from '@/features/ChatInput/Topic';
12
12
  import { useSendMessage } from '@/features/ChatInput/useSend';
13
13
  import { useChatStore } from '@/store/chat';
14
- import { chatSelectors, topicSelectors } from '@/store/chat/selectors';
15
- import { filesSelectors, useFileStore } from '@/store/file';
14
+ import { chatSelectors } from '@/store/chat/selectors';
16
15
  import { useUserStore } from '@/store/user';
17
16
  import { preferenceSelectors } from '@/store/user/selectors';
18
17
  import { isMacOS } from '@/utils/platform';
19
18
 
20
- import LocalFiles from '../LocalFiles';
19
+ import LocalFiles from '../FilePreview';
21
20
  import SendMore from './SendMore';
22
21
 
23
22
  const useStyles = createStyles(({ css, prefixCls, token }) => {
@@ -57,25 +56,14 @@ const Footer = memo<FooterProps>(({ setExpand, expand }) => {
57
56
 
58
57
  const { theme, styles } = useStyles();
59
58
 
60
- const [
61
- isAIGenerating,
62
- isHasMessageLoading,
63
- isCreatingMessage,
64
- isCreatingTopic,
65
- stopGenerateMessage,
66
- ] = useChatStore((s) => [
59
+ const [isAIGenerating, stopGenerateMessage] = useChatStore((s) => [
67
60
  chatSelectors.isAIGenerating(s),
68
- chatSelectors.isHasMessageLoading(s),
69
- chatSelectors.isCreatingMessage(s),
70
- topicSelectors.isCreatingTopic(s),
71
61
  s.stopGenerateMessage,
72
62
  ]);
73
63
 
74
- const isImageUploading = useFileStore(filesSelectors.isImageUploading);
75
-
76
64
  const [useCmdEnterToSend] = useUserStore((s) => [preferenceSelectors.useCmdEnterToSend(s)]);
77
65
 
78
- const sendMessage = useSendMessage();
66
+ const { send: sendMessage, canSend } = useSendMessage();
79
67
 
80
68
  const [isMac, setIsMac] = useState<boolean>();
81
69
  useEffect(() => {
@@ -105,9 +93,6 @@ const Footer = memo<FooterProps>(({ setExpand, expand }) => {
105
93
 
106
94
  const wrapperShortcut = useCmdEnterToSend ? enter : cmdEnter;
107
95
 
108
- const buttonDisabled =
109
- isImageUploading || isHasMessageLoading || isCreatingTopic || isCreatingMessage;
110
-
111
96
  return (
112
97
  <Flexbox
113
98
  align={'end'}
@@ -146,8 +131,8 @@ const Footer = memo<FooterProps>(({ setExpand, expand }) => {
146
131
  ) : (
147
132
  <Space.Compact>
148
133
  <Button
149
- disabled={buttonDisabled}
150
- loading={buttonDisabled}
134
+ disabled={!canSend}
135
+ loading={!canSend}
151
136
  onClick={() => {
152
137
  sendMessage();
153
138
  setExpand?.(false);
@@ -156,7 +141,7 @@ const Footer = memo<FooterProps>(({ setExpand, expand }) => {
156
141
  >
157
142
  {t('input.send')}
158
143
  </Button>
159
- <SendMore disabled={buttonDisabled} isMac={isMac} />
144
+ <SendMore disabled={!canSend} isMac={isMac} />
160
145
  </Space.Compact>
161
146
  )}
162
147
  </Flexbox>