Files
fn_registry/python/functions/ml/comfyui_bump_skill_version.md
T
egutierrez bcf731275e feat(ml): cierre del bucle de mejora comfyui-skill (genera→juzga→bump)
Tres funciones nuevas que cierran el lazo skill→generación→juicio→promoción
del grupo comfyui-skill (issue 0087):

- comfyui_bump_skill_version (impura): promueve una versión nueva SOLO si el
  score del panel-juez sube (gate objetivo). Snapshot versions/vN.json
  pre-mutación, deep-merge de recipe_patch, semver↑, línea en growth_log.jsonl.
  force=True salta el gate. No usa datetime.now().
- comfyui_update_skill_score (impura): media incremental de score_mean/score_n
  reescribiendo recipe.json in-place (sin snapshot ni growth_log).
- comfyui_generate_with_skill_oneshot (pipeline): one-shot load→build→submit→
  wait→fetch→judge→score_mean. recipe_patch prueba variantes sin guardar score.
  Compone 7 funciones del registry.

Tests offline: 11 passed (gate, semver, deep-merge, media incremental, errores).
Página madre docs/capabilities/comfyui-skill.md: +3 funciones, sección "Bucle de
mejora" con diagrama, fronteras de scoring actualizadas.

Demo real verificada: skill seed portrait_cinematic_sd15 (SD1.5) generó imagen
SFW real, el panel la juzgó, una variante puntuó más alto (4.787 > 4.7276) y el
gate promovió v1.0.0→v1.1.0 con el judge_run_id como evidencia.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 15:09:33 +02:00

5.3 KiB

name, kind, lang, domain, version, purity, signature, description, error_type, tags, uses_functions, uses_types, returns, returns_optional, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description error_type tags uses_functions uses_types returns returns_optional imports params output tested tests test_file_path file_path
comfyui_bump_skill_version function py ml 1.0.0 impure def comfyui_bump_skill_version(slug: str, change: str, *, score_before: float, score_after: float, judge_run_id: str = None, recipe_patch: dict = None, force: bool = False, bump: str = "minor", library_dir: str = None, timestamp: float = None) -> dict Promueve una version nueva de una skill ComfyUI SOLO si el score sube (gate objetivo del bucle de mejora, grupo comfyui-skill). Si score_after <= score_before y no force, rechaza con ok=False sin tocar nada. Si pasa: snapshot pre-mutacion versions/vN.json, aplica recipe_patch (deep-merge) a recipe.json, sube el semver (minor default), y appende a growth_log.jsonl una linea {version,date,change,score_before,score_after,judge_run_id,diff}. library_dir default ~/ComfyUI/skills_library. Slug inexistente -> ok=False. No usa datetime.now (deriva la fecha del timestamp recibido o time.time). Impura: disco. Nunca lanza. error_py_core
comfyui
comfyui-skill
ml
skill
versioning
growth
false
name desc
slug Slug de la skill (su carpeta en la libreria).
name desc
change Descripcion de una linea del cambio que motiva el bump (va al growth_log).
name desc
score_before Score 0-10 de la version actual (del panel comfyui-judge). keyword-only.
name desc
score_after Score 0-10 de la variante candidata. Debe ser > score_before salvo force=True. keyword-only.
name desc
judge_run_id Identificador de la corrida del juez que justifica el bump (evidencia trazable). keyword-only.
name desc
recipe_patch Dict con los cambios a aplicar sobre la receta (deep-merge). Ej. {'params': {'steps': 32}}. keyword-only.
name desc
force Si True, salta el gate y promueve aunque el score no mejore. keyword-only.
name desc
bump Parte del semver a subir: 'minor' (default), 'major' o 'patch'. keyword-only.
name desc
library_dir Raiz de la libreria. Default ~/ComfyUI/skills_library. keyword-only.
name desc
timestamp Epoch en segundos para la fecha del growth_log; None = time.time(). keyword-only.
dict {ok, slug, old_version, new_version, snapshot_file, growth_entry, recipe_path, error}. ok=False con error si el gate rechaza el bump, si la skill no existe, o si falla la escritura; nunca lanza. true
test_semver_helper
test_deep_merge_no_pisa_otras_claves
test_golden_promueve_cuando_score_sube
test_edge_major_y_patch
test_error_gate_bloquea_si_no_mejora
test_error_force_salta_gate
test_error_skill_inexistente
python/functions/ml/tests/test_comfyui_bump_skill_version.py python/functions/ml/comfyui_bump_skill_version.py

comfyui_bump_skill_version

Pieza de cierre del bucle de mejora del grupo comfyui-skill: una skill genera, el panel comfyui-judge la puntúa, y esta función promueve una versión nueva solo si el score sube. El juez decide, no el humano. Es el "crecimiento por composición" del issue 0087 aplicado a la generación de imágenes.

Ejemplo

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

# La variante con steps=32 puntuó 7.4 vs 6.5 de la versión vigente → se promueve.
res = comfyui_bump_skill_version(
    "portrait_cinematic_sd15", "subir steps 28→32 (mejor detalle facial)",
    score_before=6.5, score_after=7.4,
    judge_run_id="judge_abc123", recipe_patch={"params": {"steps": 32}},
)
print(res["old_version"], "→", res["new_version"])   # 1.0.0 → 1.1.0
# recipe.json ahora en 1.1.0 con steps=32; versions/vN.json conserva la 1.0.0;
# growth_log.jsonl tiene una línea con score_before/after + judge_run_id.

Cuando usarla

Tras juzgar una variante de una skill: si el score del panel supera al de la versión vigente, llama a esta función para promover la mejora (snapshot + semver + growth_log). Si el score no sube, NO la llames (o se rechaza por el gate) — esa es justo la garantía del bucle. Pásale el judge_run_id de comfyui_generate_with_skill_oneshot como evidencia trazable.

Gotchas

  • Gate duro: score_after <= score_before sin force=True devuelve {ok:False} y NO toca nada (ni snapshot, ni growth_log, ni versión). Es el comportamiento deseado, no un error.
  • force=True salta el gate (promueve aunque empeore) y marca growth_entry.forced=True. Úsalo solo para correcciones manuales, no en el bucle automático.
  • recipe_patch es deep-merge: dicts anidados (params) se fusionan; listas (loras, blocks) se reemplazan enteras (no se concatenan).
  • Snapshot pre-mutación: versions/vN.json guarda la receta ANTES del patch; el recipe.json queda con la versión nueva. Recupera la vieja con comfyui_load_skill(slug, version=N).
  • Fecha sin datetime.now(): se deriva de timestamp o time.time() vía time.strftime (compatible con entornos que prohíben datetime.now()).
  • No genera ni juzga: solo promueve la receta. Generar + puntuar es trabajo de comfyui_generate_with_skill_oneshot + comfyui_judge_image.