@lobehub/chat 0.122.9 → 0.123.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/.env.example +22 -2
- package/.eslintrc.js +1 -0
- package/CHANGELOG.md +25 -0
- package/README.md +11 -9
- package/README.zh-CN.md +11 -9
- 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 -1
- 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/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 +102 -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 +11 -4
- 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 +32 -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 +242 -78
- package/src/store/global/slices/settings/selectors/__snapshots__/selectors.test.ts.snap +2 -0
- package/src/store/global/slices/settings/selectors/modelProvider.test.ts +171 -47
- package/src/store/global/slices/settings/selectors/modelProvider.ts +136 -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 +27 -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,28 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { DEFAULT_SETTINGS } from '@/const/settings';
|
|
4
|
+
import { agentSelectors } from '@/store/session/slices/agent';
|
|
5
|
+
import { merge } from '@/utils/merge';
|
|
6
|
+
|
|
7
|
+
import { GlobalStore, useGlobalStore } from '../../../store';
|
|
8
|
+
import { initialSettingsState } from '../initialState';
|
|
2
9
|
import { modelProviderSelectors } from './modelProvider';
|
|
3
10
|
|
|
4
11
|
describe('modelProviderSelectors', () => {
|
|
5
12
|
describe('CUSTOM_MODELS', () => {
|
|
6
13
|
it('custom deletion, addition, and renaming of models', () => {
|
|
7
|
-
const s = {
|
|
14
|
+
const s = merge(initialSettingsState, {
|
|
8
15
|
serverConfig: {
|
|
9
16
|
customModelName:
|
|
10
17
|
'-all,+llama,+claude-2,-gpt-3.5-turbo,gpt-4-0125-preview=gpt-4-turbo,gpt-4-0125-preview=gpt-4-32k',
|
|
11
18
|
},
|
|
12
|
-
|
|
13
|
-
languageModel: {
|
|
14
|
-
openAI: {},
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
} as unknown as GlobalStore;
|
|
19
|
+
}) as unknown as GlobalStore;
|
|
18
20
|
|
|
19
|
-
const result = modelProviderSelectors.
|
|
21
|
+
const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
|
|
20
22
|
|
|
21
23
|
expect(result).toMatchSnapshot();
|
|
22
24
|
});
|
|
23
25
|
|
|
24
26
|
it('duplicate naming model', () => {
|
|
25
|
-
const s = {
|
|
27
|
+
const s = merge(initialSettingsState, {
|
|
26
28
|
serverConfig: {},
|
|
27
29
|
settings: {
|
|
28
30
|
languageModel: {
|
|
@@ -31,57 +33,138 @@ describe('modelProviderSelectors', () => {
|
|
|
31
33
|
},
|
|
32
34
|
},
|
|
33
35
|
},
|
|
34
|
-
} as unknown as GlobalStore;
|
|
36
|
+
}) as unknown as GlobalStore;
|
|
35
37
|
|
|
36
|
-
const result = modelProviderSelectors.
|
|
38
|
+
const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
|
|
37
39
|
|
|
38
40
|
expect(result).toMatchSnapshot();
|
|
39
41
|
});
|
|
40
42
|
|
|
41
43
|
it('should delete model', () => {
|
|
42
|
-
const s = {
|
|
43
|
-
serverConfig: {
|
|
44
|
-
|
|
44
|
+
const s = merge(initialSettingsState, {
|
|
45
|
+
serverConfig: { customModelName: '-gpt-4' },
|
|
46
|
+
}) as unknown as GlobalStore;
|
|
47
|
+
|
|
48
|
+
const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
|
|
49
|
+
|
|
50
|
+
expect(result).toEqual([
|
|
51
|
+
{
|
|
52
|
+
chatModels: [
|
|
53
|
+
{
|
|
54
|
+
description: 'GPT 3.5 Turbo,适用于各种文本生成和理解任务',
|
|
55
|
+
displayName: 'GPT-3.5 Turbo',
|
|
56
|
+
functionCall: true,
|
|
57
|
+
id: 'gpt-3.5-turbo',
|
|
58
|
+
tokens: 4096,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
displayName: 'GPT-3.5 Turbo (0125)',
|
|
62
|
+
functionCall: true,
|
|
63
|
+
id: 'gpt-3.5-turbo-0125',
|
|
64
|
+
tokens: 16385,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
displayName: 'GPT-3.5 Turbo (1106)',
|
|
68
|
+
functionCall: true,
|
|
69
|
+
hidden: true,
|
|
70
|
+
id: 'gpt-3.5-turbo-1106',
|
|
71
|
+
tokens: 16385,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
hidden: true,
|
|
75
|
+
id: 'gpt-3.5-turbo-instruct',
|
|
76
|
+
tokens: 4096,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
hidden: true,
|
|
80
|
+
id: 'gpt-3.5-turbo-16k',
|
|
81
|
+
tokens: 16385,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
hidden: true,
|
|
85
|
+
id: 'gpt-3.5-turbo-0613',
|
|
86
|
+
legacy: true,
|
|
87
|
+
tokens: 4096,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
hidden: true,
|
|
91
|
+
id: 'gpt-3.5-turbo-16k-0613',
|
|
92
|
+
legacy: true,
|
|
93
|
+
tokens: 4096,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
displayName: 'GPT-4 Turbo Preview',
|
|
97
|
+
functionCall: true,
|
|
98
|
+
id: 'gpt-4-turbo-preview',
|
|
99
|
+
tokens: 128000,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
displayName: 'GPT-4 Turbo Preview (0125)',
|
|
103
|
+
functionCall: true,
|
|
104
|
+
id: 'gpt-4-0125-preview',
|
|
105
|
+
tokens: 128000,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
description: 'GPT-4 视觉预览版,支持视觉任务',
|
|
109
|
+
displayName: 'GPT-4 Turbo Vision (Preview)',
|
|
110
|
+
id: 'gpt-4-vision-preview',
|
|
111
|
+
tokens: 128000,
|
|
112
|
+
vision: true,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
functionCall: true,
|
|
116
|
+
hidden: true,
|
|
117
|
+
id: 'gpt-4-1106-preview',
|
|
118
|
+
tokens: 128000,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
functionCall: true,
|
|
122
|
+
hidden: true,
|
|
123
|
+
id: 'gpt-4-0613',
|
|
124
|
+
tokens: 8192,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
functionCall: true,
|
|
128
|
+
hidden: true,
|
|
129
|
+
id: 'gpt-4-32k',
|
|
130
|
+
tokens: 32768,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
functionCall: true,
|
|
134
|
+
hidden: true,
|
|
135
|
+
id: 'gpt-4-32k-0613',
|
|
136
|
+
tokens: 32768,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
enabled: true,
|
|
140
|
+
id: 'openai',
|
|
45
141
|
},
|
|
142
|
+
]);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('show the hidden model', () => {
|
|
146
|
+
const s = merge(initialSettingsState, {
|
|
147
|
+
serverConfig: {},
|
|
46
148
|
settings: {
|
|
47
149
|
languageModel: {
|
|
48
|
-
openAI: {
|
|
150
|
+
openAI: {
|
|
151
|
+
customModelName: '+gpt-4-1106-preview',
|
|
152
|
+
},
|
|
49
153
|
},
|
|
50
154
|
},
|
|
51
|
-
} as unknown as GlobalStore;
|
|
155
|
+
}) as unknown as GlobalStore;
|
|
52
156
|
|
|
53
|
-
const result = modelProviderSelectors.
|
|
157
|
+
const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
|
|
54
158
|
|
|
55
|
-
expect(result).toEqual(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
displayName: 'gpt-3.5-turbo-1106',
|
|
62
|
-
name: 'gpt-3.5-turbo-1106',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
displayName: 'gpt-3.5-turbo-16k',
|
|
66
|
-
name: 'gpt-3.5-turbo-16k',
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
displayName: 'gpt-4-32k',
|
|
70
|
-
name: 'gpt-4-32k',
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
displayName: 'gpt-4-0125-preview',
|
|
74
|
-
name: 'gpt-4-0125-preview',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
displayName: 'gpt-4-vision-preview',
|
|
78
|
-
name: 'gpt-4-vision-preview',
|
|
79
|
-
},
|
|
80
|
-
]);
|
|
159
|
+
expect(result[0].chatModels.find((o) => o.id === 'gpt-4-1106-preview')).toEqual({
|
|
160
|
+
functionCall: true,
|
|
161
|
+
id: 'gpt-4-1106-preview',
|
|
162
|
+
tokens: 128000,
|
|
163
|
+
});
|
|
81
164
|
});
|
|
82
165
|
|
|
83
166
|
it('only add the model', () => {
|
|
84
|
-
const s = {
|
|
167
|
+
const s = merge(initialSettingsState, {
|
|
85
168
|
serverConfig: {},
|
|
86
169
|
settings: {
|
|
87
170
|
languageModel: {
|
|
@@ -90,11 +173,52 @@ describe('modelProviderSelectors', () => {
|
|
|
90
173
|
},
|
|
91
174
|
},
|
|
92
175
|
},
|
|
93
|
-
} as unknown as GlobalStore;
|
|
176
|
+
}) as unknown as GlobalStore;
|
|
94
177
|
|
|
95
|
-
const result = modelProviderSelectors.
|
|
178
|
+
const result = modelProviderSelectors.modelSelectList(s).filter((r) => r.enabled);
|
|
96
179
|
|
|
97
180
|
expect(result).toMatchSnapshot();
|
|
98
181
|
});
|
|
99
182
|
});
|
|
183
|
+
|
|
184
|
+
describe('modelEnabledVision', () => {
|
|
185
|
+
it('should return true if the model has vision ability', () => {
|
|
186
|
+
const hasAbility = modelProviderSelectors.modelEnabledVision('gpt-4-vision-preview')(
|
|
187
|
+
useGlobalStore.getState(),
|
|
188
|
+
);
|
|
189
|
+
expect(hasAbility).toBeTruthy();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('should return false if the model does not have vision ability', () => {
|
|
193
|
+
const hasAbility = modelProviderSelectors.modelEnabledVision('some-other-model')(
|
|
194
|
+
useGlobalStore.getState(),
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
expect(hasAbility).toBeFalsy();
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should return false if the model include vision in id', () => {
|
|
201
|
+
const hasAbility = modelProviderSelectors.modelEnabledVision('some-other-model-vision')(
|
|
202
|
+
useGlobalStore.getState(),
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
expect(hasAbility).toBeTruthy();
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe('modelEnabledVision', () => {
|
|
210
|
+
it('should return true if the model is in the list of models that show tokens', () => {
|
|
211
|
+
const show = modelProviderSelectors.modelHasMaxToken('gpt-3.5-turbo')(
|
|
212
|
+
useGlobalStore.getState(),
|
|
213
|
+
);
|
|
214
|
+
expect(show).toBeTruthy();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should return false if the model is not in the list of models that show tokens', () => {
|
|
218
|
+
const show = modelProviderSelectors.modelHasMaxToken('some-other-model')(
|
|
219
|
+
useGlobalStore.getState(),
|
|
220
|
+
);
|
|
221
|
+
expect(show).toBe(false);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
100
224
|
});
|
|
@@ -1,64 +1,157 @@
|
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
const enableAzure = (s: GlobalStore) => modelProvider(s).openAI.useAzure;
|
|
34
|
+
const azureConfig = (s: GlobalStore) => modelProvider(s).azure;
|
|
35
|
+
|
|
36
|
+
// const azureModelList = (s: GlobalStore): ModelProviderCard => {
|
|
37
|
+
// const azure = azureConfig(s);
|
|
38
|
+
// return {
|
|
39
|
+
// chatModels: parseModelString(azure.deployments),
|
|
40
|
+
// id: 'azure',
|
|
41
|
+
// };
|
|
42
|
+
// };
|
|
43
|
+
|
|
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
|
+
}
|
|
28
52
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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);
|
|
33
58
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
displayName: displayName || name,
|
|
51
|
-
name,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
95
|
+
const modelConfig = parseModelString(string);
|
|
54
96
|
|
|
55
|
-
|
|
97
|
+
const chatModels = processChatModels(modelConfig);
|
|
98
|
+
|
|
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 modelHasMaxToken = (id: string) => (s: GlobalStore) =>
|
|
126
|
+
typeof modelCardById(id)(s)?.tokens !== 'undefined';
|
|
127
|
+
|
|
128
|
+
const modelMaxToken = (id: string) => (s: GlobalStore) => modelCardById(id)(s)?.tokens || 0;
|
|
129
|
+
|
|
130
|
+
/* eslint-disable sort-keys-fix/sort-keys-fix, */
|
|
58
131
|
export const modelProviderSelectors = {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
132
|
+
modelSelectList,
|
|
133
|
+
|
|
134
|
+
modelCardById,
|
|
135
|
+
modelMaxToken,
|
|
136
|
+
modelEnabledFunctionCall,
|
|
137
|
+
modelEnabledVision,
|
|
138
|
+
modelHasMaxToken,
|
|
139
|
+
// OpenAI
|
|
62
140
|
openAIConfig,
|
|
63
|
-
|
|
141
|
+
openAIAPIKey,
|
|
142
|
+
openAIProxyUrl,
|
|
143
|
+
// Azure OpenAI
|
|
144
|
+
enableAzure,
|
|
145
|
+
azureConfig,
|
|
146
|
+
// Zhipu
|
|
147
|
+
enableZhipu,
|
|
148
|
+
zhipuAPIKey,
|
|
149
|
+
zhipuProxyUrl,
|
|
150
|
+
// Google
|
|
151
|
+
enableGoogle,
|
|
152
|
+
googleAPIKey,
|
|
153
|
+
googleProxyUrl,
|
|
154
|
+
// Bedrock
|
|
155
|
+
enableBedrock,
|
|
156
|
+
bedrockConfig,
|
|
64
157
|
};
|
|
@@ -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,33 @@ 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
|
+
* 是否支持 Function Call
|
|
25
|
+
*/
|
|
26
|
+
functionCall?: boolean;
|
|
27
|
+
hidden?: boolean;
|
|
28
|
+
id: string;
|
|
29
|
+
/**
|
|
30
|
+
* user defined model
|
|
31
|
+
*/
|
|
32
|
+
isCustom?: boolean;
|
|
33
|
+
legacy?: boolean;
|
|
34
|
+
tokens?: number;
|
|
35
|
+
/**
|
|
36
|
+
* 是否支持视觉识别
|
|
37
|
+
*/
|
|
38
|
+
vision?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ModelProviderCard {
|
|
42
|
+
chatModels: ChatModelCard[];
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
id: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
20
47
|
// 语言模型的设置参数
|
|
21
48
|
export interface LLMParams {
|
|
22
49
|
/**
|