@lobehub/chat 0.146.2 → 0.147.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. package/.env.example +3 -5
  2. package/.github/workflows/issue-close-require.yml +1 -1
  3. package/.github/workflows/release.yml +1 -1
  4. package/.github/workflows/test.yml +3 -1
  5. package/.i18nrc.js +13 -8
  6. package/.seorc.cjs +9 -0
  7. package/CHANGELOG.md +98 -0
  8. package/README.md +25 -25
  9. package/README.zh-CN.md +25 -25
  10. package/contributing/Home.md +1 -1
  11. package/docs/self-hosting/advanced/analytics.mdx +13 -0
  12. package/docs/self-hosting/advanced/analytics.zh-CN.mdx +11 -0
  13. package/docs/self-hosting/advanced/authentication.mdx +26 -6
  14. package/docs/self-hosting/advanced/authentication.zh-CN.mdx +22 -6
  15. package/docs/self-hosting/advanced/sso-providers/auth0.mdx +76 -33
  16. package/docs/self-hosting/advanced/sso-providers/auth0.zh-CN.mdx +74 -33
  17. package/docs/self-hosting/advanced/sso-providers/authentik.mdx +49 -30
  18. package/docs/self-hosting/advanced/sso-providers/authentik.zh-CN.mdx +43 -28
  19. package/docs/self-hosting/advanced/sso-providers/github.mdx +62 -20
  20. package/docs/self-hosting/advanced/sso-providers/github.zh-CN.mdx +70 -34
  21. package/docs/self-hosting/advanced/sso-providers/microsoft-entra-id.mdx +69 -35
  22. package/docs/self-hosting/advanced/sso-providers/microsoft-entra-id.zh-CN.mdx +57 -32
  23. package/docs/self-hosting/advanced/sso-providers/zitadel.mdx +80 -35
  24. package/docs/self-hosting/advanced/sso-providers/zitadel.zh-CN.mdx +75 -37
  25. package/docs/self-hosting/advanced/upstream-sync.mdx +45 -23
  26. package/docs/self-hosting/advanced/upstream-sync.zh-CN.mdx +42 -23
  27. package/docs/self-hosting/environment-variables/analytics.mdx +16 -0
  28. package/docs/self-hosting/environment-variables/analytics.zh-CN.mdx +14 -0
  29. package/docs/self-hosting/environment-variables/auth.mdx +15 -0
  30. package/docs/self-hosting/environment-variables/auth.zh-CN.mdx +16 -1
  31. package/docs/self-hosting/environment-variables/basic.mdx +16 -0
  32. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +12 -0
  33. package/docs/self-hosting/environment-variables/model-provider.mdx +27 -0
  34. package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +11 -0
  35. package/docs/self-hosting/environment-variables.mdx +14 -2
  36. package/docs/self-hosting/environment-variables.zh-CN.mdx +10 -0
  37. package/docs/self-hosting/examples/azure-openai.mdx +24 -8
  38. package/docs/self-hosting/examples/azure-openai.zh-CN.mdx +24 -8
  39. package/docs/self-hosting/examples/ollama.mdx +14 -0
  40. package/docs/self-hosting/examples/ollama.zh-CN.mdx +12 -0
  41. package/docs/self-hosting/faq/no-v1-suffix.mdx +13 -0
  42. package/docs/self-hosting/faq/no-v1-suffix.zh-CN.mdx +10 -0
  43. package/docs/self-hosting/faq/proxy-with-unable-to-verify-leaf-signature.mdx +15 -0
  44. package/docs/self-hosting/faq/proxy-with-unable-to-verify-leaf-signature.zh-CN.mdx +12 -0
  45. package/docs/self-hosting/platform/docker-compose.mdx +103 -80
  46. package/docs/self-hosting/platform/docker-compose.zh-CN.mdx +92 -73
  47. package/docs/self-hosting/platform/docker.mdx +107 -89
  48. package/docs/self-hosting/platform/docker.zh-CN.mdx +106 -89
  49. package/docs/self-hosting/platform/netlify.mdx +109 -44
  50. package/docs/self-hosting/platform/netlify.zh-CN.mdx +102 -39
  51. package/docs/self-hosting/platform/railway.mdx +20 -6
  52. package/docs/self-hosting/platform/railway.zh-CN.mdx +19 -6
  53. package/docs/self-hosting/platform/repocloud.mdx +20 -6
  54. package/docs/self-hosting/platform/repocloud.zh-CN.mdx +18 -6
  55. package/docs/self-hosting/platform/sealos.mdx +19 -6
  56. package/docs/self-hosting/platform/sealos.zh-CN.mdx +18 -6
  57. package/docs/self-hosting/platform/vercel.mdx +21 -7
  58. package/docs/self-hosting/platform/vercel.zh-CN.mdx +20 -7
  59. package/docs/self-hosting/platform/zeabur.mdx +19 -6
  60. package/docs/self-hosting/platform/zeabur.zh-CN.mdx +18 -6
  61. package/docs/self-hosting/start.mdx +23 -1
  62. package/docs/self-hosting/start.zh-CN.mdx +15 -1
  63. package/docs/usage/agents/concepts.mdx +26 -2
  64. package/docs/usage/agents/concepts.zh-CN.mdx +23 -2
  65. package/docs/usage/agents/custom-agent.mdx +25 -4
  66. package/docs/usage/agents/custom-agent.zh-CN.mdx +22 -6
  67. package/docs/usage/agents/model.mdx +14 -5
  68. package/docs/usage/agents/model.zh-CN.mdx +18 -5
  69. package/docs/usage/agents/prompt.mdx +22 -5
  70. package/docs/usage/agents/prompt.zh-CN.mdx +17 -5
  71. package/docs/usage/agents/topics.mdx +22 -1
  72. package/docs/usage/agents/topics.zh-CN.mdx +20 -1
  73. package/docs/usage/features/agent-market.mdx +16 -6
  74. package/docs/usage/features/agent-market.zh-CN.mdx +14 -0
  75. package/docs/usage/features/local-llm.mdx +18 -3
  76. package/docs/usage/features/local-llm.zh-CN.mdx +9 -4
  77. package/docs/usage/features/mobile.mdx +15 -2
  78. package/docs/usage/features/mobile.zh-CN.mdx +17 -1
  79. package/docs/usage/features/more.mdx +14 -0
  80. package/docs/usage/features/more.zh-CN.mdx +11 -0
  81. package/docs/usage/features/multi-ai-providers.mdx +25 -3
  82. package/docs/usage/features/multi-ai-providers.zh-CN.mdx +28 -2
  83. package/docs/usage/features/plugin-system.mdx +20 -8
  84. package/docs/usage/features/plugin-system.zh-CN.mdx +18 -7
  85. package/docs/usage/features/pwa.mdx +21 -5
  86. package/docs/usage/features/pwa.zh-CN.mdx +24 -4
  87. package/docs/usage/features/text-to-image.mdx +11 -1
  88. package/docs/usage/features/text-to-image.zh-CN.mdx +14 -0
  89. package/docs/usage/features/theme.mdx +18 -2
  90. package/docs/usage/features/theme.zh-CN.mdx +18 -1
  91. package/docs/usage/features/tts.mdx +14 -1
  92. package/docs/usage/features/tts.zh-CN.mdx +13 -0
  93. package/docs/usage/features/vision.mdx +11 -1
  94. package/docs/usage/features/vision.zh-CN.mdx +11 -0
  95. package/docs/usage/plugins/basic-usage.mdx +43 -7
  96. package/docs/usage/plugins/basic-usage.zh-CN.mdx +41 -7
  97. package/docs/usage/plugins/custom-plugin.mdx +13 -0
  98. package/docs/usage/plugins/custom-plugin.zh-CN.mdx +11 -0
  99. package/docs/usage/plugins/development.mdx +97 -30
  100. package/docs/usage/plugins/development.zh-CN.mdx +92 -31
  101. package/docs/usage/plugins/store.mdx +23 -2
  102. package/docs/usage/plugins/store.zh-CN.mdx +20 -2
  103. package/docs/usage/providers/groq.mdx +45 -13
  104. package/docs/usage/providers/groq.zh-CN.mdx +41 -13
  105. package/docs/usage/providers/ollama/gemma.mdx +40 -14
  106. package/docs/usage/providers/ollama/gemma.zh-CN.mdx +40 -14
  107. package/docs/usage/providers/ollama/qwen.mdx +41 -19
  108. package/docs/usage/providers/ollama/qwen.zh-CN.mdx +35 -14
  109. package/docs/usage/providers/ollama.mdx +44 -21
  110. package/docs/usage/providers/ollama.zh-CN.mdx +45 -21
  111. package/docs/usage/start.mdx +13 -2
  112. package/docs/usage/start.zh-CN.mdx +11 -2
  113. package/locales/ar/common.json +0 -26
  114. package/locales/ar/components.json +15 -0
  115. package/locales/ar/error.json +1 -52
  116. package/locales/ar/modelProvider.json +226 -0
  117. package/locales/ar/setting.json +48 -199
  118. package/locales/bg-BG/common.json +0 -26
  119. package/locales/bg-BG/components.json +15 -0
  120. package/locales/bg-BG/error.json +1 -52
  121. package/locales/bg-BG/modelProvider.json +226 -0
  122. package/locales/bg-BG/setting.json +48 -199
  123. package/locales/de-DE/common.json +0 -26
  124. package/locales/de-DE/components.json +15 -0
  125. package/locales/de-DE/error.json +1 -52
  126. package/locales/de-DE/modelProvider.json +226 -0
  127. package/locales/de-DE/setting.json +48 -199
  128. package/locales/en-US/common.json +0 -26
  129. package/locales/en-US/components.json +15 -0
  130. package/locales/en-US/error.json +1 -52
  131. package/locales/en-US/modelProvider.json +226 -0
  132. package/locales/en-US/setting.json +48 -199
  133. package/locales/es-ES/common.json +0 -26
  134. package/locales/es-ES/components.json +15 -0
  135. package/locales/es-ES/error.json +1 -52
  136. package/locales/es-ES/modelProvider.json +226 -0
  137. package/locales/es-ES/setting.json +48 -199
  138. package/locales/fr-FR/common.json +0 -26
  139. package/locales/fr-FR/components.json +15 -0
  140. package/locales/fr-FR/error.json +1 -52
  141. package/locales/fr-FR/modelProvider.json +226 -0
  142. package/locales/fr-FR/setting.json +48 -199
  143. package/locales/it-IT/common.json +0 -26
  144. package/locales/it-IT/components.json +15 -0
  145. package/locales/it-IT/error.json +1 -52
  146. package/locales/it-IT/modelProvider.json +226 -0
  147. package/locales/it-IT/setting.json +59 -210
  148. package/locales/ja-JP/common.json +0 -26
  149. package/locales/ja-JP/components.json +15 -0
  150. package/locales/ja-JP/error.json +1 -52
  151. package/locales/ja-JP/modelProvider.json +226 -0
  152. package/locales/ja-JP/setting.json +59 -210
  153. package/locales/ko-KR/common.json +0 -26
  154. package/locales/ko-KR/components.json +15 -0
  155. package/locales/ko-KR/error.json +1 -52
  156. package/locales/ko-KR/modelProvider.json +226 -0
  157. package/locales/ko-KR/setting.json +48 -199
  158. package/locales/nl-NL/common.json +0 -26
  159. package/locales/nl-NL/components.json +15 -0
  160. package/locales/nl-NL/error.json +4 -55
  161. package/locales/nl-NL/modelProvider.json +226 -0
  162. package/locales/nl-NL/setting.json +49 -200
  163. package/locales/pl-PL/common.json +0 -26
  164. package/locales/pl-PL/components.json +15 -0
  165. package/locales/pl-PL/error.json +1 -52
  166. package/locales/pl-PL/modelProvider.json +226 -0
  167. package/locales/pl-PL/setting.json +48 -199
  168. package/locales/pt-BR/common.json +0 -26
  169. package/locales/pt-BR/components.json +15 -0
  170. package/locales/pt-BR/error.json +1 -52
  171. package/locales/pt-BR/modelProvider.json +226 -0
  172. package/locales/pt-BR/setting.json +48 -199
  173. package/locales/ru-RU/common.json +0 -26
  174. package/locales/ru-RU/components.json +15 -0
  175. package/locales/ru-RU/error.json +1 -52
  176. package/locales/ru-RU/modelProvider.json +226 -0
  177. package/locales/ru-RU/setting.json +48 -199
  178. package/locales/tr-TR/common.json +0 -26
  179. package/locales/tr-TR/components.json +15 -0
  180. package/locales/tr-TR/error.json +1 -52
  181. package/locales/tr-TR/modelProvider.json +226 -0
  182. package/locales/tr-TR/setting.json +48 -199
  183. package/locales/vi-VN/common.json +0 -26
  184. package/locales/vi-VN/components.json +15 -0
  185. package/locales/vi-VN/error.json +1 -52
  186. package/locales/vi-VN/modelProvider.json +226 -0
  187. package/locales/vi-VN/setting.json +48 -199
  188. package/locales/zh-CN/common.json +0 -26
  189. package/locales/zh-CN/components.json +15 -0
  190. package/locales/zh-CN/error.json +2 -53
  191. package/locales/zh-CN/modelProvider.json +226 -0
  192. package/locales/zh-CN/setting.json +48 -199
  193. package/locales/zh-TW/common.json +0 -26
  194. package/locales/zh-TW/components.json +15 -0
  195. package/locales/zh-TW/error.json +1 -52
  196. package/locales/zh-TW/modelProvider.json +226 -0
  197. package/locales/zh-TW/setting.json +48 -199
  198. package/package.json +120 -116
  199. package/scripts/mdxWorkflow/index.ts +48 -0
  200. package/src/app/api/chat/[provider]/route.test.ts +4 -9
  201. package/src/app/api/chat/[provider]/route.ts +6 -23
  202. package/src/app/api/chat/{[provider]/agentRuntime.test.ts → agentRuntime.test.ts} +12 -12
  203. package/src/app/api/chat/{[provider]/agentRuntime.ts → agentRuntime.ts} +11 -30
  204. package/src/app/api/chat/auth/index.ts +42 -0
  205. package/src/app/api/chat/models/[provider]/route.ts +45 -0
  206. package/src/app/api/config/__snapshots__/route.test.ts.snap +127 -0
  207. package/src/app/api/config/route.test.ts +170 -0
  208. package/src/app/api/config/route.ts +46 -11
  209. package/src/app/api/plugin/gateway/route.ts +1 -1
  210. package/src/app/settings/llm/Azure/index.tsx +36 -43
  211. package/src/app/settings/llm/Bedrock/index.tsx +12 -20
  212. package/src/app/settings/llm/Ollama/index.tsx +2 -2
  213. package/src/app/settings/llm/OpenAI/index.tsx +9 -121
  214. package/src/app/settings/llm/OpenRouter/index.tsx +1 -1
  215. package/src/app/settings/llm/TogetherAI/index.tsx +0 -1
  216. package/src/app/settings/llm/components/ProviderConfig/index.tsx +48 -32
  217. package/src/app/settings/llm/components/ProviderModelList/CustomModelOption.tsx +94 -0
  218. package/src/app/settings/llm/components/ProviderModelList/MaxTokenSlider.tsx +88 -0
  219. package/src/app/settings/llm/components/ProviderModelList/ModelConfigModal.tsx +128 -0
  220. package/src/app/settings/llm/components/ProviderModelList/ModelFetcher.tsx +81 -0
  221. package/src/app/settings/llm/components/ProviderModelList/Option.tsx +38 -0
  222. package/src/app/settings/llm/components/ProviderModelList/index.tsx +142 -0
  223. package/src/app/settings/llm/const.ts +1 -1
  224. package/src/app/settings/llm/index.tsx +7 -6
  225. package/src/app/settings/tts/TTS/index.tsx +1 -1
  226. package/src/components/AntdStaticMethods/index.test.tsx +43 -0
  227. package/src/components/ModelIcon/index.tsx +25 -7
  228. package/src/components/ModelSelect/index.tsx +67 -56
  229. package/src/config/modelProviders/anthropic.ts +6 -1
  230. package/src/config/modelProviders/azure.ts +42 -0
  231. package/src/config/modelProviders/bedrock.ts +4 -1
  232. package/src/config/modelProviders/google.ts +2 -14
  233. package/src/config/modelProviders/groq.ts +3 -0
  234. package/src/config/modelProviders/index.ts +19 -14
  235. package/src/config/modelProviders/mistral.ts +5 -0
  236. package/src/config/modelProviders/moonshot.ts +3 -1
  237. package/src/config/modelProviders/ollama.ts +6 -17
  238. package/src/config/modelProviders/openai.ts +9 -13
  239. package/src/config/modelProviders/openrouter.ts +6 -1
  240. package/src/config/modelProviders/perplexity.ts +2 -0
  241. package/src/config/modelProviders/togetherai.ts +11 -0
  242. package/src/config/modelProviders/zeroone.ts +3 -0
  243. package/src/config/modelProviders/zhipu.ts +3 -0
  244. package/src/config/server/provider.ts +52 -7
  245. package/src/const/auth.ts +0 -1
  246. package/src/const/{settings.ts → settings/index.ts} +31 -4
  247. package/src/const/url.ts +1 -1
  248. package/src/database/core/db.ts +14 -0
  249. package/src/database/schemas/user.ts +1 -25
  250. package/src/features/AgentSetting/AgentConfig/ModelSelect.tsx +7 -11
  251. package/src/features/ChatInput/STT/common.tsx +80 -78
  252. package/src/features/ChatInput/STT/index.tsx +8 -6
  253. package/src/features/Conversation/Error/APIKeyForm/Bedrock.tsx +8 -8
  254. package/src/features/Conversation/Error/APIKeyForm/ProviderApiKeyForm.tsx +73 -0
  255. package/src/features/Conversation/Error/APIKeyForm/ProviderAvatar.tsx +74 -0
  256. package/src/features/Conversation/Error/APIKeyForm/index.tsx +25 -49
  257. package/src/features/ModelSwitchPanel/index.tsx +40 -13
  258. package/src/hooks/_header.ts +5 -20
  259. package/src/libs/agent-runtime/BaseAI.ts +17 -1
  260. package/src/libs/agent-runtime/anthropic/index.ts +3 -7
  261. package/src/libs/agent-runtime/azureOpenai/index.test.ts +166 -0
  262. package/src/libs/agent-runtime/azureOpenai/index.ts +16 -8
  263. package/src/libs/agent-runtime/bedrock/index.test.ts +199 -22
  264. package/src/libs/agent-runtime/bedrock/index.ts +11 -18
  265. package/src/libs/agent-runtime/groq/index.test.ts +350 -0
  266. package/src/libs/agent-runtime/groq/index.ts +14 -77
  267. package/src/libs/agent-runtime/mistral/index.test.ts +25 -19
  268. package/src/libs/agent-runtime/mistral/index.ts +24 -86
  269. package/src/libs/agent-runtime/moonshot/index.test.ts +2 -2
  270. package/src/libs/agent-runtime/moonshot/index.ts +14 -77
  271. package/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap +99 -0
  272. package/src/libs/agent-runtime/openai/fixtures/openai-models.json +170 -0
  273. package/src/libs/agent-runtime/openai/index.test.ts +15 -50
  274. package/src/libs/agent-runtime/openai/index.ts +15 -107
  275. package/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +82 -0
  276. package/src/libs/agent-runtime/openrouter/fixtures/models.json +62 -0
  277. package/src/libs/agent-runtime/openrouter/index.test.ts +25 -9
  278. package/src/libs/agent-runtime/openrouter/index.ts +42 -84
  279. package/src/libs/agent-runtime/openrouter/type.ts +28 -0
  280. package/src/libs/agent-runtime/togetherai/index.test.ts +12 -9
  281. package/src/libs/agent-runtime/togetherai/index.ts +20 -85
  282. package/src/libs/agent-runtime/utils/anthropicHelpers.test.ts +14 -22
  283. package/src/libs/agent-runtime/utils/anthropicHelpers.ts +4 -10
  284. package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +147 -0
  285. package/src/libs/agent-runtime/zeroone/index.test.ts +350 -0
  286. package/src/libs/agent-runtime/zeroone/index.ts +14 -77
  287. package/src/locales/default/common.ts +0 -28
  288. package/src/locales/default/components.ts +15 -0
  289. package/src/locales/default/error.ts +2 -54
  290. package/src/locales/default/index.ts +4 -0
  291. package/src/locales/default/modelProvider.ts +229 -0
  292. package/src/locales/default/setting.ts +51 -202
  293. package/src/locales/resources.test.ts +49 -0
  294. package/src/locales/resources.ts +7 -20
  295. package/src/migrations/FromV3ToV4/fixtures/azure-input-v3.json +79 -0
  296. package/src/migrations/FromV3ToV4/fixtures/azure-output-v4.json +75 -0
  297. package/src/migrations/FromV3ToV4/fixtures/ollama-input-v3.json +85 -0
  298. package/src/migrations/FromV3ToV4/fixtures/ollama-output-v4.json +86 -0
  299. package/src/migrations/FromV3ToV4/fixtures/openai-input-v3.json +77 -0
  300. package/src/migrations/FromV3ToV4/fixtures/openai-output-v4.json +79 -0
  301. package/src/migrations/FromV3ToV4/fixtures/openrouter-input-v3.json +82 -0
  302. package/src/migrations/FromV3ToV4/fixtures/openrouter-output-v4.json +89 -0
  303. package/src/migrations/FromV3ToV4/fixtures/output-v4-from-v1.json +203 -0
  304. package/src/migrations/FromV3ToV4/index.ts +96 -0
  305. package/src/migrations/FromV3ToV4/migrations.test.ts +195 -0
  306. package/src/migrations/FromV3ToV4/types/v3.ts +59 -0
  307. package/src/migrations/FromV3ToV4/types/v4.ts +37 -0
  308. package/src/migrations/index.ts +11 -3
  309. package/src/services/_auth.test.ts +4 -6
  310. package/src/services/_auth.ts +8 -60
  311. package/src/services/_header.ts +5 -22
  312. package/src/services/_url.ts +1 -0
  313. package/src/services/chat.ts +16 -6
  314. package/src/services/global.ts +1 -1
  315. package/src/services/models.ts +23 -0
  316. package/src/services/ollama.ts +2 -2
  317. package/src/store/chat/slices/share/action.test.ts +113 -0
  318. package/src/store/chat/slices/share/action.ts +1 -1
  319. package/src/store/global/slices/common/action.test.ts +166 -1
  320. package/src/store/global/slices/common/action.ts +2 -1
  321. package/src/store/global/slices/settings/{action.test.ts → actions/general.test.ts} +1 -19
  322. package/src/store/global/slices/settings/{action.ts → actions/general.ts} +4 -19
  323. package/src/store/global/slices/settings/actions/index.ts +18 -0
  324. package/src/store/global/slices/settings/actions/llm.test.ts +60 -0
  325. package/src/store/global/slices/settings/actions/llm.ts +88 -0
  326. package/src/store/global/slices/settings/initialState.ts +3 -1
  327. package/src/store/global/slices/settings/reducers/customModelCard.test.ts +204 -0
  328. package/src/store/global/slices/settings/reducers/customModelCard.ts +64 -0
  329. package/src/store/global/slices/settings/selectors/index.ts +1 -0
  330. package/src/store/global/slices/settings/selectors/modelConfig.test.ts +189 -0
  331. package/src/store/global/slices/settings/selectors/modelConfig.ts +179 -0
  332. package/src/store/global/slices/settings/selectors/modelProvider.test.ts +47 -138
  333. package/src/store/global/slices/settings/selectors/modelProvider.ts +102 -243
  334. package/src/store/global/store.ts +1 -1
  335. package/src/types/llm.ts +12 -1
  336. package/src/types/serverConfig.ts +22 -0
  337. package/src/types/settings/index.ts +0 -12
  338. package/src/types/settings/modelProvider.ts +34 -90
  339. package/src/utils/client/switchLang.test.ts +34 -0
  340. package/src/utils/difference.test.ts +46 -0
  341. package/src/utils/difference.ts +15 -2
  342. package/src/utils/fetch.ts +1 -3
  343. package/src/utils/parseModels.ts +62 -0
  344. package/vercel.json +1 -1
  345. package/docs/package.json +0 -5
  346. package/src/features/Conversation/Error/APIKeyForm/Anthropic.tsx +0 -40
  347. package/src/features/Conversation/Error/APIKeyForm/Google.tsx +0 -61
  348. package/src/features/Conversation/Error/APIKeyForm/Groq.tsx +0 -60
  349. package/src/features/Conversation/Error/APIKeyForm/Mistral.tsx +0 -60
  350. package/src/features/Conversation/Error/APIKeyForm/Moonshot.tsx +0 -60
  351. package/src/features/Conversation/Error/APIKeyForm/OpenAI.tsx +0 -63
  352. package/src/features/Conversation/Error/APIKeyForm/OpenRouter.tsx +0 -40
  353. package/src/features/Conversation/Error/APIKeyForm/Perplexity.tsx +0 -60
  354. package/src/features/Conversation/Error/APIKeyForm/TogetherAI.tsx +0 -40
  355. package/src/features/Conversation/Error/APIKeyForm/ZeroOne.tsx +0 -60
  356. package/src/features/Conversation/Error/APIKeyForm/Zhipu.tsx +0 -62
  357. package/src/libs/agent-runtime/utils/env.ts +0 -1
  358. package/src/store/global/slices/settings/selectors/__snapshots__/modelProvider.test.ts.snap +0 -230
  359. /package/src/app/api/chat/{auth.ts → auth/utils.ts} +0 -0
  360. /package/src/components/{AntdStaticMethods.tsx → AntdStaticMethods/index.tsx} +0 -0
@@ -1,203 +1,119 @@
1
- import { produce } from 'immer';
2
-
3
1
  import {
4
- AnthropicProvider,
5
- BedrockProvider,
6
- GoogleProvider,
7
- GroqProvider,
8
- LOBE_DEFAULT_MODEL_LIST,
9
- MistralProvider,
10
- MoonshotProvider,
11
- OllamaProvider,
12
- OpenAIProvider,
13
- OpenRouterProvider,
14
- PerplexityProvider,
15
- TogetherAIProvider,
16
- ZeroOneProvider,
17
- ZhiPuProvider,
2
+ AnthropicProviderCard,
3
+ AzureProviderCard,
4
+ BedrockProviderCard,
5
+ GoogleProviderCard,
6
+ GroqProviderCard,
7
+ MistralProviderCard,
8
+ MoonshotProviderCard,
9
+ OllamaProviderCard,
10
+ OpenAIProviderCard,
11
+ OpenRouterProviderCard,
12
+ PerplexityProviderCard,
13
+ TogetherAIProviderCard,
14
+ ZeroOneProviderCard,
15
+ ZhiPuProviderCard,
16
+ filterEnabledModels,
18
17
  } from '@/config/modelProviders';
19
18
  import { ChatModelCard, ModelProviderCard } from '@/types/llm';
19
+ import { ServerModelProviderConfig } from '@/types/serverConfig';
20
20
  import { GlobalLLMProviderKey } from '@/types/settings';
21
- import { parseModelString } from '@/utils/parseModels';
22
21
 
23
22
  import { GlobalStore } from '../../../store';
24
23
  import { currentSettings } from './settings';
25
24
 
26
- const modelProvider = (s: GlobalStore) => currentSettings(s).languageModel;
27
- const providerEnabled = (provider: GlobalLLMProviderKey) => (s: GlobalStore) =>
28
- currentSettings(s).languageModel[provider]?.enabled || false;
29
-
30
- const openAIConfig = (s: GlobalStore) => modelProvider(s).openAI;
31
-
32
- const openAIAPIKey = (s: GlobalStore) => openAIConfig(s).OPENAI_API_KEY;
33
- const openAIProxyUrl = (s: GlobalStore) => openAIConfig(s).endpoint;
34
-
35
- const enableZhipu = (s: GlobalStore) => modelProvider(s).zhipu.enabled;
36
- const zhipuAPIKey = (s: GlobalStore) => modelProvider(s).zhipu.apiKey;
37
- const zhipuProxyUrl = (s: GlobalStore) => modelProvider(s).zhipu.endpoint;
38
-
39
- const enableBedrock = (s: GlobalStore) => modelProvider(s).bedrock.enabled;
40
- const bedrockConfig = (s: GlobalStore) => modelProvider(s).bedrock;
41
-
42
- const enableGoogle = (s: GlobalStore) => modelProvider(s).google.enabled;
43
- const googleAPIKey = (s: GlobalStore) => modelProvider(s).google.apiKey;
44
- const googleProxyUrl = (s: GlobalStore) => modelProvider(s).google.endpoint;
45
-
46
- const enableAzure = (s: GlobalStore) => modelProvider(s).openAI.useAzure;
47
- const azureConfig = (s: GlobalStore) => modelProvider(s).azure;
48
-
49
- const enableMistral = (s: GlobalStore) => modelProvider(s).mistral.enabled;
50
- const mistralAPIKey = (s: GlobalStore) => modelProvider(s).mistral.apiKey;
51
-
52
- const enableMoonshot = (s: GlobalStore) => modelProvider(s).moonshot.enabled;
53
- const moonshotAPIKey = (s: GlobalStore) => modelProvider(s).moonshot.apiKey;
54
-
55
- const enableOllama = (s: GlobalStore) => modelProvider(s).ollama.enabled;
56
- const ollamaProxyUrl = (s: GlobalStore) => modelProvider(s).ollama.endpoint;
57
-
58
- const enablePerplexity = (s: GlobalStore) => modelProvider(s).perplexity.enabled;
59
- const perplexityAPIKey = (s: GlobalStore) => modelProvider(s).perplexity.apiKey;
60
-
61
- const enableAnthropic = (s: GlobalStore) => modelProvider(s).anthropic.enabled;
62
- const anthropicAPIKey = (s: GlobalStore) => modelProvider(s).anthropic.apiKey;
63
- const anthropicProxyUrl = (s: GlobalStore) => modelProvider(s).anthropic.endpoint;
64
-
65
- const enableGroq = (s: GlobalStore) => modelProvider(s).groq.enabled;
66
- const groqAPIKey = (s: GlobalStore) => modelProvider(s).groq.apiKey;
25
+ /**
26
+ * get the server side model cards
27
+ */
28
+ const serverProviderModelCards =
29
+ (provider: GlobalLLMProviderKey) =>
30
+ (s: GlobalStore): ChatModelCard[] | undefined => {
31
+ const config = s.serverConfig.languageModel?.[provider] as
32
+ | ServerModelProviderConfig
33
+ | undefined;
34
+
35
+ if (!config) return;
36
+
37
+ return config.serverModelCards;
38
+ };
39
+
40
+ const remoteProviderModelCards =
41
+ (provider: GlobalLLMProviderKey) =>
42
+ (s: GlobalStore): ChatModelCard[] | undefined => {
43
+ const cards = currentSettings(s).languageModel?.[provider]?.remoteModelCards as
44
+ | ChatModelCard[]
45
+ | undefined;
46
+
47
+ if (!cards) return;
48
+
49
+ return cards;
50
+ };
51
+
52
+ /**
53
+ * define all the model list of providers
54
+ */
55
+ const providerModelList = (s: GlobalStore): ModelProviderCard[] => {
56
+ /**
57
+ * Because we have several model cards sources, we need to merge the model cards
58
+ * the priority is below:
59
+ * 1 - server side model cards
60
+ * 2 - remote model cards
61
+ * 3 - default model cards
62
+ */
63
+
64
+ const mergeModels = (provider: GlobalLLMProviderKey, defaultChatModels: ChatModelCard[]) => {
65
+ // if the chat model is config in the server side, use the server side model cards
66
+ const serverChatModels = serverProviderModelCards(provider)(s);
67
+ const remoteChatModels = remoteProviderModelCards(provider)(s);
68
+
69
+ return serverChatModels ?? remoteChatModels ?? defaultChatModels;
70
+ };
67
71
 
68
- const enableOpenrouter = (s: GlobalStore) => modelProvider(s).openrouter.enabled;
69
- const openrouterAPIKey = (s: GlobalStore) => modelProvider(s).openrouter.apiKey;
70
-
71
- const enableTogetherAI = (s: GlobalStore) => modelProvider(s).togetherai.enabled;
72
- const togetheraiAPIKey = (s: GlobalStore) => modelProvider(s).togetherai.apiKey;
73
-
74
- const enableZeroone = (s: GlobalStore) => modelProvider(s).zeroone.enabled;
75
- const zerooneAPIKey = (s: GlobalStore) => modelProvider(s).zeroone.apiKey;
76
-
77
- // const azureModelList = (s: GlobalStore): ModelProviderCard => {
78
- // const azure = azureConfig(s);
79
- // return {
80
- // chatModels: parseModelString(azure.deployments),
81
- // id: 'azure',
82
- // };
83
- // };
84
-
85
- // 提取处理 chatModels 的专门方法
86
- const processChatModels = (
87
- modelConfig: ReturnType<typeof parseModelString>,
88
- defaultChartModels = OpenAIProvider.chatModels,
89
- ): ChatModelCard[] => {
90
- let chatModels = modelConfig.removeAll ? [] : defaultChartModels;
91
-
92
- // 处理移除逻辑
93
- if (!modelConfig.removeAll) {
94
- chatModels = chatModels.filter((m) => !modelConfig.removed.includes(m.id));
95
- }
96
-
97
- return produce(chatModels, (draft) => {
98
- // 处理添加或替换逻辑
99
- for (const toAddModel of modelConfig.add) {
100
- // first try to find the model in LOBE_DEFAULT_MODEL_LIST to confirm if it is a known model
101
- const knownModel = LOBE_DEFAULT_MODEL_LIST.find((model) => model.id === toAddModel.id);
102
-
103
- // if the model is known, update it based on the known model
104
- if (knownModel) {
105
- const modelInList = draft.find((model) => model.id === toAddModel.id);
106
-
107
- // if the model is already in chatModels, update it
108
- if (modelInList) {
109
- if (modelInList.hidden) delete modelInList.hidden;
110
- if (toAddModel.displayName) modelInList.displayName = toAddModel.displayName;
111
- } else {
112
- // if the model is not in chatModels, add it
113
- draft.push({
114
- ...knownModel,
115
- displayName: toAddModel.displayName || knownModel.displayName || knownModel.id,
116
- hidden: undefined,
117
- });
118
- }
119
- } else {
120
- // if the model is not in LOBE_DEFAULT_MODEL_LIST, add it as a new custom model
121
- draft.push({
122
- ...toAddModel,
123
- displayName: toAddModel.displayName || toAddModel.id,
124
- functionCall: true,
125
- isCustom: true,
126
- vision: true,
127
- });
128
- }
129
- }
130
- });
72
+ return [
73
+ {
74
+ ...OpenAIProviderCard,
75
+ chatModels: mergeModels('openai', OpenAIProviderCard.chatModels),
76
+ },
77
+ { ...AzureProviderCard, chatModels: [] },
78
+ { ...OllamaProviderCard, chatModels: mergeModels('ollama', OllamaProviderCard.chatModels) },
79
+ AnthropicProviderCard,
80
+ GoogleProviderCard,
81
+ {
82
+ ...OpenRouterProviderCard,
83
+ chatModels: mergeModels('openrouter', OpenRouterProviderCard.chatModels),
84
+ },
85
+ {
86
+ ...TogetherAIProviderCard,
87
+ chatModels: mergeModels('togetherai', TogetherAIProviderCard.chatModels),
88
+ },
89
+ BedrockProviderCard,
90
+ PerplexityProviderCard,
91
+ MistralProviderCard,
92
+ GroqProviderCard,
93
+ MoonshotProviderCard,
94
+ ZeroOneProviderCard,
95
+ ZhiPuProviderCard,
96
+ ];
131
97
  };
132
98
 
133
- const modelSelectList = (s: GlobalStore): ModelProviderCard[] => {
134
- const openaiModelString = [
135
- s.serverConfig.customModelName,
136
- currentSettings(s).languageModel.openAI.customModelName,
137
- ]
138
- .filter(Boolean)
139
- .join(',');
140
-
141
- const openaiModelConfig = parseModelString(openaiModelString);
142
-
143
- const openaiChatModels = processChatModels(openaiModelConfig);
144
-
145
- const ollamaModelString = [
146
- s.serverConfig.languageModel?.ollama?.customModelName,
147
- currentSettings(s).languageModel.ollama.customModelName,
148
- ]
149
- .filter(Boolean)
150
- .join(',');
151
-
152
- const ollamaModelConfig = parseModelString(ollamaModelString);
99
+ const providerCard = (provider: string) => (s: GlobalStore) =>
100
+ providerModelList(s).find((s) => s.id === provider);
153
101
 
154
- const ollamaChatModels = processChatModels(ollamaModelConfig, OllamaProvider.chatModels);
102
+ /**
103
+ * get the default enabled models for a provider
104
+ * it's a default enabled model list by Lobe Chat
105
+ * e.g. openai is ['gpt-3.5-turbo','gpt-4-turbo-preview','gpt-4-vision-preview']
106
+ */
107
+ const defaultEnabledProviderModels = (provider: string) => (s: GlobalStore) => {
108
+ const modelProvider = providerCard(provider)(s);
155
109
 
156
- const openrouterModelString = [
157
- s.serverConfig.languageModel?.openrouter?.customModelName,
158
- currentSettings(s).languageModel.openrouter.customModelName,
159
- ]
160
- .filter(Boolean)
161
- .join(',');
110
+ if (modelProvider) return filterEnabledModels(modelProvider);
162
111
 
163
- const openrouterModelConfig = parseModelString(openrouterModelString);
164
-
165
- const openrouterChatModels = processChatModels(
166
- openrouterModelConfig,
167
- OpenRouterProvider.chatModels,
168
- );
169
-
170
- const togetheraiModelConfig = parseModelString(
171
- currentSettings(s).languageModel.togetherai.customModelName,
172
- );
173
- const togetheraiChatModels = processChatModels(
174
- togetheraiModelConfig,
175
- TogetherAIProvider.chatModels,
176
- );
177
-
178
- return [
179
- {
180
- ...OpenAIProvider,
181
- chatModels: openaiChatModels,
182
- },
183
- // { ...azureModelList(s), enabled: enableAzure(s) },
184
- { ...OllamaProvider, chatModels: ollamaChatModels, enabled: enableOllama(s) },
185
- { ...AnthropicProvider, enabled: enableAnthropic(s) },
186
- { ...GoogleProvider, enabled: enableGoogle(s) },
187
- { ...BedrockProvider, enabled: enableBedrock(s) },
188
- { ...PerplexityProvider, enabled: enablePerplexity(s) },
189
- { ...MistralProvider, enabled: enableMistral(s) },
190
- { ...GroqProvider, enabled: enableGroq(s) },
191
- { ...ZhiPuProvider, enabled: enableZhipu(s) },
192
- { ...MoonshotProvider, enabled: enableMoonshot(s) },
193
- { ...OpenRouterProvider, chatModels: openrouterChatModels, enabled: enableOpenrouter(s) },
194
- { ...ZeroOneProvider, enabled: enableZeroone(s) },
195
- { ...TogetherAIProvider, chatModels: togetheraiChatModels, enabled: enableTogetherAI(s) },
196
- ];
112
+ return undefined;
197
113
  };
198
114
 
199
115
  const modelCardById = (id: string) => (s: GlobalStore) => {
200
- const list = modelSelectList(s);
116
+ const list = providerModelList(s);
201
117
 
202
118
  return list.flatMap((i) => i.chatModels).find((m) => m.id === id);
203
119
  };
@@ -222,7 +138,9 @@ const modelMaxToken = (id: string) => (s: GlobalStore) => modelCardById(id)(s)?.
222
138
 
223
139
  /* eslint-disable sort-keys-fix/sort-keys-fix, */
224
140
  export const modelProviderSelectors = {
225
- modelSelectList,
141
+ providerModelList,
142
+ providerCard,
143
+ defaultEnabledProviderModels,
226
144
 
227
145
  modelCardById,
228
146
  modelMaxToken,
@@ -232,63 +150,4 @@ export const modelProviderSelectors = {
232
150
  modelEnabledVision,
233
151
  modelEnabledFiles,
234
152
  modelEnabledUpload,
235
-
236
- modelProviderConfig: modelProvider,
237
- providerEnabled,
238
-
239
- // OpenAI
240
- openAIConfig,
241
- openAIAPIKey,
242
- openAIProxyUrl,
243
- // Azure OpenAI
244
- enableAzure,
245
- azureConfig,
246
- // Zhipu
247
- enableZhipu,
248
- zhipuAPIKey,
249
- zhipuProxyUrl,
250
- // Google
251
- enableGoogle,
252
- googleAPIKey,
253
- googleProxyUrl,
254
- // Bedrock
255
- enableBedrock,
256
- bedrockConfig,
257
-
258
- // Moonshot
259
- enableMoonshot,
260
- moonshotAPIKey,
261
-
262
- // Ollama
263
- enableOllama,
264
- ollamaProxyUrl,
265
-
266
- // Perplexity
267
- enablePerplexity,
268
- perplexityAPIKey,
269
-
270
- // Anthropic
271
- enableAnthropic,
272
- anthropicAPIKey,
273
- anthropicProxyUrl,
274
-
275
- // Mistral
276
- enableMistral,
277
- mistralAPIKey,
278
-
279
- // Groq
280
- enableGroq,
281
- groqAPIKey,
282
-
283
- // OpenRouter
284
- enableOpenrouter,
285
- openrouterAPIKey,
286
-
287
- // ZeroOne 零一万物
288
- enableZeroone,
289
- zerooneAPIKey,
290
-
291
- // TogetherAI
292
- enableTogetherAI,
293
- togetheraiAPIKey,
294
153
  };
@@ -9,7 +9,7 @@ import { createHyperStorage } from '../middleware/createHyperStorage';
9
9
  import { type GlobalState, initialState } from './initialState';
10
10
  import { type CommonAction, createCommonSlice } from './slices/common/action';
11
11
  import { type PreferenceAction, createPreferenceSlice } from './slices/preference/action';
12
- import { type SettingsAction, createSettingsSlice } from './slices/settings/action';
12
+ import { type SettingsAction, createSettingsSlice } from './slices/settings/actions';
13
13
 
14
14
  // =============== 聚合 createStoreFn ============ //
15
15
 
package/src/types/llm.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  export interface ChatModelCard {
2
+ /**
3
+ * only used in azure
4
+ */
5
+ deploymentName?: string;
2
6
  description?: string;
7
+ /**
8
+ * the name show for end user
9
+ */
3
10
  displayName?: string;
11
+
12
+ /**
13
+ * whether model is enabled by default
14
+ */
15
+ enabled?: boolean;
4
16
  /**
5
17
  * whether model supports file upload
6
18
  */
@@ -9,7 +21,6 @@ export interface ChatModelCard {
9
21
  * whether model supports function call
10
22
  */
11
23
  functionCall?: boolean;
12
- hidden?: boolean;
13
24
  id: string;
14
25
  /**
15
26
  * whether model is custom
@@ -0,0 +1,22 @@
1
+ import { DeepPartial } from 'utility-types';
2
+
3
+ import { ChatModelCard } from '@/types/llm';
4
+ import { GlobalDefaultAgent, GlobalLLMProviderKey } from '@/types/settings';
5
+
6
+ export interface ServerModelProviderConfig {
7
+ enabled?: boolean;
8
+
9
+ /**
10
+ * the model cards defined in server
11
+ */
12
+ serverModelCards?: ChatModelCard[];
13
+ }
14
+
15
+ export interface GlobalServerConfig {
16
+ defaultAgent?: DeepPartial<GlobalDefaultAgent>;
17
+ enabledOAuthSSO?: boolean;
18
+ languageModel?: Partial<Record<GlobalLLMProviderKey, ServerModelProviderConfig>>;
19
+ telemetry: {
20
+ langfuse?: boolean;
21
+ };
22
+ }
@@ -1,5 +1,3 @@
1
- import { DeepPartial } from 'utility-types';
2
-
3
1
  import type { LobeAgentSession } from '@/types/session';
4
2
 
5
3
  import { GlobalBaseSettings } from './base';
@@ -20,16 +18,6 @@ export interface GlobalTool {
20
18
  };
21
19
  }
22
20
 
23
- export interface GlobalServerConfig {
24
- customModelName?: string;
25
- defaultAgent?: DeepPartial<GlobalDefaultAgent>;
26
- enabledOAuthSSO?: boolean;
27
- languageModel?: DeepPartial<GlobalLLMConfig>;
28
- telemetry: {
29
- langfuse?: boolean;
30
- };
31
- }
32
-
33
21
  /**
34
22
  * 配置设置
35
23
  */
@@ -1,114 +1,58 @@
1
+ import { ChatModelCard } from '@/types/llm';
2
+
1
3
  export type CustomModels = { displayName: string; id: string }[];
2
4
 
3
- export interface OpenAIConfig {
4
- OPENAI_API_KEY: string;
5
- azureApiVersion?: string;
5
+ export interface GeneralModelProviderConfig {
6
+ apiKey?: string;
7
+ /**
8
+ * whether to auto fetch model lists
9
+ */
10
+ autoFetchModelLists?: boolean;
6
11
  /**
7
- * custom mode name for fine-tuning or openai like model
12
+ * user defined model cards
8
13
  */
9
- customModelName?: string;
14
+ customModelCards?: ChatModelCard[];
10
15
  enabled: boolean;
16
+ /**
17
+ * enabled models id
18
+ */
19
+ enabledModels?: string[] | null;
11
20
  endpoint?: string;
12
21
  /**
13
- * @deprecated
22
+ * the latest fetch model list time
23
+ */
24
+ latestFetchTime?: number;
25
+ /**
26
+ * fetched models from provider side
14
27
  */
15
- models?: string[];
16
- useAzure?: boolean;
28
+ remoteModelCards?: ChatModelCard[];
17
29
  }
18
30
 
19
- export interface AzureOpenAIConfig {
20
- apiKey: string;
31
+ export interface AzureOpenAIConfig extends GeneralModelProviderConfig {
21
32
  apiVersion?: string;
22
- deployments: string;
23
- enabled: boolean;
24
- endpoint?: string;
25
- }
26
-
27
- export interface ZhiPuConfig {
28
- apiKey?: string;
29
- enabled: boolean;
30
- endpoint?: string;
31
- }
32
-
33
- export interface MoonshotConfig {
34
- apiKey?: string;
35
- enabled: boolean;
36
- }
37
-
38
- export interface GoogleConfig {
39
- apiKey?: string;
40
- enabled: boolean;
41
- endpoint?: string;
42
33
  }
43
34
 
44
- export interface AWSBedrockConfig {
35
+ export interface AWSBedrockConfig extends Omit<GeneralModelProviderConfig, 'apiKey' | 'endpoint'> {
45
36
  accessKeyId?: string;
46
- enabled: boolean;
47
37
  region?: string;
48
38
  secretAccessKey?: string;
49
39
  }
50
40
 
51
- export interface OllamaConfig {
52
- customModelName?: string;
53
- enabled?: boolean;
54
- endpoint?: string;
55
- }
56
-
57
- export interface PerplexityConfig {
58
- apiKey?: string;
59
- enabled: boolean;
60
- endpoint?: string;
61
- }
62
-
63
- export interface AnthropicConfig {
64
- apiKey?: string;
65
- enabled: boolean;
66
- endpoint?: string;
67
- }
68
-
69
- export interface MistralConfig {
70
- apiKey?: string;
71
- enabled: boolean;
72
- }
73
-
74
- export interface GroqConfig {
75
- apiKey?: string;
76
- enabled: boolean;
77
- }
78
-
79
- export interface OpenRouterConfig {
80
- apiKey?: string;
81
- customModelName?: string;
82
- enabled?: boolean;
83
- }
84
-
85
- export interface ZeroOneConfig {
86
- apiKey?: string;
87
- customModelName?: string;
88
- enabled?: boolean;
89
- }
90
-
91
- export interface TogetherAIConfig {
92
- apiKey?: string;
93
- customModelName?: string;
94
- enabled?: boolean;
95
- }
96
-
97
41
  export interface GlobalLLMConfig {
98
- anthropic: AnthropicConfig;
42
+ anthropic: GeneralModelProviderConfig;
99
43
  azure: AzureOpenAIConfig;
100
44
  bedrock: AWSBedrockConfig;
101
- google: GoogleConfig;
102
- groq: GroqConfig;
103
- mistral: MistralConfig;
104
- moonshot: MoonshotConfig;
105
- ollama: OllamaConfig;
106
- openAI: OpenAIConfig;
107
- openrouter: OpenRouterConfig;
108
- perplexity: PerplexityConfig;
109
- togetherai: TogetherAIConfig;
110
- zeroone: ZeroOneConfig;
111
- zhipu: ZhiPuConfig;
45
+ google: GeneralModelProviderConfig;
46
+ groq: GeneralModelProviderConfig;
47
+ mistral: GeneralModelProviderConfig;
48
+ moonshot: GeneralModelProviderConfig;
49
+ ollama: GeneralModelProviderConfig;
50
+ openai: GeneralModelProviderConfig;
51
+ openrouter: GeneralModelProviderConfig;
52
+ perplexity: GeneralModelProviderConfig;
53
+ togetherai: GeneralModelProviderConfig;
54
+ zeroone: GeneralModelProviderConfig;
55
+ zhipu: GeneralModelProviderConfig;
112
56
  }
113
57
 
114
58
  export type GlobalLLMProviderKey = keyof GlobalLLMConfig;
@@ -0,0 +1,34 @@
1
+ import { changeLanguage } from 'i18next';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+
4
+ import { LocaleMode } from '@/types/locale';
5
+
6
+ import { switchLang } from './switchLang';
7
+
8
+ vi.mock('i18next', () => ({
9
+ changeLanguage: vi.fn(),
10
+ }));
11
+
12
+ describe('switchLang', () => {
13
+ afterEach(() => {
14
+ vi.resetAllMocks();
15
+ });
16
+
17
+ it('should change language to the specified locale', () => {
18
+ const locale: LocaleMode = 'en-US';
19
+ switchLang(locale);
20
+
21
+ expect(changeLanguage).toHaveBeenCalledWith(locale);
22
+ expect(document.documentElement.lang).toBe(locale);
23
+ });
24
+
25
+ it('should change language based on navigator.language when locale is "auto"', () => {
26
+ const navigatorLanguage = 'fr';
27
+ vi.spyOn(navigator, 'language', 'get').mockReturnValue(navigatorLanguage);
28
+
29
+ switchLang('auto');
30
+
31
+ expect(changeLanguage).toHaveBeenCalledWith(navigatorLanguage);
32
+ expect(document.documentElement.lang).toBe(navigatorLanguage);
33
+ });
34
+ });