update
This commit is contained in:
@@ -15,6 +15,8 @@ import math
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
import uuid
|
||||
|
||||
from agents import run_agent
|
||||
from bausteine import _pdfs_konvertieren, quelle_ordner
|
||||
from config import (
|
||||
@@ -22,9 +24,9 @@ from config import (
|
||||
LESBARKEIT_AKTIV, TEMPLATES_DIR,
|
||||
)
|
||||
import lesbarkeit
|
||||
from database import list_guides, update_guide, list_bausteine, list_subbausteine, set_guide_content
|
||||
from database import list_guides, update_guide, list_bausteine, list_subbausteine, set_guide_content, get_guide_content
|
||||
from fsutil import atomic_write_json, atomic_write_text
|
||||
from jsonio import read_json_file as _json_datei
|
||||
from jsonio import read_json_file as _json_datei, parse_json_text as _parse_json_text
|
||||
from paths import bausteine_path, guide_content_path, project_dir, subbausteine_path
|
||||
from pipeline import (
|
||||
CANCELLED, FAILED, GenContext, _claude_error, _extra,
|
||||
@@ -816,3 +818,88 @@ async def generate_guide(guide_id: str, topic: str, format_name: str, instructio
|
||||
await _fail(guide_id, str(e)[:2000])
|
||||
finally:
|
||||
clear_guide_cancelled(guide_id)
|
||||
|
||||
|
||||
# --- On-Demand: eine Section prüfen / beheben / neu schreiben (Fokus, interaktiv) ---
|
||||
|
||||
SECTION_PRUEFEN_TIMEOUT = 300
|
||||
SECTION_FIX_TIMEOUT = 600
|
||||
|
||||
|
||||
def _section_spec() -> str:
|
||||
return (TEMPLATES_DIR / "Format" / "Section.md").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _section_facts(topic: str) -> str:
|
||||
project = quelle_ordner(topic)
|
||||
return _prompt("Guide-Fakten-Projekt", project=project) if project else _prompt("Guide-Fakten-Thema")
|
||||
|
||||
|
||||
def _hinweis_block(hinweis: str) -> str:
|
||||
hinweis = (hinweis or "").strip()
|
||||
return f"HINWEIS DES NUTZERS (besonders beachten):\n{hinweis}" if hinweis else ""
|
||||
|
||||
|
||||
async def _subs_text(topic: str, baustein: str) -> str:
|
||||
"""Relevante Subbausteine eines Bausteins mit Stufe — als Checkliste für die Agenten."""
|
||||
subs_raw = await _load_subbausteine(topic)
|
||||
subs = [s for s in subs_raw.get(_titel(baustein), []) if s.get("relevanz") != "rand"]
|
||||
if not subs:
|
||||
return "(keine Subbausteine hinterlegt — 3–7 knappe Punkte abdecken)"
|
||||
return "\n".join(f"- [{s['stufe']}] {s['titel']}" for s in subs)
|
||||
|
||||
|
||||
async def _guide_content_laden(topic: str, format_name: str) -> dict | None:
|
||||
js = await get_guide_content(topic, format_name)
|
||||
if not js:
|
||||
return None
|
||||
try:
|
||||
return json.loads(js)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def _section_finden(content: dict, baustein: str) -> dict | None:
|
||||
for ch in content.get("chapters", []):
|
||||
for s in ch.get("sections", []):
|
||||
if s.get("title") == baustein:
|
||||
return s
|
||||
return None
|
||||
|
||||
|
||||
async def block_pruefen(topic: str, format_name: str, baustein: str, stelle: str, block: str, hinweis: str = "", provider: str = DEFAULT_PROVIDER) -> str | None:
|
||||
"""Einen Abschnitt (Markdown-Block) gegen die Guide-Regeln prüfen → korrigierte
|
||||
Block-Version als Markdown. None = Fehler/Section fehlt."""
|
||||
content = await _guide_content_laden(topic, format_name)
|
||||
sec = _section_finden(content, baustein) if content else None
|
||||
if sec is None:
|
||||
return None
|
||||
ganze = sec.get("kompakt", "") if str(stelle).startswith("kompakt") else sec.get("md", "")
|
||||
prompt = _prompt(
|
||||
"Block-Pruefen", topic=topic, spec=_section_spec(), facts=_section_facts(topic),
|
||||
subbausteine=await _subs_text(topic, baustein), kontext=ganze, block=block, hinweis=_hinweis_block(hinweis),
|
||||
)
|
||||
rc, stdout, _ = await run_agent(
|
||||
f"block-pruefen-{uuid.uuid4()}", prompt, SECTION_PRUEFEN_TIMEOUT,
|
||||
provider=provider, role="judge", capabilities="none", lane="interactive",
|
||||
)
|
||||
neu = stdout.strip() if rc == 0 else ""
|
||||
return neu or None
|
||||
|
||||
|
||||
async def block_uebernehmen(topic: str, format_name: str, baustein: str, stelle: str, alt: str, neu: str) -> dict | None:
|
||||
"""Einen Block (alt→neu) im Feld kompakt/ausführlich ersetzen + persistieren.
|
||||
→ {kompakt, md, gefunden}; None = Section fehlt."""
|
||||
content = await _guide_content_laden(topic, format_name)
|
||||
sec = _section_finden(content, baustein) if content else None
|
||||
if sec is None:
|
||||
return None
|
||||
feld = "kompakt" if str(stelle).startswith("kompakt") else "md"
|
||||
aktuell = sec.get(feld, "") or ""
|
||||
gefunden = alt in aktuell
|
||||
if gefunden:
|
||||
sec[feld] = aktuell.replace(alt, neu, 1)
|
||||
js = json.dumps(content, ensure_ascii=False)
|
||||
await set_guide_content(topic, format_name, js)
|
||||
atomic_write_json(guide_content_path(topic, format_name), content, indent=1)
|
||||
return {"kompakt": sec.get("kompakt", ""), "md": sec.get("md", ""), "gefunden": gefunden}
|
||||
|
||||
Reference in New Issue
Block a user