From eb07a8f5965da0173d308e1cfc7f10136032d9e4 Mon Sep 17 00:00:00 2001 From: Legende <68666984+xLegende@users.noreply.github.com> Date: Wed, 25 Feb 2026 19:34:56 +0100 Subject: [PATCH] Fix non-deterministic random generation. --- categorized_prompt_analyzer.py | 6 +++--- categorized_prompt_formatter.py | 16 ++++++++-------- categorized_random_prompt_formatter.py | 12 +++++------- wildcard_importer.py | 12 ++++++------ 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/categorized_prompt_analyzer.py b/categorized_prompt_analyzer.py index d371ea3..79bf0dc 100644 --- a/categorized_prompt_analyzer.py +++ b/categorized_prompt_analyzer.py @@ -61,14 +61,14 @@ class CategorizedPromptAnalyzer: if raw_yaml_data: cache = {} for cat_name in list(raw_yaml_data.keys()): - if str(cat_name).strip() not in [INCLUDE_DIRECTIVE, TAGS_KEY]: + if str(cat_name).strip() not in[INCLUDE_DIRECTIVE, TAGS_KEY]: tags_set = resolve_category_tags(cat_name, raw_yaml_data, cache, self.NODE_NAME) key = str(cat_name).strip() if case_sensitive else str(cat_name).strip().lower() resolved_category_tags[key] = {t if case_sensitive else t.lower() for t in tags_set} # --- 2. Parse Targets --- targets_info = [] - original_targets = [t.strip() for t in analyze_targets.split(kwargs.get("target_delimiter", ",")) if t.strip()] + original_targets =[t.strip() for t in analyze_targets.split(kwargs.get("target_delimiter", ",")) if t.strip()] match_spaces = kwargs.get("match_underscores_spaces", True) for target in original_targets: @@ -115,6 +115,6 @@ class CategorizedPromptAnalyzer: unmatched_str = "" if kwargs.get("generate_unmatched_output", False): - unmatched_str = output_delimiter.join(list(all_input_tags - matched_input_tags)) + unmatched_str = output_delimiter.join(sorted(all_input_tags - matched_input_tags)) return (summary, total_count, details_str, unmatched_str) \ No newline at end of file diff --git a/categorized_prompt_formatter.py b/categorized_prompt_formatter.py index e8f4b75..334b0f1 100644 --- a/categorized_prompt_formatter.py +++ b/categorized_prompt_formatter.py @@ -64,7 +64,7 @@ class CategorizedPromptFormatter: if raw_yaml_data: resolved_tags_cache = {} for cat_name in list(raw_yaml_data.keys()): - if str(cat_name).strip() not in [INCLUDE_DIRECTIVE, TAGS_KEY]: + if str(cat_name).strip() not in[INCLUDE_DIRECTIVE, TAGS_KEY]: resolve_category_tags(cat_name, raw_yaml_data, resolved_tags_cache, self.NODE_NAME) case_sensitive = kwargs.get("case_sensitive_matching", False) @@ -74,7 +74,7 @@ class CategorizedPromptFormatter: if key: tag_to_categories_map[key].append(cat_name) for key in tag_to_categories_map: - tag_to_categories_map[key] = list(set(tag_to_categories_map[key])) + tag_to_categories_map[key] = sorted(set(tag_to_categories_map[key])) # --- 2. Parse Input Prompt & Categorize --- categorized_tags = defaultdict(list) @@ -98,7 +98,7 @@ class CategorizedPromptFormatter: variants.add(lookup_key.replace(' ', '_')) variants.add(lookup_key.replace('_', ' ')) - for variant in variants: + for variant in sorted(variants): if variant in tag_to_categories_map: for category in tag_to_categories_map[variant]: categorized_tags[category].append(tag_original) @@ -110,7 +110,7 @@ class CategorizedPromptFormatter: disable_dupes = kwargs.get("disable_duplicates", False) added_tags = set() used_tags = set() - result_parts = [] + result_parts =[] last_end = 0 for match in re.finditer(r"<\|([^:]+?)(?::(-?\d+))?\|>", output_template): @@ -118,14 +118,14 @@ class CategorizedPromptFormatter: result_parts.append(output_template[last_end:start]) limit = int(limit_str) if limit_str else None - tags_for_cat = categorized_tags.get(cat_name, []) + tags_for_cat = categorized_tags.get(cat_name,[]) tags_to_process = tags_for_cat if limit is not None: - tags_to_process = tags_for_cat[:limit] if limit > 0 else (tags_for_cat[limit:] if limit < 0 else []) + tags_to_process = tags_for_cat[:limit] if limit > 0 else (tags_for_cat[limit:] if limit < 0 else[]) used_tags.update(tags_to_process) - tags_to_join = [t for t in tags_to_process if not (disable_dupes and t in added_tags and not added_tags.add(t))] + tags_to_join =[t for t in tags_to_process if not (disable_dupes and t in added_tags and not added_tags.add(t))] if tags_to_join: result_parts.append(output_delimiter.join(tags_to_join)) last_end = end @@ -136,7 +136,7 @@ class CategorizedPromptFormatter: unmatched_handling = kwargs.get("unmatched_tag_handling", "discard") rejected_prompt = "" if unmatched_handling != "discard": - rejected_tags = list(all_input_tags - used_tags) + rejected_tags = sorted(all_input_tags - used_tags) if rejected_tags: rejected_prompt = output_delimiter.join(rejected_tags) if unmatched_handling == "append_end": diff --git a/categorized_random_prompt_formatter.py b/categorized_random_prompt_formatter.py index 7000057..2ced917 100644 --- a/categorized_random_prompt_formatter.py +++ b/categorized_random_prompt_formatter.py @@ -1,4 +1,4 @@ -#/ComfyUI-Prompt-Formatter/categorized_random_prompt_formatter.py +# /ComfyUI-Prompt-Formatter/categorized_random_prompt_formatter.py import yaml import re @@ -68,7 +68,7 @@ class CategorizedRandomPromptFormatter: return ("", used_seed) # --- 3. Process Template & Generate Prompt --- - result_parts = [] + result_parts =[] last_end = 0 for match in re.finditer(r"<\|([^:]+?)(?::(\d+))?\|>", output_template): cat_name, count_str, start, end = match.group(1).strip(), match.group(2), *match.span() @@ -76,10 +76,10 @@ class CategorizedRandomPromptFormatter: num_to_pick = int(count_str) if count_str and int(count_str) >= 0 else 1 if num_to_pick > 0: - available_tags = list(resolved_categories.get(cat_name, [])) + available_tags = list(resolved_categories.get(cat_name,[])) if available_tags: sample_count = min(num_to_pick, len(available_tags)) - tags_to_join = rng.sample(available_tags, sample_count) + tags_to_join = rng.sample(sorted(available_tags), sample_count) result_parts.append(output_delimiter.join(tags_to_join)) else: print(f"Warning [{self.NODE_NAME}]: Category '{cat_name}' not found or empty.") @@ -89,6 +89,4 @@ class CategorizedRandomPromptFormatter: result_parts.append(output_template[last_end:]) final_prompt = clean_output_string("".join(result_parts), output_delimiter) - return (final_prompt, used_seed) - - \ No newline at end of file + return (final_prompt, used_seed) \ No newline at end of file diff --git a/wildcard_importer.py b/wildcard_importer.py index fecd6a6..8788243 100644 --- a/wildcard_importer.py +++ b/wildcard_importer.py @@ -74,13 +74,13 @@ class WildcardImporter: # --- 3. Identify and Filter Target Wildcards --- try: - all_wildcards = list(wildcard_dir_path.rglob('*.txt')) + all_wildcards = sorted(wildcard_dir_path.rglob('*.txt')) except Exception as e: status_msg = f"ERROR: Could not scan wildcard directory: {e}" print(f"[Importer] {status_msg}") return ("", status_msg, 0) - target_wildcards = [] + target_wildcards =[] if wildcards_to_import.strip() == '*': target_wildcards = all_wildcards else: @@ -114,14 +114,14 @@ class WildcardImporter: # --- MERGE LOGIC --- if write_mode == "Merge (Append Unique Tags)" and category_name in yaml_data: # Append unique tags to an existing category - existing_tags = set(yaml_data.get(category_name, [])) - new_tags = list(existing_tags.union(wildcard_tags)) + existing_tags = set(yaml_data.get(category_name,[])) + new_tags = sorted(existing_tags.union(wildcard_tags)) tags_added_this_run = len(new_tags) - len(existing_tags) yaml_data[category_name] = new_tags total_tags_added += tags_added_this_run else: # Overwrite or create new category - yaml_data[category_name] = list(wildcard_tags) + yaml_data[category_name] = sorted(wildcard_tags) total_tags_added += len(wildcard_tags) processed_count += 1 @@ -143,4 +143,4 @@ class WildcardImporter: print(f"[Importer] {status_msg}") return ("", status_msg, 0) - return (str(output_path), status_msg, processed_count) + return (str(output_path), status_msg, processed_count) \ No newline at end of file