Skip to content

Commit 403175f

Browse files
authored
πŸ› fix: add advace config back in agent/group profiles (#11727)
* fix: add the agents advace config modal back * feat: add the group/profiles the advance settings
1 parent c484d1a commit 403175f

File tree

8 files changed

+381
-10
lines changed

8 files changed

+381
-10
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
'use client';
2+
3+
import { Avatar, Block, Flexbox, Icon, Text } from '@lobehub/ui';
4+
import { useTheme } from 'antd-style';
5+
import type { ItemType } from 'antd/es/menu/interface';
6+
import isEqual from 'fast-deep-equal';
7+
import { BrainIcon, MessageSquareHeartIcon, Settings2Icon } from 'lucide-react';
8+
import { memo, useMemo, useState } from 'react';
9+
import { useTranslation } from 'react-i18next';
10+
11+
import Menu from '@/components/Menu';
12+
import { DEFAULT_AVATAR, DEFAULT_INBOX_AVATAR } from '@/const/meta';
13+
import { AgentSettings as Settings } from '@/features/AgentSetting';
14+
import { useAgentStore } from '@/store/agent';
15+
import { agentSelectors, builtinAgentSelectors } from '@/store/agent/selectors';
16+
import { ChatSettingsTabs } from '@/store/global/initialState';
17+
18+
const Content = memo(() => {
19+
const { t } = useTranslation('setting');
20+
const theme = useTheme();
21+
const [agentId, isInbox] = useAgentStore((s) => [
22+
s.activeAgentId,
23+
builtinAgentSelectors.isInboxAgent(s),
24+
]);
25+
const config = useAgentStore(agentSelectors.currentAgentConfig, isEqual);
26+
const meta = useAgentStore(agentSelectors.currentAgentMeta, isEqual);
27+
const [tab, setTab] = useState(ChatSettingsTabs.Chat);
28+
29+
const updateAgentConfig = async (config: any) => {
30+
if (!agentId) return;
31+
await useAgentStore.getState().optimisticUpdateAgentConfig(agentId, config);
32+
};
33+
34+
const updateAgentMeta = async (meta: any) => {
35+
if (!agentId) return;
36+
await useAgentStore.getState().optimisticUpdateAgentMeta(agentId, meta);
37+
};
38+
39+
const menuItems: ItemType[] = useMemo(
40+
() =>
41+
[
42+
{
43+
icon: <Icon icon={Settings2Icon} />,
44+
key: ChatSettingsTabs.Chat,
45+
label: t('agentTab.chat'),
46+
},
47+
!isInbox
48+
? {
49+
icon: <Icon icon={MessageSquareHeartIcon} />,
50+
key: ChatSettingsTabs.Opening,
51+
label: t('agentTab.opening'),
52+
}
53+
: null,
54+
{
55+
icon: <Icon icon={BrainIcon} />,
56+
key: ChatSettingsTabs.Modal,
57+
label: t('agentTab.modal'),
58+
},
59+
].filter(Boolean) as ItemType[],
60+
[t, isInbox],
61+
);
62+
63+
const displayTitle = isInbox ? 'Lobe AI' : meta.title || t('defaultSession', { ns: 'common' });
64+
65+
return (
66+
<Flexbox
67+
direction="horizontal"
68+
height="100%"
69+
style={{
70+
padding: 0,
71+
position: 'relative',
72+
}}
73+
>
74+
<Flexbox
75+
height={'100%'}
76+
paddingBlock={24}
77+
paddingInline={8}
78+
style={{
79+
background: theme.colorBgLayout,
80+
borderRight: `1px solid ${theme.colorBorderSecondary}`,
81+
}}
82+
width={200}
83+
>
84+
<Block
85+
align={'center'}
86+
gap={8}
87+
horizontal
88+
paddingBlock={'14px 16px'}
89+
paddingInline={4}
90+
style={{
91+
overflow: 'hidden',
92+
}}
93+
variant={'borderless'}
94+
>
95+
<Avatar
96+
avatar={isInbox ? DEFAULT_INBOX_AVATAR : meta.avatar || DEFAULT_AVATAR}
97+
background={meta.backgroundColor || undefined}
98+
shape={'square'}
99+
size={28}
100+
/>
101+
<Text ellipsis weight={500}>
102+
{displayTitle}
103+
</Text>
104+
</Block>
105+
<Menu
106+
items={menuItems}
107+
onClick={({ key }) => setTab(key as ChatSettingsTabs)}
108+
selectable
109+
selectedKeys={[tab]}
110+
style={{ width: '100%' }}
111+
/>
112+
</Flexbox>
113+
<Flexbox
114+
flex={1}
115+
paddingBlock={24}
116+
paddingInline={64}
117+
style={{ overflow: 'scroll', width: '100%' }}
118+
>
119+
<Settings
120+
config={config}
121+
id={agentId}
122+
loading={false}
123+
meta={meta}
124+
onConfigChange={updateAgentConfig}
125+
onMetaChange={updateAgentMeta}
126+
tab={tab}
127+
/>
128+
</Flexbox>
129+
</Flexbox>
130+
);
131+
});
132+
133+
export default Content;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use client';
2+
3+
import { Modal } from '@lobehub/ui';
4+
import { memo } from 'react';
5+
6+
import { useAgentStore } from '@/store/agent';
7+
8+
import Content from './Content';
9+
10+
const AgentSettings = memo(() => {
11+
const showAgentSetting = useAgentStore((s) => s.showAgentSetting);
12+
13+
return (
14+
<Modal
15+
centered
16+
footer={null}
17+
onCancel={() => useAgentStore.setState({ showAgentSetting: false })}
18+
open={showAgentSetting}
19+
styles={{
20+
body: {
21+
height: '60vh',
22+
overflow: 'scroll',
23+
padding: 0,
24+
position: 'relative',
25+
},
26+
}}
27+
title={null}
28+
width={960}
29+
>
30+
<Content />
31+
</Modal>
32+
);
33+
});
34+
35+
export default AgentSettings;

β€Žsrc/app/[variants]/(main)/agent/profile/features/ProfileEditor/index.tsxβ€Ž

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
import { ENABLE_BUSINESS_FEATURES } from '@lobechat/business-const';
44
import { Button, Flexbox } from '@lobehub/ui';
55
import { Divider } from 'antd';
6+
import { useTheme } from 'antd-style';
67
import isEqual from 'fast-deep-equal';
7-
import { Clock, PlayIcon } from 'lucide-react';
8+
import { Clock, PlayIcon, Settings2Icon } from 'lucide-react';
89
import React, { memo, useCallback } from 'react';
910
import { useTranslation } from 'react-i18next';
1011
import urlJoin from 'url-join';
@@ -16,13 +17,15 @@ import { agentSelectors } from '@/store/agent/selectors';
1617
import { useChatStore } from '@/store/chat';
1718

1819
import AgentCronJobs from '../AgentCronJobs';
20+
import AgentSettings from '../AgentSettings';
1921
import EditorCanvas from '../EditorCanvas';
2022
import AgentPublishButton from '../Header/AgentPublishButton';
2123
import AgentHeader from './AgentHeader';
2224
import AgentTool from './AgentTool';
2325

2426
const ProfileEditor = memo(() => {
2527
const { t } = useTranslation('setting');
28+
const theme = useTheme();
2629
const config = useAgentStore(agentSelectors.currentAgentConfig, isEqual);
2730
const updateConfig = useAgentStore((s) => s.updateAgentConfig);
2831
const agentId = useAgentStore((s) => s.activeAgentId);
@@ -44,7 +47,7 @@ const ProfileEditor = memo(() => {
4447
>
4548
{/* Header: Avatar + Name + Description */}
4649
<AgentHeader />
47-
{/* Config Bar: Model Selector */}
50+
{/* Config Bar: Model Selector + Settings Button */}
4851
<Flexbox
4952
align={'center'}
5053
gap={8}
@@ -59,6 +62,15 @@ const ProfileEditor = memo(() => {
5962
provider: config.provider,
6063
}}
6164
/>
65+
<Button
66+
icon={Settings2Icon}
67+
onClick={() => useAgentStore.setState({ showAgentSetting: true })}
68+
size={'small'}
69+
style={{ color: theme.colorTextSecondary }}
70+
type={'text'}
71+
>
72+
{t('advancedSettings')}
73+
</Button>
6274
</Flexbox>
6375
<AgentTool />
6476
<Flexbox
@@ -93,6 +105,8 @@ const ProfileEditor = memo(() => {
93105
<EditorCanvas />
94106
{/* Agent Cron Jobs Display (only show if jobs exist) */}
95107
{ENABLE_BUSINESS_FEATURES && <AgentCronJobs />}
108+
{/* Advanced Settings Modal */}
109+
<AgentSettings />
96110
</>
97111
);
98112
});
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
'use client';
2+
3+
import { Avatar, Block, Flexbox, Icon, Text } from '@lobehub/ui';
4+
import { useTheme } from 'antd-style';
5+
import type { ItemType } from 'antd/es/menu/interface';
6+
import { MessageSquareHeartIcon } from 'lucide-react';
7+
import { memo, useMemo, useState } from 'react';
8+
import { useTranslation } from 'react-i18next';
9+
10+
import Menu from '@/components/Menu';
11+
import { DEFAULT_AVATAR } from '@/const/meta';
12+
import { AgentSettings as Settings } from '@/features/AgentSetting';
13+
import { useAgentGroupStore } from '@/store/agentGroup';
14+
import { agentGroupSelectors } from '@/store/agentGroup/selectors';
15+
import { ChatSettingsTabs } from '@/store/global/initialState';
16+
17+
const Content = memo(() => {
18+
const { t } = useTranslation('setting');
19+
const theme = useTheme();
20+
const groupId = useAgentGroupStore(agentGroupSelectors.activeGroupId);
21+
const currentGroup = useAgentGroupStore(agentGroupSelectors.currentGroup);
22+
const [tab] = useState(ChatSettingsTabs.Opening);
23+
24+
const updateGroupConfig = async (config: any) => {
25+
if (!groupId) return;
26+
// Only update openingMessage and openingQuestions
27+
const groupConfig = {
28+
openingMessage: config.openingMessage,
29+
openingQuestions: config.openingQuestions,
30+
};
31+
await useAgentGroupStore.getState().updateGroupConfig(groupConfig);
32+
};
33+
34+
const updateGroupMeta = async (meta: any) => {
35+
if (!groupId) return;
36+
await useAgentGroupStore.getState().updateGroup(groupId, meta);
37+
};
38+
39+
// Convert group config to agent config format for AgentSettings component
40+
const agentConfig = useMemo(
41+
() =>
42+
({
43+
chatConfig: {},
44+
model: '',
45+
openingMessage: currentGroup?.config?.openingMessage,
46+
openingQuestions: currentGroup?.config?.openingQuestions,
47+
params: {},
48+
systemRole: '',
49+
tts: {},
50+
}) as any,
51+
[currentGroup?.config],
52+
);
53+
54+
const agentMeta = useMemo(
55+
() => ({
56+
avatar: currentGroup?.avatar || undefined,
57+
backgroundColor: currentGroup?.backgroundColor || undefined,
58+
description: currentGroup?.description || undefined,
59+
tags: [] as string[],
60+
title: currentGroup?.title || undefined,
61+
}),
62+
[currentGroup],
63+
);
64+
65+
const menuItems: ItemType[] = useMemo(
66+
() => [
67+
{
68+
icon: <Icon icon={MessageSquareHeartIcon} />,
69+
key: ChatSettingsTabs.Opening,
70+
label: t('agentTab.opening'),
71+
},
72+
],
73+
[t],
74+
);
75+
76+
const displayTitle = currentGroup?.title || t('defaultSession', { ns: 'common' });
77+
78+
return (
79+
<Flexbox
80+
direction="horizontal"
81+
height="100%"
82+
style={{
83+
padding: 0,
84+
position: 'relative',
85+
}}
86+
>
87+
<Flexbox
88+
height={'100%'}
89+
paddingBlock={24}
90+
paddingInline={8}
91+
style={{
92+
background: theme.colorBgLayout,
93+
borderRight: `1px solid ${theme.colorBorderSecondary}`,
94+
}}
95+
width={200}
96+
>
97+
<Block
98+
align={'center'}
99+
gap={8}
100+
horizontal
101+
paddingBlock={'14px 16px'}
102+
paddingInline={4}
103+
style={{
104+
overflow: 'hidden',
105+
}}
106+
variant={'borderless'}
107+
>
108+
<Avatar
109+
avatar={currentGroup?.avatar || DEFAULT_AVATAR}
110+
background={currentGroup?.backgroundColor || undefined}
111+
shape={'square'}
112+
size={28}
113+
/>
114+
<Text ellipsis weight={500}>
115+
{displayTitle}
116+
</Text>
117+
</Block>
118+
<Menu items={menuItems} selectable selectedKeys={[tab]} style={{ width: '100%' }} />
119+
</Flexbox>
120+
<Flexbox
121+
flex={1}
122+
paddingBlock={24}
123+
paddingInline={64}
124+
style={{ overflow: 'scroll', width: '100%' }}
125+
>
126+
<Settings
127+
config={agentConfig}
128+
id={groupId}
129+
loading={false}
130+
meta={agentMeta}
131+
onConfigChange={updateGroupConfig}
132+
onMetaChange={updateGroupMeta}
133+
tab={tab}
134+
/>
135+
</Flexbox>
136+
</Flexbox>
137+
);
138+
});
139+
140+
export default Content;

0 commit comments

Comments
Β (0)