--- name: comfyui_generate_styles_llm kind: function lang: py domain: ml version: "1.0.0" purity: impure signature: "def comfyui_generate_styles_llm(category: str, n: int = 8, prefix: str = '', avoid: list[str] | None = None, model: str = 'claude-haiku-4-5-20251001') -> dict" description: "Genera N estilos para el selector WAS de ComfyUI de una CATEGORIA tematica usando el LLM via ask_llm (grupo claude-direct, API directa de Anthropic, arranque 0). Devuelve el dict en el formato exacto {nombre: {prompt, negative_prompt}}, con prompts que son MODIFICADORES de estilo (camara, lente, iluminacion, render, medio, paleta, mood), sin descripcion de sujeto y sin el placeholder {prompt}. Robusta por diseno: extrae el primer bloque JSON de la respuesta (tolera fences markdown y prosa), valida entrada por entrada (descarta sin prompt, dedup contra avoid, rellena negative por defecto, limpia {prompt} si aparece) y ante CUALQUIER fallo (429 rate-limit, JSON corrupto, respuesta vacia, ask_llm ausente) devuelve {} en vez de lanzar — asi el caller itera categorias y sigue aunque una falle. Impura: llama a la API del LLM (red); no escribe disco." tags: [comfyui, ml, comfyui-styles, styles, was, llm, claude-direct] uses_functions: [ask_llm_py_core] uses_types: [] returns: [] returns_optional: false error_type: error_go_core imports: [] params: - name: category desc: "Tema de los estilos (texto libre que dirige el contenido), ej. 'vaporwave aesthetics', 'baroque painting', 'macro insect photography'." - name: n desc: "Numero de estilos a pedir. El modelo puede devolver menos; se validan todos. Default 8." - name: prefix desc: "Prefijo para los nombres generados (ej. 'vapor-') para agrupar y reducir colisiones con estilos existentes. Vacio = sin prefijo." - name: avoid desc: "Lista de nombres ya existentes que el modelo NO debe repetir (dedup previo). Tambien se filtran a posteriori en la validacion." - name: model desc: "Id del modelo Anthropic. Default claude-haiku-4-5-20251001 (mas cuota, rapido). Otros: claude-opus-4-8, claude-sonnet-4-6." output: "dict {nombre: {prompt, negative_prompt}} ya validado (prompt no vacio, sin {prompt}, negative rellenado). Vacio {} si el LLM falla, no hay JSON valido o no quedan entradas utilizables. NUNCA lanza: el error-path es devolver {}." tested: true tests: ["edge extract json plano", "edge extract json con fence markdown y prosa alrededor", "edge extract json corrupto/vacio -> None", "edge validate descarta no-dict, prompt vacio, duplicado en avoid; rellena negative por defecto", "edge validate limpia el placeholder {prompt}", "error ask_llm lanza (429) -> devuelve {} sin propagar", "error ask_llm ausente (None) -> {}", "golden respuesta JSON valida se parsea a dict de estilos"] test_file_path: "python/functions/ml/comfyui_generate_styles_llm_test.py" file_path: "python/functions/ml/comfyui_generate_styles_llm.py" --- ## Ejemplo ```python import sys, os sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions")) from ml.comfyui_generate_styles_llm import comfyui_generate_styles_llm from ml.comfyui_append_styles import comfyui_append_styles # Generar 8 estilos de una categoria y fusionarlos (best-effort: si el LLM falla, devuelve {}) nuevos = comfyui_generate_styles_llm("vaporwave and synthwave aesthetics", n=8, prefix="vapor-") if nuevos: comfyui_append_styles(nuevos) # merge+dedup+backup sobre el styles.json real print("generados:", len(nuevos)) ``` O por CLI: `python/.venv/bin/python3 python/functions/ml/comfyui_generate_styles_llm.py "art deco poster" 6 deco-` ## Cuando usarla Cuando quieras AMPLIAR el repositorio de estilos WAS con estilos NUEVOS de una categoria concreta que no estan en `comfyui_curated_styles_catalog`, generandolos con el LLM en el formato correcto. Encadena con `comfyui_append_styles` para escribirlos (merge+dedup). Por ser best-effort (devuelve {} ante fallo), puedes llamarla en bucle sobre varias categorias y seguir aunque alguna falle por rate-limit. Para un set grande y fiable sin depender de la red, prefiere el catalogo curado. ## Gotchas - **Rate limits**: ask_llm puede dar `HTTP 429` en rafagas. Esta funcion lo absorbe devolviendo {}; espacia las llamadas o usa el modelo haiku (default, mas cuota). No reintenta sola. - **No determinista**: el LLM puede devolver menos de `n`, nombres distintos cada vez o repetir modificadores. Pasa `avoid` con los nombres existentes para reducir colisiones; el dedup final por nombre lo cierra `comfyui_append_styles`. - **No escribe disco**: solo genera y valida. La escritura (con backup) es de `comfyui_append_styles`. - **Calidad variable**: revisa una muestra de lo generado antes de fusionar en lote grande; el catalogo curado es la fuente fiable, esto es el complemento. ## Capability growth log (v1.0.0 — sin cambios todavia.)