"""Settings for semif-serve. Contract: semif-serve.contract.md ยง Configuration. Every value is validated at startup and a bad one is refused with a ValueError naming the variable: a service that starts and then rejects every request (or runs uncapped) is worse than one that does not start (bug hunt 2026-09-27: C1, S1, S2, S8). """ from __future__ import annotations import json import math from collections.abc import Mapping from dataclasses import dataclass, field from pathlib import Path MIN_TOKEN_CHARS = 32 MIN_TEMPERATURE, MAX_TEMPERATURE = 0.05, 20.0 SEMIF_COMMIT = "23cf1f39fc9534fe81437200959b6dfc7106e45a" DEFAULT_MODEL = "Qwen/Qwen3.5-4B" DEFAULT_REVISION = "851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a" @dataclass(frozen=True) class Settings: api_token: str model: str = DEFAULT_MODEL revision: str = DEFAULT_REVISION device: str = "cuda" vram_cap_gib: float | None = None max_tokens: int = 4096 max_decisions: int = 64 max_body_bytes: int = 1024 * 1024 max_queue: int = 32 calibration: dict[str, float] = field(default_factory=dict) @classmethod def from_env(cls, env: Mapping[str, str]) -> "Settings": token = env.get("SEMIF_API_TOKEN", "") # INV-6: visible ASCII only. A CR, LF or NUL can never arrive in a header, so a token # carrying one would lock every caller out while /health still said ok. if len(token) < MIN_TOKEN_CHARS or not all(33 <= ord(c) <= 126 for c in token): raise ValueError(f"SEMIF_API_TOKEN must be at least {MIN_TOKEN_CHARS} visible ASCII characters") return cls( api_token=token, model=env.get("SEMIF_MODEL", DEFAULT_MODEL), revision=env.get("SEMIF_REVISION", DEFAULT_REVISION), device=env.get("SEMIF_DEVICE", "cuda"), vram_cap_gib=_positive_float(env, "SEMIF_VRAM_CAP_GIB"), max_tokens=_positive_int(env, "SEMIF_MAX_TOKENS", 4096), max_decisions=_positive_int(env, "SEMIF_MAX_DECISIONS", 64), max_body_bytes=_positive_int(env, "SEMIF_MAX_BODY_BYTES", 1024 * 1024), max_queue=_positive_int(env, "SEMIF_MAX_QUEUE", 32), calibration=_load_calibration(env.get("SEMIF_CALIBRATION")), ) def _positive_int(env: Mapping[str, str], name: str, default: int) -> int: raw = env.get(name) if raw is None: return default try: value = int(raw) except ValueError: raise ValueError(f"{name} must be an integer, got {raw!r}") from None if value < 1: raise ValueError(f"{name} must be >= 1, got {value}") return value def _positive_float(env: Mapping[str, str], name: str) -> float | None: """Unset means no cap. When set it must be finite and > 0: `0` used to slip through as 'no cap'.""" raw = env.get(name) if raw is None or raw == "": return None try: value = float(raw) except ValueError: raise ValueError(f"{name} must be a number, got {raw!r}") from None if not math.isfinite(value) or value <= 0: raise ValueError(f"{name} must be a finite number > 0, got {raw!r}") return value def _load_calibration(path: str | None) -> dict[str, float]: """{workload: T}; T scales option logits before softmax, so it is kept in a sane range (a tiny T overflows to NaN and the response then fails to render).""" if not path: return {} try: table = json.loads(Path(path).read_text()) except (OSError, ValueError) as exc: raise ValueError(f"SEMIF_CALIBRATION {path!r} could not be read as JSON: {exc}") from None if not isinstance(table, dict) or not all( isinstance(t, (int, float)) and not isinstance(t, bool) and math.isfinite(t) and MIN_TEMPERATURE <= t <= MAX_TEMPERATURE for t in table.values() ): raise ValueError(f"SEMIF_CALIBRATION must be a JSON object of workload -> temperature in " f"[{MIN_TEMPERATURE}, {MAX_TEMPERATURE}]") return {str(k): float(v) for k, v in table.items()}