feat: resume fixes, OpenRouter templates, and project context
Delegate expected output filenames to modules so resume works for rembg and composite; normalize G'MIC multi-frame output; add OpenRouter style reference support with tests. Add Crusaders, orange, and team gallery pipelines plus SOUL/AGENTS context files. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
@@ -73,6 +74,92 @@ class TestAIParameters:
|
||||
assert params["model"] == "black-forest-labs/flux.2-klein-4b"
|
||||
assert params["strength"] == 0.3
|
||||
assert params["api_key_env"] == "OPENROUTER_API_KEY"
|
||||
assert params["template_image"] is None
|
||||
|
||||
def test_openrouter_accepts_template_image(self, tmp_path: Path) -> None:
|
||||
template = tmp_path / "ref.png"
|
||||
make_png(template)
|
||||
params = OpenRouterEditModule.validate_module_params(
|
||||
{"prompt": "match style", "template_image": template}
|
||||
)
|
||||
assert params["template_image"] == template
|
||||
|
||||
def test_build_payload_with_template(self) -> None:
|
||||
payload = OpenRouterEditModule._build_payload(
|
||||
"data:image/jpeg;base64,abc",
|
||||
"match colors",
|
||||
"google/gemini-3-pro-image",
|
||||
0.3,
|
||||
template_data_url="data:image/jpeg;base64,ref",
|
||||
)
|
||||
assert payload["modalities"] == ["image", "text"]
|
||||
assert "image_config" not in payload
|
||||
content = payload["messages"][0]["content"]
|
||||
assert content[0]["type"] == "text"
|
||||
assert "FIRST image" in content[0]["text"]
|
||||
assert content[1]["image_url"]["url"] == "data:image/jpeg;base64,ref"
|
||||
assert content[2]["image_url"]["url"] == "data:image/jpeg;base64,abc"
|
||||
|
||||
def test_build_payload_flux_keeps_strength(self) -> None:
|
||||
payload = OpenRouterEditModule._build_payload(
|
||||
"data:image/jpeg;base64,abc",
|
||||
"brighten",
|
||||
"black-forest-labs/flux.2-klein-4b",
|
||||
0.25,
|
||||
)
|
||||
assert payload["modalities"] == ["image"]
|
||||
assert payload["image_config"] == {"strength": 0.25}
|
||||
|
||||
def test_save_result_matching_source_preserves_png_size(
|
||||
self, tmp_path: Path
|
||||
) -> None:
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
pytest.skip("Pillow not installed")
|
||||
|
||||
source = tmp_path / "source.png"
|
||||
dest = tmp_path / "out.png"
|
||||
with Image.new("RGBA", (16, 12), (10, 20, 30, 128)) as image:
|
||||
image.save(source, format="PNG")
|
||||
|
||||
with Image.new("RGB", (8, 6), (200, 100, 50)) as edited:
|
||||
buffer = io.BytesIO()
|
||||
edited.save(buffer, format="PNG")
|
||||
result_bytes = buffer.getvalue()
|
||||
|
||||
OpenRouterEditModule._save_result_matching_source(source, result_bytes, dest)
|
||||
|
||||
with Image.open(dest) as saved:
|
||||
assert saved.size == (16, 12)
|
||||
assert saved.mode == "RGBA"
|
||||
assert saved.getchannel("A").getextrema() == (128, 128)
|
||||
|
||||
def test_missing_template_image_raises(
|
||||
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setenv("OPENROUTER_API_KEY", "test-key")
|
||||
src = tmp_path / "photo.png"
|
||||
make_png(src)
|
||||
output_dir = tmp_path / "out"
|
||||
output_dir.mkdir()
|
||||
ctx = ModuleContext(
|
||||
input_paths=[src],
|
||||
matched_groups=[],
|
||||
output_dir=output_dir,
|
||||
params=OpenRouterEditModule.validate_module_params(
|
||||
{
|
||||
"prompt": "match",
|
||||
"template_image": tmp_path / "missing.png",
|
||||
"max_edge": 0,
|
||||
}
|
||||
),
|
||||
pipeline_output_root=tmp_path,
|
||||
step_id="openrouter_edit_01",
|
||||
logger=None,
|
||||
)
|
||||
with pytest.raises(FileNotFoundError, match="Template image not found"):
|
||||
OpenRouterEditModule().run(ctx)
|
||||
|
||||
def test_comfy_requires_prompt(self) -> None:
|
||||
with pytest.raises(ValueError, match="required"):
|
||||
|
||||
Reference in New Issue
Block a user