diff --git a/deployments/ai-stack/openwebui-tools/smart_image_gen.py b/deployments/ai-stack/openwebui-tools/smart_image_gen.py index 8ca9289..6edffa2 100644 --- a/deployments/ai-stack/openwebui-tools/smart_image_gen.py +++ b/deployments/ai-stack/openwebui-tools/smart_image_gen.py @@ -1,7 +1,7 @@ """ title: Smart Image Generator & Editor (ComfyUI) author: ai-stack -version: 0.7.7 +version: 0.7.8 description: Generate or edit images via ComfyUI with automatic SDXL checkpoint routing. Two methods — generate_image (txt2img) and edit_image (img2img on the user's most recently attached image). The @@ -263,6 +263,12 @@ def _seed_value(seed: int) -> int: return seed if seed > 0 else int(time.time() * 1000) % (2**31) +def _job_prefix(kind: str) -> str: + """Per-submission filename_prefix so SaveImage outputs from concurrent + jobs can never share an auto-numbered counter and cross over.""" + return f"{kind}_{uuid.uuid4().hex[:10]}" + + def _build_txt2img(positive: str, negative: str, settings: dict, width: int, height: int, seed: int) -> dict: """ @@ -286,7 +292,7 @@ def _build_txt2img(positive: str, negative: str, settings: dict, "7": {"class_type": "CLIPTextEncode", "inputs": {"text": negative, "clip": ["10", 0]}}, "8": {"class_type": "VAEDecode", "inputs": {"samples": ["3", 0], "vae": ["4", 2]}}, "9": {"class_type": "SaveImage", - "inputs": {"filename_prefix": "smartgen", "images": ["8", 0]}}, + "inputs": {"filename_prefix": _job_prefix("smartgen"), "images": ["8", 0]}}, "10": {"class_type": "CLIPSetLastLayer", "inputs": {"stop_at_clip_layer": -settings["clip_skip"], "clip": ["4", 1]}}, @@ -329,7 +335,7 @@ def _build_inpaint(positive: str, negative: str, settings: dict, "7": {"class_type": "CLIPTextEncode", "inputs": {"text": negative, "clip": ["10", 0]}}, "8": {"class_type": "VAEDecode", "inputs": {"samples": ["3", 0], "vae": ["4", 2]}}, "9": {"class_type": "SaveImage", - "inputs": {"filename_prefix": "smartinpaint", "images": ["8", 0]}}, + "inputs": {"filename_prefix": _job_prefix("smartinpaint"), "images": ["8", 0]}}, "10": {"class_type": "CLIPSetLastLayer", "inputs": {"stop_at_clip_layer": -settings["clip_skip"], "clip": ["4", 1]}}, @@ -381,7 +387,7 @@ def _build_img2img(positive: str, negative: str, settings: dict, "7": {"class_type": "CLIPTextEncode", "inputs": {"text": negative, "clip": ["10", 0]}}, "8": {"class_type": "VAEDecode", "inputs": {"samples": ["3", 0], "vae": ["4", 2]}}, "9": {"class_type": "SaveImage", - "inputs": {"filename_prefix": "smartedit", "images": ["8", 0]}}, + "inputs": {"filename_prefix": _job_prefix("smartedit"), "images": ["8", 0]}}, "10": {"class_type": "CLIPSetLastLayer", "inputs": {"stop_at_clip_layer": -settings["clip_skip"], "clip": ["4", 1]}}, @@ -943,7 +949,14 @@ class Tools: "(paperclip / drag-drop), or call generate_image instead." ) - await emit("Uploading source to ComfyUI…") + # Diagnostic emit so a misrouted source ("wrong image + # returned") shows up in the status track instead of being + # invisible. SHA-1 is fast and the first 8 hex chars are + # plenty to compare against the prior generation's hash if + # cross-talk is suspected. + import hashlib # local import — keeps the module import surface clean + src_hash = hashlib.sha1(raw_in).hexdigest()[:8] + await emit(f"Uploading source to ComfyUI… (sha1={src_hash}, {len(raw_in)} bytes)") uploaded_name = await _upload_to_comfyui(session, base, raw_in) if not uploaded_name: return "Failed to upload source image to ComfyUI."