@lobehub/chat 0.147.9 → 0.147.10
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 +17 -0
- package/package.json +1 -1
- package/src/config/modelProviders/index.ts +18 -0
- package/src/features/AgentSetting/AgentConfig/ModelSelect.tsx +1 -0
- package/src/store/global/slices/common/action.ts +9 -0
- package/src/store/global/slices/settings/actions/llm.test.ts +91 -5
- package/src/store/global/slices/settings/actions/llm.ts +96 -0
- package/src/store/global/slices/settings/initialState.ts +6 -0
- package/src/store/global/slices/settings/selectors/modelProvider.test.ts +1 -65
- package/src/store/global/slices/settings/selectors/modelProvider.ts +11 -78
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.147.10](https://github.com/lobehub/lobe-chat/compare/v0.147.9...v0.147.10)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2024-04-13**</sup>
|
|
8
|
+
|
|
9
|
+
<br/>
|
|
10
|
+
|
|
11
|
+
<details>
|
|
12
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
13
|
+
|
|
14
|
+
</details>
|
|
15
|
+
|
|
16
|
+
<div align="right">
|
|
17
|
+
|
|
18
|
+
[](#readme-top)
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
5
22
|
### [Version 0.147.9](https://github.com/lobehub/lobe-chat/compare/v0.147.8...v0.147.9)
|
|
6
23
|
|
|
7
24
|
<sup>Released on **2024-04-12**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.147.
|
|
3
|
+
"version": "0.147.10",
|
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ChatModelCard, ModelProviderCard } from '@/types/llm';
|
|
2
2
|
|
|
3
3
|
import AnthropicProvider from './anthropic';
|
|
4
|
+
import AzureProvider from './azure';
|
|
4
5
|
import BedrockProvider from './bedrock';
|
|
5
6
|
import GoogleProvider from './google';
|
|
6
7
|
import GroqProvider from './groq';
|
|
@@ -30,6 +31,23 @@ export const LOBE_DEFAULT_MODEL_LIST: ChatModelCard[] = [
|
|
|
30
31
|
ZeroOneProvider.chatModels,
|
|
31
32
|
].flat();
|
|
32
33
|
|
|
34
|
+
export const DEFAULT_MODEL_PROVIDER_LIST = [
|
|
35
|
+
OpenAIProvider,
|
|
36
|
+
{ ...AzureProvider, chatModels: [] },
|
|
37
|
+
OllamaProvider,
|
|
38
|
+
AnthropicProvider,
|
|
39
|
+
GoogleProvider,
|
|
40
|
+
OpenRouterProvider,
|
|
41
|
+
TogetherAIProvider,
|
|
42
|
+
BedrockProvider,
|
|
43
|
+
PerplexityProvider,
|
|
44
|
+
MistralProvider,
|
|
45
|
+
GroqProvider,
|
|
46
|
+
MoonshotProvider,
|
|
47
|
+
ZeroOneProvider,
|
|
48
|
+
ZhiPuProvider,
|
|
49
|
+
];
|
|
50
|
+
|
|
33
51
|
export const filterEnabledModels = (provider: ModelProviderCard) => {
|
|
34
52
|
return provider.chatModels.filter((v) => v.enabled).map((m) => m.id);
|
|
35
53
|
};
|
|
@@ -62,6 +62,9 @@ export const createCommonSlice: StateCreator<
|
|
|
62
62
|
|
|
63
63
|
refreshUserConfig: async () => {
|
|
64
64
|
await mutate([USER_CONFIG_FETCH_KEY, true]);
|
|
65
|
+
|
|
66
|
+
// when get the user config ,refresh the model provider list to the latest
|
|
67
|
+
get().refreshModelProviderList();
|
|
65
68
|
},
|
|
66
69
|
|
|
67
70
|
switchBackToChat: (sessionId) => {
|
|
@@ -159,7 +162,10 @@ export const createCommonSlice: StateCreator<
|
|
|
159
162
|
};
|
|
160
163
|
|
|
161
164
|
const defaultSettings = merge(get().defaultSettings, serverSettings);
|
|
165
|
+
|
|
162
166
|
set({ defaultSettings, serverConfig: data }, false, n('initGlobalConfig'));
|
|
167
|
+
|
|
168
|
+
get().refreshDefaultModelProviderList();
|
|
163
169
|
}
|
|
164
170
|
},
|
|
165
171
|
revalidateOnFocus: false,
|
|
@@ -181,6 +187,9 @@ export const createCommonSlice: StateCreator<
|
|
|
181
187
|
n('fetchUserConfig', data),
|
|
182
188
|
);
|
|
183
189
|
|
|
190
|
+
// when get the user config ,refresh the model provider list to the latest
|
|
191
|
+
get().refreshModelProviderList();
|
|
192
|
+
|
|
184
193
|
const { language } = settingsSelectors.currentSettings(get());
|
|
185
194
|
if (language === 'auto') {
|
|
186
195
|
switchLang('auto');
|
|
@@ -2,9 +2,18 @@ import { act, renderHook } from '@testing-library/react';
|
|
|
2
2
|
import { describe, expect, it, vi } from 'vitest';
|
|
3
3
|
|
|
4
4
|
import { userService } from '@/services/user';
|
|
5
|
-
import { useGlobalStore } from '@/store/global';
|
|
6
|
-
import {
|
|
5
|
+
import { GlobalStore, useGlobalStore } from '@/store/global';
|
|
6
|
+
import {
|
|
7
|
+
GlobalSettingsState,
|
|
8
|
+
initialSettingsState,
|
|
9
|
+
} from '@/store/global/slices/settings/initialState';
|
|
10
|
+
import {
|
|
11
|
+
modelConfigSelectors,
|
|
12
|
+
modelProviderSelectors,
|
|
13
|
+
settingsSelectors,
|
|
14
|
+
} from '@/store/global/slices/settings/selectors';
|
|
7
15
|
import { GeneralModelProviderConfig } from '@/types/settings';
|
|
16
|
+
import { merge } from '@/utils/merge';
|
|
8
17
|
|
|
9
18
|
import { CustomModelCardDispatch, customModelCardsReducer } from '../reducers/customModelCard';
|
|
10
19
|
|
|
@@ -15,9 +24,6 @@ vi.mock('@/services/user', () => ({
|
|
|
15
24
|
resetUserSettings: vi.fn(),
|
|
16
25
|
},
|
|
17
26
|
}));
|
|
18
|
-
vi.mock('../reducers/customModelCard', () => ({
|
|
19
|
-
customModelCardsReducer: vi.fn().mockReturnValue([]),
|
|
20
|
-
}));
|
|
21
27
|
|
|
22
28
|
describe('LLMSettingsSliceAction', () => {
|
|
23
29
|
describe('setModelProviderConfig', () => {
|
|
@@ -57,4 +63,84 @@ describe('LLMSettingsSliceAction', () => {
|
|
|
57
63
|
expect(result.current.setModelProviderConfig).not.toHaveBeenCalled();
|
|
58
64
|
});
|
|
59
65
|
});
|
|
66
|
+
|
|
67
|
+
describe('refreshDefaultModelProviderList', () => {
|
|
68
|
+
it('default', async () => {
|
|
69
|
+
const { result } = renderHook(() => useGlobalStore());
|
|
70
|
+
|
|
71
|
+
act(() => {
|
|
72
|
+
useGlobalStore.setState({
|
|
73
|
+
serverConfig: {
|
|
74
|
+
languageModel: {
|
|
75
|
+
azure: { serverModelCards: [{ id: 'abc', deploymentName: 'abc' }] },
|
|
76
|
+
},
|
|
77
|
+
telemetry: {},
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
act(() => {
|
|
83
|
+
result.current.refreshDefaultModelProviderList();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Assert that setModelProviderConfig was not called
|
|
87
|
+
const azure = result.current.defaultModelProviderList.find((m) => m.id === 'azure');
|
|
88
|
+
expect(azure?.chatModels).toEqual([{ id: 'abc', deploymentName: 'abc' }]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('refreshModelProviderList', () => {
|
|
93
|
+
it('visible', async () => {
|
|
94
|
+
const { result } = renderHook(() => useGlobalStore());
|
|
95
|
+
act(() => {
|
|
96
|
+
useGlobalStore.setState({
|
|
97
|
+
settings: {
|
|
98
|
+
languageModel: {
|
|
99
|
+
ollama: { enabledModels: ['llava'] },
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
act(() => {
|
|
106
|
+
result.current.refreshModelProviderList();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const ollamaList = result.current.modelProviderList.find((r) => r.id === 'ollama');
|
|
110
|
+
// Assert that setModelProviderConfig was not called
|
|
111
|
+
expect(ollamaList?.chatModels.find((c) => c.id === 'llava')).toEqual({
|
|
112
|
+
displayName: 'LLaVA 7B',
|
|
113
|
+
functionCall: false,
|
|
114
|
+
enabled: true,
|
|
115
|
+
id: 'llava',
|
|
116
|
+
tokens: 4000,
|
|
117
|
+
vision: true,
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('modelProviderListForModelSelect should return only enabled providers', () => {
|
|
122
|
+
const { result } = renderHook(() => useGlobalStore());
|
|
123
|
+
|
|
124
|
+
act(() => {
|
|
125
|
+
useGlobalStore.setState({
|
|
126
|
+
settings: {
|
|
127
|
+
languageModel: {
|
|
128
|
+
perplexity: { enabled: true },
|
|
129
|
+
azure: { enabled: false },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
act(() => {
|
|
136
|
+
result.current.refreshModelProviderList();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const enabledProviders = modelProviderSelectors.modelProviderListForModelSelect(
|
|
140
|
+
result.current,
|
|
141
|
+
);
|
|
142
|
+
expect(enabledProviders).toHaveLength(2);
|
|
143
|
+
expect(enabledProviders[1].id).toBe('perplexity');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
60
146
|
});
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import useSWR, { SWRResponse } from 'swr';
|
|
2
2
|
import type { StateCreator } from 'zustand/vanilla';
|
|
3
3
|
|
|
4
|
+
import {
|
|
5
|
+
AnthropicProviderCard,
|
|
6
|
+
AzureProviderCard,
|
|
7
|
+
BedrockProviderCard,
|
|
8
|
+
GoogleProviderCard,
|
|
9
|
+
GroqProviderCard,
|
|
10
|
+
MistralProviderCard,
|
|
11
|
+
MoonshotProviderCard,
|
|
12
|
+
OllamaProviderCard,
|
|
13
|
+
OpenAIProviderCard,
|
|
14
|
+
OpenRouterProviderCard,
|
|
15
|
+
PerplexityProviderCard,
|
|
16
|
+
TogetherAIProviderCard,
|
|
17
|
+
ZeroOneProviderCard,
|
|
18
|
+
ZhiPuProviderCard,
|
|
19
|
+
} from '@/config/modelProviders';
|
|
4
20
|
import { GlobalStore } from '@/store/global';
|
|
5
21
|
import { ChatModelCard } from '@/types/llm';
|
|
6
22
|
import { GlobalLLMConfig, GlobalLLMProviderKey } from '@/types/settings';
|
|
7
23
|
|
|
8
24
|
import { CustomModelCardDispatch, customModelCardsReducer } from '../reducers/customModelCard';
|
|
25
|
+
import { modelProviderSelectors } from '../selectors/modelProvider';
|
|
9
26
|
import { settingsSelectors } from '../selectors/settings';
|
|
10
27
|
|
|
11
28
|
/**
|
|
@@ -16,12 +33,18 @@ export interface LLMSettingsAction {
|
|
|
16
33
|
provider: GlobalLLMProviderKey,
|
|
17
34
|
payload: CustomModelCardDispatch,
|
|
18
35
|
) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* make sure the default model provider list is sync to latest state
|
|
38
|
+
*/
|
|
39
|
+
refreshDefaultModelProviderList: () => void;
|
|
40
|
+
refreshModelProviderList: () => void;
|
|
19
41
|
removeEnabledModels: (provider: GlobalLLMProviderKey, model: string) => Promise<void>;
|
|
20
42
|
setModelProviderConfig: <T extends GlobalLLMProviderKey>(
|
|
21
43
|
provider: T,
|
|
22
44
|
config: Partial<GlobalLLMConfig[T]>,
|
|
23
45
|
) => Promise<void>;
|
|
24
46
|
toggleEditingCustomModelCard: (params?: { id: string; provider: GlobalLLMProviderKey }) => void;
|
|
47
|
+
|
|
25
48
|
toggleProviderEnabled: (provider: GlobalLLMProviderKey, enabled: boolean) => Promise<void>;
|
|
26
49
|
|
|
27
50
|
useFetchProviderModelList: (
|
|
@@ -46,6 +69,76 @@ export const llmSettingsSlice: StateCreator<
|
|
|
46
69
|
await get().setModelProviderConfig(provider, { customModelCards: nextState });
|
|
47
70
|
},
|
|
48
71
|
|
|
72
|
+
refreshDefaultModelProviderList: () => {
|
|
73
|
+
/**
|
|
74
|
+
* Because we have several model cards sources, we need to merge the model cards
|
|
75
|
+
* the priority is below:
|
|
76
|
+
* 1 - server side model cards
|
|
77
|
+
* 2 - remote model cards
|
|
78
|
+
* 3 - default model cards
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
82
|
+
const mergeModels = (provider: GlobalLLMProviderKey, defaultChatModels: ChatModelCard[]) => {
|
|
83
|
+
// if the chat model is config in the server side, use the server side model cards
|
|
84
|
+
const serverChatModels = modelProviderSelectors.serverProviderModelCards(provider)(get());
|
|
85
|
+
const remoteChatModels = modelProviderSelectors.remoteProviderModelCards(provider)(get());
|
|
86
|
+
|
|
87
|
+
return serverChatModels ?? remoteChatModels ?? defaultChatModels;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const defaultModelProviderList = [
|
|
91
|
+
{
|
|
92
|
+
...OpenAIProviderCard,
|
|
93
|
+
chatModels: mergeModels('openai', OpenAIProviderCard.chatModels),
|
|
94
|
+
},
|
|
95
|
+
{ ...AzureProviderCard, chatModels: mergeModels('azure', []) },
|
|
96
|
+
{ ...OllamaProviderCard, chatModels: mergeModels('ollama', OllamaProviderCard.chatModels) },
|
|
97
|
+
AnthropicProviderCard,
|
|
98
|
+
GoogleProviderCard,
|
|
99
|
+
{
|
|
100
|
+
...OpenRouterProviderCard,
|
|
101
|
+
chatModels: mergeModels('openrouter', OpenRouterProviderCard.chatModels),
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
...TogetherAIProviderCard,
|
|
105
|
+
chatModels: mergeModels('togetherai', TogetherAIProviderCard.chatModels),
|
|
106
|
+
},
|
|
107
|
+
BedrockProviderCard,
|
|
108
|
+
PerplexityProviderCard,
|
|
109
|
+
MistralProviderCard,
|
|
110
|
+
GroqProviderCard,
|
|
111
|
+
MoonshotProviderCard,
|
|
112
|
+
ZeroOneProviderCard,
|
|
113
|
+
ZhiPuProviderCard,
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
set({ defaultModelProviderList }, false, 'refreshDefaultModelProviderList');
|
|
117
|
+
|
|
118
|
+
get().refreshModelProviderList();
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
refreshModelProviderList: () => {
|
|
122
|
+
const modelProviderList = get().defaultModelProviderList.map((list) => ({
|
|
123
|
+
...list,
|
|
124
|
+
chatModels: modelProviderSelectors
|
|
125
|
+
.getModelCardsById(list.id)(get())
|
|
126
|
+
?.map((model) => {
|
|
127
|
+
const models = modelProviderSelectors.getEnableModelsById(list.id)(get());
|
|
128
|
+
|
|
129
|
+
if (!models) return model;
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
...model,
|
|
133
|
+
enabled: models?.some((m) => m === model.id),
|
|
134
|
+
};
|
|
135
|
+
}),
|
|
136
|
+
enabled: modelProviderSelectors.isProviderEnabled(list.id as any)(get()),
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
set({ modelProviderList }, false, 'refreshModelProviderList');
|
|
140
|
+
},
|
|
141
|
+
|
|
49
142
|
removeEnabledModels: async (provider, model) => {
|
|
50
143
|
const config = settingsSelectors.providerConfig(provider)(get());
|
|
51
144
|
|
|
@@ -60,6 +153,7 @@ export const llmSettingsSlice: StateCreator<
|
|
|
60
153
|
toggleEditingCustomModelCard: (params) => {
|
|
61
154
|
set({ editingCustomCardModel: params }, false, 'toggleEditingCustomModelCard');
|
|
62
155
|
},
|
|
156
|
+
|
|
63
157
|
toggleProviderEnabled: async (provider, enabled) => {
|
|
64
158
|
await get().setSettings({ languageModel: { [provider]: { enabled } } });
|
|
65
159
|
},
|
|
@@ -79,6 +173,8 @@ export const llmSettingsSlice: StateCreator<
|
|
|
79
173
|
latestFetchTime: Date.now(),
|
|
80
174
|
remoteModelCards: data,
|
|
81
175
|
});
|
|
176
|
+
|
|
177
|
+
get().refreshDefaultModelProviderList();
|
|
82
178
|
}
|
|
83
179
|
},
|
|
84
180
|
revalidateOnFocus: false,
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { DeepPartial } from 'utility-types';
|
|
2
2
|
|
|
3
|
+
import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
|
|
3
4
|
import { DEFAULT_SETTINGS } from '@/const/settings';
|
|
5
|
+
import { ModelProviderCard } from '@/types/llm';
|
|
4
6
|
import { GlobalServerConfig } from '@/types/serverConfig';
|
|
5
7
|
import { GlobalSettings } from '@/types/settings';
|
|
6
8
|
|
|
7
9
|
export interface GlobalSettingsState {
|
|
8
10
|
avatar?: string;
|
|
11
|
+
defaultModelProviderList: ModelProviderCard[];
|
|
9
12
|
defaultSettings: GlobalSettings;
|
|
10
13
|
editingCustomCardModel?: { id: string; provider: string } | undefined;
|
|
14
|
+
modelProviderList: ModelProviderCard[];
|
|
11
15
|
serverConfig: GlobalServerConfig;
|
|
12
16
|
settings: DeepPartial<GlobalSettings>;
|
|
13
17
|
userId?: string;
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
export const initialSettingsState: GlobalSettingsState = {
|
|
21
|
+
defaultModelProviderList: DEFAULT_MODEL_PROVIDER_LIST,
|
|
17
22
|
defaultSettings: DEFAULT_SETTINGS,
|
|
23
|
+
modelProviderList: DEFAULT_MODEL_PROVIDER_LIST,
|
|
18
24
|
serverConfig: {
|
|
19
25
|
telemetry: {},
|
|
20
26
|
},
|
|
@@ -7,71 +7,7 @@ import { GlobalSettingsState, initialSettingsState } from '../initialState';
|
|
|
7
7
|
import { getDefaultModeProviderById, modelProviderSelectors } from './modelProvider';
|
|
8
8
|
|
|
9
9
|
describe('modelProviderSelectors', () => {
|
|
10
|
-
describe('
|
|
11
|
-
it('visible', () => {
|
|
12
|
-
const s = merge(initialSettingsState, {
|
|
13
|
-
settings: {
|
|
14
|
-
languageModel: {
|
|
15
|
-
ollama: {
|
|
16
|
-
enabledModels: ['llava'],
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
} as GlobalSettingsState) as unknown as GlobalStore;
|
|
21
|
-
|
|
22
|
-
const ollamaList = modelProviderSelectors.modelProviderList(s).find((r) => r.id === 'ollama');
|
|
23
|
-
|
|
24
|
-
expect(ollamaList?.chatModels.find((c) => c.id === 'llava')).toEqual({
|
|
25
|
-
displayName: 'LLaVA 7B',
|
|
26
|
-
functionCall: false,
|
|
27
|
-
enabled: true,
|
|
28
|
-
id: 'llava',
|
|
29
|
-
tokens: 4000,
|
|
30
|
-
vision: true,
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
it('with user custom models', () => {
|
|
34
|
-
const s = merge(initialSettingsState, {
|
|
35
|
-
settings: {
|
|
36
|
-
languageModel: {
|
|
37
|
-
perplexity: {
|
|
38
|
-
customModelCards: [{ id: 'sonar-online', displayName: 'Sonar Online' }],
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
} as GlobalSettingsState) as unknown as GlobalStore;
|
|
43
|
-
|
|
44
|
-
const providerList = modelProviderSelectors
|
|
45
|
-
.modelProviderList(s)
|
|
46
|
-
.find((r) => r.id === 'perplexity');
|
|
47
|
-
|
|
48
|
-
expect(providerList?.chatModels.find((c) => c.id === 'sonar-online')).toEqual({
|
|
49
|
-
id: 'sonar-online',
|
|
50
|
-
displayName: 'Sonar Online',
|
|
51
|
-
enabled: false,
|
|
52
|
-
isCustom: true,
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe('providerListForModelSelect', () => {
|
|
58
|
-
it('should return only enabled providers', () => {
|
|
59
|
-
const s = merge(initialSettingsState, {
|
|
60
|
-
settings: {
|
|
61
|
-
languageModel: {
|
|
62
|
-
perplexity: { enabled: true },
|
|
63
|
-
azure: { enabled: false },
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
} as GlobalSettingsState) as unknown as GlobalStore;
|
|
67
|
-
|
|
68
|
-
const enabledProviders = modelProviderSelectors.modelProviderListForModelSelect(s);
|
|
69
|
-
expect(enabledProviders).toHaveLength(2);
|
|
70
|
-
expect(enabledProviders[1].id).toBe('perplexity');
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe('providerCard', () => {
|
|
10
|
+
describe('getDefaultModeProviderById', () => {
|
|
75
11
|
it('should return the correct ModelProviderCard when provider ID matches', () => {
|
|
76
12
|
const s = merge(initialSettingsState, {}) as unknown as GlobalStore;
|
|
77
13
|
|
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
import { uniqBy } from 'lodash-es';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
AnthropicProviderCard,
|
|
5
|
-
AzureProviderCard,
|
|
6
|
-
BedrockProviderCard,
|
|
7
|
-
GoogleProviderCard,
|
|
8
|
-
GroqProviderCard,
|
|
9
|
-
MistralProviderCard,
|
|
10
|
-
MoonshotProviderCard,
|
|
11
|
-
OllamaProviderCard,
|
|
12
|
-
OpenAIProviderCard,
|
|
13
|
-
OpenRouterProviderCard,
|
|
14
|
-
PerplexityProviderCard,
|
|
15
|
-
TogetherAIProviderCard,
|
|
16
|
-
ZeroOneProviderCard,
|
|
17
|
-
ZhiPuProviderCard,
|
|
18
|
-
filterEnabledModels,
|
|
19
|
-
} from '@/config/modelProviders';
|
|
3
|
+
import { filterEnabledModels } from '@/config/modelProviders';
|
|
20
4
|
import { ChatModelCard, ModelProviderCard } from '@/types/llm';
|
|
21
5
|
import { ServerModelProviderConfig } from '@/types/serverConfig';
|
|
22
6
|
import { GlobalLLMProviderKey } from '@/types/settings';
|
|
@@ -59,49 +43,8 @@ const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: GlobalStore) =
|
|
|
59
43
|
/**
|
|
60
44
|
* define all the model list of providers
|
|
61
45
|
*/
|
|
62
|
-
const defaultModelProviderList = (s: GlobalStore): ModelProviderCard[] =>
|
|
63
|
-
|
|
64
|
-
* Because we have several model cards sources, we need to merge the model cards
|
|
65
|
-
* the priority is below:
|
|
66
|
-
* 1 - server side model cards
|
|
67
|
-
* 2 - remote model cards
|
|
68
|
-
* 3 - default model cards
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
const mergeModels = (provider: GlobalLLMProviderKey, defaultChatModels: ChatModelCard[]) => {
|
|
72
|
-
// if the chat model is config in the server side, use the server side model cards
|
|
73
|
-
const serverChatModels = serverProviderModelCards(provider)(s);
|
|
74
|
-
const remoteChatModels = remoteProviderModelCards(provider)(s);
|
|
75
|
-
|
|
76
|
-
return serverChatModels ?? remoteChatModels ?? defaultChatModels;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
return [
|
|
80
|
-
{
|
|
81
|
-
...OpenAIProviderCard,
|
|
82
|
-
chatModels: mergeModels('openai', OpenAIProviderCard.chatModels),
|
|
83
|
-
},
|
|
84
|
-
{ ...AzureProviderCard, chatModels: mergeModels('azure', []) },
|
|
85
|
-
{ ...OllamaProviderCard, chatModels: mergeModels('ollama', OllamaProviderCard.chatModels) },
|
|
86
|
-
AnthropicProviderCard,
|
|
87
|
-
GoogleProviderCard,
|
|
88
|
-
{
|
|
89
|
-
...OpenRouterProviderCard,
|
|
90
|
-
chatModels: mergeModels('openrouter', OpenRouterProviderCard.chatModels),
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
...TogetherAIProviderCard,
|
|
94
|
-
chatModels: mergeModels('togetherai', TogetherAIProviderCard.chatModels),
|
|
95
|
-
},
|
|
96
|
-
BedrockProviderCard,
|
|
97
|
-
PerplexityProviderCard,
|
|
98
|
-
MistralProviderCard,
|
|
99
|
-
GroqProviderCard,
|
|
100
|
-
MoonshotProviderCard,
|
|
101
|
-
ZeroOneProviderCard,
|
|
102
|
-
ZhiPuProviderCard,
|
|
103
|
-
];
|
|
104
|
-
};
|
|
46
|
+
const defaultModelProviderList = (s: GlobalStore): ModelProviderCard[] =>
|
|
47
|
+
s.defaultModelProviderList;
|
|
105
48
|
|
|
106
49
|
export const getDefaultModeProviderById = (provider: string) => (s: GlobalStore) =>
|
|
107
50
|
defaultModelProviderList(s).find((s) => s.id === provider);
|
|
@@ -146,21 +89,7 @@ const getEnableModelsById = (provider: string) => (s: GlobalStore) => {
|
|
|
146
89
|
return getProviderConfigById(provider)(s)?.enabledModels?.filter(Boolean);
|
|
147
90
|
};
|
|
148
91
|
|
|
149
|
-
const modelProviderList = (s: GlobalStore): ModelProviderCard[] =>
|
|
150
|
-
defaultModelProviderList(s).map((list) => ({
|
|
151
|
-
...list,
|
|
152
|
-
chatModels: getModelCardsById(list.id)(s)?.map((model) => {
|
|
153
|
-
const models = getEnableModelsById(list.id)(s);
|
|
154
|
-
|
|
155
|
-
if (!models) return model;
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
...model,
|
|
159
|
-
enabled: models?.some((m) => m === model.id),
|
|
160
|
-
};
|
|
161
|
-
}),
|
|
162
|
-
enabled: isProviderEnabled(list.id as any)(s),
|
|
163
|
-
}));
|
|
92
|
+
const modelProviderList = (s: GlobalStore): ModelProviderCard[] => s.modelProviderList;
|
|
164
93
|
|
|
165
94
|
const modelProviderListForModelSelect = (s: GlobalStore): ModelProviderCard[] =>
|
|
166
95
|
modelProviderList(s)
|
|
@@ -196,22 +125,26 @@ const modelMaxToken = (id: string) => (s: GlobalStore) => getModelCardById(id)(s
|
|
|
196
125
|
|
|
197
126
|
export const modelProviderSelectors = {
|
|
198
127
|
defaultModelProviderList,
|
|
199
|
-
|
|
200
128
|
getDefaultEnabledModelsById,
|
|
201
129
|
getDefaultModelCardById,
|
|
202
130
|
|
|
203
131
|
getEnableModelsById,
|
|
204
132
|
getModelCardById,
|
|
205
|
-
getModelCardsById,
|
|
206
133
|
|
|
134
|
+
getModelCardsById,
|
|
207
135
|
isModelEnabledFiles,
|
|
208
136
|
isModelEnabledFunctionCall,
|
|
209
137
|
isModelEnabledUpload,
|
|
210
138
|
isModelEnabledVision,
|
|
211
139
|
isModelHasMaxToken,
|
|
212
140
|
|
|
213
|
-
|
|
141
|
+
isProviderEnabled,
|
|
214
142
|
|
|
143
|
+
modelMaxToken,
|
|
215
144
|
modelProviderList,
|
|
145
|
+
|
|
216
146
|
modelProviderListForModelSelect,
|
|
147
|
+
|
|
148
|
+
remoteProviderModelCards,
|
|
149
|
+
serverProviderModelCards,
|
|
217
150
|
};
|