3838from comfy_execution .graph_utils import GraphBuilder , is_link
3939from comfy_execution .validation import validate_node_input
4040from comfy_execution .progress import get_progress_state , reset_progress_state , add_progress_handler , WebUIProgressHandler
41+ from comfy_execution .jobs import extract_workflow_id
4142from comfy_execution .utils import CurrentNodeContext
4243from comfy_api .internal import _ComfyNodeInternal , _NodeOutputInternal , first_real_override , is_class , make_locked_method_func
4344from comfy_api .latest import io , _io
@@ -417,15 +418,15 @@ def _is_intermediate_output(dynprompt, node_id):
417418 class_def = nodes .NODE_CLASS_MAPPINGS [class_type ]
418419 return getattr (class_def , 'HAS_INTERMEDIATE_OUTPUT' , False )
419420
420- def _send_cached_ui (server , node_id , display_node_id , cached , prompt_id , ui_outputs ):
421+ def _send_cached_ui (server , node_id , display_node_id , cached , prompt_id , workflow_id , ui_outputs ):
421422 if server .client_id is None :
422423 return
423424 cached_ui = cached .ui or {}
424- server .send_sync ("executed" , { "node" : node_id , "display_node" : display_node_id , "output" : cached_ui .get ("output" , None ), "prompt_id" : prompt_id }, server .client_id )
425+ server .send_sync ("executed" , { "node" : node_id , "display_node" : display_node_id , "output" : cached_ui .get ("output" , None ), "prompt_id" : prompt_id , "workflow_id" : workflow_id }, server .client_id )
425426 if cached .ui is not None :
426427 ui_outputs [node_id ] = cached .ui
427428
428- async def execute (server , dynprompt , caches , current_item , extra_data , executed , prompt_id , execution_list , pending_subgraph_results , pending_async_nodes , ui_outputs ):
429+ async def execute (server , dynprompt , caches , current_item , extra_data , executed , prompt_id , workflow_id , execution_list , pending_subgraph_results , pending_async_nodes , ui_outputs ):
429430 unique_id = current_item
430431 real_node_id = dynprompt .get_real_node_id (unique_id )
431432 display_node_id = dynprompt .get_display_node_id (unique_id )
@@ -435,7 +436,7 @@ async def execute(server, dynprompt, caches, current_item, extra_data, executed,
435436 class_def = nodes .NODE_CLASS_MAPPINGS [class_type ]
436437 cached = await caches .outputs .get (unique_id )
437438 if cached is not None :
438- _send_cached_ui (server , unique_id , display_node_id , cached , prompt_id , ui_outputs )
439+ _send_cached_ui (server , unique_id , display_node_id , cached , prompt_id , workflow_id , ui_outputs )
439440 get_progress_state ().finish_progress (unique_id )
440441 execution_list .cache_update (unique_id , cached )
441442 return (ExecutionResult .SUCCESS , None , None )
@@ -483,7 +484,7 @@ async def execute(server, dynprompt, caches, current_item, extra_data, executed,
483484 input_data_all , missing_keys , v3_data = get_input_data (inputs , class_def , unique_id , execution_list , dynprompt , extra_data )
484485 if server .client_id is not None :
485486 server .last_node_id = display_node_id
486- server .send_sync ("executing" , { "node" : unique_id , "display_node" : display_node_id , "prompt_id" : prompt_id }, server .client_id )
487+ server .send_sync ("executing" , { "node" : unique_id , "display_node" : display_node_id , "prompt_id" : prompt_id , "workflow_id" : workflow_id }, server .client_id )
487488
488489 obj = await caches .objects .get (unique_id )
489490 if obj is None :
@@ -513,6 +514,7 @@ def execution_block_cb(block):
513514 if block .message is not None :
514515 mes = {
515516 "prompt_id" : prompt_id ,
517+ "workflow_id" : workflow_id ,
516518 "node_id" : unique_id ,
517519 "node_type" : class_type ,
518520 "executed" : list (executed ),
@@ -561,7 +563,7 @@ async def await_completion():
561563 "output" : output_ui
562564 }
563565 if server .client_id is not None :
564- server .send_sync ("executed" , { "node" : unique_id , "display_node" : display_node_id , "output" : output_ui , "prompt_id" : prompt_id }, server .client_id )
566+ server .send_sync ("executed" , { "node" : unique_id , "display_node" : display_node_id , "output" : output_ui , "prompt_id" : prompt_id , "workflow_id" : workflow_id }, server .client_id )
565567 if has_subgraph :
566568 cached_outputs = []
567569 new_node_ids = []
@@ -658,6 +660,7 @@ def reset(self):
658660 self .caches = CacheSet (cache_type = self .cache_type , cache_args = self .cache_args )
659661 self .status_messages = []
660662 self .success = True
663+ self .workflow_id = None
661664
662665 def add_message (self , event , data : dict , broadcast : bool ):
663666 data = {
@@ -677,6 +680,7 @@ def handle_execution_error(self, prompt_id, prompt, current_outputs, executed, e
677680 if isinstance (ex , comfy .model_management .InterruptProcessingException ):
678681 mes = {
679682 "prompt_id" : prompt_id ,
683+ "workflow_id" : self .workflow_id ,
680684 "node_id" : node_id ,
681685 "node_type" : class_type ,
682686 "executed" : list (executed ),
@@ -685,6 +689,7 @@ def handle_execution_error(self, prompt_id, prompt, current_outputs, executed, e
685689 else :
686690 mes = {
687691 "prompt_id" : prompt_id ,
692+ "workflow_id" : self .workflow_id ,
688693 "node_id" : node_id ,
689694 "node_type" : class_type ,
690695 "executed" : list (executed ),
@@ -723,7 +728,9 @@ async def execute_async(self, prompt, prompt_id, extra_data={}, execute_outputs=
723728 self .server .client_id = None
724729
725730 self .status_messages = []
726- self .add_message ("execution_start" , { "prompt_id" : prompt_id }, broadcast = False )
731+ self .workflow_id = extract_workflow_id (extra_data )
732+ self .server .last_workflow_id = self .workflow_id
733+ self .add_message ("execution_start" , { "prompt_id" : prompt_id , "workflow_id" : self .workflow_id }, broadcast = False )
727734
728735 self ._notify_prompt_lifecycle ("start" , prompt_id )
729736 ram_headroom = int (self .cache_args ["ram" ] * (1024 ** 3 ))
@@ -733,7 +740,7 @@ async def execute_async(self, prompt, prompt_id, extra_data={}, execute_outputs=
733740 try :
734741 with torch .inference_mode ():
735742 dynamic_prompt = DynamicPrompt (prompt )
736- reset_progress_state (prompt_id , dynamic_prompt )
743+ reset_progress_state (prompt_id , dynamic_prompt , self . workflow_id )
737744 add_progress_handler (WebUIProgressHandler (self .server ))
738745 is_changed_cache = IsChangedCache (prompt_id , dynamic_prompt , self .caches .outputs )
739746 for cache in self .caches .all :
@@ -751,7 +758,7 @@ async def execute_async(self, prompt, prompt_id, extra_data={}, execute_outputs=
751758
752759 comfy .model_management .cleanup_models_gc ()
753760 self .add_message ("execution_cached" ,
754- { "nodes" : cached_nodes , "prompt_id" : prompt_id },
761+ { "nodes" : cached_nodes , "prompt_id" : prompt_id , "workflow_id" : self . workflow_id },
755762 broadcast = False )
756763 pending_subgraph_results = {}
757764 pending_async_nodes = {} # TODO - Unify this with pending_subgraph_results
@@ -769,7 +776,7 @@ async def execute_async(self, prompt, prompt_id, extra_data={}, execute_outputs=
769776 break
770777
771778 assert node_id is not None , "Node ID should not be None at this point"
772- result , error , ex = await execute (self .server , dynamic_prompt , self .caches , node_id , extra_data , executed , prompt_id , execution_list , pending_subgraph_results , pending_async_nodes , ui_node_outputs )
779+ result , error , ex = await execute (self .server , dynamic_prompt , self .caches , node_id , extra_data , executed , prompt_id , self . workflow_id , execution_list , pending_subgraph_results , pending_async_nodes , ui_node_outputs )
773780 self .success = result != ExecutionResult .FAILURE
774781 if result == ExecutionResult .FAILURE :
775782 self .handle_execution_error (prompt_id , dynamic_prompt .original_prompt , current_outputs , executed , error , ex )
@@ -793,8 +800,8 @@ async def execute_async(self, prompt, prompt_id, extra_data={}, execute_outputs=
793800 cached = await self .caches .outputs .get (node_id )
794801 if cached is not None :
795802 display_node_id = dynamic_prompt .get_display_node_id (node_id )
796- _send_cached_ui (self .server , node_id , display_node_id , cached , prompt_id , ui_node_outputs )
797- self .add_message ("execution_success" , { "prompt_id" : prompt_id }, broadcast = False )
803+ _send_cached_ui (self .server , node_id , display_node_id , cached , prompt_id , self . workflow_id , ui_node_outputs )
804+ self .add_message ("execution_success" , { "prompt_id" : prompt_id , "workflow_id" : self . workflow_id }, broadcast = False )
798805
799806 ui_outputs = {}
800807 meta_outputs = {}
@@ -811,6 +818,8 @@ async def execute_async(self, prompt, prompt_id, extra_data={}, execute_outputs=
811818 finally :
812819 comfy .memory_management .set_ram_cache_release_state (None , 0 )
813820 self ._notify_prompt_lifecycle ("end" , prompt_id )
821+ self .server .last_workflow_id = None
822+ self .workflow_id = None
814823
815824
816825async def validate_inputs (prompt_id , prompt , item , validated , visiting = None ):
0 commit comments