Ctrl K
ComunidadGuías…

client/config.py

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""
Zentrale Konfiguration für den Nova GTK4-Client.

Alle veränderlichen Parameter (Server-Adressen, Farben, Fenstergrößen,
Timeouts, Logging-Einstellungen) werden hier gebündelt, damit andere
Module ausschließlich aus dieser Datei importieren.
"""

from dataclasses import dataclass
from pathlib import Path

# ─────────────────────────────────────────────
# Server-Verbindung
# ─────────────────────────────────────────────
SERVER_HOST = "localhost"
SERVER_PORT = 8000
SERVER_URL  = f"http://{SERVER_HOST}:{SERVER_PORT}"
WS_URL      = f"ws://{SERVER_HOST}:{SERVER_PORT}/ws"
SSE_URL     = f"{SERVER_URL}/chat/stream"
HEALTH_URL  = f"{SERVER_URL}/health"

# ─────────────────────────────────────────────
# Netzwerk-Timeouts (Sekunden)
# ─────────────────────────────────────────────
SSE_CONNECT_TIMEOUT: float       = 10.0   # requests-Connect-Timeout für SSE
SSE_READ_TIMEOUT                 = None   # None = kein Read-Timeout (Server entscheidet)
WS_RECONNECT_INTERVAL: float     = 5.0    # Wartezeit zwischen WS-Reconnect-Versuchen
WS_PING_INTERVAL: float          = 30.0   # Keepalive-Takt: erkennt die stumm gestorbene Leitung
WS_PING_TIMEOUT: float           = 10.0   # Frist auf ein Pong; muss unter WS_PING_INTERVAL liegen
SSE_STOP_WAIT_TIMEOUT: float     = 5.0    # Schlafzeit in der WS-Reconnect-Schleife (stopbar)
THREAD_SHUTDOWN_TIMEOUT: float   = 2.0    # Max. Wartezeit beim Join während Shutdown
PANEL_REQUEST_TIMEOUT: float     = 8.0    # Einheitlicher Timeout für Panel-Requests

# ─────────────────────────────────────────────
# Benutzer / Gesprächspaar
# ─────────────────────────────────────────────
DEFAULT_USER_ID: str   = "meister"
ASSISTANT_USER_ID: str = "nova"


@dataclass(frozen=True)
class GespraechsPerspektive:
    """Ein Eintrag im Perspektive-Selector.

    Jede Perspektive legt drei API-Parameter fest: welches Gespräch
    (``user_id`` + ``character_id``) geladen wird und aus wessen Sicht
    (``beobachter``) gefiltert wird.
    """

    label:        str   # Anzeige im Dropdown.
    user_id:      str
    character_id: str
    beobachter:   str   # "user" oder "assistant"


# Im Panel-Header wählbare Gesprächspaar-Perspektiven.
# Später dynamisch aus Config/DB befüllen (alle bekannten
# user_id/character_id-Paare jeweils zweimal — einmal pro Beobachter).
PERSPEKTIVEN: list[GespraechsPerspektive] = [
    GespraechsPerspektive(
        label        = "Meister — Gespräch mit Nova",
        user_id      = DEFAULT_USER_ID,
        character_id = ASSISTANT_USER_ID,
        beobachter   = "user",
    ),
    GespraechsPerspektive(
        label        = "Nova — Gespräch mit Meister",
        user_id      = DEFAULT_USER_ID,
        character_id = ASSISTANT_USER_ID,
        beobachter   = "assistant",
    ),
]

# ─────────────────────────────────────────────
# Chat-Darstellung (wird in das HTML-Template eingesetzt)
# ─────────────────────────────────────────────
MAX_MESSAGE_WIDTH_PERCENT = 80
USER_BUBBLE_COLOR         = "#2B5278"   # Blau, rechts (User)
ASSISTANT_BUBBLE_COLOR    = "#1A3A2A"   # Grün-dunkel, links (Nova)
IMPULSE_BUBBLE_COLOR      = "#2A3A1A"   # Grün-leicht, links (Pixie-Impulse)
IMPULSE_BORDER_COLOR      = "#4A7A3A"   # Akzent-Rand links an Impuls-Bubbles
UNZUGEORDNET_BORDER_COLOR = "#C46A2A"   # Rand an Antworten, die nicht zur letzten Frage gehören
BACKGROUND_COLOR          = "#1E1E1E"   # Dunkler Hintergrund
TEXT_COLOR                = "#E0E0E0"   # Heller Text
STAGE_TEXT_COLOR          = "#888"      # Pipeline-Stage (kursiv, zentriert)
TABLE_BORDER_COLOR        = "#444"      # Zellenrahmen in Markdown-Tabellen
LINK_COLOR                = "#6CA6E8"   # Anchor-Farbe in Chat-Bubbles
BLOCKQUOTE_BORDER_COLOR   = "#555"      # Linker Rand von >-Zitaten
BLOCKQUOTE_TEXT_COLOR     = "#AAA"      # Textfarbe in >-Zitaten
FONT_FAMILY               = "system-ui, sans-serif"
FONT_SIZE                 = "15px"

# ─────────────────────────────────────────────
# Hauptfenster
# ─────────────────────────────────────────────
WINDOW_TITLE          = "Nova"
WINDOW_DEFAULT_WIDTH  = 900
WINDOW_DEFAULT_HEIGHT = 700
WINDOW_MIN_WIDTH      = 400
WINDOW_MIN_HEIGHT     = 300

# Toolbar / Statusbar (GTK-CSS via main_window._apply_css)
TOOLBAR_BG_COLOR      = "#252525"
STATUSBAR_BG_COLOR    = "#181818"
STATUSBAR_TEXT_COLOR  = "#AAAAAA"

# ─────────────────────────────────────────────
# Radar-Chart — Cairo-Farben (RGBA-Tupel, je 0.0–1.0)
# ─────────────────────────────────────────────
RADAR_TITLE_COLOR:       tuple[float, float, float, float] = (0.6, 0.6, 0.6, 1.0)
RADAR_GRID_COLOR:        tuple[float, float, float, float] = (0.4, 0.4, 0.4, 0.3)
RADAR_DATA_FILL_COLOR:   tuple[float, float, float, float] = (0.3, 0.8, 0.3, 0.25)
RADAR_DATA_STROKE_COLOR: tuple[float, float, float, float] = (0.3, 0.8, 0.3, 0.8)
RADAR_DATA_DOT_COLOR:    tuple[float, float, float, float] = (0.3, 0.8, 0.3, 1.0)
RADAR_LABEL_COLOR:       tuple[float, float, float, float] = (0.7, 0.7, 0.7, 1.0)
# Der Punkt, der zeigt, wie weit das Ergebnis von der Nabe abliegt. Bewusst
# nicht das Grün der Speichenfläche: Er ist keine elfte Achse, sondern die
# aus allen Achsen gerechnete Bilanz.
RADAR_NABE_COLOR:        tuple[float, float, float, float] = (0.95, 0.65, 0.2, 1.0)

# ─────────────────────────────────────────────
# Avatar
# ─────────────────────────────────────────────
# Verzeichnis der Bildebenen (`base<i>.png`, `neck<i>.png`, `face<i>.png`), relativ
# zum Paket bestimmt. Die Bilder liegen nicht im Repositorium; fehlen sie, zeigt das
# Avatar-Panel eine Meldung statt des Gesichts.
AVATAR_IMAGE_DIR: Path = Path(__file__).resolve().parent / "avatar" / "images"

# ─────────────────────────────────────────────
# Logging
# ─────────────────────────────────────────────
LOG_FORMAT = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
LOG_LEVEL  = "DEBUG"