From c5186ecbd2d6835b9a6619bef458ea1346e44daa Mon Sep 17 00:00:00 2001 From: GalaxyTimeMachine <52193044+GalaxyTimeMachine@users.noreply.github.com> Date: Tue, 9 Sep 2025 09:23:15 +0200 Subject: [PATCH 1/6] Update README.md Translated to English --- README.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 40e351b..d2f6783 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,21 @@ -# ComfyUI Wan2.2提示词生成插件 +# ComfyUI Wan2.2 Prompt Generation Plugin -基于Wan2.2的提示词预设插件,用于自动生成高质量的视频生成提示词。 +A preset prompt plugin based on the Wan2.2 template, used to automatically generate high-quality video generation prompts. -## 功能 +## Features -- 支持人物和物体两种主体类型 -- 19种人物运镜预设 + 18种物体运镜预设 -- 21种光线效果 -- 31种人物动作预设 -- 10种情绪表情预设 +- Supports two subject types: **characters** and **objects**. +- 19 preset camera movements for characters + 18 for objects. +- 21 lighting effects. +- 31 preset character actions. +- 10 preset emotion expressions. -## 安装 +## Installation -1. 将插件文件夹复制到ComfyUI的`custom_nodes`目录 -2. 重启ComfyUI -3. 在节点菜单中找到`Wan2.2/提示词生成`分类 +1. Copy the plugin folder into ComfyUI's `custom_nodes` directory. +2. Restart ComfyUI. +3. Find the `Wan2.2/Prompt Generation` category in the node menu. -## 使用 - -选择主体类型,输入自定义主体描述,选择运镜、光线、动作等参数,自动生成完整的Wan2.2格式提示词。 +## Usage +Select the subject type, input a custom subject description, and choose camera movement, lighting, action, and other parameters to automatically generate a complete Wan2.2-formatted prompt. From f36d057abf3c8512184b232cfeba7ea03da34ddf Mon Sep 17 00:00:00 2001 From: GalaxyTimeMachine <52193044+GalaxyTimeMachine@users.noreply.github.com> Date: Tue, 9 Sep 2025 09:34:17 +0200 Subject: [PATCH 2/6] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d2f6783..f12893b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +This repo is provided aas an English translation to the original from https://github.com/ZB678232321/ComfyUI-wan-prompt-generator + # ComfyUI Wan2.2 Prompt Generation Plugin A preset prompt plugin based on the Wan2.2 template, used to automatically generate high-quality video generation prompts. From 07e9cb3584342f1a5bf58d8e8721e66f20aa8df6 Mon Sep 17 00:00:00 2001 From: GalaxyTimeMachine <52193044+GalaxyTimeMachine@users.noreply.github.com> Date: Tue, 9 Sep 2025 09:43:16 +0200 Subject: [PATCH 3/6] Update nodes.py Corrected some errors --- nodes.py | 444 ++++++++++++++++--------------------------------------- 1 file changed, 124 insertions(+), 320 deletions(-) diff --git a/nodes.py b/nodes.py index 1ec7977..3ae02b6 100644 --- a/nodes.py +++ b/nodes.py @@ -8,19 +8,19 @@ import base64 from io import BytesIO -# Try to import PIL, use a mock if it fails +# Try importing PIL, use a mock if it fails try: from PIL import Image except ImportError: Image = None -# Try to import requests +# Try importing requests try: import requests except ImportError: requests = None -# Try to import utils module, create a mock if it fails +# Try importing utils module, create a mock if it fails try: from .utils import logger, log_function_call, safe_json_load, validate_api_key, handle_api_error, ErrorHandler except ImportError: @@ -28,372 +28,176 @@ class MockLogger: def info(self, msg): print(f"[INFO] {msg}") def error(self, msg): print(f"[ERROR] {msg}") - + logger = MockLogger() - + def log_function_call(func): return func - + def safe_json_load(path): with open(path, 'r', encoding='utf-8') as f: return json.load(f) - + def validate_api_key(key, provider): return True, "OK" - + def handle_api_error(error, provider): return f"{provider} API Error: {str(error)}" - + class ErrorHandler: @staticmethod def validate_inputs(**kwargs): pass - + @staticmethod def handle_node_error(node_name, method_name, error): - return (f"Node {node_name}.{method_name} Error: {str(error)}",) + return (f"Node {node_name}.{method_name} failed: {str(error)}",) class Wan22PromptGenerator: """ - Wan2.2 Prompt Preset Generator Node - Generates a complete WAN2.2 prompt based on user selections for subject type, camera type, and lighting type + Wan2.2 Prompt Generator Node """ - - CATEGORY = "Wan2.2/Prompt Generation" - FUNCTION = "generate_preset_prompt" - RETURN_TYPES = ("STRING",) - RETURN_NAMES = ("Generated Prompt",) - def __init__(self): - # Load wan2.2 template configuration self.templates = self.load_templates() - - def load_templates(self): - """Load wan2.2 template configuration file""" + + @staticmethod + def load_templates(): + """Safely load JSON templates""" + current_dir = os.path.dirname(os.path.abspath(__file__)) + json_path = os.path.join(current_dir, "wan22_templates.json") try: - current_dir = os.path.dirname(os.path.abspath(__file__)) - template_path = os.path.join(current_dir, "wan22_templates.json") - - with open(template_path, 'r', encoding='utf-8') as f: - templates = json.load(f) - - # Load character action presets - character_actions_path = os.path.join(current_dir, "character_actions.json") - if os.path.exists(character_actions_path): - with open(character_actions_path, 'r', encoding='utf-8') as f: - character_actions = json.load(f) - # Merge character action presets into the templates - if "character action presets" in character_actions: - actions = character_actions["character action presets"]["actions"] - action_options = [f"{k} - {v['name']}" for k, v in actions.items()] - action_options.insert(0, "No Specific Action") - - # Update parameter options - if "parameter_options" not in templates: - templates["parameter_options"] = {} - templates["parameter_options"]["Character Action"] = action_options - - # Add character action preset library - templates["character action preset library"] = { - "presets": {f"{k} - {v['name']}": {"description": v['description']} for k, v in actions.items()} - } - - return templates + with open(json_path, 'r', encoding='utf-8') as f: + return json.load(f) except Exception as e: - print(f"[Wan22PromptGenerator] Failed to load template file: {str(e)}") - return self.get_default_templates() - - def get_default_templates(self): - """Get default template configuration""" + logger.error(f"Failed to load wan22_templates.json: {str(e)}") + return None + + @classmethod + def INPUT_TYPES(cls): + """Define node input types""" + templates = cls.load_templates() + if not templates: + return {} + + options_map = templates.get("parameter_options", {}) + + logger.info(f"Loaded parameter options: {list(options_map.keys())}") + for k, v in options_map.items(): + logger.info(f"{k}: {len(v)} options") + return { "required": { - "Subject Type": (["Character", "Object"], {"default": "Character"}), - "Custom Subject": ("STRING", {"default": "girl", "multiline": False}), - "Camera Type": (["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"], {"default": "1"}), - "Lighting Type": (["No Lighting Effect", "Soft Natural Light", "Top Spotlight", "Neon Gradient Light", "Afterglow of the Sunset", "Cold Moonlight", "Morning Mist Light", "Flickering Strobe Light", "Spotlight Sweep", "Candlelight", "Thunderstorm Flash"], {"default": "No Lighting Effect"}), + "subject_type": (options_map.get("subject_type", []),), + "custom_subject": ("STRING", {"multiline": False, "default": ""}), + "character_camera_type": (options_map.get("character_camera_type", []), {"default": "No Specific Action"}), + "object_camera_type": (options_map.get("object_camera_type", []), {"default": "No Specific Action"}), + "lighting_type": (options_map.get("lighting_type", []), {"default": "No Lighting Effect"}), + "character_action": (options_map.get("character_action", []), {"default": "No Specific Action"}), + "emotional_expression": (options_map.get("emotional_expression", []), {"default": "No Specific Emotion"}) } } - def resolve_preset_id(self, selection, presets): - """Parses camera selection to a preset number, compatible with the following formats: - - 'Number - Name', e.g., '1 - Fixed Composition' - - Number only, e.g., '1' - - Name only, e.g., 'Fixed Composition' - - Directly as a number key - """ - try: - if not presets: - return "1" - - print(f"[DEBUG] Parsing preset selection: '{selection}'") - print(f"[DEBUG] Available preset keys: {list(presets.keys())}") - - # Direct key match - if selection in presets: - print(f"[DEBUG] Direct key match: {selection}") - return selection - - # 'Number - Name' format - if " - " in selection: - preset_id = selection.split(" - ", 1)[0].strip() - print(f"[DEBUG] Extracted number: {preset_id}") - if preset_id in presets: - print(f"[DEBUG] Number match successful: {preset_id}") - return preset_id - - # Number only - if selection.isdigit() and selection in presets: - print(f"[DEBUG] Numeric key match: {selection}") - return selection - - # Reverse lookup by name - for k, v in presets.items(): - if isinstance(v, dict) and v.get("name") == selection: - print(f"[DEBUG] Name match successful: {k}") - return k - - # Fallback to the smallest number - available_keys = list(presets.keys()) - if available_keys: - fallback = sorted(available_keys, key=lambda x: int(x) if str(x).isdigit() else 999)[0] - print(f"[DEBUG] Using fallback key: {fallback}") - return fallback - - return "1" - except Exception as e: - print(f"[DEBUG] Preset parsing exception: {e}") - return "1" - - @classmethod - def INPUT_TYPES(cls): - """Defines node input parameter types""" - try: - instance = cls() - options = instance.templates.get("parameter_options", {}) - - print(f"[DEBUG] Loaded parameter options: {list(options.keys())}") - - # Ensure all options have default values - default_options = { - "Subject Type": ["Character", "Object"], - "Character Camera Type": ["1 - Fixed Composition"], - "Object Camera Type": ["1 - Rotate in place (Camera surrounding)"], - "Lighting Type": ["No Lighting Effect"], - "Character Action": ["No Specific Action"], - "Emotional Expression": ["No Specific Emotion"] - } - - # Merge options, prioritizing those from the template - final_options = {} - for key, default_value in default_options.items(): - final_options[key] = options.get(key, default_value) - print(f"[DEBUG] {key}: {len(final_options[key])} options") - - return { - "required": { - "Subject Type": (final_options["Subject Type"], {"default": "Character"}), - "Custom Subject": ("STRING", {"default": "girl", "multiline": False}), - }, - "optional": { - "Character Camera Type": (final_options["Character Camera Type"], {"default": final_options["Character Camera Type"][0]}), - "Object Camera Type": (final_options["Object Camera Type"], {"default": final_options["Object Camera Type"][0]}), - "Lighting Type": (final_options["Lighting Type"], {"default": "No Lighting Effect"}), - "Character Action": (final_options["Character Action"], {"default": "No Specific Action"}), - "Emotional Expression": (final_options["Emotional Expression"], {"default": "No Specific Emotion"}), - } - } - except Exception as e: - print(f"[ERROR] INPUT_TYPES failed to load: {e}") - # Return basic default configuration - return { - "required": { - "Subject Type": (["Character", "Object"], {"default": "Character"}), - "Custom Subject": ("STRING", {"default": "girl", "multiline": False}), - }, - "optional": { - "Character Camera Type": (["1 - Fixed Composition"], {"default": "1 - Fixed Composition"}), - "Object Camera Type": (["1 - Rotate in place (Camera surrounding)"], {"default": "1 - Rotate in place (Camera surrounding)"}), - "Lighting Type": (["No Lighting Effect"], {"default": "No Lighting Effect"}), - "Character Action": (["No Specific Action"], {"default": "No Specific Action"}), - "Emotional Expression": (["No Specific Emotion"], {"default": "No Specific Emotion"}), - } - } - + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("prompt",) + FUNCTION = "generate_preset_prompt" + CATEGORY = "Wan2.2/Prompt Generation" + @log_function_call - def generate_preset_prompt(self, subject_type, custom_subject, character_camera_type=None, object_camera_type=None, lighting_type="No Lighting Effect", character_action="No Specific Action", emotional_expression="No Specific Emotion"): - """Generate wan2.2 preset prompt""" + def generate_preset_prompt(self, subject_type, custom_subject, character_camera_type, object_camera_type, lighting_type, character_action, emotional_expression): + """Generate a complete Wan2.2 format prompt""" try: - # Validate input parameters - ErrorHandler.validate_inputs( - subject_type=subject_type, custom_subject=custom_subject - ) - - logger.info(f"Starting WAN2.2 prompt generation - Subject Type: {subject_type}, Subject: {custom_subject}") - logger.info(f"Camera Type: {character_camera_type if subject_type == 'Character' else object_camera_type}, Lighting: {lighting_type}") - logger.info(f"Character Action: {character_action}, Emotional Expression: {emotional_expression}") - - # Select camera template based on subject type - use default if not specified - if subject_type == "Character": - if not character_camera_type: - character_camera_type = "1 - Fixed Composition" # Use default value - print(f"[INFO] No camera type specified for character, using default: {character_camera_type}") - camera_type = character_camera_type - camera_presets = self.templates.get("character camera presets", {}).get("presets", {}) - else: # Object - if not object_camera_type: - object_camera_type = "1 - Rotate in place (Camera surrounding)" # Use default value - print(f"[INFO] No camera type specified for object, using default: {object_camera_type}") - camera_type = object_camera_type - camera_presets = self.templates.get("object camera presets", {}).get("presets", {}) - - # Parse camera selection to preset number - preset_number = self.resolve_preset_id(camera_type, camera_presets) - print(f"[DEBUG] Final preset number used: {preset_number}") - - # Get the corresponding camera template - camera_template = camera_presets.get(preset_number, {}).get("template", "") - print(f"[DEBUG] Retrieved camera template: {camera_template[:100] if camera_template else 'None'}...") + # Load templates again inside the function to be safe + self.templates = self.load_templates() + if not self.templates: + return ("Error: Template file not loaded.",) - if not camera_template: - print(f"[ERROR] Template for preset number {preset_number} not found") - print(f"[ERROR] Available presets: {list(camera_presets.keys())}") - return (f"Error: Template for camera type {preset_number} not found. Available presets: {list(camera_presets.keys())}",) - - # Build the new prompt structure: Custom Subject -> Emotional Expression -> Character Action -> Camera Type -> Lighting Effect prompt_parts = [] - # 1. Custom subject description - if subject_type == "Character": - subject_description = f"{custom_subject} stands in the center of the frame, body naturally upright, expression calm, gazing straight ahead." - else: - subject_description = f"{custom_subject} is located in the center of the frame, with a complete and clear structure, and a stable base touching the ground." - prompt_parts.append(subject_description) - - # 2. Emotional expression (if an expression is selected) - if emotional_expression != "No Specific Emotion": - # Look up in the emotional expression preset library - emotional_expression_library = self.templates.get("emotional expression preset library", {}).get("presets", {}) - if emotional_expression in emotional_expression_library: - emotion_description = emotional_expression_library[emotional_expression].get("description", "") - if emotion_description: - prompt_parts.append(emotion_description) - else: - # Look up in emotional expression presets - emotional_expression_presets = self.templates.get("emotional expression presets", {}) - if emotional_expression in emotional_expression_presets: - emotion_description = emotional_expression_presets[emotional_expression].get("description", "") - if emotion_description: - prompt_parts.append(emotion_description) - - # 3. Character action (if a character action is selected) - if character_action != "No Specific Action": - # Look up in the character action preset library - character_action_library = self.templates.get("character action preset library", {}).get("presets", {}) - if character_action in character_action_library: - action_description = character_action_library[character_action].get("description", "") - if action_description: - prompt_parts.append(action_description) - else: - # Look up in character action presets (character_actions.json format) - character_action_presets = self.templates.get("character action presets", {}).get("actions", {}) - action_description = None - - # Try multiple matching methods - for key, action in character_action_presets.items(): - action_option = f"{key} - {action['name']}" - # Match full format "Number - Name" - if character_action == action_option: - action_description = action['description'] - break - # Match name only - elif character_action == action['name']: - action_description = action['description'] - break - # Match number only - elif character_action == key: - action_description = action['description'] - break - # Match format with number prefix - elif character_action.startswith(f"{key} - "): - action_description = action['description'] - break - - if action_description: - prompt_parts.append(action_description) - - # 4. Camera description (extract camera portion after replacing subject words in the template) - camera_description = camera_template + # 1. Subject Type (mandatory) + if not custom_subject or custom_subject.strip() == "": + return ("Error: Please provide a custom subject description.",) + + prompt_parts.append(custom_subject) + + # 2. Emotional Expression (if selected) + emotional_expression_presets = self.templates.get("emotional expression presets", {}) + if emotional_expression != "No Specific Emotion" and emotional_expression in emotional_expression_presets: + emotion_description = emotional_expression_presets[emotional_expression].get("description", "") + prompt_parts.append(emotion_description) + + # 3. Character Action (if selected) + character_action_presets = self.templates.get("character action presets", {}).get("actions", {}) + if character_action != "No Specific Action" and character_action in character_action_presets: + action_description = character_action_presets[character_action].get("description", "") + + # Replace the generic subject with the custom subject + if "subject" in action_description.lower(): + action_description = action_description.replace("The subject", custom_subject.capitalize()) + + prompt_parts.append(action_description) + + # 4. Camera Movement (conditional based on subject type) if subject_type == "Character": - # Replace character-related words - camera_description = camera_description.replace("girl", custom_subject) - camera_description = camera_description.replace("she", custom_subject) - camera_description = camera_description.replace("her", f"{custom_subject}’s") - camera_description = camera_description.replace("character", custom_subject) - camera_description = camera_description.replace("subject", custom_subject) - camera_description = camera_description.replace("subject’s back", f"{custom_subject} back") - camera_description = camera_description.replace("subject’s", f"{custom_subject}’s") - # Accurately remove subject description prefix, keeping camera description - prefixes_to_remove = [ - f"{custom_subject} stands in the center of the frame, body naturally upright, arms down, expression calm, gazing straight ahead.", - f"{custom_subject} stands in the center of the frame, body remains still, expression calm.", - f"{custom_subject} stands naturally, facing the camera, arms down, hair clinging to her cheeks.", - f"{custom_subject} is located in the center of the frame, expression determined, gazing straight ahead.", - f"{custom_subject} stands in the center of the frame, body naturally upright, hair hanging down, expression calm.", - f"{custom_subject} stands in the center of the frame, expression calm,", - f"{custom_subject} stands in the center of the frame, arms naturally down, expression calm.", - f"{custom_subject} stands in the center of the frame,", - f"{custom_subject} stands facing the camera, expression calm.", - f"{custom_subject} stands still in the center of the frame, expression determined.", - f"{custom_subject} stands still,", - f"{custom_subject} stands in the center of the frame, the camera is close to the front of {custom_subject}.", - f"{custom_subject} slowly walks toward the camera," - ] - for prefix in prefixes_to_remove: - if camera_description.startswith(prefix): - camera_description = camera_description[len(prefix):].strip() + camera_presets = self.templates.get("character camera presets", {}).get("presets", {}) + camera_description = "" + for preset_id, preset_data in camera_presets.items(): + if preset_data.get("name") == character_camera_type: + camera_description = preset_data.get("template", "") break - else: - # Replace object-related words - camera_description = camera_description.replace("subject", custom_subject) - camera_description = camera_description.replace("subject’s back", f"{custom_subject} back") - camera_description = camera_description.replace("subject’s", f"{custom_subject}’s") - # Accurately remove object description prefix, keeping camera description - prefixes_to_remove = [ - f"{custom_subject} is located in the center of the frame, with a complete and clear structure, and a stable base touching the ground.", - f"{custom_subject} is located in the center of the frame, with the whole object visible.", - f"{custom_subject} is located in the center of the frame,", - ] - for prefix in prefixes_to_remove: - if camera_description.startswith(prefix): - camera_description = camera_description[len(prefix):].strip() + + if camera_description: + # Replace the generic subject with the custom subject + camera_description = camera_description.replace("Subject", custom_subject.capitalize()).replace("subject", custom_subject.capitalize()) + prompt_parts.append(camera_description) + + elif subject_type == "Object": + camera_presets = self.templates.get("object camera presets", {}).get("presets", {}) + camera_description = "" + for preset_id, preset_data in camera_presets.items(): + if preset_data.get("name") == object_camera_type: + camera_description = preset_data.get("template", "") break - - prompt_parts.append(camera_description) - - # 5. Lighting effect (if a lighting type is selected) - placed at the end - lighting_effects_library = self.templates.get("lighting effects library", {}).get("effects", {}) - if lighting_type != "No Lighting Effect" and lighting_type in lighting_effects_library: - lighting_description = lighting_effects_library[lighting_type] + + if camera_description: + # Replace the generic subject with the custom subject + camera_description = camera_description.replace("Subject", custom_subject.capitalize()).replace("subject", custom_subject.capitalize()) + prompt_parts.append(camera_description) + + # 5. Lighting Effect (if selected) + lighting_effects = self.templates.get("lighting effects library", {}).get("effects", {}) + if lighting_type != "No Lighting Effect" and lighting_type in lighting_effects: + lighting_description = lighting_effects[lighting_type] + + # Replace the generic subject with the custom subject + lighting_description = lighting_description.replace("Subject", custom_subject.capitalize()).replace("subject", custom_subject.capitalize()) + prompt_parts.append(lighting_description) # Combine the final prompt final_prompt = " ".join(prompt_parts) - print(f"[Wan22PromptGenerator] Generated WAN2.2 prompt length: {len(final_prompt)}") - print(f"[Wan22PromptGenerator] WAN2.2 prompt: {final_prompt[:100]}...") + logger.info(f"Generated WAN2.2 prompt length: {len(final_prompt)}") + logger.info(f"WAN2.2 prompt: {final_prompt[:100]}...") return (final_prompt,) except Exception as e: - error_msg = f"An error occurred while generating the WAN2.2 prompt: {str(e)}" - print(f"[Wan22PromptGenerator] Error: {error_msg}") - print(f"[Wan22PromptGenerator] Error details: {traceback.format_exc()}") - return (f"Error: {error_msg}",) + error_msg = f"An error occurred while generating the Wan2.2 prompt: {str(e)}" + return ErrorHandler.handle_node_error("Wan22PromptGenerator", "generate_preset_prompt", error_msg) + + @classmethod + def IS_CHANGED(cls, **kwargs): + """Prevent caching of the node's output""" + return float("NaN") + + @classmethod + def IS_A_VALID_NODE(cls): + """Check if the node is valid to load""" + return cls.load_templates() is not None -# Node class mapping +# Define the node mappings for ComfyUI NODE_CLASS_MAPPINGS = { "Wan22PromptGenerator": Wan22PromptGenerator, - } NODE_DISPLAY_NAME_MAPPINGS = { From 82998d3aaa8672fe291948c159f9bfe23c28e6a6 Mon Sep 17 00:00:00 2001 From: GalaxyTimeMachine <52193044+GalaxyTimeMachine@users.noreply.github.com> Date: Tue, 9 Sep 2025 09:44:17 +0200 Subject: [PATCH 4/6] Update wan22_templates.json Corrected some errors --- wan22_templates.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wan22_templates.json b/wan22_templates.json index 35680a0..895c8c1 100644 --- a/wan22_templates.json +++ b/wan22_templates.json @@ -348,11 +348,11 @@ } }, "parameter_options": { - "Subject Type": [ + "subject_type": [ "Character", "Object" ], - "Character Camera Type": [ + "character_camera_type": [ "1 - Fixed Composition", "2 - Slow Zoom-In", "3 - Slow Zoom-Out", @@ -373,7 +373,7 @@ "18 - Horizontal Orbit (180° Two-Segment)", "19 - Orbit + Flip" ], - "Object Camera Type": [ + "object_camera_type": [ "1 - Rotate in place (Camera surrounding)", "2 - Zoom to Detail", "3 - Bird's-Eye View Rotation", @@ -393,7 +393,7 @@ "17 - Empty Shot (Pan Down)", "18 - Stable Shot" ], - "Lighting Type": [ + "lighting_type": [ "No Lighting Effect", "Sunlight", "Morning Light", @@ -416,7 +416,7 @@ "Chest Spotlight", "Full-Color Light" ], - "Character Action": [ + "character_action": [ "No Specific Action", "1 - Standing Still", "2 - Slow Walk (Forward)", @@ -450,7 +450,7 @@ "30 - Embracing Action", "31 - Punching Action" ], - "Emotional Expression": [ + "emotional_expression": [ "No Specific Emotion", "Laughing with Mouth Open", "Shocked with Eyes Wide", From 7191190b199ca3c3b6414792057f3992e080054f Mon Sep 17 00:00:00 2001 From: GalaxyTimeMachine <52193044+GalaxyTimeMachine@users.noreply.github.com> Date: Tue, 9 Sep 2025 11:15:42 +0200 Subject: [PATCH 5/6] Update README.md Typo correction --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f12893b..e8636a6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -This repo is provided aas an English translation to the original from https://github.com/ZB678232321/ComfyUI-wan-prompt-generator +This repo is provided as an English translation to the original from https://github.com/ZB678232321/ComfyUI-wan-prompt-generator # ComfyUI Wan2.2 Prompt Generation Plugin From d89d76068eb988bd7d7aaa090d25aef6020f767b Mon Sep 17 00:00:00 2001 From: GalaxyTimeMachine <52193044+GalaxyTimeMachine@users.noreply.github.com> Date: Tue, 9 Sep 2025 11:20:41 +0200 Subject: [PATCH 6/6] Update requirements.txt --- requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 3a37d47..fa60851 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -# ComfyUI Wan2.2提示词生成插件依赖包 -openai>=1.0.0 # OpenAI API支持 -anthropic>=0.7.0 # Claude API支持 -pillow>=9.0.0 # 图像处理 -requests>=2.28.0 # HTTP请求 \ No newline at end of file +# ComfyUI Wan2.2 Prompt Generator +openai>=1.0.0 # OpenAI API support +anthropic>=0.7.0 # Claude API support +pillow>=9.0.0 # Image processing +requests>=2.28.0 # HTTP requests