@lobehub/chat 1.43.6 → 1.44.0

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 (298) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -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/package.json +4 -4
  59. package/src/app/(main)/(mobile)/me/settings/features/Category.tsx +1 -1
  60. package/src/app/(main)/(mobile)/me/settings/features/useCategory.tsx +12 -5
  61. package/src/app/(main)/changelog/features/VersionTag.tsx +1 -2
  62. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/Thread.tsx +1 -1
  63. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/ThreadItem.tsx +1 -2
  64. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +0 -1
  65. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/AgentsSuggest.tsx +1 -1
  66. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/QuestionSuggest.tsx +1 -1
  67. package/src/app/(main)/chat/(workspace)/@conversation/features/ZenModeToast/Toast.tsx +1 -1
  68. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ThreadItem/index.tsx +0 -2
  69. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/TopicItem/index.tsx +0 -1
  70. package/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Tags.tsx +2 -3
  71. package/src/app/(main)/chat/@session/features/SessionListContent/CollapseGroup/index.tsx +1 -1
  72. package/src/app/(main)/chat/features/Migration/Start.tsx +1 -1
  73. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/ConversationExample/TopicList.tsx +4 -3
  74. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/Header.tsx +1 -1
  75. package/src/app/(main)/discover/(detail)/features/ShareButton.tsx +2 -1
  76. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx +1 -1
  77. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/Header.tsx +1 -1
  78. package/src/app/(main)/discover/(detail)/provider/[slug]/features/Header.tsx +1 -1
  79. package/src/app/(main)/discover/(list)/_layout/Desktop/Nav.tsx +0 -1
  80. package/src/app/(main)/discover/(list)/assistants/features/Card.tsx +1 -1
  81. package/src/app/(main)/discover/(list)/models/features/Card.tsx +1 -1
  82. package/src/app/(main)/discover/(list)/plugins/features/Card.tsx +1 -1
  83. package/src/app/(main)/discover/(list)/providers/features/Card.tsx +1 -1
  84. package/src/app/(main)/discover/components/GridLoadingCard.tsx +2 -1
  85. package/src/app/(main)/discover/components/Title.tsx +1 -1
  86. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/EmptyStatus.tsx +1 -1
  87. package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/Item/index.tsx +0 -1
  88. package/src/app/(main)/files/(content)/@modal/(.)[id]/FullscreenModal.tsx +2 -2
  89. package/src/app/(main)/files/(content)/NotSupportClient.tsx +2 -2
  90. package/src/app/(main)/profile/_layout/Desktop/SideBar.tsx +1 -1
  91. package/src/app/(main)/profile/stats/features/ShareButton/Preview.tsx +5 -5
  92. package/src/app/(main)/repos/[id]/evals/components/Container.tsx +1 -1
  93. package/src/app/(main)/repos/[id]/evals/dataset/DatasetList/Item.tsx +0 -1
  94. package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +1 -1
  95. package/src/app/(main)/settings/about/features/ItemCard.tsx +3 -3
  96. package/src/app/(main)/settings/about/features/Version.tsx +1 -1
  97. package/src/app/(main)/settings/hooks/useCategory.tsx +22 -9
  98. package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +2 -1
  99. package/src/app/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -1
  100. package/src/app/(main)/settings/provider/(detail)/[id]/index.tsx +19 -0
  101. package/src/app/(main)/settings/provider/(detail)/[id]/page.tsx +95 -0
  102. package/src/app/(main)/settings/provider/(detail)/azure/page.tsx +119 -0
  103. package/src/app/(main)/settings/provider/(detail)/bedrock/page.tsx +91 -0
  104. package/src/app/(main)/settings/provider/(detail)/cloudflare/page.tsx +58 -0
  105. package/src/app/(main)/settings/provider/(detail)/github/page.tsx +67 -0
  106. package/src/app/(main)/settings/provider/(detail)/huggingface/page.tsx +67 -0
  107. package/src/app/(main)/settings/provider/(detail)/ollama/Checker.tsx +73 -0
  108. package/src/app/(main)/settings/provider/(detail)/ollama/page.tsx +34 -0
  109. package/src/app/(main)/settings/provider/(detail)/openai/page.tsx +23 -0
  110. package/src/app/(main)/settings/provider/(detail)/wenxin/page.tsx +61 -0
  111. package/src/app/(main)/settings/provider/(list)/Footer.tsx +36 -0
  112. package/src/app/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +134 -0
  113. package/src/app/(main)/settings/provider/(list)/ProviderGrid/index.tsx +91 -0
  114. package/src/app/(main)/settings/provider/(list)/index.tsx +19 -0
  115. package/src/app/(main)/settings/provider/ProviderMenu/AddNew.tsx +28 -0
  116. package/src/app/(main)/settings/provider/ProviderMenu/All.tsx +29 -0
  117. package/src/app/(main)/settings/provider/ProviderMenu/Item.tsx +69 -0
  118. package/src/app/(main)/settings/provider/ProviderMenu/List.tsx +76 -0
  119. package/src/app/(main)/settings/provider/ProviderMenu/SearchResult.tsx +43 -0
  120. package/src/app/(main)/settings/provider/ProviderMenu/SkeletonList.tsx +60 -0
  121. package/src/app/(main)/settings/provider/ProviderMenu/SortProviderModal/GroupItem.tsx +30 -0
  122. package/src/app/(main)/settings/provider/ProviderMenu/SortProviderModal/index.tsx +91 -0
  123. package/src/app/(main)/settings/provider/ProviderMenu/index.tsx +80 -0
  124. package/src/app/(main)/settings/provider/_layout/Desktop.tsx +37 -0
  125. package/src/app/(main)/settings/provider/_layout/Mobile.tsx +14 -0
  126. package/src/app/(main)/settings/provider/const.ts +20 -0
  127. package/src/app/(main)/settings/provider/features/CreateNewProvider/index.tsx +146 -0
  128. package/src/app/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +105 -0
  129. package/src/app/(main)/settings/provider/features/ModelList/CreateNewModelModal/index.tsx +69 -0
  130. package/src/app/(main)/settings/provider/features/ModelList/DisabledModels.tsx +29 -0
  131. package/src/app/(main)/settings/provider/features/ModelList/EmptyModels.tsx +101 -0
  132. package/src/app/(main)/settings/provider/features/ModelList/EnabledModelList/index.tsx +85 -0
  133. package/src/app/(main)/settings/provider/features/ModelList/ModelConfigModal/Form.tsx +109 -0
  134. package/src/app/(main)/settings/provider/features/ModelList/ModelConfigModal/index.tsx +76 -0
  135. package/src/app/(main)/settings/provider/features/ModelList/ModelItem.tsx +346 -0
  136. package/src/app/(main)/settings/provider/features/ModelList/ModelTitle/Search.tsx +37 -0
  137. package/src/app/(main)/settings/provider/features/ModelList/ModelTitle/index.tsx +145 -0
  138. package/src/app/(main)/settings/provider/features/ModelList/SearchResult.tsx +67 -0
  139. package/src/app/(main)/settings/provider/features/ModelList/SkeletonList.tsx +63 -0
  140. package/src/app/(main)/settings/provider/features/ModelList/SortModelModal/ListItem.tsx +20 -0
  141. package/src/app/(main)/settings/provider/features/ModelList/SortModelModal/index.tsx +96 -0
  142. package/src/app/(main)/settings/provider/features/ModelList/index.tsx +59 -0
  143. package/src/app/(main)/settings/provider/features/ProviderConfig/Checker.tsx +120 -0
  144. package/src/app/(main)/settings/provider/features/ProviderConfig/SkeletonInput.tsx +5 -0
  145. package/src/app/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +137 -0
  146. package/src/app/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/index.tsx +49 -0
  147. package/src/app/(main)/settings/provider/features/ProviderConfig/index.tsx +343 -0
  148. package/src/app/(main)/settings/provider/layout.tsx +21 -0
  149. package/src/app/(main)/settings/provider/page.tsx +17 -0
  150. package/src/app/(main)/settings/provider/type.ts +5 -0
  151. package/src/app/(main)/settings/sync/features/DeviceInfo/Card.tsx +1 -1
  152. package/src/app/(main)/settings/sync/features/DeviceInfo/index.tsx +1 -1
  153. package/src/app/@modal/(.)changelog/modal/features/ReadDetail.tsx +1 -1
  154. package/src/app/@modal/(.)changelog/modal/features/VersionTag.tsx +1 -2
  155. package/src/app/@modal/(.)changelog/modal/layout.tsx +1 -1
  156. package/src/components/Cell/index.tsx +1 -1
  157. package/src/components/DragUpload/index.tsx +2 -3
  158. package/src/components/FeatureList/index.tsx +1 -1
  159. package/src/components/FileParsingStatus/EmbeddingStatus.tsx +1 -1
  160. package/src/components/FileParsingStatus/index.tsx +1 -1
  161. package/src/components/FunctionModal/style.tsx +2 -2
  162. package/src/components/GoBack/index.tsx +1 -2
  163. package/src/components/HotKeys/index.tsx +1 -1
  164. package/src/components/InstantSwitch/index.tsx +28 -0
  165. package/src/components/Menu/index.tsx +1 -1
  166. package/src/components/ModelSelect/index.tsx +2 -3
  167. package/src/components/Notification/index.tsx +2 -1
  168. package/src/components/StatisticCard/index.tsx +5 -6
  169. package/src/config/aiModels/ai21.ts +38 -0
  170. package/src/config/aiModels/ai360.ts +71 -0
  171. package/src/config/aiModels/anthropic.ts +152 -0
  172. package/src/config/aiModels/azure.ts +86 -0
  173. package/src/config/aiModels/baichuan.ts +107 -0
  174. package/src/config/aiModels/bedrock.ts +315 -0
  175. package/src/config/aiModels/cloudflare.ts +88 -0
  176. package/src/config/aiModels/deepseek.ts +27 -0
  177. package/src/config/aiModels/fireworksai.ts +232 -0
  178. package/src/config/aiModels/giteeai.ts +137 -0
  179. package/src/config/aiModels/github.ts +273 -0
  180. package/src/config/aiModels/google.ts +317 -0
  181. package/src/config/aiModels/groq.ts +202 -0
  182. package/src/config/aiModels/higress.ts +2828 -0
  183. package/src/config/aiModels/huggingface.ts +56 -0
  184. package/src/config/aiModels/hunyuan.ts +151 -0
  185. package/src/config/aiModels/index.ts +98 -0
  186. package/src/config/aiModels/internlm.ts +40 -0
  187. package/src/config/aiModels/minimax.ts +55 -0
  188. package/src/config/aiModels/mistral.ts +172 -0
  189. package/src/config/aiModels/moonshot.ts +44 -0
  190. package/src/config/aiModels/novita.ts +124 -0
  191. package/src/config/aiModels/ollama.ts +412 -0
  192. package/src/config/aiModels/openai.ts +537 -0
  193. package/src/config/aiModels/openrouter.ts +252 -0
  194. package/src/config/aiModels/perplexity.ts +67 -0
  195. package/src/config/aiModels/qwen.ts +302 -0
  196. package/src/config/aiModels/sensenova.ts +114 -0
  197. package/src/config/aiModels/siliconcloud.ts +679 -0
  198. package/src/config/aiModels/spark.ts +68 -0
  199. package/src/config/aiModels/stepfun.ts +153 -0
  200. package/src/config/aiModels/taichu.ts +19 -0
  201. package/src/config/aiModels/togetherai.ts +334 -0
  202. package/src/config/aiModels/upstage.ts +37 -0
  203. package/src/config/aiModels/wenxin.ts +171 -0
  204. package/src/config/aiModels/xai.ts +72 -0
  205. package/src/config/aiModels/zeroone.ts +156 -0
  206. package/src/config/aiModels/zhipu.ts +235 -0
  207. package/src/config/featureFlags/schema.ts +3 -0
  208. package/src/config/modelProviders/anthropic.ts +1 -0
  209. package/src/config/modelProviders/github.ts +0 -1
  210. package/src/config/modelProviders/google.ts +1 -0
  211. package/src/config/modelProviders/stepfun.ts +2 -0
  212. package/src/database/migrations/0013_add_ai_infra.sql +44 -0
  213. package/src/database/migrations/meta/0013_snapshot.json +3598 -0
  214. package/src/database/migrations/meta/_journal.json +7 -0
  215. package/src/database/repositories/aiInfra/index.ts +115 -0
  216. package/src/database/schemas/aiInfra.ts +69 -0
  217. package/src/database/schemas/index.ts +1 -0
  218. package/src/database/server/models/__tests__/aiModel.test.ts +318 -0
  219. package/src/database/server/models/__tests__/aiProvider.test.ts +373 -0
  220. package/src/database/server/models/aiModel.ts +250 -0
  221. package/src/database/server/models/aiProvider.ts +234 -0
  222. package/src/features/AgentSetting/AgentPrompt/index.tsx +2 -2
  223. package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +2 -1
  224. package/src/features/ChatInput/ActionBar/Tools/index.tsx +2 -3
  225. package/src/features/ChatInput/ActionBar/Upload/ServerMode.tsx +2 -3
  226. package/src/features/ChatInput/Desktop/FilePreview/FileItem/index.tsx +3 -2
  227. package/src/features/ChatInput/Desktop/FilePreview/FileList.tsx +2 -2
  228. package/src/features/ChatInput/Mobile/Files/FileItem/File.tsx +2 -2
  229. package/src/features/ChatInput/Mobile/InputArea/index.tsx +1 -1
  230. package/src/features/ChatInput/STT/common.tsx +1 -1
  231. package/src/features/Conversation/Error/style.tsx +2 -2
  232. package/src/features/Conversation/Messages/Assistant/FileChunks/Item/style.ts +2 -2
  233. package/src/features/Conversation/Messages/Assistant/FileChunks/index.tsx +1 -1
  234. package/src/features/Conversation/Messages/Assistant/ToolCallItem/Inspector/style.ts +2 -3
  235. package/src/features/Conversation/Messages/Assistant/ToolCallItem/style.ts +2 -3
  236. package/src/features/Conversation/Messages/User/FileListViewer/Item.tsx +0 -1
  237. package/src/features/Conversation/components/BackBottom/style.ts +2 -2
  238. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/Icon.tsx +2 -3
  239. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx +3 -3
  240. package/src/features/Conversation/components/MarkdownElements/LobeThinking/Render.tsx +1 -1
  241. package/src/features/Conversation/components/OTPInput.tsx +2 -2
  242. package/src/features/DataImporter/Loading.tsx +1 -1
  243. package/src/features/FileManager/FileList/EmptyStatus.tsx +1 -1
  244. package/src/features/FileManager/FileList/index.tsx +1 -1
  245. package/src/features/FileManager/UploadDock/Item.tsx +1 -1
  246. package/src/features/FileManager/UploadDock/index.tsx +4 -4
  247. package/src/features/FileViewer/NotSupport/index.tsx +1 -1
  248. package/src/features/FileViewer/Renderer/MSDoc/index.tsx +0 -1
  249. package/src/features/FileViewer/Renderer/TXT/index.tsx +1 -1
  250. package/src/features/InitClientDB/EnableModal.tsx +1 -1
  251. package/src/features/InitClientDB/ErrorResult.tsx +1 -1
  252. package/src/features/InitClientDB/InitIndicator.tsx +1 -1
  253. package/src/features/KnowledgeBaseModal/AddFilesToKnowledgeBase/SelectForm.tsx +0 -1
  254. package/src/features/ModelSwitchPanel/index.tsx +2 -2
  255. package/src/features/PluginsUI/Render/Loading.tsx +0 -1
  256. package/src/features/Portal/Home/Body/Files/FileList/Item.tsx +1 -1
  257. package/src/features/Portal/Home/Body/Plugins/ArtifactList/Item/style.ts +1 -2
  258. package/src/features/Setting/SettingContainer.tsx +8 -1
  259. package/src/features/ShareModal/ShareImage/style.ts +2 -2
  260. package/src/features/ShareModal/style.ts +2 -2
  261. package/src/features/User/DataStatistics.tsx +1 -1
  262. package/src/hooks/useEnabledChatModels.ts +10 -1
  263. package/src/hooks/useModelSupportToolUse.ts +15 -0
  264. package/src/hooks/useModelSupportVision.ts +15 -0
  265. package/src/layout/AuthProvider/Clerk/useAppearance.ts +3 -3
  266. package/src/layout/GlobalProvider/AppTheme.tsx +1 -1
  267. package/src/layout/GlobalProvider/StoreInitialization.tsx +5 -0
  268. package/src/locales/default/common.ts +1 -0
  269. package/src/locales/default/modelProvider.ts +178 -0
  270. package/src/locales/default/setting.ts +1 -0
  271. package/src/server/modules/KeyVaultsEncrypt/index.ts +1 -1
  272. package/src/server/routers/lambda/aiModel.ts +128 -0
  273. package/src/server/routers/lambda/aiProvider.ts +127 -0
  274. package/src/server/routers/lambda/index.ts +4 -0
  275. package/src/services/__tests__/_auth.test.ts +16 -49
  276. package/src/services/__tests__/chat.test.ts +2 -0
  277. package/src/services/_auth.ts +42 -25
  278. package/src/services/aiModel.ts +52 -0
  279. package/src/services/aiProvider.ts +47 -0
  280. package/src/services/chat.ts +62 -18
  281. package/src/store/aiInfra/index.ts +2 -0
  282. package/src/store/aiInfra/initialState.ts +11 -0
  283. package/src/store/aiInfra/selectors.ts +2 -0
  284. package/src/store/aiInfra/slices/aiModel/action.ts +146 -0
  285. package/src/store/aiInfra/slices/aiModel/index.ts +3 -0
  286. package/src/store/aiInfra/slices/aiModel/initialState.ts +14 -0
  287. package/src/store/aiInfra/slices/aiModel/selectors.ts +63 -0
  288. package/src/store/aiInfra/slices/aiProvider/action.ts +208 -0
  289. package/src/store/aiInfra/slices/aiProvider/index.ts +3 -0
  290. package/src/store/aiInfra/slices/aiProvider/initialState.ts +32 -0
  291. package/src/store/aiInfra/slices/aiProvider/selectors.ts +99 -0
  292. package/src/store/aiInfra/store.ts +25 -0
  293. package/src/store/global/initialState.ts +1 -0
  294. package/src/store/serverConfig/selectors.test.ts +1 -0
  295. package/src/styles/global.ts +1 -1
  296. package/src/types/aiModel.ts +32 -6
  297. package/src/types/aiProvider.ts +11 -4
  298. package/src/utils/fetch/fetchSSE.ts +3 -1
@@ -15,7 +15,6 @@ const content = css`
15
15
 
16
16
  width: calc(100% + 2px);
17
17
  height: calc(100% + 2px);
18
-
19
18
  border: 0;
20
19
  `;
21
20
 
@@ -10,9 +10,9 @@ const useStyles = createStyles(({ css, token }) => ({
10
10
  page: css`
11
11
  width: 100%;
12
12
  padding: 24px;
13
+ border-radius: 4px;
13
14
 
14
15
  background: ${token.colorBgContainer};
15
- border-radius: 4px;
16
16
  box-shadow: ${token.boxShadowTertiary};
17
17
  `,
18
18
  }));
@@ -31,8 +31,8 @@ const useStyles = createStyles(({ css, token, isDarkMode, responsive }) => ({
31
31
  iconCtn: css`
32
32
  width: 72px;
33
33
  height: 72px;
34
- background: ${isDarkMode ? token.blue1 : token.geekblue1};
35
34
  border-radius: 50%;
35
+ background: ${isDarkMode ? token.blue1 : token.geekblue1};
36
36
  `,
37
37
  intro: css`
38
38
  ${responsive.mobile} {
@@ -19,9 +19,9 @@ const useStyles = createStyles(({ css, token }) => ({
19
19
 
20
20
  padding-block: 8px;
21
21
  padding-inline: 24px;
22
+ border-radius: 40px;
22
23
 
23
24
  background: ${token.red6};
24
- border-radius: 40px;
25
25
 
26
26
  transition: transform 0.2s;
27
27
 
@@ -17,8 +17,8 @@ const useStyles = createStyles(({ css, token, prefixCls }) => ({
17
17
  bg: css`
18
18
  padding-block: 8px;
19
19
  padding-inline: 8px 32px;
20
- background: ${token.colorText};
21
20
  border-radius: 40px;
21
+ background: ${token.colorText};
22
22
  `,
23
23
  container: css`
24
24
  position: fixed;
@@ -14,7 +14,6 @@ const useStyles = createStyles(({ css, token }) => ({
14
14
  height: 48px;
15
15
  padding-block: 4px;
16
16
  padding-inline: 8px;
17
-
18
17
  border: 1px solid ${token.colorSplit};
19
18
  border-radius: 6px;
20
19
  `,
@@ -9,12 +9,12 @@ import { useTranslation } from 'react-i18next';
9
9
  import { Flexbox } from 'react-layout-kit';
10
10
 
11
11
  import { ModelItemRender, ProviderItemRender } from '@/components/ModelSelect';
12
+ import { isServerMode } from '@/const/version';
12
13
  import { useEnabledChatModels } from '@/hooks/useEnabledChatModels';
13
14
  import { useIsMobile } from '@/hooks/useIsMobile';
14
15
  import { useAgentStore } from '@/store/agent';
15
16
  import { agentSelectors } from '@/store/agent/slices/chat';
16
17
  import { EnabledProviderWithModels } from '@/types/aiModel';
17
- import { withBasePath } from '@/utils/basePath';
18
18
 
19
19
  const useStyles = createStyles(({ css, prefixCls }) => ({
20
20
  menu: css`
@@ -76,7 +76,7 @@ const ModelSwitchPanel = memo<PropsWithChildren>(({ children }) => {
76
76
  </Flexbox>
77
77
  ),
78
78
  onClick: () => {
79
- router.push(withBasePath('/settings/llm'));
79
+ router.push(!isServerMode ? '/settings/llm' : `/settings/provider/${provider.id}`);
80
80
  },
81
81
  },
82
82
  ];
@@ -12,7 +12,6 @@ const useStyles = createStyles(
12
12
 
13
13
  width: 300px;
14
14
  height: 12px;
15
-
16
15
  border: 1px solid ${token.colorBorder};
17
16
  border-radius: 10px;
18
17
 
@@ -17,9 +17,9 @@ const useStyles = createStyles(({ css, token }) => ({
17
17
  max-width: 420px;
18
18
  padding-block: 8px;
19
19
  padding-inline: 12px;
20
+ border-radius: 8px;
20
21
 
21
22
  background: ${token.colorFillTertiary};
22
- border-radius: 8px;
23
23
 
24
24
  &:hover {
25
25
  background: ${token.colorFillSecondary};
@@ -8,11 +8,11 @@ export const useStyles = createStyles(({ css, token }) => ({
8
8
  padding-block: 10px;
9
9
  padding-inline: 8px;
10
10
  padding-inline-end: 12px;
11
+ border-radius: 8px;
11
12
 
12
13
  color: ${token.colorText};
13
14
 
14
15
  background: ${token.colorBgElevated};
15
- border-radius: 8px;
16
16
 
17
17
  &:hover {
18
18
  background: ${token.colorFillSecondary};
@@ -33,7 +33,6 @@ export const useStyles = createStyles(({ css, token }) => ({
33
33
 
34
34
  width: 24px;
35
35
  height: 24px;
36
-
37
36
  border-radius: 4px;
38
37
  `,
39
38
  tagBlue: css`
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useResponsive } from 'antd-style';
4
+ import { usePathname } from 'next/navigation';
4
5
  import { PropsWithChildren, ReactNode, memo } from 'react';
5
6
  import { Flexbox, FlexboxProps } from 'react-layout-kit';
6
7
 
@@ -21,7 +22,13 @@ const SettingContainer = memo<PropsWithChildren<SettingContainerProps>>(
21
22
  ...rest
22
23
  }) => {
23
24
  const { mobile = false } = useResponsive();
24
- return (
25
+ const pathname = usePathname();
26
+
27
+ const isProviderPath = pathname.startsWith('/settings/provider');
28
+
29
+ return isProviderPath ? (
30
+ children
31
+ ) : (
25
32
  <Flexbox
26
33
  align={'center'}
27
34
  height={'100%'}
@@ -30,14 +30,14 @@ export const useStyles = createStyles(({ css, token, cx }, withBackground: boole
30
30
  header: css`
31
31
  margin-block-end: -24px;
32
32
  padding: 16px;
33
- background: ${token.colorBgContainer};
34
33
  border-block-end: 1px solid ${token.colorBorder};
34
+ background: ${token.colorBgContainer};
35
35
  `,
36
36
  role: css`
37
37
  margin-block-start: 12px;
38
38
  padding-block-start: 12px;
39
- opacity: 0.75;
40
39
  border-block-start: 1px dashed ${token.colorBorderSecondary};
40
+ opacity: 0.75;
41
41
 
42
42
  * {
43
43
  font-size: 12px !important;
@@ -8,11 +8,11 @@ export const useContainerStyles = createStyles(({ css, token, stylish, cx, respo
8
8
 
9
9
  width: 100%;
10
10
  max-height: 70dvh;
11
-
12
- background: ${token.colorBgLayout};
13
11
  border: 1px solid ${token.colorBorder};
14
12
  border-radius: ${token.borderRadiusLG}px;
15
13
 
14
+ background: ${token.colorBgLayout};
15
+
16
16
  * {
17
17
  pointer-events: none;
18
18
 
@@ -21,8 +21,8 @@ const useStyles = createStyles(({ css, token }) => ({
21
21
  card: css`
22
22
  padding-block: 6px;
23
23
  padding-inline: 8px;
24
- background: ${token.colorFillTertiary};
25
24
  border-radius: ${token.borderRadius}px;
25
+ background: ${token.colorFillTertiary};
26
26
 
27
27
  &:hover {
28
28
  background: ${token.colorFillSecondary};
@@ -1,9 +1,18 @@
1
1
  import isEqual from 'fast-deep-equal';
2
2
 
3
+ import { isServerMode } from '@/const/version';
4
+ import { useAiInfraStore } from '@/store/aiInfra';
3
5
  import { useUserStore } from '@/store/user';
4
6
  import { modelProviderSelectors } from '@/store/user/selectors';
5
7
  import { EnabledProviderWithModels } from '@/types/aiModel';
6
8
 
7
9
  export const useEnabledChatModels = (): EnabledProviderWithModels[] => {
8
- return useUserStore(modelProviderSelectors.modelProviderListForModelSelect, isEqual);
10
+ const enabledList = useUserStore(modelProviderSelectors.modelProviderListForModelSelect, isEqual);
11
+ const enabledChatModelList = useAiInfraStore((s) => s.enabledChatModelList, isEqual);
12
+
13
+ if (!isServerMode) {
14
+ return enabledList;
15
+ }
16
+
17
+ return enabledChatModelList || [];
9
18
  };
@@ -0,0 +1,15 @@
1
+ import { isServerMode } from '@/const/version';
2
+ import { aiModelSelectors, useAiInfraStore } from '@/store/aiInfra';
3
+ import { useUserStore } from '@/store/user';
4
+ import { modelProviderSelectors } from '@/store/user/selectors';
5
+
6
+ export const useModelSupportToolUse = (model: string) => {
7
+ const newValue = useAiInfraStore(aiModelSelectors.isModelSupportToolUse(model));
8
+
9
+ // TODO: remove this in V2.0
10
+ const oldValue = useUserStore(modelProviderSelectors.isModelEnabledFunctionCall(model));
11
+ if (!isServerMode) return oldValue;
12
+ //
13
+
14
+ return newValue;
15
+ };
@@ -0,0 +1,15 @@
1
+ import { isServerMode } from '@/const/version';
2
+ import { aiModelSelectors, useAiInfraStore } from '@/store/aiInfra';
3
+ import { useUserStore } from '@/store/user';
4
+ import { modelProviderSelectors } from '@/store/user/selectors';
5
+
6
+ export const useModelSupportVision = (model: string) => {
7
+ const newValue = useAiInfraStore(aiModelSelectors.isModelSupportVision(model));
8
+
9
+ // TODO: remove this in V2.0
10
+ const oldValue = useUserStore(modelProviderSelectors.isModelEnabledVision(model));
11
+ if (!isServerMode) return oldValue;
12
+ //
13
+
14
+ return newValue;
15
+ };
@@ -16,8 +16,8 @@ export const useStyles = createStyles(
16
16
  height: 40px;
17
17
  `,
18
18
  cardBox: css`
19
- background: ${token.colorBgContainer};
20
19
  border-radius: ${token.borderRadiusLG}px;
20
+ background: ${token.colorBgContainer};
21
21
  box-shadow: 0 0 0 1px ${token.colorBorderSecondary};
22
22
  `,
23
23
  header: css`
@@ -66,17 +66,17 @@ export const useStyles = createStyles(
66
66
  .${prefixCls}-cardBox {
67
67
  width: 100%;
68
68
  height: 100%;
69
-
70
69
  border: unset;
71
70
  border-radius: unset;
71
+
72
72
  box-shadow: unset;
73
73
  }
74
74
  }
75
75
  `,
76
76
  scrollBox: css`
77
- background: ${isDarkMode ? token.colorFillQuaternary : token.colorBgElevated};
78
77
  border: unset;
79
78
  border-radius: unset;
79
+ background: ${isDarkMode ? token.colorFillQuaternary : token.colorBgElevated};
80
80
  box-shadow: 0 1px 0 1px ${token.colorFillTertiary};
81
81
  `,
82
82
  socialButtons: css`
@@ -69,9 +69,9 @@ const useStyles = createStyles(({ css, token }) => ({
69
69
  }
70
70
 
71
71
  :hover::-webkit-scrollbar-thumb {
72
+ border: 3px solid transparent;
72
73
  background-color: ${token.colorText};
73
74
  background-clip: content-box;
74
- border: 3px solid transparent;
75
75
  }
76
76
 
77
77
  ::-webkit-scrollbar-track {
@@ -9,6 +9,7 @@ import { LOBE_URL_IMPORT_NAME } from '@/const/url';
9
9
  import { useIsMobile } from '@/hooks/useIsMobile';
10
10
  import { useEnabledDataSync } from '@/hooks/useSyncData';
11
11
  import { useAgentStore } from '@/store/agent';
12
+ import { useAiInfraStore } from '@/store/aiInfra';
12
13
  import { useGlobalStore } from '@/store/global';
13
14
  import { systemStatusSelectors } from '@/store/global/selectors';
14
15
  import { useServerConfigStore } from '@/store/serverConfig';
@@ -35,6 +36,7 @@ const StoreInitialization = memo(() => {
35
36
  const useInitSystemStatus = useGlobalStore((s) => s.useInitSystemStatus);
36
37
 
37
38
  const useInitAgentStore = useAgentStore((s) => s.useInitAgentStore);
39
+ const useInitAiProviderKeyVaults = useAiInfraStore((s) => s.useFetchAiProviderRuntimeState);
38
40
 
39
41
  // init the system preference
40
42
  useInitSystemStatus();
@@ -57,6 +59,9 @@ const StoreInitialization = memo(() => {
57
59
  // init inbox agent and default agent config
58
60
  useInitAgentStore(isLoginOnInit, serverConfig.defaultAgent?.config);
59
61
 
62
+ // init user provider key vaults
63
+ useInitAiProviderKeyVaults(isLoginOnInit);
64
+
60
65
  // init user state
61
66
  useInitUserState(isLoginOnInit, serverConfig, {
62
67
  onSuccess: (state) => {
@@ -269,6 +269,7 @@ export default {
269
269
  },
270
270
  temp: '临时',
271
271
  terms: '服务条款',
272
+ update: '更新',
272
273
  updateAgent: '更新助理信息',
273
274
  upgradeVersion: {
274
275
  action: '升级',
@@ -64,6 +64,44 @@ export default {
64
64
  title: 'Cloudflare 账户 ID / API 地址',
65
65
  },
66
66
  },
67
+ createNewAiProvider: {
68
+ apiKey: {
69
+ placeholder: '请填写你的 API Key',
70
+ required: '请填写你的 API Key',
71
+ title: 'API Key',
72
+ },
73
+ basicTitle: '基本信息',
74
+ configTitle: '配置信息',
75
+ confirm: '新建',
76
+ createSuccess: '新建成功',
77
+ description: {
78
+ placeholder: '服务商简介(选填)',
79
+ title: '服务商简介',
80
+ },
81
+ id: {
82
+ placeholder: '建议全小写,例如 openai,创建后将不可修改',
83
+ required: '请填写服务商 ID',
84
+ title: '服务商 ID',
85
+ },
86
+ logo: {
87
+ required: '请上传正确的服务商 Logo',
88
+ title: '服务商 Logo',
89
+ },
90
+ name: {
91
+ placeholder: '请输入服务商的展示名称',
92
+ required: '请填写服务商名称',
93
+ title: '服务商名称',
94
+ },
95
+ proxyUrl: {
96
+ placeholder: '请填写你的请求地址,如果不填则会使用 SDK 对应的请求地址',
97
+ title: '代理地址',
98
+ },
99
+ sdkType: {
100
+ required: '请选择 SDK 类型',
101
+ title: '请求格式',
102
+ },
103
+ title: '创建自定义 AI 服务商',
104
+ },
67
105
  github: {
68
106
  personalAccessToken: {
69
107
  desc: '填入你的 Github PAT,点击 [这里](https://github.com/settings/tokens) 创建',
@@ -78,6 +116,23 @@ export default {
78
116
  title: 'HuggingFace Token',
79
117
  },
80
118
  },
119
+ list: {
120
+ title: {
121
+ disabled: '未启用服务商',
122
+ enabled: '已启用服务商',
123
+ },
124
+ },
125
+ menu: {
126
+ addCustomProvider: '添加自定义服务商',
127
+ all: '全部',
128
+ list: {
129
+ disabled: '未启用',
130
+ enabled: '已启用',
131
+ },
132
+ notFound: '未找到搜索结果',
133
+ searchProviders: '搜索服务商...',
134
+ sort: '自定义排序',
135
+ },
81
136
  ollama: {
82
137
  checker: {
83
138
  desc: '测试代理地址是否正确填写',
@@ -134,6 +189,129 @@ export default {
134
189
  title: '下载指定的 Ollama 模型',
135
190
  },
136
191
  },
192
+ providerModels: {
193
+ config: {
194
+ aesGcm: '您的秘钥与代理地址等将使用 <1>AES-GCM</1> 加密算法进行加密',
195
+ apiKey: {
196
+ desc: '请填写你的 {{name}} API Key',
197
+ placeholder: '{{name}} API Key',
198
+ title: 'API Key',
199
+ },
200
+ baseURL: {
201
+ desc: '必须包含 http(s)://',
202
+ placeholder: 'https://your-proxy-url.com/v1',
203
+ title: 'API 代理地址',
204
+ },
205
+ checker: {
206
+ button: '检查',
207
+ desc: '测试 Api Key 与代理地址是否正确填写',
208
+ pass: '检查通过',
209
+ title: '连通性检查',
210
+ },
211
+ fetchOnClient: {
212
+ desc: '客户端请求模式将从浏览器直接发起会话请求,可提升响应速度',
213
+ title: '使用客户端请求模式',
214
+ },
215
+ helpDoc: '配置教程',
216
+ waitingForMore: '更多模型正在 <1>计划接入</1> 中,敬请期待',
217
+ },
218
+ createNew: {
219
+ title: '创建自定义 AI 模型',
220
+ },
221
+ item: {
222
+ config: '配置模型',
223
+ customModelCards: {
224
+ addNew: '创建并添加 {{id}} 模型',
225
+ confirmDelete: '即将删除该自定义模型,删除后将不可恢复,请谨慎操作。',
226
+ },
227
+ delete: {
228
+ confirm: '确认删除模型 {{displayName}}?',
229
+ success: '删除成功',
230
+ title: '删除模型',
231
+ },
232
+ modelConfig: {
233
+ azureDeployName: {
234
+ extra: '在 Azure OpenAI 中实际请求的字段',
235
+ placeholder: '请输入 Azure 中的模型部署名称',
236
+ title: '模型部署名称',
237
+ },
238
+ displayName: {
239
+ placeholder: '请输入模型的展示名称,例如 ChatGPT、GPT-4 等',
240
+ title: '模型展示名称',
241
+ },
242
+ files: {
243
+ extra: '当前文件上传实现仅为一种 Hack 方案,仅限自行尝试。完整文件上传能力请等待后续实现',
244
+ title: '支持文件上传',
245
+ },
246
+ functionCall: {
247
+ extra:
248
+ '此配置将仅开启应用中的函数调用能力,是否支持函数调用完全取决于模型本身,请自行测试该模型的函数调用能力可用性',
249
+ title: '支持函数调用',
250
+ },
251
+ id: {
252
+ extra: '将作为模型标签进行展示',
253
+ placeholder: '请输入模型id,例如 gpt-4-turbo-preview 或 claude-2.1',
254
+ title: '模型 ID',
255
+ },
256
+ modalTitle: '自定义模型配置',
257
+ tokens: {
258
+ title: '最大 token 数',
259
+ unlimited: '无限制',
260
+ },
261
+ vision: {
262
+ extra:
263
+ '此配置将仅开启应用中的图片上传配置,是否支持识别完全取决于模型本身,请自行测试该模型的视觉识别能力可用性',
264
+ title: '支持视觉识别',
265
+ },
266
+ },
267
+ pricing: {
268
+ image: '${{amount}}/图片',
269
+ inputCharts: '${{amount}}/M 字符',
270
+ inputMinutes: '${{amount}}/分钟',
271
+ inputTokens: '输入 ${{amount}}/M',
272
+ outputTokens: '输出 ${{amount}}/M',
273
+ },
274
+ releasedAt: '发布于{{releasedAt}}',
275
+ },
276
+ list: {
277
+ addNew: '添加模型',
278
+ disabled: '未启用',
279
+ empty: {
280
+ desc: '请创建自定义模型或拉取模型后开始使用吧',
281
+ title: '暂无可用模型',
282
+ },
283
+ enabled: '已启用',
284
+ enabledActions: {
285
+ disableAll: '全部禁用',
286
+ enableAll: '全部启用',
287
+ sort: '自定义模型排序',
288
+ },
289
+ enabledEmpty: '暂无启用模型,请从下方列表中启用心仪的模型吧~',
290
+ fetcher: {
291
+ clear: '清除获取的模型',
292
+ fetch: '获取模型列表',
293
+ fetching: '正在获取模型列表...',
294
+ latestTime: '上次更新时间:{{time}}',
295
+ noLatestTime: '暂未获取列表',
296
+ },
297
+ search: '搜索模型...',
298
+ searchResult: '搜索到 {{count}} 个模型',
299
+ title: '模型列表',
300
+ total: '共 {{count}} 个模型可用',
301
+ },
302
+ searchNotFound: '未找到搜索结果',
303
+ },
304
+ sortModal: {
305
+ success: '排序更新成功',
306
+ title: '自定义排序',
307
+ update: '更新',
308
+ },
309
+ updateAiProvider: {
310
+ confirmDelete: '即将删除该 AI 服务商,删除后将无法找回,确认是否删除?',
311
+ deleteSuccess: '删除成功',
312
+ tooltip: '更新服务商基础配置',
313
+ updateSuccess: '更新成功',
314
+ },
137
315
  wenxin: {
138
316
  accessKey: {
139
317
  desc: '填入百度千帆平台的 Access Key',
@@ -413,6 +413,7 @@ export default {
413
413
  'common': '通用设置',
414
414
  'experiment': '实验',
415
415
  'llm': '语言模型',
416
+ 'provider': 'AI 服务商',
416
417
  'sync': '云端同步',
417
418
  'system-agent': '系统助手',
418
419
  'tts': '语音服务',
@@ -105,7 +105,7 @@ If you don't have it, please run \`openssl rand -base64 32\` to create one.
105
105
 
106
106
  if (wasAuthentic) {
107
107
  try {
108
- decryptKeyVaults = JSON.parse(plaintext);
108
+ if (!!plaintext) decryptKeyVaults = JSON.parse(plaintext);
109
109
  } catch (e) {
110
110
  console.error(`Failed to parse keyVaults, userId: ${userId}. Error:`, e);
111
111
  }
@@ -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;