@lobehub/lobehub 2.0.0-next.5 → 2.0.0-next.51

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 (1468) hide show
  1. package/.env.desktop +1 -2
  2. package/.env.example +11 -3
  3. package/.env.example.development +0 -2
  4. package/.github/workflows/claude-auto-testing.yml +73 -0
  5. package/.github/workflows/claude-translate-comments.yml +67 -0
  6. package/.github/workflows/desktop-pr-build.yml +18 -16
  7. package/.github/workflows/docker.yml +25 -20
  8. package/.github/workflows/e2e.yml +17 -3
  9. package/.github/workflows/release-desktop-beta.yml +12 -12
  10. package/.github/workflows/release.yml +3 -5
  11. package/.github/workflows/test.yml +48 -12
  12. package/.nvmrc +1 -1
  13. package/CHANGELOG.md +1134 -0
  14. package/Dockerfile +1 -3
  15. package/README.md +3 -46
  16. package/README.zh-CN.md +3 -46
  17. package/apps/desktop/package.json +1 -1
  18. package/apps/desktop/src/main/controllers/AuthCtr.ts +78 -39
  19. package/apps/desktop/src/main/controllers/MenuCtr.ts +5 -5
  20. package/apps/desktop/src/main/controllers/NotificationCtr.ts +29 -29
  21. package/apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts +16 -16
  22. package/apps/desktop/src/main/controllers/ShellCommandCtr.ts +242 -0
  23. package/apps/desktop/src/main/controllers/ShortcutCtr.ts +2 -2
  24. package/apps/desktop/src/main/controllers/TrayMenuCtr.ts +18 -18
  25. package/apps/desktop/src/main/controllers/UpdaterCtr.ts +4 -4
  26. package/apps/desktop/src/main/controllers/__tests__/AuthCtr.test.ts +706 -0
  27. package/apps/desktop/src/main/controllers/__tests__/ShellCommandCtr.test.ts +499 -0
  28. package/apps/desktop/src/main/controllers/__tests__/TrayMenuCtr.test.ts +5 -5
  29. package/apps/desktop/src/main/controllers/index.ts +4 -4
  30. package/apps/desktop/src/main/core/infrastructure/ProtocolManager.ts +9 -4
  31. package/apps/desktop/src/main/core/infrastructure/UpdaterManager.ts +23 -2
  32. package/apps/desktop/src/main/modules/networkProxy/__tests__/dispatcher.test.ts +401 -0
  33. package/apps/desktop/src/main/modules/networkProxy/__tests__/tester.test.ts +531 -0
  34. package/apps/desktop/src/main/modules/networkProxy/__tests__/urlBuilder.test.ts +349 -0
  35. package/apps/desktop/src/main/modules/networkProxy/__tests__/validator.test.ts +492 -0
  36. package/apps/desktop/src/main/utils/next-electron-rsc.ts +7 -5
  37. package/apps/desktop/tsconfig.json +0 -1
  38. package/changelog/v1.json +388 -0
  39. package/docker-compose/local/.env.example +3 -0
  40. package/docs/development/database-schema.dbml +5 -1
  41. package/docs/self-hosting/advanced/auth/next-auth/auth0.mdx +2 -2
  42. package/docs/self-hosting/advanced/auth/next-auth/auth0.zh-CN.mdx +2 -2
  43. package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +2 -2
  44. package/docs/self-hosting/advanced/auth/next-auth/authelia.zh-CN.mdx +2 -2
  45. package/docs/self-hosting/advanced/auth/next-auth/authentik.mdx +2 -2
  46. package/docs/self-hosting/advanced/auth/next-auth/authentik.zh-CN.mdx +2 -2
  47. package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +2 -2
  48. package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +2 -2
  49. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.mdx +2 -2
  50. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.zh-CN.mdx +2 -2
  51. package/docs/self-hosting/advanced/auth/next-auth/github.mdx +2 -2
  52. package/docs/self-hosting/advanced/auth/next-auth/github.zh-CN.mdx +2 -2
  53. package/docs/self-hosting/advanced/auth/next-auth/google.mdx +32 -29
  54. package/docs/self-hosting/advanced/auth/next-auth/keycloak.mdx +2 -2
  55. package/docs/self-hosting/advanced/auth/next-auth/keycloak.zh-CN.mdx +2 -2
  56. package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +5 -3
  57. package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +5 -3
  58. package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.mdx +2 -2
  59. package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.zh-CN.mdx +2 -2
  60. package/docs/self-hosting/advanced/auth/next-auth/okta.mdx +2 -2
  61. package/docs/self-hosting/advanced/auth/next-auth/okta.zh-CN.mdx +2 -2
  62. package/docs/self-hosting/advanced/auth/next-auth/wechat.mdx +2 -2
  63. package/docs/self-hosting/advanced/auth/next-auth/wechat.zh-CN.mdx +2 -2
  64. package/docs/self-hosting/advanced/auth/next-auth/zitadel.mdx +2 -2
  65. package/docs/self-hosting/advanced/auth/next-auth/zitadel.zh-CN.mdx +2 -2
  66. package/docs/self-hosting/advanced/auth.mdx +32 -21
  67. package/docs/self-hosting/advanced/auth.zh-CN.mdx +30 -19
  68. package/docs/self-hosting/advanced/feature-flags.mdx +0 -1
  69. package/docs/self-hosting/advanced/feature-flags.zh-CN.mdx +0 -1
  70. package/docs/self-hosting/environment-variables/basic.mdx +49 -3
  71. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +49 -4
  72. package/docs/self-hosting/server-database/docker-compose.mdx +29 -0
  73. package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +29 -0
  74. package/e2e/src/features/discover/detail-pages.feature +95 -0
  75. package/e2e/src/features/discover/interactions.feature +113 -0
  76. package/e2e/src/features/discover/smoke.feature +34 -1
  77. package/e2e/src/steps/discover/detail-pages.steps.ts +295 -0
  78. package/e2e/src/steps/discover/interactions.steps.ts +451 -0
  79. package/e2e/src/steps/discover/smoke.steps.ts +116 -4
  80. package/e2e/tsconfig.json +0 -1
  81. package/locales/ar/auth.json +45 -1
  82. package/locales/ar/chat.json +22 -0
  83. package/locales/ar/common.json +1 -0
  84. package/locales/ar/components.json +6 -0
  85. package/locales/ar/discover.json +45 -0
  86. package/locales/ar/labs.json +4 -0
  87. package/locales/ar/marketAuth.json +42 -0
  88. package/locales/ar/modelProvider.json +13 -1
  89. package/locales/ar/models.json +6 -6
  90. package/locales/ar/oauth.json +1 -0
  91. package/locales/ar/plugin.json +1 -0
  92. package/locales/ar/setting.json +94 -1
  93. package/locales/ar/topic.json +1 -0
  94. package/locales/bg-BG/auth.json +45 -1
  95. package/locales/bg-BG/chat.json +22 -0
  96. package/locales/bg-BG/common.json +1 -0
  97. package/locales/bg-BG/components.json +6 -0
  98. package/locales/bg-BG/discover.json +45 -0
  99. package/locales/bg-BG/labs.json +4 -0
  100. package/locales/bg-BG/marketAuth.json +42 -0
  101. package/locales/bg-BG/modelProvider.json +13 -1
  102. package/locales/bg-BG/models.json +6 -6
  103. package/locales/bg-BG/oauth.json +1 -0
  104. package/locales/bg-BG/plugin.json +1 -0
  105. package/locales/bg-BG/setting.json +94 -1
  106. package/locales/bg-BG/topic.json +1 -0
  107. package/locales/de-DE/auth.json +45 -1
  108. package/locales/de-DE/chat.json +22 -0
  109. package/locales/de-DE/common.json +1 -0
  110. package/locales/de-DE/components.json +6 -0
  111. package/locales/de-DE/discover.json +45 -0
  112. package/locales/de-DE/labs.json +4 -0
  113. package/locales/de-DE/marketAuth.json +42 -0
  114. package/locales/de-DE/modelProvider.json +13 -1
  115. package/locales/de-DE/models.json +6 -6
  116. package/locales/de-DE/oauth.json +1 -0
  117. package/locales/de-DE/plugin.json +1 -0
  118. package/locales/de-DE/setting.json +94 -1
  119. package/locales/de-DE/topic.json +1 -0
  120. package/locales/en-US/auth.json +45 -1
  121. package/locales/en-US/chat.json +22 -0
  122. package/locales/en-US/common.json +1 -0
  123. package/locales/en-US/components.json +6 -0
  124. package/locales/en-US/discover.json +45 -0
  125. package/locales/en-US/labs.json +4 -0
  126. package/locales/en-US/marketAuth.json +42 -0
  127. package/locales/en-US/modelProvider.json +13 -1
  128. package/locales/en-US/models.json +6 -6
  129. package/locales/en-US/oauth.json +1 -0
  130. package/locales/en-US/plugin.json +1 -0
  131. package/locales/en-US/setting.json +94 -1
  132. package/locales/en-US/topic.json +1 -0
  133. package/locales/es-ES/auth.json +45 -1
  134. package/locales/es-ES/chat.json +22 -0
  135. package/locales/es-ES/common.json +1 -0
  136. package/locales/es-ES/components.json +6 -0
  137. package/locales/es-ES/discover.json +45 -0
  138. package/locales/es-ES/labs.json +4 -0
  139. package/locales/es-ES/marketAuth.json +42 -0
  140. package/locales/es-ES/modelProvider.json +13 -1
  141. package/locales/es-ES/models.json +6 -6
  142. package/locales/es-ES/oauth.json +1 -0
  143. package/locales/es-ES/plugin.json +1 -0
  144. package/locales/es-ES/setting.json +94 -1
  145. package/locales/es-ES/topic.json +1 -0
  146. package/locales/fa-IR/auth.json +45 -1
  147. package/locales/fa-IR/chat.json +22 -0
  148. package/locales/fa-IR/common.json +1 -0
  149. package/locales/fa-IR/components.json +6 -0
  150. package/locales/fa-IR/discover.json +45 -0
  151. package/locales/fa-IR/labs.json +4 -0
  152. package/locales/fa-IR/marketAuth.json +42 -0
  153. package/locales/fa-IR/modelProvider.json +13 -1
  154. package/locales/fa-IR/models.json +6 -6
  155. package/locales/fa-IR/oauth.json +1 -0
  156. package/locales/fa-IR/plugin.json +1 -0
  157. package/locales/fa-IR/setting.json +94 -1
  158. package/locales/fa-IR/topic.json +1 -0
  159. package/locales/fr-FR/auth.json +45 -1
  160. package/locales/fr-FR/chat.json +22 -0
  161. package/locales/fr-FR/common.json +1 -0
  162. package/locales/fr-FR/components.json +6 -0
  163. package/locales/fr-FR/discover.json +45 -0
  164. package/locales/fr-FR/labs.json +4 -0
  165. package/locales/fr-FR/marketAuth.json +42 -0
  166. package/locales/fr-FR/modelProvider.json +13 -1
  167. package/locales/fr-FR/models.json +6 -6
  168. package/locales/fr-FR/oauth.json +1 -0
  169. package/locales/fr-FR/plugin.json +1 -0
  170. package/locales/fr-FR/setting.json +94 -1
  171. package/locales/fr-FR/topic.json +1 -0
  172. package/locales/it-IT/auth.json +45 -1
  173. package/locales/it-IT/chat.json +22 -0
  174. package/locales/it-IT/common.json +1 -0
  175. package/locales/it-IT/components.json +6 -0
  176. package/locales/it-IT/discover.json +45 -0
  177. package/locales/it-IT/labs.json +4 -0
  178. package/locales/it-IT/marketAuth.json +42 -0
  179. package/locales/it-IT/modelProvider.json +13 -1
  180. package/locales/it-IT/models.json +6 -6
  181. package/locales/it-IT/oauth.json +1 -0
  182. package/locales/it-IT/plugin.json +1 -0
  183. package/locales/it-IT/setting.json +94 -1
  184. package/locales/it-IT/topic.json +1 -0
  185. package/locales/ja-JP/auth.json +45 -1
  186. package/locales/ja-JP/chat.json +22 -0
  187. package/locales/ja-JP/common.json +1 -0
  188. package/locales/ja-JP/components.json +6 -0
  189. package/locales/ja-JP/discover.json +45 -0
  190. package/locales/ja-JP/labs.json +4 -0
  191. package/locales/ja-JP/marketAuth.json +42 -0
  192. package/locales/ja-JP/modelProvider.json +13 -1
  193. package/locales/ja-JP/models.json +6 -6
  194. package/locales/ja-JP/oauth.json +1 -0
  195. package/locales/ja-JP/plugin.json +1 -0
  196. package/locales/ja-JP/setting.json +94 -1
  197. package/locales/ja-JP/topic.json +1 -0
  198. package/locales/ko-KR/auth.json +45 -1
  199. package/locales/ko-KR/chat.json +22 -0
  200. package/locales/ko-KR/common.json +1 -0
  201. package/locales/ko-KR/components.json +6 -0
  202. package/locales/ko-KR/discover.json +45 -0
  203. package/locales/ko-KR/labs.json +4 -0
  204. package/locales/ko-KR/marketAuth.json +42 -0
  205. package/locales/ko-KR/modelProvider.json +13 -1
  206. package/locales/ko-KR/models.json +12 -12
  207. package/locales/ko-KR/oauth.json +1 -0
  208. package/locales/ko-KR/plugin.json +1 -0
  209. package/locales/ko-KR/setting.json +94 -1
  210. package/locales/ko-KR/topic.json +1 -0
  211. package/locales/nl-NL/auth.json +45 -1
  212. package/locales/nl-NL/chat.json +22 -0
  213. package/locales/nl-NL/common.json +1 -0
  214. package/locales/nl-NL/components.json +6 -0
  215. package/locales/nl-NL/discover.json +45 -0
  216. package/locales/nl-NL/labs.json +4 -0
  217. package/locales/nl-NL/marketAuth.json +42 -0
  218. package/locales/nl-NL/modelProvider.json +13 -1
  219. package/locales/nl-NL/models.json +6 -6
  220. package/locales/nl-NL/oauth.json +1 -0
  221. package/locales/nl-NL/plugin.json +1 -0
  222. package/locales/nl-NL/setting.json +94 -1
  223. package/locales/nl-NL/topic.json +1 -0
  224. package/locales/pl-PL/auth.json +45 -1
  225. package/locales/pl-PL/chat.json +22 -0
  226. package/locales/pl-PL/common.json +1 -0
  227. package/locales/pl-PL/components.json +6 -0
  228. package/locales/pl-PL/discover.json +45 -0
  229. package/locales/pl-PL/labs.json +4 -0
  230. package/locales/pl-PL/marketAuth.json +42 -0
  231. package/locales/pl-PL/modelProvider.json +13 -1
  232. package/locales/pl-PL/models.json +6 -6
  233. package/locales/pl-PL/oauth.json +1 -0
  234. package/locales/pl-PL/plugin.json +1 -0
  235. package/locales/pl-PL/setting.json +94 -1
  236. package/locales/pl-PL/topic.json +1 -0
  237. package/locales/pt-BR/auth.json +45 -1
  238. package/locales/pt-BR/chat.json +22 -0
  239. package/locales/pt-BR/common.json +1 -0
  240. package/locales/pt-BR/components.json +6 -0
  241. package/locales/pt-BR/discover.json +45 -0
  242. package/locales/pt-BR/labs.json +4 -0
  243. package/locales/pt-BR/marketAuth.json +42 -0
  244. package/locales/pt-BR/modelProvider.json +13 -1
  245. package/locales/pt-BR/models.json +6 -6
  246. package/locales/pt-BR/oauth.json +1 -0
  247. package/locales/pt-BR/plugin.json +1 -0
  248. package/locales/pt-BR/setting.json +94 -1
  249. package/locales/pt-BR/topic.json +1 -0
  250. package/locales/ru-RU/auth.json +45 -1
  251. package/locales/ru-RU/chat.json +22 -0
  252. package/locales/ru-RU/common.json +1 -0
  253. package/locales/ru-RU/components.json +6 -0
  254. package/locales/ru-RU/discover.json +45 -0
  255. package/locales/ru-RU/labs.json +4 -0
  256. package/locales/ru-RU/marketAuth.json +42 -0
  257. package/locales/ru-RU/modelProvider.json +13 -1
  258. package/locales/ru-RU/models.json +6 -6
  259. package/locales/ru-RU/oauth.json +1 -0
  260. package/locales/ru-RU/plugin.json +1 -0
  261. package/locales/ru-RU/setting.json +94 -1
  262. package/locales/ru-RU/topic.json +1 -0
  263. package/locales/tr-TR/auth.json +45 -1
  264. package/locales/tr-TR/chat.json +22 -0
  265. package/locales/tr-TR/common.json +1 -0
  266. package/locales/tr-TR/components.json +6 -0
  267. package/locales/tr-TR/discover.json +45 -0
  268. package/locales/tr-TR/labs.json +4 -0
  269. package/locales/tr-TR/marketAuth.json +42 -0
  270. package/locales/tr-TR/modelProvider.json +13 -1
  271. package/locales/tr-TR/models.json +6 -6
  272. package/locales/tr-TR/oauth.json +1 -0
  273. package/locales/tr-TR/plugin.json +1 -0
  274. package/locales/tr-TR/setting.json +94 -1
  275. package/locales/tr-TR/topic.json +1 -0
  276. package/locales/vi-VN/auth.json +45 -1
  277. package/locales/vi-VN/chat.json +22 -0
  278. package/locales/vi-VN/common.json +1 -0
  279. package/locales/vi-VN/components.json +6 -0
  280. package/locales/vi-VN/discover.json +45 -0
  281. package/locales/vi-VN/labs.json +4 -0
  282. package/locales/vi-VN/marketAuth.json +42 -0
  283. package/locales/vi-VN/modelProvider.json +13 -1
  284. package/locales/vi-VN/models.json +6 -6
  285. package/locales/vi-VN/oauth.json +1 -0
  286. package/locales/vi-VN/plugin.json +1 -0
  287. package/locales/vi-VN/setting.json +94 -1
  288. package/locales/vi-VN/topic.json +1 -0
  289. package/locales/zh-CN/auth.json +45 -1
  290. package/locales/zh-CN/chat.json +22 -0
  291. package/locales/zh-CN/common.json +1 -0
  292. package/locales/zh-CN/components.json +6 -0
  293. package/locales/zh-CN/discover.json +45 -0
  294. package/locales/zh-CN/labs.json +4 -0
  295. package/locales/zh-CN/marketAuth.json +42 -0
  296. package/locales/zh-CN/modelProvider.json +13 -1
  297. package/locales/zh-CN/models.json +6 -6
  298. package/locales/zh-CN/oauth.json +1 -0
  299. package/locales/zh-CN/plugin.json +1 -0
  300. package/locales/zh-CN/setting.json +94 -1
  301. package/locales/zh-CN/topic.json +1 -0
  302. package/locales/zh-TW/auth.json +45 -1
  303. package/locales/zh-TW/chat.json +22 -0
  304. package/locales/zh-TW/common.json +1 -0
  305. package/locales/zh-TW/components.json +6 -0
  306. package/locales/zh-TW/discover.json +45 -0
  307. package/locales/zh-TW/labs.json +4 -0
  308. package/locales/zh-TW/marketAuth.json +42 -0
  309. package/locales/zh-TW/modelProvider.json +13 -1
  310. package/locales/zh-TW/models.json +6 -6
  311. package/locales/zh-TW/oauth.json +1 -0
  312. package/locales/zh-TW/plugin.json +1 -0
  313. package/locales/zh-TW/setting.json +94 -1
  314. package/locales/zh-TW/topic.json +1 -0
  315. package/next.config.ts +7 -9
  316. package/package.json +84 -83
  317. package/packages/agent-runtime/src/core/InterventionChecker.ts +5 -16
  318. package/packages/agent-runtime/src/core/__tests__/InterventionChecker.test.ts +27 -80
  319. package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +141 -87
  320. package/packages/agent-runtime/src/core/runtime.ts +68 -19
  321. package/packages/agent-runtime/src/types/event.ts +2 -1
  322. package/packages/agent-runtime/src/types/generalAgent.ts +56 -0
  323. package/packages/agent-runtime/src/types/index.ts +1 -0
  324. package/packages/agent-runtime/src/types/instruction.ts +13 -5
  325. package/packages/agent-runtime/src/types/state.ts +9 -1
  326. package/packages/const/src/hotkeys.ts +3 -3
  327. package/packages/const/src/index.ts +0 -1
  328. package/packages/const/src/models.ts +2 -2
  329. package/packages/const/src/settings/tool.ts +1 -5
  330. package/packages/const/src/url.ts +2 -4
  331. package/packages/const/src/user.ts +4 -2
  332. package/packages/const/src/utils/merge.ts +3 -3
  333. package/packages/const/src/version.ts +3 -3
  334. package/packages/context-engine/src/base/BaseProcessor.ts +13 -13
  335. package/packages/context-engine/src/base/BaseProvider.ts +2 -2
  336. package/packages/context-engine/src/base/__tests__/BaseProcessor.test.ts +5 -5
  337. package/packages/context-engine/src/index.ts +1 -6
  338. package/packages/context-engine/src/processors/GroupMessageFlatten.ts +20 -8
  339. package/packages/context-engine/src/processors/MessageCleanup.ts +7 -6
  340. package/packages/context-engine/src/processors/MessageContent.ts +17 -17
  341. package/packages/context-engine/src/processors/PlaceholderVariables.ts +4 -4
  342. package/packages/context-engine/src/processors/ToolCall.ts +18 -18
  343. package/packages/context-engine/src/processors/ToolMessageReorder.ts +10 -10
  344. package/packages/context-engine/src/processors/__tests__/GroupMessageFlatten.test.ts +83 -19
  345. package/packages/context-engine/src/processors/__tests__/MessageCleanup.test.ts +28 -0
  346. package/packages/context-engine/src/providers/HistorySummary.ts +6 -6
  347. package/packages/context-engine/src/providers/ToolSystemRole.ts +7 -7
  348. package/packages/context-engine/src/providers/index.ts +0 -2
  349. package/packages/context-engine/src/tools/ToolsEngine.ts +8 -8
  350. package/packages/context-engine/src/types.ts +35 -35
  351. package/packages/conversation-flow/package.json +13 -0
  352. package/packages/conversation-flow/src/__tests__/fixtures/index.ts +48 -0
  353. package/packages/conversation-flow/src/__tests__/fixtures/inputs/assistant-chain-with-followup.json +56 -0
  354. package/packages/conversation-flow/src/__tests__/fixtures/inputs/assistant-with-tools.json +144 -0
  355. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/active-index-1.json +131 -0
  356. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-branch.json +96 -0
  357. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-group-branches.json +249 -0
  358. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/assistant-user-branch.json +123 -0
  359. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/conversation.json +128 -0
  360. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/index.ts +18 -0
  361. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/multi-assistant-group.json +260 -0
  362. package/packages/conversation-flow/src/__tests__/fixtures/inputs/branch/nested.json +179 -0
  363. package/packages/conversation-flow/src/__tests__/fixtures/inputs/compare/index.ts +8 -0
  364. package/packages/conversation-flow/src/__tests__/fixtures/inputs/compare/simple.json +85 -0
  365. package/packages/conversation-flow/src/__tests__/fixtures/inputs/compare/with-tools.json +169 -0
  366. package/packages/conversation-flow/src/__tests__/fixtures/inputs/complex-scenario.json +107 -0
  367. package/packages/conversation-flow/src/__tests__/fixtures/inputs/index.ts +14 -0
  368. package/packages/conversation-flow/src/__tests__/fixtures/inputs/linear-conversation.json +59 -0
  369. package/packages/conversation-flow/src/__tests__/fixtures/outputs/assistant-chain-with-followup.json +135 -0
  370. package/packages/conversation-flow/src/__tests__/fixtures/outputs/assistant-with-tools.json +340 -0
  371. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/active-index-1.json +246 -0
  372. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/assistant-branch.json +208 -0
  373. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/assistant-group-branches.json +481 -0
  374. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/assistant-user-branch.json +254 -0
  375. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/conversation.json +264 -0
  376. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/index.ts +18 -0
  377. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/multi-assistant-group.json +407 -0
  378. package/packages/conversation-flow/src/__tests__/fixtures/outputs/branch/nested.json +405 -0
  379. package/packages/conversation-flow/src/__tests__/fixtures/outputs/compare/index.ts +8 -0
  380. package/packages/conversation-flow/src/__tests__/fixtures/outputs/compare/simple.json +224 -0
  381. package/packages/conversation-flow/src/__tests__/fixtures/outputs/compare/with-tools.json +418 -0
  382. package/packages/conversation-flow/src/__tests__/fixtures/outputs/complex-scenario.json +261 -0
  383. package/packages/conversation-flow/src/__tests__/fixtures/outputs/linear-conversation.json +138 -0
  384. package/packages/conversation-flow/src/__tests__/parse.test.ts +132 -0
  385. package/packages/conversation-flow/src/index.ts +17 -0
  386. package/packages/conversation-flow/src/indexing.ts +58 -0
  387. package/packages/conversation-flow/src/parse.ts +53 -0
  388. package/packages/conversation-flow/src/structuring.ts +38 -0
  389. package/packages/conversation-flow/src/transformation/BranchResolver.ts +66 -0
  390. package/packages/conversation-flow/src/transformation/ContextTreeBuilder.ts +292 -0
  391. package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +502 -0
  392. package/packages/conversation-flow/src/transformation/MessageCollector.ts +166 -0
  393. package/packages/conversation-flow/src/transformation/MessageTransformer.ts +177 -0
  394. package/packages/conversation-flow/src/transformation/__tests__/BranchResolver.test.ts +151 -0
  395. package/packages/conversation-flow/src/transformation/__tests__/ContextTreeBuilder.test.ts +385 -0
  396. package/packages/conversation-flow/src/transformation/__tests__/FlatListBuilder.test.ts +511 -0
  397. package/packages/conversation-flow/src/transformation/__tests__/MessageCollector.test.ts +220 -0
  398. package/packages/conversation-flow/src/transformation/__tests__/MessageTransformer.test.ts +287 -0
  399. package/packages/conversation-flow/src/transformation/index.ts +78 -0
  400. package/packages/conversation-flow/src/types/contextTree.ts +65 -0
  401. package/packages/conversation-flow/src/types/flatMessageList.ts +54 -0
  402. package/packages/conversation-flow/src/types/index.ts +25 -0
  403. package/packages/conversation-flow/src/types/shared.ts +63 -0
  404. package/packages/conversation-flow/vitest.config.mts +10 -0
  405. package/packages/database/migrations/0042_improve_agent_index.sql +1 -0
  406. package/packages/database/migrations/0043_add_ai_model_settings.sql +1 -0
  407. package/packages/database/migrations/0044_add_tool_intervention.sql +1 -0
  408. package/packages/database/migrations/0044_high_toxin.sql +1 -0
  409. package/packages/database/migrations/0045_add_tool_intervention.sql +1 -0
  410. package/packages/database/migrations/meta/0039_snapshot.json +1 -1
  411. package/packages/database/migrations/meta/0042_snapshot.json +7800 -0
  412. package/packages/database/migrations/meta/0043_snapshot.json +8419 -0
  413. package/packages/database/migrations/meta/0044_snapshot.json +7813 -0
  414. package/packages/database/migrations/meta/0045_snapshot.json +8431 -0
  415. package/packages/database/migrations/meta/_journal.json +28 -0
  416. package/packages/database/package.json +2 -2
  417. package/packages/database/src/core/migrations.json +52 -7
  418. package/packages/database/src/core/web-server.ts +2 -1
  419. package/packages/database/src/models/__tests__/apiKey.test.ts +444 -0
  420. package/packages/database/src/models/__tests__/messages/message.create.test.ts +549 -0
  421. package/packages/database/src/models/__tests__/messages/message.delete.test.ts +481 -0
  422. package/packages/database/src/models/__tests__/messages/message.query.test.ts +1187 -0
  423. package/packages/database/src/models/__tests__/messages/message.stats.test.ts +633 -0
  424. package/packages/database/src/models/__tests__/messages/message.update.test.ts +757 -0
  425. package/packages/database/src/models/agent.ts +16 -13
  426. package/packages/database/src/models/file.ts +15 -1
  427. package/packages/database/src/models/message.ts +47 -81
  428. package/packages/database/src/models/session.ts +62 -10
  429. package/packages/database/src/models/user.ts +2 -1
  430. package/packages/database/src/repositories/aiInfra/index.test.ts +199 -1
  431. package/packages/database/src/repositories/aiInfra/index.ts +2 -1
  432. package/packages/database/src/repositories/dataExporter/index.test.ts +1 -1
  433. package/packages/database/src/repositories/dataImporter/deprecated/__tests__/index.test.ts +2 -1
  434. package/packages/database/src/repositories/dataImporter/deprecated/index.ts +7 -1
  435. package/packages/database/src/repositories/tableViewer/index.test.ts +1 -1
  436. package/packages/database/src/schemas/agent.ts +5 -1
  437. package/packages/database/src/schemas/aiInfra.ts +2 -0
  438. package/packages/database/src/schemas/message.ts +5 -8
  439. package/packages/electron-client-ipc/package.json +4 -1
  440. package/packages/electron-client-ipc/src/events/index.ts +6 -1
  441. package/packages/electron-client-ipc/src/events/remoteServer.ts +8 -0
  442. package/packages/fetch-sse/package.json +29 -0
  443. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/fetchSSE.test.ts +4 -4
  444. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/parseError.test.ts +7 -4
  445. package/packages/{utils/src/fetch → fetch-sse/src}/fetchSSE.ts +17 -17
  446. package/packages/{utils/src/fetch → fetch-sse/src}/headers.ts +3 -3
  447. package/packages/{utils/src/fetch → fetch-sse/src}/parseError.ts +3 -3
  448. package/packages/{utils/src/fetch → fetch-sse/src}/request.ts +5 -5
  449. package/packages/file-loaders/package.json +1 -0
  450. package/packages/file-loaders/src/loaders/docx/index.ts +1 -1
  451. package/packages/memory-extract/package.json +2 -2
  452. package/packages/model-bank/src/aiModels/google.ts +1 -1
  453. package/packages/model-bank/src/aiModels/mistral.ts +2 -1
  454. package/packages/model-bank/src/aiModels/wenxin.ts +1348 -291
  455. package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +17 -11
  456. package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +1 -1
  457. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +1 -1
  458. package/packages/model-runtime/src/core/contextBuilders/google.ts +3 -6
  459. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +33 -7
  460. package/packages/model-runtime/src/core/contextBuilders/openai.ts +18 -4
  461. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.test.ts +1 -1
  462. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
  463. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +3 -6
  464. package/packages/model-runtime/src/core/streams/openai/responsesStream.test.ts +1 -1
  465. package/packages/model-runtime/src/helpers/mergeChatMethodOptions.ts +2 -1
  466. package/packages/model-runtime/src/providers/aihubmix/index.test.ts +1 -1
  467. package/packages/model-runtime/src/providers/anthropic/generateObject.test.ts +1 -1
  468. package/packages/model-runtime/src/providers/anthropic/index.test.ts +1 -1
  469. package/packages/model-runtime/src/providers/azureai/index.ts +34 -2
  470. package/packages/model-runtime/src/providers/baichuan/index.test.ts +1 -1
  471. package/packages/model-runtime/src/providers/bedrock/index.test.ts +1 -1
  472. package/packages/model-runtime/src/providers/bfl/createImage.test.ts +4 -4
  473. package/packages/model-runtime/src/providers/bfl/createImage.ts +1 -1
  474. package/packages/model-runtime/src/providers/cloudflare/index.test.ts +1 -1
  475. package/packages/model-runtime/src/providers/cohere/index.test.ts +1 -1
  476. package/packages/model-runtime/src/providers/google/createImage.test.ts +2 -2
  477. package/packages/model-runtime/src/providers/google/createImage.ts +1 -1
  478. package/packages/model-runtime/src/providers/google/generateObject.test.ts +1 -1
  479. package/packages/model-runtime/src/providers/google/index.test.ts +1 -4
  480. package/packages/model-runtime/src/providers/groq/index.test.ts +1 -1
  481. package/packages/model-runtime/src/providers/hunyuan/index.test.ts +1 -1
  482. package/packages/model-runtime/src/providers/minimax/createImage.test.ts +1 -1
  483. package/packages/model-runtime/src/providers/mistral/index.test.ts +1 -1
  484. package/packages/model-runtime/src/providers/moonshot/index.test.ts +1 -1
  485. package/packages/model-runtime/src/providers/novita/index.test.ts +1 -1
  486. package/packages/model-runtime/src/providers/ollama/index.test.ts +43 -32
  487. package/packages/model-runtime/src/providers/ollama/index.ts +31 -7
  488. package/packages/model-runtime/src/providers/openrouter/index.test.ts +1 -1
  489. package/packages/model-runtime/src/providers/perplexity/index.test.ts +1 -1
  490. package/packages/model-runtime/src/providers/ppio/index.test.ts +1 -1
  491. package/packages/model-runtime/src/providers/qwen/createImage.test.ts +1 -1
  492. package/packages/model-runtime/src/providers/search1api/index.test.ts +1 -1
  493. package/packages/model-runtime/src/providers/siliconcloud/createImage.ts +1 -1
  494. package/packages/model-runtime/src/providers/taichu/index.test.ts +1 -1
  495. package/packages/model-runtime/src/providers/wenxin/index.test.ts +1 -1
  496. package/packages/model-runtime/src/providers/wenxin/index.ts +22 -1
  497. package/packages/model-runtime/src/providers/zhipu/index.test.ts +1 -1
  498. package/packages/model-runtime/src/types/chat.ts +4 -0
  499. package/packages/model-runtime/src/utils/errorResponse.test.ts +1 -1
  500. package/packages/model-runtime/src/utils/googleErrorParser.test.ts +125 -0
  501. package/packages/model-runtime/src/utils/googleErrorParser.ts +103 -77
  502. package/packages/model-runtime/src/utils/modelParse.ts +6 -0
  503. package/packages/obervability-otel/package.json +4 -4
  504. package/packages/obervability-otel/src/api.ts +2 -0
  505. package/packages/obervability-otel/src/node.ts +17 -7
  506. package/packages/obervability-otel/src/trpc/convention.ts +16 -0
  507. package/packages/obervability-otel/src/trpc/index.test.ts +38 -0
  508. package/packages/obervability-otel/src/trpc/index.ts +62 -0
  509. package/packages/obervability-otel/src/trpc/metrics.ts +31 -0
  510. package/packages/ssrf-safe-fetch/index.browser.ts +14 -0
  511. package/packages/ssrf-safe-fetch/package.json +8 -1
  512. package/packages/types/src/aiChat.ts +2 -0
  513. package/packages/types/src/aiProvider.ts +1 -1
  514. package/packages/types/src/discover/assistants.ts +16 -0
  515. package/packages/types/src/discover/mcp.ts +6 -0
  516. package/packages/types/src/document/index.ts +38 -38
  517. package/packages/types/src/exportConfig.ts +15 -15
  518. package/packages/types/src/generation/index.ts +5 -5
  519. package/packages/types/src/importer.ts +2 -2
  520. package/packages/types/src/index.ts +1 -1
  521. package/packages/types/src/message/common/base.ts +14 -1
  522. package/packages/types/src/message/common/image.ts +8 -0
  523. package/packages/types/src/message/common/metadata.ts +44 -1
  524. package/packages/types/src/message/common/tools.ts +26 -0
  525. package/packages/types/src/message/db/item.ts +15 -1
  526. package/packages/types/src/message/db/params.ts +47 -1
  527. package/packages/types/src/message/ui/chat.ts +28 -3
  528. package/packages/types/src/message/ui/extra.ts +2 -2
  529. package/packages/types/src/message/ui/params.ts +66 -7
  530. package/packages/types/src/meta.ts +4 -0
  531. package/packages/types/src/openai/chat.ts +15 -15
  532. package/packages/types/src/plugins/mcp.ts +33 -30
  533. package/packages/types/src/plugins/protocol.ts +43 -43
  534. package/packages/types/src/search.ts +20 -4
  535. package/packages/types/src/serverConfig.ts +2 -6
  536. package/packages/types/src/session/agentSession.ts +2 -0
  537. package/packages/types/src/tool/builtin.ts +9 -0
  538. package/packages/types/src/tool/intervention.ts +32 -3
  539. package/packages/types/src/tool/plugin.ts +3 -3
  540. package/packages/types/src/topic/topic.ts +14 -0
  541. package/packages/types/src/usage/usageRecord.ts +54 -0
  542. package/packages/types/src/user/index.ts +2 -76
  543. package/packages/types/src/user/preference.ts +101 -0
  544. package/packages/types/src/user/settings/index.ts +22 -0
  545. package/packages/types/src/user/settings/tool.ts +2 -39
  546. package/packages/utils/src/apiKey.test.ts +139 -0
  547. package/packages/utils/src/client/clipboard.ts +2 -2
  548. package/packages/utils/src/client/exportFile.ts +10 -10
  549. package/packages/utils/src/client/parserPlaceholder.ts +18 -18
  550. package/packages/utils/src/client/topic.ts +10 -10
  551. package/packages/utils/src/client/xor-obfuscation.ts +11 -11
  552. package/packages/utils/src/clientIP.ts +6 -6
  553. package/packages/utils/src/compass.ts +11 -11
  554. package/packages/utils/src/compressImage.ts +3 -3
  555. package/packages/utils/src/format.ts +2 -2
  556. package/packages/utils/src/imageToBase64.ts +17 -10
  557. package/packages/utils/src/index.ts +1 -1
  558. package/packages/utils/src/merge.ts +3 -3
  559. package/packages/utils/src/object.ts +3 -3
  560. package/packages/utils/src/sanitizeUTF8.ts +4 -4
  561. package/packages/utils/src/server/__tests__/response.test.ts +79 -0
  562. package/packages/utils/src/server/auth.ts +6 -6
  563. package/packages/utils/src/server/geo.ts +9 -9
  564. package/packages/utils/src/server/index.ts +1 -0
  565. package/packages/utils/src/server/response.ts +110 -0
  566. package/packages/utils/src/server/validateRedirectHost.test.ts +352 -0
  567. package/packages/utils/src/server/xor.ts +7 -7
  568. package/packages/utils/src/tokenizer/index.ts +3 -11
  569. package/packages/utils/src/toolManifest.ts +4 -4
  570. package/packages/utils/src/trace.test.ts +359 -0
  571. package/packages/utils/src/uriParser.ts +4 -4
  572. package/packages/web-crawler/src/crawImpl/browserless.ts +1 -1
  573. package/packages/web-crawler/src/crawImpl/naive.ts +9 -9
  574. package/packages/web-crawler/src/crawler.ts +5 -5
  575. package/packages/web-crawler/src/urlRules.ts +13 -13
  576. package/packages/web-crawler/src/utils/appUrlRules.ts +5 -5
  577. package/packages/web-crawler/tsconfig.json +0 -1
  578. package/renovate.json +40 -1
  579. package/scripts/migrateServerDB/errorHint.js +1 -7
  580. package/src/app/(backend)/f/[id]/route.ts +55 -0
  581. package/src/app/(backend)/market/agent/[[...segments]]/route.ts +153 -0
  582. package/src/app/(backend)/market/oidc/[[...segments]]/route.ts +207 -0
  583. package/src/app/(backend)/webapi/revalidate/route.ts +1 -1
  584. package/src/app/(backend)/webapi/stt/openai/route.ts +0 -2
  585. package/src/app/(backend)/webapi/tts/edge/route.ts +8 -2
  586. package/src/app/(backend)/webapi/tts/microsoft/route.ts +8 -2
  587. package/src/app/(backend)/webapi/tts/openai/route.ts +15 -3
  588. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -8
  589. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +9 -0
  590. package/src/app/[variants]/(main)/(mobile)/me/(home)/features/UserBanner.tsx +3 -6
  591. package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +0 -2
  592. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +1 -0
  593. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/PinList/index.tsx +4 -2
  594. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +1 -4
  595. package/src/app/[variants]/(main)/chat/ChatRouter.tsx +83 -0
  596. package/src/app/[variants]/(main)/chat/_layout/ChatLayout.tsx +22 -0
  597. package/src/app/[variants]/(main)/chat/_layout/Desktop/SessionPanel.tsx +12 -7
  598. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +2 -4
  599. package/src/app/[variants]/(main)/chat/_layout/FeatureFlagsProvider.tsx +24 -0
  600. package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +4 -7
  601. package/src/app/[variants]/(main)/chat/_layout/type.ts +0 -1
  602. package/src/app/[variants]/(main)/chat/components/ConversationArea.tsx +29 -0
  603. package/src/app/[variants]/(main)/chat/components/MainChatPage.tsx +25 -0
  604. package/src/app/[variants]/(main)/chat/components/PortalPanel.tsx +28 -0
  605. package/src/app/[variants]/(main)/chat/components/SessionPanel.tsx +33 -0
  606. package/src/app/[variants]/(main)/chat/{settings/page.tsx → components/SettingsPage.tsx} +35 -3
  607. package/src/app/[variants]/(main)/chat/components/TopicSidebar.tsx +30 -0
  608. package/src/app/[variants]/(main)/chat/components/WorkspaceLayout.tsx +73 -0
  609. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/MessageFromUrl.tsx +3 -3
  610. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/index.tsx +3 -3
  611. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/useSend.ts +9 -7
  612. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/useSend.ts +21 -16
  613. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/Thread.tsx +1 -1
  614. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/index.tsx +9 -16
  615. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/Content.tsx +5 -3
  616. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/OpeningQuestions.tsx +2 -2
  617. package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/GroupUsageSuggest.tsx +2 -2
  618. package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/TopicContent.tsx +1 -1
  619. package/src/app/[variants]/(main)/chat/{layout.ts → layout.tsx} +0 -1
  620. package/src/app/[variants]/(main)/chat/page.tsx +12 -0
  621. package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/Item/Actions.tsx +4 -29
  622. package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/Item/index.tsx +7 -6
  623. package/src/app/[variants]/(main)/chat/settings/features/AgentInfoDescription/index.tsx +349 -0
  624. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +3 -63
  625. package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +64 -0
  626. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +196 -0
  627. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishModal.tsx +358 -0
  628. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/index.tsx +75 -0
  629. package/src/app/[variants]/(main)/discover/(detail)/assistant/AssistantDetailPage.tsx +11 -2
  630. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +12 -1
  631. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Nav.tsx +19 -12
  632. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/TagList.tsx +14 -5
  633. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/index.tsx +2 -0
  634. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Related/index.tsx +14 -5
  635. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/TagList.tsx +14 -5
  636. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/index.tsx +43 -29
  637. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Versions/index.tsx +137 -0
  638. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/index.tsx +2 -0
  639. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Header.tsx +9 -10
  640. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/ActionButton/AddAgent.tsx +105 -14
  641. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/Related/index.tsx +20 -6
  642. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/StatusPage/index.tsx +113 -0
  643. package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +4 -3
  644. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +3 -1
  645. package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantPage.tsx +4 -1
  646. package/src/app/[variants]/(main)/discover/(list)/assistant/Client.tsx +6 -2
  647. package/src/app/[variants]/(main)/discover/(list)/assistant/features/Category/index.tsx +7 -3
  648. package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +13 -2
  649. package/src/app/[variants]/(main)/discover/(list)/assistant/features/MarketSourceSwitch.tsx +64 -0
  650. package/src/app/[variants]/(main)/discover/(list)/features/Pagination.tsx +1 -0
  651. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +27 -8
  652. package/src/app/[variants]/(main)/discover/(list)/mcp/features/List/Item.tsx +1 -0
  653. package/src/app/[variants]/(main)/discover/(list)/model/features/List/Item.tsx +1 -0
  654. package/src/app/[variants]/(main)/discover/(list)/provider/features/List/Item.tsx +1 -0
  655. package/src/app/[variants]/(main)/discover/components/CategoryMenu.tsx +9 -1
  656. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicList.tsx +1 -0
  657. package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +1 -1
  658. package/src/app/[variants]/(main)/image/page.tsx +0 -2
  659. package/src/app/[variants]/(main)/labs/components/LabCard.tsx +8 -6
  660. package/src/app/[variants]/(main)/labs/page.tsx +10 -22
  661. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +18 -19
  662. package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +5 -9
  663. package/src/app/[variants]/(main)/profile/hooks/useCategory.tsx +10 -1
  664. package/src/app/[variants]/(main)/profile/usage/Client.tsx +114 -0
  665. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/ModelTable.tsx +175 -0
  666. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/ActiveModels/index.tsx +126 -0
  667. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/MonthSpend.tsx +53 -0
  668. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/TodaySpend.tsx +67 -0
  669. package/src/app/[variants]/(main)/profile/usage/features/UsageCards/index.tsx +19 -0
  670. package/src/app/[variants]/(main)/profile/usage/features/UsageTable.tsx +145 -0
  671. package/src/app/[variants]/(main)/profile/usage/features/UsageTrends.tsx +107 -0
  672. package/src/app/[variants]/(main)/profile/usage/features/components/UsageBarChart.tsx +48 -0
  673. package/src/app/[variants]/(main)/{(mobile)/me/data → profile/usage}/page.tsx +6 -12
  674. package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +0 -2
  675. package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +0 -2
  676. package/src/app/[variants]/(main)/settings/_layout/type.ts +1 -1
  677. package/src/app/[variants]/(main)/settings/agent/index.tsx +11 -10
  678. package/src/app/[variants]/(main)/settings/common/index.tsx +1 -1
  679. package/src/app/[variants]/(main)/settings/page.tsx +13 -10
  680. package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +1 -1
  681. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +35 -36
  682. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/List.tsx +97 -7
  683. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/SearchResult.tsx +5 -5
  684. package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/Container.tsx +10 -4
  685. package/src/app/[variants]/(main)/settings/provider/detail/azure/index.tsx +6 -8
  686. package/src/app/[variants]/(main)/settings/provider/detail/azureai/index.tsx +1 -1
  687. package/src/app/[variants]/(main)/settings/provider/detail/bedrock/index.tsx +1 -1
  688. package/src/app/[variants]/(main)/settings/provider/detail/cloudflare/index.tsx +1 -1
  689. package/src/app/[variants]/(main)/settings/provider/detail/comfyui/index.tsx +1 -1
  690. package/src/app/[variants]/(main)/settings/provider/detail/github/index.tsx +1 -1
  691. package/src/app/[variants]/(main)/settings/provider/detail/vertexai/index.tsx +1 -1
  692. package/src/app/[variants]/(main)/settings/provider/features/ModelList/DisabledModels.tsx +144 -8
  693. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +2 -4
  694. package/src/app/[variants]/layout.tsx +1 -0
  695. package/src/app/[variants]/loading/index.tsx +1 -10
  696. package/src/app/[variants]/oauth/ResultLayout.tsx +47 -0
  697. package/src/app/[variants]/oauth/callback/error/page.tsx +20 -33
  698. package/src/app/[variants]/oauth/callback/layout.tsx +1 -0
  699. package/src/app/[variants]/oauth/callback/success/page.tsx +8 -22
  700. package/src/app/[variants]/oauth/consent/[uid]/Consent/BuiltinConsent.tsx +47 -0
  701. package/src/app/[variants]/oauth/consent/[uid]/{Consent.tsx → Consent/index.tsx} +12 -3
  702. package/src/app/[variants]/oauth/consent/[uid]/Login.tsx +19 -4
  703. package/src/app/market-auth-callback/layout.tsx +15 -0
  704. package/src/app/market-auth-callback/page.tsx +196 -0
  705. package/src/app/sitemap.tsx +7 -1
  706. package/src/components/InvalidAPIKey/APIKeyForm/Bedrock.tsx +8 -13
  707. package/src/components/Link.tsx +12 -0
  708. package/src/components/Skeleton/SkeletonSwitch.tsx +13 -0
  709. package/src/components/Skeleton/index.ts +2 -0
  710. package/src/components/Thinking/index.tsx +4 -3
  711. package/src/config/db.ts +0 -5
  712. package/src/config/featureFlags/schema.test.ts +0 -2
  713. package/src/config/featureFlags/schema.ts +0 -6
  714. package/src/config/modelProviders/ai21.ts +1 -16
  715. package/src/config/modelProviders/ai302.ts +1 -128
  716. package/src/config/modelProviders/ai360.ts +1 -32
  717. package/src/config/modelProviders/anthropic.ts +1 -71
  718. package/src/config/modelProviders/azure.ts +1 -51
  719. package/src/config/modelProviders/baichuan.ts +1 -57
  720. package/src/config/modelProviders/bedrock.ts +1 -276
  721. package/src/config/modelProviders/cloudflare.ts +1 -64
  722. package/src/config/modelProviders/deepseek.ts +1 -19
  723. package/src/config/modelProviders/fireworksai.ts +1 -174
  724. package/src/config/modelProviders/giteeai.ts +1 -135
  725. package/src/config/modelProviders/github.ts +1 -254
  726. package/src/config/modelProviders/google.ts +1 -130
  727. package/src/config/modelProviders/groq.ts +1 -119
  728. package/src/config/modelProviders/higress.ts +1 -1713
  729. package/src/config/modelProviders/huggingface.ts +1 -54
  730. package/src/config/modelProviders/hunyuan.ts +1 -83
  731. package/src/config/modelProviders/infiniai.ts +1 -74
  732. package/src/config/modelProviders/internlm.ts +1 -20
  733. package/src/config/modelProviders/mistral.ts +1 -95
  734. package/src/config/modelProviders/modelscope.ts +1 -27
  735. package/src/config/modelProviders/moonshot.ts +1 -29
  736. package/src/config/modelProviders/novita.ts +1 -105
  737. package/src/config/modelProviders/ollama.ts +1 -325
  738. package/src/config/modelProviders/openai.ts +1 -242
  739. package/src/config/modelProviders/openrouter.ts +1 -240
  740. package/src/config/modelProviders/perplexity.ts +1 -45
  741. package/src/config/modelProviders/ppio.ts +1 -152
  742. package/src/config/modelProviders/qiniu.ts +1 -18
  743. package/src/config/modelProviders/qwen.ts +1 -245
  744. package/src/config/modelProviders/search1api.ts +1 -34
  745. package/src/config/modelProviders/sensenova.ts +1 -69
  746. package/src/config/modelProviders/siliconcloud.ts +1 -417
  747. package/src/config/modelProviders/spark.ts +1 -59
  748. package/src/config/modelProviders/stepfun.ts +1 -98
  749. package/src/config/modelProviders/taichu.ts +1 -18
  750. package/src/config/modelProviders/togetherai.ts +1 -274
  751. package/src/config/modelProviders/upstage.ts +1 -28
  752. package/src/config/modelProviders/wenxin.ts +3 -143
  753. package/src/config/modelProviders/xai.ts +1 -38
  754. package/src/config/modelProviders/zeroone.ts +1 -81
  755. package/src/config/modelProviders/zhipu.ts +1 -108
  756. package/src/envs/__tests__/app.test.ts +47 -13
  757. package/src/envs/app.ts +13 -9
  758. package/src/envs/auth.ts +0 -179
  759. package/src/features/AgentSetting/AgentPlugin/index.tsx +2 -2
  760. package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +3 -2
  761. package/src/features/AgentSetting/AgentTTS/SelectWithTTSPreview.tsx +1 -1
  762. package/src/features/AgentSetting/store/action.ts +1 -1
  763. package/src/features/ChatInput/ActionBar/STT/browser.tsx +6 -6
  764. package/src/features/ChatInput/ActionBar/STT/openai.tsx +6 -6
  765. package/src/features/ChatInput/ActionBar/Tools/useControls.tsx +1 -3
  766. package/src/features/ChatInput/ActionBar/index.tsx +2 -2
  767. package/src/features/ChatInput/InputEditor/index.tsx +2 -2
  768. package/src/features/ChatItem/components/Title.tsx +20 -16
  769. package/src/features/Conversation/Error/AccessCodeForm.tsx +1 -1
  770. package/src/features/Conversation/Error/ChatInvalidApiKey.tsx +1 -1
  771. package/src/features/Conversation/Error/ClerkLogin/index.tsx +1 -1
  772. package/src/features/Conversation/Error/ErrorJsonViewer.tsx +4 -3
  773. package/src/features/Conversation/Error/OAuthForm.tsx +1 -1
  774. package/src/features/Conversation/Error/OllamaBizError/index.tsx +7 -2
  775. package/src/features/Conversation/Error/index.tsx +15 -10
  776. package/src/features/Conversation/MarkdownElements/LobeArtifact/Render/index.tsx +2 -2
  777. package/src/features/Conversation/MarkdownElements/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +133 -0
  778. package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +48 -0
  779. package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +2 -1
  780. package/src/features/Conversation/Messages/Assistant/Actions/index.tsx +8 -7
  781. package/src/features/Conversation/Messages/Assistant/Extra/index.test.tsx +4 -9
  782. package/src/features/Conversation/Messages/Assistant/Extra/index.tsx +10 -11
  783. package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +12 -12
  784. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/BuiltinPluginTitle.tsx +2 -2
  785. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/PluginResult.tsx +2 -2
  786. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/PluginState.tsx +2 -2
  787. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/ToolTitle.tsx +4 -2
  788. package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +5 -5
  789. package/src/features/Conversation/Messages/Assistant/Tool/Render/PluginSettings.tsx +4 -1
  790. package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +3 -4
  791. package/src/features/Conversation/Messages/Assistant/Tool/index.tsx +2 -2
  792. package/src/features/Conversation/Messages/Assistant/index.tsx +89 -77
  793. package/src/features/Conversation/Messages/Default.tsx +3 -2
  794. package/src/features/Conversation/Messages/Group/Actions/WithContentId.tsx +178 -0
  795. package/src/features/Conversation/Messages/Group/Actions/WithoutContentId.tsx +93 -0
  796. package/src/features/Conversation/Messages/Group/Actions/index.tsx +21 -0
  797. package/src/features/Conversation/Messages/Group/ContentBlock.tsx +89 -0
  798. package/src/features/Conversation/Messages/Group/EditState.tsx +51 -0
  799. package/src/features/Conversation/Messages/Group/Error/index.tsx +53 -0
  800. package/src/features/Conversation/Messages/Group/GroupChildren.tsx +56 -0
  801. package/src/features/Conversation/Messages/Group/GroupContext.tsx +15 -0
  802. package/src/features/Conversation/Messages/Group/GroupItem.tsx +43 -0
  803. package/src/features/Conversation/Messages/Group/MessageContent.tsx +45 -0
  804. package/src/features/Conversation/Messages/Group/Tool/Inspector/BuiltinPluginTitle.tsx +47 -0
  805. package/src/features/Conversation/Messages/Group/Tool/Inspector/Debug.tsx +70 -0
  806. package/src/features/Conversation/Messages/Group/Tool/Inspector/PluginResult.tsx +34 -0
  807. package/src/features/Conversation/Messages/Group/Tool/Inspector/PluginState.tsx +18 -0
  808. package/src/features/Conversation/Messages/Group/Tool/Inspector/Settings.tsx +40 -0
  809. package/src/features/Conversation/Messages/Group/Tool/Inspector/ToolTitle.tsx +90 -0
  810. package/src/features/Conversation/Messages/Group/Tool/Inspector/index.tsx +187 -0
  811. package/src/features/Conversation/Messages/Group/Tool/Render/Arguments/ObjectEntity.tsx +81 -0
  812. package/src/features/Conversation/Messages/Group/Tool/Render/Arguments/ValueCell.tsx +43 -0
  813. package/src/features/Conversation/Messages/Group/Tool/Render/Arguments/index.tsx +136 -0
  814. package/src/features/Conversation/Messages/Group/Tool/Render/CustomRender.tsx +88 -0
  815. package/src/features/Conversation/Messages/Group/Tool/Render/ErrorResponse.tsx +35 -0
  816. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ApprovalActions.tsx +143 -0
  817. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/Fallback.tsx +98 -0
  818. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/KeyValueEditor.tsx +213 -0
  819. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ModeSelector.tsx +133 -0
  820. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/index.tsx +103 -0
  821. package/src/features/Conversation/Messages/Group/Tool/Render/LoadingPlaceholder/index.tsx +29 -0
  822. package/src/features/Conversation/Messages/Group/Tool/Render/PluginSettings.tsx +66 -0
  823. package/src/features/Conversation/Messages/Group/Tool/Render/RejectedResponse.tsx +45 -0
  824. package/src/features/Conversation/Messages/Group/Tool/Render/index.tsx +134 -0
  825. package/src/features/Conversation/Messages/Group/Tool/index.tsx +97 -0
  826. package/src/features/Conversation/Messages/Group/Tools.tsx +48 -0
  827. package/src/features/Conversation/Messages/Group/index.tsx +145 -0
  828. package/src/features/Conversation/Messages/Supervisor/index.tsx +14 -5
  829. package/src/features/Conversation/Messages/User/{Actions.tsx → Actions/ActionsBar.tsx} +26 -25
  830. package/src/features/Conversation/Messages/User/Actions/MessageBranch.tsx +107 -0
  831. package/src/features/Conversation/Messages/User/Actions/index.tsx +42 -0
  832. package/src/features/Conversation/Messages/User/Extra.tsx +2 -2
  833. package/src/features/Conversation/Messages/User/index.tsx +59 -54
  834. package/src/features/Conversation/Messages/index.tsx +22 -20
  835. package/src/features/Conversation/components/AutoScroll.tsx +4 -4
  836. package/src/features/Conversation/components/Extras/TTS/InitPlayer.tsx +1 -1
  837. package/src/features/Conversation/components/Extras/Usage/UsageDetail/AnimatedNumber.tsx +55 -0
  838. package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +50 -14
  839. package/src/features/Conversation/components/Extras/Usage/UsageDetail/tokens.ts +2 -5
  840. package/src/features/Conversation/components/Extras/Usage/index.tsx +13 -6
  841. package/src/features/Conversation/components/ShareMessageModal/ShareImage/Preview.tsx +2 -2
  842. package/src/features/Conversation/components/VirtualizedList/index.tsx +31 -21
  843. package/src/features/Conversation/hooks/useChatListActionsBar.tsx +26 -14
  844. package/src/features/DataImporter/index.tsx +15 -60
  845. package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -2
  846. package/src/features/LocalFile/LocalFile.tsx +55 -5
  847. package/src/features/MCP/utils.test.ts +91 -0
  848. package/src/features/MCP/utils.ts +20 -2
  849. package/src/features/PluginStore/Content.tsx +2 -3
  850. package/src/features/PluginStore/McpList/index.tsx +6 -2
  851. package/src/features/PluginTag/PluginStatus.tsx +1 -1
  852. package/src/features/PluginTag/index.tsx +1 -3
  853. package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +37 -28
  854. package/src/features/PluginsUI/Render/BuiltinType/index.tsx +1 -1
  855. package/src/features/PluginsUI/Render/MCPType/index.tsx +72 -0
  856. package/src/features/PluginsUI/Render/StandaloneType/Iframe.tsx +2 -2
  857. package/src/features/PluginsUI/Render/index.tsx +17 -0
  858. package/src/features/Portal/Artifacts/Body/index.tsx +2 -2
  859. package/src/features/Portal/GroupThread/Body/index.tsx +1 -1
  860. package/src/features/Portal/Thread/Chat/ChatInput/useSend.ts +3 -3
  861. package/src/helpers/isCanUseFC.ts +0 -8
  862. package/src/hooks/useAgentOwnershipCheck.ts +143 -0
  863. package/src/hooks/useEnabledChatModels.ts +0 -8
  864. package/src/hooks/useHotkeys/chatScope.ts +16 -8
  865. package/src/hooks/useInterceptingRoutes.test.ts +21 -3
  866. package/src/hooks/useModelContextWindowTokens.ts +0 -8
  867. package/src/hooks/useModelHasContextWindowToken.ts +1 -10
  868. package/src/hooks/useModelSupportFiles.ts +1 -11
  869. package/src/hooks/useModelSupportReasoning.ts +1 -11
  870. package/src/hooks/useModelSupportToolUse.ts +1 -11
  871. package/src/hooks/useModelSupportVision.ts +1 -11
  872. package/src/instrumentation.node.ts +3 -2
  873. package/src/layout/AuthProvider/Clerk/index.tsx +2 -16
  874. package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +364 -0
  875. package/src/layout/AuthProvider/MarketAuth/errors.ts +75 -0
  876. package/src/layout/AuthProvider/MarketAuth/index.ts +2 -0
  877. package/src/layout/AuthProvider/MarketAuth/oidc.ts +382 -0
  878. package/src/layout/AuthProvider/MarketAuth/types.ts +64 -0
  879. package/src/layout/AuthProvider/index.tsx +17 -4
  880. package/src/libs/mcp/client.ts +3 -2
  881. package/src/libs/mcp/types.ts +71 -0
  882. package/src/libs/next-auth/auth.config.ts +3 -6
  883. package/src/libs/next-auth/sso-providers/auth0.ts +0 -7
  884. package/src/libs/next-auth/sso-providers/authelia.ts +3 -5
  885. package/src/libs/next-auth/sso-providers/authentik.ts +0 -7
  886. package/src/libs/next-auth/sso-providers/cloudflare-zero-trust.ts +3 -6
  887. package/src/libs/next-auth/sso-providers/cognito.ts +1 -5
  888. package/src/libs/next-auth/sso-providers/generic-oidc.ts +3 -5
  889. package/src/libs/next-auth/sso-providers/github.ts +0 -6
  890. package/src/libs/next-auth/sso-providers/google.ts +0 -2
  891. package/src/libs/next-auth/sso-providers/keycloak.ts +0 -3
  892. package/src/libs/next-auth/sso-providers/logto.ts +3 -5
  893. package/src/libs/next-auth/sso-providers/okta.ts +0 -4
  894. package/src/libs/next-auth/sso-providers/zitadel.ts +0 -7
  895. package/src/libs/trpc/client/index.ts +0 -1
  896. package/src/libs/trpc/client/lambda.ts +12 -8
  897. package/src/libs/trpc/lambda/context.ts +4 -1
  898. package/src/libs/trpc/lambda/index.ts +5 -2
  899. package/src/libs/trpc/middleware/openTelemetry.ts +141 -0
  900. package/src/locales/default/auth.ts +44 -0
  901. package/src/locales/default/chat.ts +23 -0
  902. package/src/locales/default/common.ts +1 -0
  903. package/src/locales/default/components.ts +6 -0
  904. package/src/locales/default/discover.ts +46 -0
  905. package/src/locales/default/index.ts +2 -0
  906. package/src/locales/default/labs.ts +4 -0
  907. package/src/locales/default/marketAuth.ts +42 -0
  908. package/src/locales/default/modelProvider.ts +15 -1
  909. package/src/locales/default/oauth.ts +1 -0
  910. package/src/locales/default/plugin.ts +1 -0
  911. package/src/locales/default/setting.ts +94 -1
  912. package/src/locales/default/topic.ts +1 -0
  913. package/src/server/globalConfig/genServerAiProviderConfig.test.ts +5 -5
  914. package/src/server/globalConfig/genServerAiProviderConfig.ts +1 -1
  915. package/src/server/globalConfig/index.ts +0 -23
  916. package/src/server/modules/AssistantStore/index.ts +1 -1
  917. package/src/server/modules/ContentChunk/index.test.ts +372 -0
  918. package/src/server/modules/ModelRuntime/trace.ts +11 -4
  919. package/src/server/modules/S3/index.test.ts +379 -0
  920. package/src/server/routers/async/__tests__/caller.test.ts +333 -0
  921. package/src/server/routers/async/caller.ts +2 -1
  922. package/src/server/routers/desktop/mcp.ts +22 -11
  923. package/src/server/routers/lambda/__tests__/aiChat.test.ts +1 -1
  924. package/src/server/routers/lambda/__tests__/integration/message.integration.test.ts +771 -57
  925. package/src/server/routers/lambda/aiChat.ts +3 -2
  926. package/src/server/routers/lambda/config/__snapshots__/index.test.ts.snap +175 -12
  927. package/src/server/routers/lambda/config/index.test.ts +38 -30
  928. package/src/server/routers/lambda/index.ts +2 -0
  929. package/src/server/routers/lambda/market/index.ts +38 -14
  930. package/src/server/routers/lambda/message.ts +59 -56
  931. package/src/server/routers/lambda/topic.ts +7 -1
  932. package/src/server/routers/lambda/usage.ts +36 -0
  933. package/src/server/routers/lambda/user.ts +32 -31
  934. package/src/server/routers/mobile/index.ts +14 -2
  935. package/src/server/routers/tools/mcp.ts +24 -7
  936. package/src/server/routers/tools/search.test.ts +1 -7
  937. package/src/server/routers/tools/search.ts +1 -4
  938. package/src/server/services/discover/index.test.ts +153 -11
  939. package/src/server/services/discover/index.ts +339 -40
  940. package/src/server/services/file/impls/local.ts +4 -1
  941. package/src/server/services/file/index.ts +96 -1
  942. package/src/server/services/mcp/contentProcessor.ts +101 -0
  943. package/src/server/services/mcp/deps/MCPSystemDepsCheckService.test.ts +541 -0
  944. package/src/server/services/mcp/deps/checkers/ManualInstallationChecker.test.ts +162 -0
  945. package/src/server/services/mcp/deps/checkers/NpmInstallationChecker.test.ts +374 -0
  946. package/src/server/services/mcp/deps/checkers/PythonInstallationChecker.test.ts +368 -0
  947. package/src/server/services/mcp/index.test.ts +80 -25
  948. package/src/server/services/mcp/index.ts +37 -23
  949. package/src/server/services/message/__tests__/index.test.ts +338 -0
  950. package/src/server/services/message/index.ts +187 -0
  951. package/src/server/services/oidc/index.test.ts +232 -0
  952. package/src/server/services/oidc/index.ts +24 -0
  953. package/src/server/services/usage/index.test.ts +310 -0
  954. package/src/server/services/usage/index.ts +164 -0
  955. package/src/server/sitemap.ts +49 -35
  956. package/src/server/utils/createSpeechResponse.ts +55 -0
  957. package/src/services/__tests__/tool.test.ts +0 -3
  958. package/src/services/_url.ts +15 -1
  959. package/src/services/aiModel/index.test.ts +3 -6
  960. package/src/services/aiModel/index.ts +55 -7
  961. package/src/services/aiProvider/index.test.ts +2 -5
  962. package/src/services/aiProvider/index.ts +47 -7
  963. package/src/services/chat/chat.test.ts +18 -45
  964. package/src/services/chat/clientModelRuntime.test.ts +1 -1
  965. package/src/services/chat/contextEngineering.test.ts +4 -30
  966. package/src/services/chat/contextEngineering.ts +7 -17
  967. package/src/services/chat/helper.ts +7 -31
  968. package/src/services/chat/index.ts +11 -16
  969. package/src/services/chat/types.ts +1 -2
  970. package/src/services/chatGroup/index.ts +64 -9
  971. package/src/services/config.ts +1 -65
  972. package/src/services/discover.ts +28 -17
  973. package/src/services/electron/desktopNotification.ts +6 -6
  974. package/src/services/electron/file.ts +6 -6
  975. package/src/services/electron/localFileService.ts +4 -0
  976. package/src/services/electron/remoteServer.ts +8 -1
  977. package/src/services/export/index.ts +9 -4
  978. package/src/services/file/ClientS3/index.ts +8 -8
  979. package/src/services/file/index.ts +59 -10
  980. package/src/services/import/index.ts +132 -7
  981. package/src/services/marketApi.ts +124 -0
  982. package/src/services/mcp.test.ts +783 -0
  983. package/src/services/mcp.ts +39 -4
  984. package/src/services/message/__tests__/metadata-race-condition.test.ts +157 -0
  985. package/src/services/message/index.ts +226 -10
  986. package/src/services/message/{__tests__/server.test.ts → server.test.ts} +3 -3
  987. package/src/services/models.ts +4 -12
  988. package/src/services/plugin/index.test.ts +8 -0
  989. package/src/services/plugin/index.ts +51 -10
  990. package/src/services/session/index.test.ts +8 -0
  991. package/src/services/session/index.ts +129 -10
  992. package/src/services/tableViewer/client.ts +12 -15
  993. package/src/services/thread/index.test.ts +8 -0
  994. package/src/services/thread/index.ts +37 -7
  995. package/src/services/topic/index.test.ts +8 -0
  996. package/src/services/topic/index.ts +74 -10
  997. package/src/services/upload.ts +11 -11
  998. package/src/services/usage.ts +13 -0
  999. package/src/services/user/index.test.ts +8 -0
  1000. package/src/services/user/index.ts +50 -11
  1001. package/src/services/utils/abortableRequest.test.ts +161 -0
  1002. package/src/services/utils/abortableRequest.ts +67 -0
  1003. package/src/store/aiInfra/slices/aiModel/action.test.ts +17 -9
  1004. package/src/store/chat/agents/GeneralChatAgent.ts +279 -0
  1005. package/src/store/chat/agents/__tests__/GeneralChatAgent.test.ts +778 -0
  1006. package/src/store/chat/agents/createAgentExecutors.ts +513 -0
  1007. package/src/store/chat/agents/createToolEngine.ts +22 -0
  1008. package/src/store/chat/helpers.ts +10 -2
  1009. package/src/store/chat/selectors.ts +1 -1
  1010. package/src/store/chat/slices/aiChat/actions/__tests__/conversationControl.test.ts +332 -0
  1011. package/src/store/chat/slices/aiChat/actions/__tests__/conversationLifecycle.test.ts +257 -0
  1012. package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +19 -6
  1013. package/src/store/chat/slices/aiChat/actions/__tests__/rag.test.ts +6 -6
  1014. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +391 -0
  1015. package/src/store/chat/slices/aiChat/actions/__tests__/streamingStates.test.ts +179 -0
  1016. package/src/store/chat/slices/aiChat/actions/conversationControl.ts +231 -0
  1017. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +374 -0
  1018. package/src/store/chat/slices/aiChat/actions/generateAIGroupChat.ts +19 -14
  1019. package/src/store/chat/slices/aiChat/actions/index.ts +12 -6
  1020. package/src/store/chat/slices/aiChat/actions/rag.ts +9 -6
  1021. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +694 -0
  1022. package/src/store/chat/slices/aiChat/actions/streamingStates.ts +84 -0
  1023. package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +7 -7
  1024. package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +17 -17
  1025. package/src/store/chat/slices/builtinTool/actions/index.ts +1 -4
  1026. package/src/store/chat/slices/builtinTool/actions/interpreter.ts +10 -10
  1027. package/src/store/chat/slices/builtinTool/actions/localSystem.ts +4 -4
  1028. package/src/store/chat/slices/builtinTool/actions/search.ts +16 -16
  1029. package/src/store/chat/slices/message/action.test.ts +199 -47
  1030. package/src/store/chat/slices/message/actions/index.ts +39 -0
  1031. package/src/store/chat/slices/message/actions/internals.ts +77 -0
  1032. package/src/store/chat/slices/message/actions/optimisticUpdate.ts +260 -0
  1033. package/src/store/chat/slices/message/actions/publicApi.ts +242 -0
  1034. package/src/store/chat/slices/message/actions/query.ts +120 -0
  1035. package/src/store/chat/slices/message/actions/runtimeState.ts +108 -0
  1036. package/src/store/chat/slices/message/initialState.ts +18 -0
  1037. package/src/store/chat/slices/message/reducer.test.ts +48 -12
  1038. package/src/store/chat/slices/message/reducer.ts +25 -4
  1039. package/src/store/chat/slices/message/selectors/chat.test.ts +92 -0
  1040. package/src/store/chat/slices/message/selectors/chat.ts +106 -0
  1041. package/src/store/chat/slices/message/selectors/dbMessage.test.ts +51 -0
  1042. package/src/store/chat/slices/message/selectors/dbMessage.ts +140 -0
  1043. package/src/store/chat/slices/message/selectors/displayMessage.test.ts +818 -0
  1044. package/src/store/chat/slices/message/selectors/displayMessage.ts +352 -0
  1045. package/src/store/chat/slices/message/selectors/index.ts +2 -0
  1046. package/src/store/chat/slices/message/selectors/messageState.test.ts +36 -0
  1047. package/src/store/chat/slices/message/selectors/messageState.ts +85 -0
  1048. package/src/store/chat/slices/plugin/action.test.ts +169 -210
  1049. package/src/store/chat/slices/plugin/actions/index.ts +39 -0
  1050. package/src/store/chat/slices/plugin/actions/internals.ts +83 -0
  1051. package/src/store/chat/slices/plugin/actions/optimisticUpdate.ts +213 -0
  1052. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +213 -0
  1053. package/src/store/chat/slices/plugin/actions/publicApi.ts +115 -0
  1054. package/src/store/chat/slices/plugin/actions/workflow.ts +121 -0
  1055. package/src/store/chat/slices/portal/selectors.test.ts +7 -7
  1056. package/src/store/chat/slices/portal/selectors.ts +2 -2
  1057. package/src/store/chat/slices/thread/action.test.ts +38 -32
  1058. package/src/store/chat/slices/thread/action.ts +15 -10
  1059. package/src/store/chat/slices/thread/selectors/index.ts +8 -6
  1060. package/src/store/chat/slices/topic/action.test.ts +1 -1
  1061. package/src/store/chat/slices/topic/action.ts +1 -2
  1062. package/src/store/chat/slices/topic/reducer.ts +12 -5
  1063. package/src/store/chat/store.ts +2 -2
  1064. package/src/store/discover/slices/assistant/action.ts +20 -7
  1065. package/src/store/file/slices/chat/action.ts +1 -4
  1066. package/src/store/file/slices/fileManager/action.ts +2 -3
  1067. package/src/store/global/initialState.ts +10 -0
  1068. package/src/store/global/selectors/systemStatus.ts +9 -0
  1069. package/src/store/global/store.ts +1 -7
  1070. package/src/store/session/slices/sessionGroup/action.test.ts +5 -5
  1071. package/src/store/tool/selectors/tool.test.ts +1 -1
  1072. package/src/store/tool/selectors/tool.ts +6 -8
  1073. package/src/store/tool/slices/builtin/action.test.ts +83 -35
  1074. package/src/store/tool/slices/builtin/action.ts +0 -9
  1075. package/src/store/tool/slices/builtin/selectors.test.ts +4 -30
  1076. package/src/store/tool/slices/builtin/selectors.ts +15 -21
  1077. package/src/store/tool/slices/mcpStore/action.test.ts +95 -3
  1078. package/src/store/tool/slices/mcpStore/action.ts +177 -53
  1079. package/src/store/tool/slices/oldStore/initialState.ts +1 -2
  1080. package/src/store/user/initialState.ts +1 -7
  1081. package/src/store/user/selectors.ts +2 -5
  1082. package/src/store/user/slices/common/action.test.ts +1 -4
  1083. package/src/store/user/slices/common/action.ts +5 -4
  1084. package/src/store/user/slices/preference/action.ts +8 -1
  1085. package/src/store/user/slices/preference/selectors/index.ts +2 -0
  1086. package/src/store/user/slices/preference/selectors/labPrefer.ts +10 -0
  1087. package/src/store/user/slices/preference/{selectors.ts → selectors/preference.ts} +0 -2
  1088. package/src/store/user/slices/settings/action.ts +27 -0
  1089. package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +0 -7
  1090. package/src/store/user/slices/settings/selectors/index.ts +2 -0
  1091. package/src/store/user/slices/settings/selectors/keyVaults.ts +21 -0
  1092. package/src/store/user/slices/settings/selectors/settings.test.ts +0 -37
  1093. package/src/store/user/slices/settings/selectors/settings.ts +0 -5
  1094. package/src/store/user/slices/settings/selectors/toolIntervention.ts +17 -0
  1095. package/src/store/user/store.ts +0 -3
  1096. package/src/tools/index.ts +0 -6
  1097. package/src/tools/interventions.ts +8 -0
  1098. package/src/tools/local-system/Intervention/RunCommand/index.tsx +56 -0
  1099. package/src/tools/local-system/Intervention/index.tsx +17 -0
  1100. package/src/tools/local-system/Render/RunCommand/index.tsx +100 -21
  1101. package/src/tools/local-system/Render/index.tsx +2 -0
  1102. package/src/tools/local-system/index.ts +180 -0
  1103. package/src/tools/local-system/systemRole.ts +61 -7
  1104. package/src/tools/renders.ts +0 -3
  1105. package/src/tools/web-browsing/Portal/Search/Footer.tsx +2 -2
  1106. package/src/tools/web-browsing/Render/Search/ConfigForm/Form.tsx +1 -1
  1107. package/{packages/utils/src → src/utils}/electron/desktopRemoteRPCFetch.ts +1 -1
  1108. package/{packages/utils/src → src/utils/server}/parseModels.ts +4 -5
  1109. package/src/utils/server/routeVariants.test.ts +340 -0
  1110. package/src/utils/server/routeVariants.ts +10 -10
  1111. package/tsconfig.json +9 -3
  1112. package/vitest.config.mts +2 -0
  1113. package/packages/const/src/guide.ts +0 -89
  1114. package/packages/context-engine/ARCHITECTURE.md +0 -425
  1115. package/packages/context-engine/src/providers/InboxGuide.ts +0 -102
  1116. package/packages/context-engine/src/providers/__tests__/InboxGuideProvider.test.ts +0 -121
  1117. package/packages/database/src/models/__tests__/message.test.ts +0 -2552
  1118. package/packages/database/src/utils/__tests__/groupMessages.test.ts +0 -989
  1119. package/packages/database/src/utils/groupMessages.ts +0 -359
  1120. package/packages/model-runtime/src/utils/imageToBase64.test.ts +0 -91
  1121. package/packages/model-runtime/src/utils/imageToBase64.ts +0 -62
  1122. package/packages/utils/src/_deprecated/__snapshots__/parseModels.test.ts.snap +0 -104
  1123. package/packages/utils/src/_deprecated/parseModels.test.ts +0 -287
  1124. package/packages/utils/src/_deprecated/parseModels.ts +0 -165
  1125. package/packages/utils/src/tokenizer/client.ts +0 -35
  1126. package/packages/utils/src/tokenizer/estimated.ts +0 -4
  1127. package/packages/utils/src/tokenizer/server.ts +0 -11
  1128. package/packages/utils/src/tokenizer/tokenizer.worker.ts +0 -12
  1129. package/src/app/(backend)/trpc/edge/[trpc]/route.ts +0 -26
  1130. package/src/app/(backend)/webapi/chat/azureai/route.test.ts +0 -25
  1131. package/src/app/(backend)/webapi/chat/azureai/route.ts +0 -6
  1132. package/src/app/(backend)/webapi/tokenizer/index.test.ts +0 -32
  1133. package/src/app/(backend)/webapi/tokenizer/route.ts +0 -8
  1134. package/src/app/[variants]/(main)/(mobile)/me/data/features/Category.tsx +0 -48
  1135. package/src/app/[variants]/(main)/(mobile)/me/data/features/Header.tsx +0 -33
  1136. package/src/app/[variants]/(main)/(mobile)/me/data/layout.tsx +0 -13
  1137. package/src/app/[variants]/(main)/(mobile)/me/data/loading.tsx +0 -5
  1138. package/src/app/[variants]/(main)/chat/(workspace)/layout.ts +0 -11
  1139. package/src/app/[variants]/(main)/chat/(workspace)/page.tsx +0 -53
  1140. package/src/app/[variants]/(main)/chat/@session/default.tsx +0 -31
  1141. package/src/app/[variants]/(main)/chat/features/Migration/DBReader.ts +0 -290
  1142. package/src/app/[variants]/(main)/chat/features/Migration/ExportConfigButton.tsx +0 -35
  1143. package/src/app/[variants]/(main)/chat/features/Migration/Failed.tsx +0 -120
  1144. package/src/app/[variants]/(main)/chat/features/Migration/Modal.tsx +0 -81
  1145. package/src/app/[variants]/(main)/chat/features/Migration/Start.tsx +0 -108
  1146. package/src/app/[variants]/(main)/chat/features/Migration/UpgradeButton.tsx +0 -71
  1147. package/src/app/[variants]/(main)/chat/features/Migration/const.ts +0 -15
  1148. package/src/app/[variants]/(main)/chat/features/Migration/index.tsx +0 -50
  1149. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +0 -98
  1150. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/index.tsx +0 -35
  1151. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/style.ts +0 -47
  1152. package/src/app/[variants]/(main)/chat/settings/layout.tsx +0 -21
  1153. package/src/app/[variants]/loading/Client/Content.tsx +0 -48
  1154. package/src/app/[variants]/loading/Client/Error.tsx +0 -27
  1155. package/src/app/[variants]/loading/Client/Redirect.tsx +0 -47
  1156. package/src/app/[variants]/loading/Client/index.tsx +0 -22
  1157. package/src/components/InnerLink.tsx +0 -20
  1158. package/src/database/_deprecated/core/__tests__/db-upgrade.test.ts +0 -42
  1159. package/src/database/_deprecated/core/__tests__/db.test.ts +0 -79
  1160. package/src/database/_deprecated/core/__tests__/model.test.ts +0 -55
  1161. package/src/database/_deprecated/core/db.ts +0 -246
  1162. package/src/database/_deprecated/core/index.ts +0 -2
  1163. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/input.json +0 -55
  1164. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/output.json +0 -60
  1165. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.test.ts +0 -14
  1166. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.ts +0 -22
  1167. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/type.ts +0 -105
  1168. package/src/database/_deprecated/core/model.ts +0 -218
  1169. package/src/database/_deprecated/core/schemas.ts +0 -88
  1170. package/src/database/_deprecated/core/types/db.ts +0 -15
  1171. package/src/database/_deprecated/models/__DEBUG.ts +0 -124
  1172. package/src/database/_deprecated/models/__tests__/file.test.ts +0 -83
  1173. package/src/database/_deprecated/models/__tests__/message.test.ts +0 -426
  1174. package/src/database/_deprecated/models/__tests__/plugin.test.ts +0 -81
  1175. package/src/database/_deprecated/models/__tests__/session.test.ts +0 -253
  1176. package/src/database/_deprecated/models/__tests__/sessionGroup.test.ts +0 -220
  1177. package/src/database/_deprecated/models/__tests__/topic.test.ts +0 -523
  1178. package/src/database/_deprecated/models/__tests__/user.test.ts +0 -82
  1179. package/src/database/_deprecated/models/file.ts +0 -51
  1180. package/src/database/_deprecated/models/message.ts +0 -277
  1181. package/src/database/_deprecated/models/plugin.ts +0 -62
  1182. package/src/database/_deprecated/models/session.ts +0 -271
  1183. package/src/database/_deprecated/models/sessionGroup.ts +0 -93
  1184. package/src/database/_deprecated/models/topic.ts +0 -250
  1185. package/src/database/_deprecated/models/user.ts +0 -69
  1186. package/src/database/_deprecated/schemas/files.ts +0 -39
  1187. package/src/database/_deprecated/schemas/message.ts +0 -50
  1188. package/src/database/_deprecated/schemas/plugin.ts +0 -12
  1189. package/src/database/_deprecated/schemas/session.ts +0 -54
  1190. package/src/database/_deprecated/schemas/sessionGroup.ts +0 -8
  1191. package/src/database/_deprecated/schemas/topic.ts +0 -12
  1192. package/src/database/_deprecated/schemas/user.ts +0 -40
  1193. package/src/envs/__tests__/auth.test.ts +0 -200
  1194. package/src/features/Conversation/Error/InvalidAccessCode.tsx +0 -79
  1195. package/src/features/DataImporter/_deprecated.ts +0 -43
  1196. package/src/features/InitClientDB/EnableModal.tsx +0 -118
  1197. package/src/features/InitClientDB/ErrorResult.tsx +0 -143
  1198. package/src/features/InitClientDB/InitIndicator.tsx +0 -124
  1199. package/src/features/InitClientDB/PGliteIcon.tsx +0 -28
  1200. package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +0 -75
  1201. package/src/features/InitClientDB/features/DatabaseRepair/Diagnosis.tsx +0 -98
  1202. package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +0 -218
  1203. package/src/features/InitClientDB/features/DatabaseRepair/index.tsx +0 -91
  1204. package/src/features/InitClientDB/index.tsx +0 -37
  1205. package/src/hooks/_header.ts +0 -23
  1206. package/src/libs/trpc/client/edge.ts +0 -26
  1207. package/src/libs/trpc/edge/context.ts +0 -71
  1208. package/src/libs/trpc/edge/index.ts +0 -45
  1209. package/src/libs/trpc/edge/init.ts +0 -26
  1210. package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +0 -75
  1211. package/src/libs/trpc/edge/middleware/jwtPayload.ts +0 -14
  1212. package/src/migrations/FromV0ToV1.ts +0 -10
  1213. package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +0 -191
  1214. package/src/migrations/FromV1ToV2/fixtures/output-v2.json +0 -202
  1215. package/src/migrations/FromV1ToV2/index.ts +0 -82
  1216. package/src/migrations/FromV1ToV2/migrations.test.ts +0 -224
  1217. package/src/migrations/FromV1ToV2/types/v1.ts +0 -78
  1218. package/src/migrations/FromV1ToV2/types/v2.ts +0 -52
  1219. package/src/migrations/FromV2ToV3/fixtures/input-v2-session.json +0 -72
  1220. package/src/migrations/FromV2ToV3/fixtures/output-v3-from-v1.json +0 -203
  1221. package/src/migrations/FromV2ToV3/fixtures/output-v3.json +0 -74
  1222. package/src/migrations/FromV2ToV3/index.ts +0 -30
  1223. package/src/migrations/FromV2ToV3/migrations.test.ts +0 -42
  1224. package/src/migrations/FromV2ToV3/types/v3.ts +0 -27
  1225. package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +0 -79
  1226. package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +0 -75
  1227. package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +0 -85
  1228. package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +0 -86
  1229. package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +0 -77
  1230. package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +0 -77
  1231. package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +0 -82
  1232. package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +0 -85
  1233. package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +0 -203
  1234. package/src/migrations/FromV3ToV4/index.ts +0 -102
  1235. package/src/migrations/FromV3ToV4/migrations.test.ts +0 -195
  1236. package/src/migrations/FromV3ToV4/types/v3.ts +0 -52
  1237. package/src/migrations/FromV3ToV4/types/v4.ts +0 -37
  1238. package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +0 -245
  1239. package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +0 -96
  1240. package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +0 -120
  1241. package/src/migrations/FromV4ToV5/index.ts +0 -58
  1242. package/src/migrations/FromV4ToV5/migrations.test.ts +0 -49
  1243. package/src/migrations/FromV4ToV5/types/v4.ts +0 -21
  1244. package/src/migrations/FromV4ToV5/types/v5.ts +0 -27
  1245. package/src/migrations/FromV5ToV6/fixtures/from-v1-to-v6-output.json +0 -247
  1246. package/src/migrations/FromV5ToV6/fixtures/session-input-v5.json +0 -81
  1247. package/src/migrations/FromV5ToV6/fixtures/session-output-v6.json +0 -85
  1248. package/src/migrations/FromV5ToV6/index.ts +0 -61
  1249. package/src/migrations/FromV5ToV6/migrations.test.ts +0 -50
  1250. package/src/migrations/FromV5ToV6/types/v5.ts +0 -48
  1251. package/src/migrations/FromV5ToV6/types/v6.ts +0 -63
  1252. package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +0 -203
  1253. package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +0 -103
  1254. package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +0 -118
  1255. package/src/migrations/FromV6ToV7/index.ts +0 -101
  1256. package/src/migrations/FromV6ToV7/migrations.test.ts +0 -64
  1257. package/src/migrations/FromV6ToV7/types/v6.ts +0 -61
  1258. package/src/migrations/FromV6ToV7/types/v7.ts +0 -69
  1259. package/src/migrations/VersionController.test.ts +0 -88
  1260. package/src/migrations/VersionController.ts +0 -67
  1261. package/src/migrations/index.ts +0 -61
  1262. package/src/server/globalConfig/_deprecated.test.ts +0 -92
  1263. package/src/server/globalConfig/_deprecated.ts +0 -41
  1264. package/src/server/routers/edge/appStatus.ts +0 -3
  1265. package/src/server/routers/edge/index.ts +0 -14
  1266. package/src/server/routers/edge/upload.ts +0 -16
  1267. package/src/services/aiModel/client.ts +0 -70
  1268. package/src/services/aiModel/server.test.ts +0 -122
  1269. package/src/services/aiModel/server.ts +0 -51
  1270. package/src/services/aiModel/type.ts +0 -32
  1271. package/src/services/aiProvider/client.ts +0 -58
  1272. package/src/services/aiProvider/server.ts +0 -43
  1273. package/src/services/aiProvider/type.ts +0 -27
  1274. package/src/services/baseClientService/index.ts +0 -9
  1275. package/src/services/chat/__snapshots__/chat.test.ts.snap +0 -110
  1276. package/src/services/chatGroup/client.ts +0 -63
  1277. package/src/services/chatGroup/server.ts +0 -67
  1278. package/src/services/chatGroup/type.ts +0 -22
  1279. package/src/services/export/_deprecated.ts +0 -155
  1280. package/src/services/export/client.ts +0 -15
  1281. package/src/services/export/server.ts +0 -9
  1282. package/src/services/export/type.ts +0 -5
  1283. package/src/services/file/_deprecated.test.ts +0 -119
  1284. package/src/services/file/_deprecated.ts +0 -80
  1285. package/src/services/file/client.test.ts +0 -199
  1286. package/src/services/file/client.ts +0 -85
  1287. package/src/services/file/server.ts +0 -53
  1288. package/src/services/file/type.ts +0 -13
  1289. package/src/services/import/_deprecated.ts +0 -115
  1290. package/src/services/import/client.test.ts +0 -1015
  1291. package/src/services/import/client.ts +0 -64
  1292. package/src/services/import/server.ts +0 -133
  1293. package/src/services/import/type.ts +0 -17
  1294. package/src/services/message/_deprecated.test.ts +0 -398
  1295. package/src/services/message/_deprecated.ts +0 -168
  1296. package/src/services/message/client.test.ts +0 -410
  1297. package/src/services/message/client.ts +0 -186
  1298. package/src/services/message/server.ts +0 -150
  1299. package/src/services/message/type.ts +0 -54
  1300. package/src/services/plugin/_deprecated.test.ts +0 -162
  1301. package/src/services/plugin/_deprecated.ts +0 -42
  1302. package/src/services/plugin/client.test.ts +0 -177
  1303. package/src/services/plugin/client.ts +0 -46
  1304. package/src/services/plugin/server.ts +0 -42
  1305. package/src/services/plugin/type.ts +0 -23
  1306. package/src/services/session/_deprecated.test.ts +0 -440
  1307. package/src/services/session/_deprecated.ts +0 -190
  1308. package/src/services/session/client.test.ts +0 -413
  1309. package/src/services/session/client.ts +0 -193
  1310. package/src/services/session/server.test.ts +0 -260
  1311. package/src/services/session/server.ts +0 -125
  1312. package/src/services/session/type.ts +0 -82
  1313. package/src/services/thread/client.ts +0 -51
  1314. package/src/services/thread/server.ts +0 -32
  1315. package/src/services/thread/type.ts +0 -21
  1316. package/src/services/topic/_deprecated.test.ts +0 -245
  1317. package/src/services/topic/_deprecated.ts +0 -75
  1318. package/src/services/topic/client.ts +0 -89
  1319. package/src/services/topic/pglite.test.ts +0 -212
  1320. package/src/services/topic/server.ts +0 -57
  1321. package/src/services/topic/type.ts +0 -40
  1322. package/src/services/user/_deprecated.test.ts +0 -101
  1323. package/src/services/user/_deprecated.ts +0 -70
  1324. package/src/services/user/client.test.ts +0 -111
  1325. package/src/services/user/client.ts +0 -104
  1326. package/src/services/user/server.test.ts +0 -149
  1327. package/src/services/user/server.ts +0 -47
  1328. package/src/services/user/type.ts +0 -21
  1329. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -1209
  1330. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +0 -718
  1331. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +0 -849
  1332. package/src/store/chat/slices/aiChat/actions/generateAIChatV2.ts +0 -591
  1333. package/src/store/chat/slices/builtinTool/actions/__tests__/dalle.test.ts +0 -121
  1334. package/src/store/chat/slices/builtinTool/actions/dalle.ts +0 -124
  1335. package/src/store/chat/slices/message/action.ts +0 -553
  1336. package/src/store/chat/slices/message/selectors.test.ts +0 -473
  1337. package/src/store/chat/slices/message/selectors.ts +0 -322
  1338. package/src/store/chat/slices/plugin/action.ts +0 -548
  1339. package/src/store/global/actions/clientDb.ts +0 -67
  1340. package/src/store/user/slices/modelList/__snapshots__/action.test.ts.snap +0 -12
  1341. package/src/store/user/slices/modelList/action.test.ts +0 -359
  1342. package/src/store/user/slices/modelList/action.ts +0 -223
  1343. package/src/store/user/slices/modelList/initialState.ts +0 -15
  1344. package/src/store/user/slices/modelList/reducers/customModelCard.test.ts +0 -204
  1345. package/src/store/user/slices/modelList/reducers/customModelCard.ts +0 -64
  1346. package/src/store/user/slices/modelList/selectors/index.ts +0 -3
  1347. package/src/store/user/slices/modelList/selectors/keyVaults.test.ts +0 -201
  1348. package/src/store/user/slices/modelList/selectors/keyVaults.ts +0 -50
  1349. package/src/store/user/slices/modelList/selectors/modelConfig.test.ts +0 -219
  1350. package/src/store/user/slices/modelList/selectors/modelConfig.ts +0 -95
  1351. package/src/store/user/slices/modelList/selectors/modelProvider.test.ts +0 -138
  1352. package/src/store/user/slices/modelList/selectors/modelProvider.ts +0 -170
  1353. package/src/tools/dalle/Render/GalleyGrid.tsx +0 -60
  1354. package/src/tools/dalle/Render/Item/EditMode.tsx +0 -66
  1355. package/src/tools/dalle/Render/Item/Error.tsx +0 -49
  1356. package/src/tools/dalle/Render/Item/Image.tsx +0 -44
  1357. package/src/tools/dalle/Render/Item/ImageFileItem.tsx +0 -57
  1358. package/src/tools/dalle/Render/Item/index.tsx +0 -88
  1359. package/src/tools/dalle/Render/ToolBar.tsx +0 -56
  1360. package/src/tools/dalle/Render/index.tsx +0 -52
  1361. package/src/tools/dalle/index.ts +0 -92
  1362. /package/packages/{utils/src/fetch → fetch-sse/src}/index.ts +0 -0
  1363. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/default.tsx +0 -0
  1364. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatHydration/index.tsx +0 -0
  1365. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/ClassicChat.tsx +0 -0
  1366. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/GroupChat.tsx +0 -0
  1367. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/index.tsx +0 -0
  1368. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Desktop/useSendMenuItems.tsx +0 -0
  1369. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/MentionedUsers/MentionedUserItem.tsx +0 -0
  1370. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/MentionedUsers/index.tsx +0 -0
  1371. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/Mobile/index.tsx +0 -0
  1372. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/ActionBar.tsx +0 -0
  1373. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/Files/index.tsx +0 -0
  1374. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/InputArea/Container.tsx +0 -0
  1375. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/InputArea/index.tsx +0 -0
  1376. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/V1Mobile/Send.tsx +0 -0
  1377. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatInput/index.tsx +0 -0
  1378. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/OrchestratorThinking.tsx +0 -0
  1379. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/ChatItem/ThreadItem.tsx +0 -0
  1380. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/AddButton.tsx +0 -0
  1381. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/AgentWelcome/index.tsx +0 -0
  1382. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/index.tsx +0 -0
  1383. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/GroupWelcome/useTemplateMatching.ts +0 -0
  1384. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/WelcomeChatItem/index.tsx +0 -0
  1385. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatList/index.tsx +0 -0
  1386. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ChatMinimap/index.tsx +0 -0
  1387. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ThreadHydration.tsx +0 -0
  1388. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ZenModeToast/Toast.tsx +0 -0
  1389. /package/src/app/[variants]/(main)/chat/{(workspace)/@conversation → components/conversation}/features/ZenModeToast/index.tsx +0 -0
  1390. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/AgentSettings/index.tsx +0 -0
  1391. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/AgentTeamSettings/index.tsx +0 -0
  1392. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/ChangelogModal.tsx +0 -0
  1393. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/SettingButton.tsx +0 -0
  1394. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/ShareButton/index.tsx +0 -0
  1395. /package/src/app/[variants]/(main)/chat/{(workspace) → components}/features/TelemetryNotification.tsx +0 -0
  1396. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/HeaderAction.tsx +0 -0
  1397. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Main.tsx +0 -0
  1398. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/HistoryLimitTags.tsx +0 -0
  1399. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/KnowledgeTag.tsx +0 -0
  1400. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/MemberCountTag.tsx +0 -0
  1401. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/SearchTags.tsx +0 -0
  1402. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/Tags/index.tsx +0 -0
  1403. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/ChatHeader/index.tsx +0 -0
  1404. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/Portal.tsx +0 -0
  1405. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/TopicPanel.tsx +0 -0
  1406. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Desktop/index.tsx +0 -0
  1407. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/ChatHeader/ChatHeaderTitle.tsx +0 -0
  1408. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/ChatHeader/index.tsx +0 -0
  1409. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/TopicModal.tsx +0 -0
  1410. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/Mobile/index.tsx +0 -0
  1411. /package/src/app/[variants]/(main)/chat/{(workspace)/_layout → components/layout}/type.ts +0 -0
  1412. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/_layout/Desktop.tsx +0 -0
  1413. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/_layout/Mobile.tsx +0 -0
  1414. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/default.tsx +0 -0
  1415. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/error.tsx +0 -0
  1416. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/features/Body.tsx +0 -0
  1417. /package/src/app/[variants]/(main)/chat/{(workspace)/@portal → components/portal}/loading.tsx +0 -0
  1418. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/_layout/Desktop.tsx +0 -0
  1419. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/_layout/Mobile.tsx +0 -0
  1420. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/default.tsx +0 -0
  1421. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/AgentConfig/SystemRole.tsx +0 -0
  1422. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/AgentConfig/index.tsx +0 -0
  1423. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/ConfigLayout.tsx +0 -0
  1424. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/ConfigSwitcher.tsx +0 -0
  1425. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupMember.tsx +0 -0
  1426. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupMemberItem.tsx +0 -0
  1427. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/GroupRole.tsx +0 -0
  1428. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/index.tsx +0 -0
  1429. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/GroupConfig/style.ts +0 -0
  1430. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/SkeletonList.tsx +0 -0
  1431. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/Header.tsx +0 -0
  1432. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ByTimeMode/GroupItem.tsx +0 -0
  1433. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ByTimeMode/index.tsx +0 -0
  1434. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/FlatMode/index.tsx +0 -0
  1435. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/SearchResult/index.tsx +0 -0
  1436. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadItem/Content.tsx +0 -0
  1437. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadItem/index.tsx +0 -0
  1438. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/ThreadList/index.tsx +0 -0
  1439. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/DefaultContent.tsx +0 -0
  1440. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/TopicItem/index.tsx +0 -0
  1441. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicListContent/index.tsx +0 -0
  1442. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/TopicSearchBar/index.tsx +0 -0
  1443. /package/src/app/[variants]/(main)/chat/{(workspace)/@topic → components/topic}/features/Topic/index.tsx +0 -0
  1444. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionHydration.tsx +0 -0
  1445. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/CollapseGroup/Actions.tsx +0 -0
  1446. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/CollapseGroup/index.tsx +0 -0
  1447. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/DefaultMode.tsx +0 -0
  1448. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Inbox/index.tsx +0 -0
  1449. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/AddButton.tsx +0 -0
  1450. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/List/index.tsx +0 -0
  1451. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/ListItem/index.tsx +0 -0
  1452. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/ConfigGroupModal/GroupItem.tsx +0 -0
  1453. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/ConfigGroupModal/index.tsx +0 -0
  1454. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/CreateGroupModal.tsx +0 -0
  1455. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/Modals/RenameGroupModal.tsx +0 -0
  1456. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/SearchMode.tsx +0 -0
  1457. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionListContent/index.tsx +0 -0
  1458. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SessionSearchBar.tsx +0 -0
  1459. /package/src/app/[variants]/(main)/chat/{@session → session}/features/SkeletonList.tsx +0 -0
  1460. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/PanelBody.tsx +0 -0
  1461. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/SessionHeader.tsx +0 -0
  1462. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Desktop/index.tsx +0 -0
  1463. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Mobile/SessionHeader.tsx +0 -0
  1464. /package/src/app/[variants]/(main)/chat/{@session/_layout → session/layout}/Mobile/index.tsx +0 -0
  1465. /package/src/{app/[variants]/(main)/settings/provider/features/ProviderConfig → components/Skeleton}/SkeletonInput.tsx +0 -0
  1466. /package/src/{middleware.ts → proxy.ts} +0 -0
  1467. /package/{packages/utils/src → src/utils/server}/__snapshots__/parseModels.test.ts.snap +0 -0
  1468. /package/{packages/utils/src → src/utils/server}/parseModels.test.ts +0 -0
@@ -1,2552 +0,0 @@
1
- import { DBMessageItem } from '@lobechat/types';
2
- import dayjs from 'dayjs';
3
- import { eq } from 'drizzle-orm';
4
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
-
6
- import { uuid } from '@/utils/uuid';
7
-
8
- import { getTestDB } from '../../models/__tests__/_util';
9
- import {
10
- agents,
11
- chatGroups,
12
- chunks,
13
- embeddings,
14
- fileChunks,
15
- files,
16
- messagePlugins,
17
- messageQueries,
18
- messageQueryChunks,
19
- messageTTS,
20
- messageTranslates,
21
- messages,
22
- messagesFiles,
23
- sessions,
24
- topics,
25
- users,
26
- } from '../../schemas';
27
- import { LobeChatDatabase } from '../../type';
28
- import { MessageModel } from '../message';
29
- import { codeEmbedding } from './fixtures/embedding';
30
-
31
- const serverDB: LobeChatDatabase = await getTestDB();
32
-
33
- const userId = 'message-db';
34
- const messageModel = new MessageModel(serverDB, userId);
35
- const embeddingsId = uuid();
36
-
37
- beforeEach(async () => {
38
- // 在每个测试用例之前,清空表
39
- await serverDB.transaction(async (trx) => {
40
- await trx.delete(users);
41
- await trx.insert(users).values([{ id: userId }, { id: '456' }]);
42
-
43
- await trx.insert(sessions).values([
44
- // { id: 'session1', userId },
45
- // { id: 'session2', userId },
46
- { id: '1', userId },
47
- ]);
48
- await trx.insert(files).values({
49
- id: 'f1',
50
- userId: userId,
51
- url: 'abc',
52
- name: 'file-1',
53
- fileType: 'image/png',
54
- size: 1000,
55
- });
56
-
57
- await trx.insert(embeddings).values({
58
- id: embeddingsId,
59
- embeddings: codeEmbedding,
60
- userId,
61
- });
62
- });
63
- });
64
-
65
- afterEach(async () => {
66
- // 在每个测试用例之后,清空表
67
- await serverDB.delete(users);
68
- });
69
-
70
- describe('MessageModel', () => {
71
- describe('query', () => {
72
- it('should query messages by user ID', async () => {
73
- // 创建测试数据
74
- await serverDB.insert(messages).values([
75
- { id: '1', userId, role: 'user', content: 'message 1', createdAt: new Date('2023-01-01') },
76
- { id: '2', userId, role: 'user', content: 'message 2', createdAt: new Date('2023-02-01') },
77
- {
78
- id: '3',
79
- userId: '456',
80
- role: 'user',
81
- content: 'message 3',
82
- createdAt: new Date('2023-03-01'),
83
- },
84
- ]);
85
-
86
- // 调用 query 方法
87
- const result = await messageModel.query();
88
-
89
- // 断言结果
90
- expect(result).toHaveLength(2);
91
- expect(result[0].id).toBe('1');
92
- expect(result[1].id).toBe('2');
93
- });
94
-
95
- it('should return empty messages if not match the user ID', async () => {
96
- // 创建测试数据
97
- await serverDB.insert(messages).values([
98
- { id: '1', userId: '456', role: 'user', content: '1', createdAt: new Date('2023-01-01') },
99
- { id: '2', userId: '456', role: 'user', content: '2', createdAt: new Date('2023-02-01') },
100
- { id: '3', userId: '456', role: 'user', content: '3', createdAt: new Date('2023-03-01') },
101
- ]);
102
-
103
- // 调用 query 方法
104
- const result = await messageModel.query();
105
-
106
- // 断言结果
107
- expect(result).toHaveLength(0);
108
- });
109
-
110
- it('should query messages with pagination', async () => {
111
- // 创建测试数据
112
- await serverDB.insert(messages).values([
113
- { id: '1', userId, role: 'user', content: 'message 1', createdAt: new Date('2023-01-01') },
114
- { id: '2', userId, role: 'user', content: 'message 2', createdAt: new Date('2023-02-01') },
115
- { id: '3', userId, role: 'user', content: 'message 3', createdAt: new Date('2023-03-01') },
116
- ]);
117
-
118
- // 测试分页
119
- const result1 = await messageModel.query({ current: 0, pageSize: 2 });
120
- expect(result1).toHaveLength(2);
121
-
122
- const result2 = await messageModel.query({ current: 1, pageSize: 1 });
123
- expect(result2).toHaveLength(1);
124
- expect(result2[0].id).toBe('2');
125
- });
126
-
127
- it('should filter messages by sessionId', async () => {
128
- // 创建测试数据
129
- await serverDB.insert(sessions).values([
130
- { id: 'session1', userId },
131
- { id: 'session2', userId },
132
- ]);
133
- await serverDB.insert(messages).values([
134
- {
135
- id: '1',
136
- userId,
137
- role: 'user',
138
- sessionId: 'session1',
139
- content: 'message 1',
140
- createdAt: new Date('2022-02-01'),
141
- },
142
- {
143
- id: '2',
144
- userId,
145
- role: 'user',
146
- sessionId: 'session1',
147
- content: 'message 2',
148
- createdAt: new Date('2023-02-02'),
149
- },
150
- { id: '3', userId, role: 'user', sessionId: 'session2', content: 'message 3' },
151
- ]);
152
-
153
- // 测试根据 sessionId 过滤
154
- const result = await messageModel.query({ sessionId: 'session1' });
155
- expect(result).toHaveLength(2);
156
- expect(result[0].id).toBe('1');
157
- expect(result[1].id).toBe('2');
158
- });
159
-
160
- it('should filter messages by topicId', async () => {
161
- // 创建测试数据
162
- const sessionId = 'session1';
163
- await serverDB.insert(sessions).values([{ id: sessionId, userId }]);
164
- const topicId = 'topic1';
165
- await serverDB.insert(topics).values([
166
- { id: topicId, sessionId, userId },
167
- { id: 'topic2', sessionId, userId },
168
- ]);
169
-
170
- await serverDB.insert(messages).values([
171
- { id: '1', userId, role: 'user', topicId, content: '1', createdAt: new Date('2022-04-01') },
172
- { id: '2', userId, role: 'user', topicId, content: '2', createdAt: new Date('2023-02-01') },
173
- { id: '3', userId, role: 'user', topicId: 'topic2', content: 'message 3' },
174
- ]);
175
-
176
- // 测试根据 topicId 过滤
177
- const result = await messageModel.query({ topicId });
178
- expect(result).toHaveLength(2);
179
- expect(result[0].id).toBe('1');
180
- expect(result[1].id).toBe('2');
181
- });
182
-
183
- it('should filter messages by groupId and expose group metadata', async () => {
184
- await serverDB.transaction(async (trx) => {
185
- await trx.insert(chatGroups).values([
186
- { id: 'group-1', userId, title: 'Group 1' },
187
- { id: 'group-2', userId, title: 'Group 2' },
188
- ]);
189
-
190
- await trx.insert(agents).values([
191
- { id: 'agent-group', userId, title: 'Agent Group' },
192
- { id: 'agent-other', userId, title: 'Agent Other' },
193
- ]);
194
-
195
- await trx.insert(messages).values([
196
- {
197
- id: 'group-message',
198
- userId,
199
- role: 'assistant',
200
- content: 'group message',
201
- groupId: 'group-1',
202
- agentId: 'agent-group',
203
- targetId: 'user',
204
- createdAt: new Date('2024-01-01'),
205
- },
206
- {
207
- id: 'other-message',
208
- userId,
209
- role: 'assistant',
210
- content: 'other group message',
211
- groupId: 'group-2',
212
- agentId: 'agent-other',
213
- targetId: 'user',
214
- createdAt: new Date('2024-01-02'),
215
- },
216
- ]);
217
- });
218
-
219
- const result = await messageModel.query({ groupId: 'group-1' });
220
-
221
- expect(result).toHaveLength(1);
222
- expect(result[0].id).toBe('group-message');
223
- expect(result[0].groupId).toBe('group-1');
224
- expect(result[0].agentId).toBe('agent-group');
225
- expect(result[0].targetId).toBe('user');
226
- });
227
-
228
- it('should query messages with join', async () => {
229
- // 创建测试数据
230
- await serverDB.transaction(async (trx) => {
231
- await trx.insert(messages).values([
232
- {
233
- id: '1',
234
- userId,
235
- role: 'user',
236
- content: 'message 1',
237
- createdAt: new Date('2023-01-01'),
238
- },
239
- {
240
- id: '2',
241
- userId,
242
- role: 'user',
243
- content: 'message 2',
244
- createdAt: new Date('2023-02-01'),
245
- },
246
- {
247
- id: '3',
248
- userId: '456',
249
- role: 'user',
250
- content: 'message 3',
251
- createdAt: new Date('2023-03-01'),
252
- },
253
- ]);
254
- await trx.insert(files).values([
255
- { id: 'f-0', url: 'abc', name: 'file-1', userId, fileType: 'image/png', size: 1000 },
256
- { id: 'f-1', url: 'abc', name: 'file-1', userId, fileType: 'image/png', size: 100 },
257
- { id: 'f-3', url: 'abc', name: 'file-3', userId, fileType: 'image/png', size: 400 },
258
- ]);
259
- await trx.insert(messageTTS).values([
260
- { id: '1', userId },
261
- { id: '2', voice: 'a', fileId: 'f-1', contentMd5: 'abc', userId },
262
- ]);
263
-
264
- await trx.insert(messagesFiles).values([
265
- { fileId: 'f-0', messageId: '1', userId },
266
- { fileId: 'f-3', messageId: '1', userId },
267
- ]);
268
- });
269
-
270
- const domain = 'http://abc.com';
271
- // 调用 query 方法
272
- const result = await messageModel.query(
273
- {},
274
- { postProcessUrl: async (path) => `${domain}/${path}` },
275
- );
276
-
277
- // 断言结果
278
- expect(result).toHaveLength(2);
279
- expect(result[0].id).toBe('1');
280
- expect(result[0].imageList).toEqual([
281
- { alt: 'file-1', id: 'f-0', url: `${domain}/abc` },
282
- { alt: 'file-3', id: 'f-3', url: `${domain}/abc` },
283
- ]);
284
-
285
- expect(result[1].id).toBe('2');
286
- expect(result[1].imageList).toEqual([]);
287
- });
288
-
289
- it('should include translate, tts and other extra fields in query result', async () => {
290
- // 创建测试数据
291
- await serverDB.transaction(async (trx) => {
292
- await trx.insert(messages).values([
293
- {
294
- id: '1',
295
- userId,
296
- role: 'user',
297
- content: 'message 1',
298
- createdAt: new Date('2023-01-01'),
299
- },
300
- ]);
301
- await trx
302
- .insert(messageTranslates)
303
- .values([{ id: '1', content: 'translated', from: 'en', to: 'zh', userId }]);
304
- await trx
305
- .insert(messageTTS)
306
- .values([{ id: '1', voice: 'voice1', fileId: 'f1', contentMd5: 'md5', userId }]);
307
- });
308
-
309
- // 调用 query 方法
310
- const result = await messageModel.query();
311
-
312
- // 断言结果
313
- expect(result[0].extra!.translate).toEqual({ content: 'translated', from: 'en', to: 'zh' });
314
- expect(result[0].extra!.tts).toEqual({
315
- contentMd5: 'md5',
316
- file: 'f1',
317
- voice: 'voice1',
318
- });
319
- });
320
-
321
- it('should handle edge cases of pagination parameters', async () => {
322
- // 创建测试数据
323
- await serverDB.insert(messages).values([
324
- { id: '1', userId, role: 'user', content: 'message 1' },
325
- { id: '2', userId, role: 'user', content: 'message 2' },
326
- { id: '3', userId, role: 'user', content: 'message 3' },
327
- ]);
328
-
329
- // 测试 current 和 pageSize 的边界情况
330
- const result1 = await messageModel.query({ current: 0, pageSize: 2 });
331
- expect(result1).toHaveLength(2);
332
-
333
- const result2 = await messageModel.query({ current: 1, pageSize: 2 });
334
- expect(result2).toHaveLength(1);
335
-
336
- const result3 = await messageModel.query({ current: 2, pageSize: 2 });
337
- expect(result3).toHaveLength(0);
338
- });
339
-
340
- describe('query with messageQueries', () => {
341
- it('should include ragQuery, ragQueryId and ragRawQuery in query results', async () => {
342
- // 创建测试数据
343
- const messageId = 'msg-with-query';
344
- const queryId = uuid();
345
-
346
- await serverDB.insert(messages).values({
347
- id: messageId,
348
- userId,
349
- role: 'user',
350
- content: 'test message',
351
- });
352
-
353
- await serverDB.insert(messageQueries).values({
354
- id: queryId,
355
- messageId,
356
- userQuery: 'original query',
357
- rewriteQuery: 'rewritten query',
358
- userId,
359
- });
360
-
361
- // 调用 query 方法
362
- const result = await messageModel.query();
363
-
364
- // 断言结果
365
- expect(result).toHaveLength(1);
366
- expect(result[0].id).toBe(messageId);
367
- expect(result[0].ragQueryId).toBe(queryId);
368
- expect(result[0].ragQuery).toBe('rewritten query');
369
- expect(result[0].ragRawQuery).toBe('original query');
370
- });
371
-
372
- it.skip('should handle multiple message queries for the same message', async () => {
373
- // 创建测试数据
374
- const messageId = 'msg-multi-query';
375
- const queryId1 = uuid();
376
- const queryId2 = uuid();
377
-
378
- await serverDB.insert(messages).values({
379
- id: messageId,
380
- userId,
381
- role: 'user',
382
- content: 'test message',
383
- });
384
-
385
- // 创建两个查询,但查询结果应该只包含一个(最新的)
386
- await serverDB.insert(messageQueries).values([
387
- {
388
- id: queryId1,
389
- messageId,
390
- userQuery: 'original query 1',
391
- rewriteQuery: 'rewritten query 1',
392
- userId,
393
- },
394
- {
395
- id: queryId2,
396
- messageId,
397
- userQuery: 'original query 2',
398
- rewriteQuery: 'rewritten query 2',
399
- userId,
400
- },
401
- ]);
402
-
403
- // 调用 query 方法
404
- const result = await messageModel.query();
405
-
406
- // 断言结果 - 应该只包含最新的查询
407
- expect(result).toHaveLength(1);
408
- expect(result[0].id).toBe(messageId);
409
- expect(result[0].ragQueryId).toBe(queryId2);
410
- expect(result[0].ragQuery).toBe('rewritten query 2');
411
- expect(result[0].ragRawQuery).toBe('original query 2');
412
- });
413
- });
414
-
415
- it('should handle complex query with multiple joins and file chunks', async () => {
416
- await serverDB.transaction(async (trx) => {
417
- const chunk1Id = uuid();
418
- const query1Id = uuid();
419
- // 创建基础消息
420
- await trx.insert(messages).values({
421
- id: 'msg1',
422
- userId,
423
- role: 'user',
424
- content: 'test message',
425
- createdAt: new Date('2023-01-01'),
426
- });
427
-
428
- // 创建文件
429
- await trx.insert(files).values([
430
- {
431
- id: 'file1',
432
- userId,
433
- name: 'test.txt',
434
- url: 'test-url',
435
- fileType: 'text/plain',
436
- size: 100,
437
- },
438
- ]);
439
-
440
- // 创建文件块
441
- await trx.insert(chunks).values({
442
- id: chunk1Id,
443
- text: 'chunk content',
444
- });
445
-
446
- // 关联消息和文件
447
- await trx.insert(messagesFiles).values({
448
- messageId: 'msg1',
449
- userId,
450
- fileId: 'file1',
451
- });
452
-
453
- // 创建文件块关联
454
- await trx.insert(fileChunks).values({
455
- fileId: 'file1',
456
- userId,
457
- chunkId: chunk1Id,
458
- });
459
-
460
- // 创建消息查询
461
- await trx.insert(messageQueries).values({
462
- id: query1Id,
463
- messageId: 'msg1',
464
- userId,
465
- userQuery: 'original query',
466
- rewriteQuery: 'rewritten query',
467
- });
468
-
469
- // 创建消息查询块关联
470
- await trx.insert(messageQueryChunks).values({
471
- messageId: 'msg1',
472
- queryId: query1Id,
473
- chunkId: chunk1Id,
474
- similarity: '0.95',
475
- userId,
476
- });
477
- });
478
-
479
- const result = await messageModel.query();
480
-
481
- expect(result).toHaveLength(1);
482
- expect(result[0].chunksList).toHaveLength(1);
483
- expect(result[0].chunksList![0]).toMatchObject({
484
- text: 'chunk content',
485
- similarity: 0.95,
486
- });
487
- });
488
-
489
- it('should return empty arrays for files and chunks if none exist', async () => {
490
- await serverDB.insert(messages).values({
491
- id: 'msg1',
492
- userId,
493
- role: 'user',
494
- content: 'test message',
495
- });
496
-
497
- const result = await messageModel.query();
498
-
499
- expect(result).toHaveLength(1);
500
- expect(result[0].fileList).toEqual([]);
501
- expect(result[0].imageList).toEqual([]);
502
- expect(result[0].chunksList).toEqual([]);
503
- });
504
- });
505
-
506
- describe('queryAll', () => {
507
- it('should return all messages belonging to the user in ascending order', async () => {
508
- // 创建测试数据
509
- await serverDB.insert(messages).values([
510
- {
511
- id: '1',
512
- userId,
513
- role: 'user',
514
- content: 'message 1',
515
- createdAt: new Date('2023-01-01'),
516
- },
517
- {
518
- id: '2',
519
- userId,
520
- role: 'user',
521
- content: 'message 2',
522
- createdAt: new Date('2023-02-01'),
523
- },
524
- {
525
- id: '3',
526
- userId: '456',
527
- role: 'user',
528
- content: 'message 3',
529
- createdAt: new Date('2023-03-01'),
530
- },
531
- ]);
532
-
533
- // 调用 queryAll 方法
534
- const result = await messageModel.queryAll();
535
-
536
- // 断言结果
537
- expect(result).toHaveLength(2);
538
- expect(result[0].id).toBe('1');
539
- expect(result[1].id).toBe('2');
540
- });
541
- });
542
-
543
- describe('findById', () => {
544
- it('should find message by ID', async () => {
545
- // 创建测试数据
546
- await serverDB.insert(messages).values([
547
- { id: '1', userId, role: 'user', content: 'message 1' },
548
- { id: '2', userId: '456', role: 'user', content: 'message 2' },
549
- ]);
550
-
551
- // 调用 findById 方法
552
- const result = await messageModel.findById('1');
553
-
554
- // 断言结果
555
- expect(result?.id).toBe('1');
556
- expect(result?.content).toBe('message 1');
557
- });
558
-
559
- it('should return undefined if message does not belong to user', async () => {
560
- // 创建测试数据
561
- await serverDB
562
- .insert(messages)
563
- .values([{ id: '1', userId: '456', role: 'user', content: 'message 1' }]);
564
-
565
- // 调用 findById 方法
566
- const result = await messageModel.findById('1');
567
-
568
- // 断言结果
569
- expect(result).toBeUndefined();
570
- });
571
- });
572
-
573
- describe('queryBySessionId', () => {
574
- it('should query messages by sessionId', async () => {
575
- // 创建测试数据
576
- const sessionId = 'session1';
577
- await serverDB.insert(sessions).values([
578
- { id: 'session1', userId },
579
- { id: 'session2', userId },
580
- ]);
581
- await serverDB.insert(messages).values([
582
- {
583
- id: '1',
584
- userId,
585
- role: 'user',
586
- sessionId,
587
- content: 'message 1',
588
- createdAt: new Date('2022-01-01'),
589
- },
590
- {
591
- id: '2',
592
- userId,
593
- role: 'user',
594
- sessionId,
595
- content: 'message 2',
596
- createdAt: new Date('2023-02-01'),
597
- },
598
- { id: '3', userId, role: 'user', sessionId: 'session2', content: 'message 3' },
599
- ]);
600
-
601
- // 调用 queryBySessionId 方法
602
- const result = await messageModel.queryBySessionId(sessionId);
603
-
604
- // 断言结果
605
- expect(result).toHaveLength(2);
606
- expect(result[0].id).toBe('1');
607
- expect(result[1].id).toBe('2');
608
- });
609
- });
610
-
611
- describe('queryByKeyWord', () => {
612
- it('should query messages by keyword', async () => {
613
- // 创建测试数据
614
- await serverDB.insert(messages).values([
615
- { id: '1', userId, role: 'user', content: 'apple', createdAt: new Date('2022-02-01') },
616
- { id: '2', userId, role: 'user', content: 'banana' },
617
- { id: '3', userId, role: 'user', content: 'pear' },
618
- { id: '4', userId, role: 'user', content: 'apple pie', createdAt: new Date('2024-02-01') },
619
- ]);
620
-
621
- // 测试查询包含特定关键字的消息
622
- const result = await messageModel.queryByKeyword('apple');
623
-
624
- // 断言结果
625
- expect(result).toHaveLength(2);
626
- expect(result[0].id).toBe('4');
627
- expect(result[1].id).toBe('1');
628
- });
629
-
630
- it('should return empty array when keyword is empty', async () => {
631
- // 创建测试数据
632
- await serverDB.insert(messages).values([
633
- { id: '1', userId, role: 'user', content: 'apple' },
634
- { id: '2', userId, role: 'user', content: 'banana' },
635
- { id: '3', userId, role: 'user', content: 'pear' },
636
- { id: '4', userId, role: 'user', content: 'apple pie' },
637
- ]);
638
-
639
- // 测试当关键字为空时返回空数组
640
- const result = await messageModel.queryByKeyword('');
641
-
642
- // 断言结果
643
- expect(result).toHaveLength(0);
644
- });
645
- });
646
-
647
- describe('createMessage', () => {
648
- it('should create a new message', async () => {
649
- // 调用 createMessage 方法
650
- await messageModel.create({ role: 'user', content: 'new message', sessionId: '1' });
651
-
652
- // 断言结果
653
- const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
654
- expect(result).toHaveLength(1);
655
- expect(result[0].content).toBe('new message');
656
- });
657
-
658
- it('should create a message', async () => {
659
- const sessionId = 'session1';
660
- await serverDB.insert(sessions).values([{ id: sessionId, userId }]);
661
-
662
- const result = await messageModel.create({
663
- content: 'message 1',
664
- role: 'user',
665
- sessionId: 'session1',
666
- });
667
-
668
- expect(result.id).toBeDefined();
669
- expect(result.content).toBe('message 1');
670
- expect(result.role).toBe('user');
671
- expect(result.sessionId).toBe('session1');
672
- expect(result.userId).toBe(userId);
673
- });
674
-
675
- it('should generate message ID automatically', async () => {
676
- // 调用 createMessage 方法
677
- await messageModel.create({
678
- role: 'user',
679
- content: 'new message',
680
- sessionId: '1',
681
- });
682
-
683
- // 断言结果
684
- const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
685
- expect(result[0].id).toBeDefined();
686
- expect(result[0].id).toHaveLength(18);
687
- });
688
-
689
- it('should create a tool message and insert into messagePlugins table', async () => {
690
- // 调用 create 方法
691
- const result = await messageModel.create({
692
- content: 'message 1',
693
- role: 'tool',
694
- sessionId: '1',
695
- tool_call_id: 'tool1',
696
- plugin: {
697
- apiName: 'api1',
698
- arguments: 'arg1',
699
- identifier: 'plugin1',
700
- type: 'default',
701
- },
702
- });
703
-
704
- // 断言结果
705
- expect(result.id).toBeDefined();
706
- expect(result.content).toBe('message 1');
707
- expect(result.role).toBe('tool');
708
- expect(result.sessionId).toBe('1');
709
-
710
- const pluginResult = await serverDB
711
- .select()
712
- .from(messagePlugins)
713
- .where(eq(messagePlugins.id, result.id));
714
- expect(pluginResult).toHaveLength(1);
715
- expect(pluginResult[0].identifier).toBe('plugin1');
716
- });
717
-
718
- it('should create tool message ', async () => {
719
- // 调用 create 方法
720
- const state = {
721
- query: 'Composio',
722
- answers: [],
723
- results: [
724
- {
725
- url: 'https://www.composio.dev/',
726
- score: 16,
727
- title: 'Composio - Connect 90+ tools to your AI agents',
728
- engine: 'bing',
729
- content:
730
- 'Faster DevelopmentHigher ReliabilityBetter Integrations. Get Started Now. Our platform lets you ditch the specs and seamlessly integrate any tool you need in less than 5 mins.',
731
- engines: ['bing', 'qwant', 'brave', 'duckduckgo'],
732
- category: 'general',
733
- template: 'default.html',
734
- positions: [1, 1, 1, 1],
735
- thumbnail: '',
736
- parsed_url: ['https', 'www.composio.dev', '/', '', '', ''],
737
- publishedDate: null,
738
- },
739
- {
740
- url: 'https://www.composio.co/',
741
- score: 10.75,
742
- title: 'Composio',
743
- engine: 'bing',
744
- content:
745
- 'Composio was created to help streamline the entire book creation process! Writing. Take time out to write / Make a schedule to write consistently. We have writing software that optimizes your books for printing or ebook format. Figure out what you want to write. Collaborate and write with others. Professional editing is a necessity.',
746
- engines: ['qwant', 'duckduckgo', 'google', 'bing', 'brave'],
747
- category: 'general',
748
- template: 'default.html',
749
- positions: [5, 2, 1, 5, 4],
750
- thumbnail: null,
751
- parsed_url: ['https', 'www.composio.co', '/', '', '', ''],
752
- publishedDate: null,
753
- },
754
- ],
755
- unresponsive_engines: [],
756
- };
757
- const result = await messageModel.create({
758
- content: '[{}]',
759
- plugin: {
760
- apiName: 'searchWithSearXNG',
761
- arguments: '{\n "query": "Composio"\n}',
762
- identifier: 'lobe-web-browsing',
763
- type: 'builtin',
764
- },
765
- pluginState: state,
766
- role: 'tool',
767
- tool_call_id: 'tool_call_ymxXC2J0',
768
- sessionId: '1',
769
- });
770
-
771
- // 断言结果
772
- expect(result.id).toBeDefined();
773
- expect(result.content).toBe('[{}]');
774
- expect(result.role).toBe('tool');
775
- expect(result.sessionId).toBe('1');
776
-
777
- const pluginResult = await serverDB
778
- .select()
779
- .from(messagePlugins)
780
- .where(eq(messagePlugins.id, result.id));
781
- expect(pluginResult).toHaveLength(1);
782
- expect(pluginResult[0].identifier).toBe('lobe-web-browsing');
783
- expect(pluginResult[0].state!).toMatchObject(state);
784
- });
785
-
786
- describe('create with advanced parameters', () => {
787
- it('should create a message with custom ID', async () => {
788
- const customId = 'custom-msg-id';
789
-
790
- const result = await messageModel.create(
791
- {
792
- role: 'user',
793
- content: 'message with custom ID',
794
- sessionId: '1',
795
- },
796
- customId,
797
- );
798
-
799
- expect(result.id).toBe(customId);
800
-
801
- // 验证数据库中的记录
802
- const dbResult = await serverDB.select().from(messages).where(eq(messages.id, customId));
803
- expect(dbResult).toHaveLength(1);
804
- expect(dbResult[0].id).toBe(customId);
805
- });
806
-
807
- it.skip('should create a message with file chunks and RAG query ID', async () => {
808
- // 创建测试数据
809
- const chunkId1 = uuid();
810
- const chunkId2 = uuid();
811
- const ragQueryId = uuid();
812
-
813
- await serverDB.insert(chunks).values([
814
- { id: chunkId1, text: 'chunk text 1' },
815
- { id: chunkId2, text: 'chunk text 2' },
816
- ]);
817
-
818
- // 调用 create 方法
819
- const result = await messageModel.create({
820
- role: 'assistant',
821
- content: 'message with file chunks',
822
- fileChunks: [
823
- { id: chunkId1, similarity: 0.95 },
824
- { id: chunkId2, similarity: 0.85 },
825
- ],
826
- ragQueryId,
827
- sessionId: '1',
828
- });
829
-
830
- // 验证消息创建成功
831
- expect(result.id).toBeDefined();
832
-
833
- // 验证消息查询块关联创建成功
834
- const queryChunks = await serverDB
835
- .select()
836
- .from(messageQueryChunks)
837
- .where(eq(messageQueryChunks.messageId, result.id));
838
-
839
- expect(queryChunks).toHaveLength(2);
840
- expect(queryChunks[0].chunkId).toBe(chunkId1);
841
- expect(queryChunks[0].queryId).toBe(ragQueryId);
842
- expect(queryChunks[0].similarity).toBe('0.95');
843
- expect(queryChunks[1].chunkId).toBe(chunkId2);
844
- expect(queryChunks[1].similarity).toBe('0.85');
845
- });
846
-
847
- it('should create a message with files', async () => {
848
- // 创建测试数据
849
- await serverDB.insert(files).values([
850
- {
851
- id: 'file1',
852
- name: 'file1.txt',
853
- fileType: 'text/plain',
854
- size: 100,
855
- url: 'url1',
856
- userId,
857
- },
858
- {
859
- id: 'file2',
860
- name: 'file2.jpg',
861
- fileType: 'image/jpeg',
862
- size: 200,
863
- url: 'url2',
864
- userId,
865
- },
866
- ]);
867
-
868
- // 调用 create 方法
869
- const result = await messageModel.create({
870
- role: 'user',
871
- content: 'message with files',
872
- files: ['file1', 'file2'],
873
- sessionId: '1',
874
- });
875
-
876
- // 验证消息创建成功
877
- expect(result.id).toBeDefined();
878
-
879
- // 验证消息文件关联创建成功
880
- const messageFiles = await serverDB
881
- .select()
882
- .from(messagesFiles)
883
- .where(eq(messagesFiles.messageId, result.id));
884
-
885
- expect(messageFiles).toHaveLength(2);
886
- expect(messageFiles[0].fileId).toBe('file1');
887
- expect(messageFiles[1].fileId).toBe('file2');
888
- });
889
-
890
- it('should create a message with custom timestamps', async () => {
891
- const customCreatedAt = '2022-05-15T10:30:00Z';
892
- const customUpdatedAt = '2022-05-16T11:45:00Z';
893
-
894
- const result = await messageModel.create({
895
- role: 'user',
896
- content: 'message with custom timestamps',
897
- createdAt: customCreatedAt as any,
898
- updatedAt: customUpdatedAt as any,
899
- sessionId: '1',
900
- });
901
-
902
- // 验证数据库中的记录
903
- const dbResult = await serverDB.select().from(messages).where(eq(messages.id, result.id));
904
-
905
- // 日期比较需要考虑时区和格式化问题,所以使用 toISOString 进行比较
906
- expect(new Date(dbResult[0].createdAt!).toISOString()).toBe(
907
- new Date(customCreatedAt).toISOString(),
908
- );
909
- expect(new Date(dbResult[0].updatedAt!).toISOString()).toBe(
910
- new Date(customUpdatedAt).toISOString(),
911
- );
912
- });
913
- });
914
- });
915
-
916
- describe('batchCreateMessages', () => {
917
- it('should batch create messages', async () => {
918
- // 准备测试数据
919
- const newMessages = [
920
- { id: '1', role: 'user', content: 'message 1' },
921
- { id: '2', role: 'assistant', content: 'message 2' },
922
- ] as DBMessageItem[];
923
-
924
- // 调用 batchCreateMessages 方法
925
- await messageModel.batchCreate(newMessages);
926
-
927
- // 断言结果
928
- const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
929
- expect(result).toHaveLength(2);
930
- expect(result[0].content).toBe('message 1');
931
- expect(result[1].content).toBe('message 2');
932
- });
933
- });
934
-
935
- describe('createNewMessage', () => {
936
- it('should create message and return id with messages list', async () => {
937
- // 调用 createNewMessage 方法
938
- const result = await messageModel.createNewMessage({
939
- role: 'user',
940
- content: 'test message',
941
- sessionId: '1',
942
- });
943
-
944
- // 断言返回结构
945
- expect(result).toHaveProperty('id');
946
- expect(result).toHaveProperty('messages');
947
- expect(result.id).toBeDefined();
948
- expect(result.messages).toBeInstanceOf(Array);
949
- });
950
-
951
- it('should return newly created message in messages list', async () => {
952
- const content = 'new test message ' + Date.now();
953
-
954
- const result = await messageModel.createNewMessage({
955
- role: 'user',
956
- content,
957
- sessionId: '1',
958
- });
959
-
960
- // 验证新创建的消息在列表中
961
- const createdMessage = result.messages.find((m) => m.id === result.id);
962
- expect(createdMessage).toBeDefined();
963
- expect(createdMessage?.content).toBe(content);
964
- expect(createdMessage?.role).toBe('user');
965
- });
966
-
967
- it('should return all messages for the session', async () => {
968
- // 创建多条消息
969
- await messageModel.create({ role: 'user', content: 'message 1', sessionId: '1' });
970
- await messageModel.create({ role: 'assistant', content: 'message 2', sessionId: '1' });
971
-
972
- // 创建第三条消息并获取完整列表
973
- const result = await messageModel.createNewMessage({
974
- role: 'user',
975
- content: 'message 3',
976
- sessionId: '1',
977
- });
978
-
979
- // 验证返回了所有消息
980
- expect(result.messages.length).toBeGreaterThanOrEqual(3);
981
- });
982
-
983
- it('should filter messages by topicId if provided', async () => {
984
- const topicId = 'topic-1';
985
- await serverDB.insert(topics).values({ id: topicId, sessionId: '1', userId });
986
-
987
- // 创建不同 topic 的消息
988
- await messageModel.create({ role: 'user', content: 'topic 1 msg', sessionId: '1', topicId });
989
- await messageModel.create({ role: 'user', content: 'no topic msg', sessionId: '1' });
990
-
991
- // 创建新消息并指定 topicId
992
- const result = await messageModel.createNewMessage({
993
- role: 'user',
994
- content: 'new topic msg',
995
- sessionId: '1',
996
- topicId,
997
- });
998
-
999
- // 验证只返回该 topic 的消息
1000
- expect(result.messages.every((m) => m.topicId === topicId || m.topicId === undefined)).toBe(
1001
- true,
1002
- );
1003
- expect(result.messages.find((m) => m.content === 'no topic msg')).toBeUndefined();
1004
- });
1005
- });
1006
-
1007
- describe('updateMessage', () => {
1008
- it('should update message content', async () => {
1009
- // 创建测试数据
1010
- await serverDB
1011
- .insert(messages)
1012
- .values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
1013
-
1014
- // 调用 updateMessage 方法
1015
- await messageModel.update('1', { content: 'updated message' });
1016
-
1017
- // 断言结果
1018
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1019
- expect(result[0].content).toBe('updated message');
1020
- });
1021
-
1022
- it('should only update messages belonging to the user', async () => {
1023
- // 创建测试数据
1024
- await serverDB
1025
- .insert(messages)
1026
- .values([{ id: '1', userId: '456', role: 'user', content: 'message 1' }]);
1027
-
1028
- // 调用 updateMessage 方法
1029
- await messageModel.update('1', { content: 'updated message' });
1030
-
1031
- // 断言结果
1032
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1033
- expect(result[0].content).toBe('message 1');
1034
- });
1035
-
1036
- it('should update message tools', async () => {
1037
- // 创建测试数据
1038
- await serverDB.insert(messages).values([
1039
- {
1040
- id: '1',
1041
- userId,
1042
- role: 'user',
1043
- content: 'message 1',
1044
- tools: [
1045
- {
1046
- id: 'call_Z8UU8LedZcoJHFGkfqYecjmT',
1047
- type: 'builtin',
1048
- apiName: 'searchWithSearXNG',
1049
- arguments:
1050
- '{"query":"杭州洪水 2023","searchEngines":["google","bing","baidu","duckduckgo","brave"]}',
1051
- identifier: 'lobe-web-browsing',
1052
- },
1053
- ],
1054
- },
1055
- ]);
1056
-
1057
- // 调用 updateMessage 方法
1058
- await messageModel.update('1', {
1059
- tools: [
1060
- {
1061
- id: 'call_Z8UU8LedZcoJHFGkfqYecjmT',
1062
- type: 'builtin',
1063
- apiName: 'searchWithSearXNG',
1064
- arguments: '{"query":"2024 杭州暴雨","searchEngines":["duckduckgo","google","brave"]}',
1065
- identifier: 'lobe-web-browsing',
1066
- },
1067
- ],
1068
- });
1069
-
1070
- // 断言结果
1071
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1072
- expect((result[0].tools as any)[0].arguments).toBe(
1073
- '{"query":"2024 杭州暴雨","searchEngines":["duckduckgo","google","brave"]}',
1074
- );
1075
- });
1076
-
1077
- describe('update with imageList', () => {
1078
- it('should update a message and add image files', async () => {
1079
- // 创建测试数据
1080
- await serverDB.insert(messages).values({
1081
- id: 'msg-to-update',
1082
- userId,
1083
- role: 'user',
1084
- content: 'original content',
1085
- });
1086
-
1087
- await serverDB.insert(files).values([
1088
- {
1089
- id: 'img1',
1090
- name: 'image1.jpg',
1091
- fileType: 'image/jpeg',
1092
- size: 100,
1093
- url: 'url1',
1094
- userId,
1095
- },
1096
- { id: 'img2', name: 'image2.png', fileType: 'image/png', size: 200, url: 'url2', userId },
1097
- ]);
1098
-
1099
- // 调用 update 方法
1100
- await messageModel.update('msg-to-update', {
1101
- content: 'updated content',
1102
- imageList: [
1103
- { id: 'img1', alt: 'image 1', url: 'url1' },
1104
- { id: 'img2', alt: 'image 2', url: 'url2' },
1105
- ],
1106
- });
1107
-
1108
- // 验证消息更新成功
1109
- const updatedMessage = await serverDB
1110
- .select()
1111
- .from(messages)
1112
- .where(eq(messages.id, 'msg-to-update'));
1113
-
1114
- expect(updatedMessage[0].content).toBe('updated content');
1115
-
1116
- // 验证消息文件关联创建成功
1117
- const messageFiles = await serverDB
1118
- .select()
1119
- .from(messagesFiles)
1120
- .where(eq(messagesFiles.messageId, 'msg-to-update'));
1121
-
1122
- expect(messageFiles).toHaveLength(2);
1123
- expect(messageFiles[0].fileId).toBe('img1');
1124
- expect(messageFiles[1].fileId).toBe('img2');
1125
- });
1126
-
1127
- it('should handle empty imageList', async () => {
1128
- // 创建测试数据
1129
- await serverDB.insert(messages).values({
1130
- id: 'msg-no-images',
1131
- userId,
1132
- role: 'user',
1133
- content: 'original content',
1134
- });
1135
-
1136
- // 调用 update 方法,不提供 imageList
1137
- await messageModel.update('msg-no-images', {
1138
- content: 'updated content',
1139
- });
1140
-
1141
- // 验证消息更新成功
1142
- const updatedMessage = await serverDB
1143
- .select()
1144
- .from(messages)
1145
- .where(eq(messages.id, 'msg-no-images'));
1146
-
1147
- expect(updatedMessage[0].content).toBe('updated content');
1148
-
1149
- // 验证没有创建消息文件关联
1150
- const messageFiles = await serverDB
1151
- .select()
1152
- .from(messagesFiles)
1153
- .where(eq(messagesFiles.messageId, 'msg-no-images'));
1154
-
1155
- expect(messageFiles).toHaveLength(0);
1156
- });
1157
-
1158
- it('should update multiple fields at once', async () => {
1159
- // 创建测试数据
1160
- await serverDB.insert(messages).values({
1161
- id: 'msg-multi-update',
1162
- userId,
1163
- role: 'user',
1164
- content: 'original content',
1165
- model: 'gpt-3.5',
1166
- });
1167
-
1168
- // 调用 update 方法,更新多个字段
1169
- await messageModel.update('msg-multi-update', {
1170
- content: 'updated content',
1171
- role: 'assistant',
1172
- model: 'gpt-4',
1173
- metadata: { tps: 1 },
1174
- });
1175
-
1176
- // 验证消息更新成功
1177
- const updatedMessage = await serverDB
1178
- .select()
1179
- .from(messages)
1180
- .where(eq(messages.id, 'msg-multi-update'));
1181
-
1182
- expect(updatedMessage[0].content).toBe('updated content');
1183
- expect(updatedMessage[0].role).toBe('assistant');
1184
- expect(updatedMessage[0].model).toBe('gpt-4');
1185
- expect(updatedMessage[0].metadata).toEqual({ tps: 1 });
1186
- });
1187
- });
1188
- });
1189
-
1190
- describe('deleteMessage', () => {
1191
- it('should delete a message', async () => {
1192
- // 创建测试数据
1193
- await serverDB
1194
- .insert(messages)
1195
- .values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
1196
-
1197
- // 调用 deleteMessage 方法
1198
- await messageModel.deleteMessage('1');
1199
-
1200
- // 断言结果
1201
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1202
- expect(result).toHaveLength(0);
1203
- });
1204
-
1205
- it('should delete a message with tool calls', async () => {
1206
- // 创建测试数据
1207
- await serverDB.transaction(async (trx) => {
1208
- await trx.insert(messages).values([
1209
- { id: '1', userId, role: 'user', content: 'message 1', tools: [{ id: 'tool1' }] },
1210
- { id: '2', userId, role: 'tool', content: 'message 1' },
1211
- ]);
1212
- await trx
1213
- .insert(messagePlugins)
1214
- .values([{ id: '2', toolCallId: 'tool1', identifier: 'plugin-1', userId }]);
1215
- });
1216
-
1217
- // 调用 deleteMessage 方法
1218
- await messageModel.deleteMessage('1');
1219
-
1220
- // 断言结果
1221
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1222
- expect(result).toHaveLength(0);
1223
-
1224
- const result2 = await serverDB
1225
- .select()
1226
- .from(messagePlugins)
1227
- .where(eq(messagePlugins.id, '2'));
1228
-
1229
- expect(result2).toHaveLength(0);
1230
- });
1231
-
1232
- it('should only delete messages belonging to the user', async () => {
1233
- // 创建测试数据
1234
- await serverDB
1235
- .insert(messages)
1236
- .values([{ id: '1', userId: '456', role: 'user', content: 'message 1' }]);
1237
-
1238
- // 调用 deleteMessage 方法
1239
- await messageModel.deleteMessage('1');
1240
-
1241
- // 断言结果
1242
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1243
- expect(result).toHaveLength(1);
1244
- });
1245
- });
1246
-
1247
- describe('deleteMessages', () => {
1248
- it('should delete 2 messages', async () => {
1249
- // 创建测试数据
1250
- await serverDB.insert(messages).values([
1251
- { id: '1', userId, role: 'user', content: 'message 1' },
1252
- { id: '2', userId, role: 'user', content: 'message 2' },
1253
- ]);
1254
-
1255
- // 调用 deleteMessage 方法
1256
- await messageModel.deleteMessages(['1', '2']);
1257
-
1258
- // 断言结果
1259
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1260
- expect(result).toHaveLength(0);
1261
- const result2 = await serverDB.select().from(messages).where(eq(messages.id, '2'));
1262
- expect(result2).toHaveLength(0);
1263
- });
1264
-
1265
- it('should only delete messages belonging to the user', async () => {
1266
- // 创建测试数据
1267
- await serverDB.insert(messages).values([
1268
- { id: '1', userId: '456', role: 'user', content: 'message 1' },
1269
- { id: '2', userId: '456', role: 'user', content: 'message 1' },
1270
- ]);
1271
-
1272
- // 调用 deleteMessage 方法
1273
- await messageModel.deleteMessages(['1', '2']);
1274
-
1275
- // 断言结果
1276
- const result = await serverDB.select().from(messages).where(eq(messages.id, '1'));
1277
- expect(result).toHaveLength(1);
1278
- });
1279
- });
1280
-
1281
- describe('deleteAllMessages', () => {
1282
- it('should delete all messages belonging to the user', async () => {
1283
- // 创建测试数据
1284
- await serverDB.insert(messages).values([
1285
- { id: '1', userId, role: 'user', content: 'message 1' },
1286
- { id: '2', userId, role: 'user', content: 'message 2' },
1287
- { id: '3', userId: '456', role: 'user', content: 'message 3' },
1288
- ]);
1289
-
1290
- // 调用 deleteAllMessages 方法
1291
- await messageModel.deleteAllMessages();
1292
-
1293
- // 断言结果
1294
- const result = await serverDB.select().from(messages).where(eq(messages.userId, userId));
1295
-
1296
- expect(result).toHaveLength(0);
1297
-
1298
- const otherResult = await serverDB.select().from(messages).where(eq(messages.userId, '456'));
1299
-
1300
- expect(otherResult).toHaveLength(1);
1301
- });
1302
- });
1303
-
1304
- describe('updatePluginState', () => {
1305
- it('should update the state field in messagePlugins table', async () => {
1306
- // 创建测试数据
1307
- await serverDB.insert(messages).values({ id: '1', content: 'abc', role: 'user', userId });
1308
- await serverDB.insert(messagePlugins).values([
1309
- {
1310
- id: '1',
1311
- toolCallId: 'tool1',
1312
- identifier: 'plugin1',
1313
- state: { key1: 'value1' },
1314
- userId,
1315
- },
1316
- ]);
1317
-
1318
- // 调用 updatePluginState 方法
1319
- await messageModel.updatePluginState('1', { key2: 'value2' });
1320
-
1321
- // 断言结果
1322
- const result = await serverDB.select().from(messagePlugins).where(eq(messagePlugins.id, '1'));
1323
-
1324
- expect(result[0].state).toEqual({ key1: 'value1', key2: 'value2' });
1325
- });
1326
-
1327
- it('should throw an error if plugin does not exist', async () => {
1328
- // 调用 updatePluginState 方法
1329
- await expect(messageModel.updatePluginState('1', { key: 'value' })).rejects.toThrowError(
1330
- 'Plugin not found',
1331
- );
1332
- });
1333
- });
1334
- describe('updateMessagePlugin', () => {
1335
- it('should update the state field in messagePlugins table', async () => {
1336
- // 创建测试数据
1337
- await serverDB.insert(messages).values({ id: '1', content: 'abc', role: 'user', userId });
1338
- await serverDB.insert(messagePlugins).values([
1339
- {
1340
- id: '1',
1341
- toolCallId: 'tool1',
1342
- identifier: 'plugin1',
1343
- state: { key1: 'value1' },
1344
- userId,
1345
- },
1346
- ]);
1347
-
1348
- // 调用 updatePluginState 方法
1349
- await messageModel.updateMessagePlugin('1', { identifier: 'plugin2' });
1350
-
1351
- // 断言结果
1352
- const result = await serverDB.select().from(messagePlugins).where(eq(messagePlugins.id, '1'));
1353
-
1354
- expect(result[0].identifier).toEqual('plugin2');
1355
- });
1356
-
1357
- it('should throw an error if plugin does not exist', async () => {
1358
- // 调用 updatePluginState 方法
1359
- await expect(messageModel.updatePluginState('1', { key: 'value' })).rejects.toThrowError(
1360
- 'Plugin not found',
1361
- );
1362
- });
1363
- });
1364
-
1365
- describe('updateMetadata', () => {
1366
- it('should update metadata for an existing message', async () => {
1367
- // 创建测试数据
1368
- await serverDB.insert(messages).values({
1369
- id: 'msg-with-metadata',
1370
- userId,
1371
- role: 'user',
1372
- content: 'test message',
1373
- metadata: { existingKey: 'existingValue' },
1374
- });
1375
-
1376
- // 调用 updateMetadata 方法
1377
- await messageModel.updateMetadata('msg-with-metadata', { newKey: 'newValue' });
1378
-
1379
- // 断言结果
1380
- const result = await serverDB
1381
- .select()
1382
- .from(messages)
1383
- .where(eq(messages.id, 'msg-with-metadata'));
1384
-
1385
- expect(result[0].metadata).toEqual({
1386
- existingKey: 'existingValue',
1387
- newKey: 'newValue',
1388
- });
1389
- });
1390
-
1391
- it('should merge new metadata with existing metadata using lodash merge behavior', async () => {
1392
- // 创建测试数据
1393
- await serverDB.insert(messages).values({
1394
- id: 'msg-merge-metadata',
1395
- userId,
1396
- role: 'assistant',
1397
- content: 'test message',
1398
- metadata: {
1399
- level1: {
1400
- level2a: 'original',
1401
- level2b: { level3: 'deep' },
1402
- },
1403
- array: [1, 2, 3],
1404
- },
1405
- });
1406
-
1407
- // 调用 updateMetadata 方法
1408
- await messageModel.updateMetadata('msg-merge-metadata', {
1409
- level1: {
1410
- level2a: 'updated',
1411
- level2c: 'new',
1412
- },
1413
- newTopLevel: 'value',
1414
- });
1415
-
1416
- // 断言结果 - 应该使用 lodash merge 行为
1417
- const result = await serverDB
1418
- .select()
1419
- .from(messages)
1420
- .where(eq(messages.id, 'msg-merge-metadata'));
1421
-
1422
- expect(result[0].metadata).toEqual({
1423
- level1: {
1424
- level2a: 'updated',
1425
- level2b: { level3: 'deep' },
1426
- level2c: 'new',
1427
- },
1428
- array: [1, 2, 3],
1429
- newTopLevel: 'value',
1430
- });
1431
- });
1432
-
1433
- it('should handle non-existent message IDs', async () => {
1434
- // 调用 updateMetadata 方法,尝试更新不存在的消息
1435
- const result = await messageModel.updateMetadata('non-existent-id', { key: 'value' });
1436
-
1437
- // 断言结果 - 应该返回 undefined
1438
- expect(result).toBeUndefined();
1439
- });
1440
-
1441
- it('should handle empty metadata updates', async () => {
1442
- // 创建测试数据
1443
- await serverDB.insert(messages).values({
1444
- id: 'msg-empty-metadata',
1445
- userId,
1446
- role: 'user',
1447
- content: 'test message',
1448
- metadata: { originalKey: 'originalValue' },
1449
- });
1450
-
1451
- // 调用 updateMetadata 方法,传递空对象
1452
- await messageModel.updateMetadata('msg-empty-metadata', {});
1453
-
1454
- // 断言结果 - 原始 metadata 应该保持不变
1455
- const result = await serverDB
1456
- .select()
1457
- .from(messages)
1458
- .where(eq(messages.id, 'msg-empty-metadata'));
1459
-
1460
- expect(result[0].metadata).toEqual({ originalKey: 'originalValue' });
1461
- });
1462
-
1463
- it('should handle message with null metadata', async () => {
1464
- // 创建测试数据
1465
- await serverDB.insert(messages).values({
1466
- id: 'msg-null-metadata',
1467
- userId,
1468
- role: 'user',
1469
- content: 'test message',
1470
- metadata: null,
1471
- });
1472
-
1473
- // 调用 updateMetadata 方法
1474
- await messageModel.updateMetadata('msg-null-metadata', { key: 'value' });
1475
-
1476
- // 断言结果 - 应该创建新的 metadata
1477
- const result = await serverDB
1478
- .select()
1479
- .from(messages)
1480
- .where(eq(messages.id, 'msg-null-metadata'));
1481
-
1482
- expect(result[0].metadata).toEqual({ key: 'value' });
1483
- });
1484
-
1485
- it('should only update messages belonging to the current user', async () => {
1486
- // 创建测试数据 - 其他用户的消息
1487
- await serverDB.insert(messages).values({
1488
- id: 'msg-other-user',
1489
- userId: '456',
1490
- role: 'user',
1491
- content: 'test message',
1492
- metadata: { originalKey: 'originalValue' },
1493
- });
1494
-
1495
- // 调用 updateMetadata 方法
1496
- const result = await messageModel.updateMetadata('msg-other-user', {
1497
- hackedKey: 'hackedValue',
1498
- });
1499
-
1500
- // 断言结果 - 应该返回 undefined
1501
- expect(result).toBeUndefined();
1502
-
1503
- // 验证原始 metadata 未被修改
1504
- const dbResult = await serverDB
1505
- .select()
1506
- .from(messages)
1507
- .where(eq(messages.id, 'msg-other-user'));
1508
-
1509
- expect(dbResult[0].metadata).toEqual({ originalKey: 'originalValue' });
1510
- });
1511
-
1512
- it('should handle complex nested metadata updates', async () => {
1513
- // 创建测试数据
1514
- await serverDB.insert(messages).values({
1515
- id: 'msg-complex-metadata',
1516
- userId,
1517
- role: 'assistant',
1518
- content: 'test message',
1519
- metadata: {
1520
- config: {
1521
- settings: {
1522
- enabled: true,
1523
- options: ['a', 'b'],
1524
- },
1525
- version: 1,
1526
- },
1527
- },
1528
- });
1529
-
1530
- // 调用 updateMetadata 方法
1531
- await messageModel.updateMetadata('msg-complex-metadata', {
1532
- config: {
1533
- settings: {
1534
- enabled: false,
1535
- timeout: 5000,
1536
- },
1537
- newField: 'value',
1538
- },
1539
- stats: { count: 10 },
1540
- });
1541
-
1542
- // 断言结果
1543
- const result = await serverDB
1544
- .select()
1545
- .from(messages)
1546
- .where(eq(messages.id, 'msg-complex-metadata'));
1547
-
1548
- expect(result[0].metadata).toEqual({
1549
- config: {
1550
- settings: {
1551
- enabled: false,
1552
- options: ['a', 'b'],
1553
- timeout: 5000,
1554
- },
1555
- version: 1,
1556
- newField: 'value',
1557
- },
1558
- stats: { count: 10 },
1559
- });
1560
- });
1561
- });
1562
-
1563
- describe('updateTranslate', () => {
1564
- it('should insert a new record if message does not exist in messageTranslates table', async () => {
1565
- // 创建测试数据
1566
- await serverDB
1567
- .insert(messages)
1568
- .values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
1569
-
1570
- // 调用 updateTranslate 方法
1571
- await messageModel.updateTranslate('1', {
1572
- content: 'translated message 1',
1573
- from: 'en',
1574
- to: 'zh',
1575
- });
1576
-
1577
- // 断言结果
1578
- const result = await serverDB
1579
- .select()
1580
- .from(messageTranslates)
1581
- .where(eq(messageTranslates.id, '1'));
1582
-
1583
- expect(result).toHaveLength(1);
1584
- expect(result[0].content).toBe('translated message 1');
1585
- });
1586
-
1587
- it('should update the corresponding fields if message exists in messageTranslates table', async () => {
1588
- // 创建测试数据
1589
- await serverDB.transaction(async (trx) => {
1590
- await trx
1591
- .insert(messages)
1592
- .values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
1593
- await trx
1594
- .insert(messageTranslates)
1595
- .values([{ id: '1', content: 'translated message 1', from: 'en', to: 'zh', userId }]);
1596
- });
1597
-
1598
- // 调用 updateTranslate 方法
1599
- await messageModel.updateTranslate('1', { content: 'updated translated message 1' });
1600
-
1601
- // 断言结果
1602
- const result = await serverDB
1603
- .select()
1604
- .from(messageTranslates)
1605
- .where(eq(messageTranslates.id, '1'));
1606
-
1607
- expect(result[0].content).toBe('updated translated message 1');
1608
- });
1609
- });
1610
-
1611
- describe('updateTTS', () => {
1612
- it('should insert a new record if message does not exist in messageTTS table', async () => {
1613
- // 创建测试数据
1614
- await serverDB
1615
- .insert(messages)
1616
- .values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
1617
-
1618
- // 调用 updateTTS 方法
1619
- await messageModel.updateTTS('1', { contentMd5: 'md5', file: 'f1', voice: 'voice1' });
1620
-
1621
- // 断言结果
1622
- const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
1623
-
1624
- expect(result).toHaveLength(1);
1625
- expect(result[0].voice).toBe('voice1');
1626
- });
1627
-
1628
- it('should update the corresponding fields if message exists in messageTTS table', async () => {
1629
- // 创建测试数据
1630
- await serverDB.transaction(async (trx) => {
1631
- await trx
1632
- .insert(messages)
1633
- .values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
1634
- await trx
1635
- .insert(messageTTS)
1636
- .values([{ id: '1', contentMd5: 'md5', fileId: 'f1', voice: 'voice1', userId }]);
1637
- });
1638
-
1639
- // 调用 updateTTS 方法
1640
- await messageModel.updateTTS('1', { voice: 'updated voice1' });
1641
-
1642
- // 断言结果
1643
- const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
1644
-
1645
- expect(result[0].voice).toBe('updated voice1');
1646
- });
1647
- });
1648
-
1649
- describe('deleteMessageTranslate', () => {
1650
- it('should delete the message translate record', async () => {
1651
- // 创建测试数据
1652
- await serverDB.insert(messages).values([{ id: '1', role: 'abc', userId }]);
1653
- await serverDB.insert(messageTranslates).values([{ id: '1', userId }]);
1654
-
1655
- // 调用 deleteMessageTranslate 方法
1656
- await messageModel.deleteMessageTranslate('1');
1657
-
1658
- // 断言结果
1659
- const result = await serverDB
1660
- .select()
1661
- .from(messageTranslates)
1662
- .where(eq(messageTranslates.id, '1'));
1663
-
1664
- expect(result).toHaveLength(0);
1665
- });
1666
- });
1667
-
1668
- describe('deleteMessageTTS', () => {
1669
- it('should delete the message TTS record', async () => {
1670
- // 创建测试数据
1671
- await serverDB.insert(messages).values([{ id: '1', role: 'abc', userId }]);
1672
- await serverDB.insert(messageTTS).values([{ userId, id: '1' }]);
1673
-
1674
- // 调用 deleteMessageTTS 方法
1675
- await messageModel.deleteMessageTTS('1');
1676
-
1677
- // 断言结果
1678
- const result = await serverDB.select().from(messageTTS).where(eq(messageTTS.id, '1'));
1679
- expect(result).toHaveLength(0);
1680
- });
1681
- });
1682
-
1683
- describe('count', () => {
1684
- it('should return the count of messages belonging to the user', async () => {
1685
- // 创建测试数据
1686
- await serverDB.insert(messages).values([
1687
- { id: '1', userId, role: 'user', content: 'message 1' },
1688
- { id: '2', userId, role: 'user', content: 'message 2' },
1689
- { id: '3', userId: '456', role: 'user', content: 'message 3' },
1690
- ]);
1691
-
1692
- // 调用 count 方法
1693
- const result = await messageModel.count();
1694
-
1695
- // 断言结果
1696
- expect(result).toBe(2);
1697
- });
1698
-
1699
- describe('count with date filters', () => {
1700
- beforeEach(async () => {
1701
- // 创建测试数据,包含不同日期的消息
1702
- await serverDB.insert(messages).values([
1703
- {
1704
- id: 'date1',
1705
- userId,
1706
- role: 'user',
1707
- content: 'message 1',
1708
- createdAt: new Date('2023-01-15'),
1709
- },
1710
- {
1711
- id: 'date2',
1712
- userId,
1713
- role: 'user',
1714
- content: 'message 2',
1715
- createdAt: new Date('2023-02-15'),
1716
- },
1717
- {
1718
- id: 'date3',
1719
- userId,
1720
- role: 'user',
1721
- content: 'message 3',
1722
- createdAt: new Date('2023-03-15'),
1723
- },
1724
- {
1725
- id: 'date4',
1726
- userId,
1727
- role: 'user',
1728
- content: 'message 4',
1729
- createdAt: new Date('2023-04-15'),
1730
- },
1731
- ]);
1732
- });
1733
-
1734
- it('should count messages with startDate filter', async () => {
1735
- const result = await messageModel.count({ startDate: '2023-02-01' });
1736
- expect(result).toBe(3); // 2月15日, 3月15日, 4月15日的消息
1737
- });
1738
-
1739
- it('should count messages with endDate filter', async () => {
1740
- const result = await messageModel.count({ endDate: '2023-03-01' });
1741
- expect(result).toBe(2); // 1月15日, 2月15日的消息
1742
- });
1743
-
1744
- it('should count messages with both startDate and endDate filters', async () => {
1745
- const result = await messageModel.count({
1746
- startDate: '2023-02-01',
1747
- endDate: '2023-03-31',
1748
- });
1749
- expect(result).toBe(2); // 2月15日, 3月15日的消息
1750
- });
1751
-
1752
- it('should count messages with range filter', async () => {
1753
- const result = await messageModel.count({
1754
- range: ['2023-02-01', '2023-04-01'],
1755
- });
1756
- expect(result).toBe(2); // 2月15日, 3月15日的消息
1757
- });
1758
-
1759
- it('should handle edge cases in date filters', async () => {
1760
- // 边界日期
1761
- const result1 = await messageModel.count({
1762
- startDate: '2023-01-15',
1763
- endDate: '2023-04-15',
1764
- });
1765
- expect(result1).toBe(4); // 包含所有消息
1766
-
1767
- // 没有消息的日期范围
1768
- const result2 = await messageModel.count({
1769
- startDate: '2023-05-01',
1770
- endDate: '2023-06-01',
1771
- });
1772
- expect(result2).toBe(0);
1773
-
1774
- // 精确到一天
1775
- const result3 = await messageModel.count({
1776
- startDate: '2023-01-15',
1777
- endDate: '2023-01-15',
1778
- });
1779
- expect(result3).toBe(1);
1780
- });
1781
- });
1782
- });
1783
-
1784
- describe('findMessageQueriesById', () => {
1785
- it('should return undefined for non-existent message query', async () => {
1786
- const result = await messageModel.findMessageQueriesById('non-existent-id');
1787
- expect(result).toBeUndefined();
1788
- });
1789
-
1790
- it('should return message query with embeddings', async () => {
1791
- const query1Id = uuid();
1792
- const embeddings1Id = uuid();
1793
-
1794
- await serverDB.transaction(async (trx) => {
1795
- await trx.insert(messages).values({ id: 'msg1', userId, role: 'user', content: 'abc' });
1796
-
1797
- await trx.insert(embeddings).values({
1798
- id: embeddings1Id,
1799
- embeddings: codeEmbedding,
1800
- });
1801
-
1802
- await trx.insert(messageQueries).values({
1803
- id: query1Id,
1804
- messageId: 'msg1',
1805
- userQuery: 'test query',
1806
- rewriteQuery: 'rewritten query',
1807
- embeddingsId: embeddings1Id,
1808
- userId,
1809
- });
1810
- });
1811
-
1812
- const result = await messageModel.findMessageQueriesById('msg1');
1813
-
1814
- expect(result).toBeDefined();
1815
- expect(result).toMatchObject({
1816
- id: query1Id,
1817
- userQuery: 'test query',
1818
- rewriteQuery: 'rewritten query',
1819
- embeddings: codeEmbedding,
1820
- });
1821
- });
1822
- });
1823
-
1824
- describe('deleteMessagesBySession', () => {
1825
- it('should delete messages by session ID', async () => {
1826
- await serverDB.insert(sessions).values([
1827
- { id: 'session1', userId },
1828
- { id: 'session2', userId },
1829
- ]);
1830
-
1831
- await serverDB.insert(messages).values([
1832
- {
1833
- id: '1',
1834
- userId,
1835
- sessionId: 'session1',
1836
- role: 'user',
1837
- content: 'message 1',
1838
- },
1839
- {
1840
- id: '2',
1841
- userId,
1842
- sessionId: 'session1',
1843
- role: 'assistant',
1844
- content: 'message 2',
1845
- },
1846
- {
1847
- id: '3',
1848
- userId,
1849
- sessionId: 'session2',
1850
- role: 'user',
1851
- content: 'message 3',
1852
- },
1853
- ]);
1854
-
1855
- await messageModel.deleteMessagesBySession('session1');
1856
-
1857
- const remainingMessages = await serverDB
1858
- .select()
1859
- .from(messages)
1860
- .where(eq(messages.userId, userId));
1861
-
1862
- expect(remainingMessages).toHaveLength(1);
1863
- expect(remainingMessages[0].id).toBe('3');
1864
- });
1865
-
1866
- it('should delete messages by session ID and topic ID', async () => {
1867
- await serverDB.insert(sessions).values([{ id: 'session1', userId }]);
1868
- await serverDB.insert(topics).values([
1869
- { id: 'topic1', sessionId: 'session1', userId },
1870
- { id: 'topic2', sessionId: 'session1', userId },
1871
- ]);
1872
-
1873
- await serverDB.insert(messages).values([
1874
- {
1875
- id: '1',
1876
- userId,
1877
- sessionId: 'session1',
1878
- topicId: 'topic1',
1879
- role: 'user',
1880
- content: 'message 1',
1881
- },
1882
- {
1883
- id: '2',
1884
- userId,
1885
- sessionId: 'session1',
1886
- topicId: 'topic2',
1887
- role: 'assistant',
1888
- content: 'message 2',
1889
- },
1890
- ]);
1891
-
1892
- await messageModel.deleteMessagesBySession('session1', 'topic1');
1893
-
1894
- const remainingMessages = await serverDB
1895
- .select()
1896
- .from(messages)
1897
- .where(eq(messages.userId, userId));
1898
-
1899
- expect(remainingMessages).toHaveLength(1);
1900
- expect(remainingMessages[0].id).toBe('2');
1901
- });
1902
- });
1903
-
1904
- describe('genId', () => {
1905
- it('should generate unique message IDs', () => {
1906
- const model = new MessageModel(serverDB, userId);
1907
- // @ts-ignore - accessing private method for testing
1908
- const id1 = model.genId();
1909
- // @ts-ignore - accessing private method for testing
1910
- const id2 = model.genId();
1911
-
1912
- expect(id1).toHaveLength(18);
1913
- expect(id2).toHaveLength(18);
1914
- expect(id1).not.toBe(id2);
1915
- expect(id1).toMatch(/^msg_/);
1916
- expect(id2).toMatch(/^msg_/);
1917
- });
1918
- });
1919
-
1920
- describe('countWords', () => {
1921
- it('should count total words of messages belonging to the user', async () => {
1922
- // 创建测试数据
1923
- await serverDB.insert(messages).values([
1924
- { id: '1', userId, role: 'user', content: 'hello world' },
1925
- { id: '2', userId, role: 'user', content: 'test message' },
1926
- { id: '3', userId: '456', role: 'user', content: 'other user message' },
1927
- ]);
1928
-
1929
- // 调用 countWords 方法
1930
- const result = await messageModel.countWords();
1931
-
1932
- // 断言结果 - 'hello world' + 'test message' = 23 characters
1933
- expect(result).toEqual(23);
1934
- });
1935
-
1936
- it('should count words within date range', async () => {
1937
- // 创建测试数据
1938
- await serverDB.insert(messages).values([
1939
- {
1940
- id: '1',
1941
- userId,
1942
- role: 'user',
1943
- content: 'old message',
1944
- createdAt: new Date('2023-01-01'),
1945
- },
1946
- {
1947
- id: '2',
1948
- userId,
1949
- role: 'user',
1950
- content: 'new message',
1951
- createdAt: new Date('2023-06-01'),
1952
- },
1953
- ]);
1954
-
1955
- // 调用 countWords 方法,设置日期范围
1956
- const result = await messageModel.countWords({
1957
- range: ['2023-05-01', '2023-07-01'],
1958
- });
1959
-
1960
- // 断言结果 - 只计算 'new message' = 11 characters
1961
- expect(result).toEqual(11);
1962
- });
1963
-
1964
- it('should handle empty content', async () => {
1965
- // 创建测试数据
1966
- await serverDB.insert(messages).values([
1967
- { id: '1', userId, role: 'user', content: '' },
1968
- { id: '2', userId, role: 'user', content: null },
1969
- ]);
1970
-
1971
- // 调用 countWords 方法
1972
- const result = await messageModel.countWords();
1973
-
1974
- // 断言结果
1975
- expect(result).toEqual(0);
1976
- });
1977
- });
1978
-
1979
- describe('getHeatmaps', () => {
1980
- it('should return heatmap data for the last year', async () => {
1981
- // 使用固定日期进行测试
1982
- vi.useFakeTimers();
1983
- const fixedDate = new Date('2023-04-07T13:00:00Z');
1984
- vi.setSystemTime(fixedDate);
1985
-
1986
- const today = dayjs(fixedDate);
1987
- const twoDaysAgoDate = today.subtract(2, 'day').format('YYYY-MM-DD');
1988
- const oneDayAgoDate = today.subtract(1, 'day').format('YYYY-MM-DD');
1989
- const todayDate = today.format('YYYY-MM-DD');
1990
-
1991
- // 创建测试数据
1992
- await serverDB.insert(messages).values([
1993
- {
1994
- id: '1',
1995
- userId,
1996
- role: 'user',
1997
- content: 'message 1',
1998
- createdAt: today.subtract(2, 'day').toDate(),
1999
- },
2000
- {
2001
- id: '2',
2002
- userId,
2003
- role: 'user',
2004
- content: 'message 2',
2005
- createdAt: today.subtract(2, 'day').toDate(),
2006
- },
2007
- {
2008
- id: '3',
2009
- userId,
2010
- role: 'user',
2011
- content: 'message 3',
2012
- createdAt: today.subtract(1, 'day').toDate(),
2013
- },
2014
- ]);
2015
-
2016
- // 调用 getHeatmaps 方法
2017
- const result = await messageModel.getHeatmaps();
2018
-
2019
- // 断言结果
2020
- expect(result.length).toBeGreaterThanOrEqual(366);
2021
- expect(result.length).toBeLessThan(368);
2022
-
2023
- // 检查两天前的数据
2024
- const twoDaysAgo = result.find((item) => item.date === twoDaysAgoDate);
2025
- expect(twoDaysAgo?.count).toBe(2);
2026
- expect(twoDaysAgo?.level).toBe(1);
2027
-
2028
- // 检查一天前的数据
2029
- const oneDayAgo = result.find((item) => item.date === oneDayAgoDate);
2030
- expect(oneDayAgo?.count).toBe(1);
2031
- expect(oneDayAgo?.level).toBe(1);
2032
-
2033
- // 检查今天的数据
2034
- const todayData = result.find((item) => item.date === todayDate);
2035
- expect(todayData?.count).toBe(0);
2036
- expect(todayData?.level).toBe(0);
2037
-
2038
- vi.useRealTimers();
2039
- });
2040
-
2041
- it('should calculate correct levels based on message count', async () => {
2042
- // 使用固定日期进行测试
2043
- vi.useFakeTimers();
2044
- const fixedDate = new Date('2023-05-15T12:00:00Z');
2045
- vi.setSystemTime(fixedDate);
2046
-
2047
- const today = dayjs(fixedDate);
2048
- const fourDaysAgoDate = today.subtract(4, 'day').format('YYYY-MM-DD');
2049
- const threeDaysAgoDate = today.subtract(3, 'day').format('YYYY-MM-DD');
2050
- const twoDaysAgoDate = today.subtract(2, 'day').format('YYYY-MM-DD');
2051
- const oneDayAgoDate = today.subtract(1, 'day').format('YYYY-MM-DD');
2052
- const todayDate = today.format('YYYY-MM-DD');
2053
-
2054
- // 创建测试数据 - 不同数量的消息以测试不同的等级
2055
- await serverDB.insert(messages).values([
2056
- // 1 message - level 1
2057
- {
2058
- id: '1',
2059
- userId,
2060
- role: 'user',
2061
- content: 'message 1',
2062
- createdAt: today.subtract(4, 'day').toDate(),
2063
- },
2064
- // 6 messages - level 2
2065
- ...Array(6)
2066
- .fill(0)
2067
- .map((_, i) => ({
2068
- id: `2-${i}`,
2069
- userId,
2070
- role: 'user',
2071
- content: `message 2-${i}`,
2072
- createdAt: today.subtract(3, 'day').toDate(),
2073
- })),
2074
- // 11 messages - level 3
2075
- ...Array(11)
2076
- .fill(0)
2077
- .map((_, i) => ({
2078
- id: `3-${i}`,
2079
- userId,
2080
- role: 'user',
2081
- content: `message 3-${i}`,
2082
- createdAt: today.subtract(2, 'day').toDate(),
2083
- })),
2084
- // 16 messages - level 4
2085
- ...Array(16)
2086
- .fill(0)
2087
- .map((_, i) => ({
2088
- id: `4-${i}`,
2089
- userId,
2090
- role: 'user',
2091
- content: `message 4-${i}`,
2092
- createdAt: today.subtract(1, 'day').toDate(),
2093
- })),
2094
- // 21 messages - level 4
2095
- ...Array(21)
2096
- .fill(0)
2097
- .map((_, i) => ({
2098
- id: `5-${i}`,
2099
- userId,
2100
- role: 'user',
2101
- content: `message 5-${i}`,
2102
- createdAt: today.toDate(),
2103
- })),
2104
- ]);
2105
-
2106
- // 调用 getHeatmaps 方法
2107
- const result = await messageModel.getHeatmaps();
2108
-
2109
- // 检查不同天数的等级
2110
- const fourDaysAgo = result.find((item) => item.date === fourDaysAgoDate);
2111
- expect(fourDaysAgo?.count).toBe(1);
2112
- expect(fourDaysAgo?.level).toBe(1);
2113
-
2114
- const threeDaysAgo = result.find((item) => item.date === threeDaysAgoDate);
2115
- expect(threeDaysAgo?.count).toBe(6);
2116
- expect(threeDaysAgo?.level).toBe(2);
2117
-
2118
- const twoDaysAgo = result.find((item) => item.date === twoDaysAgoDate);
2119
- expect(twoDaysAgo?.count).toBe(11);
2120
- expect(twoDaysAgo?.level).toBe(3);
2121
-
2122
- const oneDayAgo = result.find((item) => item.date === oneDayAgoDate);
2123
- expect(oneDayAgo?.count).toBe(16);
2124
- expect(oneDayAgo?.level).toBe(4);
2125
-
2126
- const todayData = result.find((item) => item.date === todayDate);
2127
- expect(todayData?.count).toBe(21);
2128
- expect(todayData?.level).toBe(4);
2129
-
2130
- vi.useRealTimers();
2131
- });
2132
-
2133
- it.skip('should return time count correctly when 19:00 time', async () => {
2134
- // 使用固定日期进行测试
2135
- vi.useFakeTimers();
2136
- const fixedDate = new Date('2025-04-02T19:00:00Z');
2137
- vi.setSystemTime(fixedDate);
2138
-
2139
- const today = dayjs(fixedDate);
2140
- const twoDaysAgoDate = today.subtract(2, 'day').format('YYYY-MM-DD');
2141
- const oneDayAgoDate = today.subtract(1, 'day').format('YYYY-MM-DD');
2142
- const todayDate = today.format('YYYY-MM-DD');
2143
-
2144
- // 创建测试数据
2145
- await serverDB.insert(messages).values([
2146
- {
2147
- id: '1',
2148
- userId,
2149
- role: 'user',
2150
- content: 'message 1',
2151
- createdAt: today.subtract(2, 'day').toDate(),
2152
- },
2153
- {
2154
- id: '2',
2155
- userId,
2156
- role: 'user',
2157
- content: 'message 2',
2158
- createdAt: today.subtract(2, 'day').toDate(),
2159
- },
2160
- {
2161
- id: '3',
2162
- userId,
2163
- role: 'user',
2164
- content: 'message 3',
2165
- createdAt: today.subtract(1, 'day').toDate(),
2166
- },
2167
- ]);
2168
-
2169
- // 调用 getHeatmaps 方法
2170
- const result = await messageModel.getHeatmaps();
2171
-
2172
- // 断言结果
2173
- expect(result.length).toBeGreaterThanOrEqual(366);
2174
- expect(result.length).toBeLessThan(368);
2175
-
2176
- // 检查两天前的数据
2177
- const twoDaysAgo = result.find((item) => item.date === twoDaysAgoDate);
2178
- expect(twoDaysAgo?.count).toBe(2);
2179
- expect(twoDaysAgo?.level).toBe(1);
2180
-
2181
- // 检查一天前的数据
2182
- const oneDayAgo = result.find((item) => item.date === oneDayAgoDate);
2183
- expect(oneDayAgo?.count).toBe(1);
2184
- expect(oneDayAgo?.level).toBe(1);
2185
-
2186
- // 检查今天的数据
2187
- const todayData = result.find((item) => item.date === todayDate);
2188
- expect(todayData?.count).toBe(0);
2189
- expect(todayData?.level).toBe(0);
2190
-
2191
- vi.useRealTimers();
2192
- });
2193
-
2194
- it('should handle empty data', async () => {
2195
- // 不创建任何消息数据
2196
-
2197
- // 调用 getHeatmaps 方法
2198
- const result = await messageModel.getHeatmaps();
2199
-
2200
- // 断言结果
2201
- expect(result.length).toBeGreaterThanOrEqual(366);
2202
- expect(result.length).toBeLessThan(368);
2203
-
2204
- // 检查所有数据的 count 和 level 是否为 0
2205
- result.forEach((item) => {
2206
- expect(item.count).toBe(0);
2207
- expect(item.level).toBe(0);
2208
- });
2209
- });
2210
- });
2211
-
2212
- describe('rankModels', () => {
2213
- it('should rank models by usage count', async () => {
2214
- // 创建测试数据
2215
- await serverDB.insert(messages).values([
2216
- { id: '1', userId, role: 'assistant', content: 'message 1', model: 'gpt-3.5' },
2217
- { id: '2', userId, role: 'assistant', content: 'message 2', model: 'gpt-3.5' },
2218
- { id: '3', userId, role: 'assistant', content: 'message 3', model: 'gpt-4' },
2219
- { id: '4', userId: '456', role: 'assistant', content: 'message 4', model: 'gpt-3.5' }, // 其他用户的消息
2220
- ]);
2221
-
2222
- // 调用 rankModels 方法
2223
- const result = await messageModel.rankModels();
2224
-
2225
- // 断言结果
2226
- expect(result).toHaveLength(2);
2227
- expect(result[0]).toEqual({ id: 'gpt-3.5', count: 2 }); // 当前用户使用 gpt-3.5 两次
2228
- expect(result[1]).toEqual({ id: 'gpt-4', count: 1 }); // 当前用户使用 gpt-4 一次
2229
- });
2230
-
2231
- it('should only count messages with model field', async () => {
2232
- // 创建测试数据,包括没有 model 字段的消息
2233
- await serverDB.insert(messages).values([
2234
- { id: '1', userId, role: 'assistant', content: 'message 1', model: 'gpt-3.5' },
2235
- { id: '2', userId, role: 'assistant', content: 'message 2', model: null },
2236
- { id: '3', userId, role: 'user', content: 'message 3' }, // 用户消息通常没有 model
2237
- ]);
2238
-
2239
- // 调用 rankModels 方法
2240
- const result = await messageModel.rankModels();
2241
-
2242
- // 断言结果
2243
- expect(result).toHaveLength(1);
2244
- expect(result[0]).toEqual({ id: 'gpt-3.5', count: 1 });
2245
- });
2246
-
2247
- it('should return empty array when no models are used', async () => {
2248
- // 创建测试数据,所有消息都没有 model
2249
- await serverDB.insert(messages).values([
2250
- { id: '1', userId, role: 'user', content: 'message 1' },
2251
- { id: '2', userId, role: 'assistant', content: 'message 2' },
2252
- ]);
2253
-
2254
- // 调用 rankModels 方法
2255
- const result = await messageModel.rankModels();
2256
-
2257
- // 断言结果
2258
- expect(result).toHaveLength(0);
2259
- });
2260
-
2261
- it('should order models by count in descending order', async () => {
2262
- // 创建测试数据,使用不同次数的模型
2263
- await serverDB.insert(messages).values([
2264
- { id: '1', userId, role: 'assistant', content: 'message 1', model: 'gpt-4' },
2265
- { id: '2', userId, role: 'assistant', content: 'message 2', model: 'gpt-3.5' },
2266
- { id: '3', userId, role: 'assistant', content: 'message 3', model: 'gpt-3.5' },
2267
- { id: '4', userId, role: 'assistant', content: 'message 4', model: 'claude' },
2268
- { id: '5', userId, role: 'assistant', content: 'message 5', model: 'gpt-3.5' },
2269
- ]);
2270
-
2271
- // 调用 rankModels 方法
2272
- const result = await messageModel.rankModels();
2273
-
2274
- // 断言结果
2275
- expect(result).toHaveLength(3);
2276
- expect(result[0]).toEqual({ id: 'gpt-3.5', count: 3 }); // 最多使用
2277
- expect(result[1]).toEqual({ id: 'claude', count: 1 });
2278
- expect(result[2]).toEqual({ id: 'gpt-4', count: 1 });
2279
- });
2280
- });
2281
-
2282
- describe('hasMoreThanN', () => {
2283
- it('should return true when message count is greater than N', async () => {
2284
- // 创建测试数据
2285
- await serverDB.insert(messages).values([
2286
- { id: '1', userId, role: 'user', content: 'message 1' },
2287
- { id: '2', userId, role: 'user', content: 'message 2' },
2288
- { id: '3', userId, role: 'user', content: 'message 3' },
2289
- ]);
2290
-
2291
- // 测试不同的 N 值
2292
- const result1 = await messageModel.hasMoreThanN(2); // 3 > 2
2293
- const result2 = await messageModel.hasMoreThanN(3); // 3 ≯ 3
2294
- const result3 = await messageModel.hasMoreThanN(4); // 3 ≯ 4
2295
-
2296
- expect(result1).toBe(true);
2297
- expect(result2).toBe(false);
2298
- expect(result3).toBe(false);
2299
- });
2300
-
2301
- it('should only count messages belonging to the user', async () => {
2302
- // 创建测试数据,包括其他用户的消息
2303
- await serverDB.insert(messages).values([
2304
- { id: '1', userId, role: 'user', content: 'message 1' },
2305
- { id: '2', userId, role: 'user', content: 'message 2' },
2306
- { id: '3', userId: '456', role: 'user', content: 'message 3' }, // 其他用户的消息
2307
- ]);
2308
-
2309
- const result = await messageModel.hasMoreThanN(2);
2310
-
2311
- expect(result).toBe(false); // 当前用户只有 2 条消息,不大于 2
2312
- });
2313
-
2314
- it('should return false when no messages exist', async () => {
2315
- const result = await messageModel.hasMoreThanN(0);
2316
- expect(result).toBe(false);
2317
- });
2318
-
2319
- it('should handle edge cases', async () => {
2320
- // 创建一条消息
2321
- await serverDB
2322
- .insert(messages)
2323
- .values([{ id: '1', userId, role: 'user', content: 'message 1' }]);
2324
-
2325
- // 测试边界情况
2326
- const result1 = await messageModel.hasMoreThanN(0); // 1 > 0
2327
- const result2 = await messageModel.hasMoreThanN(1); // 1 ≯ 1
2328
- const result3 = await messageModel.hasMoreThanN(-1); // 1 > -1
2329
-
2330
- expect(result1).toBe(true);
2331
- expect(result2).toBe(false);
2332
- expect(result3).toBe(true);
2333
- });
2334
- });
2335
-
2336
- describe('createMessageQuery', () => {
2337
- it('should create a new message query', async () => {
2338
- // 创建测试数据
2339
- await serverDB.insert(messages).values({
2340
- id: 'msg1',
2341
- userId,
2342
- role: 'user',
2343
- content: 'test message',
2344
- });
2345
-
2346
- // 调用 createMessageQuery 方法
2347
- const result = await messageModel.createMessageQuery({
2348
- messageId: 'msg1',
2349
- userQuery: 'original query',
2350
- rewriteQuery: 'rewritten query',
2351
- embeddingsId,
2352
- });
2353
-
2354
- // 断言结果
2355
- expect(result).toBeDefined();
2356
- expect(result.id).toBeDefined();
2357
- expect(result.messageId).toBe('msg1');
2358
- expect(result.userQuery).toBe('original query');
2359
- expect(result.rewriteQuery).toBe('rewritten query');
2360
- expect(result.userId).toBe(userId);
2361
-
2362
- // 验证数据库中的记录
2363
- const dbResult = await serverDB
2364
- .select()
2365
- .from(messageQueries)
2366
- .where(eq(messageQueries.id, result.id));
2367
-
2368
- expect(dbResult).toHaveLength(1);
2369
- expect(dbResult[0].messageId).toBe('msg1');
2370
- expect(dbResult[0].userQuery).toBe('original query');
2371
- expect(dbResult[0].rewriteQuery).toBe('rewritten query');
2372
- });
2373
-
2374
- it('should create a message query with embeddings ID', async () => {
2375
- // 创建测试数据
2376
- await serverDB.insert(messages).values({
2377
- id: 'msg2',
2378
- userId,
2379
- role: 'user',
2380
- content: 'test message',
2381
- });
2382
-
2383
- // 调用 createMessageQuery 方法
2384
- const result = await messageModel.createMessageQuery({
2385
- messageId: 'msg2',
2386
- userQuery: 'test query',
2387
- rewriteQuery: 'test rewritten query',
2388
- embeddingsId,
2389
- });
2390
-
2391
- // 断言结果
2392
- expect(result).toBeDefined();
2393
- expect(result.embeddingsId).toBe(embeddingsId);
2394
-
2395
- // 验证数据库中的记录
2396
- const dbResult = await serverDB
2397
- .select()
2398
- .from(messageQueries)
2399
- .where(eq(messageQueries.id, result.id));
2400
-
2401
- expect(dbResult[0].embeddingsId).toBe(embeddingsId);
2402
- });
2403
-
2404
- it('should generate a unique ID for each message query', async () => {
2405
- // 创建测试数据
2406
- await serverDB.insert(messages).values({
2407
- id: 'msg3',
2408
- userId,
2409
- role: 'user',
2410
- content: 'test message',
2411
- });
2412
-
2413
- // 连续创建两个消息查询
2414
- const result1 = await messageModel.createMessageQuery({
2415
- messageId: 'msg3',
2416
- userQuery: 'query 1',
2417
- rewriteQuery: 'rewritten query 1',
2418
- embeddingsId,
2419
- });
2420
-
2421
- const result2 = await messageModel.createMessageQuery({
2422
- messageId: 'msg3',
2423
- userQuery: 'query 2',
2424
- rewriteQuery: 'rewritten query 2',
2425
- embeddingsId,
2426
- });
2427
-
2428
- // 断言结果
2429
- expect(result1.id).not.toBe(result2.id);
2430
- });
2431
- });
2432
-
2433
- describe('updateMessageRAG', () => {
2434
- it('should insert message query chunks for RAG', async () => {
2435
- // prepare message and query
2436
- const messageId = 'rag-msg-1';
2437
- const queryId = uuid();
2438
- const chunk1 = uuid();
2439
- const chunk2 = uuid();
2440
-
2441
- await serverDB.transaction(async (trx) => {
2442
- await trx.insert(messages).values({ id: messageId, role: 'user', userId, content: 'c' });
2443
- await trx.insert(chunks).values([
2444
- { id: chunk1, text: 'a' },
2445
- { id: chunk2, text: 'b' },
2446
- ]);
2447
- await trx
2448
- .insert(messageQueries)
2449
- .values({ id: queryId, messageId, userId, userQuery: 'q', rewriteQuery: 'rq' });
2450
- });
2451
-
2452
- await messageModel.updateMessageRAG(messageId, {
2453
- ragQueryId: queryId,
2454
- fileChunks: [
2455
- { id: chunk1, similarity: 0.9 },
2456
- { id: chunk2, similarity: 0.8 },
2457
- ],
2458
- });
2459
-
2460
- const rows = await serverDB
2461
- .select()
2462
- .from(messageQueryChunks)
2463
- .where(eq(messageQueryChunks.messageId, messageId));
2464
-
2465
- expect(rows).toHaveLength(2);
2466
- const s1 = rows.find((r) => r.chunkId === chunk1)!;
2467
- const s2 = rows.find((r) => r.chunkId === chunk2)!;
2468
- expect(s1.queryId).toBe(queryId);
2469
- expect(s1.similarity).toBe('0.90000');
2470
- expect(s2.similarity).toBe('0.80000');
2471
- });
2472
- });
2473
-
2474
- describe('deleteMessageQuery', () => {
2475
- it('should delete a message query by ID', async () => {
2476
- // 创建测试数据
2477
- const queryId = uuid();
2478
- await serverDB.insert(messages).values({
2479
- id: 'msg4',
2480
- userId,
2481
- role: 'user',
2482
- content: 'test message',
2483
- });
2484
-
2485
- await serverDB.insert(messageQueries).values({
2486
- id: queryId,
2487
- messageId: 'msg4',
2488
- userQuery: 'test query',
2489
- rewriteQuery: 'rewritten query',
2490
- userId,
2491
- });
2492
-
2493
- // 验证查询已创建
2494
- const beforeDelete = await serverDB
2495
- .select()
2496
- .from(messageQueries)
2497
- .where(eq(messageQueries.id, queryId));
2498
-
2499
- expect(beforeDelete).toHaveLength(1);
2500
-
2501
- // 调用 deleteMessageQuery 方法
2502
- await messageModel.deleteMessageQuery(queryId);
2503
-
2504
- // 验证查询已删除
2505
- const afterDelete = await serverDB
2506
- .select()
2507
- .from(messageQueries)
2508
- .where(eq(messageQueries.id, queryId));
2509
-
2510
- expect(afterDelete).toHaveLength(0);
2511
- });
2512
-
2513
- it('should only delete message queries belonging to the user', async () => {
2514
- // 创建测试数据 - 其他用户的查询
2515
- const queryId = uuid();
2516
- await serverDB.insert(messages).values({
2517
- id: 'msg5',
2518
- userId: '456',
2519
- role: 'user',
2520
- content: 'test message',
2521
- });
2522
-
2523
- await serverDB.insert(messageQueries).values({
2524
- id: queryId,
2525
- messageId: 'msg5',
2526
- userQuery: 'test query',
2527
- rewriteQuery: 'rewritten query',
2528
- userId: '456', // 其他用户
2529
- });
2530
-
2531
- // 调用 deleteMessageQuery 方法
2532
- await messageModel.deleteMessageQuery(queryId);
2533
-
2534
- // 验证查询未被删除
2535
- const afterDelete = await serverDB
2536
- .select()
2537
- .from(messageQueries)
2538
- .where(eq(messageQueries.id, queryId));
2539
-
2540
- expect(afterDelete).toHaveLength(1);
2541
- });
2542
-
2543
- it('should throw error when deleting non-existent message query', async () => {
2544
- // 调用 deleteMessageQuery 方法删除不存在的查询
2545
- try {
2546
- await messageModel.deleteMessageQuery('non-existent-id');
2547
- } catch (e) {
2548
- expect(e).toBeInstanceOf(Error);
2549
- }
2550
- });
2551
- });
2552
- });