This commit is contained in:
Team3
2026-07-04 21:27:47 +02:00
parent c05421a8c1
commit 2d9ca00b47
3 changed files with 71 additions and 9 deletions

View File

@@ -656,7 +656,18 @@ def _finder_material(folder, sources: list[str] | None, queries: list[str]) -> t
return "", "Backed, not invented. Verify uncertain points via web search.", ("files" if folder else "full")
def _build_research_prompt(topic: str, out_path: Path, instructions: str, type: str, folder: Path | None, fokus: str = "", section: str = "") -> str:
def material_folder(topic: str) -> Path | None:
"""Korpus fürs Inline-Material: echte Quelle (uni/projekt/link) oder bei thema die
Fundstellen der Research-Reader (arbeit/material/*.txt). Nur für Evidence-Packs —
Konsens-Gate und QA messen unverändert gegen die konfigurierte Quelle (Messinvarianz)."""
f = source_folder(topic)
if f is not None:
return f
d = arbeit_dir(topic) / "material"
return d if d.is_dir() and any(d.glob("*.txt")) else None
def _build_research_prompt(topic: str, out_path: Path, instructions: str, type: str, folder: Path | None, fokus: str = "", section: str = "", material_path: Path | None = None) -> str:
if section:
# Section mode (uni/projekt): text directly in the prompt → small context, no file reading.
source = section
@@ -664,6 +675,13 @@ def _build_research_prompt(topic: str, out_path: Path, instructions: str, type:
source = _prompt(_SOURCE_TEMPLATE[type], project=folder)
else:
source = _prompt("Blocks-Source-Thema", topic=topic)
if material_path is not None:
# thema: Fundstellen sichern — sie werden das Inline-Material der Folgeschritte
# (Finder/Facts liefen sonst mit eigener Websuche → Reasoning-Schleifen, Retries)
source += ("\n\nALSO write the file " + str(material_path) + " as you research: for every "
"source you use, append one line with the URL followed by the relevant excerpt "
"(plain text). Later steps back all facts ONLY against this material — "
"an excerpt you skip here cannot back anything later.")
return _prompt(
"Blocks-Research",
topic=topic, source=source, blocks_path=out_path, focus=fokus, extra=_extra(instructions),
@@ -790,6 +808,7 @@ async def _subblocks_block(ctx: GenContext, set_p, files: dict, entries: dict, i
topic, provider, is_cancelled = ctx.topic, ctx.provider, ctx.is_cancelled
work_dir = files["arbeit"]
folder = source_folder(topic)
mat = material_folder(topic) # thema: Research-Fundstellen als Inline-Korpus
caps = "files" if folder else "full"
# Source for the evidence exam in the clarify step (discards invented/unsupportable subs).
_type = load_source(topic).get("type", "thema")
@@ -896,7 +915,7 @@ async def _subblocks_block(ctx: GenContext, set_p, files: dict, entries: dict, i
# Material once per package (excerpts are round-invariant; one query per block
# keeps the coverage guarantee of _evidence_pack).
material, backing, round_caps = await asyncio.to_thread(
_finder_material, folder, sources, [str(entries[num]) for num in chunk])
_finder_material, mat, sources, [str(entries[num]) for num in chunk])
start = time.monotonic()
round_n = 0
while not is_cancelled():
@@ -1031,9 +1050,9 @@ async def _subblocks_block(ctx: GenContext, set_p, files: dict, entries: dict, i
if pending:
# Inline evidence: corpus excerpts in the prompt (no self-research); the judge
# answers as TEXT, the engine persists the j-file (resume + majority unchanged).
ev = _evidence_pack(folder, sources,
ev = _evidence_pack(mat, sources,
[title_by_num[num] for num in chunk]
+ [s for num in chunk for s in shown_by_num.get(num, [])]) if folder else ""
+ [s for num in chunk for s in shown_by_num.get(num, [])]) if mat else ""
j_source = _prompt("Blocks-Source-Inline", excerpts=ev) if ev else source
def _sink(result, p):
@@ -1147,7 +1166,7 @@ async def _subblocks_block(ctx: GenContext, set_p, files: dict, entries: dict, i
"Subbausteine. Suche gezielt nach WEITEREN belegbaren Kernaspekten, die "
"oben fehlen. Nimm NUR auf, was die Quellen wirklich hergeben — nicht aufblähen.")
material, backing, round_caps = await asyncio.to_thread(
_finder_material, folder, sources, [str(entries[num]) for num in lacking])
_finder_material, mat, sources, [str(entries[num]) for num in lacking])
paths = [work_dir / f"subblock-x{k}-c{c}-{i}.md" for i in (1, 2, 3)]
keys = [f"blocks-{topic}-{ns}subblock-x{k}-c{c}-{i}" for i in (1, 2, 3)]
new = await _one_round(f"{lbl}Subblocks catch-up {c} X{k}", lacking, assignment, paths, keys, known, focus, material, backing, round_caps)
@@ -1494,7 +1513,7 @@ async def _luecken_runde(ctx: GenContext, files: dict, title: str, luecken: list
known = ("\n\nBEREITS ERFASST — liste diese NICHT erneut:\n"
+ "\n".join(f"- {s}" for s in have)) if have else ""
material, backing, caps = await asyncio.to_thread(
_finder_material, folder, sources, [title] + list(luecken))
_finder_material, material_folder(topic), sources, [title] + list(luecken))
paths = [work_dir / f"luecken-{ns}r1-{i}.md" for i in (1, 2, 3)]
slots = [{
"key": f"blocks-{topic}-{ns}luecken-r1-{i}",
@@ -1901,7 +1920,8 @@ async def _facts_block(ctx, set_p, files: dict, raw: dict, q: dict, folder, inst
Zeichen) und endeten mit leerem Turn — Retry-Wellen à 6090 s seriell pro Block.
No-Tool-Calls mit Inline-Material hatten 0 solcher Fälle (Muster: Facts-Check).
Fail-open: ohne Treffer bleibt die alte Selbst-Recherche."""
ev = _evidence_pack(folder, sources, queries) if folder else ""
mat = material_folder(topic)
ev = _evidence_pack(mat, sources, queries) if mat else ""
if ev:
return _prompt("Blocks-Source-Inline", excerpts=ev), "none"
return source, caps
@@ -1974,7 +1994,8 @@ async def _facts_block(ctx, set_p, files: dict, raw: dict, q: dict, folder, inst
cites = [bf.get("source", "") for fm in per.values() for fk in fm.values()
for bf in fk.get("cited_facts", [])]
fallback = [blocks[i][0] for i in idxs] + [fk["sub"] for fm in per.values() for fk in fm.values()]
ev = _cited_evidence(folder, sources, cites, fallback) if folder else ""
mat = material_folder(topic)
ev = _cited_evidence(mat, sources, cites, fallback) if mat else ""
c_source = _prompt("Blocks-Source-Inline", excerpts=ev) if ev else source
pending = [j for j in panel if _facts_check_schema(_json_file(chk_path(ci, j))) is None]
tmap = {asyncio.create_task(