update
This commit is contained in:
@@ -52,7 +52,7 @@ BAUSTEINE_STEPS = (
|
||||
"Subbausteine finden", "Subbausteine wählen", "Subbausteine klären",
|
||||
"Stufen finden", "Stufen wählen", "Stufen 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",
|
||||
"Stufen finden", "Stufen wählen", "Stufen 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
|
||||
return (("Quelle laden",) if q["type"] == "link" else ()) + mitte
|
||||
@@ -165,7 +165,7 @@ PHASEN = (
|
||||
("Subbausteine", ("Subbausteine finden", "Subbausteine wählen", "Subbausteine klären")),
|
||||
("Stufen", ("Stufen finden", "Stufen wählen", "Stufen 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())
|
||||
|
||||
|
||||
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:
|
||||
"""Block E: drei Phasen — Finden (1 Generator je Baustein, parallel), Wählen (Code:
|
||||
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():
|
||||
return None
|
||||
|
||||
# Phase „Fragen wählen": Code — nur relevante Subbausteine, Dubletten je Baustein raus.
|
||||
set_p("Fragen wählen…", step=_step_idx(topic, "Fragen wählen"))
|
||||
roh_by_c = {}
|
||||
for c, (titel, rel) in enumerate(bausteine, 1):
|
||||
# Phase „Fragen wählen": Code — Dubletten je Baustein raus, Subbaustein-Titel locker
|
||||
# auf die relevanten mappen (nichts wegen Titel-Abweichung verwerfen).
|
||||
def _waehle(c, rel):
|
||||
eintraege = _frage_muster_schema(_json_datei(roh_path(c))) or []
|
||||
rel_set = set(rel)
|
||||
gesehen, sauber = set(), []
|
||||
for e in eintraege:
|
||||
norm = _norm_frage(e["frage"])
|
||||
if e["subbaustein"] not in rel_set or norm in gesehen:
|
||||
if norm in gesehen:
|
||||
continue
|
||||
gesehen.add(norm)
|
||||
sauber.append(e)
|
||||
roh_by_c[c] = sauber
|
||||
sauber.append({**e, "subbaustein": _match_sub(e["subbaustein"], rel)})
|
||||
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).
|
||||
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():
|
||||
return None
|
||||
|
||||
# Final: geklärte Tabelle je Baustein, Fallback auf Roh-Muster.
|
||||
ergebnis = {}
|
||||
for c, (titel, rel) in enumerate(bausteine, 1):
|
||||
rel_set = set(rel)
|
||||
final = _frage_muster_schema(_json_datei(final_path(c)))
|
||||
if not final:
|
||||
final = roh_by_c[c]
|
||||
ergebnis[titel] = [e for e in final if e["subbaustein"] in rel_set]
|
||||
# Geklärte Tabelle je Baustein, Fallback auf Roh-Muster. Subbaustein-Titel locker mappen.
|
||||
def _finalisiere(c, rel):
|
||||
final = _frage_muster_schema(_json_datei(final_path(c))) or roh_by_c[c]
|
||||
return [{**e, "subbaustein": _match_sub(e["subbaustein"], rel)} for e in final]
|
||||
|
||||
ergebnis = {titel: _finalisiere(c, rel) for c, (titel, rel) in enumerate(bausteine, 1)}
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user