"""Shared dataclasses used across the package.""" from __future__ import annotations from dataclasses import dataclass, field from typing import Literal, Optional ColorStrategy = Literal["bg_mean_offset", "near_bg_dark", "near_bg_light", "fixed"] Position = Literal[ "bottom_middle", "top_middle", "top_left", "top_right", "bottom_left", "bottom_right", "center", ] @dataclass(frozen=True) class RenderSpec: """A fully-specified typographic overlay: the thing the optimizer searches over. Coordinates and font sizes are defined at a canonical 1024px reference and scaled to the true image size at render time. """ text: str font_family: str = "DejaVuSans" font_px: int = 14 # @1024 reference; readability floor ~8-10px alpha: float = 0.25 # 0..1; 0.25 still readable by VLMs color_strategy: ColorStrategy = "bg_mean_offset" brightness_offset: int = 20 # used by bg_mean_offset fixed_rgb: tuple[int, int, int] = (5, 5, 5) # used by color_strategy="fixed" position: Position = "bottom_middle" repetition: int = 1 # tiled copies in low-variance region(s) rotation_deg: float = 0.0 def key(self) -> str: """Stable string key for caching.""" return ( f"{self.text}|{self.font_family}|{self.font_px}|{self.alpha:.3f}|" f"{self.color_strategy}|{self.brightness_offset}|{self.fixed_rgb}|" f"{self.position}|{self.repetition}|{self.rotation_deg:.1f}" ) @dataclass class LabelResult: """The unified output of any Target: a parsed label plus provenance.""" parsed_label: str raw: str model: str latency_s: float = 0.0 cost_usd: float = 0.0 logprobs: Optional[dict] = None refused: bool = False error: Optional[str] = None @dataclass class StealthReport: """Human-imperceptibility metrics for a rendered candidate.""" psnr: float ssim: float lpips: float delta_e_p95: float passed: bool failures: list[str] = field(default_factory=list) @dataclass class Candidate: """A render spec plus all scores accumulated during optimization.""" spec: RenderSpec surrogate_fitness: float = 0.0 blackbox_fitness: float = 0.0 stealth: Optional[StealthReport] = None per_model_distance: dict[str, float] = field(default_factory=dict) reachability: float = 0.0 notes: dict = field(default_factory=dict)