diff --git a/browser_tests/assets/old_workflow_converted_input.json b/browser_tests/assets/old_workflow_converted_input.json new file mode 100644 index 000000000..8734433b1 --- /dev/null +++ b/browser_tests/assets/old_workflow_converted_input.json @@ -0,0 +1,128 @@ +{ + "last_node_id": 2, + "last_link_id": 1, + "nodes": [ + { + "id": 1, + "type": "ControlNetApplyAdvanced", + "pos": { + "0": 449, + "1": 204 + }, + "size": [ + 340.20001220703125, + 166 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "name": "positive", + "type": "CONDITIONING", + "link": null + }, + { + "name": "negative", + "type": "CONDITIONING", + "link": null + }, + { + "name": "control_net", + "type": "CONTROL_NET", + "link": null + }, + { + "name": "image", + "type": "IMAGE", + "link": null + }, + { + "name": "strength", + "type": "FLOAT", + "link": 1, + "widget": { + "name": "strength" + } + } + ], + "outputs": [ + { + "name": "positive", + "type": "CONDITIONING", + "links": null + }, + { + "name": "negative", + "type": "CONDITIONING", + "links": null + } + ], + "properties": { + "Node name for S&R": "ControlNetApplyAdvanced" + }, + "widgets_values": [ + 1, + 0, + 1 + ] + }, + { + "id": 2, + "type": "PrimitiveNode", + "pos": { + "0": 177, + "1": 265 + }, + "size": [ + 210, + 82 + ], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "FLOAT", + "type": "FLOAT", + "links": [ + 1 + ], + "widget": { + "name": "strength" + } + } + ], + "properties": { + "Run widget replace on values": false + }, + "widgets_values": [ + 1, + "fixed" + ] + } + ], + "links": [ + [ + 1, + 2, + 0, + 1, + 4, + "FLOAT" + ] + ], + "groups": [], + "config": {}, + "extra": { + "ds": { + "scale": 1, + "offset": { + "0": 47.541666666666515, + "1": 186.9375 + } + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/browser_tests/nodeDisplay.spec.ts b/browser_tests/nodeDisplay.spec.ts index bbbf98ae5..05d0157ce 100644 --- a/browser_tests/nodeDisplay.spec.ts +++ b/browser_tests/nodeDisplay.spec.ts @@ -32,4 +32,16 @@ test.describe('Optional input', () => { // If the node's multiline text widget is visible, then it was loaded successfully expect(comfyPage.page.locator('.comfy-multiline-input')).toHaveCount(1) }) + test('Old workflow with converted input', async ({ comfyPage }) => { + await comfyPage.loadWorkflow('old_workflow_converted_input') + const node = await comfyPage.getNodeRefById('1') + const inputs = await node.getProperty('inputs') + const vaeInput = inputs.find((w) => w.name === 'vae') + const convertedInput = inputs.find((w) => w.name === 'strength') + + expect(vaeInput).toBeDefined() + expect(convertedInput).toBeDefined() + expect(vaeInput.link).toBeNull() + expect(convertedInput.link).not.toBeNull() + }) }) diff --git a/src/scripts/app.ts b/src/scripts/app.ts index ff0fe446e..d1f250a10 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -38,7 +38,7 @@ import { SYSTEM_NODE_DEFS, useNodeDefStore } from '@/stores/nodeDefStore' -import { Vector2 } from '@comfyorg/litegraph' +import { INodeInputSlot, Vector2 } from '@comfyorg/litegraph' import _ from 'lodash' import { showExecutionErrorDialog, @@ -2093,6 +2093,11 @@ export class ComfyApp { incoming: Record ) => { const result = { ...incoming } + if (current.widget === undefined && incoming.widget !== undefined) { + // Field must be input as only inputs can be converted + this.inputs.push(current as INodeInputSlot) + return incoming + } for (const key of ['name', 'type', 'shape']) { if (current[key] !== undefined) { result[key] = current[key]