File size: 1,631 Bytes
414dc55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""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"