Skip to content

Commit f81b191

Browse files
authored
Fix execution output & previews not displayed (#4506)
1 parent 4cd0c27 commit f81b191

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

src/stores/executionStore.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { LGraph, Subgraph } from '@comfyorg/litegraph'
1+
import type { LGraph, LGraphNode, Subgraph } from '@comfyorg/litegraph'
22
import { defineStore } from 'pinia'
33
import { computed, ref } from 'vue'
44

@@ -24,7 +24,7 @@ import type {
2424
} from '@/schemas/comfyWorkflowSchema'
2525
import { api } from '@/scripts/api'
2626
import { app } from '@/scripts/app'
27-
import type { NodeLocatorId } from '@/types/nodeIdentification'
27+
import type { NodeExecutionId, NodeLocatorId } from '@/types/nodeIdentification'
2828
import { createNodeLocatorId } from '@/types/nodeIdentification'
2929

3030
import { useCanvasStore } from './graphStore'
@@ -54,6 +54,22 @@ export const useExecutionStore = defineStore('execution', () => {
5454
// This is the progress of all nodes in the currently executing workflow
5555
const nodeProgressStates = ref<Record<string, NodeProgressState>>({})
5656

57+
/**
58+
* @deprecated Workaround for Subgraph phase 1 - execution IDs may share locator IDs.
59+
* The most recently executed execution ID for each node locator ID.
60+
*/
61+
const locatorIdToExecutionIdMap = new Map<NodeLocatorId, NodeExecutionId>()
62+
63+
/**
64+
* Get the NodeLocatorId for a node.
65+
* @param node The node
66+
* @returns The NodeLocatorId
67+
*/
68+
const getNodeLocatorId = (node: LGraphNode): NodeLocatorId =>
69+
node.graph?.isRootGraph
70+
? node.id.toString()
71+
: [node.graph?.id, node.id].join(':')
72+
5773
/**
5874
* Convert execution context node IDs to NodeLocatorIds
5975
* @param nodeId The node ID from execution context (could be execution ID)
@@ -468,6 +484,8 @@ export const useExecutionStore = defineStore('execution', () => {
468484
_executingNodeProgress,
469485
// NodeLocatorId conversion helpers
470486
executionIdToNodeLocatorId,
471-
nodeLocatorIdToExecutionId
487+
nodeLocatorIdToExecutionId,
488+
locatorIdToExecutionIdMap,
489+
getNodeLocatorId
472490
}
473491
})

src/stores/imagePreviewStore.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import {
88
} from '@/schemas/apiSchema'
99
import { api } from '@/scripts/api'
1010
import { app } from '@/scripts/app'
11+
import type { NodeExecutionId } from '@/types'
1112
import { parseFilePath } from '@/utils/formatUtil'
1213
import { isVideoNode } from '@/utils/litegraphUtil'
1314

15+
import { useExecutionStore } from './executionStore'
16+
1417
const createOutputs = (
1518
filenames: string[],
1619
type: ResultItemType,
@@ -23,16 +26,20 @@ const createOutputs = (
2326
}
2427

2528
export const useNodeOutputStore = defineStore('nodeOutput', () => {
26-
const getNodeId = (node: LGraphNode): string => node.id.toString()
29+
const executionStore = useExecutionStore()
30+
const getMostRecentExecutionId = (node: LGraphNode): NodeExecutionId =>
31+
executionStore.locatorIdToExecutionIdMap.get(
32+
executionStore.getNodeLocatorId(node)
33+
) ?? node.id.toString()
2734

2835
function getNodeOutputs(
2936
node: LGraphNode
3037
): ExecutedWsMessage['output'] | undefined {
31-
return app.nodeOutputs[getNodeId(node)]
38+
return app.nodeOutputs[getMostRecentExecutionId(node)]
3239
}
3340

3441
function getNodePreviews(node: LGraphNode): string[] | undefined {
35-
return app.nodePreviewImages[getNodeId(node)]
42+
return app.nodePreviewImages[getMostRecentExecutionId(node)]
3643
}
3744

3845
/**
@@ -96,7 +103,7 @@ export const useNodeOutputStore = defineStore('nodeOutput', () => {
96103
) {
97104
if (!filenames || !node) return
98105

99-
const nodeId = getNodeId(node)
106+
const nodeId = getMostRecentExecutionId(node)
100107

101108
if (typeof filenames === 'string') {
102109
app.nodeOutputs[nodeId] = createOutputs([filenames], folder, isAnimated)

src/utils/executionUtil.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
ComfyApiWorkflow,
1515
ComfyWorkflowJSON
1616
} from '@/schemas/comfyWorkflowSchema'
17+
import { useExecutionStore } from '@/stores/executionStore'
1718

1819
import { ExecutableGroupNodeDTO, isGroupNode } from './executableGroupNodeDto'
1920
import { compressWidgetInputSlots } from './litegraphUtil'
@@ -58,6 +59,8 @@ export const graphToPrompt = async (
5859
options: { sortNodes?: boolean; queueNodeIds?: NodeId[] } = {}
5960
): Promise<{ workflow: ComfyWorkflowJSON; output: ComfyApiWorkflow }> => {
6061
const { sortNodes = false, queueNodeIds } = options
62+
const executionStore = useExecutionStore()
63+
executionStore.locatorIdToExecutionIdMap.clear()
6164

6265
for (const node of graph.computeExecutionOrder(false)) {
6366
const innerNodes = node.getInnerNodes
@@ -159,6 +162,13 @@ export const graphToPrompt = async (
159162
]
160163
}
161164

165+
// Temporary workaround for Subgraph phase 1. Overwrites the ID, but keeps the image.
166+
const baseNodeId = node.id.split(':').at(-1)
167+
executionStore.locatorIdToExecutionIdMap.set(
168+
`${node.subgraphId}:${baseNodeId}`,
169+
node.id
170+
)
171+
162172
output[String(node.id)] = {
163173
inputs,
164174
// TODO(huchenlei): Filter out all nodes that cannot be mapped to a

0 commit comments

Comments
 (0)