@lobehub/chat 1.43.5 → 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.
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/docs/self-hosting/server-database/docker-compose.mdx +2 -2
- package/locales/ar/common.json +1 -0
- package/locales/ar/modelProvider.json +176 -0
- package/locales/ar/setting.json +1 -0
- package/locales/bg-BG/common.json +1 -0
- package/locales/bg-BG/modelProvider.json +176 -0
- package/locales/bg-BG/setting.json +1 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/modelProvider.json +176 -0
- package/locales/de-DE/setting.json +1 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/modelProvider.json +176 -0
- package/locales/en-US/setting.json +1 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/es-ES/modelProvider.json +176 -0
- package/locales/es-ES/setting.json +1 -0
- package/locales/fa-IR/common.json +1 -0
- package/locales/fa-IR/modelProvider.json +176 -0
- package/locales/fa-IR/setting.json +1 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/modelProvider.json +176 -0
- package/locales/fr-FR/setting.json +1 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/modelProvider.json +176 -0
- package/locales/it-IT/setting.json +1 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ja-JP/modelProvider.json +176 -0
- package/locales/ja-JP/setting.json +1 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/modelProvider.json +176 -0
- package/locales/ko-KR/setting.json +1 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/nl-NL/modelProvider.json +176 -0
- package/locales/nl-NL/setting.json +1 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/modelProvider.json +176 -0
- package/locales/pl-PL/setting.json +1 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/pt-BR/modelProvider.json +176 -0
- package/locales/pt-BR/setting.json +1 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/modelProvider.json +176 -0
- package/locales/ru-RU/setting.json +1 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/tr-TR/modelProvider.json +176 -0
- package/locales/tr-TR/setting.json +1 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/modelProvider.json +176 -0
- package/locales/vi-VN/setting.json +1 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-CN/modelProvider.json +176 -0
- package/locales/zh-CN/setting.json +1 -0
- package/locales/zh-TW/common.json +1 -0
- package/locales/zh-TW/modelProvider.json +176 -0
- package/locales/zh-TW/setting.json +1 -0
- package/package.json +4 -4
- package/src/app/(main)/(mobile)/me/settings/features/Category.tsx +1 -1
- package/src/app/(main)/(mobile)/me/settings/features/useCategory.tsx +12 -5
- package/src/app/(main)/changelog/features/VersionTag.tsx +1 -2
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/Thread.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/ThreadItem.tsx +1 -2
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +0 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/AgentsSuggest.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/QuestionSuggest.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ZenModeToast/Toast.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ThreadItem/index.tsx +0 -2
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/TopicItem/index.tsx +0 -1
- package/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Tags.tsx +2 -3
- package/src/app/(main)/chat/(workspace)/_layout/Desktop/index.tsx +6 -1
- package/src/app/(main)/chat/@session/features/SessionListContent/CollapseGroup/index.tsx +1 -1
- package/src/app/(main)/chat/features/Migration/Start.tsx +1 -1
- package/src/app/(main)/discover/(detail)/assistant/[slug]/features/ConversationExample/TopicList.tsx +4 -3
- package/src/app/(main)/discover/(detail)/assistant/[slug]/features/Header.tsx +1 -1
- package/src/app/(main)/discover/(detail)/features/ShareButton.tsx +2 -1
- package/src/app/(main)/discover/(detail)/model/[...slugs]/features/Header.tsx +1 -1
- package/src/app/(main)/discover/(detail)/plugin/[slug]/features/Header.tsx +1 -1
- package/src/app/(main)/discover/(detail)/provider/[slug]/features/Header.tsx +1 -1
- package/src/app/(main)/discover/(list)/_layout/Desktop/Nav.tsx +0 -1
- package/src/app/(main)/discover/(list)/assistants/features/Card.tsx +1 -1
- package/src/app/(main)/discover/(list)/models/features/Card.tsx +1 -1
- package/src/app/(main)/discover/(list)/plugins/features/Card.tsx +1 -1
- package/src/app/(main)/discover/(list)/providers/features/Card.tsx +1 -1
- package/src/app/(main)/discover/components/GridLoadingCard.tsx +2 -1
- package/src/app/(main)/discover/components/Title.tsx +1 -1
- package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/EmptyStatus.tsx +1 -1
- package/src/app/(main)/files/(content)/@menu/features/KnowledgeBase/Item/index.tsx +0 -1
- package/src/app/(main)/files/(content)/@modal/(.)[id]/FullscreenModal.tsx +2 -2
- package/src/app/(main)/files/(content)/NotSupportClient.tsx +2 -2
- package/src/app/(main)/profile/_layout/Desktop/SideBar.tsx +1 -1
- package/src/app/(main)/profile/stats/features/ShareButton/Preview.tsx +5 -5
- package/src/app/(main)/repos/[id]/evals/components/Container.tsx +1 -1
- package/src/app/(main)/repos/[id]/evals/dataset/DatasetList/Item.tsx +0 -1
- package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +1 -1
- package/src/app/(main)/settings/about/features/ItemCard.tsx +3 -3
- package/src/app/(main)/settings/about/features/Version.tsx +1 -1
- package/src/app/(main)/settings/hooks/useCategory.tsx +22 -9
- package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +2 -1
- package/src/app/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -1
- package/src/app/(main)/settings/provider/(detail)/[id]/index.tsx +19 -0
- package/src/app/(main)/settings/provider/(detail)/[id]/page.tsx +95 -0
- package/src/app/(main)/settings/provider/(detail)/azure/page.tsx +119 -0
- package/src/app/(main)/settings/provider/(detail)/bedrock/page.tsx +91 -0
- package/src/app/(main)/settings/provider/(detail)/cloudflare/page.tsx +58 -0
- package/src/app/(main)/settings/provider/(detail)/github/page.tsx +67 -0
- package/src/app/(main)/settings/provider/(detail)/huggingface/page.tsx +67 -0
- package/src/app/(main)/settings/provider/(detail)/ollama/Checker.tsx +73 -0
- package/src/app/(main)/settings/provider/(detail)/ollama/page.tsx +34 -0
- package/src/app/(main)/settings/provider/(detail)/openai/page.tsx +23 -0
- package/src/app/(main)/settings/provider/(detail)/wenxin/page.tsx +61 -0
- package/src/app/(main)/settings/provider/(list)/Footer.tsx +36 -0
- package/src/app/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +134 -0
- package/src/app/(main)/settings/provider/(list)/ProviderGrid/index.tsx +91 -0
- package/src/app/(main)/settings/provider/(list)/index.tsx +19 -0
- package/src/app/(main)/settings/provider/ProviderMenu/AddNew.tsx +28 -0
- package/src/app/(main)/settings/provider/ProviderMenu/All.tsx +29 -0
- package/src/app/(main)/settings/provider/ProviderMenu/Item.tsx +69 -0
- package/src/app/(main)/settings/provider/ProviderMenu/List.tsx +76 -0
- package/src/app/(main)/settings/provider/ProviderMenu/SearchResult.tsx +43 -0
- package/src/app/(main)/settings/provider/ProviderMenu/SkeletonList.tsx +60 -0
- package/src/app/(main)/settings/provider/ProviderMenu/SortProviderModal/GroupItem.tsx +30 -0
- package/src/app/(main)/settings/provider/ProviderMenu/SortProviderModal/index.tsx +91 -0
- package/src/app/(main)/settings/provider/ProviderMenu/index.tsx +80 -0
- package/src/app/(main)/settings/provider/_layout/Desktop.tsx +37 -0
- package/src/app/(main)/settings/provider/_layout/Mobile.tsx +14 -0
- package/src/app/(main)/settings/provider/const.ts +20 -0
- package/src/app/(main)/settings/provider/features/CreateNewProvider/index.tsx +146 -0
- package/src/app/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +105 -0
- package/src/app/(main)/settings/provider/features/ModelList/CreateNewModelModal/index.tsx +69 -0
- package/src/app/(main)/settings/provider/features/ModelList/DisabledModels.tsx +29 -0
- package/src/app/(main)/settings/provider/features/ModelList/EmptyModels.tsx +101 -0
- package/src/app/(main)/settings/provider/features/ModelList/EnabledModelList/index.tsx +85 -0
- package/src/app/(main)/settings/provider/features/ModelList/ModelConfigModal/Form.tsx +109 -0
- package/src/app/(main)/settings/provider/features/ModelList/ModelConfigModal/index.tsx +76 -0
- package/src/app/(main)/settings/provider/features/ModelList/ModelItem.tsx +346 -0
- package/src/app/(main)/settings/provider/features/ModelList/ModelTitle/Search.tsx +37 -0
- package/src/app/(main)/settings/provider/features/ModelList/ModelTitle/index.tsx +145 -0
- package/src/app/(main)/settings/provider/features/ModelList/SearchResult.tsx +67 -0
- package/src/app/(main)/settings/provider/features/ModelList/SkeletonList.tsx +63 -0
- package/src/app/(main)/settings/provider/features/ModelList/SortModelModal/ListItem.tsx +20 -0
- package/src/app/(main)/settings/provider/features/ModelList/SortModelModal/index.tsx +96 -0
- package/src/app/(main)/settings/provider/features/ModelList/index.tsx +59 -0
- package/src/app/(main)/settings/provider/features/ProviderConfig/Checker.tsx +120 -0
- package/src/app/(main)/settings/provider/features/ProviderConfig/SkeletonInput.tsx +5 -0
- package/src/app/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +137 -0
- package/src/app/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/index.tsx +49 -0
- package/src/app/(main)/settings/provider/features/ProviderConfig/index.tsx +343 -0
- package/src/app/(main)/settings/provider/layout.tsx +21 -0
- package/src/app/(main)/settings/provider/page.tsx +17 -0
- package/src/app/(main)/settings/provider/type.ts +5 -0
- package/src/app/(main)/settings/sync/features/DeviceInfo/Card.tsx +1 -1
- package/src/app/(main)/settings/sync/features/DeviceInfo/index.tsx +1 -1
- package/src/app/@modal/(.)changelog/modal/features/ReadDetail.tsx +1 -1
- package/src/app/@modal/(.)changelog/modal/features/VersionTag.tsx +1 -2
- package/src/app/@modal/(.)changelog/modal/layout.tsx +1 -1
- package/src/components/Cell/index.tsx +1 -1
- package/src/components/DragUpload/index.tsx +2 -3
- package/src/components/FeatureList/index.tsx +1 -1
- package/src/components/FileParsingStatus/EmbeddingStatus.tsx +1 -1
- package/src/components/FileParsingStatus/index.tsx +1 -1
- package/src/components/FunctionModal/style.tsx +2 -2
- package/src/components/GoBack/index.tsx +1 -2
- package/src/components/HotKeys/index.tsx +1 -1
- package/src/components/InstantSwitch/index.tsx +28 -0
- package/src/components/Menu/index.tsx +1 -1
- package/src/components/ModelSelect/index.tsx +2 -3
- package/src/components/Notification/index.tsx +2 -1
- package/src/components/StatisticCard/index.tsx +5 -6
- package/src/config/aiModels/ai21.ts +38 -0
- package/src/config/aiModels/ai360.ts +71 -0
- package/src/config/aiModels/anthropic.ts +152 -0
- package/src/config/aiModels/azure.ts +86 -0
- package/src/config/aiModels/baichuan.ts +107 -0
- package/src/config/aiModels/bedrock.ts +315 -0
- package/src/config/aiModels/cloudflare.ts +88 -0
- package/src/config/aiModels/deepseek.ts +27 -0
- package/src/config/aiModels/fireworksai.ts +232 -0
- package/src/config/aiModels/giteeai.ts +137 -0
- package/src/config/aiModels/github.ts +273 -0
- package/src/config/aiModels/google.ts +317 -0
- package/src/config/aiModels/groq.ts +202 -0
- package/src/config/aiModels/higress.ts +2828 -0
- package/src/config/aiModels/huggingface.ts +56 -0
- package/src/config/aiModels/hunyuan.ts +151 -0
- package/src/config/aiModels/index.ts +98 -0
- package/src/config/aiModels/internlm.ts +40 -0
- package/src/config/aiModels/minimax.ts +55 -0
- package/src/config/aiModels/mistral.ts +172 -0
- package/src/config/aiModels/moonshot.ts +44 -0
- package/src/config/aiModels/novita.ts +124 -0
- package/src/config/aiModels/ollama.ts +412 -0
- package/src/config/aiModels/openai.ts +537 -0
- package/src/config/aiModels/openrouter.ts +252 -0
- package/src/config/aiModels/perplexity.ts +67 -0
- package/src/config/aiModels/qwen.ts +302 -0
- package/src/config/aiModels/sensenova.ts +114 -0
- package/src/config/aiModels/siliconcloud.ts +679 -0
- package/src/config/aiModels/spark.ts +68 -0
- package/src/config/aiModels/stepfun.ts +153 -0
- package/src/config/aiModels/taichu.ts +19 -0
- package/src/config/aiModels/togetherai.ts +334 -0
- package/src/config/aiModels/upstage.ts +37 -0
- package/src/config/aiModels/wenxin.ts +171 -0
- package/src/config/aiModels/xai.ts +72 -0
- package/src/config/aiModels/zeroone.ts +156 -0
- package/src/config/aiModels/zhipu.ts +235 -0
- package/src/config/featureFlags/schema.ts +3 -0
- package/src/config/modelProviders/anthropic.ts +1 -0
- package/src/config/modelProviders/github.ts +0 -1
- package/src/config/modelProviders/google.ts +1 -0
- package/src/config/modelProviders/stepfun.ts +2 -0
- package/src/database/migrations/0013_add_ai_infra.sql +44 -0
- package/src/database/migrations/meta/0013_snapshot.json +3598 -0
- package/src/database/migrations/meta/_journal.json +7 -0
- package/src/database/repositories/aiInfra/index.ts +115 -0
- package/src/database/schemas/aiInfra.ts +69 -0
- package/src/database/schemas/index.ts +1 -0
- package/src/database/server/models/__tests__/aiModel.test.ts +318 -0
- package/src/database/server/models/__tests__/aiProvider.test.ts +373 -0
- package/src/database/server/models/aiModel.ts +250 -0
- package/src/database/server/models/aiProvider.ts +234 -0
- package/src/features/AgentSetting/AgentPrompt/index.tsx +2 -2
- package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +2 -1
- package/src/features/ChatInput/ActionBar/Tools/index.tsx +2 -3
- package/src/features/ChatInput/ActionBar/Upload/ServerMode.tsx +2 -3
- package/src/features/ChatInput/Desktop/FilePreview/FileItem/index.tsx +3 -2
- package/src/features/ChatInput/Desktop/FilePreview/FileList.tsx +2 -2
- package/src/features/ChatInput/Mobile/Files/FileItem/File.tsx +2 -2
- package/src/features/ChatInput/Mobile/InputArea/index.tsx +1 -1
- package/src/features/ChatInput/STT/common.tsx +1 -1
- package/src/features/Conversation/Error/style.tsx +2 -2
- package/src/features/Conversation/Messages/Assistant/FileChunks/Item/style.ts +2 -2
- package/src/features/Conversation/Messages/Assistant/FileChunks/index.tsx +1 -1
- package/src/features/Conversation/Messages/Assistant/ToolCallItem/Inspector/style.ts +2 -3
- package/src/features/Conversation/Messages/Assistant/ToolCallItem/style.ts +2 -3
- package/src/features/Conversation/Messages/User/FileListViewer/Item.tsx +0 -1
- package/src/features/Conversation/components/BackBottom/style.ts +2 -2
- package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/Icon.tsx +2 -3
- package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx +3 -3
- package/src/features/Conversation/components/MarkdownElements/LobeThinking/Render.tsx +1 -1
- package/src/features/Conversation/components/OTPInput.tsx +2 -2
- package/src/features/DataImporter/Loading.tsx +1 -1
- package/src/features/FileManager/FileList/EmptyStatus.tsx +1 -1
- package/src/features/FileManager/FileList/index.tsx +1 -1
- package/src/features/FileManager/UploadDock/Item.tsx +1 -1
- package/src/features/FileManager/UploadDock/index.tsx +4 -4
- package/src/features/FileViewer/NotSupport/index.tsx +1 -1
- package/src/features/FileViewer/Renderer/MSDoc/index.tsx +0 -1
- package/src/features/FileViewer/Renderer/TXT/index.tsx +1 -1
- package/src/features/InitClientDB/EnableModal.tsx +1 -1
- package/src/features/InitClientDB/ErrorResult.tsx +1 -1
- package/src/features/InitClientDB/InitIndicator.tsx +1 -1
- package/src/features/KnowledgeBaseModal/AddFilesToKnowledgeBase/SelectForm.tsx +0 -1
- package/src/features/ModelSwitchPanel/index.tsx +2 -2
- package/src/features/PluginsUI/Render/Loading.tsx +0 -1
- package/src/features/Portal/Home/Body/Files/FileList/Item.tsx +1 -1
- package/src/features/Portal/Home/Body/Plugins/ArtifactList/Item/style.ts +1 -2
- package/src/features/Setting/SettingContainer.tsx +8 -1
- package/src/features/ShareModal/ShareImage/style.ts +2 -2
- package/src/features/ShareModal/style.ts +2 -2
- package/src/features/User/DataStatistics.tsx +1 -1
- package/src/hooks/useEnabledChatModels.ts +10 -1
- package/src/hooks/useModelSupportToolUse.ts +15 -0
- package/src/hooks/useModelSupportVision.ts +15 -0
- package/src/layout/AuthProvider/Clerk/useAppearance.ts +3 -3
- package/src/layout/GlobalProvider/AppTheme.tsx +1 -1
- package/src/layout/GlobalProvider/StoreInitialization.tsx +5 -0
- package/src/locales/default/common.ts +1 -0
- package/src/locales/default/modelProvider.ts +178 -0
- package/src/locales/default/setting.ts +1 -0
- package/src/server/modules/KeyVaultsEncrypt/index.ts +1 -1
- package/src/server/routers/lambda/aiModel.ts +128 -0
- package/src/server/routers/lambda/aiProvider.ts +127 -0
- package/src/server/routers/lambda/index.ts +4 -0
- package/src/services/__tests__/_auth.test.ts +16 -49
- package/src/services/__tests__/chat.test.ts +2 -0
- package/src/services/_auth.ts +42 -25
- package/src/services/aiModel.ts +52 -0
- package/src/services/aiProvider.ts +47 -0
- package/src/services/chat.ts +62 -18
- package/src/store/aiInfra/index.ts +2 -0
- package/src/store/aiInfra/initialState.ts +11 -0
- package/src/store/aiInfra/selectors.ts +2 -0
- package/src/store/aiInfra/slices/aiModel/action.ts +146 -0
- package/src/store/aiInfra/slices/aiModel/index.ts +3 -0
- package/src/store/aiInfra/slices/aiModel/initialState.ts +14 -0
- package/src/store/aiInfra/slices/aiModel/selectors.ts +63 -0
- package/src/store/aiInfra/slices/aiProvider/action.ts +208 -0
- package/src/store/aiInfra/slices/aiProvider/index.ts +3 -0
- package/src/store/aiInfra/slices/aiProvider/initialState.ts +32 -0
- package/src/store/aiInfra/slices/aiProvider/selectors.ts +99 -0
- package/src/store/aiInfra/store.ts +25 -0
- package/src/store/global/initialState.ts +1 -0
- package/src/store/serverConfig/selectors.test.ts +1 -0
- package/src/styles/global.ts +1 -1
- package/src/types/aiModel.ts +32 -6
- package/src/types/aiProvider.ts +11 -4
- package/src/utils/fetch/fetchSSE.ts +3 -1
@@ -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
|
-
|
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
|
-
|
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
|
-
|
56
|
-
|
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
|
-
|
74
|
-
|
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
|
-
|
83
|
-
|
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
|
-
|
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
|
// 需要在修改模拟后重新导入相关模块
|
package/src/services/_auth.ts
CHANGED
@@ -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 {
|
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 = (
|
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 } =
|
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:
|
47
|
-
azureApiVersion:
|
48
|
-
baseURL:
|
56
|
+
apiKey: keyVaults.apiKey,
|
57
|
+
azureApiVersion: keyVaults.apiVersion,
|
58
|
+
baseURL: keyVaults.endpoint,
|
49
59
|
};
|
50
60
|
}
|
51
61
|
|
52
62
|
case ModelProvider.Ollama: {
|
53
|
-
|
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:
|
63
|
-
cloudflareBaseURLOrAccountID:
|
68
|
+
apiKey: keyVaults?.apiKey,
|
69
|
+
cloudflareBaseURLOrAccountID: keyVaults?.baseURLOrAccountID,
|
64
70
|
};
|
65
71
|
}
|
66
72
|
|
67
73
|
default: {
|
68
|
-
|
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, ...
|
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();
|
package/src/services/chat.ts
CHANGED
@@ -16,6 +16,7 @@ import {
|
|
16
16
|
} from '@/libs/agent-runtime';
|
17
17
|
import { filesPrompts } from '@/prompts/files';
|
18
18
|
import { BuiltinSystemRolePrompts } from '@/prompts/systemRole';
|
19
|
+
import { aiModelSelectors, aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
|
19
20
|
import { useSessionStore } from '@/store/session';
|
20
21
|
import { sessionMetaSelectors } from '@/store/session/selectors';
|
21
22
|
import { useToolStore } from '@/store/tool';
|
@@ -36,9 +37,50 @@ import { FetchSSEOptions, fetchSSE, getMessageError } from '@/utils/fetch';
|
|
36
37
|
import { genToolCallingName } from '@/utils/toolCall';
|
37
38
|
import { createTraceHeader, getTraceId } from '@/utils/trace';
|
38
39
|
|
39
|
-
import { createHeaderWithAuth,
|
40
|
+
import { createHeaderWithAuth, createPayloadWithKeyVaults } from './_auth';
|
40
41
|
import { API_ENDPOINTS } from './_url';
|
41
42
|
|
43
|
+
const isCanUseFC = (model: string) => {
|
44
|
+
// TODO: remove isDeprecatedEdition condition in V2.0
|
45
|
+
if (!isServerMode) {
|
46
|
+
return modelProviderSelectors.isModelEnabledFunctionCall(model)(useUserStore.getState());
|
47
|
+
}
|
48
|
+
|
49
|
+
return aiModelSelectors.isModelSupportToolUse(model)(useAiInfraStore.getState());
|
50
|
+
};
|
51
|
+
|
52
|
+
const findAzureDeploymentName = (model: string) => {
|
53
|
+
let deploymentId = model;
|
54
|
+
|
55
|
+
// TODO: remove isDeprecatedEdition condition in V2.0
|
56
|
+
if (!isServerMode) {
|
57
|
+
const chatModelCards = modelProviderSelectors.getModelCardsById(ModelProvider.Azure)(
|
58
|
+
useUserStore.getState(),
|
59
|
+
);
|
60
|
+
|
61
|
+
const deploymentName = chatModelCards.find((i) => i.id === model)?.deploymentName;
|
62
|
+
if (deploymentName) deploymentId = deploymentName;
|
63
|
+
} else {
|
64
|
+
// find the model by id
|
65
|
+
const modelItem = useAiInfraStore.getState().enabledAiModels?.find((i) => i.id === model);
|
66
|
+
|
67
|
+
if (modelItem && modelItem.config?.deploymentName) {
|
68
|
+
deploymentId = modelItem.config?.deploymentName;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
return deploymentId;
|
73
|
+
};
|
74
|
+
|
75
|
+
const isEnableFetchOnClient = (provider: string) => {
|
76
|
+
// TODO: remove this condition in V2.0
|
77
|
+
if (!isServerMode) {
|
78
|
+
return modelConfigSelectors.isProviderFetchOnClient(provider)(useUserStore.getState());
|
79
|
+
} else {
|
80
|
+
return aiProviderSelectors.isProviderFetchOnClient(provider)(useAiInfraStore.getState());
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
42
84
|
interface FetchOptions extends FetchSSEOptions {
|
43
85
|
historySummary?: string;
|
44
86
|
isWelcomeQuestion?: boolean;
|
@@ -83,7 +125,7 @@ interface CreateAssistantMessageStream extends FetchSSEOptions {
|
|
83
125
|
*/
|
84
126
|
export function initializeWithClientStore(provider: string, payload: any) {
|
85
127
|
// add auth payload
|
86
|
-
const providerAuthPayload =
|
128
|
+
const providerAuthPayload = { ...payload, ...createPayloadWithKeyVaults(provider) };
|
87
129
|
const commonOptions = {
|
88
130
|
// Some provider base openai sdk, so enable it run on browser
|
89
131
|
dangerouslyAllowBrowser: true,
|
@@ -200,9 +242,8 @@ class ChatService {
|
|
200
242
|
const filterTools = toolSelectors.enabledSchema(enabledPlugins)(useToolStore.getState());
|
201
243
|
|
202
244
|
// check this model can use function call
|
203
|
-
const canUseFC =
|
204
|
-
|
205
|
-
);
|
245
|
+
const canUseFC = isCanUseFC(payload.model);
|
246
|
+
|
206
247
|
// the rule that model can use tools:
|
207
248
|
// 1. tools is not empty
|
208
249
|
// 2. model can use function call
|
@@ -245,12 +286,7 @@ class ChatService {
|
|
245
286
|
|
246
287
|
// if the provider is Azure, get the deployment name as the request model
|
247
288
|
if (provider === ModelProvider.Azure) {
|
248
|
-
|
249
|
-
useUserStore.getState(),
|
250
|
-
);
|
251
|
-
|
252
|
-
const deploymentName = chatModelCards.find((i) => i.id === model)?.deploymentName;
|
253
|
-
if (deploymentName) model = deploymentName;
|
289
|
+
model = findAzureDeploymentName(model);
|
254
290
|
}
|
255
291
|
|
256
292
|
const payload = merge(
|
@@ -261,9 +297,7 @@ class ChatService {
|
|
261
297
|
/**
|
262
298
|
* Use browser agent runtime
|
263
299
|
*/
|
264
|
-
|
265
|
-
useUserStore.getState(),
|
266
|
-
);
|
300
|
+
let enableFetchOnClient = isEnableFetchOnClient(provider);
|
267
301
|
|
268
302
|
let fetcher: typeof fetch | undefined = undefined;
|
269
303
|
|
@@ -302,7 +336,19 @@ class ChatService {
|
|
302
336
|
|
303
337
|
const providerConfig = DEFAULT_MODEL_PROVIDER_LIST.find((item) => item.id === provider);
|
304
338
|
|
305
|
-
|
339
|
+
let sdkType = provider;
|
340
|
+
const isBuiltin = Object.values(ModelProvider).includes(provider as any);
|
341
|
+
|
342
|
+
// TODO: remove `!isDeprecatedEdition` condition in V2.0
|
343
|
+
if (isServerMode && !isBuiltin) {
|
344
|
+
const providerConfig = aiProviderSelectors.providerConfigById(provider)(
|
345
|
+
useAiInfraStore.getState(),
|
346
|
+
);
|
347
|
+
|
348
|
+
sdkType = providerConfig?.settings.sdkType || 'openai';
|
349
|
+
}
|
350
|
+
|
351
|
+
return fetchSSE(API_ENDPOINTS.chat(sdkType), {
|
306
352
|
body: JSON.stringify(payload),
|
307
353
|
fetcher: fetcher,
|
308
354
|
headers,
|
@@ -467,9 +513,7 @@ class ChatService {
|
|
467
513
|
|
468
514
|
// Inject Tool SystemRole
|
469
515
|
const hasTools = tools && tools?.length > 0;
|
470
|
-
const hasFC =
|
471
|
-
hasTools &&
|
472
|
-
modelProviderSelectors.isModelEnabledFunctionCall(model)(useUserStore.getState());
|
516
|
+
const hasFC = hasTools && isCanUseFC(model);
|
473
517
|
const toolsSystemRoles =
|
474
518
|
hasFC && toolSelectors.enabledSystemRoles(tools)(useToolStore.getState());
|
475
519
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { AIModelsState, initialAIModelState } from './slices/aiModel';
|
2
|
+
import { AIProviderState, initialAIProviderState } from './slices/aiProvider';
|
3
|
+
|
4
|
+
export interface AIProviderStoreState extends AIProviderState, AIModelsState {
|
5
|
+
/* empty */
|
6
|
+
}
|
7
|
+
|
8
|
+
export const initialState: AIProviderStoreState = {
|
9
|
+
...initialAIProviderState,
|
10
|
+
...initialAIModelState,
|
11
|
+
};
|