From 710a2cec63be19a77491d153c24ef0c191536ded Mon Sep 17 00:00:00 2001 From: Andro-Meta <146106280+Andro-Meta@users.noreply.github.com> Date: Tue, 30 Jun 2026 12:16:34 -0500 Subject: [PATCH] Improve random and mashup moodboard UX Balance random selection across style families so photo-like boards do not dominate, and make mashups show the resolved source moodboards while accepting metadata_json, titles, search phrases, UUIDs, slugs, or URLs. Co-authored-by: Cursor --- README.md | 29 ++++- examples/krea2_turbo_moodboard_workflow.json | 2 +- examples/manual_krea2_prompt_wiring.json | 2 +- examples/moodboard_mashup_prompt_wiring.json | 107 +++++++++++++++++++ moodboard_catalog.py | 68 +++++++++++- nodes.py | 89 +++++++++++++-- pyproject.toml | 2 +- tests/test_bundled_catalog.py | 13 +++ tests/test_catalog.py | 56 ++++++++++ tests/test_nodes.py | 52 +++++++++ tests/test_registry_metadata.py | 2 +- 11 files changed, 404 insertions(+), 18 deletions(-) create mode 100644 examples/moodboard_mashup_prompt_wiring.json diff --git a/README.md b/README.md index 85bbac6..1eda425 100644 --- a/README.md +++ b/README.md @@ -69,12 +69,37 @@ Use `style_only` if you want to feed the moodboard text into another prompt enha ### Krea Moodboard Random -Picks a deterministic random style by seed. Add a query to randomize within a style family, for example `query = cinematic noir` and `random_from_top_k = 25`. +Picks a deterministic random style by seed. By default it uses `random_mode = balanced`, which samples a style family first so the largest family in the catalog, especially photo-like boards, does not dominate random results. + +Random modes: + +- `balanced`: recommended default; samples across style families first. +- `any`: pure random from the whole matching pool. +- `non_photo`: avoids boards classified as photo-family when possible. +- `photo`: only photo-family boards when possible. + +Add a query to randomize within a style family, for example `query = cinematic noir` and `random_from_top_k = 25`. ### Krea Moodboard Mashup Blends two to four moodboards by concatenating transferable style guidance, deduping style axes and negative guidance. +What to put in each `board` box: + +- Best option: paste or connect the `metadata_json` output from `Krea Moodboard Search`, `Krea Moodboard Random`, or `Krea Moodboard Style`. +- Also works: a moodboard title, search phrase, UUID, slug, or Krea moodboard URL. + +Examples: + +```text +Abyssal Gothic +warm pastel product +https://www.krea.ai/moodboard-feed/... +{"uuid": "f8ba7b69-987b-5cc3-abd8-fc734a82223a"} +``` + +The `preview` output lists which source moodboards were resolved. If the mashup looks wrong, check `preview` first and make the board boxes more specific. + ### Krea Moodboard Style Looks up one moodboard by exact title, slug, UUID, URL, or search phrase. This avoids a 2500-item dropdown while keeping every option findable. @@ -92,6 +117,8 @@ Looks up one moodboard by exact title, slug, UUID, URL, or search phrase. This a 7. Connect `Krea Moodboard Apply.positive` to the Krea-2 Turbo subgraph `Text String (User Prompt)` input. 8. If your workflow exposes a negative prompt or CFG path, connect `Krea Moodboard Apply.negative` there. If it does not, leave it unused. +For mashups, use two or more `Krea Moodboard Search` or `Krea Moodboard Random` nodes, then connect their `metadata_json` outputs into `Krea Moodboard Mashup.board_1`, `board_2`, etc. Connect the Mashup `positive` and `negative` outputs into `Krea Moodboard Apply`. + ### Manual Krea 2 Graph Use these nodes before Krea text encoding: diff --git a/examples/krea2_turbo_moodboard_workflow.json b/examples/krea2_turbo_moodboard_workflow.json index a4e4a2e..0f3505c 100644 --- a/examples/krea2_turbo_moodboard_workflow.json +++ b/examples/krea2_turbo_moodboard_workflow.json @@ -18,7 +18,7 @@ { "name": "metadata_json", "type": "STRING", "links": [3] }, { "name": "preview", "type": "STRING", "links": null } ], - "widgets_values": ["dark teal gothic", 5, 1, 0, 0, "normal"] + "widgets_values": ["dark teal gothic", 5, 1, 0, 0, "normal", "balanced"] }, { "id": 2, diff --git a/examples/manual_krea2_prompt_wiring.json b/examples/manual_krea2_prompt_wiring.json index 2152bc8..00c8e09 100644 --- a/examples/manual_krea2_prompt_wiring.json +++ b/examples/manual_krea2_prompt_wiring.json @@ -17,7 +17,7 @@ { "name": "title", "type": "STRING", "links": null }, { "name": "metadata_json", "type": "STRING", "links": [3] } ], - "widgets_values": [1234, "cinematic noir", 25, "normal"] + "widgets_values": [1234, "cinematic noir", 25, "normal", "balanced"] }, { "id": 2, diff --git a/examples/moodboard_mashup_prompt_wiring.json b/examples/moodboard_mashup_prompt_wiring.json new file mode 100644 index 0000000..bf4b277 --- /dev/null +++ b/examples/moodboard_mashup_prompt_wiring.json @@ -0,0 +1,107 @@ +{ + "last_node_id": 5, + "last_link_id": 7, + "nodes": [ + { + "id": 1, + "type": "KreaMoodboardSearch", + "pos": [120, 120], + "size": [360, 220], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { "name": "positive", "type": "STRING", "links": null }, + { "name": "negative", "type": "STRING", "links": null }, + { "name": "title", "type": "STRING", "links": null }, + { "name": "metadata_json", "type": "STRING", "links": [1] }, + { "name": "preview", "type": "STRING", "links": null } + ], + "widgets_values": ["dark teal gothic", 5, 1, 0, 0, "normal", "balanced"] + }, + { + "id": 2, + "type": "KreaMoodboardSearch", + "pos": [120, 420], + "size": [360, 220], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { "name": "positive", "type": "STRING", "links": null }, + { "name": "negative", "type": "STRING", "links": null }, + { "name": "title", "type": "STRING", "links": null }, + { "name": "metadata_json", "type": "STRING", "links": [2] }, + { "name": "preview", "type": "STRING", "links": null } + ], + "widgets_values": ["warm pastel product", 5, 1, 0, 0, "normal", "balanced"] + }, + { + "id": 3, + "type": "KreaMoodboardMashup", + "pos": [560, 180], + "size": [420, 300], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { "name": "board_1", "type": "STRING", "link": 1 }, + { "name": "board_2", "type": "STRING", "link": 2 } + ], + "outputs": [ + { "name": "positive", "type": "STRING", "links": [3] }, + { "name": "negative", "type": "STRING", "links": [4] }, + { "name": "title", "type": "STRING", "links": null }, + { "name": "metadata_json", "type": "STRING", "links": [5] }, + { "name": "preview", "type": "STRING", "links": null } + ], + "widgets_values": ["", "", 0.65, 0.35, "normal", "", "", 1.0, 1.0] + }, + { + "id": 4, + "type": "KreaMoodboardApply", + "pos": [1040, 180], + "size": [420, 280], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + { "name": "prompt", "type": "STRING", "link": null }, + { "name": "negative_prompt", "type": "STRING", "link": null }, + { "name": "moodboard_positive", "type": "STRING", "link": 3 }, + { "name": "moodboard_negative", "type": "STRING", "link": 4 }, + { "name": "metadata_json", "type": "STRING", "link": 5 } + ], + "outputs": [ + { "name": "positive", "type": "STRING", "links": null }, + { "name": "negative", "type": "STRING", "links": null }, + { "name": "metadata_json", "type": "STRING", "links": null } + ], + "widgets_values": [ + "a ceramic fox on a table, editorial product photo", + "", + "", + "", + "{}", + "normal", + false, + "newline" + ] + } + ], + "links": [ + [1, 1, 3, 3, 0, "STRING"], + [2, 2, 3, 3, 1, "STRING"], + [3, 3, 0, 4, 2, "STRING"], + [4, 3, 1, 4, 3, "STRING"], + [5, 3, 3, 4, 4, "STRING"] + ], + "groups": [], + "config": {}, + "extra": { + "info": "Example mashup wiring: Search metadata_json outputs feed Mashup board inputs, then Mashup positive/negative feed Apply." + }, + "version": 0.4 +} diff --git a/moodboard_catalog.py b/moodboard_catalog.py index 2376465..f47517f 100644 --- a/moodboard_catalog.py +++ b/moodboard_catalog.py @@ -36,6 +36,16 @@ FIELD_WEIGHTS: tuple[tuple[str, int], ...] = ( ("negative_guidance", 3), ) +STYLE_FAMILY_TERMS: tuple[tuple[str, tuple[str, ...]], ...] = ( + ("anime", ("anime", "manga", "kawaii", "chibi", "retroanime")), + ("illustration", ("illustration", "illustrated", "ink", "watercolor", "drawing", "sketch", "storybook")), + ("graphic", ("graphic", "poster", "typography", "halftone", "pop art", "comic", "vector")), + ("abstract", ("abstract", "abstraction", "geometric", "surreal", "spectral", "iridescent")), + ("3d", ("3d", "voxel", "isometric", "clay", "render", "cgi", "plastic")), + ("photo", ("photo", "photograph", "photographic", "photoreal", "documentary", "camera", "lens")), + ("cinematic", ("cinematic", "film", "35mm", "noir", "editorial")), +) + def load_catalog(path: str | Path = CATALOG_PATH) -> list[dict[str, Any]]: catalog_path = Path(path) @@ -113,6 +123,7 @@ def random_board( query: str = "", random_from_top_k: int = 0, min_score: int = 1, + random_mode: str = "balanced", ) -> dict[str, Any]: pool = catalog if query.strip(): @@ -121,7 +132,21 @@ def random_board( pool = [match["board"] for match in matches] if not pool: raise ValueError("No Krea moodboards matched the query.") - return random.Random(int(seed)).choice(pool) + rng = random.Random(int(seed)) + if random_mode == "any": + return rng.choice(pool) + if random_mode == "photo": + filtered = [board for board in pool if style_family(board) == "photo"] + return rng.choice(filtered or pool) + if random_mode == "non_photo": + filtered = [board for board in pool if style_family(board) != "photo"] + return rng.choice(filtered or pool) + + grouped: dict[str, list[dict[str, Any]]] = {} + for board in pool: + grouped.setdefault(style_family(board), []).append(board) + family = rng.choice(sorted(grouped)) + return rng.choice(grouped[family]) def find_board(catalog: list[dict[str, Any]], value: str) -> dict[str, Any]: @@ -143,6 +168,27 @@ def find_board(catalog: list[dict[str, Any]], value: str) -> dict[str, Any]: raise ValueError(f"No Krea moodboard matched: {value}") +def resolve_board_reference(catalog: list[dict[str, Any]], value: str) -> dict[str, Any]: + """Resolve title/search text, slug, UUID, URL, or metadata_json into a board.""" + raw = str(value or "").strip() + if not raw: + raise ValueError("Provide a moodboard title, search text, URL, UUID, slug, or metadata_json.") + try: + data = json.loads(raw) + except json.JSONDecodeError: + return find_board(catalog, raw) + if not isinstance(data, dict): + return find_board(catalog, raw) + for key in ("uuid", "url", "slug", "title"): + candidate = str(data.get(key) or "").strip() + if candidate: + try: + return find_board(catalog, candidate) + except ValueError: + continue + return find_board(catalog, raw) + + def style_from_board(board: dict[str, Any], *, strength: str = "normal") -> dict[str, str]: guidance = _guidance(board) style_axes = _string_list(guidance.get("style_axes")) @@ -246,15 +292,33 @@ def mashup_boards( style_axes.append(axis) sources.append({"title": title, "url": metadata.get("url", ""), "uuid": metadata.get("uuid", "")}) + source_titles = [source["title"] for source in sources] + mashup_title = "Mashup: " + " + ".join(source_titles[:4]) metadata = {"source_count": len(sources), "sources": sources, "style_axes": style_axes} + preview = "\n".join( + f"{idx}. {source['title']} | {source['url']}" for idx, source in enumerate(sources, start=1) + ) return { "positive": "Blend these Krea moodboard styles: " + " | ".join(positives), "negative": " ".join(_dedupe(negatives)), - "title": "Krea Moodboard Mashup", + "title": mashup_title, "metadata_json": json.dumps(metadata, ensure_ascii=False, sort_keys=True), + "preview": ( + "Mashup sources resolved. Paste metadata_json from Search/Random/Style nodes, " + "or type a moodboard title, search phrase, UUID, slug, or Krea URL.\n" + f"{preview}" + ), } +def style_family(board: dict[str, Any]) -> str: + text = " ".join(_search_fields(board).values()).lower() + for family, terms in STYLE_FAMILY_TERMS: + if any(term in text for term in terms): + return family + return "other" + + def _score_board(board: dict[str, Any], expanded_terms: list[str]) -> tuple[int, list[str]]: score = 0 matched: list[str] = [] diff --git a/nodes.py b/nodes.py index e525496..c932c29 100644 --- a/nodes.py +++ b/nodes.py @@ -10,6 +10,7 @@ from moodboard_catalog import ( load_catalog, mashup_boards, random_board, + resolve_board_reference, search_boards, style_from_board, ) @@ -17,6 +18,7 @@ from moodboard_catalog import ( STRENGTHS = ["concise", "normal", "strong"] SEPARATORS = ["newline", "comma"] +RANDOM_MODES = ["balanced", "any", "non_photo", "photo"] @lru_cache(maxsize=1) @@ -110,10 +112,26 @@ class KreaMoodboardSearch: STRENGTHS, {"default": "normal", "tooltip": "Controls detail level in the positive style text."}, ), + "random_mode": ( + RANDOM_MODES, + { + "default": "balanced", + "tooltip": "balanced samples style families first; any samples the whole pool; non_photo avoids photo-family boards.", + }, + ), } } - def search(self, query: str, top_k: int, min_score: int, random_from_top_k: int, seed: int, strength: str): + def search( + self, + query: str, + top_k: int, + min_score: int, + random_from_top_k: int, + seed: int, + strength: str, + random_mode: str = "balanced", + ): catalog = _catalog() matches = search_boards(catalog, query, top_k=top_k, min_score=min_score) if not matches: @@ -125,6 +143,7 @@ class KreaMoodboardSearch: query=query, random_from_top_k=min(random_from_top_k, top_k), min_score=min_score, + random_mode=random_mode, ) else: board = matches[0]["board"] @@ -158,19 +177,39 @@ class KreaMoodboardRandom: {"default": 25, "min": 1, "max": 100, "step": 1, "tooltip": "Random pool size after search."}, ), "strength": (STRENGTHS, {"default": "normal"}), + "random_mode": ( + RANDOM_MODES, + { + "default": "balanced", + "tooltip": "balanced samples style families first so photo boards do not dominate random picks.", + }, + ), } } - def random_style(self, seed: int, query: str, random_from_top_k: int, strength: str): - board = random_board(_catalog(), seed=seed, query=query, random_from_top_k=random_from_top_k) + def random_style( + self, + seed: int, + query: str, + random_from_top_k: int, + strength: str, + random_mode: str = "balanced", + ): + board = random_board( + _catalog(), + seed=seed, + query=query, + random_from_top_k=random_from_top_k, + random_mode=random_mode, + ) style = style_from_board(board, strength=strength) return style["positive"], style["negative"], style["title"], style["metadata_json"] class KreaMoodboardMashup: CATEGORY = "Krea/Moodboards" - RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING") - RETURN_NAMES = ("positive", "negative", "title", "metadata_json") + RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING") + RETURN_NAMES = ("positive", "negative", "title", "metadata_json", "preview") FUNCTION = "mashup" DESCRIPTION = "Blend two to four Krea moodboards into one prompt style." @@ -178,15 +217,43 @@ class KreaMoodboardMashup: def INPUT_TYPES(cls): return { "required": { - "board_1": ("STRING", {"default": "", "multiline": False}), - "board_2": ("STRING", {"default": "", "multiline": False}), + "board_1": ( + "STRING", + { + "default": "", + "multiline": True, + "tooltip": "Paste metadata_json from another Krea Moodboard node, or type a title, search phrase, UUID, slug, or URL.", + }, + ), + "board_2": ( + "STRING", + { + "default": "", + "multiline": True, + "tooltip": "Paste metadata_json from another Krea Moodboard node, or type a title, search phrase, UUID, slug, or URL.", + }, + ), "weight_1": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 5.0, "step": 0.05}), "weight_2": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 5.0, "step": 0.05}), "strength": (STRENGTHS, {"default": "normal"}), }, "optional": { - "board_3": ("STRING", {"default": "", "multiline": False}), - "board_4": ("STRING", {"default": "", "multiline": False}), + "board_3": ( + "STRING", + { + "default": "", + "multiline": True, + "tooltip": "Optional third board: metadata_json, title, search phrase, UUID, slug, or URL.", + }, + ), + "board_4": ( + "STRING", + { + "default": "", + "multiline": True, + "tooltip": "Optional fourth board: metadata_json, title, search phrase, UUID, slug, or URL.", + }, + ), "weight_3": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 5.0, "step": 0.05}), "weight_4": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 5.0, "step": 0.05}), }, @@ -207,9 +274,9 @@ class KreaMoodboardMashup: catalog = _catalog() names = [board_1, board_2, board_3, board_4] weights = [weight_1, weight_2, weight_3, weight_4] - boards = [find_board(catalog, name) for name in names if str(name or "").strip()] + boards = [resolve_board_reference(catalog, name) for name in names if str(name or "").strip()] style = mashup_boards(boards, weights=weights[: len(boards)], strength=strength) - return style["positive"], style["negative"], style["title"], style["metadata_json"] + return style["positive"], style["negative"], style["title"], style["metadata_json"], style["preview"] class KreaMoodboardApply: diff --git a/pyproject.toml b/pyproject.toml index f0aba50..9aabd03 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "comfyui-krea-moodboards" -version = "0.1.0" +version = "0.1.1" description = "Prompt-only Krea moodboard search and style nodes for ComfyUI." readme = "README.md" requires-python = ">=3.10" diff --git a/tests/test_bundled_catalog.py b/tests/test_bundled_catalog.py index 733692d..98907b9 100644 --- a/tests/test_bundled_catalog.py +++ b/tests/test_bundled_catalog.py @@ -1,5 +1,8 @@ from __future__ import annotations +import json +from pathlib import Path + from moodboard_catalog import CATALOG_PATH, load_catalog @@ -10,3 +13,13 @@ def test_bundled_catalog_contains_prompt_only_krea_moodboards() -> None: assert all(board.get("url", "").startswith("https://www.krea.ai/moodboard-feed/") for board in catalog) assert all("image_urls" not in board for board in catalog) assert all(board.get("qwen_guidance", {}).get("prompt_guidance") for board in catalog) + + +def test_example_workflows_are_valid_json() -> None: + example_paths = sorted(Path("examples").glob("*.json")) + + assert example_paths + for path in example_paths: + payload = json.loads(path.read_text(encoding="utf-8")) + assert payload.get("nodes"), path + assert payload.get("version"), path diff --git a/tests/test_catalog.py b/tests/test_catalog.py index bd8df26..6fab00e 100644 --- a/tests/test_catalog.py +++ b/tests/test_catalog.py @@ -11,6 +11,7 @@ from moodboard_catalog import ( load_catalog, mashup_boards, random_board, + resolve_board_reference, search_boards, style_from_board, ) @@ -102,6 +103,58 @@ def test_random_board_is_deterministic_and_can_use_top_matches(tmp_path: Path) - assert first["uuid"] == second["uuid"] +def test_balanced_random_does_not_let_photo_styles_dominate() -> None: + photo_boards = [ + { + "url": f"https://www.krea.ai/moodboard-feed/photo-{index}", + "slug": f"photo-{index}", + "uuid": f"photo-{index}", + "title": f"Photo Style {index}", + "taste_profile": "cinematic photo lens documentary film look", + "keywords": ["photo", "cinematic"], + "qwen_guidance": { + "prompt_guidance": "Use photographic lens lighting and cinematic film texture.", + "negative_guidance": "", + "style_axes": ["photographic"], + "conditioning_notes": [], + "source_summary": "Photo style.", + }, + } + for index in range(20) + ] + illustration_board = { + "url": "https://www.krea.ai/moodboard-feed/illustration", + "slug": "illustration", + "uuid": "illustration", + "title": "Ink Illustration", + "taste_profile": "flat ink drawing and illustrated poster language", + "keywords": ["illustration", "ink"], + "qwen_guidance": { + "prompt_guidance": "Use ink illustration, flat shapes, and graphic poster texture.", + "negative_guidance": "", + "style_axes": ["illustration"], + "conditioning_notes": [], + "source_summary": "Illustration style.", + }, + } + catalog = photo_boards + [illustration_board] + + picks = [random_board(catalog, seed=seed, random_mode="balanced") for seed in range(100)] + + assert sum(board["uuid"] == "illustration" for board in picks) >= 25 + + +def test_resolve_board_reference_accepts_metadata_json_or_search_text(tmp_path: Path) -> None: + catalog = load_catalog(write_catalog(tmp_path / "catalog.json")) + metadata_ref = json.dumps({"uuid": "11111111-1111-5111-9111-111111111111"}) + + from_metadata = resolve_board_reference(catalog, metadata_ref) + from_search = resolve_board_reference(catalog, "warm product") + + assert from_metadata["title"] == "Abyssal Gothic" + assert from_search["title"] == "Warm Product Pastel" + + def test_style_from_board_returns_positive_negative_and_metadata(tmp_path: Path) -> None: catalog = load_catalog(write_catalog(tmp_path / "catalog.json")) @@ -140,6 +193,9 @@ def test_mashup_dedupes_negative_guidance_and_style_axes(tmp_path: Path) -> None assert "Abyssal Gothic" in mashup["positive"] assert "Warm Product Pastel" in mashup["positive"] + assert mashup["title"] == "Mashup: Abyssal Gothic + Warm Product Pastel" assert "Avoid flat bright daylight" in mashup["negative"] assert metadata["source_count"] == 2 assert "deep teal" in metadata["style_axes"] + assert "Abyssal Gothic" in mashup["preview"] + assert "Warm Product Pastel" in mashup["preview"] diff --git a/tests/test_nodes.py b/tests/test_nodes.py index 96593a1..69fd913 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -70,3 +70,55 @@ def test_apply_node_combines_prompt_and_style_metadata() -> None: assert "warm pastel lighting" in positive assert negative == "low quality, Avoid harsh contrast." assert json.loads(metadata_json)["title"] == "Warm Pastel" + + +def test_mashup_node_accepts_metadata_json_and_outputs_preview(monkeypatch) -> None: + boards = [ + { + "url": "https://www.krea.ai/moodboard-feed/gothic", + "slug": "gothic", + "uuid": "gothic-uuid", + "title": "Gothic Teal", + "taste_profile": "Deep teal gothic style.", + "keywords": ["gothic", "teal"], + "qwen_guidance": { + "prompt_guidance": "Use deep teal gothic lighting.", + "negative_guidance": "Avoid flat daylight.", + "style_axes": ["deep teal"], + "conditioning_notes": [], + "source_summary": "summary", + }, + }, + { + "url": "https://www.krea.ai/moodboard-feed/pastel", + "slug": "pastel", + "uuid": "pastel-uuid", + "title": "Pastel Product", + "taste_profile": "Warm product studio style.", + "keywords": ["pastel", "product"], + "qwen_guidance": { + "prompt_guidance": "Use warm pastel studio lighting.", + "negative_guidance": "Avoid harsh contrast.", + "style_axes": ["warm pastel"], + "conditioning_notes": [], + "source_summary": "summary", + }, + }, + ] + monkeypatch.setattr(nodes, "_catalog", lambda: boards) + + positive, negative, title, metadata_json, preview = nodes.KreaMoodboardMashup().mashup( + board_1=json.dumps({"uuid": "gothic-uuid"}), + board_2="pastel product", + weight_1=0.7, + weight_2=0.3, + strength="normal", + ) + + assert title == "Mashup: Gothic Teal + Pastel Product" + assert "Gothic Teal" in positive + assert "Pastel Product" in positive + assert "Avoid flat daylight" in negative + assert json.loads(metadata_json)["source_count"] == 2 + assert "Gothic Teal" in preview + assert "Paste metadata_json" in preview diff --git a/tests/test_registry_metadata.py b/tests/test_registry_metadata.py index e00f851..77bd77e 100644 --- a/tests/test_registry_metadata.py +++ b/tests/test_registry_metadata.py @@ -8,7 +8,7 @@ def test_pyproject_has_comfy_registry_metadata() -> None: pyproject = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8")) assert pyproject["project"]["name"] == "comfyui-krea-moodboards" - assert pyproject["project"]["version"] == "0.1.0" + assert pyproject["project"]["version"] == "0.1.1" assert pyproject["project"]["dependencies"] == [] assert pyproject["tool"]["comfy"]["PublisherId"] == "andrometa" assert pyproject["tool"]["comfy"]["DisplayName"] == "Krea Moodboards"