Dateien nach "app/core" hochladen
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 3s

This commit is contained in:
Lars 2025-11-17 21:23:49 +01:00
parent 8998269377
commit 4e98d5bfa1

View File

@ -5,15 +5,12 @@ Modul: app/core/derive_edges.py
Zweck: Zweck:
- Bewahrt bestehende Edgelogik (belongs_to, prev/next, references, backlink) - Bewahrt bestehende Edgelogik (belongs_to, prev/next, references, backlink)
- Ergänzt typenbasierte Default-Kanten (edge_defaults aus config/types.yaml) - Ergänzt typenbasierte Default-Kanten (edge_defaults aus config/types.yaml)
- Unterstützt "typed inline relations": - Unterstützt "typed inline relations" ([[rel:KIND | Target]] / [[rel:KIND Target]])
* [[rel:KIND | Target]] - Unterstützt Obsidian-Callouts (> [!edge] KIND: [[Target]] [[Target2]] ...)
* [[rel:KIND Target]]
* rel: KIND [[Target]]
- Unterstützt Obsidian-Callouts:
* > [!edge] KIND: [[Target]] [[Target2]] ...
Kompatibilität: Kompatibilität:
- build_edges_for_note(...) Signatur unverändert - build_edges_for_note(...) Signatur unverändert
- rule_id Werte: - rule_id Werte exakt wie zuvor erwartet (ohne Versionssuffix):
* structure:belongs_to * structure:belongs_to
* structure:order * structure:order
* explicit:wikilink * explicit:wikilink
@ -40,7 +37,7 @@ except Exception: # pragma: no cover
def _get(d: dict, *keys, default=None): def _get(d: dict, *keys, default=None):
for k in keys: for k in keys:
if isinstance(d, dict) and k in d and d[k] is not None: if k in d and d[k] is not None:
return d[k] return d[k]
return default return default
@ -138,21 +135,15 @@ def _edge_defaults_for(note_type: Optional[str], reg: dict) -> List[str]:
_WIKILINK_RE = re.compile(r"\[\[(?:[^\|\]]+\|)?([a-zA-Z0-9_\-#:. ]+)\]\]") _WIKILINK_RE = re.compile(r"\[\[(?:[^\|\]]+\|)?([a-zA-Z0-9_\-#:. ]+)\]\]")
# Getypte Inline-Relationen: # Getypte Inline-Relationen:
# [[rel:KIND | Target]] # [[rel:depends_on | Target]]
# [[rel:KIND Target]] # [[rel:related_to Target]]
_REL_PIPE = re.compile(r"\[\[\s*rel:(?P<kind>[a-z_]+)\s*\|\s*(?P<target>[^\]]+?)\s*\]\]", re.IGNORECASE) _REL_PIPE = re.compile(r"\[\[\s*rel:(?P<kind>[a-z_]+)\s*\|\s*(?P<target>[^\]]+?)\s*\]\]", re.IGNORECASE)
_REL_SPACE = re.compile(r"\[\[\s*rel:(?P<kind>[a-z_]+)\s+(?P<target>[^\]]+?)\s*\]\]", re.IGNORECASE) _REL_SPACE = re.compile(r"\[\[\s*rel:(?P<kind>[a-z_]+)\s+(?P<target>[^\]]+?)\s*\]\]", re.IGNORECASE)
# rel: KIND [[Target]] (reines Textmuster)
_REL_TEXT = re.compile(r"rel\s*:\s*(?P<kind>[a-z_]+)\s*\[\[\s*(?P<target>[^\]]+?)\s*\]\]", re.IGNORECASE)
def _extract_typed_relations(text: str) -> Tuple[List[Tuple[str,str]], str]: def _extract_typed_relations(text: str) -> Tuple[List[Tuple[str,str]], str]:
""" """
Gibt Liste (kind, target) zurück und den Text mit entfernten getypten Relation-Links, Gibt Liste (kind, target) zurück und den Text mit entfernten getypten Relation-Links,
damit die generische Wikilink-Erkennung sie nicht doppelt zählt. damit die generische Wikilink-Erkennung sie nicht doppelt zählt.
Unterstützt drei Varianten:
- [[rel:KIND | Target]]
- [[rel:KIND Target]]
- rel: KIND [[Target]]
""" """
pairs: List[Tuple[str,str]] = [] pairs: List[Tuple[str,str]] = []
def _collect(m): def _collect(m):
@ -161,10 +152,8 @@ def _extract_typed_relations(text: str) -> Tuple[List[Tuple[str,str]], str]:
if k and t: if k and t:
pairs.append((k, t)) pairs.append((k, t))
return "" # Link entfernen return "" # Link entfernen
text = _REL_PIPE.sub(_collect, text) text = _REL_PIPE.sub(_collect, text)
text = _REL_SPACE.sub(_collect, text) text = _REL_SPACE.sub(_collect, text)
text = _REL_TEXT.sub(_collect, text)
return pairs, text return pairs, text
# Obsidian Callout Parser # Obsidian Callout Parser
@ -249,7 +238,7 @@ def build_edges_for_note(
- belongs_to: für jeden Chunk (chunk -> note) - belongs_to: für jeden Chunk (chunk -> note)
- next / prev: zwischen aufeinanderfolgenden Chunks - next / prev: zwischen aufeinanderfolgenden Chunks
- references: pro Chunk aus window/text (via Wikilinks) - references: pro Chunk aus window/text (via Wikilinks)
- typed inline relations: [[rel:KIND | Target]] / [[rel:KIND Target]] / rel: KIND [[Target]] - typed inline relations: [[rel:KIND | Target]] oder [[rel:KIND Target]]
- Obsidian Callouts: > [!edge] KIND: [[Target]] [[Target2]] - Obsidian Callouts: > [!edge] KIND: [[Target]] [[Target2]]
- optional note-scope references/backlinks: dedupliziert über alle Chunk-Funde + note_level_references - optional note-scope references/backlinks: dedupliziert über alle Chunk-Funde + note_level_references
- typenbasierte Default-Kanten (edge_defaults) je gefundener Referenz - typenbasierte Default-Kanten (edge_defaults) je gefundener Referenz
@ -380,7 +369,6 @@ def build_edges_for_note(
"rule_id": f"edge_defaults:{note_type}:{rel}", "rule_id": f"edge_defaults:{note_type}:{rel}",
"confidence": 0.7, "confidence": 0.7,
})) }))
refs_all.extend(refs) refs_all.extend(refs)
# 4) optional note-scope refs/backlinks (+ defaults) # 4) optional note-scope refs/backlinks (+ defaults)