Spaces:
Sleeping
Sleeping
File size: 3,272 Bytes
c519923 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | """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
|