feat(ml): auto-commit con 7 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
---
|
||||
name: comfyui_stream_progress
|
||||
kind: function
|
||||
lang: py
|
||||
domain: ml
|
||||
version: "1.1.0"
|
||||
purity: impure
|
||||
signature: "def comfyui_stream_progress(prompt_id: str, *, server: str = \"127.0.0.1:8188\", client_id: str | None = None, timeout: float = 300.0) -> dict"
|
||||
description: "Sigue en vivo el progreso de un prompt ComfyUI por WebSocket ws://<server>/ws?clientId= (eventos progress paso/total, executing por nodo, execution_success/execution_error) en vez de hacer polling. Alternativa en-vivo a comfyui_wait_result. Si websocket-client NO esta en el interprete que ejecuta (el venv del registry no lo trae; el de ComfyUI si), cae limpiamente a polling de /history reutilizando comfyui_wait_result y marca method='polling'. Devuelve {ok, completed, steps_seen, last_node, method, error}. Impura: WebSocket o HTTP."
|
||||
tags: [comfyui, ml, progress, websocket, stream, http]
|
||||
uses_functions: [comfyui_wait_result_py_ml]
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: []
|
||||
params:
|
||||
- name: prompt_id
|
||||
desc: "id devuelto por comfyui_submit_workflow, el prompt cuyo progreso seguir."
|
||||
- name: server
|
||||
desc: "host:port del servidor ComfyUI sin esquema (default '127.0.0.1:8188')."
|
||||
- name: client_id
|
||||
desc: "clientId para registrar el socket; si None se genera un uuid4 hex."
|
||||
- name: timeout
|
||||
desc: "maximo de segundos a esperar a que el prompt complete (default 300)."
|
||||
output: "dict con ok (bool), completed (bool, True si el prompt termino), steps_seen (int, mensajes 'progress' vistos por WS; 0 en fallback de polling), last_node (str, ultimo nodo en ejecucion visto), method (str, 'websocket' o 'polling'), error (str, vacio si OK)."
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/ml/comfyui_stream_progress.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
import sys, os, uuid
|
||||
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
|
||||
from ml.comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow
|
||||
from ml.comfyui_submit_workflow import comfyui_submit_workflow
|
||||
from ml.comfyui_stream_progress import comfyui_stream_progress
|
||||
|
||||
cid = uuid.uuid4().hex # MISMO clientId en submit y en stream para ver progress en vivo
|
||||
wf = comfyui_build_txt2img_workflow(
|
||||
ckpt_name="dreamshaper_8.safetensors",
|
||||
positive="an ornate brass clockwork dragon", steps=25, seed=424242)
|
||||
pid = comfyui_submit_workflow(wf, client_id=cid)["prompt_id"]
|
||||
|
||||
res = comfyui_stream_progress(pid, client_id=cid, timeout=300)
|
||||
# {'ok': True, 'completed': True, 'steps_seen': 13, 'last_node': '9',
|
||||
# 'method': 'websocket', 'error': ''}
|
||||
```
|
||||
|
||||
Si NO compartes el `client_id`, el seguimiento sigue funcionando (detecta el fin por
|
||||
`/history`) pero `steps_seen` sale 0: ComfyUI envia los eventos `progress` al socket
|
||||
del `clientId` que encolo el prompt, no a otro.
|
||||
|
||||
Para WebSocket real hay que ejecutarlo con un interprete que tenga `websocket-client`
|
||||
(el venv de ComfyUI lo trae). Con el venv del registry (`./fn run`) cae a polling
|
||||
automaticamente y devuelve `method='polling'`.
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando quieres feedback en vivo de una generacion larga (hires-fix, vídeo, 3D
|
||||
multi-vista) en lugar de esperar a ciegas con `comfyui_wait_result`: ver por que
|
||||
nodo va el grafo (`last_node`) y cuantos pasos de sampler han pasado
|
||||
(`steps_seen`). Util para barras de progreso o para detectar un cuelgue (si
|
||||
`steps_seen` no avanza). Para el caso simple "solo dime cuando esta listo",
|
||||
`comfyui_wait_result` (polling) basta y es mas portable.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- `websocket-client` NO esta en el venv del registry, asi que `./fn run
|
||||
comfyui_stream_progress <pid>` cae a polling (`method='polling'`, `steps_seen=0`).
|
||||
Para el WebSocket real, ejecutalo con el python de ComfyUI (que si lo trae). El
|
||||
fallback es transparente: mismo dict de retorno.
|
||||
- `steps_seen` cuenta mensajes `progress` del WS, no el "step N/total" exacto del
|
||||
sampler; sirve como senal de avance, no como porcentaje preciso. En trabajos con
|
||||
nodos cacheados (que completan en <1s) puede salir 0 con `completed=True`: no hubo
|
||||
pasos que emitir, el fin se detecto por el chequeo de `/history`.
|
||||
- **Carrera submit/WS (v1.1.0):** un prompt rapido o cacheado puede terminar antes de
|
||||
que el WS reciba su `execution_success`. La funcion se defiende: comprueba `/history`
|
||||
al entrar (si ya termino, retorna ya) y en cada ventana de recv sin eventos (detecta
|
||||
el fin sin esperar al timeout). Por eso NO se cuelga 300s en trabajos veloces.
|
||||
- **`client_id` debe coincidir con el del submit para ver `progress`.** ComfyUI
|
||||
enruta los eventos `progress`/`executing` al socket cuyo `clientId` encolo el
|
||||
prompt (`send_sync(..., sid=client_id)`). Si llamas a esta funcion con un
|
||||
`client_id` distinto (o None, que genera uno nuevo) NO recibiras esos eventos de
|
||||
ese prompt y `steps_seen` saldra 0 — aunque `completed` se detecta igual por el
|
||||
chequeo de `/history`. Para barra de progreso real: genera un `cid`, pasalo a
|
||||
`comfyui_submit_workflow(..., client_id=cid)` Y a esta funcion.
|
||||
- En fallo de conexion del WS degrada al fallback de polling en vez de lanzar; si
|
||||
tambien falla el polling, devuelve `ok=False` con el motivo en `error`.
|
||||
- Los frames binarios del WS (previews de imagen en vivo) se ignoran; esta funcion
|
||||
solo sigue el progreso, no descarga la imagen (para eso, `comfyui_fetch_output_image`).
|
||||
|
||||
## Capability growth log
|
||||
|
||||
- v1.1.0 (24/06/2026) — robustez ante la carrera submit/WS: pre-check de `/history` al
|
||||
entrar + re-check de `/history` en cada ventana de recv sin eventos y al agotar el
|
||||
timeout. Evita el cuelgue hasta timeout cuando un trabajo cacheado/rapido completa
|
||||
antes de que el WS reciba `execution_success`. Smoke previo lo destapo (prompt
|
||||
cacheado completaba en ~0.7s y la v1.0.0 esperaba 180s en vano).
|
||||
Reference in New Issue
Block a user