File size: 2,498 Bytes
f4d9ca1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250666a
f4d9ca1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8e98f03
 
 
 
 
250666a
 
 
 
 
 
 
 
09213ce
 
 
 
 
f4d9ca1
 
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
"""Central configuration, loaded from environment / .env."""
from __future__ import annotations

import os
from dataclasses import dataclass

from dotenv import load_dotenv

load_dotenv()


def _int(name: str, default: int) -> int:
    try:
        return int(os.getenv(name, str(default)))
    except ValueError:
        return default


@dataclass(frozen=True)
class Config:
    # LLM
    llm_provider: str = os.getenv("LLM_PROVIDER", "anthropic").lower()
    ollama_model: str = os.getenv("OLLAMA_MODEL", "qwen2.5:7b-instruct")
    ollama_host: str = os.getenv("OLLAMA_HOST", "http://localhost:11434")
    anthropic_api_key: str = os.getenv("ANTHROPIC_API_KEY", "")
    anthropic_model: str = os.getenv("ANTHROPIC_MODEL", "claude-haiku-4-5-20251001")

    # Embeddings
    embed_model: str = os.getenv("EMBED_MODEL", "sentence-transformers/all-MiniLM-L6-v2")

    # Retrieval / chunking
    top_k: int = _int("TOP_K", 6)
    chunk_target_words: int = _int("CHUNK_TARGET_WORDS", 180)
    chunk_overlap_words: int = _int("CHUNK_OVERLAP_WORDS", 30)

    # Storage
    chroma_dir: str = os.getenv("CHROMA_DIR", "data/chroma")
    transcript_dir: str = os.getenv("TRANSCRIPT_DIR", "data/transcripts")
    collection_name: str = os.getenv("COLLECTION_NAME", "youtube_kb")

    # Durable decision store. When DATABASE_URL is set (Neon Postgres on the deployed Space), the
    # audit log persists there so it survives container restarts/rebuilds; otherwise it falls back
    # to the local JSONL file at `audit_log_path` (fine for local dev and the offline tests).
    database_url: str = os.getenv("DATABASE_URL", "")

    # --- Triage copilot (T&S) ---
    policy_path: str = os.getenv("POLICY_PATH", "data/policy.md")
    campaigns_dir: str = os.getenv("CAMPAIGNS_DIR", "data/campaigns")
    sanctions_path: str = os.getenv("SANCTIONS_PATH", "data/sanctions.json")
    audit_log_path: str = os.getenv("AUDIT_LOG_PATH", "data/audit_log.jsonl")
    policy_collection: str = os.getenv("POLICY_COLLECTION", "policy_rules")
    cases_collection: str = os.getenv("CASES_COLLECTION", "past_cases")

    # Public-demo lockdown (set PUBLIC_DEMO=1 on the deployed Space). When on, the billed
    # /api/triage endpoint refuses to bypass its per-campaign cache and serves Anthropic only, so
    # total spend is bounded by construction to the 18 fixed campaigns once each (then cache hits).
    public_demo: bool = os.getenv("PUBLIC_DEMO", "").strip().lower() in ("1", "true", "yes", "on")


CONFIG = Config()