Krea 2 accepts reference latents, but they arrive with no position, so the model treats them as a loose style hint: it borrows the look and reinvents the content. That is the whole reason an outpaint drifts instead of continuing the photo. Krea 2 Encode attaches the reference latents and emits the negative from the same node, so a turbo graph at CFG 1.0 stops carrying a second text encode that does nothing. Krea 2 Outpaint Model Patch registers those reference tokens into the target grid at the rectangle the stitcher records, on frame axis 1. Load Image + Pad gained a `reference` output - the unpadded source, fitted to a 384px long edge and a multiple of 16, because the VAE downsamples by 8 and the DiT patchifies by 2. It is APPENDED after `stitcher`, never inserted: a workflow stores links by output slot index, so any other position silently rewires every saved graph. The stitcher now records where the source sits, as source_bbox in pixels and bbox_normalized in 0..1. Padding knows the rectangle exactly, so it rides with the canvas instead of a parallel wire that can be left unplugged. apply_stitch reads neither key, so an older stitcher stitches identically. Ported from the lab rather than copied: the lab's _krea2_helpers had its own pad_image, feather_pad_mask, plan_pad_canvas, parse_fill_color and build_canvas_stitcher. Duplicating the padding engine here would let the outpaint path and the inpaint path disagree about what a stitcher is, so the public module keeps only what is specific to Krea 2 and uses the existing helpers for the rest. Two departures from the lab version. The model patch declared a kv_cache input and never read it - the cache was always on - so it is wired up now. And it imports comfy's flux internals when you run it rather than at startup: a core release that moves one then surfaces as an error on that node, instead of deleting it from the menu and leaving saved workflows reporting it missing.
95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
"""ComfyUI-AusBoss entry point.
|
|
|
|
Every node lives in its own file under nodes/ and exports its own
|
|
NODE_CLASS_MAPPINGS / NODE_DISPLAY_NAME_MAPPINGS. This file merges them
|
|
and hands the result to ComfyUI. To register a new node, add its module
|
|
name to NODE_MODULES below — nothing else to wire up.
|
|
|
|
A module that fails to import is skipped with a console warning instead
|
|
of taking the whole pack down, so one broken node never hides the rest.
|
|
"""
|
|
|
|
import importlib
|
|
import os
|
|
import re
|
|
import traceback
|
|
|
|
# One entry per file in nodes/. Keep alphabetical-ish; order only affects
|
|
# nothing functional.
|
|
NODE_MODULES = [
|
|
"node_align_image",
|
|
"node_color_match",
|
|
"node_compare",
|
|
"node_frame_chooser",
|
|
"node_frame_interpolate",
|
|
"node_image_crop_rotate_pad",
|
|
"node_image_size",
|
|
"node_inpaint_crop_stitch",
|
|
"node_krea2_encode",
|
|
"node_krea2_model_patch",
|
|
"node_lama_inpaint",
|
|
"node_lmstudio_chat",
|
|
"node_load_image_pad",
|
|
"node_load_video",
|
|
"node_lora_loader",
|
|
"node_refine_mask",
|
|
"node_save_video",
|
|
"node_select_frame",
|
|
"node_video_crop_rotate_pad",
|
|
]
|
|
|
|
NODE_CLASS_MAPPINGS = {}
|
|
NODE_DISPLAY_NAME_MAPPINGS = {}
|
|
_failed_modules = []
|
|
|
|
for _module_name in NODE_MODULES:
|
|
try:
|
|
_module = importlib.import_module(f".nodes.{_module_name}", __name__)
|
|
NODE_CLASS_MAPPINGS.update(getattr(_module, "NODE_CLASS_MAPPINGS", {}))
|
|
NODE_DISPLAY_NAME_MAPPINGS.update(
|
|
getattr(_module, "NODE_DISPLAY_NAME_MAPPINGS", {})
|
|
)
|
|
except Exception:
|
|
_failed_modules.append(_module_name)
|
|
traceback.print_exc()
|
|
|
|
# Folder ComfyUI serves to the browser; every .js file in it is loaded as a
|
|
# frontend extension. Shared modules use .mjs so they are import-only.
|
|
WEB_DIRECTORY = "./js"
|
|
|
|
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
|
|
|
|
|
|
def _read_version():
|
|
"""Version straight from pyproject.toml so it is never duplicated."""
|
|
try:
|
|
pyproject = os.path.join(os.path.dirname(__file__), "pyproject.toml")
|
|
with open(pyproject, "r", encoding="utf-8") as f:
|
|
match = re.search(r'^version\s*=\s*"([^"]+)"', f.read(), re.MULTILINE)
|
|
return match.group(1) if match else "unknown"
|
|
except Exception:
|
|
return "unknown"
|
|
|
|
|
|
def _print_banner():
|
|
# ASCII only in here: ComfyUI on Windows often runs with a cp1252
|
|
# console, and a UnicodeEncodeError at import time kills the whole pack.
|
|
teal = "\033[38;2;0;180;170m"
|
|
grey = "\033[0;37m"
|
|
red = "\033[0;31m"
|
|
reset = "\033[0m"
|
|
bar = f"{teal}{'-' * 70}{reset}"
|
|
|
|
print(bar)
|
|
print(
|
|
f" {teal}AusBoss{reset} v{_read_version()} | "
|
|
f"{len(NODE_CLASS_MAPPINGS)} nodes loaded"
|
|
)
|
|
if _failed_modules:
|
|
print(f" {red}Failed to load: {', '.join(_failed_modules)}{reset}")
|
|
print(f" {grey}https://github.com/ausboss/ComfyUI-AusBoss{reset}")
|
|
print(bar)
|
|
|
|
|
|
_print_banner()
|