feat:智能体探索窗口与任务过程探索窗口联动修改

This commit is contained in:
liailing1026
2026-01-13 13:57:56 +08:00
parent 59fd94e783
commit 69587c0481
6 changed files with 177 additions and 169 deletions

View File

@@ -35,7 +35,7 @@ const branchInputRef = ref<InstanceType<typeof HTMLInputElement>>()
const branchLoading = ref(false)
// Mock 数据配置
const USE_MOCK_DATA = true
const USE_MOCK_DATA = false
// 节点和边数据
const nodes = ref<Node[]>([])
@@ -164,19 +164,14 @@ const initializeFlow = () => {
// 🆕 获取当前流程数据
const taskStepId = currentTask.value.Id
// 🆕 获取当前 agent 组合(用于区分不同 agent 组合的分支数据)
const currentAgents = currentTask.value.AgentSelection || []
// 🆕 从不可变的 agentRawPlan 中获取当前任务的原始数据(不受分支切换影响)
const collaborationProcess = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []
const currentTaskRaw = collaborationProcess.find((task: any) => task.Id === taskStepId)
// 🆕 优先使用不可变的数据源,降级到 taskProcess.value
let currentTaskProcess: any[]
if (currentTaskRaw && currentTaskRaw.TaskProcess) {
currentTaskProcess = currentTaskRaw.TaskProcess
} else {
currentTaskProcess = taskProcess.value
}
// 🆕 直接使用 taskProcess.value 作为数据源
// 注意:虽然 currentTask.id 相同,但不同的 agent 组合对应的 agent 任务过程不同
// taskProcess.value 从 currentTask.TaskProcess 获取,能正确反映当前 agent 组合的任务过程
const currentTaskProcess = taskProcess.value
console.log('currentTaskProcess:', currentTaskProcess)
// 🆕 立即保存为副本(深拷贝)
const taskProcessCopy = JSON.parse(JSON.stringify(currentTaskProcess))
@@ -263,22 +258,29 @@ const initializeFlow = () => {
// taskStepId 已在前面声明 (line 163)
if (taskStepId) {
const savedBranches = selectionStore.getTaskProcessBranches(taskStepId)
// 🆕 使用当前 agent 组合获取分支数据
const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
// 🆕 检查是否已经初始化过
const branchesInitKey = `${BRANCHES_INIT_KEY_PREFIX}${taskStepId}`
// 🆕 检查是否已经初始化过(针对该任务和 agent 组合)
const branchesInitKey = `${BRANCHES_INIT_KEY_PREFIX}${taskStepId}_${selectionStore.getAgentGroupKey(
currentAgents
)}`
const branchesInitialized = sessionStorage.getItem(branchesInitKey) === 'true'
if (branchesInitialized && savedBranches.length > 0) {
// 已有分支,恢复分支节点和边
// 已有分支,完全从 store 恢复所有节点和边
// 🔑 关键清空当前节点完全从store恢复确保初始流程节点位置和数据不变
nodes.value = []
edges.value = []
savedBranches.forEach(branch => {
// 恢复节点
// 恢复节点(深拷贝,避免引用问题)
branch.nodes.forEach(node => {
nodes.value.push(node)
nodes.value.push(JSON.parse(JSON.stringify(node)))
})
// 恢复边
// 恢复边(深拷贝)
branch.edges.forEach(edge => {
edges.value.push(edge)
edges.value.push(JSON.parse(JSON.stringify(edge)))
})
})
@@ -291,22 +293,22 @@ const initializeFlow = () => {
let nodesToHighlight: string[] = []
if (lastSelectedBranch.branchContent === '初始流程') {
// 初始流程:高亮所有主流程节点
nodesToHighlight = newNodes
// 初始流程:高亮所有主流程节点从恢复的nodes中获取
nodesToHighlight = nodes.value
.filter(n => !n.data.isBranchTask && n.id !== 'root')
.map(n => n.id)
} else {
// 其他分支:高亮主流程路径 + 分支节点(支持多级分支)
const firstBranchNode = lastSelectedBranch.nodes[0]
if (firstBranchNode) {
// 找到连接到该分支的第一个节点的边
const incomingEdge = newEdges.find(edge => edge.target === firstBranchNode.id)
// 找到连接到该分支的第一个节点的边从恢复的edges中查找
const incomingEdge = edges.value.find(edge => edge.target === firstBranchNode.id)
if (incomingEdge) {
// 回溯主流程路径
let currentNode = nodes.value.find(n => n.id === incomingEdge.source)
while (currentNode && currentNode.id !== 'root') {
nodesToHighlight.unshift(currentNode.id)
const prevEdge = newEdges.find(e => e.target === currentNode.id)
const prevEdge = edges.value.find(e => e.target === currentNode.id)
currentNode = prevEdge
? nodes.value.find(n => n.id === prevEdge.source)
: undefined
@@ -323,86 +325,29 @@ const initializeFlow = () => {
}
selectedNodeIds.value = new Set(nodesToHighlight)
// 恢复 TaskProcess 数据
if (lastSelectedBranch.branchContent === '初始流程') {
// 初始流程:直接使用分支的任务
selectionStore.setActiveTaskProcessData(taskStepId, lastSelectedBranch.tasks)
agentsStore.setCurrentTaskProcess(lastSelectedBranch.tasks)
} else {
// 其他分支:需要构建完整路径(主流程 + 所有相关分支)
if (nodesToHighlight.length > 0) {
const completeTaskProcess: any[] = []
// 添加主流程节点的数据
const initialBranch = savedBranches.find(b => b.branchContent === '初始流程')
const mainProcessData = initialBranch?.tasks || taskProcessCopy
nodesToHighlight.forEach(nodeId => {
const node = nodes.value.find(n => n.id === nodeId)
if (
node &&
node.data &&
!node.data.isBranchTask &&
node.data.originalIndex !== undefined
) {
const processData = mainProcessData[node.data.originalIndex]
if (
processData &&
processData.ID &&
processData.AgentName &&
processData.Description
) {
completeTaskProcess.push(processData)
}
}
})
// 🆕 添加分支节点的任务数据
if (lastSelectedBranch.tasks) {
const validBranchTasks = lastSelectedBranch.tasks.filter(
task => task && task.ID && task.AgentName && task.Description
)
completeTaskProcess.push(...validBranchTasks)
console.log(` 🔄 恢复分支任务: ${validBranchTasks.length}`)
}
console.log(`✅ 分支恢复完成:`, {
主流程任务数:
completeTaskProcess.length -
(lastSelectedBranch.tasks?.filter(
task => task && task.ID && task.AgentName && task.Description
).length || 0),
分支任务数: lastSelectedBranch.tasks?.length || 0,
总任务数: completeTaskProcess.length
})
selectionStore.setActiveTaskProcessData(taskStepId, completeTaskProcess)
agentsStore.setCurrentTaskProcess(completeTaskProcess)
}
}
} else {
// 找不到最后选中的分支,默认选中初始流程
selectionStore.setActiveTaskProcessData(taskStepId, taskProcessCopy)
const mainProcessNodes = newNodes
// 找不到最后选中的分支,默认选中初始流程的高亮状态
const mainProcessNodes = nodes.value
.filter(n => !n.data.isBranchTask && n.id !== 'root')
.map(n => n.id)
selectedNodeIds.value = new Set(mainProcessNodes)
}
} else {
// 没有保存的选中分支,默认选中初始流程
selectionStore.setActiveTaskProcessData(taskStepId, taskProcessCopy)
const mainProcessNodes = newNodes
// 没有保存的选中分支,默认选中初始流程的高亮状态
const mainProcessNodes = nodes.value
.filter(n => !n.data.isBranchTask && n.id !== 'root')
.map(n => n.id)
selectedNodeIds.value = new Set(mainProcessNodes)
}
} else {
// 🆕 首次初始化:将主流程保存为"初始流程"分支
const initialBranchNodes = newNodes.filter(node => node.id !== 'root')
// 🆕 首次初始化:设置节点和边,并保存为"初始流程"分支
nodes.value = newNodes
edges.value = newEdges
const initialBranchNodes = newNodes // ✅ 保留所有节点,包括根节点
const initialBranchEdges = [...newEdges]
const initialBranchId = selectionStore.addTaskProcessBranch(taskStepId, {
const initialBranchId = selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
parentNodeId: 'root',
branchContent: '初始流程',
branchType: 'root',
@@ -411,16 +356,13 @@ const initializeFlow = () => {
tasks: taskProcessCopy // 👈 使用副本(已经是深拷贝)
})
// 🆕 标记已初始化(针对该任务步骤)
// 🆕 标记已初始化(针对该任务步骤和 agent 组合
sessionStorage.setItem(branchesInitKey, 'true')
// 🆕 首次初始化时,设置初始流程为当前选中分支
selectionStore.setActiveTaskProcessBranch(taskStepId, initialBranchId)
selectionStore.setActiveTaskProcessBranch(taskStepId, currentAgents, initialBranchId)
// 🆕 首次初始化时,保存初始流程的 TaskProcess 数据
selectionStore.setActiveTaskProcessData(taskStepId, taskProcessCopy)
// 默认选中"初始流程"
// 默认选中"初始流程"的高亮状态
const mainProcessNodes = newNodes
.filter(n => !n.data.isBranchTask && n.id !== 'root')
.map(n => n.id)
@@ -435,9 +377,11 @@ const syncBranchesToStore = () => {
isSyncing = true
const taskStepId = currentTask.value.Id
// 🆕 获取当前 agent 组合
const currentAgents = currentTask.value.AgentSelection || []
// 🔄 获取现有的分支数据(用于保留初始流程分支)
const existingBranches = selectionStore.getTaskProcessBranches(taskStepId)
const existingBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
const existingBranchesMap = new Map<string, any>()
existingBranches.forEach(branch => {
// 使用分支ID作为key
@@ -553,7 +497,7 @@ const syncBranchesToStore = () => {
} else {
}
selectionStore.addTaskProcessBranch(taskStepId, {
selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
parentNodeId,
branchContent: JSON.parse(JSON.stringify(branchData.branchContent)),
branchType: JSON.parse(JSON.stringify(branchData.branchType)),
@@ -682,7 +626,8 @@ const onNodeClick = (event: any) => {
// 🆕 从 store 中获取"初始流程"副本(而不是使用 taskProcess.value
const taskStepId = currentTask.value.Id
const branches = selectionStore.getTaskProcessBranches(taskStepId)
const currentAgents = currentTask.value.AgentSelection || []
const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
const initialBranch = branches.find(branch => branch.branchContent === '初始流程')
const mainProcessData = initialBranch?.tasks || taskProcess.value
@@ -735,7 +680,11 @@ const onNodeClick = (event: any) => {
console.log(`💾 保存选中的分支ID: ${matchedBranch.id}`)
}
selectionStore.setActiveTaskProcessData(currentTask.value.Id, completeTaskProcess)
selectionStore.setActiveTaskProcessData(
currentTask.value.Id,
currentAgents,
completeTaskProcess
)
agentsStore.setCurrentTaskProcess(completeTaskProcess)
}
} else {
@@ -754,12 +703,13 @@ const onNodeClick = (event: any) => {
// 🆕 点击主流程节点时,从 store 读取"初始流程"分支的副本
if (currentTask.value) {
const taskStepId = currentTask.value.Id
const branches = selectionStore.getTaskProcessBranches(taskStepId)
const currentAgents = currentTask.value.AgentSelection || []
const branches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
const initialBranch = branches.find(branch => branch.branchContent === '初始流程')
if (initialBranch && initialBranch.tasks) {
// 使用 store 中保存的初始流程副本
selectionStore.setActiveTaskProcessData(taskStepId, initialBranch.tasks)
selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, initialBranch.tasks)
// 🆕 同步更新 currentTask.TaskProcess实现全局数据联动
agentsStore.setCurrentTaskProcess(initialBranch.tasks)
@@ -769,7 +719,7 @@ const onNodeClick = (event: any) => {
} else {
// 降级:使用 taskProcess.value
const originalTaskProcess = taskProcess.value
selectionStore.setActiveTaskProcessData(taskStepId, originalTaskProcess)
selectionStore.setActiveTaskProcessData(taskStepId, currentAgents, originalTaskProcess)
// 🆕 同步更新 currentTask.TaskProcess实现全局数据联动
agentsStore.setCurrentTaskProcess(originalTaskProcess)
@@ -831,7 +781,8 @@ const submitBranch = async () => {
// 💾 同步更新 store 中保存的分支位置
if (currentTask.value?.Id) {
const taskStepId = currentTask.value.Id
const savedBranches = selectionStore.getTaskProcessBranches(taskStepId)
const currentAgents = currentTask.value.AgentSelection || []
const savedBranches = selectionStore.getTaskProcessBranches(taskStepId, currentAgents)
savedBranches.forEach(branch => {
branch.nodes.forEach(branchNode => {
@@ -1021,8 +972,9 @@ const submitBranch = async () => {
// 使用任务过程分支存储
// 注意:需要对 nodes 和 edges 进行深拷贝,避免保存响应式引用
const taskStepId = currentTask.value?.Id || ''
const currentAgents = currentTask.value?.AgentSelection || []
isSyncing = true // 设置标志,避免 watch 触发重复同步
selectionStore.addTaskProcessBranch(taskStepId, {
selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
parentNodeId: parentNodeId,
branchContent: branchContent,
branchType: 'root',
@@ -1219,8 +1171,9 @@ const submitBranch = async () => {
// 使用任务过程分支存储
// 注意:需要对 nodes 和 edges 进行深拷贝,避免保存响应式引用
const taskStepId = currentTask.value?.Id || ''
const currentAgents = currentTask.value?.AgentSelection || []
isSyncing = true // 设置标志,避免 watch 触发重复同步
selectionStore.addTaskProcessBranch(taskStepId, {
selectionStore.addTaskProcessBranch(taskStepId, currentAgents, {
parentNodeId: parentNodeId,
branchContent: branchContent,
branchType: 'task',
@@ -1277,8 +1230,8 @@ onConnect(params => addEdges(params))
v-model:nodes="nodes"
v-model:edges="edges"
:delete-key-code="null"
:default-viewport="{ zoom: 0.3, x: 0, y: 0 }"
:min-zoom="0.2"
:default-viewport="{ zoom: 0.5, x: 0, y: 0 }"
:min-zoom="0.5"
:max-zoom="4"
@node-click="onNodeClick"
class="vue-flow-container"

View File

@@ -18,7 +18,9 @@ const branchCount = computed(() => {
// 获取该任务步骤的分支数据
const taskStepId = props.step.Id
const branches = selectionStore.getTaskProcessBranches(taskStepId)
// 🆕 获取该任务的 agent 组合
const agents = props.step.AgentSelection || []
const branches = selectionStore.getTaskProcessBranches(taskStepId, agents)
// 主分支(1) + 额外分支数量
return branches.length || 1

View File

@@ -66,7 +66,7 @@ const selectionStore = useSelectionStore()
// Mock 数据配置
// 开关:控制是否使用 mock 数据(开发时设置为 true生产时设置为 false
const USE_MOCK_DATA = true
const USE_MOCK_DATA = false
// 获取协作流程数据
const collaborationProcess = computed(() => {
@@ -218,7 +218,6 @@ const initializeFlow = () => {
// 如果已经初始化过,只恢复已保存的分支,不重新创建
if (branchesInitialized && savedBranches.length > 0) {
const newNodes: Node[] = []
const newEdges: Edge[] = []
@@ -535,7 +534,6 @@ onMounted(() => {
// 节点点击事件
const onNodeClick = (event: any) => {
const nodeId = event.node.id
const nodeData = event.node.data as any
@@ -604,7 +602,6 @@ const onNodeClick = (event: any) => {
const fullProcessTasks: IRawStepTask[] = []
const allBranches = selectionStore.getAllFlowBranches()
// 遍历所有高亮节点,收集对应的任务数据
nodesToHighlight.forEach(nodeId => {
const node = nodes.value.find(n => n.id === nodeId)
@@ -649,7 +646,6 @@ const onNodeClick = (event: any) => {
// 更新选中的节点集合
selectedNodeIds.value = new Set(nodesToHighlight)
}
// 编辑任务
@@ -672,7 +668,6 @@ const handleCancelAddBranch = () => {
// 添加分支
const handleAddBranch = async (taskId: string, branchContent: string) => {
// 获取父节点
const parentNode = nodes.value.find(n => n.id === taskId)
if (!parentNode) return
@@ -1100,7 +1095,6 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
edges: newBranchEdges,
tasks: JSON.parse(JSON.stringify(newTasks))
})
}
}
@@ -1124,7 +1118,6 @@ const handleAddBranch = async (taskId: string, branchContent: string) => {
// 删除分支
const handleDeleteBranch = (branchId: string) => {
// 删除分支节点
nodes.value = nodes.value.filter(n => n.id !== branchId)

View File

@@ -79,7 +79,7 @@ const handleSubmit = async () => {
// 使用 Mock API 进行测试(开发阶段)
// 切换到真实API时只需将 mockAgentSelectModifyAddAspect 改为 agentSelectModifyAddAspect
const response = await api.mockAgentSelectModifyAddAspect({
const response = await api.agentSelectModifyAddAspect({
aspectList: [...scoreDimensions.value, newDimension]
})
@@ -169,7 +169,7 @@ const confirmAgentSelection = async () => {
// 调用 Mock API 填充任务流程
try {
isLoadingConfirm.value = true
console.log('=== 开始调用 mockFillStepTaskTaskProcess Mock API ===')
console.log('=== 开始调用 fillStepTaskTaskProcess Mock API ===')
console.log('1. 当前任务数据 (IRawStepTask 格式):', currentTask.value)
console.log('2. 选中的 agents:', agentArray)
@@ -194,7 +194,7 @@ const confirmAgentSelection = async () => {
console.log('4. General Goal:', goal)
// 调用 Mock API
const filledTask = await api.mockFillStepTaskTaskProcess({
const filledTask = await api.fillStepTaskTaskProcess({
goal,
stepTask: stepTaskForApi,
agents: agentArray
@@ -273,7 +273,7 @@ const selectAgentGroup = async (agentNames: string[]) => {
})
// 调用 Mock API 加载数据
const filledTask = await api.mockFillStepTaskTaskProcess({
const filledTask = await api.fillStepTaskTaskProcess({
goal,
stepTask: stepTaskForApi,
agents: agentNames
@@ -511,10 +511,10 @@ const fetchAgentScores = async () => {
}
// TODO: 切换到真实API时取消注释下面这行
// const agentScores = await api.agentSelectModifyInit({
// goal: agentsStore.agentRawPlan.data?.['General Goal'] || '',
// stepTask: currentTask.value
// })
const agentScores = await api.agentSelectModifyInit({
goal: agentsStore.agentRawPlan.data?.['General Goal'] || '',
stepTask: currentTask.value
})
// 🆕 使用 Mock API开发阶段传递当前任务的 AgentSelection 以获取对应的维度
const goal = agentsStore.agentRawPlan.data?.['General Goal'] || '开发智能协作系统'
@@ -524,7 +524,7 @@ const fetchAgentScores = async () => {
agentSelection: currentTask.value?.AgentSelection
})
const agentScores = await api.mockAgentSelectModifyInit()
// const agentScores = await api.mockAgentSelectModifyInit()
// 从转换后的数据中提取维度列表第一个agent的所有维度
const firstAgent = Object.keys(agentScores)[0]
@@ -759,7 +759,7 @@ watch(
console.log('4. General Goal:', goal)
// 调用 Mock API 获取 TaskProcess
const filledTask = await api.mockFillStepTaskTaskProcess({
const filledTask = await api.fillStepTaskTaskProcess({
goal,
stepTask: stepTaskForApi,
agents: newTask.AgentSelection