@lobehub/chat 0.160.7 → 0.161.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/locales/ar/setting.json +9 -0
- package/locales/bg-BG/setting.json +9 -0
- package/locales/de-DE/setting.json +9 -0
- package/locales/en-US/setting.json +9 -0
- package/locales/es-ES/setting.json +9 -0
- package/locales/fr-FR/setting.json +9 -0
- package/locales/it-IT/setting.json +9 -0
- package/locales/ja-JP/setting.json +9 -0
- package/locales/ko-KR/setting.json +9 -0
- package/locales/nl-NL/setting.json +9 -0
- package/locales/pl-PL/setting.json +30 -20
- package/locales/pt-BR/setting.json +9 -0
- package/locales/ru-RU/setting.json +29 -20
- package/locales/tr-TR/setting.json +29 -20
- package/locales/vi-VN/setting.json +9 -0
- package/locales/zh-CN/setting.json +9 -0
- package/locales/zh-TW/setting.json +9 -0
- package/package.json +1 -1
- package/src/app/(main)/settings/common/page.tsx +1 -0
- package/src/app/(main)/settings/hooks/useCategory.tsx +49 -12
- package/src/app/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +1 -0
- package/src/app/(main)/settings/llm/components/ProviderModelList/index.tsx +8 -1
- package/src/app/(main)/settings/system-agent/features/Translation.tsx +60 -0
- package/src/app/(main)/settings/system-agent/index.tsx +9 -0
- package/src/app/(main)/settings/system-agent/page.tsx +14 -0
- package/src/app/@modal/(.)settings/modal/index.tsx +5 -0
- package/src/components/ModelSelect/index.tsx +13 -5
- package/src/const/settings/agent.ts +36 -0
- package/src/const/settings/common.ts +8 -0
- package/src/const/settings/index.ts +15 -172
- package/src/const/settings/llm.ts +110 -0
- package/src/const/settings/sync.ts +5 -0
- package/src/const/settings/systemAgent.ts +12 -0
- package/src/const/settings/tool.ts +5 -0
- package/src/const/settings/tts.ts +10 -0
- package/src/features/AgentSetting/AgentMeta/index.tsx +1 -1
- package/src/features/AgentSetting/AgentModal/ModelSelect.tsx +4 -52
- package/src/features/ModelSelect/index.tsx +67 -0
- package/src/features/PluginStore/index.tsx +1 -1
- package/src/locales/default/setting.ts +16 -7
- package/src/store/chat/slices/enchance/action.ts +9 -2
- package/src/store/global/initialState.ts +1 -0
- package/src/store/user/selectors.ts +1 -0
- package/src/store/user/slices/settings/actions/general.test.ts +22 -0
- package/src/store/user/slices/settings/actions/general.ts +11 -0
- package/src/store/user/slices/settings/selectors/index.ts +1 -0
- package/src/store/user/slices/settings/selectors/settings.ts +10 -1
- package/src/store/user/slices/settings/selectors/systemAgent.ts +14 -0
- package/src/types/settings/index.ts +3 -0
- package/src/types/settings/systemAgent.ts +8 -0
|
@@ -1,65 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createStyles } from 'antd-style';
|
|
3
|
-
import isEqual from 'fast-deep-equal';
|
|
4
|
-
import { memo, useMemo } from 'react';
|
|
1
|
+
import { memo } from 'react';
|
|
5
2
|
|
|
6
|
-
import
|
|
7
|
-
import { useUserStore } from '@/store/user';
|
|
8
|
-
import { modelProviderSelectors } from '@/store/user/selectors';
|
|
9
|
-
import { ModelProviderCard } from '@/types/llm';
|
|
3
|
+
import Select from '@/features/ModelSelect';
|
|
10
4
|
|
|
11
5
|
import { useStore } from '../store';
|
|
12
6
|
|
|
13
|
-
const useStyles = createStyles(({ css, prefixCls }) => ({
|
|
14
|
-
select: css`
|
|
15
|
-
.${prefixCls}-select-dropdown .${prefixCls}-select-item-option-grouped {
|
|
16
|
-
padding-inline-start: 12px;
|
|
17
|
-
}
|
|
18
|
-
`,
|
|
19
|
-
}));
|
|
20
|
-
interface ModelOption {
|
|
21
|
-
label: any;
|
|
22
|
-
provider: string;
|
|
23
|
-
value: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
7
|
const ModelSelect = memo(() => {
|
|
27
8
|
const [model, updateConfig] = useStore((s) => [s.config.model, s.setAgentConfig]);
|
|
28
|
-
const enabledList = useUserStore(modelProviderSelectors.modelProviderListForModelSelect, isEqual);
|
|
29
|
-
|
|
30
|
-
const { styles } = useStyles();
|
|
31
|
-
|
|
32
|
-
const options = useMemo<SelectProps['options']>(() => {
|
|
33
|
-
const getChatModels = (provider: ModelProviderCard) =>
|
|
34
|
-
provider.chatModels.map((model) => ({
|
|
35
|
-
label: <ModelItemRender {...model} />,
|
|
36
|
-
provider: provider.id,
|
|
37
|
-
value: model.id,
|
|
38
|
-
}));
|
|
39
|
-
|
|
40
|
-
if (enabledList.length === 1) {
|
|
41
|
-
const provider = enabledList[0];
|
|
42
|
-
|
|
43
|
-
return getChatModels(provider);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return enabledList.map((provider) => ({
|
|
47
|
-
label: <ProviderItemRender provider={provider.id} />,
|
|
48
|
-
options: getChatModels(provider),
|
|
49
|
-
}));
|
|
50
|
-
}, [enabledList]);
|
|
51
9
|
|
|
52
10
|
return (
|
|
53
11
|
<Select
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
updateConfig({
|
|
57
|
-
model,
|
|
58
|
-
provider: (option as unknown as ModelOption).provider,
|
|
59
|
-
});
|
|
12
|
+
onChange={(props) => {
|
|
13
|
+
updateConfig(props);
|
|
60
14
|
}}
|
|
61
|
-
options={options}
|
|
62
|
-
popupMatchSelectWidth={false}
|
|
63
15
|
value={model}
|
|
64
16
|
/>
|
|
65
17
|
);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Select, SelectProps } from 'antd';
|
|
2
|
+
import { createStyles } from 'antd-style';
|
|
3
|
+
import isEqual from 'fast-deep-equal';
|
|
4
|
+
import { memo, useMemo } from 'react';
|
|
5
|
+
|
|
6
|
+
import { ModelItemRender, ProviderItemRender } from '@/components/ModelSelect';
|
|
7
|
+
import { useUserStore } from '@/store/user';
|
|
8
|
+
import { modelProviderSelectors } from '@/store/user/selectors';
|
|
9
|
+
import { ModelProviderCard } from '@/types/llm';
|
|
10
|
+
|
|
11
|
+
const useStyles = createStyles(({ css, prefixCls }) => ({
|
|
12
|
+
select: css`
|
|
13
|
+
.${prefixCls}-select-dropdown .${prefixCls}-select-item-option-grouped {
|
|
14
|
+
padding-inline-start: 12px;
|
|
15
|
+
}
|
|
16
|
+
`,
|
|
17
|
+
}));
|
|
18
|
+
interface ModelOption {
|
|
19
|
+
label: any;
|
|
20
|
+
provider: string;
|
|
21
|
+
value: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface ModelSelectProps {
|
|
25
|
+
onChange?: (props: { model: string; provider: string }) => void;
|
|
26
|
+
value?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const ModelSelect = memo<ModelSelectProps>(({ value, onChange }) => {
|
|
30
|
+
const enabledList = useUserStore(modelProviderSelectors.modelProviderListForModelSelect, isEqual);
|
|
31
|
+
|
|
32
|
+
const { styles } = useStyles();
|
|
33
|
+
|
|
34
|
+
const options = useMemo<SelectProps['options']>(() => {
|
|
35
|
+
const getChatModels = (provider: ModelProviderCard) =>
|
|
36
|
+
provider.chatModels.map((model) => ({
|
|
37
|
+
label: <ModelItemRender {...model} />,
|
|
38
|
+
provider: provider.id,
|
|
39
|
+
value: model.id,
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
if (enabledList.length === 1) {
|
|
43
|
+
const provider = enabledList[0];
|
|
44
|
+
|
|
45
|
+
return getChatModels(provider);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return enabledList.map((provider) => ({
|
|
49
|
+
label: <ProviderItemRender provider={provider.id} />,
|
|
50
|
+
options: getChatModels(provider),
|
|
51
|
+
}));
|
|
52
|
+
}, [enabledList]);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Select
|
|
56
|
+
className={styles.select}
|
|
57
|
+
onChange={(model, option) => {
|
|
58
|
+
onChange?.({ model, provider: (option as unknown as ModelOption).provider });
|
|
59
|
+
}}
|
|
60
|
+
options={options}
|
|
61
|
+
popupMatchSelectWidth={false}
|
|
62
|
+
value={value}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
export default ModelSelect;
|
|
@@ -363,14 +363,23 @@ export default {
|
|
|
363
363
|
title: 'WebRTC 同步',
|
|
364
364
|
},
|
|
365
365
|
},
|
|
366
|
+
systemAgent: {
|
|
367
|
+
title: '系统助手',
|
|
368
|
+
translation: {
|
|
369
|
+
label: '翻译模型',
|
|
370
|
+
modelDesc: '指定用于翻译的模型',
|
|
371
|
+
title: '翻译助手设置',
|
|
372
|
+
},
|
|
373
|
+
},
|
|
366
374
|
tab: {
|
|
367
|
-
about: '关于',
|
|
368
|
-
agent: '默认助手',
|
|
369
|
-
common: '通用设置',
|
|
370
|
-
experiment: '实验',
|
|
371
|
-
llm: '语言模型',
|
|
372
|
-
sync: '云端同步',
|
|
373
|
-
|
|
375
|
+
'about': '关于',
|
|
376
|
+
'agent': '默认助手',
|
|
377
|
+
'common': '通用设置',
|
|
378
|
+
'experiment': '实验',
|
|
379
|
+
'llm': '语言模型',
|
|
380
|
+
'sync': '云端同步',
|
|
381
|
+
'system-agent': '系统助手',
|
|
382
|
+
'tts': '语音服务',
|
|
374
383
|
},
|
|
375
384
|
tools: {
|
|
376
385
|
builtins: {
|
|
@@ -9,7 +9,10 @@ import { chatService } from '@/services/chat';
|
|
|
9
9
|
import { messageService } from '@/services/message';
|
|
10
10
|
import { chatSelectors } from '@/store/chat/selectors';
|
|
11
11
|
import { ChatStore } from '@/store/chat/store';
|
|
12
|
+
import { useUserStore } from '@/store/user';
|
|
13
|
+
import { systemAgentSelectors } from '@/store/user/selectors';
|
|
12
14
|
import { ChatTTS, ChatTranslate } from '@/types/message';
|
|
15
|
+
import { merge } from '@/utils/merge';
|
|
13
16
|
import { setNamespace } from '@/utils/storeDebug';
|
|
14
17
|
|
|
15
18
|
const n = setNamespace('enhance');
|
|
@@ -48,12 +51,16 @@ export const chatEnhance: StateCreator<
|
|
|
48
51
|
topicId: get().activeTopicId,
|
|
49
52
|
...data,
|
|
50
53
|
}),
|
|
54
|
+
|
|
51
55
|
translateMessage: async (id, targetLang) => {
|
|
52
56
|
const { internal_toggleChatLoading, updateMessageTranslate, internal_dispatchMessage } = get();
|
|
53
57
|
|
|
54
58
|
const message = chatSelectors.getMessageById(id)(get());
|
|
55
59
|
if (!message) return;
|
|
56
60
|
|
|
61
|
+
// Get current agent for translation
|
|
62
|
+
const translationSetting = systemAgentSelectors.translation(useUserStore.getState());
|
|
63
|
+
|
|
57
64
|
// create translate extra
|
|
58
65
|
await updateMessageTranslate(id, { content: '', from: '', to: targetLang });
|
|
59
66
|
|
|
@@ -69,7 +76,7 @@ export const chatEnhance: StateCreator<
|
|
|
69
76
|
|
|
70
77
|
await updateMessageTranslate(id, { content, from, to: targetLang });
|
|
71
78
|
},
|
|
72
|
-
params: chainLangDetect(message.content),
|
|
79
|
+
params: merge(translationSetting, chainLangDetect(message.content)),
|
|
73
80
|
trace: get().getCurrentTracePayload({ traceName: TraceNameMap.LanguageDetect }),
|
|
74
81
|
});
|
|
75
82
|
|
|
@@ -95,7 +102,7 @@ export const chatEnhance: StateCreator<
|
|
|
95
102
|
}
|
|
96
103
|
}
|
|
97
104
|
},
|
|
98
|
-
params: chainTranslate(message.content, targetLang),
|
|
105
|
+
params: merge(translationSetting, chainTranslate(message.content, targetLang)),
|
|
99
106
|
trace: get().getCurrentTracePayload({ traceName: TraceNameMap.Translator }),
|
|
100
107
|
});
|
|
101
108
|
},
|
|
@@ -112,4 +112,26 @@ describe('SettingsAction', () => {
|
|
|
112
112
|
expect(userService.updateUserSettings).toHaveBeenCalledWith({ defaultAgent: updatedAgent });
|
|
113
113
|
});
|
|
114
114
|
});
|
|
115
|
+
|
|
116
|
+
describe('setTranslationSystemAgent', () => {
|
|
117
|
+
it('should set partial settings', async () => {
|
|
118
|
+
const { result } = renderHook(() => useUserStore());
|
|
119
|
+
const systemAgentSettings: Partial<GlobalSettings> = {
|
|
120
|
+
systemAgent: {
|
|
121
|
+
translation: {
|
|
122
|
+
model: 'testmodel',
|
|
123
|
+
provider: 'provider',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Perform the action
|
|
129
|
+
await act(async () => {
|
|
130
|
+
await result.current.setTranslationSystemAgent('provider', 'testmodel');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Assert that updateUserSettings was called with the correct settings
|
|
134
|
+
expect(userService.updateUserSettings).toHaveBeenCalledWith(systemAgentSettings);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
115
137
|
});
|
|
@@ -16,6 +16,7 @@ export interface GeneralSettingsAction {
|
|
|
16
16
|
importAppSettings: (settings: GlobalSettings) => Promise<void>;
|
|
17
17
|
resetSettings: () => Promise<void>;
|
|
18
18
|
setSettings: (settings: DeepPartial<GlobalSettings>) => Promise<void>;
|
|
19
|
+
setTranslationSystemAgent: (provider: string, model: string) => Promise<void>;
|
|
19
20
|
switchLocale: (locale: LocaleMode) => Promise<void>;
|
|
20
21
|
switchThemeMode: (themeMode: ThemeMode) => Promise<void>;
|
|
21
22
|
updateDefaultAgent: (agent: DeepPartial<LobeAgentSettings>) => Promise<void>;
|
|
@@ -50,6 +51,16 @@ export const generalSettingsSlice: StateCreator<
|
|
|
50
51
|
await userService.updateUserSettings(diffs);
|
|
51
52
|
await get().refreshUserConfig();
|
|
52
53
|
},
|
|
54
|
+
setTranslationSystemAgent: async (provider, model) => {
|
|
55
|
+
await get().setSettings({
|
|
56
|
+
systemAgent: {
|
|
57
|
+
translation: {
|
|
58
|
+
model: model,
|
|
59
|
+
provider: provider,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
},
|
|
53
64
|
switchLocale: async (locale) => {
|
|
54
65
|
await get().setSettings({ language: locale });
|
|
55
66
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { DEFAULT_LANG } from '@/const/locale';
|
|
2
2
|
import { DEFAULT_AGENT_META } from '@/const/meta';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_AGENT,
|
|
5
|
+
DEFAULT_AGENT_CONFIG,
|
|
6
|
+
DEFAULT_SYSTEM_AGENT_CONFIG,
|
|
7
|
+
DEFAULT_TTS_CONFIG,
|
|
8
|
+
} from '@/const/settings';
|
|
4
9
|
import { Locales } from '@/locales/resources';
|
|
5
10
|
import { GeneralModelProviderConfig, GlobalLLMProviderKey, GlobalSettings } from '@/types/settings';
|
|
6
11
|
import { isOnServerSide } from '@/utils/env';
|
|
@@ -53,9 +58,13 @@ export const currentThemeMode = (s: UserStore) => {
|
|
|
53
58
|
const dalleConfig = (s: UserStore) => currentSettings(s).tool?.dalle || {};
|
|
54
59
|
const isDalleAutoGenerating = (s: UserStore) => currentSettings(s).tool?.dalle?.autoGenerate;
|
|
55
60
|
|
|
61
|
+
const currentSystemAgent = (s: UserStore) =>
|
|
62
|
+
merge(DEFAULT_SYSTEM_AGENT_CONFIG, currentSettings(s).systemAgent);
|
|
63
|
+
|
|
56
64
|
export const settingsSelectors = {
|
|
57
65
|
currentLanguage,
|
|
58
66
|
currentSettings,
|
|
67
|
+
currentSystemAgent,
|
|
59
68
|
currentTTS,
|
|
60
69
|
currentThemeMode,
|
|
61
70
|
dalleConfig,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_AGENT_CONFIG } from '@/const/settings';
|
|
2
|
+
import type { UserStore } from '@/store/user';
|
|
3
|
+
import { merge } from '@/utils/merge';
|
|
4
|
+
|
|
5
|
+
import { currentSettings } from './settings';
|
|
6
|
+
|
|
7
|
+
const currentSystemAgent = (s: UserStore) =>
|
|
8
|
+
merge(DEFAULT_SYSTEM_AGENT_CONFIG, currentSettings(s).systemAgent);
|
|
9
|
+
|
|
10
|
+
const translation = (s: UserStore) => currentSystemAgent(s).translation;
|
|
11
|
+
|
|
12
|
+
export const systemAgentSelectors = {
|
|
13
|
+
translation,
|
|
14
|
+
};
|
|
@@ -3,6 +3,7 @@ import type { LobeAgentSession } from '@/types/session';
|
|
|
3
3
|
import { GlobalBaseSettings } from './base';
|
|
4
4
|
import { GlobalLLMConfig } from './modelProvider';
|
|
5
5
|
import { GlobalSyncSettings } from './sync';
|
|
6
|
+
import { GlobalSystemAgentConfig } from './systemAgent';
|
|
6
7
|
import { GlobalTTSConfig } from './tts';
|
|
7
8
|
|
|
8
9
|
export type GlobalDefaultAgent = Pick<LobeAgentSession, 'config' | 'meta'>;
|
|
@@ -10,6 +11,7 @@ export type GlobalDefaultAgent = Pick<LobeAgentSession, 'config' | 'meta'>;
|
|
|
10
11
|
export * from './base';
|
|
11
12
|
export * from './modelProvider';
|
|
12
13
|
export * from './sync';
|
|
14
|
+
export * from './systemAgent';
|
|
13
15
|
export * from './tts';
|
|
14
16
|
|
|
15
17
|
export interface GlobalTool {
|
|
@@ -25,6 +27,7 @@ export interface GlobalSettings extends GlobalBaseSettings {
|
|
|
25
27
|
defaultAgent: GlobalDefaultAgent;
|
|
26
28
|
languageModel: GlobalLLMConfig;
|
|
27
29
|
sync: GlobalSyncSettings;
|
|
30
|
+
systemAgent: GlobalSystemAgentConfig;
|
|
28
31
|
tool: GlobalTool;
|
|
29
32
|
tts: GlobalTTSConfig;
|
|
30
33
|
}
|