Revert PRs #4506 and #4507 - Fix execution output issues (#4508)

This commit is contained in:
Christian Byrne
2025-07-23 17:53:04 -07:00
committed by GitHub
parent e34d9bb411
commit 052d5320c0
4 changed files with 11 additions and 59 deletions

View File

@@ -100,8 +100,7 @@ export const useImageUploadWidget = () => {
// Add our own callback to the combo widget to render an image when it changes // Add our own callback to the combo widget to render an image when it changes
fileComboWidget.callback = function () { fileComboWidget.callback = function () {
nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, { nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, {
isAnimated, isAnimated
isInitialLoad: true
}) })
node.graph?.setDirtyCanvas(true) node.graph?.setDirtyCanvas(true)
} }
@@ -111,8 +110,7 @@ export const useImageUploadWidget = () => {
// No change callbacks seem to be fired on initial setting of the value // No change callbacks seem to be fired on initial setting of the value
requestAnimationFrame(() => { requestAnimationFrame(() => {
nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, { nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, {
isAnimated, isAnimated
isInitialLoad: true
}) })
showPreview({ block: false }) showPreview({ block: false })
}) })

View File

@@ -1,4 +1,4 @@
import type { LGraph, LGraphNode, Subgraph } from '@comfyorg/litegraph' import type { LGraph, Subgraph } from '@comfyorg/litegraph'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
@@ -24,7 +24,7 @@ import type {
} from '@/schemas/comfyWorkflowSchema' } from '@/schemas/comfyWorkflowSchema'
import { api } from '@/scripts/api' import { api } from '@/scripts/api'
import { app } from '@/scripts/app' import { app } from '@/scripts/app'
import type { NodeExecutionId, NodeLocatorId } from '@/types/nodeIdentification' import type { NodeLocatorId } from '@/types/nodeIdentification'
import { createNodeLocatorId } from '@/types/nodeIdentification' import { createNodeLocatorId } from '@/types/nodeIdentification'
import { useCanvasStore } from './graphStore' import { useCanvasStore } from './graphStore'
@@ -54,22 +54,6 @@ export const useExecutionStore = defineStore('execution', () => {
// This is the progress of all nodes in the currently executing workflow // This is the progress of all nodes in the currently executing workflow
const nodeProgressStates = ref<Record<string, NodeProgressState>>({}) const nodeProgressStates = ref<Record<string, NodeProgressState>>({})
/**
* @deprecated Workaround for Subgraph phase 1 - execution IDs may share locator IDs.
* The most recently executed execution ID for each node locator ID.
*/
const locatorIdToExecutionIdMap = new Map<NodeLocatorId, NodeExecutionId>()
/**
* Get the NodeLocatorId for a node.
* @param node The node
* @returns The NodeLocatorId
*/
const getNodeLocatorId = (node: LGraphNode): NodeLocatorId =>
node.graph?.isRootGraph
? node.id.toString()
: [node.graph?.id, node.id].join(':')
/** /**
* Convert execution context node IDs to NodeLocatorIds * Convert execution context node IDs to NodeLocatorIds
* @param nodeId The node ID from execution context (could be execution ID) * @param nodeId The node ID from execution context (could be execution ID)
@@ -484,8 +468,6 @@ export const useExecutionStore = defineStore('execution', () => {
_executingNodeProgress, _executingNodeProgress,
// NodeLocatorId conversion helpers // NodeLocatorId conversion helpers
executionIdToNodeLocatorId, executionIdToNodeLocatorId,
nodeLocatorIdToExecutionId, nodeLocatorIdToExecutionId
locatorIdToExecutionIdMap,
getNodeLocatorId
} }
}) })

View File

@@ -8,12 +8,9 @@ import {
} from '@/schemas/apiSchema' } from '@/schemas/apiSchema'
import { api } from '@/scripts/api' import { api } from '@/scripts/api'
import { app } from '@/scripts/app' import { app } from '@/scripts/app'
import type { NodeExecutionId } from '@/types'
import { parseFilePath } from '@/utils/formatUtil' import { parseFilePath } from '@/utils/formatUtil'
import { isVideoNode } from '@/utils/litegraphUtil' import { isVideoNode } from '@/utils/litegraphUtil'
import { useExecutionStore } from './executionStore'
const createOutputs = ( const createOutputs = (
filenames: string[], filenames: string[],
type: ResultItemType, type: ResultItemType,
@@ -26,20 +23,16 @@ const createOutputs = (
} }
export const useNodeOutputStore = defineStore('nodeOutput', () => { export const useNodeOutputStore = defineStore('nodeOutput', () => {
const executionStore = useExecutionStore() const getNodeId = (node: LGraphNode): string => node.id.toString()
const getMostRecentExecutionId = (node: LGraphNode): NodeExecutionId =>
executionStore.locatorIdToExecutionIdMap.get(
executionStore.getNodeLocatorId(node)
) ?? node.id.toString()
function getNodeOutputs( function getNodeOutputs(
node: LGraphNode node: LGraphNode
): ExecutedWsMessage['output'] | undefined { ): ExecutedWsMessage['output'] | undefined {
return app.nodeOutputs[getMostRecentExecutionId(node)] return app.nodeOutputs[getNodeId(node)]
} }
function getNodePreviews(node: LGraphNode): string[] | undefined { function getNodePreviews(node: LGraphNode): string[] | undefined {
return app.nodePreviewImages[getMostRecentExecutionId(node)] return app.nodePreviewImages[getNodeId(node)]
} }
/** /**
@@ -98,23 +91,12 @@ export const useNodeOutputStore = defineStore('nodeOutput', () => {
filenames: string | string[] | ResultItem, filenames: string | string[] | ResultItem,
{ {
folder = 'input', folder = 'input',
isAnimated = false, isAnimated = false
isInitialLoad = false }: { folder?: ResultItemType; isAnimated?: boolean } = {}
}: {
folder?: ResultItemType
isAnimated?: boolean
isInitialLoad?: boolean
} = {}
) { ) {
if (!filenames || !node) return if (!filenames || !node) return
const nodeId = isInitialLoad const nodeId = getNodeId(node)
? executionStore.getNodeLocatorId(node)
: getMostRecentExecutionId(node)
if (isInitialLoad) {
executionStore.locatorIdToExecutionIdMap.set(nodeId, nodeId)
}
if (typeof filenames === 'string') { if (typeof filenames === 'string') {
app.nodeOutputs[nodeId] = createOutputs([filenames], folder, isAnimated) app.nodeOutputs[nodeId] = createOutputs([filenames], folder, isAnimated)

View File

@@ -14,7 +14,6 @@ import type {
ComfyApiWorkflow, ComfyApiWorkflow,
ComfyWorkflowJSON ComfyWorkflowJSON
} from '@/schemas/comfyWorkflowSchema' } from '@/schemas/comfyWorkflowSchema'
import { useExecutionStore } from '@/stores/executionStore'
import { ExecutableGroupNodeDTO, isGroupNode } from './executableGroupNodeDto' import { ExecutableGroupNodeDTO, isGroupNode } from './executableGroupNodeDto'
import { compressWidgetInputSlots } from './litegraphUtil' import { compressWidgetInputSlots } from './litegraphUtil'
@@ -59,8 +58,6 @@ export const graphToPrompt = async (
options: { sortNodes?: boolean; queueNodeIds?: NodeId[] } = {} options: { sortNodes?: boolean; queueNodeIds?: NodeId[] } = {}
): Promise<{ workflow: ComfyWorkflowJSON; output: ComfyApiWorkflow }> => { ): Promise<{ workflow: ComfyWorkflowJSON; output: ComfyApiWorkflow }> => {
const { sortNodes = false, queueNodeIds } = options const { sortNodes = false, queueNodeIds } = options
const executionStore = useExecutionStore()
executionStore.locatorIdToExecutionIdMap.clear()
for (const node of graph.computeExecutionOrder(false)) { for (const node of graph.computeExecutionOrder(false)) {
const innerNodes = node.getInnerNodes const innerNodes = node.getInnerNodes
@@ -162,13 +159,6 @@ export const graphToPrompt = async (
] ]
} }
// Temporary workaround for Subgraph phase 1. Overwrites the ID, but keeps the image.
const baseNodeId = node.id.split(':').at(-1)
executionStore.locatorIdToExecutionIdMap.set(
`${node.subgraphId}:${baseNodeId}`,
node.id
)
output[String(node.id)] = { output[String(node.id)] = {
inputs, inputs,
// TODO(huchenlei): Filter out all nodes that cannot be mapped to a // TODO(huchenlei): Filter out all nodes that cannot be mapped to a