Hook up more of the API

This commit is contained in:
space-nuko
2023-05-11 23:11:07 -05:00
parent 4d74720ae9
commit 34c18dea90
11 changed files with 388 additions and 179 deletions

View File

@@ -1,6 +1,6 @@
import { LiteGraph, LGraph, LGraphCanvas, LGraphNode, type LGraphNodeConstructor, type LGraphNodeExecutable, type SerializedLGraph, type SerializedLGraphGroup, type SerializedLGraphNode, type SerializedLLink, NodeMode, type Vector2, BuiltInSlotType, type INodeInputSlot } from "@litegraph-ts/core";
import type { LConnectionKind, INodeSlot } from "@litegraph-ts/core";
import ComfyAPI, { type ComfyAPIQueueStatus } from "$lib/api"
import ComfyAPI, { type ComfyAPIStatusResponse, type NodeID, type PromptID } from "$lib/api"
import { getPngMetadata, importA1111 } from "$lib/pnginfo";
import EventEmitter from "events";
import type TypedEmitter from "typed-emitter";
@@ -32,6 +32,7 @@ import { download, jsonToJsObject, promptToGraphVis, range, workflowToGraphVis }
import notify from "$lib/notify";
import configState from "$lib/stores/configState";
import { blankGraph } from "$lib/defaultGraph";
import type { GalleryOutput } from "$lib/nodes/ComfyWidgetNodes";
export const COMFYBOX_SERIAL_VERSION = 1;
@@ -55,20 +56,22 @@ export type SerializedAppState = {
}
/** [link origin, link index] | value */
export type SerializedPromptInput = [string, number] | any
export type SerializedPromptInput = [NodeID, number] | any
export type SerializedPromptInputs = {
inputs: Record<string, SerializedPromptInput>,
inputs: Record<NodeID, SerializedPromptInput>,
class_type: string
}
export type SerializedPromptOutput = Record<string, SerializedPromptInputs>
export type SerializedPromptInputsAll = Record<NodeID, SerializedPromptInputs>
export type SerializedPrompt = {
workflow: SerializedLGraph,
output: SerializedPromptOutput
output: SerializedPromptInputsAll
}
export type SerializedPromptOutputs = Record<NodeID, GalleryOutput>
export type Progress = {
value: number,
max: number
@@ -176,6 +179,8 @@ export default class ComfyApp {
this.addPasteHandler();
this.addKeyboardHandler();
await this.updateHistoryAndQueue();
// await this.#invokeExtensionsAsync("setup");
// Ensure the canvas fills the window
@@ -319,47 +324,48 @@ export default class ComfyApp {
* Handles updates from the API socket
*/
private addApiUpdateHandlers() {
this.api.addEventListener("status", ({ detail: ComfyAPIStatus }: CustomEvent) => {
// this.ui.setStatus(detail);
this.api.addEventListener("status", (status: ComfyAPIStatusResponse) => {
queueState.statusUpdated(status);
});
this.api.addEventListener("reconnecting", () => {
// this.ui.dialog.show("Reconnecting...");
uiState.reconnecting()
});
this.api.addEventListener("reconnected", () => {
// this.ui.dialog.close();
uiState.reconnected()
});
this.api.addEventListener("progress", ({ detail }: CustomEvent) => {
queueState.progressUpdated(detail);
this.api.addEventListener("progress", (progress: Progress) => {
queueState.progressUpdated(progress);
this.lGraph.setDirtyCanvas(true, false);
});
this.api.addEventListener("executing", ({ detail }: CustomEvent) => {
queueState.executingUpdated(detail.node);
this.api.addEventListener("executing", (promptID: PromptID | null, nodeID: NodeID | null) => {
queueState.executingUpdated(promptID, nodeID);
this.lGraph.setDirtyCanvas(true, false);
});
this.api.addEventListener("status", (ev: CustomEvent) => {
queueState.statusUpdated(ev.detail as ComfyAPIQueueStatus);
this.api.addEventListener("status", (status: ComfyAPIStatusResponse | null) => {
queueState.statusUpdated(status);
});
this.api.addEventListener("executed", ({ detail }: CustomEvent) => {
this.nodeOutputs[detail.node] = detail.output;
const node = this.lGraph.getNodeById(detail.node) as ComfyGraphNode;
this.api.addEventListener("executed", (promptID: PromptID, nodeID: NodeID, output: GalleryOutput) => {
this.nodeOutputs[nodeID] = output;
const node = this.lGraph.getNodeById(parseInt(nodeID)) as ComfyGraphNode;
if (node?.onExecuted) {
node.onExecuted(detail.output);
node.onExecuted(output);
}
queueState.onExecuted(promptID, nodeID, output)
});
this.api.addEventListener("execution_cached", ({ detail }: CustomEvent) => {
// TODO detail.nodes
this.api.addEventListener("execution_cached", (promptID: PromptID, nodes: NodeID[]) => {
queueState.executionCached(promptID, nodes)
});
this.api.addEventListener("execution_error", ({ detail }: CustomEvent) => {
queueState.update(s => { s.progress = null; s.runningNodeId = null; return s; })
notify(`Execution error: ${detail.message}`, { type: "error", timeout: 10000 })
this.api.addEventListener("execution_error", (promptID: PromptID, message: string) => {
queueState.executionError(promptID, message)
notify(`Execution error: ${message}`, { type: "error", timeout: 10000 })
});
this.api.init();
@@ -379,6 +385,13 @@ export default class ComfyApp {
});
}
private async updateHistoryAndQueue() {
const queue = await this.api.getQueue();
const history = await this.api.getHistory();
console.warn("QUEUE", queue)
console.warn("HISTORY", history)
}
private requestPermissions() {
if (Notification.permission === "default") {
Notification.requestPermission()
@@ -443,6 +456,8 @@ export default class ComfyApp {
this.lGraph.start();
this.lGraph.eventBus.on("afterExecute", () => this.lCanvas.draw(true))
uiState.update(s => { s.uiUnlocked = this.lGraph._nodes.length === 0; return s; })
}
async initDefaultGraph() {
@@ -729,10 +744,20 @@ export default class ComfyApp {
const p = await this.graphToPrompt(tag);
console.debug(promptToGraphVis(p))
const extra_data = { extra_pnginfo: { workflow: p.workflow } }
let error = null;
let promptID = null;
try {
await this.api.queuePrompt(num, p);
const response = await this.api.queuePrompt(num, p, extra_data);
promptID = response.promptID;
error = response.error;
} catch (error) {
// this.ui.dialog.show(error.response || error.toString());
error = error.toString();
}
if (error != null) {
const mes = error.response || error.toString()
notify(`Error queuing prompt:\n${mes}`, { type: "error" })
console.error(promptToGraphVis(p))
@@ -748,7 +773,7 @@ export default class ComfyApp {
}
this.lCanvas.draw(true, true);
// await this.ui.queue.update();
queueState.afterQueued(promptID, num, p, extra_data)
}
}
} finally {
@@ -767,7 +792,7 @@ export default class ComfyApp {
if (pngInfo.comfyBoxConfig) {
this.deserialize(JSON.parse(pngInfo.comfyBoxConfig));
} else if (pngInfo.parameters) {
throw "TODO import A111 import!"
throw "TODO A111 import!"
// importA1111(this.lGraph, pngInfo.parameters, this.api);
}
else {

View File

@@ -49,18 +49,18 @@
$: if (entries) {
_entries = []
// for (const entry of entries) {
// for (const outputs of Object.values(entry.outputs)) {
// const allImages = outputs.images.map(r => {
// // TODO configure backend URL
// const url = "http://localhost:8188/view?"
// const params = new URLSearchParams(r)
// return url + params
// });
//
// _entries.push({ allImages, name: "Output" })
// }
// }
for (const entry of entries) {
for (const outputs of Object.values(entry.outputs)) {
const allImages = outputs.images.map(r => {
// TODO configure backend URL
const url = "http://localhost:8188/view?"
const params = new URLSearchParams(r)
return url + params
});
_entries.push({ allImages, name: "Output" })
}
}
}
</script>
@@ -76,9 +76,9 @@
{/each}
</div>
<div class="bottom">
{#if $queueState.runningNodeId || $queueState.progress}
{#if $queueState.runningNodeID || $queueState.progress}
<div class="node-name">
<span>Node: {getNodeInfo($queueState.runningNodeId)}</span>
<span>Node: {getNodeInfo($queueState.runningNodeID)}</span>
</div>
<div>
<ProgressBar value={$queueState.progress?.value} max={$queueState.progress?.max} styles="height: 30px;" />

View File

@@ -50,7 +50,7 @@
$: if ($queueState && widget && widget.node) {
dragItem.isNodeExecuting = $queueState.runningNodeId === widget.node.id;
dragItem.isNodeExecuting = $queueState.runningNodeID === widget.node.id;
}
function getWidgetClass() {
@@ -72,7 +72,7 @@
<div class="widget {widget.attrs.classes} {getWidgetClass()}"
class:edit={edit}
class:selected={$uiState.uiUnlocked && $layoutState.currentSelection.includes(widget.id)}
class:is-executing={$queueState.runningNodeId && $queueState.runningNodeId == widget.node.id}
class:is-executing={$queueState.runningNodeID && $queueState.runningNodeId == widget.node.id}
class:hidden={hidden}
>
<svelte:component this={widget.node.svelteComponentType} {widget} {isMobile} />