@lobehub/chat 1.43.6 → 1.44.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 (301) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/docs/self-hosting/server-database/docker-compose.mdx +2 -2
  4. package/locales/ar/common.json +1 -0
  5. package/locales/ar/modelProvider.json +176 -0
  6. package/locales/ar/setting.json +1 -0
  7. package/locales/bg-BG/common.json +1 -0
  8. package/locales/bg-BG/modelProvider.json +176 -0
  9. package/locales/bg-BG/setting.json +1 -0
  10. package/locales/de-DE/common.json +1 -0
  11. package/locales/de-DE/modelProvider.json +176 -0
  12. package/locales/de-DE/setting.json +1 -0
  13. package/locales/en-US/common.json +1 -0
  14. package/locales/en-US/modelProvider.json +176 -0
  15. package/locales/en-US/setting.json +1 -0
  16. package/locales/es-ES/common.json +1 -0
  17. package/locales/es-ES/modelProvider.json +176 -0
  18. package/locales/es-ES/setting.json +1 -0
  19. package/locales/fa-IR/common.json +1 -0
  20. package/locales/fa-IR/modelProvider.json +176 -0
  21. package/locales/fa-IR/setting.json +1 -0
  22. package/locales/fr-FR/common.json +1 -0
  23. package/locales/fr-FR/modelProvider.json +176 -0
  24. package/locales/fr-FR/setting.json +1 -0
  25. package/locales/it-IT/common.json +1 -0
  26. package/locales/it-IT/modelProvider.json +176 -0
  27. package/locales/it-IT/setting.json +1 -0
  28. package/locales/ja-JP/common.json +1 -0
  29. package/locales/ja-JP/modelProvider.json +176 -0
  30. package/locales/ja-JP/setting.json +1 -0
  31. package/locales/ko-KR/common.json +1 -0
  32. package/locales/ko-KR/modelProvider.json +176 -0
  33. package/locales/ko-KR/setting.json +1 -0
  34. package/locales/nl-NL/common.json +1 -0
  35. package/locales/nl-NL/modelProvider.json +176 -0
  36. package/locales/nl-NL/setting.json +1 -0
  37. package/locales/pl-PL/common.json +1 -0
  38. package/locales/pl-PL/modelProvider.json +176 -0
  39. package/locales/pl-PL/setting.json +1 -0
  40. package/locales/pt-BR/common.json +1 -0
  41. package/locales/pt-BR/modelProvider.json +176 -0
  42. package/locales/pt-BR/setting.json +1 -0
  43. package/locales/ru-RU/common.json +1 -0
  44. package/locales/ru-RU/modelProvider.json +176 -0
  45. package/locales/ru-RU/setting.json +1 -0
  46. package/locales/tr-TR/common.json +1 -0
  47. package/locales/tr-TR/modelProvider.json +176 -0
  48. package/locales/tr-TR/setting.json +1 -0
  49. package/locales/vi-VN/common.json +1 -0
  50. package/locales/vi-VN/modelProvider.json +176 -0
  51. package/locales/vi-VN/setting.json +1 -0
  52. package/locales/zh-CN/common.json +1 -0
  53. package/locales/zh-CN/modelProvider.json +176 -0
  54. package/locales/zh-CN/setting.json +1 -0
  55. package/locales/zh-TW/common.json +1 -0
  56. package/locales/zh-TW/modelProvider.json +176 -0
  57. package/locales/zh-TW/setting.json +1 -0
  58. package/next.config.ts +1 -1
  59. package/package.json +4 -4
  60. package/src/app/(main)/(mobile)/me/settings/features/Category.tsx +1 -1
  61. package/src/app/(main)/(mobile)/me/settings/features/useCategory.tsx +12 -5
  62. package/src/app/(main)/changelog/features/VersionTag.tsx +1 -2
  63. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/Thread.tsx +1 -1
  64. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/ThreadItem.tsx +1 -2
  65. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +0 -1
  66. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/AgentsSuggest.tsx +1 -1
  67. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/QuestionSuggest.tsx +1 -1
  68. package/src/app/(main)/chat/(workspace)/@conversation/features/ZenModeToast/Toast.tsx +1 -1
  69. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ThreadItem/index.tsx +0 -2
  70. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/TopicItem/index.tsx +0 -1
  71. package/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Tags.tsx +2 -3
  72. package/src/app/(main)/chat/@session/features/SessionListContent/CollapseGroup/index.tsx +1 -1
  73. package/src/app/(main)/chat/features/Migration/Start.tsx +1 -1
  74. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/ConversationExample/TopicList.tsx +4 -3
  75. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/Header.tsx +1 -1
  76. package/src/app/(main)/discover/(detail)/features/ShareButton.tsx +2 -1
  77. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx +1 -1
  78. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/Header.tsx +1 -1
  79. package/src/app/(main)/discover/(detail)/provider/[slug]/features/Header.tsx +1 -1
  80. package/src/app/(main)/discover/(list)/_layout/Desktop/Nav.tsx +0 -1
  81. package/src/app/(main)/discover/(list)/assistants/features/Card.tsx +1 -1
  82. package/src/app/(main)/discover/(list)/models/features/Card.tsx +1 -1
  83. package/src/app/(main)/discover/(list)/plugins/features/Card.tsx +1 -1
  84. package/src/app/(main)/discover/(list)/providers/features/Card.tsx +1 -1
  85. package/src/app/(main)/discover/components/GridLoadingCard.tsx +2 -1
  86. package/src/app/(main)/discover/components/Title.tsx +1 -1
  87. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/EmptyStatus.tsx +1 -1
  88. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/Item/index.tsx +0 -1
  89. package/src/app/(main)/files/(content)/@modal/(.)[id]/FullscreenModal.tsx +2 -2
  90. package/src/app/(main)/files/(content)/NotSupportClient.tsx +2 -2
  91. package/src/app/(main)/profile/_layout/Desktop/SideBar.tsx +1 -1
  92. package/src/app/(main)/profile/stats/features/ShareButton/Preview.tsx +5 -5
  93. package/src/app/(main)/repos/[id]/evals/components/Container.tsx +1 -1
  94. package/src/app/(main)/repos/[id]/evals/dataset/DatasetList/Item.tsx +0 -1
  95. package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +1 -1
  96. package/src/app/(main)/settings/about/features/ItemCard.tsx +3 -3
  97. package/src/app/(main)/settings/about/features/Version.tsx +1 -1
  98. package/src/app/(main)/settings/hooks/useCategory.tsx +22 -9
  99. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +2 -1
  100. package/src/app/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -1
  101. package/src/app/(main)/settings/provider/(detail)/[id]/index.tsx +19 -0
  102. package/src/app/(main)/settings/provider/(detail)/[id]/page.tsx +95 -0
  103. package/src/app/(main)/settings/provider/(detail)/azure/page.tsx +119 -0
  104. package/src/app/(main)/settings/provider/(detail)/bedrock/page.tsx +91 -0
  105. package/src/app/(main)/settings/provider/(detail)/cloudflare/page.tsx +58 -0
  106. package/src/app/(main)/settings/provider/(detail)/github/page.tsx +67 -0
  107. package/src/app/(main)/settings/provider/(detail)/huggingface/page.tsx +67 -0
  108. package/src/app/(main)/settings/provider/(detail)/ollama/Checker.tsx +73 -0
  109. package/src/app/(main)/settings/provider/(detail)/ollama/page.tsx +34 -0
  110. package/src/app/(main)/settings/provider/(detail)/openai/page.tsx +23 -0
  111. package/src/app/(main)/settings/provider/(detail)/wenxin/page.tsx +61 -0
  112. package/src/app/(main)/settings/provider/(list)/Footer.tsx +36 -0
  113. package/src/app/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +134 -0
  114. package/src/app/(main)/settings/provider/(list)/ProviderGrid/index.tsx +91 -0
  115. package/src/app/(main)/settings/provider/(list)/index.tsx +19 -0
  116. package/src/app/(main)/settings/provider/ProviderMenu/AddNew.tsx +28 -0
  117. package/src/app/(main)/settings/provider/ProviderMenu/All.tsx +29 -0
  118. package/src/app/(main)/settings/provider/ProviderMenu/Item.tsx +69 -0
  119. package/src/app/(main)/settings/provider/ProviderMenu/List.tsx +76 -0
  120. package/src/app/(main)/settings/provider/ProviderMenu/SearchResult.tsx +43 -0
  121. package/src/app/(main)/settings/provider/ProviderMenu/SkeletonList.tsx +60 -0
  122. package/src/app/(main)/settings/provider/ProviderMenu/SortProviderModal/GroupItem.tsx +30 -0
  123. package/src/app/(main)/settings/provider/ProviderMenu/SortProviderModal/index.tsx +91 -0
  124. package/src/app/(main)/settings/provider/ProviderMenu/index.tsx +80 -0
  125. package/src/app/(main)/settings/provider/_layout/Desktop.tsx +37 -0
  126. package/src/app/(main)/settings/provider/_layout/Mobile.tsx +14 -0
  127. package/src/app/(main)/settings/provider/const.ts +20 -0
  128. package/src/app/(main)/settings/provider/features/CreateNewProvider/index.tsx +146 -0
  129. package/src/app/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +105 -0
  130. package/src/app/(main)/settings/provider/features/ModelList/CreateNewModelModal/index.tsx +69 -0
  131. package/src/app/(main)/settings/provider/features/ModelList/DisabledModels.tsx +29 -0
  132. package/src/app/(main)/settings/provider/features/ModelList/EmptyModels.tsx +101 -0
  133. package/src/app/(main)/settings/provider/features/ModelList/EnabledModelList/index.tsx +85 -0
  134. package/src/app/(main)/settings/provider/features/ModelList/ModelConfigModal/Form.tsx +109 -0
  135. package/src/app/(main)/settings/provider/features/ModelList/ModelConfigModal/index.tsx +76 -0
  136. package/src/app/(main)/settings/provider/features/ModelList/ModelItem.tsx +346 -0
  137. package/src/app/(main)/settings/provider/features/ModelList/ModelTitle/Search.tsx +37 -0
  138. package/src/app/(main)/settings/provider/features/ModelList/ModelTitle/index.tsx +145 -0
  139. package/src/app/(main)/settings/provider/features/ModelList/SearchResult.tsx +67 -0
  140. package/src/app/(main)/settings/provider/features/ModelList/SkeletonList.tsx +63 -0
  141. package/src/app/(main)/settings/provider/features/ModelList/SortModelModal/ListItem.tsx +20 -0
  142. package/src/app/(main)/settings/provider/features/ModelList/SortModelModal/index.tsx +96 -0
  143. package/src/app/(main)/settings/provider/features/ModelList/index.tsx +59 -0
  144. package/src/app/(main)/settings/provider/features/ProviderConfig/Checker.tsx +120 -0
  145. package/src/app/(main)/settings/provider/features/ProviderConfig/SkeletonInput.tsx +5 -0
  146. package/src/app/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +137 -0
  147. package/src/app/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/index.tsx +49 -0
  148. package/src/app/(main)/settings/provider/features/ProviderConfig/index.tsx +343 -0
  149. package/src/app/(main)/settings/provider/layout.tsx +21 -0
  150. package/src/app/(main)/settings/provider/page.tsx +17 -0
  151. package/src/app/(main)/settings/provider/type.ts +5 -0
  152. package/src/app/(main)/settings/sync/features/DeviceInfo/Card.tsx +1 -1
  153. package/src/app/(main)/settings/sync/features/DeviceInfo/index.tsx +1 -1
  154. package/src/app/@modal/(.)changelog/modal/features/ReadDetail.tsx +1 -1
  155. package/src/app/@modal/(.)changelog/modal/features/VersionTag.tsx +1 -2
  156. package/src/app/@modal/(.)changelog/modal/layout.tsx +1 -1
  157. package/src/components/Cell/index.tsx +1 -1
  158. package/src/components/DragUpload/index.tsx +2 -3
  159. package/src/components/FeatureList/index.tsx +1 -1
  160. package/src/components/FileParsingStatus/EmbeddingStatus.tsx +1 -1
  161. package/src/components/FileParsingStatus/index.tsx +1 -1
  162. package/src/components/FunctionModal/style.tsx +2 -2
  163. package/src/components/GoBack/index.tsx +1 -2
  164. package/src/components/HotKeys/index.tsx +1 -1
  165. package/src/components/InstantSwitch/index.tsx +28 -0
  166. package/src/components/Menu/index.tsx +1 -1
  167. package/src/components/ModelSelect/index.tsx +20 -10
  168. package/src/components/Notification/index.tsx +2 -1
  169. package/src/components/StatisticCard/index.tsx +5 -6
  170. package/src/config/aiModels/ai21.ts +38 -0
  171. package/src/config/aiModels/ai360.ts +71 -0
  172. package/src/config/aiModels/anthropic.ts +152 -0
  173. package/src/config/aiModels/azure.ts +86 -0
  174. package/src/config/aiModels/baichuan.ts +107 -0
  175. package/src/config/aiModels/bedrock.ts +315 -0
  176. package/src/config/aiModels/cloudflare.ts +88 -0
  177. package/src/config/aiModels/deepseek.ts +27 -0
  178. package/src/config/aiModels/fireworksai.ts +232 -0
  179. package/src/config/aiModels/giteeai.ts +137 -0
  180. package/src/config/aiModels/github.ts +273 -0
  181. package/src/config/aiModels/google.ts +317 -0
  182. package/src/config/aiModels/groq.ts +202 -0
  183. package/src/config/aiModels/higress.ts +2828 -0
  184. package/src/config/aiModels/huggingface.ts +56 -0
  185. package/src/config/aiModels/hunyuan.ts +151 -0
  186. package/src/config/aiModels/index.ts +98 -0
  187. package/src/config/aiModels/internlm.ts +40 -0
  188. package/src/config/aiModels/minimax.ts +55 -0
  189. package/src/config/aiModels/mistral.ts +172 -0
  190. package/src/config/aiModels/moonshot.ts +44 -0
  191. package/src/config/aiModels/novita.ts +124 -0
  192. package/src/config/aiModels/ollama.ts +412 -0
  193. package/src/config/aiModels/openai.ts +537 -0
  194. package/src/config/aiModels/openrouter.ts +252 -0
  195. package/src/config/aiModels/perplexity.ts +67 -0
  196. package/src/config/aiModels/qwen.ts +302 -0
  197. package/src/config/aiModels/sensenova.ts +114 -0
  198. package/src/config/aiModels/siliconcloud.ts +679 -0
  199. package/src/config/aiModels/spark.ts +68 -0
  200. package/src/config/aiModels/stepfun.ts +153 -0
  201. package/src/config/aiModels/taichu.ts +19 -0
  202. package/src/config/aiModels/togetherai.ts +334 -0
  203. package/src/config/aiModels/upstage.ts +37 -0
  204. package/src/config/aiModels/wenxin.ts +171 -0
  205. package/src/config/aiModels/xai.ts +72 -0
  206. package/src/config/aiModels/zeroone.ts +156 -0
  207. package/src/config/aiModels/zhipu.ts +235 -0
  208. package/src/config/featureFlags/schema.ts +3 -0
  209. package/src/config/modelProviders/anthropic.ts +1 -0
  210. package/src/config/modelProviders/github.ts +0 -1
  211. package/src/config/modelProviders/google.ts +1 -0
  212. package/src/config/modelProviders/stepfun.ts +2 -0
  213. package/src/database/migrations/0013_add_ai_infra.sql +44 -0
  214. package/src/database/migrations/meta/0013_snapshot.json +3598 -0
  215. package/src/database/migrations/meta/_journal.json +7 -0
  216. package/src/database/repositories/aiInfra/index.ts +117 -0
  217. package/src/database/schemas/aiInfra.ts +69 -0
  218. package/src/database/schemas/index.ts +1 -0
  219. package/src/database/server/models/__tests__/aiModel.test.ts +318 -0
  220. package/src/database/server/models/__tests__/aiProvider.test.ts +373 -0
  221. package/src/database/server/models/aiModel.ts +251 -0
  222. package/src/database/server/models/aiProvider.ts +234 -0
  223. package/src/features/AgentSetting/AgentPrompt/index.tsx +2 -2
  224. package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +2 -1
  225. package/src/features/ChatInput/ActionBar/Tools/index.tsx +2 -3
  226. package/src/features/ChatInput/ActionBar/Upload/ServerMode.tsx +2 -3
  227. package/src/features/ChatInput/Desktop/FilePreview/FileItem/index.tsx +3 -2
  228. package/src/features/ChatInput/Desktop/FilePreview/FileList.tsx +2 -2
  229. package/src/features/ChatInput/Mobile/Files/FileItem/File.tsx +2 -2
  230. package/src/features/ChatInput/Mobile/InputArea/index.tsx +1 -1
  231. package/src/features/ChatInput/STT/common.tsx +1 -1
  232. package/src/features/Conversation/Error/style.tsx +2 -2
  233. package/src/features/Conversation/Messages/Assistant/FileChunks/Item/style.ts +2 -2
  234. package/src/features/Conversation/Messages/Assistant/FileChunks/index.tsx +1 -1
  235. package/src/features/Conversation/Messages/Assistant/ToolCallItem/Inspector/style.ts +2 -3
  236. package/src/features/Conversation/Messages/Assistant/ToolCallItem/style.ts +2 -3
  237. package/src/features/Conversation/Messages/User/FileListViewer/Item.tsx +0 -1
  238. package/src/features/Conversation/components/BackBottom/style.ts +2 -2
  239. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/Icon.tsx +2 -3
  240. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx +3 -3
  241. package/src/features/Conversation/components/MarkdownElements/LobeThinking/Render.tsx +1 -1
  242. package/src/features/Conversation/components/OTPInput.tsx +2 -2
  243. package/src/features/DataImporter/Loading.tsx +1 -1
  244. package/src/features/FileManager/FileList/EmptyStatus.tsx +1 -1
  245. package/src/features/FileManager/FileList/index.tsx +1 -1
  246. package/src/features/FileManager/UploadDock/Item.tsx +1 -1
  247. package/src/features/FileManager/UploadDock/index.tsx +4 -4
  248. package/src/features/FileViewer/NotSupport/index.tsx +1 -1
  249. package/src/features/FileViewer/Renderer/MSDoc/index.tsx +0 -1
  250. package/src/features/FileViewer/Renderer/TXT/index.tsx +1 -1
  251. package/src/features/InitClientDB/EnableModal.tsx +1 -1
  252. package/src/features/InitClientDB/ErrorResult.tsx +1 -1
  253. package/src/features/InitClientDB/InitIndicator.tsx +1 -1
  254. package/src/features/KnowledgeBaseModal/AddFilesToKnowledgeBase/SelectForm.tsx +0 -1
  255. package/src/features/ModelSelect/index.tsx +8 -1
  256. package/src/features/ModelSwitchPanel/index.tsx +10 -3
  257. package/src/features/PluginsUI/Render/Loading.tsx +0 -1
  258. package/src/features/Portal/Home/Body/Files/FileList/Item.tsx +1 -1
  259. package/src/features/Portal/Home/Body/Plugins/ArtifactList/Item/style.ts +1 -2
  260. package/src/features/Setting/SettingContainer.tsx +8 -1
  261. package/src/features/ShareModal/ShareImage/style.ts +2 -2
  262. package/src/features/ShareModal/style.ts +2 -2
  263. package/src/features/User/DataStatistics.tsx +1 -1
  264. package/src/hooks/useEnabledChatModels.ts +10 -1
  265. package/src/hooks/useModelSupportToolUse.ts +15 -0
  266. package/src/hooks/useModelSupportVision.ts +15 -0
  267. package/src/layout/AuthProvider/Clerk/useAppearance.ts +3 -3
  268. package/src/layout/GlobalProvider/AppTheme.tsx +1 -1
  269. package/src/layout/GlobalProvider/StoreInitialization.tsx +5 -0
  270. package/src/locales/default/common.ts +1 -0
  271. package/src/locales/default/modelProvider.ts +178 -0
  272. package/src/locales/default/setting.ts +1 -0
  273. package/src/server/modules/KeyVaultsEncrypt/index.ts +1 -1
  274. package/src/server/routers/lambda/aiModel.ts +128 -0
  275. package/src/server/routers/lambda/aiProvider.ts +127 -0
  276. package/src/server/routers/lambda/index.ts +4 -0
  277. package/src/services/__tests__/_auth.test.ts +16 -49
  278. package/src/services/__tests__/chat.test.ts +2 -0
  279. package/src/services/_auth.ts +42 -25
  280. package/src/services/aiModel.ts +52 -0
  281. package/src/services/aiProvider.ts +47 -0
  282. package/src/services/chat.ts +62 -18
  283. package/src/store/aiInfra/index.ts +2 -0
  284. package/src/store/aiInfra/initialState.ts +11 -0
  285. package/src/store/aiInfra/selectors.ts +2 -0
  286. package/src/store/aiInfra/slices/aiModel/action.ts +146 -0
  287. package/src/store/aiInfra/slices/aiModel/index.ts +3 -0
  288. package/src/store/aiInfra/slices/aiModel/initialState.ts +14 -0
  289. package/src/store/aiInfra/slices/aiModel/selectors.ts +63 -0
  290. package/src/store/aiInfra/slices/aiProvider/action.ts +208 -0
  291. package/src/store/aiInfra/slices/aiProvider/index.ts +3 -0
  292. package/src/store/aiInfra/slices/aiProvider/initialState.ts +32 -0
  293. package/src/store/aiInfra/slices/aiProvider/selectors.ts +99 -0
  294. package/src/store/aiInfra/store.ts +25 -0
  295. package/src/store/global/initialState.ts +1 -0
  296. package/src/store/serverConfig/selectors.test.ts +1 -0
  297. package/src/store/user/slices/modelList/selectors/modelProvider.ts +1 -0
  298. package/src/styles/global.ts +1 -1
  299. package/src/types/aiModel.ts +36 -6
  300. package/src/types/aiProvider.ts +14 -5
  301. package/src/utils/fetch/fetchSSE.ts +3 -1
@@ -0,0 +1,128 @@
1
+ import { z } from 'zod';
2
+
3
+ import { AiInfraRepos } from '@/database/repositories/aiInfra';
4
+ import { serverDB } from '@/database/server';
5
+ import { AiModelModel } from '@/database/server/models/aiModel';
6
+ import { UserModel } from '@/database/server/models/user';
7
+ import { authedProcedure, router } from '@/libs/trpc';
8
+ import { getServerGlobalConfig } from '@/server/globalConfig';
9
+ import { KeyVaultsGateKeeper } from '@/server/modules/KeyVaultsEncrypt';
10
+ import {
11
+ AiProviderModelListItem,
12
+ CreateAiModelSchema,
13
+ ToggleAiModelEnableSchema,
14
+ UpdateAiModelSchema,
15
+ } from '@/types/aiModel';
16
+ import { ProviderConfig } from '@/types/user/settings';
17
+
18
+ const aiModelProcedure = authedProcedure.use(async (opts) => {
19
+ const { ctx } = opts;
20
+
21
+ const gateKeeper = await KeyVaultsGateKeeper.initWithEnvKey();
22
+ const { languageModel } = getServerGlobalConfig();
23
+
24
+ return opts.next({
25
+ ctx: {
26
+ aiInfraRepos: new AiInfraRepos(
27
+ serverDB,
28
+ ctx.userId,
29
+ languageModel as Record<string, ProviderConfig>,
30
+ ),
31
+ aiModelModel: new AiModelModel(serverDB, ctx.userId),
32
+ gateKeeper,
33
+ userModel: new UserModel(serverDB, ctx.userId),
34
+ },
35
+ });
36
+ });
37
+
38
+ export const aiModelRouter = router({
39
+ batchToggleAiModels: aiModelProcedure
40
+ .input(
41
+ z.object({
42
+ enabled: z.boolean(),
43
+ id: z.string(),
44
+ models: z.array(z.string()),
45
+ }),
46
+ )
47
+ .mutation(async ({ input, ctx }) => {
48
+ return ctx.aiModelModel.batchToggleAiModels(input.id, input.models, input.enabled);
49
+ }),
50
+ batchUpdateAiModels: aiModelProcedure
51
+ .input(
52
+ z.object({
53
+ id: z.string(),
54
+ // TODO: 补齐校验 Schema
55
+ models: z.array(z.any()),
56
+ }),
57
+ )
58
+ .mutation(async ({ input, ctx }) => {
59
+ return ctx.aiModelModel.batchUpdateAiModels(input.id, input.models);
60
+ }),
61
+
62
+ clearRemoteModels: aiModelProcedure
63
+ .input(z.object({ providerId: z.string() }))
64
+ .mutation(async ({ input, ctx }) => {
65
+ return ctx.aiModelModel.clearRemoteModels(input.providerId);
66
+ }),
67
+
68
+ createAiModel: aiModelProcedure.input(CreateAiModelSchema).mutation(async ({ input, ctx }) => {
69
+ const data = await ctx.aiModelModel.create(input);
70
+
71
+ return data?.id;
72
+ }),
73
+
74
+ getAiModelById: aiModelProcedure
75
+ .input(z.object({ id: z.string() }))
76
+
77
+ .query(async ({ input, ctx }) => {
78
+ return ctx.aiModelModel.findById(input.id);
79
+ }),
80
+
81
+ getAiProviderModelList: aiModelProcedure
82
+ .input(z.object({ id: z.string() }))
83
+ .query(async ({ ctx, input }): Promise<AiProviderModelListItem[]> => {
84
+ return ctx.aiInfraRepos.getAiProviderModelList(input.id);
85
+ }),
86
+
87
+ removeAiModel: aiModelProcedure
88
+ .input(z.object({ id: z.string(), providerId: z.string() }))
89
+ .mutation(async ({ input, ctx }) => {
90
+ return ctx.aiModelModel.delete(input.id, input.providerId);
91
+ }),
92
+
93
+ toggleModelEnabled: aiModelProcedure
94
+ .input(ToggleAiModelEnableSchema)
95
+ .mutation(async ({ input, ctx }) => {
96
+ return ctx.aiModelModel.toggleModelEnabled(input);
97
+ }),
98
+
99
+ updateAiModel: aiModelProcedure
100
+ .input(
101
+ z.object({
102
+ id: z.string(),
103
+ providerId: z.string(),
104
+ value: UpdateAiModelSchema,
105
+ }),
106
+ )
107
+ .mutation(async ({ input, ctx }) => {
108
+ return ctx.aiModelModel.update(input.id, input.providerId, input.value);
109
+ }),
110
+
111
+ updateAiModelOrder: aiModelProcedure
112
+ .input(
113
+ z.object({
114
+ providerId: z.string(),
115
+ sortMap: z.array(
116
+ z.object({
117
+ id: z.string(),
118
+ sort: z.number(),
119
+ }),
120
+ ),
121
+ }),
122
+ )
123
+ .mutation(async ({ input, ctx }) => {
124
+ return ctx.aiModelModel.updateModelsOrder(input.providerId, input.sortMap);
125
+ }),
126
+ });
127
+
128
+ export type AiModelRouter = typeof aiModelRouter;
@@ -0,0 +1,127 @@
1
+ import { z } from 'zod';
2
+
3
+ import { AiInfraRepos } from '@/database/repositories/aiInfra';
4
+ import { serverDB } from '@/database/server';
5
+ import { AiProviderModel } from '@/database/server/models/aiProvider';
6
+ import { UserModel } from '@/database/server/models/user';
7
+ import { authedProcedure, router } from '@/libs/trpc';
8
+ import { getServerGlobalConfig } from '@/server/globalConfig';
9
+ import { KeyVaultsGateKeeper } from '@/server/modules/KeyVaultsEncrypt';
10
+ import {
11
+ AiProviderDetailItem,
12
+ AiProviderRuntimeState,
13
+ CreateAiProviderSchema,
14
+ UpdateAiProviderConfigSchema,
15
+ } from '@/types/aiProvider';
16
+ import { ProviderConfig } from '@/types/user/settings';
17
+
18
+ const aiProviderProcedure = authedProcedure.use(async (opts) => {
19
+ const { ctx } = opts;
20
+
21
+ const { languageModel } = getServerGlobalConfig();
22
+
23
+ const gateKeeper = await KeyVaultsGateKeeper.initWithEnvKey();
24
+ return opts.next({
25
+ ctx: {
26
+ aiInfraRepos: new AiInfraRepos(
27
+ serverDB,
28
+ ctx.userId,
29
+ languageModel as Record<string, ProviderConfig>,
30
+ ),
31
+ aiProviderModel: new AiProviderModel(serverDB, ctx.userId),
32
+ gateKeeper,
33
+ userModel: new UserModel(serverDB, ctx.userId),
34
+ },
35
+ });
36
+ });
37
+
38
+ export const aiProviderRouter = router({
39
+ createAiProvider: aiProviderProcedure
40
+ .input(CreateAiProviderSchema)
41
+ .mutation(async ({ input, ctx }) => {
42
+ const data = await ctx.aiProviderModel.create(input, ctx.gateKeeper.encrypt);
43
+
44
+ return data?.id;
45
+ }),
46
+
47
+ getAiProviderById: aiProviderProcedure
48
+ .input(z.object({ id: z.string() }))
49
+
50
+ .query(async ({ input, ctx }): Promise<AiProviderDetailItem | undefined> => {
51
+ return ctx.aiProviderModel.getAiProviderById(input.id, KeyVaultsGateKeeper.getUserKeyVaults);
52
+ }),
53
+
54
+ getAiProviderList: aiProviderProcedure.query(async ({ ctx }) => {
55
+ return await ctx.aiInfraRepos.getAiProviderList();
56
+ }),
57
+
58
+ getAiProviderRuntimeState: aiProviderProcedure
59
+ .input(z.object({ isLogin: z.boolean().optional() }))
60
+ .query(async ({ ctx }): Promise<AiProviderRuntimeState> => {
61
+ const runtimeConfig = await ctx.aiProviderModel.getAiProviderRuntimeConfig(
62
+ KeyVaultsGateKeeper.getUserKeyVaults,
63
+ );
64
+
65
+ const enabledAiProviders = await ctx.aiInfraRepos.getUserEnabledProviderList();
66
+
67
+ const enabledAiModels = await ctx.aiInfraRepos.getEnabledModels();
68
+
69
+ return { enabledAiModels, enabledAiProviders, runtimeConfig };
70
+ }),
71
+
72
+ removeAiProvider: aiProviderProcedure
73
+ .input(z.object({ id: z.string() }))
74
+ .mutation(async ({ input, ctx }) => {
75
+ return ctx.aiProviderModel.delete(input.id);
76
+ }),
77
+
78
+ toggleProviderEnabled: aiProviderProcedure
79
+ .input(
80
+ z.object({
81
+ enabled: z.boolean(),
82
+ id: z.string(),
83
+ }),
84
+ )
85
+ .mutation(async ({ input, ctx }) => {
86
+ return ctx.aiProviderModel.toggleProviderEnabled(input.id, input.enabled);
87
+ }),
88
+
89
+ updateAiProvider: aiProviderProcedure
90
+ .input(
91
+ z.object({
92
+ id: z.string(),
93
+ value: CreateAiProviderSchema.partial(),
94
+ }),
95
+ )
96
+ .mutation(async ({ input, ctx }) => {
97
+ return ctx.aiProviderModel.update(input.id, input.value);
98
+ }),
99
+
100
+ updateAiProviderConfig: aiProviderProcedure
101
+ .input(
102
+ z.object({
103
+ id: z.string(),
104
+ value: UpdateAiProviderConfigSchema,
105
+ }),
106
+ )
107
+ .mutation(async ({ input, ctx }) => {
108
+ return ctx.aiProviderModel.updateConfig(input.id, input.value, ctx.gateKeeper.encrypt);
109
+ }),
110
+
111
+ updateAiProviderOrder: aiProviderProcedure
112
+ .input(
113
+ z.object({
114
+ sortMap: z.array(
115
+ z.object({
116
+ id: z.string(),
117
+ sort: z.number(),
118
+ }),
119
+ ),
120
+ }),
121
+ )
122
+ .mutation(async ({ input, ctx }) => {
123
+ return ctx.aiProviderModel.updateOrder(input.sortMap);
124
+ }),
125
+ });
126
+
127
+ export type AiProviderRouter = typeof aiProviderRouter;
@@ -4,6 +4,8 @@
4
4
  import { publicProcedure, router } from '@/libs/trpc';
5
5
 
6
6
  import { agentRouter } from './agent';
7
+ import { aiModelRouter } from './aiModel';
8
+ import { aiProviderRouter } from './aiProvider';
7
9
  import { chunkRouter } from './chunk';
8
10
  import { fileRouter } from './file';
9
11
  import { importerRouter } from './importer';
@@ -19,6 +21,8 @@ import { userRouter } from './user';
19
21
 
20
22
  export const lambdaRouter = router({
21
23
  agent: agentRouter,
24
+ aiModel: aiModelRouter,
25
+ aiProvider: aiProviderRouter,
22
26
  chunk: chunkRouter,
23
27
  file: fileRouter,
24
28
  healthcheck: publicProcedure.query(() => "i'm live!"),
@@ -34,29 +34,19 @@ const setModelProviderConfig = <T extends GlobalLLMProviderKey>(
34
34
 
35
35
  describe('getProviderAuthPayload', () => {
36
36
  it('should return correct payload for ZhiPu provider', () => {
37
- act(() => {
38
- setModelProviderConfig('zhipu', { apiKey: mockZhiPuAPIKey });
39
- });
40
-
41
- const payload = getProviderAuthPayload(ModelProvider.ZhiPu);
37
+ const payload = getProviderAuthPayload(ModelProvider.ZhiPu, { apiKey: mockZhiPuAPIKey });
42
38
  expect(payload).toEqual({ apiKey: mockZhiPuAPIKey });
43
39
  });
44
40
 
45
41
  it('should return correct payload for Moonshot provider', () => {
46
- act(() => {
47
- setModelProviderConfig('moonshot', { apiKey: mockMoonshotAPIKey });
48
- });
49
-
50
- const payload = getProviderAuthPayload(ModelProvider.Moonshot);
42
+ const payload = getProviderAuthPayload(ModelProvider.Moonshot, { apiKey: mockMoonshotAPIKey });
51
43
  expect(payload).toEqual({ apiKey: mockMoonshotAPIKey });
52
44
  });
53
45
 
54
46
  it('should return correct payload for Anthropic provider', () => {
55
- act(() => {
56
- setModelProviderConfig('anthropic', { apiKey: mockAnthropicAPIKey });
47
+ const payload = getProviderAuthPayload(ModelProvider.Anthropic, {
48
+ apiKey: mockAnthropicAPIKey,
57
49
  });
58
-
59
- const payload = getProviderAuthPayload(ModelProvider.Anthropic);
60
50
  expect(payload).toEqual({ apiKey: mockAnthropicAPIKey });
61
51
  });
62
52
 
@@ -65,34 +55,26 @@ describe('getProviderAuthPayload', () => {
65
55
  setModelProviderConfig('mistral', { apiKey: mockMistralAPIKey });
66
56
  });
67
57
 
68
- const payload = getProviderAuthPayload(ModelProvider.Mistral);
58
+ const payload = getProviderAuthPayload(ModelProvider.Mistral, { apiKey: mockMistralAPIKey });
69
59
  expect(payload).toEqual({ apiKey: mockMistralAPIKey });
70
60
  });
71
61
 
72
62
  it('should return correct payload for OpenRouter provider', () => {
73
- act(() => {
74
- setModelProviderConfig('openrouter', { apiKey: mockOpenRouterAPIKey });
63
+ const payload = getProviderAuthPayload(ModelProvider.OpenRouter, {
64
+ apiKey: mockOpenRouterAPIKey,
75
65
  });
76
-
77
- const payload = getProviderAuthPayload(ModelProvider.OpenRouter);
78
66
  expect(payload).toEqual({ apiKey: mockOpenRouterAPIKey });
79
67
  });
80
68
 
81
69
  it('should return correct payload for TogetherAI provider', () => {
82
- act(() => {
83
- setModelProviderConfig('togetherai', { apiKey: mockTogetherAIAPIKey });
70
+ const payload = getProviderAuthPayload(ModelProvider.TogetherAI, {
71
+ apiKey: mockTogetherAIAPIKey,
84
72
  });
85
-
86
- const payload = getProviderAuthPayload(ModelProvider.TogetherAI);
87
73
  expect(payload).toEqual({ apiKey: mockTogetherAIAPIKey });
88
74
  });
89
75
 
90
76
  it('should return correct payload for Google provider', () => {
91
- act(() => {
92
- setModelProviderConfig('google', { apiKey: mockGoogleAPIKey });
93
- });
94
-
95
- const payload = getProviderAuthPayload(ModelProvider.Google);
77
+ const payload = getProviderAuthPayload(ModelProvider.Google, { apiKey: mockGoogleAPIKey });
96
78
  expect(payload).toEqual({ apiKey: mockGoogleAPIKey });
97
79
  });
98
80
 
@@ -103,11 +85,8 @@ describe('getProviderAuthPayload', () => {
103
85
  region: 'bedrock-region',
104
86
  secretAccessKey: 'bedrock-secret-access-key',
105
87
  };
106
- act(() => {
107
- setModelProviderConfig('bedrock', mockBedrockConfig);
108
- });
109
88
 
110
- const payload = getProviderAuthPayload(ModelProvider.Bedrock);
89
+ const payload = getProviderAuthPayload(ModelProvider.Bedrock, mockBedrockConfig);
111
90
  expect(payload).toEqual({
112
91
  apiKey: mockBedrockConfig.secretAccessKey + mockBedrockConfig.accessKeyId,
113
92
  awsAccessKeyId: mockBedrockConfig.accessKeyId,
@@ -123,11 +102,8 @@ describe('getProviderAuthPayload', () => {
123
102
  apiVersion: 'azure-api-version',
124
103
  endpoint: 'azure-endpoint',
125
104
  };
126
- act(() => {
127
- setModelProviderConfig('azure', mockAzureConfig);
128
- });
129
105
 
130
- const payload = getProviderAuthPayload(ModelProvider.Azure);
106
+ const payload = getProviderAuthPayload(ModelProvider.Azure, mockAzureConfig);
131
107
  expect(payload).toEqual({
132
108
  apiKey: mockAzureConfig.apiKey,
133
109
  azureApiVersion: mockAzureConfig.apiVersion,
@@ -138,11 +114,8 @@ describe('getProviderAuthPayload', () => {
138
114
  it('should return correct payload for Ollama provider', () => {
139
115
  // 假设的 Ollama 配置
140
116
  const mockOllamaProxyUrl = 'ollama-proxy-url';
141
- act(() => {
142
- setModelProviderConfig('ollama', { baseURL: mockOllamaProxyUrl });
143
- });
144
117
 
145
- const payload = getProviderAuthPayload(ModelProvider.Ollama);
118
+ const payload = getProviderAuthPayload(ModelProvider.Ollama, { baseURL: mockOllamaProxyUrl });
146
119
  expect(payload).toEqual({
147
120
  baseURL: mockOllamaProxyUrl,
148
121
  });
@@ -156,11 +129,8 @@ describe('getProviderAuthPayload', () => {
156
129
  useAzure: true,
157
130
  azureApiVersion: 'openai-azure-api-version',
158
131
  };
159
- act(() => {
160
- setModelProviderConfig('openai', mockOpenAIConfig);
161
- });
162
132
 
163
- const payload = getProviderAuthPayload(ModelProvider.OpenAI);
133
+ const payload = getProviderAuthPayload(ModelProvider.OpenAI, mockOpenAIConfig);
164
134
  expect(payload).toEqual({
165
135
  apiKey: mockOpenAIConfig.apiKey,
166
136
  baseURL: mockOpenAIConfig.baseURL,
@@ -173,11 +143,8 @@ describe('getProviderAuthPayload', () => {
173
143
  apiKey: 'stepfun-api-key',
174
144
  baseURL: 'stepfun-baseURL',
175
145
  };
176
- act(() => {
177
- setModelProviderConfig('stepfun', mockOpenAIConfig);
178
- });
179
146
 
180
- const payload = getProviderAuthPayload(ModelProvider.Stepfun);
147
+ const payload = getProviderAuthPayload(ModelProvider.Stepfun, mockOpenAIConfig);
181
148
  expect(payload).toEqual({
182
149
  apiKey: mockOpenAIConfig.apiKey,
183
150
  baseURL: mockOpenAIConfig.baseURL,
@@ -185,7 +152,7 @@ describe('getProviderAuthPayload', () => {
185
152
  });
186
153
 
187
154
  it('should return an empty object or throw an error for an unknown provider', () => {
188
- const payload = getProviderAuthPayload('UnknownProvider');
155
+ const payload = getProviderAuthPayload('UnknownProvider', {});
189
156
  expect(payload).toEqual({});
190
157
  });
191
158
  });
@@ -60,6 +60,7 @@ beforeEach(() => {
60
60
  // 默认设置 isServerMode 为 false
61
61
  vi.mock('@/const/version', () => ({
62
62
  isServerMode: false,
63
+ isDeprecatedEdition: true,
63
64
  }));
64
65
  });
65
66
 
@@ -836,6 +837,7 @@ describe('ChatService', () => {
836
837
  // 重新模拟模块,设置 isServerMode 为 true
837
838
  vi.doMock('@/const/version', () => ({
838
839
  isServerMode: true,
840
+ isDeprecatedEdition: true,
839
841
  }));
840
842
 
841
843
  // 需要在修改模拟后重新导入相关模块
@@ -1,15 +1,29 @@
1
1
  import { JWTPayload, LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
2
+ import { isServerMode } from '@/const/version';
2
3
  import { ModelProvider } from '@/libs/agent-runtime';
4
+ import { aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
3
5
  import { useUserStore } from '@/store/user';
4
6
  import { keyVaultsConfigSelectors, userProfileSelectors } from '@/store/user/selectors';
5
- import { GlobalLLMProviderKey } from '@/types/user/settings';
7
+ import {
8
+ AWSBedrockKeyVault,
9
+ AzureOpenAIKeyVault,
10
+ CloudflareKeyVault,
11
+ OpenAICompatibleKeyVault,
12
+ WenxinKeyVault,
13
+ } from '@/types/user/settings';
6
14
  import { createJWT } from '@/utils/jwt';
7
15
 
8
- export const getProviderAuthPayload = (provider: string) => {
16
+ export const getProviderAuthPayload = (
17
+ provider: string,
18
+ keyVaults: OpenAICompatibleKeyVault &
19
+ AzureOpenAIKeyVault &
20
+ AWSBedrockKeyVault &
21
+ WenxinKeyVault &
22
+ CloudflareKeyVault,
23
+ ) => {
9
24
  switch (provider) {
10
25
  case ModelProvider.Bedrock: {
11
- const { accessKeyId, region, secretAccessKey, sessionToken } =
12
- keyVaultsConfigSelectors.bedrockConfig(useUserStore.getState());
26
+ const { accessKeyId, region, secretAccessKey, sessionToken } = keyVaults;
13
27
 
14
28
  const awsSecretAccessKey = secretAccessKey;
15
29
  const awsAccessKeyId = accessKeyId;
@@ -26,9 +40,7 @@ export const getProviderAuthPayload = (provider: string) => {
26
40
  }
27
41
 
28
42
  case ModelProvider.Wenxin: {
29
- const { secretKey, accessKey } = keyVaultsConfigSelectors.wenxinConfig(
30
- useUserStore.getState(),
31
- );
43
+ const { secretKey, accessKey } = keyVaults;
32
44
 
33
45
  const apiKey = (accessKey || '') + (secretKey || '');
34
46
 
@@ -40,36 +52,26 @@ export const getProviderAuthPayload = (provider: string) => {
40
52
  }
41
53
 
42
54
  case ModelProvider.Azure: {
43
- const azure = keyVaultsConfigSelectors.azureConfig(useUserStore.getState());
44
-
45
55
  return {
46
- apiKey: azure.apiKey,
47
- azureApiVersion: azure.apiVersion,
48
- baseURL: azure.endpoint,
56
+ apiKey: keyVaults.apiKey,
57
+ azureApiVersion: keyVaults.apiVersion,
58
+ baseURL: keyVaults.endpoint,
49
59
  };
50
60
  }
51
61
 
52
62
  case ModelProvider.Ollama: {
53
- const config = keyVaultsConfigSelectors.ollamaConfig(useUserStore.getState());
54
-
55
- return { baseURL: config?.baseURL };
63
+ return { baseURL: keyVaults?.baseURL };
56
64
  }
57
65
 
58
66
  case ModelProvider.Cloudflare: {
59
- const config = keyVaultsConfigSelectors.cloudflareConfig(useUserStore.getState());
60
-
61
67
  return {
62
- apiKey: config?.apiKey,
63
- cloudflareBaseURLOrAccountID: config?.baseURLOrAccountID,
68
+ apiKey: keyVaults?.apiKey,
69
+ cloudflareBaseURLOrAccountID: keyVaults?.baseURLOrAccountID,
64
70
  };
65
71
  }
66
72
 
67
73
  default: {
68
- const config = keyVaultsConfigSelectors.getVaultByProvider(provider as GlobalLLMProviderKey)(
69
- useUserStore.getState(),
70
- );
71
-
72
- return { apiKey: config?.apiKey, baseURL: config?.baseURL };
74
+ return { apiKey: keyVaults?.apiKey, baseURL: keyVaults?.baseURL };
73
75
  }
74
76
  }
75
77
  };
@@ -88,12 +90,27 @@ interface AuthParams {
88
90
  provider?: string;
89
91
  }
90
92
 
93
+ export const createPayloadWithKeyVaults = (provider: string) => {
94
+ let keyVaults = {};
95
+
96
+ // TODO: remove this condition in V2.0
97
+ if (!isServerMode) {
98
+ keyVaults = keyVaultsConfigSelectors.getVaultByProvider(provider as any)(
99
+ useUserStore.getState(),
100
+ );
101
+ } else {
102
+ keyVaults = aiProviderSelectors.providerKeyVaults(provider)(useAiInfraStore.getState()) || {};
103
+ }
104
+
105
+ return getProviderAuthPayload(provider, keyVaults);
106
+ };
107
+
91
108
  // eslint-disable-next-line no-undef
92
109
  export const createHeaderWithAuth = async (params?: AuthParams): Promise<HeadersInit> => {
93
110
  let payload = params?.payload || {};
94
111
 
95
112
  if (params?.provider) {
96
- payload = { ...payload, ...getProviderAuthPayload(params?.provider) };
113
+ payload = { ...payload, ...createPayloadWithKeyVaults(params?.provider) };
97
114
  }
98
115
 
99
116
  const token = await createAuthTokenWithPayload(payload);
@@ -0,0 +1,52 @@
1
+ import { lambdaClient } from '@/libs/trpc/client';
2
+ import {
3
+ AiModelSortMap,
4
+ AiProviderModelListItem,
5
+ CreateAiModelParams,
6
+ ToggleAiModelEnableParams,
7
+ UpdateAiModelParams,
8
+ } from '@/types/aiModel';
9
+
10
+ class AiModelService {
11
+ createAiModel = async (params: CreateAiModelParams) => {
12
+ return lambdaClient.aiModel.createAiModel.mutate(params);
13
+ };
14
+
15
+ getAiProviderModelList = async (id: string): Promise<AiProviderModelListItem[]> => {
16
+ return lambdaClient.aiModel.getAiProviderModelList.query({ id });
17
+ };
18
+
19
+ getAiModelById = async (id: string) => {
20
+ return lambdaClient.aiModel.getAiModelById.query({ id });
21
+ };
22
+
23
+ toggleModelEnabled = async (params: ToggleAiModelEnableParams) => {
24
+ return lambdaClient.aiModel.toggleModelEnabled.mutate(params);
25
+ };
26
+
27
+ updateAiModel = async (id: string, providerId: string, value: UpdateAiModelParams) => {
28
+ return lambdaClient.aiModel.updateAiModel.mutate({ id, providerId, value });
29
+ };
30
+
31
+ batchUpdateAiModels = async (id: string, models: AiProviderModelListItem[]) => {
32
+ return lambdaClient.aiModel.batchUpdateAiModels.mutate({ id, models });
33
+ };
34
+
35
+ batchToggleAiModels = async (id: string, models: string[], enabled: boolean) => {
36
+ return lambdaClient.aiModel.batchToggleAiModels.mutate({ enabled, id, models });
37
+ };
38
+
39
+ clearRemoteModels = async (providerId: string) => {
40
+ return lambdaClient.aiModel.clearRemoteModels.mutate({ providerId });
41
+ };
42
+
43
+ updateAiModelOrder = async (providerId: string, items: AiModelSortMap[]) => {
44
+ return lambdaClient.aiModel.updateAiModelOrder.mutate({ providerId, sortMap: items });
45
+ };
46
+
47
+ deleteAiModel = async (params: { id: string; providerId: string }) => {
48
+ return lambdaClient.aiModel.removeAiModel.mutate(params);
49
+ };
50
+ }
51
+
52
+ export const aiModelService = new AiModelService();
@@ -0,0 +1,47 @@
1
+ import { lambdaClient } from '@/libs/trpc/client';
2
+ import {
3
+ AiProviderRuntimeState,
4
+ AiProviderSortMap,
5
+ CreateAiProviderParams,
6
+ UpdateAiProviderConfigParams,
7
+ } from '@/types/aiProvider';
8
+
9
+ class AiProviderService {
10
+ createAiProvider = async (params: CreateAiProviderParams) => {
11
+ return lambdaClient.aiProvider.createAiProvider.mutate(params);
12
+ };
13
+
14
+ getAiProviderList = async () => {
15
+ return lambdaClient.aiProvider.getAiProviderList.query();
16
+ };
17
+
18
+ getAiProviderById = async (id: string) => {
19
+ return lambdaClient.aiProvider.getAiProviderById.query({ id });
20
+ };
21
+
22
+ toggleProviderEnabled = async (id: string, enabled: boolean) => {
23
+ return lambdaClient.aiProvider.toggleProviderEnabled.mutate({ enabled, id });
24
+ };
25
+
26
+ updateAiProvider = async (id: string, value: any) => {
27
+ return lambdaClient.aiProvider.updateAiProvider.mutate({ id, value });
28
+ };
29
+
30
+ updateAiProviderConfig = async (id: string, value: UpdateAiProviderConfigParams) => {
31
+ return lambdaClient.aiProvider.updateAiProviderConfig.mutate({ id, value });
32
+ };
33
+
34
+ updateAiProviderOrder = async (items: AiProviderSortMap[]) => {
35
+ return lambdaClient.aiProvider.updateAiProviderOrder.mutate({ sortMap: items });
36
+ };
37
+
38
+ deleteAiProvider = async (id: string) => {
39
+ return lambdaClient.aiProvider.removeAiProvider.mutate({ id });
40
+ };
41
+
42
+ getAiProviderRuntimeState = async (isLogin?: boolean): Promise<AiProviderRuntimeState> => {
43
+ return lambdaClient.aiProvider.getAiProviderRuntimeState.query({ isLogin });
44
+ };
45
+ }
46
+
47
+ export const aiProviderService = new AiProviderService();