@lobehub/chat 0.122.9 → 0.123.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.
- package/.env.example +22 -2
- package/.eslintrc.js +1 -0
- package/CHANGELOG.md +59 -0
- package/Dockerfile +7 -1
- package/README.md +12 -10
- package/README.zh-CN.md +12 -10
- package/docs/Deployment/Docker-Deployment.md +1 -1
- package/docs/Deployment/Docker-Deployment.zh-CN.md +1 -1
- package/docs/Deployment/Environment-Variable.md +65 -23
- package/docs/Deployment/Environment-Variable.zh-CN.md +64 -22
- package/locales/ar/chat.json +12 -1
- package/locales/ar/common.json +16 -0
- package/locales/ar/error.json +35 -6
- package/locales/ar/setting.json +53 -6
- package/locales/de-DE/chat.json +12 -1
- package/locales/de-DE/common.json +16 -0
- package/locales/de-DE/error.json +35 -6
- package/locales/de-DE/setting.json +53 -6
- package/locales/en-US/chat.json +13 -2
- package/locales/en-US/common.json +16 -0
- package/locales/en-US/error.json +35 -6
- package/locales/en-US/setting.json +53 -6
- package/locales/es-ES/chat.json +12 -1
- package/locales/es-ES/common.json +16 -0
- package/locales/es-ES/error.json +35 -6
- package/locales/es-ES/setting.json +53 -6
- package/locales/fr-FR/chat.json +13 -2
- package/locales/fr-FR/common.json +16 -0
- package/locales/fr-FR/error.json +35 -6
- package/locales/fr-FR/setting.json +53 -6
- package/locales/it-IT/chat.json +12 -1
- package/locales/it-IT/common.json +16 -0
- package/locales/it-IT/error.json +35 -6
- package/locales/it-IT/setting.json +53 -6
- package/locales/ja-JP/chat.json +12 -1
- package/locales/ja-JP/common.json +16 -0
- package/locales/ja-JP/error.json +35 -6
- package/locales/ja-JP/setting.json +53 -6
- package/locales/ko-KR/chat.json +12 -1
- package/locales/ko-KR/common.json +16 -0
- package/locales/ko-KR/error.json +35 -6
- package/locales/ko-KR/setting.json +53 -6
- package/locales/nl-NL/chat.json +12 -1
- package/locales/nl-NL/common.json +16 -0
- package/locales/nl-NL/error.json +35 -6
- package/locales/nl-NL/setting.json +53 -6
- package/locales/pl-PL/chat.json +12 -1
- package/locales/pl-PL/common.json +16 -0
- package/locales/pl-PL/error.json +35 -6
- package/locales/pl-PL/setting.json +53 -6
- package/locales/pt-BR/chat.json +12 -1
- package/locales/pt-BR/common.json +16 -0
- package/locales/pt-BR/error.json +35 -6
- package/locales/pt-BR/setting.json +53 -6
- package/locales/ru-RU/chat.json +12 -1
- package/locales/ru-RU/common.json +16 -0
- package/locales/ru-RU/error.json +35 -6
- package/locales/ru-RU/setting.json +53 -6
- package/locales/tr-TR/chat.json +12 -1
- package/locales/tr-TR/common.json +16 -0
- package/locales/tr-TR/error.json +35 -6
- package/locales/tr-TR/setting.json +53 -6
- package/locales/vi-VN/chat.json +12 -1
- package/locales/vi-VN/common.json +16 -0
- package/locales/vi-VN/error.json +35 -6
- package/locales/vi-VN/setting.json +53 -6
- package/locales/zh-CN/chat.json +12 -1
- package/locales/zh-CN/common.json +16 -0
- package/locales/zh-CN/error.json +34 -5
- package/locales/zh-CN/setting.json +59 -12
- package/locales/zh-TW/chat.json +12 -1
- package/locales/zh-TW/common.json +16 -0
- package/locales/zh-TW/error.json +35 -6
- package/locales/zh-TW/setting.json +53 -6
- package/next.config.mjs +8 -2
- package/package.json +8 -2
- package/src/app/api/chat/[provider]/agentRuntime.ts +129 -0
- package/src/app/api/chat/[provider]/route.ts +64 -0
- package/src/app/api/chat/auth.ts +42 -0
- package/src/app/api/chat/google/route.ts +86 -0
- package/src/app/api/config/route.ts +6 -1
- package/src/app/api/config.ts +3 -3
- package/src/app/api/errorResponse.test.ts +8 -8
- package/src/app/api/errorResponse.ts +43 -6
- package/src/app/api/openai/createBizOpenAI/createAzureOpenai.ts +1 -1
- package/src/app/api/openai/createBizOpenAI/createOpenai.ts +1 -1
- package/src/app/api/openai/createBizOpenAI/index.ts +2 -2
- package/src/app/api/plugin/gateway/route.ts +4 -1
- package/src/app/chat/(desktop)/features/ChatHeader.tsx +6 -4
- package/src/app/chat/(desktop)/features/ChatInput/Footer/index.tsx +13 -3
- package/src/app/chat/(desktop)/features/ChatInput/Header/index.tsx +16 -24
- package/src/app/chat/(desktop)/features/SideBar/index.tsx +1 -0
- package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +3 -3
- package/src/app/chat/features/SessionListContent/List/Item/index.tsx +2 -3
- package/src/app/settings/llm/Azure/index.tsx +145 -0
- package/src/app/settings/llm/Bedrock/index.tsx +109 -0
- package/src/app/settings/llm/{LLM/Checker.tsx → Checker.tsx} +11 -14
- package/src/app/settings/llm/Google/index.tsx +74 -0
- package/src/app/settings/llm/{LLM → OpenAI}/index.tsx +26 -44
- package/src/app/settings/llm/Zhipu/index.tsx +78 -0
- package/src/app/settings/llm/const.ts +13 -0
- package/src/app/settings/llm/page.tsx +42 -2
- package/src/app/settings/llm/useSyncSettings.ts +23 -0
- package/src/chains/__tests__/langDetect.test.ts +2 -2
- package/src/chains/__tests__/pickEmoji.test.ts +2 -2
- package/src/chains/langDetect.ts +2 -2
- package/src/chains/pickEmoji.ts +2 -2
- package/src/chains/summaryAgentName.ts +2 -2
- package/src/chains/summaryDescription.ts +2 -2
- package/src/chains/summaryTags.ts +2 -2
- package/src/chains/summaryTitle.ts +2 -2
- package/src/chains/translate.ts +2 -2
- package/src/components/ModelIcon/index.tsx +37 -0
- package/src/components/ModelProviderIcon/index.tsx +44 -0
- package/src/components/ModelSelect/index.tsx +133 -0
- package/src/components/ModelTag/ModelIcon.tsx +35 -0
- package/src/components/ModelTag/index.tsx +13 -0
- package/src/config/modelProviders/bedrock.ts +43 -0
- package/src/config/modelProviders/google.ts +20 -0
- package/src/config/modelProviders/index.ts +18 -0
- package/src/config/modelProviders/openai.ts +110 -0
- package/src/config/modelProviders/zhipu.ts +34 -0
- package/src/config/{server.ts → server/app.ts} +1 -24
- package/src/config/server/index.ts +13 -0
- package/src/config/server/provider.ts +78 -0
- package/src/const/auth.ts +30 -0
- package/src/const/fetch.ts +3 -0
- package/src/const/settings.ts +24 -4
- package/src/database/core/migrations/migrateSettingsToUser/index.test.ts +2 -1
- package/src/database/core/migrations/migrateSettingsToUser/index.ts +1 -18
- package/src/database/core/migrations/migrateSettingsToUser/type.ts +100 -0
- package/src/database/models/message.ts +3 -1
- package/src/database/schemas/message.ts +1 -0
- package/src/database/schemas/session.ts +1 -0
- package/src/features/AgentSetting/AgentConfig/ModelSelect.tsx +71 -0
- package/src/features/AgentSetting/AgentConfig/index.tsx +171 -161
- package/src/features/AgentSetting/AgentConfig/useSyncConfig.ts +23 -0
- package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +39 -0
- package/src/features/AgentSetting/AgentPrompt/index.tsx +4 -26
- package/src/features/AgentSetting/store/index.ts +10 -2
- package/src/features/ChatInput/ActionBar/FileUpload.tsx +15 -5
- package/src/features/ChatInput/ActionBar/ModelSwitch.tsx +56 -14
- package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +42 -7
- package/src/features/ChatInput/ActionBar/Token/index.tsx +5 -2
- package/src/features/ChatInput/ActionBar/Tools/index.tsx +11 -1
- package/src/features/ChatInput/useChatInput.ts +5 -1
- package/src/features/Conversation/Error/APIKeyForm/Bedrock.tsx +80 -0
- package/src/features/Conversation/Error/APIKeyForm/Google.tsx +61 -0
- package/src/features/Conversation/Error/APIKeyForm/OpenAI.tsx +63 -0
- package/src/features/Conversation/Error/APIKeyForm/Zhipu.tsx +62 -0
- package/src/features/Conversation/Error/APIKeyForm/index.tsx +72 -0
- package/src/features/Conversation/Error/AccessCodeForm.tsx +63 -0
- package/src/features/Conversation/Error/ErrorJsonViewer.tsx +26 -0
- package/src/features/Conversation/Error/InvalidAPIKey.tsx +16 -0
- package/src/features/Conversation/Error/InvalidAccessCode.tsx +50 -0
- package/src/features/Conversation/Error/OpenAiBizError.tsx +9 -17
- package/src/features/Conversation/Error/{Plugin/PluginSettings.tsx → PluginSettings.tsx} +8 -3
- package/src/features/Conversation/Error/index.tsx +75 -70
- package/src/features/Conversation/Error/style.tsx +9 -3
- package/src/features/Conversation/Extras/Assistant.tsx +2 -3
- package/src/features/Conversation/Plugins/Inspector/index.tsx +8 -2
- package/src/features/Conversation/components/ChatItem/index.tsx +9 -24
- package/src/features/Conversation/types/index.tsx +2 -5
- package/src/hooks/_header.ts +35 -0
- package/src/libs/agent-runtime/BaseAI.ts +9 -0
- package/src/libs/agent-runtime/azureOpenai/index.ts +72 -0
- package/src/libs/agent-runtime/bedrock/index.ts +134 -0
- package/src/libs/agent-runtime/error.ts +26 -0
- package/src/libs/agent-runtime/google/index.ts +160 -0
- package/src/libs/agent-runtime/index.ts +9 -0
- package/src/libs/agent-runtime/openai/index.test.ts +176 -0
- package/src/libs/agent-runtime/openai/index.ts +107 -0
- package/src/libs/agent-runtime/types/chat.ts +119 -0
- package/src/libs/agent-runtime/types/index.ts +2 -0
- package/src/libs/agent-runtime/types/type.ts +34 -0
- package/src/libs/agent-runtime/utils/createError.ts +10 -0
- package/src/libs/agent-runtime/utils/debugStream.ts +18 -0
- package/src/libs/agent-runtime/utils/env.ts +1 -0
- package/src/libs/agent-runtime/utils/handleOpenAIError.ts +39 -0
- package/src/libs/agent-runtime/utils/uriParser.ts +16 -0
- package/src/libs/agent-runtime/zhipu/authToken.ts +22 -0
- package/src/libs/agent-runtime/zhipu/index.ts +125 -0
- package/src/locales/default/chat.ts +12 -2
- package/src/locales/default/common.ts +16 -0
- package/src/locales/default/error.ts +42 -5
- package/src/locales/default/setting.ts +61 -12
- package/src/services/__tests__/chat.test.ts +8 -2
- package/src/services/__tests__/message.test.ts +1 -1
- package/src/services/_auth.ts +106 -0
- package/src/services/_header.ts +1 -0
- package/src/services/_url.ts +0 -2
- package/src/services/chat.ts +34 -14
- package/src/store/chat/slices/message/action.ts +9 -6
- package/src/store/global/slices/common/action.ts +8 -2
- package/src/store/global/slices/settings/action.test.ts +2 -2
- package/src/store/global/slices/settings/action.ts +11 -4
- package/src/store/global/slices/settings/selectors/__snapshots__/modelProvider.test.ts.snap +24 -92
- package/src/store/global/slices/settings/selectors/__snapshots__/selectors.test.ts.snap +2 -0
- package/src/store/global/slices/settings/selectors/modelProvider.test.ts +127 -50
- package/src/store/global/slices/settings/selectors/modelProvider.ts +145 -43
- package/src/store/session/slices/agent/selectors.test.ts +0 -48
- package/src/store/session/slices/agent/selectors.ts +7 -12
- package/src/types/agent/index.ts +6 -2
- package/src/types/fetch.ts +4 -2
- package/src/types/files.ts +3 -3
- package/src/types/llm.ts +34 -0
- package/src/types/message/index.ts +7 -3
- package/src/types/openai/chat.ts +6 -11
- package/src/types/settings/index.ts +1 -0
- package/src/types/settings/modelProvider.ts +37 -1
- package/src/utils/__snapshots__/parseModels.test.ts.snap +63 -0
- package/src/utils/parseModels.test.ts +24 -0
- package/src/utils/parseModels.ts +37 -0
- package/src/app/api/openai/chat/createChatCompletion.test.ts +0 -166
- package/src/app/api/openai/chat/createChatCompletion.ts +0 -76
- package/src/app/api/openai/chat/route.ts +0 -19
- package/src/app/api/openai/models/route.ts +0 -17
- package/src/app/settings/llm/LLM/ModelList.tsx +0 -51
- package/src/app/settings/llm/LLM/getModelList.ts +0 -9
- package/src/app/settings/llm/index.tsx +0 -36
- package/src/const/llm.ts +0 -32
- package/src/features/Conversation/Error/ApiKeyForm.tsx +0 -87
- package/src/features/Conversation/Error/ErrorActionContainer.tsx +0 -23
- package/src/features/Conversation/Error/InvalidAccess.tsx +0 -90
- package/src/features/Conversation/Error/OpenAPIKey.tsx +0 -13
- package/src/features/Conversation/Error/Plugin/PluginError.tsx +0 -30
- package/src/services/modelList.ts +0 -15
- /package/src/app/chat/(desktop)/features/ChatInput/{Header → Footer}/DragUpload.tsx +0 -0
- /package/src/{app/api/openai/chat → libs/agent-runtime/utils}/desensitizeUrl.test.ts +0 -0
- /package/src/{app/api/openai/chat → libs/agent-runtime/utils}/desensitizeUrl.ts +0 -0
- /package/src/types/{translate.ts → message/translate.ts} +0 -0
|
@@ -1,64 +1,166 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { produce } from 'immer';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
BedrockProvider,
|
|
5
|
+
GoogleProvider,
|
|
6
|
+
LOBE_DEFAULT_MODEL_LIST,
|
|
7
|
+
OpenAIProvider,
|
|
8
|
+
ZhiPuProvider,
|
|
9
|
+
} from '@/config/modelProviders';
|
|
10
|
+
import { ChatModelCard, ModelProviderCard } from '@/types/llm';
|
|
11
|
+
import { parseModelString } from '@/utils/parseModels';
|
|
3
12
|
|
|
4
13
|
import { GlobalStore } from '../../../store';
|
|
5
14
|
import { currentSettings } from './settings';
|
|
6
15
|
|
|
7
|
-
const
|
|
16
|
+
const modelProvider = (s: GlobalStore) => currentSettings(s).languageModel;
|
|
17
|
+
const openAIConfig = (s: GlobalStore) => modelProvider(s).openAI;
|
|
8
18
|
|
|
9
|
-
const
|
|
10
|
-
|
|
19
|
+
const openAIAPIKey = (s: GlobalStore) => openAIConfig(s).OPENAI_API_KEY;
|
|
20
|
+
const openAIProxyUrl = (s: GlobalStore) => openAIConfig(s).endpoint;
|
|
11
21
|
|
|
12
|
-
const
|
|
22
|
+
const enableZhipu = (s: GlobalStore) => modelProvider(s).zhipu.enabled;
|
|
23
|
+
const zhipuAPIKey = (s: GlobalStore) => modelProvider(s).zhipu.apiKey;
|
|
24
|
+
const zhipuProxyUrl = (s: GlobalStore) => modelProvider(s).zhipu.endpoint;
|
|
13
25
|
|
|
14
|
-
const
|
|
15
|
-
|
|
26
|
+
const enableBedrock = (s: GlobalStore) => modelProvider(s).bedrock.enabled;
|
|
27
|
+
const bedrockConfig = (s: GlobalStore) => modelProvider(s).bedrock;
|
|
16
28
|
|
|
17
|
-
const
|
|
18
|
-
|
|
29
|
+
const enableGoogle = (s: GlobalStore) => modelProvider(s).google.enabled;
|
|
30
|
+
const googleAPIKey = (s: GlobalStore) => modelProvider(s).google.apiKey;
|
|
31
|
+
const googleProxyUrl = (s: GlobalStore) => modelProvider(s).google.endpoint;
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
...DEFAULT_OPENAI_MODEL_LIST,
|
|
23
|
-
...(s.serverConfig.customModelName || '').split(/[,,]/).filter(Boolean),
|
|
24
|
-
...(currentSettings(s).languageModel.openAI.customModelName || '')
|
|
25
|
-
.split(/[,,]/)
|
|
26
|
-
.filter(Boolean),
|
|
27
|
-
];
|
|
33
|
+
const enableAzure = (s: GlobalStore) => modelProvider(s).openAI.useAzure;
|
|
34
|
+
const azureConfig = (s: GlobalStore) => modelProvider(s).azure;
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
// const azureModelList = (s: GlobalStore): ModelProviderCard => {
|
|
37
|
+
// const azure = azureConfig(s);
|
|
38
|
+
// return {
|
|
39
|
+
// chatModels: parseModelString(azure.deployments),
|
|
40
|
+
// id: 'azure',
|
|
41
|
+
// };
|
|
42
|
+
// };
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
// 提取处理 chatModels 的专门方法
|
|
45
|
+
const processChatModels = (modelConfig: ReturnType<typeof parseModelString>): ChatModelCard[] => {
|
|
46
|
+
let chatModels = modelConfig.removeAll ? [] : OpenAIProvider.chatModels;
|
|
47
|
+
|
|
48
|
+
// 处理移除逻辑
|
|
49
|
+
if (!modelConfig.removeAll) {
|
|
50
|
+
chatModels = chatModels.filter((m) => !modelConfig.removed.includes(m.id));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return produce(chatModels, (draft) => {
|
|
54
|
+
// 处理添加或替换逻辑
|
|
55
|
+
for (const customModel of modelConfig.add) {
|
|
56
|
+
// 首先尝试在 LOBE_DEFAULT_MODEL_LIST 中查找模型
|
|
57
|
+
const defaultModel = LOBE_DEFAULT_MODEL_LIST.find((model) => model.id === customModel.id);
|
|
58
|
+
|
|
59
|
+
// 如果在默认列表中找到了模型,则基于该模型进行更新
|
|
60
|
+
if (defaultModel) {
|
|
61
|
+
const model = draft.find((model) => model.id === customModel.id);
|
|
62
|
+
// 如果当前 chatModels 中已有该模型,更新它
|
|
63
|
+
if (model) {
|
|
64
|
+
if (model.hidden) delete model.hidden;
|
|
65
|
+
if (customModel.displayName) model.displayName = customModel.displayName;
|
|
66
|
+
} else {
|
|
67
|
+
// 如果当前 chatModels 中没有该模型,添加它
|
|
68
|
+
draft.push({
|
|
69
|
+
...defaultModel,
|
|
70
|
+
displayName: customModel.displayName || defaultModel.displayName,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
// 如果在默认列表中未找到模型,作为新的自定义模型添加
|
|
75
|
+
draft.push({
|
|
76
|
+
...customModel,
|
|
77
|
+
displayName: customModel.displayName || customModel.id,
|
|
78
|
+
functionCall: true,
|
|
79
|
+
isCustom: true,
|
|
80
|
+
vision: true,
|
|
81
|
+
});
|
|
38
82
|
}
|
|
39
|
-
removedModels.push(name);
|
|
40
|
-
continue;
|
|
41
83
|
}
|
|
84
|
+
});
|
|
85
|
+
};
|
|
42
86
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
87
|
+
const modelSelectList = (s: GlobalStore): ModelProviderCard[] => {
|
|
88
|
+
const string = [
|
|
89
|
+
s.serverConfig.customModelName,
|
|
90
|
+
currentSettings(s).languageModel.openAI.customModelName,
|
|
91
|
+
]
|
|
92
|
+
.filter(Boolean)
|
|
93
|
+
.join(',');
|
|
48
94
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
});
|
|
53
|
-
}
|
|
95
|
+
const modelConfig = parseModelString(string);
|
|
96
|
+
|
|
97
|
+
const chatModels = processChatModels(modelConfig);
|
|
54
98
|
|
|
55
|
-
return
|
|
99
|
+
return [
|
|
100
|
+
{
|
|
101
|
+
...OpenAIProvider,
|
|
102
|
+
chatModels,
|
|
103
|
+
},
|
|
104
|
+
// { ...azureModelList(s), enabled: enableAzure(s) },
|
|
105
|
+
{ ...ZhiPuProvider, enabled: enableZhipu(s) },
|
|
106
|
+
{ ...GoogleProvider, enabled: enableGoogle(s) },
|
|
107
|
+
{ ...BedrockProvider, enabled: enableBedrock(s) },
|
|
108
|
+
];
|
|
56
109
|
};
|
|
57
110
|
|
|
111
|
+
const modelCardById = (id: string) => (s: GlobalStore) => {
|
|
112
|
+
const list = modelSelectList(s);
|
|
113
|
+
|
|
114
|
+
return list.flatMap((i) => i.chatModels).find((m) => m.id === id);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const modelEnabledFunctionCall = (id: string) => (s: GlobalStore) =>
|
|
118
|
+
modelCardById(id)(s)?.functionCall || false;
|
|
119
|
+
|
|
120
|
+
// vision model white list, these models will change the content from string to array
|
|
121
|
+
// refs: https://github.com/lobehub/lobe-chat/issues/790
|
|
122
|
+
const modelEnabledVision = (id: string) => (s: GlobalStore) =>
|
|
123
|
+
modelCardById(id)(s)?.vision || id.includes('vision');
|
|
124
|
+
|
|
125
|
+
const modelEnabledFiles = (id: string) => (s: GlobalStore) => modelCardById(id)(s)?.files;
|
|
126
|
+
|
|
127
|
+
const modelEnabledUpload = (id: string) => (s: GlobalStore) =>
|
|
128
|
+
modelEnabledVision(id)(s) || modelEnabledFiles(id)(s);
|
|
129
|
+
|
|
130
|
+
const modelHasMaxToken = (id: string) => (s: GlobalStore) =>
|
|
131
|
+
typeof modelCardById(id)(s)?.tokens !== 'undefined';
|
|
132
|
+
|
|
133
|
+
const modelMaxToken = (id: string) => (s: GlobalStore) => modelCardById(id)(s)?.tokens || 0;
|
|
134
|
+
|
|
135
|
+
/* eslint-disable sort-keys-fix/sort-keys-fix, */
|
|
58
136
|
export const modelProviderSelectors = {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
137
|
+
modelSelectList,
|
|
138
|
+
|
|
139
|
+
modelCardById,
|
|
140
|
+
modelMaxToken,
|
|
141
|
+
modelHasMaxToken,
|
|
142
|
+
|
|
143
|
+
modelEnabledFunctionCall,
|
|
144
|
+
modelEnabledVision,
|
|
145
|
+
modelEnabledFiles,
|
|
146
|
+
modelEnabledUpload,
|
|
147
|
+
|
|
148
|
+
// OpenAI
|
|
62
149
|
openAIConfig,
|
|
63
|
-
|
|
150
|
+
openAIAPIKey,
|
|
151
|
+
openAIProxyUrl,
|
|
152
|
+
// Azure OpenAI
|
|
153
|
+
enableAzure,
|
|
154
|
+
azureConfig,
|
|
155
|
+
// Zhipu
|
|
156
|
+
enableZhipu,
|
|
157
|
+
zhipuAPIKey,
|
|
158
|
+
zhipuProxyUrl,
|
|
159
|
+
// Google
|
|
160
|
+
enableGoogle,
|
|
161
|
+
googleAPIKey,
|
|
162
|
+
googleProxyUrl,
|
|
163
|
+
// Bedrock
|
|
164
|
+
enableBedrock,
|
|
165
|
+
bedrockConfig,
|
|
64
166
|
};
|
|
@@ -177,52 +177,4 @@ describe('agentSelectors', () => {
|
|
|
177
177
|
expect(description).toBe('noDescription'); // Assuming translation returns this key
|
|
178
178
|
});
|
|
179
179
|
});
|
|
180
|
-
|
|
181
|
-
describe('showTokenTag', () => {
|
|
182
|
-
it('should return true if the model is in the list of models that show tokens', () => {
|
|
183
|
-
const show = agentSelectors.showTokenTag(mockSessionStore);
|
|
184
|
-
expect(show).toBe(true);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('should return false if the model is not in the list of models that show tokens', () => {
|
|
188
|
-
const modifiedSessionStore = {
|
|
189
|
-
...mockSessionStore,
|
|
190
|
-
sessions: [
|
|
191
|
-
{
|
|
192
|
-
...mockSessionStore.sessions[0],
|
|
193
|
-
config: {
|
|
194
|
-
...mockSessionStore.sessions[0].config,
|
|
195
|
-
model: 'some-other-model',
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
};
|
|
200
|
-
const show = agentSelectors.showTokenTag(modifiedSessionStore);
|
|
201
|
-
expect(show).toBe(false);
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
describe('modelHasVisionAbility', () => {
|
|
206
|
-
it('should return true if the model has vision ability', () => {
|
|
207
|
-
const hasAbility = agentSelectors.modelHasVisionAbility(mockSessionStore);
|
|
208
|
-
expect(hasAbility).toBe(false);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('should return false if the model does not have vision ability', () => {
|
|
212
|
-
const modifiedSessionStore = {
|
|
213
|
-
...mockSessionStore,
|
|
214
|
-
sessions: [
|
|
215
|
-
{
|
|
216
|
-
...mockSessionStore.sessions[0],
|
|
217
|
-
config: {
|
|
218
|
-
...mockSessionStore.sessions[0].config,
|
|
219
|
-
model: 'some-other-model',
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
],
|
|
223
|
-
};
|
|
224
|
-
const hasAbility = agentSelectors.modelHasVisionAbility(modifiedSessionStore);
|
|
225
|
-
expect(hasAbility).toBe(false);
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
180
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { VoiceList } from '@lobehub/tts';
|
|
2
2
|
import { t } from 'i18next';
|
|
3
3
|
|
|
4
|
-
import { DEFAULT_OPENAI_MODEL_LIST, isVisionModel } from '@/const/llm';
|
|
5
4
|
import { DEFAULT_AVATAR, DEFAULT_BACKGROUND_COLOR, DEFAULT_INBOX_AVATAR } from '@/const/meta';
|
|
6
5
|
import { DEFAULT_AGENT_CONFIG, DEFAUTT_AGENT_TTS_CONFIG } from '@/const/settings';
|
|
7
6
|
import { useGlobalStore } from '@/store/global';
|
|
@@ -36,6 +35,12 @@ const currentAgentModel = (s: SessionStore): LanguageModel | string => {
|
|
|
36
35
|
return config?.model || LanguageModel.GPT3_5;
|
|
37
36
|
};
|
|
38
37
|
|
|
38
|
+
const currentAgentModelProvider = (s: SessionStore) => {
|
|
39
|
+
const config = currentAgentConfig(s);
|
|
40
|
+
|
|
41
|
+
return config?.provider;
|
|
42
|
+
};
|
|
43
|
+
|
|
39
44
|
const currentAgentPlugins = (s: SessionStore) => {
|
|
40
45
|
const config = currentAgentConfig(s);
|
|
41
46
|
|
|
@@ -99,20 +104,11 @@ const getTitle = (s: MetaData) => s.title || t('defaultSession', { ns: 'common'
|
|
|
99
104
|
export const getDescription = (s: MetaData) =>
|
|
100
105
|
s.description || t('noDescription', { ns: 'common' });
|
|
101
106
|
|
|
102
|
-
const showTokenTag = (s: SessionStore) => {
|
|
103
|
-
const model = currentAgentModel(s);
|
|
104
|
-
|
|
105
|
-
return DEFAULT_OPENAI_MODEL_LIST.includes(model);
|
|
106
|
-
};
|
|
107
107
|
const hasSystemRole = (s: SessionStore) => {
|
|
108
108
|
const config = currentAgentConfig(s);
|
|
109
109
|
|
|
110
110
|
return !!config.systemRole;
|
|
111
111
|
};
|
|
112
|
-
const modelHasVisionAbility = (s: SessionStore): boolean => {
|
|
113
|
-
const model = currentAgentModel(s);
|
|
114
|
-
return isVisionModel(model);
|
|
115
|
-
};
|
|
116
112
|
|
|
117
113
|
export const agentSelectors = {
|
|
118
114
|
currentAgentAvatar,
|
|
@@ -121,6 +117,7 @@ export const agentSelectors = {
|
|
|
121
117
|
currentAgentDescription,
|
|
122
118
|
currentAgentMeta,
|
|
123
119
|
currentAgentModel,
|
|
120
|
+
currentAgentModelProvider,
|
|
124
121
|
currentAgentPlugins,
|
|
125
122
|
currentAgentSystemRole,
|
|
126
123
|
currentAgentTTS,
|
|
@@ -130,6 +127,4 @@ export const agentSelectors = {
|
|
|
130
127
|
getDescription,
|
|
131
128
|
getTitle,
|
|
132
129
|
hasSystemRole,
|
|
133
|
-
modelHasVisionAbility,
|
|
134
|
-
showTokenTag,
|
|
135
130
|
};
|
package/src/types/agent/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FewShots, LLMParams
|
|
1
|
+
import { FewShots, LLMParams } from '@/types/llm';
|
|
2
2
|
|
|
3
3
|
export type TTSServer = 'openai' | 'edge' | 'microsoft';
|
|
4
4
|
|
|
@@ -37,7 +37,7 @@ export interface LobeAgentConfig {
|
|
|
37
37
|
* 角色所使用的语言模型
|
|
38
38
|
* @default gpt-3.5-turbo
|
|
39
39
|
*/
|
|
40
|
-
model:
|
|
40
|
+
model: string;
|
|
41
41
|
/**
|
|
42
42
|
* 语言模型参数
|
|
43
43
|
*/
|
|
@@ -46,6 +46,10 @@ export interface LobeAgentConfig {
|
|
|
46
46
|
* 启用的插件
|
|
47
47
|
*/
|
|
48
48
|
plugins?: string[];
|
|
49
|
+
/**
|
|
50
|
+
* 模型供应商
|
|
51
|
+
*/
|
|
52
|
+
provider?: string;
|
|
49
53
|
/**
|
|
50
54
|
* 系统角色
|
|
51
55
|
*/
|
package/src/types/fetch.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
|
2
|
+
import { ILobeAgentRuntimeErrorType } from '@/libs/agent-runtime';
|
|
3
|
+
|
|
2
4
|
export const ChatErrorType = {
|
|
3
5
|
// ******* 业务错误语义 ******* //
|
|
4
6
|
|
|
5
7
|
InvalidAccessCode: 'InvalidAccessCode', // 密码无效
|
|
6
8
|
OpenAIBizError: 'OpenAIBizError', // OpenAI 返回的业务错误
|
|
7
|
-
|
|
9
|
+
NoOpenAIAPIKey: 'NoOpenAIAPIKey',
|
|
8
10
|
|
|
9
11
|
// ******* 客户端错误 ******* //
|
|
10
12
|
BadRequest: 400,
|
|
@@ -26,5 +28,5 @@ export type ErrorType = (typeof ChatErrorType)[keyof typeof ChatErrorType];
|
|
|
26
28
|
|
|
27
29
|
export interface ErrorResponse {
|
|
28
30
|
body: any;
|
|
29
|
-
errorType: ErrorType;
|
|
31
|
+
errorType: ErrorType | ILobeAgentRuntimeErrorType;
|
|
30
32
|
}
|
package/src/types/files.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export interface FilePreview extends Pick<DB_File, 'saveMode' | 'fileType'> {
|
|
1
|
+
export interface FilePreview {
|
|
4
2
|
base64Url?: string;
|
|
5
3
|
data?: ArrayBuffer;
|
|
4
|
+
fileType: string;
|
|
6
5
|
name: string;
|
|
6
|
+
saveMode: 'local' | 'url';
|
|
7
7
|
url: string;
|
|
8
8
|
}
|
package/src/types/llm.ts
CHANGED
|
@@ -17,6 +17,40 @@ export enum LanguageModel {
|
|
|
17
17
|
GPT4_VISION_PREVIEW = 'gpt-4-vision-preview',
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
export interface ChatModelCard {
|
|
21
|
+
description?: string;
|
|
22
|
+
displayName?: string;
|
|
23
|
+
/**
|
|
24
|
+
* whether model supports file upload
|
|
25
|
+
*/
|
|
26
|
+
files?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* whether model supports function call
|
|
29
|
+
*/
|
|
30
|
+
functionCall?: boolean;
|
|
31
|
+
hidden?: boolean;
|
|
32
|
+
id: string;
|
|
33
|
+
/**
|
|
34
|
+
* whether model is custom
|
|
35
|
+
*/
|
|
36
|
+
isCustom?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* whether model is legacy (deprecated but not removed yet)
|
|
39
|
+
*/
|
|
40
|
+
legacy?: boolean;
|
|
41
|
+
tokens?: number;
|
|
42
|
+
/**
|
|
43
|
+
* whether model supports vision
|
|
44
|
+
*/
|
|
45
|
+
vision?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface ModelProviderCard {
|
|
49
|
+
chatModels: ChatModelCard[];
|
|
50
|
+
enabled?: boolean;
|
|
51
|
+
id: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
20
54
|
// 语言模型的设置参数
|
|
21
55
|
export interface LLMParams {
|
|
22
56
|
/**
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { IPluginErrorType } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
|
|
3
|
+
import { ILobeAgentRuntimeErrorType } from '@/libs/agent-runtime';
|
|
1
4
|
import { ErrorType } from '@/types/fetch';
|
|
2
|
-
import { Translate } from '@/types/translate';
|
|
3
5
|
|
|
4
6
|
import { LLMRoleType } from '../llm';
|
|
5
7
|
import { BaseDataModel } from '../meta';
|
|
6
8
|
import { ChatPluginPayload } from './tools';
|
|
9
|
+
import { Translate } from './translate';
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* 聊天消息错误对象
|
|
@@ -11,7 +14,7 @@ import { ChatPluginPayload } from './tools';
|
|
|
11
14
|
export interface ChatMessageError {
|
|
12
15
|
body?: any;
|
|
13
16
|
message: string;
|
|
14
|
-
type: ErrorType;
|
|
17
|
+
type: ErrorType | IPluginErrorType | ILobeAgentRuntimeErrorType;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
export interface ChatTranslate extends Translate {
|
|
@@ -28,10 +31,11 @@ export * from './tools';
|
|
|
28
31
|
|
|
29
32
|
export interface ChatMessage extends BaseDataModel {
|
|
30
33
|
content: string;
|
|
31
|
-
error?:
|
|
34
|
+
error?: ChatMessageError;
|
|
32
35
|
// 扩展字段
|
|
33
36
|
extra?: {
|
|
34
37
|
fromModel?: string;
|
|
38
|
+
fromProvider?: string;
|
|
35
39
|
// 翻译
|
|
36
40
|
translate?: ChatTranslate | false;
|
|
37
41
|
// TTS
|
package/src/types/openai/chat.ts
CHANGED
|
@@ -32,24 +32,15 @@ export interface OpenAIChatMessage {
|
|
|
32
32
|
role: LLMRoleType;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export interface OpenAIChatStringMessage {
|
|
36
|
-
content: string;
|
|
37
|
-
role: LLMRoleType;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
35
|
/**
|
|
41
|
-
* @title
|
|
36
|
+
* @title Chat Stream Payload
|
|
42
37
|
*/
|
|
43
|
-
export interface
|
|
38
|
+
export interface ChatStreamPayload {
|
|
44
39
|
/**
|
|
45
40
|
* @title 控制生成文本中的惩罚系数,用于减少重复性
|
|
46
41
|
* @default 0
|
|
47
42
|
*/
|
|
48
43
|
frequency_penalty?: number;
|
|
49
|
-
/**
|
|
50
|
-
* @deprecated
|
|
51
|
-
*/
|
|
52
|
-
functions?: ChatCompletionFunctions[];
|
|
53
44
|
/**
|
|
54
45
|
* @title 生成文本的最大长度
|
|
55
46
|
*/
|
|
@@ -75,6 +66,10 @@ export interface OpenAIChatStreamPayload {
|
|
|
75
66
|
* @default 0
|
|
76
67
|
*/
|
|
77
68
|
presence_penalty?: number;
|
|
69
|
+
/**
|
|
70
|
+
* @default openai
|
|
71
|
+
*/
|
|
72
|
+
provider?: string;
|
|
78
73
|
/**
|
|
79
74
|
* @title 是否开启流式请求
|
|
80
75
|
* @default true
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CustomModels = { displayName: string;
|
|
1
|
+
export type CustomModels = { displayName: string; id: string }[];
|
|
2
2
|
|
|
3
3
|
export interface OpenAIConfig {
|
|
4
4
|
OPENAI_API_KEY: string;
|
|
@@ -8,10 +8,46 @@ export interface OpenAIConfig {
|
|
|
8
8
|
*/
|
|
9
9
|
customModelName?: string;
|
|
10
10
|
endpoint?: string;
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated
|
|
13
|
+
*/
|
|
11
14
|
models?: string[];
|
|
12
15
|
useAzure?: boolean;
|
|
13
16
|
}
|
|
14
17
|
|
|
18
|
+
export interface AzureOpenAIConfig {
|
|
19
|
+
apiKey: string;
|
|
20
|
+
apiVersion?: string;
|
|
21
|
+
deployments: string;
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
endpoint?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ZhiPuConfig {
|
|
27
|
+
apiKey?: string;
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
endpoint?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface GoogleConfig {
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
endpoint?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface AWSBedrockConfig {
|
|
39
|
+
accessKeyId?: string;
|
|
40
|
+
enabled: boolean;
|
|
41
|
+
region?: string;
|
|
42
|
+
secretAccessKey?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
15
45
|
export interface GlobalLLMConfig {
|
|
46
|
+
azure: AzureOpenAIConfig;
|
|
47
|
+
bedrock: AWSBedrockConfig;
|
|
48
|
+
google: GoogleConfig;
|
|
16
49
|
openAI: OpenAIConfig;
|
|
50
|
+
zhipu: ZhiPuConfig;
|
|
17
51
|
}
|
|
52
|
+
|
|
53
|
+
export type GlobalLLMProviderKey = keyof GlobalLLMConfig;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`parseModelString > custom deletion, addition, and renaming of models 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"add": [
|
|
6
|
+
{
|
|
7
|
+
"displayName": undefined,
|
|
8
|
+
"id": "llama",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"displayName": undefined,
|
|
12
|
+
"id": "claude-2",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"displayName": "gpt-4-32k",
|
|
16
|
+
"id": "gpt-4-1106-preview",
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
"removeAll": true,
|
|
20
|
+
"removed": [
|
|
21
|
+
"all",
|
|
22
|
+
"gpt-3.5-turbo",
|
|
23
|
+
],
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
exports[`parseModelString > duplicate naming model 1`] = `
|
|
28
|
+
{
|
|
29
|
+
"add": [
|
|
30
|
+
{
|
|
31
|
+
"displayName": "gpt-4-32k",
|
|
32
|
+
"id": "gpt-4-1106-preview",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
"removeAll": false,
|
|
36
|
+
"removed": [],
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
exports[`parseModelString > only add the model 1`] = `
|
|
41
|
+
{
|
|
42
|
+
"add": [
|
|
43
|
+
{
|
|
44
|
+
"displayName": undefined,
|
|
45
|
+
"id": "model1",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"displayName": undefined,
|
|
49
|
+
"id": "model2",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"displayName": undefined,
|
|
53
|
+
"id": "model3",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"displayName": undefined,
|
|
57
|
+
"id": "model4",
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
"removeAll": false,
|
|
61
|
+
"removed": [],
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { parseModelString } from './parseModels';
|
|
4
|
+
|
|
5
|
+
describe('parseModelString', () => {
|
|
6
|
+
it('custom deletion, addition, and renaming of models', () => {
|
|
7
|
+
const result = parseModelString(
|
|
8
|
+
'-all,+llama,+claude-2,-gpt-3.5-turbo,gpt-4-1106-preview=gpt-4-turbo,gpt-4-1106-preview=gpt-4-32k',
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
expect(result).toMatchSnapshot();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('duplicate naming model', () => {
|
|
15
|
+
const result = parseModelString('gpt-4-1106-preview=gpt-4-turbo,gpt-4-1106-preview=gpt-4-32k');
|
|
16
|
+
expect(result).toMatchSnapshot();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('only add the model', () => {
|
|
20
|
+
const result = parseModelString('model1,model2,model3,model4');
|
|
21
|
+
|
|
22
|
+
expect(result).toMatchSnapshot();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { CustomModels } from '@/types/settings';
|
|
2
|
+
|
|
3
|
+
export const parseModelString = (modelString: string = '') => {
|
|
4
|
+
let models: CustomModels = [];
|
|
5
|
+
let removeAll = false;
|
|
6
|
+
const removedModels: string[] = [];
|
|
7
|
+
const modelNames = modelString.split(/[,,]/).filter(Boolean);
|
|
8
|
+
|
|
9
|
+
for (const item of modelNames) {
|
|
10
|
+
const disable = item.startsWith('-');
|
|
11
|
+
const nameConfig = item.startsWith('+') || item.startsWith('-') ? item.slice(1) : item;
|
|
12
|
+
const [id, displayName] = nameConfig.split('=');
|
|
13
|
+
|
|
14
|
+
if (disable) {
|
|
15
|
+
// Disable all models.
|
|
16
|
+
if (id === 'all') {
|
|
17
|
+
removeAll = true;
|
|
18
|
+
}
|
|
19
|
+
removedModels.push(id);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Remove duplicate model entries.
|
|
24
|
+
const existingIndex = models.findIndex(({ id: n }) => n === id);
|
|
25
|
+
if (existingIndex !== -1) {
|
|
26
|
+
models.splice(existingIndex, 1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
models.push({ displayName, id: id });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
add: models,
|
|
34
|
+
removeAll,
|
|
35
|
+
removed: removedModels,
|
|
36
|
+
};
|
|
37
|
+
};
|