Files
fn_registry/docs/capabilities/comfyui.md
T
egutierrez 1311c7e585 feat(ml): auto-commit con 7 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-24 01:16:37 +02:00

20 KiB
Raw Blame History

ComfyUI — Generación de imágenes por API HTTP y por la UI (CDP)

Tag: comfyui. Grupo de funciones para controlar ComfyUI (motor de Stable Diffusion basado en grafos de nodos) de dos formas complementarias:

  • Por su API HTTP (/prompt, /history, /object_info): construir un workflow en "API format", encolarlo, esperar el resultado. Headless, scriptable, sin navegador.
  • Por su UI web vía CDP: operar la pestaña de ComfyUI ya abierta en el navegador diario (cargar un workflow en el grafo visual, editar widgets en vivo, encolar como si pulsaras "Queue Prompt", exportar el grafo, refrescar combos). Lo que el usuario ve, el agente lo toca. Todas las funciones de UI componen la primitiva de transport cdp_eval_py_browser — no reinventan CDP.

Filtro MCP: mcp__registry__fn_search query="" tag="comfyui".

Dos caminos, mismo motor

API HTTP (dominio ml)                      UI web vía CDP (dominio browser)
──────────────────────                     ───────────────────────────────
build_txt2img_workflow  (dict API format)  load_workflow_ui   (dict -> grafo visual)
        │                                   set_node_widget_ui (tuning en vivo)
        ▼                                   queue_prompt_ui    (= botón Queue Prompt)
submit_workflow  (POST /prompt -> id)       export_workflow_ui (grafo -> dict API format)
        ▼                                   refresh_nodes_ui   (recarga combos)
wait_result      (poll /history -> PNG)
object_info      (catálogo de nodos)        download_model (dominio ml) -> baja checkpoints

El API format (dict de nodos numerados que produce build_txt2img_workflow y consume submit_workflow) es el puente entre ambos mundos: load_workflow_ui lo carga en la UI y export_workflow_ui lo recupera de la UI, así que puedes mezclar libremente API y navegador.

Funciones del grupo

Por API HTTP — dominio ml

ID Firma corta Qué hace
comfyui_build_txt2img_workflow_py_ml build_txt2img_workflow(ckpt_name, positive, negative='', *, steps, cfg, width, height, seed, ...) -> dict Construye el dict del workflow txt2img básico (Checkpoint → CLIPTextEncode×2 + EmptyLatent → KSampler → VAEDecode → SaveImage) en API format. Pura.
comfyui_object_info_py_ml object_info(server='127.0.0.1:8188', node_class=None, timeout) -> dict Catálogo de nodos del server: inputs, tipos y enums (lista de checkpoints/samplers visibles). Para validar antes de enviar. Impura.
comfyui_submit_workflow_py_ml submit_workflow(workflow, server, client_id, timeout) -> dict Encola un workflow API format vía POST /prompt; devuelve prompt_id + posición en cola. HTTP 400 propaga la validación por nodo. Impura.
comfyui_wait_result_py_ml wait_result(prompt_id, server, timeout, poll_interval) -> dict Sondea GET /history/{prompt_id} hasta que termina; devuelve los outputs (PNGs con filename/subfolder/type). Impura.
comfyui_download_model_py_ml download_model(url, dest_subdir='checkpoints', *, comfyui_dir, filename, token, overwrite, timeout_s) -> dict Descarga un checkpoint/LoRA/VAE a models/<dest_subdir>/. Soporta Civitai (token) y HuggingFace. Valida que no sea HTML de error ni .safetensors corrupto. Impura.

Builders, validación e import — dominio ml (P0, issue 0064)

ID Firma corta Qué hace
comfyui_build_img2img_workflow_py_ml build_img2img_workflow(ckpt_name, init_image, positive, negative='', *, denoise=0.6, steps, cfg, seed, ...) -> dict Builder img2img (Checkpoint + LoadImage → VAEEncode → KSampler con denoise → VAEDecode → SaveImage). Pura.
comfyui_build_upscale_workflow_py_ml build_upscale_workflow(image, *, model_name='4x-UltraSharp.pth', method='model') -> dict Builder upscale: method='model' (ESRGAN: UpscaleModelLoader + ImageUpscaleWithModel) o method='latent' (ImageScaleBy x2 sin modelo). Pura.
comfyui_inject_lora_py_ml inject_lora(workflow, lora_name, *, strength_model=1.0, strength_clip=1.0, model_node=None, clip_node=None) -> dict Inserta un LoraLoader en un workflow ya construido, reconectando model/clip de la fuente a sus consumidores. Encadenable. Pura (no muta la entrada).
comfyui_validate_workflow_py_ml validate_workflow(workflow, server='127.0.0.1:8188', timeout) -> dict Cruza class_type y nombres de modelo contra /object_info; devuelve {valid, missing_nodes, missing_models} ANTES de encolar. Compone object_info. Impura.
comfyui_import_workflow_json_py_ml import_workflow_json(source, *, server, timeout) -> dict Lee un workflow JSON de URL o path local; normaliza UI graph → API format (widgets vía object_info); passthrough si ya es API. Impura.
comfyui_import_workflow_png_py_ml import_workflow_png(png_path_or_url, *, timeout) -> dict Extrae el workflow embebido en los chunks prompt (API) / workflow (UI) de un PNG de ComfyUI (tEXt/zTXt/iTXt, stdlib). Path o URL. Impura.
comfyui_download_workflow_py_ml download_workflow(source, dest=None, *, server, civitai_token, hf_token, timeout) -> dict Dispatcher: descarga un workflow de CUALQUIER fuente (Google Drive, GitHub, Civitai, HuggingFace, URL directa o path local) y lo normaliza a API format. Detecta el tipo por la URL y delega; tras bajar compone import_workflow_json/import_workflow_png. Catálogo de fuentes: reports/0080. Impura.
comfyui_read_png_metadata_py_ml read_png_metadata(png_path) -> dict Lee los parámetros de generación (modelo, seed, steps, cfg, sampler, prompts) de un PNG generado por ComfyUI. Impura (I/O disco).
comfyui_fetch_output_image_py_ml fetch_output_image(filename, *, subfolder='', type_='output', server, dest_dir='.', timeout) -> dict Descarga el PNG generado vía GET /view a disco local (wait_result solo da metadata). Impura.

Potencia y assets de internet — dominio ml (P1, issue 0064)

ID Firma corta Qué hace
comfyui_build_inpaint_workflow_py_ml build_inpaint_workflow(ckpt_name, image, mask, positive, negative='', *, denoise=1.0, steps, cfg, seed, ...) -> dict Builder inpaint: CheckpointLoaderSimple + LoadImage + LoadImageMask → VAEEncodeForInpaint → KSampler → VAEDecode → SaveImage. Regenera solo la zona enmascarada. Pura.
comfyui_build_controlnet_workflow_py_ml build_controlnet_workflow(ckpt_name, control_image, cn_name, positive, negative='', *, strength=1.0, steps, cfg, seed, width, height) -> dict Builder ControlNet: ControlNetLoader + ControlNetApply inyectan el mapa de control sobre el condicionamiento positivo. Pura.
comfyui_build_sdxl_refiner_workflow_py_ml build_sdxl_refiner_workflow(base_ckpt, refiner_ckpt, positive, negative='', *, base_steps=20, refiner_steps=5, cfg, seed, width=1024, height=1024) -> dict SDXL base+refiner: dos KSamplerAdvanced encadenados (base con return_with_leftover_noise, refiner termina). Pura.
comfyui_search_civitai_models_py_ml search_civitai_models(query, *, types='Checkpoint', base_model=None, sort, limit=20, token=None) -> dict Busca modelos/LoRAs en la API pública de Civitai → {ok, items:[{name, type, base_model, version_id, download_url, nsfw}], count, error}. Sin token funciona. Impura.
comfyui_install_custom_node_py_ml install_custom_node(repo_url, *, comfyui_dir, pip_install=True, restart=False) -> dict git clone en custom_nodes/ + pip/uv install de requirements en el venv de ComfyUI. NO reinicia el server (restart=False). Impura.
comfyui_resolve_workflow_deps_py_ml resolve_workflow_deps(workflow, server='127.0.0.1:8188') -> dict Para un workflow ajeno: valida y traduce lo que falta en acciones ({missing_nodes, missing_models, suggestions}). Compone validate_workflow. Impura.
comfyui_list_installed_models_py_ml list_installed_models(folder=None, comfyui_dir='~/ComfyUI') -> dict Lista modelos por carpeta resolviendo la ruta real de extra_model_paths.yaml (/mnt/2tb/comfyui_models/) + la nativa. Escaneo de FS, no depende del server. Impura.

Imagen → 3D (Hunyuan3D-2 nativo) — dominio ml + pipelines (tag img-to-3d)

ComfyUI ≥ 0.26.0 trae soporte nativo de Hunyuan3D-2 (sin custom node): una imagen se reconstruye en una malla 3D GLB con un grafo de 9 nodos (LoadImage → ImageOnlyCheckpointLoader → CLIPVisionEncode → Hunyuan3Dv2Conditioning → EmptyLatentHunyuan3Dv2 → KSampler → VAEDecodeHunyuan3D → VoxelToMeshBasic → SaveGLB). El checkpoint es self-contained (DiT de forma + VAE 3D + encoder de imagen en un .safetensors). Salida shape-only (sin color/textura). Detalle y benchmark en reports/0069-2026-06-23-comfyui-img-to-3d.md. Para mejorar la cara trasera/laterales, genera vistas novel-view desde 1 imagen (generate_views_from_image, reports 0073); para VER el GLB resultante interactivo dentro de un nodo de la UI, monta el visor Load3D (build_view_3d_workflow, report 0079).

ID Firma corta Qué hace
comfyui_build_image_to_3d_workflow_py_ml build_image_to_3d_workflow(image_name, ckpt_name='hunyuan3d-dit-v2-mini.safetensors', *, resolution, steps, cfg, seed, octree_resolution, num_chunks, threshold, ...) -> dict Builder del workflow imagen→3D de 9 nodos (Hunyuan3D-2 nativo) en API format. El SaveGLB produce un .glb. Pura.
comfyui_generate_views_from_image_py_ml generate_views_from_image(image_name, *, method='auto', server, azimuths=(90,180,270), elevation, dest_dir, validate_only=False, ...) -> dict Sintetiza vistas novel-view (back/left/right) desde 1 imagen con StableZero123/SV3D nativos, para alimentar el 3D multi-vista. Honesta: si el nodo+checkpoint no están, devuelve ok=False con la acción y NO encola. validate_only=True valida sin tocar GPU. Impura.
comfyui_build_view_3d_workflow_py_ml build_view_3d_workflow(model_file, *, animation=False, width, height) -> dict Monta el visor 3D nativo Load3D (o Load3DAdvanced con animation=True) para VER un GLB/OBJ existente, orbitando con el ratón, sin ejecutar el grafo. model_file relativo a input/3d/. Cárgalo con load_workflow_ui. Pura.
comfyui_fetch_output_mesh_py_ml fetch_output_mesh(prompt_id, *, server, dest=None, timeout) -> dict Localiza la malla en /history/{prompt_id} (el SaveGLB la expone bajo la clave "3d", no "images") y la baja via GET /view a disco. Hermana de fetch_output_image. Impura.
comfyui_install_3d_model_py_ml install_3d_model(variant='mini', *, hf_token=None, comfyui_dir) -> dict Instala el checkpoint Hunyuan3D-2 (mini/standard/mv) en checkpoints/. Cascada: ya-instalado → cache de HF → descarga. Resuelve la ruta real via extra_model_paths.yaml. Impura.
comfyui_image_to_3d_oneshot_py_pipelines image_to_3d_oneshot(image_path, *, server, variant='mini', dest=None, wait_timeout, **gen) -> dict Pipeline imagen en disco → malla GLB en una llamada: upload + build + submit + wait + fetch. Promoción de la secuencia (issue 0087). Impuro.

Por la UI web (CDP) — dominio browser

ID Firma corta Qué hace
comfyui_load_workflow_ui_py_browser load_workflow_ui(workflow, *, port=9222, server_url_substr='8188', filename, timeout_s) -> dict Carga un workflow API format en el grafo visual (app.loadApiJson). Impura (CDP + muta UI).
comfyui_set_node_widget_ui_py_browser set_node_widget_ui(node, widget_name, value, *, match='type', port, server_url_substr, timeout_s) -> dict Edita en vivo un widget de un nodo (texto del CLIPTextEncode, steps/seed/cfg del KSampler). Localiza por type/id/title. Impura.
comfyui_queue_prompt_ui_py_browser queue_prompt_ui(*, port, server_url_substr, timeout_s) -> dict Encola el grafo actual (app.queuePrompt(0)), = botón "Queue Prompt". Impura (dispara GPU).
comfyui_export_workflow_ui_py_browser export_workflow_ui(*, port, server_url_substr, api_format=True, save_path, timeout_s) -> dict Exporta el grafo actual: API format (graphToPrompt().output) o UI graph (graph.serialize()); opcional a disco. Impura.
comfyui_refresh_nodes_ui_py_browser refresh_nodes_ui(*, port, server_url_substr, timeout_s) -> dict Refresca los combos (checkpoints/loras/vae) sin recargar la página (app.refreshComboInNodes). Impura.

Ejemplo canónico end-to-end (build → load → tune → queue → resultado)

Combina API + UI: construyes el workflow por API, lo cargas en la UI del usuario, ajustas el prompt y los pasos en vivo, encolas y esperas el PNG. Requiere el server en 127.0.0.1:8188 y la pestaña de ComfyUI abierta en un Chrome con --remote-debugging-port=9222.

import sys, os, time, glob
sys.path.insert(0, os.path.join("python", "functions"))
from ml.comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow
from browser.comfyui_load_workflow_ui import comfyui_load_workflow_ui
from browser.comfyui_set_node_widget_ui import comfyui_set_node_widget_ui
from browser.comfyui_queue_prompt_ui import comfyui_queue_prompt_ui

# 1. Construir (API format, función pura) con un prefijo de salida localizable.
prefix = f"demo_{int(time.time())}"
wf = comfyui_build_txt2img_workflow(
    ckpt_name="dreamshaper_8.safetensors",
    positive="placeholder",
    steps=8, seed=111, filename_prefix=prefix,
)

# 2. Cargar el grafo en la UI del navegador del usuario.
comfyui_load_workflow_ui(wf)                                  # {'ok': True, 'loaded': True}

# 3. Tuning en vivo: prompt (widget de texto) + pasos (widget numérico).
comfyui_set_node_widget_ui("CLIPTextEncode", "text",
                           "a green glass bottle on a marble shelf", match="type")
comfyui_set_node_widget_ui("KSampler", "steps", 12, match="type")

# 4. Encolar (= pulsar "Queue Prompt") y localizar el PNG nuevo en output/.
comfyui_queue_prompt_ui()                                     # {'ok': True, 'queued': True}
before = set(glob.glob(os.path.expanduser("~/ComfyUI/output/*.png")))
while True:
    new = [p for p in set(glob.glob(os.path.expanduser("~/ComfyUI/output/*.png"))) - before
           if prefix in os.path.basename(p)]
    if new:
        print("PNG generado:", new[0]); break
    time.sleep(1.5)

Variante 100% headless (sin navegador): cambia los pasos 2-4 por comfyui_submit_workflow(wf)comfyui_wait_result(prompt_id). Misma capacidad, sin UI.

Ejemplo canónico imagen → 3D (Hunyuan3D-2 nativo)

Una imagen de un objeto → su malla GLB, en una sola llamada. Requiere el server en 127.0.0.1:8188 y el checkpoint mini instalado (lo hace install_3d_model la primera vez, reutilizando la cache de HF; ~60 s de GPU por reconstrucción en una RTX 3070).

import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from ml.comfyui_install_3d_model import comfyui_install_3d_model
from pipelines.comfyui_image_to_3d_oneshot import comfyui_image_to_3d_oneshot

# 1. Asegurar el checkpoint (instantáneo si ya está; reused_cache=True).
comfyui_install_3d_model("mini")

# 2. Imagen en disco -> malla GLB en /tmp/meshes.
res = comfyui_image_to_3d_oneshot(
    os.path.expanduser("~/ComfyUI/input/3d_src_robot_00001_.png"),
    dest="/tmp/meshes", variant="mini", seed=42,
)
print(res["mesh_path"], res["faces"])   # /tmp/meshes/3d_mesh_00001_.glb 1668040

Para tunear nodo a nodo en vez del oneshot: build_image_to_3d_workflow(image_name)submit_workflowwait_resultfetch_output_mesh(prompt_id, dest=...).

Fronteras

  • No es un grupo de generación genérica de imágenes: cubre ComfyUI concretamente (su API y su frontend litegraph). Para otros backends (Automatic1111, diffusers) harían falta otras funciones.
  • Los builders cubren txt2img, img2img, upscale, LoRA stacks, inpaint, ControlNet y SDXL refiner (build_txt2img_workflow, build_img2img_workflow, build_upscale_workflow, inject_lora, build_inpaint_workflow, build_controlnet_workflow, build_sdxl_refiner_workflow). Workflows aún más complejos (multi-ControlNet avanzado, IPAdapter, vídeo) se montan en la UI a mano y se capturan con export_workflow_ui, o se importan de internet con import_workflow_json/import_workflow_png, se resuelven sus dependencias con resolve_workflow_deps (instala nodos con install_custom_node, descubre modelos con search_civitai_models) y se validan con validate_workflow antes de encolar.
  • Las funciones *_ui requieren la pestaña abierta y el navegador con CDP (puerto 9222 por defecto). Sin target que matchee server_url_substr, devuelven ok=False. Para automatización desatendida sin navegador, usa el camino API (submit_workflow + wait_result).
  • download_model no gestiona el catálogo del server: tras bajar un modelo, llama refresh_nodes_ui (o recarga la página) para que ComfyUI lo vea en los combos.
  • El camino imagen→3D es shape-only: los nodos nativos de Hunyuan3D-2 (build_image_to_3d_workflow, fetch_output_mesh, install_3d_model, image_to_3d_oneshot) reconstruyen la FORMA, sin color ni textura horneada. Para color/textura haría falta el wrapper de kijai (compila custom_rasterizer) — fuera del grupo. Tampoco hay decimación: las mallas son densas (decenas de MB de GLB). Decisión y comparación vs la app local en reports/0069-2026-06-23-comfyui-img-to-3d.md.
  • La primitiva de transport CDP es cdp_eval (grupo navegador): si necesitas leer/escribir algo del grafo que estas funciones no cubren, compón cdp_eval directamente antes de inventar nada.