@lobehub/chat 1.141.7 → 1.141.9
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 +50 -0
- package/apps/desktop/package.json +1 -0
- package/apps/desktop/src/main/controllers/LocalFileCtr.ts +279 -52
- package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +392 -0
- package/changelog/v1.json +18 -0
- package/docs/usage/features/{group-chat.mdx → agent-team.mdx} +14 -14
- package/docs/usage/features/agent-team.zh-CN.mdx +52 -0
- package/locales/ar/chat.json +17 -17
- package/locales/ar/setting.json +15 -19
- package/locales/ar/welcome.json +1 -1
- package/locales/bg-BG/chat.json +17 -17
- package/locales/bg-BG/setting.json +15 -19
- package/locales/de-DE/chat.json +17 -17
- package/locales/de-DE/setting.json +15 -19
- package/locales/de-DE/welcome.json +1 -1
- package/locales/en-US/chat.json +17 -17
- package/locales/en-US/setting.json +15 -19
- package/locales/en-US/welcome.json +1 -1
- package/locales/es-ES/chat.json +17 -17
- package/locales/es-ES/setting.json +15 -19
- package/locales/es-ES/welcome.json +1 -1
- package/locales/fa-IR/chat.json +17 -17
- package/locales/fa-IR/setting.json +15 -19
- package/locales/fa-IR/welcome.json +1 -1
- package/locales/fr-FR/chat.json +16 -16
- package/locales/fr-FR/setting.json +15 -19
- package/locales/fr-FR/welcome.json +1 -1
- package/locales/it-IT/chat.json +17 -17
- package/locales/it-IT/setting.json +15 -19
- package/locales/it-IT/welcome.json +1 -1
- package/locales/ja-JP/chat.json +17 -17
- package/locales/ja-JP/setting.json +15 -19
- package/locales/ja-JP/welcome.json +1 -1
- package/locales/ko-KR/chat.json +17 -17
- package/locales/ko-KR/setting.json +15 -19
- package/locales/ko-KR/welcome.json +1 -1
- package/locales/nl-NL/chat.json +17 -17
- package/locales/nl-NL/setting.json +15 -19
- package/locales/nl-NL/welcome.json +1 -1
- package/locales/pl-PL/chat.json +17 -17
- package/locales/pl-PL/setting.json +15 -19
- package/locales/pt-BR/chat.json +17 -17
- package/locales/pt-BR/setting.json +15 -19
- package/locales/pt-BR/welcome.json +1 -1
- package/locales/ru-RU/chat.json +17 -17
- package/locales/ru-RU/setting.json +15 -19
- package/locales/ru-RU/welcome.json +1 -1
- package/locales/tr-TR/chat.json +17 -17
- package/locales/tr-TR/setting.json +15 -19
- package/locales/vi-VN/chat.json +15 -15
- package/locales/vi-VN/setting.json +15 -19
- package/locales/zh-CN/chat.json +17 -17
- package/locales/zh-CN/setting.json +15 -19
- package/locales/zh-CN/welcome.json +1 -1
- package/locales/zh-TW/chat.json +17 -17
- package/locales/zh-TW/setting.json +15 -19
- package/locales/zh-TW/welcome.json +1 -1
- package/package.json +1 -1
- package/packages/agent-runtime/src/core/InterventionChecker.ts +173 -0
- package/packages/agent-runtime/src/core/UsageCounter.ts +248 -0
- package/packages/agent-runtime/src/core/__tests__/InterventionChecker.test.ts +334 -0
- package/packages/agent-runtime/src/core/__tests__/UsageCounter.test.ts +873 -0
- package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +32 -26
- package/packages/agent-runtime/src/core/index.ts +2 -0
- package/packages/agent-runtime/src/core/runtime.ts +31 -18
- package/packages/agent-runtime/src/types/instruction.ts +1 -1
- package/packages/agent-runtime/src/types/state.ts +3 -3
- package/packages/agent-runtime/src/types/usage.ts +34 -25
- package/packages/const/src/settings/systemAgent.ts +0 -1
- package/packages/context-engine/src/index.ts +1 -0
- package/packages/context-engine/src/tools/ToolNameResolver.ts +2 -2
- package/packages/context-engine/src/tools/ToolsEngine.ts +37 -8
- package/packages/context-engine/src/tools/__tests__/ToolsEngine.test.ts +149 -5
- package/packages/context-engine/src/tools/__tests__/utils.test.ts +2 -2
- package/packages/context-engine/src/tools/index.ts +1 -0
- package/packages/context-engine/src/tools/types.ts +18 -3
- package/packages/context-engine/src/tools/utils.ts +4 -4
- package/packages/types/src/tool/builtin.ts +54 -1
- package/packages/types/src/tool/index.ts +1 -0
- package/packages/types/src/tool/intervention.ts +114 -0
- package/packages/types/src/user/settings/systemAgent.ts +0 -1
- package/packages/types/src/user/settings/tool.ts +37 -0
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/OrchestratorThinking.tsx +2 -3
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +2 -2
- package/src/app/[variants]/(main)/chat/(workspace)/@topic/features/GroupConfig/GroupMember.tsx +34 -2
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Main.tsx +1 -1
- package/src/app/[variants]/(main)/chat/(workspace)/features/{GroupChatSettings → AgentTeamSettings}/index.tsx +4 -5
- package/src/app/[variants]/(main)/chat/(workspace)/features/SettingButton.tsx +2 -2
- package/src/app/[variants]/(main)/chat/@session/_layout/Desktop/SessionHeader.tsx +2 -0
- package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/CollapseGroup/Actions.tsx +18 -1
- package/src/components/ChatGroupWizard/ChatGroupWizard.tsx +33 -5
- package/src/components/MemberSelectionModal/MemberSelectionModal.tsx +170 -26
- package/src/features/Conversation/Messages/Assistant/Actions/index.tsx +7 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +4 -2
- package/src/features/Conversation/Messages/User/Actions.tsx +8 -2
- package/src/features/GroupChatSettings/{ChatGroupSettings.tsx → AgentTeamChatSettings.tsx} +6 -5
- package/src/features/GroupChatSettings/{GroupMembers.tsx → AgentTeamMembersSettings.tsx} +64 -19
- package/src/features/GroupChatSettings/{ChatGroupMeta.tsx → AgentTeamMetaSettings.tsx} +2 -2
- package/src/features/GroupChatSettings/AgentTeamSettings.tsx +54 -0
- package/src/features/GroupChatSettings/index.ts +4 -5
- package/src/locales/default/chat.ts +17 -17
- package/src/locales/default/setting.ts +15 -19
- package/src/locales/default/welcome.ts +1 -1
- package/src/store/chat/slices/aiChat/actions/generateAIGroupChat.ts +2 -1
- package/src/store/chat/slices/builtinTool/actions/{dalle.test.ts → __tests__/dalle.test.ts} +2 -5
- package/src/store/chat/slices/builtinTool/actions/__tests__/{localFile.test.ts → localSystem.test.ts} +4 -4
- package/src/store/chat/slices/builtinTool/actions/index.ts +2 -2
- package/src/store/chat/slices/builtinTool/actions/{localFile.ts → localSystem.ts} +183 -69
- package/src/store/chatGroup/action.ts +36 -1
- package/src/store/electron/selectors/__tests__/desktopState.test.ts +3 -3
- package/src/store/electron/selectors/desktopState.ts +11 -2
- package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +0 -4
- package/src/store/user/slices/settings/selectors/systemAgent.ts +0 -2
- package/src/tools/local-system/Placeholder/ListFiles.tsx +10 -8
- package/src/tools/local-system/Placeholder/SearchFiles.tsx +12 -10
- package/src/tools/local-system/Placeholder/index.tsx +1 -1
- package/src/tools/local-system/Render/ReadLocalFile/ReadFileSkeleton.tsx +8 -18
- package/src/tools/local-system/Render/ReadLocalFile/ReadFileView.tsx +21 -6
- package/src/tools/local-system/Render/SearchFiles/Result.tsx +5 -4
- package/src/tools/local-system/Render/SearchFiles/SearchQuery/SearchView.tsx +4 -15
- package/src/tools/local-system/Render/SearchFiles/index.tsx +3 -2
- package/src/tools/local-system/type.ts +39 -0
- package/docs/usage/features/group-chat.zh-CN.mdx +0 -52
- package/src/features/GroupChatSettings/GroupSettings.tsx +0 -30
- package/src/features/GroupChatSettings/GroupSettingsContent.tsx +0 -24
- package/src/tools/local-system/Placeholder/ReadLocalFile.tsx +0 -9
- package/src/tools/local-system/Render/ReadLocalFile/style.ts +0 -37
- /package/src/store/chat/slices/builtinTool/actions/{search.test.ts → __tests__/search.test.ts} +0 -0
|
@@ -46,6 +46,8 @@ const Header = memo(() => {
|
|
|
46
46
|
const { showCreateSession, enableGroupChat } = useServerConfigStore(featureFlagsSelectors);
|
|
47
47
|
const [isGroupWizardOpen, setIsGroupWizardOpen] = useState(false);
|
|
48
48
|
|
|
49
|
+
// const enableGroupChatInLabs = useUserStore(preferenceSelectors.enableGroupChat);
|
|
50
|
+
|
|
49
51
|
// We need pass inital member list so we cannot use mutate
|
|
50
52
|
const [isCreatingGroup, setIsCreatingGroup] = useState(false);
|
|
51
53
|
|
|
@@ -82,11 +82,28 @@ const Actions = memo<ActionsProps>(
|
|
|
82
82
|
},
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
const handleCreateGroupWithMembers = async (
|
|
85
|
+
const handleCreateGroupWithMembers = async (
|
|
86
|
+
selectedAgents: string[],
|
|
87
|
+
hostConfig?: { model?: string; provider?: string },
|
|
88
|
+
enableSupervisor?: boolean,
|
|
89
|
+
) => {
|
|
86
90
|
try {
|
|
87
91
|
setIsCreatingGroup(true);
|
|
92
|
+
|
|
93
|
+
const config: any = {};
|
|
94
|
+
|
|
95
|
+
if (enableSupervisor !== undefined) {
|
|
96
|
+
config.enableSupervisor = enableSupervisor;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (hostConfig) {
|
|
100
|
+
config.orchestratorModel = hostConfig.model;
|
|
101
|
+
config.orchestratorProvider = hostConfig.provider;
|
|
102
|
+
}
|
|
103
|
+
|
|
88
104
|
await createGroup(
|
|
89
105
|
{
|
|
106
|
+
config: Object.keys(config).length > 0 ? config : undefined,
|
|
90
107
|
title: 'New Group Chat',
|
|
91
108
|
},
|
|
92
109
|
selectedAgents,
|
|
@@ -5,11 +5,11 @@ import { Button, Checkbox, Empty, Switch } from 'antd';
|
|
|
5
5
|
import { createStyles, useTheme } from 'antd-style';
|
|
6
6
|
import { omit } from 'lodash-es';
|
|
7
7
|
import { Users } from 'lucide-react';
|
|
8
|
-
import { ChangeEvent, memo, useCallback, useEffect, useMemo, useState } from 'react';
|
|
8
|
+
import { ChangeEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
|
10
10
|
import { Flexbox } from 'react-layout-kit';
|
|
11
11
|
|
|
12
|
-
import { DEFAULT_AVATAR
|
|
12
|
+
import { DEFAULT_AVATAR } from '@/const/meta';
|
|
13
13
|
import ModelSelect from '@/features/ModelSelect';
|
|
14
14
|
import { useEnabledChatModels } from '@/hooks/useEnabledChatModels';
|
|
15
15
|
import { useSessionStore } from '@/store/session';
|
|
@@ -233,6 +233,7 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
|
|
|
233
233
|
return { model: undefined, provider: undefined };
|
|
234
234
|
}, [enabledModels]);
|
|
235
235
|
|
|
236
|
+
const [inputValue, setInputValue] = useState('');
|
|
236
237
|
const [searchTerm, setSearchTerm] = useState('');
|
|
237
238
|
const [selectedTemplate, setSelectedTemplate] = useState<string>('');
|
|
238
239
|
const [selectedAgents, setSelectedAgents] = useState<string[]>([]);
|
|
@@ -244,6 +245,8 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
|
|
|
244
245
|
const [isCreatingCustom, setIsCreatingCustom] = useState(false);
|
|
245
246
|
const [activePanel, setActivePanel] = useState<'templates' | 'agents'>('templates');
|
|
246
247
|
|
|
248
|
+
const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
249
|
+
|
|
247
250
|
const isCreatingFromTemplate = externalLoading ?? false;
|
|
248
251
|
|
|
249
252
|
const handleTemplateToggle = useCallback((templateId: string) => {
|
|
@@ -278,10 +281,16 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
|
|
|
278
281
|
const handleReset = () => {
|
|
279
282
|
setSelectedTemplate('');
|
|
280
283
|
setSelectedAgents([]);
|
|
284
|
+
setInputValue('');
|
|
281
285
|
setSearchTerm('');
|
|
282
286
|
setRemovedMembers({});
|
|
283
287
|
setIsHostRemoved(false);
|
|
284
288
|
setHostModelConfig(defaultModel.model && defaultModel.provider ? defaultModel : {});
|
|
289
|
+
|
|
290
|
+
// Clear any pending debounce timer
|
|
291
|
+
if (debounceTimerRef.current) {
|
|
292
|
+
clearTimeout(debounceTimerRef.current);
|
|
293
|
+
}
|
|
285
294
|
};
|
|
286
295
|
|
|
287
296
|
const handleHostModelChange = useCallback((config: { model?: string; provider?: string }) => {
|
|
@@ -319,11 +328,31 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
|
|
|
319
328
|
}, []);
|
|
320
329
|
|
|
321
330
|
const handleSearchChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
|
|
322
|
-
|
|
331
|
+
const value = event.target.value;
|
|
332
|
+
setInputValue(value);
|
|
333
|
+
|
|
334
|
+
// Clear previous timer
|
|
335
|
+
if (debounceTimerRef.current) {
|
|
336
|
+
clearTimeout(debounceTimerRef.current);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Set new timer to update searchTerm after 300ms
|
|
340
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
341
|
+
setSearchTerm(value);
|
|
342
|
+
}, 300);
|
|
323
343
|
}, []);
|
|
324
344
|
|
|
325
345
|
const agentCount = visibleAgentSessions.length;
|
|
326
346
|
|
|
347
|
+
// Cleanup debounce timer on unmount
|
|
348
|
+
useEffect(() => {
|
|
349
|
+
return () => {
|
|
350
|
+
if (debounceTimerRef.current) {
|
|
351
|
+
clearTimeout(debounceTimerRef.current);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
}, []);
|
|
355
|
+
|
|
327
356
|
useEffect(() => {
|
|
328
357
|
if (!open) return;
|
|
329
358
|
|
|
@@ -551,7 +580,7 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
|
|
|
551
580
|
onChange={handleSearchChange}
|
|
552
581
|
placeholder={t('memberSelection.searchAgents')}
|
|
553
582
|
style={{ margin: `${theme.paddingSM}px ${theme.paddingSM}px 0 ${theme.paddingSM}px` }}
|
|
554
|
-
value={
|
|
583
|
+
value={inputValue}
|
|
555
584
|
variant="filled"
|
|
556
585
|
/>
|
|
557
586
|
<Flexbox flex={1} style={{ overflowY: 'auto', padding: `0 ${theme.paddingSM}px` }}>
|
|
@@ -636,7 +665,6 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
|
|
|
636
665
|
<Flexbox className={styles.rightColumn} flex={1}>
|
|
637
666
|
<Flexbox flex={1} gap={16} style={{ overflowY: 'auto' }}>
|
|
638
667
|
<Flexbox align="center" className={styles.hostCard} gap={12} horizontal>
|
|
639
|
-
<Avatar avatar={DEFAULT_SUPERVISOR_AVATAR} shape="circle" size={40} />
|
|
640
668
|
<Flexbox flex={1} gap={2}>
|
|
641
669
|
<Text
|
|
642
670
|
style={{ fontSize: 14, fontWeight: 500 }}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { ActionIcon, Avatar, List, Modal, SearchBar } from '@lobehub/ui';
|
|
3
|
+
import { ActionIcon, Avatar, List, Modal, SearchBar, Text, Tooltip } from '@lobehub/ui';
|
|
4
4
|
import { useHover } from 'ahooks';
|
|
5
|
-
import { List as AntdList, Button, Checkbox, Empty, Typography } from 'antd';
|
|
5
|
+
import { List as AntdList, Button, Checkbox, Empty, Switch, Typography } from 'antd';
|
|
6
6
|
import { createStyles } from 'antd-style';
|
|
7
7
|
import { X } from 'lucide-react';
|
|
8
8
|
import { type ChangeEvent, memo, useCallback, useMemo, useRef, useState } from 'react';
|
|
@@ -10,10 +10,12 @@ import { useTranslation } from 'react-i18next';
|
|
|
10
10
|
import { Flexbox } from 'react-layout-kit';
|
|
11
11
|
|
|
12
12
|
import { DEFAULT_AVATAR } from '@/const/meta';
|
|
13
|
+
import ModelSelect from '@/features/ModelSelect';
|
|
14
|
+
import { useEnabledChatModels } from '@/hooks/useEnabledChatModels';
|
|
13
15
|
import { useSessionStore } from '@/store/session';
|
|
14
16
|
import { LobeAgentSession, LobeSessionType } from '@/types/session';
|
|
15
17
|
|
|
16
|
-
const { Text } = Typography;
|
|
18
|
+
const { Text: AntText } = Typography;
|
|
17
19
|
|
|
18
20
|
const AvailableAgentItem = memo<{
|
|
19
21
|
agent: LobeAgentSession;
|
|
@@ -56,11 +58,11 @@ const AvailableAgentItem = memo<{
|
|
|
56
58
|
/>
|
|
57
59
|
</Flexbox>
|
|
58
60
|
<Flexbox flex={1} gap={2} style={{ minWidth: 0 }}>
|
|
59
|
-
<
|
|
61
|
+
<AntText className={styles.title}>{title}</AntText>
|
|
60
62
|
{description && (
|
|
61
|
-
<
|
|
63
|
+
<AntText className={styles.description} ellipsis>
|
|
62
64
|
{description}
|
|
63
|
-
</
|
|
65
|
+
</AntText>
|
|
64
66
|
)}
|
|
65
67
|
</Flexbox>
|
|
66
68
|
</Flexbox>
|
|
@@ -82,6 +84,14 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
82
84
|
line-height: 1.2;
|
|
83
85
|
color: ${token.colorTextSecondary};
|
|
84
86
|
`,
|
|
87
|
+
hostCard: css`
|
|
88
|
+
margin-block-end: ${token.paddingSM}px;
|
|
89
|
+
padding: ${token.padding}px;
|
|
90
|
+
border: 1px solid ${token.colorBorderSecondary};
|
|
91
|
+
border-radius: ${token.borderRadiusLG}px;
|
|
92
|
+
|
|
93
|
+
background: ${token.colorFillTertiary};
|
|
94
|
+
`,
|
|
85
95
|
leftColumn: css`
|
|
86
96
|
user-select: none;
|
|
87
97
|
|
|
@@ -107,6 +117,9 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
107
117
|
background: ${token.colorFillTertiary};
|
|
108
118
|
}
|
|
109
119
|
`,
|
|
120
|
+
modelSelectDisabled: css`
|
|
121
|
+
pointer-events: none;
|
|
122
|
+
`,
|
|
110
123
|
rightColumn: css`
|
|
111
124
|
overflow-y: auto;
|
|
112
125
|
flex: 1;
|
|
@@ -121,6 +134,14 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
121
134
|
export type MemberSelectionMode = 'create' | 'add';
|
|
122
135
|
|
|
123
136
|
export interface MemberSelectionModalProps {
|
|
137
|
+
/**
|
|
138
|
+
* Current host configuration (for add mode)
|
|
139
|
+
*/
|
|
140
|
+
currentHostConfig?: {
|
|
141
|
+
enableSupervisor?: boolean;
|
|
142
|
+
orchestratorModel?: string;
|
|
143
|
+
orchestratorProvider?: string;
|
|
144
|
+
};
|
|
124
145
|
/**
|
|
125
146
|
* Existing group members to exclude from available agents (for add mode)
|
|
126
147
|
*/
|
|
@@ -136,7 +157,11 @@ export interface MemberSelectionModalProps {
|
|
|
136
157
|
*/
|
|
137
158
|
mode: MemberSelectionMode;
|
|
138
159
|
onCancel: () => void;
|
|
139
|
-
onConfirm: (
|
|
160
|
+
onConfirm: (
|
|
161
|
+
selectedAgents: string[],
|
|
162
|
+
hostConfig?: { model?: string; provider?: string },
|
|
163
|
+
enableSupervisor?: boolean,
|
|
164
|
+
) => void | Promise<void>;
|
|
140
165
|
open: boolean;
|
|
141
166
|
/**
|
|
142
167
|
* Pre-selected agent IDs (useful for editing existing groups)
|
|
@@ -145,15 +170,56 @@ export interface MemberSelectionModalProps {
|
|
|
145
170
|
}
|
|
146
171
|
|
|
147
172
|
const MemberSelectionModal = memo<MemberSelectionModalProps>(
|
|
148
|
-
({
|
|
173
|
+
({
|
|
174
|
+
currentHostConfig,
|
|
175
|
+
existingMembers = [],
|
|
176
|
+
mode,
|
|
177
|
+
onCancel,
|
|
178
|
+
onConfirm,
|
|
179
|
+
open,
|
|
180
|
+
preSelectedAgents = [],
|
|
181
|
+
}) => {
|
|
149
182
|
const { t } = useTranslation(['chat', 'common']);
|
|
150
183
|
const { styles, cx } = useStyles();
|
|
184
|
+
const enabledModels = useEnabledChatModels();
|
|
151
185
|
const [selectedAgents, setSelectedAgents] = useState<string[]>(preSelectedAgents);
|
|
152
186
|
const [searchTerm, setSearchTerm] = useState('');
|
|
153
187
|
|
|
188
|
+
// Determine if host card should be shown
|
|
189
|
+
const isHostCurrentlyEnabled = mode === 'add' && currentHostConfig?.enableSupervisor === true;
|
|
190
|
+
|
|
191
|
+
// Initialize host state:
|
|
192
|
+
// - In create mode: default to enabled (isHostRemoved = false)
|
|
193
|
+
// - In add mode with host disabled: default to disabled (isHostRemoved = true)
|
|
194
|
+
const [isHostRemoved, setIsHostRemoved] = useState(mode === 'add' ? true : false);
|
|
195
|
+
const [hostModelConfig, setHostModelConfig] = useState<{ model?: string; provider?: string }>(
|
|
196
|
+
() => {
|
|
197
|
+
if (mode === 'add' && currentHostConfig) {
|
|
198
|
+
return {
|
|
199
|
+
model: currentHostConfig.orchestratorModel,
|
|
200
|
+
provider: currentHostConfig.orchestratorProvider,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
// Set default for create mode
|
|
204
|
+
if (enabledModels.length > 0 && enabledModels[0].children.length > 0) {
|
|
205
|
+
const firstProvider = enabledModels[0];
|
|
206
|
+
const firstModel = firstProvider.children[0];
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
model: firstModel.id,
|
|
210
|
+
provider: firstProvider.id,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return {};
|
|
214
|
+
},
|
|
215
|
+
);
|
|
216
|
+
|
|
154
217
|
const agentSessions = useSessionStore((s) => {
|
|
155
218
|
const allSessions = s.sessions || [];
|
|
156
|
-
return allSessions.filter(
|
|
219
|
+
return allSessions.filter(
|
|
220
|
+
(session): session is LobeAgentSession =>
|
|
221
|
+
session.type === LobeSessionType.Agent && !session.config?.virtual,
|
|
222
|
+
);
|
|
157
223
|
});
|
|
158
224
|
|
|
159
225
|
const currentSessionId = useSessionStore((s) => s.activeId);
|
|
@@ -172,6 +238,14 @@ const MemberSelectionModal = memo<MemberSelectionModalProps>(
|
|
|
172
238
|
setSearchTerm(e.target.value);
|
|
173
239
|
}, []);
|
|
174
240
|
|
|
241
|
+
const handleHostToggle = useCallback((enabled: boolean) => {
|
|
242
|
+
setIsHostRemoved(!enabled);
|
|
243
|
+
}, []);
|
|
244
|
+
|
|
245
|
+
const handleHostModelChange = useCallback((config: { model?: string; provider?: string }) => {
|
|
246
|
+
setHostModelConfig(config);
|
|
247
|
+
}, []);
|
|
248
|
+
|
|
175
249
|
// Filter logic based on mode
|
|
176
250
|
const availableAgents = useMemo(() => {
|
|
177
251
|
if (mode === 'create') {
|
|
@@ -237,14 +311,35 @@ const MemberSelectionModal = memo<MemberSelectionModalProps>(
|
|
|
237
311
|
const handleReset = () => {
|
|
238
312
|
setSelectedAgents(preSelectedAgents);
|
|
239
313
|
setSearchTerm('');
|
|
314
|
+
setIsHostRemoved(mode === 'add' ? true : false);
|
|
315
|
+
if (mode === 'add' && currentHostConfig) {
|
|
316
|
+
setHostModelConfig({
|
|
317
|
+
model: currentHostConfig.orchestratorModel,
|
|
318
|
+
provider: currentHostConfig.orchestratorProvider,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
240
321
|
};
|
|
241
322
|
|
|
242
323
|
const [isAdding, setIsAdding] = useState(false);
|
|
243
324
|
|
|
325
|
+
const normalizedHostModelConfig = useMemo(() => {
|
|
326
|
+
const model = hostModelConfig.model;
|
|
327
|
+
const provider = hostModelConfig.provider;
|
|
328
|
+
|
|
329
|
+
if (!model || !provider) return undefined;
|
|
330
|
+
|
|
331
|
+
return { model, provider };
|
|
332
|
+
}, [hostModelConfig]);
|
|
333
|
+
|
|
244
334
|
const handleConfirm = async () => {
|
|
245
335
|
try {
|
|
246
336
|
setIsAdding(true);
|
|
247
|
-
|
|
337
|
+
// Only pass host config if the host card is visible (being managed in this modal)
|
|
338
|
+
const shouldManageHost = !isHostCurrentlyEnabled;
|
|
339
|
+
const hostConfig =
|
|
340
|
+
shouldManageHost && !isHostRemoved ? normalizedHostModelConfig : undefined;
|
|
341
|
+
const enableSupervisor = shouldManageHost ? !isHostRemoved : undefined;
|
|
342
|
+
await onConfirm(selectedAgents, hostConfig, enableSupervisor);
|
|
248
343
|
handleReset();
|
|
249
344
|
} catch (error) {
|
|
250
345
|
console.error('Failed to confirm action:', error);
|
|
@@ -265,8 +360,13 @@ const MemberSelectionModal = memo<MemberSelectionModalProps>(
|
|
|
265
360
|
const confirmButtonText =
|
|
266
361
|
mode === 'create' ? t('memberSelection.createGroup') : t('memberSelection.addMember');
|
|
267
362
|
|
|
363
|
+
// Calculate total member count including host if enabled
|
|
364
|
+
// Only count the host when the host card is visible (create mode or add mode with host disabled)
|
|
365
|
+
const shouldShowHostCard = !isHostCurrentlyEnabled;
|
|
366
|
+
const totalMemberCount = selectedAgents.length + (shouldShowHostCard && !isHostRemoved ? 1 : 0);
|
|
367
|
+
|
|
268
368
|
const minMembersRequired = mode === 'create' ? 1 : 0; // At least 1 member for group creation
|
|
269
|
-
const isConfirmDisabled =
|
|
369
|
+
const isConfirmDisabled = totalMemberCount < minMembersRequired || isAdding;
|
|
270
370
|
|
|
271
371
|
return (
|
|
272
372
|
<Modal
|
|
@@ -280,7 +380,7 @@ const MemberSelectionModal = memo<MemberSelectionModalProps>(
|
|
|
280
380
|
onClick={handleConfirm}
|
|
281
381
|
type="primary"
|
|
282
382
|
>
|
|
283
|
-
{confirmButtonText} ({
|
|
383
|
+
{confirmButtonText} ({totalMemberCount})
|
|
284
384
|
</Button>
|
|
285
385
|
</Flexbox>
|
|
286
386
|
}
|
|
@@ -337,22 +437,66 @@ const MemberSelectionModal = memo<MemberSelectionModalProps>(
|
|
|
337
437
|
</Flexbox>
|
|
338
438
|
</Flexbox>
|
|
339
439
|
|
|
340
|
-
{/* Right Column - Selected Agents */}
|
|
440
|
+
{/* Right Column - Host and Selected Agents */}
|
|
341
441
|
<Flexbox className={styles.rightColumn} flex={1}>
|
|
342
|
-
{
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
:
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
442
|
+
<Flexbox gap={16}>
|
|
443
|
+
{/* Host Card - Only show in create mode or when host is disabled in add mode */}
|
|
444
|
+
{!isHostCurrentlyEnabled && (
|
|
445
|
+
<Flexbox align="center" className={styles.hostCard} gap={12} horizontal>
|
|
446
|
+
<Flexbox flex={1} gap={2}>
|
|
447
|
+
<Text
|
|
448
|
+
style={{ fontSize: 14, fontWeight: 500 }}
|
|
449
|
+
type={isHostRemoved ? 'secondary' : undefined}
|
|
450
|
+
>
|
|
451
|
+
{t('groupWizard.host.title')}
|
|
452
|
+
</Text>
|
|
453
|
+
<Text
|
|
454
|
+
style={{ color: '#999', fontSize: 12 }}
|
|
455
|
+
type={isHostRemoved ? 'secondary' : undefined}
|
|
456
|
+
>
|
|
457
|
+
{t('groupWizard.host.description')}
|
|
458
|
+
</Text>
|
|
459
|
+
</Flexbox>
|
|
460
|
+
<Flexbox align="center" gap={12} horizontal>
|
|
461
|
+
<div
|
|
462
|
+
className={cx(isHostRemoved && styles.modelSelectDisabled)}
|
|
463
|
+
style={{ opacity: isHostRemoved ? 0.6 : 1 }}
|
|
464
|
+
>
|
|
465
|
+
<ModelSelect
|
|
466
|
+
onChange={handleHostModelChange}
|
|
467
|
+
requiredAbilities={['functionCall']}
|
|
468
|
+
value={normalizedHostModelConfig}
|
|
469
|
+
/>
|
|
470
|
+
</div>
|
|
471
|
+
<Tooltip title={t('groupWizard.host.tooltip')}>
|
|
472
|
+
<Switch
|
|
473
|
+
checked={!isHostRemoved}
|
|
474
|
+
onChange={(checked) => handleHostToggle(checked)}
|
|
475
|
+
size="small"
|
|
476
|
+
/>
|
|
477
|
+
</Tooltip>
|
|
478
|
+
</Flexbox>
|
|
479
|
+
</Flexbox>
|
|
480
|
+
)}
|
|
481
|
+
|
|
482
|
+
{/* Selected Agents List */}
|
|
483
|
+
<Flexbox flex={1}>
|
|
484
|
+
{selectedAgentListItems.length === 0 ? (
|
|
485
|
+
<Flexbox align="center" flex={1} justify="center">
|
|
486
|
+
<Empty
|
|
487
|
+
description={
|
|
488
|
+
mode === 'create'
|
|
489
|
+
? t('memberSelection.noSelectedAgents')
|
|
490
|
+
: t('memberSelection.noSelectedAgents')
|
|
491
|
+
}
|
|
492
|
+
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
|
493
|
+
/>
|
|
494
|
+
</Flexbox>
|
|
495
|
+
) : (
|
|
496
|
+
<List items={selectedAgentListItems} />
|
|
497
|
+
)}
|
|
352
498
|
</Flexbox>
|
|
353
|
-
|
|
354
|
-
<List items={selectedAgentListItems} />
|
|
355
|
-
)}
|
|
499
|
+
</Flexbox>
|
|
356
500
|
</Flexbox>
|
|
357
501
|
</Flexbox>
|
|
358
502
|
</Modal>
|
|
@@ -8,6 +8,8 @@ import ShareMessageModal from '@/features/Conversation/components/ShareMessageMo
|
|
|
8
8
|
import { VirtuosoContext } from '@/features/Conversation/components/VirtualizedList/VirtuosoContext';
|
|
9
9
|
import { useChatStore } from '@/store/chat';
|
|
10
10
|
import { threadSelectors } from '@/store/chat/selectors';
|
|
11
|
+
import { useSessionStore } from '@/store/session';
|
|
12
|
+
import { sessionSelectors } from '@/store/session/selectors';
|
|
11
13
|
import { ChatMessage } from '@/types/message';
|
|
12
14
|
|
|
13
15
|
import { InPortalThreadContext } from '../../../context/InPortalThreadContext';
|
|
@@ -25,6 +27,7 @@ export const AssistantActionsBar = memo<AssistantActionsProps>(({ id, data, inde
|
|
|
25
27
|
!!s.activeThreadId,
|
|
26
28
|
threadSelectors.hasThreadBySourceMsgId(id)(s),
|
|
27
29
|
]);
|
|
30
|
+
const isGroupSession = useSessionStore(sessionSelectors.isCurrentSessionGroupSession);
|
|
28
31
|
const [showShareModal, setShareModal] = useState(false);
|
|
29
32
|
|
|
30
33
|
const {
|
|
@@ -49,8 +52,10 @@ export const AssistantActionsBar = memo<AssistantActionsProps>(({ id, data, inde
|
|
|
49
52
|
const items = useMemo(() => {
|
|
50
53
|
if (hasTools) return [delAndRegenerate, copy];
|
|
51
54
|
|
|
52
|
-
return [edit, copy, inThread ? null : branching].filter(
|
|
53
|
-
|
|
55
|
+
return [edit, copy, inThread || isGroupSession ? null : branching].filter(
|
|
56
|
+
Boolean,
|
|
57
|
+
) as ActionIconGroupItemType[];
|
|
58
|
+
}, [inThread, hasTools, isGroupSession]);
|
|
54
59
|
|
|
55
60
|
const { t } = useTranslation('common');
|
|
56
61
|
const searchParams = useSearchParams();
|
|
@@ -52,8 +52,10 @@ const Render = memo<RenderProps>(
|
|
|
52
52
|
|
|
53
53
|
// 如果是 LOADING_FLAT 则说明还在加载中
|
|
54
54
|
// 而 standalone 模式的插件 content 应该始终是 LOADING_FLAT
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
const inPlaceholder =
|
|
56
|
+
toolMessage.content === LOADING_FLAT && toolMessage.plugin?.type !== 'standalone';
|
|
57
|
+
|
|
58
|
+
if (inPlaceholder) return placeholder;
|
|
57
59
|
|
|
58
60
|
return (
|
|
59
61
|
<Suspense fallback={placeholder}>
|
|
@@ -9,6 +9,8 @@ import { useTranslation } from 'react-i18next';
|
|
|
9
9
|
|
|
10
10
|
import { useChatStore } from '@/store/chat';
|
|
11
11
|
import { threadSelectors } from '@/store/chat/selectors';
|
|
12
|
+
import { useSessionStore } from '@/store/session';
|
|
13
|
+
import { sessionSelectors } from '@/store/session/selectors';
|
|
12
14
|
|
|
13
15
|
import { VirtuosoContext } from '../../components/VirtualizedList/VirtuosoContext';
|
|
14
16
|
import { InPortalThreadContext } from '../../context/InPortalThreadContext';
|
|
@@ -54,6 +56,8 @@ export const UserActionsBar = memo<UserActionsProps>(({ id, data, index }) => {
|
|
|
54
56
|
s.delAndResendThreadMessage,
|
|
55
57
|
]);
|
|
56
58
|
|
|
59
|
+
const isGroupSession = useSessionStore(sessionSelectors.isCurrentSessionGroupSession);
|
|
60
|
+
|
|
57
61
|
const { regenerate, edit, copy, divider, del, branching, tts, translate } = useChatListActionsBar(
|
|
58
62
|
{ hasThread },
|
|
59
63
|
);
|
|
@@ -63,8 +67,10 @@ export const UserActionsBar = memo<UserActionsProps>(({ id, data, index }) => {
|
|
|
63
67
|
|
|
64
68
|
const items = useMemo(
|
|
65
69
|
() =>
|
|
66
|
-
[regenerate, edit, inThread ? null : branching].filter(
|
|
67
|
-
|
|
70
|
+
[regenerate, edit, inThread || isGroupSession ? null : branching].filter(
|
|
71
|
+
Boolean,
|
|
72
|
+
) as ActionIconGroupItemType[],
|
|
73
|
+
[inThread, isGroupSession],
|
|
68
74
|
);
|
|
69
75
|
|
|
70
76
|
const { message } = App.useApp();
|
|
@@ -22,9 +22,9 @@ import { selectors, useStore } from './store';
|
|
|
22
22
|
const { TextArea } = Input;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Chat Settings for Group Chat
|
|
25
|
+
* Chat Settings for Agent Team (Group Chat)
|
|
26
26
|
*/
|
|
27
|
-
const
|
|
27
|
+
const AgentTeamChatSettings = memo(() => {
|
|
28
28
|
const { t } = useTranslation(['setting', 'common']);
|
|
29
29
|
const [form] = Form.useForm();
|
|
30
30
|
const updateConfig = useStore((s) => s.updateGroupConfig);
|
|
@@ -171,8 +171,9 @@ const ChatGroupSettings = memo(() => {
|
|
|
171
171
|
itemsType={'group'}
|
|
172
172
|
onFinish={async ({ _modelConfig, ...rest }) => {
|
|
173
173
|
await updateConfig({
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
// Preserve existing values when _modelConfig is undefined (enableSupervisor is false)
|
|
175
|
+
orchestratorModel: _modelConfig?.model ?? config?.orchestratorModel,
|
|
176
|
+
orchestratorProvider: _modelConfig?.provider ?? config?.orchestratorProvider,
|
|
176
177
|
...rest,
|
|
177
178
|
});
|
|
178
179
|
|
|
@@ -184,4 +185,4 @@ const ChatGroupSettings = memo(() => {
|
|
|
184
185
|
);
|
|
185
186
|
});
|
|
186
187
|
|
|
187
|
-
export default
|
|
188
|
+
export default AgentTeamChatSettings;
|