update
This commit is contained in:
@@ -1272,6 +1272,71 @@ async def _proc_dedup(ctx: GenContext, flow: Flow, cards):
|
||||
flow.wake.set()
|
||||
|
||||
|
||||
async def _attach_nachzuegler(ctx: GenContext, flow: Flow, rows: list[dict]) -> set[str]:
|
||||
"""Nachzügler-Atome (Supplement-/Lücken-Welle) zuerst an BESTEHENDE fertige Blöcke
|
||||
anschließen: das Atom wird Sub des Blocks (Bottom-up-Persistenz) statt Zwergblock
|
||||
mit einem Sub; die Board-2-Karte des Blocks geht zurück auf generate (Re-Anreicherung,
|
||||
Resume-Hash ändert sich mit der Sub-Menge). Erstwelle hat keine done_block-Blöcke →
|
||||
no-op. Ohne Zuordnung bleibt das Atom standalone (echtes neues Konzept).
|
||||
→ card_ids der angeschlossenen rows."""
|
||||
topic = flow.topic
|
||||
done = [c for c in await db.kanban_cards(topic, board=BOARD, kind="block", stage="done_block")
|
||||
if c["payload"].get("mirrored_norm")]
|
||||
if not done or not rows:
|
||||
return set()
|
||||
work_dir = flow.work_dir
|
||||
h = _h(*[r["card_id"] for r in rows], "attach")
|
||||
path = work_dir / f"gruppierung-attach-{h}.json"
|
||||
ids = set(range(1, len(rows) + 1))
|
||||
add = _completion_schema(_json_file(path), len(done), ids)
|
||||
if add is None:
|
||||
anchors = "\n".join(
|
||||
f"UMBRELLA {k}: {c['payload'].get('title', '')} — {(c['payload'].get('description') or '')[:160]}"
|
||||
for k, c in enumerate(done))
|
||||
rest = "\n".join(f"{i}. {_t_text(r)}" for i, r in enumerate(rows, 1))
|
||||
status, add = await run_single_slot(
|
||||
ctx, "Gruppierung Anschluss", key=f"blocks-{topic}-gruppierung-attach-{h}",
|
||||
prompt=_prompt("Blocks-Gruppierung-Completion", topic=topic, umbrellas=anchors,
|
||||
rest=rest, out_path=path),
|
||||
role="judge", capabilities="files",
|
||||
payload=lambda result, p=path: _completion_schema(_json_file(p), len(done), ids),
|
||||
timeout=_timeout("research_mapping", len(rows)))
|
||||
if status != OK or add is None:
|
||||
return set()
|
||||
attached: set[str] = set()
|
||||
moves = []
|
||||
for k, members in (add or []):
|
||||
c = done[k]
|
||||
bnorm = c["payload"]["mirrored_norm"]
|
||||
btitle = c["payload"].get("title", "")
|
||||
traf = False
|
||||
for m in members:
|
||||
if not (1 <= m <= len(rows)) or rows[m - 1]["card_id"] in attached:
|
||||
continue
|
||||
r = rows[m - 1]
|
||||
sn = _norm_title(r["title"])
|
||||
if not sn:
|
||||
continue
|
||||
await db.put_subblock(topic, bnorm, sn, btitle, r["title"], status="consensus")
|
||||
r["payload"].update(reason="attach", merged_into=btitle)
|
||||
await db.kanban_set_payload(topic, BOARD, r["card_id"], r["payload"])
|
||||
moves.append((r["card_id"], "grouped"))
|
||||
attached.add(r["card_id"])
|
||||
ch = c["payload"].setdefault("children", [])
|
||||
if r["title"] not in ch:
|
||||
ch.append(r["title"])
|
||||
traf = True
|
||||
if traf:
|
||||
await db.kanban_set_payload(topic, BOARD, c["card_id"], c["payload"])
|
||||
b2 = await db.kanban_get_card(topic, "artefacts", bnorm)
|
||||
if b2 and b2["stage"] != "generate": # neuen Sub anreichern lassen
|
||||
await db.kanban_advance(topic, "artefacts", bnorm, "generate")
|
||||
if moves:
|
||||
await db.kanban_advance_many(topic, BOARD, moves)
|
||||
_log(topic, f"Gruppierung: {len(moves)} Nachzügler an bestehende Blöcke angeschlossen")
|
||||
return attached
|
||||
|
||||
|
||||
def _themen_zielband(n: int) -> tuple[int, int]:
|
||||
"""Weiches Prompt-Band der Themenzahl: k = GROUP_THEMES_PER_SQRT·√n, ±30 %, min 2.
|
||||
n ist die Item-Zahl der GROUPING-WELLE — die Supplement-Welle bekommt bewusst ein
|
||||
@@ -1291,6 +1356,13 @@ async def _proc_grouping(ctx: GenContext, flow: Flow, cards):
|
||||
"title": c["payload"].get("title", ""),
|
||||
"description": c["payload"].get("description") or "",
|
||||
"title_norm": _norm_title(c["payload"].get("title", ""))} for c in cards]
|
||||
# Nachzügler-Wellen: erst an bestehende fertige Blöcke anschließen (Sub statt Zwergblock)
|
||||
attached = await _attach_nachzuegler(ctx, flow, rows)
|
||||
if attached:
|
||||
rows = [r for r in rows if r["card_id"] not in attached]
|
||||
if not rows:
|
||||
flow.wake.set()
|
||||
return
|
||||
n = len(rows)
|
||||
if not (BLOCKS_GRUPPIERUNG_AKTIV and await _emb_ok(flow)) or n < 3:
|
||||
await db.kanban_advance_many(topic, BOARD, [(r["card_id"], "gap_check") for r in rows])
|
||||
|
||||
Reference in New Issue
Block a user