---
name: comfyui_build_txt2img_workflow
kind: function
lang: py
domain: ml
version: "1.0.0"
purity: pure
signature: "def comfyui_build_txt2img_workflow(ckpt_name: str, positive: str, negative: str = \"\", *, steps: int = 20, cfg: float = 7.0, width: int = 512, height: int = 512, seed: int = 0, sampler_name: str = \"euler\", scheduler: str = \"normal\", filename_prefix: str = \"comfy\") -> dict"
description: "Construye el dict de un workflow ComfyUI txt2img en API format (nodos numerados con class_type + inputs, conexiones como [node_id, output_index]) para SD1.5/SDXL: CheckpointLoaderSimple -> CLIPTextEncode x2 + EmptyLatentImage -> KSampler -> VAEDecode -> SaveImage. Pura, sin red ni I/O."
tags: [comfyui, ml, image-generation, txt2img, stable-diffusion, workflow]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
params:
  - name: ckpt_name
    desc: "Nombre del checkpoint tal como lo ve el servidor ComfyUI (ej. 'IMG_v1-5-pruned-emaonly-fp16.safetensors'). Debe estar en la lista que devuelve comfyui_object_info para CheckpointLoaderSimple."
  - name: positive
    desc: "Prompt positivo: lo que se quiere ver en la imagen."
  - name: negative
    desc: "Prompt negativo: lo que se quiere evitar. Por defecto cadena vacia."
  - name: steps
    desc: "Pasos de sampling del KSampler. keyword-only."
  - name: cfg
    desc: "Classifier-free guidance scale. keyword-only."
  - name: width
    desc: "Ancho del latente/imagen en px, multiplo de 8. keyword-only."
  - name: height
    desc: "Alto del latente/imagen en px, multiplo de 8. keyword-only."
  - name: seed
    desc: "Semilla del KSampler. 0 es determinista; cambiar para variar la imagen. keyword-only."
  - name: sampler_name
    desc: "Nombre del sampler (ej. 'euler', 'dpmpp_2m'). keyword-only."
  - name: scheduler
    desc: "Scheduler del sampler (ej. 'normal', 'karras'). keyword-only."
  - name: filename_prefix
    desc: "Prefijo del PNG que SaveImage escribe en output/. keyword-only."
output: "dict en API format con node_ids '3'..'9' como claves; cada valor tiene class_type + inputs. Listo para comfyui_submit_workflow."
tested: true
tests: ["class_types esperados (6 nodos)", "params seed/steps/cfg/width/height reflejados", "filename_prefix en SaveImage", "determinismo: misma entrada -> mismo dict (builder puro)"]
test_file_path: "python/functions/ml/tests/test_comfyui_build_txt2img_workflow.py"
file_path: "python/functions/ml/comfyui_build_txt2img_workflow.py"
---

## Ejemplo

```python
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow

wf = comfyui_build_txt2img_workflow(
    ckpt_name="IMG_v1-5-pruned-emaonly-fp16.safetensors",
    positive="a red apple on a wooden table, sharp focus",
    negative="blurry, low quality",
    steps=20,
    seed=42,
)
# wf["3"]["class_type"] == "KSampler"
# wf["3"]["inputs"]["model"] == ["4", 0]   # conexion al CheckpointLoader
# wf["9"]["class_type"] == "SaveImage"
```

O lanzable directo con: `./fn run comfyui_build_txt2img_workflow` (imprime el JSON del workflow de ejemplo).

## Cuando usarla

Antes de enviar una generacion txt2img a ComfyUI: construye aqui el dict del
workflow y pasalo a `comfyui_submit_workflow`. Usala siempre que necesites un
txt2img basico sin tener que escribir el grafo de nodos a mano. Para workflows
mas complejos (img2img, ControlNet, upscalers) construye el dict tu mismo o
extiende esta funcion con un builder hermano.

## Gotchas

- Es API format (nodos numerados), NO el formato de la UI de ComfyUI (graph con
  links). No se puede pegar en la UI tal cual; es el formato que acepta POST
  /prompt.
- `ckpt_name` debe coincidir EXACTAMENTE con un checkpoint visible para el
  servidor. Si no existe, ComfyUI rechaza el workflow con HTTP 400 al enviarlo
  (no aqui — esta funcion es pura y no valida contra el servidor).
- `width`/`height` deben ser multiplos de 8 o el KSampler fallara en el
  servidor.
- Asume que el checkpoint trae VAE embebido (VAEDecode usa `["4", 2]`, la salida
  VAE del CheckpointLoaderSimple). Para un VAE externo cambia esa conexion.
