@lobehub/lobehub 2.0.0-next.346 → 2.0.0-next.347

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 CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.347](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.346...v2.0.0-next.347)
6
+
7
+ <sup>Released on **2026-01-23**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Add advace config back in agent/group profiles.
12
+
13
+ #### 💄 Styles
14
+
15
+ - **misc**: Move plugin store button outside scroll container.
16
+
17
+ <br/>
18
+
19
+ <details>
20
+ <summary><kbd>Improvements and Fixes</kbd></summary>
21
+
22
+ #### What's fixed
23
+
24
+ - **misc**: Add advace config back in agent/group profiles, closes [#11727](https://github.com/lobehub/lobe-chat/issues/11727) ([403175f](https://github.com/lobehub/lobe-chat/commit/403175f))
25
+
26
+ #### Styles
27
+
28
+ - **misc**: Move plugin store button outside scroll container, closes [#11728](https://github.com/lobehub/lobe-chat/issues/11728) ([c484d1a](https://github.com/lobehub/lobe-chat/commit/c484d1a))
29
+
30
+ </details>
31
+
32
+ <div align="right">
33
+
34
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
35
+
36
+ </div>
37
+
5
38
  ## [Version 2.0.0-next.346](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.345...v2.0.0-next.346)
6
39
 
7
40
  <sup>Released on **2026-01-23**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,16 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Add advace config back in agent/group profiles."
6
+ ],
7
+ "improvements": [
8
+ "Move plugin store button outside scroll container."
9
+ ]
10
+ },
11
+ "date": "2026-01-23",
12
+ "version": "2.0.0-next.347"
13
+ },
2
14
  {
3
15
  "children": {},
4
16
  "date": "2026-01-23",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.346",
3
+ "version": "2.0.0-next.347",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent 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",
@@ -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;
@@ -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;
@@ -3,8 +3,9 @@
3
3
  import { ENABLE_BUSINESS_FEATURES } from '@lobechat/business-const';
4
4
  import { Button, Flexbox } from '@lobehub/ui';
5
5
  import { Divider } from 'antd';
6
+ import { useTheme } from 'antd-style';
6
7
  import isEqual from 'fast-deep-equal';
7
- import { Clock, PlayIcon } from 'lucide-react';
8
+ import { Clock, PlayIcon, Settings2Icon } from 'lucide-react';
8
9
  import React, { memo, useCallback } from 'react';
9
10
  import { useTranslation } from 'react-i18next';
10
11
  import urlJoin from 'url-join';
@@ -16,6 +17,7 @@ import { agentSelectors } from '@/store/agent/selectors';
16
17
  import { useChatStore } from '@/store/chat';
17
18
 
18
19
  import AgentCronJobs from '../AgentCronJobs';
20
+ import AgentSettings from '../AgentSettings';
19
21
  import EditorCanvas from '../EditorCanvas';
20
22
  import AgentPublishButton from '../Header/AgentPublishButton';
21
23
  import AgentHeader from './AgentHeader';
@@ -23,6 +25,7 @@ import AgentTool from './AgentTool';
23
25
 
24
26
  const ProfileEditor = memo(() => {
25
27
  const { t } = useTranslation('setting');
28
+ const theme = useTheme();
26
29
  const config = useAgentStore(agentSelectors.currentAgentConfig, isEqual);
27
30
  const updateConfig = useAgentStore((s) => s.updateAgentConfig);
28
31
  const agentId = useAgentStore((s) => s.activeAgentId);
@@ -44,7 +47,7 @@ const ProfileEditor = memo(() => {
44
47
  >
45
48
  {/* Header: Avatar + Name + Description */}
46
49
  <AgentHeader />
47
- {/* Config Bar: Model Selector */}
50
+ {/* Config Bar: Model Selector + Settings Button */}
48
51
  <Flexbox
49
52
  align={'center'}
50
53
  gap={8}
@@ -59,6 +62,15 @@ const ProfileEditor = memo(() => {
59
62
  provider: config.provider,
60
63
  }}
61
64
  />
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>
62
74
  </Flexbox>
63
75
  <AgentTool />
64
76
  <Flexbox
@@ -93,6 +105,8 @@ const ProfileEditor = memo(() => {
93
105
  <EditorCanvas />
94
106
  {/* Agent Cron Jobs Display (only show if jobs exist) */}
95
107
  {ENABLE_BUSINESS_FEATURES && <AgentCronJobs />}
108
+ {/* Advanced Settings Modal */}
109
+ <AgentSettings />
96
110
  </>
97
111
  );
98
112
  });
@@ -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,0 +1,36 @@
1
+ 'use client';
2
+
3
+ import { Modal } from '@lobehub/ui';
4
+ import { memo } from 'react';
5
+
6
+ import Content from './Content';
7
+
8
+ interface AgentSettingsProps {
9
+ onCancel: () => void;
10
+ open: boolean;
11
+ }
12
+
13
+ const AgentSettings = memo<AgentSettingsProps>(({ open, onCancel }) => {
14
+ return (
15
+ <Modal
16
+ centered
17
+ footer={null}
18
+ onCancel={onCancel}
19
+ open={open}
20
+ styles={{
21
+ body: {
22
+ height: '60vh',
23
+ overflow: 'scroll',
24
+ padding: 0,
25
+ position: 'relative',
26
+ },
27
+ }}
28
+ title={null}
29
+ width={960}
30
+ >
31
+ <Content />
32
+ </Modal>
33
+ );
34
+ });
35
+
36
+ export default AgentSettings;
@@ -2,8 +2,9 @@
2
2
 
3
3
  import { Button, Flexbox } from '@lobehub/ui';
4
4
  import { Divider } from 'antd';
5
- import { PlayIcon } from 'lucide-react';
6
- import { memo, useCallback, useMemo } from 'react';
5
+ import { useTheme } from 'antd-style';
6
+ import { PlayIcon, Settings2Icon } from 'lucide-react';
7
+ import { memo, useCallback, useMemo, useState } from 'react';
7
8
  import { useTranslation } from 'react-i18next';
8
9
  import urlJoin from 'url-join';
9
10
 
@@ -13,12 +14,15 @@ import { useAgentGroupStore } from '@/store/agentGroup';
13
14
  import { agentGroupSelectors } from '@/store/agentGroup/selectors';
14
15
  import { useGroupProfileStore } from '@/store/groupProfile';
15
16
 
17
+ import AgentSettings from '../AgentSettings';
16
18
  import AutoSaveHint from '../Header/AutoSaveHint';
17
19
  import GroupPublishButton from '../Header/GroupPublishButton';
18
20
  import GroupHeader from './GroupHeader';
19
21
 
20
22
  const GroupProfile = memo(() => {
21
23
  const { t } = useTranslation(['setting', 'chat']);
24
+ const theme = useTheme();
25
+ const [showAgentSetting, setShowAgentSetting] = useState(false);
22
26
  const groupId = useAgentGroupStore(agentGroupSelectors.activeGroupId);
23
27
  const currentGroup = useAgentGroupStore(agentGroupSelectors.currentGroup);
24
28
  const updateGroup = useAgentGroupStore((s) => s.updateGroup);
@@ -86,6 +90,15 @@ const GroupProfile = memo(() => {
86
90
  {t('startConversation')}
87
91
  </Button>
88
92
  <GroupPublishButton />
93
+ <Button
94
+ icon={Settings2Icon}
95
+ onClick={() => setShowAgentSetting(true)}
96
+ size={'small'}
97
+ style={{ color: theme.colorTextSecondary }}
98
+ type={'text'}
99
+ >
100
+ {t('advancedSettings')}
101
+ </Button>
89
102
  </Flexbox>
90
103
  </Flexbox>
91
104
  <Divider />
@@ -97,6 +110,8 @@ const GroupProfile = memo(() => {
97
110
  onContentChange={onContentChange}
98
111
  placeholder={t('group.profile.contentPlaceholder', { ns: 'chat' })}
99
112
  />
113
+ {/* Advanced Settings Modal */}
114
+ <AgentSettings onCancel={() => setShowAgentSetting(false)} open={showAgentSetting} />
100
115
  </>
101
116
  );
102
117
  });
@@ -86,13 +86,14 @@ const OpeningQuestions = memo(() => {
86
86
  const isRepeat = openingQuestions.includes(questionInput.trim());
87
87
 
88
88
  return (
89
- <Flexbox gap={8}>
90
- <Flexbox gap={4}>
91
- <Space.Compact>
89
+ <Flexbox gap={8} width={'100%'}>
90
+ <Flexbox gap={4} width={'100%'}>
91
+ <Space.Compact style={{ width: '100%' }}>
92
92
  <Input
93
93
  onChange={(e) => setQuestionInput(e.target.value)}
94
94
  onPressEnter={addQuestion}
95
95
  placeholder={t('settingOpening.openingQuestions.placeholder')}
96
+ style={{ flex: 1 }}
96
97
  value={questionInput}
97
98
  />
98
99
  <Button
@@ -4,8 +4,6 @@ import { Form } from '@lobehub/ui';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
- import { FORM_STYLE } from '@/const/layoutTokens';
8
-
9
7
  import OpeningMessage from './OpeningMessage';
10
8
  import OpeningQuestions from './OpeningQuestions';
11
9
 
@@ -44,7 +42,6 @@ const AgentOpening = memo(() => {
44
42
  ]}
45
43
  itemsType={'group'}
46
44
  variant={'borderless'}
47
- {...FORM_STYLE}
48
45
  />
49
46
  );
50
47
  });
@@ -35,6 +35,7 @@ import { type LobeToolMetaWithAvailability } from '@/store/tool/slices/builtin/s
35
35
 
36
36
  import PluginTag from './PluginTag';
37
37
 
38
+
38
39
  const WEB_BROWSING_IDENTIFIER = 'lobe-web-browsing';
39
40
 
40
41
  type TabType = 'all' | 'installed';
@@ -44,13 +45,7 @@ const prefixCls = 'ant';
44
45
  const styles = createStaticStyles(({ css }) => ({
45
46
  dropdown: css`
46
47
  overflow: hidden;
47
-
48
48
  width: 100%;
49
- border: 1px solid ${cssVar.colorBorderSecondary};
50
- border-radius: ${cssVar.borderRadiusLG};
51
-
52
- background: ${cssVar.colorBgElevated};
53
- box-shadow: ${cssVar.boxShadowSecondary};
54
49
 
55
50
  .${prefixCls}-dropdown-menu {
56
51
  border-radius: 0 !important;
@@ -339,7 +334,7 @@ const AgentTool = memo<AgentToolProps>(
339
334
  () => [
340
335
  // 原有的 builtin 工具
341
336
  ...filteredBuiltinList.map((item) => ({
342
- icon: <Avatar avatar={item.meta.avatar} size={20} style={{ flex: 'none' }} />,
337
+ icon: <Avatar avatar={item.meta.avatar} size={20} style={{ flex: 'none', marginRight: 0 }} />,
343
338
  key: item.identifier,
344
339
  label: (
345
340
  <ToolItem
@@ -412,18 +407,6 @@ const AgentTool = memo<AgentToolProps>(
412
407
  ),
413
408
  type: 'group',
414
409
  },
415
- {
416
- type: 'divider',
417
- },
418
- {
419
- extra: <Icon icon={ArrowRight} />,
420
- icon: Store,
421
- key: 'plugin-store',
422
- label: t('tools.plugins.store'),
423
- onClick: () => {
424
- createSkillStoreModal();
425
- },
426
- },
427
410
  ],
428
411
  [builtinItems, pluginItems, enablePluginCount, t],
429
412
  );
@@ -557,7 +540,6 @@ const AgentTool = memo<AgentToolProps>(
557
540
  {/* Plugin Selector Dropdown - Using Action component pattern */}
558
541
  <Suspense fallback={button}>
559
542
  <ActionDropdown
560
- maxHeight={500}
561
543
  maxWidth={400}
562
544
  menu={{
563
545
  items: currentItems,
@@ -567,11 +549,10 @@ const AgentTool = memo<AgentToolProps>(
567
549
  overflowY: 'visible',
568
550
  },
569
551
  }}
570
- minHeight={isKlavisEnabledInEnv || isLobehubSkillEnabled ? 500 : undefined}
571
552
  minWidth={400}
572
553
  placement={'bottomLeft'}
573
554
  popupRender={(menu) => (
574
- <div className={styles.dropdown}>
555
+ <Flexbox className={styles.dropdown} style={{ maxHeight: 500 }}>
575
556
  {/* stopPropagation prevents dropdown's onClick from calling preventDefault on Segmented */}
576
557
  <div className={styles.header} onClick={(e) => e.stopPropagation()}>
577
558
  <Segmented
@@ -591,16 +572,26 @@ const AgentTool = memo<AgentToolProps>(
591
572
  value={effectiveTab}
592
573
  />
593
574
  </div>
594
- <div
595
- className={styles.scroller}
575
+ <div className={styles.scroller} style={{ flex: 1 }}>
576
+ {menu}
577
+ </div>
578
+ <Flexbox
579
+ align="center"
580
+ gap={8}
581
+ horizontal
582
+ onClick={() => createSkillStoreModal()}
596
583
  style={{
597
- maxHeight: 500,
598
- minHeight: isKlavisEnabledInEnv || isLobehubSkillEnabled ? 500 : undefined,
584
+ borderBlockStart: `1px solid ${cssVar.colorBorderSecondary}`,
585
+ cursor: 'pointer',
586
+ flex: 'none',
587
+ padding: cssVar.paddingSM,
599
588
  }}
600
589
  >
601
- {menu}
602
- </div>
603
- </div>
590
+ <Icon icon={Store} />
591
+ <span style={{ flex: 1 }}>{t('tools.plugins.store')}</span>
592
+ <Icon icon={ArrowRight} />
593
+ </Flexbox>
594
+ </Flexbox>
604
595
  )}
605
596
  trigger={'click'}
606
597
  >