case0 / src /case_zero /constants.py
HusseinEid's picture
Case Zero - initial public release (fully local: Qwen2.5-1.5B via llama.cpp + Supertonic, custom pixel-noir SPA via gradio.Server)
414dc55
raw
history blame
1.63 kB
"""Project-wide constants. No secrets, no environment reads here (see config.py)."""
from __future__ import annotations
from pathlib import Path
from typing import Final
# Repository layout anchors. config.py resolves user-overridable paths from here.
PACKAGE_ROOT: Final[Path] = Path(__file__).resolve().parent
PROJECT_ROOT: Final[Path] = PACKAGE_ROOT.parent.parent
ASSETS_DIR: Final[Path] = PROJECT_ROOT / "assets"
SPRITES_DIR: Final[Path] = ASSETS_DIR / "sprites"
VOICES_DIR: Final[Path] = ASSETS_DIR / "voices"
FONTS_DIR: Final[Path] = ASSETS_DIR / "fonts"
CASES_DIR: Final[Path] = PROJECT_ROOT / "cases"
SEED_CASES_DIR: Final[Path] = CASES_DIR / "seeds"
MODELS_DIR: Final[Path] = PROJECT_ROOT / "models"
GRAMMARS_DIR: Final[Path] = PACKAGE_ROOT / "llm" / "grammars"
# Generation envelope. The model invents within these structural bounds so the
# mystery stays solvable; the bounds constrain shape, never creative content.
MIN_SUSPECTS: Final[int] = 3
MAX_SUSPECTS: Final[int] = 6
DAY_MINUTES: Final[int] = 24 * 60
# Interrogation pacing. Short, punchy suspect lines improve both UX and latency - and on
# a 2-vCPU CPU Space the prompt is reprocessed every turn, so a smaller rolling buffer is
# a direct latency win.
SPOKEN_MAX_TOKENS: Final[int] = 96
ROLLING_BUFFER_TURNS: Final[int] = 5
# Deception is reported by the model on a 0-100 scale but is advisory only;
# the deterministic director is the authority on whether a lie was caught.
DECEPTION_MIN: Final[int] = 0
DECEPTION_MAX: Final[int] = 100
# Schema version stamped onto persisted cases so old saves are detectable.
CASE_SCHEMA_VERSION: Final[str] = "1.0"