* Renamed the extension to "Prompt Post-Processor".
* Improved logging. * Fix compatibility with A1111 hiresfix.
This commit is contained in:
@@ -1,23 +1,27 @@
|
||||
# Send to Negative for Stable Diffusion WebUI
|
||||
# Prompt Postprocessor for Stable Diffusion WebUI
|
||||
|
||||
Extension for the [AUTOMATIC1111 Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui) or compatible UIs.
|
||||
(formerly known as "sd-webui-sendtonegative")
|
||||
|
||||
Extension for [AUTOMATIC1111 Stable Diffusion WebUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui). Compatible with [SD.Next](https://github.com/vladmandic/automatic).
|
||||
|
||||
## Purpose
|
||||
|
||||
This extension allows the tagging of parts of the prompt and moves them to the
|
||||
The purpose of this extension is to process the prompt after other extensions have possibly modified it.
|
||||
|
||||
Currently this extension allows the tagging of parts of the prompt and moves them to the
|
||||
negative prompt. This allows useful tricks when using a wildcard extension
|
||||
since you can add negative content from choices made in the positive prompt.
|
||||
|
||||
Note: The extension must be loaded after the installed wildcards extension. Extensions
|
||||
load by their folder in alphanumeric order.
|
||||
load by their folder name in alphanumeric order.
|
||||
|
||||
With the ["Dynamic Prompts" extension](https://github.com/adieyal/sd-dynamic-prompts)
|
||||
this happens by default due to default folder names for both extensions. But if
|
||||
this is not the case, you can just rename the extension folder so the ordering
|
||||
this is not the case, you can just rename this extension's folder so the ordering
|
||||
works out.
|
||||
|
||||
With the ["AUTOMATIC1111 Wildcards" extension](https://github.com/AUTOMATIC1111/stable-diffusion-webui-wildcards)
|
||||
you will have to rename one of the folders, so that it loads before than "Send to Negative".
|
||||
you will have to rename one of the folders, so that it loads before than this extension.
|
||||
|
||||
When in doubt, just rename this extension's folder with a "z" in front (for example) so that it is the last one to load, or manually set such folder name when installing it.
|
||||
|
||||
@@ -29,17 +33,19 @@ Note: it only recognizes regular A1111 prompt formats. So:
|
||||
|
||||
In SD.Next that means only the A1111 or Full parsers.
|
||||
|
||||
It does not build AND/BREAK separations into the negative prompt.
|
||||
It does not build equivalent AND/BREAK separations into the negative prompt.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Go to Extensions > Install from URL
|
||||
2. Paste <https://github.com/acorderob/sd-webui-sendtonegative> in the URL for extension's git repository text field
|
||||
2. Paste <https://github.com/acorderob/sd-webui-prompt-postprocessor> in the URL for extension's git repository text field
|
||||
3. Click the Install button
|
||||
4. Restart the webui
|
||||
|
||||
## Usage
|
||||
|
||||
### Sending content to the negative prompt
|
||||
|
||||
The format of the tags is like this:
|
||||
|
||||
```text
|
||||
@@ -60,7 +66,7 @@ Where position can be:
|
||||
|
||||
If the insertion point is not found it inserts at the start.
|
||||
|
||||
## Example
|
||||
#### Example
|
||||
|
||||
You have a wildcard for hair colors (\_\_haircolors\_\_) with one being
|
||||
strawberry blonde, but you don't want strawberries. So in that option you add a
|
||||
@@ -87,7 +93,7 @@ Try to clean-up the prompt after processing: by default cleans up the positive p
|
||||
|
||||
## Notes
|
||||
|
||||
The content of the negative tags is not processed and is copied as is to the negative prompt. Other modifiers around the tags are processed in the following way.
|
||||
The content of the negative tags is not processed and is copied as-is to the negative prompt. Other modifiers around the tags are processed in the following way.
|
||||
|
||||
### Attention modifiers (weights)
|
||||
|
||||
|
||||
+60
-39
@@ -4,9 +4,9 @@ import math
|
||||
import lark
|
||||
|
||||
|
||||
class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
NAME = "Send to Negative"
|
||||
VERSION = "2.1.4"
|
||||
class PromptPostProcessor: # pylint: disable=too-few-public-methods
|
||||
NAME = "Prompt Post-Processor"
|
||||
VERSION = "2.1.5"
|
||||
|
||||
DEFAULT_SEPARATOR = ", "
|
||||
|
||||
@@ -34,26 +34,28 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
|
||||
iN - tags the position of insertion point N. Used only in the negative prompt and does not accept content. N can be 0 to 9.
|
||||
"""
|
||||
self.__opts = opts
|
||||
self.__logger = log
|
||||
self.__debug = getattr(self.__opts, "ppp_debug", False)
|
||||
if opts is not None and getattr(opts, "prompt_attention", "") == "Compel parser":
|
||||
self.__logger.warning("Compel parser is not supported!")
|
||||
self.__ignore_repeats = (
|
||||
ignore_repeats if ignore_repeats is not None else getattr(opts, "stn_ignorerepeats", True)
|
||||
ignore_repeats if ignore_repeats is not None else getattr(opts, "ppp_stn_ignorerepeats", True)
|
||||
)
|
||||
self.__join_attention = (
|
||||
join_attention
|
||||
if join_attention is not None
|
||||
else getattr(opts, "stn_joinattention", True)
|
||||
else getattr(opts, "ppp_stn_joinattention", True)
|
||||
if opts is not None
|
||||
else True
|
||||
)
|
||||
self.__cleanup = (
|
||||
cleanup if cleanup is not None else getattr(opts, "stn_cleanup", True) if opts is not None else True
|
||||
cleanup if cleanup is not None else getattr(opts, "ppp_cleanup", True) if opts is not None else True
|
||||
)
|
||||
self.__separator = (
|
||||
separator
|
||||
if separator is not None
|
||||
else getattr(opts, "stn_separator", self.DEFAULT_SEPARATOR)
|
||||
else getattr(opts, "ppp_separator", self.DEFAULT_SEPARATOR)
|
||||
if opts is not None
|
||||
else self.DEFAULT_SEPARATOR
|
||||
)
|
||||
@@ -81,9 +83,10 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
)
|
||||
|
||||
class ReadTree(lark.visitors.Interpreter):
|
||||
def __init__(self, logger, ignorerepeats, joinattention, prompt, add_at):
|
||||
def __init__(self, logger, debug, ignorerepeats, joinattention, prompt, add_at):
|
||||
super().__init__()
|
||||
self.__logger = logger
|
||||
self.__debug = debug
|
||||
self.__ignore_repeats = ignorerepeats
|
||||
self.__join_attention = joinattention
|
||||
self.__prompt = prompt
|
||||
@@ -112,16 +115,18 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
pos = int(pos)
|
||||
# self.__shell.append(self.AccumulatedShell("sc", tree.meta.start_pos, pos))
|
||||
if before is not None and hasattr(before, "data"):
|
||||
self.__logger.debug(
|
||||
f"Shell scheduled before at {[before.meta.start_pos,before.meta.end_pos] if hasattr(before,'meta') and not before.meta.empty else '?'} : {pos}"
|
||||
)
|
||||
if self.__debug:
|
||||
self.__logger.info(
|
||||
f"Shell scheduled before at {[before.meta.start_pos,before.meta.end_pos] if hasattr(before,'meta') and not before.meta.empty else '?'} with position {pos}"
|
||||
)
|
||||
self.__shell.append(self.AccumulatedShell("scb", pos, None))
|
||||
self.visit(before)
|
||||
self.__shell.pop()
|
||||
if hasattr(after, "data"):
|
||||
self.__logger.debug(
|
||||
f"Shell scheduled after at {[after.meta.start_pos,after.meta.end_pos] if hasattr(after,'meta') and not after.meta.empty else '?'} : {pos}"
|
||||
)
|
||||
if self.__debug:
|
||||
self.__logger.info(
|
||||
f"Shell scheduled after at {[after.meta.start_pos,after.meta.end_pos] if hasattr(after,'meta') and not after.meta.empty else '?'} with position {pos}"
|
||||
)
|
||||
self.__shell.append(self.AccumulatedShell("sca", pos, None))
|
||||
self.visit(after)
|
||||
self.__shell.pop()
|
||||
@@ -130,9 +135,10 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
def alternate(self, tree):
|
||||
# self.__shell.append(self.AccumulatedShell("al", tree.meta.start_pos, len(tree.children)))
|
||||
for i, opt in enumerate(tree.children):
|
||||
self.__logger.debug(
|
||||
f"Shell alternate at {[opt.meta.start_pos,opt.meta.end_pos] if hasattr(opt,'meta') and not opt.meta.empty else '?'} : {i+1}"
|
||||
)
|
||||
if self.__debug:
|
||||
self.__logger.info(
|
||||
f"Shell alternate at {[opt.meta.start_pos,opt.meta.end_pos] if hasattr(opt,'meta') and not opt.meta.empty else '?'} option {i+1}"
|
||||
)
|
||||
if hasattr(opt, "data"):
|
||||
self.__shell.append(self.AccumulatedShell("alo", i + 1, len(tree.children)))
|
||||
self.visit(opt)
|
||||
@@ -142,18 +148,20 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
def emphasized(self, tree):
|
||||
numpar = tree.children[-1]
|
||||
weight = self.__get_numpar_value(numpar) if numpar is not None else 1.1
|
||||
self.__logger.debug(
|
||||
f"Shell attention at {[tree.meta.start_pos,tree.meta.end_pos] if hasattr(tree,'meta') and not tree.meta.empty else '?'}: {weight}"
|
||||
)
|
||||
if self.__debug:
|
||||
self.__logger.info(
|
||||
f"Shell attention at {[tree.meta.start_pos,tree.meta.end_pos] if hasattr(tree,'meta') and not tree.meta.empty else '?'} with weight {weight}"
|
||||
)
|
||||
self.__shell.append(self.AccumulatedShell("at", weight, None))
|
||||
self.visit_children(tree)
|
||||
self.__shell.pop()
|
||||
|
||||
def deemphasized(self, tree):
|
||||
weight = 0.9
|
||||
self.__logger.debug(
|
||||
f"Shell attention at {[tree.meta.start_pos,tree.meta.end_pos] if hasattr(tree,'meta') and not tree.meta.empty else '?'}: {weight}"
|
||||
)
|
||||
if self.__debug:
|
||||
self.__logger.info(
|
||||
f"Shell attention at {[tree.meta.start_pos,tree.meta.end_pos] if hasattr(tree,'meta') and not tree.meta.empty else '?'} with weight {weight}"
|
||||
)
|
||||
self.__shell.append(self.AccumulatedShell("at", weight, None))
|
||||
self.visit_children(tree)
|
||||
self.__shell.pop()
|
||||
@@ -172,9 +180,10 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
self.__negtags.append(
|
||||
self.NegTag(tree.meta.start_pos, tree.meta.end_pos, content, parameters, self.__shell.copy())
|
||||
)
|
||||
self.__logger.debug(
|
||||
f"Negative tag at {[tree.meta.start_pos,tree.meta.end_pos] if hasattr(tree,'meta') and not tree.meta.empty else '?'}: {parameters}: {content.encode('unicode_escape').decode('utf-8')}"
|
||||
)
|
||||
if self.__debug:
|
||||
self.__logger.info(
|
||||
f"Negative tag at {[tree.meta.start_pos,tree.meta.end_pos] if hasattr(tree,'meta') and not tree.meta.empty else '?'}: {parameters or 'with no parameters :'} {content.encode('unicode_escape').decode('utf-8')}"
|
||||
)
|
||||
|
||||
def start(self, tree):
|
||||
self.visit_children(tree)
|
||||
@@ -222,9 +231,10 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
if content not in self.__already_processed:
|
||||
if self.__ignore_repeats:
|
||||
self.__already_processed.append(content)
|
||||
self.__logger.debug(
|
||||
f"Adding content at position {position}: {content.encode('unicode_escape').decode('utf-8')}"
|
||||
)
|
||||
if self.__debug:
|
||||
self.__logger.info(
|
||||
f"Adding content at position {position}: {content.encode('unicode_escape').decode('utf-8')}"
|
||||
)
|
||||
if position == "e":
|
||||
self.add_at["end"].append(content)
|
||||
elif position.startswith("p"):
|
||||
@@ -246,16 +256,21 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
try:
|
||||
prompt = original_prompt
|
||||
negative_prompt = original_negative_prompt
|
||||
self.__logger.debug(f"Input prompt: {prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
self.__logger.debug(f"Input negative_prompt: {negative_prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
self.__debug = getattr(self.__opts, "ppp_debug", False)
|
||||
if self.__debug:
|
||||
self.__logger.info(f"Input prompt: {prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
self.__logger.info(f"Input negative_prompt: {negative_prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
prompt, add_at = self.__find_tags(prompt)
|
||||
negative_prompt = self.__add_to_insertion_points(negative_prompt, add_at["insertion_point"])
|
||||
if len(add_at["start"]) > 0:
|
||||
negative_prompt = self.__add_to_start(negative_prompt, add_at["start"])
|
||||
if len(add_at["end"]) > 0:
|
||||
negative_prompt = self.__add_to_end(negative_prompt, add_at["end"])
|
||||
self.__logger.debug(f"Output prompt: {prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
self.__logger.debug(f"Output negative_prompt: {negative_prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
if self.__debug:
|
||||
self.__logger.info(f"Output prompt: {prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
self.__logger.info(
|
||||
f"Output negative_prompt: {negative_prompt.encode('unicode_escape').decode('utf-8')}"
|
||||
)
|
||||
return prompt, negative_prompt
|
||||
except Exception as e: # pylint: disable=broad-exception-caught
|
||||
self.__logger.exception(e)
|
||||
@@ -264,29 +279,35 @@ class SendToNegative: # pylint: disable=too-few-public-methods
|
||||
def __find_tags(self, prompt):
|
||||
add_at = {"start": [], "insertion_point": [[] for x in range(10)], "end": []}
|
||||
tree = self.__schedule_parser.parse(prompt)
|
||||
self.__logger.debug(f"Initial tree:\n{tree.pretty()}")
|
||||
# if self.__debug:
|
||||
# self.__logger.info(f"Initial tree:\n{tree.pretty()}")
|
||||
|
||||
readtree = self.ReadTree(self.__logger, self.__ignore_repeats, self.__join_attention, prompt, add_at)
|
||||
readtree = self.ReadTree(
|
||||
self.__logger, self.__debug, self.__ignore_repeats, self.__join_attention, prompt, add_at
|
||||
)
|
||||
readtree.visit(tree)
|
||||
|
||||
for r in readtree.remove[::-1]:
|
||||
prompt = prompt[: r[0]] + prompt[r[1] :]
|
||||
if self.__cleanup:
|
||||
if self.__debug:
|
||||
self.__logger.info(f"Prompt before cleanup: {prompt.encode('unicode_escape').decode('utf-8')}")
|
||||
prompt = re.sub(r"\((?::[+-]?[\d\.]+)?\)", "", prompt) # clean up empty attention
|
||||
prompt = re.sub(r"\[\]", "", prompt) # clean up empty attention
|
||||
prompt = re.sub(r"\[:?:[+-]?[\d\.]+\]", "", prompt) # clean up empty scheduling
|
||||
prompt = re.sub(r"\[\|+\]", "", prompt) # clean up empty alternation
|
||||
# clean up whitespace and extra separators
|
||||
prompt = re.sub(r"[ ]{2,}", " ", prompt) # collapse spaces
|
||||
# clean up extra separators
|
||||
prompt = (
|
||||
prompt.replace(" ", " ")
|
||||
.replace(self.__separator + self.__separator, self.__separator)
|
||||
prompt.replace(self.__separator + self.__separator, self.__separator)
|
||||
.replace(" " + self.__separator, self.__separator)
|
||||
.removeprefix(self.__separator)
|
||||
.removesuffix(self.__separator)
|
||||
.strip()
|
||||
)
|
||||
add_at = readtree.add_at
|
||||
self.__logger.debug(f"New negative additions: {add_at}")
|
||||
if self.__debug:
|
||||
self.__logger.info(f"New negative additions: {add_at}")
|
||||
|
||||
return prompt, add_at
|
||||
|
||||
@@ -3,7 +3,7 @@ import copy
|
||||
import logging
|
||||
|
||||
|
||||
class SendToNegativeLogFactory:
|
||||
class PromptPostProcessorLogFactory:
|
||||
class ColoredFormatter(logging.Formatter):
|
||||
COLORS = {
|
||||
"DEBUG": "\033[0;36m", # CYAN
|
||||
@@ -22,19 +22,16 @@ class SendToNegativeLogFactory:
|
||||
return super().format(colored_record)
|
||||
|
||||
def __init__(self):
|
||||
logsd = logging.getLogger("sd")
|
||||
stnlog = logging.getLogger("SendToNegative")
|
||||
stnlog.setLevel(logging.INFO)
|
||||
stnlog.handlers = logsd.handlers
|
||||
if not stnlog.handlers:
|
||||
ppplog = logging.getLogger("PromptPostProcessor")
|
||||
ppplog.propagate = False
|
||||
if not ppplog.handlers:
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(self.ColoredFormatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
|
||||
stnlog.addHandler(handler)
|
||||
self.log = stnlog
|
||||
else:
|
||||
self.log = SendToNegativeLogCustomAdapter(stnlog)
|
||||
ppplog.addHandler(handler)
|
||||
ppplog.setLevel(logging.INFO)
|
||||
self.log = PromptPostProcessorLogCustomAdapter(ppplog)
|
||||
|
||||
|
||||
class SendToNegativeLogCustomAdapter(logging.LoggerAdapter):
|
||||
class PromptPostProcessorLogCustomAdapter(logging.LoggerAdapter):
|
||||
def process(self, msg, kwargs):
|
||||
return f"[SendToNegative] {msg}", kwargs
|
||||
return f"[PromptPostProcessor] {msg}", kwargs
|
||||
@@ -12,49 +12,54 @@ sys.path.insert(1, os.path.join(sys.path[0], ".."))
|
||||
from modules import scripts, shared, script_callbacks
|
||||
from modules.processing import StableDiffusionProcessing
|
||||
from modules.shared import opts
|
||||
from sendtonegative import SendToNegative
|
||||
from stnlogging import SendToNegativeLogFactory
|
||||
from ppp import PromptPostProcessor
|
||||
from ppp_logging import PromptPostProcessorLogFactory
|
||||
|
||||
|
||||
class SendToNegativeScript(scripts.Script):
|
||||
class PromptPostProcessorScript(scripts.Script):
|
||||
def __init__(self):
|
||||
if not hasattr(self, "callbacks_added"):
|
||||
lf = SendToNegativeLogFactory()
|
||||
self.__logstn = lf.log
|
||||
lf = PromptPostProcessorLogFactory()
|
||||
self.__logppp = lf.log
|
||||
script_callbacks.on_ui_settings(self.__on_ui_settings)
|
||||
self.callbacks_added = True
|
||||
|
||||
def title(self):
|
||||
return SendToNegative.NAME
|
||||
return PromptPostProcessor.NAME
|
||||
|
||||
def show(self, is_img2img):
|
||||
return scripts.AlwaysVisible
|
||||
|
||||
def process(self, p: StableDiffusionProcessing, *args, **kwargs):
|
||||
stn = SendToNegative(self.__logstn, opts=opts)
|
||||
ppp = PromptPostProcessor(self.__logppp, opts=opts)
|
||||
for i in range(len(p.all_prompts)): # pylint: disable=consider-using-enumerate
|
||||
p.all_prompts[i], p.all_negative_prompts[i] = stn.process_prompt(
|
||||
p.all_prompts[i], p.all_negative_prompts[i] = ppp.process_prompt(
|
||||
p.all_prompts[i], p.all_negative_prompts[i]
|
||||
)
|
||||
# make it compatible with A1111 hires fix
|
||||
if hasattr(p, "all_hr_prompts") and hasattr(p, "all_hr_negative_prompts"):
|
||||
if (
|
||||
hasattr(p, "all_hr_prompts")
|
||||
and p.all_hr_prompts is not None
|
||||
and hasattr(p, "all_hr_negative_prompts")
|
||||
and p.all_hr_negative_prompts is not None
|
||||
):
|
||||
for i in range(len(p.all_hr_prompts)): # pylint: disable=consider-using-enumerate
|
||||
p.all_hr_prompts[i], p.all_hr_negative_prompts[i] = stn.process_prompt(
|
||||
p.all_hr_prompts[i], p.all_hr_negative_prompts[i] = ppp.process_prompt(
|
||||
p.all_hr_prompts[i], p.all_hr_negative_prompts[i]
|
||||
)
|
||||
|
||||
def __on_ui_settings(self):
|
||||
section = ("send-to-negative", SendToNegative.NAME)
|
||||
section = ("prompt-post-processor", PromptPostProcessor.NAME)
|
||||
shared.opts.add_option(
|
||||
key="stn_separator",
|
||||
key="ppp_separator",
|
||||
info=shared.OptionInfo(
|
||||
SendToNegative.DEFAULT_SEPARATOR,
|
||||
PromptPostProcessor.DEFAULT_SEPARATOR,
|
||||
label="Separator used when adding to the negative prompt",
|
||||
section=section,
|
||||
),
|
||||
)
|
||||
shared.opts.add_option(
|
||||
key="stn_ignorerepeats",
|
||||
key="ppp_stn_ignorerepeats",
|
||||
info=shared.OptionInfo(
|
||||
True,
|
||||
label="Ignore tags with repeated content",
|
||||
@@ -62,7 +67,7 @@ class SendToNegativeScript(scripts.Script):
|
||||
),
|
||||
)
|
||||
shared.opts.add_option(
|
||||
key="stn_joinattention",
|
||||
key="ppp_stn_joinattention",
|
||||
info=shared.OptionInfo(
|
||||
True,
|
||||
label="Join attention modifiers (weights) when possible",
|
||||
@@ -70,10 +75,18 @@ class SendToNegativeScript(scripts.Script):
|
||||
),
|
||||
)
|
||||
shared.opts.add_option(
|
||||
key="stn_cleanup",
|
||||
key="ppp_cleanup",
|
||||
info=shared.OptionInfo(
|
||||
True,
|
||||
label="Try to clean-up the prompt after processing (removes extra spaces or the configured separator)",
|
||||
label="Try to clean-up the prompt after processing (removes extra spaces, empty attention, or the configured separator)",
|
||||
section=section,
|
||||
),
|
||||
)
|
||||
shared.opts.add_option(
|
||||
key="ppp_debug",
|
||||
info=shared.OptionInfo(
|
||||
False,
|
||||
label="Debug",
|
||||
section=section,
|
||||
),
|
||||
)
|
||||
+8
-8
@@ -5,16 +5,16 @@ import os
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], ".."))
|
||||
|
||||
from sendtonegative import SendToNegative # pylint: disable=import-error
|
||||
from stnlogging import SendToNegativeLogFactory
|
||||
from ppp import PromptPostProcessor # pylint: disable=import-error
|
||||
from ppp_logging import PromptPostProcessorLogFactory
|
||||
|
||||
|
||||
class TestSendToNegative(unittest.TestCase):
|
||||
class TestPromptPostProcessor(unittest.TestCase):
|
||||
def setUp(self):
|
||||
lf = SendToNegativeLogFactory()
|
||||
lf = PromptPostProcessorLogFactory()
|
||||
self.__log = lf.log
|
||||
self.__log.setLevel(logging.DEBUG)
|
||||
self.defstn = SendToNegative(self.__log, separator=", ", ignore_repeats=True, join_attention=True, cleanup=True)
|
||||
self.defppp = PromptPostProcessor(self.__log, separator=", ", ignore_repeats=True, join_attention=True, cleanup=True)
|
||||
|
||||
def process(
|
||||
self,
|
||||
@@ -22,9 +22,9 @@ class TestSendToNegative(unittest.TestCase):
|
||||
negative_prompt,
|
||||
expected_prompt,
|
||||
expected_negative_prompt,
|
||||
stn=None,
|
||||
ppp=None,
|
||||
):
|
||||
the_obj = self.defstn if stn is None else stn
|
||||
the_obj = self.defppp if ppp is None else ppp
|
||||
result_prompt, result_negative_prompt = the_obj.process_prompt(prompt, negative_prompt)
|
||||
self.assertEqual(result_prompt, expected_prompt, f"Prompt should be '{expected_prompt}'")
|
||||
self.assertEqual(
|
||||
@@ -119,7 +119,7 @@ class TestSendToNegative(unittest.TestCase):
|
||||
"normal quality, <!!i0!!>, bad quality<!!i1!!>, worse quality",
|
||||
" (), flowers , , ",
|
||||
"red, (pink), normal quality, yellow, bad quality, green, worse quality, purple, blue",
|
||||
SendToNegative(self.__log, separator=", ", ignore_repeats=True, join_attention=True, cleanup=False),
|
||||
PromptPostProcessor(self.__log, separator=", ", ignore_repeats=True, join_attention=True, cleanup=False),
|
||||
)
|
||||
|
||||
def test_inside_attention1(self):
|
||||
|
||||
Reference in New Issue
Block a user