/* * @Author: ZhaoYing * @Date: 2026-02-03 16:29:33 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-20 15:16:25 */ import { useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react' import { useTranslation } from 'react-i18next' import { useParams } from 'react-router-dom'; import { Form, Space, Row, Col, Button, Flex, App, Select, Spin } from 'antd' import Card from './components/Card' import Tag from './components/Tag' import { getMultiAgentConfig, saveMultiAgentConfig, getApplicationList } from '@/api/application'; import type { Config, SubAgentModalRef, ChatData, SubAgentItem, ClusterRef, ModelConfigModalRef, FeaturesConfigForm } from './types' import Chat from './components/Chat' import RbCard from '@/components/RbCard/Card' import SubAgentModal from './components/SubAgentModal' import Empty from '@/components/Empty' import RadioGroupCard from '@/components/RadioGroupCard' import ModelSelect from '@/components/ModelSelect' import ModelConfigModal from './components/ModelConfigModal' import type { Application } from '@/views/ApplicationManagement/types' // import FeaturesConfig from './components/FeaturesConfig' const MAX_LENGTH = 5; /** * Multi-agent cluster configuration component * Manages multi-agent orchestration, sub-agents, and collaboration modes */ const Cluster = forwardRef void }>(({ onFeaturesLoad }, ref) => { const { t } = useTranslation() const { message } = App.useApp() const [form] = Form.useForm() const { id } = useParams() const subAgentModalRef = useRef(null) const [data, setData] = useState(null) const values = Form.useWatch([], form) const [subAgents, setSubAgents] = useState([]) const [chatList, setChatList] = useState([ { list: [] }, ]) const [loading, setLoading] = useState(false) /** * Save cluster configuration * @param flag - Whether to show success message * @returns Promise that resolves when save is complete */ const handleSave = (flag = true) => { if (!data) return Promise.resolve() if (!values.default_model_config_id && values.orchestration_mode === 'supervisor') { message.warning(t('common.selectPlaceholder', { title: t('application.model') })) return Promise.resolve() } const params = { id: data.id, app_id: data.app_id, ...values, sub_agents: (subAgents || []).map(item => ({ ...item, priority: 1, })) } return new Promise((resolve, reject) => { form.validateFields().then(() => { saveMultiAgentConfig(id as string, params) .then((res) => { if (flag) { message.success(t('common.saveSuccess')) } resolve(res) }) .catch(error => { reject(error) }) }) .catch(error => { reject(error) }) }) } useEffect(() => { getData() }, [id]) /** * Fetch cluster configuration data */ const getData = () => { if (!id) { return } setLoading(true) getMultiAgentConfig(id as string).then(res => { const response = res as Config setData(response) form.setFieldsValue({ ...response, }) let sub_agents = response.sub_agents || [] if (sub_agents.length > 0) { console.log({ ids: sub_agents?.map(item => item.agent_id) }) getApplicationList({ ids: sub_agents?.map(item => item.agent_id).join(',')}) .then(res => { const applicationList = (res as Application[]) || [] setSubAgents(sub_agents.map(vo => { const filterVO = applicationList.find(item => item.id === vo.agent_id) if (filterVO) { return { ...vo, name: filterVO.name, is_active: filterVO.is_active } } return vo })) }) } else { setSubAgents(sub_agents) } onFeaturesLoad?.(response.features) }) .finally(() => { setLoading(false) }) } /** * Open sub-agent modal for add or edit * @param agent - Optional agent data for edit mode */ const handleSubAgentModal = (agent?: SubAgentItem) => { subAgentModalRef.current?.handleOpen(agent) } /** * Refresh sub-agents list after add or edit * @param agent - Agent data to add or update */ const refreshSubAgents = (agent: SubAgentItem) => { const index = subAgents.findIndex(item => item.agent_id === agent.agent_id) const newSubAgents = [...subAgents] if (index === -1) { if (subAgents.length >= MAX_LENGTH) { message.warning(t('application.subAgentMaxLength', {maxLength: MAX_LENGTH})) return } setSubAgents([...newSubAgents, agent]) } else { newSubAgents[index] = agent setSubAgents(newSubAgents) } } /** * Delete sub-agent from list * @param agent - Agent to delete */ const handleDeleteSubAgent = (agent: SubAgentItem) => { setSubAgents(prev => prev.filter(item => item.agent_id !== agent.agent_id)) } useImperativeHandle(ref, () => ({ handleSave, features: data?.features })) const modelConfigModalRef = useRef(null) /** * Open model configuration modal */ const handleEditModelConfig = () => { modelConfigModalRef.current?.handleOpen('multi_agent', values.model_parameters) } /** * Save model configuration * @param values - Model parameters */ const handleSaveModelConfig = (values: Config['model_parameters']) => { form.setFieldsValue({ model_parameters: values }) } // const handleSaveFeaturesConfig = (value: FeaturesConfigForm) => { // form.setFieldValue('features', value) // } return ( <> {loading && }
{/* */} ({ value: type, label: t(`application.${type}`), labelDesc: t(`application.${type}Desc`), }))} allowClear={false} block={true} /> {t('application.subAgentsManagement')} ({subAgents.length}/{MAX_LENGTH}) } extra={} > {subAgents.length === 0 ?
: {subAgents.map((agent, index) => (
{agent.name} {agent.is_active ? t('common.enable') : t('common.deleted')}
{agent.role &&
{agent.role || '-'}
} {agent.capabilities && {agent.capabilities.map((tag, tagIndex) => {tag})} }
handleSubAgentModal(agent)} >
handleDeleteSubAgent(agent)} >
))}
}
{values?.orchestration_mode !== 'collaboration' && {t('application.model')}} required={true} className="rb:mb-4!" > {t('application.orchestrationMode')}} className="rb:mb-4!" > ({ value: type, label: t(`application.${type}`), }))} placeholder={t('common.pleaseSelect')} /> }
) }) export default Cluster