@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,128 @@
|
|
|
1
|
+
import { Form, type FormItemProps, Icon, type ItemGroup, Tooltip } from '@lobehub/ui';
|
|
2
|
+
import { Button } from 'antd';
|
|
3
|
+
import { UserCircle, Wand2 } from 'lucide-react';
|
|
4
|
+
import { ReactNode, memo, useMemo } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
|
|
7
|
+
import EmojiPicker from '@/components/EmojiPicker';
|
|
8
|
+
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
9
|
+
import { AgentAction, SessionLoadingState } from '@/store/session/slices/agentConfig';
|
|
10
|
+
import { MetaData } from '@/types/meta';
|
|
11
|
+
import { LobeAgentConfig } from '@/types/session';
|
|
12
|
+
|
|
13
|
+
import AutoGenerateInput from './AutoGenerateInput';
|
|
14
|
+
import BackgroundSwatches from './BackgroundSwatches';
|
|
15
|
+
|
|
16
|
+
export interface Autocomplete {
|
|
17
|
+
autocompleteMeta: AgentAction['autocompleteMeta'];
|
|
18
|
+
autocompleteSessionAgentMeta: AgentAction['autocompleteSessionAgentMeta'];
|
|
19
|
+
id: string | null;
|
|
20
|
+
loading: SessionLoadingState;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AgentMetaProps {
|
|
24
|
+
autocomplete?: Autocomplete;
|
|
25
|
+
config: LobeAgentConfig;
|
|
26
|
+
meta: MetaData;
|
|
27
|
+
updateMeta: AgentAction['updateAgentMeta'];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const AgentMeta = memo<AgentMetaProps>(({ config, meta, updateMeta, autocomplete }) => {
|
|
31
|
+
const { t } = useTranslation('setting');
|
|
32
|
+
|
|
33
|
+
const hasSystemRole = useMemo(() => !!config.systemRole, [config]);
|
|
34
|
+
|
|
35
|
+
let extra: ReactNode | undefined;
|
|
36
|
+
|
|
37
|
+
const basic = [
|
|
38
|
+
{
|
|
39
|
+
key: 'title',
|
|
40
|
+
label: t('settingAgent.name.title'),
|
|
41
|
+
placeholder: t('settingAgent.name.placeholder'),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: 'description',
|
|
45
|
+
label: t('settingAgent.description.title'),
|
|
46
|
+
placeholder: t('settingAgent.description.placeholder'),
|
|
47
|
+
},
|
|
48
|
+
// { key: 'tag', label: t('agentTag'), placeholder: t('agentTagPlaceholder') },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const autocompleteItems: FormItemProps[] = basic.map((item) => {
|
|
52
|
+
const handleGenerate = () => autocomplete?.autocompleteMeta(item.key as keyof typeof meta);
|
|
53
|
+
return {
|
|
54
|
+
children: (
|
|
55
|
+
<AutoGenerateInput
|
|
56
|
+
loading={autocomplete?.loading[item.key as keyof SessionLoadingState]}
|
|
57
|
+
onChange={(e) => {
|
|
58
|
+
updateMeta({ [item.key]: e.target.value });
|
|
59
|
+
}}
|
|
60
|
+
onGenerate={autocomplete ? handleGenerate : undefined}
|
|
61
|
+
placeholder={item.placeholder}
|
|
62
|
+
value={meta[item.key as keyof typeof meta]}
|
|
63
|
+
/>
|
|
64
|
+
),
|
|
65
|
+
label: item.label,
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (autocomplete) {
|
|
70
|
+
const { autocompleteSessionAgentMeta, loading, id } = autocomplete;
|
|
71
|
+
|
|
72
|
+
extra = (
|
|
73
|
+
<Tooltip title={t('autoGenerateTooltip', { ns: 'common' })}>
|
|
74
|
+
<Button
|
|
75
|
+
disabled={!hasSystemRole}
|
|
76
|
+
icon={<Icon icon={Wand2} />}
|
|
77
|
+
loading={Object.values(loading).some((i) => !!i)}
|
|
78
|
+
onClick={(e: any) => {
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
if (!id) return;
|
|
81
|
+
autocompleteSessionAgentMeta(id, true);
|
|
82
|
+
}}
|
|
83
|
+
size={'small'}
|
|
84
|
+
>
|
|
85
|
+
{t('autoGenerate', { ns: 'common' })}
|
|
86
|
+
</Button>
|
|
87
|
+
</Tooltip>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const metaData: ItemGroup = useMemo(
|
|
92
|
+
() => ({
|
|
93
|
+
children: [
|
|
94
|
+
{
|
|
95
|
+
children: (
|
|
96
|
+
<EmojiPicker
|
|
97
|
+
avatar={meta.avatar}
|
|
98
|
+
backgroundColor={meta.backgroundColor}
|
|
99
|
+
onChange={(avatar) => updateMeta({ avatar })}
|
|
100
|
+
/>
|
|
101
|
+
),
|
|
102
|
+
label: t('settingAgent.avatar.title'),
|
|
103
|
+
minWidth: undefined,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
children: (
|
|
107
|
+
<BackgroundSwatches
|
|
108
|
+
backgroundColor={meta.backgroundColor}
|
|
109
|
+
onChange={(backgroundColor) => updateMeta({ backgroundColor })}
|
|
110
|
+
/>
|
|
111
|
+
),
|
|
112
|
+
divider: false,
|
|
113
|
+
label: t('settingAgent.backgroundColor.title'),
|
|
114
|
+
minWidth: undefined,
|
|
115
|
+
},
|
|
116
|
+
...autocompleteItems,
|
|
117
|
+
],
|
|
118
|
+
extra: extra,
|
|
119
|
+
icon: UserCircle,
|
|
120
|
+
title: t('settingAgent.title'),
|
|
121
|
+
}),
|
|
122
|
+
[autocompleteItems, extra, meta],
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return <Form items={[metaData]} {...FORM_STYLE} />;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
export default AgentMeta;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { Avatar, Form, ItemGroup } from '@lobehub/ui';
|
|
2
2
|
import { Switch } from 'antd';
|
|
3
|
-
import isEqual from 'fast-deep-equal';
|
|
4
3
|
import { ToyBrick } from 'lucide-react';
|
|
5
|
-
import { useMemo } from 'react';
|
|
4
|
+
import { memo, useMemo } from 'react';
|
|
6
5
|
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import { shallow } from 'zustand/shallow';
|
|
8
6
|
|
|
9
7
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
10
8
|
import { PluginsMap } from '@/plugins';
|
|
11
|
-
import {
|
|
9
|
+
import { AgentAction } from '@/store/session/slices/agentConfig';
|
|
10
|
+
import { LobeAgentConfig } from '@/types/session';
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
export interface AgentPluginProps {
|
|
13
|
+
config: LobeAgentConfig;
|
|
14
|
+
updateConfig: AgentAction['toggleAgentPlugin'];
|
|
15
|
+
}
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
const AgentPlugin = memo<AgentPluginProps>(({ config, updateConfig }) => {
|
|
18
|
+
const { t } = useTranslation('setting');
|
|
19
19
|
|
|
20
20
|
const plugin: ItemGroup = useMemo(
|
|
21
21
|
() => ({
|
|
@@ -24,7 +24,7 @@ const PluginList = () => {
|
|
|
24
24
|
children: (
|
|
25
25
|
<Switch
|
|
26
26
|
checked={!config.plugins ? false : config.plugins.includes(item.name)}
|
|
27
|
-
onChange={() =>
|
|
27
|
+
onChange={() => updateConfig(item.name)}
|
|
28
28
|
/>
|
|
29
29
|
),
|
|
30
30
|
desc: item.schema.description,
|
|
@@ -39,6 +39,6 @@ const PluginList = () => {
|
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
return <Form items={[plugin]} {...FORM_STYLE} />;
|
|
42
|
-
};
|
|
42
|
+
});
|
|
43
43
|
|
|
44
|
-
export default
|
|
44
|
+
export default AgentPlugin;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { CodeEditor, FormGroup, TokenTag } from '@lobehub/ui';
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
|
+
import { encode } from 'gpt-tokenizer';
|
|
3
4
|
import { Bot } from 'lucide-react';
|
|
4
|
-
import { memo } from 'react';
|
|
5
|
+
import { memo, useMemo } from 'react';
|
|
5
6
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { shallow } from 'zustand/shallow';
|
|
7
7
|
|
|
8
8
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
9
9
|
import { ModelTokens } from '@/const/modelTokens';
|
|
10
|
-
import {
|
|
10
|
+
import { AgentAction } from '@/store/session/slices/agentConfig';
|
|
11
|
+
import { LobeAgentConfig } from '@/types/session';
|
|
11
12
|
|
|
12
13
|
export const useStyles = createStyles(({ css, token }) => ({
|
|
13
14
|
input: css`
|
|
@@ -22,18 +23,16 @@ export const useStyles = createStyles(({ css, token }) => ({
|
|
|
22
23
|
`,
|
|
23
24
|
}));
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
export interface AgentPromptProps {
|
|
27
|
+
config: LobeAgentConfig;
|
|
28
|
+
updateConfig: AgentAction['updateAgentConfig'];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const AgentPrompt = memo<AgentPromptProps>(({ config, updateConfig }) => {
|
|
26
32
|
const { t } = useTranslation('setting');
|
|
27
33
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
agentSelectors.currentAgentSystemRole(s),
|
|
31
|
-
agentSelectors.currentAgentModel(s),
|
|
32
|
-
chatSelectors.systemRoleTokenCount(s),
|
|
33
|
-
s.updateAgentConfig,
|
|
34
|
-
],
|
|
35
|
-
shallow,
|
|
36
|
-
);
|
|
34
|
+
const { systemRole, model } = config;
|
|
35
|
+
const systemTokenCount = useMemo(() => encode(systemRole || '').length, [systemRole]);
|
|
37
36
|
|
|
38
37
|
return (
|
|
39
38
|
<FormGroup
|
|
@@ -46,9 +45,7 @@ const AgentPrompt = memo(() => {
|
|
|
46
45
|
>
|
|
47
46
|
<CodeEditor
|
|
48
47
|
language={'md'}
|
|
49
|
-
onValueChange={(e) => {
|
|
50
|
-
updateAgentConfig({ systemRole: e });
|
|
51
|
-
}}
|
|
48
|
+
onValueChange={(e) => updateConfig({ systemRole: e })}
|
|
52
49
|
placeholder={t('settingAgent.name.placeholder')}
|
|
53
50
|
resize={false}
|
|
54
51
|
style={{ marginTop: 16 }}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"exportType": "agents",
|
|
3
|
+
"state": {
|
|
4
|
+
"sessions": {
|
|
5
|
+
"9a2def55-ff50-4f7f-ad6c-b97dac817193": {
|
|
6
|
+
"chats": {},
|
|
7
|
+
"config": {
|
|
8
|
+
"model": "gpt-3.5-turbo",
|
|
9
|
+
"params": { "temperature": 0.6 },
|
|
10
|
+
"systemRole": "你是一名专业的前端。擅长书写 Typescript JSDoc 代码,代码的示例如下:\n\n```ts\ninterface Props {\n/**\n* 尺寸\n* */\nloading: boolean;\n/**\n* 头像形状\n* @default 'square'\n* @enum [\"square\",\"circle\"]\n* @enumNames [ \"方形\", \"圆形\"]\n*/\nshape?: 'square' | 'circle';\n/**\n* 返回事件\n* @ignore\n*/\nonBack: () => void;\n/**\n* 选择路由的回调函数\n* @param key - 选中的路由\n* @ignore\n*/\nonSelect?: (key: string) => any;\n/**\n* 点击事件回调函数\n* @ignore\n*/\nonClick?: () => void;\n/**\n* 引用\n* @ignore\n*/\nref: any;\n/**\n* Tooltip 提示框位置\n* @enum ['top', 'left', 'right', 'bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight', 'leftTop', 'leftBottom', 'rightTop', 'rightBottom']\n* @enumNames ['上', '左', '右', '下', '左上', '右上', '左下', '右下', '左上', '左下', '右上', '右下']\n* @default 'top'\n*/\nplacement?: TooltipPlacement;\n}\n```\n\n\n接下来用户会输入一串 interface 代码,需要你补全 jsdoc。其中接口的类型不可改变"
|
|
11
|
+
},
|
|
12
|
+
"createAt": 1690184262713,
|
|
13
|
+
"id": "9a2def55-ff50-4f7f-ad6c-b97dac817193",
|
|
14
|
+
"meta": { "backgroundColor": "#ec5e41", "avatar": "🥲" },
|
|
15
|
+
"type": "agent",
|
|
16
|
+
"updateAt": 1690184262713,
|
|
17
|
+
"topics": {}
|
|
18
|
+
},
|
|
19
|
+
"744fe028-c8a2-410c-8b0a-66cfa00d647b": {
|
|
20
|
+
"chats": {},
|
|
21
|
+
"config": {
|
|
22
|
+
"model": "gpt-3.5-turbo",
|
|
23
|
+
"params": { "temperature": 0.6 },
|
|
24
|
+
"systemRole": "- dafdsafa\n- da- dafdsafa\n- da- dafdsafa\n- da- dafdsafa\n- da- dafdsafa\n- da"
|
|
25
|
+
},
|
|
26
|
+
"createAt": 1690184730185,
|
|
27
|
+
"id": "744fe028-c8a2-410c-8b0a-66cfa00d647b",
|
|
28
|
+
"meta": {
|
|
29
|
+
"backgroundColor": "#ffef5c",
|
|
30
|
+
"title": "dafaa",
|
|
31
|
+
"description": "safsafsafsafsafsafsfasfas"
|
|
32
|
+
},
|
|
33
|
+
"type": "agent",
|
|
34
|
+
"updateAt": 1690184730185,
|
|
35
|
+
"topics": {}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"version": 1
|
|
40
|
+
}
|
|
@@ -8,17 +8,24 @@ import {
|
|
|
8
8
|
Github,
|
|
9
9
|
Heart,
|
|
10
10
|
Settings,
|
|
11
|
+
Settings2,
|
|
11
12
|
} from 'lucide-react';
|
|
12
13
|
import Router from 'next/router';
|
|
13
|
-
import {
|
|
14
|
+
import { memo, useMemo } from 'react';
|
|
14
15
|
import { useTranslation } from 'react-i18next';
|
|
15
16
|
|
|
16
17
|
import { useExportConfig } from '@/hooks/useExportConfig';
|
|
17
18
|
import { useImportConfig } from '@/hooks/useImportConfig';
|
|
19
|
+
import { SettingsStore } from '@/store/settings';
|
|
18
20
|
|
|
19
21
|
import pkg from '../../../package.json';
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
export interface BottomActionProps {
|
|
24
|
+
setTab: SettingsStore['switchSideBar'];
|
|
25
|
+
tab: SettingsStore['sidebarKey'];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const BottomActions = memo<BottomActionProps>(({ tab, setTab }) => {
|
|
22
29
|
const { t } = useTranslation('common');
|
|
23
30
|
|
|
24
31
|
const { exportSessions, exportSettings, exportAll, exportAgents } = useExportConfig();
|
|
@@ -93,7 +100,10 @@ const BottomAction = memo<{ children: ReactNode }>(({ children }) => {
|
|
|
93
100
|
icon: <Icon icon={Settings} />,
|
|
94
101
|
key: 'setting',
|
|
95
102
|
label: t('setting'),
|
|
96
|
-
onClick: () =>
|
|
103
|
+
onClick: () => {
|
|
104
|
+
setTab('settings');
|
|
105
|
+
Router.push('/settings');
|
|
106
|
+
},
|
|
97
107
|
},
|
|
98
108
|
],
|
|
99
109
|
[],
|
|
@@ -103,10 +113,10 @@ const BottomAction = memo<{ children: ReactNode }>(({ children }) => {
|
|
|
103
113
|
<>
|
|
104
114
|
<ActionIcon icon={Github} onClick={() => window.open(pkg.homepage, '__blank')} />
|
|
105
115
|
<Dropdown arrow={false} menu={{ items }} trigger={['click']}>
|
|
106
|
-
{
|
|
116
|
+
<ActionIcon active={tab === 'settings'} icon={Settings2} />
|
|
107
117
|
</Dropdown>
|
|
108
118
|
</>
|
|
109
119
|
);
|
|
110
120
|
});
|
|
111
121
|
|
|
112
|
-
export default
|
|
122
|
+
export default BottomActions;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ActionIcon } from '@lobehub/ui';
|
|
2
|
+
import { MessageSquare, Sticker } from 'lucide-react';
|
|
3
|
+
import Router from 'next/router';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
|
|
7
|
+
import { SettingsStore } from '@/store/settings';
|
|
8
|
+
|
|
9
|
+
export interface TopActionProps {
|
|
10
|
+
setTab: SettingsStore['switchSideBar'];
|
|
11
|
+
tab: SettingsStore['sidebarKey'];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const TopActions = memo<TopActionProps>(({ tab, setTab }) => {
|
|
15
|
+
const { t } = useTranslation('common');
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<ActionIcon
|
|
20
|
+
active={tab === 'chat'}
|
|
21
|
+
icon={MessageSquare}
|
|
22
|
+
onClick={() => {
|
|
23
|
+
// 如果已经在 chat 路径下了,那么就不用再跳转了
|
|
24
|
+
if (Router.asPath.startsWith('/chat')) return;
|
|
25
|
+
|
|
26
|
+
Router.push('/');
|
|
27
|
+
}}
|
|
28
|
+
size="large"
|
|
29
|
+
title={t('tab.chat')}
|
|
30
|
+
/>
|
|
31
|
+
<ActionIcon
|
|
32
|
+
active={tab === 'market'}
|
|
33
|
+
icon={Sticker}
|
|
34
|
+
onClick={() => setTab('market')}
|
|
35
|
+
size="large"
|
|
36
|
+
title={t('tab.market')}
|
|
37
|
+
/>
|
|
38
|
+
</>
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export default TopActions;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { MessageSquare, Settings2, Sticker } from 'lucide-react';
|
|
3
|
-
import Router from 'next/router';
|
|
1
|
+
import { SideNav } from '@lobehub/ui';
|
|
4
2
|
import { memo } from 'react';
|
|
5
3
|
import { shallow } from 'zustand/shallow';
|
|
6
4
|
|
|
7
5
|
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
8
6
|
import { useSettings } from '@/store/settings';
|
|
9
7
|
|
|
10
|
-
import
|
|
8
|
+
import BottomActions from './BottomActions';
|
|
9
|
+
import TopActions from './TopActions';
|
|
11
10
|
|
|
12
11
|
export default memo(() => {
|
|
13
12
|
const [tab, setTab] = useSettings((s) => [s.sidebarKey, s.switchSideBar], shallow);
|
|
@@ -15,33 +14,9 @@ export default memo(() => {
|
|
|
15
14
|
return (
|
|
16
15
|
<SideNav
|
|
17
16
|
avatar={<AvatarWithUpload />}
|
|
18
|
-
bottomActions={
|
|
19
|
-
<BottomAction>
|
|
20
|
-
<ActionIcon active={tab === 'setting'} icon={Settings2} />
|
|
21
|
-
</BottomAction>
|
|
22
|
-
}
|
|
17
|
+
bottomActions={<BottomActions setTab={setTab} tab={tab} />}
|
|
23
18
|
style={{ height: '100vh' }}
|
|
24
|
-
topActions={
|
|
25
|
-
<>
|
|
26
|
-
<ActionIcon
|
|
27
|
-
active={tab === 'chat'}
|
|
28
|
-
icon={MessageSquare}
|
|
29
|
-
onClick={() => {
|
|
30
|
-
// 如果已经在 chat 路径下了,那么就不用再跳转了
|
|
31
|
-
if (Router.asPath.startsWith('/chat')) return;
|
|
32
|
-
|
|
33
|
-
Router.push('/');
|
|
34
|
-
}}
|
|
35
|
-
size="large"
|
|
36
|
-
/>
|
|
37
|
-
<ActionIcon
|
|
38
|
-
active={tab === 'market'}
|
|
39
|
-
icon={Sticker}
|
|
40
|
-
onClick={() => setTab('market')}
|
|
41
|
-
size="large"
|
|
42
|
-
/>
|
|
43
|
-
</>
|
|
44
|
-
}
|
|
19
|
+
topActions={<TopActions setTab={setTab} tab={tab} />}
|
|
45
20
|
/>
|
|
46
21
|
);
|
|
47
22
|
});
|
|
@@ -6,13 +6,13 @@ import { importConfigFile } from '@/utils/config';
|
|
|
6
6
|
|
|
7
7
|
export const useImportConfig = () => {
|
|
8
8
|
const importSessions = useSessionStore((s) => s.importSessions);
|
|
9
|
-
const
|
|
9
|
+
const importAppSettings = useSettings((s) => s.importAppSettings);
|
|
10
10
|
|
|
11
11
|
const importConfig = (info: any) => {
|
|
12
12
|
importConfigFile(info, (config) => {
|
|
13
13
|
switch (config.exportType) {
|
|
14
14
|
case 'settings': {
|
|
15
|
-
|
|
15
|
+
importAppSettings(config.state.settings);
|
|
16
16
|
break;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ export const useImportConfig = () => {
|
|
|
24
24
|
|
|
25
25
|
case 'all': {
|
|
26
26
|
importSessions(config.state.sessions);
|
|
27
|
-
|
|
27
|
+
importAppSettings(config.state.settings);
|
|
28
28
|
|
|
29
29
|
break;
|
|
30
30
|
}
|
|
@@ -33,7 +33,7 @@ const List = () => {
|
|
|
33
33
|
const [displayMode, chatLoadingId, deleteMessage, resendMessage, dispatchMessage] =
|
|
34
34
|
useSessionStore(
|
|
35
35
|
(s) => [
|
|
36
|
-
agentSelectors.
|
|
36
|
+
agentSelectors.currentAgentConfig(s).displayMode,
|
|
37
37
|
s.chatLoadingId,
|
|
38
38
|
s.deleteMessage,
|
|
39
39
|
s.resendMessage,
|
|
@@ -16,7 +16,7 @@ const InputActions = memo(() => {
|
|
|
16
16
|
shallow,
|
|
17
17
|
);
|
|
18
18
|
const [model, temperature] = useSessionStore((s) => {
|
|
19
|
-
const config = agentSelectors.
|
|
19
|
+
const config = agentSelectors.currentAgentConfig(s);
|
|
20
20
|
return [
|
|
21
21
|
config.model,
|
|
22
22
|
config.params.temperature,
|
|
@@ -40,7 +40,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
40
40
|
`,
|
|
41
41
|
}));
|
|
42
42
|
|
|
43
|
-
const
|
|
43
|
+
const Inner = memo(() => {
|
|
44
44
|
const [openModal, setOpenModal] = useState(false);
|
|
45
45
|
const { styles } = useStyles();
|
|
46
46
|
const [systemRole, updateAgentConfig] = useSessionStore(
|
|
@@ -87,4 +87,4 @@ const SideBar = memo(() => {
|
|
|
87
87
|
);
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
export default
|
|
90
|
+
export default Inner;
|
|
@@ -4,6 +4,7 @@ import { createStyles } from 'antd-style';
|
|
|
4
4
|
import { MoreVertical, PencilLine, Star, Trash } from 'lucide-react';
|
|
5
5
|
import { memo, useMemo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import { Flexbox } from 'react-layout-kit';
|
|
7
8
|
import { shallow } from 'zustand/shallow';
|
|
8
9
|
|
|
9
10
|
import { useSessionStore } from '@/store/session';
|
|
@@ -82,7 +83,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav }) => {
|
|
|
82
83
|
);
|
|
83
84
|
|
|
84
85
|
return (
|
|
85
|
-
|
|
86
|
+
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'}>
|
|
86
87
|
<ActionIcon
|
|
87
88
|
color={fav ? theme.colorWarning : undefined}
|
|
88
89
|
fill={fav ? theme.colorWarning : 'transparent'}
|
|
@@ -93,7 +94,6 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav }) => {
|
|
|
93
94
|
}}
|
|
94
95
|
size={'small'}
|
|
95
96
|
/>
|
|
96
|
-
|
|
97
97
|
{!editing ? (
|
|
98
98
|
<Paragraph
|
|
99
99
|
className={styles.title}
|
|
@@ -115,11 +115,9 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav }) => {
|
|
|
115
115
|
showEditIcon={false}
|
|
116
116
|
size={'small'}
|
|
117
117
|
style={{
|
|
118
|
-
background: theme.colorBgContainer,
|
|
119
|
-
borderRadius: 6,
|
|
120
118
|
height: 28,
|
|
121
|
-
padding: '0 2px',
|
|
122
119
|
}}
|
|
120
|
+
type={'pure'}
|
|
123
121
|
value={title}
|
|
124
122
|
/>
|
|
125
123
|
)}
|
|
@@ -144,7 +142,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav }) => {
|
|
|
144
142
|
/>
|
|
145
143
|
</Dropdown>
|
|
146
144
|
)}
|
|
147
|
-
|
|
145
|
+
</Flexbox>
|
|
148
146
|
);
|
|
149
147
|
});
|
|
150
148
|
|
|
@@ -7,7 +7,7 @@ import HeaderSpacing from '@/components/HeaderSpacing';
|
|
|
7
7
|
import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
|
|
8
8
|
import { useSettings } from '@/store/settings';
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import Inner from './Inner';
|
|
11
11
|
|
|
12
12
|
const useStyles = createStyles(({ cx, css, token, stylish }) => ({
|
|
13
13
|
drawer: cx(
|
|
@@ -38,7 +38,7 @@ const Config = () => {
|
|
|
38
38
|
>
|
|
39
39
|
<HeaderSpacing />
|
|
40
40
|
<DraggablePanelContainer style={{ flex: 'none', minWidth: CHAT_SIDEBAR_WIDTH }}>
|
|
41
|
-
<
|
|
41
|
+
<Inner />
|
|
42
42
|
</DraggablePanelContainer>
|
|
43
43
|
</DraggablePanel>
|
|
44
44
|
);
|
|
@@ -7,9 +7,9 @@ import { sessionSelectors, useSessionStore } from '@/store/session';
|
|
|
7
7
|
import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
|
|
8
8
|
|
|
9
9
|
import Layout from '../layout';
|
|
10
|
-
import Config from './Config';
|
|
11
10
|
import Conversation from './Conversation';
|
|
12
11
|
import Header from './Header';
|
|
12
|
+
import Config from './Sidebar';
|
|
13
13
|
|
|
14
14
|
const Chat = memo(() => {
|
|
15
15
|
const [title] = useSessionStore((s) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import isEqual from 'fast-deep-equal';
|
|
1
2
|
import Head from 'next/head';
|
|
2
3
|
import { memo } from 'react';
|
|
3
4
|
import { useTranslation } from 'react-i18next';
|
|
@@ -6,20 +7,28 @@ import { shallow } from 'zustand/shallow';
|
|
|
6
7
|
|
|
7
8
|
import HeaderSpacing from '@/components/HeaderSpacing';
|
|
8
9
|
import { HEADER_HEIGHT } from '@/const/layoutTokens';
|
|
10
|
+
import { AgentConfig, AgentMeta, AgentPlugin, AgentPrompt } from '@/features/AgentSetting';
|
|
9
11
|
import { agentSelectors, useSessionStore } from '@/store/session';
|
|
10
12
|
import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
|
|
11
13
|
|
|
12
14
|
import ChatLayout from '../../layout';
|
|
13
|
-
import AgentConfig from './AgentConfig';
|
|
14
|
-
import AgentMeta from './AgentMeta';
|
|
15
|
-
import AgentPlugin from './AgentPlugin';
|
|
16
|
-
import AgentPrompt from './AgentPrompt';
|
|
17
15
|
import Header from './Header';
|
|
18
16
|
|
|
19
17
|
const EditPage = memo(() => {
|
|
20
18
|
const { t } = useTranslation('setting');
|
|
19
|
+
const config = useSessionStore(agentSelectors.currentAgentConfig, isEqual);
|
|
20
|
+
const meta = useSessionStore(agentSelectors.currentAgentMeta, isEqual);
|
|
21
|
+
const autocomplete = useSessionStore(agentSelectors.currentAutocomplete, shallow);
|
|
22
|
+
const [updateAgentConfig, toggleAgentPlugin, updateAgentMeta, title] = useSessionStore(
|
|
23
|
+
(s) => [
|
|
24
|
+
s.updateAgentConfig,
|
|
25
|
+
s.toggleAgentPlugin,
|
|
26
|
+
s.updateAgentMeta,
|
|
27
|
+
agentSelectors.currentAgentTitle(s),
|
|
28
|
+
],
|
|
29
|
+
shallow,
|
|
30
|
+
);
|
|
21
31
|
|
|
22
|
-
const title = useSessionStore(agentSelectors.currentAgentTitle, shallow);
|
|
23
32
|
const pageTitle = genSiteHeadTitle(t('header.sessionWithName', { name: title }));
|
|
24
33
|
|
|
25
34
|
return (
|
|
@@ -31,10 +40,15 @@ const EditPage = memo(() => {
|
|
|
31
40
|
<Header />
|
|
32
41
|
<Flexbox align={'center'} flex={1} gap={16} padding={24} style={{ overflow: 'auto' }}>
|
|
33
42
|
<HeaderSpacing height={HEADER_HEIGHT - 16} />
|
|
34
|
-
<AgentPrompt />
|
|
35
|
-
<AgentMeta
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
<AgentPrompt config={config} updateConfig={updateAgentConfig} />
|
|
44
|
+
<AgentMeta
|
|
45
|
+
autocomplete={autocomplete}
|
|
46
|
+
config={config}
|
|
47
|
+
meta={meta}
|
|
48
|
+
updateMeta={updateAgentMeta}
|
|
49
|
+
/>
|
|
50
|
+
<AgentConfig config={config} updateConfig={updateAgentConfig} />
|
|
51
|
+
<AgentPlugin config={config} updateConfig={toggleAgentPlugin} />
|
|
38
52
|
</Flexbox>
|
|
39
53
|
</ChatLayout>
|
|
40
54
|
</>
|