[Bug] Fix broken output link id during reroute migration (#3244)

This commit is contained in:
Chenlei Hu
2025-03-26 16:00:54 -04:00
committed by GitHub
parent 1d66d6d7d3
commit 3e25e08b10
3 changed files with 116 additions and 93 deletions

View File

@@ -1,3 +1,5 @@
import _ from 'lodash'
import type { import type {
ComfyLink, ComfyLink,
ComfyNode, ComfyNode,
@@ -67,10 +69,15 @@ export function createNewLinks(
workflow: WorkflowJSON04, workflow: WorkflowJSON04,
rerouteMap: Map<NodeId, RerouteEntry> rerouteMap: Map<NodeId, RerouteEntry>
): { ): {
nodes: ComfyNode[]
reroutes: Reroute[] reroutes: Reroute[]
links: ComfyLink[] links: ComfyLink[]
linkExtensions: LinkExtension[] linkExtensions: LinkExtension[]
} { } {
const nodeById = _.keyBy(
workflow.nodes.filter((node) => node.type !== 'Reroute').map(_.cloneDeep),
'id'
)
const links: ComfyLink[] = [] const links: ComfyLink[] = []
const linkExtensions: LinkExtension[] = [] const linkExtensions: LinkExtension[] = []
@@ -153,6 +160,23 @@ export function createNewLinks(
validLinkExtensions.push(linkExtension) validLinkExtensions.push(linkExtension)
chainedReroutes.forEach((reroute) => validReroutes.add(reroute)) chainedReroutes.forEach((reroute) => validReroutes.add(reroute))
// Update source node's output slot's link ids to point to the new link.
const sourceNode = nodeById[sourceNodeId]
if (!sourceNode) {
throw new Error(
`Corrupted workflow: Source node ${sourceNodeId} not found`
)
}
const outputSlot = sourceNode.outputs?.[sourceSlot]
if (!outputSlot) {
throw new Error(
`Corrupted workflow: Output slot ${sourceSlot} not found`
)
}
outputSlot.links = outputSlot.links?.map((l) =>
l === rerouteInputLink[0] ? linkId : l
)
} }
entry = undefined entry = undefined
} }
@@ -160,6 +184,7 @@ export function createNewLinks(
} }
return { return {
nodes: Object.values(nodeById),
links, links,
linkExtensions: validLinkExtensions, linkExtensions: validLinkExtensions,
reroutes: Array.from(validReroutes) reroutes: Array.from(validReroutes)
@@ -192,16 +217,14 @@ export const migrateLegacyRerouteNodes = (
const rerouteMap = createReroutePoints(legacyRerouteNodes) const rerouteMap = createReroutePoints(legacyRerouteNodes)
// Create new links and link extensions // Create new links and link extensions
const { links, linkExtensions, reroutes } = createNewLinks( const { nodes, links, linkExtensions, reroutes } = createNewLinks(
workflow, workflow,
rerouteMap rerouteMap
) )
// Update the workflow // Update the workflow
newWorkflow.links = links newWorkflow.links = links
newWorkflow.nodes = newWorkflow.nodes.filter( newWorkflow.nodes = nodes
(node) => node.type !== 'Reroute'
)
newWorkflow.extra.reroutes = reroutes newWorkflow.extra.reroutes = reroutes
newWorkflow.extra.linkExtensions = linkExtensions newWorkflow.extra.linkExtensions = linkExtensions

View File

@@ -2,6 +2,51 @@
"last_node_id": 27, "last_node_id": 27,
"last_link_id": 34, "last_link_id": 34,
"nodes": [ "nodes": [
{
"id": 4,
"type": "CheckpointLoaderSimple",
"pos": [
47.948699951171875,
239.2628173828125
],
"size": [
315,
98
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"slot_index": 0,
"links": []
},
{
"name": "CLIP",
"type": "CLIP",
"slot_index": 1,
"links": []
},
{
"name": "VAE",
"type": "VAE",
"slot_index": 2,
"links": [
13,
21
]
}
],
"properties": {
"Node name for S&R": "CheckpointLoaderSimple"
},
"widgets_values": [
"v1-5-pruned-emaonly.safetensors"
]
},
{ {
"id": 12, "id": 12,
"type": "VAEDecode", "type": "VAEDecode",
@@ -40,51 +85,6 @@
}, },
"widgets_values": [] "widgets_values": []
}, },
{
"id": 4,
"type": "CheckpointLoaderSimple",
"pos": [
47.948699951171875,
239.2628173828125
],
"size": [
315,
98
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"slot_index": 0,
"links": []
},
{
"name": "CLIP",
"type": "CLIP",
"slot_index": 1,
"links": []
},
{
"name": "VAE",
"type": "VAE",
"slot_index": 2,
"links": [
13,
31
]
}
],
"properties": {
"Node name for S&R": "CheckpointLoaderSimple"
},
"widgets_values": [
"v1-5-pruned-emaonly.safetensors"
]
},
{ {
"id": 26, "id": 26,
"type": "VAEDecode", "type": "VAEDecode",

View File

@@ -2,6 +2,50 @@
"last_node_id": 24, "last_node_id": 24,
"last_link_id": 30, "last_link_id": 30,
"nodes": [ "nodes": [
{
"id": 4,
"type": "CheckpointLoaderSimple",
"pos": [
160,
240
],
"size": [
315,
98
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"slot_index": 0,
"links": []
},
{
"name": "CLIP",
"type": "CLIP",
"slot_index": 1,
"links": []
},
{
"name": "VAE",
"type": "VAE",
"slot_index": 2,
"links": [
21
]
}
],
"properties": {
"Node name for S&R": "CheckpointLoaderSimple"
},
"widgets_values": [
"v1-5-pruned-emaonly.safetensors"
]
},
{ {
"id": 12, "id": 12,
"type": "VAEDecode", "type": "VAEDecode",
@@ -39,50 +83,6 @@
"Node name for S&R": "VAEDecode" "Node name for S&R": "VAEDecode"
}, },
"widgets_values": [] "widgets_values": []
},
{
"id": 4,
"type": "CheckpointLoaderSimple",
"pos": [
160,
240
],
"size": [
315,
98
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"slot_index": 0,
"links": []
},
{
"name": "CLIP",
"type": "CLIP",
"slot_index": 1,
"links": []
},
{
"name": "VAE",
"type": "VAE",
"slot_index": 2,
"links": [
13
]
}
],
"properties": {
"Node name for S&R": "CheckpointLoaderSimple"
},
"widgets_values": [
"v1-5-pruned-emaonly.safetensors"
]
} }
], ],
"links": [ "links": [