Abhishek
Initialize project files and updated hackathon tags
485459a
Raw
History Blame Contribute Delete
4.22 kB
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Sequence
import json
from datetime import datetime, timezone
from .demo_pack_loader import DemoPack, MemorySeed, load_default_demo_pack
from .prompt_rewriter import RewriteResult, rewrite_memory
from .quilt import assemble_quilt, card_summaries, render_tile, save_image
@dataclass(frozen=True)
class QuiltState:
cards: tuple[RewriteResult, ...] = ()
style: str = "Fabric Quilt"
pack_id: str = ""
@dataclass(frozen=True)
class RenderResult:
quilt_path: Path
tile_path: Path
log_path: Path
cards: tuple[RewriteResult, ...]
def empty_state(style: str = "Fabric Quilt") -> QuiltState:
return QuiltState(cards=(), style=style, pack_id="")
def seed_state_from_pack(pack: DemoPack, count: int = 6) -> QuiltState:
cards = tuple(
rewrite_memory(memory.text, memory.location, pack.style)
for memory in pack.memories[: min(count, len(pack.memories))]
)
return QuiltState(cards=cards, style=pack.style, pack_id=pack.pack_id)
def add_memory_to_state(state: QuiltState, memory_text: str, location_tag: str = "", style: str | None = None, photo_path: str | None = None) -> tuple[QuiltState, RewriteResult]:
resolved_style = style or state.style or "Fabric Quilt"
card = rewrite_memory(memory_text, location_tag, resolved_style, photo_path=photo_path)
next_state = QuiltState(cards=state.cards + (card,), style=resolved_style, pack_id=state.pack_id)
return next_state, card
def build_quilt_image(state: QuiltState):
cards = list(state.cards)
if not cards:
raise ValueError("build_quilt_image requires at least one model-generated card")
return assemble_quilt(cards)
def build_single_tile(card: RewriteResult):
return render_tile(card)
def _timestamp_slug() -> str:
return datetime.now().strftime("%Y%m%d_%H%M%S")
def render_artifacts(state: QuiltState, output_dir: str | Path, stem: str = "memory_quilt") -> RenderResult:
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
cards = list(state.cards)
if not cards:
raise ValueError("render_artifacts requires at least one model-generated card")
quilt_image = assemble_quilt(cards)
tile_source = render_tile(cards[-1])
tile_backend = str(getattr(tile_source, "info", {}).get("backend", "flux-diffusers"))
tile_image = tile_source.convert("RGBA")
last_card = cards[-1]
last_meta = last_card.inference_meta if isinstance(last_card.inference_meta, dict) else {}
quilt_path = save_image(quilt_image, output_path / f"{stem}_quilt.png")
tile_path = save_image(tile_image, output_path / f"{stem}_tile.png")
log_path = output_path / f"{stem}_log.json"
log_payload = {
"rendered_at": datetime.now(timezone.utc).isoformat(),
"stem": stem,
"card_count": len(cards),
"cards": card_summaries(cards),
"tile_backend": tile_backend,
"model_id": str(last_meta.get("model_id") or last_card.selected_model_id),
"adapter_name": str(last_meta.get("adapter_name") or last_card.prompt_source),
"checkpoint_path": str(last_meta.get("checkpoint_path") or last_card.checkpoint_path),
"checkpoint_source": str(last_meta.get("checkpoint_source") or "unknown"),
"generation_stats": last_meta.get("generation_stats", {}),
"quilt_path": str(quilt_path),
"tile_path": str(tile_path),
}
log_path.write_text(json.dumps(log_payload, indent=2, ensure_ascii=False), encoding="utf-8")
return RenderResult(quilt_path=quilt_path, tile_path=tile_path, log_path=log_path, cards=tuple(cards))
def render_sample_pack(output_dir: str | Path, count: int = 6) -> tuple[QuiltState, RenderResult, DemoPack]:
pack = load_default_demo_pack()
state = seed_state_from_pack(pack, count=count)
result = render_artifacts(state, output_dir, stem=f"{pack.pack_id}_sample")
return state, result, pack
def state_summary(state: QuiltState) -> str:
if not state.cards:
return "0 stitched contributions"
return f"{len(state.cards)} stitched contribution(s) using {state.style}"