@lobehub/lobehub 2.0.0-next.187 → 2.0.0-next.189

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.
Files changed (177) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/e2e/CLAUDE.md +109 -2
  4. package/e2e/docs/llm-mock.md +68 -0
  5. package/e2e/docs/local-setup.md +354 -0
  6. package/e2e/docs/testing-tips.md +94 -0
  7. package/e2e/src/features/journeys/agent/agent-conversation.feature +0 -32
  8. package/e2e/src/mocks/llm/index.ts +6 -6
  9. package/e2e/src/steps/agent/conversation.steps.ts +3 -471
  10. package/locales/ar/models.json +89 -5
  11. package/locales/ar/plugin.json +5 -0
  12. package/locales/ar/providers.json +1 -0
  13. package/locales/bg-BG/models.json +68 -0
  14. package/locales/bg-BG/plugin.json +5 -0
  15. package/locales/bg-BG/providers.json +1 -0
  16. package/locales/de-DE/models.json +85 -0
  17. package/locales/de-DE/plugin.json +5 -0
  18. package/locales/de-DE/providers.json +1 -0
  19. package/locales/en-US/models.json +11 -10
  20. package/locales/en-US/plugin.json +5 -0
  21. package/locales/en-US/providers.json +1 -0
  22. package/locales/es-ES/models.json +72 -0
  23. package/locales/es-ES/plugin.json +5 -0
  24. package/locales/es-ES/providers.json +1 -0
  25. package/locales/fa-IR/models.json +86 -0
  26. package/locales/fa-IR/plugin.json +5 -0
  27. package/locales/fa-IR/providers.json +1 -0
  28. package/locales/fr-FR/models.json +49 -0
  29. package/locales/fr-FR/plugin.json +5 -0
  30. package/locales/fr-FR/providers.json +1 -0
  31. package/locales/it-IT/models.json +82 -0
  32. package/locales/it-IT/plugin.json +5 -0
  33. package/locales/it-IT/providers.json +1 -0
  34. package/locales/ja-JP/models.json +42 -5
  35. package/locales/ja-JP/plugin.json +5 -0
  36. package/locales/ja-JP/providers.json +1 -0
  37. package/locales/ko-KR/models.json +54 -0
  38. package/locales/ko-KR/plugin.json +5 -0
  39. package/locales/ko-KR/providers.json +1 -0
  40. package/locales/nl-NL/models.json +12 -1
  41. package/locales/nl-NL/plugin.json +5 -0
  42. package/locales/nl-NL/providers.json +1 -0
  43. package/locales/pl-PL/models.json +46 -0
  44. package/locales/pl-PL/plugin.json +5 -0
  45. package/locales/pl-PL/providers.json +1 -0
  46. package/locales/pt-BR/models.json +59 -0
  47. package/locales/pt-BR/plugin.json +5 -0
  48. package/locales/pt-BR/providers.json +1 -0
  49. package/locales/ru-RU/models.json +85 -0
  50. package/locales/ru-RU/plugin.json +5 -0
  51. package/locales/ru-RU/providers.json +1 -0
  52. package/locales/tr-TR/models.json +81 -0
  53. package/locales/tr-TR/plugin.json +5 -0
  54. package/locales/tr-TR/providers.json +1 -0
  55. package/locales/vi-VN/models.json +54 -0
  56. package/locales/vi-VN/plugin.json +5 -0
  57. package/locales/vi-VN/providers.json +1 -0
  58. package/locales/zh-CN/models.json +42 -5
  59. package/locales/zh-CN/plugin.json +5 -0
  60. package/locales/zh-CN/providers.json +1 -0
  61. package/locales/zh-TW/models.json +85 -0
  62. package/locales/zh-TW/plugin.json +5 -0
  63. package/locales/zh-TW/providers.json +1 -0
  64. package/package.json +2 -2
  65. package/packages/builtin-tool-gtd/src/manifest.ts +13 -8
  66. package/packages/builtin-tool-gtd/src/systemRole.ts +54 -19
  67. package/packages/builtin-tool-knowledge-base/package.json +1 -0
  68. package/packages/builtin-tool-knowledge-base/src/client/Inspector/ReadKnowledge/index.tsx +97 -0
  69. package/packages/builtin-tool-knowledge-base/src/client/Inspector/SearchKnowledgeBase/index.tsx +75 -0
  70. package/packages/builtin-tool-knowledge-base/src/client/Inspector/index.ts +11 -0
  71. package/packages/builtin-tool-knowledge-base/src/client/Render/ReadKnowledge/FileCard.tsx +12 -12
  72. package/packages/builtin-tool-knowledge-base/src/client/Render/ReadKnowledge/index.tsx +16 -25
  73. package/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx +21 -47
  74. package/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/index.tsx +19 -31
  75. package/packages/builtin-tool-knowledge-base/src/client/Render/index.ts +0 -5
  76. package/packages/builtin-tool-knowledge-base/src/client/index.ts +5 -1
  77. package/packages/builtin-tool-knowledge-base/src/executor/index.ts +119 -0
  78. package/packages/builtin-tool-local-system/package.json +1 -0
  79. package/packages/builtin-tool-local-system/src/client/Inspector/EditLocalFile/index.tsx +44 -29
  80. package/packages/builtin-tool-local-system/src/client/Inspector/GrepContent/index.tsx +20 -18
  81. package/packages/builtin-tool-local-system/src/client/Inspector/ListLocalFiles/index.tsx +76 -0
  82. package/packages/builtin-tool-local-system/src/client/Inspector/ReadLocalFile/index.tsx +8 -32
  83. package/packages/builtin-tool-local-system/src/client/Inspector/RenameLocalFile/index.tsx +62 -0
  84. package/packages/builtin-tool-local-system/src/client/Inspector/SearchLocalFiles/index.tsx +17 -11
  85. package/packages/builtin-tool-local-system/src/client/Inspector/WriteLocalFile/index.tsx +61 -0
  86. package/packages/builtin-tool-local-system/src/client/Inspector/index.ts +6 -0
  87. package/packages/builtin-tool-local-system/src/client/Render/EditLocalFile/index.tsx +6 -1
  88. package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/SearchView.tsx +19 -31
  89. package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/index.tsx +2 -42
  90. package/packages/builtin-tool-local-system/src/client/Render/index.ts +0 -2
  91. package/packages/builtin-tool-local-system/src/client/components/FilePathDisplay.tsx +56 -0
  92. package/packages/builtin-tool-local-system/src/client/components/index.ts +2 -0
  93. package/packages/builtin-tool-local-system/src/executor/index.ts +435 -0
  94. package/packages/builtin-tool-web-browsing/src/client/Inspector/Search/index.tsx +32 -5
  95. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +84 -0
  96. package/packages/model-runtime/src/core/contextBuilders/google.ts +37 -1
  97. package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/Actions.tsx +4 -13
  98. package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/index.tsx +23 -29
  99. package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/useDropdownMenu.tsx +3 -3
  100. package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/Actions.tsx +4 -13
  101. package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/index.tsx +10 -18
  102. package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/useDropdownMenu.tsx +3 -3
  103. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Sidebar/ActionButton/AddAgent.tsx +47 -27
  104. package/src/app/[variants]/(main)/community/(detail)/user/features/UserAgentCard.tsx +4 -3
  105. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/Actions.tsx +4 -13
  106. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/index.tsx +23 -29
  107. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/useDropdownMenu.tsx +3 -3
  108. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/Actions.tsx +4 -13
  109. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/index.tsx +10 -18
  110. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/useDropdownMenu.tsx +3 -3
  111. package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/TopicSelector.tsx +18 -20
  112. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/AgentGroupItem/index.tsx +19 -25
  113. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/AgentItem/index.tsx +21 -26
  114. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/Item/Actions.tsx +4 -13
  115. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/Item/useDropdownMenu.tsx +3 -3
  116. package/src/app/[variants]/(main)/home/_layout/Body/Project/List/Actions.tsx +4 -13
  117. package/src/app/[variants]/(main)/home/_layout/Body/Project/List/Item.tsx +8 -15
  118. package/src/app/[variants]/(main)/home/_layout/Body/Project/List/useDropdownMenu.tsx +3 -3
  119. package/src/app/[variants]/(main)/home/_layout/Header/components/AddButton.tsx +3 -4
  120. package/src/app/[variants]/(main)/page/_layout/Body/List/Item/Actions.tsx +4 -13
  121. package/src/app/[variants]/(main)/page/_layout/Body/List/Item/index.tsx +13 -20
  122. package/src/app/[variants]/(main)/page/_layout/Body/List/Item/useDropdownMenu.tsx +3 -3
  123. package/src/app/[variants]/(main)/resource/(home)/_layout/Body/LibraryList/List/Item/Actions.tsx +4 -13
  124. package/src/app/[variants]/(main)/resource/(home)/_layout/Body/LibraryList/List/Item/index.tsx +16 -23
  125. package/src/app/[variants]/(main)/resource/(home)/_layout/Body/LibraryList/List/Item/useDropdownMenu.tsx +3 -3
  126. package/src/app/[variants]/(main)/resource/library/_layout/Header/LibraryHead.tsx +4 -6
  127. package/src/features/AgentBuilder/TopicSelector.tsx +18 -17
  128. package/src/features/Conversation/ChatItem/style.ts +7 -0
  129. package/src/features/Conversation/Messages/Assistant/Actions/Error.tsx +1 -3
  130. package/src/features/Conversation/Messages/Assistant/Actions/index.tsx +37 -16
  131. package/src/features/Conversation/Messages/AssistantGroup/Actions/index.tsx +36 -17
  132. package/src/features/Conversation/Messages/Supervisor/Actions/index.tsx +36 -17
  133. package/src/features/Conversation/Messages/Task/Actions/Error.tsx +1 -3
  134. package/src/features/Conversation/Messages/Task/Actions/index.tsx +31 -15
  135. package/src/features/Conversation/Messages/User/Actions/index.tsx +1 -1
  136. package/src/features/Conversation/Messages/index.tsx +8 -59
  137. package/src/features/Conversation/components/ShareMessageModal/index.tsx +1 -1
  138. package/src/features/Conversation/hooks/useChatItemContextMenu.tsx +313 -83
  139. package/src/features/NavPanel/components/NavItem.tsx +33 -3
  140. package/src/features/PageEditor/Copilot/TopicSelector/Actions.tsx +6 -14
  141. package/src/features/PageEditor/Copilot/TopicSelector/TopicItem.tsx +1 -0
  142. package/src/features/PageEditor/Copilot/TopicSelector/useDropdownMenu.tsx +6 -3
  143. package/src/features/ResourceManager/components/Explorer/ItemDropdown/DropdownMenu.tsx +12 -35
  144. package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +4 -8
  145. package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +162 -160
  146. package/src/features/ResourceManager/components/Explorer/MasonryView/MasonryFileItem/index.tsx +16 -8
  147. package/src/features/ResourceManager/components/Explorer/ToolBar/ActionIconWithChevron.tsx +4 -3
  148. package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +6 -12
  149. package/src/features/ResourceManager/components/Explorer/ToolBar/SortDropdown.tsx +8 -8
  150. package/src/features/ResourceManager/components/Explorer/ToolBar/ViewSwitcher.tsx +8 -11
  151. package/src/features/ResourceManager/components/Tree/index.tsx +121 -122
  152. package/src/helpers/toolEngineering/index.ts +1 -1
  153. package/src/layout/GlobalProvider/index.tsx +5 -2
  154. package/src/locales/default/plugin.ts +6 -0
  155. package/src/server/modules/Mecha/AgentToolsEngine/__tests__/index.test.ts +1 -1
  156. package/src/server/modules/Mecha/AgentToolsEngine/index.ts +1 -1
  157. package/src/store/chat/slices/builtinTool/actions/index.ts +1 -11
  158. package/src/store/tool/slices/builtin/executors/index.ts +4 -0
  159. package/src/styles/global.ts +6 -0
  160. package/src/styles/text.ts +1 -1
  161. package/src/tools/executionRuntimes.ts +3 -8
  162. package/src/tools/identifiers.ts +1 -1
  163. package/src/tools/index.ts +1 -1
  164. package/src/tools/inspectors.ts +5 -0
  165. package/src/tools/renders.ts +6 -12
  166. package/packages/builtin-tool-local-system/src/client/Render/RenameLocalFile/index.tsx +0 -37
  167. package/src/features/Conversation/components/ContextMenu.tsx +0 -418
  168. package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +0 -201
  169. package/src/store/chat/slices/builtinTool/actions/knowledgeBase.ts +0 -163
  170. package/src/store/chat/slices/builtinTool/actions/localSystem.ts +0 -241
  171. package/src/tools/knowledge-base/ExecutionRuntime/index.ts +0 -25
  172. package/src/tools/knowledge-base/Render/ReadKnowledge/index.tsx +0 -29
  173. package/src/tools/knowledge-base/Render/SearchKnowledgeBase/index.tsx +0 -29
  174. package/src/tools/knowledge-base/Render/index.ts +0 -7
  175. package/src/tools/knowledge-base/index.ts +0 -12
  176. package/src/tools/local-system/ExecutionRuntime/index.ts +0 -9
  177. package/src/tools/local-system/systemRole.ts +0 -1
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Dropdown, Flexbox, Icon, Skeleton, Tag } from '@lobehub/ui';
1
+ import { ActionIcon, Flexbox, Icon, Skeleton, Tag } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { MessageSquareDashed, Star } from 'lucide-react';
4
4
  import { Suspense, memo, useCallback } from 'react';
@@ -92,34 +92,28 @@ const TopicItem = memo<TopicItemProps>(({ id, title, fav, active, threadId }) =>
92
92
 
93
93
  return (
94
94
  <Flexbox style={{ position: 'relative' }}>
95
- <Dropdown
96
- menu={{
97
- items: dropdownMenu,
98
- }}
99
- trigger={['contextMenu']}
100
- >
101
- <NavItem
102
- actions={<Actions dropdownMenu={dropdownMenu} />}
103
- active={active && !threadId && !isInAgentSubRoute}
104
- disabled={editing}
105
- icon={
106
- <ActionIcon
107
- color={fav ? cssVar.colorWarning : undefined}
108
- fill={fav ? cssVar.colorWarning : 'transparent'}
109
- icon={Star}
110
- onClick={(e) => {
111
- e.stopPropagation();
112
- favoriteTopic(id, !fav);
113
- }}
114
- size={'small'}
115
- />
116
- }
117
- loading={isLoading}
118
- onClick={handleClick}
119
- onDoubleClick={handleDoubleClick}
120
- title={title}
121
- />
122
- </Dropdown>
95
+ <NavItem
96
+ actions={<Actions dropdownMenu={dropdownMenu} />}
97
+ active={active && !threadId && !isInAgentSubRoute}
98
+ contextMenuItems={dropdownMenu}
99
+ disabled={editing}
100
+ icon={
101
+ <ActionIcon
102
+ color={fav ? cssVar.colorWarning : undefined}
103
+ fill={fav ? cssVar.colorWarning : 'transparent'}
104
+ icon={Star}
105
+ onClick={(e) => {
106
+ e.stopPropagation();
107
+ favoriteTopic(id, !fav);
108
+ }}
109
+ size={'small'}
110
+ />
111
+ }
112
+ loading={isLoading}
113
+ onClick={handleClick}
114
+ onDoubleClick={handleDoubleClick}
115
+ title={title}
116
+ />
123
117
  <Editing id={id} title={title} toggleEditing={toggleEditing} />
124
118
  {active && (
125
119
  <Suspense
@@ -1,7 +1,7 @@
1
1
  import { Icon, type MenuProps } from '@lobehub/ui';
2
2
  import { App } from 'antd';
3
3
  import { ExternalLink, LucideCopy, PencilLine, Trash, Wand2 } from 'lucide-react';
4
- import { useMemo } from 'react';
4
+ import { useCallback } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { isDesktop } from '@/const/version';
@@ -17,7 +17,7 @@ interface TopicItemDropdownMenuProps {
17
17
  export const useTopicItemDropdownMenu = ({
18
18
  id,
19
19
  toggleEditing,
20
- }: TopicItemDropdownMenuProps): MenuProps['items'] => {
20
+ }: TopicItemDropdownMenuProps): (() => MenuProps['items']) => {
21
21
  const { t } = useTranslation(['topic', 'common']);
22
22
  const { modal } = App.useApp();
23
23
 
@@ -30,7 +30,7 @@ export const useTopicItemDropdownMenu = ({
30
30
  s.removeTopic,
31
31
  ]);
32
32
 
33
- return useMemo(() => {
33
+ return useCallback(() => {
34
34
  if (!id) return [];
35
35
 
36
36
  return [
@@ -1,25 +1,16 @@
1
- import { ActionIcon, Dropdown, type MenuProps } from '@lobehub/ui';
1
+ import { ActionIcon, type DropdownItem, DropdownMenu } from '@lobehub/ui';
2
2
  import { MoreHorizontalIcon } from 'lucide-react';
3
3
  import { memo } from 'react';
4
4
 
5
5
  interface ActionProps {
6
- dropdownMenu: MenuProps['items'];
6
+ dropdownMenu: DropdownItem[] | (() => DropdownItem[]);
7
7
  }
8
8
 
9
9
  const Actions = memo<ActionProps>(({ dropdownMenu }) => {
10
10
  return (
11
- <Dropdown
12
- arrow={false}
13
- menu={{
14
- items: dropdownMenu,
15
- onClick: ({ domEvent }) => {
16
- domEvent.stopPropagation();
17
- },
18
- }}
19
- trigger={['click']}
20
- >
11
+ <DropdownMenu items={dropdownMenu}>
21
12
  <ActionIcon icon={MoreHorizontalIcon} size={'small'} />
22
- </Dropdown>
13
+ </DropdownMenu>
23
14
  );
24
15
  });
25
16
 
@@ -1,4 +1,4 @@
1
- import { Dropdown, Icon } from '@lobehub/ui';
1
+ import { Icon } from '@lobehub/ui';
2
2
  import { TreeDownRightIcon } from '@lobehub/ui/icons';
3
3
  import { cssVar } from 'antd-style';
4
4
  import { memo, useCallback } from 'react';
@@ -46,23 +46,15 @@ const ThreadItem = memo<ThreadItemProps>(({ title, id }) => {
46
46
 
47
47
  return (
48
48
  <>
49
- <Dropdown
50
- menu={{
51
- items: dropdownMenu,
52
- }}
53
- trigger={['contextMenu']}
54
- >
55
- <NavItem
56
- actions={<Actions dropdownMenu={dropdownMenu} />}
57
- active={active && !isInAgentSubRoute}
58
- disabled={editing}
59
- icon={
60
- <Icon color={cssVar.colorTextDescription} icon={TreeDownRightIcon} size={'small'} />
61
- }
62
- onClick={handleClick}
63
- title={title}
64
- />
65
- </Dropdown>
49
+ <NavItem
50
+ actions={<Actions dropdownMenu={dropdownMenu} />}
51
+ active={active && !isInAgentSubRoute}
52
+ contextMenuItems={dropdownMenu}
53
+ disabled={editing}
54
+ icon={<Icon color={cssVar.colorTextDescription} icon={TreeDownRightIcon} size={'small'} />}
55
+ onClick={handleClick}
56
+ title={title}
57
+ />
66
58
  <Editing id={id} title={title} toggleEditing={toggleEditing} />
67
59
  </>
68
60
  );
@@ -1,7 +1,7 @@
1
1
  import { Icon, type MenuProps } from '@lobehub/ui';
2
2
  import { App } from 'antd';
3
3
  import { PencilLine, Trash } from 'lucide-react';
4
- import { useMemo } from 'react';
4
+ import { useCallback } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { useChatStore } from '@/store/chat';
@@ -14,13 +14,13 @@ interface ThreadItemDropdownMenuProps {
14
14
  export const useThreadItemDropdownMenu = ({
15
15
  id,
16
16
  toggleEditing,
17
- }: ThreadItemDropdownMenuProps): MenuProps['items'] => {
17
+ }: ThreadItemDropdownMenuProps): (() => MenuProps['items']) => {
18
18
  const { t } = useTranslation(['thread', 'common']);
19
19
  const { modal } = App.useApp();
20
20
 
21
21
  const [removeThread] = useChatStore((s) => [s.removeThread]);
22
22
 
23
- return useMemo(() => {
23
+ return useCallback(() => {
24
24
  return [
25
25
  {
26
26
  icon: <Icon icon={PencilLine} />,
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { Icon } from '@lobehub/ui';
4
- import { App, Dropdown } from 'antd';
3
+ import { Button, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
4
+ import { App } from 'antd';
5
5
  import { createStaticStyles } from 'antd-style';
6
6
  import { ChevronDownIcon } from 'lucide-react';
7
7
  import { memo, useState } from 'react';
@@ -17,10 +17,17 @@ import { useHomeStore } from '@/store/home';
17
17
  import { useDetailContext } from '../../DetailProvider';
18
18
 
19
19
  const styles = createStaticStyles(({ css }) => ({
20
- button: css`
21
- button {
22
- width: 100%;
23
- }
20
+ buttonGroup: css`
21
+ width: 100%;
22
+ `,
23
+ menuButton: css`
24
+ padding-inline: 8px;
25
+ border-start-start-radius: 0 !important;
26
+ border-end-start-radius: 0 !important;
27
+ `,
28
+ primaryButton: css`
29
+ border-start-end-radius: 0 !important;
30
+ border-end-end-radius: 0 !important;
24
31
  `,
25
32
  }));
26
33
 
@@ -127,28 +134,41 @@ const AddAgent = memo<{ mobile?: boolean }>(({ mobile }) => {
127
134
  }
128
135
  };
129
136
 
137
+ const menuItems = [
138
+ {
139
+ key: 'addAgent',
140
+ label: t('assistants.addAgent'),
141
+ onClick: handleAddAgent,
142
+ },
143
+ ];
144
+
130
145
  return (
131
- <Dropdown.Button
132
- className={styles.button}
133
- icon={<Icon icon={ChevronDownIcon} />}
134
- loading={isLoading}
135
- menu={{
136
- items: [
137
- {
138
- key: 'addAgent',
139
- label: t('assistants.addAgent'),
140
- onClick: handleAddAgent,
141
- },
142
- ],
143
- }}
144
- onClick={handleAddAgentAndConverse}
145
- overlayStyle={{ minWidth: 267 }}
146
- size={'large'}
147
- style={{ flex: 1, width: 'unset' }}
148
- type={'primary'}
149
- >
150
- {t('assistants.addAgentAndConverse')}
151
- </Dropdown.Button>
146
+ <Flexbox className={styles.buttonGroup} gap={0} horizontal>
147
+ <Button
148
+ block
149
+ className={styles.primaryButton}
150
+ loading={isLoading}
151
+ onClick={handleAddAgentAndConverse}
152
+ size={'large'}
153
+ style={{ flex: 1, width: 'unset' }}
154
+ type={'primary'}
155
+ >
156
+ {t('assistants.addAgentAndConverse')}
157
+ </Button>
158
+ <DropdownMenu
159
+ items={menuItems}
160
+ popupProps={{ style: { minWidth: 267 } }}
161
+ triggerProps={{ disabled: isLoading }}
162
+ >
163
+ <Button
164
+ className={styles.menuButton}
165
+ disabled={isLoading}
166
+ icon={<Icon icon={ChevronDownIcon} />}
167
+ size={'large'}
168
+ type={'primary'}
169
+ />
170
+ </DropdownMenu>
171
+ </Flexbox>
152
172
  );
153
173
  });
154
174
 
@@ -4,6 +4,7 @@ import {
4
4
  Tag as AntTag,
5
5
  Avatar,
6
6
  Block,
7
+ DropdownMenu,
7
8
  Flexbox,
8
9
  Icon,
9
10
  Tag,
@@ -11,7 +12,7 @@ import {
11
12
  Tooltip,
12
13
  TooltipGroup,
13
14
  } from '@lobehub/ui';
14
- import { App, Dropdown } from 'antd';
15
+ import { App } from 'antd';
15
16
  import { createStaticStyles, cx } from 'antd-style';
16
17
  import {
17
18
  AlertTriangle,
@@ -258,14 +259,14 @@ const UserAgentCard = memo<UserAgentCardProps>(
258
259
  width={'100%'}
259
260
  >
260
261
  {isOwner && (
261
- <Dropdown menu={{ items: menuItems }} trigger={['click']}>
262
+ <DropdownMenu items={menuItems}>
262
263
  <div
263
264
  className={cx('more-button', styles.moreButton)}
264
265
  onClick={(e) => e.stopPropagation()}
265
266
  >
266
267
  <Icon icon={MoreVerticalIcon} size={16} style={{ cursor: 'pointer' }} />
267
268
  </div>
268
- </Dropdown>
269
+ </DropdownMenu>
269
270
  )}
270
271
  <Flexbox
271
272
  align={'flex-start'}
@@ -1,25 +1,16 @@
1
- import { ActionIcon, Dropdown, type MenuProps } from '@lobehub/ui';
1
+ import { ActionIcon, type DropdownItem, DropdownMenu } from '@lobehub/ui';
2
2
  import { MoreHorizontalIcon } from 'lucide-react';
3
3
  import { memo } from 'react';
4
4
 
5
5
  interface ActionProps {
6
- dropdownMenu: MenuProps['items'];
6
+ dropdownMenu: DropdownItem[] | (() => DropdownItem[]);
7
7
  }
8
8
 
9
9
  const Actions = memo<ActionProps>(({ dropdownMenu }) => {
10
10
  return (
11
- <Dropdown
12
- arrow={false}
13
- menu={{
14
- items: dropdownMenu,
15
- onClick: ({ domEvent }) => {
16
- domEvent.stopPropagation();
17
- },
18
- }}
19
- trigger={['click']}
20
- >
11
+ <DropdownMenu items={dropdownMenu}>
21
12
  <ActionIcon icon={MoreHorizontalIcon} size={'small'} />
22
- </Dropdown>
13
+ </DropdownMenu>
23
14
  );
24
15
  });
25
16
 
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Dropdown, Flexbox, Icon, Skeleton, Tag } from '@lobehub/ui';
1
+ import { ActionIcon, Flexbox, Icon, Skeleton, Tag } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { MessageSquareDashed, Star } from 'lucide-react';
4
4
  import { Suspense, memo, useCallback } from 'react';
@@ -92,34 +92,28 @@ const TopicItem = memo<TopicItemProps>(({ id, title, fav, active, threadId }) =>
92
92
 
93
93
  return (
94
94
  <Flexbox style={{ position: 'relative' }}>
95
- <Dropdown
96
- menu={{
97
- items: dropdownMenu,
98
- }}
99
- trigger={['contextMenu']}
100
- >
101
- <NavItem
102
- actions={<Actions dropdownMenu={dropdownMenu} />}
103
- active={active && !threadId && !isInAgentSubRoute}
104
- disabled={editing}
105
- icon={
106
- <ActionIcon
107
- color={fav ? cssVar.colorWarning : undefined}
108
- fill={fav ? cssVar.colorWarning : 'transparent'}
109
- icon={Star}
110
- onClick={(e) => {
111
- e.stopPropagation();
112
- favoriteTopic(id, !fav);
113
- }}
114
- size={'small'}
115
- />
116
- }
117
- loading={isLoading}
118
- onClick={handleClick}
119
- onDoubleClick={handleDoubleClick}
120
- title={title}
121
- />
122
- </Dropdown>
95
+ <NavItem
96
+ actions={<Actions dropdownMenu={dropdownMenu} />}
97
+ active={active && !threadId && !isInAgentSubRoute}
98
+ contextMenuItems={dropdownMenu}
99
+ disabled={editing}
100
+ icon={
101
+ <ActionIcon
102
+ color={fav ? cssVar.colorWarning : undefined}
103
+ fill={fav ? cssVar.colorWarning : 'transparent'}
104
+ icon={Star}
105
+ onClick={(e) => {
106
+ e.stopPropagation();
107
+ favoriteTopic(id, !fav);
108
+ }}
109
+ size={'small'}
110
+ />
111
+ }
112
+ loading={isLoading}
113
+ onClick={handleClick}
114
+ onDoubleClick={handleDoubleClick}
115
+ title={title}
116
+ />
123
117
  <Editing id={id} title={title} toggleEditing={toggleEditing} />
124
118
  {active && (
125
119
  <Suspense
@@ -1,7 +1,7 @@
1
1
  import { Icon, type MenuProps } from '@lobehub/ui';
2
2
  import { App } from 'antd';
3
3
  import { ExternalLink, LucideCopy, PencilLine, Trash, Wand2 } from 'lucide-react';
4
- import { useMemo } from 'react';
4
+ import { useCallback } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { isDesktop } from '@/const/version';
@@ -17,7 +17,7 @@ interface TopicItemDropdownMenuProps {
17
17
  export const useTopicItemDropdownMenu = ({
18
18
  id,
19
19
  toggleEditing,
20
- }: TopicItemDropdownMenuProps): MenuProps['items'] => {
20
+ }: TopicItemDropdownMenuProps): (() => MenuProps['items']) => {
21
21
  const { t } = useTranslation(['topic', 'common']);
22
22
  const { modal } = App.useApp();
23
23
 
@@ -30,7 +30,7 @@ export const useTopicItemDropdownMenu = ({
30
30
  s.removeTopic,
31
31
  ]);
32
32
 
33
- return useMemo(() => {
33
+ return useCallback(() => {
34
34
  if (!id) return [];
35
35
 
36
36
  return [
@@ -1,25 +1,16 @@
1
- import { ActionIcon, Dropdown, type MenuProps } from '@lobehub/ui';
1
+ import { ActionIcon, type DropdownItem, DropdownMenu } from '@lobehub/ui';
2
2
  import { MoreHorizontalIcon } from 'lucide-react';
3
3
  import { memo } from 'react';
4
4
 
5
5
  interface ActionProps {
6
- dropdownMenu: MenuProps['items'];
6
+ dropdownMenu: DropdownItem[] | (() => DropdownItem[]);
7
7
  }
8
8
 
9
9
  const Actions = memo<ActionProps>(({ dropdownMenu }) => {
10
10
  return (
11
- <Dropdown
12
- arrow={false}
13
- menu={{
14
- items: dropdownMenu,
15
- onClick: ({ domEvent }) => {
16
- domEvent.stopPropagation();
17
- },
18
- }}
19
- trigger={['click']}
20
- >
11
+ <DropdownMenu items={dropdownMenu}>
21
12
  <ActionIcon icon={MoreHorizontalIcon} size={'small'} />
22
- </Dropdown>
13
+ </DropdownMenu>
23
14
  );
24
15
  });
25
16
 
@@ -1,4 +1,4 @@
1
- import { Dropdown, Icon } from '@lobehub/ui';
1
+ import { Icon } from '@lobehub/ui';
2
2
  import { TreeDownRightIcon } from '@lobehub/ui/icons';
3
3
  import { cssVar } from 'antd-style';
4
4
  import { memo, useCallback } from 'react';
@@ -46,23 +46,15 @@ const ThreadItem = memo<ThreadItemProps>(({ title, id }) => {
46
46
 
47
47
  return (
48
48
  <>
49
- <Dropdown
50
- menu={{
51
- items: dropdownMenu,
52
- }}
53
- trigger={['contextMenu']}
54
- >
55
- <NavItem
56
- actions={<Actions dropdownMenu={dropdownMenu} />}
57
- active={active && !isInAgentSubRoute}
58
- disabled={editing}
59
- icon={
60
- <Icon color={cssVar.colorTextDescription} icon={TreeDownRightIcon} size={'small'} />
61
- }
62
- onClick={handleClick}
63
- title={title}
64
- />
65
- </Dropdown>
49
+ <NavItem
50
+ actions={<Actions dropdownMenu={dropdownMenu} />}
51
+ active={active && !isInAgentSubRoute}
52
+ contextMenuItems={dropdownMenu}
53
+ disabled={editing}
54
+ icon={<Icon color={cssVar.colorTextDescription} icon={TreeDownRightIcon} size={'small'} />}
55
+ onClick={handleClick}
56
+ title={title}
57
+ />
66
58
  <Editing id={id} title={title} toggleEditing={toggleEditing} />
67
59
  </>
68
60
  );
@@ -1,7 +1,7 @@
1
1
  import { Icon, type MenuProps } from '@lobehub/ui';
2
2
  import { App } from 'antd';
3
3
  import { PencilLine, Trash } from 'lucide-react';
4
- import { useMemo } from 'react';
4
+ import { useCallback } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { useChatStore } from '@/store/chat';
@@ -14,13 +14,13 @@ interface ThreadItemDropdownMenuProps {
14
14
  export const useThreadItemDropdownMenu = ({
15
15
  id,
16
16
  toggleEditing,
17
- }: ThreadItemDropdownMenuProps): MenuProps['items'] => {
17
+ }: ThreadItemDropdownMenuProps): (() => MenuProps['items']) => {
18
18
  const { t } = useTranslation(['thread', 'common']);
19
19
  const { modal } = App.useApp();
20
20
 
21
21
  const [removeThread] = useChatStore((s) => [s.removeThread]);
22
22
 
23
- return useMemo(() => {
23
+ return useCallback(() => {
24
24
  return [
25
25
  {
26
26
  icon: <Icon icon={PencilLine} />,
@@ -1,6 +1,4 @@
1
- import { ActionIcon, Tag } from '@lobehub/ui';
2
- import { Dropdown } from 'antd';
3
- import type { ItemType } from 'antd/es/menu/interface';
1
+ import { ActionIcon, DropdownMenu, type DropdownMenuCheckboxItem, Tag } from '@lobehub/ui';
4
2
  import { Clock3Icon, PlusIcon } from 'lucide-react';
5
3
  import { memo, useMemo } from 'react';
6
4
  import { useTranslation } from 'react-i18next';
@@ -32,15 +30,23 @@ const TopicSelector = memo<TopicSelectorProps>(({ agentId }) => {
32
30
  [topics, activeTopicId],
33
31
  );
34
32
 
35
- const items = useMemo<ItemType[]>(
33
+ const items = useMemo<DropdownMenuCheckboxItem[]>(
36
34
  () =>
37
35
  (topics || []).map((topic) => ({
36
+ checked: topic.id === activeTopicId,
37
+ closeOnClick: true,
38
38
  key: topic.id,
39
39
  label: topic.title,
40
- onClick: () => switchTopic(topic.id),
40
+ onCheckedChange: (checked) => {
41
+ if (checked) {
42
+ switchTopic(topic.id);
43
+ }
44
+ },
45
+ type: 'checkbox',
41
46
  })),
42
- [topics, t, switchTopic],
47
+ [topics, switchTopic, activeTopicId],
43
48
  );
49
+ const isEmpty = !topics || topics.length === 0;
44
50
 
45
51
  return (
46
52
  <NavHeader
@@ -53,22 +59,14 @@ const TopicSelector = memo<TopicSelectorProps>(({ agentId }) => {
53
59
  size={DESKTOP_HEADER_ICON_SIZE}
54
60
  title={t('actions.addNewTopic')}
55
61
  />
56
- <Dropdown
57
- disabled={!topics || topics.length === 0}
58
- menu={{
59
- items,
60
- selectedKeys: activeTopicId ? [activeTopicId] : [],
61
- }}
62
- overlayStyle={{
63
- maxHeight: 600,
64
- minWidth: 200,
65
- overflowY: 'auto',
66
- }}
62
+ <DropdownMenu
63
+ items={items}
67
64
  placement="bottomRight"
68
- trigger={['click']}
65
+ popupProps={{ style: { maxHeight: 600, minWidth: 200, overflowY: 'auto' } }}
66
+ triggerProps={{ disabled: isEmpty }}
69
67
  >
70
- <ActionIcon disabled={!topics || topics.length === 0} icon={Clock3Icon} />
71
- </Dropdown>
68
+ <ActionIcon disabled={isEmpty} icon={Clock3Icon} />
69
+ </DropdownMenu>
72
70
  </>
73
71
  }
74
72
  showTogglePanelButton={false}
@@ -1,6 +1,6 @@
1
1
  import { GROUP_CHAT_URL } from '@lobechat/const';
2
2
  import type { SidebarAgentItem } from '@lobechat/types';
3
- import { ActionIcon, Dropdown, Icon, type MenuProps } from '@lobehub/ui';
3
+ import { ActionIcon, Icon } from '@lobehub/ui';
4
4
  import { cssVar } from 'antd-style';
5
5
  import { Loader2, PinIcon } from 'lucide-react';
6
6
  import { type CSSProperties, type DragEvent, memo, useCallback, useMemo } from 'react';
@@ -85,7 +85,7 @@ const GroupItem = memo<GroupItemProps>(({ item, style, className }) => {
85
85
  return <GroupAvatar avatars={(avatar as any) || []} size={22} />;
86
86
  }, [isUpdating, avatar]);
87
87
 
88
- const dropdownMenu: MenuProps['items'] = useDropdownMenu({
88
+ const dropdownMenu = useDropdownMenu({
89
89
  group: undefined,
90
90
  id,
91
91
  openCreateGroupModal: () => {}, // Groups don't need this
@@ -97,29 +97,23 @@ const GroupItem = memo<GroupItemProps>(({ item, style, className }) => {
97
97
 
98
98
  return (
99
99
  <>
100
- <Dropdown
101
- menu={{
102
- items: dropdownMenu,
103
- }}
104
- trigger={['contextMenu']}
105
- >
106
- <Link aria-label={id} to={groupUrl}>
107
- <NavItem
108
- actions={<Actions dropdownMenu={dropdownMenu} />}
109
- className={className}
110
- disabled={editing || isUpdating}
111
- draggable={!editing && !isUpdating}
112
- extra={pinIcon}
113
- icon={avatarIcon}
114
- key={id}
115
- onDoubleClick={handleDoubleClick}
116
- onDragEnd={handleDragEnd}
117
- onDragStart={handleDragStart}
118
- style={style}
119
- title={displayTitle}
120
- />
121
- </Link>
122
- </Dropdown>
100
+ <Link aria-label={id} to={groupUrl}>
101
+ <NavItem
102
+ actions={<Actions dropdownMenu={dropdownMenu} />}
103
+ className={className}
104
+ contextMenuItems={dropdownMenu}
105
+ disabled={editing || isUpdating}
106
+ draggable={!editing && !isUpdating}
107
+ extra={pinIcon}
108
+ icon={avatarIcon}
109
+ key={id}
110
+ onDoubleClick={handleDoubleClick}
111
+ onDragEnd={handleDragEnd}
112
+ onDragStart={handleDragStart}
113
+ style={style}
114
+ title={displayTitle}
115
+ />
116
+ </Link>
123
117
  <Editing id={id} title={displayTitle} toggleEditing={toggleEditing} />
124
118
  </>
125
119
  );