WP24c - Agentic Edge Validation & Chunk-Aware Multigraph-System (v4.5.8) #22
|
|
@ -206,6 +206,8 @@ def parse_edges_robust(text: str) -> List[Dict[str, Any]]:
|
|||
"""
|
||||
Extrahiert Kanten-Kandidaten aus Wikilinks und Callouts.
|
||||
WP-24c v4.2.7: Gibt Liste von Dicts zurück mit is_callout Flag für Chunk-Attribution.
|
||||
WP-24c v4.2.9 Fix A: current_edge_type bleibt über Leerzeilen hinweg erhalten,
|
||||
damit alle Links in einem Callout-Block korrekt verarbeitet werden.
|
||||
|
||||
Returns:
|
||||
List[Dict] mit keys: "edge" (str: "kind:target"), "is_callout" (bool)
|
||||
|
|
@ -234,11 +236,16 @@ def parse_edges_robust(text: str) -> List[Dict[str, Any]]:
|
|||
found_edges.append({"edge": f"{current_edge_type}:{l}", "is_callout": True})
|
||||
continue
|
||||
# Links in Folgezeilen des Callouts
|
||||
# WP-24c v4.2.9 Fix A: current_edge_type bleibt über Leerzeilen hinweg erhalten
|
||||
# innerhalb eines Callout-Blocks, damit alle Links korrekt verarbeitet werden
|
||||
if current_edge_type and stripped.startswith('>'):
|
||||
# Fortsetzung des Callout-Blocks: Links extrahieren
|
||||
links = re.findall(r'\[\[([^\]]+)\]\]', stripped)
|
||||
for l in links:
|
||||
if "rel:" not in l:
|
||||
found_edges.append({"edge": f"{current_edge_type}:{l}", "is_callout": True})
|
||||
elif not stripped.startswith('>'):
|
||||
elif current_edge_type and not stripped.startswith('>') and stripped:
|
||||
# Nicht-Callout-Zeile mit Inhalt: Callout-Block beendet
|
||||
current_edge_type = None
|
||||
# Leerzeilen werden ignoriert - current_edge_type bleibt erhalten
|
||||
return found_edges
|
||||
|
|
@ -212,6 +212,9 @@ def build_edges_for_note(
|
|||
WP-24c v4.2.7: Chunk-Attribution für Callouts über candidate_pool mit explicit:callout Provenance.
|
||||
WP-24c v4.2.9: Finalisierung der Chunk-Attribution - Synchronisation mit "Semantic First" Signal.
|
||||
Callout-Keys werden VOR dem globalen Scan aus candidate_pool gesammelt.
|
||||
WP-24c v4.2.9 Fix B: Zwei-Phasen-Synchronisation für Chunk-Autorität.
|
||||
Phase 1: Sammle alle explicit:callout Keys VOR Text-Scan.
|
||||
Phase 2: Globaler Scan respektiert all_chunk_callout_keys als Ausschlusskriterium.
|
||||
|
||||
Args:
|
||||
note_id: ID der Note
|
||||
|
|
@ -292,26 +295,31 @@ def build_edges_for_note(
|
|||
defaults = get_edge_defaults_for(note_type, reg)
|
||||
refs_all: List[str] = []
|
||||
|
||||
# WP-24c v4.2.9: Sammle alle Callout-Keys aus Chunks für Smart Logic
|
||||
# WP-24c v4.2.9 Fix B: Zwei-Phasen-Synchronisation für Chunk-Autorität
|
||||
# WICHTIG: Diese Menge muss VOR dem globalen Scan vollständig sein
|
||||
all_chunk_callout_keys: Set[Tuple[str, str, Optional[str]]] = set()
|
||||
|
||||
# WP-24c v4.2.9: PHASE 1: Sammle alle Callout-Keys aus candidate_pool VOR Text-Scan
|
||||
# PHASE 1 (Sicherung der Chunk-Autorität): Sammle alle Callout-Keys aus candidate_pool
|
||||
# BEVOR der globale Markdown-Scan oder der Loop über die Chunks beginnt
|
||||
# Dies stellt sicher, dass bereits geerntete Callouts nicht dupliziert werden
|
||||
for ch in chunks:
|
||||
cid = _get(ch, "chunk_id", "id")
|
||||
if not cid: continue
|
||||
|
||||
# B. Candidate Pool (WP-15b Validierte KI-Kanten)
|
||||
# WP-24c v4.2.9: Sammle Callout-Keys VOR Text-Scan für Synchronisation
|
||||
# Iteriere durch candidate_pool und sammle explicit:callout Kanten
|
||||
pool = ch.get("candidate_pool") or ch.get("candidate_edges") or []
|
||||
for cand in pool:
|
||||
raw_t, k, p = cand.get("to"), cand.get("kind", "related_to"), cand.get("provenance", "semantic_ai")
|
||||
t, sec = parse_link_target(raw_t, note_id)
|
||||
if t and p == "explicit:callout":
|
||||
# WP-24c v4.2.9: Markiere als bereits auf Chunk-Ebene verarbeitet
|
||||
# Dies verhindert, dass der globale Scan diese Kante als Note-Scope neu anlegt
|
||||
all_chunk_callout_keys.add((k, t, sec))
|
||||
raw_t = cand.get("to")
|
||||
k = cand.get("kind", "related_to")
|
||||
p = cand.get("provenance", "semantic_ai")
|
||||
|
||||
# WP-24c v4.2.9 Fix B: Wenn Provenance explicit:callout, extrahiere Key
|
||||
if p == "explicit:callout":
|
||||
t, sec = parse_link_target(raw_t, note_id)
|
||||
if t:
|
||||
# Key-Format: (kind, target, section) für Multigraph-Präzision
|
||||
# Dies verhindert, dass der globale Scan diese Kante als Note-Scope neu anlegt
|
||||
all_chunk_callout_keys.add((k, t, sec))
|
||||
|
||||
# WP-24c v4.2.9: PHASE 2: Verarbeite Chunks und erstelle Kanten
|
||||
for ch in chunks:
|
||||
|
|
@ -426,15 +434,16 @@ def build_edges_for_note(
|
|||
# 4) WP-24c v4.2.0: Note-Scope Edges hinzufügen (VOR De-Duplizierung)
|
||||
edges.extend(note_scope_edges)
|
||||
|
||||
# 5) WP-24c v4.2.9: Callout-Extraktion aus Markdown (NACH Chunk-Verarbeitung)
|
||||
# Deduplizierungs-Garantie: Nur Callouts, die NICHT in all_chunk_callout_keys sind,
|
||||
# werden mit scope: "note" angelegt. Dies verhindert Duplikate für bereits geerntete Callouts.
|
||||
# 5) WP-24c v4.2.9 Fix B PHASE 2 (Deduplizierung): Callout-Extraktion aus Markdown
|
||||
# Der globale Scan des markdown_body nutzt all_chunk_callout_keys als Ausschlusskriterium.
|
||||
# Callouts, die bereits in Phase 1 als Chunk-Kanten identifiziert wurden,
|
||||
# dürfen nicht erneut als Note-Scope Kanten angelegt werden.
|
||||
callout_edges_from_markdown: List[dict] = []
|
||||
if markdown_body:
|
||||
callout_edges_from_markdown = extract_callouts_from_markdown(
|
||||
markdown_body,
|
||||
note_id,
|
||||
existing_chunk_callouts=all_chunk_callout_keys # WP-24c v4.2.9: Strikte Respektierung
|
||||
existing_chunk_callouts=all_chunk_callout_keys # WP-24c v4.2.9 Fix B: Strikte Respektierung
|
||||
)
|
||||
edges.extend(callout_edges_from_markdown)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user