fix: fix tracking display order issue.

Export the formatNode functions for both Iteration and Loop, and merge
them into a unified method called formatIterationAndLoopNode. This
method will handle the NodeTracing List uniformly, addressing the
timing issues in the tracing logs caused by the previous categorized
handling.
This commit is contained in:
Wood 2025-03-05 00:50:19 +08:00
parent 90c89bf699
commit 6588bfddb9
3 changed files with 77 additions and 10 deletions

View File

@ -1,16 +1,83 @@
import type { NodeTracing } from '@/types/workflow'
import formatIterationNode from './iteration'
import formatLoopNode from './loop'
import { addChildrenToIterationNode } from './iteration'
import { addChildrenToLoopNode } from './loop'
import formatParallelNode from './parallel'
import formatRetryNode from './retry'
import formatAgentNode from './agent'
import { cloneDeep } from 'lodash-es'
import { BlockEnum } from '../../../types'
import { orderBy } from 'lodash-es'
const formatIterationAndLoopNode = (list: NodeTracing[], t: any) => {
const clonedList = cloneDeep(list)
// Identify all loop and iteration nodes
const loopNodeIds = clonedList
.filter(item => item.node_type === BlockEnum.Loop)
.map(item => item.node_id)
const iterationNodeIds = clonedList
.filter(item => item.node_type === BlockEnum.Iteration)
.map(item => item.node_id)
// Identify all child nodes for both loop and iteration
const loopChildrenNodeIds = clonedList
.filter(item => item.execution_metadata?.loop_id && loopNodeIds.includes(item.execution_metadata.loop_id))
.map(item => item.node_id)
const iterationChildrenNodeIds = clonedList
.filter(item => item.execution_metadata?.iteration_id && iterationNodeIds.includes(item.execution_metadata.iteration_id))
.map(item => item.node_id)
// Filter out child nodes as they will be included in their parent nodes
const result = clonedList
.filter(item => !loopChildrenNodeIds.includes(item.node_id) && !iterationChildrenNodeIds.includes(item.node_id))
.map((item) => {
// Process Loop nodes
if (item.node_type === BlockEnum.Loop) {
const childrenNodes = clonedList.filter(child => child.execution_metadata?.loop_id === item.node_id)
const error = childrenNodes.find(child => child.status === 'failed')
if (error) {
item.status = 'failed'
item.error = error.error
}
const addedChildrenList = addChildrenToLoopNode(item, childrenNodes)
// Handle parallel nodes in loop node
if (addedChildrenList.details && addedChildrenList.details.length > 0) {
addedChildrenList.details = addedChildrenList.details.map((row) => {
return formatParallelNode(row, t)
})
}
return addedChildrenList
}
// Process Iteration nodes
if (item.node_type === BlockEnum.Iteration) {
const childrenNodes = clonedList.filter(child => child.execution_metadata?.iteration_id === item.node_id)
const error = childrenNodes.find(child => child.status === 'failed')
if (error) {
item.status = 'failed'
item.error = error.error
}
const addedChildrenList = addChildrenToIterationNode(item, childrenNodes)
// Handle parallel nodes in iteration node
if (addedChildrenList.details && addedChildrenList.details.length > 0) {
addedChildrenList.details = addedChildrenList.details.map((row) => {
return formatParallelNode(row, t)
})
}
return addedChildrenList
}
return item
})
return result
}
const formatToTracingNodeList = (list: NodeTracing[], t: any) => {
const allItems = cloneDeep([...list]).sort((a, b) => a.index - b.index)
const loopRelatedListIds = allItems.filter(item => (!!item.execution_metadata?.loop_id || item.node_type === BlockEnum.Loop)).map(x => x.id)
/*
* First handle not change list structure node
* Because Handle struct node will put the node in different
@ -18,10 +85,8 @@ const formatToTracingNodeList = (list: NodeTracing[], t: any) => {
const formattedAgentList = formatAgentNode(allItems)
const formattedRetryList = formatRetryNode(formattedAgentList) // retry one node
// would change the structure of the list. Iteration and parallel can include each other.
const formattedIterationList = formatIterationNode(formattedRetryList.filter(item => !loopRelatedListIds.includes(item.id)), t)
const formattedLoopList = formatLoopNode(formattedRetryList.filter(item => loopRelatedListIds.includes(item.id)), t)
const orderedNodeList = orderBy([...formattedIterationList, ...formattedLoopList], 'finished_at', 'asc')
const formattedParallelList = formatParallelNode(orderedNodeList, t)
const formattedLoopAndIterationList = formatIterationAndLoopNode(formattedRetryList, t)
const formattedParallelList = formatParallelNode(formattedLoopAndIterationList, t)
const result = formattedParallelList
// console.log(allItems)

View File

@ -1,7 +1,8 @@
import { BlockEnum } from '@/app/components/workflow/types'
import type { NodeTracing } from '@/types/workflow'
import formatParallelNode from '../parallel'
function addChildrenToIterationNode(iterationNode: NodeTracing, childrenNodes: NodeTracing[]): NodeTracing {
export function addChildrenToIterationNode(iterationNode: NodeTracing, childrenNodes: NodeTracing[]): NodeTracing {
const details: NodeTracing[][] = []
childrenNodes.forEach((item, index) => {
if (!item.execution_metadata) return

View File

@ -1,7 +1,8 @@
import { BlockEnum } from '@/app/components/workflow/types'
import type { NodeTracing } from '@/types/workflow'
import formatParallelNode from '../parallel'
function addChildrenToLoopNode(loopNode: NodeTracing, childrenNodes: NodeTracing[]): NodeTracing {
export function addChildrenToLoopNode(loopNode: NodeTracing, childrenNodes: NodeTracing[]): NodeTracing {
const details: NodeTracing[][] = []
childrenNodes.forEach((item) => {
if (!item.execution_metadata) return