@lobehub/lobehub 2.0.0-next.298 → 2.0.0-next.299

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 (82) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/changelog/v1.json +9 -0
  3. package/package.json +2 -2
  4. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/Actions.tsx +4 -13
  5. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/Actions.tsx +4 -13
  6. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/index.tsx +2 -9
  7. package/src/app/[variants]/(main)/agent/features/Conversation/ConversationArea.tsx +2 -2
  8. package/src/app/[variants]/(main)/agent/features/Conversation/Header/Tags/KnowledgeTag.tsx +3 -4
  9. package/src/app/[variants]/(main)/agent/profile/features/ProfileEditor/MentionList/types.ts +4 -2
  10. package/src/app/[variants]/(main)/community/(detail)/model/features/Sidebar/ActionButton/ChatWithModel.tsx +3 -8
  11. package/src/app/[variants]/(main)/community/(list)/assistant/features/MarketSourceSwitch.tsx +44 -23
  12. package/src/app/[variants]/(main)/community/(list)/features/SortButton/index.tsx +40 -19
  13. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/Actions.tsx +4 -13
  14. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/index.tsx +2 -9
  15. package/src/app/[variants]/(main)/group/features/Conversation/ConversationArea.tsx +2 -2
  16. package/src/app/[variants]/(main)/group/features/Conversation/Header/Tags/KnowledgeTag.tsx +3 -4
  17. package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/AgentBuilderProvider.tsx +2 -2
  18. package/src/app/[variants]/(main)/group/profile/features/MemberProfile/MentionList/types.ts +4 -2
  19. package/src/app/[variants]/(main)/home/_layout/Body/Agent/Actions.tsx +3 -11
  20. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/Group/Actions.tsx +3 -12
  21. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/Group/Item.tsx +2 -9
  22. package/src/app/[variants]/(main)/home/_layout/Body/Agent/index.tsx +2 -9
  23. package/src/app/[variants]/(main)/home/_layout/Body/Project/index.tsx +2 -9
  24. package/src/app/[variants]/(main)/home/features/CommunityAgents/index.tsx +11 -13
  25. package/src/app/[variants]/(main)/home/features/FeaturedPlugins/index.tsx +11 -13
  26. package/src/app/[variants]/(main)/home/features/RecentPage/index.tsx +12 -14
  27. package/src/app/[variants]/(main)/home/features/RecentResource/index.tsx +12 -14
  28. package/src/app/[variants]/(main)/memory/contexts/features/ContextDropdown.tsx +5 -3
  29. package/src/app/[variants]/(main)/memory/experiences/features/ExperienceDropdown.tsx +5 -3
  30. package/src/app/[variants]/(main)/memory/identities/features/IdentityDropdown.tsx +5 -3
  31. package/src/app/[variants]/(main)/memory/preferences/features/PreferenceDropdown.tsx +5 -3
  32. package/src/app/[variants]/(main)/page/_layout/Body/Actions.tsx +3 -13
  33. package/src/app/[variants]/(main)/page/_layout/Body/index.tsx +2 -9
  34. package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +1 -1
  35. package/src/app/[variants]/(main)/settings/profile/features/SSOProvidersList/index.tsx +3 -3
  36. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Actions.tsx +3 -11
  37. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/List.tsx +12 -28
  38. package/src/app/[variants]/(main)/settings/provider/features/ModelList/DisabledModels.tsx +7 -8
  39. package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelTitle/index.tsx +18 -20
  40. package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/CollapseGroup/Actions.tsx +10 -14
  41. package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/List/Item/Actions.tsx +3 -13
  42. package/src/app/[variants]/share/t/[id]/SharedMessageList.tsx +2 -2
  43. package/src/business/server/lambda-routers/file.ts +1 -1
  44. package/src/features/AgentBuilder/AgentBuilderProvider.tsx +2 -2
  45. package/src/features/ChatInput/ActionBar/History/index.tsx +1 -1
  46. package/src/features/ChatInput/ActionBar/STT/common.tsx +1 -1
  47. package/src/features/ChatInput/ActionBar/Search/index.tsx +1 -1
  48. package/src/features/ChatInput/ActionBar/Upload/ServerMode.tsx +1 -0
  49. package/src/features/ChatInput/ActionBar/components/Action.tsx +4 -8
  50. package/src/features/ChatInput/ActionBar/components/ActionDropdown.tsx +225 -37
  51. package/src/features/Conversation/ConversationProvider.tsx +2 -1
  52. package/src/features/Conversation/Messages/Assistant/Actions/index.tsx +10 -6
  53. package/src/features/Conversation/Messages/AssistantGroup/Actions/index.tsx +10 -6
  54. package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Intervention/ApprovalActions.tsx +11 -13
  55. package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Intervention/ModeSelector.tsx +8 -10
  56. package/src/features/Conversation/Messages/Supervisor/Actions/index.tsx +10 -6
  57. package/src/features/Conversation/Messages/Task/Actions/index.tsx +10 -6
  58. package/src/features/Conversation/Messages/User/Actions/index.tsx +10 -6
  59. package/src/features/Conversation/StoreUpdater.tsx +1 -1
  60. package/src/features/Conversation/store/initialState.ts +3 -1
  61. package/src/features/Conversation/store/slices/data/action.ts +6 -5
  62. package/src/features/LibraryModal/AssignKnowledgeBase/Item/Action.tsx +23 -26
  63. package/src/features/ModelSwitchPanel/components/List/MultipleProvidersModelItem.tsx +16 -18
  64. package/src/features/ModelSwitchPanel/styles.ts +18 -1
  65. package/src/features/PageEditor/Copilot/AgentSelector/Actions.tsx +6 -13
  66. package/src/features/PageEditor/PageAgentProvider.tsx +2 -2
  67. package/src/features/PluginStore/InstalledList/List/Item/Action.tsx +33 -36
  68. package/src/features/PluginStore/McpList/List/Action.tsx +25 -28
  69. package/src/features/PluginStore/PluginList/List/Action.tsx +25 -28
  70. package/src/features/PluginTag/index.tsx +3 -4
  71. package/src/features/Portal/Artifacts/Body/Renderer/SVG.tsx +14 -11
  72. package/src/features/Portal/Thread/Chat/index.tsx +2 -2
  73. package/src/features/ProfileEditor/AgentTool.tsx +1 -1
  74. package/src/features/ResourceManager/components/Explorer/ToolBar/SortDropdown.tsx +21 -18
  75. package/src/features/ResourceManager/components/Explorer/ToolBar/ViewSwitcher.tsx +7 -13
  76. package/src/features/ResourceManager/components/Header/AddButton.tsx +4 -11
  77. package/src/features/User/UserPanel/LangButton.tsx +56 -44
  78. package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +1 -1
  79. package/src/services/document/index.ts +11 -1
  80. package/src/store/page/slices/crud/action.ts +0 -48
  81. package/src/styles/global.ts +2 -2
  82. package/src/types/shim-lobe-ui.d.ts +7 -0
@@ -16,16 +16,20 @@ import { useUserActions } from './useUserActions';
16
16
  // Helper to strip handleClick from action items before passing to ActionIconGroup
17
17
  const stripHandleClick = (item: MessageActionItemOrDivider): ActionIconGroupItemType => {
18
18
  if ('type' in item && item.type === 'divider') return item as unknown as ActionIconGroupItemType;
19
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
- const { handleClick, children, ...rest } = item as MessageActionItem;
19
+ const { children, ...rest } = item as MessageActionItem;
20
+ const baseItem = { ...rest } as MessageActionItem;
21
+ delete (baseItem as { handleClick?: unknown }).handleClick;
21
22
  if (children) {
22
23
  return {
23
- ...rest,
24
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
- children: children.map(({ handleClick: _, ...child }) => child),
24
+ ...baseItem,
25
+ children: children.map((child) => {
26
+ const nextChild = { ...child } as MessageActionItem;
27
+ delete (nextChild as { handleClick?: unknown }).handleClick;
28
+ return nextChild;
29
+ }),
26
30
  } as ActionIconGroupItemType;
27
31
  }
28
- return rest as ActionIconGroupItemType;
32
+ return baseItem as ActionIconGroupItemType;
29
33
  };
30
34
 
31
35
  // Build action items map for handleAction lookup
@@ -30,7 +30,7 @@ export interface StoreUpdaterProps {
30
30
  /**
31
31
  * Callback when messages are fetched or changed internally
32
32
  */
33
- onMessagesChange?: (messages: UIChatMessage[]) => void;
33
+ onMessagesChange?: (messages: UIChatMessage[], context: ConversationContext) => void;
34
34
  /**
35
35
  * External operation state (from ChatStore)
36
36
  */
@@ -33,8 +33,10 @@ export interface State extends DataState, InputState, MessageStateState, VirtuaL
33
33
 
34
34
  /**
35
35
  * Callback when messages are fetched or changed internally
36
+ * @param messages - The updated messages array
37
+ * @param context - The context that this data belongs to (prevents race conditions)
36
38
  */
37
- onMessagesChange?: (messages: UIChatMessage[]) => void;
39
+ onMessagesChange?: (messages: UIChatMessage[], context: ConversationContext) => void;
38
40
 
39
41
  /**
40
42
  * External operation state (from ChatStore)
@@ -74,7 +74,7 @@ export const dataSlice: StateCreator<
74
74
  });
75
75
 
76
76
  // Sync changes to external store (ChatStore)
77
- get().onMessagesChange?.(newDbMessages);
77
+ get().onMessagesChange?.(newDbMessages, get().context);
78
78
  },
79
79
 
80
80
  replaceMessages: (messages) => {
@@ -84,7 +84,7 @@ export const dataSlice: StateCreator<
84
84
  set({ dbMessages: messages, displayMessages: flatList }, false, 'replaceMessages');
85
85
 
86
86
  // Sync changes to external store (ChatStore)
87
- get().onMessagesChange?.(messages);
87
+ get().onMessagesChange?.(messages, get().context);
88
88
  },
89
89
 
90
90
  switchMessageBranch: async (messageId, branchIndex) => {
@@ -106,7 +106,6 @@ export const dataSlice: StateCreator<
106
106
  // Also skip fetch when topicId is null (new conversation state) - there's no server data,
107
107
  // only local optimistic updates. Fetching would return empty array and overwrite local data.
108
108
  const shouldFetch = !skipFetch && !!context.agentId && !!context.topicId;
109
-
110
109
  return useClientDataSWRWithSync<UIChatMessage[]>(
111
110
  shouldFetch ? ['CONVERSATION_FETCH_MESSAGES', context] : null,
112
111
 
@@ -116,6 +115,7 @@ export const dataSlice: StateCreator<
116
115
  {
117
116
  onData: (data) => {
118
117
  if (!data) return;
118
+ if (!context.topicId) return;
119
119
 
120
120
  // Parse messages using conversation-flow
121
121
  const { flatList } = parse(data);
@@ -126,8 +126,9 @@ export const dataSlice: StateCreator<
126
126
  messagesInit: true,
127
127
  });
128
128
 
129
- // Call onMessagesChange callback if provided
130
- get().onMessagesChange?.(data);
129
+ // Call onMessagesChange callback with the request context (not current context)
130
+ // This ensures data is stored to the correct topic even if user switched topics
131
+ get().onMessagesChange?.(data, context);
131
132
  },
132
133
  },
133
134
  );
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Button, Dropdown, Flexbox, Icon } from '@lobehub/ui';
1
+ import { ActionIcon, Button, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
2
2
  import { InfoIcon, MoreVerticalIcon, Trash2 } from 'lucide-react';
3
3
  import { memo, useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
@@ -54,36 +54,33 @@ const Actions = memo<ActionsProps>(({ id, type, enabled }) => {
54
54
  return (
55
55
  <Flexbox align={'center'} horizontal>
56
56
  {enabled ? (
57
- <Dropdown
58
- menu={{
59
- items: [
60
- {
61
- icon: <Icon icon={InfoIcon} />,
62
- key: 'detail',
63
- label: t('knowledgeBase.library.action.detail'),
64
- onClick: () => {
65
- if (type === KnowledgeType.KnowledgeBase) {
66
- window.open(`/resource/library/${id}`);
67
- return;
68
- }
57
+ <DropdownMenu
58
+ items={[
59
+ {
60
+ icon: <Icon icon={InfoIcon} />,
61
+ key: 'detail',
62
+ label: t('knowledgeBase.library.action.detail'),
63
+ onClick: () => {
64
+ if (type === KnowledgeType.KnowledgeBase) {
65
+ window.open(`/resource/library/${id}`);
66
+ return;
67
+ }
69
68
 
70
- window.open(`/knowledge?file=${id}`);
71
- },
69
+ window.open(`/knowledge?file=${id}`);
72
70
  },
73
- {
74
- danger: true,
75
- icon: <Icon icon={Trash2} />,
76
- key: 'remove',
77
- label: t('knowledgeBase.library.action.remove'),
78
- onClick: removeKnowledge,
79
- },
80
- ],
81
- }}
71
+ },
72
+ {
73
+ danger: true,
74
+ icon: <Icon icon={Trash2} />,
75
+ key: 'remove',
76
+ label: t('knowledgeBase.library.action.remove'),
77
+ onClick: removeKnowledge,
78
+ },
79
+ ]}
82
80
  placement="bottomRight"
83
- trigger={['click']}
84
81
  >
85
82
  <ActionIcon icon={MoreVerticalIcon} loading={loading} />
86
- </Dropdown>
83
+ </DropdownMenu>
87
84
  ) : (
88
85
  <Button
89
86
  loading={loading}
@@ -1,6 +1,5 @@
1
- import { ActionIcon, Dropdown } from '@lobehub/ui';
2
- import { MenuItemType } from 'antd/es/menu/interface';
3
- import { LucideBolt } from 'lucide-react';
1
+ import { ActionIcon, type DropdownItem, DropdownMenu } from '@lobehub/ui';
2
+ import { Check, LucideBolt } from 'lucide-react';
4
3
  import { memo, useMemo } from 'react';
5
4
  import { useTranslation } from 'react-i18next';
6
5
  import { useNavigate } from 'react-router-dom';
@@ -34,6 +33,8 @@ export const MultipleProvidersModelItem = memo<MultipleProvidersModelItemProps>(
34
33
  type: 'group',
35
34
  },
36
35
  ...data.providers.map((p) => {
36
+ const key = menuKey(p.id, data.model.id);
37
+
37
38
  return {
38
39
  extra: (
39
40
  <ActionIcon
@@ -53,7 +54,8 @@ export const MultipleProvidersModelItem = memo<MultipleProvidersModelItemProps>(
53
54
  title={t('ModelSwitchPanel.goToSettings')}
54
55
  />
55
56
  ),
56
- key: menuKey(p.id, data.model.id),
57
+ icon: activeKey === key ? Check : undefined,
58
+ key,
57
59
  label: (
58
60
  <ProviderItemRender
59
61
  logo={p.logo}
@@ -70,23 +72,19 @@ export const MultipleProvidersModelItem = memo<MultipleProvidersModelItemProps>(
70
72
  },
71
73
  };
72
74
  }),
73
- ] as MenuItemType[],
74
- [data.model.id, data.providers, navigate, onModelChange, onClose, t],
75
+ ] as DropdownItem[],
76
+ [activeKey, data.model.id, data.providers, navigate, onModelChange, onClose, t],
75
77
  );
76
78
 
77
79
  return (
78
- <Dropdown
79
- align={{ offset: [12, -48] }}
80
- arrow={false}
81
- classNames={{
82
- item: styles.menuItem,
83
- }}
84
- menu={{
85
- items,
86
- selectedKeys: [activeKey],
87
- }}
88
- // @ts-ignore
80
+ <DropdownMenu
81
+ items={items}
89
82
  placement="rightTop"
83
+ popupProps={{ className: styles.dropdownMenu }}
84
+ positionerProps={{
85
+ alignOffset: -48,
86
+ sideOffset: 12,
87
+ }}
90
88
  >
91
89
  <ModelItemRender
92
90
  {...data.model}
@@ -95,7 +93,7 @@ export const MultipleProvidersModelItem = memo<MultipleProvidersModelItemProps>(
95
93
  newBadgeLabel={newLabel}
96
94
  showInfoTag={true}
97
95
  />
98
- </Dropdown>
96
+ </DropdownMenu>
99
97
  );
100
98
  },
101
99
  );
@@ -5,10 +5,27 @@ export const styles = createStaticStyles(({ css, cssVar }) => ({
5
5
  overflow: hidden;
6
6
  padding: 0 !important;
7
7
  `,
8
+ dropdownMenu: css`
9
+ [role='menuitem'] {
10
+ margin-block: 1px;
11
+ margin-inline: 4px;
12
+ padding-block: 8px;
13
+ padding-inline: 8px;
14
+ border-radius: ${cssVar.borderRadiusSM};
15
+ }
16
+
17
+ [role='menuitem'] .settings-icon {
18
+ opacity: 0;
19
+ }
20
+
21
+ [role='menuitem']:hover .settings-icon {
22
+ opacity: 1;
23
+ }
24
+ `,
25
+
8
26
  footer: css`
9
27
  border-block-start: 1px solid ${cssVar.colorBorderSecondary};
10
28
  `,
11
-
12
29
  groupHeader: css`
13
30
  width: 100%;
14
31
  color: ${cssVar.colorTextSecondary};
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Dropdown, type MenuProps } from '@lobehub/ui';
1
+ import { ActionIcon, DropdownMenu, type MenuProps } from '@lobehub/ui';
2
2
  import { MoreHorizontalIcon } from 'lucide-react';
3
3
  import { memo } from 'react';
4
4
 
@@ -7,21 +7,14 @@ interface ActionsProps {
7
7
  }
8
8
 
9
9
  const Actions = memo<ActionsProps>(({ dropdownMenu }) => {
10
- if (!dropdownMenu || dropdownMenu.length === 0) return null;
10
+ const menuItems = dropdownMenu ?? [];
11
+
12
+ if (menuItems.length === 0) return null;
11
13
 
12
14
  return (
13
- <Dropdown
14
- arrow={false}
15
- menu={{
16
- items: dropdownMenu,
17
- onClick: ({ domEvent }) => {
18
- domEvent.stopPropagation();
19
- },
20
- }}
21
- trigger={['click']}
22
- >
15
+ <DropdownMenu items={menuItems}>
23
16
  <ActionIcon icon={MoreHorizontalIcon} size={'small'} />
24
- </Dropdown>
17
+ </DropdownMenu>
25
18
  );
26
19
  });
27
20
 
@@ -49,8 +49,8 @@ const PageAgentProvider = memo<PageAgentProviderProps>(({ pageAgentId, children
49
49
  context={context}
50
50
  hasInitMessages={!!messages}
51
51
  messages={messages}
52
- onMessagesChange={(msgs) => {
53
- replaceMessages(msgs, { context });
52
+ onMessagesChange={(msgs, ctx) => {
53
+ replaceMessages(msgs, { context: ctx });
54
54
  }}
55
55
  operationState={operationState}
56
56
  >
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Button, Dropdown, Flexbox, Icon } from '@lobehub/ui';
1
+ import { ActionIcon, Button, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
2
2
  import { App } from 'antd';
3
3
  import { InfoIcon, MoreVerticalIcon, PackageSearch, Settings, Trash2 } from 'lucide-react';
4
4
  import { memo, useState } from 'react';
@@ -72,46 +72,43 @@ const Actions = memo<ActionsProps>(({ identifier, type, isMCP }) => {
72
72
  title={t('store.actions.settings')}
73
73
  />
74
74
  )}
75
- <Dropdown
76
- menu={{
77
- items: [
78
- {
79
- icon: <Icon icon={InfoIcon} />,
80
- key: 'detail',
81
- label: t('store.actions.detail'),
82
- onClick: () => {
83
- setOpen(true);
84
- setTab('info');
85
- },
75
+ <DropdownMenu
76
+ items={[
77
+ {
78
+ icon: <Icon icon={InfoIcon} />,
79
+ key: 'detail',
80
+ label: t('store.actions.detail'),
81
+ onClick: () => {
82
+ setOpen(true);
83
+ setTab('info');
86
84
  },
87
- {
88
- danger: true,
89
- icon: <Icon icon={Trash2} />,
90
- key: 'uninstall',
91
- label: t('store.actions.uninstall'),
92
- onClick: () => {
93
- modal.confirm({
94
- centered: true,
95
- okButtonProps: { danger: true },
96
- onOk: async () => {
97
- // If plugin is enabled in current agent, disable it first
98
- if (isPluginEnabledInAgent) {
99
- await togglePlugin(identifier, false);
100
- }
101
- await unInstallPlugin(identifier);
102
- },
103
- title: t('store.actions.confirmUninstall'),
104
- type: 'error',
105
- });
106
- },
85
+ },
86
+ {
87
+ danger: true,
88
+ icon: <Icon icon={Trash2} />,
89
+ key: 'uninstall',
90
+ label: t('store.actions.uninstall'),
91
+ onClick: () => {
92
+ modal.confirm({
93
+ centered: true,
94
+ okButtonProps: { danger: true },
95
+ onOk: async () => {
96
+ // If plugin is enabled in current agent, disable it first
97
+ if (isPluginEnabledInAgent) {
98
+ await togglePlugin(identifier, false);
99
+ }
100
+ await unInstallPlugin(identifier);
101
+ },
102
+ title: t('store.actions.confirmUninstall'),
103
+ type: 'error',
104
+ });
107
105
  },
108
- ],
109
- }}
106
+ },
107
+ ]}
110
108
  placement="bottomRight"
111
- trigger={['click']}
112
109
  >
113
110
  <ActionIcon icon={MoreVerticalIcon} loading={installing} />
114
- </Dropdown>
111
+ </DropdownMenu>
115
112
  </>
116
113
  ) : (
117
114
  <Button
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Button, Dropdown, Flexbox, Icon } from '@lobehub/ui';
1
+ import { ActionIcon, Button, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
2
2
  import { App } from 'antd';
3
3
  import { MoreVerticalIcon, Trash2 } from 'lucide-react';
4
4
  import { memo } from 'react';
@@ -39,34 +39,31 @@ const Actions = memo<ActionsProps>(({ identifier }) => {
39
39
  return (
40
40
  <Flexbox align={'center'} horizontal>
41
41
  {installed ? (
42
- <Dropdown
43
- menu={{
44
- items: [
45
- {
46
- danger: true,
47
- icon: <Icon icon={Trash2} />,
48
- key: 'uninstall',
49
- label: t('store.actions.uninstall'),
50
- onClick: () => {
51
- modal.confirm({
52
- centered: true,
53
- okButtonProps: { danger: true },
54
- onOk: async () => {
55
- // If plugin is enabled in current agent, disable it first
56
- if (isPluginEnabledInAgent) {
57
- await togglePlugin(identifier, false);
58
- }
59
- await unInstallPlugin(identifier);
60
- },
61
- title: t('store.actions.confirmUninstall'),
62
- type: 'error',
63
- });
64
- },
42
+ <DropdownMenu
43
+ items={[
44
+ {
45
+ danger: true,
46
+ icon: <Icon icon={Trash2} />,
47
+ key: 'uninstall',
48
+ label: t('store.actions.uninstall'),
49
+ onClick: () => {
50
+ modal.confirm({
51
+ centered: true,
52
+ okButtonProps: { danger: true },
53
+ onOk: async () => {
54
+ // If plugin is enabled in current agent, disable it first
55
+ if (isPluginEnabledInAgent) {
56
+ await togglePlugin(identifier, false);
57
+ }
58
+ await unInstallPlugin(identifier);
59
+ },
60
+ title: t('store.actions.confirmUninstall'),
61
+ type: 'error',
62
+ });
65
63
  },
66
- ],
67
- }}
64
+ },
65
+ ]}
68
66
  placement="bottomRight"
69
- trigger={['click']}
70
67
  >
71
68
  <ActionIcon
72
69
  icon={MoreVerticalIcon}
@@ -75,7 +72,7 @@ const Actions = memo<ActionsProps>(({ identifier }) => {
75
72
  e.stopPropagation();
76
73
  }}
77
74
  />
78
- </Dropdown>
75
+ </DropdownMenu>
79
76
  ) : installing ? (
80
77
  <Button
81
78
  onClick={async (e) => {
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Button, Dropdown, Flexbox, Icon } from '@lobehub/ui';
1
+ import { ActionIcon, Button, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
2
2
  import { App } from 'antd';
3
3
  import { MoreVerticalIcon, Trash2 } from 'lucide-react';
4
4
  import { memo } from 'react';
@@ -31,37 +31,34 @@ const Actions = memo<ActionsProps>(({ identifier }) => {
31
31
  return (
32
32
  <Flexbox align={'center'} horizontal>
33
33
  {installed ? (
34
- <Dropdown
35
- menu={{
36
- items: [
37
- {
38
- danger: true,
39
- icon: <Icon icon={Trash2} />,
40
- key: 'uninstall',
41
- label: t('store.actions.uninstall'),
42
- onClick: () => {
43
- modal.confirm({
44
- centered: true,
45
- okButtonProps: { danger: true },
46
- onOk: async () => {
47
- // If plugin is enabled in current agent, disable it first
48
- if (isPluginEnabledInAgent) {
49
- await togglePlugin(identifier, false);
50
- }
51
- await unInstallPlugin(identifier);
52
- },
53
- title: t('store.actions.confirmUninstall'),
54
- type: 'error',
55
- });
56
- },
34
+ <DropdownMenu
35
+ items={[
36
+ {
37
+ danger: true,
38
+ icon: <Icon icon={Trash2} />,
39
+ key: 'uninstall',
40
+ label: t('store.actions.uninstall'),
41
+ onClick: () => {
42
+ modal.confirm({
43
+ centered: true,
44
+ okButtonProps: { danger: true },
45
+ onOk: async () => {
46
+ // If plugin is enabled in current agent, disable it first
47
+ if (isPluginEnabledInAgent) {
48
+ await togglePlugin(identifier, false);
49
+ }
50
+ await unInstallPlugin(identifier);
51
+ },
52
+ title: t('store.actions.confirmUninstall'),
53
+ type: 'error',
54
+ });
57
55
  },
58
- ],
59
- }}
56
+ },
57
+ ]}
60
58
  placement="bottomRight"
61
- trigger={['click']}
62
59
  >
63
60
  <ActionIcon icon={MoreVerticalIcon} loading={installing} />
64
- </Dropdown>
61
+ </DropdownMenu>
65
62
  ) : (
66
63
  <Button
67
64
  loading={installing}
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { Dropdown, Icon, type MenuProps, Tag } from '@lobehub/ui';
4
- import { Center } from '@lobehub/ui';
3
+ import { Center, DropdownMenu, Icon, type MenuProps, Tag } from '@lobehub/ui';
5
4
  import isEqual from 'fast-deep-equal';
6
5
  import { LucideToyBrick } from 'lucide-react';
7
6
  import { memo } from 'react';
@@ -49,7 +48,7 @@ const PluginTag = memo<PluginTagProps>(({ plugins }) => {
49
48
  const count = plugins.length;
50
49
 
51
50
  return (
52
- <Dropdown menu={{ items }}>
51
+ <DropdownMenu items={items}>
53
52
  <div>
54
53
  <Tag>
55
54
  {<Icon icon={LucideToyBrick} />}
@@ -57,7 +56,7 @@ const PluginTag = memo<PluginTagProps>(({ plugins }) => {
57
56
  {count > 1 && <div>({plugins.length - 1}+)</div>}
58
57
  </Tag>
59
58
  </div>
60
- </Dropdown>
59
+ </DropdownMenu>
61
60
  );
62
61
  });
63
62
 
@@ -1,6 +1,6 @@
1
1
  import { BRANDING_NAME } from '@lobechat/business-const';
2
2
  import { copyImageToClipboard, sanitizeSVGContent } from '@lobechat/utils/client';
3
- import { Button, Center, Dropdown, Flexbox, Tooltip } from '@lobehub/ui';
3
+ import { Button, Center, DropdownMenu, Flexbox, Tooltip } from '@lobehub/ui';
4
4
  import { snapdom } from '@zumer/snapdom';
5
5
  import { App, Space } from 'antd';
6
6
  import { css, cx } from 'antd-style';
@@ -98,19 +98,22 @@ const SVGRenderer = ({ content }: SVGRendererProps) => {
98
98
  />
99
99
  <Flexbox className={cx(actions)}>
100
100
  <Space.Compact>
101
- <Dropdown
102
- menu={{
103
- items: [
104
- { key: 'png', label: t('artifacts.svg.download.png') },
105
- { key: 'svg', label: t('artifacts.svg.download.svg') },
106
- ],
107
- onClick: ({ key }) => {
108
- downloadImage(key);
101
+ <DropdownMenu
102
+ items={[
103
+ {
104
+ key: 'png',
105
+ label: t('artifacts.svg.download.png'),
106
+ onClick: () => downloadImage('png'),
109
107
  },
110
- }}
108
+ {
109
+ key: 'svg',
110
+ label: t('artifacts.svg.download.svg'),
111
+ onClick: () => downloadImage('svg'),
112
+ },
113
+ ]}
111
114
  >
112
115
  <Button icon={DownloadIcon} />
113
- </Dropdown>
116
+ </DropdownMenu>
114
117
  <Tooltip title={t('artifacts.svg.copyAsImage')}>
115
118
  <Button
116
119
  icon={CopyIcon}
@@ -204,8 +204,8 @@ const ThreadChat = memo(() => {
204
204
  hasInitMessages={!!messages}
205
205
  hooks={hooks}
206
206
  messages={messages}
207
- onMessagesChange={(msgs) => {
208
- replaceMessages(msgs, { context });
207
+ onMessagesChange={(msgs, ctx) => {
208
+ replaceMessages(msgs, { context: ctx });
209
209
  }}
210
210
  operationState={operationState}
211
211
  skipFetch={isCreatingNewThread}
@@ -617,7 +617,7 @@ const AgentTool = memo<AgentToolProps>(
617
617
  </div>
618
618
  </div>
619
619
  )}
620
- trigger={['click']}
620
+ trigger={'click'}
621
621
  >
622
622
  {button}
623
623
  </ActionDropdown>