@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
@@ -17,88 +17,90 @@ const useStyles = createStyles(({ css, token }) => ({
17
17
  `,
18
18
  }));
19
19
 
20
- const CommonSTT = memo<{
21
- desc: string;
22
- error?: ChatMessageError;
23
- formattedTime: string;
24
- handleCloseError: () => void;
25
- handleRetry: () => void;
26
- handleTriggerStartStop: () => void;
27
- isLoading: boolean;
28
- isRecording: boolean;
29
- mobile?: boolean;
30
- time: number;
31
- }>(({
20
+ const CommonSTT = memo<{
21
+ desc: string;
22
+ error?: ChatMessageError;
23
+ formattedTime: string;
24
+ handleCloseError: () => void;
25
+ handleRetry: () => void;
26
+ handleTriggerStartStop: () => void;
27
+ isLoading: boolean;
28
+ isRecording: boolean;
29
+ mobile?: boolean;
30
+ time: number;
31
+ }>(
32
+ ({
32
33
  mobile,
33
- isLoading,
34
- formattedTime,
35
- time,
36
- isRecording,
37
- error,
34
+ isLoading,
35
+ formattedTime,
36
+ time,
37
+ isRecording,
38
+ error,
38
39
  handleRetry,
39
40
  handleTriggerStartStop,
40
41
  handleCloseError,
41
42
  desc,
42
- }) => {
43
- const { t } = useTranslation('chat');
44
- const { styles } = useStyles();
43
+ }) => {
44
+ const { t } = useTranslation('chat');
45
+ const { styles } = useStyles();
45
46
 
46
- return (
47
- <Dropdown
48
- dropdownRender={
49
- error
50
- ? () => (
51
- <Alert
52
- action={
53
- <Button onClick={handleRetry} size={'small'} type={'primary'}>
54
- {t('retry', { ns: 'common' })}
55
- </Button>
56
- }
57
- closable
58
- extra={
59
- error.body && (
60
- <Highlighter copyButtonSize={'small'} language={'json'} type={'pure'}>
61
- {JSON.stringify(error.body, null, 2)}
62
- </Highlighter>
63
- )
64
- }
65
- message={error.message}
66
- onClose={handleCloseError}
67
- style={{ alignItems: 'center' }}
68
- type="error"
69
- />
70
- )
71
- : undefined
72
- }
73
- menu={{
74
- activeKey: 'time',
75
- items: [
76
- {
77
- key: 'time',
78
- label: (
79
- <Flexbox align={'center'} gap={8} horizontal>
80
- <div className={styles.recording} />
81
- {time > 0 ? formattedTime : t(isRecording ? 'stt.loading' : 'stt.prettifying')}
82
- </Flexbox>
83
- ),
84
- },
85
- ],
86
- }}
87
- open={!!error || isRecording || isLoading}
88
- placement={mobile ? 'topRight' : 'top'}
89
- trigger={['click']}
90
- >
91
- <ActionIcon
92
- active={isRecording}
93
- icon={isLoading ? MicOff : Mic}
94
- onClick={handleTriggerStartStop}
95
- placement={'bottom'}
96
- size={mobile ? { blockSize: 36, fontSize: 16 } : { fontSize: 22 }}
97
- style={{ flex: 'none' }}
98
- title={desc}
99
- />
100
- </Dropdown>
101
- );
102
- });
47
+ return (
48
+ <Dropdown
49
+ dropdownRender={
50
+ error
51
+ ? () => (
52
+ <Alert
53
+ action={
54
+ <Button onClick={handleRetry} size={'small'} type={'primary'}>
55
+ {t('retry', { ns: 'common' })}
56
+ </Button>
57
+ }
58
+ closable
59
+ extra={
60
+ error.body && (
61
+ <Highlighter copyButtonSize={'small'} language={'json'} type={'pure'}>
62
+ {JSON.stringify(error.body, null, 2)}
63
+ </Highlighter>
64
+ )
65
+ }
66
+ message={error.message}
67
+ onClose={handleCloseError}
68
+ style={{ alignItems: 'center' }}
69
+ type="error"
70
+ />
71
+ )
72
+ : undefined
73
+ }
74
+ menu={{
75
+ activeKey: 'time',
76
+ items: [
77
+ {
78
+ key: 'time',
79
+ label: (
80
+ <Flexbox align={'center'} gap={8} horizontal>
81
+ <div className={styles.recording} />
82
+ {time > 0 ? formattedTime : t(isRecording ? 'stt.loading' : 'stt.prettifying')}
83
+ </Flexbox>
84
+ ),
85
+ },
86
+ ],
87
+ }}
88
+ open={!!error || isRecording || isLoading}
89
+ placement={mobile ? 'topRight' : 'top'}
90
+ trigger={['click']}
91
+ >
92
+ <ActionIcon
93
+ active={isRecording}
94
+ icon={isLoading ? MicOff : Mic}
95
+ onClick={handleTriggerStartStop}
96
+ placement={'bottom'}
97
+ size={mobile ? { blockSize: 36, fontSize: 16 } : { fontSize: 22 }}
98
+ style={{ flex: 'none' }}
99
+ title={desc}
100
+ />
101
+ </Dropdown>
102
+ );
103
+ },
104
+ );
103
105
 
104
- export default CommonSTT;
106
+ export default CommonSTT;
@@ -1,18 +1,20 @@
1
+ import isEqual from 'fast-deep-equal';
1
2
  import { memo } from 'react';
3
+
2
4
  import { useGlobalStore } from '@/store/global';
3
5
  import { settingsSelectors } from '@/store/global/selectors';
4
- import isEqual from 'fast-deep-equal';
6
+
5
7
  import BrowserSTT from './browser';
6
8
  import OpenaiSTT from './openai';
7
9
 
8
10
  const STT = memo<{ mobile?: boolean }>(({ mobile }) => {
9
- const { sttServer } = useGlobalStore(settingsSelectors.currentTTS, isEqual)
11
+ const { sttServer } = useGlobalStore(settingsSelectors.currentTTS, isEqual);
10
12
  switch (sttServer) {
11
13
  case 'openai': {
12
- return <OpenaiSTT mobile={mobile} />
14
+ return <OpenaiSTT mobile={mobile} />;
13
15
  }
14
16
  }
15
- return <BrowserSTT mobile={mobile} />
16
- })
17
+ return <BrowserSTT mobile={mobile} />;
18
+ });
17
19
 
18
- export default STT
20
+ export default STT;
@@ -8,18 +8,18 @@ import { useTranslation } from 'react-i18next';
8
8
 
9
9
  import { ModelProvider } from '@/libs/agent-runtime';
10
10
  import { useGlobalStore } from '@/store/global';
11
- import { modelProviderSelectors } from '@/store/global/selectors';
11
+ import { modelConfigSelectors } from '@/store/global/selectors';
12
12
 
13
13
  import { FormAction } from '../style';
14
14
 
15
15
  const BedrockForm = memo(() => {
16
- const { t } = useTranslation('error');
16
+ const { t } = useTranslation('modelProvider');
17
17
  const [showRegion, setShow] = useState(false);
18
18
 
19
19
  const [accessKeyId, secretAccessKey, region, setConfig] = useGlobalStore((s) => [
20
- modelProviderSelectors.bedrockConfig(s).accessKeyId,
21
- modelProviderSelectors.bedrockConfig(s).secretAccessKey,
22
- modelProviderSelectors.bedrockConfig(s).region,
20
+ modelConfigSelectors.bedrockConfig(s).accessKeyId,
21
+ modelConfigSelectors.bedrockConfig(s).secretAccessKey,
22
+ modelConfigSelectors.bedrockConfig(s).region,
23
23
  s.setModelProviderConfig,
24
24
  ]);
25
25
 
@@ -27,8 +27,8 @@ const BedrockForm = memo(() => {
27
27
  return (
28
28
  <FormAction
29
29
  avatar={<Aws.Color color={theme.colorText} size={56} />}
30
- description={t('unlock.apikey.Bedrock.description')}
31
- title={t('unlock.apikey.Bedrock.title')}
30
+ description={t('bedrock.unlock.description')}
31
+ title={t('bedrock.unlock.title')}
32
32
  >
33
33
  <Input.Password
34
34
  autoComplete={'new-password'}
@@ -70,7 +70,7 @@ const BedrockForm = memo(() => {
70
70
  }}
71
71
  type={'text'}
72
72
  >
73
- {t('unlock.apikey.Bedrock.customRegion')}
73
+ {t('bedrock.unlock.customRegion')}
74
74
  </Button>
75
75
  )}
76
76
  </FormAction>
@@ -0,0 +1,73 @@
1
+ import { Icon } from '@lobehub/ui';
2
+ import { Button, Input } from 'antd';
3
+ import { Network } from 'lucide-react';
4
+ import { ReactNode, memo, useState } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import { useGlobalStore } from '@/store/global';
8
+ import { modelConfigSelectors } from '@/store/global/selectors';
9
+ import { GlobalLLMProviderKey } from '@/types/settings';
10
+
11
+ import { FormAction } from '../style';
12
+
13
+ interface ProviderApiKeyFormProps {
14
+ apiKeyPlaceholder?: string;
15
+ avatar?: ReactNode;
16
+ provider: GlobalLLMProviderKey;
17
+ showEndpoint?: boolean;
18
+ }
19
+
20
+ const ProviderApiKeyForm = memo<ProviderApiKeyFormProps>(
21
+ ({ provider, avatar, showEndpoint = false, apiKeyPlaceholder }) => {
22
+ const { t } = useTranslation('modelProvider');
23
+ const { t: errorT } = useTranslation('error');
24
+ const [showProxy, setShow] = useState(false);
25
+
26
+ const [apiKey, proxyUrl, setConfig] = useGlobalStore((s) => [
27
+ modelConfigSelectors.providerConfig(provider)(s)?.apiKey,
28
+ modelConfigSelectors.providerConfig(provider)(s)?.endpoint,
29
+ s.setModelProviderConfig,
30
+ ]);
31
+
32
+ return (
33
+ <FormAction
34
+ avatar={avatar}
35
+ description={t(`${provider}.unlock.description` as any)}
36
+ title={t(`${provider}.unlock.title` as any)}
37
+ >
38
+ <Input.Password
39
+ autoComplete={'new-password'}
40
+ onChange={(e) => {
41
+ setConfig(provider, { apiKey: e.target.value });
42
+ }}
43
+ placeholder={apiKeyPlaceholder || 'sk-***********************'}
44
+ type={'block'}
45
+ value={apiKey}
46
+ />
47
+ {showEndpoint &&
48
+ (showProxy ? (
49
+ <Input
50
+ onChange={(e) => {
51
+ setConfig(provider, { endpoint: e.target.value });
52
+ }}
53
+ placeholder={'https://api.openai.com/v1'}
54
+ type={'block'}
55
+ value={proxyUrl}
56
+ />
57
+ ) : (
58
+ <Button
59
+ icon={<Icon icon={Network} />}
60
+ onClick={() => {
61
+ setShow(true);
62
+ }}
63
+ type={'text'}
64
+ >
65
+ {errorT('unlock.addProxyUrl')}
66
+ </Button>
67
+ ))}
68
+ </FormAction>
69
+ );
70
+ },
71
+ );
72
+
73
+ export default ProviderApiKeyForm;
@@ -0,0 +1,74 @@
1
+ import {
2
+ Anthropic,
3
+ Google,
4
+ Groq,
5
+ Mistral,
6
+ Moonshot,
7
+ OpenAI,
8
+ OpenRouter,
9
+ Perplexity,
10
+ Together,
11
+ ZeroOne,
12
+ Zhipu,
13
+ } from '@lobehub/icons';
14
+ import { useTheme } from 'antd-style';
15
+ import { memo } from 'react';
16
+
17
+ import { ModelProvider } from '@/libs/agent-runtime';
18
+
19
+ interface ProviderAvatarProps {
20
+ provider: ModelProvider;
21
+ }
22
+
23
+ const ProviderAvatar = memo<ProviderAvatarProps>(({ provider }) => {
24
+ const theme = useTheme();
25
+
26
+ switch (provider as ModelProvider) {
27
+ case ModelProvider.Google: {
28
+ return <Google.Color size={56} />;
29
+ }
30
+
31
+ case ModelProvider.ZhiPu: {
32
+ return <Zhipu.Color size={64} />;
33
+ }
34
+
35
+ case ModelProvider.Mistral: {
36
+ return <Mistral.Color size={56} />;
37
+ }
38
+
39
+ case ModelProvider.Moonshot: {
40
+ return <Moonshot size={56} />;
41
+ }
42
+
43
+ case ModelProvider.Perplexity: {
44
+ return <Perplexity.Color size={56} />;
45
+ }
46
+
47
+ case ModelProvider.Anthropic: {
48
+ return <Anthropic color={Anthropic.colorPrimary} size={52} />;
49
+ }
50
+
51
+ case ModelProvider.Groq: {
52
+ return <Groq color={Groq.colorPrimary} size={56} />;
53
+ }
54
+
55
+ case ModelProvider.OpenRouter: {
56
+ return <OpenRouter color={OpenRouter.colorPrimary} size={56} />;
57
+ }
58
+
59
+ case ModelProvider.TogetherAI: {
60
+ return <Together color={Together.colorPrimary} size={56} />;
61
+ }
62
+
63
+ case ModelProvider.ZeroOne: {
64
+ return <ZeroOne color={ZeroOne.colorPrimary} size={56} />;
65
+ }
66
+
67
+ default:
68
+ case ModelProvider.OpenAI: {
69
+ return <OpenAI color={theme.colorText} size={64} />;
70
+ }
71
+ }
72
+ });
73
+
74
+ export default ProviderAvatar;
@@ -5,19 +5,11 @@ import { Center, Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import { ModelProvider } from '@/libs/agent-runtime';
7
7
  import { useChatStore } from '@/store/chat';
8
+ import { GlobalLLMProviderKey } from '@/types/settings';
8
9
 
9
- import AnthropicForm from './Anthropic';
10
10
  import BedrockForm from './Bedrock';
11
- import GoogleForm from './Google';
12
- import GroqForm from './Groq';
13
- import MistralForm from './Mistral';
14
- import MoonshotForm from './Moonshot';
15
- import OpenAIForm from './OpenAI';
16
- import OpenRouterForm from './OpenRouter';
17
- import PerplexityForm from './Perplexity';
18
- import TogetherAIForm from './TogetherAI';
19
- import ZeroOneForm from './ZeroOne';
20
- import ZhipuForm from './Zhipu';
11
+ import ProviderApiKeyForm from './ProviderApiKeyForm';
12
+ import ProviderAvatar from './ProviderAvatar';
21
13
 
22
14
  interface APIKeyFormProps {
23
15
  id: string;
@@ -29,62 +21,46 @@ const APIKeyForm = memo<APIKeyFormProps>(({ id, provider }) => {
29
21
 
30
22
  const [resend, deleteMessage] = useChatStore((s) => [s.internalResendMessage, s.deleteMessage]);
31
23
 
32
- const action = useMemo(() => {
33
- switch (provider as ModelProvider) {
34
- case ModelProvider.Bedrock: {
35
- return <BedrockForm />;
36
- }
37
-
38
- case ModelProvider.Google: {
39
- return <GoogleForm />;
40
- }
41
-
42
- case ModelProvider.ZhiPu: {
43
- return <ZhipuForm />;
44
- }
45
-
46
- case ModelProvider.Mistral: {
47
- return <MistralForm />;
24
+ const apiKeyPlaceholder = useMemo(() => {
25
+ switch (provider) {
26
+ case ModelProvider.Anthropic: {
27
+ return 'sk-ant_*****************************';
48
28
  }
49
29
 
50
- case ModelProvider.Moonshot: {
51
- return <MoonshotForm />;
30
+ case ModelProvider.OpenRouter: {
31
+ return 'sk-or-********************************';
52
32
  }
53
33
 
54
34
  case ModelProvider.Perplexity: {
55
- return <PerplexityForm />;
35
+ return 'pplx-********************************';
56
36
  }
57
37
 
58
- case ModelProvider.Anthropic: {
59
- return <AnthropicForm />;
38
+ case ModelProvider.ZhiPu: {
39
+ return '*********************.*************';
60
40
  }
61
41
 
62
42
  case ModelProvider.Groq: {
63
- return <GroqForm />;
64
- }
65
-
66
- case ModelProvider.OpenRouter: {
67
- return <OpenRouterForm />;
68
- }
69
-
70
- case ModelProvider.TogetherAI: {
71
- return <TogetherAIForm />;
72
- }
73
-
74
- case ModelProvider.ZeroOne: {
75
- return <ZeroOneForm />;
43
+ return 'gsk_*****************************';
76
44
  }
77
45
 
78
- default:
79
- case ModelProvider.OpenAI: {
80
- return <OpenAIForm />;
46
+ default: {
47
+ return '*********************************';
81
48
  }
82
49
  }
83
50
  }, [provider]);
84
51
 
85
52
  return (
86
53
  <Center gap={16} style={{ maxWidth: 300 }}>
87
- {action}
54
+ {provider === ModelProvider.Bedrock ? (
55
+ <BedrockForm />
56
+ ) : (
57
+ <ProviderApiKeyForm
58
+ apiKeyPlaceholder={apiKeyPlaceholder}
59
+ avatar={<ProviderAvatar provider={provider as ModelProvider} />}
60
+ provider={provider as GlobalLLMProviderKey}
61
+ showEndpoint={provider === ModelProvider.OpenAI}
62
+ />
63
+ )}
88
64
  <Flexbox gap={12} width={'100%'}>
89
65
  <Button
90
66
  block
@@ -1,14 +1,20 @@
1
+ import { Icon } from '@lobehub/ui';
1
2
  import { Dropdown } from 'antd';
2
3
  import { createStyles } from 'antd-style';
3
4
  import isEqual from 'fast-deep-equal';
5
+ import { LucideArrowRight } from 'lucide-react';
6
+ import { useRouter } from 'next/navigation';
4
7
  import { PropsWithChildren, memo, useMemo } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { Flexbox } from 'react-layout-kit';
5
10
 
6
11
  import { ModelItemRender, ProviderItemRender } from '@/components/ModelSelect';
7
12
  import { useGlobalStore } from '@/store/global';
8
- import { modelProviderSelectors } from '@/store/global/selectors';
13
+ import { modelConfigSelectors } from '@/store/global/selectors';
9
14
  import { useSessionStore } from '@/store/session';
10
15
  import { agentSelectors } from '@/store/session/selectors';
11
16
  import { ModelProviderCard } from '@/types/llm';
17
+ import { withBasePath } from '@/utils/basePath';
12
18
 
13
19
  const useStyles = createStyles(({ css, prefixCls }) => ({
14
20
  menu: css`
@@ -32,30 +38,51 @@ const useStyles = createStyles(({ css, prefixCls }) => ({
32
38
  }));
33
39
 
34
40
  const ModelSwitchPanel = memo<PropsWithChildren>(({ children }) => {
35
- const { styles } = useStyles();
41
+ const { t } = useTranslation('components');
42
+ const { styles, theme } = useStyles();
36
43
  const model = useSessionStore(agentSelectors.currentAgentModel);
37
44
  const updateAgentConfig = useSessionStore((s) => s.updateAgentConfig);
38
45
 
39
- const select = useGlobalStore(modelProviderSelectors.modelSelectList, isEqual);
40
- const enabledList = select.filter((s) => s.enabled);
46
+ const router = useRouter();
47
+ const enabledList = useGlobalStore(modelConfigSelectors.enabledModelProviderList, isEqual);
41
48
 
42
49
  const items = useMemo(() => {
43
- const getModelItems = (provider: ModelProviderCard) =>
44
- provider.chatModels
45
- .filter((c) => !c.hidden)
46
- .map((model) => ({
47
- key: model.id,
48
- label: <ModelItemRender {...model} />,
49
- onClick: () => {
50
- updateAgentConfig({ model: model.id, provider: provider.id });
50
+ const getModelItems = (provider: ModelProviderCard) => {
51
+ const items = provider.chatModels.map((model) => ({
52
+ key: model.id,
53
+ label: <ModelItemRender {...model} />,
54
+ onClick: () => {
55
+ updateAgentConfig({ model: model.id, provider: provider.id });
56
+ },
57
+ }));
58
+
59
+ // if there is empty items, add a placeholder guide
60
+ if (items.length === 0)
61
+ return [
62
+ {
63
+ key: 'empty',
64
+ label: (
65
+ <Flexbox gap={8} horizontal style={{ color: theme.colorTextTertiary }}>
66
+ {t('ModelSwitchPanel.emptyModel')}
67
+ <Icon icon={LucideArrowRight} />
68
+ </Flexbox>
69
+ ),
70
+ onClick: () => {
71
+ router.push(withBasePath('/settings/llm'));
72
+ },
51
73
  },
52
- }));
74
+ ];
75
+
76
+ return items;
77
+ };
53
78
 
79
+ // If there is only one provider, just remove the group, show model directly
54
80
  if (enabledList.length === 1) {
55
81
  const provider = enabledList[0];
56
82
  return getModelItems(provider);
57
83
  }
58
84
 
85
+ // otherwise show with provider group
59
86
  return enabledList.map((provider) => ({
60
87
  children: getModelItems(provider),
61
88
  key: provider.id,
@@ -1,35 +1,20 @@
1
- import {
2
- AZURE_OPENAI_API_VERSION,
3
- LOBE_CHAT_ACCESS_CODE,
4
- OPENAI_API_KEY_HEADER_KEY,
5
- OPENAI_END_POINT,
6
- USE_AZURE_OPENAI,
7
- } from '@/const/fetch';
1
+ import { LOBE_CHAT_ACCESS_CODE, OPENAI_API_KEY_HEADER_KEY, OPENAI_END_POINT } from '@/const/fetch';
8
2
  import { useGlobalStore } from '@/store/global';
9
- import { modelProviderSelectors, settingsSelectors } from '@/store/global/selectors';
3
+ import { modelConfigSelectors, settingsSelectors } from '@/store/global/selectors';
10
4
 
11
5
  // TODO: Need to be removed after tts refactor
12
6
  // eslint-disable-next-line no-undef
13
7
  export const createHeaderWithOpenAI = (header?: HeadersInit): HeadersInit => {
14
- const openai = modelProviderSelectors.openAIConfig(useGlobalStore.getState());
8
+ const openai = modelConfigSelectors.openAIConfig(useGlobalStore.getState());
15
9
 
16
- const apiKey = openai.OPENAI_API_KEY || '';
10
+ const apiKey = openai.apiKey || '';
17
11
  const endpoint = openai.endpoint || '';
18
12
 
19
13
  // eslint-disable-next-line no-undef
20
- const result: HeadersInit = {
14
+ return {
21
15
  ...header,
22
16
  [LOBE_CHAT_ACCESS_CODE]: settingsSelectors.password(useGlobalStore.getState()),
23
17
  [OPENAI_API_KEY_HEADER_KEY]: apiKey,
24
18
  [OPENAI_END_POINT]: endpoint,
25
19
  };
26
-
27
- if (openai.useAzure) {
28
- Object.assign(result, {
29
- [AZURE_OPENAI_API_VERSION]: openai.azureApiVersion || '',
30
- [USE_AZURE_OPENAI]: '1',
31
- });
32
- }
33
-
34
- return result;
35
20
  };
@@ -1,12 +1,28 @@
1
1
  import { StreamingTextResponse } from 'ai';
2
+ import OpenAI from 'openai';
3
+
4
+ import { ChatModelCard } from '@/types/llm';
2
5
 
3
6
  import { ChatCompetitionOptions, ChatStreamPayload } from './types';
4
7
 
5
8
  export interface LobeRuntimeAI {
6
9
  baseURL?: string;
7
-
8
10
  chat(
9
11
  payload: ChatStreamPayload,
10
12
  options?: ChatCompetitionOptions,
11
13
  ): Promise<StreamingTextResponse>;
14
+
15
+ models?(): Promise<any>;
16
+ }
17
+
18
+ export abstract class LobeOpenAICompatibleRuntime {
19
+ abstract baseURL: string;
20
+ abstract client: OpenAI;
21
+
22
+ abstract chat(
23
+ payload: ChatStreamPayload,
24
+ options?: ChatCompetitionOptions,
25
+ ): Promise<StreamingTextResponse>;
26
+
27
+ abstract models(): Promise<ChatModelCard[]>;
12
28
  }