138 lines
4.9 KiB
Python
138 lines
4.9 KiB
Python
import random
|
||
import time
|
||
|
||
class Simple_Prompt_Library:
|
||
"""
|
||
Simple Prompt Library – Text field + seed only
|
||
• Empty lines separate projects (no empty lines inside a project)
|
||
• Lines starting with ### are project titles/comments → ignored in output
|
||
• --- or ---- separates positive/negative prompt (can be mid-line)
|
||
• Positive prompt can be empty → separator at start allowed
|
||
• No separator → entire text treated as positive prompt
|
||
• Seed behavior:
|
||
- -1 → random project (time-based seed), UI remains -1
|
||
- 0 or 1 → first project
|
||
- 1–999 → project index (1-based); if index exceeds count → treat as seed
|
||
- ≥1000 → always treat as random seed
|
||
"""
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(s):
|
||
return {
|
||
"required": {
|
||
"prompt_text": ("STRING", {
|
||
"multiline": True,
|
||
"default": "### Masterpiece\nmasterpiece, best quality --- low quality, blurry"
|
||
}),
|
||
"random_seed": ("INT", {"default": -1, "min": -1, "max": 0xffffffffffffffff}),
|
||
}
|
||
}
|
||
|
||
RETURN_TYPES = ("STRING", "INT")
|
||
RETURN_NAMES = ("prompt", "used_seed")
|
||
FUNCTION = "get_prompt"
|
||
CATEGORY = "hexxacubic"
|
||
|
||
def get_prompt(self, prompt_text, random_seed, **kwargs):
|
||
if not prompt_text.strip():
|
||
return ("", random_seed)
|
||
|
||
# --- 1. Parse projects: empty line = project boundary ---
|
||
projects = []
|
||
current_lines = []
|
||
|
||
for line in prompt_text.split('\n'):
|
||
stripped = line.strip()
|
||
|
||
# Empty line ends current project
|
||
if not stripped:
|
||
if current_lines:
|
||
projects.append(current_lines)
|
||
current_lines = []
|
||
continue
|
||
|
||
# ### lines are titles/comments → keep in block but ignore in output
|
||
if stripped.startswith("###"):
|
||
current_lines.append("") # placeholder to maintain block structure
|
||
continue
|
||
|
||
# Regular line → preserve original formatting
|
||
current_lines.append(line)
|
||
|
||
# Append final project
|
||
if current_lines:
|
||
projects.append(current_lines)
|
||
|
||
if not projects:
|
||
return ("", random_seed)
|
||
|
||
num_projects = len(projects)
|
||
available_indices = list(range(1, num_projects + 1))
|
||
|
||
# --- 2. Seed / Index logic ---
|
||
used_seed = random_seed
|
||
project_idx = 1
|
||
|
||
if random_seed == -1:
|
||
# Random selection with time-based seed
|
||
actual_seed = int(time.time() * 1000000) % 0xffffffffffffffff
|
||
gen = random.Random(actual_seed)
|
||
project_idx = gen.choice(available_indices)
|
||
used_seed = -1 # UI stays -1
|
||
elif random_seed >= 1000:
|
||
# High values → treat as seed
|
||
gen = random.Random(random_seed)
|
||
project_idx = gen.choice(available_indices)
|
||
used_seed = random_seed
|
||
else:
|
||
# 0 or 1–999: try as 1-based index
|
||
desired_idx = 1 if random_seed <= 0 else random_seed
|
||
if desired_idx <= num_projects:
|
||
project_idx = desired_idx
|
||
used_seed = random_seed
|
||
else:
|
||
# Index out of range → fall back to seed
|
||
gen = random.Random(random_seed)
|
||
project_idx = gen.choice(available_indices)
|
||
used_seed = random_seed
|
||
|
||
# --- 3. Build selected project (exclude ### lines) ---
|
||
selected_lines = projects[project_idx - 1]
|
||
clean_lines = []
|
||
|
||
for line in selected_lines:
|
||
if line.strip().startswith("###"):
|
||
continue # skip title lines in output
|
||
if line != "": # skip placeholder empty lines
|
||
clean_lines.append(line)
|
||
|
||
raw_project = '\n'.join(clean_lines).strip()
|
||
if not raw_project:
|
||
return ("", used_seed)
|
||
|
||
# --- 4. Split positive / negative ---
|
||
separator = None
|
||
if '----' in raw_project:
|
||
separator = '----'
|
||
elif '---' in raw_project:
|
||
separator = '---'
|
||
|
||
if separator:
|
||
pos_part, neg_part = raw_project.split(separator, 1)
|
||
pos = pos_part.strip()
|
||
neg = neg_part.strip()
|
||
if pos:
|
||
result = f"{pos}{separator}{neg}"
|
||
else:
|
||
result = f"{separator}{neg}" # allow empty positive
|
||
else:
|
||
result = raw_project # all positive
|
||
|
||
return (result, used_seed)
|
||
|
||
@classmethod
|
||
def IS_CHANGED(s, prompt_text, random_seed, **kwargs):
|
||
if random_seed == -1:
|
||
return float("nan")
|
||
return hash(prompt_text + str(random_seed))
|