mirror of
https://github.com/langgenius/dify.git
synced 2026-05-03 08:58:09 +08:00
feat: implement Schedule Trigger validation with multi-start node topology support (#24134)
This commit is contained in:
@ -94,19 +94,28 @@ export const getNodesConnectedSourceOrTargetHandleIdsMap = (changes: ConnectedSo
|
||||
}
|
||||
|
||||
export const getValidTreeNodes = (nodes: Node[], edges: Edge[]) => {
|
||||
const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
|
||||
// Find all start nodes (Start and Trigger nodes)
|
||||
const startNodes = nodes.filter(node =>
|
||||
node.data.type === BlockEnum.Start
|
||||
|| node.data.type === BlockEnum.TriggerSchedule
|
||||
|| node.data.type === BlockEnum.TriggerWebhook
|
||||
|| node.data.type === BlockEnum.TriggerPlugin,
|
||||
)
|
||||
|
||||
if (!startNode) {
|
||||
if (startNodes.length === 0) {
|
||||
return {
|
||||
validNodes: [],
|
||||
maxDepth: 0,
|
||||
}
|
||||
}
|
||||
|
||||
const list: Node[] = [startNode]
|
||||
let maxDepth = 1
|
||||
const list: Node[] = []
|
||||
let maxDepth = 0
|
||||
|
||||
const traverse = (root: Node, depth: number) => {
|
||||
// Add the current node to the list
|
||||
list.push(root)
|
||||
|
||||
if (depth > maxDepth)
|
||||
maxDepth = depth
|
||||
|
||||
@ -114,19 +123,19 @@ export const getValidTreeNodes = (nodes: Node[], edges: Edge[]) => {
|
||||
|
||||
if (outgoers.length) {
|
||||
outgoers.forEach((outgoer) => {
|
||||
list.push(outgoer)
|
||||
// Only traverse if we haven't processed this node yet (avoid cycles)
|
||||
if (!list.find(n => n.id === outgoer.id)) {
|
||||
if (outgoer.data.type === BlockEnum.Iteration)
|
||||
list.push(...nodes.filter(node => node.parentId === outgoer.id))
|
||||
if (outgoer.data.type === BlockEnum.Loop)
|
||||
list.push(...nodes.filter(node => node.parentId === outgoer.id))
|
||||
|
||||
if (outgoer.data.type === BlockEnum.Iteration)
|
||||
list.push(...nodes.filter(node => node.parentId === outgoer.id))
|
||||
if (outgoer.data.type === BlockEnum.Loop)
|
||||
list.push(...nodes.filter(node => node.parentId === outgoer.id))
|
||||
|
||||
traverse(outgoer, depth + 1)
|
||||
traverse(outgoer, depth + 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
list.push(root)
|
||||
|
||||
else {
|
||||
// Leaf node - add iteration/loop children if any
|
||||
if (root.data.type === BlockEnum.Iteration)
|
||||
list.push(...nodes.filter(node => node.parentId === root.id))
|
||||
if (root.data.type === BlockEnum.Loop)
|
||||
@ -134,7 +143,11 @@ export const getValidTreeNodes = (nodes: Node[], edges: Edge[]) => {
|
||||
}
|
||||
}
|
||||
|
||||
traverse(startNode, maxDepth)
|
||||
// Start traversal from all start nodes
|
||||
startNodes.forEach((startNode) => {
|
||||
if (!list.find(n => n.id === startNode.id))
|
||||
traverse(startNode, 1)
|
||||
})
|
||||
|
||||
return {
|
||||
validNodes: uniqBy(list, 'id'),
|
||||
@ -196,7 +209,12 @@ export const getParallelInfo = (nodes: Node[], edges: Edge[], parentNodeId?: str
|
||||
startNode = nodes.find(node => node.id === (parentNode.data as (IterationNodeType | LoopNodeType)).start_node_id)
|
||||
}
|
||||
else {
|
||||
startNode = nodes.find(node => node.data.type === BlockEnum.Start)
|
||||
startNode = nodes.find(node =>
|
||||
node.data.type === BlockEnum.Start
|
||||
|| node.data.type === BlockEnum.TriggerSchedule
|
||||
|| node.data.type === BlockEnum.TriggerWebhook
|
||||
|| node.data.type === BlockEnum.TriggerPlugin,
|
||||
)
|
||||
}
|
||||
if (!startNode)
|
||||
throw new Error('Start node not found')
|
||||
|
||||
Reference in New Issue
Block a user