update
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
# Standard-Provider für alle Agenten (Pflicht — es gibt keinen Code-Default)
|
||||||
|
DEFAULT_PROVIDER=minimax
|
||||||
|
|
||||||
# Datei nach .env kopieren (wird nicht committet).
|
# Datei nach .env kopieren (wird nicht committet).
|
||||||
|
|
||||||
# Claude-Provider: lokal einmal 'claude setup-token' ausführen, Token eintragen.
|
# Claude-Provider: lokal einmal 'claude setup-token' ausführen, Token eintragen.
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ def _fk_of(e: dict) -> dict:
|
|||||||
async def _generate_block(ctx: GenContext, files: dict, title: str, description: str,
|
async def _generate_block(ctx: GenContext, files: dict, title: str, description: str,
|
||||||
instructions: str = "", ns: str = "", lbl: str = "",
|
instructions: str = "", ns: str = "", lbl: str = "",
|
||||||
sources: list[str] | None = None,
|
sources: list[str] | None = None,
|
||||||
seeds: list[str] | None = None) -> dict | None:
|
seeds: list[str] | None = None, melde=None) -> dict | None:
|
||||||
"""GEN_PANEL unabhängige Generatoren liefern je Subs+Facts+Level/Relevanz in EINEM Call;
|
"""GEN_PANEL unabhängige Generatoren liefern je Subs+Facts+Level/Relevanz in EINEM Call;
|
||||||
Konsens im Code (Variant-Cluster über beide Ausgaben, ≥2 unabhängige Generatoren =
|
Konsens im Code (Variant-Cluster über beide Ausgaben, ≥2 unabhängige Generatoren =
|
||||||
consensus). Einzelnennungen und ungedeckte Seeds werden „unsicher" — der Prüfer
|
consensus). Einzelnennungen und ungedeckte Seeds werden „unsicher" — der Prüfer
|
||||||
@@ -237,6 +237,8 @@ async def _generate_block(ctx: GenContext, files: dict, title: str, description:
|
|||||||
"the material; if backed AND not already covered by another entry, include "
|
"the material; if backed AND not already covered by another entry, include "
|
||||||
"them — rephrased as a standalone statement):\n"
|
"them — rephrased as a standalone statement):\n"
|
||||||
+ "\n".join(f"- {s}" for s in dict.fromkeys(seeds) if s) + "\n")
|
+ "\n".join(f"- {s}" for s in dict.fromkeys(seeds) if s) + "\n")
|
||||||
|
if melde:
|
||||||
|
melde("Generate")
|
||||||
h = _h8(title, description, "gen")
|
h = _h8(title, description, "gen")
|
||||||
paths = [work_dir / f"gen-{h}-g{g}.json" for g in range(1, GEN_PANEL + 1)]
|
paths = [work_dir / f"gen-{h}-g{g}.json" for g in range(1, GEN_PANEL + 1)]
|
||||||
prompt = _prompt("Subblock-Generate", topic=topic,
|
prompt = _prompt("Subblock-Generate", topic=topic,
|
||||||
@@ -335,7 +337,7 @@ def _default_vote(stimmen: list[str], default: str) -> str:
|
|||||||
|
|
||||||
async def _verify_block(ctx: GenContext, files: dict, title: str, gen: dict, q: dict,
|
async def _verify_block(ctx: GenContext, files: dict, title: str, gen: dict, q: dict,
|
||||||
instructions: str = "", ns: str = "", lbl: str = "",
|
instructions: str = "", ns: str = "", lbl: str = "",
|
||||||
sources: list[str] | None = None) -> dict | None:
|
sources: list[str] | None = None, melde=None) -> dict | None:
|
||||||
"""VERIFY_PANEL unabhängige Prüfer auditieren den Block in EINEM Call (MECE-Faltung,
|
"""VERIFY_PANEL unabhängige Prüfer auditieren den Block in EINEM Call (MECE-Faltung,
|
||||||
Fremd, Lücken, Unsicher-Übernahme, Facts-Korrektheit, Level/Relevanz). Auswertung mit
|
Fremd, Lücken, Unsicher-Übernahme, Facts-Korrektheit, Level/Relevanz). Auswertung mit
|
||||||
Schnittmengen-Semantik pro Befundklasse (Faltung/Fremd/Übernahme einstimmig, Discard
|
Schnittmengen-Semantik pro Befundklasse (Faltung/Fremd/Übernahme einstimmig, Discard
|
||||||
@@ -356,6 +358,8 @@ async def _verify_block(ctx: GenContext, files: dict, title: str, gen: dict, q:
|
|||||||
(u for u in unsicher if u["title"] == t), {})
|
(u for u in unsicher if u["title"] == t), {})
|
||||||
return (fk.get("key_points") or [])[:3]
|
return (fk.get("key_points") or [])[:3]
|
||||||
|
|
||||||
|
if melde:
|
||||||
|
melde("Verify")
|
||||||
verdicts: list[dict] = []
|
verdicts: list[dict] = []
|
||||||
if n:
|
if n:
|
||||||
zeilen = "\n".join(f"{k}. {t}" + "".join(f"\n - {p}" for p in _kp(t))
|
zeilen = "\n".join(f"{k}. {t}" + "".join(f"\n - {p}" for p in _kp(t))
|
||||||
@@ -524,6 +528,8 @@ async def _verify_block(ctx: GenContext, files: dict, title: str, gen: dict, q:
|
|||||||
|
|
||||||
# 8. Fix-Tail (0–1 Call): Korrekturen + belegte Lücken
|
# 8. Fix-Tail (0–1 Call): Korrekturen + belegte Lücken
|
||||||
if (korrekturen or luecken) and not ctx.is_cancelled():
|
if (korrekturen or luecken) and not ctx.is_cancelled():
|
||||||
|
if melde:
|
||||||
|
melde("Fix")
|
||||||
neu = await _fix_befunde(ctx, files, title, korrekturen, luecken,
|
neu = await _fix_befunde(ctx, files, title, korrekturen, luecken,
|
||||||
[s["title"] for s in sidecar_subs], instructions, ns, lbl, sources)
|
[s["title"] for s in sidecar_subs], instructions, ns, lbl, sources)
|
||||||
for e in neu or []:
|
for e in neu or []:
|
||||||
@@ -603,7 +609,7 @@ def _subs_text(title: str, sidecar_subs: list[dict]) -> str:
|
|||||||
|
|
||||||
async def _artefakte_block(ctx: GenContext, files: dict, title: str,
|
async def _artefakte_block(ctx: GenContext, files: dict, title: str,
|
||||||
sidecar_subs: list[dict], instructions: str = "",
|
sidecar_subs: list[dict], instructions: str = "",
|
||||||
ns: str = "", lbl: str = "") -> dict | None:
|
ns: str = "", lbl: str = "", melde=None) -> dict | None:
|
||||||
"""EIN Generator-Call liefert Fragen + Flashcards + Beispiele (Split in 2 parallele
|
"""EIN Generator-Call liefert Fragen + Flashcards + Beispiele (Split in 2 parallele
|
||||||
Calls bei > ART_SPLIT_SUBS Subs), EIN Prüfer-Call verifiziert Beispiele, bereinigt
|
Calls bei > ART_SPLIT_SUBS Subs), EIN Prüfer-Call verifiziert Beispiele, bereinigt
|
||||||
die Fragen und ergänzt fehlende. → {pattern, artefacts} | None (nur Cancel)."""
|
die Fragen und ergänzt fehlende. → {pattern, artefacts} | None (nur Cancel)."""
|
||||||
@@ -611,6 +617,8 @@ async def _artefakte_block(ctx: GenContext, files: dict, title: str,
|
|||||||
work_dir = files["arbeit"]
|
work_dir = files["arbeit"]
|
||||||
if not sidecar_subs:
|
if not sidecar_subs:
|
||||||
return {"pattern": {title: []}, "artefacts": {"flashcard": [], "example": []}}
|
return {"pattern": {title: []}, "artefacts": {"flashcard": [], "example": []}}
|
||||||
|
if melde:
|
||||||
|
melde("Artefakte gen")
|
||||||
sh = _subs_hash({title: sidecar_subs})
|
sh = _subs_hash({title: sidecar_subs})
|
||||||
haelften = ([sidecar_subs] if len(sidecar_subs) <= ART_SPLIT_SUBS
|
haelften = ([sidecar_subs] if len(sidecar_subs) <= ART_SPLIT_SUBS
|
||||||
else [sidecar_subs[:len(sidecar_subs) // 2], sidecar_subs[len(sidecar_subs) // 2:]])
|
else [sidecar_subs[:len(sidecar_subs) // 2], sidecar_subs[len(sidecar_subs) // 2:]])
|
||||||
@@ -647,6 +655,8 @@ async def _artefakte_block(ctx: GenContext, files: dict, title: str,
|
|||||||
fehlend = [t for t in sub_titles
|
fehlend = [t for t in sub_titles
|
||||||
if _norm_title(t) not in {_norm_title(p["subblock"]) for p in pattern}]
|
if _norm_title(t) not in {_norm_title(p["subblock"]) for p in pattern}]
|
||||||
if pattern or examples:
|
if pattern or examples:
|
||||||
|
if melde:
|
||||||
|
melde("Artefakte check")
|
||||||
tabelle = "\n".join(f"({p['subblock']}) {p['question']}" for p in pattern) or "(keine)"
|
tabelle = "\n".join(f"({p['subblock']}) {p['question']}" for p in pattern) or "(keine)"
|
||||||
beisp = "\n\n".join(
|
beisp = "\n\n".join(
|
||||||
f"{k}. PROBLEM: {e['problem']}\n SCHRITTE: " + " | ".join(e["steps"])
|
f"{k}. PROBLEM: {e['problem']}\n SCHRITTE: " + " | ".join(e["steps"])
|
||||||
|
|||||||
@@ -167,6 +167,19 @@ async def _seed_map(topic: str) -> dict[str, list[str]]:
|
|||||||
return seeds
|
return seeds
|
||||||
|
|
||||||
|
|
||||||
|
def _melder(flow: Flow, norm: str):
|
||||||
|
"""Live-Stepper der Karte: Phasenname → card_info (ging bei der Call-Verschmelzung
|
||||||
|
verloren — Karten liefen ohne Badge/Stepper durch das Board)."""
|
||||||
|
set_p = _card_set_p(flow, norm)
|
||||||
|
|
||||||
|
def melde(schritt: str) -> None:
|
||||||
|
try:
|
||||||
|
set_p(f"{schritt}…", step=blocks._step_idx(flow.topic, schritt))
|
||||||
|
except ValueError:
|
||||||
|
set_p(f"{schritt}…")
|
||||||
|
return melde
|
||||||
|
|
||||||
|
|
||||||
async def _proc_generate(ctx: GenContext, flow: Flow, files: dict, instructions: str, cards):
|
async def _proc_generate(ctx: GenContext, flow: Flow, files: dict, instructions: str, cards):
|
||||||
"""Verschmolzener Erzeuger: 2 unabhängige Generatoren liefern Subs+Facts+Einstufung
|
"""Verschmolzener Erzeuger: 2 unabhängige Generatoren liefern Subs+Facts+Einstufung
|
||||||
in EINEM Call, Konsens im Code (block_calls._generate_block)."""
|
in EINEM Call, Konsens im Code (block_calls._generate_block)."""
|
||||||
@@ -181,7 +194,8 @@ async def _proc_generate(ctx: GenContext, flow: Flow, files: dict, instructions:
|
|||||||
p.get("description", ""), instructions,
|
p.get("description", ""), instructions,
|
||||||
ns=f"{_safe(norm)}-", lbl=f"{p.get('title', norm)} · ",
|
ns=f"{_safe(norm)}-", lbl=f"{p.get('title', norm)} · ",
|
||||||
sources=p.get("sources"),
|
sources=p.get("sources"),
|
||||||
seeds=[s for s in seeds.get(norm, []) if s] or None)
|
seeds=[s for s in seeds.get(norm, []) if s] or None,
|
||||||
|
melde=_melder(flow, norm))
|
||||||
if gen is None:
|
if gen is None:
|
||||||
return _fail_or_cancel(ctx, f"Generate {p.get('title', norm)}")
|
return _fail_or_cancel(ctx, f"Generate {p.get('title', norm)}")
|
||||||
p["raw"], p["facts"] = gen["raw"], gen["facts"]
|
p["raw"], p["facts"] = gen["raw"], gen["facts"]
|
||||||
@@ -207,7 +221,7 @@ async def _proc_verify(ctx: GenContext, flow: Flow, files: dict, q: dict, instru
|
|||||||
"unsicher": p.get("unsicher") or [], "votes": p.get("votes") or {}}
|
"unsicher": p.get("unsicher") or [], "votes": p.get("votes") or {}}
|
||||||
res = await _verify_block(ctx, _pfiles(files, norm), title, gen, q, instructions,
|
res = await _verify_block(ctx, _pfiles(files, norm), title, gen, q, instructions,
|
||||||
ns=f"{_safe(norm)}-", lbl=f"{title or norm} · ",
|
ns=f"{_safe(norm)}-", lbl=f"{title or norm} · ",
|
||||||
sources=p.get("sources"))
|
sources=p.get("sources"), melde=_melder(flow, norm))
|
||||||
if res is None:
|
if res is None:
|
||||||
return None # nur Cancel — Karte bleibt liegen
|
return None # nur Cancel — Karte bleibt liegen
|
||||||
p["raw"], p["facts"], p["sidecar"] = res["raw"], res["facts"], res["sidecar"]
|
p["raw"], p["facts"], p["sidecar"] = res["raw"], res["facts"], res["sidecar"]
|
||||||
@@ -230,7 +244,8 @@ async def _proc_artefakte(ctx: GenContext, flow: Flow, files: dict, instructions
|
|||||||
title = p.get("title", "")
|
title = p.get("title", "")
|
||||||
res = await _artefakte_block(ctx, _pfiles(files, norm), title,
|
res = await _artefakte_block(ctx, _pfiles(files, norm), title,
|
||||||
(p.get("sidecar") or {}).get(title) or [],
|
(p.get("sidecar") or {}).get(title) or [],
|
||||||
instructions, ns=f"{_safe(norm)}-", lbl=f"{title or norm} · ")
|
instructions, ns=f"{_safe(norm)}-", lbl=f"{title or norm} · ",
|
||||||
|
melde=_melder(flow, norm))
|
||||||
if res is None:
|
if res is None:
|
||||||
return None # nur Cancel
|
return None # nur Cancel
|
||||||
p["pattern"] = res["pattern"]
|
p["pattern"] = res["pattern"]
|
||||||
|
|||||||
@@ -266,7 +266,10 @@ FORMAT_PURPOSE = {
|
|||||||
# "judge" = mapping/judge/check agents — cold (low temperature,
|
# "judge" = mapping/judge/check agents — cold (low temperature,
|
||||||
# no thinking) for stable verdicts; Claude/local map to "fast",
|
# no thinking) for stable verdicts; Claude/local map to "fast",
|
||||||
# "guide" = large generation (proposals, writer).
|
# "guide" = large generation (proposals, writer).
|
||||||
DEFAULT_PROVIDER = "claude"
|
# Kein Provider-Default im Code (Betreiber-Vorgabe): die .env entscheidet.
|
||||||
|
DEFAULT_PROVIDER = os.getenv("DEFAULT_PROVIDER", "")
|
||||||
|
if not DEFAULT_PROVIDER:
|
||||||
|
raise RuntimeError("DEFAULT_PROVIDER fehlt in der .env (z. B. DEFAULT_PROVIDER=minimax)")
|
||||||
PROVIDERS = {
|
PROVIDERS = {
|
||||||
"claude": {
|
"claude": {
|
||||||
"cli": "claude",
|
"cli": "claude",
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ def aktivieren(welt: Welt, setattr_fn=setattr) -> None:
|
|||||||
import qa
|
import qa
|
||||||
import repair
|
import repair
|
||||||
|
|
||||||
async def fake_run_agent(agent_key, prompt, timeout, provider="claude", role="fast",
|
async def fake_run_agent(agent_key, prompt, timeout, provider="", role="fast",
|
||||||
capabilities="none", lane="batch", scope=None, on_line=None, label=""):
|
capabilities="none", lane="batch", scope=None, on_line=None, label=""):
|
||||||
return welt.respond(agent_key, prompt, capabilities)
|
return welt.respond(agent_key, prompt, capabilities)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ FormatType = Literal[
|
|||||||
"Rest",
|
"Rest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
from config import DEFAULT_PROVIDER
|
||||||
|
|
||||||
ProviderType = Literal["claude", "minimax", "lokal"]
|
ProviderType = Literal["claude", "minimax", "lokal"]
|
||||||
|
|
||||||
SourceType = Literal["thema", "projekt", "uni", "link"]
|
SourceType = Literal["thema", "projekt", "uni", "link"]
|
||||||
@@ -16,7 +18,7 @@ class GuideCreateRequest(BaseModel):
|
|||||||
topic: str = Field(min_length=1, max_length=100)
|
topic: str = Field(min_length=1, max_length=100)
|
||||||
format: FormatType
|
format: FormatType
|
||||||
instructions: str = Field(default="", max_length=2000)
|
instructions: str = Field(default="", max_length=2000)
|
||||||
provider: ProviderType = "claude"
|
provider: ProviderType = DEFAULT_PROVIDER
|
||||||
ab_step: int | None = Field(default=None, ge=0, le=5) # re-run from board stage (0 lernziele … 5 lesbarkeit); None = full/resume
|
ab_step: int | None = Field(default=None, ge=0, le=5) # re-run from board stage (0 lernziele … 5 lesbarkeit); None = full/resume
|
||||||
|
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ class RepairRequest(BaseModel):
|
|||||||
class BlocksCreateRequest(BaseModel):
|
class BlocksCreateRequest(BaseModel):
|
||||||
topic: str = Field(min_length=1, max_length=100)
|
topic: str = Field(min_length=1, max_length=100)
|
||||||
instructions: str = Field(default="", max_length=2000)
|
instructions: str = Field(default="", max_length=2000)
|
||||||
provider: ProviderType = "claude"
|
provider: ProviderType = DEFAULT_PROVIDER
|
||||||
source_type: SourceType = "thema"
|
source_type: SourceType = "thema"
|
||||||
source_location: str = Field(default="", max_length=2000)
|
source_location: str = Field(default="", max_length=2000)
|
||||||
research: bool = True # False = Continue: drain the existing kanban queue, no new search
|
research: bool = True # False = Continue: drain the existing kanban queue, no new search
|
||||||
@@ -157,7 +159,7 @@ class GuideChatRequest(BaseModel):
|
|||||||
section: str = Field(default="", max_length=20000)
|
section: str = Field(default="", max_length=20000)
|
||||||
outline: str = Field(default="", max_length=8000)
|
outline: str = Field(default="", max_length=8000)
|
||||||
messages: list[ChatMessage] = Field(min_length=1)
|
messages: list[ChatMessage] = Field(min_length=1)
|
||||||
provider: ProviderType = "claude"
|
provider: ProviderType = DEFAULT_PROVIDER
|
||||||
|
|
||||||
|
|
||||||
class GuideChatResponse(BaseModel):
|
class GuideChatResponse(BaseModel):
|
||||||
@@ -172,7 +174,7 @@ class BlockChatRequest(BaseModel):
|
|||||||
section: str = Field(default="", max_length=20000) # detailed version
|
section: str = Field(default="", max_length=20000) # detailed version
|
||||||
section_compact: str = Field(default="", max_length=20000) # compact version (mnemonics)
|
section_compact: str = Field(default="", max_length=20000) # compact version (mnemonics)
|
||||||
messages: list[ChatMessage] = Field(min_length=1)
|
messages: list[ChatMessage] = Field(min_length=1)
|
||||||
provider: ProviderType = "claude"
|
provider: ProviderType = DEFAULT_PROVIDER
|
||||||
|
|
||||||
|
|
||||||
class BlockChatResponse(BaseModel):
|
class BlockChatResponse(BaseModel):
|
||||||
@@ -203,7 +205,7 @@ class BlockExamRequest(BaseModel):
|
|||||||
# Base + cap are kept server-side (anchor / subs×25) — the client cap is only a hint.
|
# Base + cap are kept server-side (anchor / subs×25) — the client cap is only a hint.
|
||||||
cap: int = Field(default=10, ge=1, le=10000) # score cap = unlocked subblocks × 25
|
cap: int = Field(default=10, ge=1, le=10000) # score cap = unlocked subblocks × 25
|
||||||
messages: list[ChatMessage] = [] # dialog so far; empty = first question
|
messages: list[ChatMessage] = [] # dialog so far; empty = first question
|
||||||
provider: ProviderType = "claude"
|
provider: ProviderType = DEFAULT_PROVIDER
|
||||||
thorough: bool = False # "thorough check": rating with a strong model (role guide)
|
thorough: bool = False # "thorough check": rating with a strong model (role guide)
|
||||||
|
|
||||||
|
|
||||||
@@ -246,7 +248,7 @@ class BlockPruefenRequest(BaseModel):
|
|||||||
spot: str = "ausführlich" # "compact" | "ausführlich" (displayed field)
|
spot: str = "ausführlich" # "compact" | "ausführlich" (displayed field)
|
||||||
snippet: str = Field(min_length=1, max_length=20000) # raw markdown block
|
snippet: str = Field(min_length=1, max_length=20000) # raw markdown block
|
||||||
hint: str = Field(default="", max_length=2000) # optional addition (✏️)
|
hint: str = Field(default="", max_length=2000) # optional addition (✏️)
|
||||||
provider: ProviderType = "claude"
|
provider: ProviderType = DEFAULT_PROVIDER
|
||||||
|
|
||||||
|
|
||||||
class BlockPruefenResponse(BaseModel):
|
class BlockPruefenResponse(BaseModel):
|
||||||
@@ -258,7 +260,7 @@ class BlockUebernehmenRequest(BaseModel):
|
|||||||
spot: str = "ausführlich"
|
spot: str = "ausführlich"
|
||||||
alt: str = Field(min_length=1, max_length=20000)
|
alt: str = Field(min_length=1, max_length=20000)
|
||||||
revised: str = Field(default="", max_length=20000)
|
revised: str = Field(default="", max_length=20000)
|
||||||
provider: ProviderType = "claude"
|
provider: ProviderType = DEFAULT_PROVIDER
|
||||||
|
|
||||||
|
|
||||||
class BlockUebernehmenResponse(BaseModel):
|
class BlockUebernehmenResponse(BaseModel):
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ async def run_repair_route(req: RepairRequest):
|
|||||||
|
|
||||||
|
|
||||||
@router.post("/blocks/research")
|
@router.post("/blocks/research")
|
||||||
async def add_blocks_research(topic: str, provider: str = "claude"):
|
async def add_blocks_research(topic: str, provider: str = DEFAULT_PROVIDER):
|
||||||
"""Attach one more research agent — to the live flow, or attach-or-start."""
|
"""Attach one more research agent — to the live flow, or attach-or-start."""
|
||||||
if add_research_agent(topic):
|
if add_research_agent(topic):
|
||||||
return {"ok": True, "attached": True}
|
return {"ok": True, "attached": True}
|
||||||
|
|||||||
@@ -71,14 +71,14 @@ async def board_env(testdb, tmp_path, monkeypatch):
|
|||||||
monkeypatch.setattr(bi, "_emb_ok", no_emb)
|
monkeypatch.setattr(bi, "_emb_ok", no_emb)
|
||||||
|
|
||||||
async def fake_generate(ctx, files, title, description, instructions="", ns="", lbl="",
|
async def fake_generate(ctx, files, title, description, instructions="", ns="", lbl="",
|
||||||
sources=None, seeds=None):
|
sources=None, seeds=None, melde=None):
|
||||||
subs = ["Sub Eins", "Sub Zwei"]
|
subs = ["Sub Eins", "Sub Zwei"]
|
||||||
return {"raw": {title: list(subs)},
|
return {"raw": {title: list(subs)},
|
||||||
"facts": {title: {_norm_title(s): {"key_points": [f"Fakt zu {s}"], "cited_facts": []}
|
"facts": {title: {_norm_title(s): {"key_points": [f"Fakt zu {s}"], "cited_facts": []}
|
||||||
for s in subs}},
|
for s in subs}},
|
||||||
"unsicher": [], "votes": {}}
|
"unsicher": [], "votes": {}}
|
||||||
|
|
||||||
async def fake_verify(ctx, files, title, gen, q, instructions="", ns="", lbl="", sources=None):
|
async def fake_verify(ctx, files, title, gen, q, instructions="", ns="", lbl="", sources=None, melde=None):
|
||||||
subs = gen["raw"].get(title) or []
|
subs = gen["raw"].get(title) or []
|
||||||
bfacts = gen["facts"].get(title) or {}
|
bfacts = gen["facts"].get(title) or {}
|
||||||
sidecar = [{"title": s, "level": "beginner",
|
sidecar = [{"title": s, "level": "beginner",
|
||||||
@@ -87,7 +87,7 @@ async def board_env(testdb, tmp_path, monkeypatch):
|
|||||||
for i, s in enumerate(subs)]
|
for i, s in enumerate(subs)]
|
||||||
return {"raw": {title: list(subs)}, "facts": {title: bfacts}, "sidecar": {title: sidecar}}
|
return {"raw": {title: list(subs)}, "facts": {title: bfacts}, "sidecar": {title: sidecar}}
|
||||||
|
|
||||||
async def fake_artefakte(ctx, files, title, sidecar_subs, instructions="", ns="", lbl=""):
|
async def fake_artefakte(ctx, files, title, sidecar_subs, instructions="", ns="", lbl="", melde=None):
|
||||||
if not sidecar_subs:
|
if not sidecar_subs:
|
||||||
return {"pattern": {title: []}, "artefacts": {"flashcard": [], "example": []}}
|
return {"pattern": {title: []}, "artefacts": {"flashcard": [], "example": []}}
|
||||||
first = sidecar_subs[0]["title"]
|
first = sidecar_subs[0]["title"]
|
||||||
@@ -242,7 +242,7 @@ async def test_empty_subblocks_completes_without_deadletter(board_env, monkeypat
|
|||||||
db, ctx, files = board_env
|
db, ctx, files = board_env
|
||||||
|
|
||||||
async def empty_gen(ctx, files, title, description, instructions="", ns="", lbl="",
|
async def empty_gen(ctx, files, title, description, instructions="", ns="", lbl="",
|
||||||
sources=None, seeds=None):
|
sources=None, seeds=None, melde=None):
|
||||||
return {"raw": {title: []}, "facts": {title: {}}, "unsicher": [], "votes": {}}
|
return {"raw": {title: []}, "facts": {title: {}}, "unsicher": [], "votes": {}}
|
||||||
monkeypatch.setattr(ba, "_generate_block", empty_gen)
|
monkeypatch.setattr(ba, "_generate_block", empty_gen)
|
||||||
await db.kanban_upsert_card(TOPIC, "artefacts", "leer", "ablock", "generate",
|
await db.kanban_upsert_card(TOPIC, "artefacts", "leer", "ablock", "generate",
|
||||||
@@ -719,7 +719,7 @@ async def test_outline_runs_before_artefacts_finish(board_env, monkeypatch):
|
|||||||
base_verify = ba._verify_block
|
base_verify = ba._verify_block
|
||||||
snapshot = {}
|
snapshot = {}
|
||||||
|
|
||||||
async def slow_verify(ctx, files, title, gen, q, instructions="", ns="", lbl="", sources=None):
|
async def slow_verify(ctx, files, title, gen, q, instructions="", ns="", lbl="", sources=None, melde=None):
|
||||||
await asyncio.sleep(0.8) # keeps one card in `verify` while the outline fires
|
await asyncio.sleep(0.8) # keeps one card in `verify` while the outline fires
|
||||||
return await base_verify(ctx, files, title, gen, q, instructions, ns=ns, lbl=lbl, sources=sources)
|
return await base_verify(ctx, files, title, gen, q, instructions, ns=ns, lbl=lbl, sources=sources)
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
# WICHTIG: config (mit CREATOR_PARAMS) lädt vor allen Pipeline-Modulen
|
# WICHTIG: config (mit CREATOR_PARAMS) lädt vor allen Pipeline-Modulen
|
||||||
import database
|
import database
|
||||||
|
from config import DEFAULT_PROVIDER
|
||||||
from fake_agents import Welt, aktivieren
|
from fake_agents import Welt, aktivieren
|
||||||
from fsutil import atomic_write_json
|
from fsutil import atomic_write_json
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ async def f0(out: str) -> None:
|
|||||||
"artefakte": tmp / "artefakte.json", "outline": tmp / "outline.json",
|
"artefakte": tmp / "artefakte.json", "outline": tmp / "outline.json",
|
||||||
"outline_slots": [tmp / f"outline-{i}.json" for i in (1, 2, 3)],
|
"outline_slots": [tmp / f"outline-{i}.json" for i in (1, 2, 3)],
|
||||||
"research": [work / f"research-{i}.md" for i in (1, 2, 3, 4, 5)]}
|
"research": [work / f"research-{i}.md" for i in (1, 2, 3, 4, 5)]}
|
||||||
ctx = GenContext(topic="f0", provider="claude", is_cancelled=lambda: False)
|
ctx = GenContext(topic="f0", provider=DEFAULT_PROVIDER, is_cancelled=lambda: False)
|
||||||
start = time.monotonic()
|
start = time.monotonic()
|
||||||
ok = await asyncio.wait_for(
|
ok = await asyncio.wait_for(
|
||||||
bi.run_boards(ctx, lambda *a, **k: None, files, {"type": "thema"}, None, "",
|
bi.run_boards(ctx, lambda *a, **k: None, files, {"type": "thema"}, None, "",
|
||||||
|
|||||||
Reference in New Issue
Block a user