108 lines
5.3 KiB
Python
108 lines
5.3 KiB
Python
from pathlib import Path
|
||
|
||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||
TEMPLATES_DIR = PROJECT_ROOT / "templates"
|
||
STORAGE_DIR = PROJECT_ROOT / "storage"
|
||
FRONTEND_DIST = PROJECT_ROOT / "frontend" / "dist"
|
||
DB_PATH = STORAGE_DIR / "creator.db"
|
||
PROJECTS_DIR = PROJECT_ROOT / "projects"
|
||
UNI_DIR = PROJECT_ROOT / "uni"
|
||
|
||
MAX_CONCURRENT_GENERATIONS = 10
|
||
|
||
# Lesbarkeits-Gate: deterministischer Prüfer (kleines deutsches Komplexitäts-Modell,
|
||
# Skala 1–7). Zu schwere Sections gehen in die Lese-Prüfungs-Überarbeitung.
|
||
# Fehlen transformers/torch oder das Modell → Gate stumm aus.
|
||
LESBARKEIT_AKTIV = True
|
||
LESBARKEIT_MODELL = "MiriUll/distilbert-german-text-complexity"
|
||
# Anker auf der 1–7-Skala (TextComplexityDE): Leichte Sprache ~1,2; Wikipedia-Schnitt
|
||
# ~3,22; ab MOS > 4 gilt ein Satz als „echt komplex" (Vereinfachungs-Grenze des Papers).
|
||
LESBARKEIT_MAX = 3.5 # Section zu schwer, wenn der Satz-Schnitt darüber liegt
|
||
LESBARKEIT_HART = 4.0 # Einzelsatz ab hier „hart"
|
||
LESBARKEIT_HART_ANTEIL = 0.30 # … ODER wenn dieser Anteil der Sätze hart ist
|
||
|
||
# Deckel für gleichzeitige CLI-Agenten-Prozesse (über alle Generierungen hinweg).
|
||
# Eigene Spur für interaktive Aufrufe (Chat, Elemente), damit sie nicht hinter
|
||
# laufenden Writern in der Warteschlange hängen.
|
||
MAX_CONCURRENT_AGENTS = 10
|
||
MAX_CONCURRENT_INTERACTIVE = 4
|
||
|
||
# Grace-Fenster der Konsens-Races (Bausteine, Guide, OnePager): Nach dem ersten
|
||
# gültigen Ergebnis dürfen die übrigen Agenten noch so viele Sekunden fertig
|
||
# werden (Kill nur, wenn das Minimum schon steht).
|
||
KONSENS_GRACE = 300
|
||
|
||
# Cap der Klärungs- und Prüf-Loops: maximale Runden, bis alles entschieden sein
|
||
# muss. In der letzten Runde MUSS der Mapping-Agent jeden Eintrag entscheiden;
|
||
# Prüf-Loops lassen Rest-Beanstandungen danach stehen.
|
||
KONSENS_MAX_RUNDEN = 3
|
||
|
||
# Timeouts pro Agenten-Schritt: (Basis-Sekunden, Sekunden pro Baustein/Section).
|
||
# Gilt für alle Provider gleich — wer zu langsam ist, wird neu gestartet bzw. überholt.
|
||
TIMEOUTS = {
|
||
"recherche": (1800, 0), # fix 30 min
|
||
"recherche_mapping": (600, 3), # n = vorgemergte Einträge
|
||
"auswahl": (300, 2), # Rest-Prüfung im Klärungs-Loop, n = Rest-Einträge
|
||
"auswahl_mapping": (600, 2), # n = Rest-Einträge
|
||
"ergaenzung": (900, 0), # Themenfeld-Ergänzung bei Projekten (Web-Recherche)
|
||
"guide_auswahl": (300, 5), # pro Baustein im Inventar
|
||
"plan": (300, 5),
|
||
"plan_judge": (600, 5), # Judge liest bis zu 5 Gliederungen, n = Sections
|
||
"inhalt": (600, 90), # Inhalte je Baustein im Chunk identifizieren (Websuche)
|
||
"inhalt_check": (300, 10), # Inhalts-Prüfung je Baustein im Paket
|
||
"subbaustein": (900, 45), # Subbausteine je Baustein im Chunk finden (Websuche)
|
||
"subbaustein_check": (300, 15), # Judge entscheidet strittige Subbausteine im Chunk
|
||
"stufe": (300, 10), # Subbausteine einstufen je Chunk
|
||
"stufe_check": (300, 10), # Judge entscheidet strittige Stufen im Chunk
|
||
"relevanz": (300, 10), # Subbausteine relevant/rand je Chunk
|
||
"relevanz_check": (300, 10), # Judge entscheidet strittige Relevanz im Chunk
|
||
"frage_muster": (300, 15), # Frage-Muster je Baustein (Subbausteine × Typen)
|
||
"frage_muster_check": (300, 10), # Kritiker bereinigt die Muster-Tabelle je Baustein
|
||
"writer": (600, 120), # pro Section im Chunk
|
||
"lese_check": (300, 10), # pro Section im Paket
|
||
}
|
||
|
||
# Auswahl-Auftrag je Format: (Mindest-Anteil, Maximal-Anteil, Mindestanzahl, Zweck).
|
||
FORMAT_ANTEIL = {
|
||
"Guide": (0.0, 1.0, 0, "einen fokussierten Guide — alles Relevante ohne Randthemen"),
|
||
"FullGuide": (0.0, 1.0, 0, "einen Komplett-Guide — das ganze Thema inkl. Randthemen"),
|
||
"Rest": (0.0, 1.0, 0, "einen Ergänzungs-Guide — nur die Randthemen"),
|
||
}
|
||
|
||
# Provider-Stacks: komplett unabhängig, einer kann jederzeit entfernt werden.
|
||
# Rollen: "quick" = Massenarbeit (Recherche, Einordnung),
|
||
# "fast" = Interaktion + Voten (Chat, Prüfung, Klärung, Elemente),
|
||
# "judge" = Mapping-/Judge-/Prüf-Agenten — kalt (niedrige Temperature,
|
||
# ohne Thinking) für stabile Urteile; Claude/Lokal mappen auf "fast",
|
||
# "guide" = große Generierung (Vorschläge, Writer).
|
||
DEFAULT_PROVIDER = "claude"
|
||
PROVIDERS = {
|
||
"claude": {
|
||
"cli": "claude",
|
||
"guide": "claude-opus-4-8[1m]",
|
||
"fast": "claude-sonnet-4-6",
|
||
"judge": "claude-sonnet-4-6", # CLI kennt keine Temperature
|
||
"quick": "claude-sonnet-4-6",
|
||
"env_key": None, # Auth via CLAUDE_CODE_OAUTH_TOKEN oder ~/.claude
|
||
},
|
||
# "minimax-kalt/…" ist KEIN eigener Stack, nur ein opencode-Provider-Eintrag
|
||
# (dev-ops/opencode.json) mit niedriger Temperature; M3 dort ohne Thinking.
|
||
"minimax": {
|
||
"cli": "opencode",
|
||
"guide": "minimax/MiniMax-M3",
|
||
"fast": "minimax-kalt/MiniMax-M2.7-highspeed",
|
||
"judge": "minimax-kalt/MiniMax-M3",
|
||
"quick": "minimax/MiniMax-M2.7-highspeed",
|
||
"env_key": "MINIMAX_API_KEY",
|
||
},
|
||
"lokal": {
|
||
"cli": "opencode",
|
||
"guide": "ollama/qwen3.6:27b",
|
||
"fast": "ollama/qwen3.5:9b",
|
||
"judge": "ollama/qwen3.5:9b",
|
||
"quick": "ollama/qwen3.5:9b",
|
||
"env_key": None,
|
||
"check_url": "http://localhost:11434/api/tags", # Ollama erreichbar?
|
||
},
|
||
}
|