Spaces:
Sleeping
Sleeping
| """Central configuration for WitnessBox. | |
| One place for model ids, backend selection, audio rates, and game tuning so the | |
| rest of the codebase never hardcodes a magic number. Everything here is plain | |
| data; importing this module has no side effects and pulls in no heavy deps. | |
| """ | |
| from __future__ import annotations | |
| import os | |
| # --------------------------------------------------------------------------- # | |
| # Backend selection | |
| # --------------------------------------------------------------------------- # | |
| # "mock" -> pure-Python backends, no GPU/Modal needed; the whole loop runs | |
| # locally (this is the default so the app boots anywhere). | |
| # "modal" -> real models served from a deployed Modal app (see modal_app.py). | |
| BACKEND = os.environ.get("WITNESSBOX_BACKEND", "mock").strip().lower() | |
| # Name the Modal app is deployed under (`modal deploy modal_app.py`). | |
| MODAL_APP_NAME = os.environ.get("WITNESSBOX_MODAL_APP", "witnessbox") | |
| # If a Modal lookup fails (secrets unset, app not deployed), fall back to mock | |
| # rather than crashing the Space. Mirrors PRD risk #10 ("Space boots even if | |
| # Modal secrets unset"). Set to "0" to hard-fail instead (useful in CI). | |
| FALLBACK_TO_MOCK = os.environ.get("WITNESSBOX_FALLBACK_TO_MOCK", "1") != "0" | |
| # --------------------------------------------------------------------------- # | |
| # Models (all < 32B; combined ~12B) — ids verified in PRD.md / HACKATHON-CONTEXT.md | |
| # --------------------------------------------------------------------------- # | |
| WITNESS_LLM = "openbmb/MiniCPM4.1-8B" # 8.2B — witness's brain (clean text model; we run text-only, so the omni model's deps weren't worth it) | |
| WITNESS_VOICE = "openbmb/VoxCPM2" # 2B — the witness's voice; style = game state | |
| PLAYER_ASR = "nvidia/nemotron-speech-streaming-en-0.6b" # 0.6B — player transcription | |
| PLAYER_ASR_FALLBACK = "openai/whisper-small" # local fallback if Nemotron install fights us | |
| # --------------------------------------------------------------------------- # | |
| # Audio | |
| # --------------------------------------------------------------------------- # | |
| ASR_SR = 16_000 # ASR models expect 16 kHz mono | |
| VOICE_SR = 48_000 # VoxCPM2 emits 48 kHz | |
| # --------------------------------------------------------------------------- # | |
| # Game tuning | |
| # --------------------------------------------------------------------------- # | |
| CATCHES_TO_WIN = 3 # surface this many contradictions -> the witness breaks | |
| SOFT_TURN_BUDGET = 12 # narrative pacing target; not a hard cap | |
| # Player credibility = the lose resource. The judge excuses the witness at 0. | |
| CREDIBILITY_START = 100 | |
| CREDIBILITY_ON_CATCH = +12 # landing a contradiction restores standing with the bench | |
| CREDIBILITY_ON_WHIFF = -14 # a question that goes nowhere costs you | |
| # Witness composure = the continuous backing for the discrete witness tiers and | |
| # drives voice-style escalation. Starts high; each catch knocks it down a band. | |
| COMPOSURE_START = 100 | |
| COMPOSURE_ON_CATCH = -30 | |
| COMPOSURE_ON_PRESSURE = -4 # confident delivery with no catch still rattles him a little | |
| # Contradiction detector: minimum match score (0..1) to count as a catch. | |
| CATCH_THRESHOLD = 0.62 | |
| # Hard ceiling so a runaway session still terminates. | |
| MAX_TURNS = 24 | |