@lobehub/lobehub 2.0.0-next.2 → 2.0.0-next.20

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 (591) hide show
  1. package/.env.desktop +1 -2
  2. package/.env.example +0 -3
  3. package/.env.example.development +0 -2
  4. package/.github/workflows/desktop-pr-build.yml +18 -16
  5. package/.github/workflows/docker.yml +25 -20
  6. package/.github/workflows/e2e.yml +17 -3
  7. package/.github/workflows/release-desktop-beta.yml +12 -12
  8. package/.github/workflows/release.yml +2 -4
  9. package/.github/workflows/test.yml +8 -10
  10. package/.nvmrc +1 -1
  11. package/CHANGELOG.md +459 -0
  12. package/Dockerfile +1 -3
  13. package/README.md +2 -45
  14. package/README.zh-CN.md +2 -45
  15. package/apps/desktop/src/main/utils/next-electron-rsc.ts +7 -5
  16. package/apps/desktop/tsconfig.json +0 -1
  17. package/changelog/v1.json +150 -0
  18. package/docs/development/database-schema.dbml +11 -1
  19. package/docs/self-hosting/advanced/auth/next-auth/auth0.mdx +2 -2
  20. package/docs/self-hosting/advanced/auth/next-auth/auth0.zh-CN.mdx +2 -2
  21. package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +2 -2
  22. package/docs/self-hosting/advanced/auth/next-auth/authelia.zh-CN.mdx +2 -2
  23. package/docs/self-hosting/advanced/auth/next-auth/authentik.mdx +2 -2
  24. package/docs/self-hosting/advanced/auth/next-auth/authentik.zh-CN.mdx +2 -2
  25. package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +2 -2
  26. package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +2 -2
  27. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.mdx +2 -2
  28. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.zh-CN.mdx +2 -2
  29. package/docs/self-hosting/advanced/auth/next-auth/github.mdx +2 -2
  30. package/docs/self-hosting/advanced/auth/next-auth/github.zh-CN.mdx +2 -2
  31. package/docs/self-hosting/advanced/auth/next-auth/google.mdx +32 -29
  32. package/docs/self-hosting/advanced/auth/next-auth/keycloak.mdx +2 -2
  33. package/docs/self-hosting/advanced/auth/next-auth/keycloak.zh-CN.mdx +2 -2
  34. package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +5 -3
  35. package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +5 -3
  36. package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.mdx +2 -2
  37. package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.zh-CN.mdx +2 -2
  38. package/docs/self-hosting/advanced/auth/next-auth/okta.mdx +2 -2
  39. package/docs/self-hosting/advanced/auth/next-auth/okta.zh-CN.mdx +2 -2
  40. package/docs/self-hosting/advanced/auth/next-auth/wechat.mdx +2 -2
  41. package/docs/self-hosting/advanced/auth/next-auth/wechat.zh-CN.mdx +2 -2
  42. package/docs/self-hosting/advanced/auth/next-auth/zitadel.mdx +2 -2
  43. package/docs/self-hosting/advanced/auth/next-auth/zitadel.zh-CN.mdx +2 -2
  44. package/docs/self-hosting/advanced/auth.mdx +32 -21
  45. package/docs/self-hosting/advanced/auth.zh-CN.mdx +30 -19
  46. package/docs/self-hosting/advanced/feature-flags.mdx +0 -1
  47. package/docs/self-hosting/advanced/feature-flags.zh-CN.mdx +0 -1
  48. package/docs/self-hosting/advanced/online-search.mdx +30 -25
  49. package/docs/self-hosting/advanced/online-search.zh-CN.mdx +25 -23
  50. package/e2e/src/features/discover/smoke.feature +34 -1
  51. package/e2e/src/steps/discover/smoke.steps.ts +116 -4
  52. package/e2e/tsconfig.json +0 -1
  53. package/locales/ar/models.json +15 -6
  54. package/locales/ar/oauth.json +1 -0
  55. package/locales/bg-BG/models.json +15 -6
  56. package/locales/bg-BG/oauth.json +1 -0
  57. package/locales/de-DE/models.json +15 -6
  58. package/locales/de-DE/oauth.json +1 -0
  59. package/locales/en-US/models.json +15 -6
  60. package/locales/en-US/oauth.json +1 -0
  61. package/locales/es-ES/models.json +15 -6
  62. package/locales/es-ES/oauth.json +1 -0
  63. package/locales/fa-IR/models.json +15 -6
  64. package/locales/fa-IR/oauth.json +1 -0
  65. package/locales/fr-FR/models.json +15 -6
  66. package/locales/fr-FR/oauth.json +1 -0
  67. package/locales/it-IT/models.json +15 -6
  68. package/locales/it-IT/oauth.json +1 -0
  69. package/locales/ja-JP/models.json +15 -6
  70. package/locales/ja-JP/oauth.json +1 -0
  71. package/locales/ko-KR/models.json +21 -12
  72. package/locales/ko-KR/oauth.json +1 -0
  73. package/locales/nl-NL/models.json +15 -6
  74. package/locales/nl-NL/oauth.json +1 -0
  75. package/locales/pl-PL/models.json +15 -6
  76. package/locales/pl-PL/oauth.json +1 -0
  77. package/locales/pt-BR/models.json +15 -6
  78. package/locales/pt-BR/oauth.json +1 -0
  79. package/locales/ru-RU/models.json +15 -6
  80. package/locales/ru-RU/oauth.json +1 -0
  81. package/locales/tr-TR/models.json +15 -6
  82. package/locales/tr-TR/oauth.json +1 -0
  83. package/locales/vi-VN/models.json +15 -6
  84. package/locales/vi-VN/oauth.json +1 -0
  85. package/locales/zh-CN/models.json +15 -6
  86. package/locales/zh-CN/oauth.json +1 -0
  87. package/locales/zh-TW/models.json +15 -6
  88. package/locales/zh-TW/oauth.json +1 -0
  89. package/next.config.ts +2 -3
  90. package/package.json +74 -80
  91. package/packages/const/src/index.ts +0 -1
  92. package/packages/const/src/models.ts +13 -0
  93. package/packages/const/src/url.ts +1 -4
  94. package/packages/const/src/version.ts +3 -3
  95. package/packages/context-engine/src/index.ts +1 -6
  96. package/packages/context-engine/src/processors/GroupMessageFlatten.ts +12 -2
  97. package/packages/context-engine/src/processors/__tests__/GroupMessageFlatten.test.ts +73 -9
  98. package/packages/context-engine/src/providers/index.ts +0 -2
  99. package/packages/database/migrations/0041_improve_index.sql +10 -0
  100. package/packages/database/migrations/meta/0041_snapshot.json +7784 -0
  101. package/packages/database/migrations/meta/_journal.json +7 -0
  102. package/packages/database/package.json +1 -1
  103. package/packages/database/src/core/migrations.json +17 -0
  104. package/packages/database/src/core/web-server.ts +2 -1
  105. package/packages/database/src/models/__tests__/message.grouping.test.ts +812 -0
  106. package/packages/database/src/models/__tests__/message.test.ts +322 -170
  107. package/packages/database/src/models/message.ts +62 -24
  108. package/packages/database/src/models/session.ts +60 -19
  109. package/packages/database/src/repositories/dataImporter/deprecated/__tests__/index.test.ts +2 -1
  110. package/packages/database/src/repositories/dataImporter/deprecated/index.ts +7 -1
  111. package/packages/database/src/schemas/agent.ts +10 -11
  112. package/packages/database/src/schemas/message.ts +5 -1
  113. package/packages/database/src/schemas/relations.ts +6 -4
  114. package/packages/database/src/schemas/session.ts +2 -0
  115. package/packages/database/src/schemas/topic.ts +6 -1
  116. package/packages/database/src/utils/__tests__/groupMessages.test.ts +145 -2
  117. package/packages/database/src/utils/groupMessages.ts +7 -5
  118. package/packages/electron-client-ipc/package.json +4 -1
  119. package/packages/file-loaders/package.json +1 -0
  120. package/packages/memory-extract/package.json +1 -1
  121. package/packages/model-bank/src/aiModels/anthropic.ts +0 -63
  122. package/packages/model-bank/src/aiModels/azure.ts +155 -0
  123. package/packages/model-bank/src/aiModels/bedrock.ts +44 -0
  124. package/packages/model-bank/src/aiModels/higress.ts +0 -55
  125. package/packages/model-bank/src/aiModels/infiniai.ts +21 -0
  126. package/packages/model-bank/src/aiModels/ollamacloud.ts +13 -0
  127. package/packages/model-bank/src/aiModels/siliconcloud.ts +19 -0
  128. package/packages/model-runtime/src/core/parameterResolver.ts +3 -0
  129. package/packages/model-runtime/src/core/streams/openai/__snapshots__/responsesStream.test.ts.snap +0 -38
  130. package/packages/model-runtime/src/providers/azureOpenai/index.ts +2 -1
  131. package/packages/model-runtime/src/providers/minimax/index.ts +5 -5
  132. package/packages/model-runtime/src/providers/search1api/index.test.ts +2 -2
  133. package/packages/model-runtime/src/utils/googleErrorParser.test.ts +125 -0
  134. package/packages/model-runtime/src/utils/googleErrorParser.ts +103 -77
  135. package/packages/types/src/message/common/base.ts +13 -0
  136. package/packages/types/src/message/common/image.ts +8 -0
  137. package/packages/types/src/message/common/metadata.ts +39 -0
  138. package/packages/types/src/message/common/tools.ts +10 -0
  139. package/packages/types/src/message/db/params.ts +47 -1
  140. package/packages/types/src/message/ui/chat.ts +4 -1
  141. package/packages/types/src/message/ui/params.ts +98 -4
  142. package/packages/types/src/search.ts +16 -0
  143. package/packages/types/src/serverConfig.ts +2 -6
  144. package/packages/types/src/user/index.ts +13 -1
  145. package/packages/types/src/user/settings/index.ts +22 -0
  146. package/packages/web-crawler/src/crawImpl/firecrawl.ts +39 -12
  147. package/packages/web-crawler/tsconfig.json +0 -1
  148. package/scripts/migrateServerDB/errorHint.js +1 -7
  149. package/scripts/migrateServerDB/index.ts +2 -1
  150. package/src/app/(backend)/webapi/revalidate/route.ts +1 -1
  151. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -8
  152. package/src/app/[variants]/(main)/(mobile)/me/(home)/__tests__/useCategory.test.tsx +9 -0
  153. package/src/app/[variants]/(main)/(mobile)/me/(home)/features/UserBanner.tsx +3 -6
  154. package/src/app/[variants]/(main)/(mobile)/me/(home)/layout.tsx +0 -2
  155. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +1 -4
  156. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/V1Mobile/index.tsx +2 -2
  157. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/V1Mobile/useSend.ts +6 -4
  158. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/useSend.ts +15 -10
  159. package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/Actions.tsx +3 -28
  160. package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/index.tsx +4 -2
  161. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +0 -2
  162. package/src/app/[variants]/(main)/chat/_layout/Mobile.tsx +1 -5
  163. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -62
  164. package/src/app/[variants]/(main)/discover/(list)/features/Pagination.tsx +1 -0
  165. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +1 -1
  166. package/src/app/[variants]/(main)/discover/(list)/mcp/features/List/Item.tsx +1 -0
  167. package/src/app/[variants]/(main)/discover/(list)/model/features/List/Item.tsx +1 -0
  168. package/src/app/[variants]/(main)/discover/(list)/provider/features/List/Item.tsx +1 -0
  169. package/src/app/[variants]/(main)/discover/components/CategoryMenu.tsx +9 -1
  170. package/src/app/[variants]/(main)/image/@topic/features/Topics/TopicList.tsx +1 -0
  171. package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +1 -1
  172. package/src/app/[variants]/(main)/image/page.tsx +0 -2
  173. package/src/app/[variants]/(main)/labs/components/LabCard.tsx +3 -1
  174. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +23 -24
  175. package/src/app/[variants]/(main)/profile/_layout/Mobile/index.tsx +5 -9
  176. package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +0 -2
  177. package/src/app/[variants]/(main)/settings/_layout/Mobile/index.tsx +0 -2
  178. package/src/app/[variants]/(main)/settings/_layout/SettingsContent.tsx +0 -3
  179. package/src/app/[variants]/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +1 -1
  180. package/src/app/[variants]/(main)/settings/provider/detail/azure/index.tsx +5 -7
  181. package/src/app/[variants]/layout.tsx +1 -0
  182. package/src/app/[variants]/loading/index.tsx +1 -10
  183. package/src/app/[variants]/oauth/ResultLayout.tsx +47 -0
  184. package/src/app/[variants]/oauth/callback/error/page.tsx +20 -33
  185. package/src/app/[variants]/oauth/callback/layout.tsx +1 -0
  186. package/src/app/[variants]/oauth/callback/success/page.tsx +8 -22
  187. package/src/app/[variants]/oauth/consent/[uid]/Consent/BuiltinConsent.tsx +47 -0
  188. package/src/app/[variants]/oauth/consent/[uid]/{Consent.tsx → Consent/index.tsx} +12 -1
  189. package/src/app/[variants]/oauth/consent/[uid]/Login.tsx +9 -1
  190. package/src/app/sitemap.tsx +7 -1
  191. package/src/components/InvalidAPIKey/APIKeyForm/Bedrock.tsx +8 -13
  192. package/src/components/Link.tsx +12 -0
  193. package/src/components/Thinking/index.tsx +4 -3
  194. package/src/config/db.ts +0 -5
  195. package/src/config/featureFlags/schema.test.ts +0 -2
  196. package/src/config/featureFlags/schema.ts +0 -6
  197. package/src/config/modelProviders/ai21.ts +1 -16
  198. package/src/config/modelProviders/ai302.ts +1 -128
  199. package/src/config/modelProviders/ai360.ts +1 -32
  200. package/src/config/modelProviders/anthropic.ts +1 -94
  201. package/src/config/modelProviders/azure.ts +1 -51
  202. package/src/config/modelProviders/baichuan.ts +1 -57
  203. package/src/config/modelProviders/bedrock.ts +1 -276
  204. package/src/config/modelProviders/cloudflare.ts +1 -64
  205. package/src/config/modelProviders/deepseek.ts +1 -19
  206. package/src/config/modelProviders/fireworksai.ts +1 -174
  207. package/src/config/modelProviders/giteeai.ts +1 -135
  208. package/src/config/modelProviders/github.ts +1 -254
  209. package/src/config/modelProviders/google.ts +1 -130
  210. package/src/config/modelProviders/groq.ts +1 -119
  211. package/src/config/modelProviders/higress.ts +1 -1736
  212. package/src/config/modelProviders/huggingface.ts +1 -54
  213. package/src/config/modelProviders/hunyuan.ts +1 -83
  214. package/src/config/modelProviders/infiniai.ts +1 -74
  215. package/src/config/modelProviders/internlm.ts +1 -20
  216. package/src/config/modelProviders/minimax.ts +1 -1
  217. package/src/config/modelProviders/mistral.ts +1 -95
  218. package/src/config/modelProviders/modelscope.ts +1 -27
  219. package/src/config/modelProviders/moonshot.ts +1 -29
  220. package/src/config/modelProviders/novita.ts +1 -105
  221. package/src/config/modelProviders/ollama.ts +1 -325
  222. package/src/config/modelProviders/openai.ts +1 -242
  223. package/src/config/modelProviders/openrouter.ts +1 -240
  224. package/src/config/modelProviders/perplexity.ts +1 -45
  225. package/src/config/modelProviders/ppio.ts +1 -152
  226. package/src/config/modelProviders/qiniu.ts +2 -19
  227. package/src/config/modelProviders/qwen.ts +1 -245
  228. package/src/config/modelProviders/search1api.ts +1 -34
  229. package/src/config/modelProviders/sensenova.ts +1 -69
  230. package/src/config/modelProviders/siliconcloud.ts +1 -417
  231. package/src/config/modelProviders/spark.ts +1 -59
  232. package/src/config/modelProviders/stepfun.ts +1 -98
  233. package/src/config/modelProviders/taichu.ts +1 -18
  234. package/src/config/modelProviders/togetherai.ts +1 -274
  235. package/src/config/modelProviders/upstage.ts +1 -28
  236. package/src/config/modelProviders/wenxin.ts +1 -140
  237. package/src/config/modelProviders/xai.ts +1 -38
  238. package/src/config/modelProviders/zeroone.ts +1 -81
  239. package/src/config/modelProviders/zhipu.ts +1 -108
  240. package/src/envs/app.ts +5 -8
  241. package/src/envs/auth.ts +0 -179
  242. package/src/features/AgentSetting/AgentPlugin/index.tsx +2 -2
  243. package/src/features/ChatInput/ActionBar/STT/browser.tsx +2 -2
  244. package/src/features/ChatInput/ActionBar/STT/openai.tsx +2 -2
  245. package/src/features/ChatInput/ActionBar/Tools/useControls.tsx +1 -3
  246. package/src/features/Conversation/Error/ErrorJsonViewer.tsx +4 -3
  247. package/src/features/Conversation/Error/OllamaBizError/index.tsx +7 -2
  248. package/src/features/Conversation/Error/index.tsx +15 -5
  249. package/src/features/Conversation/MarkdownElements/LobeArtifact/Render/index.tsx +2 -2
  250. package/src/features/Conversation/Messages/Assistant/Extra/index.tsx +2 -2
  251. package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +5 -3
  252. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/BuiltinPluginTitle.tsx +2 -2
  253. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/ToolTitle.tsx +4 -2
  254. package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +2 -2
  255. package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +2 -2
  256. package/src/features/Conversation/Messages/Assistant/Tool/index.tsx +2 -2
  257. package/src/features/Conversation/Messages/Assistant/index.tsx +4 -4
  258. package/src/features/Conversation/Messages/Default.tsx +2 -2
  259. package/src/features/Conversation/Messages/User/Extra.tsx +2 -2
  260. package/src/features/Conversation/Messages/User/index.tsx +4 -4
  261. package/src/features/Conversation/Messages/index.tsx +3 -3
  262. package/src/features/Conversation/components/AutoScroll.tsx +2 -2
  263. package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +9 -6
  264. package/src/features/DataImporter/index.tsx +15 -60
  265. package/src/features/DevPanel/PostgresViewer/usePgTable.ts +3 -2
  266. package/src/features/PluginTag/index.tsx +1 -3
  267. package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +37 -28
  268. package/src/features/Portal/Artifacts/Body/index.tsx +2 -2
  269. package/src/helpers/isCanUseFC.ts +0 -8
  270. package/src/hooks/useEnabledChatModels.ts +0 -8
  271. package/src/hooks/useInterceptingRoutes.test.ts +21 -3
  272. package/src/hooks/useModelContextWindowTokens.ts +0 -8
  273. package/src/hooks/useModelHasContextWindowToken.ts +1 -10
  274. package/src/hooks/useModelSupportFiles.ts +1 -11
  275. package/src/hooks/useModelSupportReasoning.ts +1 -11
  276. package/src/hooks/useModelSupportToolUse.ts +1 -11
  277. package/src/hooks/useModelSupportVision.ts +1 -11
  278. package/src/layout/AuthProvider/Clerk/index.tsx +2 -16
  279. package/src/libs/next-auth/auth.config.ts +3 -6
  280. package/src/libs/next-auth/sso-providers/auth0.ts +0 -7
  281. package/src/libs/next-auth/sso-providers/authelia.ts +3 -5
  282. package/src/libs/next-auth/sso-providers/authentik.ts +0 -7
  283. package/src/libs/next-auth/sso-providers/cloudflare-zero-trust.ts +3 -6
  284. package/src/libs/next-auth/sso-providers/cognito.ts +1 -5
  285. package/src/libs/next-auth/sso-providers/generic-oidc.ts +3 -5
  286. package/src/libs/next-auth/sso-providers/github.ts +0 -6
  287. package/src/libs/next-auth/sso-providers/google.ts +0 -2
  288. package/src/libs/next-auth/sso-providers/index.ts +0 -2
  289. package/src/libs/next-auth/sso-providers/keycloak.ts +0 -3
  290. package/src/libs/next-auth/sso-providers/logto.ts +3 -5
  291. package/src/libs/next-auth/sso-providers/okta.ts +0 -4
  292. package/src/libs/next-auth/sso-providers/zitadel.ts +0 -7
  293. package/src/libs/oidc-provider/provider.ts +1 -1
  294. package/src/libs/trpc/client/index.ts +0 -1
  295. package/src/libs/trpc/client/lambda.ts +8 -5
  296. package/src/libs/trpc/lambda/context.ts +4 -1
  297. package/src/locales/default/oauth.ts +1 -0
  298. package/src/server/globalConfig/index.ts +0 -23
  299. package/src/server/modules/AssistantStore/index.ts +1 -1
  300. package/src/server/modules/ModelRuntime/trace.ts +11 -4
  301. package/src/server/routers/desktop/mcp.ts +1 -3
  302. package/src/server/routers/lambda/__tests__/integration/message.integration.test.ts +0 -41
  303. package/src/server/routers/lambda/config/__snapshots__/index.test.ts.snap +175 -12
  304. package/src/server/routers/lambda/config/index.test.ts +38 -30
  305. package/src/server/routers/lambda/message.ts +17 -13
  306. package/src/server/routers/lambda/session.ts +8 -5
  307. package/src/server/routers/lambda/user.ts +24 -25
  308. package/src/server/routers/tools/mcp.ts +2 -3
  309. package/src/server/routers/tools/search.test.ts +1 -7
  310. package/src/server/routers/tools/search.ts +1 -4
  311. package/src/server/services/search/impls/firecrawl/index.ts +51 -11
  312. package/src/server/services/search/impls/firecrawl/type.ts +60 -9
  313. package/src/services/__tests__/tool.test.ts +0 -3
  314. package/src/services/aiModel/index.test.ts +0 -3
  315. package/src/services/aiModel/index.ts +1 -7
  316. package/src/services/aiProvider/index.test.ts +0 -3
  317. package/src/services/aiProvider/index.ts +1 -7
  318. package/src/services/chat/chat.test.ts +13 -40
  319. package/src/services/chat/contextEngineering.test.ts +0 -30
  320. package/src/services/chat/contextEngineering.ts +1 -12
  321. package/src/services/chat/helper.ts +7 -31
  322. package/src/services/chat/index.ts +2 -7
  323. package/src/services/chat/types.ts +1 -1
  324. package/src/services/chatGroup/index.ts +1 -10
  325. package/src/services/config.ts +1 -65
  326. package/src/services/export/index.ts +1 -4
  327. package/src/services/file/index.ts +1 -11
  328. package/src/services/import/index.ts +1 -7
  329. package/src/services/message/index.ts +1 -11
  330. package/src/services/message/server.ts +7 -6
  331. package/src/services/message/type.ts +6 -3
  332. package/src/services/models.ts +2 -11
  333. package/src/services/plugin/index.ts +1 -11
  334. package/src/services/session/index.ts +1 -11
  335. package/src/services/tableViewer/client.ts +12 -15
  336. package/src/services/thread/index.ts +1 -7
  337. package/src/services/topic/index.ts +1 -11
  338. package/src/services/user/index.ts +1 -13
  339. package/src/store/chat/helpers.test.ts +99 -0
  340. package/src/store/chat/helpers.ts +21 -2
  341. package/src/store/chat/selectors.ts +1 -1
  342. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +0 -241
  343. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChatV2.test.ts +26 -1
  344. package/src/store/chat/slices/aiChat/actions/__tests__/helpers.ts +3 -1
  345. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +45 -155
  346. package/src/store/chat/slices/builtinTool/actions/index.ts +1 -4
  347. package/src/store/chat/slices/message/action.test.ts +5 -1
  348. package/src/store/chat/slices/message/action.ts +102 -14
  349. package/src/store/chat/slices/message/reducer.test.ts +363 -5
  350. package/src/store/chat/slices/message/reducer.ts +87 -3
  351. package/src/store/chat/slices/message/{selectors.test.ts → selectors/chat.test.ts} +266 -30
  352. package/src/store/chat/slices/message/{selectors.ts → selectors/chat.ts} +29 -79
  353. package/src/store/chat/slices/message/selectors/index.ts +2 -0
  354. package/src/store/chat/slices/message/selectors/messageState.test.ts +36 -0
  355. package/src/store/chat/slices/message/selectors/messageState.ts +80 -0
  356. package/src/store/chat/slices/plugin/action.test.ts +34 -132
  357. package/src/store/chat/slices/plugin/action.ts +1 -44
  358. package/src/store/global/store.ts +1 -7
  359. package/src/store/tool/selectors/tool.test.ts +1 -1
  360. package/src/store/tool/selectors/tool.ts +6 -8
  361. package/src/store/tool/slices/builtin/action.test.ts +83 -35
  362. package/src/store/tool/slices/builtin/action.ts +0 -9
  363. package/src/store/tool/slices/builtin/selectors.test.ts +4 -30
  364. package/src/store/tool/slices/builtin/selectors.ts +15 -21
  365. package/src/store/user/initialState.ts +1 -7
  366. package/src/store/user/selectors.ts +1 -5
  367. package/src/store/user/slices/common/action.test.ts +1 -4
  368. package/src/store/user/slices/common/action.ts +5 -4
  369. package/src/store/user/slices/settings/selectors/index.ts +1 -0
  370. package/src/store/user/slices/settings/selectors/keyVaults.ts +21 -0
  371. package/src/store/user/store.ts +0 -3
  372. package/src/tools/index.ts +0 -6
  373. package/src/tools/renders.ts +0 -3
  374. package/src/tools/web-browsing/Portal/Search/Footer.tsx +2 -2
  375. package/src/tools/web-browsing/Render/Search/ConfigForm/Form.tsx +1 -1
  376. package/tsconfig.json +9 -3
  377. package/packages/const/src/guide.ts +0 -89
  378. package/packages/context-engine/src/providers/InboxGuide.ts +0 -102
  379. package/packages/context-engine/src/providers/__tests__/InboxGuideProvider.test.ts +0 -121
  380. package/packages/utils/src/_deprecated/__snapshots__/parseModels.test.ts.snap +0 -104
  381. package/packages/utils/src/_deprecated/parseModels.test.ts +0 -287
  382. package/packages/utils/src/_deprecated/parseModels.ts +0 -165
  383. package/src/app/(backend)/trpc/edge/[trpc]/route.ts +0 -26
  384. package/src/app/[variants]/(main)/(mobile)/me/data/features/Category.tsx +0 -48
  385. package/src/app/[variants]/(main)/(mobile)/me/data/features/Header.tsx +0 -33
  386. package/src/app/[variants]/(main)/(mobile)/me/data/layout.tsx +0 -13
  387. package/src/app/[variants]/(main)/(mobile)/me/data/loading.tsx +0 -5
  388. package/src/app/[variants]/(main)/(mobile)/me/data/page.tsx +0 -29
  389. package/src/app/[variants]/(main)/chat/features/Migration/DBReader.ts +0 -290
  390. package/src/app/[variants]/(main)/chat/features/Migration/ExportConfigButton.tsx +0 -35
  391. package/src/app/[variants]/(main)/chat/features/Migration/Failed.tsx +0 -120
  392. package/src/app/[variants]/(main)/chat/features/Migration/Modal.tsx +0 -81
  393. package/src/app/[variants]/(main)/chat/features/Migration/Start.tsx +0 -108
  394. package/src/app/[variants]/(main)/chat/features/Migration/UpgradeButton.tsx +0 -71
  395. package/src/app/[variants]/(main)/chat/features/Migration/const.ts +0 -15
  396. package/src/app/[variants]/(main)/chat/features/Migration/index.tsx +0 -50
  397. package/src/app/[variants]/(main)/settings/llm/ProviderList/Azure/index.tsx +0 -93
  398. package/src/app/[variants]/(main)/settings/llm/ProviderList/Bedrock/index.tsx +0 -70
  399. package/src/app/[variants]/(main)/settings/llm/ProviderList/Cloudflare/index.tsx +0 -39
  400. package/src/app/[variants]/(main)/settings/llm/ProviderList/Github/index.tsx +0 -52
  401. package/src/app/[variants]/(main)/settings/llm/ProviderList/HuggingFace/index.tsx +0 -52
  402. package/src/app/[variants]/(main)/settings/llm/ProviderList/Ollama/index.tsx +0 -20
  403. package/src/app/[variants]/(main)/settings/llm/ProviderList/OpenAI/index.tsx +0 -17
  404. package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +0 -132
  405. package/src/app/[variants]/(main)/settings/llm/components/Checker.tsx +0 -118
  406. package/src/app/[variants]/(main)/settings/llm/components/ProviderConfig/index.tsx +0 -303
  407. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/CustomModelOption.tsx +0 -98
  408. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/Form.tsx +0 -104
  409. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/index.tsx +0 -77
  410. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -105
  411. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/Option.tsx +0 -68
  412. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/index.tsx +0 -146
  413. package/src/app/[variants]/(main)/settings/llm/const.ts +0 -20
  414. package/src/app/[variants]/(main)/settings/llm/features/Footer.tsx +0 -35
  415. package/src/app/[variants]/(main)/settings/llm/index.tsx +0 -30
  416. package/src/app/[variants]/(main)/settings/llm/type.ts +0 -5
  417. package/src/app/[variants]/loading/Client/Content.tsx +0 -48
  418. package/src/app/[variants]/loading/Client/Error.tsx +0 -27
  419. package/src/app/[variants]/loading/Client/Redirect.tsx +0 -47
  420. package/src/app/[variants]/loading/Client/index.tsx +0 -22
  421. package/src/components/InnerLink.tsx +0 -20
  422. package/src/database/_deprecated/core/__tests__/db-upgrade.test.ts +0 -42
  423. package/src/database/_deprecated/core/__tests__/db.test.ts +0 -79
  424. package/src/database/_deprecated/core/__tests__/model.test.ts +0 -55
  425. package/src/database/_deprecated/core/db.ts +0 -246
  426. package/src/database/_deprecated/core/index.ts +0 -2
  427. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/input.json +0 -55
  428. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/fixtures/output.json +0 -60
  429. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.test.ts +0 -14
  430. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/index.ts +0 -22
  431. package/src/database/_deprecated/core/migrations/migrateSettingsToUser/type.ts +0 -105
  432. package/src/database/_deprecated/core/model.ts +0 -218
  433. package/src/database/_deprecated/core/schemas.ts +0 -88
  434. package/src/database/_deprecated/core/types/db.ts +0 -15
  435. package/src/database/_deprecated/models/__DEBUG.ts +0 -124
  436. package/src/database/_deprecated/models/__tests__/file.test.ts +0 -83
  437. package/src/database/_deprecated/models/__tests__/message.test.ts +0 -426
  438. package/src/database/_deprecated/models/__tests__/plugin.test.ts +0 -81
  439. package/src/database/_deprecated/models/__tests__/session.test.ts +0 -253
  440. package/src/database/_deprecated/models/__tests__/sessionGroup.test.ts +0 -220
  441. package/src/database/_deprecated/models/__tests__/topic.test.ts +0 -523
  442. package/src/database/_deprecated/models/__tests__/user.test.ts +0 -82
  443. package/src/database/_deprecated/models/file.ts +0 -51
  444. package/src/database/_deprecated/models/message.ts +0 -277
  445. package/src/database/_deprecated/models/plugin.ts +0 -62
  446. package/src/database/_deprecated/models/session.ts +0 -271
  447. package/src/database/_deprecated/models/sessionGroup.ts +0 -93
  448. package/src/database/_deprecated/models/topic.ts +0 -250
  449. package/src/database/_deprecated/models/user.ts +0 -69
  450. package/src/database/_deprecated/schemas/files.ts +0 -39
  451. package/src/database/_deprecated/schemas/message.ts +0 -50
  452. package/src/database/_deprecated/schemas/plugin.ts +0 -12
  453. package/src/database/_deprecated/schemas/session.ts +0 -54
  454. package/src/database/_deprecated/schemas/sessionGroup.ts +0 -8
  455. package/src/database/_deprecated/schemas/topic.ts +0 -12
  456. package/src/database/_deprecated/schemas/user.ts +0 -40
  457. package/src/envs/__tests__/auth.test.ts +0 -200
  458. package/src/features/DataImporter/_deprecated.ts +0 -43
  459. package/src/features/InitClientDB/EnableModal.tsx +0 -118
  460. package/src/features/InitClientDB/ErrorResult.tsx +0 -143
  461. package/src/features/InitClientDB/InitIndicator.tsx +0 -124
  462. package/src/features/InitClientDB/PGliteIcon.tsx +0 -28
  463. package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +0 -75
  464. package/src/features/InitClientDB/features/DatabaseRepair/Diagnosis.tsx +0 -98
  465. package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +0 -218
  466. package/src/features/InitClientDB/features/DatabaseRepair/index.tsx +0 -91
  467. package/src/features/InitClientDB/index.tsx +0 -37
  468. package/src/hooks/_header.ts +0 -23
  469. package/src/libs/next-auth/sso-providers/azure-ad.ts +0 -33
  470. package/src/libs/trpc/client/edge.ts +0 -26
  471. package/src/libs/trpc/edge/context.ts +0 -71
  472. package/src/libs/trpc/edge/index.ts +0 -45
  473. package/src/libs/trpc/edge/init.ts +0 -26
  474. package/src/libs/trpc/edge/middleware/jwtPayload.test.ts +0 -75
  475. package/src/libs/trpc/edge/middleware/jwtPayload.ts +0 -14
  476. package/src/migrations/FromV0ToV1.ts +0 -10
  477. package/src/migrations/FromV1ToV2/fixtures/input-v1-session.json +0 -191
  478. package/src/migrations/FromV1ToV2/fixtures/output-v2.json +0 -202
  479. package/src/migrations/FromV1ToV2/index.ts +0 -82
  480. package/src/migrations/FromV1ToV2/migrations.test.ts +0 -224
  481. package/src/migrations/FromV1ToV2/types/v1.ts +0 -78
  482. package/src/migrations/FromV1ToV2/types/v2.ts +0 -52
  483. package/src/migrations/FromV2ToV3/fixtures/input-v2-session.json +0 -72
  484. package/src/migrations/FromV2ToV3/fixtures/output-v3-from-v1.json +0 -203
  485. package/src/migrations/FromV2ToV3/fixtures/output-v3.json +0 -74
  486. package/src/migrations/FromV2ToV3/index.ts +0 -30
  487. package/src/migrations/FromV2ToV3/migrations.test.ts +0 -42
  488. package/src/migrations/FromV2ToV3/types/v3.ts +0 -27
  489. package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +0 -79
  490. package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +0 -75
  491. package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +0 -85
  492. package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +0 -86
  493. package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +0 -77
  494. package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +0 -77
  495. package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +0 -82
  496. package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +0 -85
  497. package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +0 -203
  498. package/src/migrations/FromV3ToV4/index.ts +0 -102
  499. package/src/migrations/FromV3ToV4/migrations.test.ts +0 -195
  500. package/src/migrations/FromV3ToV4/types/v3.ts +0 -52
  501. package/src/migrations/FromV3ToV4/types/v4.ts +0 -37
  502. package/src/migrations/FromV4ToV5/fixtures/from-v1-to-v5-output.json +0 -245
  503. package/src/migrations/FromV4ToV5/fixtures/function-input-v4.json +0 -96
  504. package/src/migrations/FromV4ToV5/fixtures/function-output-v5.json +0 -120
  505. package/src/migrations/FromV4ToV5/index.ts +0 -58
  506. package/src/migrations/FromV4ToV5/migrations.test.ts +0 -49
  507. package/src/migrations/FromV4ToV5/types/v4.ts +0 -21
  508. package/src/migrations/FromV4ToV5/types/v5.ts +0 -27
  509. package/src/migrations/FromV5ToV6/fixtures/from-v1-to-v6-output.json +0 -247
  510. package/src/migrations/FromV5ToV6/fixtures/session-input-v5.json +0 -81
  511. package/src/migrations/FromV5ToV6/fixtures/session-output-v6.json +0 -85
  512. package/src/migrations/FromV5ToV6/index.ts +0 -61
  513. package/src/migrations/FromV5ToV6/migrations.test.ts +0 -50
  514. package/src/migrations/FromV5ToV6/types/v5.ts +0 -48
  515. package/src/migrations/FromV5ToV6/types/v6.ts +0 -63
  516. package/src/migrations/FromV6ToV7/fixtures/output-v7-from-v1.json +0 -203
  517. package/src/migrations/FromV6ToV7/fixtures/provider-input-v6.json +0 -103
  518. package/src/migrations/FromV6ToV7/fixtures/provider-output-v7.json +0 -118
  519. package/src/migrations/FromV6ToV7/index.ts +0 -101
  520. package/src/migrations/FromV6ToV7/migrations.test.ts +0 -64
  521. package/src/migrations/FromV6ToV7/types/v6.ts +0 -61
  522. package/src/migrations/FromV6ToV7/types/v7.ts +0 -69
  523. package/src/migrations/VersionController.test.ts +0 -88
  524. package/src/migrations/VersionController.ts +0 -67
  525. package/src/migrations/index.ts +0 -61
  526. package/src/server/globalConfig/_deprecated.test.ts +0 -92
  527. package/src/server/globalConfig/_deprecated.ts +0 -41
  528. package/src/server/routers/edge/appStatus.ts +0 -3
  529. package/src/server/routers/edge/index.ts +0 -14
  530. package/src/server/routers/edge/upload.ts +0 -16
  531. package/src/services/aiModel/client.ts +0 -70
  532. package/src/services/aiProvider/client.ts +0 -58
  533. package/src/services/baseClientService/index.ts +0 -9
  534. package/src/services/chat/__snapshots__/chat.test.ts.snap +0 -110
  535. package/src/services/chatGroup/client.ts +0 -63
  536. package/src/services/export/_deprecated.ts +0 -155
  537. package/src/services/export/client.ts +0 -15
  538. package/src/services/file/_deprecated.test.ts +0 -119
  539. package/src/services/file/_deprecated.ts +0 -80
  540. package/src/services/file/client.test.ts +0 -199
  541. package/src/services/file/client.ts +0 -85
  542. package/src/services/import/_deprecated.ts +0 -115
  543. package/src/services/import/client.test.ts +0 -1015
  544. package/src/services/import/client.ts +0 -64
  545. package/src/services/message/_deprecated.test.ts +0 -398
  546. package/src/services/message/_deprecated.ts +0 -168
  547. package/src/services/message/client.test.ts +0 -410
  548. package/src/services/message/client.ts +0 -186
  549. package/src/services/plugin/_deprecated.test.ts +0 -162
  550. package/src/services/plugin/_deprecated.ts +0 -42
  551. package/src/services/plugin/client.test.ts +0 -177
  552. package/src/services/plugin/client.ts +0 -46
  553. package/src/services/session/_deprecated.test.ts +0 -440
  554. package/src/services/session/_deprecated.ts +0 -190
  555. package/src/services/session/client.test.ts +0 -413
  556. package/src/services/session/client.ts +0 -193
  557. package/src/services/thread/client.ts +0 -51
  558. package/src/services/topic/_deprecated.test.ts +0 -245
  559. package/src/services/topic/_deprecated.ts +0 -75
  560. package/src/services/topic/client.ts +0 -89
  561. package/src/services/topic/pglite.test.ts +0 -212
  562. package/src/services/user/_deprecated.test.ts +0 -101
  563. package/src/services/user/_deprecated.ts +0 -70
  564. package/src/services/user/client.test.ts +0 -108
  565. package/src/services/user/client.ts +0 -104
  566. package/src/store/chat/slices/builtinTool/actions/__tests__/dalle.test.ts +0 -121
  567. package/src/store/chat/slices/builtinTool/actions/dalle.ts +0 -124
  568. package/src/store/global/actions/clientDb.ts +0 -67
  569. package/src/store/user/slices/modelList/__snapshots__/action.test.ts.snap +0 -12
  570. package/src/store/user/slices/modelList/action.test.ts +0 -359
  571. package/src/store/user/slices/modelList/action.ts +0 -223
  572. package/src/store/user/slices/modelList/initialState.ts +0 -15
  573. package/src/store/user/slices/modelList/reducers/customModelCard.test.ts +0 -204
  574. package/src/store/user/slices/modelList/reducers/customModelCard.ts +0 -64
  575. package/src/store/user/slices/modelList/selectors/index.ts +0 -3
  576. package/src/store/user/slices/modelList/selectors/keyVaults.test.ts +0 -201
  577. package/src/store/user/slices/modelList/selectors/keyVaults.ts +0 -50
  578. package/src/store/user/slices/modelList/selectors/modelConfig.test.ts +0 -219
  579. package/src/store/user/slices/modelList/selectors/modelConfig.ts +0 -95
  580. package/src/store/user/slices/modelList/selectors/modelProvider.test.ts +0 -138
  581. package/src/store/user/slices/modelList/selectors/modelProvider.ts +0 -170
  582. package/src/tools/dalle/Render/GalleyGrid.tsx +0 -60
  583. package/src/tools/dalle/Render/Item/EditMode.tsx +0 -66
  584. package/src/tools/dalle/Render/Item/Error.tsx +0 -49
  585. package/src/tools/dalle/Render/Item/Image.tsx +0 -44
  586. package/src/tools/dalle/Render/Item/ImageFileItem.tsx +0 -57
  587. package/src/tools/dalle/Render/Item/index.tsx +0 -88
  588. package/src/tools/dalle/Render/ToolBar.tsx +0 -56
  589. package/src/tools/dalle/Render/index.tsx +0 -52
  590. package/src/tools/dalle/index.ts +0 -92
  591. /package/src/{middleware.ts → proxy.ts} +0 -0
@@ -86,6 +86,119 @@ describe('googleErrorParser', () => {
86
86
  });
87
87
  expect(result.prefix).toBe('Error');
88
88
  });
89
+
90
+ it('should handle multiple spaces between status code and text', () => {
91
+ const input = 'Error [500 Internal Server Error] Something went wrong';
92
+ const result = extractStatusCodeFromError(input);
93
+
94
+ expect(result.errorDetails).toEqual({
95
+ message: 'Something went wrong',
96
+ statusCode: 500,
97
+ statusCodeText: '[500 Internal Server Error]',
98
+ });
99
+ expect(result.prefix).toBe('Error');
100
+ });
101
+
102
+ it('should handle status code at the beginning of message', () => {
103
+ const input = '[429 Too Many Requests] Rate limit exceeded';
104
+ const result = extractStatusCodeFromError(input);
105
+
106
+ expect(result.errorDetails).toEqual({
107
+ message: 'Rate limit exceeded',
108
+ statusCode: 429,
109
+ statusCodeText: '[429 Too Many Requests]',
110
+ });
111
+ expect(result.prefix).toBe('');
112
+ });
113
+
114
+ it('should handle status code at the end of message', () => {
115
+ const input = 'Request failed [503 Service Unavailable]';
116
+ const result = extractStatusCodeFromError(input);
117
+
118
+ expect(result.errorDetails).toEqual({
119
+ message: '',
120
+ statusCode: 503,
121
+ statusCodeText: '[503 Service Unavailable]',
122
+ });
123
+ expect(result.prefix).toBe('Request failed');
124
+ });
125
+
126
+ it('should not be vulnerable to ReDoS attacks', () => {
127
+ // Test with a potentially malicious input that could cause catastrophic backtracking
128
+ const maliciousInput = 'Error ' + 'a'.repeat(10000) + ' [not matching]';
129
+ const startTime = Date.now();
130
+ const result = extractStatusCodeFromError(maliciousInput);
131
+ const endTime = Date.now();
132
+
133
+ // Should complete quickly (under 100ms) even with large input
134
+ expect(endTime - startTime).toBeLessThan(100);
135
+ expect(result.errorDetails).toBeNull();
136
+ });
137
+
138
+ it('should not be vulnerable to ReDoS with many spaces', () => {
139
+ // Test the specific case mentioned in the security warning: '[9 ' + many spaces
140
+ const maliciousInput = '[9 ' + ' '.repeat(10000) + ']';
141
+ const startTime = Date.now();
142
+ const result = extractStatusCodeFromError(maliciousInput);
143
+ const endTime = Date.now();
144
+
145
+ // Should complete quickly (under 100ms) even with many spaces
146
+ expect(endTime - startTime).toBeLessThan(100);
147
+ expect(result.errorDetails).toBeDefined();
148
+ });
149
+
150
+ it('should handle very long error messages efficiently', () => {
151
+ const longMessage = 'a'.repeat(50000);
152
+ const input = `Prefix [400 Bad Request] ${longMessage}`;
153
+ const startTime = Date.now();
154
+ const result = extractStatusCodeFromError(input);
155
+ const endTime = Date.now();
156
+
157
+ // Should complete quickly even with very long input
158
+ expect(endTime - startTime).toBeLessThan(100);
159
+ expect(result.errorDetails?.statusCode).toBe(400);
160
+ });
161
+
162
+ it('should safely handle edge cases with match.index', () => {
163
+ // Test various edge cases where match.index might be 0 or at different positions
164
+ const testCases = [
165
+ { input: '[400 Bad Request]', expectedPrefix: '' },
166
+ { input: '[500 Error] Message', expectedPrefix: '' },
167
+ { input: 'Some text [404 Not Found] More text', expectedPrefix: 'Some text' },
168
+ ];
169
+
170
+ testCases.forEach(({ input, expectedPrefix }) => {
171
+ const result = extractStatusCodeFromError(input);
172
+ expect(result.errorDetails).toBeDefined();
173
+ expect(result.prefix).toBe(expectedPrefix);
174
+ });
175
+ });
176
+
177
+ it('should find status code when there are multiple brackets', () => {
178
+ // Real-world case from Google AI API errors with JSON arrays in the message
179
+ const input =
180
+ '[GoogleGenerativeAI Error]: Error fetching: [400 Bad Request] API key not valid. [{"@type":"type.googleapis.com"}]';
181
+ const result = extractStatusCodeFromError(input);
182
+
183
+ expect(result.errorDetails).toEqual({
184
+ message: 'API key not valid. [{"@type":"type.googleapis.com"}]',
185
+ statusCode: 400,
186
+ statusCodeText: '[400 Bad Request]',
187
+ });
188
+ expect(result.prefix).toBe('[GoogleGenerativeAI Error]: Error fetching:');
189
+ });
190
+
191
+ it('should skip brackets that do not contain valid status codes', () => {
192
+ const input = 'Error [not a code] happened [500 Internal Server Error] please retry';
193
+ const result = extractStatusCodeFromError(input);
194
+
195
+ expect(result.errorDetails).toEqual({
196
+ message: 'please retry',
197
+ statusCode: 500,
198
+ statusCodeText: '[500 Internal Server Error]',
199
+ });
200
+ expect(result.prefix).toBe('Error [not a code] happened');
201
+ });
89
202
  });
90
203
 
91
204
  describe('parseGoogleErrorMessage', () => {
@@ -110,6 +223,18 @@ describe('googleErrorParser', () => {
110
223
  });
111
224
  });
112
225
 
226
+ it('should not be vulnerable to ReDoS in status JSON parsing', () => {
227
+ // Test with malicious input that could cause catastrophic backtracking
228
+ const maliciousInput = 'got status: UNAVAILABLE. ' + 'a'.repeat(10000);
229
+ const startTime = Date.now();
230
+ const result = parseGoogleErrorMessage(maliciousInput);
231
+ const endTime = Date.now();
232
+
233
+ // Should complete quickly (under 100ms) even with large input
234
+ expect(endTime - startTime).toBeLessThan(100);
235
+ expect(result.errorType).toBe(AgentRuntimeErrorType.ProviderBizError);
236
+ });
237
+
113
238
  it('should handle direct JSON parsing', () => {
114
239
  const input =
115
240
  '{"error":{"code":400,"message":"* API key not valid. Please pass a valid API key.","status":"INVALID_ARGUMENT"}}';
@@ -17,64 +17,81 @@ export interface GoogleChatError {
17
17
  export type GoogleChatErrors = GoogleChatError[];
18
18
 
19
19
  /**
20
- * 清理错误消息,移除格式化字符和多余的空格
21
- * @param message - 原始错误消息
22
- * @returns 清理后的错误消息
20
+ * Clean error message by removing formatting characters and extra spaces
21
+ * @param message - Original error message
22
+ * @returns Cleaned error message
23
23
  */
24
24
  export function cleanErrorMessage(message: string): string {
25
25
  return message
26
- .replaceAll(/^\*\s*/g, '') // 移除开头的星号和空格
27
- .replaceAll('\\n', '\n') // 转换转义的换行符
28
- .replaceAll(/\n+/g, ' ') // 将多个换行符替换为单个空格
29
- .trim(); // 去除首尾空格
26
+ .replaceAll(/^\*\s*/g, '') // Remove leading asterisks and spaces
27
+ .replaceAll('\\n', '\n') // Convert escaped newlines
28
+ .replaceAll(/\n+/g, ' ') // Replace multiple newlines with single space
29
+ .trim(); // Trim leading/trailing spaces
30
30
  }
31
31
 
32
32
  /**
33
- * 从错误消息中提取状态码信息
34
- * @param message - 错误消息
35
- * @returns 提取的错误详情和前缀
33
+ * Extract status code information from error message
34
+ * @param message - Error message
35
+ * @returns Extracted error details and prefix
36
36
  */
37
37
  export function extractStatusCodeFromError(message: string): {
38
38
  errorDetails: any;
39
39
  prefix: string;
40
40
  } {
41
- // 使用正则表达式匹配状态码部分 [数字 描述文本]
42
- const regex = /^(.*?)(\[\d+ [^\]]+])(.*)$/;
43
- const match = message.match(regex);
44
-
45
- if (match) {
46
- const prefix = match[1].trim();
47
- const statusCodeWithBrackets = match[2].trim();
48
- const messageContent = match[3].trim();
49
-
50
- // 提取状态码数字
51
- const statusCodeMatch = statusCodeWithBrackets.match(/\[(\d+)/);
52
- const statusCode = statusCodeMatch ? parseInt(statusCodeMatch[1]) : null;
53
-
54
- // 创建包含状态码和消息的JSON
55
- const resultJson = {
56
- message: messageContent,
57
- statusCode: statusCode,
58
- statusCodeText: statusCodeWithBrackets,
59
- };
41
+ // Match status code pattern [number description text]
42
+ // Use string methods instead of regex to avoid ReDoS attacks
43
+ // We need to find a bracket that contains a status code (3-digit number followed by space and text)
44
+
45
+ let searchStart = 0;
46
+ // eslint-disable-next-line no-constant-condition
47
+ while (true) {
48
+ const openBracketIndex = message.indexOf('[', searchStart);
49
+ if (openBracketIndex === -1) {
50
+ return { errorDetails: null, prefix: message };
51
+ }
60
52
 
61
- return {
62
- errorDetails: resultJson,
63
- prefix: prefix,
64
- };
65
- }
53
+ const closeBracketIndex = message.indexOf(']', openBracketIndex);
54
+ if (closeBracketIndex === -1) {
55
+ return { errorDetails: null, prefix: message };
56
+ }
66
57
 
67
- // 如果无法匹配,返回原始消息
68
- return {
69
- errorDetails: null,
70
- prefix: message,
71
- };
58
+ const bracketContent = message.slice(openBracketIndex + 1, closeBracketIndex).trim();
59
+
60
+ // Find the first space to separate status code from description
61
+ const spaceIndex = bracketContent.indexOf(' ');
62
+ if (spaceIndex !== -1) {
63
+ const statusCodeStr = bracketContent.slice(0, spaceIndex);
64
+ const statusCode = parseInt(statusCodeStr, 10);
65
+
66
+ // Validate that statusCode is a valid HTTP status code (3 digits)
67
+ if (!isNaN(statusCode) && statusCode >= 100 && statusCode < 600) {
68
+ const statusText = bracketContent.slice(spaceIndex + 1).trim();
69
+ const prefix = message.slice(0, openBracketIndex).trim();
70
+ const messageContent = message.slice(closeBracketIndex + 1).trim();
71
+
72
+ // Create JSON containing status code and message
73
+ const resultJson = {
74
+ message: messageContent,
75
+ statusCode: statusCode,
76
+ statusCodeText: `[${statusCode} ${statusText}]`,
77
+ };
78
+
79
+ return {
80
+ errorDetails: resultJson,
81
+ prefix: prefix,
82
+ };
83
+ }
84
+ }
85
+
86
+ // Move to next bracket
87
+ searchStart = openBracketIndex + 1;
88
+ }
72
89
  }
73
90
 
74
91
  /**
75
- * 解析Google AI API返回的错误消息
76
- * @param message - 原始错误消息
77
- * @returns 解析后的错误对象和错误类型
92
+ * Parse error message from Google AI API
93
+ * @param message - Original error message
94
+ * @returns Parsed error object and error type
78
95
  */
79
96
  export function parseGoogleErrorMessage(message: string): ParsedError {
80
97
  const defaultError = {
@@ -82,12 +99,12 @@ export function parseGoogleErrorMessage(message: string): ParsedError {
82
99
  errorType: AgentRuntimeErrorType.ProviderBizError,
83
100
  };
84
101
 
85
- // 快速识别特殊错误
102
+ // Quick identification of special errors
86
103
  if (message.includes('location is not supported')) {
87
104
  return { error: { message }, errorType: AgentRuntimeErrorType.LocationNotSupportError };
88
105
  }
89
106
 
90
- // 统一的错误类型判断函数
107
+ // Unified error type determination function
91
108
  const getErrorType = (code: number | null, message: string): ILobeAgentRuntimeErrorType => {
92
109
  if (code === 400 && message.includes('API key not valid')) {
93
110
  return AgentRuntimeErrorType.InvalidProviderAPIKey;
@@ -97,30 +114,30 @@ export function parseGoogleErrorMessage(message: string): ParsedError {
97
114
  return AgentRuntimeErrorType.ProviderBizError;
98
115
  };
99
116
 
100
- // 递归解析JSON,处理嵌套的JSON字符串
117
+ // Recursively parse JSON, handling nested JSON strings
101
118
  const parseJsonRecursively = (str: string, maxDepth: number = 5): any => {
102
119
  if (maxDepth <= 0) return null;
103
120
 
104
121
  try {
105
122
  const parsed = JSON.parse(str);
106
123
 
107
- // 如果解析出的对象包含error字段
124
+ // If parsed object contains error field
108
125
  if (parsed && typeof parsed === 'object' && parsed.error) {
109
126
  const errorInfo = parsed.error;
110
127
 
111
- // 清理错误消息
128
+ // Clean error message
112
129
  if (typeof errorInfo.message === 'string') {
113
130
  errorInfo.message = cleanErrorMessage(errorInfo.message);
114
131
 
115
- // 如果error.message还是一个JSON字符串,继续递归解析
132
+ // If error.message is still a JSON string, continue recursive parsing
116
133
  try {
117
134
  const nestedResult = parseJsonRecursively(errorInfo.message, maxDepth - 1);
118
- // 只有当深层结果包含带有 code error 对象时,才优先返回深层结果
135
+ // Only return deeper result if it contains an error object with code
119
136
  if (nestedResult && nestedResult.error && nestedResult.error.code) {
120
137
  return nestedResult;
121
138
  }
122
139
  } catch {
123
- // 如果嵌套解析失败,使用当前层的信息
140
+ // If nested parsing fails, use current layer info
124
141
  }
125
142
  }
126
143
 
@@ -133,31 +150,40 @@ export function parseGoogleErrorMessage(message: string): ParsedError {
133
150
  }
134
151
  };
135
152
 
136
- // 1. 处理 "got status: UNAVAILABLE. {JSON}" 格式
137
- const statusJsonMatch = message.match(/got status: (\w+)\.\s*({.*})$/);
138
- if (statusJsonMatch) {
139
- const statusFromMessage = statusJsonMatch[1];
140
- const jsonPart = statusJsonMatch[2];
141
-
142
- const parsedError = parseJsonRecursively(jsonPart);
143
- if (parsedError && parsedError.error) {
144
- const errorInfo = parsedError.error;
145
- const finalMessage = errorInfo.message || message;
146
- const finalCode = errorInfo.code || null;
147
- const finalStatus = errorInfo.status || statusFromMessage;
148
-
149
- return {
150
- error: {
151
- code: finalCode,
152
- message: finalMessage,
153
- status: finalStatus,
154
- },
155
- errorType: getErrorType(finalCode, finalMessage),
156
- };
153
+ // 1. Handle "got status: UNAVAILABLE. {JSON}" format
154
+ const statusPrefix = 'got status: ';
155
+ const statusPrefixIndex = message.indexOf(statusPrefix);
156
+ if (statusPrefixIndex !== -1) {
157
+ const afterPrefix = message.slice(statusPrefixIndex + statusPrefix.length);
158
+ const dotIndex = afterPrefix.indexOf('.');
159
+ if (dotIndex !== -1) {
160
+ const statusFromMessage = afterPrefix.slice(0, dotIndex).trim();
161
+ const afterDot = afterPrefix.slice(dotIndex + 1).trim();
162
+ const braceIndex = afterDot.indexOf('{');
163
+ if (braceIndex !== -1) {
164
+ const jsonPart = afterDot.slice(braceIndex);
165
+
166
+ const parsedError = parseJsonRecursively(jsonPart);
167
+ if (parsedError && parsedError.error) {
168
+ const errorInfo = parsedError.error;
169
+ const finalMessage = errorInfo.message || message;
170
+ const finalCode = errorInfo.code || null;
171
+ const finalStatus = errorInfo.status || statusFromMessage;
172
+
173
+ return {
174
+ error: {
175
+ code: finalCode,
176
+ message: finalMessage,
177
+ status: finalStatus,
178
+ },
179
+ errorType: getErrorType(finalCode, finalMessage),
180
+ };
181
+ }
182
+ }
157
183
  }
158
184
  }
159
185
 
160
- // 2. 尝试直接解析整个消息作为JSON
186
+ // 2. Try to parse entire message as JSON directly
161
187
  const directParsed = parseJsonRecursively(message);
162
188
  if (directParsed && directParsed.error) {
163
189
  const errorInfo = directParsed.error;
@@ -175,7 +201,7 @@ export function parseGoogleErrorMessage(message: string): ParsedError {
175
201
  };
176
202
  }
177
203
 
178
- // 3. 处理嵌套JSON格式,特别是message字段包含JSON的情况
204
+ // 3. Handle nested JSON format, especially when message field contains JSON
179
205
  try {
180
206
  const firstLevelParsed = JSON.parse(message);
181
207
  if (firstLevelParsed && firstLevelParsed.error && firstLevelParsed.error.message) {
@@ -197,10 +223,10 @@ export function parseGoogleErrorMessage(message: string): ParsedError {
197
223
  }
198
224
  }
199
225
  } catch {
200
- // 继续其他解析方式
226
+ // Continue with other parsing methods
201
227
  }
202
228
 
203
- // 4. 原有的数组格式解析逻辑
229
+ // 4. Original array format parsing logic
204
230
  const startIndex = message.lastIndexOf('[');
205
231
  if (startIndex !== -1) {
206
232
  try {
@@ -214,11 +240,11 @@ export function parseGoogleErrorMessage(message: string): ParsedError {
214
240
 
215
241
  return { error: json, errorType: AgentRuntimeErrorType.ProviderBizError };
216
242
  } catch {
217
- // 忽略解析错误
243
+ // Ignore parsing errors
218
244
  }
219
245
  }
220
246
 
221
- // 5. 使用状态码提取逻辑作为最后的后备方案
247
+ // 5. Use status code extraction logic as last fallback
222
248
  const errorObj = extractStatusCodeFromError(message);
223
249
  if (errorObj.errorDetails) {
224
250
  return { error: errorObj.errorDetails, errorType: AgentRuntimeErrorType.ProviderBizError };
@@ -1,5 +1,6 @@
1
1
  import type { ILobeAgentRuntimeErrorType } from '@lobechat/model-runtime';
2
2
  import type { IPluginErrorType } from '@lobehub/chat-plugin-sdk';
3
+ import { z } from 'zod';
3
4
 
4
5
  import { ErrorType } from '../../fetch';
5
6
 
@@ -12,6 +13,12 @@ export interface ChatMessageError {
12
13
  type: ErrorType | IPluginErrorType | ILobeAgentRuntimeErrorType;
13
14
  }
14
15
 
16
+ export const ChatMessageErrorSchema = z.object({
17
+ body: z.any().optional(),
18
+ message: z.string(),
19
+ type: z.union([z.string(), z.number()]),
20
+ });
21
+
15
22
  export interface ChatCitationItem {
16
23
  id?: string;
17
24
  onlyUrl?: boolean;
@@ -24,3 +31,9 @@ export interface ModelReasoning {
24
31
  duration?: number;
25
32
  signature?: string;
26
33
  }
34
+
35
+ export const ModelReasoningSchema = z.object({
36
+ content: z.string().optional(),
37
+ duration: z.number().optional(),
38
+ signature: z.string().optional(),
39
+ });
@@ -1,9 +1,17 @@
1
+ import { z } from 'zod';
2
+
1
3
  export interface ChatImageItem {
2
4
  alt: string;
3
5
  id: string;
4
6
  url: string;
5
7
  }
6
8
 
9
+ export const ChatImageItemSchema = z.object({
10
+ alt: z.string(),
11
+ id: z.string(),
12
+ url: z.string(),
13
+ });
14
+
7
15
  export interface ChatImageChunk {
8
16
  data: string;
9
17
  id: string;
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable sort-keys-fix/sort-keys-fix , typescript-sort-keys/interface */
2
+ import { z } from 'zod';
2
3
 
3
4
  export interface ModelTokensUsage {
4
5
  // Input tokens breakdown
@@ -38,6 +39,44 @@ export interface ModelTokensUsage {
38
39
  totalTokens?: number;
39
40
  }
40
41
 
42
+ export const ModelUsageSchema = z.object({
43
+ // Input tokens breakdown
44
+ inputCachedTokens: z.number().optional(),
45
+ inputCacheMissTokens: z.number().optional(),
46
+ inputWriteCacheTokens: z.number().optional(),
47
+ inputTextTokens: z.number().optional(),
48
+ inputImageTokens: z.number().optional(),
49
+ inputAudioTokens: z.number().optional(),
50
+ inputCitationTokens: z.number().optional(),
51
+
52
+ // Output tokens breakdown
53
+ outputTextTokens: z.number().optional(),
54
+ outputImageTokens: z.number().optional(),
55
+ outputAudioTokens: z.number().optional(),
56
+ outputReasoningTokens: z.number().optional(),
57
+
58
+ // Prediction tokens
59
+ acceptedPredictionTokens: z.number().optional(),
60
+ rejectedPredictionTokens: z.number().optional(),
61
+
62
+ // Total tokens
63
+ totalInputTokens: z.number().optional(),
64
+ totalOutputTokens: z.number().optional(),
65
+ totalTokens: z.number().optional(),
66
+
67
+ // Cost
68
+ cost: z.number().optional(),
69
+ });
70
+
71
+ export const ModelPerformanceSchema = z.object({
72
+ tps: z.number().optional(),
73
+ ttft: z.number().optional(),
74
+ duration: z.number().optional(),
75
+ latency: z.number().optional(),
76
+ });
77
+
78
+ export const MessageMetadataSchema = ModelUsageSchema.merge(ModelPerformanceSchema);
79
+
41
80
  export interface ModelUsage extends ModelTokensUsage {
42
81
  /**
43
82
  * dollar
@@ -16,6 +16,7 @@ export interface ChatToolPayload {
16
16
  arguments: string;
17
17
  id: string;
18
18
  identifier: string;
19
+ result_msg_id?: string;
19
20
  type: LobeToolRenderType;
20
21
  }
21
22
 
@@ -85,6 +86,15 @@ export const MessageToolCallSchema = z.object({
85
86
  type: z.string(),
86
87
  });
87
88
 
89
+ export const ChatToolPayloadSchema = z.object({
90
+ apiName: z.string(),
91
+ arguments: z.string(),
92
+ id: z.string(),
93
+ identifier: z.string(),
94
+ result_msg_id: z.string().optional(),
95
+ type: z.string(),
96
+ });
97
+
88
98
  /**
89
99
  * 聊天消息错误对象
90
100
  */
@@ -1,11 +1,20 @@
1
- import { GroundingSearch } from '../../search';
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import { z } from 'zod';
3
+
4
+ import { GroundingSearch, GroundingSearchSchema } from '../../search';
2
5
  import {
3
6
  ChatImageItem,
7
+ ChatImageItemSchema,
4
8
  ChatMessageError,
9
+ ChatMessageErrorSchema,
5
10
  ChatToolPayload,
11
+ ChatToolPayloadSchema,
6
12
  MessageMetadata,
13
+ MessageMetadataSchema,
7
14
  MessageToolCall,
15
+ MessageToolCallSchema,
8
16
  ModelReasoning,
17
+ ModelReasoningSchema,
9
18
  } from '../common';
10
19
  import { UIChatMessage } from '../ui';
11
20
 
@@ -34,6 +43,21 @@ export interface CreateMessageResult {
34
43
  messages: UIChatMessage[];
35
44
  }
36
45
 
46
+ /**
47
+ * Result type for updateMessage
48
+ * Contains success status and optional message list
49
+ */
50
+ export interface UpdateMessageResult {
51
+ /**
52
+ * Updated message list (only present when success is true and sessionId/topicId provided)
53
+ */
54
+ messages?: UIChatMessage[];
55
+ /**
56
+ * Whether the update was successful
57
+ */
58
+ success: boolean;
59
+ }
60
+
37
61
  export interface NewMessage {
38
62
  agentId?: string | null;
39
63
  clientId?: string | null;
@@ -67,12 +91,14 @@ export interface UpdateMessageParams {
67
91
  imageList?: ChatImageItem[];
68
92
  metadata?: MessageMetadata;
69
93
  model?: string;
94
+ observationId?: string;
70
95
  provider?: string;
71
96
  reasoning?: ModelReasoning;
72
97
  role?: string;
73
98
  search?: GroundingSearch;
74
99
  toolCalls?: MessageToolCall[];
75
100
  tools?: ChatToolPayload[] | null;
101
+ traceId?: string;
76
102
  }
77
103
 
78
104
  export interface NewMessageQueryParams {
@@ -81,3 +107,23 @@ export interface NewMessageQueryParams {
81
107
  rewriteQuery: string;
82
108
  userQuery: string;
83
109
  }
110
+
111
+ // ========== Zod Schemas ========== //
112
+
113
+ export const UpdateMessageParamsSchema = z
114
+ .object({
115
+ content: z.string().optional(),
116
+ error: ChatMessageErrorSchema.nullable().optional(),
117
+ imageList: z.array(ChatImageItemSchema).optional(),
118
+ metadata: MessageMetadataSchema.optional(),
119
+ model: z.string().optional(),
120
+ observationId: z.string().optional(),
121
+ provider: z.string().optional(),
122
+ reasoning: ModelReasoningSchema.optional(),
123
+ role: z.string().optional(),
124
+ search: GroundingSearchSchema.optional(),
125
+ toolCalls: z.array(MessageToolCallSchema).optional(),
126
+ tools: z.array(ChatToolPayloadSchema).nullable().optional(),
127
+ traceId: z.string().optional(),
128
+ })
129
+ .passthrough();
@@ -26,10 +26,11 @@ export interface ChatFileItem {
26
26
 
27
27
  export interface AssistantContentBlock {
28
28
  content: string;
29
- fileList?: ChatFileItem[];
29
+ error?: ChatMessageError | null;
30
30
  id: string;
31
31
  imageList?: ChatImageItem[];
32
32
  performance?: ModelPerformance;
33
+ reasoning?: ModelReasoning;
33
34
  tools?: ChatToolPayloadWithResult[];
34
35
  usage?: ModelUsage;
35
36
  }
@@ -62,6 +63,7 @@ export interface UIChatMessage {
62
63
  imageList?: ChatImageItem[];
63
64
  meta: MetaData;
64
65
  metadata?: MessageMetadata | null;
66
+ model?: string | null;
65
67
  /**
66
68
  * observation id
67
69
  */
@@ -78,6 +80,7 @@ export interface UIChatMessage {
78
80
  plugin?: ChatPluginPayload;
79
81
  pluginError?: any;
80
82
  pluginState?: any;
83
+ provider?: string | null;
81
84
  /**
82
85
  * quoted other message's id
83
86
  */