From 1c7e656eb4e1d37c3f67af015f616f24acedc616 Mon Sep 17 00:00:00 2001 From: bymyself Date: Thu, 19 Feb 2026 23:35:24 -0800 Subject: [PATCH] Add prompt_id to progress_text binary WS messages Add supports_progress_text_metadata feature flag and extend send_progress_text() to accept optional prompt_id param. When prompt_id is provided and the client supports the new format, the binary wire format includes a length-prefixed prompt_id field: [4B event_type][4B prompt_id_len][prompt_id][4B node_id_len][node_id][text] Legacy format preserved for clients without the flag. Both callers (nodes_images.py, client.py) updated to pass prompt_id from get_executing_context(). Part of COM-12671: parallel workflow execution support. Amp-Thread-ID: https://ampcode.com/threads/T-019c79f7-f19b-70d9-b662-0687cc206282 --- comfy_api/feature_flags.py | 1 + comfy_api_nodes/util/client.py | 5 ++++- comfy_extras/nodes_images.py | 5 ++++- server.py | 23 ++++++++++++++++++++--- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/comfy_api/feature_flags.py b/comfy_api/feature_flags.py index a90a5ca40..c3c804c96 100644 --- a/comfy_api/feature_flags.py +++ b/comfy_api/feature_flags.py @@ -12,6 +12,7 @@ from comfy.cli_args import args # Default server capabilities SERVER_FEATURE_FLAGS: dict[str, Any] = { "supports_preview_metadata": True, + "supports_progress_text_metadata": True, "max_upload_size": args.max_upload_size * 1024 * 1024, # Convert MB to bytes "extension": {"manager": {"supports_v4": True}}, "node_replacements": True, diff --git a/comfy_api_nodes/util/client.py b/comfy_api_nodes/util/client.py index 94886af7b..d0ec6e026 100644 --- a/comfy_api_nodes/util/client.py +++ b/comfy_api_nodes/util/client.py @@ -17,6 +17,7 @@ from pydantic import BaseModel from comfy import utils from comfy_api.latest import IO +from comfy_execution.utils import get_executing_context from server import PromptServer from . import request_logger @@ -446,7 +447,9 @@ def _display_text( if text is not None: display_lines.append(text) if display_lines: - PromptServer.instance.send_progress_text("\n".join(display_lines), get_node_id(node_cls)) + ctx = get_executing_context() + prompt_id = ctx.prompt_id if ctx is not None else None + PromptServer.instance.send_progress_text("\n".join(display_lines), get_node_id(node_cls), prompt_id=prompt_id) def _display_time_progress( diff --git a/comfy_extras/nodes_images.py b/comfy_extras/nodes_images.py index 727d7d09d..30aee6229 100644 --- a/comfy_extras/nodes_images.py +++ b/comfy_extras/nodes_images.py @@ -577,7 +577,10 @@ class GetImageSize(IO.ComfyNode): # Send progress text to display size on the node if cls.hidden.unique_id: - PromptServer.instance.send_progress_text(f"width: {width}, height: {height}\n batch size: {batch_size}", cls.hidden.unique_id) + from comfy_execution.utils import get_executing_context + ctx = get_executing_context() + prompt_id = ctx.prompt_id if ctx is not None else None + PromptServer.instance.send_progress_text(f"width: {width}, height: {height}\n batch size: {batch_size}", cls.hidden.unique_id, prompt_id=prompt_id) return IO.NodeOutput(width, height, batch_size) diff --git a/server.py b/server.py index 275bce5a7..2e9bacbf6 100644 --- a/server.py +++ b/server.py @@ -1233,13 +1233,30 @@ class PromptServer(): return json_data def send_progress_text( - self, text: Union[bytes, bytearray, str], node_id: str, sid=None + self, text: Union[bytes, bytearray, str], node_id: str, prompt_id: Optional[str] = None, sid=None ): if isinstance(text, str): text = text.encode("utf-8") node_id_bytes = str(node_id).encode("utf-8") - # Pack the node_id length as a 4-byte unsigned integer, followed by the node_id bytes - message = struct.pack(">I", len(node_id_bytes)) + node_id_bytes + text + # When prompt_id is provided and client supports the new format, + # prepend prompt_id as a length-prefixed field before node_id + target_sid = sid if sid is not None else self.client_id + if prompt_id and feature_flags.supports_feature( + self.sockets_metadata, target_sid, "supports_progress_text_metadata" + ): + prompt_id_bytes = prompt_id.encode("utf-8") + # Pack prompt_id length as a 4-byte unsigned integer, followed by prompt_id bytes, + # then node_id length as a 4-byte unsigned integer, followed by node_id bytes, then text + message = ( + struct.pack(">I", len(prompt_id_bytes)) + + prompt_id_bytes + + struct.pack(">I", len(node_id_bytes)) + + node_id_bytes + + text + ) + else: + # Pack the node_id length as a 4-byte unsigned integer, followed by the node_id bytes + message = struct.pack(">I", len(node_id_bytes)) + node_id_bytes + text self.send_sync(BinaryEventTypes.TEXT, message, sid)