@lobehub/chat 1.98.2 → 1.99.1

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 (458) hide show
  1. package/.cursor/rules/backend-architecture.mdc +93 -17
  2. package/.cursor/rules/cursor-ux.mdc +45 -35
  3. package/.cursor/rules/project-introduce.mdc +72 -6
  4. package/.cursor/rules/rules-attach.mdc +16 -7
  5. package/.eslintrc.js +10 -0
  6. package/CHANGELOG.md +44 -0
  7. package/apps/desktop/README.md +7 -0
  8. package/apps/desktop/electron-builder.js +5 -0
  9. package/apps/desktop/package.json +2 -1
  10. package/apps/desktop/src/main/appBrowsers.ts +1 -1
  11. package/apps/desktop/src/main/const/dir.ts +3 -0
  12. package/apps/desktop/src/main/controllers/UploadFileCtr.ts +13 -8
  13. package/apps/desktop/src/main/core/App.ts +8 -0
  14. package/apps/desktop/src/main/core/BrowserManager.ts +5 -2
  15. package/apps/desktop/src/main/core/StaticFileServerManager.ts +221 -0
  16. package/apps/desktop/src/main/services/fileSrv.ts +231 -44
  17. package/apps/desktop/src/main/utils/next-electron-rsc.ts +36 -5
  18. package/changelog/v1.json +14 -0
  19. package/docs/development/database-schema.dbml +70 -0
  20. package/locales/ar/common.json +2 -0
  21. package/locales/ar/components.json +35 -0
  22. package/locales/ar/error.json +2 -0
  23. package/locales/ar/image.json +100 -0
  24. package/locales/ar/metadata.json +4 -0
  25. package/locales/ar/modelProvider.json +1 -0
  26. package/locales/ar/models.json +15 -0
  27. package/locales/ar/plugin.json +22 -0
  28. package/locales/ar/providers.json +3 -0
  29. package/locales/ar/setting.json +5 -0
  30. package/locales/bg-BG/common.json +2 -0
  31. package/locales/bg-BG/components.json +35 -0
  32. package/locales/bg-BG/error.json +2 -0
  33. package/locales/bg-BG/image.json +100 -0
  34. package/locales/bg-BG/metadata.json +4 -0
  35. package/locales/bg-BG/modelProvider.json +1 -0
  36. package/locales/bg-BG/models.json +15 -0
  37. package/locales/bg-BG/plugin.json +22 -0
  38. package/locales/bg-BG/providers.json +3 -0
  39. package/locales/bg-BG/setting.json +5 -0
  40. package/locales/de-DE/common.json +2 -0
  41. package/locales/de-DE/components.json +35 -0
  42. package/locales/de-DE/error.json +2 -0
  43. package/locales/de-DE/image.json +100 -0
  44. package/locales/de-DE/metadata.json +4 -0
  45. package/locales/de-DE/modelProvider.json +1 -0
  46. package/locales/de-DE/models.json +15 -0
  47. package/locales/de-DE/plugin.json +22 -0
  48. package/locales/de-DE/providers.json +3 -0
  49. package/locales/de-DE/setting.json +5 -0
  50. package/locales/en-US/common.json +2 -0
  51. package/locales/en-US/components.json +35 -0
  52. package/locales/en-US/error.json +2 -0
  53. package/locales/en-US/image.json +100 -0
  54. package/locales/en-US/metadata.json +4 -0
  55. package/locales/en-US/modelProvider.json +1 -0
  56. package/locales/en-US/models.json +15 -0
  57. package/locales/en-US/plugin.json +22 -0
  58. package/locales/en-US/providers.json +3 -0
  59. package/locales/en-US/setting.json +5 -0
  60. package/locales/es-ES/common.json +2 -0
  61. package/locales/es-ES/components.json +35 -0
  62. package/locales/es-ES/error.json +2 -0
  63. package/locales/es-ES/image.json +100 -0
  64. package/locales/es-ES/metadata.json +4 -0
  65. package/locales/es-ES/modelProvider.json +1 -0
  66. package/locales/es-ES/models.json +15 -0
  67. package/locales/es-ES/plugin.json +22 -0
  68. package/locales/es-ES/providers.json +3 -0
  69. package/locales/es-ES/setting.json +5 -0
  70. package/locales/fa-IR/common.json +2 -0
  71. package/locales/fa-IR/components.json +35 -0
  72. package/locales/fa-IR/error.json +2 -0
  73. package/locales/fa-IR/image.json +100 -0
  74. package/locales/fa-IR/metadata.json +4 -0
  75. package/locales/fa-IR/modelProvider.json +1 -0
  76. package/locales/fa-IR/models.json +15 -0
  77. package/locales/fa-IR/plugin.json +22 -0
  78. package/locales/fa-IR/providers.json +3 -0
  79. package/locales/fa-IR/setting.json +5 -0
  80. package/locales/fr-FR/common.json +2 -0
  81. package/locales/fr-FR/components.json +35 -0
  82. package/locales/fr-FR/error.json +2 -0
  83. package/locales/fr-FR/image.json +100 -0
  84. package/locales/fr-FR/metadata.json +4 -0
  85. package/locales/fr-FR/modelProvider.json +1 -0
  86. package/locales/fr-FR/models.json +15 -0
  87. package/locales/fr-FR/plugin.json +22 -0
  88. package/locales/fr-FR/providers.json +3 -0
  89. package/locales/fr-FR/setting.json +5 -0
  90. package/locales/it-IT/common.json +2 -0
  91. package/locales/it-IT/components.json +35 -0
  92. package/locales/it-IT/error.json +2 -0
  93. package/locales/it-IT/image.json +100 -0
  94. package/locales/it-IT/metadata.json +4 -0
  95. package/locales/it-IT/modelProvider.json +1 -0
  96. package/locales/it-IT/models.json +15 -0
  97. package/locales/it-IT/plugin.json +22 -0
  98. package/locales/it-IT/providers.json +3 -0
  99. package/locales/it-IT/setting.json +5 -0
  100. package/locales/ja-JP/common.json +2 -0
  101. package/locales/ja-JP/components.json +35 -0
  102. package/locales/ja-JP/error.json +2 -0
  103. package/locales/ja-JP/image.json +100 -0
  104. package/locales/ja-JP/metadata.json +4 -0
  105. package/locales/ja-JP/modelProvider.json +1 -0
  106. package/locales/ja-JP/models.json +15 -0
  107. package/locales/ja-JP/plugin.json +22 -0
  108. package/locales/ja-JP/providers.json +3 -0
  109. package/locales/ja-JP/setting.json +5 -0
  110. package/locales/ko-KR/common.json +2 -0
  111. package/locales/ko-KR/components.json +35 -0
  112. package/locales/ko-KR/error.json +2 -0
  113. package/locales/ko-KR/image.json +100 -0
  114. package/locales/ko-KR/metadata.json +4 -0
  115. package/locales/ko-KR/modelProvider.json +1 -0
  116. package/locales/ko-KR/models.json +15 -0
  117. package/locales/ko-KR/plugin.json +22 -0
  118. package/locales/ko-KR/providers.json +3 -0
  119. package/locales/ko-KR/setting.json +5 -0
  120. package/locales/nl-NL/common.json +2 -0
  121. package/locales/nl-NL/components.json +35 -0
  122. package/locales/nl-NL/error.json +2 -0
  123. package/locales/nl-NL/image.json +100 -0
  124. package/locales/nl-NL/metadata.json +4 -0
  125. package/locales/nl-NL/modelProvider.json +1 -0
  126. package/locales/nl-NL/models.json +15 -0
  127. package/locales/nl-NL/plugin.json +22 -0
  128. package/locales/nl-NL/providers.json +3 -0
  129. package/locales/nl-NL/setting.json +5 -0
  130. package/locales/pl-PL/common.json +2 -0
  131. package/locales/pl-PL/components.json +35 -0
  132. package/locales/pl-PL/error.json +2 -0
  133. package/locales/pl-PL/image.json +100 -0
  134. package/locales/pl-PL/metadata.json +4 -0
  135. package/locales/pl-PL/modelProvider.json +1 -0
  136. package/locales/pl-PL/models.json +15 -0
  137. package/locales/pl-PL/plugin.json +22 -0
  138. package/locales/pl-PL/providers.json +3 -0
  139. package/locales/pl-PL/setting.json +5 -0
  140. package/locales/pt-BR/common.json +2 -0
  141. package/locales/pt-BR/components.json +35 -0
  142. package/locales/pt-BR/error.json +2 -0
  143. package/locales/pt-BR/image.json +100 -0
  144. package/locales/pt-BR/metadata.json +4 -0
  145. package/locales/pt-BR/modelProvider.json +1 -0
  146. package/locales/pt-BR/models.json +15 -0
  147. package/locales/pt-BR/plugin.json +22 -0
  148. package/locales/pt-BR/providers.json +3 -0
  149. package/locales/pt-BR/setting.json +5 -0
  150. package/locales/ru-RU/common.json +2 -0
  151. package/locales/ru-RU/components.json +35 -0
  152. package/locales/ru-RU/error.json +2 -0
  153. package/locales/ru-RU/image.json +100 -0
  154. package/locales/ru-RU/metadata.json +4 -0
  155. package/locales/ru-RU/modelProvider.json +1 -0
  156. package/locales/ru-RU/models.json +15 -0
  157. package/locales/ru-RU/plugin.json +22 -0
  158. package/locales/ru-RU/providers.json +3 -0
  159. package/locales/ru-RU/setting.json +5 -0
  160. package/locales/tr-TR/common.json +2 -0
  161. package/locales/tr-TR/components.json +35 -0
  162. package/locales/tr-TR/error.json +2 -0
  163. package/locales/tr-TR/image.json +100 -0
  164. package/locales/tr-TR/metadata.json +4 -0
  165. package/locales/tr-TR/modelProvider.json +1 -0
  166. package/locales/tr-TR/models.json +15 -0
  167. package/locales/tr-TR/plugin.json +22 -0
  168. package/locales/tr-TR/providers.json +3 -0
  169. package/locales/tr-TR/setting.json +5 -0
  170. package/locales/vi-VN/common.json +2 -0
  171. package/locales/vi-VN/components.json +35 -0
  172. package/locales/vi-VN/error.json +2 -0
  173. package/locales/vi-VN/image.json +100 -0
  174. package/locales/vi-VN/metadata.json +4 -0
  175. package/locales/vi-VN/modelProvider.json +1 -0
  176. package/locales/vi-VN/models.json +15 -0
  177. package/locales/vi-VN/plugin.json +22 -0
  178. package/locales/vi-VN/providers.json +3 -0
  179. package/locales/vi-VN/setting.json +5 -0
  180. package/locales/zh-CN/common.json +2 -0
  181. package/locales/zh-CN/components.json +35 -0
  182. package/locales/zh-CN/error.json +2 -0
  183. package/locales/zh-CN/image.json +100 -0
  184. package/locales/zh-CN/metadata.json +4 -0
  185. package/locales/zh-CN/modelProvider.json +1 -0
  186. package/locales/zh-CN/models.json +15 -0
  187. package/locales/zh-CN/plugin.json +22 -0
  188. package/locales/zh-CN/providers.json +3 -0
  189. package/locales/zh-CN/setting.json +5 -0
  190. package/locales/zh-TW/common.json +2 -0
  191. package/locales/zh-TW/components.json +35 -0
  192. package/locales/zh-TW/error.json +2 -0
  193. package/locales/zh-TW/image.json +100 -0
  194. package/locales/zh-TW/metadata.json +4 -0
  195. package/locales/zh-TW/modelProvider.json +1 -0
  196. package/locales/zh-TW/models.json +15 -0
  197. package/locales/zh-TW/plugin.json +22 -0
  198. package/locales/zh-TW/providers.json +3 -0
  199. package/locales/zh-TW/setting.json +5 -0
  200. package/package.json +11 -4
  201. package/packages/electron-server-ipc/src/events/file.ts +3 -1
  202. package/packages/electron-server-ipc/src/types/file.ts +15 -0
  203. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +11 -1
  204. package/src/app/[variants]/(main)/image/@menu/components/AspectRatioSelect/index.tsx +73 -0
  205. package/src/app/[variants]/(main)/image/@menu/components/SeedNumberInput/index.tsx +39 -0
  206. package/src/app/[variants]/(main)/image/@menu/components/SizeSelect/index.tsx +89 -0
  207. package/src/app/[variants]/(main)/image/@menu/default.tsx +11 -0
  208. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/AspectRatioSelect.tsx +24 -0
  209. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/DimensionControlGroup.tsx +107 -0
  210. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageNum.tsx +290 -0
  211. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageUpload.tsx +504 -0
  212. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageUrl.tsx +18 -0
  213. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ImageUrlsUpload.tsx +19 -0
  214. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/ModelSelect.tsx +155 -0
  215. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/MultiImagesUpload/ImageManageModal.tsx +415 -0
  216. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/MultiImagesUpload/index.tsx +732 -0
  217. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/SeedNumberInput.tsx +24 -0
  218. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/SizeSelect.tsx +17 -0
  219. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/SizeSliderInput.tsx +15 -0
  220. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/components/StepsSliderInput.tsx +11 -0
  221. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/constants.ts +1 -0
  222. package/src/app/[variants]/(main)/image/@menu/features/ConfigPanel/index.tsx +93 -0
  223. package/src/app/[variants]/(main)/image/@topic/default.tsx +17 -0
  224. package/src/app/[variants]/(main)/image/@topic/features/Topics/NewTopicButton.tsx +64 -0
  225. package/src/app/[variants]/(main)/image/@topic/features/Topics/SkeletonList.tsx +34 -0
  226. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicItem.tsx +136 -0
  227. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicItemContainer.tsx +91 -0
  228. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicList.tsx +57 -0
  229. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicUrlSync.tsx +37 -0
  230. package/src/app/[variants]/(main)/image/@topic/features/Topics/index.tsx +19 -0
  231. package/src/app/[variants]/(main)/image/NotSupportClient.tsx +153 -0
  232. package/src/app/[variants]/(main)/image/_layout/Desktop/Container.tsx +35 -0
  233. package/src/app/[variants]/(main)/image/_layout/Desktop/RegisterHotkeys.tsx +10 -0
  234. package/src/app/[variants]/(main)/image/_layout/Desktop/index.tsx +30 -0
  235. package/src/app/[variants]/(main)/image/_layout/Mobile/index.tsx +14 -0
  236. package/src/app/[variants]/(main)/image/_layout/type.ts +7 -0
  237. package/src/app/[variants]/(main)/image/features/GenerationFeed/BatchItem.tsx +196 -0
  238. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/ActionButtons.tsx +60 -0
  239. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/ElapsedTime.tsx +90 -0
  240. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/ErrorState.tsx +65 -0
  241. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/LoadingState.tsx +44 -0
  242. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/SuccessState.tsx +49 -0
  243. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/index.tsx +154 -0
  244. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/styles.ts +51 -0
  245. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/types.ts +39 -0
  246. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/utils.ts +11 -0
  247. package/src/app/[variants]/(main)/image/features/GenerationFeed/index.tsx +97 -0
  248. package/src/app/[variants]/(main)/image/features/ImageWorkspace/Content.tsx +48 -0
  249. package/src/app/[variants]/(main)/image/features/ImageWorkspace/EmptyState.tsx +37 -0
  250. package/src/app/[variants]/(main)/image/features/ImageWorkspace/SkeletonList.tsx +50 -0
  251. package/src/app/[variants]/(main)/image/features/ImageWorkspace/index.tsx +23 -0
  252. package/src/app/[variants]/(main)/image/features/PromptInput/Title.tsx +38 -0
  253. package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +114 -0
  254. package/src/app/[variants]/(main)/image/layout.tsx +19 -0
  255. package/src/app/[variants]/(main)/image/loading.tsx +3 -0
  256. package/src/app/[variants]/(main)/image/page.tsx +47 -0
  257. package/src/app/[variants]/(main)/settings/system-agent/index.tsx +2 -1
  258. package/src/chains/summaryGenerationTitle.ts +25 -0
  259. package/src/components/ImageItem/index.tsx +9 -6
  260. package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/Bedrock.tsx +3 -4
  261. package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/ProviderApiKeyForm.tsx +5 -4
  262. package/src/components/InvalidAPIKey/APIKeyForm/index.tsx +108 -0
  263. package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/useApiKey.ts +2 -1
  264. package/src/components/InvalidAPIKey/index.tsx +30 -0
  265. package/src/components/KeyValueEditor/index.tsx +203 -0
  266. package/src/components/KeyValueEditor/utils.ts +42 -0
  267. package/src/config/aiModels/fal.ts +52 -0
  268. package/src/config/aiModels/index.ts +3 -0
  269. package/src/config/aiModels/openai.ts +20 -6
  270. package/src/config/llm.ts +6 -0
  271. package/src/config/modelProviders/fal.ts +21 -0
  272. package/src/config/modelProviders/index.ts +3 -0
  273. package/src/config/paramsSchemas/fal/flux-kontext-dev.ts +8 -0
  274. package/src/config/paramsSchemas/fal/flux-pro-kontext.ts +11 -0
  275. package/src/config/paramsSchemas/fal/flux-schnell.ts +9 -0
  276. package/src/config/paramsSchemas/fal/imagen4.ts +10 -0
  277. package/src/config/paramsSchemas/openai/gpt-image-1.ts +10 -0
  278. package/src/const/hotkeys.ts +2 -2
  279. package/src/const/image.ts +6 -0
  280. package/src/const/settings/systemAgent.ts +1 -0
  281. package/src/database/client/migrations.json +27 -0
  282. package/src/database/migrations/0026_add_autovacuum_tuning.sql +2 -0
  283. package/src/database/migrations/0027_ai_image.sql +47 -0
  284. package/src/database/migrations/meta/0027_snapshot.json +6003 -0
  285. package/src/database/migrations/meta/_journal.json +7 -0
  286. package/src/database/models/__tests__/asyncTask.test.ts +7 -5
  287. package/src/database/models/__tests__/file.test.ts +287 -0
  288. package/src/database/models/__tests__/generation.test.ts +786 -0
  289. package/src/database/models/__tests__/generationBatch.test.ts +614 -0
  290. package/src/database/models/__tests__/generationTopic.test.ts +411 -0
  291. package/src/database/models/aiModel.ts +2 -0
  292. package/src/database/models/asyncTask.ts +1 -1
  293. package/src/database/models/file.ts +28 -20
  294. package/src/database/models/generation.ts +197 -0
  295. package/src/database/models/generationBatch.ts +212 -0
  296. package/src/database/models/generationTopic.ts +131 -0
  297. package/src/database/repositories/aiInfra/index.test.ts +157 -1
  298. package/src/database/repositories/aiInfra/index.ts +37 -19
  299. package/src/database/repositories/tableViewer/index.test.ts +1 -1
  300. package/src/database/schemas/file.ts +8 -0
  301. package/src/database/schemas/generation.ts +127 -0
  302. package/src/database/schemas/index.ts +1 -0
  303. package/src/database/schemas/relations.ts +45 -1
  304. package/src/database/type.ts +2 -0
  305. package/src/database/utils/idGenerator.ts +3 -0
  306. package/src/features/Conversation/Error/ChatInvalidApiKey.tsx +39 -0
  307. package/src/features/Conversation/Error/InvalidAccessCode.tsx +2 -2
  308. package/src/features/Conversation/Error/index.tsx +3 -3
  309. package/src/features/ImageSidePanel/index.tsx +83 -0
  310. package/src/features/ImageTopicPanel/index.tsx +79 -0
  311. package/src/features/PluginDevModal/MCPManifestForm/CollapsibleSection.tsx +62 -0
  312. package/src/features/PluginDevModal/MCPManifestForm/QuickImportSection.tsx +158 -0
  313. package/src/features/PluginDevModal/MCPManifestForm/index.tsx +99 -155
  314. package/src/features/PluginStore/McpList/Detail/Settings/index.tsx +5 -2
  315. package/src/hooks/useDownloadImage.ts +31 -0
  316. package/src/hooks/useFetchGenerationTopics.ts +13 -0
  317. package/src/hooks/useHotkeys/imageScope.ts +48 -0
  318. package/src/libs/mcp/client.ts +55 -22
  319. package/src/libs/mcp/types.ts +42 -6
  320. package/src/libs/model-runtime/BaseAI.ts +3 -1
  321. package/src/libs/model-runtime/ModelRuntime.test.ts +80 -0
  322. package/src/libs/model-runtime/ModelRuntime.ts +15 -1
  323. package/src/libs/model-runtime/UniformRuntime/index.ts +4 -1
  324. package/src/libs/model-runtime/fal/index.test.ts +442 -0
  325. package/src/libs/model-runtime/fal/index.ts +88 -0
  326. package/src/libs/model-runtime/openai/index.test.ts +396 -2
  327. package/src/libs/model-runtime/openai/index.ts +129 -3
  328. package/src/libs/model-runtime/runtimeMap.ts +2 -0
  329. package/src/libs/model-runtime/types/image.ts +25 -0
  330. package/src/libs/model-runtime/types/type.ts +1 -0
  331. package/src/libs/model-runtime/utils/openaiCompatibleFactory/index.ts +10 -0
  332. package/src/libs/standard-parameters/index.ts +1 -0
  333. package/src/libs/standard-parameters/meta-schema.test.ts +214 -0
  334. package/src/libs/standard-parameters/meta-schema.ts +147 -0
  335. package/src/libs/swr/index.ts +1 -0
  336. package/src/libs/trpc/async/asyncAuth.ts +29 -8
  337. package/src/libs/trpc/async/context.ts +42 -4
  338. package/src/libs/trpc/async/index.ts +17 -4
  339. package/src/libs/trpc/async/init.ts +8 -0
  340. package/src/libs/trpc/client/lambda.ts +19 -2
  341. package/src/locales/default/common.ts +2 -0
  342. package/src/locales/default/components.ts +35 -0
  343. package/src/locales/default/error.ts +2 -0
  344. package/src/locales/default/image.ts +100 -0
  345. package/src/locales/default/index.ts +2 -0
  346. package/src/locales/default/metadata.ts +4 -0
  347. package/src/locales/default/modelProvider.ts +2 -0
  348. package/src/locales/default/plugin.ts +22 -0
  349. package/src/locales/default/setting.ts +5 -0
  350. package/src/middleware.ts +1 -0
  351. package/src/server/modules/ElectronIPCClient/index.ts +9 -1
  352. package/src/server/modules/S3/index.ts +15 -0
  353. package/src/server/routers/async/caller.ts +9 -1
  354. package/src/server/routers/async/image.ts +253 -0
  355. package/src/server/routers/async/index.ts +2 -0
  356. package/src/server/routers/lambda/aiProvider.test.ts +2 -0
  357. package/src/server/routers/lambda/generation.test.ts +267 -0
  358. package/src/server/routers/lambda/generation.ts +86 -0
  359. package/src/server/routers/lambda/generationBatch.test.ts +376 -0
  360. package/src/server/routers/lambda/generationBatch.ts +56 -0
  361. package/src/server/routers/lambda/generationTopic.test.ts +508 -0
  362. package/src/server/routers/lambda/generationTopic.ts +93 -0
  363. package/src/server/routers/lambda/image.ts +248 -0
  364. package/src/server/routers/lambda/index.ts +8 -0
  365. package/src/server/routers/tools/mcp.ts +15 -0
  366. package/src/server/services/file/__tests__/index.test.ts +135 -0
  367. package/src/server/services/file/impls/local.test.ts +153 -52
  368. package/src/server/services/file/impls/local.ts +70 -46
  369. package/src/server/services/file/impls/s3.test.ts +114 -0
  370. package/src/server/services/file/impls/s3.ts +40 -0
  371. package/src/server/services/file/impls/type.ts +10 -0
  372. package/src/server/services/file/index.ts +14 -0
  373. package/src/server/services/generation/index.ts +239 -0
  374. package/src/server/services/mcp/index.ts +20 -2
  375. package/src/services/__tests__/generation.test.ts +40 -0
  376. package/src/services/__tests__/generationBatch.test.ts +36 -0
  377. package/src/services/__tests__/generationTopic.test.ts +72 -0
  378. package/src/services/electron/file.ts +3 -1
  379. package/src/services/generation.ts +16 -0
  380. package/src/services/generationBatch.ts +25 -0
  381. package/src/services/generationTopic.ts +28 -0
  382. package/src/services/image.ts +33 -0
  383. package/src/services/mcp.ts +12 -7
  384. package/src/services/upload.ts +43 -9
  385. package/src/store/aiInfra/slices/aiProvider/action.ts +31 -6
  386. package/src/store/aiInfra/slices/aiProvider/initialState.ts +1 -0
  387. package/src/store/aiInfra/slices/aiProvider/selectors.ts +3 -0
  388. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +5 -5
  389. package/src/store/chat/slices/message/action.ts +2 -2
  390. package/src/store/chat/slices/translate/action.ts +1 -1
  391. package/src/store/global/initialState.ts +9 -0
  392. package/src/store/global/selectors/systemStatus.ts +8 -0
  393. package/src/store/image/index.ts +2 -0
  394. package/src/store/image/initialState.ts +25 -0
  395. package/src/store/image/selectors.ts +4 -0
  396. package/src/store/image/slices/createImage/action.test.ts +330 -0
  397. package/src/store/image/slices/createImage/action.ts +134 -0
  398. package/src/store/image/slices/createImage/initialState.ts +9 -0
  399. package/src/store/image/slices/createImage/selectors.test.ts +114 -0
  400. package/src/store/image/slices/createImage/selectors.ts +9 -0
  401. package/src/store/image/slices/generationBatch/action.test.ts +495 -0
  402. package/src/store/image/slices/generationBatch/action.ts +303 -0
  403. package/src/store/image/slices/generationBatch/initialState.ts +13 -0
  404. package/src/store/image/slices/generationBatch/reducer.test.ts +568 -0
  405. package/src/store/image/slices/generationBatch/reducer.ts +101 -0
  406. package/src/store/image/slices/generationBatch/selectors.test.ts +307 -0
  407. package/src/store/image/slices/generationBatch/selectors.ts +36 -0
  408. package/src/store/image/slices/generationConfig/action.test.ts +351 -0
  409. package/src/store/image/slices/generationConfig/action.ts +295 -0
  410. package/src/store/image/slices/generationConfig/hooks.test.ts +304 -0
  411. package/src/store/image/slices/generationConfig/hooks.ts +118 -0
  412. package/src/store/image/slices/generationConfig/index.ts +1 -0
  413. package/src/store/image/slices/generationConfig/initialState.ts +37 -0
  414. package/src/store/image/slices/generationConfig/selectors.test.ts +204 -0
  415. package/src/store/image/slices/generationConfig/selectors.ts +25 -0
  416. package/src/store/image/slices/generationTopic/action.test.ts +687 -0
  417. package/src/store/image/slices/generationTopic/action.ts +319 -0
  418. package/src/store/image/slices/generationTopic/index.ts +2 -0
  419. package/src/store/image/slices/generationTopic/initialState.ts +14 -0
  420. package/src/store/image/slices/generationTopic/reducer.test.ts +198 -0
  421. package/src/store/image/slices/generationTopic/reducer.ts +66 -0
  422. package/src/store/image/slices/generationTopic/selectors.test.ts +103 -0
  423. package/src/store/image/slices/generationTopic/selectors.ts +15 -0
  424. package/src/store/image/store.ts +42 -0
  425. package/src/store/image/utils/size.ts +51 -0
  426. package/src/store/tool/slices/customPlugin/action.ts +10 -1
  427. package/src/store/tool/slices/mcpStore/action.ts +6 -4
  428. package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +4 -0
  429. package/src/store/user/slices/settings/selectors/systemAgent.ts +2 -0
  430. package/src/types/aiModel.ts +8 -3
  431. package/src/types/aiProvider.ts +2 -0
  432. package/src/types/asyncTask.ts +2 -0
  433. package/src/types/files/index.ts +5 -0
  434. package/src/types/generation/index.ts +80 -0
  435. package/src/types/hotkey.ts +2 -0
  436. package/src/types/plugins/mcp.ts +2 -6
  437. package/src/types/tool/plugin.ts +8 -0
  438. package/src/types/user/settings/keyVaults.ts +5 -0
  439. package/src/types/user/settings/systemAgent.ts +1 -0
  440. package/src/utils/client/downloadFile.ts +33 -4
  441. package/src/utils/number.test.ts +105 -0
  442. package/src/utils/number.ts +25 -0
  443. package/src/utils/server/__tests__/geo.test.ts +6 -3
  444. package/src/utils/storeDebug.test.ts +152 -0
  445. package/src/utils/storeDebug.ts +16 -7
  446. package/src/utils/time.test.ts +259 -0
  447. package/src/utils/time.ts +18 -0
  448. package/src/utils/units.ts +61 -0
  449. package/src/utils/url.test.ts +358 -9
  450. package/src/utils/url.ts +105 -3
  451. package/{vitest.server.config.ts → vitest.config.server.ts} +3 -0
  452. package/.cursor/rules/i18n/i18n-auto-attached.mdc +0 -6
  453. package/src/features/Conversation/Error/APIKeyForm/index.tsx +0 -105
  454. package/src/features/Conversation/Error/InvalidAPIKey.tsx +0 -16
  455. package/src/features/PluginDevModal/MCPManifestForm/EnvEditor.tsx +0 -227
  456. /package/.cursor/rules/{i18n/i18n.mdc → i18n.mdc} +0 -0
  457. /package/src/app/[variants]/(main)/settings/system-agent/features/{createForm.tsx → SystemAgentForm.tsx} +0 -0
  458. /package/src/{features/Conversation/Error → components/InvalidAPIKey}/APIKeyForm/LoadingContext.ts +0 -0
@@ -1,8 +1,9 @@
1
1
  ---
2
- description:
2
+ description:
3
3
  globs: src/services/**/*,src/database/**/*,src/server/**/*
4
4
  alwaysApply: false
5
5
  ---
6
+
6
7
  # LobeChat 后端技术架构指南
7
8
 
8
9
  本指南旨在阐述 LobeChat 项目的后端分层架构,重点介绍各核心目录的职责以及它们之间的协作方式。
@@ -29,24 +30,21 @@ LobeChat 的后端设计注重模块化、可测试性和灵活性,以适应
29
30
  其主要分层如下:
30
31
 
31
32
  1. 客户端服务层 (`src/services`):
32
-
33
33
  - 位于 src/services/。
34
34
  - 这是客户端业务逻辑的核心层,负责封装各种业务操作和数据处理逻辑。
35
35
  - 环境适配: 根据不同的运行环境,服务层会选择合适的数据访问方式:
36
- - 本地数据库模式: 直接调用 `Model` 层进行数据操作,适用于浏览器 PGLite 和本地 Electron 应用。
37
- - 远程数据库模式: 通过 `tRPC` 客户端调用服务端 API,适用于需要云同步的场景。
36
+ - 本地数据库模式: 直接调用 `Model` 层进行数据操作,适用于浏览器 PGLite 和本地 Electron 应用。
37
+ - 远程数据库模式: 通过 `tRPC` 客户端调用服务端 API,适用于需要云同步的场景。
38
38
  - 类型转换: 对于简单的数据类型转换,直接在此层进行类型断言,如 `this.pluginModel.query() as Promise<LobeTool[]>`
39
39
  - 每个服务模块通常包含 `client.ts`(本地模式)、`server.ts`(远程模式)和 `type.ts`(接口定义)文件,在实现时应该确保本地模式和远程模式业务逻辑实现一致,只是数据库不同。
40
40
 
41
41
  2. API 接口层 (`TRPC`):
42
-
43
42
  - 位于 src/server/routers/
44
43
  - 使用 `tRPC` 构建类型安全的 API。Router 根据运行时环境(如 Edge Functions, Node.js Lambda)进行组织。
45
44
  - 负责接收客户端请求,并将其路由到相应的 `Service` 层进行处理。
46
45
  - 新建 lambda 端点时可以参考 src/server/routers/lambda/\_template.ts
47
46
 
48
47
  3. 仓库层 (`Repositories`):
49
-
50
48
  - 位于 src/database/repositories/。
51
49
  - 主要处理复杂的跨表查询和数据聚合逻辑,特别是当需要从多个 `Model` 获取数据并进行组合时。
52
50
  - 与 `Model` 层不同,`Repository` 层专注于复杂的业务查询场景,而不涉及简单的领域模型转换。
@@ -54,7 +52,6 @@ LobeChat 的后端设计注重模块化、可测试性和灵活性,以适应
54
52
  - 如果数据操作简单(仅涉及单个 `Model`),则通常直接在 `src/services` 层调用 `Model` 并进行简单的类型断言。
55
53
 
56
54
  4. 模型层 (`Models`):
57
-
58
55
  - 位于 src/database/models/ (例如 src/database/models/plugin.ts 和 src/database/models/document.ts)。
59
56
  - 提供对数据库中各个表(由 src/database/schemas/ 中的 Drizzle ORM schema 定义)的基本 CRUD (创建、读取、更新、删除) 操作和简单的查询能力。
60
57
  - `Model` 类专注于单个数据表的直接操作,不涉及复杂的领域模型转换,这些转换通常在上层的 `src/services` 中通过类型断言完成。
@@ -65,11 +62,11 @@ LobeChat 的后端设计注重模块化、可测试性和灵活性,以适应
65
62
  - 客户端模式 (浏览器/PWA): 使用 PGLite (基于 WASM 的 PostgreSQL),数据存储在用户浏览器本地。
66
63
  - 服务端模式 (云部署): 使用远程 PostgreSQL 数据库。
67
64
  - Electron 桌面应用:
68
- - Electron 客户端会启动一个本地 Node.js 服务。
69
- - 本地服务通过 `tRPC` 与 Electron 的渲染进程通信。
70
- - 数据库选择依赖于是否开启云同步功能:
71
- - 云同步开启: 连接到远程 PostgreSQL 数据库。
72
- - 云同步关闭: 使用 PGLite (通过 Node.js 的 WASM 实现) 在本地存储数据。
65
+ - Electron 客户端会启动一个本地 Node.js 服务。
66
+ - 本地服务通过 `tRPC` 与 Electron 的渲染进程通信。
67
+ - 数据库选择依赖于是否开启云同步功能:
68
+ - 云同步开启: 连接到远程 PostgreSQL 数据库。
69
+ - 云同步关闭: 使用 PGLite (通过 Node.js 的 WASM 实现) 在本地存储数据。
73
70
 
74
71
  ## 数据流向说明
75
72
 
@@ -93,8 +90,87 @@ UI (Electron Renderer) → Zustand action → Client Service -> TRPC Client →
93
90
 
94
91
  ## 服务层 (Server Services)
95
92
 
96
- - 位于 src/server/services/。
97
- - 核心职责是封装独立的、可复用的业务逻辑单元。这些服务应易于测试。
98
- - 平台差异抽象: 一个关键特性是通过其内部的 `impls` 子目录(例如 src/server/services/file/impls 包含 s3.ts 和 local.ts)来抹平不同运行环境带来的差异(例如云端使用 S3 存储,桌面版使用本地文件系统)。这使得上层(如 `tRPC` routers)无需关心底层具体实现。
99
- - 目标是使 `tRPC` router 层的逻辑尽可能纯粹,专注于请求处理和业务流程编排。
100
- - 服务可能会调用 `Repository` 层或直接调用 `Model` 层进行数据持久化和检索,也可能调用其他服务。
93
+ - 位于 src/server/services/。
94
+ - 核心职责是封装独立的、可复用的业务逻辑单元。这些服务应易于测试。
95
+ - 平台差异抽象: 一个关键特性是通过其内部的 `impls` 子目录(例如 src/server/services/file/impls 包含 s3.ts 和 local.ts)来抹平不同运行环境带来的差异(例如云端使用 S3 存储,桌面版使用本地文件系统)。这使得上层(如 `tRPC` routers)无需关心底层具体实现。
96
+ - 目标是使 `tRPC` router 层的逻辑尽可能纯粹,专注于请求处理和业务流程编排。
97
+ - 服务可能会调用 `Repository` 层或直接调用 `Model` 层进行数据持久化和检索,也可能调用其他服务。
98
+
99
+ ## 最佳实践 (Best Practices)
100
+
101
+ ### 数据库操作封装原则
102
+
103
+ **连续的数据库操作应该封装到 Model 层**
104
+
105
+ 当业务逻辑涉及多个相关的数据库操作时,建议将这些操作封装到 Model 层中,而不是在上层(Service 或 Router 层)中进行多次数据库调用。
106
+
107
+ **优势:**
108
+
109
+ - **代码复用**: Client DB 环境的 service 实现和 Server DB 的 lambda 层实现可以复用相同的 Model 方法
110
+ - **事务一致性**: 相关的数据库操作可以在同一个方法中管理,便于维护数据一致性
111
+ - **性能优化**: 减少数据库连接次数,提高查询效率
112
+ - **职责清晰**: Model 层专注数据访问,上层专注业务协调
113
+
114
+ **示例:**
115
+
116
+ ```typescript
117
+ // ✅ 推荐:在 Model 层封装连续的数据库操作
118
+ class GenerationBatchModel {
119
+ async delete(id: string): Promise<{ deletedBatch: BatchItem; thumbnailUrls: string[] }> {
120
+ // 1. 查询相关数据
121
+ const batchWithGenerations = await this.db.query.generationBatches.findFirst({...});
122
+
123
+ // 2. 收集需要处理的数据
124
+ const thumbnailUrls = [...];
125
+
126
+ // 3. 执行删除操作
127
+ const [deletedBatch] = await this.db.delete(generationBatches)...;
128
+
129
+ return { deletedBatch, thumbnailUrls };
130
+ }
131
+ }
132
+
133
+ // ✅ 上层使用简洁
134
+ const { thumbnailUrls } = await model.delete(id);
135
+ await fileService.deleteFiles(thumbnailUrls);
136
+ ```
137
+
138
+ ### 文件操作与数据库操作的执行顺序
139
+
140
+ **删除操作原则:数据库删除在前,文件删除在后**
141
+
142
+ 当业务逻辑同时涉及数据库记录和文件系统操作时,应该遵循"数据库优先"的原则。
143
+
144
+ **原因:**
145
+
146
+ - **用户体验优先**: 如果先删除文件再删除数据库记录,可能出现文件已删除但数据库记录仍存在的情况,用户访问时会遇到文件不存在的错误
147
+ - **影响程度较小**: 如果先删除数据库记录再删除文件,即使文件删除失败,用户也看不到这个记录,只是造成一些存储空间浪费,对用户体验影响更小
148
+ - **数据一致性**: 数据库记录是业务逻辑的核心,应该优先保证其一致性
149
+
150
+ **示例:**
151
+
152
+ ```typescript
153
+ // ✅ 推荐:先删除数据库记录,再删除文件
154
+ async deleteGeneration(id: string) {
155
+ // 1. 先删除数据库记录
156
+ const deletedGeneration = await generationModel.delete(id);
157
+
158
+ // 2. 再删除相关文件
159
+ if (deletedGeneration.asset?.thumbnailUrl) {
160
+ await fileService.deleteFile(deletedGeneration.asset.thumbnailUrl);
161
+ }
162
+ }
163
+
164
+ // ❌ 不推荐:先删除文件
165
+ async deleteGeneration(id: string) {
166
+ const generation = await generationModel.findById(id);
167
+
168
+ // 如果这里删除成功,但后面数据库删除失败,用户会遇到访问错误
169
+ await fileService.deleteFile(generation.asset.thumbnailUrl);
170
+ await generationModel.delete(id); // 可能失败
171
+ }
172
+ ```
173
+
174
+ **创建操作原则:数据库创建在前,文件操作在后**
175
+
176
+ 创建操作同样应该优先处理数据库记录,确保数据的一致性和完整性。
@@ -1,21 +1,25 @@
1
1
  ---
2
- description:
3
- globs:
2
+ description:
3
+ globs:
4
4
  alwaysApply: true
5
5
  ---
6
+
6
7
  # Guide to Optimize Output(Response) Rendering
7
8
 
8
9
  ## File Path and Code Symbol Rendering
9
10
 
10
11
  - When rendering file paths, use backtick wrapping instead of markdown links so they can be parsed as clickable links in Cursor IDE.
12
+ - Good: `src/components/Button.tsx`
13
+ - Bad: [src/components/Button.tsx](src/components/Button.tsx)
11
14
 
12
- - Good: `src/components/Button.tsx`
13
- - Bad: [src/components/Button.tsx](mdc:src/components/Button.tsx)
15
+ - Don't use line and column number in file path, this will make file path not clickable in Cursor IDE.
16
+ - Good: `src/components/Button.tsx` `10:20` (add a space between the file path and the line and column number)
17
+ - Bad: `src/components/Button.tsx:10:20`
14
18
 
15
19
  - When rendering functions, variables, or other code symbols, use backtick wrapping so they can be parsed as navigable links in Cursor IDE
16
- - Good: The `useState` hook in `MyComponent`
17
- - Bad: The useState hook in MyComponent
18
-
20
+ - Good: The `useState` hook in `MyComponent`
21
+ - Bad: The useState hook in MyComponent
22
+
19
23
  ## Markdown Render
20
24
 
21
25
  - don't use br tag to wrap in table cell
@@ -23,9 +27,9 @@ alwaysApply: true
23
27
  ## Terminal Command Output
24
28
 
25
29
  - If terminal commands don't produce output, it's likely due to paging issues. Try piping the command to `cat` to ensure full output is displayed.
26
- - Good: `git show commit_hash -- file.txt | cat`
27
- - Good: `git log --oneline | cat`
28
- - Reason: Some git commands use pagers by default, which may prevent output from being captured properly
30
+ - Good: `git show commit_hash -- file.txt | cat`
31
+ - Good: `git log --oneline | cat`
32
+ - Reason: Some git commands use pagers by default, which may prevent output from being captured properly
29
33
 
30
34
  ## Mermaid Diagram Generation: Strict Syntax Validation Checklist
31
35
 
@@ -44,50 +48,56 @@ Before producing any Mermaid diagram, you **must** compare your final code line-
44
48
 
45
49
  ### Checklist Details
46
50
 
47
- #### Rule 1: Edge Labels – Must Be Plain Text Only
51
+ #### Rule 1: Edge Labels – Must Be Plain Text Only
52
+
48
53
  > **Essence:** Anything inside `|...|` must contain pure, unformatted text. Absolutely NO Markdown, list markers, or parentheses/brackets allowed—these often cause rendering failures.
49
54
 
50
- - **✅ Do:** `A -->|Process plain text data| B`
51
- - **❌ Don't:** `A -->|1. Ordered list item| B` (No numbered lists)
52
- - **❌ Don't:** `CC --"1. fetch('/api/...')"--> API` (No square brackets)
53
- - **❌ Don't:** `A -->|- Unordered list item| B` (No hyphen lists)
54
- - **❌ Don't:** `A -->|Transform (important)| B` (No parentheses)
55
- - **❌ Don't:** `A -->|Transform [important]| B` (No square brackets)
55
+ - **✅ Do:** `A -->|Process plain text data| B`
56
+ - **❌ Don't:** `A -->|1. Ordered list item| B` (No numbered lists)
57
+ - **❌ Don't:** `CC --"1. fetch('/api/...')"--> API` (No square brackets)
58
+ - **❌ Don't:** `A -->|- Unordered list item| B` (No hyphen lists)
59
+ - **❌ Don't:** `A -->|Transform (important)| B` (No parentheses)
60
+ - **❌ Don't:** `A -->|Transform [important]| B` (No square brackets)
61
+
62
+ #### Rule 2: Node Definition – Handle Special Characters with Care
56
63
 
57
- #### Rule 2: Node Definition – Handle Special Characters with Care
58
64
  > **Essence:** When node text or subgraph titles contain special characters like `()` or `[]`, wrap the text in quotes to avoid conflicts with Mermaid shape syntax.
59
65
 
60
- - **When your node text includes parentheses (e.g., 'React (JSX)'):**
61
- - **✅ Do:** `I_REACT["<b>React component (JSX)</b>"]` (Quotes wrap all text)
62
- - **❌ Don't:** `I_REACT(<b>React component (JSX)</b>)` (Wrong, Mermaid parses this as a shape)
63
- - **❌ Don't:** `subgraph Plugin Features (Plugins)` (Wrong, subgraph titles with parentheses must also be wrapped in quotes)
66
+ - **When your node text includes parentheses (e.g., 'React (JSX)'):**
67
+ - **✅ Do:** `I_REACT["<b>React component (JSX)</b>"]` (Quotes wrap all text)
68
+ - **❌ Don't:** `I_REACT(<b>React component (JSX)</b>)` (Wrong, Mermaid parses this as a shape)
69
+ - **❌ Don't:** `subgraph Plugin Features (Plugins)` (Wrong, subgraph titles with parentheses must also be wrapped in quotes)
70
+
71
+ #### Rule 3: Double Quotes in Text – Must Be Escaped
64
72
 
65
- #### Rule 3: Double Quotes in Text – Must Be Escaped
66
73
  > **Essence:** Use `&quot;` for double quotes **inside node text**.
67
74
 
68
- - **✅ Do:** `A[This node contains &quot;quotes&quot;]`
69
- - **❌ Don't:** `A[This node contains "quotes"]`
75
+ - **✅ Do:** `A[This node contains &quot;quotes&quot;]`
76
+ - **❌ Don't:** `A[This node contains "quotes"]`
77
+
78
+ #### Rule 4: All Formatting Must Use HTML Tags (NOT Markdown!)
70
79
 
71
- #### Rule 4: All Formatting Must Use HTML Tags (NOT Markdown!)
72
80
  > **Essence:** For newlines, bold, and other text formatting in nodes, use HTML tags only. Markdown is not supported.
73
81
 
74
- - **✅ Do (robust):** `A["<b>Bold</b> and <code>code</code><br>This is a new line"]`
75
- - **❌ Don't (not rendered):** `C["# This is a heading"]`
76
- - **❌ Don't (not rendered):** ``C["`const` means constant"]``
77
- - **⚠️ Warning (unreliable):** `B["Markdown **bold** might sometimes work but DON'T rely on it"]`
82
+ - **✅ Do (robust):** `A["<b>Bold</b> and <code>code</code><br>This is a new line"]`
83
+ - **❌ Don't (not rendered):** `C["# This is a heading"]`
84
+ - **❌ Don't (not rendered):** ``C["`const` means constant"]``
85
+ - **⚠️ Warning (unreliable):** `B["Markdown **bold** might sometimes work but DON'T rely on it"]`
86
+
87
+ #### Rule 5: No HTML Tags for Participants and Message Labels (Sequence Diagrams)
78
88
 
79
- #### Rule 5: No HTML Tags for Participants and Message Labels (Sequence Diagrams)
80
89
  > **Important Addition:**
81
90
  > In Mermaid sequence diagrams, you MUST NOT use any HTML tags (such as `<b>`, `<code>`, etc.) in:
91
+ >
82
92
  > - `participant` display names (`as` part)
83
93
  > - Message labels (the text after `:` in diagram flows)
84
94
  >
85
95
  > These tags are generally not rendered—they may appear as-is or cause compatibility issues.
86
96
 
87
- - **✅ Do:** `participant A as Client`
88
- - **❌ Don't:** `participant A as <b>Client</b>`
89
- - **✅ Do:** `A->>B: 1. Establish connection`
90
- - **❌ Don't:** `A->>B: 1. <code>Establish connection</code>`
97
+ - **✅ Do:** `participant A as Client`
98
+ - **❌ Don't:** `participant A as <b>Client</b>`
99
+ - **✅ Do:** `A->>B: 1. Establish connection`
100
+ - **❌ Don't:** `A->>B: 1. <code>Establish connection</code>`
91
101
 
92
102
  ---
93
103
 
@@ -1,19 +1,71 @@
1
1
  ---
2
- description:
3
- globs:
4
2
  alwaysApply: true
5
3
  ---
4
+
6
5
  ## Project Description
7
6
 
8
- You are developing an open-source, modern-design AI chat framework: lobe chat.
7
+ You are developing an open-source, modern-design AI chat framework: lobe chat.
8
+
9
+ Emoji logo: 🤯
10
+
11
+ ## Project Technologies Stack
12
+
13
+ read [package.json](mdc:package.json) to know all npm packages you can use. read [folder-structure.mdx](mdc:docs/development/basic/folder-structure.mdx) to learn project structure.
14
+
15
+ The project uses the following technologies:
16
+
17
+ - pnpm as package manager
18
+ - Next.js 15 for frontend and backend, using app router instead of pages router
19
+ - react 19, using hooks, functional components, react server components
20
+ - TypeScript programming language
21
+ - antd, @lobehub/ui for component framework
22
+ - antd-style for css-in-js framework
23
+ - react-layout-kit for flex layout
24
+ - react-i18next for i18n
25
+ - lucide-react, @ant-design/icons for icons
26
+ - @lobehub/icons for AI provider/model logo icon
27
+ - @formkit/auto-animate for react list animation
28
+ - zustand for global state management
29
+ - nuqs for type-safe search params state manager
30
+ - SWR for react data fetch
31
+ - aHooks for react hooks library
32
+ - dayjs for date and time library
33
+ - lodash-es for utility library
34
+ - fast-deep-equal for deep comparison of JavaScript objects
35
+ - zod for data validation
36
+ - TRPC for type safe backend
37
+ - PGLite for client DB and PostgreSQL for backend DB
38
+ - Drizzle ORM
39
+ - Vitest for testing, testing-library for react component test
40
+ - Prettier for code formatting
41
+ - ESLint for code linting
42
+ - Cursor AI for code editing and AI coding assistance
43
+
44
+ Note: All tools and libraries used are the latest versions. The application only needs to be compatible with the latest browsers;
45
+
46
+ ## Often used npm scripts
47
+
48
+ ```bash
49
+ # type check
50
+ bun type-check
51
+
52
+ # install dependencies
53
+ pnpm install
54
+
55
+ # !: don't any build script to check weather code can work after modify
56
+ ```
57
+
58
+ check [testing guide](./testing-guide.mdc) to learn test scripts.
59
+
60
+ ## Project Description
9
61
 
10
- Emoji logo: 🤯
62
+ You are developing an open-source, modern-design AI chat framework: lobe chat.
11
63
 
64
+ Emoji logo: 🤯
12
65
 
13
66
  ## Project Technologies Stack
14
67
 
15
- read [package.json](mdc:package.json) to know all npm packages you can use.
16
- read [folder-structure.mdx](mdc:docs/development/basic/folder-structure.mdx) to learn project structure.
68
+ read [package.json](mdc:package.json) to know all npm packages you can use. read [folder-structure.mdx](mdc:docs/development/basic/folder-structure.mdx) to learn project structure.
17
69
 
18
70
  The project uses the following technologies:
19
71
 
@@ -45,3 +97,17 @@ The project uses the following technologies:
45
97
  - Cursor AI for code editing and AI coding assistance
46
98
 
47
99
  Note: All tools and libraries used are the latest versions. The application only needs to be compatible with the latest browsers;
100
+
101
+ ## Often used npm scripts
102
+
103
+ ```bash
104
+ # type check
105
+ bun type-check
106
+
107
+ # install dependencies
108
+ pnpm install
109
+
110
+ # !: don't any build script to check weather code can work after modify
111
+ ```
112
+
113
+ check [testing guide](./testing-guide.mdc) to learn test scripts.
@@ -1,8 +1,9 @@
1
1
  ---
2
- description:
3
- globs:
2
+ description:
3
+ globs:
4
4
  alwaysApply: true
5
5
  ---
6
+
6
7
  # LobeChat Cursor Rules System Guide
7
8
 
8
9
  This document explains how the LobeChat project's Cursor rules system works and serves as an index for manually accessible rules.
@@ -14,22 +15,26 @@ This document explains how the LobeChat project's Cursor rules system works and
14
15
  ## 📚 Four Ways to Access Rules
15
16
 
16
17
  ### 1. **Always Applied Rules** - `always_applied_workspace_rules`
18
+
17
19
  - **What**: Core project guidelines that are always active
18
20
  - **Content**: Project tech stack, basic coding standards, output formatting rules
19
21
  - **Access**: No tools needed - automatically provided in every conversation
20
22
 
21
23
  ### 2. **Dynamic Context Rules** - `cursor_rules_context`
24
+
22
25
  - **What**: Rules automatically matched based on files referenced in the conversation
23
26
  - **Trigger**: Only when user **explicitly @ mentions files** or **opens files in Cursor**
24
27
  - **Content**: May include brief descriptions or full rule content, depending on relevance
25
28
  - **Access**: No tools needed - automatically updated when files are referenced
26
29
 
27
30
  ### 3. **Agent Requestable Rules** - `agent_requestable_workspace_rules`
31
+
28
32
  - **What**: Detailed operational guides that can be requested on-demand
29
33
  - **Access**: Use `fetch_rules` tool with rule names
30
34
  - **Examples**: `debug`, `i18n/i18n`, `code-review`
31
35
 
32
36
  ### 4. **Manual Rules Index** - This file + `read_file`
37
+
33
38
  - **What**: Additional rules not covered by the above mechanisms
34
39
  - **Why needed**: Cursor's rule system only supports "agent request" or "auto attach" modes
35
40
  - **Access**: Use `read_file` tool to read specific `.mdc` files
@@ -47,10 +52,13 @@ Use `read_file` to access rules from the index below when:
47
52
  The following rules are available via `read_file` from the `.cursor/rules/` directory:
48
53
 
49
54
  - `backend-architecture.mdc` – Backend layer architecture and design guidelines
50
- - `zustand-action-patterns.mdc` – Recommended patterns for organizing Zustand actions
51
- - `zustand-slice-organization.mdc` – Best practices for structuring Zustand slices
55
+ - `define-database-model.mdc` – Database model definition guidelines
52
56
  - `drizzle-schema-style-guide.mdc` – Style guide for defining Drizzle ORM schemas
53
57
  - `react-component.mdc` – React component style guide and conventions
58
+ - `testing-guide.mdc` – Comprehensive testing guide for Vitest environment
59
+ - `typescript.mdc` – TypeScript code style guide
60
+ - `zustand-action-patterns.mdc` – Recommended patterns for organizing Zustand actions
61
+ - `zustand-slice-organization.mdc` – Best practices for structuring Zustand slices
54
62
 
55
63
  ## ❌ Common Misunderstandings to Avoid
56
64
 
@@ -62,7 +70,7 @@ The following rules are available via `read_file` from the `.cursor/rules/` dire
62
70
 
63
71
  ```
64
72
  1. Start with always_applied_workspace_rules (automatic)
65
- 2. Check cursor_rules_context for auto-matched rules (automatic)
73
+ 2. Check cursor_rules_context for auto-matched rules (automatic)
66
74
  3. If you need specific guides: fetch_rules (manual)
67
75
  4. If you identify gaps: consult this index → read_file (manual)
68
76
  ```
@@ -70,7 +78,8 @@ The following rules are available via `read_file` from the `.cursor/rules/` dire
70
78
  ## Example Decision Flow
71
79
 
72
80
  **Scenario**: Working on a new Zustand store slice
81
+
73
82
  1. Follow always_applied_workspace_rules ✅
74
- 2. If store files were @ mentioned → use cursor_rules_context rules ✅
83
+ 2. If store files were @ mentioned → use cursor_rules_context rules ✅
75
84
  3. Need detailed Zustand guidance → `read_file('.cursor/rules/zustand-slice-organization.mdc')` ✅
76
- 4. All rules apply simultaneously - no conflicts ✅
85
+ 4. All rules apply simultaneously - no conflicts ✅
package/.eslintrc.js CHANGED
@@ -36,6 +36,16 @@ config.overrides = [
36
36
  'mdx/code-blocks': false,
37
37
  },
38
38
  },
39
+
40
+ {
41
+ files: ['src/store/image/**/*', 'src/types/generation/**/*'],
42
+ rules: {
43
+ '@typescript-eslint/no-empty-interface': 0,
44
+ 'sort-keys-fix/sort-keys-fix': 0,
45
+ 'typescript-sort-keys/interface': 0,
46
+ 'typescript-sort-keys/string-enum': 0,
47
+ },
48
+ },
39
49
  ];
40
50
 
41
51
  module.exports = config;
package/CHANGELOG.md CHANGED
@@ -2,6 +2,50 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.99.1](https://github.com/lobehub/lobe-chat/compare/v1.99.0...v1.99.1)
6
+
7
+ <sup>Released on **2025-07-15**</sup>
8
+
9
+ <br/>
10
+
11
+ <details>
12
+ <summary><kbd>Improvements and Fixes</kbd></summary>
13
+
14
+ </details>
15
+
16
+ <div align="right">
17
+
18
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
19
+
20
+ </div>
21
+
22
+ ## [Version 1.99.0](https://github.com/lobehub/lobe-chat/compare/v1.98.2...v1.99.0)
23
+
24
+ <sup>Released on **2025-07-14**</sup>
25
+
26
+ #### ✨ Features
27
+
28
+ - **plugin**: Support Streamable HTTP MCP Server Auth.
29
+ - **misc**: support AI Image.
30
+
31
+ <br/>
32
+
33
+ <details>
34
+ <summary><kbd>Improvements and Fixes</kbd></summary>
35
+
36
+ #### What's improved
37
+
38
+ - **plugin**: Support Streamable HTTP MCP Server Auth, closes [#8425](https://github.com/lobehub/lobe-chat/issues/8425) ([853a09a](https://github.com/lobehub/lobe-chat/commit/853a09a))
39
+ - **misc**: support AI Image, closes [#8312](https://github.com/lobehub/lobe-chat/issues/8312) ([095de57](https://github.com/lobehub/lobe-chat/commit/095de57))
40
+
41
+ </details>
42
+
43
+ <div align="right">
44
+
45
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
46
+
47
+ </div>
48
+
5
49
  ### [Version 1.98.2](https://github.com/lobehub/lobe-chat/compare/v1.98.1...v1.98.2)
6
50
 
7
51
  <sup>Released on **2025-07-14**</sup>
@@ -24,6 +24,13 @@ LobeHub Desktop 是 [LobeChat](https://github.com/lobehub/lobe-chat) 的跨平
24
24
  pnpm install-isolated
25
25
  ```
26
26
 
27
+ ### 配置环境变量
28
+
29
+ 复制 `.env.desktop` 到 `.env`。
30
+
31
+ > [!WARNING]
32
+ > 注意提前备份好 `.env` 文件,避免丢失配置。
33
+
27
34
  ### 开发模式运行
28
35
 
29
36
  ```bash
@@ -25,6 +25,11 @@ const config = {
25
25
  artifactName: '${productName}-${version}.${ext}',
26
26
  },
27
27
  asar: true,
28
+ asarUnpack: [
29
+ // https://github.com/electron-userland/electron-builder/issues/9001#issuecomment-2778802044
30
+ '**/node_modules/sharp/**/*',
31
+ '**/node_modules/@img/**/*',
32
+ ],
28
33
  detectUpdateChannel: true,
29
34
  directories: {
30
35
  buildResources: 'build',
@@ -14,12 +14,13 @@
14
14
  "build-local": "npm run build && electron-builder --dir --config electron-builder.js --c.mac.notarize=false -c.mac.identity=null --c.asar=false",
15
15
  "build:linux": "npm run build && electron-builder --linux --config electron-builder.js --publish never",
16
16
  "build:mac": "npm run build && electron-builder --mac --config electron-builder.js --publish never",
17
+ "build:mac:local": "npm run build && UPDATE_CHANNEL=nightly electron-builder --mac --config electron-builder.js --publish never",
17
18
  "build:win": "npm run build && electron-builder --win --config electron-builder.js --publish never",
18
19
  "electron:dev": "electron-vite dev",
19
20
  "electron:run-unpack": "electron .",
20
21
  "format": "prettier --write ",
21
22
  "i18n": "bun run scripts/i18nWorkflow/index.ts && lobe-i18n",
22
- "postinstall": "electron-builder install-app-deps",
23
+ "postinstall": "electron-builder install-app-deps && pnpm rebuild sharp",
23
24
  "install-isolated": "pnpm install",
24
25
  "lint": "eslint --cache ",
25
26
  "pg-server": "bun run scripts/pglite-server.ts",
@@ -36,7 +36,7 @@ export const appBrowsers = {
36
36
  autoHideMenuBar: true,
37
37
  height: 800,
38
38
  identifier: 'settings',
39
- keepAlive: true,
39
+ // keepAlive: true,
40
40
  minWidth: 600,
41
41
  parentIdentifier: 'chat',
42
42
  path: '/settings',
@@ -27,3 +27,6 @@ export const LOCAL_DATABASE_DIR = 'lobehub-local-db';
27
27
  export const FILE_STORAGE_DIR = 'file-storage';
28
28
  // Plugin 安装目录
29
29
  export const INSTALL_PLUGINS_DIR = 'plugins';
30
+
31
+ // Desktop file service
32
+ export const LOCAL_STORAGE_URL_PREFIX = '/lobe-desktop-file';
@@ -1,15 +1,10 @@
1
+ import { UploadFileParams } from '@lobechat/electron-client-ipc';
2
+ import { CreateFileParams } from '@lobechat/electron-server-ipc';
3
+
1
4
  import FileService from '@/services/fileSrv';
2
5
 
3
6
  import { ControllerModule, ipcClientEvent, ipcServerEvent } from './index';
4
7
 
5
- interface UploadFileParams {
6
- content: ArrayBuffer;
7
- filename: string;
8
- hash: string;
9
- path: string;
10
- type: string;
11
- }
12
-
13
8
  export default class UploadFileCtr extends ControllerModule {
14
9
  private get fileService() {
15
10
  return this.app.getService(FileService);
@@ -27,8 +22,18 @@ export default class UploadFileCtr extends ControllerModule {
27
22
  return this.fileService.getFilePath(id);
28
23
  }
29
24
 
25
+ @ipcServerEvent('getFileHTTPURL')
26
+ async getFileHTTPURL(path: string) {
27
+ return this.fileService.getFileHTTPURL(path);
28
+ }
29
+
30
30
  @ipcServerEvent('deleteFiles')
31
31
  async deleteFiles(paths: string[]) {
32
32
  return this.fileService.deleteFiles(paths);
33
33
  }
34
+
35
+ @ipcServerEvent('createFile')
36
+ async createFile(params: CreateFileParams) {
37
+ return this.fileService.uploadFile(params);
38
+ }
34
39
  }