Saltar al contenido principal

LiteGraph

La interfaz de Comfy UI está construida sobre LiteGraph. Gran parte de la funcionalidad de Comfy la proporciona LiteGraph, así que si desarrollas nodos más complejos, probablemente te resulte útil clonar ese repositorio y explorar la documentación, que se encuentra en doc/index.html.

ComfyApp

El objeto app (siempre accesible mediante import { app } from "../../scripts/app.js";) representa la aplicación de Comfy que se ejecuta en el navegador y contiene varias propiedades y funciones útiles, algunas de las cuales se enumeran a continuación.
Obsoleto: Secuestrar o parchear funciones de forma manual (monkey-patching) en app o en sus prototipos está obsoleto y puede cambiar en cualquier momento en un futuro cercano. En su lugar, usa los ganchos de extensión y la API del Menú Contextual oficiales.
No se recomienda secuestrar funciones en app, ya que Comfy está en constante desarrollo y el comportamiento del núcleo puede cambiar.

Propiedades

Entre las propiedades importantes de app se incluyen (esta no es una lista exhaustiva): canvas (para los elementos gráficos) y graph (para las conexiones lógicas) son probablemente los que más querrás consultar.

Funciones

De nuevo, hay muchas. Algunas de las más importantes son:

LGraph

El objeto LGraph forma parte del framework LiteGraph y representa el estado lógico actual del gráfico (nodos y conexiones). Si quieres manipular el gráfico, la documentación de LiteGraph (en doc/index.html si clonas https://github.com/jagenjo/litegraph.js) describe las funciones que necesitarás. Puedes usar graph para obtener detalles de nodos y conexiones, por ejemplo:
El objeto LLink, accesible a través de graph.links, representa un enlace individual del gráfico, desde el slot de salida link.origin_slot del nodo link.origin_id hasta el slot link.target_slot del nodo link.target_id. También incluye una cadena que representa el tipo de dato en link.type, además de link.id. Los LLink se crean en el método connect de un LGraphNode (del cual ComfyNode es una subclase).
Evita crear tus propios objetos LLink: usa las funciones de LiteGraph en su lugar.

ComfyNode

ComfyNode es una subclase de LGraphNode, por lo que la documentación de LiteGraph resulta útil para operaciones más genéricas. Sin embargo, Comfy ha ampliado de forma significativa el comportamiento del núcleo de LiteGraph y tampoco hace uso de toda la funcionalidad de LiteGraph.
La descripción que sigue se aplica a un nodo normal. Los nodos de grupo, los nodos primitivos, las notas y los nodos de redirección tienen propiedades diferentes.
Un objeto ComfyNode representa un nodo del flujo de trabajo actual. Tiene una serie de propiedades importantes que quizá quieras aprovechar, además de una gran cantidad de funciones que puedes usar o interceptar para modificar su comportamiento.
Obsoleto: Interceptar los métodos del prototipo en ComfyNode o LGraphNode está obsoleto y puede cambiar en cualquier momento en un futuro próximo. Usa los ganchos de extensión oficiales cuando estén disponibles, como getNodeMenuItems para los menús contextuales. Consulta la Guía de migración del menú contextual para ver ejemplos.
Para hacerte una idea más completa del objeto nodo, puede resultarte útil insertar el siguiente código en tu extensión y colocar un punto de interrupción en el comando console.log. Cuando crees un nodo nuevo, podrás usar tu depurador favorito para inspeccionar el nodo.

Propiedades

Funciones

Hay una cantidad muy grande de funciones (85, la última vez que las conté). A continuación se muestra una selección. La mayoría de estas funciones no presentan modificaciones respecto al código central de LiteGraph.

Entradas, salidas y widgets

Conexiones

Visualización

collapse tiene un nombre poco adecuado: alterna el estado contraído. Recibe un parámetro booleano, que se puede usar para anular node.collapsable === false.

Otros

Entradas y widgets

Las entradas y los widgets representan las dos formas de introducir datos en un nodo. Por lo general, puedes convertir un widget en una entrada, pero no todas las entradas pueden convertirse en un widget (ya que muchos tipos de datos no se pueden introducir mediante un elemento de la interfaz). node.inputs es una lista de las entradas actuales (los puntos de colores del lado izquierdo del nodo), que especifica su .name, .type y .link (una referencia al LLink conectado en app.graph.links). Si una entrada es un widget que se ha convertido, también guarda una referencia al widget, ahora inactivo, en .widget. node.widgets es una lista de todos los widgets, tanto si se han convertido en una entrada como si no. Un widget tiene:

Tipos de widget

app.widgets es un diccionario de los tipos de widget registrados actualmente, indexado por la versión en MAYÚSCULAS del nombre del tipo. Entre los tipos de widget integrados de Comfy se incluyen los obvios BOOLEAN, INT y FLOAT, así como STRING (que tiene dos variantes, de una línea y de varias líneas), COMBO para seleccionar de una lista desplegable, e IMAGEUPLOAD, que se usa en los nodos Load Image. Puedes agregar tipos de widget personalizados proporcionando un método getCustomWidgets en tu extensión.

Widgets enlazados

También puedes enlazar widgets, como ocurre con el comportamiento integrado de seed y control_after_generate, por ejemplo. Un widget enlazado tiene .type = 'base_widget_type:base_widget_name'; así, control_after_generate puede tener el tipo int:seed.

Prompt

Cuando presionas el botón Queue Prompt en Comfy, se llama al método app.graphToPrompt() para convertir el gráfico actual en un prompt que se pueda enviar al servidor. app.graphToPrompt devuelve un objeto (al que aquí llamamos prompt) con dos propiedades, output y workflow.

output

prompt.output asigna el node_id de cada nodo del gráfico a un objeto con dos propiedades.
  • prompt.output[node_id].class_type, el nombre único de la clase del nodo personalizado, tal como se define en el código de Python
  • prompt.output[node_id].inputs, que contiene el valor de cada entrada (o widget) como un mapa del nombre de la entrada a:
    • el valor seleccionado, si es un widget, o
    • un arreglo que contiene (upstream_node_id, upstream_node_output_slot) si hay una conexión en la entrada, o
    • undefined, si es un widget que se ha convertido en entrada y no está conectado
    • las demás entradas no conectadas no se incluyen en .inputs
Ten en cuenta que el upstream_node_id del arreglo que describe una entrada conectada se representa como una cadena, no como un entero.

workflow

prompt.workflow contiene las siguientes propiedades:
  • config - un diccionario de opciones de configuración adicionales (vacío de forma predeterminada)
  • extra - un diccionario con información adicional sobre el flujo de trabajo. De forma predeterminada contiene:
    • extra.ds - describe la vista actual del gráfico (scale y offset)
  • groups - todos los grupos del flujo de trabajo
  • last_link_id - el id del último enlace agregado
  • last_node_id - el id del último nodo agregado
  • links - una lista de todos los enlaces del gráfico. Cada entrada es un arreglo de cinco enteros y una cadena:
    • (link_id, upstream_node_id, upstream_node_output_slot, downstream_node_id, downstream_node_input_slot, data type)
  • nodes - una lista de todos los nodos del gráfico. Cada entrada es un mapa de un subconjunto de las propiedades del nodo como se describe arriba
    • Se incluyen las siguientes propiedades: flags, id, inputs, mode, order, pos, properties, size, type, widgets_values
    • Además, a menos que un nodo no tenga salidas, existe una propiedad outputs, que es una lista de las salidas del nodo, y cada una contiene:
      • name - el nombre de la salida
      • type - el tipo de dato de la salida
      • links - una lista de los link_id de todos los enlaces desde esta salida (si no hay conexiones, puede ser una lista vacía o null),
      • shape - la forma usada para dibujar la salida (3 de forma predeterminada para un punto)
      • slot_index - el número de ranura de la salida
  • version - el número de versión de LiteGraph (al momento de escribir esto, 0.4)
nodes.output no existe en los nodos sin salidas, no es una lista vacía.