This commit is contained in:
team3
2026-06-22 13:44:33 +02:00
parent 0adc223c0a
commit 613a4a2b1f
4 changed files with 51 additions and 30 deletions

View File

@@ -25,7 +25,7 @@ from lernen import FRAGETYPEN
from paths import arbeit_dir, bausteine_path, frage_muster_path, project_dir, subbausteine_path, quelle_path, quelle_crawl_dir, safe_ordner
from crawl import crawl
from pipeline import (
CANCELLED, FAILED, GenContext, _extra, _log, _prompt, _race, _relevanz_schema, _rest_schema,
CANCELLED, FAILED, GenContext, _extra, _gather_fortschritt, _log, _prompt, _race, _relevanz_schema, _rest_schema,
_runde_schema, _semaphore, _str_liste, _stufen_schema, _timeout, run_single_slot,
)
from textkit import (
@@ -158,6 +158,14 @@ def _step_idx(topic: str, name: str) -> int:
return _bausteine_steps(topic).index(name)
def _melde_p(set_p, topic: str, schritt: str):
"""Async-Melde-Callback für _gather_fortschritt: setzt „<Schritt> d/t…" + Schritt-Index."""
idx = _step_idx(topic, schritt)
async def melde(d, t):
set_p(f"{schritt} {d}/{t}", step=idx)
return melde
# Grobe Anzeige-Phasen: bündeln die Feinschritte (intern bleibt alles feingranular).
# Sonderschritte (Quelle laden, Ergänzung) gehören zur Phase „Inventar".
PHASEN = (
@@ -572,8 +580,7 @@ async def _subbausteine_block(ctx: GenContext, set_p, files: dict, entries: dict
neu = await _race(topic, f"Subbausteine Paket {c}", slots, 2 - vorhanden, _timeout("subbaustein", len(chunk)), provider, cancelled=is_cancelled, grace=KONSENS_GRACE)
return not is_cancelled() and neu is not None
set_p(f"Subbausteine finden ({n} Pakete)…", step=_step_idx(topic, "Subbausteine finden"))
oks = await asyncio.gather(*[_finde(c, chunk) for c, chunk in enumerate(chunks, 1)], return_exceptions=True)
oks = await _gather_fortschritt([_finde(c, chunk) for c, chunk in enumerate(chunks, 1)], len(chunks), _melde_p(set_p, topic, "Subbausteine finden"))
if is_cancelled():
return None
if not all(ok is True for ok in oks):
@@ -607,8 +614,7 @@ async def _subbausteine_block(ctx: GenContext, set_p, files: dict, entries: dict
if status == FAILED:
_log(topic, f"Subbaustein-Klärung Paket {c} fehlgeschlagen — nur Konsens übernommen")
set_p(f"Subbausteine klären ({n} Pakete)…", step=_step_idx(topic, "Subbausteine klären"))
await asyncio.gather(*[_klaere(c, chunk) for c, chunk in enumerate(chunks, 1)], return_exceptions=True)
await _gather_fortschritt([_klaere(c, chunk) for c, chunk in enumerate(chunks, 1)], len(chunks), _melde_p(set_p, topic, "Subbausteine klären"))
if is_cancelled():
return None
@@ -664,8 +670,7 @@ async def _stufen_block(ctx: GenContext, set_p, files: dict, roh: dict, instruct
neu = await _race(topic, f"Stufen Paket {c}", slots, 2 - vorhanden, _timeout("stufe", len(item_idxs)), provider, cancelled=is_cancelled, grace=KONSENS_GRACE)
return not is_cancelled() and neu is not None
set_p(f"Stufen finden ({n} Pakete)…", step=_step_idx(topic, "Stufen finden"))
oks = await asyncio.gather(*[_rate(c, idxs) for c, idxs in enumerate(chunks, 1)], return_exceptions=True)
oks = await _gather_fortschritt([_rate(c, idxs) for c, idxs in enumerate(chunks, 1)], len(chunks), _melde_p(set_p, topic, "Stufen finden"))
if is_cancelled():
return None
if not all(ok is True for ok in oks):
@@ -719,8 +724,7 @@ async def _stufen_block(ctx: GenContext, set_p, files: dict, roh: dict, instruct
ergebnis = {**{k: "mittel" for k in strittig}, **ergebnis, **entsch}
return {item_idxs[k - 1] + 1: stufe for k, stufe in ergebnis.items()}
set_p(f"Stufen klären ({n} Pakete)…", step=_step_idx(topic, "Stufen klären"))
parts = await asyncio.gather(*[_klaere(c, idxs) for c, idxs in enumerate(chunks, 1)], return_exceptions=True)
parts = await _gather_fortschritt([_klaere(c, idxs) for c, idxs in enumerate(chunks, 1)], len(chunks), _melde_p(set_p, topic, "Stufen klären"))
if is_cancelled():
return None
stufe_by_id: dict[int, str] = {}
@@ -783,8 +787,7 @@ async def _relevanz_block(ctx: GenContext, set_p, files: dict, sidecar: dict, in
neu = await _race(topic, f"Relevanz Paket {c}", slots, 2 - vorhanden, _timeout("relevanz", len(item_idxs)), provider, cancelled=is_cancelled, grace=KONSENS_GRACE)
return not is_cancelled() and neu is not None
set_p(f"Relevanz finden ({n} Pakete)…", step=_step_idx(topic, "Relevanz finden"))
oks = await asyncio.gather(*[_rate(c, idxs) for c, idxs in enumerate(chunks, 1)], return_exceptions=True)
oks = await _gather_fortschritt([_rate(c, idxs) for c, idxs in enumerate(chunks, 1)], len(chunks), _melde_p(set_p, topic, "Relevanz finden"))
if is_cancelled():
return None
if not all(ok is True for ok in oks):
@@ -838,8 +841,7 @@ async def _relevanz_block(ctx: GenContext, set_p, files: dict, sidecar: dict, in
ergebnis = {**{k: "relevant" for k in strittig}, **ergebnis, **entsch}
return {item_idxs[k - 1] + 1: rel for k, rel in ergebnis.items()}
set_p(f"Relevanz klären ({n} Pakete)…", step=_step_idx(topic, "Relevanz klären"))
parts = await asyncio.gather(*[_klaere(c, idxs) for c, idxs in enumerate(chunks, 1)], return_exceptions=True)
parts = await _gather_fortschritt([_klaere(c, idxs) for c, idxs in enumerate(chunks, 1)], len(chunks), _melde_p(set_p, topic, "Relevanz klären"))
if is_cancelled():
return None
relevanz_by_id: dict[int, str] = {}
@@ -915,8 +917,7 @@ async def _frage_muster_block(ctx: GenContext, set_p, files: dict, sidecar: dict
if status == FAILED:
_log(topic, f"Frage-Muster Baustein {c} fehlgeschlagen — kein Muster (Fallback Live)")
set_p(f"Fragen finden ({len(bausteine)} Bausteine)…", step=_step_idx(topic, "Fragen finden"))
await asyncio.gather(*[_finde(c, t, r) for c, (t, r) in enumerate(bausteine, 1)], return_exceptions=True)
await _gather_fortschritt([_finde(c, t, r) for c, (t, r) in enumerate(bausteine, 1)], len(bausteine), _melde_p(set_p, topic, "Fragen finden"))
if is_cancelled():
return None
@@ -954,8 +955,7 @@ async def _frage_muster_block(ctx: GenContext, set_p, files: dict, sidecar: dict
if status == FAILED:
_log(topic, f"Frage-Muster-Klärung Baustein {c} fehlgeschlagen — Roh-Muster übernommen")
set_p(f"Fragen klären ({len(bausteine)} Bausteine)…", step=_step_idx(topic, "Fragen klären"))
await asyncio.gather(*[_klaere(c, t) for c, (t, _) in enumerate(bausteine, 1)], return_exceptions=True)
await _gather_fortschritt([_klaere(c, t) for c, (t, _) in enumerate(bausteine, 1)], len(bausteine), _melde_p(set_p, topic, "Fragen klären"))
if is_cancelled():
return None
@@ -967,19 +967,19 @@ async def _frage_muster_block(ctx: GenContext, set_p, files: dict, sidecar: dict
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"))
set_p("Fragen prüfen…", 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)
await _gather_fortschritt([_finde(c, t, r) for c, t, r in leer], len(leer), _melde_p(set_p, topic, "Fragen prüfen"))
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)
await _gather_fortschritt([_klaere(c, t) for c, t, r in leer], len(leer), _melde_p(set_p, topic, "Fragen prüfen"))
if is_cancelled():
return None
for c, t, r in leer: