diff --git a/CHANGELOG.md b/CHANGELOG.md index 56a91248..3ceefcc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +# 4.39.0 + +* Adds generating transparent images + # 4.38.0 * Add waitress / db metrics to heartbeat diff --git a/horde/apis/models/stable_v2.py b/horde/apis/models/stable_v2.py index 9951fc84..69a3a262 100644 --- a/horde/apis/models/stable_v2.py +++ b/horde/apis/models/stable_v2.py @@ -405,6 +405,10 @@ def __init__(self, api): enum=list(KNOWN_WORKFLOWS), description="Explicitly specify the horde-engine workflow to use.", ), + "transparent": fields.Boolean( + default=False, + description="Set to True to generate the image using Layer Diffuse, creating an image with a transparent background.", + ), }, ) self.response_model_generation_payload = api.inherit( diff --git a/horde/apis/v2/stable.py b/horde/apis/v2/stable.py index 150128c2..ce78bf8c 100644 --- a/horde/apis/v2/stable.py +++ b/horde/apis/v2/stable.py @@ -178,6 +178,13 @@ def validate(self): raise e.BadRequest("explicit LoRa version requests have to be a version ID (i.e integer).", rc="BadLoraVersion") if "tis" in self.params and len(self.params["tis"]) > 20: raise e.BadRequest("You cannot request more than 20 Textual Inversions per generation.", rc="TooManyTIs") + if self.params.get("transparent", False) is True and any( + model_reference.get_model_baseline(model_name) not in ["stable_diffusion_xl", "stable diffusion 1"] + for model_name in self.args.models + ): + raise e.BadRequest( + "Generating Transparent images is is only possible for Stable Diffusion 1.5 and XL models.", rc="InvalidTransparency", + ) if self.args.source_processing == "remix" and any( not model_reference.get_model_baseline(model_name).startswith("stable_cascade") for model_name in self.args.models ): @@ -573,7 +580,7 @@ def post(self): if "blacklist" in post_ret.get("skipped", {}): db_skipped["blacklist"] = post_ret["skipped"]["blacklist"] post_ret["skipped"] = db_skipped - + # logger.debug(post_ret) return post_ret, retcode def check_in(self): diff --git a/horde/bridge_reference.py b/horde/bridge_reference.py index b842761e..b7c098c6 100644 --- a/horde/bridge_reference.py +++ b/horde/bridge_reference.py @@ -5,6 +5,7 @@ BRIDGE_CAPABILITIES = { "AI Horde Worker reGen": { + 8: {"layer_diffuse"}, 7: {"qr_code", "extra_texts", "workflow"}, 6: {"stable_cascade_2pass"}, 5: {"extra_source_images"}, diff --git a/horde/consts.py b/horde/consts.py index 0af26183..83735f71 100644 --- a/horde/consts.py +++ b/horde/consts.py @@ -1,4 +1,4 @@ -HORDE_VERSION = "4.38.1" +HORDE_VERSION = "4.39.0" WHITELISTED_SERVICE_IPS = { "212.227.227.178", # Turing Bot diff --git a/horde/database/functions.py b/horde/database/functions.py index 301bc4a1..e74c2675 100644 --- a/horde/database/functions.py +++ b/horde/database/functions.py @@ -836,6 +836,13 @@ def get_sorted_wp_filtered_to_worker(worker, models_list=None, blacklist=None, p worker.speed >= 500000, # 0.5 MPS/s ImageWaitingPrompt.slow_workers == True, # noqa E712 ), + or_( + ImageWaitingPrompt.params["transparent"].astext.cast(Boolean).is_(False), + and_( + check_bridge_capability("layer_diffuse", worker.bridge_agent), + worker.allow_sdxl_controlnet == True, # noqa E712 + ) + ), ) ) # logger.debug(final_wp_list) @@ -1067,6 +1074,10 @@ def count_skipped_image_wp(worker, models_list=None, blacklist=None, priority_us not check_bridge_capability("tiling", worker.bridge_agent), ImageWaitingPrompt.params["tiling"].astext.cast(Boolean).is_(True), ), + and_( + not check_bridge_capability("layer_diffuse", worker.bridge_agent), + ImageWaitingPrompt.params["transparent"].astext.cast(Boolean).is_(True), + ), ), ).count() if skipped_bv > 0: diff --git a/horde/exceptions.py b/horde/exceptions.py index 4e318fe9..d2a14b00 100644 --- a/horde/exceptions.py +++ b/horde/exceptions.py @@ -143,6 +143,7 @@ "MoreThanMinExtraSourceImage", "InvalidExtraTexts", "MissingExtraTexts", + "InvalidTransparency", ]