---
name: comfyui_replicate_civitai_oneshot
kind: pipeline
lang: py
domain: pipelines
version: "1.0.0"
purity: impure
signature: "def comfyui_replicate_civitai_oneshot(url_or_id, *, server: str = \"127.0.0.1:8188\", dest: str | None = None, judge: bool = True, token: str | None = None, wait_timeout: float = 600.0) -> dict"
description: "Replica una imagen de Civitai en una sola llamada: te paso un link y entra, observa como lo hicieron, construye un workflow que lo replique, lo genera y lo juzga. Acepta civitai.com/images/<id>, su id numerico, un modelVersionId (replica su primera imagen SFW) o directamente una URL/ruta/dict de un workflow ComfyUI (PNG embebido, .json, API format). Pasos: fetch_civitai_image_meta (observa receta) -> map_a1111_params (traduce a ComfyUI) -> workflow embebido tal cual O reconstruido con build_txt2img + inject_lora sustituyendo el checkpoint original por el mas parecido INSTALADO de la misma familia y descartando los LoRAs ausentes -> run_foreign_workflow_oneshot (resolve+submit+wait+fetch) -> judge_image. NO baja modelos a ciegas (los reporta en missing_models con la sustitucion). Respeta SFW: una imagen NSFW devuelve ok=False sin generar. Pipeline impuro: HTTP + disco + subprocess."
tags: [comfyui, civitai, replicate, pipeline, oneshot, ml, image, stable-diffusion]
uses_functions:
  - comfyui_fetch_civitai_image_meta_py_ml
  - comfyui_map_a1111_params_py_ml
  - comfyui_object_info_py_ml
  - comfyui_build_txt2img_workflow_py_ml
  - comfyui_inject_lora_py_ml
  - comfyui_search_civitai_images_py_ml
  - comfyui_run_foreign_workflow_oneshot_py_pipelines
  - comfyui_judge_image_py_ml
uses_types: []
returns: []
returns_optional: false
error_type: error_go_core
imports: []
params:
  - name: url_or_id
    desc: "Link/URL de una imagen Civitai (civitai.com/images/<id>), su id numerico (int o str), un modelVersionId (se replica su primera imagen SFW), o directamente una URL/ruta/dict de un workflow ComfyUI (PNG con workflow embebido, .json, o dict en API format)."
  - name: server
    desc: "host:port del servidor ComfyUI (sin esquema). keyword-only."
  - name: dest
    desc: "Directorio donde guardar la replica. None = ~/ComfyUI/civitai_replicas. keyword-only."
  - name: judge
    desc: "Si True, juzga la replica con el panel comfyui_judge_image contra el prompt extraido. keyword-only."
  - name: token
    desc: "Token Civitai (Bearer). None lo resuelve de 'pass civitai/api-token'. No hardcodear. keyword-only."
  - name: wait_timeout
    desc: "Segundos maximos esperando a que ComfyUI termine. keyword-only."
output: "dict {ok, source, replica_image_path, prompt_id, judge, missing_models, has_workflow, error}. source = receta observada {image_id, page_url, prompt, negative, model, family, sampler_name, scheduler, steps, cfg, width, height, seed, loras, process, has_workflow_embedded}. replica_image_path = ruta local de la imagen replica. missing_models = modelos que la receta pedia y no teniamos, con la sustitucion aplicada (NUNCA descargados). judge = dict del panel (None si judge=False o no se genero). has_workflow = True si se replico un workflow embebido tal cual. ok=False con error si el link es invalido/privado/sin meta, la imagen es NSFW (se respeta SFW), el server no responde, o la generacion falla."
tested: true
tests:
  - "test_classify_input_image_modelversion_workflow_error"
  - "test_pick_checkpoint_familia_y_exacto"
  - "test_find_installed_match_normalizado"
  - "test_extract_positive_from_workflow"
test_file_path: "python/functions/pipelines/comfyui_replicate_civitai_oneshot_test.py"
file_path: "python/functions/pipelines/comfyui_replicate_civitai_oneshot.py"
---

## Ejemplo

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

# Te paso un link de Civitai SFW -> entra, observa la receta, la replica y la juzga:
out = comfyui_replicate_civitai_oneshot("https://civitai.com/images/23526611")
print(out["ok"], out["replica_image_path"])
print(out["source"]["family"], out["source"]["sampler_name"])   # flux euler
print(out["missing_models"])   # [{'kind':'checkpoint','name':'FLUX','substituted_with':'IMG_juggernaut_xl_v11.safetensors',...}]
print(out["judge"]["verdict"], round(out["judge"]["score"], 2))  # bad 4.74 (parecido aproximado sin el modelo exacto)
```

## Cuando usarla

Cuando te pasen el link de una imagen de Civitai que te gusta y quieras **reproducirla en tu
ComfyUI**: extrae cómo se hizo y genera una versión equivalente con lo que tienes instalado,
sin reconstruir el workflow a mano. También sirve para ejecutar un workflow ComfyUI ajeno
(PNG/JSON/dict) tal cual. Es la doctrina del issue 0087 aplicada a "replicar desde un link":
observar una receta pública y reproducirla en un solo paso.

## Gotchas

- **El parecido es aproximado cuando falta el modelo exacto.** Casi nunca tendrás el mismo
  checkpoint/LoRA que Civitai: se sustituye por el más parecido instalado (misma familia) y se
  reporta en `missing_models`. Replicar un FLUX con un SDXL clava la composición pero no el
  texto/estilo fino — es esperado, no un fallo.
- **NO baja modelos a ciegas.** Lo que no tienes se reporta, no se descarga. Bajarlo es una
  decisión aparte (`comfyui_search_civitai_models` + `comfyui_download_model`).
- **SFW estricto.** Una imagen con `nsfw_level>1` devuelve `ok=False` sin generar ni descargar.
- Requiere el servidor ComfyUI vivo en `server` y al menos un checkpoint de imagen instalado.
  Los checkpoints se detectan vía `/object_info` (reflejan `extra_model_paths.yaml`), no por
  `listdir` — funciona aunque los modelos vivan fuera de `~/ComfyUI/models/`.
- El juez LLM puede caer por rate-limit (HTTP 429) si compite con otros agentes; el panel
  degrada y vota con los jueces restantes (estético + CLIP), no crashea.
- Los LoRAs de Civitai se nombran por su nombre de modelo, no por el filename instalado: el
  match es best-effort (normalizado); si no casa, el LoRA se omite y se reporta.

## Capability growth log

(v1.0.0 — versión inicial; aún no ha crecido.)
