This commit is contained in:
team3
2026-07-12 20:02:13 +02:00
parent 31a42bbf1d
commit cde1721d10
23 changed files with 731 additions and 219 deletions

View File

@@ -18,7 +18,7 @@ from pathlib import Path
import db
import llm
from config import DIAGRAMM_MIN_KANTEN, DIAGRAMM_TYPEN, DURCHGANG, VERIFY_PANEL
from config import DIAGRAMM_TYPEN, DURCHGANG, VERIFY_PANEL
log = logging.getLogger("creator2.diagramme")
@@ -61,26 +61,6 @@ def _atome_von(baustein_id: int) -> list[dict]:
" ('gemerged','verworfen') ORDER BY ord", (baustein_id,))
def _interne_kanten(topic: str, ids: set[int]) -> list[dict]:
"""aktive braucht-Kanten, deren BEIDE Enden im Baustein liegen."""
if len(ids) < 2:
return []
return [k for k in db.query(
"SELECT * FROM kanten WHERE topic=? AND art='braucht' AND status='aktiv'", (topic,))
if k["von_atom"] in ids and k["zu_atom"] in ids]
# ── Spec (JSON-Zwischenrepräsentation) ────────────────────────────────────────
def _dag_spec(atome: list[dict], kanten: list[dict]) -> dict:
"""Abhängigkeitsdiagramm direkt aus dem braucht-Graph. `von braucht zu` ⇒ Pfeil
zu→von (Voraussetzung zeigt auf das, was sie ermöglicht). Kein LLM."""
knoten = [{"id": str(a["id"]), "label": a["titel"]} for a in atome]
kanten_spec = [{"von": str(k["zu_atom"]), "zu": str(k["von_atom"]), "label": ""}
for k in kanten]
return {"typ": "dependency", "knoten": knoten, "kanten": kanten_spec}
# ── Kompilieren (deterministisch, kein LLM) ───────────────────────────────────
def _sid(raw) -> str:
@@ -129,21 +109,6 @@ def _kompilieren(topic: str) -> None:
# ── Planung (welche + Typ) ────────────────────────────────────────────────────
def _planen(topic: str) -> None:
"""Deterministischer Zweig: Baustein mit ≥DIAGRAMM_MIN_KANTEN internen
braucht-Kanten → Abhängigkeitsdiagramm aus dem DAG. Idempotent: Bausteine mit
bestehender Diagramm-Zeile werden übersprungen. Kein LLM, null Halluzination."""
for b in _bausteine(topic):
if db.one("SELECT id FROM diagramme WHERE baustein_id=?", (b["id"],)):
continue
atome = _atome_von(b["id"])
ids = {a["id"] for a in atome}
kanten = _interne_kanten(topic, ids)
if len(kanten) >= DIAGRAMM_MIN_KANTEN:
db.insert("diagramme", topic=topic, baustein_id=b["id"], typ="dependency",
quelle="dag", spec=db.j(_dag_spec(atome, kanten)), status="geplant")
def _atom_liste(atome: list[dict]) -> str:
return "\n".join(f"{a['id']}: {a['titel']}{a['definition']}" for a in atome)
@@ -175,7 +140,7 @@ async def _plan_judge(ctx: llm.Kontext) -> None:
if res is None:
return # Ausfall → nächste Runde erneut (kein 'kein'-Eintrag)
typ = str(res.get("typ", "")).strip()
if res.get("noetig") and typ in DIAGRAMM_TYPEN and typ != "dependency":
if res.get("noetig") and typ in DIAGRAMM_TYPEN:
db.insert("diagramme", topic=ctx.topic, baustein_id=b["id"], typ=typ,
quelle="llm", status="geplant")
else:
@@ -254,16 +219,11 @@ async def _verifizieren(ctx: llm.Kontext) -> None:
async def bauen(ctx: llm.Kontext) -> None:
ctx.ebene = EBENE
_planen(ctx.topic) # welche/Typ: deterministisch (DAG)
await _plan_judge(ctx) # welche/Typ: Judge (Automaten/Abläufe/Bäume)
await _plan_judge(ctx) # welche/Typ: Judge (Automaten/Abläufe/Bäume) — kein DAG mehr
await _spec_bauen(ctx) # LLM → Struktur-JSON (kein rohes Mermaid)
_kompilieren(ctx.topic) # Spec → Mermaid (deterministisch)
_gate_kandidaten(ctx.topic) # Parse-Gate: ungültige Mermaid-Quelle → verworfen
# dag-Diagramme sind per Konstruktion gegroundet → nach bestandenem Gate verifiziert
for d in db.query("SELECT id FROM diagramme WHERE topic=? AND status='kandidat'"
" AND quelle='dag'", (ctx.topic,)):
db.update("diagramme", "id", d["id"], status="verifiziert")
await _verifizieren(ctx) # LLM-Diagramme: Grounding-Panel gegen die Atome
await _verifizieren(ctx) # Grounding-Panel gegen die Atome
def _gate_kandidaten(topic: str) -> None: