@lobehub/chat 0.33.0 → 0.35.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 +53 -0
- package/locales/en_US/common.json +11 -1
- package/locales/en_US/error.json +26 -0
- package/locales/en_US/plugin.json +20 -1
- package/locales/en_US/setting.json +6 -1
- package/locales/zh_CN/common.json +10 -0
- package/locales/zh_CN/error.json +26 -0
- package/locales/zh_CN/plugin.json +20 -2
- package/locales/zh_CN/setting.json +8 -3
- package/package.json +2 -2
- package/src/components/EmojiPicker/index.tsx +48 -0
- package/src/components/EmojiPicker/style.ts +28 -0
- package/src/const/meta.ts +3 -0
- package/src/const/settings.ts +50 -0
- package/src/{pages/chat/[id]/edit → features/AgentSetting}/AgentConfig/index.tsx +13 -11
- package/src/{pages/chat/[id]/edit → features/AgentSetting}/AgentMeta/AutoGenerateInput.tsx +16 -14
- package/src/features/AgentSetting/AgentMeta/BackgroundSwatches.tsx +27 -0
- package/src/features/AgentSetting/AgentMeta/index.tsx +128 -0
- package/src/{pages/chat/[id]/edit → features/AgentSetting}/AgentPlugin/index.tsx +12 -12
- package/src/{pages/chat/[id]/edit → features/AgentSetting}/AgentPrompt/index.tsx +13 -16
- package/src/features/AgentSetting/index.ts +4 -0
- package/src/features/AgentSetting/test.json +40 -0
- package/src/features/SideBar/{BottomAction.tsx → BottomActions.tsx} +15 -5
- package/src/features/SideBar/TopActions.tsx +42 -0
- package/src/features/SideBar/index.tsx +5 -30
- package/src/hooks/useImportConfig.ts +3 -3
- package/src/locales/default/common.ts +4 -0
- package/src/locales/default/setting.ts +4 -0
- package/src/pages/chat/[id]/Conversation/ChatList/index.tsx +1 -1
- package/src/pages/chat/[id]/Conversation/Input/Action.tsx +1 -1
- package/src/pages/chat/[id]/Header.tsx +1 -1
- package/src/pages/chat/[id]/{Config/SideBar.tsx → Sidebar/Inner.tsx} +2 -2
- package/src/pages/chat/[id]/{Config → Sidebar}/Topic/TopicContent.tsx +4 -6
- package/src/pages/chat/[id]/{Config → Sidebar}/index.tsx +2 -2
- package/src/pages/chat/[id]/index.page.tsx +1 -1
- package/src/pages/chat/[id]/{edit → setting}/index.page.tsx +23 -9
- package/src/pages/settings/Settings/Agent.tsx +25 -0
- package/src/pages/{setting/SettingForm.tsx → settings/Settings/Common.tsx} +7 -113
- package/src/pages/settings/Settings/index.tsx +50 -0
- package/src/pages/{setting → settings}/index.page.tsx +2 -2
- package/src/pages/{setting → settings}/layout.tsx +1 -1
- package/src/plugins/searchEngine/Render.tsx +3 -1
- package/src/store/session/slices/agentConfig/action.ts +8 -1
- package/src/store/session/slices/agentConfig/initialState.ts +2 -13
- package/src/store/session/slices/agentConfig/selectors.ts +13 -9
- package/src/store/session/slices/chat/actions/message.ts +12 -5
- package/src/store/session/slices/chat/actions/topic.ts +4 -2
- package/src/store/session/slices/chat/selectors/chat.ts +1 -1
- package/src/store/session/slices/session/action.ts +23 -16
- package/src/store/session/slices/session/initialState.ts +2 -1
- package/src/store/settings/action.ts +82 -11
- package/src/store/settings/initialState.ts +4 -27
- package/src/store/settings/selectors.ts +12 -7
- package/src/store/settings/store.ts +2 -2
- package/src/types/settings.ts +16 -8
- package/src/utils/storeDebug.ts +11 -0
- package/src/pages/chat/[id]/edit/AgentMeta/BackgroundSwatches.tsx +0 -31
- package/src/pages/chat/[id]/edit/AgentMeta/EmojiPicker.tsx +0 -78
- package/src/pages/chat/[id]/edit/AgentMeta/index.tsx +0 -111
- /package/src/pages/chat/[id]/{Config → Sidebar}/Header.tsx +0 -0
- /package/src/pages/chat/[id]/{Config → Sidebar}/Topic/DefaultContent.tsx +0 -0
- /package/src/pages/chat/[id]/{Config → Sidebar}/Topic/TopicItem.tsx +0 -0
- /package/src/pages/chat/[id]/{Config → Sidebar}/Topic/index.tsx +0 -0
- /package/src/pages/chat/[id]/{edit → setting}/Header.tsx +0 -0
- /package/src/pages/{setting → settings}/Header.tsx +0 -0
- /package/src/pages/{setting → settings}/ThemeSwatches/ThemeSwatchesNeutral.tsx +0 -0
- /package/src/pages/{setting → settings}/ThemeSwatches/ThemeSwatchesPrimary.tsx +0 -0
- /package/src/pages/{setting → settings}/ThemeSwatches/index.ts +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import isEqual from 'fast-deep-equal';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { shallow } from 'zustand/shallow';
|
|
4
|
+
|
|
5
|
+
import { AgentConfig, AgentMeta, AgentPlugin, AgentPrompt } from '@/features/AgentSetting';
|
|
6
|
+
import { settingsSelectors, useSettings } from '@/store/settings';
|
|
7
|
+
|
|
8
|
+
const Agent = memo(() => {
|
|
9
|
+
const config = useSettings(settingsSelectors.currentAgentConfig, isEqual);
|
|
10
|
+
const meta = useSettings(settingsSelectors.currentAgentMeta, isEqual);
|
|
11
|
+
const [setAgentConfig, setAgentMeta, toggleAgentPlugin] = useSettings(
|
|
12
|
+
(s) => [s.setAgentConfig, s.setAgentMeta, s.toggleAgentPlugin],
|
|
13
|
+
shallow,
|
|
14
|
+
);
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<AgentPrompt config={config} updateConfig={setAgentConfig} />
|
|
18
|
+
<AgentMeta config={config} meta={meta} updateMeta={setAgentMeta} />
|
|
19
|
+
<AgentConfig config={config} updateConfig={setAgentConfig} />
|
|
20
|
+
<AgentPlugin config={config} updateConfig={toggleAgentPlugin} />
|
|
21
|
+
</>
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export default Agent;
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { Form, type ItemGroup, ThemeSwitch } from '@lobehub/ui';
|
|
2
|
-
import { Form as AntForm, App, Button, Input, Select
|
|
2
|
+
import { Form as AntForm, App, Button, Input, Select } from 'antd';
|
|
3
3
|
import isEqual from 'fast-deep-equal';
|
|
4
4
|
import { debounce } from 'lodash-es';
|
|
5
|
-
import { AppWindow,
|
|
5
|
+
import { AppWindow, Palette, Webhook } from 'lucide-react';
|
|
6
6
|
import { memo, useCallback, useMemo } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import SliderWithInput from 'src/components/SliderWithInput';
|
|
9
9
|
import { shallow } from 'zustand/shallow';
|
|
10
10
|
|
|
11
11
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
12
|
+
import { DEFAULT_SETTINGS } from '@/const/settings';
|
|
12
13
|
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
13
14
|
import { options } from '@/locales/options';
|
|
14
15
|
import { useSessionStore } from '@/store/session';
|
|
15
16
|
import { settingsSelectors, useSettings } from '@/store/settings';
|
|
16
|
-
import { DEFAULT_SETTINGS } from '@/store/settings/initialState';
|
|
17
|
-
import { LanguageModel } from '@/types/llm';
|
|
18
17
|
import { ConfigKeys } from '@/types/settings';
|
|
19
18
|
|
|
20
|
-
import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from '
|
|
19
|
+
import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from '../ThemeSwatches';
|
|
21
20
|
|
|
22
21
|
type SettingItemGroup = ItemGroup & {
|
|
23
22
|
children: {
|
|
@@ -25,7 +24,7 @@ type SettingItemGroup = ItemGroup & {
|
|
|
25
24
|
}[];
|
|
26
25
|
};
|
|
27
26
|
|
|
28
|
-
const
|
|
27
|
+
const Common = memo(() => {
|
|
29
28
|
const { t } = useTranslation('setting');
|
|
30
29
|
const [form] = AntForm.useForm();
|
|
31
30
|
const clearSessions = useSessionStore((s) => s.clearSessions);
|
|
@@ -147,111 +146,6 @@ const SettingForm = memo(() => {
|
|
|
147
146
|
[settings],
|
|
148
147
|
);
|
|
149
148
|
|
|
150
|
-
const chat: SettingItemGroup = useMemo(
|
|
151
|
-
() => ({
|
|
152
|
-
children: [
|
|
153
|
-
{
|
|
154
|
-
children: <Switch />,
|
|
155
|
-
label: t('settingChat.enableHistoryCount.title'),
|
|
156
|
-
minWidth: undefined,
|
|
157
|
-
name: 'enableHistoryCount',
|
|
158
|
-
valuePropName: 'checked',
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
children: <SliderWithInput max={32} min={0} />,
|
|
162
|
-
desc: t('settingChat.historyCount.desc'),
|
|
163
|
-
hidden: !settings.enableHistoryCount,
|
|
164
|
-
label: t('settingChat.historyCount.title'),
|
|
165
|
-
name: 'historyCount',
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
children: <Switch />,
|
|
169
|
-
label: t('settingChat.enableCompressThreshold.title'),
|
|
170
|
-
minWidth: undefined,
|
|
171
|
-
name: 'enableCompressThreshold',
|
|
172
|
-
valuePropName: 'checked',
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
children: <SliderWithInput max={32} min={0} />,
|
|
176
|
-
desc: t('settingChat.compressThreshold.desc'),
|
|
177
|
-
hidden: !settings.enableCompressThreshold,
|
|
178
|
-
label: t('settingChat.compressThreshold.title'),
|
|
179
|
-
name: 'compressThreshold',
|
|
180
|
-
},
|
|
181
|
-
],
|
|
182
|
-
icon: MessagesSquare,
|
|
183
|
-
title: t('settingChat.title'),
|
|
184
|
-
}),
|
|
185
|
-
[settings],
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
const model: SettingItemGroup = useMemo(
|
|
189
|
-
() => ({
|
|
190
|
-
children: [
|
|
191
|
-
{
|
|
192
|
-
children: (
|
|
193
|
-
<Select
|
|
194
|
-
options={Object.values(LanguageModel).map((value) => ({
|
|
195
|
-
label: value,
|
|
196
|
-
value,
|
|
197
|
-
}))}
|
|
198
|
-
/>
|
|
199
|
-
),
|
|
200
|
-
desc: t('settingModel.model.desc'),
|
|
201
|
-
label: t('settingModel.model.title'),
|
|
202
|
-
name: 'model',
|
|
203
|
-
tag: 'model',
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
children: <SliderWithInput max={1} min={0} step={0.1} />,
|
|
207
|
-
desc: t('settingModel.temperature.desc'),
|
|
208
|
-
label: t('settingModel.temperature.title'),
|
|
209
|
-
name: 'temperature',
|
|
210
|
-
tag: 'temperature',
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
children: <SliderWithInput max={1} min={0} step={0.1} />,
|
|
214
|
-
desc: t('settingModel.topP.desc'),
|
|
215
|
-
label: t('settingModel.topP.title'),
|
|
216
|
-
name: 'topP',
|
|
217
|
-
tag: 'top_p',
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
children: <SliderWithInput max={2} min={-2} step={0.1} />,
|
|
221
|
-
desc: t('settingModel.presencePenalty.desc'),
|
|
222
|
-
label: t('settingModel.presencePenalty.title'),
|
|
223
|
-
name: 'presencePenalty',
|
|
224
|
-
tag: 'presence_penalty',
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
children: <SliderWithInput max={2} min={-2} step={0.1} />,
|
|
228
|
-
desc: t('settingModel.frequencyPenalty.desc'),
|
|
229
|
-
label: t('settingModel.frequencyPenalty.title'),
|
|
230
|
-
name: 'frequencyPenalty',
|
|
231
|
-
tag: 'frequency_penalty',
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
children: <Switch />,
|
|
235
|
-
label: t('settingModel.enableMaxTokens.title'),
|
|
236
|
-
minWidth: undefined,
|
|
237
|
-
name: 'enableMaxTokens',
|
|
238
|
-
valuePropName: 'checked',
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
children: <SliderWithInput max={32_000} min={0} step={100} />,
|
|
242
|
-
desc: t('settingModel.maxTokens.desc'),
|
|
243
|
-
hidden: !settings.enableMaxTokens,
|
|
244
|
-
label: t('settingModel.maxTokens.title'),
|
|
245
|
-
name: 'maxTokens',
|
|
246
|
-
tag: 'max_tokens',
|
|
247
|
-
},
|
|
248
|
-
],
|
|
249
|
-
icon: BrainCog,
|
|
250
|
-
title: t('settingModel.title'),
|
|
251
|
-
}),
|
|
252
|
-
[settings],
|
|
253
|
-
);
|
|
254
|
-
|
|
255
149
|
const system: SettingItemGroup = useMemo(
|
|
256
150
|
() => ({
|
|
257
151
|
children: [
|
|
@@ -288,7 +182,7 @@ const SettingForm = memo(() => {
|
|
|
288
182
|
[settings],
|
|
289
183
|
);
|
|
290
184
|
|
|
291
|
-
const items = useMemo(() => [theme, openAI,
|
|
185
|
+
const items = useMemo(() => [theme, openAI, system], [settings]);
|
|
292
186
|
|
|
293
187
|
return (
|
|
294
188
|
<Form
|
|
@@ -301,4 +195,4 @@ const SettingForm = memo(() => {
|
|
|
301
195
|
);
|
|
302
196
|
});
|
|
303
197
|
|
|
304
|
-
export default
|
|
198
|
+
export default Common;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Segmented } from 'antd';
|
|
2
|
+
import { createStyles } from 'antd-style';
|
|
3
|
+
import { memo, useState } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { Center } from 'react-layout-kit';
|
|
6
|
+
|
|
7
|
+
import Agent from './Agent';
|
|
8
|
+
import Common from './Common';
|
|
9
|
+
|
|
10
|
+
const useStyles = createStyles(({ css, token }) => ({
|
|
11
|
+
tabs: css`
|
|
12
|
+
padding: 4px;
|
|
13
|
+
border: 1px solid ${token.colorBorderSecondary};
|
|
14
|
+
border-radius: ${token.borderRadiusLG}px;
|
|
15
|
+
|
|
16
|
+
&:hover {
|
|
17
|
+
border-color: ${token.colorBorder};
|
|
18
|
+
}
|
|
19
|
+
`,
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
enum Tabs {
|
|
23
|
+
common,
|
|
24
|
+
agent,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const Settings = memo(() => {
|
|
28
|
+
const [tab, setTab] = useState<Tabs>(Tabs.common);
|
|
29
|
+
const { styles } = useStyles();
|
|
30
|
+
const { t } = useTranslation('setting');
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Center gap={16} width={'100%'}>
|
|
34
|
+
<div className={styles.tabs}>
|
|
35
|
+
<Segmented
|
|
36
|
+
onChange={(e) => setTab(e as Tabs)}
|
|
37
|
+
options={[
|
|
38
|
+
{ label: t('tab.common'), value: Tabs.common },
|
|
39
|
+
{ label: t('tab.agent'), value: Tabs.agent },
|
|
40
|
+
]}
|
|
41
|
+
value={tab}
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
{tab === Tabs.common && <Common />}
|
|
45
|
+
{tab === Tabs.agent && <Agent />}
|
|
46
|
+
</Center>
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export default Settings;
|
|
@@ -4,7 +4,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
4
4
|
import HeaderSpacing from '@/components/HeaderSpacing';
|
|
5
5
|
|
|
6
6
|
import Header from './Header';
|
|
7
|
-
import
|
|
7
|
+
import Settings from './Settings';
|
|
8
8
|
import SettingLayout from './layout';
|
|
9
9
|
|
|
10
10
|
const Setting = memo(() => {
|
|
@@ -13,7 +13,7 @@ const Setting = memo(() => {
|
|
|
13
13
|
<Header />
|
|
14
14
|
<Flexbox align={'center'} flex={1} padding={24} style={{ overflow: 'auto' }}>
|
|
15
15
|
<HeaderSpacing />
|
|
16
|
-
<
|
|
16
|
+
<Settings />
|
|
17
17
|
</Flexbox>
|
|
18
18
|
</SettingLayout>
|
|
19
19
|
);
|
|
@@ -21,7 +21,7 @@ const SettingLayout = memo<{ children: ReactNode }>(({ children }) => {
|
|
|
21
21
|
useEffect(() => {
|
|
22
22
|
const hasRehydrated = useSettings.persist.hasHydrated();
|
|
23
23
|
if (hasRehydrated) {
|
|
24
|
-
useSettings.setState({ sidebarKey: '
|
|
24
|
+
useSettings.setState({ sidebarKey: 'settings' });
|
|
25
25
|
}
|
|
26
26
|
}, []);
|
|
27
27
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createStyles } from 'antd-style';
|
|
2
|
+
import Image from 'next/image';
|
|
2
3
|
import Link from 'next/link';
|
|
3
4
|
import { memo } from 'react';
|
|
4
5
|
import { Flexbox } from 'react-layout-kit';
|
|
@@ -59,11 +60,12 @@ const Render = memo<PluginRenderProps<Result>>(({ content }) => {
|
|
|
59
60
|
<Flexbox>
|
|
60
61
|
<Flexbox align={'center'} gap={12} horizontal>
|
|
61
62
|
{item.favicon && (
|
|
62
|
-
<
|
|
63
|
+
<Image
|
|
63
64
|
alt={item.title || item.link}
|
|
64
65
|
className={styles.favicon}
|
|
65
66
|
height={24}
|
|
66
67
|
src={item.favicon}
|
|
68
|
+
unoptimized
|
|
67
69
|
width={24}
|
|
68
70
|
/>
|
|
69
71
|
)}
|
|
@@ -6,9 +6,12 @@ import { SessionStore, sessionSelectors } from '@/store/session';
|
|
|
6
6
|
import { MetaData } from '@/types/meta';
|
|
7
7
|
import { LobeAgentConfig } from '@/types/session';
|
|
8
8
|
import { fetchPresetTaskResult } from '@/utils/fetch';
|
|
9
|
+
import { setNamespace } from '@/utils/storeDebug';
|
|
9
10
|
|
|
10
11
|
import { SessionLoadingState } from './initialState';
|
|
11
12
|
|
|
13
|
+
const t = setNamespace('agentConfig');
|
|
14
|
+
|
|
12
15
|
/**
|
|
13
16
|
* 代理行为接口
|
|
14
17
|
*/
|
|
@@ -234,6 +237,10 @@ export const createAgentSlice: StateCreator<
|
|
|
234
237
|
}
|
|
235
238
|
},
|
|
236
239
|
updateLoadingState: (key, value) => {
|
|
237
|
-
set(
|
|
240
|
+
set(
|
|
241
|
+
{ autocompleteLoading: { ...get().autocompleteLoading, [key]: value } },
|
|
242
|
+
false,
|
|
243
|
+
t('updateLoadingState', { key, value }),
|
|
244
|
+
);
|
|
238
245
|
},
|
|
239
246
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
|
2
2
|
import { MetaData } from '@/types/meta';
|
|
3
3
|
import { LobeAgentConfig } from '@/types/session';
|
|
4
4
|
|
|
@@ -8,18 +8,7 @@ export interface AgentConfigState {
|
|
|
8
8
|
autocompleteLoading: SessionLoadingState;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export const initialLobeAgentConfig: LobeAgentConfig =
|
|
12
|
-
displayMode: 'chat',
|
|
13
|
-
model: LanguageModel.GPT3_5,
|
|
14
|
-
params: {
|
|
15
|
-
frequency_penalty: 0,
|
|
16
|
-
presence_penalty: 0,
|
|
17
|
-
temperature: 0.6,
|
|
18
|
-
top_p: 1,
|
|
19
|
-
},
|
|
20
|
-
plugins: [],
|
|
21
|
-
systemRole: '',
|
|
22
|
-
};
|
|
11
|
+
export const initialLobeAgentConfig: LobeAgentConfig = DEFAULT_AGENT_CONFIG;
|
|
23
12
|
|
|
24
13
|
export const initialAgentConfigState: AgentConfigState = {
|
|
25
14
|
// // loading 中间态
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { t } from 'i18next';
|
|
2
|
+
import { defaults } from 'lodash-es';
|
|
2
3
|
|
|
3
4
|
import { DEFAULT_AVATAR, DEFAULT_BACKGROUND_COLOR } from '@/const/meta';
|
|
5
|
+
import { Autocomplete } from '@/features/AgentSetting/AgentMeta';
|
|
4
6
|
import { SessionStore } from '@/store/session';
|
|
5
7
|
import { LanguageModel } from '@/types/llm';
|
|
6
8
|
import { MetaData } from '@/types/meta';
|
|
7
|
-
import { LobeAgentConfig } from '@/types/session';
|
|
8
9
|
|
|
9
10
|
import { sessionSelectors } from '../session';
|
|
10
11
|
import { initialLobeAgentConfig } from './initialState';
|
|
@@ -15,6 +16,13 @@ const currentAgentMeta = (s: SessionStore): MetaData => {
|
|
|
15
16
|
return { avatar: DEFAULT_AVATAR, backgroundColor: DEFAULT_BACKGROUND_COLOR, ...session?.meta };
|
|
16
17
|
};
|
|
17
18
|
|
|
19
|
+
const currentAutocomplete = (s: SessionStore): Autocomplete => ({
|
|
20
|
+
autocompleteMeta: s.autocompleteMeta,
|
|
21
|
+
autocompleteSessionAgentMeta: s.autocompleteSessionAgentMeta,
|
|
22
|
+
id: s.activeId,
|
|
23
|
+
loading: s.autocompleteLoading,
|
|
24
|
+
});
|
|
25
|
+
|
|
18
26
|
const currentAgentTitle = (s: SessionStore) => currentAgentMeta(s)?.title || t('defaultSession');
|
|
19
27
|
|
|
20
28
|
const currentAgentDescription = (s: SessionStore) =>
|
|
@@ -34,15 +42,11 @@ const currentAgentAvatar = (s: SessionStore) => {
|
|
|
34
42
|
|
|
35
43
|
const currentAgentConfig = (s: SessionStore) => {
|
|
36
44
|
const session = sessionSelectors.currentSession(s);
|
|
37
|
-
return session?.config;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const currentAgentConfigSafe = (s: SessionStore): LobeAgentConfig => {
|
|
41
|
-
return currentAgentConfig(s) || initialLobeAgentConfig;
|
|
45
|
+
return defaults(session?.config, initialLobeAgentConfig);
|
|
42
46
|
};
|
|
43
47
|
|
|
44
48
|
const currentAgentSystemRole = (s: SessionStore) => {
|
|
45
|
-
return
|
|
49
|
+
return currentAgentConfig(s).systemRole;
|
|
46
50
|
};
|
|
47
51
|
|
|
48
52
|
const currentAgentModel = (s: SessionStore): LanguageModel => {
|
|
@@ -52,7 +56,7 @@ const currentAgentModel = (s: SessionStore): LanguageModel => {
|
|
|
52
56
|
};
|
|
53
57
|
|
|
54
58
|
const hasSystemRole = (s: SessionStore) => {
|
|
55
|
-
const config =
|
|
59
|
+
const config = currentAgentConfig(s);
|
|
56
60
|
|
|
57
61
|
return !!config.systemRole;
|
|
58
62
|
};
|
|
@@ -64,12 +68,12 @@ export const agentSelectors = {
|
|
|
64
68
|
currentAgentAvatar,
|
|
65
69
|
currentAgentBackgroundColor,
|
|
66
70
|
currentAgentConfig,
|
|
67
|
-
currentAgentConfigSafe,
|
|
68
71
|
currentAgentDescription,
|
|
69
72
|
currentAgentMeta,
|
|
70
73
|
currentAgentModel,
|
|
71
74
|
currentAgentSystemRole,
|
|
72
75
|
currentAgentTitle,
|
|
76
|
+
currentAutocomplete,
|
|
73
77
|
getAvatar,
|
|
74
78
|
getTitle,
|
|
75
79
|
hasSystemRole,
|
|
@@ -8,10 +8,13 @@ import { SessionStore, agentSelectors, chatSelectors, sessionSelectors } from '@
|
|
|
8
8
|
import { ChatMessage, OpenAIFunctionCall } from '@/types/chatMessage';
|
|
9
9
|
import { fetchSSE } from '@/utils/fetch';
|
|
10
10
|
import { isFunctionMessage } from '@/utils/message';
|
|
11
|
+
import { setNamespace } from '@/utils/storeDebug';
|
|
11
12
|
import { nanoid } from '@/utils/uuid';
|
|
12
13
|
|
|
13
14
|
import { MessageDispatch, messagesReducer } from '../reducers/message';
|
|
14
15
|
|
|
16
|
+
const t = setNamespace('chat/message');
|
|
17
|
+
|
|
15
18
|
/**
|
|
16
19
|
* 聊天操作
|
|
17
20
|
*/
|
|
@@ -111,8 +114,12 @@ export const chatMessage: StateCreator<
|
|
|
111
114
|
|
|
112
115
|
generateMessage: async (messages, assistantId) => {
|
|
113
116
|
const { dispatchMessage } = get();
|
|
114
|
-
set(
|
|
115
|
-
|
|
117
|
+
set(
|
|
118
|
+
{ chatLoadingId: assistantId },
|
|
119
|
+
false,
|
|
120
|
+
t('generateMessage(start)', { assistantId, messages }),
|
|
121
|
+
);
|
|
122
|
+
const config = agentSelectors.currentAgentConfig(get());
|
|
116
123
|
|
|
117
124
|
const compiler = template(config.inputTemplate, { interpolate: /{{([\S\s]+?)}}/g });
|
|
118
125
|
|
|
@@ -137,7 +144,7 @@ export const chatMessage: StateCreator<
|
|
|
137
144
|
// 2. TODO 按参数设定截断长度
|
|
138
145
|
|
|
139
146
|
// 3. 添加 systemRole
|
|
140
|
-
const { systemRole } = agentSelectors.
|
|
147
|
+
const { systemRole } = agentSelectors.currentAgentConfig(get());
|
|
141
148
|
if (systemRole) {
|
|
142
149
|
postMessages.unshift({ content: systemRole, role: 'system' } as ChatMessage);
|
|
143
150
|
}
|
|
@@ -180,7 +187,7 @@ export const chatMessage: StateCreator<
|
|
|
180
187
|
},
|
|
181
188
|
});
|
|
182
189
|
|
|
183
|
-
set({ chatLoadingId: undefined });
|
|
190
|
+
set({ chatLoadingId: undefined }, false, t('generateMessage(end)'));
|
|
184
191
|
|
|
185
192
|
return { isFunctionCall };
|
|
186
193
|
},
|
|
@@ -188,7 +195,7 @@ export const chatMessage: StateCreator<
|
|
|
188
195
|
realFetchAIResponse: async (messages, userMessageId) => {
|
|
189
196
|
const { dispatchMessage, generateMessage, triggerFunctionCall, activeTopicId } = get();
|
|
190
197
|
|
|
191
|
-
const { model } = agentSelectors.
|
|
198
|
+
const { model } = agentSelectors.currentAgentConfig(get());
|
|
192
199
|
|
|
193
200
|
// 添加一个空的信息用于放置 ai 响应,注意顺序不能反
|
|
194
201
|
// 因为如果顺序反了,messages 中将包含新增的 ai message
|
|
@@ -4,10 +4,12 @@ import { LOADING_FLAT } from '@/const/message';
|
|
|
4
4
|
import { promptSummaryTitle } from '@/prompts/chat';
|
|
5
5
|
import { SessionStore, chatSelectors, sessionSelectors, topicSelectors } from '@/store/session';
|
|
6
6
|
import { fetchPresetTaskResult } from '@/utils/fetch';
|
|
7
|
+
import { setNamespace } from '@/utils/storeDebug';
|
|
7
8
|
import { nanoid } from '@/utils/uuid';
|
|
8
9
|
|
|
9
10
|
import { ChatTopicDispatch, topicReducer } from '../reducers/topic';
|
|
10
11
|
|
|
12
|
+
const t = setNamespace('chat/topic');
|
|
11
13
|
export interface ChatTopicAction {
|
|
12
14
|
/**
|
|
13
15
|
* 分发主题
|
|
@@ -116,9 +118,9 @@ export const chatTopic: StateCreator<
|
|
|
116
118
|
});
|
|
117
119
|
},
|
|
118
120
|
toggleTopic: (id) => {
|
|
119
|
-
set({ activeTopicId: id });
|
|
121
|
+
set({ activeTopicId: id }, false, t('toggleTopic'));
|
|
120
122
|
},
|
|
121
123
|
updateTopicLoading: (id) => {
|
|
122
|
-
set({ topicLoadingId: id });
|
|
124
|
+
set({ topicLoadingId: id }, false, t('updateTopicLoading'));
|
|
123
125
|
},
|
|
124
126
|
});
|
|
@@ -23,7 +23,7 @@ export const currentChats = (s: SessionStore): ChatMessage[] => {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export const systemRoleSel = (s: SessionStore): string => {
|
|
26
|
-
const config = agentSelectors.
|
|
26
|
+
const config = agentSelectors.currentAgentConfig(s);
|
|
27
27
|
|
|
28
28
|
return config.systemRole;
|
|
29
29
|
};
|
|
@@ -5,10 +5,12 @@ import { StateCreator } from 'zustand/vanilla';
|
|
|
5
5
|
|
|
6
6
|
import { SessionStore, initLobeSession } from '@/store/session';
|
|
7
7
|
import { LobeAgentSession, LobeSessions } from '@/types/session';
|
|
8
|
+
import { setNamespace } from '@/utils/storeDebug';
|
|
8
9
|
import { uuid } from '@/utils/uuid';
|
|
9
10
|
|
|
10
11
|
import { SessionDispatch, sessionsReducer } from './reducers/session';
|
|
11
12
|
|
|
13
|
+
const t = setNamespace('session');
|
|
12
14
|
export interface SessionAction {
|
|
13
15
|
activeSession: (sessionId: string) => void;
|
|
14
16
|
clearSessions: () => void;
|
|
@@ -63,11 +65,11 @@ export const createSessionSlice: StateCreator<
|
|
|
63
65
|
SessionAction
|
|
64
66
|
> = (set, get) => ({
|
|
65
67
|
activeSession: (sessionId) => {
|
|
66
|
-
set({ activeId: sessionId });
|
|
68
|
+
set({ activeId: sessionId }, false, t('activeSession'));
|
|
67
69
|
},
|
|
68
70
|
|
|
69
71
|
clearSessions: () => {
|
|
70
|
-
set({ sessions: {} });
|
|
72
|
+
set({ sessions: {} }, false, t('clearSessions'));
|
|
71
73
|
},
|
|
72
74
|
|
|
73
75
|
createSession: async () => {
|
|
@@ -91,24 +93,29 @@ export const createSessionSlice: StateCreator<
|
|
|
91
93
|
|
|
92
94
|
dispatchSession: (payload) => {
|
|
93
95
|
const { type, ...res } = payload;
|
|
94
|
-
set(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
set(
|
|
97
|
+
{ sessions: sessionsReducer(get().sessions, payload) },
|
|
98
|
+
false,
|
|
99
|
+
t(`dispatchChat/${type}`, res),
|
|
100
|
+
);
|
|
98
101
|
},
|
|
99
102
|
|
|
100
103
|
importSessions: (importSessions) => {
|
|
101
104
|
const { sessions } = get();
|
|
102
|
-
set(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
set(
|
|
106
|
+
{
|
|
107
|
+
sessions: produce(sessions, (draft) => {
|
|
108
|
+
for (const [id, session] of Object.entries(importSessions)) {
|
|
109
|
+
// 如果已经存在,则跳过
|
|
110
|
+
if (draft[id]) continue;
|
|
111
|
+
|
|
112
|
+
draft[id] = session;
|
|
113
|
+
}
|
|
114
|
+
}),
|
|
115
|
+
},
|
|
116
|
+
false,
|
|
117
|
+
t('importSessions', importSessions),
|
|
118
|
+
);
|
|
112
119
|
},
|
|
113
120
|
// genShareUrl: () => {
|
|
114
121
|
// const session = sessionSelectors.currentSession(get());
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEFAULT_AGENT_META } from '@/const/meta';
|
|
1
2
|
import { LobeAgentSession, LobeSessionType } from '@/types/session';
|
|
2
3
|
|
|
3
4
|
import { initialLobeAgentConfig } from '../agentConfig';
|
|
@@ -18,7 +19,7 @@ export const initLobeSession: LobeAgentSession = {
|
|
|
18
19
|
config: initialLobeAgentConfig,
|
|
19
20
|
createAt: Date.now(),
|
|
20
21
|
id: '',
|
|
21
|
-
meta:
|
|
22
|
+
meta: DEFAULT_AGENT_META,
|
|
22
23
|
type: LobeSessionType.Agent,
|
|
23
24
|
updateAt: Date.now(),
|
|
24
25
|
};
|