From d17c966301590d1203b677e11e10b9586b375612 Mon Sep 17 00:00:00 2001 From: Lars Date: Tue, 6 Jan 2026 10:20:55 +0100 Subject: [PATCH] Enhance callout extraction in graph_extractors.py: Update regex to support nested [!edge] callouts and improve handling of indentation levels. This allows for more flexible parsing of callout structures in the input text. --- app/core/graph/graph_extractors.py | 61 ++++++++++++++++++----- docs/00_General/00_Marketing_V3.md | 69 ++++++++++++++++++++++++++ docs/06_Roadmap/06_Feature-Backlog.md | 39 +++++++++++++++ docs/06_Roadmap/06_Sprintplanung_01.md | 29 +++++++++++ 4 files changed, 186 insertions(+), 12 deletions(-) create mode 100644 docs/00_General/00_Marketing_V3.md create mode 100644 docs/06_Roadmap/06_Feature-Backlog.md create mode 100644 docs/06_Roadmap/06_Sprintplanung_01.md diff --git a/app/core/graph/graph_extractors.py b/app/core/graph/graph_extractors.py index 690e561..b0ae82d 100644 --- a/app/core/graph/graph_extractors.py +++ b/app/core/graph/graph_extractors.py @@ -15,7 +15,8 @@ _REL_PIPE = re.compile(r"\[\[\s*rel:(?P[a-z_]+)\s*\|\s*(?P[^\]]+? _REL_SPACE = re.compile(r"\[\[\s*rel:(?P[a-z_]+)\s+(?P[^\]]+?)\s*\]\]", re.IGNORECASE) _REL_TEXT = re.compile(r"rel\s*:\s*(?P[a-z_]+)\s*\[\[\s*(?P[^\]]+?)\s*\]\]", re.IGNORECASE) -_CALLOUT_START = re.compile(r"^\s*>\s*\[!edge\]\s*(.*)$", re.IGNORECASE) +# Erkennt [!edge] Callouts mit einem oder mehreren '>' am Anfang (für verschachtelte Callouts) +_CALLOUT_START = re.compile(r"^\s*>{1,}\s*\[!edge\]\s*(.*)$", re.IGNORECASE) # Erkennt "kind: targets..." _REL_LINE = re.compile(r"^(?P[a-z_]+)\s*:\s*(?P.+?)\s*$", re.IGNORECASE) # Erkennt reine Typen (z.B. "depends_on" im Header) @@ -43,6 +44,7 @@ def extract_callout_relations(text: str) -> Tuple[List[Tuple[str,str]], str]: Unterstützt zwei Formate: 1. Explizit: "kind: [[Target]]" 2. Implizit (Header): "> [!edge] kind" gefolgt von "[[Target]]" Zeilen + 3. Verschachtelt: ">> [!edge] kind" in verschachtelten Callouts """ if not text: return [], text lines = text.splitlines() @@ -61,17 +63,35 @@ def extract_callout_relations(text: str) -> Tuple[List[Tuple[str,str]], str]: # Callout-Block gefunden. Wir sammeln alle relevanten Zeilen. block_lines = [] - # Header Content prüfen (z.B. "type" aus "> [!edge] type") + # Header Content prüfen (z.B. "type" aus "> [!edge] type" oder ">> [!edge] type") header_raw = m.group(1).strip() if header_raw: block_lines.append(header_raw) + + # Bestimme die Einrückungsebene (Anzahl der '>' am Anfang der ersten Zeile) + leading_gt_count = len(line) - len(line.lstrip('>')) + if leading_gt_count == 0: + leading_gt_count = 1 # Fallback für den Fall, dass kein '>' gefunden wurde i += 1 - while i < len(lines) and lines[i].lstrip().startswith('>'): - # Entferne '>' und führende Leerzeichen - content = lines[i].lstrip()[1:].lstrip() - if content: - block_lines.append(content) + # Sammle alle Zeilen, die mit mindestens der gleichen Anzahl '>' beginnen + while i < len(lines): + next_line = lines[i] + stripped = next_line.lstrip() + # Prüfe, ob die Zeile mit mindestens der gleichen Anzahl '>' beginnt + if not stripped.startswith('>'): + break + next_leading_gt_count = len(next_line) - len(next_line.lstrip('>')) + # Wenn die Einrückung kleiner wird, haben wir den Block verlassen + if next_leading_gt_count < leading_gt_count: + break + # Entferne genau die Anzahl der führenden '>' entsprechend der Einrückungsebene + # und dann führende Leerzeichen + if next_leading_gt_count >= leading_gt_count: + # Entferne die führenden '>' (entsprechend der Einrückungsebene) + content = stripped[leading_gt_count:].lstrip() + if content: + block_lines.append(content) i += 1 # Verarbeitung des Blocks @@ -86,6 +106,26 @@ def extract_callout_relations(text: str) -> Tuple[List[Tuple[str,str]], str]: current_kind = first.lower() for bl in block_lines: + # Prüfe, ob diese Zeile selbst ein neuer [!edge] Callout ist (für verschachtelte Blöcke) + edge_match = re.match(r"^\s*\[!edge\]\s*(.*)$", bl, re.IGNORECASE) + if edge_match: + # Neuer Edge-Callout gefunden, setze den Typ + edge_content = edge_match.group(1).strip() + if edge_content: + # Prüfe, ob es ein "kind: targets" Format ist + mrel = _REL_LINE.match(edge_content) + if mrel: + current_kind = mrel.group("kind").strip().lower() + targets = mrel.group("targets") + # Links extrahieren + found = _WIKILINK_RE.findall(targets) + if found: + for t in found: out_pairs.append((current_kind, t.strip())) + elif _SIMPLE_KIND.match(edge_content): + # Reiner Typ ohne Targets + current_kind = edge_content.lower() + continue + # 1. Prüfen auf explizites "Kind: Targets" (überschreibt Header-Typ für diese Zeile) mrel = _REL_LINE.match(bl) if mrel: @@ -101,11 +141,8 @@ def extract_callout_relations(text: str) -> Tuple[List[Tuple[str,str]], str]: for raw in re.split(r"[,;]", targets): if raw.strip(): out_pairs.append((line_kind, raw.strip())) - # Wenn wir eine explizite Zeile gefunden haben, aktualisieren wir NICHT - # den current_kind für nachfolgende Zeilen (Design-Entscheidung: lokal scope), - # oder wir machen es doch? - # Üblicher ist: Header setzt Default, Zeile überschreibt lokal. - # Wir lassen current_kind also unangetastet. + # Aktualisiere current_kind für nachfolgende Zeilen + current_kind = line_kind continue # 2. Kein Key:Value Muster -> Prüfen auf Links, die den current_kind nutzen diff --git a/docs/00_General/00_Marketing_V3.md b/docs/00_General/00_Marketing_V3.md new file mode 100644 index 0000000..08c21c3 --- /dev/null +++ b/docs/00_General/00_Marketing_V3.md @@ -0,0 +1,69 @@ +# Mindnet V3.0: Der Aufstieg des Digitalen Zwillings +## Von der Wissensdatenbank zum strategischen Partner – Ein Paradigmenwechsel + +### Einleitung: Die Vision von Version 3.0 +Mit der Vollendung des Meilensteins WP25 (inklusive der Architektur-Erweiterungen 25a und 25b) transformiert sich Mindnet von einem reinen Retrieval-System (V2) zu einem autonomen, agentischen Ökosystem (V3.0). Mindnet V3.0 ist nicht länger nur ein Werkzeug zur Informationswiedergabe; es ist ein **Digitaler Zwilling**, der in der Lage ist, komplexe Realitäten durch Multi-Stream-Analysen zu erfassen, strategische Empfehlungen auf Basis individueller Werte zu geben und eine bisher unerreichte Ausfallsicherheit zu garantieren. + +--- + +### Die 6 Säulen der Mindnet V3.0 Architektur + +#### 1. Agentic Multi-Stream Retrieval (WP-25) +Das Herzstück von V3.0 ist die neue `DecisionEngine`. Während herkömmliche Systeme lediglich eine einfache Vektorsuche durchführen, orchestriert die DecisionEngine parallele Wissens-Streams: +* **Werte-Stream:** Abgleich von Anfragen mit Ihrer ethischen und strategischen Identität. +* **Fakten-Stream:** Analyse der operativen Realität und aktueller Projektdaten. +* **Biografie-Stream:** Integration persönlicher Erfahrungen und historischer Kontexte. +* **Risiko-Radar:** Proaktive Identifikation von Hindernissen und Zielkonflikten. +* **Technik-Wissen:** Tiefgreifende fachliche Expertise für spezialisierte Aufgaben. + +Dieses System erlaubt es Mindnet, eine Anfrage aus fünf verschiedenen Perspektiven gleichzeitig zu beleuchten, bevor eine finale Synthese erfolgt. + +#### 2. Mixture of Experts (MoE) & Dynamic Profiling (WP-25a) +Mindnet V3.0 nutzt nicht mehr nur "ein" Modell. Über die zentrale Steuerung in der `llm_profiles.yaml` wird für jede Teilaufgabe der ideale "Experte" gerufen: +* **Der Architekt (Gemini 2.0 Flash):** Für hochkomplexe reasoning-intensive Synthesen. +* **Der Ingenieur (Qwen 2.5):** Spezialisiert auf präzise Code-Generierung und technische Problemlösung. +* **Der Dampfhammer (Mistral 7B):** Optimiert für blitzschnelles Routing und asynchrone Inhaltskompression. +* **Der Wächter (Phi-3 Mini):** Ein lokales Modell via Ollama, das maximale Privatsphäre für sensible Identitätsdaten garantiert. + +#### 3. Hierarchische Lazy-Prompt-Orchestration (WP-25b) +Ein technologisches Highlight ist die Einführung des **Lazy-Promptings**. Prompts werden nicht mehr statisch im Code verwaltet, sondern erst im Moment der Modellauswahl hierarchisch aufgelöst: +1. **Modell-Ebene:** Spezifisch für die jeweilige Modell-ID optimierte Instruktionen. +2. **Provider-Ebene:** Fallback-Anweisungen für OpenRouter oder Ollama. +3. **Global-Ebene:** Sicherheits-Instruktionen als ultimativer Anker. + +Dies garantiert, dass jedes Modell in seiner "Muttersprache" angesprochen wird, was die Antwortqualität drastisch erhöht. + +#### 4. Die unzerstörbare Fallback-Kaskade +Resilienz ist in V3.0 kein Schlagwort, sondern ein Algorithmus. Sollte ein Cloud-Anbieter (wie OpenRouter) ausfallen oder in ein Rate-Limit laufen, reagiert das System autonom: +* Automatischer Wechsel auf das Backup-Profil (z.B. von Gemini auf Llama). +* In letzter Instanz: Rückzug auf die lokale Hardware (Ollama/Phi-3), sodass Mindnet auch offline voll einsatzfähig bleibt. +* **Lazy-Re-Formatting:** Beim Wechsel des Modells wird auch der Prompt sofort neu geladen und für das neue Modell optimiert. + +#### 5. Hochpräzises Intent-Routing mit Regex-Cleaning +Durch den neuen ultra-robusten Router in der `DecisionEngine` v1.3.2 erkennt Mindnet Nutzerintentionen mit chirurgischer Präzision. Modell-Artefakte (wie Stop-Marker oder überflüssige Tags freier Modelle) werden durch aggressive Regex-Filter eliminiert, bevor sie das System-Routing stören können. Dies stellt sicher, dass eine Coding-Frage niemals fälschlicherweise im Fakten-Modus landet. + +#### 6. Semantische Ingestion-Validierung v2.14.0 +Die Qualität des Wissensgraphen wird durch eine neue Validierungsebene geschützt. Während des Imports prüft Mindnet semantisch, ob vorgeschlagene Verknüpfungen (Edges) zwischen Informationen wirklich sinnvoll sind. Dabei unterscheidet das System zwischen temporären Netzwerkfehlern und dauerhaften Logikfehlern, um die Integrität Ihres digitalen Gedächtnisses zu wahren. + +--- + +### Technische Highlights für Power-User + +| Feature | Technologie | Nutzen | +| :--- | :--- | :--- | +| **Orchestrator** | `DecisionEngine v1.3.2` | Agentische Steuerung & Multi-Stream Retrieval | +| **Hybrid Cloud** | OpenRouter & Ollama | Maximale Flexibilität zwischen Leistung und Datenschutz | +| **Traceability** | `[PROMPT-TRACE]` Logs | Volle Transparenz über die genutzten KI-Instruktionen | +| **Context Guard** | Asynchrone Kompression | Optimierung der Kontextfenster für maximale Kosten-Effizienz | +| **Resilienz** | Rekursive Fallback-Kaskade | 100% Verfügbarkeit durch Cloud-to-Local Automatisierung | + +--- + +### Fazit: Ihr Gehirn, erweitert durch Mindnet V3.0 +Mindnet V3.0 ist das Ergebnis einer konsequenten Weiterentwicklung hin zu einer **Zero-Failure-Architektur**. Durch die Kombination aus agentischer Intelligenz, hybrider Modellnutzung und der neuen Lazy-Prompt-Infrastruktur bietet es eine Basis, die nicht nur mit Ihrem Wissen wächst, sondern aktiv dabei hilft, dieses Wissen in strategisches Handeln zu übersetzen. + +**Willkommen in der Ära von Mindnet V3.0 – Ihr strategischer Partner ist bereit.** + +--- +*Dokumentations-Identifikator: `mindnet_v3_core_release`* +*Synchronisations-Stand: WP-25b Final* \ No newline at end of file diff --git a/docs/06_Roadmap/06_Feature-Backlog.md b/docs/06_Roadmap/06_Feature-Backlog.md new file mode 100644 index 0000000..eb7b94d --- /dev/null +++ b/docs/06_Roadmap/06_Feature-Backlog.md @@ -0,0 +1,39 @@ +# 📋 Mindnet Feature-Backlog (V3.1 - V4.0) + +**Projekt:** Mindnet – Der Digitale Zwilling +**Status:** Aktiv nach Meilenstein WP-25b +**Architektur:** MoE, Multi-Stream RAG, Lazy-Prompt-Orchestration + +--- + +## 🟢 Priorisierte Features (V3.1 - V3.5) + +### WP-26: Conversational Soul (Memory & Context) +* **Nutzerwert:** Ermöglicht echte Dialoge ("Erkläre mir den Punkt von eben genauer"). +* **Lösungsskizze:** + * Implementierung eines `SessionStore` (SQLite) für Chat-Verläufe. + * Erweiterung der `DecisionEngine` um einen `ContextReducer`, der die Historie asynchron zusammenfasst (via Profil `compression_fast`). + * Einspeisung der Historie in die Synthese-Prompts via `{history}` Platzhalter. +* **Abhängigkeiten:** `DecisionEngine` v1.3.2, `LLMService` v3.5.6. + +### WP-27: Autonomous Tuning (Self-Calibration) +* **Nutzerwert:** Das System lernt aus Fehlern und optimiert das Retrieval selbstständig. +* **Lösungsskizze:** + * Auswertung der JSONL-Feedback-Logs (Daumen hoch/runter). + * Automatisierte Anpassung von `edge_boosts` und `top_k` in einer neuen `tuning_registry.json`, die Werte in der `decision_engine.yaml` überschreibt. +* **Besonderheit:** Nutzt den `[PROMPT-TRACE]` zur Korrelation von Erfolg und Instruktions-Set. + +### WP-28: Global Discovery Screen (UI) +* **Nutzerwert:** Eine zentrale Anlaufstelle für Suche und Wissens-Exploration. +* **Lösungsskizze:** + * Hybride Suche: Kombination aus Keyword (BM25), Vektor (Semantic) und Graph-Traversierung. + * "Reasoning-Trace" Visualisierung: Grafische Darstellung, warum ein Chunk gefunden wurde (Tracing über `stream_origin`). + +--- + +## 🟡 Zukünftige Features (Ideenspeicher) + +* **WP-13 (Agentic Layer):** MCP-Server Integration für externe Agenten (Claude/OpenAI). +* **WP-21 (Semantic Routing v2):** Dynamisches Intent-Boosting (Bessere Gewichte basierend auf der Frage-Art). +* **WP-18 (Graph Health):** Automatisierte Reparatur von "Dangling Edges" und Inconsistencies. +* **WP-24 (Knowledge Mining):** Automatisches Erstellen von Notiz-Drafts aus Chat-Erkenntnissen ("Chat-to-Vault"). \ No newline at end of file diff --git a/docs/06_Roadmap/06_Sprintplanung_01.md b/docs/06_Roadmap/06_Sprintplanung_01.md new file mode 100644 index 0000000..1553477 --- /dev/null +++ b/docs/06_Roadmap/06_Sprintplanung_01.md @@ -0,0 +1,29 @@ +# 🏃 Sprint-Planung: Sprint 1 (V3.1) +**Fokus:** Intelligenz & Gedächtnis + +## 🎯 Sprint-Ziel +Mindnet kann sich an den Kontext des aktuellen Gesprächs erinnern und seine Retrieval-Logik basierend auf historischen Feedback-Daten anpassen. + +## 🛠️ Aufgaben & Lösungsskizzen + +### Aufgabe 1: SQLite Session Management (Backend) +* **Datei:** `app/core/retrieval/session_manager.py` (Neu) +* **Details:** Erstelle eine DB-Struktur für `sessions` und `messages`. +* **Logik:** Jede Anfrage im `chat.py` Endpunkt muss eine `session_id` verarbeiten. + +### Aufgabe 2: Context Injection in DecisionEngine +* **Datei:** `app/core/retrieval/decision_engine.py` +* **Details:** 1. Abruf der letzten 5 Nachrichten aus dem `SessionManager`. + 2. Verdichtung der Historie auf max. 500 Token via `llm_service.generate_raw_response(prompt_key="compression_template", ...)`. + 3. Injection in `_generate_final_answer` als Variable `history`. + +### Aufgabe 3: Das Tuning-Modul (Self-Calibration) +* **Datei:** `app/services/tuning_service.py` (Neu) +* **Details:** 1. Parser für `logs/feedback.jsonl`. + 2. Logik: Wenn `negative_feedback` + `intent == 'CODING'`, erhöhe `tech_stream` boost um 0.5. + 3. Persistenz in `config/tuning_registry.yaml`. + +## 📦 Definition of Done (DoD) +- [ ] Test A: Rückfrage "Was meinst du damit?" bezieht sich auf das vorherige Ergebnis. +- [ ] Test B: Tuning-Werte werden nach manuellem Feedback in den Logs berücksichtigt. +- [ ] Test C: `[PROMPT-TRACE]` zeigt korrekte Level-1/2 Matches für Memory-Prompts. \ No newline at end of file