fix(gamedev): card_art hires roto (UltimateSDUpscale exige batch_size) + INDEX conteo gamedev 10->20
El nodo UltimateSDUpscale declara batch_size como input requerido en /object_info; comfyui_build_hires_fix_workflow y comfyui_inject_hires_fix no lo proveian, por lo que card_art con hires=True fallaba en runtime. Se anade batch_size: 1 a ambos constructores + guards de regresion en los tests (card_art golden hires, builder e inject). Verificado con una generacion real en ComfyUI (carta 768x1152, sin node_errors, prompt_id 4033fb0b). Bump de version 1.0.0->1.0.1 en ambos .md con growth log y gotcha. INDEX.md: la fila gamedev decia count=10; el cluster de assets 2D documentado en gamedev-2d.md tiene 20 funciones (15 builders tag gamedev-2d + 5 de apoyo). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ Indice de grupos de capacidades del registry. Cada grupo agrupa >=3 funciones qu
|
|||||||
|
|
||||||
| Grupo | N | Que cubre |
|
| Grupo | N | Que cubre |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| [gamedev](gamedev-2d.md) | 10 | Assets 2D para Godot: builders de workflow ComfyUI (pixelart/seamless/iso/sprite/VFX, tag `gamedev-2d`) + post-proceso (pixelize, luma->alpha) + puente de assets a Godot 4 (.import + reimport headless) |
|
| [gamedev](gamedev-2d.md) | 20 | Assets 2D para Godot: 15 builders de workflow ComfyUI (pixelart/seamless/iso/sprite/topdown/card/enemy/prop/VFX..., tag `gamedev-2d`) + 5 de apoyo: post-proceso (pixelize, luma->alpha) + puente de assets a Godot 4 (.import + reimport headless) |
|
||||||
| [registry](registry.md) | 17 | Auditoria y monitorizacion del propio registry: copied-code, uses-functions, unused, proposals, telemetria |
|
| [registry](registry.md) | 17 | Auditoria y monitorizacion del propio registry: copied-code, uses-functions, unused, proposals, telemetria |
|
||||||
| [systemd](systemd.md) | 14 | Generar, instalar, restart y status de unit files systemd via SSH (deploys a VPS) |
|
| [systemd](systemd.md) | 14 | Generar, instalar, restart y status de unit files systemd via SSH (deploys a VPS) |
|
||||||
| [ssh](ssh.md) | 19 | Operar hosts remotos via SSH: config, conn, ejecutar comandos, port-forward, deploys con SCP/rsync |
|
| [ssh](ssh.md) | 19 | Operar hosts remotos via SSH: config, conn, ejecutar comandos, port-forward, deploys con SCP/rsync |
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ def test_golden_hires_recipe():
|
|||||||
assert latent["width"] == 512
|
assert latent["width"] == 512
|
||||||
assert latent["height"] == 768
|
assert latent["height"] == 768
|
||||||
assert latent["width"] < latent["height"]
|
assert latent["width"] < latent["height"]
|
||||||
|
# Regresion: UltimateSDUpscale exige batch_size (input requerido segun
|
||||||
|
# /object_info). Sin el, el submit con hires=True fallaba con node_errors.
|
||||||
|
usd = _by_class(wf, "UltimateSDUpscale")[0]["inputs"]
|
||||||
|
assert usd["batch_size"] == 1
|
||||||
|
|
||||||
|
|
||||||
def test_edge_no_hires_plain_txt2img():
|
def test_edge_no_hires_plain_txt2img():
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: comfyui_build_hires_fix_workflow
|
|||||||
kind: function
|
kind: function
|
||||||
lang: py
|
lang: py
|
||||||
domain: ml
|
domain: ml
|
||||||
version: "1.0.0"
|
version: "1.0.1"
|
||||||
purity: pure
|
purity: pure
|
||||||
signature: "def comfyui_build_hires_fix_workflow(ckpt_name: str, positive: str, negative: str = \"\", *, first_pass: tuple[int, int] = (768, 768), upscale_by: float = 1.5, denoise: float = 0.4, steps: int = 20, cfg: float = 7.0, seed: int = 0, upscale_model: str = \"4x_foolhardy_Remacri.pth\", sampler_name: str = \"euler\", scheduler: str = \"normal\", tile_width: int = 512, tile_height: int = 512, filename_prefix: str = \"hires\") -> dict"
|
signature: "def comfyui_build_hires_fix_workflow(ckpt_name: str, positive: str, negative: str = \"\", *, first_pass: tuple[int, int] = (768, 768), upscale_by: float = 1.5, denoise: float = 0.4, steps: int = 20, cfg: float = 7.0, seed: int = 0, upscale_model: str = \"4x_foolhardy_Remacri.pth\", sampler_name: str = \"euler\", scheduler: str = \"normal\", tile_width: int = 512, tile_height: int = 512, filename_prefix: str = \"hires\") -> dict"
|
||||||
description: "Construye un workflow ComfyUI de hires-fix de 2 pasadas en API format: genera una imagen base pequena (KSampler) y la amplia re-difundiendola por tiles con UltimateSDUpscale + un modelo de upscale (Remacri), anadiendo detalle real a alta resolucion. UltimateSDUpscale es la segunda pasada de muestreo (recibe model/positive/negative/vae). Distinto de comfyui_build_upscale_workflow, que es ESRGAN puro sin re-difusion. Class_types verificados en /object_info. Pura, sin red ni I/O."
|
description: "Construye un workflow ComfyUI de hires-fix de 2 pasadas en API format: genera una imagen base pequena (KSampler) y la amplia re-difundiendola por tiles con UltimateSDUpscale + un modelo de upscale (Remacri), anadiendo detalle real a alta resolucion. UltimateSDUpscale es la segunda pasada de muestreo (recibe model/positive/negative/vae). Distinto de comfyui_build_upscale_workflow, que es ESRGAN puro sin re-difusion. Class_types verificados en /object_info. Pura, sin red ni I/O."
|
||||||
@@ -47,7 +47,7 @@ params:
|
|||||||
desc: "Prefijo del PNG final que escribe SaveImage. keyword-only."
|
desc: "Prefijo del PNG final que escribe SaveImage. keyword-only."
|
||||||
output: "dict en API format listo para comfyui_submit_workflow. node_ids: '4' CheckpointLoaderSimple, '5' EmptyLatentImage, '6'/'7' CLIPTextEncode, '3' KSampler (base), '8' VAEDecode, '11' UpscaleModelLoader, '12' UltimateSDUpscale, '9' SaveImage."
|
output: "dict en API format listo para comfyui_submit_workflow. node_ids: '4' CheckpointLoaderSimple, '5' EmptyLatentImage, '6'/'7' CLIPTextEncode, '3' KSampler (base), '8' VAEDecode, '11' UpscaleModelLoader, '12' UltimateSDUpscale, '9' SaveImage."
|
||||||
tested: true
|
tested: true
|
||||||
tests: ["cadena base (KSampler) + UltimateSDUpscale + SaveImage", "denoise de la 2a pasada <1 (re-difusion parcial)", "first_pass refleja width/height en EmptyLatentImage", "upscale_model llega a UpscaleModelLoader", "determinismo: misma entrada -> mismo dict (builder puro)"]
|
tests: ["cadena base (KSampler) + UltimateSDUpscale + SaveImage", "UltimateSDUpscale provee batch_size (input requerido)", "denoise de la 2a pasada <1 (re-difusion parcial)", "first_pass refleja width/height en EmptyLatentImage", "upscale_model llega a UpscaleModelLoader", "determinismo: misma entrada -> mismo dict (builder puro)"]
|
||||||
test_file_path: "python/functions/ml/tests/test_comfyui_build_hires_fix_workflow.py"
|
test_file_path: "python/functions/ml/tests/test_comfyui_build_hires_fix_workflow.py"
|
||||||
file_path: "python/functions/ml/comfyui_build_hires_fix_workflow.py"
|
file_path: "python/functions/ml/comfyui_build_hires_fix_workflow.py"
|
||||||
---
|
---
|
||||||
@@ -102,3 +102,15 @@ queda corto porque no inventa detalle nuevo. Después: `comfyui_submit_workflow`
|
|||||||
tiles de 512 y `upscale_by` 1.5–2.0.
|
tiles de 512 y `upscale_by` 1.5–2.0.
|
||||||
- Coste real: la 2ª pasada re-difunde N tiles, es bastante más lenta que un upscale
|
- Coste real: la 2ª pasada re-difunde N tiles, es bastante más lenta que un upscale
|
||||||
ESRGAN puro. Para solo agrandar sin re-difusión usa `comfyui_build_upscale_workflow`.
|
ESRGAN puro. Para solo agrandar sin re-difusión usa `comfyui_build_upscale_workflow`.
|
||||||
|
- El nodo `UltimateSDUpscale` declara `batch_size` como input **requerido** en
|
||||||
|
`/object_info` (esta versión de ComfyUI). El builder lo fija a `1`; sin él el
|
||||||
|
server aceptaba el POST pero el grafo fallaba en runtime (input faltante). Si
|
||||||
|
cambia la firma del custom node, verifica con
|
||||||
|
`curl /object_info/UltimateSDUpscale`.
|
||||||
|
|
||||||
|
## Capability growth log
|
||||||
|
|
||||||
|
- v1.0.1 (2026-06-27) — bugfix: el nodo `UltimateSDUpscale` exige `batch_size`
|
||||||
|
(input requerido en `/object_info`); se añade `batch_size: 1`. Sin él, los
|
||||||
|
workflows con hires fallaban en runtime (afectaba a `comfyui_build_card_art_workflow`,
|
||||||
|
único consumidor). Verificado con submit real a ComfyUI (768×1152, sin node_errors).
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ def comfyui_build_hires_fix_workflow(
|
|||||||
"seam_fix_padding": 16,
|
"seam_fix_padding": 16,
|
||||||
"force_uniform_tiles": True,
|
"force_uniform_tiles": True,
|
||||||
"tiled_decode": False,
|
"tiled_decode": False,
|
||||||
|
"batch_size": 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"9": {
|
"9": {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: comfyui_inject_hires_fix
|
|||||||
kind: function
|
kind: function
|
||||||
lang: py
|
lang: py
|
||||||
domain: ml
|
domain: ml
|
||||||
version: "1.0.0"
|
version: "1.0.1"
|
||||||
purity: pure
|
purity: pure
|
||||||
signature: "def comfyui_inject_hires_fix(workflow: dict, *, upscale_by: float = 1.5, denoise: float = 0.4, steps: int = 20, cfg: float = 7.0, seed: int = 0, upscale_model: str = '4x_foolhardy_Remacri.pth', sampler_name: str = 'euler', scheduler: str = 'normal', tile_width: int = 512, tile_height: int = 512) -> dict"
|
signature: "def comfyui_inject_hires_fix(workflow: dict, *, upscale_by: float = 1.5, denoise: float = 0.4, steps: int = 20, cfg: float = 7.0, seed: int = 0, upscale_model: str = '4x_foolhardy_Remacri.pth', sampler_name: str = 'euler', scheduler: str = 'normal', tile_width: int = 512, tile_height: int = 512) -> dict"
|
||||||
description: "Inyecta una segunda pasada hires-fix en un workflow ComfyUI ya construido (API format) que termina en VAEDecode -> SaveImage. Anade UpscaleModelLoader + UltimateSDUpscale (re-difusion por tiles) conectados a la imagen del VAEDecode y al model/vae del CheckpointLoaderSimple, y repunta el SaveImage a la imagen ampliada. Version encadenable-sobre-dict de comfyui_build_hires_fix_workflow. Pura: no muta el dict de entrada (copia profunda)."
|
description: "Inyecta una segunda pasada hires-fix en un workflow ComfyUI ya construido (API format) que termina en VAEDecode -> SaveImage. Anade UpscaleModelLoader + UltimateSDUpscale (re-difusion por tiles) conectados a la imagen del VAEDecode y al model/vae del CheckpointLoaderSimple, y repunta el SaveImage a la imagen ampliada. Version encadenable-sobre-dict de comfyui_build_hires_fix_workflow. Pura: no muta el dict de entrada (copia profunda)."
|
||||||
@@ -39,7 +39,7 @@ params:
|
|||||||
desc: "Alto de tile de UltimateSDUpscale (px). keyword-only."
|
desc: "Alto de tile de UltimateSDUpscale (px). keyword-only."
|
||||||
output: "copia del workflow con UpscaleModelLoader + UltimateSDUpscale anadidos (node_ids = max id numerico + 1 y + 2) y el SaveImage repuntado a la salida [ultimatesdupscale_id, 0]. Si no habia SaveImage, se anade uno con filename_prefix 'hires'."
|
output: "copia del workflow con UpscaleModelLoader + UltimateSDUpscale anadidos (node_ids = max id numerico + 1 y + 2) y el SaveImage repuntado a la salida [ultimatesdupscale_id, 0]. Si no habia SaveImage, se anade uno con filename_prefix 'hires'."
|
||||||
tested: true
|
tested: true
|
||||||
tests: ["no muta el dict de entrada (pureza)", "inserta UltimateSDUpscale y UpscaleModelLoader", "repunta el SaveImage al UltimateSDUpscale", "params reflejados (upscale_by/denoise/seed)", "lanza ValueError si falta VAEDecode"]
|
tests: ["no muta el dict de entrada (pureza)", "inserta UltimateSDUpscale y UpscaleModelLoader", "repunta el SaveImage al UltimateSDUpscale", "params reflejados (upscale_by/denoise/seed) + batch_size", "lanza ValueError si falta VAEDecode"]
|
||||||
test_file_path: "python/functions/ml/tests/test_comfyui_inject_hires_fix.py"
|
test_file_path: "python/functions/ml/tests/test_comfyui_inject_hires_fix.py"
|
||||||
file_path: "python/functions/ml/comfyui_inject_hires_fix.py"
|
file_path: "python/functions/ml/comfyui_inject_hires_fix.py"
|
||||||
---
|
---
|
||||||
@@ -81,3 +81,12 @@ VAEDecode -> SaveImage. Una sola llamada anade la segunda pasada completa.
|
|||||||
Para grafos multi-salida construye con un builder dedicado.
|
Para grafos multi-salida construye con un builder dedicado.
|
||||||
- El nuevo node_id es `max(ids numericos) + 1` (y +2). Si tu workflow usa ids no
|
- El nuevo node_id es `max(ids numericos) + 1` (y +2). Si tu workflow usa ids no
|
||||||
numericos, el contador cae a `len(workflow) + 1`.
|
numericos, el contador cae a `len(workflow) + 1`.
|
||||||
|
- El nodo `UltimateSDUpscale` declara `batch_size` como input **requerido** en
|
||||||
|
`/object_info`; la inyección lo fija a `1`. Sin él, el submit pasaba la
|
||||||
|
validación de POST pero el grafo fallaba en runtime por input faltante.
|
||||||
|
|
||||||
|
## Capability growth log
|
||||||
|
|
||||||
|
- v1.0.1 (2026-06-27) — bugfix paralelo al de `comfyui_build_hires_fix_workflow`:
|
||||||
|
el nodo `UltimateSDUpscale` exige `batch_size` (input requerido en `/object_info`);
|
||||||
|
se añade `batch_size: 1` al nodo inyectado para que el workflow no falle en runtime.
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ def comfyui_inject_hires_fix(
|
|||||||
"seam_fix_padding": 16,
|
"seam_fix_padding": 16,
|
||||||
"force_uniform_tiles": True,
|
"force_uniform_tiles": True,
|
||||||
"tiled_decode": False,
|
"tiled_decode": False,
|
||||||
|
"batch_size": 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,15 @@ def test_base_ksampler_and_ultimate_upscale_present():
|
|||||||
assert wf["9"]["inputs"]["images"] == ["12", 0]
|
assert wf["9"]["inputs"]["images"] == ["12", 0]
|
||||||
|
|
||||||
|
|
||||||
|
def test_ultimate_upscale_provee_batch_size():
|
||||||
|
# /object_info marca batch_size como input REQUERIDO de UltimateSDUpscale.
|
||||||
|
# Sin el, el submit fallaba con node_errors. Regresion guard.
|
||||||
|
wf = comfyui_build_hires_fix_workflow(
|
||||||
|
ckpt_name="dreamshaper_8.safetensors", positive="x",
|
||||||
|
)
|
||||||
|
assert wf["12"]["inputs"]["batch_size"] == 1
|
||||||
|
|
||||||
|
|
||||||
def test_second_pass_denoise_is_partial():
|
def test_second_pass_denoise_is_partial():
|
||||||
wf = comfyui_build_hires_fix_workflow(
|
wf = comfyui_build_hires_fix_workflow(
|
||||||
ckpt_name="dreamshaper_8.safetensors", positive="x", denoise=0.4,
|
ckpt_name="dreamshaper_8.safetensors", positive="x", denoise=0.4,
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ def test_params_reflejados():
|
|||||||
assert up_in["mode_type"] == "Linear"
|
assert up_in["mode_type"] == "Linear"
|
||||||
assert up_in["force_uniform_tiles"] is True
|
assert up_in["force_uniform_tiles"] is True
|
||||||
assert up_in["tiled_decode"] is False
|
assert up_in["tiled_decode"] is False
|
||||||
|
# /object_info marca batch_size como input REQUERIDO de UltimateSDUpscale.
|
||||||
|
# Sin el, el submit fallaba con node_errors. Regresion guard.
|
||||||
|
assert up_in["batch_size"] == 1
|
||||||
|
|
||||||
|
|
||||||
def test_lanza_valueerror_sin_vaedecode():
|
def test_lanza_valueerror_sin_vaedecode():
|
||||||
|
|||||||
Reference in New Issue
Block a user