diff --git a/simple_syrup/third_party/groundingdino_runtime/util/slconfig.py b/simple_syrup/third_party/groundingdino_runtime/util/slconfig.py index 87aa481..fed5031 100644 --- a/simple_syrup/third_party/groundingdino_runtime/util/slconfig.py +++ b/simple_syrup/third_party/groundingdino_runtime/util/slconfig.py @@ -56,11 +56,11 @@ class SLConfig(object): [0, 1] >>> cfg = Config.fromfile('tests/data/config/a.py') >>> cfg.filename - "/tests/data/config/a.py" + "tests/data/config/a.py" >>> cfg.item4 'test' >>> cfg - "Config [path: /tests/data/config/a.py]: " + "Config [path: tests/data/config/a.py]: " "{'item1': [1, 2], 'item2': {'a': 0}, 'item3': True, 'item4': 'test'}" """ diff --git a/tests/test_anima_regional_diagnostics.py b/tests/test_anima_regional_diagnostics.py index 77d27cf..f903942 100644 --- a/tests/test_anima_regional_diagnostics.py +++ b/tests/test_anima_regional_diagnostics.py @@ -676,16 +676,16 @@ def _composition( model = ModelCloneLineage(uuid4(), uuid4()) cache = RegionalLoraExecutionCache() uses: tuple[tuple[AnimaLoraTarget, str, int, float], ...] = ( - (first_target, r"\one.safetensors", 0, 1.0), + (first_target, "private-adapter-path/one.safetensors", 0, 1.0), ( first_target, - r"\one.safetensors", + "private-adapter-path/one.safetensors", min(1, region_count - 1), 0.5, ), ( second_target, - r"\two.safetensors", + "private-adapter-path/two.safetensors", min(1, region_count - 1), -0.25, ), diff --git a/tests/test_anima_regional_permutation_diagnostics.py b/tests/test_anima_regional_permutation_diagnostics.py index b66e6f0..d8f5bd4 100644 --- a/tests/test_anima_regional_permutation_diagnostics.py +++ b/tests/test_anima_regional_permutation_diagnostics.py @@ -258,8 +258,8 @@ def test_region_and_adapter_order_permutations_change_safe_diagnostics( anima_surface, targets=(first, second), identities=( - r"\adapter-a.safetensors", - r"\adapter-b.safetensors", + "private/adapter-a.safetensors", + "private/adapter-b.safetensors", ), regions=(0, 1), ) @@ -267,8 +267,8 @@ def test_region_and_adapter_order_permutations_change_safe_diagnostics( anima_surface, targets=(first, second), identities=( - r"\adapter-a.safetensors", - r"\adapter-b.safetensors", + "private/adapter-a.safetensors", + "private/adapter-b.safetensors", ), regions=(1, 0), ) @@ -276,8 +276,8 @@ def test_region_and_adapter_order_permutations_change_safe_diagnostics( anima_surface, targets=(second, first), identities=( - r"\adapter-b.safetensors", - r"\adapter-a.safetensors", + "private/adapter-b.safetensors", + "private/adapter-a.safetensors", ), regions=(1, 0), ) @@ -295,7 +295,7 @@ def test_region_and_adapter_order_permutations_change_safe_diagnostics( tuple(use.adapter_token for use in adapter_permuted.adapter_uses), ) serialized = json.dumps(baseline.to_log_fields()) - assert r"" not in serialized + assert "private/" not in serialized assert [use.composition_index for use in baseline.adapter_uses] == [0, 1] diff --git a/tests/test_comfy_integration_baseline_workflow.py b/tests/test_comfy_integration_baseline_workflow.py index c7d03c6..c46f410 100644 --- a/tests/test_comfy_integration_baseline_workflow.py +++ b/tests/test_comfy_integration_baseline_workflow.py @@ -6,6 +6,11 @@ from __future__ import annotations +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) from tools.comfy_integration.baseline_workflow import build_baseline_workflow @@ -26,12 +31,12 @@ def test_baseline_is_small_deterministic_loader_to_saved_image_graph() -> None: } ) assert workflow.prompt["1"]["inputs"] == { - "diffusion_model": "Anima\\diffusion-model.safetensors", + "diffusion_model": ANIMA_DIFFUSION_SELECTION, "quantization": "Original", "diffusion_weight_dtype": "default", - "text_encoder": "qwen\\qwen_3_06b_base.safetensors", + "text_encoder": ANIMA_TEXT_ENCODER_SELECTION, "text_encoder_device": "default", - "vae": "qwen\\qwen_image_vae.safetensors", + "vae": ANIMA_VAE_SELECTION, } assert workflow.prompt["5"]["inputs"] == { "model": ["1", 0], diff --git a/tests/test_comfy_tool_defaults.py b/tests/test_comfy_tool_defaults.py new file mode 100644 index 0000000..8493f31 --- /dev/null +++ b/tests/test_comfy_tool_defaults.py @@ -0,0 +1,76 @@ +# SimpleSyrup - workflow-focused ComfyUI extensions for image generation +# Copyright (C) 2026 Artificial Sweetener and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +"""Verify portable managed-Comfy defaults and generic fixture selections.""" + +from __future__ import annotations + +from pathlib import Path + +import pytest + +from tools.comfy_integration.anima_fixture_selections import ANIMA_BASE_SELECTIONS +from tools.comfy_integration.default_paths import ( + COMFY_ROOT_ENVIRONMENT_VARIABLE, + default_benchmark_artifact_root, + default_comfy_root, + default_custom_node_root, + default_input_root, +) +from tools.comfy_integration.portable_font import load_label_font + + +def test_explicit_comfy_root_owns_every_derived_directory( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + """Derive all tool paths from one explicit host boundary.""" + + monkeypatch.setenv(COMFY_ROOT_ENVIRONMENT_VARIABLE, str(tmp_path)) + + assert default_comfy_root() == tmp_path.resolve() + assert default_input_root() == tmp_path.resolve() / "input" + assert default_benchmark_artifact_root("family/case") == ( + tmp_path.resolve() / "benchmark_artifacts" / "family" / "case" + ) + assert default_custom_node_root("sibling/node") == ( + tmp_path.resolve() / "custom_nodes" / "sibling" / "node" + ) + + +def test_comfy_root_and_suffixes_fail_closed( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Reject relative host roots and attempts to leave managed directories.""" + + monkeypatch.setenv(COMFY_ROOT_ENVIRONMENT_VARIABLE, "relative-root") + with pytest.raises(ValueError, match="must be an absolute path"): + default_comfy_root() + + monkeypatch.setenv(COMFY_ROOT_ENVIRONMENT_VARIABLE, str(Path.cwd())) + with pytest.raises(ValueError, match="must stay relative"): + default_benchmark_artifact_root("../outside") + + +def test_anima_fixture_selections_are_generic_managed_aliases() -> None: + """Keep real artifact identities outside repository workflow declarations.""" + + assert tuple(category for category, _ in ANIMA_BASE_SELECTIONS) == ( + "diffusion_models", + "text_encoders", + "vae", + ) + assert all( + selection.startswith("simple_syrup_anima\\") + for _, selection in ANIMA_BASE_SELECTIONS + ) + assert all( + "qwen" not in selection.casefold() for _, selection in ANIMA_BASE_SELECTIONS + ) + + +def test_label_font_has_no_operating_system_font_dependency() -> None: + """Load a readable bundled font without consulting a machine font path.""" + + assert load_label_font(20).getbbox("SimpleSyrup") is not None diff --git a/tests/test_node_tooltips.py b/tests/test_node_tooltips.py index d5f6804..329ae69 100644 --- a/tests/test_node_tooltips.py +++ b/tests/test_node_tooltips.py @@ -29,8 +29,8 @@ class _FakeFolderPaths(ModuleType): """Create deterministic ComfyUI filename lists.""" super().__init__("folder_paths") - self.models_dir = "\\models" - self.user_directory = "\\user" + self.models_dir = "models" + self.user_directory = "user" self._files = { "checkpoints": ["model.safetensors"], "diffusion_models": ["diffusion.safetensors"], diff --git a/tests/test_prompt_control_attention_coupling_cli.py b/tests/test_prompt_control_attention_coupling_cli.py index dba5b1b..6d22f15 100644 --- a/tests/test_prompt_control_attention_coupling_cli.py +++ b/tests/test_prompt_control_attention_coupling_cli.py @@ -4,17 +4,16 @@ """Verify the P9.1 managed coordinator remains a thin explicit entrypoint.""" -from pathlib import Path +import sys from subprocess import run def test_cli_help_exposes_managed_source_baseline_and_timeout_boundaries() -> None: """Keep external install and evidence locations caller-controlled.""" - python = Path(r"\venv\Scripts\python.exe") completed = run( [ - str(python), + sys.executable, "-m", "tools.run_prompt_control_attention_coupling_integration", "--help", diff --git a/tests/test_prompt_control_characterization_cli.py b/tests/test_prompt_control_characterization_cli.py index b66c3ad..dc8ab88 100644 --- a/tests/test_prompt_control_characterization_cli.py +++ b/tests/test_prompt_control_characterization_cli.py @@ -4,16 +4,15 @@ """Verify the Prompt Control coordinator remains a thin module entrypoint.""" -from pathlib import Path +import sys from subprocess import run def test_cli_help_exposes_explicit_external_boundaries() -> None: """Keep source root, loopback server, output, and timeout caller-controlled.""" - python = Path(r"\venv\Scripts\python.exe") completed = run( - [str(python), "-m", "tools.characterize_prompt_control", "--help"], + [sys.executable, "-m", "tools.characterize_prompt_control", "--help"], check=True, capture_output=True, text=True, diff --git a/tests/test_prompt_control_source_identity.py b/tests/test_prompt_control_source_identity.py index c64ac79..1a69176 100644 --- a/tests/test_prompt_control_source_identity.py +++ b/tests/test_prompt_control_source_identity.py @@ -8,6 +8,7 @@ from pathlib import Path import pytest +from tools.comfy_integration.default_paths import default_custom_node_root from tools.prompt_control_characterization.source_identity import ( inspect_source, validate_pinned_source, @@ -17,7 +18,7 @@ from tools.prompt_control_characterization.source_identity import ( def test_installed_prompt_control_matches_pinned_tracked_tree() -> None: """Pin version, path count, and canonical path-plus-content digest.""" - identity = inspect_source(Path(r"\custom_nodes\ComfyUI-Prompt-Control")) + identity = inspect_source(default_custom_node_root("ComfyUI-Prompt-Control")) validate_pinned_source(identity) assert identity.version == "3.0.0-beta.3" assert identity.tracked_path_count == 53 diff --git a/tests/test_repository_path_portability.py b/tests/test_repository_path_portability.py new file mode 100644 index 0000000..2cf6017 --- /dev/null +++ b/tests/test_repository_path_portability.py @@ -0,0 +1,34 @@ +# SimpleSyrup - workflow-focused ComfyUI extensions for image generation +# Copyright (C) 2026 Artificial Sweetener and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +"""Prevent executable repository code from acquiring machine-specific paths.""" + +from __future__ import annotations + +import re +from pathlib import Path + +REPOSITORY_ROOT = Path(__file__).resolve().parents[1] +EXECUTABLE_ROOTS = ( + REPOSITORY_ROOT / "simple_syrup", + REPOSITORY_ROOT / "tools", + REPOSITORY_ROOT / "tests", +) +WINDOWS_ABSOLUTE_PATH = re.compile(r"(? None: + """Require host paths to enter through runtime configuration owners.""" + + violations: list[str] = [] + for root in EXECUTABLE_ROOTS: + for source_path in root.rglob("*.py"): + source = source_path.read_text(encoding="utf-8") + if WINDOWS_ABSOLUTE_PATH.search(source) or POSIX_MACHINE_PATH.search( + source + ): + violations.append(str(source_path.relative_to(REPOSITORY_ROOT))) + + assert violations == [] diff --git a/tests/test_sdxl_visual_model_links.py b/tests/test_sdxl_visual_model_links.py index 475f0cc..6b258d8 100644 --- a/tests/test_sdxl_visual_model_links.py +++ b/tests/test_sdxl_visual_model_links.py @@ -62,6 +62,41 @@ def test_links_are_hard_links_and_cleanup_removes_only_owned_targets( assert not (loras / "simple_syrup_u11").exists() +def test_links_support_split_model_categories(tmp_path: Path) -> None: + """Expose split diffusion, text-encoder, and VAE fixtures transactionally.""" + + model_root = tmp_path / "models" + categories = ("diffusion_models", "text_encoders", "vae") + sources: list[Path] = [] + for category in categories: + (model_root / category).mkdir(parents=True) + source = tmp_path / f"{category}.safetensors" + source.write_bytes(category.encode()) + sources.append(source) + owner = ManagedComfyModelLinks( + model_root=model_root, + links=tuple( + ManagedModelLink( + source, + category, + f"managed/{category}.safetensors", + ) + for category, source in zip(categories, sources, strict=True) + ), + ) + + with owner: + assert all( + (model_root / category / "managed" / f"{category}.safetensors").is_file() + for category in categories + ) + + assert owner.cleaned + assert all( + not (model_root / category / "managed").exists() for category in categories + ) + + def test_collision_fails_before_creating_any_link(tmp_path: Path) -> None: """Refuse ambiguous ownership without touching the existing target.""" diff --git a/third_party/NOTICE.md b/third_party/NOTICE.md new file mode 100644 index 0000000..ef1fd92 --- /dev/null +++ b/third_party/NOTICE.md @@ -0,0 +1,57 @@ +# Third-Party Notices + +This repository vendors selected third-party behavior for runtime use. Each +vendored component is recorded in `third_party/manifest.toml`, and the +corresponding license text is stored in `third_party/licenses/`. + +## SAM-HQ and MobileSAM runtime + +SimpleSyrup vendors selected SAM-HQ and MobileSAM runtime files under +Apache-2.0 for loading SAM-family segmentation models inside ComfyUI. The +vendored runtime is kept under `simple_syrup/third_party/sam_hq_runtime/` +and preserves upstream copyright notices where the source files carried them. + +## GroundingDINO runtime + +SimpleSyrup vendors selected GroundingDINO runtime files under Apache-2.0 for +prompt-based box detection. The vendored runtime is kept under +`simple_syrup/third_party/groundingdino_runtime/` and preserves upstream +copyright notices where the source files carried them. + +## RES4LYF beta57 scheduler preset + +SimpleSyrup vendors the RES4LYF `beta57` scheduler preset under AGPL-3.0. +The preset uses ComfyUI's beta scheduler with `alpha=0.5` and `beta=0.7`. +SimpleSyrup resolves the preset locally for `KSampler (Extras)` and does not +patch ComfyUI's global scheduler registry. + +## AUTOMATIC1111 Euler a sampler integration + +SimpleSyrup vendors selected AUTOMATIC1111 WebUI sampler integration behavior +under AGPL-3.0. This provenance covers the `Euler a` sampler mapping, the +`Automatic` scheduler fallback behavior, and the documented decision not to +port AUTOMATIC1111 ENSD or RNG hijacking behavior. + +## k-diffusion Euler ancestral sampler + +SimpleSyrup vendors the Euler ancestral sampler loop from k-diffusion under +the MIT license. The local sampler keeps the A1111/k-diffusion loop structure +while running inside ComfyUI's deterministic seed system. + +## Mixture of Diffusers and MultiDiffusion tiled diffusion behavior + +SimpleSyrup reimplements tiled denoising behavior after +inspecting the local `multidiffusion-upscaler-for-automatic1111` extension, +which is licensed under CC-BY-NC-SA-4.0. The implementation preserves the +extension's latent tile planning, Mixture Gaussian tile weighting, +MultiDiffusion uniform tile averaging, regional prompt mask blending, and +pre-CFG model prediction blending behavior without importing the extension at +runtime. + +## SmilingWolf WD tagger models + +SimpleSyrup's `Tile & Tag SEGS` node can download selected SmilingWolf WD +tagger ONNX models and `selected_tags.csv` files at runtime from Hugging Face. +These model files are not vendored in this repository. The runtime catalog +points to the corresponding `SmilingWolf/*` repositories and stores downloaded +files in the user's ComfyUI model directory. diff --git a/tools/anima_attention_coupling_workflow.py b/tools/anima_attention_coupling_workflow.py index 9b9a6ee..90dcf8e 100644 --- a/tools/anima_attention_coupling_workflow.py +++ b/tools/anima_attention_coupling_workflow.py @@ -19,6 +19,11 @@ from tools.anima_latent_source_workflow import ( ) from tools.anima_workflow_graph import AnimaWorkflowGraph, NodeReference from tools.comfy_api import JsonObject +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) SEED = 1_029_384_756 WIDTH = 1024 @@ -178,12 +183,12 @@ class AnimaAttentionCouplingWorkflowBuilder: graph = AnimaWorkflowGraph() loader = graph.add( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ) loaded = ModifiedAnimaModel([loader, 0], [loader, 1]) modified = ( diff --git a/tools/anima_lora_characterization/workflow.py b/tools/anima_lora_characterization/workflow.py index b7034d7..626dff3 100644 --- a/tools/anima_lora_characterization/workflow.py +++ b/tools/anima_lora_characterization/workflow.py @@ -12,6 +12,11 @@ from pathlib import Path from tools.attention_coupling_benchmark.manifest_types import SamplingSettings from tools.comfy_api import JsonObject +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) from .matrix import AdapterDefinition, LoraRun @@ -48,12 +53,12 @@ class LoraWorkflowBuilder: graph = _Graph() loader = graph.add( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ) model_link: object = [loader, 0] if run.profile.mode == "static": diff --git a/tools/anima_regional_output_capture/workflow.py b/tools/anima_regional_output_capture/workflow.py index 31958b1..7d2f0de 100644 --- a/tools/anima_regional_output_capture/workflow.py +++ b/tools/anima_regional_output_capture/workflow.py @@ -10,6 +10,11 @@ import json from dataclasses import dataclass from tools.comfy_api import JsonObject +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) from .matrix import ( CFG, @@ -54,12 +59,12 @@ class VisualOutputWorkflowBuilder: graph = _Graph() loader = graph.add( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ) model: object = [loader, 0] for adapter in profile.global_adapters: diff --git a/tools/anima_regression_oracle/manifest.py b/tools/anima_regression_oracle/manifest.py index 07f8fb9..6f6aaa8 100644 --- a/tools/anima_regression_oracle/manifest.py +++ b/tools/anima_regression_oracle/manifest.py @@ -9,13 +9,15 @@ from __future__ import annotations from dataclasses import dataclass from pathlib import Path -DEFAULT_PERFORMANCE_ARTIFACT_INVENTORY = Path( - r"\benchmark_artifacts\execution-inventories" - r"\anima-performance-fresh-20260814.json" +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, ) -DEFAULT_MODEL_VISIBILITY_INVENTORY = Path( - r"\benchmark_artifacts\execution-inventories" - r"\anima-complete-oracle-model-visibility-20260817.json" + +DEFAULT_PERFORMANCE_ARTIFACT_INVENTORY = default_benchmark_artifact_root( + "execution-inventories/anima-performance-fresh-20260814.json" +) +DEFAULT_MODEL_VISIBILITY_INVENTORY = default_benchmark_artifact_root( + "execution-inventories/anima-complete-oracle-model-visibility-20260817.json" ) @@ -78,7 +80,7 @@ def default_manifest(repo_root: Path) -> AnimaRegressionManifest: ) ruff = str((repo_root / ".." / ".." / "venv" / "Scripts" / "ruff.exe").resolve()) mypy = str((repo_root / ".." / ".." / "venv" / "Scripts" / "mypy.exe").resolve()) - evidence_root = Path(r"\benchmark_artifacts\anima-regional-prompting-v1") + evidence_root = default_benchmark_artifact_root("anima-regional-prompting-v1") character_root = ( evidence_root / "user-prompt-character-ownership-proof" diff --git a/tools/anima_regression_oracle/model_visibility.py b/tools/anima_regression_oracle/model_visibility.py index 95bf707..d5ce744 100644 --- a/tools/anima_regression_oracle/model_visibility.py +++ b/tools/anima_regression_oracle/model_visibility.py @@ -18,12 +18,15 @@ from tools.anima_attention_coupling_prompts import ( PINNED_SECONDARY_ADAPTER, PINNED_TERTIARY_ADAPTER, ) +from tools.comfy_integration.anima_fixture_selections import ANIMA_BASE_SELECTIONS from tools.comfy_integration.managed_model_links import ( ManagedComfyModelLinks, ManagedModelLink, ) -ANIMA_ORACLE_ADAPTER_SELECTIONS = ( +ANIMA_ORACLE_MODEL_SELECTIONS = tuple( + selection_name for _, selection_name in ANIMA_BASE_SELECTIONS +) + ( PINNED_PRIMARY_ADAPTER, PINNED_SECONDARY_ADAPTER, PINNED_TERTIARY_ADAPTER, @@ -88,12 +91,12 @@ def anima_oracle_model_visibility( *, model_root: Path, ) -> ManagedOracleModelVisibility: - """Build the complete Anima oracle's declared adapter visibility scope.""" + """Build the complete Anima oracle's declared model visibility scope.""" return ManagedOracleModelVisibility.from_inventory( inventory_path, model_root=model_root, - required_selections=ANIMA_ORACLE_ADAPTER_SELECTIONS, + required_selections=ANIMA_ORACLE_MODEL_SELECTIONS, ) diff --git a/tools/anima_visual_performance_comparison/results.py b/tools/anima_visual_performance_comparison/results.py index 07e5be4..e8ba205 100644 --- a/tools/anima_visual_performance_comparison/results.py +++ b/tools/anima_visual_performance_comparison/results.py @@ -11,14 +11,13 @@ import io import json from pathlib import Path -from PIL import Image, ImageDraw, ImageFont +from PIL import Image, ImageDraw from tools.comfy_api import JsonObject +from tools.comfy_integration.portable_font import load_label_font from .cases import AnimaVisualCase -_FONT = Path(r"") - class AnimaVisualResultRecorder: """Own ordered images, timing evidence, and visible labels.""" @@ -102,7 +101,7 @@ def _label( canvas = Image.new("RGB", (1024, 1144), (20, 20, 20)) canvas.paste(image, (0, 120)) draw = ImageDraw.Draw(canvas) - draw.text((22, 15), label, fill="white", font=ImageFont.truetype(str(_FONT), 28)) + draw.text((22, 15), label, fill="white", font=load_label_font(28)) detail = ( f"30 steps · 1024×1024 · model {model_runtime / 1000:.2f}s · " f"wall {wall_runtime_ms / 1000:.2f}s" @@ -111,7 +110,7 @@ def _label( (22, 66), detail, fill=(205, 205, 205), - font=ImageFont.truetype(str(_FONT), 21), + font=load_label_font(21), ) canvas.save(path, format="PNG") diff --git a/tools/attention_coupling_benchmark/workflow.py b/tools/attention_coupling_benchmark/workflow.py index be08d8d..71831e5 100644 --- a/tools/attention_coupling_benchmark/workflow.py +++ b/tools/attention_coupling_benchmark/workflow.py @@ -8,6 +8,12 @@ from __future__ import annotations from dataclasses import dataclass +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) + from .manifest_types import ( BenchmarkCase, BenchmarkManifest, @@ -49,12 +55,12 @@ class BenchmarkWorkflowBuilder: prompt: Workflow = { "1": self._node( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ), "2": self._node( "SimpleSyrup.EncodePromptBatch", diff --git a/tools/benchmark_anima_regional_lora.py b/tools/benchmark_anima_regional_lora.py index 31fa337..c7f6efb 100644 --- a/tools/benchmark_anima_regional_lora.py +++ b/tools/benchmark_anima_regional_lora.py @@ -27,6 +27,9 @@ from tools.anima_regional_lora_performance.results import ( # noqa: E402 evaluate, write_result, ) +from tools.comfy_integration.default_paths import ( # noqa: E402 + default_benchmark_artifact_root, +) def main() -> int: @@ -71,9 +74,7 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--output-root", type=Path, - default=Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p5.7" - ), + default=default_benchmark_artifact_root("anima-regional-prompting-v1/p5.7"), ) return parser.parse_args() diff --git a/tools/benchmark_anima_regional_lora_scaling.py b/tools/benchmark_anima_regional_lora_scaling.py index 0b72bb8..1761034 100644 --- a/tools/benchmark_anima_regional_lora_scaling.py +++ b/tools/benchmark_anima_regional_lora_scaling.py @@ -21,6 +21,7 @@ from tools.anima_regional_lora_performance.matrix_results import ( from tools.anima_regional_lora_performance.matrix_runner import ( ANIMA_REGIONAL_LORA_SCALING_RUNNER, ) +from tools.comfy_integration.default_paths import default_benchmark_artifact_root def main() -> int: @@ -64,9 +65,8 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--output-root", type=Path, - default=Path( - r"\benchmark_artifacts\anima-regional-prompting-v1" - r"\p10.1\scaling-matrix" + default=default_benchmark_artifact_root( + "anima-regional-prompting-v1/p10.1/scaling-matrix" ), ) return parser.parse_args() diff --git a/tools/benchmark_attention_coupling.py b/tools/benchmark_attention_coupling.py index d3b8b95..ee67082 100644 --- a/tools/benchmark_attention_coupling.py +++ b/tools/benchmark_attention_coupling.py @@ -23,6 +23,10 @@ from tools.attention_coupling_benchmark.results import ( ) from tools.attention_coupling_benchmark.workflow import BenchmarkWorkflowBuilder from tools.comfy_api import LoopbackComfyClient +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_input_root, +) LOGGER = logging.getLogger("simple_syrup.attention_coupling_benchmark") @@ -132,14 +136,12 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--comfy-input-root", type=Path, - default=Path(r"\input"), + default=default_input_root(), ) parser.add_argument( "--output-root", type=Path, - default=Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p0.6" - ), + default=default_benchmark_artifact_root("anima-regional-prompting-v1/p0.6"), ) parser.add_argument("--prompt-timeout", type=float, default=1800.0) parser.add_argument("--max-runs", type=_positive_integer) diff --git a/tools/benchmark_sdxl_cold_upstream_trace.py b/tools/benchmark_sdxl_cold_upstream_trace.py index 23114c1..3fb34b8 100644 --- a/tools/benchmark_sdxl_cold_upstream_trace.py +++ b/tools/benchmark_sdxl_cold_upstream_trace.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, @@ -25,8 +29,8 @@ from tools.sdxl_full_strength_lora_fidelity.composition_cases import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-cold-upstream-trace" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-cold-upstream-trace" ) @@ -36,7 +40,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) args = parser.parse_args(argv) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") diff --git a/tools/benchmark_sdxl_conventional_variant_floor.py b/tools/benchmark_sdxl_conventional_variant_floor.py index 4a9ff1c..3d02768 100644 --- a/tools/benchmark_sdxl_conventional_variant_floor.py +++ b/tools/benchmark_sdxl_conventional_variant_floor.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, @@ -27,9 +31,8 @@ from tools.sdxl_regional_lora_performance.conventional_variant_runner import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter" - r"\sdxl-conventional-variant-floor" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-conventional-variant-floor" ) @@ -39,7 +42,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) args = parser.parse_args(argv) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") diff --git a/tools/benchmark_sdxl_materialization_parity.py b/tools/benchmark_sdxl_materialization_parity.py index 9adbee2..f3e7134 100644 --- a/tools/benchmark_sdxl_materialization_parity.py +++ b/tools/benchmark_sdxl_materialization_parity.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, @@ -25,8 +29,8 @@ from tools.sdxl_full_strength_lora_fidelity.composition_cases import ( from tools.sdxl_materialization_parity.runner import run_materialization_parity LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-materialization-parity" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-materialization-parity" ) @@ -36,7 +40,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) args = parser.parse_args(argv) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") diff --git a/tools/benchmark_sdxl_regional_lora.py b/tools/benchmark_sdxl_regional_lora.py index 60cc23b..ffc423e 100644 --- a/tools/benchmark_sdxl_regional_lora.py +++ b/tools/benchmark_sdxl_regional_lora.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, @@ -19,8 +23,8 @@ from tools.sdxl_attention_coupling_integration.visual_inventory import ( from tools.sdxl_regional_lora_performance.runner import run_steady_state_comparison LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-steady-state" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-steady-state" ) @@ -30,7 +34,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) args = parser.parse_args(argv) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") diff --git a/tools/benchmark_sdxl_regional_lora_cold_path.py b/tools/benchmark_sdxl_regional_lora_cold_path.py index 036526a..afb0e87 100644 --- a/tools/benchmark_sdxl_regional_lora_cold_path.py +++ b/tools/benchmark_sdxl_regional_lora_cold_path.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, @@ -27,8 +31,8 @@ from tools.sdxl_regional_lora_performance.cold_path_runner import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-cold-path" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-cold-path" ) @@ -38,7 +42,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) args = parser.parse_args(argv) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") diff --git a/tools/benchmark_sdxl_regional_lora_scaling.py b/tools/benchmark_sdxl_regional_lora_scaling.py index 6906b02..0ece8f8 100644 --- a/tools/benchmark_sdxl_regional_lora_scaling.py +++ b/tools/benchmark_sdxl_regional_lora_scaling.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, ) @@ -23,8 +27,8 @@ from tools.sdxl_regional_lora_performance.scaling_runner import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-active-use-scaling" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-active-use-scaling" ) @@ -34,7 +38,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) args = parser.parse_args(argv) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") diff --git a/tools/benchmark_sdxl_two_regional_loras.py b/tools/benchmark_sdxl_two_regional_loras.py index 157fc56..0d2ea0c 100644 --- a/tools/benchmark_sdxl_two_regional_loras.py +++ b/tools/benchmark_sdxl_two_regional_loras.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, @@ -27,8 +31,8 @@ from tools.sdxl_regional_lora_performance.matched_floor_runner import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-matched-floor" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-matched-floor" ) @@ -38,7 +42,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) args = parser.parse_args(argv) logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") diff --git a/tools/capture_anima_regional_outputs.py b/tools/capture_anima_regional_outputs.py index 319acfb..28db6b7 100644 --- a/tools/capture_anima_regional_outputs.py +++ b/tools/capture_anima_regional_outputs.py @@ -17,14 +17,18 @@ from tools.anima_regional_output_capture.workflow import VisualOutputWorkflowBui from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p5.7\visual" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p5.7/visual" ) diff --git a/tools/capture_sdxl_visual_diagnostics.py b/tools/capture_sdxl_visual_diagnostics.py index 720a691..a6aea1f 100644 --- a/tools/capture_sdxl_visual_diagnostics.py +++ b/tools/capture_sdxl_visual_diagnostics.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_case_selection import ( select_visual_cases, @@ -30,9 +34,9 @@ from tools.sdxl_full_strength_lora_fidelity.composition_cases import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-visual-diagnostics" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-visual-diagnostics" ) diff --git a/tools/characterize_anima_lora.py b/tools/characterize_anima_lora.py index c63e415..b73ad1c 100644 --- a/tools/characterize_anima_lora.py +++ b/tools/characterize_anima_lora.py @@ -27,6 +27,9 @@ from tools.anima_lora_characterization.workflow import LoraWorkflowBuilder from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.manifest_types import BenchmarkManifest from tools.comfy_api import JsonObject, LoopbackComfyClient +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, +) LOGGER = logging.getLogger("simple_syrup.anima_lora_characterization") @@ -196,9 +199,7 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--output-root", type=Path, - default=Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p0.7" - ), + default=default_benchmark_artifact_root("anima-regional-prompting-v1/p0.7"), ) parser.add_argument("--prompt-timeout", type=float, default=1800.0) parser.add_argument("--max-runs", type=_positive_integer) diff --git a/tools/characterize_prompt_control.py b/tools/characterize_prompt_control.py index 13d282e..24b6290 100644 --- a/tools/characterize_prompt_control.py +++ b/tools/characterize_prompt_control.py @@ -11,6 +11,10 @@ import logging from pathlib import Path from tools.comfy_api import JsonObject, LoopbackComfyClient +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_custom_node_root, +) from tools.prompt_control_characterization.cases import PromptControlCase, cases from tools.prompt_control_characterization.history_outputs import parse_outputs from tools.prompt_control_characterization.results import PromptControlResultRecorder @@ -141,15 +145,13 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--prompt-control-root", type=Path, - default=Path(r"\custom_nodes\ComfyUI-Prompt-Control"), + default=default_custom_node_root("ComfyUI-Prompt-Control"), ) parser.add_argument("--server-url", default="http://127.0.0.1:8297") parser.add_argument( "--output-root", type=Path, - default=Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p0.8" - ), + default=default_benchmark_artifact_root("anima-regional-prompting-v1/p0.8"), ) parser.add_argument("--prompt-timeout", type=float, default=600.0) return parser.parse_args() diff --git a/tools/comfy_integration/anima_fixture_selections.py b/tools/comfy_integration/anima_fixture_selections.py new file mode 100644 index 0000000..a8c5136 --- /dev/null +++ b/tools/comfy_integration/anima_fixture_selections.py @@ -0,0 +1,17 @@ +# SimpleSyrup - workflow-focused ComfyUI extensions for image generation +# Copyright (C) 2026 Artificial Sweetener and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +"""Name generic managed aliases for external Anima benchmark fixtures.""" + +from __future__ import annotations + +ANIMA_DIFFUSION_SELECTION = r"simple_syrup_anima\diffusion-model.safetensors" +ANIMA_TEXT_ENCODER_SELECTION = r"simple_syrup_anima\text-encoder.safetensors" +ANIMA_VAE_SELECTION = r"simple_syrup_anima\vae.safetensors" + +ANIMA_BASE_SELECTIONS = ( + ("diffusion_models", ANIMA_DIFFUSION_SELECTION), + ("text_encoders", ANIMA_TEXT_ENCODER_SELECTION), + ("vae", ANIMA_VAE_SELECTION), +) diff --git a/tools/comfy_integration/baseline_workflow.py b/tools/comfy_integration/baseline_workflow.py index c5c3d73..514b481 100644 --- a/tools/comfy_integration/baseline_workflow.py +++ b/tools/comfy_integration/baseline_workflow.py @@ -9,6 +9,11 @@ from __future__ import annotations from dataclasses import dataclass from tools.comfy_api import JsonObject +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) @dataclass(frozen=True) @@ -31,12 +36,12 @@ def build_baseline_workflow(run_id: str) -> BuiltBaselineWorkflow: graph = _Graph() loader = graph.add( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ) positive = graph.add("CLIPTextEncode", clip=[loader, 1], text="a red cube") negative = graph.add("CLIPTextEncode", clip=[loader, 1], text="low quality") diff --git a/tools/comfy_integration/default_paths.py b/tools/comfy_integration/default_paths.py new file mode 100644 index 0000000..baf5932 --- /dev/null +++ b/tools/comfy_integration/default_paths.py @@ -0,0 +1,59 @@ +# SimpleSyrup - workflow-focused ComfyUI extensions for image generation +# Copyright (C) 2026 Artificial Sweetener and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +"""Derive portable local paths for managed Comfy development tools.""" + +from __future__ import annotations + +import os +from pathlib import Path, PurePosixPath + +COMFY_ROOT_ENVIRONMENT_VARIABLE = "SIMPLE_SYRUP_COMFY_ROOT" + + +def default_comfy_root() -> Path: + """Return the explicit or installation-derived Comfy application root.""" + + configured = os.environ.get(COMFY_ROOT_ENVIRONMENT_VARIABLE) + if configured: + root = Path(configured).expanduser() + if not root.is_absolute(): + raise ValueError( + f"{COMFY_ROOT_ENVIRONMENT_VARIABLE} must be an absolute path." + ) + return root.resolve() + for candidate in Path(__file__).resolve().parents: + if (candidate / "main.py").is_file() and (candidate / "comfy").is_dir(): + return candidate + raise RuntimeError( + "Cannot locate the Comfy application root; set " + f"{COMFY_ROOT_ENVIRONMENT_VARIABLE}." + ) + + +def default_benchmark_artifact_root(relative_path: str = "") -> Path: + """Return a validated artifact directory beneath the active Comfy root.""" + + return default_comfy_root() / "benchmark_artifacts" / _relative_parts(relative_path) + + +def default_input_root() -> Path: + """Return the active Comfy input directory.""" + + return default_comfy_root() / "input" + + +def default_custom_node_root(relative_path: str) -> Path: + """Return a validated sibling custom-node path beneath the Comfy root.""" + + return default_comfy_root() / "custom_nodes" / _relative_parts(relative_path) + + +def _relative_parts(relative_path: str) -> Path: + """Normalize a portable relative path and reject root escape.""" + + normalized = PurePosixPath(relative_path.replace("\\", "/")) + if normalized.is_absolute() or any(part == ".." for part in normalized.parts): + raise ValueError("Managed Comfy path suffixes must stay relative.") + return Path(*normalized.parts) diff --git a/tools/comfy_integration/managed_model_links.py b/tools/comfy_integration/managed_model_links.py index 951d7dc..f6fe6d3 100644 --- a/tools/comfy_integration/managed_model_links.py +++ b/tools/comfy_integration/managed_model_links.py @@ -23,7 +23,9 @@ class ManagedModelLink: class ManagedComfyModelLinks: """Own temporary model visibility beneath known Comfy categories.""" - _CATEGORIES = frozenset({"checkpoints", "loras"}) + _CATEGORIES = frozenset( + {"checkpoints", "diffusion_models", "loras", "text_encoders", "vae"} + ) def __init__( self, diff --git a/tools/comfy_integration/portable_font.py b/tools/comfy_integration/portable_font.py new file mode 100644 index 0000000..9f20a11 --- /dev/null +++ b/tools/comfy_integration/portable_font.py @@ -0,0 +1,17 @@ +# SimpleSyrup - workflow-focused ComfyUI extensions for image generation +# Copyright (C) 2026 Artificial Sweetener and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +"""Load portable fonts for generated benchmark labels.""" + +from __future__ import annotations + +from PIL import ImageFont + + +def load_label_font(size: int) -> ImageFont.FreeTypeFont | ImageFont.ImageFont: + """Return Pillow's bundled font at the requested readable label size.""" + + if size <= 0: + raise ValueError("Label font size must be positive.") + return ImageFont.load_default(size=size) diff --git a/tools/global_lora_visual_proof/results.py b/tools/global_lora_visual_proof/results.py index 467ad2e..fee6560 100644 --- a/tools/global_lora_visual_proof/results.py +++ b/tools/global_lora_visual_proof/results.py @@ -10,9 +10,10 @@ import hashlib import json from pathlib import Path -from PIL import Image, ImageDraw, ImageFont +from PIL import Image, ImageDraw from tools.comfy_api import ImageReference, JsonObject +from tools.comfy_integration.portable_font import load_label_font from .matrix import GlobalLoraVisualCase @@ -142,8 +143,8 @@ class GlobalLoraVisualProofRecorder: header = 80 canvas = Image.new("RGB", (panel * 3, (panel + header) * 2), (20, 20, 20)) draw = ImageDraw.Draw(canvas) - title_font = ImageFont.truetype(r"", 24) - body_font = ImageFont.truetype(r"", 20) + title_font = load_label_font(24) + body_font = load_label_font(20) for index, case in enumerate(definitions): column = index % 3 row = index // 3 diff --git a/tools/global_style_character_proof/results.py b/tools/global_style_character_proof/results.py index 1f5d637..b87da72 100644 --- a/tools/global_style_character_proof/results.py +++ b/tools/global_style_character_proof/results.py @@ -10,9 +10,10 @@ import hashlib import json from pathlib import Path -from PIL import Image, ImageDraw, ImageFont +from PIL import Image, ImageDraw from tools.comfy_api import ImageReference, JsonObject +from tools.comfy_integration.portable_font import load_label_font from .matrix import GlobalStyleCharacterCase @@ -112,7 +113,7 @@ class GlobalStyleCharacterProofRecorder: panel = 1024 canvas = Image.new("RGB", (panel * 3, panel + header), (20, 20, 20)) draw = ImageDraw.Draw(canvas) - font = ImageFont.truetype(r"", 25) + font = load_label_font(25) for index, case in enumerate(definitions): with Image.open(self._images[case.case_id]) as source: image = source.convert("RGB") diff --git a/tools/measure_anima_regional_lora_vram.py b/tools/measure_anima_regional_lora_vram.py index 2e47742..9cd7a22 100644 --- a/tools/measure_anima_regional_lora_vram.py +++ b/tools/measure_anima_regional_lora_vram.py @@ -20,6 +20,9 @@ from tools.anima_regional_lora_performance.isolated_runner import ( from tools.anima_regional_lora_performance.matrix_manifest import ( default_scaling_manifest, ) +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, +) def main() -> int: @@ -50,7 +53,7 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--output-root", type=Path, - default=Path(r"\benchmark_artifacts\anima-regional-prompting-v1") + default=default_benchmark_artifact_root("anima-regional-prompting-v1") / "p10.1" / "isolated-vram", ) diff --git a/tools/profile_anima_regional_lora.py b/tools/profile_anima_regional_lora.py index cba0580..d371ffd 100644 --- a/tools/profile_anima_regional_lora.py +++ b/tools/profile_anima_regional_lora.py @@ -15,6 +15,9 @@ from tools.anima_regional_lora_performance.profiling import ( capture_performance_profiles, ) from tools.anima_regional_lora_performance.suite import performance_suite_session +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, +) def main() -> int: @@ -41,8 +44,8 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--output-root", type=Path, - default=Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p10.1\profiles" + default=default_benchmark_artifact_root( + "anima-regional-prompting-v1/p10.1/profiles" ), ) return parser.parse_args() diff --git a/tools/profile_anima_regional_lora_scaling.py b/tools/profile_anima_regional_lora_scaling.py index 83ca388..6e524a2 100644 --- a/tools/profile_anima_regional_lora_scaling.py +++ b/tools/profile_anima_regional_lora_scaling.py @@ -17,6 +17,7 @@ from tools.anima_regional_lora_performance.matrix_profiling import ( capture_scaling_profiles, ) from tools.anima_regional_lora_performance.matrix_suite import scaling_suite_session +from tools.comfy_integration.default_paths import default_benchmark_artifact_root def main() -> int: @@ -43,9 +44,8 @@ def _arguments() -> argparse.Namespace: parser.add_argument( "--output-root", type=Path, - default=Path( - r"\benchmark_artifacts\anima-regional-prompting-v1" - r"\p10.1\scaling-profiles" + default=default_benchmark_artifact_root( + "anima-regional-prompting-v1/p10.1/scaling-profiles" ), ) return parser.parse_args() diff --git a/tools/profile_sdxl_regional_lora_scaling.py b/tools/profile_sdxl_regional_lora_scaling.py index 993b7b6..18879c3 100644 --- a/tools/profile_sdxl_regional_lora_scaling.py +++ b/tools/profile_sdxl_regional_lora_scaling.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, ) @@ -23,8 +27,8 @@ from tools.sdxl_regional_lora_performance.scaling_profile_runner import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-active-use-profile" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-active-use-profile" ) @@ -34,7 +38,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) parser.add_argument("--call-index", type=_positive_call_index, default=30) args = parser.parse_args(argv) diff --git a/tools/prompt_control_attention_coupling_integration/baseline.py b/tools/prompt_control_attention_coupling_integration/baseline.py index cc9b914..079fce4 100644 --- a/tools/prompt_control_attention_coupling_integration/baseline.py +++ b/tools/prompt_control_attention_coupling_integration/baseline.py @@ -12,6 +12,9 @@ from dataclasses import dataclass from pathlib import Path from tools.comfy_api import JsonObject +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, +) from tools.prompt_control_characterization.cases import PromptControlCase, cases from tools.prompt_control_characterization.evidence_validation import validate_evidence from tools.prompt_control_characterization.history_outputs import PromptControlOutputs @@ -21,8 +24,8 @@ from tools.prompt_control_characterization.source_identity import ( PINNED_VERSION, ) -DEFAULT_BASELINE_PATH = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p0.8\result.json" +DEFAULT_BASELINE_PATH = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p0.8/result.json" ) diff --git a/tools/prompt_control_characterization/workflow.py b/tools/prompt_control_characterization/workflow.py index c704c0d..5a7de52 100644 --- a/tools/prompt_control_characterization/workflow.py +++ b/tools/prompt_control_characterization/workflow.py @@ -11,6 +11,11 @@ from dataclasses import dataclass from tools.anima_workflow_graph import AnimaWorkflowGraph, NodeReference from tools.comfy_api import JsonObject +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) from .cases import PromptControlCase from .conditioning import ( @@ -40,12 +45,12 @@ class PromptControlWorkflowBuilder: graph = AnimaWorkflowGraph() loader = graph.add( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ) expansion_spec = expansion_inputs(case) expansion = graph.add( diff --git a/tools/prove_sdxl_visual_registration.py b/tools/prove_sdxl_visual_registration.py index 9c3f7fc..27b84d3 100644 --- a/tools/prove_sdxl_visual_registration.py +++ b/tools/prove_sdxl_visual_registration.py @@ -13,6 +13,10 @@ from pathlib import Path from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer from tools.sdxl_attention_coupling_integration.visual_adapter_selections import ( @@ -37,9 +41,9 @@ from tools.sdxl_attention_coupling_integration.visual_workflow import ( build_sdxl_visual_workflow, ) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\u11-registration" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/u11-registration" ) _METADATA_NODE_IDS = ( "CheckpointLoaderSimple", diff --git a/tools/regional_strategy_comparison/workflow.py b/tools/regional_strategy_comparison/workflow.py index 3bb239a..d4189d8 100644 --- a/tools/regional_strategy_comparison/workflow.py +++ b/tools/regional_strategy_comparison/workflow.py @@ -13,6 +13,11 @@ from tools.anima_attention_coupling_conditioning import ( ) from tools.anima_workflow_graph import AnimaWorkflowGraph, NodeReference from tools.comfy_api import JsonObject +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) from .matrix import ( CFG, @@ -69,12 +74,12 @@ class StrategyComparisonWorkflowBuilder: graph = AnimaWorkflowGraph() loader = graph.add( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ) conditioning = ScheduledRegionalPromptConditioningWorkflow( global_loras=(), diff --git a/tools/regional_visual_benchmark/workflow.py b/tools/regional_visual_benchmark/workflow.py index 25d82a4..0b8e752 100644 --- a/tools/regional_visual_benchmark/workflow.py +++ b/tools/regional_visual_benchmark/workflow.py @@ -14,6 +14,11 @@ from tools.attention_coupling_benchmark.manifest_types import ( BenchmarkManifest, ) from tools.comfy_api import JsonObject +from tools.comfy_integration.anima_fixture_selections import ( + ANIMA_DIFFUSION_SELECTION, + ANIMA_TEXT_ENCODER_SELECTION, + ANIMA_VAE_SELECTION, +) from .matrix import ( CONTEXTUAL_GLOBAL_STEPS, @@ -171,12 +176,12 @@ class VisualBenchmarkWorkflowBuilder: return graph.add( "SimpleSyrup.SimpleLoadAnima", - diffusion_model="Anima\\diffusion-model.safetensors", + diffusion_model=ANIMA_DIFFUSION_SELECTION, quantization="Original", diffusion_weight_dtype="default", - text_encoder="qwen\\qwen_3_06b_base.safetensors", + text_encoder=ANIMA_TEXT_ENCODER_SELECTION, text_encoder_device="default", - vae="qwen\\qwen_image_vae.safetensors", + vae=ANIMA_VAE_SELECTION, ) @staticmethod diff --git a/tools/run_anima_attention_coupling_integration.py b/tools/run_anima_attention_coupling_integration.py index fb30c8d..c7ba3a5 100644 --- a/tools/run_anima_attention_coupling_integration.py +++ b/tools/run_anima_attention_coupling_integration.py @@ -27,14 +27,18 @@ from tools.anima_attention_coupling_workflow import HEIGHT, WIDTH from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p5.9" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p5.9" ) diff --git a/tools/run_anima_contextual_attention_coupling_integration.py b/tools/run_anima_contextual_attention_coupling_integration.py index 20a0bfd..54b2695 100644 --- a/tools/run_anima_contextual_attention_coupling_integration.py +++ b/tools/run_anima_contextual_attention_coupling_integration.py @@ -33,14 +33,18 @@ from tools.anima_contextual_attention_coupling_integration.workflow import ( from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p7.8" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p7.8" ) diff --git a/tools/run_anima_regional_lora_admission_integration.py b/tools/run_anima_regional_lora_admission_integration.py index f22cb8d..e9410b5 100644 --- a/tools/run_anima_regional_lora_admission_integration.py +++ b/tools/run_anima_regional_lora_admission_integration.py @@ -32,14 +32,18 @@ from tools.anima_regional_lora_admission_integration.workflow import ( from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p9.5" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p9.5" ) FIXTURE_NODE_ID = "SimpleSyrupBenchmark.CreateRegionalHookFixture" diff --git a/tools/run_anima_regional_nondiffusion_rejection_integration.py b/tools/run_anima_regional_nondiffusion_rejection_integration.py index 10107a0..6806d4c 100644 --- a/tools/run_anima_regional_nondiffusion_rejection_integration.py +++ b/tools/run_anima_regional_nondiffusion_rejection_integration.py @@ -32,13 +32,17 @@ from tools.anima_regional_nondiffusion_rejection_integration.results import ( from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p9.6" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p9.6" ) FIXTURE_NODE_ID = "SimpleSyrupBenchmark.CreateRegionalHookFixture" diff --git a/tools/run_anima_regression_oracle.py b/tools/run_anima_regression_oracle.py index b37ee05..10ebafa 100644 --- a/tools/run_anima_regression_oracle.py +++ b/tools/run_anima_regression_oracle.py @@ -36,13 +36,16 @@ from tools.anima_regression_oracle.model_visibility import ( # noqa: E402 from tools.anima_regression_oracle.results import ( # noqa: E402 AnimaRegressionResultRecorder, ) +from tools.comfy_integration.default_paths import ( # noqa: E402 + default_benchmark_artifact_root, +) from tools.sdxl_attention_coupling_integration.comfy_model_root import ( # noqa: E402 resolve_active_comfy_model_root, ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\anima-oracle" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/anima-oracle" ) diff --git a/tools/run_anima_tiled_attention_coupling_integration.py b/tools/run_anima_tiled_attention_coupling_integration.py index 7836ec2..3301df3 100644 --- a/tools/run_anima_tiled_attention_coupling_integration.py +++ b/tools/run_anima_tiled_attention_coupling_integration.py @@ -31,14 +31,18 @@ from tools.anima_tiled_attention_coupling_integration.workflow import ( from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p6.9" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p6.9" ) diff --git a/tools/run_anima_visual_performance_comparison.py b/tools/run_anima_visual_performance_comparison.py index dff6cbc..e4101a1 100644 --- a/tools/run_anima_visual_performance_comparison.py +++ b/tools/run_anima_visual_performance_comparison.py @@ -26,14 +26,18 @@ from tools.anima_visual_performance_comparison.workflow import ( ) from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\visual-performance-fresh" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/visual-performance-fresh" ) diff --git a/tools/run_character_ownership_proof.py b/tools/run_character_ownership_proof.py index f7c3960..10b31b0 100644 --- a/tools/run_character_ownership_proof.py +++ b/tools/run_character_ownership_proof.py @@ -11,16 +11,20 @@ import logging from pathlib import Path from typing import cast -from PIL import Image, ImageDraw, ImageFont +from PIL import Image, ImageDraw from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer +from tools.comfy_integration.portable_font import load_label_font LOGGER = logging.getLogger(__name__) -COMFY_ROOT = Path(r"") +COMFY_ROOT = default_comfy_root() OUTPUT_ROOT = ( COMFY_ROOT / "benchmark_artifacts" @@ -163,7 +167,7 @@ def _label(root: Path) -> None: canvas.paste(before, (0, header)) canvas.paste(after, (1024, header)) draw = ImageDraw.Draw(canvas) - font = ImageFont.truetype(r"", 28) + font = load_label_font(28) draw.text( (24, 30), "BEFORE — global self-attention takeover", fill="white", font=font ) diff --git a/tools/run_global_lora_visual_proof.py b/tools/run_global_lora_visual_proof.py index 179bb46..e56348f 100644 --- a/tools/run_global_lora_visual_proof.py +++ b/tools/run_global_lora_visual_proof.py @@ -16,6 +16,9 @@ from PIL import Image, ImageDraw from tools.comfy_api import ImageReference, JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer @@ -28,7 +31,7 @@ from tools.global_lora_visual_proof.matrix import ( from tools.global_lora_visual_proof.results import GlobalLoraVisualProofRecorder LOGGER = logging.getLogger(__name__) -COMFY_ROOT = Path(r"") +COMFY_ROOT = default_comfy_root() OUTPUT_ROOT = ( COMFY_ROOT / "benchmark_artifacts" diff --git a/tools/run_global_regional_lora_integration.py b/tools/run_global_regional_lora_integration.py index 2740934..e3508d5 100644 --- a/tools/run_global_regional_lora_integration.py +++ b/tools/run_global_regional_lora_integration.py @@ -18,6 +18,10 @@ from tools.anima_attention_coupling_workflow import HEIGHT, WIDTH from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer @@ -27,9 +31,9 @@ from tools.global_regional_lora_integration.results import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p9.3" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p9.3" ) diff --git a/tools/run_global_style_character_proof.py b/tools/run_global_style_character_proof.py index 599ba16..b416924 100644 --- a/tools/run_global_style_character_proof.py +++ b/tools/run_global_style_character_proof.py @@ -16,6 +16,9 @@ from PIL import Image, ImageDraw from tools.comfy_api import ImageReference, JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer @@ -29,7 +32,7 @@ from tools.global_style_character_proof.results import ( ) LOGGER = logging.getLogger(__name__) -COMFY_ROOT = Path(r"") +COMFY_ROOT = default_comfy_root() OUTPUT_ROOT = ( COMFY_ROOT / "benchmark_artifacts" diff --git a/tools/run_managed_comfy_baseline.py b/tools/run_managed_comfy_baseline.py index c8a6243..63e6c9e 100644 --- a/tools/run_managed_comfy_baseline.py +++ b/tools/run_managed_comfy_baseline.py @@ -13,14 +13,18 @@ from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts from tools.comfy_integration.baseline_workflow import build_baseline_workflow +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p0.9" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p0.9" ) diff --git a/tools/run_primary_adapter_ownership_proof.py b/tools/run_primary_adapter_ownership_proof.py index f1eb45b..78b31db 100644 --- a/tools/run_primary_adapter_ownership_proof.py +++ b/tools/run_primary_adapter_ownership_proof.py @@ -11,16 +11,20 @@ import logging from pathlib import Path from typing import cast -from PIL import Image, ImageDraw, ImageFont +from PIL import Image, ImageDraw from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer +from tools.comfy_integration.portable_font import load_label_font LOGGER = logging.getLogger(__name__) -COMFY_ROOT = Path(r"") +COMFY_ROOT = default_comfy_root() OUTPUT_ROOT = ( COMFY_ROOT / "benchmark_artifacts" @@ -165,7 +169,7 @@ def _label(root: Path) -> None: header = 96 canvas = Image.new("RGB", (3072, 1024 + header), color=(20, 20, 20)) draw = ImageDraw.Draw(canvas) - font = ImageFont.truetype(r"", 26) + font = load_label_font(26) for index, (path, label) in enumerate(zip(inputs, labels, strict=True)): image = Image.open(path).convert("RGB") if image.size != (1024, 1024): diff --git a/tools/run_prompt_control_attention_coupling_integration.py b/tools/run_prompt_control_attention_coupling_integration.py index 5ed6167..72260c1 100644 --- a/tools/run_prompt_control_attention_coupling_integration.py +++ b/tools/run_prompt_control_attention_coupling_integration.py @@ -18,6 +18,11 @@ from tools.anima_attention_coupling_integration.schema import ( from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, + default_custom_node_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer @@ -45,10 +50,10 @@ from tools.prompt_control_characterization.source_identity import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_PROMPT_CONTROL_ROOT = Path(r"\custom_nodes\ComfyUI-Prompt-Control") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p9.1" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_PROMPT_CONTROL_ROOT = default_custom_node_root("ComfyUI-Prompt-Control") +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p9.1" ) diff --git a/tools/run_regional_patch_interop_integration.py b/tools/run_regional_patch_interop_integration.py index 45451d2..12d5f0d 100644 --- a/tools/run_regional_patch_interop_integration.py +++ b/tools/run_regional_patch_interop_integration.py @@ -23,6 +23,10 @@ from tools.attention_coupling_benchmark.manifest_types import ModelArtifact from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer from tools.regional_patch_interop_integration.history import ( @@ -58,9 +62,9 @@ from tools.sdxl_attention_coupling_integration.checkpoint_link import ( LOGGER = logging.getLogger(__name__) REPOSITORY_ROOT = Path(__file__).resolve().parents[1] -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p9.7" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p9.7" ) METADATA_NODE_IDS = ( FULL_NODE_ID, diff --git a/tools/run_regional_strategy_comparison.py b/tools/run_regional_strategy_comparison.py index cd01258..881b1db 100644 --- a/tools/run_regional_strategy_comparison.py +++ b/tools/run_regional_strategy_comparison.py @@ -15,6 +15,10 @@ from pathlib import Path from tools.attention_coupling_benchmark.manifest import load_manifest from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer from tools.regional_strategy_comparison.history import parse_completed_evidence @@ -36,9 +40,9 @@ from tools.regional_strategy_comparison.workflow import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p10.2" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p10.2" ) diff --git a/tools/run_regional_visual_benchmark.py b/tools/run_regional_visual_benchmark.py index 9c7440b..2d36989 100644 --- a/tools/run_regional_visual_benchmark.py +++ b/tools/run_regional_visual_benchmark.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.attention_coupling_benchmark.manifest import load_manifest +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.regional_visual_benchmark.execution import ( DEFAULT_SEGMENT_SIZE, VisualCorpusExecutor, @@ -19,9 +23,9 @@ from tools.regional_visual_benchmark.execution import ( from tools.regional_visual_benchmark.run_artifacts import VisualBenchmarkRunArtifacts LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p10.3" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p10.3" ) diff --git a/tools/run_sdxl_attention_couple_parity.py b/tools/run_sdxl_attention_couple_parity.py index 0366457..58e7325 100644 --- a/tools/run_sdxl_attention_couple_parity.py +++ b/tools/run_sdxl_attention_couple_parity.py @@ -14,6 +14,10 @@ from pathlib import Path from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_model_links import ( @@ -54,9 +58,9 @@ from tools.sdxl_attention_coupling_integration.visual_masks import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\ra01-parity" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/ra01-parity" ) _CUSTOM_NODE_WHITELIST = ("SimpleSyrup", "substitute-backend", "comfyui-ppm") diff --git a/tools/run_sdxl_attention_coupling_integration.py b/tools/run_sdxl_attention_coupling_integration.py index 58a1ec8..45c3028 100644 --- a/tools/run_sdxl_attention_coupling_integration.py +++ b/tools/run_sdxl_attention_coupling_integration.py @@ -15,6 +15,10 @@ from pathlib import Path from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer from tools.sdxl_attention_coupling_integration.checkpoint_link import ( @@ -32,9 +36,9 @@ from tools.sdxl_attention_coupling_integration.workflow import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p8.5-sdxl" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p8.5-sdxl" ) diff --git a/tools/run_sdxl_composed_lora_completion.py b/tools/run_sdxl_composed_lora_completion.py index a62e10c..f57cf02 100644 --- a/tools/run_sdxl_composed_lora_completion.py +++ b/tools/run_sdxl_composed_lora_completion.py @@ -7,8 +7,10 @@ from __future__ import annotations from collections.abc import Sequence -from pathlib import Path +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, +) from tools.sdxl_attention_coupling_integration.selected_external_visual_runner import ( SelectedExternalVisualRun, ) @@ -16,8 +18,8 @@ from tools.sdxl_composed_lora_completion.cases import ( composed_lora_completion_cases, ) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\composed-lora-completion" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/composed-lora-completion" ) RUN = SelectedExternalVisualRun( description=__doc__ or "Run SDXL composed-LoRA visual proofs.", diff --git a/tools/run_sdxl_full_strength_lora_composition.py b/tools/run_sdxl_full_strength_lora_composition.py index ce42380..ab9eb52 100644 --- a/tools/run_sdxl_full_strength_lora_composition.py +++ b/tools/run_sdxl_full_strength_lora_composition.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_case_selection import ( select_visual_cases, @@ -30,9 +34,9 @@ from tools.sdxl_full_strength_lora_fidelity.composition_cases import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\full-strength-composition" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/full-strength-composition" ) diff --git a/tools/run_sdxl_full_strength_lora_fidelity.py b/tools/run_sdxl_full_strength_lora_fidelity.py index a9820e4..028837c 100644 --- a/tools/run_sdxl_full_strength_lora_fidelity.py +++ b/tools/run_sdxl_full_strength_lora_fidelity.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_adapter_selections import ( LEFT_CHARACTER_SELECTION, @@ -27,9 +31,9 @@ from tools.sdxl_full_strength_lora_fidelity.cases import ( from tools.sdxl_full_strength_lora_fidelity.execution import execute_fidelity_cases LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\full-strength-fidelity" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/full-strength-fidelity" ) diff --git a/tools/run_sdxl_global_lora_reference.py b/tools/run_sdxl_global_lora_reference.py index a808c4c..511afd2 100644 --- a/tools/run_sdxl_global_lora_reference.py +++ b/tools/run_sdxl_global_lora_reference.py @@ -14,6 +14,10 @@ from pathlib import Path from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_model_links import ( @@ -41,9 +45,9 @@ from tools.sdxl_global_lora_reference.workflow import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\ra05-native-global-lora-reference" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/ra05-native-global-lora-reference" ) diff --git a/tools/run_sdxl_lora_baseline_matrix.py b/tools/run_sdxl_lora_baseline_matrix.py index d5f378d..c9e5e0f 100644 --- a/tools/run_sdxl_lora_baseline_matrix.py +++ b/tools/run_sdxl_lora_baseline_matrix.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_couple_parity.cases import load_parity_case from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, @@ -25,9 +29,9 @@ from tools.sdxl_attention_coupling_integration.visual_matrix_execution import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-lora-baseline" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-lora-baseline" ) diff --git a/tools/run_sdxl_no_lora_comparison.py b/tools/run_sdxl_no_lora_comparison.py index 6413546..3a7868e 100644 --- a/tools/run_sdxl_no_lora_comparison.py +++ b/tools/run_sdxl_no_lora_comparison.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_coupling_integration.visual_inventory import ( SdxlVisualInventory, ) @@ -21,8 +25,8 @@ from tools.sdxl_attention_coupling_integration.visual_prompt_fixture import ( from tools.sdxl_no_lora_comparison.runner import run_no_lora_comparison LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-no-lora-comparison" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-no-lora-comparison" ) @@ -32,7 +36,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) parser.add_argument("--readiness-timeout", type=float, default=240.0) parser.add_argument("--prompt-timeout", type=float, default=1200.0) diff --git a/tools/run_sdxl_plain_ksampler_comparator.py b/tools/run_sdxl_plain_ksampler_comparator.py index 13462b0..e2b5dcb 100644 --- a/tools/run_sdxl_plain_ksampler_comparator.py +++ b/tools/run_sdxl_plain_ksampler_comparator.py @@ -17,6 +17,10 @@ from typing import cast from tools.comfy_api import JsonObject from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_model_links import ( @@ -39,9 +43,9 @@ from tools.sdxl_full_strength_lora_fidelity.plain_workflow import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\plain-ksampler" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/plain-ksampler" ) diff --git a/tools/run_sdxl_post_optimization_visual_proof.py b/tools/run_sdxl_post_optimization_visual_proof.py index eb1ebdf..dec1785 100644 --- a/tools/run_sdxl_post_optimization_visual_proof.py +++ b/tools/run_sdxl_post_optimization_visual_proof.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_coupling_integration.sampling_controls import ( SDXL_VISUAL_SAMPLING, ) @@ -32,8 +36,8 @@ from tools.sdxl_post_optimization_visual_proof.cases import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\post-cache-visual-proof" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/post-cache-visual-proof" ) @@ -43,7 +47,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) parser.add_argument("--case-id", action="append", default=[]) parser.add_argument("--seed", type=int, default=SDXL_VISUAL_SAMPLING.seed) diff --git a/tools/run_sdxl_regional_lora_operator_profile.py b/tools/run_sdxl_regional_lora_operator_profile.py index 5a9e27f..edf9ca9 100644 --- a/tools/run_sdxl_regional_lora_operator_profile.py +++ b/tools/run_sdxl_regional_lora_operator_profile.py @@ -13,6 +13,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer from tools.sdxl_attention_couple_parity.cases import load_parity_case @@ -49,8 +53,8 @@ from tools.sdxl_regional_lora_performance.two_adapter_workflow import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-operator-profile" +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-operator-profile" ) @@ -60,7 +64,7 @@ def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=DEFAULT_OUTPUT_ROOT) parser.add_argument( "--mode", diff --git a/tools/run_sdxl_regional_lora_visual_matrix.py b/tools/run_sdxl_regional_lora_visual_matrix.py index 79baf96..5128393 100644 --- a/tools/run_sdxl_regional_lora_visual_matrix.py +++ b/tools/run_sdxl_regional_lora_visual_matrix.py @@ -12,6 +12,10 @@ from collections.abc import Sequence from pathlib import Path from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.sdxl_attention_coupling_integration.visual_case_selection import ( select_visual_cases, ) @@ -24,10 +28,8 @@ from tools.sdxl_attention_coupling_integration.visual_matrix_execution import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\universal-regional-adapter\u11" -) +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root("universal-regional-adapter/u11") def main(argv: Sequence[str] | None = None) -> int: diff --git a/tools/run_sdxl_schedule_mask_completion.py b/tools/run_sdxl_schedule_mask_completion.py index 4593692..05d4206 100644 --- a/tools/run_sdxl_schedule_mask_completion.py +++ b/tools/run_sdxl_schedule_mask_completion.py @@ -7,8 +7,8 @@ from __future__ import annotations from collections.abc import Sequence -from pathlib import Path +from tools.comfy_integration.default_paths import default_benchmark_artifact_root from tools.sdxl_attention_coupling_integration.selected_external_visual_runner import ( SelectedExternalVisualRun, ) @@ -18,9 +18,8 @@ from tools.sdxl_schedule_mask_completion.cases import ( RUN = SelectedExternalVisualRun( description=__doc__ or "Run SDXL schedule and mask-geometry proofs.", - output_root=Path( - r"\benchmark_artifacts\universal-regional-adapter" - r"\ra06-schedule-mask-completion" + output_root=default_benchmark_artifact_root( + "universal-regional-adapter/ra06-schedule-mask-completion" ), log_label="SDXL schedule and mask-geometry proof", case_factory=schedule_mask_completion_cases, diff --git a/tools/run_sdxl_spatial_mode_oracle.py b/tools/run_sdxl_spatial_mode_oracle.py index 0eae4fd..e870d71 100644 --- a/tools/run_sdxl_spatial_mode_oracle.py +++ b/tools/run_sdxl_spatial_mode_oracle.py @@ -7,8 +7,8 @@ from __future__ import annotations from collections.abc import Sequence -from pathlib import Path +from tools.comfy_integration.default_paths import default_benchmark_artifact_root from tools.sdxl_attention_coupling_integration.selected_external_visual_runner import ( SelectedExternalVisualRun, ) @@ -16,9 +16,8 @@ from tools.sdxl_spatial_mode_oracle import spatial_mode_oracle_cases RUN = SelectedExternalVisualRun( description=__doc__ or "Run the SDXL spatial-mode oracle.", - output_root=Path( - r"\benchmark_artifacts\universal-regional-adapter" - r"\sdxl-spatial-mode-oracle" + output_root=default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-spatial-mode-oracle" ), log_label="SDXL spatial-mode oracle", case_factory=spatial_mode_oracle_cases, diff --git a/tools/run_sdxl_two_character_oracle.py b/tools/run_sdxl_two_character_oracle.py index 5e5a0ad..1ab986d 100644 --- a/tools/run_sdxl_two_character_oracle.py +++ b/tools/run_sdxl_two_character_oracle.py @@ -7,8 +7,10 @@ from __future__ import annotations from collections.abc import Sequence -from pathlib import Path +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, +) from tools.sdxl_attention_coupling_integration.selected_external_visual_runner import ( SelectedExternalVisualRun, ) @@ -16,8 +18,8 @@ from tools.sdxl_two_character_oracle import two_character_oracle_cases RUN = SelectedExternalVisualRun( description=__doc__ or "Run the SDXL two-character oracle.", - output_root=Path( - r"\benchmark_artifacts\universal-regional-adapter\sdxl-two-character-oracle" + output_root=default_benchmark_artifact_root( + "universal-regional-adapter/sdxl-two-character-oracle" ), log_label="SDXL two-character oracle", case_factory=two_character_oracle_cases, diff --git a/tools/run_text_encoder_lora_integration.py b/tools/run_text_encoder_lora_integration.py index 879461c..fb3b67f 100644 --- a/tools/run_text_encoder_lora_integration.py +++ b/tools/run_text_encoder_lora_integration.py @@ -38,6 +38,10 @@ from tools.anima_tiled_attention_coupling_integration.schema import ( from tools.attention_coupling_benchmark.manifest import load_manifest from tools.attention_coupling_benchmark.mask_artifacts import MaskArtifactWriter from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_benchmark_artifact_root, + default_comfy_root, +) from tools.comfy_integration.history_output import extract_saved_image from tools.comfy_integration.loopback_port import is_loopback_port_available from tools.comfy_integration.managed_server import ManagedComfyServer @@ -58,9 +62,9 @@ from tools.text_encoder_lora_integration.workflow import ( ) LOGGER = logging.getLogger(__name__) -DEFAULT_COMFY_ROOT = Path(r"") -DEFAULT_OUTPUT_ROOT = Path( - r"\benchmark_artifacts\anima-regional-prompting-v1\p9.4" +DEFAULT_COMFY_ROOT = default_comfy_root() +DEFAULT_OUTPUT_ROOT = default_benchmark_artifact_root( + "anima-regional-prompting-v1/p9.4" ) diff --git a/tools/sdxl_attention_coupling_integration/selected_external_visual_runner.py b/tools/sdxl_attention_coupling_integration/selected_external_visual_runner.py index de1938a..70f744a 100644 --- a/tools/sdxl_attention_coupling_integration/selected_external_visual_runner.py +++ b/tools/sdxl_attention_coupling_integration/selected_external_visual_runner.py @@ -14,6 +14,9 @@ from pathlib import Path from typing import TypeAlias from tools.comfy_integration.artifacts import IntegrationArtifacts +from tools.comfy_integration.default_paths import ( + default_comfy_root, +) from .visual_case_model import SdxlVisualCase from .visual_case_selection import select_visual_cases @@ -46,7 +49,7 @@ class SelectedExternalVisualRun: parser.add_argument("--inventory", type=Path, required=True) parser.add_argument("--prompt-case", type=Path, required=True) parser.add_argument("--case-id", action="append", required=True) - parser.add_argument("--comfy-root", type=Path, default=Path(r"")) + parser.add_argument("--comfy-root", type=Path, default=default_comfy_root()) parser.add_argument("--output-root", type=Path, default=self.output_root) parser.add_argument("--readiness-timeout", type=float, default=240.0) parser.add_argument("--prompt-timeout", type=float, default=1200.0) diff --git a/tools/sdxl_global_lora_reference/results.py b/tools/sdxl_global_lora_reference/results.py index 03e40ee..e7338e0 100644 --- a/tools/sdxl_global_lora_reference/results.py +++ b/tools/sdxl_global_lora_reference/results.py @@ -11,14 +11,13 @@ import io import json from pathlib import Path -from PIL import Image, ImageDraw, ImageFont +from PIL import Image, ImageDraw from tools.comfy_api import JsonObject +from tools.comfy_integration.portable_font import load_label_font from .workflow import GLOBAL_LORA_STRENGTH, BuiltNativeGlobalLoraWorkflow -_FONT_PATH = Path(r"") - class NativeGlobalLoraResultRecorder: """Own exact and labeled evidence for one individually presented image.""" @@ -110,8 +109,8 @@ def _write_labeled(image: Image.Image, path: Path, label: str) -> None: canvas = Image.new("RGB", (1024, 1024 + header_height), (20, 20, 20)) canvas.paste(image, (0, header_height)) draw = ImageDraw.Draw(canvas) - title_font = ImageFont.truetype(str(_FONT_PATH), 30) - detail_font = ImageFont.truetype(str(_FONT_PATH), 21) + title_font = load_label_font(30) + detail_font = load_label_font(21) draw.text((24, 18), label, fill="white", font=title_font) draw.text( (24, 66),