| """Central configuration: single source of truth for thresholds, budgets, routing. |
| |
| Loads from environment / .env via pydantic-settings. Every tunable knob lives |
| here so the rest of the package reads defaults from one place. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from pydantic import Field |
| from pydantic_settings import BaseSettings, SettingsConfigDict |
|
|
|
|
| class StealthThresholds(BaseSettings): |
| """Hard gate thresholds for human-imperceptibility (from the research).""" |
|
|
| psnr_min: float = 38.0 |
| ssim_min: float = 0.94 |
| lpips_max: float = 0.10 |
| delta_e_p95_max: float = 2.0 |
|
|
|
|
| |
| |
| STEALTH_PRESETS: dict[str, dict[str, float]] = { |
| "strict": {"psnr_min": 38.0, "ssim_min": 0.94, "lpips_max": 0.10, "delta_e_p95_max": 2.0}, |
| "medium": {"psnr_min": 32.0, "ssim_min": 0.90, "lpips_max": 0.20, "delta_e_p95_max": 5.0}, |
| "loose": {"psnr_min": 26.0, "ssim_min": 0.82, "lpips_max": 0.40, "delta_e_p95_max": 12.0}, |
| } |
|
|
|
|
| def stealth_preset(level: str) -> StealthThresholds: |
| return StealthThresholds(**STEALTH_PRESETS[level]) |
|
|
|
|
| class Budget(BaseSettings): |
| """Query/spend caps. All paid pressure is isolated to Tier B.""" |
|
|
| max_blackbox_queries_per_image: int = 50 |
| top_k_to_validate: int = 4 |
| hard_usd_cap_per_image: float = 0.50 |
|
|
|
|
| class RobustnessSim(BaseSettings): |
| """Scraper-preprocessing simulation baked into fitness eval.""" |
|
|
| jpeg_quality: int = 85 |
| gaussian_blur_radius: float = 0.5 |
|
|
|
|
| class OptimizerConfig(BaseSettings): |
| """Tier A search shape. |
| |
| Grid size = decoys x grid_positions x grid_colors x |grid_font_px|. Each cell |
| scores every surrogate, so keep the product modest: with ~2s/call surrogates a |
| grid of ~50 cells is ~2 min/image. `grid_positions`/`grid_colors` cap how many |
| of the available positions/color strategies the coarse grid explores. |
| """ |
|
|
| decoy_shortlist_size: int = 4 |
| grid_font_px: tuple[int, ...] = (12, 20) |
| grid_positions: int = 2 |
| grid_colors: int = 2 |
| grid_alpha: float = 0.25 |
| tier_a_workers: int = 4 |
| evo_population: int = 6 |
| evo_generations: int = 4 |
| alpha_range: tuple[float, float] = (0.10, 0.35) |
| font_px_range: tuple[int, int] = (8, 24) |
| early_stop_epsilon: float = 1e-3 |
| early_stop_patience: int = 2 |
|
|
|
|
| class Settings(BaseSettings): |
| """Top-level settings, populated from environment / .env.""" |
|
|
| model_config = SettingsConfigDict( |
| env_file=".env", env_file_encoding="utf-8", extra="ignore" |
| ) |
|
|
| |
| openrouter_api_key: str = Field(default="", alias="OPENROUTER_API_KEY") |
| openrouter_base_url: str = "https://openrouter.ai/api/v1" |
| blackbox_target_models: tuple[str, ...] = ( |
| "openai/gpt-5.5", |
| "google/gemini-3.5-flash", |
| ) |
| embedding_model: str = "openai/text-embedding-3-small" |
|
|
| |
| |
| klaus3_qwen_base_url: str = Field( |
| default="http://127.0.0.1:8081/v1", alias="KLAUS3_QWEN_BASE_URL" |
| ) |
| klaus3_gemma4b_base_url: str = Field( |
| default="http://127.0.0.1:8082/v1", alias="KLAUS3_GEMMA4B_BASE_URL" |
| ) |
| klaus3_gemma12b_base_url: str = Field( |
| default="http://127.0.0.1:8080/v1", alias="KLAUS3_GEMMA12B_BASE_URL" |
| ) |
| klaus3_vision_service_url: str = Field( |
| default="http://127.0.0.1:8090", alias="KLAUS3_VISION_SERVICE_URL" |
| ) |
| |
| surrogate_models: tuple[str, ...] = ("qwen-3.5-4b", "gemma-4-4b") |
|
|
| |
| |
| aggregation: str = "mean" |
|
|
| |
| stealth: StealthThresholds = Field(default_factory=StealthThresholds) |
| budget: Budget = Field(default_factory=Budget) |
| robustness: RobustnessSim = Field(default_factory=RobustnessSim) |
| optimizer: OptimizerConfig = Field(default_factory=OptimizerConfig) |
|
|
| |
| cache_dir: str = ".cache" |
| artifacts_dir: str = "artifacts" |
|
|
|
|
| _settings: Settings | None = None |
|
|
|
|
| def get_settings(reload: bool = False) -> Settings: |
| """Process-wide singleton accessor for Settings.""" |
| global _settings |
| if _settings is None or reload: |
| _settings = Settings() |
| return _settings |
|
|