---
name: comfyui_generate_with_skill_oneshot
kind: pipeline
lang: py
domain: pipelines
version: "1.0.0"
purity: impure
signature: "def comfyui_generate_with_skill_oneshot(slug: str, subject: str, *, server: str = \"127.0.0.1:8188\", dest: str | None = None, seed: int = 0, judge: bool = True, recipe_patch: dict | None = None, library_dir: str | None = None, wait_timeout: float = 600.0) -> dict"
description: "Pipeline skill + subject -> PNG juzgado en una sola llamada. Carga la receta de la skill, la compila para el subject (build_skill_workflow), encola, espera, descarga el PNG y si judge=True lo puntua con el panel comfyui-judge, acumulando el score en la media de la skill (salvo que se pase recipe_patch, que prueba una variante en memoria sin guardar score). Cierra el bucle de generacion->juicio del grupo comfyui-skill (issue 0087). Compone comfyui_load_skill + comfyui_build_skill_workflow + comfyui_submit_workflow + comfyui_wait_result + comfyui_fetch_output_image + comfyui_judge_image + comfyui_update_skill_score. Impuro: HTTP + disco + API Anthropic."
tags: [comfyui, comfyui-skill, pipelines, txt2img, judge, launcher]
uses_functions: [comfyui_load_skill_py_ml, comfyui_build_skill_workflow_py_ml, comfyui_submit_workflow_py_ml, comfyui_wait_result_py_ml, comfyui_fetch_output_image_py_ml, comfyui_judge_image_py_ml, comfyui_update_skill_score_py_ml]
uses_types: []
returns: []
returns_optional: false
error_type: error_py_core
imports: [comfyui_load_skill_py_ml, comfyui_build_skill_workflow_py_ml, comfyui_submit_workflow_py_ml, comfyui_wait_result_py_ml, comfyui_fetch_output_image_py_ml, comfyui_judge_image_py_ml, comfyui_update_skill_score_py_ml]
params:
  - name: slug
    desc: "Slug de la skill a usar (su carpeta en la libreria)."
  - name: subject
    desc: "Sujeto concreto que sustituye {subject} en el scaffold del prompt (p.ej. 'a woman with red hair')."
  - name: server
    desc: "host:port del servidor ComfyUI (sin esquema). keyword-only."
  - name: dest
    desc: "Directorio local donde guardar el PNG (None = cwd). keyword-only."
  - name: seed
    desc: "Semilla de generacion. keyword-only."
  - name: judge
    desc: "Si True, puntua el PNG con el panel comfyui-judge y acumula el score en la skill (salvo recipe_patch). keyword-only."
  - name: recipe_patch
    desc: "Dict de cambios aplicados a la receta EN MEMORIA antes de compilar (deep-merge), para probar una variante sin guardarla; con patch el score NO se acumula. keyword-only."
  - name: library_dir
    desc: "Raiz de la libreria. Default ~/ComfyUI/skills_library. keyword-only."
  - name: wait_timeout
    desc: "Segundos maximos esperando al servidor. keyword-only."
output: "dict {ok, slug, prompt_id, image_path, prompt_resolved, judge, judge_run_id, score_mean, score_n, error}. judge = {verdict, score, votes} o None. judge_run_id correlaciona el juicio (evidencia para comfyui_bump_skill_version). Si falla, ok=False y error explica el paso."
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/pipelines/comfyui_generate_with_skill_oneshot.py"
---

# comfyui_generate_with_skill_oneshot

One-shot del bucle de mejora del grupo [`comfyui-skill`](../../../docs/capabilities/comfyui-skill.md):
de una skill guardada a un PNG **ya puntuado** por el panel
[`comfyui-judge`](../../../docs/capabilities/comfyui-judge.md), en una llamada. Promoción de la
secuencia repetida `load → build → submit → wait → fetch → judge` (issue 0087).

## Ejemplo

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

# Genera + juzga con la receta canónica (acumula score_mean):
res = comfyui_generate_with_skill_oneshot(
    "portrait_cinematic_sd15", "a woman with red hair",
    dest="/tmp/comfy_skill", seed=42, judge=True,
)
print(res["image_path"], res["judge"]["verdict"], res["judge"]["score"], res["score_mean"])

# Probar una variante sin guardar (no toca score_mean); su judge_run_id sirve de evidencia
# para promoverla con comfyui_bump_skill_version si supera a la canónica:
var = comfyui_generate_with_skill_oneshot(
    "portrait_cinematic_sd15", "a woman with red hair",
    seed=42, recipe_patch={"params": {"steps": 32}},
)
print(var["judge"]["score"], var["judge_run_id"])
```

## Cuando usarla

Cuando quieras generar una imagen a partir de una skill ya guardada y saber al instante si es
buena (veredicto del panel). Para el **bucle de mejora**: genera la canónica, luego genera una
variante con `recipe_patch`, compara `judge.score`, y si la variante gana llama a
`comfyui_bump_skill_version` con su `judge_run_id`.

## Gotchas

- **Cuesta API**: con `judge=True` invoca el panel multi-juez (incluye 1 llamada LLM-vision a
  Anthropic). Pásalo a `judge=False` para generar sin puntuar.
- **`recipe_patch` no persiste**: aplica la variante solo en memoria y NO acumula su score en la
  skill (es una prueba). Promueve la variante explícitamente con `comfyui_bump_skill_version`.
- **Server vivo requerido**: necesita ComfyUI en `server` con el checkpoint/LoRAs/detector de la
  receta instalados. `build_skill_workflow` es puro y no valida contra el servidor.
- **`wait_timeout` amplio (600s)**: cubre jobs con facedetailer/hires. Imágenes simples retornan en
  cuanto los outputs están listos.
- **Juez caído ≠ fallo fatal**: si el panel entero falla, la imagen ya está en disco; el resultado
  vuelve con `ok=True`, `judge=None` y `error` anotado.
- **OOM en 8GB**: si el server va corto de VRAM, usa una skill SD1.5 (`IMG_dreamshaper_8`) a resolución
  modesta; el error de OOM se propaga en `{ok:False, error}` sin reiniciar el server.
