fixing prompt output, fixing widgets

This commit is contained in:
Sammy Franklin 2023-10-27 16:05:15 -07:00
parent 757fce2561
commit 71a3686ae9
2 changed files with 59 additions and 88 deletions

View File

@ -64,58 +64,45 @@ app.registerExtension({
node.widgets = [node.widgets[0]]; node.widgets = [node.widgets[0]];
// Map widgets // Map widgets
subflow.extras.widgetNodes = []; subflow.extras.widgetSlots = {};
const resolveWidgetPath = (thisNode, path, widgetIndex) => { // const resolveWidgetPath = (thisNode, path, widgetIndex) => {
const subflowNodes = thisNode.subflow.nodes; // const subflowNodes = thisNode.subflow.nodes;
let q = 0; // get what would be the q-th exported widget // let q = 0; // get what would be the q-th exported widget
console.log(path); // console.log(path);
for (const subflowNode of subflowNodes) { // for (const subflowNode of subflowNodes) {
const exportedWidgets = subflowNode.properties?.exports?.widgets; // const exportedWidgets = subflowNode.properties?.exports?.widgets;
console.log("has nodes", q, widgetIndex); // console.log("has nodes", q, widgetIndex);
if (exportedWidgets) { // if (exportedWidgets) {
console.log("in exports"); // console.log("in exports");
const childPath = `${path}${subflowNode.id}/`; // const childPath = `${path}${subflowNode.id}/`;
for (const i in exportedWidgets) { // for (const i in exportedWidgets) {
console.log("exported Widgets",q, widgetIndex); // console.log("exported Widgets",q, widgetIndex);
if (widgetIndex == q) { // if (widgetIndex == q) {
console.log(subflowNode); // console.log(subflowNode);
if (subflowNode.subflow) { // if (subflowNode.subflow) {
console.log("widget is inside subflow!") // console.log("widget is inside subflow!")
return resolveWidgetPath(subflowNode, childPath, i); // return resolveWidgetPath(subflowNode, childPath, i);
} // }
return `${childPath}${subflowNode.id}/`; // return `${childPath}${subflowNode.id}/`;
} // }
q++; // q++;
} // }
} // }
} // }
console.warn("couldn't export a widget"); // console.warn("couldn't export a widget");
}; // };
const subflowNodes = subflow.nodes; const subflowNodes = subflow.nodes;
for (const subflowNode of subflowNodes) { console.log(subflow.extras.widgetSlots);
const exportedWidgets = subflowNode.properties?.exports?.widgets;
if (exportedWidgets) {
const childPath = `/${subflowNode.id}/`;
for (const i in exportedWidgets) {
console.log("exporting", exportedWidgets[i].name);
if (subflowNode.subflow) {
subflow.extras.widgetNodes.push(resolveWidgetPath(subflowNode, childPath, i));
} else {
subflow.extras.widgetNodes.push(childPath);
}
}
}
}
console.log(subflow.extras.widgetNodes);
let widgetIndex = 1; let widgetIndex = 1;
for (const subflowNode of subflowNodes) { for (const subflowNode of subflowNodes) {
const exports = subflowNode.properties?.exports; const exports = subflowNode.properties?.exports;
if (exports) { if (exports) {
for (const exportedWidget of exports.widgets) { for (const exportedWidget of exports.widgets) {
subflow.extras.widgetSlots[exportedWidget.name] = subflowNode;
let type = exportedWidget.config[0]; let type = exportedWidget.config[0];
let options = type; let options = type;
if (type instanceof Array) { if (type instanceof Array) {
@ -144,7 +131,7 @@ app.registerExtension({
} }
} }
console.log(subflow.extras.widgetNodes); console.log(subflow.extras.widgetSlots);
}; };

View File

@ -1589,13 +1589,14 @@ export class ComfyApp {
* @returns The workflow and node links * @returns The workflow and node links
*/ */
async graphToPrompt(graph=this.graph, nodeIdOffset=0, path="/", globalMappings={}) { async graphToPrompt(graph=this.graph, nodeIdOffset=0, path="/", globalMappings={}) {
console.log("MY PATH IS ", path)
const workflow = graph.serialize(); const workflow = graph.serialize();
const output = {}; const output = {};
let childNodeIdOffset = nodeIdOffset + graph.last_node_id; // let childNodeIdOffset = nodeIdOffset + graph.last_node_id;
let childNodeCount = 0;
// Process nodes in order of execution // Process nodes in order of execution
for (const node of graph.computeExecutionOrder(false)) { for (const node of graph.computeExecutionOrder(false)) {
console.log("handling", node.id, `${path}${node.id}/`, node.type);
const n = workflow.nodes.find((n) => n.id === node.id); const n = workflow.nodes.find((n) => n.id === node.id);
if (node.isVirtualNode) { if (node.isVirtualNode) {
@ -1613,48 +1614,46 @@ export class ComfyApp {
if (node.subflow) { if (node.subflow) {
const subgraph = new LGraph(); const subgraph = new LGraph();
console.log("configuring subflow");
subgraph.configure(node.subflow); subgraph.configure(node.subflow);
console.log("subgraph last node id is ", subgraph.last_node_id); const subgraphNodeIdOffset = nodeIdOffset + childNodeCount + graph.last_node_id;
const subgraphPrompt = (await this.graphToPrompt(subgraph, childNodeIdOffset, path+String(node.id)+"/", globalMappings)); const subgraphPrompt = (await this.graphToPrompt(subgraph, subgraphNodeIdOffset, path+String(node.id)+"/", globalMappings));
const subgraphPromptOutput = subgraphPrompt.output; const subgraphPromptOutput = subgraphPrompt.output;
const subgraphGlobalMappings = subgraphPrompt.globalMappings; const subgraphGlobalMappings = subgraphPrompt.globalMappings;
const subgraphNodeCount = subgraphPrompt.nodeCount;
childNodeCount += subgraphNodeCount;
// replace ids to not conflict with existing ids
for ( const [key, value] of Object.entries(subgraphPromptOutput) ) { for ( const [key, value] of Object.entries(subgraphPromptOutput) ) {
// for ( const [inputKey, inputValue] of Object.entries(value.inputs) ) {
// if (Array.isArray(inputValue)) {
// value.inputs[inputKey][0] = String(Number(value.inputs[inputKey][0]) + subflowNodeIdOffset);
// }
// }
output[key] = { output[key] = {
...value, ...value,
for_subflow: String(node.id) // keep reference of root level subflow node for_subflow: String(node.id) // keep reference of root level subflow node
}; };
// subflowNodes[node.id][key] = value;
} }
// childNodeIdOffset += subgraph.last_node_id;
// subflowIdOffsets[node.id] = subflowNodeIdOffset;
childNodeIdOffset += subgraph.last_node_id;
Object.assign(globalMappings, subgraphGlobalMappings); Object.assign(globalMappings, subgraphGlobalMappings);
} }
const inputs = {}; const inputs = {};
const widgets = node.widgets; const widgets = node.widgets;
const getWidgetRef = (inputNode, widgetName, inputPath) => {
if (inputNode.subflow) {
const underlyingNode = inputNode.subflow.extras.widgetSlots[widgetName];
return getWidgetRef(underlyingNode, widgetName, `${inputPath}${String(inputNode.id)}/` );
}
const globalId = globalMappings[`${inputPath}${inputNode.id}/`];
return globalId;
};
// Store all widget values // Store all widget values
if (widgets) { if (widgets) {
for (const i in widgets) { for (const i in widgets) {
const widget = widgets[i]; const widget = widgets[i];
if (!widget.options || widget.options.serialize !== false) { if (!widget.options || widget.options.serialize !== false) {
if (node.subflow) { if (node.subflow) {
if (widget.type !== "button") { if (i != 0) { // skip the load widget
// use the callback to obtain node reference const globalId = getWidgetRef(node, widget.name, path);
console.log(node.subflow.extras.widgetNodes);
const globalMappingKey = node.subflow.extras.widgetNodes[i];
const globalId = globalMappings[globalMappingKey];
if (!output[globalId]) { if (!output[globalId]) {
console.log("couldn't find reference with global mapping key", globalMappingKey); console.log("couldn't find reference with global mapping key", globalMappingKey);
} }
@ -1669,34 +1668,21 @@ export class ComfyApp {
const getOutputRef = (inputNode, inputSlot, inputPath) => { const getOutputRef = (inputNode, inputSlot, inputPath) => {
if (inputNode.subflow) { if (inputNode.subflow) {
// input should be mapped to inner node
// const [ , originSlot ] = inputNode.getExportedOutput(inputSlot);
const [ underlyingNode, underlyingSlot ] = inputNode.subflow.extras.inputSlots[inputSlot]; const [ underlyingNode, underlyingSlot ] = inputNode.subflow.extras.inputSlots[inputSlot];
console.log("GOT UNDERLYING NODE", underlyingNode, "from input of", inputSlot, "calling", inputNode);
return getOutputRef(underlyingNode, underlyingSlot, `${inputPath}${String(inputNode.id)}/` ); return getOutputRef(underlyingNode, underlyingSlot, `${inputPath}${String(inputNode.id)}/` );
// const originId = nodeIdOffset + localOriginId;
// return [String(originId), parseInt(originSlot)];
} }
const globalId = globalMappings[`${inputPath}${inputNode.id}/`]; const globalId = globalMappings[`${inputPath}${inputNode.id}/`];
console.log("outputRef", inputNode, `${inputPath}${inputNode.id}/`, globalId);
return [globalId, parseInt(inputSlot)]; return [globalId, parseInt(inputSlot)];
}; };
const getInputRef = (inputNode, inputSlot, inputPath) => { const getInputRef = (inputNode, inputSlot, inputPath) => {
if (inputNode.subflow) { if (inputNode.subflow) {
// input should be mapped to inner node
// const [ , originSlot ] = inputNode.getExportedOutput(inputSlot);
const [ underlyingNode, underlyingSlot ] = inputNode.subflow.extras.outputSlots[inputSlot]; const [ underlyingNode, underlyingSlot ] = inputNode.subflow.extras.outputSlots[inputSlot];
return getInputRef(underlyingNode, underlyingSlot, `${inputPath}${String(inputNode.id)}/`); return getInputRef(underlyingNode, underlyingSlot, `${inputPath}${String(inputNode.id)}/`);
// const originId = nodeIdOffset + localOriginId;
// return [String(originId), parseInt(originSlot)];
} }
const globalId = globalMappings[`${inputPath}${inputNode.id}/`]; const globalId = globalMappings[`${inputPath}${inputNode.id}/`];
console.log(globalMappings);
console.log("inputRef", inputNode,`${inputPath}${inputNode.id}/`, globalId);
return [globalId, parseInt(inputSlot)]; return [globalId, parseInt(inputSlot)];
}; };
@ -1740,23 +1726,22 @@ export class ComfyApp {
if (link) { if (link) {
if (node.subflow) { if (node.subflow) {
// inner node's input should be used
// const [ targetNode, targetSlot ] = node.getExportedInput(link.target_slot);
const [targetId, targetSlot] = getOutputRef(node, link.target_slot, path); const [targetId, targetSlot] = getOutputRef(node, link.target_slot, path);
console.log("received targetId", targetId, link);
output[ targetId ].inputs[ node.inputs[targetSlot].name ] = getInputRef(parent, link.origin_slot, path); output[ targetId ].inputs[ node.inputs[targetSlot].name ] = getInputRef(parent, link.origin_slot, path);
} }
console.log("handling", node.type, node.id, node.inputs[i].name );
inputs[node.inputs[i].name] = getInputRef(parent, link.origin_slot, path); inputs[node.inputs[i].name] = getInputRef(parent, link.origin_slot, path);
} }
} }
} }
if (!node.subflow) { if (!node.subflow) {
const globalId = String(node.id + nodeIdOffset); const globalId = String(nodeIdOffset + node.id);
console.log("setting globalMapping", path+String(node.id)+"/", globalId); console.log("setting globalMapping", path+String(node.id)+"/", globalId);
globalMappings[path+String(node.id)+"/"] = globalId; globalMappings[path+String(node.id)+"/"] = globalId;
if (output[globalId]) {
console.log("PROBLEM: overwriting", globalId, output[globalId]);
}
output[globalId] = { output[globalId] = {
inputs, inputs,
class_type: node.comfyClass, class_type: node.comfyClass,
@ -1768,16 +1753,15 @@ export class ComfyApp {
for (const o in output) { for (const o in output) {
for (const i in output[o].inputs) { for (const i in output[o].inputs) {
if (Array.isArray(output[o].inputs[i]) if (Array.isArray(output[o].inputs[i]) && output[o].inputs[i].length === 2 && !output[output[o].inputs[i][0]]) {
&& output[o].inputs[i].length === 2
&& !output[output[o].inputs[i][0]]) {
delete output[o].inputs[i]; delete output[o].inputs[i];
} }
} }
} }
console.log(output); console.log(output);
return { workflow, output, globalMappings }; const nodeCount = childNodeCount + graph.last_node_id;
return { workflow, output, globalMappings, nodeCount };
} }
#formatPromptError(error) { #formatPromptError(error) {