CodeVetter · Repo Unpack · Behavior traces
Comfy-Org/ComfyUI
Traced flows: (1) startup from `python main.py` through arg parsing, env setup, prestartup scripts, node loading, DB init, route registration and server bind; (2) a prompt's journey from POST /prompt through validation, queueing, per-node execution, caching and WebSocket events; (3) model loading from a CheckpointLoaderSimple node through state-dict detection into a VRAM-managed ModelPatcher; (4) interrupt and memory-pressure handling; (5) image upload and /view retrieval with traversal guards.
- Startup order: comfy.options.enable_args_parsing -> args parse -> setup_logger -> (optional) comfy_aimdo.control.init for DynamicVRAM -> apply_custom_paths (extra_model_paths.yaml, dir overrides) -> init_mime_types -> execute_prestartup_script over custom_nodes -> import execution/server/nodes -> start_comfyui: PromptServer(loop) -> init_extra_nodes -> set_cudnn_benchmark -> setup_database(init_db + asset_manager.startup) -> add_routes -> hijack_progress -> prompt_worker thread -> prompt_server.setup + run -> TCPSite bind on --listen/--port.
- Prompt submission order: post_prompt -> request.json -> trigger_on_prompt -> client prompt_id validation via validate_job_id (canonical UUID) -> node_replace_manager.apply_replacements -> validate_prompt -> sensitive key extraction -> prompt_queue.put -> queue_updated() broadcasts status -> worker q.get pops the item.
- Worker execution order: prompt_worker gets item -> asset_manager.pause_background_scan -> PromptExecutor.execute -> execute_async: set_preview_method -> interrupt_processing(False) -> execution_start msg -> torch.inference_mode -> DynamicPrompt + reset_progress_state -> caches.set_prompt/clean_unused -> execution_cached msg -> loop stage_node_execution/execute -> execution_success or handle_execution_error -> task_done stores history -> send 'executing' node=None.
- Single node step order inside execute(): dynprompt id mapping (real/display/parent) -> caches.outputs.get short-circuit -> get_input_data (links via execution_list.get_cache, hidden PROMPT/DYNPROMPT/EXTRA_PNGINFO/UNIQUE_ID injection) -> send 'executing' -> lazy check via check_lazy_status -> get_output_data -> _async_map_node_over_list (slices list inputs, asyncio.create_task for coroutine functions, ExecutionBlocker propagation) -> merge_result_data -> caches.outputs.set + execution_list.cache_update -> 'executed' event.
- Interrupt trace: POST /interrupt -> nodes.interrupt_processing -> comfy.model_management.interrupt_current_processing(True) -> flag checked by throw_exception_if_processing_interrupted inside the progress hook and before_node_execution -> InterruptProcessingException caught in execute() -> handle_execution_error sends 'execution_interrupted'.
- Checkpoint load trace: CheckpointLoaderSimple node -> comfy.sd.load_checkpoint_guess_config -> utils.load_torch_file -> model_detection.unet_prefix_from_state_dict + model_config_from_unet (state-dict key/shape fingerprinting) -> model_config classes from comfy.supported_models -> CLIP/VAE patchers built -> ModelPatcher returned as MODEL output -> later load_models_gpu/free_memory decide device placement and weight offloading.
- Image upload trace: POST /upload/image -> request.post() -> image_upload -> get_dir_by_type(input/temp/output) -> normpath join + commonpath containment check -> hash-compare dedup loop renaming 'name (i).ext' -> write file -> asset_manager.register_upload -> JSON {name, subfolder, type, asset?}.
- WebSocket lifecycle: GET /ws -> ws.prepare -> sid from clientId query or uuid4 -> sockets[sid]=ws -> send 'status' with queue info -> first TEXT message may carry feature_flags (stored in sockets_metadata, server flags replied) -> all server->client traffic funnels through send_sync -> messages queue -> publish_loop -> send_json/send_bytes.
- OOM/error path: exception inside execute() -> formatted inputs captured -> comfy.model_management.is_oom check triggers unload_all_models and debug_memory_summary logging -> error_details {node_id, exception_message, exception_type, traceback, current_inputs} -> handle_execution_error -> 'execution_error' WebSocket message -> worker records status 'error' in history.
- RAM-pressure caching behavior: with default RAM_PRESSURE cache, execute_async wires ram_release callback into memory_management.set_ram_cache_release_state; after each node it releases toward inactive headroom, computes shortfall vs virtual_memory_available, frees large intermediates then pins if needed.