This commit is contained in:
root
2026-06-07 05:01:30 +00:00
parent 656b5bb621
commit fce82fbd16
2 changed files with 13 additions and 12 deletions

View File

@@ -22,11 +22,11 @@ TIMEOUTS = {
"onepager_verify": (300, 0),
}
# Auswahl-Auftrag je Format: (Mindest-Anteil, Mindestanzahl, Zweck).
# Auswahl-Auftrag je Format: (Mindest-Anteil, Maximal-Anteil, Mindestanzahl, Zweck).
FORMAT_ANTEIL = {
"MiniGuide": (0.05, 8, "einen kompakten Anfänger-Guide — der schnelle Einstieg ins Thema"),
"Guide": (0.33, 20, "einen ausführlichen Anfänger-Guide — ein solides Fundament im Thema"),
"FullGuide": (0.90, 0, "einen Komplett-Guide — das ganze Thema"),
"MiniGuide": (0.05, 0.10, 8, "einen kompakten Anfänger-Guide — der schnelle Einstieg ins Thema"),
"Guide": (0.25, 0.35, 20, "einen ausführlichen Anfänger-Guide — ein solides Fundament im Thema"),
"FullGuide": (0.90, 1.00, 0, "einen Komplett-Guide — das ganze Thema"),
}
# Provider-Stacks: komplett unabhängig, einer kann jederzeit entfernt werden.

View File

@@ -508,13 +508,13 @@ async def generate_bausteine(topic: str, instructions: str = "", provider: str =
# Kleine Pakete vermeiden Lazy-Output bei langen Listen und begrenzen den Schaden
# eines fehlgeschlagenen Writers.
WRITER_SECTIONS = 30
WRITER_MAX = 10
WRITER_MAX = 20
def _resolve_gliederung(data, entries: dict[int, str], soll: int) -> list[dict] | None:
def _resolve_gliederung(data, entries: dict[int, str], soll_min: int, soll_max: int) -> list[dict] | None:
"""{"kapitel": [{"titel", "bausteine": [Titel]}]} → [{"title", "nums"}].
`soll` = Mindest-Anzahl gewählter Bausteine (mit kleiner Toleranz).
`soll_min`/`soll_max` = erlaubte Spanne gewählter Bausteine (mit kleiner Toleranz).
"""
if not isinstance(data, dict) or not isinstance(data.get("kapitel"), list):
return None
@@ -540,7 +540,7 @@ def _resolve_gliederung(data, entries: dict[int, str], soll: int) -> list[dict]
return None
if (total - unknown) / total < 0.85:
return None
if len(seen) < 0.9 * soll:
if len(seen) < 0.9 * soll_min or len(seen) > 1.1 * soll_max:
return None
return chapters
@@ -719,10 +719,11 @@ async def _generate_sections(
spec = (TEMPLATES_DIR / "Format" / "Section.md").read_text(encoding="utf-8")
bausteine_liste = "\n".join(f"- {t}" for t in entries.values())
n = len(entries)
anteil, minimum, zweck = FORMAT_ANTEIL[format_name]
k = min(n, max(minimum, math.ceil(anteil * n)))
anteil_min, anteil_max, minimum, zweck = FORMAT_ANTEIL[format_name]
k_min = min(n, max(minimum, math.ceil(anteil_min * n)))
k_max = min(n, max(k_min, math.floor(anteil_max * n)))
auswahl_auftrag = (
f"Wähle MINDESTENS {k} der Bausteine und baue daraus {zweck}. "
f"Wähle MINDESTENS {k_min} und HÖCHSTENS {k_max} der Bausteine und baue daraus {zweck}. "
"Wähle, was diesem Zweck dient — lass weg, was dafür nicht nötig ist."
)
@@ -738,7 +739,7 @@ async def _generate_sections(
auswahl_auftrag=auswahl_auftrag, out_path=plan_path, extra=_extra(instructions),
),
"role": "guide", "capabilities": "files",
"payload": (lambda result: _resolve_gliederung(_json_datei(plan_path), entries, k)),
"payload": (lambda result: _resolve_gliederung(_json_datei(plan_path), entries, k_min, k_max)),
}]
res = await _race(topic, "Gliederung", slots, 1, _timeout("plan", n), provider, cancelled=is_cancelled)
if is_cancelled():