@lobehub/lobehub 2.0.0-next.266 → 2.0.0-next.268
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/.cursor/rules/microcopy-cn.mdc +75 -63
- package/.cursor/rules/microcopy-en.mdc +4 -8
- package/CHANGELOG.md +50 -0
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/apps/desktop/src/main/locales/default/common.ts +2 -2
- package/changelog/v1.json +10 -0
- package/docs/development/database-schema.dbml +4 -0
- package/e2e/CLAUDE.md +43 -81
- package/e2e/cucumber.config.js +1 -0
- package/e2e/docs/local-setup.md +67 -219
- package/e2e/scripts/setup.ts +529 -0
- package/e2e/src/features/home/sidebarAgent.feature +62 -0
- package/e2e/src/features/home/sidebarGroup.feature +62 -0
- package/e2e/src/features/page/README.md +118 -0
- package/e2e/src/features/page/crud.feature +62 -0
- package/e2e/src/features/page/editor-content.feature +93 -0
- package/e2e/src/features/page/editor-meta.feature +60 -0
- package/e2e/src/steps/agent/conversation.steps.ts +4 -4
- package/e2e/src/steps/home/sidebarAgent.steps.ts +370 -0
- package/e2e/src/steps/home/sidebarGroup.steps.ts +168 -0
- package/e2e/src/steps/hooks.ts +4 -0
- package/e2e/src/steps/page/editor-content.steps.ts +344 -0
- package/e2e/src/steps/page/editor-meta.steps.ts +410 -0
- package/e2e/src/steps/page/page-crud.steps.ts +363 -0
- package/e2e/src/support/world.ts +12 -0
- package/locales/ar/file.json +2 -0
- package/locales/bg-BG/file.json +2 -0
- package/locales/de-DE/file.json +2 -0
- package/locales/en-US/auth.json +1 -1
- package/locales/en-US/file.json +2 -0
- package/locales/en-US/metadata.json +2 -2
- package/locales/es-ES/file.json +2 -0
- package/locales/fa-IR/file.json +2 -0
- package/locales/fr-FR/file.json +2 -0
- package/locales/it-IT/file.json +2 -0
- package/locales/ja-JP/file.json +2 -0
- package/locales/ko-KR/file.json +2 -0
- package/locales/nl-NL/file.json +2 -0
- package/locales/pl-PL/file.json +2 -0
- package/locales/pt-BR/file.json +2 -0
- package/locales/ru-RU/file.json +2 -0
- package/locales/tr-TR/file.json +2 -0
- package/locales/vi-VN/file.json +2 -0
- package/locales/zh-CN/file.json +2 -0
- package/locales/zh-TW/file.json +2 -0
- package/package.json +3 -3
- package/packages/builtin-agents/src/agents/agent-builder/index.ts +1 -1
- package/packages/builtin-agents/src/agents/group-agent-builder/index.ts +1 -1
- package/packages/builtin-agents/src/agents/page-agent/index.ts +1 -1
- package/packages/const/src/settings/group.ts +0 -10
- package/packages/database/migrations/0068_update_group_data.sql +4 -0
- package/packages/database/migrations/meta/0068_snapshot.json +9588 -0
- package/packages/database/migrations/meta/_journal.json +7 -0
- package/packages/database/src/models/__tests__/chatGroup.test.ts +5 -7
- package/packages/database/src/models/__tests__/knowledgeBase.test.ts +185 -0
- package/packages/database/src/models/knowledgeBase.ts +67 -3
- package/packages/database/src/repositories/agentGroup/index.test.ts +23 -29
- package/packages/database/src/repositories/agentGroup/index.ts +4 -9
- package/packages/database/src/repositories/knowledge/index.ts +3 -3
- package/packages/database/src/schemas/chatGroup.ts +4 -3
- package/packages/database/src/types/chatGroup.ts +0 -7
- package/packages/types/src/agentGroup/index.ts +30 -9
- package/packages/utils/src/multimodalContent.test.ts +302 -0
- package/packages/utils/src/server/__tests__/sse.test.ts +353 -0
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/AgentGroupItem/Editing.tsx +4 -11
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/AgentGroupItem/index.tsx +3 -3
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/ModalProvider.tsx +9 -32
- package/src/app/[variants]/(main)/home/_layout/hooks/useCreateMenuItems.tsx +3 -37
- package/src/app/[variants]/(main)/home/_layout/hooks/useSessionGroupMenuItems.tsx +7 -53
- package/src/app/[variants]/(main)/home/features/RecentPage/List.tsx +2 -1
- package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +1 -1
- package/src/app/[variants]/(main)/resource/library/_layout/Sidebar.tsx +2 -2
- package/src/app/[variants]/(main)/resource/library/features/LibraryMenu.tsx +2 -2
- package/src/app/[variants]/(mobile)/chat/settings/features/SettingButton.tsx +2 -12
- package/src/components/ChatGroupWizard/ChatGroupWizard.tsx +5 -27
- package/src/components/DragUpload/index.tsx +24 -27
- package/src/components/MemberSelectionModal/MemberSelectionModal.tsx +2 -11
- package/src/features/ChatInput/ActionBar/Params/Controls.tsx +42 -7
- package/src/features/CommandMenu/useCommandMenu.ts +4 -14
- package/src/features/ResourceManager/components/Editor/index.tsx +2 -3
- package/src/features/ResourceManager/components/Explorer/Header/index.tsx +13 -17
- package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +1 -1
- package/src/features/ResourceManager/components/Explorer/ListView/ListItem/TruncatedFileName.tsx +130 -0
- package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +36 -4
- package/src/features/ResourceManager/components/Explorer/ListView/Skeleton.tsx +4 -3
- package/src/features/ResourceManager/components/Explorer/ListView/index.tsx +58 -2
- package/src/features/ResourceManager/components/Explorer/MasonryView/index.tsx +58 -6
- package/src/features/ResourceManager/components/Explorer/MoveToFolderModal.tsx +2 -5
- package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +9 -5
- package/src/features/ResourceManager/components/Explorer/index.tsx +11 -56
- package/src/features/ResourceManager/components/Header/AddButton.tsx +5 -6
- package/src/features/ResourceManager/components/LibraryHierarchy/HierarchyNode.tsx +382 -0
- package/src/features/ResourceManager/components/LibraryHierarchy/index.tsx +396 -0
- package/src/features/ResourceManager/components/LibraryHierarchy/styles.ts +19 -0
- package/src/features/ResourceManager/components/LibraryHierarchy/treeState.ts +178 -0
- package/src/features/ResourceManager/components/LibraryHierarchy/types.ts +10 -0
- package/src/features/ResourceManager/index.tsx +3 -0
- package/src/layout/GlobalProvider/GroupWizardProvider.tsx +6 -29
- package/src/locales/default/auth.ts +1 -1
- package/src/locales/default/file.ts +2 -0
- package/src/locales/default/metadata.ts +2 -2
- package/src/server/modules/AgentRuntime/AgentRuntimeCoordinator.ts +30 -30
- package/src/server/modules/AgentRuntime/AgentStateManager.ts +23 -23
- package/src/server/modules/AgentRuntime/InMemoryAgentStateManager.ts +16 -16
- package/src/server/modules/AgentRuntime/InMemoryStreamEventManager.ts +13 -13
- package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +2 -2
- package/src/server/modules/AgentRuntime/StreamEventManager.ts +18 -18
- package/src/server/modules/AgentRuntime/types.ts +21 -21
- package/src/server/routers/lambda/__tests__/agentGroup.test.ts +8 -8
- package/src/server/routers/lambda/agentGroup.ts +10 -12
- package/src/server/services/document/index.ts +1 -0
- package/src/store/agentGroup/slices/curd.test.ts +4 -4
- package/src/store/file/slices/fileManager/action.ts +12 -4
- package/src/store/home/slices/homeInput/action.ts +0 -3
- package/src/store/home/slices/sidebarUI/action.ts +9 -0
- package/src/store/session/slices/session/action.ts +5 -9
- package/src/app/[variants]/(mobile)/chat/settings/features/AgentTeamSettings/index.tsx +0 -95
- package/src/features/GroupChatSettings/AgentCard.tsx +0 -154
- package/src/features/GroupChatSettings/AgentTeamChatSettings.tsx +0 -179
- package/src/features/GroupChatSettings/AgentTeamMembersSettings.tsx +0 -244
- package/src/features/GroupChatSettings/AgentTeamMetaSettings.tsx +0 -94
- package/src/features/GroupChatSettings/AgentTeamSettings.tsx +0 -54
- package/src/features/GroupChatSettings/GroupCategory/index.tsx +0 -30
- package/src/features/GroupChatSettings/GroupCategory/useGroupCategory.tsx +0 -42
- package/src/features/GroupChatSettings/GroupChatSettingsProvider.tsx +0 -19
- package/src/features/GroupChatSettings/HostMemberCard.tsx +0 -113
- package/src/features/GroupChatSettings/StoreUpdater.tsx +0 -34
- package/src/features/GroupChatSettings/hooks/useGroupChatSettings.ts +0 -25
- package/src/features/GroupChatSettings/index.ts +0 -16
- package/src/features/GroupChatSettings/store/action.ts +0 -105
- package/src/features/GroupChatSettings/store/index.ts +0 -18
- package/src/features/GroupChatSettings/store/initialState.ts +0 -23
- package/src/features/GroupChatSettings/store/selectors.ts +0 -13
- package/src/features/ResourceManager/components/Tree/index.tsx +0 -883
- /package/src/features/ResourceManager/components/{Tree → LibraryHierarchy}/TreeSkeleton.tsx +0 -0
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { Avatar, Flexbox, Icon, Skeleton, Text, Tooltip } from '@lobehub/ui';
|
|
4
|
-
import { Switch } from 'antd';
|
|
5
|
-
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
|
-
import { Bot, Loader2 } from 'lucide-react';
|
|
7
|
-
import { memo } from 'react';
|
|
8
|
-
import { useTranslation } from 'react-i18next';
|
|
9
|
-
|
|
10
|
-
import { DEFAULT_AVATAR } from '@/const/meta';
|
|
11
|
-
import { useIsDark } from '@/hooks/useIsDark';
|
|
12
|
-
import { type LobeAgentSession } from '@/types/session';
|
|
13
|
-
|
|
14
|
-
const styles = createStaticStyles(({ css }) => ({
|
|
15
|
-
container: css`
|
|
16
|
-
position: relative;
|
|
17
|
-
|
|
18
|
-
overflow: hidden;
|
|
19
|
-
|
|
20
|
-
height: 100%;
|
|
21
|
-
border-radius: 12px;
|
|
22
|
-
|
|
23
|
-
background: ${cssVar.colorBgContainer};
|
|
24
|
-
|
|
25
|
-
transition: border-color 0.2s ${cssVar.motionEaseInOut};
|
|
26
|
-
|
|
27
|
-
&:hover {
|
|
28
|
-
border-color: ${cssVar.colorPrimary};
|
|
29
|
-
}
|
|
30
|
-
`,
|
|
31
|
-
containerDark: css`
|
|
32
|
-
border: 1px solid ${cssVar.colorBorder};
|
|
33
|
-
`,
|
|
34
|
-
containerLight: css`
|
|
35
|
-
border: 1px solid ${cssVar.colorBorderSecondary};
|
|
36
|
-
`,
|
|
37
|
-
desc: css`
|
|
38
|
-
overflow: hidden;
|
|
39
|
-
|
|
40
|
-
height: 3em;
|
|
41
|
-
margin-block-end: 0 !important;
|
|
42
|
-
|
|
43
|
-
line-height: 1.5;
|
|
44
|
-
color: ${cssVar.colorTextDescription};
|
|
45
|
-
`,
|
|
46
|
-
title: css`
|
|
47
|
-
line-height: 1.3;
|
|
48
|
-
`,
|
|
49
|
-
}));
|
|
50
|
-
|
|
51
|
-
interface AgentCardProps {
|
|
52
|
-
agent: LobeAgentSession;
|
|
53
|
-
inGroup: boolean;
|
|
54
|
-
isHost?: boolean;
|
|
55
|
-
loading?: boolean;
|
|
56
|
-
onAction: (agentId: string, action: 'add' | 'remove') => void;
|
|
57
|
-
operationLoading?: boolean;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const AgentCard = memo<AgentCardProps>(
|
|
61
|
-
({ agent, inGroup, isHost, loading, onAction, operationLoading }) => {
|
|
62
|
-
const { t } = useTranslation('setting');
|
|
63
|
-
const isDarkMode = useIsDark();
|
|
64
|
-
|
|
65
|
-
if (loading) {
|
|
66
|
-
return (
|
|
67
|
-
<Flexbox
|
|
68
|
-
className={cx(
|
|
69
|
-
styles.container,
|
|
70
|
-
isDarkMode ? styles.containerDark : styles.containerLight,
|
|
71
|
-
)}
|
|
72
|
-
gap={24}
|
|
73
|
-
padding={16}
|
|
74
|
-
>
|
|
75
|
-
<Skeleton active />
|
|
76
|
-
</Flexbox>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const agentId = agent.config?.id;
|
|
81
|
-
const title = agent.meta?.title || t('settingGroupMembers.defaultAgent');
|
|
82
|
-
const description = agent.meta?.description || '';
|
|
83
|
-
const avatar = agent.meta?.avatar || DEFAULT_AVATAR;
|
|
84
|
-
const avatarBackground = agent.meta?.backgroundColor;
|
|
85
|
-
|
|
86
|
-
if (!agentId) return null;
|
|
87
|
-
|
|
88
|
-
const handleAction = (checked: boolean) => {
|
|
89
|
-
onAction(agentId, checked ? 'add' : 'remove');
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<Flexbox
|
|
94
|
-
className={cx(styles.container, isDarkMode ? styles.containerDark : styles.containerLight)}
|
|
95
|
-
gap={24}
|
|
96
|
-
>
|
|
97
|
-
<Flexbox gap={12} padding={16} width={'100%'}>
|
|
98
|
-
<Flexbox gap={12} width={'100%'}>
|
|
99
|
-
<Flexbox align={'center'} horizontal justify={'space-between'}>
|
|
100
|
-
<Flexbox align={'center'} flex={1} gap={8} horizontal style={{ minWidth: 0 }}>
|
|
101
|
-
<Avatar
|
|
102
|
-
avatar={avatar}
|
|
103
|
-
background={avatarBackground}
|
|
104
|
-
shape={'square'}
|
|
105
|
-
size={24}
|
|
106
|
-
style={{ flexShrink: 0 }}
|
|
107
|
-
/>
|
|
108
|
-
<Text
|
|
109
|
-
className={styles.title}
|
|
110
|
-
ellipsis
|
|
111
|
-
style={{ fontSize: 16, fontWeight: 'bold', minWidth: 0 }}
|
|
112
|
-
>
|
|
113
|
-
{title}
|
|
114
|
-
</Text>
|
|
115
|
-
{isHost && (
|
|
116
|
-
<Tooltip title={t('settingGroupMembers.groupHost')}>
|
|
117
|
-
<Icon icon={Bot} size="small" style={{ color: '#1890ff' }} />
|
|
118
|
-
</Tooltip>
|
|
119
|
-
)}
|
|
120
|
-
</Flexbox>
|
|
121
|
-
</Flexbox>
|
|
122
|
-
<Text
|
|
123
|
-
className={styles.desc}
|
|
124
|
-
ellipsis={{
|
|
125
|
-
rows: 2,
|
|
126
|
-
}}
|
|
127
|
-
>
|
|
128
|
-
{description || t('settingGroupMembers.noDescription')}
|
|
129
|
-
</Text>
|
|
130
|
-
</Flexbox>
|
|
131
|
-
<Flexbox align="center" horizontal justify={'space-between'} width={'100%'}>
|
|
132
|
-
<Icon icon={Loader2} size="small" spin style={{ opacity: operationLoading ? 1 : 0 }} />
|
|
133
|
-
<Tooltip
|
|
134
|
-
title={
|
|
135
|
-
inGroup
|
|
136
|
-
? t('settingGroupMembers.removeFromGroup')
|
|
137
|
-
: t('settingGroupMembers.addToGroup')
|
|
138
|
-
}
|
|
139
|
-
>
|
|
140
|
-
<Switch
|
|
141
|
-
checked={inGroup}
|
|
142
|
-
disabled={operationLoading}
|
|
143
|
-
onChange={handleAction}
|
|
144
|
-
size="small"
|
|
145
|
-
/>
|
|
146
|
-
</Tooltip>
|
|
147
|
-
</Flexbox>
|
|
148
|
-
</Flexbox>
|
|
149
|
-
</Flexbox>
|
|
150
|
-
);
|
|
151
|
-
},
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
export default AgentCard;
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
Form,
|
|
5
|
-
type FormGroupItemType,
|
|
6
|
-
Icon,
|
|
7
|
-
Segmented,
|
|
8
|
-
Select,
|
|
9
|
-
SliderWithInput,
|
|
10
|
-
} from '@lobehub/ui';
|
|
11
|
-
import { Form as AntdForm, App, Input, Switch } from 'antd';
|
|
12
|
-
import { isEqual } from 'es-toolkit/compat';
|
|
13
|
-
import { Coffee, Rabbit, Turtle } from 'lucide-react';
|
|
14
|
-
import { memo } from 'react';
|
|
15
|
-
import { useTranslation } from 'react-i18next';
|
|
16
|
-
|
|
17
|
-
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
18
|
-
|
|
19
|
-
import ModelSelect from '../ModelSelect';
|
|
20
|
-
import { selectors, useStore } from './store';
|
|
21
|
-
|
|
22
|
-
const { TextArea } = Input;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Chat Settings for Agent Team (Group Chat)
|
|
26
|
-
*/
|
|
27
|
-
const AgentTeamChatSettings = memo(() => {
|
|
28
|
-
const { t } = useTranslation(['setting', 'common']);
|
|
29
|
-
const [form] = Form.useForm();
|
|
30
|
-
const updateConfig = useStore((s) => s.updateGroupConfig);
|
|
31
|
-
const config = useStore(selectors.currentChatConfig, isEqual);
|
|
32
|
-
|
|
33
|
-
const { message } = App.useApp();
|
|
34
|
-
|
|
35
|
-
// Watch the allowDM value to conditionally show revealDM
|
|
36
|
-
const allowDM = AntdForm.useWatch('allowDM', form);
|
|
37
|
-
// Watch the enableSupervisor value to conditionally show host options
|
|
38
|
-
const enableSupervisor = AntdForm.useWatch('enableSupervisor', form);
|
|
39
|
-
|
|
40
|
-
const responseSpeedOptions = [
|
|
41
|
-
{
|
|
42
|
-
icon: <Icon icon={Turtle} size={16} />,
|
|
43
|
-
label: t('settingGroupChat.responseSpeed.options.slow'),
|
|
44
|
-
value: 'slow',
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
icon: <Icon icon={Coffee} size={16} />,
|
|
48
|
-
label: t('settingGroupChat.responseSpeed.options.medium'),
|
|
49
|
-
value: 'medium',
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
icon: <Icon icon={Rabbit} size={16} />,
|
|
53
|
-
label: t('settingGroupChat.responseSpeed.options.fast'),
|
|
54
|
-
value: 'fast',
|
|
55
|
-
},
|
|
56
|
-
];
|
|
57
|
-
|
|
58
|
-
const supervisorOptions: FormGroupItemType = {
|
|
59
|
-
children: [
|
|
60
|
-
{
|
|
61
|
-
children: <Switch />,
|
|
62
|
-
desc: t('settingGroupChat.enableSupervisor.desc'),
|
|
63
|
-
divider: false,
|
|
64
|
-
label: t('settingGroupChat.enableSupervisor.title'),
|
|
65
|
-
name: 'enableSupervisor',
|
|
66
|
-
},
|
|
67
|
-
// Only show other options when enableSupervisor is true
|
|
68
|
-
...(enableSupervisor
|
|
69
|
-
? [
|
|
70
|
-
{
|
|
71
|
-
children: <ModelSelect requiredAbilities={['structuredOutput']} />,
|
|
72
|
-
desc: t('settingGroupChat.model.desc'),
|
|
73
|
-
label: t('settingGroupChat.model.title'),
|
|
74
|
-
name: '_modelConfig',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
children: (
|
|
78
|
-
<TextArea
|
|
79
|
-
autoSize={{ maxRows: 8, minRows: 3 }}
|
|
80
|
-
placeholder={t('settingGroupChat.systemPrompt.placeholder')}
|
|
81
|
-
rows={4}
|
|
82
|
-
/>
|
|
83
|
-
),
|
|
84
|
-
desc: t('settingGroupChat.systemPrompt.desc'),
|
|
85
|
-
label: t('settingGroupChat.systemPrompt.title'),
|
|
86
|
-
name: 'systemPrompt',
|
|
87
|
-
},
|
|
88
|
-
]
|
|
89
|
-
: []),
|
|
90
|
-
],
|
|
91
|
-
title: t('settingGroupChat.orchestratorTitle'),
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const chatOptions: FormGroupItemType = {
|
|
95
|
-
children: [
|
|
96
|
-
{
|
|
97
|
-
children: <Segmented options={responseSpeedOptions} />,
|
|
98
|
-
desc: t('settingGroupChat.responseSpeed.desc'),
|
|
99
|
-
label: t('settingGroupChat.responseSpeed.title'),
|
|
100
|
-
name: 'responseSpeed',
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
children: (
|
|
104
|
-
<Select
|
|
105
|
-
options={[
|
|
106
|
-
{
|
|
107
|
-
label: t('settingGroupChat.responseOrder.options.sequential'),
|
|
108
|
-
value: 'sequential',
|
|
109
|
-
},
|
|
110
|
-
{ label: t('settingGroupChat.responseOrder.options.natural'), value: 'natural' },
|
|
111
|
-
]}
|
|
112
|
-
placeholder={t('settingGroupChat.responseOrder.placeholder')}
|
|
113
|
-
/>
|
|
114
|
-
),
|
|
115
|
-
desc: t('settingGroupChat.responseOrder.desc'),
|
|
116
|
-
label: t('settingGroupChat.responseOrder.title'),
|
|
117
|
-
name: 'responseOrder',
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
children: <SliderWithInput max={32} min={0} step={1} unlimitedInput={true} />,
|
|
121
|
-
desc: t('settingGroupChat.maxResponseInRow.desc'),
|
|
122
|
-
divider: false,
|
|
123
|
-
label: t('settingGroupChat.maxResponseInRow.title'),
|
|
124
|
-
name: 'maxResponseInRow',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
children: <Switch />,
|
|
128
|
-
desc: t('settingGroupChat.allowDM.desc'),
|
|
129
|
-
divider: false,
|
|
130
|
-
label: t('settingGroupChat.allowDM.title'),
|
|
131
|
-
name: 'allowDM',
|
|
132
|
-
},
|
|
133
|
-
// Only show revealDM when allowDM is true
|
|
134
|
-
...(allowDM
|
|
135
|
-
? [
|
|
136
|
-
{
|
|
137
|
-
children: <Switch />,
|
|
138
|
-
desc: t('settingGroupChat.revealDM.desc'),
|
|
139
|
-
divider: false,
|
|
140
|
-
label: t('settingGroupChat.revealDM.title'),
|
|
141
|
-
name: 'revealDM',
|
|
142
|
-
},
|
|
143
|
-
]
|
|
144
|
-
: []),
|
|
145
|
-
],
|
|
146
|
-
title: t('settingGroupChat.title'),
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
return (
|
|
150
|
-
<Form
|
|
151
|
-
footer={<Form.SubmitFooter />}
|
|
152
|
-
form={form}
|
|
153
|
-
initialValues={{
|
|
154
|
-
...config,
|
|
155
|
-
_modelConfig: {
|
|
156
|
-
model: config?.orchestratorModel,
|
|
157
|
-
provider: config?.orchestratorProvider,
|
|
158
|
-
},
|
|
159
|
-
enableSupervisor: config?.enableSupervisor ?? true,
|
|
160
|
-
}}
|
|
161
|
-
items={[supervisorOptions, ...(enableSupervisor ? [chatOptions] : [])]}
|
|
162
|
-
itemsType={'group'}
|
|
163
|
-
onFinish={async ({ _modelConfig, ...rest }) => {
|
|
164
|
-
await updateConfig({
|
|
165
|
-
// Preserve existing values when _modelConfig is undefined (enableSupervisor is false)
|
|
166
|
-
orchestratorModel: _modelConfig?.model ?? config?.orchestratorModel,
|
|
167
|
-
orchestratorProvider: _modelConfig?.provider ?? config?.orchestratorProvider,
|
|
168
|
-
...rest,
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
message.success(t('message.success'));
|
|
172
|
-
}}
|
|
173
|
-
variant={'borderless'}
|
|
174
|
-
{...FORM_STYLE}
|
|
175
|
-
/>
|
|
176
|
-
);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
export default AgentTeamChatSettings;
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { ActionIcon, Flexbox, Grid, Tag, Text } from '@lobehub/ui';
|
|
4
|
-
import { createStaticStyles } from 'antd-style';
|
|
5
|
-
import { Plus } from 'lucide-react';
|
|
6
|
-
import { memo, useMemo, useState } from 'react';
|
|
7
|
-
import { useTranslation } from 'react-i18next';
|
|
8
|
-
|
|
9
|
-
import { DEFAULT_AVATAR } from '@/const/meta';
|
|
10
|
-
import { useAgentGroupStore } from '@/store/agentGroup';
|
|
11
|
-
import { agentGroupSelectors } from '@/store/agentGroup/selectors';
|
|
12
|
-
import { useSessionStore } from '@/store/session';
|
|
13
|
-
import { sessionSelectors } from '@/store/session/selectors';
|
|
14
|
-
import { type LobeAgentSession, type LobeGroupSession, LobeSessionType } from '@/types/session';
|
|
15
|
-
|
|
16
|
-
import AgentCard from './AgentCard';
|
|
17
|
-
import HostMemberCard from './HostMemberCard';
|
|
18
|
-
|
|
19
|
-
const styles = createStaticStyles(({ css }) => ({
|
|
20
|
-
container: css`
|
|
21
|
-
width: 100%;
|
|
22
|
-
`,
|
|
23
|
-
}));
|
|
24
|
-
|
|
25
|
-
const HOST_MEMBER_ID = 'supervisor';
|
|
26
|
-
|
|
27
|
-
const AgentTeamMembersSettings = memo(() => {
|
|
28
|
-
const { t } = useTranslation('setting');
|
|
29
|
-
const [loadingAgentId, setLoadingAgentId] = useState<string | null>(null);
|
|
30
|
-
const [isCreatingMember, setIsCreatingMember] = useState(false);
|
|
31
|
-
|
|
32
|
-
const activeGroupId = useSessionStore((s) => s.activeId);
|
|
33
|
-
const currentSession = useSessionStore(sessionSelectors.currentSession) as LobeGroupSession;
|
|
34
|
-
const groupConfig = useAgentGroupStore(agentGroupSelectors.currentGroupConfig);
|
|
35
|
-
|
|
36
|
-
const addAgentsToGroup = useAgentGroupStore((s) => s.addAgentsToGroup);
|
|
37
|
-
const removeAgentFromGroup = useAgentGroupStore((s) => s.removeAgentFromGroup);
|
|
38
|
-
const updateGroupConfig = useAgentGroupStore((s) => s.updateGroupConfig);
|
|
39
|
-
const refreshSessions = useSessionStore((s) => s.refreshSessions);
|
|
40
|
-
const createSession = useSessionStore((s) => s.createSession);
|
|
41
|
-
|
|
42
|
-
// Get all agent sessions
|
|
43
|
-
const agentSessions = useSessionStore((s) => {
|
|
44
|
-
const allSessions = s.sessions || [];
|
|
45
|
-
return allSessions.filter(
|
|
46
|
-
(session) => session.type === LobeSessionType.Agent,
|
|
47
|
-
) as LobeAgentSession[];
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const currentSessionId = useSessionStore((s) => s.activeId);
|
|
51
|
-
|
|
52
|
-
const isSupervisorEnabled = Boolean(groupConfig?.enableSupervisor);
|
|
53
|
-
|
|
54
|
-
// Get member IDs from current session
|
|
55
|
-
const memberIds = useMemo(() => {
|
|
56
|
-
return currentSession?.members?.map((member: any) => member.id) || [];
|
|
57
|
-
}, [currentSession?.members]);
|
|
58
|
-
|
|
59
|
-
// Separate agents into two groups: in group and not in group
|
|
60
|
-
const { agentsInGroup, agentsNotInGroup } = useMemo(() => {
|
|
61
|
-
const inGroup: LobeAgentSession[] = [];
|
|
62
|
-
const notInGroup: LobeAgentSession[] = [];
|
|
63
|
-
|
|
64
|
-
agentSessions.forEach((agent) => {
|
|
65
|
-
const agentId = agent.config?.id;
|
|
66
|
-
if (!agentId || agent.id === currentSessionId) return; // Skip current session
|
|
67
|
-
|
|
68
|
-
if (memberIds.includes(agentId)) {
|
|
69
|
-
inGroup.push(agent);
|
|
70
|
-
} else {
|
|
71
|
-
notInGroup.push(agent);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
return { agentsInGroup: inGroup, agentsNotInGroup: notInGroup };
|
|
76
|
-
}, [agentSessions, memberIds, currentSessionId]);
|
|
77
|
-
|
|
78
|
-
const handleAgentAction = async (agentId: string, action: 'add' | 'remove') => {
|
|
79
|
-
if (!activeGroupId) {
|
|
80
|
-
console.error('No active group to perform action on');
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Check if this is the host member
|
|
85
|
-
const isHostMember = agentId === HOST_MEMBER_ID;
|
|
86
|
-
|
|
87
|
-
// Set loading state for this specific agent
|
|
88
|
-
setLoadingAgentId(agentId);
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
if (action === 'add') {
|
|
92
|
-
if (isHostMember) {
|
|
93
|
-
// Host toggle updates supervisor flag instead of modifying members
|
|
94
|
-
await updateGroupConfig({ enableSupervisor: true });
|
|
95
|
-
} else {
|
|
96
|
-
await addAgentsToGroup(activeGroupId, [agentId]);
|
|
97
|
-
}
|
|
98
|
-
} else {
|
|
99
|
-
if (isHostMember) {
|
|
100
|
-
// Host toggle updates supervisor flag instead of modifying members
|
|
101
|
-
await updateGroupConfig({ enableSupervisor: false });
|
|
102
|
-
} else {
|
|
103
|
-
await removeAgentFromGroup(activeGroupId, agentId);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Refresh session data to reflect the changes
|
|
108
|
-
await refreshSessions();
|
|
109
|
-
} catch (error) {
|
|
110
|
-
console.error(`Failed to ${action} agent ${action === 'add' ? 'to' : 'from'} group:`, error);
|
|
111
|
-
} finally {
|
|
112
|
-
// Clear loading state
|
|
113
|
-
setLoadingAgentId(null);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const hostOperationLoading = loadingAgentId === HOST_MEMBER_ID;
|
|
118
|
-
|
|
119
|
-
const handleHostToggle = (checked: boolean) => {
|
|
120
|
-
handleAgentAction(HOST_MEMBER_ID, checked ? 'add' : 'remove');
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const handleCreateMember = async () => {
|
|
124
|
-
if (!activeGroupId || isCreatingMember) return;
|
|
125
|
-
|
|
126
|
-
setIsCreatingMember(true);
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
// Create a virtual assistant
|
|
130
|
-
const sessionId = await createSession(
|
|
131
|
-
{
|
|
132
|
-
config: {
|
|
133
|
-
virtual: true,
|
|
134
|
-
},
|
|
135
|
-
meta: {
|
|
136
|
-
avatar: DEFAULT_AVATAR,
|
|
137
|
-
description: '',
|
|
138
|
-
title: t('settingGroupMembers.defaultAgent'),
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
false, // Don't switch to the new session
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
// Refresh sessions to get the latest data
|
|
145
|
-
await refreshSessions();
|
|
146
|
-
|
|
147
|
-
// Get the agent ID from the created session
|
|
148
|
-
const session = sessionSelectors.getSessionById(sessionId)(useSessionStore.getState());
|
|
149
|
-
if (session && session.type === LobeSessionType.Agent) {
|
|
150
|
-
const agentSession = session as LobeAgentSession;
|
|
151
|
-
const agentId = agentSession.config?.id;
|
|
152
|
-
|
|
153
|
-
if (agentId) {
|
|
154
|
-
// Add the agent to the current group
|
|
155
|
-
await addAgentsToGroup(activeGroupId, [agentId]);
|
|
156
|
-
await refreshSessions();
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
} catch (error) {
|
|
160
|
-
console.error('Failed to create virtual member:', error);
|
|
161
|
-
} finally {
|
|
162
|
-
setIsCreatingMember(false);
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const groupMemberCount = agentsInGroup.length + (isSupervisorEnabled ? 1 : 0);
|
|
167
|
-
const availableAgentCount = agentsNotInGroup.length + (isSupervisorEnabled ? 0 : 1);
|
|
168
|
-
|
|
169
|
-
return (
|
|
170
|
-
<Flexbox className={styles.container} gap={40}>
|
|
171
|
-
{/* Agents in Group Section */}
|
|
172
|
-
<Flexbox gap={24}>
|
|
173
|
-
<Flexbox align={'center'} gap={8} horizontal justify="space-between">
|
|
174
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
175
|
-
<Text strong style={{ fontSize: 18 }}>
|
|
176
|
-
{t('settingGroupMembers.groupMembers')}
|
|
177
|
-
</Text>
|
|
178
|
-
<Tag>{groupMemberCount}</Tag>
|
|
179
|
-
</Flexbox>
|
|
180
|
-
<ActionIcon
|
|
181
|
-
icon={Plus}
|
|
182
|
-
loading={isCreatingMember}
|
|
183
|
-
onClick={handleCreateMember}
|
|
184
|
-
title={t('settingGroupMembers.createMember')}
|
|
185
|
-
/>
|
|
186
|
-
</Flexbox>
|
|
187
|
-
<Grid gap={16} rows={3}>
|
|
188
|
-
{isSupervisorEnabled && (
|
|
189
|
-
<HostMemberCard checked loading={hostOperationLoading} onToggle={handleHostToggle} />
|
|
190
|
-
)}
|
|
191
|
-
{agentsInGroup.map((agent) => (
|
|
192
|
-
<AgentCard
|
|
193
|
-
agent={agent}
|
|
194
|
-
inGroup={true}
|
|
195
|
-
key={agent.config?.id}
|
|
196
|
-
onAction={handleAgentAction}
|
|
197
|
-
operationLoading={loadingAgentId === agent.config?.id}
|
|
198
|
-
/>
|
|
199
|
-
))}
|
|
200
|
-
{agentsInGroup.length === 0 && !isSupervisorEnabled && (
|
|
201
|
-
<Text style={{ color: '#999', gridColumn: '1 / -1', padding: 40, textAlign: 'center' }}>
|
|
202
|
-
{t('settingGroupMembers.noMembersInGroup')}
|
|
203
|
-
</Text>
|
|
204
|
-
)}
|
|
205
|
-
</Grid>
|
|
206
|
-
</Flexbox>
|
|
207
|
-
|
|
208
|
-
{/* Agents not in Group Section */}
|
|
209
|
-
<Flexbox gap={24}>
|
|
210
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
211
|
-
<Text strong style={{ fontSize: 18 }}>
|
|
212
|
-
{t('settingGroupMembers.availableAgents')}
|
|
213
|
-
</Text>
|
|
214
|
-
<Tag>{availableAgentCount}</Tag>
|
|
215
|
-
</Flexbox>
|
|
216
|
-
<Grid gap={16} rows={3}>
|
|
217
|
-
{!isSupervisorEnabled && (
|
|
218
|
-
<HostMemberCard
|
|
219
|
-
checked={false}
|
|
220
|
-
loading={hostOperationLoading}
|
|
221
|
-
onToggle={handleHostToggle}
|
|
222
|
-
/>
|
|
223
|
-
)}
|
|
224
|
-
{agentsNotInGroup.map((agent) => (
|
|
225
|
-
<AgentCard
|
|
226
|
-
agent={agent}
|
|
227
|
-
inGroup={false}
|
|
228
|
-
key={agent.config?.id}
|
|
229
|
-
onAction={handleAgentAction}
|
|
230
|
-
operationLoading={loadingAgentId === agent.config?.id}
|
|
231
|
-
/>
|
|
232
|
-
))}
|
|
233
|
-
{agentsNotInGroup.length === 0 && isSupervisorEnabled && (
|
|
234
|
-
<Text style={{ color: '#999', gridColumn: '1 / -1', padding: 40, textAlign: 'center' }}>
|
|
235
|
-
{t('settingGroupMembers.noAvailableAgents')}
|
|
236
|
-
</Text>
|
|
237
|
-
)}
|
|
238
|
-
</Grid>
|
|
239
|
-
</Flexbox>
|
|
240
|
-
</Flexbox>
|
|
241
|
-
);
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
export default AgentTeamMembersSettings;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { Form, type FormGroupItemType, Icon, Segmented } from '@lobehub/ui';
|
|
4
|
-
import { useUpdateEffect } from 'ahooks';
|
|
5
|
-
import { Input } from 'antd';
|
|
6
|
-
import isEqual from 'fast-deep-equal';
|
|
7
|
-
import { Briefcase, Coffee } from 'lucide-react';
|
|
8
|
-
import { memo } from 'react';
|
|
9
|
-
import { useTranslation } from 'react-i18next';
|
|
10
|
-
|
|
11
|
-
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
12
|
-
|
|
13
|
-
import { selectors, useStore } from './store';
|
|
14
|
-
|
|
15
|
-
const { TextArea } = Input;
|
|
16
|
-
|
|
17
|
-
const AgentTeamMetaSettings = memo(() => {
|
|
18
|
-
const { t } = useTranslation(['setting', 'common']);
|
|
19
|
-
const [form] = Form.useForm();
|
|
20
|
-
|
|
21
|
-
const updateMeta = useStore((s) => s.updateGroupMeta);
|
|
22
|
-
const meta = useStore(selectors.currentMetaConfig, isEqual) || {};
|
|
23
|
-
const updateConfig = useStore((s) => s.updateGroupConfig);
|
|
24
|
-
const config = useStore(selectors.currentChatConfig, isEqual) || {};
|
|
25
|
-
|
|
26
|
-
useUpdateEffect(() => {
|
|
27
|
-
form.setFieldsValue({ ...meta, scene: config.scene });
|
|
28
|
-
}, [meta, config?.scene]);
|
|
29
|
-
|
|
30
|
-
const groupSettings: FormGroupItemType = {
|
|
31
|
-
children: [
|
|
32
|
-
{
|
|
33
|
-
children: <Input placeholder={t('settingGroup.name.placeholder')} />,
|
|
34
|
-
label: t('settingGroup.name.title'),
|
|
35
|
-
name: 'title',
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
children: (
|
|
39
|
-
<TextArea
|
|
40
|
-
autoSize={{ maxRows: 10, minRows: 5 }}
|
|
41
|
-
placeholder={t('settingGroup.description.placeholder')}
|
|
42
|
-
rows={4}
|
|
43
|
-
/>
|
|
44
|
-
),
|
|
45
|
-
label: t('settingGroup.description.title'),
|
|
46
|
-
name: 'description',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
children: (
|
|
50
|
-
<Segmented
|
|
51
|
-
options={[
|
|
52
|
-
{
|
|
53
|
-
icon: <Icon icon={Coffee} size={16} />,
|
|
54
|
-
label: t('settingGroup.scene.options.casual'),
|
|
55
|
-
value: 'casual',
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
icon: <Icon icon={Briefcase} size={16} />,
|
|
59
|
-
label: t('settingGroup.scene.options.productive'),
|
|
60
|
-
value: 'productive',
|
|
61
|
-
},
|
|
62
|
-
]}
|
|
63
|
-
/>
|
|
64
|
-
),
|
|
65
|
-
desc: t('settingGroup.scene.desc'),
|
|
66
|
-
label: t('settingGroup.scene.title'),
|
|
67
|
-
minWidth: undefined,
|
|
68
|
-
name: 'scene',
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
title: t('settingGroup.title'),
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<Form
|
|
76
|
-
footer={<Form.SubmitFooter />}
|
|
77
|
-
form={form}
|
|
78
|
-
initialValues={{ ...meta, scene: config.scene }}
|
|
79
|
-
items={[groupSettings]}
|
|
80
|
-
itemsType={'group'}
|
|
81
|
-
onFinish={async (values) => {
|
|
82
|
-
const { scene, ...metaPayload } = values as any;
|
|
83
|
-
await updateMeta(metaPayload);
|
|
84
|
-
if (scene && scene !== config.scene) {
|
|
85
|
-
await updateConfig({ scene });
|
|
86
|
-
}
|
|
87
|
-
}}
|
|
88
|
-
variant={'borderless'}
|
|
89
|
-
{...FORM_STYLE}
|
|
90
|
-
/>
|
|
91
|
-
);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
export default AgentTeamMetaSettings;
|