@lobehub/lobehub 2.0.0-next.332 → 2.0.0-next.334

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 (234) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/apps/desktop/src/main/const/dir.ts +3 -0
  3. package/apps/desktop/src/main/controllers/SystemCtr.ts +19 -0
  4. package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +1 -0
  5. package/apps/desktop/src/main/menus/impls/macOS.test.ts +1 -0
  6. package/changelog/v1.json +21 -0
  7. package/docs/changelog/2023-09-09-plugin-system.mdx +3 -2
  8. package/docs/changelog/2023-11-14-gpt4-vision.mdx +6 -4
  9. package/docs/changelog/2023-11-19-tts-stt.mdx +3 -2
  10. package/docs/changelog/2023-12-22-dalle-3.mdx +5 -2
  11. package/docs/changelog/2023-12-22-dalle-3.zh-CN.mdx +2 -2
  12. package/docs/changelog/2024-02-08-sso-oauth.mdx +2 -2
  13. package/docs/changelog/2024-06-19-lobe-chat-v1.mdx +3 -2
  14. package/docs/changelog/2024-06-19-lobe-chat-v1.zh-CN.mdx +2 -2
  15. package/docs/changelog/2024-07-19-gpt-4o-mini.mdx +3 -2
  16. package/docs/changelog/2024-07-19-gpt-4o-mini.zh-CN.mdx +2 -2
  17. package/docs/changelog/2024-08-02-lobe-chat-database-docker.mdx +3 -2
  18. package/docs/changelog/2024-08-21-file-upload-and-knowledge-base.mdx +5 -4
  19. package/docs/changelog/2024-09-13-openai-o1-models.mdx +2 -2
  20. package/docs/changelog/2024-09-20-artifacts.mdx +3 -2
  21. package/docs/changelog/2024-09-20-artifacts.zh-CN.mdx +2 -2
  22. package/docs/changelog/2024-10-27-pin-assistant.mdx +3 -2
  23. package/docs/changelog/2024-11-06-share-text-json.mdx +4 -2
  24. package/docs/changelog/2024-11-06-share-text-json.zh-CN.mdx +2 -2
  25. package/docs/changelog/2024-11-25-november-providers.mdx +2 -2
  26. package/docs/changelog/2024-11-27-forkable-chat.mdx +2 -2
  27. package/docs/changelog/2025-01-03-user-profile.mdx +2 -2
  28. package/docs/changelog/2025-01-22-new-ai-provider.mdx +2 -2
  29. package/docs/changelog/2025-02-02-deepseek-r1.mdx +4 -4
  30. package/docs/development/basic/add-new-authentication-providers.mdx +4 -0
  31. package/docs/development/basic/add-new-authentication-providers.zh-CN.mdx +4 -0
  32. package/docs/development/basic/add-new-image-model.mdx +4 -0
  33. package/docs/development/basic/add-new-image-model.zh-CN.mdx +4 -0
  34. package/docs/development/basic/architecture.mdx +4 -0
  35. package/docs/development/basic/architecture.zh-CN.mdx +4 -0
  36. package/docs/development/basic/chat-api.mdx +4 -0
  37. package/docs/development/basic/chat-api.zh-CN.mdx +4 -0
  38. package/docs/development/basic/comfyui-development.mdx +3 -1
  39. package/docs/development/basic/contributing-guidelines.mdx +4 -0
  40. package/docs/development/basic/contributing-guidelines.zh-CN.mdx +4 -0
  41. package/docs/development/basic/feature-development-frontend.mdx +11 -3
  42. package/docs/development/basic/feature-development-frontend.zh-CN.mdx +11 -3
  43. package/docs/development/basic/feature-development.mdx +14 -5
  44. package/docs/development/basic/feature-development.zh-CN.mdx +14 -5
  45. package/docs/development/basic/folder-structure.mdx +7 -0
  46. package/docs/development/basic/folder-structure.zh-CN.mdx +7 -0
  47. package/docs/development/basic/resources.mdx +4 -0
  48. package/docs/development/basic/resources.zh-CN.mdx +4 -0
  49. package/docs/development/basic/setup-development.mdx +4 -0
  50. package/docs/development/basic/setup-development.zh-CN.mdx +4 -0
  51. package/docs/development/basic/test.mdx +4 -0
  52. package/docs/development/basic/test.zh-CN.mdx +4 -0
  53. package/docs/development/basic/work-with-server-side-database.mdx +5 -5
  54. package/docs/development/basic/work-with-server-side-database.zh-CN.mdx +5 -5
  55. package/docs/development/internationalization/add-new-locale.mdx +4 -0
  56. package/docs/development/internationalization/add-new-locale.zh-CN.mdx +4 -0
  57. package/docs/development/internationalization/internationalization-implementation.mdx +4 -0
  58. package/docs/development/internationalization/internationalization-implementation.zh-CN.mdx +4 -0
  59. package/docs/development/others/lighthouse.mdx +4 -0
  60. package/docs/development/others/lighthouse.zh-CN.mdx +4 -0
  61. package/docs/development/start.mdx +4 -0
  62. package/docs/development/start.zh-CN.mdx +4 -0
  63. package/docs/development/state-management/state-management-intro.mdx +4 -2
  64. package/docs/development/state-management/state-management-intro.zh-CN.mdx +4 -2
  65. package/docs/development/state-management/state-management-selectors.mdx +6 -1
  66. package/docs/development/state-management/state-management-selectors.zh-CN.mdx +6 -1
  67. package/docs/development/tests/integration-testing.zh-CN.mdx +4 -0
  68. package/docs/self-hosting/advanced/analytics.mdx +2 -2
  69. package/docs/self-hosting/advanced/auth/better-auth/apple.mdx +132 -0
  70. package/docs/self-hosting/advanced/auth/better-auth/apple.zh-CN.mdx +127 -0
  71. package/docs/self-hosting/advanced/auth/better-auth/auth0.mdx +111 -0
  72. package/docs/self-hosting/advanced/auth/better-auth/auth0.zh-CN.mdx +107 -0
  73. package/docs/self-hosting/advanced/auth/better-auth/authelia.mdx +66 -0
  74. package/docs/self-hosting/advanced/auth/better-auth/authelia.zh-CN.mdx +62 -0
  75. package/docs/self-hosting/advanced/auth/better-auth/authentik.mdx +67 -0
  76. package/docs/self-hosting/advanced/auth/better-auth/authentik.zh-CN.mdx +63 -0
  77. package/docs/self-hosting/advanced/auth/better-auth/casdoor.mdx +62 -0
  78. package/docs/self-hosting/advanced/auth/better-auth/casdoor.zh-CN.mdx +58 -0
  79. package/docs/self-hosting/advanced/auth/better-auth/cloudflare-zero-trust.mdx +59 -0
  80. package/docs/self-hosting/advanced/auth/better-auth/cloudflare-zero-trust.zh-CN.mdx +55 -0
  81. package/docs/self-hosting/advanced/auth/better-auth/cognito.mdx +88 -0
  82. package/docs/self-hosting/advanced/auth/better-auth/cognito.zh-CN.mdx +85 -0
  83. package/docs/self-hosting/advanced/auth/better-auth/feishu.mdx +73 -0
  84. package/docs/self-hosting/advanced/auth/better-auth/feishu.zh-CN.mdx +69 -0
  85. package/docs/self-hosting/advanced/auth/better-auth/generic-oidc.mdx +86 -0
  86. package/docs/self-hosting/advanced/auth/better-auth/generic-oidc.zh-CN.mdx +83 -0
  87. package/docs/self-hosting/advanced/auth/better-auth/github.mdx +93 -0
  88. package/docs/self-hosting/advanced/auth/better-auth/github.zh-CN.mdx +90 -0
  89. package/docs/self-hosting/advanced/auth/better-auth/google.mdx +80 -0
  90. package/docs/self-hosting/advanced/auth/better-auth/google.zh-CN.mdx +77 -0
  91. package/docs/self-hosting/advanced/auth/better-auth/keycloak.mdx +77 -0
  92. package/docs/self-hosting/advanced/auth/better-auth/keycloak.zh-CN.mdx +74 -0
  93. package/docs/self-hosting/advanced/auth/better-auth/logto.mdx +64 -0
  94. package/docs/self-hosting/advanced/auth/better-auth/logto.zh-CN.mdx +60 -0
  95. package/docs/self-hosting/advanced/auth/better-auth/microsoft.mdx +113 -0
  96. package/docs/self-hosting/advanced/auth/better-auth/microsoft.zh-CN.mdx +109 -0
  97. package/docs/self-hosting/advanced/auth/better-auth/okta.mdx +67 -0
  98. package/docs/self-hosting/advanced/auth/better-auth/okta.zh-CN.mdx +63 -0
  99. package/docs/self-hosting/advanced/auth/better-auth/wechat.mdx +77 -0
  100. package/docs/self-hosting/advanced/auth/better-auth/wechat.zh-CN.mdx +72 -0
  101. package/docs/self-hosting/advanced/auth/better-auth/zitadel.mdx +73 -0
  102. package/docs/self-hosting/advanced/auth/better-auth/zitadel.zh-CN.mdx +69 -0
  103. package/docs/self-hosting/advanced/auth/clerk.mdx +2 -2
  104. package/docs/self-hosting/advanced/auth/legacy.mdx +106 -0
  105. package/docs/self-hosting/advanced/auth/legacy.zh-CN.mdx +101 -0
  106. package/docs/self-hosting/advanced/auth/next-auth/auth0.mdx +3 -2
  107. package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +3 -2
  108. package/docs/self-hosting/advanced/auth/next-auth/authentik.mdx +3 -2
  109. package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +5 -2
  110. package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +2 -0
  111. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.mdx +3 -2
  112. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.zh-CN.mdx +2 -2
  113. package/docs/self-hosting/advanced/auth/next-auth/github.mdx +3 -2
  114. package/docs/self-hosting/advanced/auth/next-auth/google.mdx +10 -12
  115. package/docs/self-hosting/advanced/auth/next-auth/keycloak.mdx +3 -2
  116. package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +2 -2
  117. package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.mdx +3 -2
  118. package/docs/self-hosting/advanced/auth/next-auth/okta.mdx +3 -2
  119. package/docs/self-hosting/advanced/auth/next-auth/okta.zh-CN.mdx +1 -3
  120. package/docs/self-hosting/advanced/auth/next-auth/wechat.mdx +2 -2
  121. package/docs/self-hosting/advanced/auth/next-auth/zitadel.mdx +3 -2
  122. package/docs/self-hosting/advanced/auth.mdx +86 -139
  123. package/docs/self-hosting/advanced/auth.zh-CN.mdx +84 -135
  124. package/docs/self-hosting/advanced/desktop.mdx +9 -3
  125. package/docs/self-hosting/advanced/desktop.zh-CN.mdx +9 -3
  126. package/docs/self-hosting/advanced/feature-flags.mdx +3 -2
  127. package/docs/self-hosting/advanced/knowledge-base.mdx +2 -2
  128. package/docs/self-hosting/advanced/model-list.mdx +2 -2
  129. package/docs/self-hosting/advanced/observability/grafana.mdx +4 -2
  130. package/docs/self-hosting/advanced/observability/grafana.zh-CN.mdx +2 -1
  131. package/docs/self-hosting/advanced/observability/langfuse.mdx +3 -2
  132. package/docs/self-hosting/advanced/online-search.mdx +4 -6
  133. package/docs/self-hosting/advanced/s3/tencent-cloud.mdx +2 -2
  134. package/docs/self-hosting/advanced/settings-url-share.mdx +3 -2
  135. package/docs/self-hosting/advanced/upstream-sync.mdx +3 -4
  136. package/docs/self-hosting/advanced/upstream-sync.zh-CN.mdx +0 -2
  137. package/docs/self-hosting/environment-variables/analytics.mdx +3 -2
  138. package/docs/self-hosting/environment-variables/auth.mdx +5 -12
  139. package/docs/self-hosting/environment-variables/auth.zh-CN.mdx +2 -9
  140. package/docs/self-hosting/environment-variables/basic.mdx +3 -10
  141. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +0 -7
  142. package/docs/self-hosting/environment-variables/model-provider.mdx +3 -4
  143. package/docs/self-hosting/environment-variables/s3.mdx +2 -2
  144. package/docs/self-hosting/environment-variables.mdx +2 -3
  145. package/docs/self-hosting/examples/azure-openai.mdx +2 -3
  146. package/docs/self-hosting/examples/azure-openai.zh-CN.mdx +0 -1
  147. package/docs/self-hosting/examples/ollama.mdx +3 -2
  148. package/docs/self-hosting/faq/no-v1-suffix.mdx +4 -4
  149. package/docs/self-hosting/faq/proxy-with-unable-to-verify-leaf-signature.mdx +3 -2
  150. package/docs/self-hosting/faq/vercel-ai-image-timeout.mdx +2 -2
  151. package/docs/self-hosting/migration/v2/breaking-changes.mdx +73 -0
  152. package/docs/self-hosting/migration/v2/breaking-changes.zh-CN.mdx +71 -0
  153. package/docs/self-hosting/platform/alibaba-cloud.mdx +2 -7
  154. package/docs/self-hosting/platform/alibaba-cloud.zh-CN.mdx +1 -6
  155. package/docs/self-hosting/platform/btpanel.mdx +4 -2
  156. package/docs/self-hosting/platform/btpanel.zh-CN.mdx +2 -2
  157. package/docs/self-hosting/platform/docker-compose.mdx +3 -3
  158. package/docs/self-hosting/platform/docker-compose.zh-CN.mdx +0 -1
  159. package/docs/self-hosting/platform/docker.mdx +2 -11
  160. package/docs/self-hosting/platform/docker.zh-CN.mdx +0 -8
  161. package/docs/self-hosting/platform/netlify.mdx +5 -17
  162. package/docs/self-hosting/platform/netlify.zh-CN.mdx +3 -17
  163. package/docs/self-hosting/platform/railway.mdx +3 -7
  164. package/docs/self-hosting/platform/railway.zh-CN.mdx +1 -7
  165. package/docs/self-hosting/platform/repocloud.mdx +3 -7
  166. package/docs/self-hosting/platform/repocloud.zh-CN.mdx +1 -6
  167. package/docs/self-hosting/platform/sealos.mdx +2 -7
  168. package/docs/self-hosting/platform/sealos.zh-CN.mdx +1 -6
  169. package/docs/self-hosting/platform/tencentcloud-lighthouse.mdx +2 -7
  170. package/docs/self-hosting/platform/tencentcloud-lighthouse.zh-CN.mdx +1 -6
  171. package/docs/self-hosting/platform/vercel.mdx +4 -9
  172. package/docs/self-hosting/platform/vercel.zh-CN.mdx +3 -8
  173. package/docs/self-hosting/platform/zeabur.mdx +2 -11
  174. package/docs/self-hosting/platform/zeabur.zh-CN.mdx +1 -10
  175. package/docs/self-hosting/server-database/docker-compose.mdx +11 -19
  176. package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +12 -21
  177. package/docs/self-hosting/server-database/docker.mdx +9 -24
  178. package/docs/self-hosting/server-database/docker.zh-CN.mdx +7 -24
  179. package/docs/self-hosting/server-database/dokploy.mdx +27 -25
  180. package/docs/self-hosting/server-database/dokploy.zh-CN.mdx +23 -21
  181. package/docs/self-hosting/server-database/netlify.mdx +2 -2
  182. package/docs/self-hosting/server-database/netlify.zh-CN.mdx +2 -2
  183. package/docs/self-hosting/server-database/railway.mdx +2 -2
  184. package/docs/self-hosting/server-database/repocloud.mdx +2 -2
  185. package/docs/self-hosting/server-database/sealos.mdx +2 -2
  186. package/docs/self-hosting/server-database/vercel.mdx +19 -72
  187. package/docs/self-hosting/server-database/vercel.zh-CN.mdx +17 -68
  188. package/docs/self-hosting/server-database/zeabur.mdx +2 -2
  189. package/docs/self-hosting/server-database.mdx +1 -19
  190. package/docs/self-hosting/server-database.zh-CN.mdx +0 -17
  191. package/docs/self-hosting/start.mdx +2 -2
  192. package/docs/self-hosting/start.zh-CN.mdx +2 -2
  193. package/locales/ar/common.json +1 -0
  194. package/locales/bg-BG/common.json +1 -0
  195. package/locales/de-DE/common.json +1 -0
  196. package/locales/en-US/common.json +1 -0
  197. package/locales/en-US/desktop-onboarding.json +1 -0
  198. package/locales/es-ES/common.json +1 -0
  199. package/locales/fa-IR/common.json +1 -0
  200. package/locales/fr-FR/common.json +1 -0
  201. package/locales/it-IT/common.json +1 -0
  202. package/locales/ja-JP/common.json +1 -0
  203. package/locales/ko-KR/common.json +1 -0
  204. package/locales/nl-NL/common.json +1 -0
  205. package/locales/pl-PL/common.json +1 -0
  206. package/locales/pt-BR/common.json +1 -0
  207. package/locales/ru-RU/common.json +1 -0
  208. package/locales/tr-TR/common.json +1 -0
  209. package/locales/vi-VN/common.json +1 -0
  210. package/locales/zh-CN/common.json +1 -0
  211. package/locales/zh-CN/desktop-onboarding.json +1 -0
  212. package/locales/zh-TW/common.json +1 -0
  213. package/package.json +2 -2
  214. package/packages/builtin-tool-cloud-sandbox/src/systemRole.ts +62 -2
  215. package/packages/const/src/url.ts +6 -0
  216. package/packages/conversation-flow/src/__tests__/fixtures/inputs/tasks/index.ts +2 -0
  217. package/packages/conversation-flow/src/__tests__/fixtures/inputs/tasks/multi-tasks-with-summary.json +234 -0
  218. package/packages/conversation-flow/src/__tests__/parse.test.ts +25 -0
  219. package/packages/conversation-flow/src/transformation/ContextTreeBuilder.ts +15 -0
  220. package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +20 -0
  221. package/packages/types/src/serverConfig.ts +0 -1
  222. package/src/app/[variants]/(desktop)/desktop-onboarding/features/LoginStep.tsx +39 -1
  223. package/src/app/[variants]/(main)/settings/common/features/Common/Common.tsx +34 -14
  224. package/src/app/[variants]/(mobile)/me/(home)/features/useCategory.tsx +16 -9
  225. package/src/app/[variants]/layout.tsx +0 -4
  226. package/src/envs/app.ts +0 -13
  227. package/src/features/User/UserPanel/useMenu.tsx +18 -9
  228. package/src/hooks/usePlatform.test.ts +5 -0
  229. package/src/hooks/usePlatform.ts +1 -0
  230. package/src/locales/default/common.ts +1 -0
  231. package/src/locales/default/desktop-onboarding.ts +1 -0
  232. package/src/server/globalConfig/index.ts +1 -2
  233. package/src/services/electron/system.ts +4 -0
  234. package/src/store/serverConfig/selectors.ts +0 -1
@@ -11,6 +11,58 @@ export const systemPrompt = `You have access to a Cloud Sandbox that provides a
11
11
  </sandbox_environment>
12
12
 
13
13
 
14
+ <preinstalled_software>
15
+ **IMPORTANT: Prefer Pre-installed Software**
16
+ The sandbox comes with pre-installed software and libraries. **Always prioritize using these pre-installed tools** when they can solve the user's problem, rather than installing additional packages.
17
+
18
+ **Operating System:**
19
+ - Debian 12
20
+
21
+ **Programming Languages & Runtimes:**
22
+ - Python (with pip)
23
+ - Node.js (with npm)
24
+
25
+ **Build Tools:**
26
+ - build-essential 12.9
27
+ - gcc/g++ 12.2.0
28
+
29
+ **Python Libraries (Pre-installed):**
30
+ - numpy 2.4.1 - Numerical computing
31
+ - scipy 1.17.0 - Scientific computing
32
+ - pandas 2.3.3 - Data analysis
33
+ - matplotlib 3.10.8 - Static visualization
34
+ - plotly 6.5.2 - Interactive visualization
35
+ - scikit-learn 1.8.0 - Machine learning
36
+ - opencv-python 4.13.0.90 - Computer vision
37
+ - Pillow 12.1.0 - Image processing
38
+ - wheel 0.45.1 - Python package installer
39
+
40
+ **Document & Media Tools:**
41
+ - LibreOffice - Office document processing
42
+ - Pandoc - Document format conversion
43
+ - pdftoppm - PDF to image conversion
44
+ - FFmpeg 5.1.8-0+deb12u1 - Audio/video processing
45
+
46
+ **Browser Automation:**
47
+ - Playwright - Browser automation
48
+ - marpc-cli - Browser-based PPTX generation
49
+
50
+ **Fonts:**
51
+ - Noto Sans CJK - Chinese/Japanese/Korean sans-serif font
52
+ - Noto Serif CJK - Chinese/Japanese/Korean serif font
53
+
54
+ **NOT Available (do not attempt to use):**
55
+ - Tesseract (OCR) - Not installed
56
+ - Puppeteer - Not installed, use Playwright instead
57
+ - mermaid-cli - Not installed
58
+
59
+ **Installation Guidelines:**
60
+ - Only install additional packages when pre-installed software cannot fulfill the requirement
61
+ - When Python libraries are already available, use them directly without pip install
62
+ - For document generation, prioritize LibreOffice and Pandoc before Python libraries
63
+ </preinstalled_software>
64
+
65
+
14
66
  <core_capabilities>
15
67
  You have access to the following tools for interacting with the cloud sandbox:
16
68
 
@@ -114,7 +166,15 @@ When code execution produces any output files (documents, images, data, etc.), y
114
166
  When executing Python code:
115
167
 
116
168
 
169
+ **Using Pre-installed Libraries:**
170
+ - **Always check if required libraries are pre-installed** (see preinstalled_software section)
171
+ - numpy, scipy, pandas, matplotlib, plotly, scikit-learn, opencv-python, Pillow are already available
172
+ - **Skip pip install** for pre-installed libraries - use them directly
173
+ - Only use \`pip install\` for libraries NOT in the pre-installed list
174
+
175
+
117
176
  **Visualization with Matplotlib:**
177
+ - matplotlib 3.10.8 is pre-installed - use directly without installation
118
178
  - Never use seaborn library
119
179
  - Give each chart its own distinct plot (no subplots)
120
180
  - Never set specific colors unless explicitly asked by the user
@@ -127,10 +187,10 @@ You MUST use the following libraries for each supported file format:
127
187
  - **DOCX**: Use \`python-docx\`
128
188
  - **XLSX**: Use \`openpyxl\`
129
189
  - **PPTX**: Use \`python-pptx\`
130
- - **CSV**: Use \`pandas\`
190
+ - **CSV**: Use pre-installed \`pandas\` (no installation needed)
131
191
  - **ODS/ODT/ODP**: Use \`odfpy\`
132
192
 
133
- Install required packages first: \`pip install <package-name>\`
193
+ For libraries NOT pre-installed: Install with \`pip install <package-name>\` before use.
134
194
  **After successful generation, automatically export the document file.**
135
195
 
136
196
 
@@ -63,3 +63,9 @@ export const AES_GCM_URL = 'https://datatracker.ietf.org/doc/html/draft-ietf-avt
63
63
  export const BASE_PROVIDER_DOC_URL = 'https://lobehub.com/docs/usage/providers';
64
64
  export const SITEMAP_BASE_URL = isDev ? '/sitemap.xml/' : 'sitemap';
65
65
  export const CHANGELOG_URL = urlJoin(OFFICIAL_SITE, 'changelog/versions');
66
+
67
+ export const DOWNLOAD_URL = {
68
+ android: 'https://play.google.com/store/apps/details?id=com.lobehub.app',
69
+ default: urlJoin(OFFICIAL_SITE, '/download'),
70
+ ios: 'https://testflight.apple.com/join/2ZbjX4Qp',
71
+ } as const;
@@ -1,8 +1,10 @@
1
1
  import type { Message } from '../../../../types';
2
+ import multiTasksWithSummary from './multi-tasks-with-summary.json';
2
3
  import simple from './simple.json';
3
4
  import withSummary from './with-summary.json';
4
5
 
5
6
  export const tasks = {
7
+ multiTasksWithSummary: multiTasksWithSummary as Message[],
6
8
  simple: simple as Message[],
7
9
  withSummary: withSummary as Message[],
8
10
  };
@@ -0,0 +1,234 @@
1
+ [
2
+ {
3
+ "id": "msg-user-1",
4
+ "role": "user",
5
+ "content": "Process these files in 10 parallel tasks and give me a summary.",
6
+ "parentId": null,
7
+ "createdAt": 1735526559382,
8
+ "updatedAt": 1735526559382
9
+ },
10
+ {
11
+ "id": "msg-assistant-1",
12
+ "role": "assistant",
13
+ "content": "I'll process these files in 10 parallel tasks.",
14
+ "parentId": "msg-user-1",
15
+ "createdAt": 1735526560163,
16
+ "updatedAt": 1735526585550,
17
+ "model": "gpt-4",
18
+ "provider": "openai",
19
+ "tools": [
20
+ {
21
+ "id": "call_exec_tasks_1",
22
+ "type": "builtin",
23
+ "apiName": "execTasks",
24
+ "arguments": "{\"tasks\": [{\"description\": \"Task 1\"}, {\"description\": \"Task 2\"}, {\"description\": \"Task 3\"}, {\"description\": \"Task 4\"}, {\"description\": \"Task 5\"}, {\"description\": \"Task 6\"}, {\"description\": \"Task 7\"}, {\"description\": \"Task 8\"}, {\"description\": \"Task 9\"}, {\"description\": \"Task 10\"}]}",
25
+ "identifier": "lobe-gtd"
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "id": "msg-tool-1",
31
+ "role": "tool",
32
+ "content": "Triggered 10 async tasks",
33
+ "parentId": "msg-assistant-1",
34
+ "tool_call_id": "call_exec_tasks_1",
35
+ "createdAt": 1735526588116,
36
+ "updatedAt": 1735526591337,
37
+ "pluginState": {
38
+ "type": "execTasks",
39
+ "tasks": [
40
+ { "description": "Task 1" },
41
+ { "description": "Task 2" },
42
+ { "description": "Task 3" },
43
+ { "description": "Task 4" },
44
+ { "description": "Task 5" },
45
+ { "description": "Task 6" },
46
+ { "description": "Task 7" },
47
+ { "description": "Task 8" },
48
+ { "description": "Task 9" },
49
+ { "description": "Task 10" }
50
+ ],
51
+ "parentMessageId": "msg-tool-1"
52
+ }
53
+ },
54
+ {
55
+ "id": "msg-task-1",
56
+ "role": "task",
57
+ "content": "Task 1 completed with results...",
58
+ "parentId": "msg-tool-1",
59
+ "createdAt": 1735526594643,
60
+ "updatedAt": 1735526756262,
61
+ "taskDetail": {
62
+ "duration": 120000,
63
+ "status": "completed",
64
+ "threadId": "thd_task_1",
65
+ "title": "Task 1",
66
+ "totalCost": 0.015,
67
+ "totalMessages": 15,
68
+ "totalTokens": 100000
69
+ }
70
+ },
71
+ {
72
+ "id": "msg-task-2",
73
+ "role": "task",
74
+ "content": "Task 2 completed with results...",
75
+ "parentId": "msg-tool-1",
76
+ "createdAt": 1735526595000,
77
+ "updatedAt": 1735526757000,
78
+ "taskDetail": {
79
+ "duration": 121000,
80
+ "status": "completed",
81
+ "threadId": "thd_task_2",
82
+ "title": "Task 2",
83
+ "totalCost": 0.016,
84
+ "totalMessages": 16,
85
+ "totalTokens": 101000
86
+ }
87
+ },
88
+ {
89
+ "id": "msg-task-3",
90
+ "role": "task",
91
+ "content": "Task 3 completed with results...",
92
+ "parentId": "msg-tool-1",
93
+ "createdAt": 1735526596000,
94
+ "updatedAt": 1735526758000,
95
+ "taskDetail": {
96
+ "duration": 122000,
97
+ "status": "completed",
98
+ "threadId": "thd_task_3",
99
+ "title": "Task 3",
100
+ "totalCost": 0.017,
101
+ "totalMessages": 17,
102
+ "totalTokens": 102000
103
+ }
104
+ },
105
+ {
106
+ "id": "msg-task-4",
107
+ "role": "task",
108
+ "content": "Task 4 completed with results...",
109
+ "parentId": "msg-tool-1",
110
+ "createdAt": 1735526597000,
111
+ "updatedAt": 1735526759000,
112
+ "taskDetail": {
113
+ "duration": 123000,
114
+ "status": "completed",
115
+ "threadId": "thd_task_4",
116
+ "title": "Task 4",
117
+ "totalCost": 0.018,
118
+ "totalMessages": 18,
119
+ "totalTokens": 103000
120
+ }
121
+ },
122
+ {
123
+ "id": "msg-task-5",
124
+ "role": "task",
125
+ "content": "Task 5 completed with results...",
126
+ "parentId": "msg-tool-1",
127
+ "createdAt": 1735526598000,
128
+ "updatedAt": 1735526760000,
129
+ "taskDetail": {
130
+ "duration": 124000,
131
+ "status": "completed",
132
+ "threadId": "thd_task_5",
133
+ "title": "Task 5",
134
+ "totalCost": 0.019,
135
+ "totalMessages": 19,
136
+ "totalTokens": 104000
137
+ }
138
+ },
139
+ {
140
+ "id": "msg-task-6",
141
+ "role": "task",
142
+ "content": "Task 6 completed with results...",
143
+ "parentId": "msg-tool-1",
144
+ "createdAt": 1735526599000,
145
+ "updatedAt": 1735526761000,
146
+ "taskDetail": {
147
+ "duration": 125000,
148
+ "status": "completed",
149
+ "threadId": "thd_task_6",
150
+ "title": "Task 6",
151
+ "totalCost": 0.02,
152
+ "totalMessages": 20,
153
+ "totalTokens": 105000
154
+ }
155
+ },
156
+ {
157
+ "id": "msg-task-7",
158
+ "role": "task",
159
+ "content": "Task 7 completed with results...",
160
+ "parentId": "msg-tool-1",
161
+ "createdAt": 1735526600000,
162
+ "updatedAt": 1735526762000,
163
+ "taskDetail": {
164
+ "duration": 126000,
165
+ "status": "completed",
166
+ "threadId": "thd_task_7",
167
+ "title": "Task 7",
168
+ "totalCost": 0.021,
169
+ "totalMessages": 21,
170
+ "totalTokens": 106000
171
+ }
172
+ },
173
+ {
174
+ "id": "msg-task-8",
175
+ "role": "task",
176
+ "content": "Task 8 completed with results...",
177
+ "parentId": "msg-tool-1",
178
+ "createdAt": 1735526601000,
179
+ "updatedAt": 1735526763000,
180
+ "taskDetail": {
181
+ "duration": 127000,
182
+ "status": "completed",
183
+ "threadId": "thd_task_8",
184
+ "title": "Task 8",
185
+ "totalCost": 0.022,
186
+ "totalMessages": 22,
187
+ "totalTokens": 107000
188
+ }
189
+ },
190
+ {
191
+ "id": "msg-task-9",
192
+ "role": "task",
193
+ "content": "Task 9 completed with results...",
194
+ "parentId": "msg-tool-1",
195
+ "createdAt": 1735526602000,
196
+ "updatedAt": 1735526764000,
197
+ "taskDetail": {
198
+ "duration": 128000,
199
+ "status": "completed",
200
+ "threadId": "thd_task_9",
201
+ "title": "Task 9",
202
+ "totalCost": 0.023,
203
+ "totalMessages": 23,
204
+ "totalTokens": 108000
205
+ }
206
+ },
207
+ {
208
+ "id": "msg-task-10",
209
+ "role": "task",
210
+ "content": "Task 10 completed with results...",
211
+ "parentId": "msg-tool-1",
212
+ "createdAt": 1735526603000,
213
+ "updatedAt": 1735526765000,
214
+ "taskDetail": {
215
+ "duration": 129000,
216
+ "status": "completed",
217
+ "threadId": "thd_task_10",
218
+ "title": "Task 10",
219
+ "totalCost": 0.024,
220
+ "totalMessages": 24,
221
+ "totalTokens": 109000
222
+ }
223
+ },
224
+ {
225
+ "id": "msg-assistant-summary",
226
+ "role": "assistant",
227
+ "content": "All 10 tasks completed successfully! Here's the comprehensive summary...",
228
+ "parentId": "msg-task-10",
229
+ "createdAt": 1735526810000,
230
+ "updatedAt": 1735526820000,
231
+ "model": "gpt-4",
232
+ "provider": "openai"
233
+ }
234
+ ]
@@ -194,6 +194,31 @@ describe('parse', () => {
194
194
 
195
195
  expect(serializeParseResult(result)).toEqual(outputs.tasks.withSummary);
196
196
  });
197
+
198
+ it('should handle 10 parallel tasks with summary as task child', () => {
199
+ const result = parse(inputs.tasks.multiTasksWithSummary);
200
+
201
+ // The critical assertions:
202
+ // 1. flatList should have 4 items: user, assistantGroup(+tool), tasks(10 tasks), assistant-summary
203
+ expect(result.flatList).toHaveLength(4);
204
+ expect(result.flatList[0].role).toBe('user');
205
+ expect(result.flatList[1].role).toBe('assistantGroup');
206
+ expect(result.flatList[2].role).toBe('tasks');
207
+ expect(result.flatList[3].role).toBe('assistant');
208
+
209
+ // 2. tasks virtual message should have 10 task messages
210
+ expect((result.flatList[2] as any).tasks).toHaveLength(10);
211
+
212
+ // 3. Verify all tasks are completed
213
+ const tasks = (result.flatList[2] as any).tasks;
214
+ for (const task of tasks) {
215
+ expect(task.taskDetail.status).toBe('completed');
216
+ }
217
+
218
+ // 4. The summary message should be present and accessible
219
+ expect(result.flatList[3].id).toBe('msg-assistant-summary');
220
+ expect(result.flatList[3].content).toContain('All 10 tasks completed');
221
+ });
197
222
  });
198
223
 
199
224
  describe('Performance', () => {
@@ -125,6 +125,21 @@ export class ContextTreeBuilder {
125
125
  for (const nonTaskChild of nonTaskChildren) {
126
126
  this.transformToLinear(nonTaskChild, contextTree);
127
127
  }
128
+
129
+ // Also check for children of task messages (e.g., summary as child of last task)
130
+ const taskChildren = idNode.children.filter((child) => {
131
+ const childMsg = this.messageMap.get(child.id);
132
+ return childMsg?.role === 'task';
133
+ });
134
+
135
+ for (const taskChild of taskChildren) {
136
+ for (const taskGrandchild of taskChild.children) {
137
+ const taskGrandchildMsg = this.messageMap.get(taskGrandchild.id);
138
+ if (taskGrandchildMsg && taskGrandchildMsg.role !== 'task') {
139
+ this.transformToLinear(taskGrandchild, contextTree);
140
+ }
141
+ }
142
+ }
128
143
  return;
129
144
  }
130
145
 
@@ -113,6 +113,26 @@ export class FlatListBuilder {
113
113
  }
114
114
  }
115
115
  }
116
+
117
+ // Also check for children of task messages (e.g., summary as child of last task)
118
+ for (const taskChildId of taskChildren) {
119
+ const taskChildrenIds = this.childrenMap.get(taskChildId) ?? [];
120
+ for (const taskGrandchildId of taskChildrenIds) {
121
+ if (!processedIds.has(taskGrandchildId)) {
122
+ const taskGrandchild = this.messageMap.get(taskGrandchildId);
123
+ if (taskGrandchild && taskGrandchild.role !== 'task') {
124
+ flatList.push(taskGrandchild);
125
+ processedIds.add(taskGrandchildId);
126
+ this.buildFlatListRecursive(
127
+ taskGrandchildId,
128
+ flatList,
129
+ processedIds,
130
+ allMessages,
131
+ );
132
+ }
133
+ }
134
+ }
135
+ }
116
136
  return;
117
137
  }
118
138
  }
@@ -56,7 +56,6 @@ export interface GlobalServerConfig {
56
56
  enableMagicLink?: boolean;
57
57
  enableMarketTrustedClient?: boolean;
58
58
  enableUploadFileToServer?: boolean;
59
- enabledAccessCode?: boolean;
60
59
  /**
61
60
  * @deprecated
62
61
  */
@@ -11,15 +11,23 @@ import { cssVar } from 'antd-style';
11
11
  import { Cloud, Server, Undo2Icon } from 'lucide-react';
12
12
  import { memo, useEffect, useState } from 'react';
13
13
  import { useTranslation } from 'react-i18next';
14
+ import urlJoin from 'url-join';
14
15
 
16
+ import { OFFICIAL_SITE } from '@/const/url';
15
17
  import { isDesktop } from '@/const/version';
16
18
  import UserInfo from '@/features/User/UserInfo';
17
19
  import { remoteServerService } from '@/services/electron/remoteServer';
20
+ import { electronSystemService } from '@/services/electron/system';
18
21
  import { useElectronStore } from '@/store/electron';
19
22
  import { setDesktopAutoOidcFirstOpenHandled } from '@/utils/electron/autoOidc';
20
23
 
21
24
  import LobeMessage from '../components/LobeMessage';
22
25
 
26
+ const LEGACY_LOCAL_DB_MIGRATION_GUIDE_URL = urlJoin(
27
+ OFFICIAL_SITE,
28
+ '/docs/usage/migrate-from-local-database',
29
+ );
30
+
23
31
  // 登录方式类型
24
32
  type LoginMethod = 'cloud' | 'selfhost';
25
33
 
@@ -62,6 +70,7 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
62
70
  const [remoteError, setRemoteError] = useState<string | null>(null);
63
71
  const [isSigningOut, setIsSigningOut] = useState(false);
64
72
  const [showEndpoint, setShowEndpoint] = useState(false);
73
+ const [hasLegacyLocalDb, setHasLegacyLocalDb] = useState(false);
65
74
 
66
75
  const [
67
76
  dataSyncConfig,
@@ -83,9 +92,24 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
83
92
  s.disconnectRemoteServer,
84
93
  ]);
85
94
 
86
- // Ensure remote server config is loaded early (desktop only hook)
87
95
  useDataSyncConfig();
88
96
 
97
+ useEffect(() => {
98
+ if (!isDesktop) return;
99
+
100
+ let mounted = true;
101
+ electronSystemService
102
+ .hasLegacyLocalDb()
103
+ .then((value) => {
104
+ if (mounted) setHasLegacyLocalDb(value);
105
+ })
106
+ .catch(() => undefined);
107
+
108
+ return () => {
109
+ mounted = false;
110
+ };
111
+ }, []);
112
+
89
113
  const isCloudAuthed = !!dataSyncConfig?.active && dataSyncConfig.storageMode === 'cloud';
90
114
  const isSelfHostAuthed = !!dataSyncConfig?.active && dataSyncConfig.storageMode === 'selfHost';
91
115
  const isSelfHostEndpointVerified =
@@ -441,6 +465,19 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
441
465
 
442
466
  <Flexbox align={'flex-start'} gap={16} style={{ width: '100%' }} width={'100%'}>
443
467
  {renderCloudContent()}
468
+ <Flexbox horizontal justify={'center'} style={{ width: '100%' }}>
469
+ {hasLegacyLocalDb && (
470
+ <Button
471
+ onClick={() =>
472
+ electronSystemService.openExternalLink(LEGACY_LOCAL_DB_MIGRATION_GUIDE_URL)
473
+ }
474
+ style={{ padding: 0 }}
475
+ type={'link'}
476
+ >
477
+ {t('screen5.legacyLocalDb.link', 'Migrate legacy local database')}
478
+ </Button>
479
+ )}
480
+ </Flexbox>
444
481
  {!showEndpoint ? (
445
482
  <Center width={'100%'}>
446
483
  <Button
@@ -460,6 +497,7 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
460
497
  OR
461
498
  </Text>
462
499
  </Divider>
500
+
463
501
  {/* Self-host 选项 */}
464
502
  {renderSelfhostContent()}
465
503
  </>
@@ -1,7 +1,14 @@
1
1
  'use client';
2
2
 
3
- import { Form, type FormGroupItemType, Icon, ImageSelect } from '@lobehub/ui';
4
- import { Select, Skeleton } from '@lobehub/ui';
3
+ import {
4
+ Flexbox,
5
+ Form,
6
+ type FormGroupItemType,
7
+ Icon,
8
+ ImageSelect,
9
+ LobeSelect as Select,
10
+ Skeleton,
11
+ } from '@lobehub/ui';
5
12
  import { Segmented, Switch } from 'antd';
6
13
  import isEqual from 'fast-deep-equal';
7
14
  import { Ban, Gauge, Loader2Icon, Monitor, Moon, Mouse, Sun, Waves } from 'lucide-react';
@@ -76,11 +83,19 @@ const Common = memo(() => {
76
83
  },
77
84
  {
78
85
  children: (
79
- <Select
80
- defaultValue={language}
81
- onChange={handleLangChange}
82
- options={[{ label: t('settingCommon.lang.autoMode'), value: 'auto' }, ...localeOptions]}
83
- />
86
+ <Flexbox horizontal justify={'flex-end'}>
87
+ <Select
88
+ defaultValue={language}
89
+ onChange={handleLangChange}
90
+ options={[
91
+ { label: t('settingCommon.lang.autoMode'), value: 'auto' },
92
+ ...localeOptions,
93
+ ]}
94
+ style={{
95
+ width: '50%',
96
+ }}
97
+ />
98
+ </Flexbox>
84
99
  ),
85
100
  label: t('settingCommon.lang.title'),
86
101
  },
@@ -136,13 +151,18 @@ const Common = memo(() => {
136
151
 
137
152
  {
138
153
  children: (
139
- <Select
140
- options={[
141
- { label: t('settingCommon.responseLanguage.auto'), value: '' },
142
- ...localeOptions,
143
- ]}
144
- placeholder={t('settingCommon.responseLanguage.placeholder')}
145
- />
154
+ <Flexbox horizontal justify={'flex-end'}>
155
+ <Select
156
+ options={[
157
+ { label: t('settingCommon.responseLanguage.auto'), value: '' },
158
+ ...localeOptions,
159
+ ]}
160
+ placeholder={t('settingCommon.responseLanguage.placeholder')}
161
+ style={{
162
+ width: '50%',
163
+ }}
164
+ />
165
+ </Flexbox>
146
166
  ),
147
167
  desc: t('settingCommon.responseLanguage.desc'),
148
168
  label: t('settingCommon.responseLanguage.title'),
@@ -1,5 +1,5 @@
1
- import { UTM_SOURCE , LOBE_CHAT_CLOUD } from '@lobechat/business-const';
2
- import { OFFICIAL_URL } from '@lobechat/const';
1
+ import { LOBE_CHAT_CLOUD, UTM_SOURCE } from '@lobechat/business-const';
2
+ import { DOWNLOAD_URL, OFFICIAL_URL } from '@lobechat/const';
3
3
  import {
4
4
  Book,
5
5
  CircleUserRound,
@@ -9,22 +9,29 @@ import {
9
9
  FileClockIcon,
10
10
  Settings2,
11
11
  } from 'lucide-react';
12
+ import { useMemo } from 'react';
12
13
  import { useTranslation } from 'react-i18next';
13
14
  import { useNavigate } from 'react-router-dom';
14
15
 
15
16
  import { type CellProps } from '@/components/Cell';
16
17
  import { DOCUMENTS, FEEDBACK } from '@/const/index';
17
- import { usePWAInstall } from '@/hooks/usePWAInstall';
18
+ import { usePlatform } from '@/hooks/usePlatform';
18
19
  import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
19
20
  import { useUserStore } from '@/store/user';
20
21
  import { authSelectors } from '@/store/user/selectors';
21
22
 
22
23
  export const useCategory = (onOpenChangelogModal: () => void) => {
23
24
  const navigate = useNavigate();
24
- const { canInstall, install } = usePWAInstall();
25
25
  const { t } = useTranslation(['common', 'setting', 'auth']);
26
26
  const { showCloudPromotion, hideDocs } = useServerConfigStore(featureFlagsSelectors);
27
27
  const [isLoginWithAuth] = useUserStore((s) => [authSelectors.isLoginWithAuth(s)]);
28
+ const { isIOS, isAndroid } = usePlatform();
29
+
30
+ const downloadUrl = useMemo(() => {
31
+ if (isIOS) return DOWNLOAD_URL.ios;
32
+ if (isAndroid) return DOWNLOAD_URL.android;
33
+ return DOWNLOAD_URL.default;
34
+ }, [isIOS, isAndroid]);
28
35
 
29
36
  const profile: CellProps[] = [
30
37
  {
@@ -47,12 +54,12 @@ export const useCategory = (onOpenChangelogModal: () => void) => {
47
54
  },
48
55
  ];
49
56
 
50
- const pwa: CellProps[] = [
57
+ const downloadClient: CellProps[] = [
51
58
  {
52
59
  icon: Download,
53
- key: 'pwa',
54
- label: t('installPWA'),
55
- onClick: () => install(),
60
+ key: 'download-client',
61
+ label: t('downloadClient'),
62
+ onClick: () => window.open(downloadUrl, '__blank'),
56
63
  },
57
64
  {
58
65
  type: 'divider',
@@ -96,7 +103,7 @@ export const useCategory = (onOpenChangelogModal: () => void) => {
96
103
  /* ↓ cloud slot ↓ */
97
104
 
98
105
  /* ↑ cloud slot ↑ */
99
- ...(canInstall ? pwa : []),
106
+ ...downloadClient,
100
107
  ...(!hideDocs ? helps : []),
101
108
  ].filter(Boolean) as CellProps[];
102
109
 
@@ -9,7 +9,6 @@ import BusinessGlobalProvider from '@/business/client/BusinessGlobalProvider';
9
9
  import Analytics from '@/components/Analytics';
10
10
  import { DEFAULT_LANG } from '@/const/locale';
11
11
  import { isDesktop } from '@/const/version';
12
- import PWAInstall from '@/features/PWAInstall';
13
12
  import AuthProvider from '@/layout/AuthProvider';
14
13
  import GlobalProvider from '@/layout/GlobalProvider';
15
14
  import { type Locales } from '@/locales/resources';
@@ -40,9 +39,6 @@ const RootLayout = async ({ children, params }: RootLayoutProps) => {
40
39
  variants={variants}
41
40
  >
42
41
  <AuthProvider>{children}</AuthProvider>
43
- <Suspense fallback={null}>
44
- <PWAInstall />
45
- </Suspense>
46
42
  </GlobalProvider>
47
43
  );
48
44
  };