Workflows can receive images from other workflows/historical prompts
This commit is contained in:
91
src/lib/nodes/actions/ComfyReceiveOutputNode.ts
Normal file
91
src/lib/nodes/actions/ComfyReceiveOutputNode.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { BuiltInSlotType, LiteGraph, type IComboWidget, type SlotLayout, type SlotType, type ITextWidget, BASE_SLOT_TYPES, LGraphNode, type Vector2, BuiltInSlotShape, LGraphCanvas } from "@litegraph-ts/core";
|
||||
import ComfyGraphNode, { type ComfyGraphNodeProperties } from "../ComfyGraphNode";
|
||||
import { getLitegraphType } from "$lib/utils";
|
||||
import notify from "$lib/notify";
|
||||
|
||||
export interface ComfyReceiveOutputNodeProperties extends ComfyGraphNodeProperties {
|
||||
name: string,
|
||||
description: string,
|
||||
type: SlotType
|
||||
}
|
||||
|
||||
function getOutputTypes(widget: IComboWidget, node: LGraphNode): string[] {
|
||||
let result = []
|
||||
result = result.concat(Array.from(BASE_SLOT_TYPES))
|
||||
result.push("COMFYBOX_IMAGE")
|
||||
result.push("COMFYBOX_IMAGES")
|
||||
return result
|
||||
}
|
||||
|
||||
export default class ComfyReceiveOutputNode extends ComfyGraphNode {
|
||||
override properties: ComfyReceiveOutputNodeProperties = {
|
||||
tags: [],
|
||||
name: "Image",
|
||||
description: "Generic image input.",
|
||||
type: "COMFYBOX_IMAGE"
|
||||
}
|
||||
|
||||
static slotLayout: SlotLayout = {
|
||||
outputs: [
|
||||
{ name: "received", type: BuiltInSlotType.EVENT }
|
||||
]
|
||||
}
|
||||
|
||||
override size: Vector2 = [180, 90];
|
||||
|
||||
nameWidget: ITextWidget;
|
||||
descriptionWidget: ITextWidget;
|
||||
typeWidget: IComboWidget;
|
||||
|
||||
isActive: boolean = false;
|
||||
|
||||
private _queue: any[] = []
|
||||
|
||||
constructor(title?: string) {
|
||||
super(title)
|
||||
|
||||
this.nameWidget = this.addWidget("text", "Name", this.properties.name, "name");
|
||||
this.descriptionWidget = this.addWidget("text", "Desc.", this.properties.description, "description", { multiline: true });
|
||||
this.typeWidget = this.addWidget<IComboWidget>("combo", "Type", "" + this.properties.type, "type", { values: getOutputTypes });
|
||||
}
|
||||
|
||||
override onPropertyChanged(property: any, value: any) {
|
||||
if (property === "type") {
|
||||
const color = LGraphCanvas.DEFAULT_CONNECTION_COLORS_BY_TYPE[value] || LGraphCanvas.DEFAULT_CONNECTION_COLORS_BY_TYPE[BuiltInSlotType.EVENT];
|
||||
this.outputs[0].color_on = color
|
||||
this.outputs[0].color_off = color
|
||||
}
|
||||
}
|
||||
|
||||
override getTitle(): string {
|
||||
if (this.flags.collapsed) {
|
||||
return this.properties.name;
|
||||
}
|
||||
return this.title;
|
||||
}
|
||||
|
||||
override onExecute() {
|
||||
while (this._queue.length > 0)
|
||||
this.triggerSlot(0, this._queue.splice(0, 1))
|
||||
}
|
||||
|
||||
receiveOutput(value: any) {
|
||||
const type = getLitegraphType(value);
|
||||
console.warn("receive", this.id, value, type)
|
||||
|
||||
if (type !== this.properties.type) {
|
||||
console.error(`Output type mismatch! ${type} != ${this.properties.type}`)
|
||||
notify("Output type mismatch!", { type: "error" })
|
||||
return;
|
||||
}
|
||||
|
||||
this._queue.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
LiteGraph.registerNodeType({
|
||||
class: ComfyReceiveOutputNode,
|
||||
title: "Comfy.ReceiveOutput",
|
||||
desc: "Receives a workflow output sent from elsewhere",
|
||||
type: "events/receive_output"
|
||||
})
|
||||
83
src/lib/nodes/actions/ComfySendOutputAction.ts
Normal file
83
src/lib/nodes/actions/ComfySendOutputAction.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import modalState, { type ModalData, type ModalState } from "$lib/stores/modalState";
|
||||
import { getLitegraphType } from "$lib/utils";
|
||||
import { BuiltInSlotType, LiteGraph, type SlotLayout } from "@litegraph-ts/core";
|
||||
import ComfyGraphNode, { type ComfyGraphNodeProperties } from "../ComfyGraphNode";
|
||||
|
||||
import SendOutputModal, { type SendOutputModalResult } from "$lib/components/modal/SendOutputModal.svelte";
|
||||
import notify from "$lib/notify";
|
||||
import workflowState from "$lib/stores/workflowState";
|
||||
import { get } from "svelte/store";
|
||||
import type ComfyApp from "$lib/components/ComfyApp";
|
||||
|
||||
export interface ComfySendOutputActionProperties extends ComfyGraphNodeProperties {
|
||||
}
|
||||
|
||||
export default class ComfySendOutputAction extends ComfyGraphNode {
|
||||
override properties: ComfySendOutputActionProperties = {
|
||||
tags: [],
|
||||
}
|
||||
|
||||
static slotLayout: SlotLayout = {
|
||||
inputs: [
|
||||
{ name: "value", type: "*" },
|
||||
{ name: "trigger", type: BuiltInSlotType.ACTION }
|
||||
],
|
||||
}
|
||||
|
||||
isActive: boolean = false;
|
||||
|
||||
override onAction(action: any, param: any) {
|
||||
const value = this.getInputData(0);
|
||||
if (value == null) {
|
||||
notify("No workflow data to send!", { type: "error" })
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isActive)
|
||||
return;
|
||||
|
||||
let type = getLitegraphType(value);
|
||||
const receiveTargets = workflowState.findReceiveOutputTargets(type);
|
||||
|
||||
this.isActive = true;
|
||||
|
||||
const doSend = (modal: ModalData) => {
|
||||
this.isActive = false;
|
||||
|
||||
const { workflow, targetNode } = get(modal.state) as SendOutputModalResult;
|
||||
console.warn("send", workflow, targetNode);
|
||||
|
||||
if (workflow == null || targetNode == null)
|
||||
return
|
||||
|
||||
const app = (window as any).app as ComfyApp;
|
||||
if (app == null) {
|
||||
console.error("Couldn't get app!")
|
||||
return
|
||||
}
|
||||
|
||||
targetNode.receiveOutput(value);
|
||||
workflowState.setActiveWorkflow(app.lCanvas, workflow.id)
|
||||
}
|
||||
|
||||
modalState.pushModal({
|
||||
title: "Send Output",
|
||||
closeOnClick: true,
|
||||
showCloseButton: true,
|
||||
svelteComponent: SendOutputModal,
|
||||
svelteProps: {
|
||||
value,
|
||||
type,
|
||||
receiveTargets
|
||||
},
|
||||
onClose: doSend
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
LiteGraph.registerNodeType({
|
||||
class: ComfySendOutputAction,
|
||||
title: "Comfy.SendOutputAction",
|
||||
desc: "Sends a workflow output elsewhere",
|
||||
type: "actions/send_output"
|
||||
})
|
||||
@@ -8,3 +8,5 @@ export { default as ComfySetNodeModeAdvancedAction } from "./ComfySetNodeModeAdv
|
||||
export { default as ComfySetPromptThumbnailsAction } from "./ComfySetPromptThumbnailsAction"
|
||||
export { default as ComfyStoreImagesAction } from "./ComfyStoreImagesAction"
|
||||
export { default as ComfySwapAction } from "./ComfySwapAction"
|
||||
export { default as ComfySendOutputAction } from "./ComfySendOutputAction"
|
||||
export { default as ComfyReceiveOutputNode } from "./ComfyReceiveOutputNode"
|
||||
|
||||
Reference in New Issue
Block a user