"""Role → model routing (charter §4/§5). Model choice is config, not law — a deploy, not a client patch. Read at call time so an env override needs no reimport. The provider abstraction (Ollama → Replicate) slots in here later (YAGNI now). """ from dataclasses import dataclass from . import config @dataclass(frozen=True) class RoleConfig: model: str options: dict think: bool | None = None # Ollama top-level `think`; None omits it def for_role(role: str) -> RoleConfig: if role == "narrator": return RoleConfig( model=config.narrator_model(), options={"temperature": 0.8, "top_p": 0.9, "num_predict": 300}, think=False, # qwen3.x thinking OFF; harmless on non-thinking models ) if role == "npc": return RoleConfig( model=config.npc_model(), options={"temperature": 0.8, "top_p": 0.9, "num_predict": 320}, think=False, ) raise KeyError(f"no routing for role: {role}")