Comfy-Org / Comfy-Org/ComfyUI

[Request] Human Readable Prompt Exportation

Open
#612 27 comments 4 reactions 0 assignees View on GitHub
User Support
Dominant language
Python
Stars
133k
Forks
15.7k
Avg merge
1d 10h
Merged PRs (30d)
153

Description

The workflow exporting is really cool, not knocking that at all, but maybe there should be a more straight forward way to distinguish what was actually used in the saved images generation.

Currently, you get the entire workflow. ***every single CLIPTextEncode*** whether in use or not. From an end user stand-point of just trying to examine the image itself, it's not clear what was actually used in the saved images generation. Both the workflow, and the prompt list out CLIPTextEncode nodes that were not even used in the generation process for the saved image, but were part of the chain.

I propose we add some specific metadata that pertains to the actual image itself, passed along from the samplers, not just the entire workflow. I don't always want to fire up ComfyUI (or have access to it), and load up a workflow (especially when I may need to then save my current workflow before loading) just to grab a prompt I am referencing or someone is asking about.

---

Subsequently I could hijack this information to create a prompt history system and prompt styles system. :P Win win. Lol

Here is an idea I drafted last night, works nicely. The idea for the auto keys was for the history list population, and when looking at the file directly.
```python
class PromptStyles:
def __init__(self, styles_file, preview_length = 32):
self.styles_file = styles_file
self.styles = {}
self.preview_length = preview_length

if os.path.exists(self.styles_file):
with open(self.styles_file, 'r') as f:
self.styles = json.load(f)

def add_style(self, prompt="", negative_prompt="", auto=False, name=None):
if auto:
date_format = '%A, %d %B %Y %I:%M %p'
date_str = datetime.datetime.now().strftime(date_format)
key = None
if prompt.strip() != "":
if len(prompt) > self.preview_length:
length = self.preview_length
else:
length = len(prompt)
key = f"[{date_str}] Positive: {prompt[:length]} ..."
elif negative_prompt.strip() != "":
if len(negative_prompt) > self.preview_length:
length = self.preview_length
else:
length = len(negative_prompt)
key = f"[{date_str}] Negative: {negative_prompt[:length]} ..."
else:
raise AttributeError("At least a `prompt`, or `negative_prompt` input is required!")
else:
if name == None or str(name).strip() == "":
raise AttributeError("A `name` input is required when not using `auto=True`")
key = str(name)

for k, v in self.styles.items():
if v['prompt'] == prompt and v['negative_prompt'] == negative_prompt:
return

self.styles[key] = {"prompt": prompt, "negative_prompt": negative_prompt}

with open(self.styles_file, "w", encoding='utf-8') as f:
json.dump(self.styles, f, indent=4)

def get_prompts(self):
return self.styles

def get_prompt(self, prompt_key):
if prompt_key in self.styles:
return self.styles[prompt_key]['prompt'], self.styles[prompt_key]['negative_prompt']
else:
print(f"Prompt style `{prompt_key}` was not found!")
return None, None
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.