update
This commit is contained in:
@@ -52,7 +52,7 @@ BAUSTEINE_STEPS = (
|
|||||||
"Subbausteine finden", "Subbausteine wählen", "Subbausteine klären",
|
"Subbausteine finden", "Subbausteine wählen", "Subbausteine klären",
|
||||||
"Stufen finden", "Stufen wählen", "Stufen klären",
|
"Stufen finden", "Stufen wählen", "Stufen klären",
|
||||||
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
|
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
|
||||||
"Fragen finden", "Fragen wählen", "Fragen klären",
|
"Fragen finden", "Fragen wählen", "Fragen klären", "Fragen prüfen",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ def _bausteine_steps(topic: str) -> tuple:
|
|||||||
"Subbausteine finden", "Subbausteine wählen", "Subbausteine klären",
|
"Subbausteine finden", "Subbausteine wählen", "Subbausteine klären",
|
||||||
"Stufen finden", "Stufen wählen", "Stufen klären",
|
"Stufen finden", "Stufen wählen", "Stufen klären",
|
||||||
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
|
"Relevanz finden", "Relevanz wählen", "Relevanz klären",
|
||||||
"Fragen finden", "Fragen wählen", "Fragen klären",
|
"Fragen finden", "Fragen wählen", "Fragen klären", "Fragen prüfen",
|
||||||
)
|
)
|
||||||
mitte = base + (("Ergänzung",) if q["type"] == "projekt" else ()) + rest
|
mitte = base + (("Ergänzung",) if q["type"] == "projekt" else ()) + rest
|
||||||
return (("Quelle laden",) if q["type"] == "link" else ()) + mitte
|
return (("Quelle laden",) if q["type"] == "link" else ()) + mitte
|
||||||
@@ -165,7 +165,7 @@ PHASEN = (
|
|||||||
("Subbausteine", ("Subbausteine finden", "Subbausteine wählen", "Subbausteine klären")),
|
("Subbausteine", ("Subbausteine finden", "Subbausteine wählen", "Subbausteine klären")),
|
||||||
("Stufen", ("Stufen finden", "Stufen wählen", "Stufen klären")),
|
("Stufen", ("Stufen finden", "Stufen wählen", "Stufen klären")),
|
||||||
("Relevanz", ("Relevanz finden", "Relevanz wählen", "Relevanz klären")),
|
("Relevanz", ("Relevanz finden", "Relevanz wählen", "Relevanz klären")),
|
||||||
("Fragen", ("Fragen finden", "Fragen wählen", "Fragen klären")),
|
("Fragen", ("Fragen finden", "Fragen wählen", "Fragen klären", "Fragen prüfen")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -859,6 +859,20 @@ def _norm_frage(t: str) -> str:
|
|||||||
return " ".join(str(t or "").lower().split())
|
return " ".join(str(t or "").lower().split())
|
||||||
|
|
||||||
|
|
||||||
|
def _match_sub(agent_sub: str, rel: list[str]) -> str:
|
||||||
|
"""Subbaustein-Titel des Agenten auf den passenden relevanten Titel mappen — exakt,
|
||||||
|
dann normalisiert, dann Teilstring (der Agent lässt z. B. das Präfix „Frage: " weg).
|
||||||
|
Kein Treffer → Agent-Titel behalten. So geht KEIN Muster durch Titel-Abweichung verloren."""
|
||||||
|
if agent_sub in rel:
|
||||||
|
return agent_sub
|
||||||
|
an = _norm_titel(agent_sub)
|
||||||
|
for r in rel:
|
||||||
|
rn = _norm_titel(r)
|
||||||
|
if an and rn and (an == rn or an in rn or rn in an):
|
||||||
|
return r
|
||||||
|
return agent_sub
|
||||||
|
|
||||||
|
|
||||||
async def _frage_muster_block(ctx: GenContext, set_p, files: dict, sidecar: dict, instructions: str) -> dict | None:
|
async def _frage_muster_block(ctx: GenContext, set_p, files: dict, sidecar: dict, instructions: str) -> dict | None:
|
||||||
"""Block E: drei Phasen — Finden (1 Generator je Baustein, parallel), Wählen (Code:
|
"""Block E: drei Phasen — Finden (1 Generator je Baustein, parallel), Wählen (Code:
|
||||||
relevante Subs + Dedup), Klären (Kritiker je Baustein bereinigt die Tabelle).
|
relevante Subs + Dedup), Klären (Kritiker je Baustein bereinigt die Tabelle).
|
||||||
@@ -905,20 +919,21 @@ async def _frage_muster_block(ctx: GenContext, set_p, files: dict, sidecar: dict
|
|||||||
if is_cancelled():
|
if is_cancelled():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Phase „Fragen wählen": Code — nur relevante Subbausteine, Dubletten je Baustein raus.
|
# Phase „Fragen wählen": Code — Dubletten je Baustein raus, Subbaustein-Titel locker
|
||||||
set_p("Fragen wählen…", step=_step_idx(topic, "Fragen wählen"))
|
# auf die relevanten mappen (nichts wegen Titel-Abweichung verwerfen).
|
||||||
roh_by_c = {}
|
def _waehle(c, rel):
|
||||||
for c, (titel, rel) in enumerate(bausteine, 1):
|
|
||||||
eintraege = _frage_muster_schema(_json_datei(roh_path(c))) or []
|
eintraege = _frage_muster_schema(_json_datei(roh_path(c))) or []
|
||||||
rel_set = set(rel)
|
|
||||||
gesehen, sauber = set(), []
|
gesehen, sauber = set(), []
|
||||||
for e in eintraege:
|
for e in eintraege:
|
||||||
norm = _norm_frage(e["frage"])
|
norm = _norm_frage(e["frage"])
|
||||||
if e["subbaustein"] not in rel_set or norm in gesehen:
|
if norm in gesehen:
|
||||||
continue
|
continue
|
||||||
gesehen.add(norm)
|
gesehen.add(norm)
|
||||||
sauber.append(e)
|
sauber.append({**e, "subbaustein": _match_sub(e["subbaustein"], rel)})
|
||||||
roh_by_c[c] = sauber
|
return sauber
|
||||||
|
|
||||||
|
set_p("Fragen wählen…", step=_step_idx(topic, "Fragen wählen"))
|
||||||
|
roh_by_c = {c: _waehle(c, rel) for c, (titel, rel) in enumerate(bausteine, 1)}
|
||||||
|
|
||||||
# Phase „Fragen klären": Kritiker je Baustein bereinigt die Tabelle (eindeutig, distinkt).
|
# Phase „Fragen klären": Kritiker je Baustein bereinigt die Tabelle (eindeutig, distinkt).
|
||||||
async def _klaere(c, titel):
|
async def _klaere(c, titel):
|
||||||
@@ -943,14 +958,34 @@ async def _frage_muster_block(ctx: GenContext, set_p, files: dict, sidecar: dict
|
|||||||
if is_cancelled():
|
if is_cancelled():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Final: geklärte Tabelle je Baustein, Fallback auf Roh-Muster.
|
# Geklärte Tabelle je Baustein, Fallback auf Roh-Muster. Subbaustein-Titel locker mappen.
|
||||||
ergebnis = {}
|
def _finalisiere(c, rel):
|
||||||
for c, (titel, rel) in enumerate(bausteine, 1):
|
final = _frage_muster_schema(_json_datei(final_path(c))) or roh_by_c[c]
|
||||||
rel_set = set(rel)
|
return [{**e, "subbaustein": _match_sub(e["subbaustein"], rel)} for e in final]
|
||||||
final = _frage_muster_schema(_json_datei(final_path(c)))
|
|
||||||
if not final:
|
ergebnis = {titel: _finalisiere(c, rel) for c, (titel, rel) in enumerate(bausteine, 1)}
|
||||||
final = roh_by_c[c]
|
|
||||||
ergebnis[titel] = [e for e in final if e["subbaustein"] in rel_set]
|
# Phase „Fragen prüfen": Bausteine mit relevanten Subs aber 0 Mustern eine Runde nachholen.
|
||||||
|
set_p(f"Fragen prüfen ({len(bausteine)} Bausteine)…", step=_step_idx(topic, "Fragen prüfen"))
|
||||||
|
leer = [(c, t, r) for c, (t, r) in enumerate(bausteine, 1) if not ergebnis.get(t)]
|
||||||
|
if leer:
|
||||||
|
_log(topic, f"Frage-Muster: {len(leer)} Baustein(e) ohne Muster — Nachrunde")
|
||||||
|
for c, t, r in leer:
|
||||||
|
roh_path(c).unlink(missing_ok=True)
|
||||||
|
final_path(c).unlink(missing_ok=True)
|
||||||
|
await asyncio.gather(*[_finde(c, t, r) for c, t, r in leer], return_exceptions=True)
|
||||||
|
if is_cancelled():
|
||||||
|
return None
|
||||||
|
for c, t, r in leer:
|
||||||
|
roh_by_c[c] = _waehle(c, r)
|
||||||
|
await asyncio.gather(*[_klaere(c, t) for c, t, r in leer], return_exceptions=True)
|
||||||
|
if is_cancelled():
|
||||||
|
return None
|
||||||
|
for c, t, r in leer:
|
||||||
|
ergebnis[t] = _finalisiere(c, r)
|
||||||
|
rest = [t for c, t, r in leer if not ergebnis.get(t)]
|
||||||
|
if rest:
|
||||||
|
_log(topic, f"Frage-Muster: {len(rest)} Baustein(e) bleiben leer (Fallback Live): {rest[:5]}")
|
||||||
return ergebnis
|
return ergebnis
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user