diff --git a/Programmmanagement/Programmplan_V2.2.md b/Programmmanagement/Programmplan_V2.2.md
index c10d375..152f1be 100644
--- a/Programmmanagement/Programmplan_V2.2.md
+++ b/Programmmanagement/Programmplan_V2.2.md
@@ -1,6 +1,6 @@
# mindnet v2.2 — Programmplan
-**Version:** 2.3.1 (Post-WP06 Decision Engine)
-**Stand:** 2025-12-09
+**Version:** 2.3.2 (Inkl. WP-10a GUI Evolution)
+**Stand:** 2025-12-10
**Status:** Aktiv
---
@@ -27,7 +27,8 @@
- [WP-07 – Interview-Assistent (geplant)](#wp-07--interview-assistent-geplant)
- [WP-08 – Self-Tuning v1/v2 (geplant)](#wp-08--self-tuning-v1v2-geplant)
- [WP-09 – Vault-Onboarding \& Migration (geplant)](#wp-09--vault-onboarding--migration-geplant)
- - [WP-10 – Chat-Interface \& Writeback (geplant)](#wp-10--chat-interface--writeback-geplant)
+ - [WP-10 – Chat-Interface \& Writeback (abgeschlossen)](#wp-10--chat-interface--writeback-abgeschlossen)
+ - [WP-10a – GUI Evolution: Interaktion \& Tools (geplant)](#wp-10a--gui-evolution-interaktion--tools-geplant)
- [WP-11 – Knowledge-Builder \& Vernetzungs-Assistent (geplant)](#wp-11--knowledge-builder--vernetzungs-assistent-geplant)
- [WP-12 – Knowledge Rewriter (Soft Mode, geplant)](#wp-12--knowledge-rewriter-soft-mode-geplant)
- [WP-13 – MCP-Integration \& Agenten-Layer (geplant)](#wp-13--mcp-integration--agenten-layer-geplant)
@@ -115,7 +116,8 @@ Kernprinzipien der Vision:
- **RAG-Chat:** KI antwortet in natürlicher Sprache auf Basis von Wissen und Persönlichkeit (WP-05 abgeschlossen).
- **Decision Engine:** System erkennt Intent (Fakt vs. Entscheidung) und wägt Werte ab (WP-06 abgeschlossen).
- **Multi-Persona:** System wechselt den Tonfall (Empathisch vs. Analytisch) situativ (WP-06 abgeschlossen).
-- Technische Basis: FastAPI, Qdrant, Ollama (Local LLM).
+- **Chat Interface:** Web-basiertes Frontend (Streamlit) für einfache Interaktion und Feedback-Gabe (WP-10 abgeschlossen).
+- Technische Basis: FastAPI, Qdrant, Ollama (Local LLM), Streamlit.
- Automatisierte Erkennung von Beziehungen:
- Wikilinks, Inline-Relationen, Callout-Edges, Typ-Defaults.
- „Mitwachsendes“ Schema ohne Obsidian-Umstrukturierungen:
@@ -124,10 +126,10 @@ Kernprinzipien der Vision:
### 3.2 Mittelfristig (Nächste Schritte)
-- **Chat Interface (WP-10):** Ablösung der Terminal-Interaktion durch ein Web-Frontend (Streamlit/React) für bessere UX und einfacheres Feedback-Geben.
-- Interview-Assistent erstellt neue Notes automatisch (strukturierte Dialoge → Markdown).
+- **Interview-Assistent (WP-07):** Geführte Dialoge zur Erfassung neuer Notizen (Startbereit).
- mindnet erzeugt Vorschläge für neue Notes & Edges und bietet einen „Vernetzungs-Assistenten“ für manuell angelegte Notizen.
- Agenten können über MCP-Tools (`mindnet_query`, `mindnet_chat`) auf mindnet zugreifen.
+- Self-Tuning optimiert die Gewichte in `retriever.yaml` basierend auf dem gesammelten Feedback (WP-08).
### 3.3 Langfristig
@@ -189,10 +191,10 @@ Die folgenden Prinzipien steuern alle Workpackages und Entscheidungen:
Phase A – Fundament & Import (Fertig)
Phase B – Semantik, Graph & Lernen (Fertig)
Phase C – Persönlichkeitsmodell & KI-Zwilling (Fertig)
- Phase D – Agenten, MCP & Interaktion (Startend)
+ Phase D – Agenten, MCP & Interaktion (Laufend)
Phase E – Review, Refactoring, Dokumentation
-Alle Workpackages sind einer Phase zugeordnet. WP-01 bis WP-06 sind bereits erfolgreich abgeschlossen.
+Alle Workpackages sind einer Phase zugeordnet. WP-01 bis WP-06 und WP-10 sind bereits erfolgreich abgeschlossen.
---
@@ -354,15 +356,15 @@ Transformation vom reinen Wissens-Abrufer zum strategischen Entscheidungspartner
### WP-07 – Interview-Assistent (geplant)
-**Phase:** C
-**Status:** 🟡 geplant
+**Phase:** C/D
+**Status:** 🟡 geplant (Nächster Fokus)
**Ziel:**
Dialogbasierter Erfassungs-Assistent, der strukturierte Interviews führt und daraus konsistente Markdown-Notizen generiert.
**Umfang:**
-- Design von Interview-Flows.
-- Konvertierung von Dialogtranskripten in typisierte Notes.
+- Design von Interview-Flows (via Router-Strategie `INTERVIEW`).
+- Konvertierung von Dialogtranskripten in typisierte Notes (Draft-Erstellung).
**Aufwand / Komplexität:**
- Aufwand: Niedrig/Mittel
@@ -406,25 +408,46 @@ Sicherstellen, dass bestehende und neue Obsidian-Vaults schrittweise in mindnet
---
-### WP-10 – Chat-Interface & Writeback (geplant)
+### WP-10 – Chat-Interface & Writeback (abgeschlossen)
**Phase:** D
-**Status:** 🟡 geplant (Priorität B - "Quick Win")
+**Status:** 🟢 abgeschlossen
**Ziel:**
Ablösung der Terminal-Interaktion durch ein grafisches Interface.
-**Umfang:**
-- Technologie: Streamlit oder einfaches HTML/JS Frontend.
-- Funktionen: Chat-Verlauf, Anzeige der Quellen (mit Scores), Daumen-hoch/runter für WP-04c Feedback.
-- Funktionen für Q&A sowie Vorschlag neuer Notes/Edges.
+**Erreichte Ergebnisse:**
+- **Tech-Stack:** Streamlit Frontend (`app/frontend/ui.py`).
+- **Funktionen:** Chat-Verlauf, Visualisierung von Intents und Quellen (Expander).
+- **Feedback:** Globales Rating (Sterne) und granulare Quellen-Bewertung (Faces).
+- **Writeback:** Mockup-Interface für neue Einträge (Vorbereitung WP-07).
+- **Deployment:** Systemd-Services für Prod (8501) und Dev (8502).
**Aufwand / Komplexität:**
-- Aufwand: Hoch (durch Writeback) / Mittel (für reines Frontend)
+- Aufwand: Hoch
- Komplexität: Hoch
---
+### WP-10a – GUI Evolution: Interaktion & Tools (geplant)
+
+**Phase:** D
+**Status:** 🟡 geplant (nach WP07/11)
+
+**Ziel:**
+Anpassung der GUI an komplexe Interaktionsmuster, die durch den Interview-Assistenten und Knowledge-Builder entstehen.
+
+**Umfang:**
+- **Draft-Editor:** Interaktive Bearbeitung und Bestätigung der Markdown-Entwürfe aus WP-07.
+- **Suggestion-UI:** Checkboxen/Toggles für Kanten-Vorschläge aus WP-11 (Human-in-the-Loop).
+- **Writeback:** Physisches Speichern der bestätigten Inhalte im Vault.
+
+**Aufwand / Komplexität:**
+- Aufwand: Mittel
+- Komplexität: Mittel
+
+---
+
### WP-11 – Knowledge-Builder & Vernetzungs-Assistent (geplant)
**Phase:** D
@@ -489,6 +512,7 @@ Aufräumen, dokumentieren, stabilisieren – insbesondere für Onboarding Dritte
WP01 → WP02 → WP03 → WP04a
WP04a → WP04b → WP04c → WP08
WP03 → WP05 → WP06 → WP07
+ WP07/WP11 → WP10a
WP03 → WP09
WP01/WP03 → WP10 → WP11 → WP12
WP03/WP04 → WP13
@@ -508,6 +532,7 @@ Aufräumen, dokumentieren, stabilisieren – insbesondere für Onboarding Dritte
| WP08 | Hoch | Hoch |
| WP09 | Mittel | Niedrig/Mittel |
| WP10 | Hoch | Hoch |
+| WP10a | Mittel | Mittel |
| WP11 | Hoch | Hoch |
| WP12 | Niedrig/Mittel | Mittel |
| WP13 | Mittel | Mittel |
@@ -531,7 +556,8 @@ Aufräumen, dokumentieren, stabilisieren – insbesondere für Onboarding Dritte
| WP07 | 🟡 |
| WP08 | 🟡 |
| WP09 | 🟡 |
-| WP10 | 🟡 |
+| WP10 | 🟢 |
+| WP10a | 🟡 |
| WP11 | 🟡 |
| WP12 | 🟡 |
| WP13 | 🟡 |
@@ -559,6 +585,7 @@ mindnet v2.2 ist so aufgesetzt, dass:
- ein **hybrider Retriever** qualitativ hochwertige, erklärbare Antworten liefert,
- ein **Self-Healing- und Self-Tuning-Mechanismus** vorbereitet ist (durch WP-04c Feedback-Daten),
- ein **Persönlichkeitsmodell** (Decision Engine, Empathie) existiert und den Tonfall situativ anpasst,
+- eine **grafische Oberfläche** (WP-10) existiert, die komplexe Zusammenhänge (Intents, Quellen) visualisiert,
- langfristig ein **KI-Zwilling** aufgebaut wird, der deine Werte, Erfahrungen und Denkweise spiegelt,
- die technische Architektur (FastAPI, Qdrant, YAML-Policies, MCP-Integration) lokal, nachvollziehbar und erweiterbar bleibt.
diff --git a/app/frontend/ui.py b/app/frontend/ui.py
new file mode 100644
index 0000000..418e82c
--- /dev/null
+++ b/app/frontend/ui.py
@@ -0,0 +1,207 @@
+import streamlit as st
+import requests
+import uuid
+import os
+import json
+from pathlib import Path
+from dotenv import load_dotenv
+
+# --- CONFIGURATION ---
+load_dotenv()
+API_BASE_URL = os.getenv("MINDNET_API_URL", "http://localhost:8002")
+CHAT_ENDPOINT = f"{API_BASE_URL}/chat"
+FEEDBACK_ENDPOINT = f"{API_BASE_URL}/feedback"
+HISTORY_FILE = Path("data/logs/search_history.jsonl")
+
+# Timeout Strategy
+timeout_setting = os.getenv("MINDNET_API_TIMEOUT") or os.getenv("MINDNET_LLM_TIMEOUT")
+API_TIMEOUT = float(timeout_setting) if timeout_setting else 300.0
+
+# --- PAGE SETUP ---
+st.set_page_config(page_title="mindnet v2.3.1", page_icon="🧠", layout="wide")
+
+# --- CSS STYLING ---
+st.markdown("""
+
+""", unsafe_allow_html=True)
+
+# --- SESSION STATE ---
+if "messages" not in st.session_state: st.session_state.messages = []
+if "user_id" not in st.session_state: st.session_state.user_id = str(uuid.uuid4())
+if "draft_note" not in st.session_state: st.session_state.draft_note = {"title": "", "content": "", "type": "concept"}
+
+# --- HELPER FUNCTIONS ---
+
+def load_history_from_logs(limit=10):
+ """Liest die letzten N Queries aus dem Logfile."""
+ queries = []
+ if HISTORY_FILE.exists():
+ try:
+ with open(HISTORY_FILE, "r", encoding="utf-8") as f:
+ lines = f.readlines()
+ for line in reversed(lines):
+ try:
+ entry = json.loads(line)
+ q = entry.get("query_text")
+ if q and q not in queries:
+ queries.append(q)
+ if len(queries) >= limit: break
+ except: continue
+ except Exception as e:
+ st.sidebar.warning(f"Log-Fehler: {e}")
+ return queries
+
+def send_chat_message(message: str, top_k: int, explain: bool):
+ try:
+ response = requests.post(
+ CHAT_ENDPOINT,
+ json={"message": message, "top_k": top_k, "explain": explain},
+ timeout=API_TIMEOUT
+ )
+ response.raise_for_status()
+ return response.json()
+ except Exception as e:
+ return {"error": str(e)}
+
+def submit_feedback(query_id, node_id, score, comment=None):
+ try:
+ requests.post(FEEDBACK_ENDPOINT, json={"query_id": query_id, "node_id": node_id, "score": score, "comment": comment}, timeout=2)
+ target = "Antwort" if node_id == "generated_answer" else "Quelle"
+ st.toast(f"Feedback für {target} gespeichert! (Score: {score})")
+ except: pass
+
+# --- UI COMPONENTS ---
+
+def render_sidebar():
+ with st.sidebar:
+ st.title("🧠 mindnet")
+ st.caption("v2.3.1 | WP-10 UI")
+
+ mode = st.radio("Modus", ["💬 Chat", "📝 Neuer Eintrag (WP-07)"], index=0)
+
+ st.divider()
+ st.subheader("⚙️ Settings")
+ top_k = st.slider("Quellen (Top-K)", 1, 10, 5)
+ explain = st.toggle("Explanation Layer", True)
+
+ st.divider()
+ st.subheader("🕒 Verlauf")
+ history = load_history_from_logs(8)
+ if not history:
+ st.caption("Noch keine Einträge.")
+ for q in history:
+ if st.button(f"🔎 {q[:30]}...", key=f"hist_{q}", help=q, use_container_width=True):
+ st.session_state.messages.append({"role": "user", "content": q})
+ st.rerun()
+
+ return mode, top_k, explain
+
+def render_chat_interface(top_k, explain):
+ # Render History
+ for msg in st.session_state.messages:
+ with st.chat_message(msg["role"]):
+ if msg["role"] == "assistant":
+ # Intent Badge MIT SOURCE (Fix für Debugging)
+ if "intent" in msg:
+ icon = {"EMPATHY": "❤️", "DECISION": "⚖️", "CODING": "💻", "FACT": "📚"}.get(msg["intent"], "🧠")
+ source_info = msg.get("intent_source", "Unknown")
+ # Hier wird die Quelle wieder angezeigt:
+ st.markdown(f'
{icon} Intent: {msg["intent"]} via {source_info}
', unsafe_allow_html=True)
+
+ st.markdown(msg["content"])
+
+ # Sources
+ if "sources" in msg:
+ for hit in msg["sources"]:
+ score = hit.get('total_score', 0)
+ icon = "🟢" if score > 0.8 else "🟡" if score > 0.5 else "⚪"
+ with st.expander(f"{icon} {hit.get('note_id', '?')} ({score:.2f})"):
+ st.markdown(f"_{hit.get('source', {}).get('text', '')[:300]}..._")
+ if hit.get('explanation'):
+ st.caption(f"Grund: {hit['explanation']['reasons'][0]['message']}")
+
+ # Granular Feedback (Faces)
+ def _cb(qid=msg["query_id"], nid=hit['node_id']):
+ val = st.session_state.get(f"fb_src_{qid}_{nid}")
+ if val is not None: submit_feedback(qid, nid, val+1, "Faces UI")
+
+ st.feedback("faces", key=f"fb_src_{msg['query_id']}_{hit['node_id']}", on_change=_cb)
+
+ # Global Feedback (Stars)
+ qid = msg["query_id"]
+ st.feedback("stars", key=f"fb_glob_{qid}", on_change=lambda: submit_feedback(qid, "generated_answer", st.session_state[f"fb_glob_{qid}"]+1))
+
+ else:
+ st.markdown(msg["content"])
+
+ # Input Logic
+ last_msg_is_user = len(st.session_state.messages) > 0 and st.session_state.messages[-1]["role"] == "user"
+
+ if prompt := st.chat_input("Frage Mindnet..."):
+ st.session_state.messages.append({"role": "user", "content": prompt})
+ st.rerun()
+
+ if last_msg_is_user:
+ last_prompt = st.session_state.messages[-1]["content"]
+ with st.chat_message("assistant"):
+ with st.spinner("Thinking..."):
+ resp = send_chat_message(last_prompt, top_k, explain)
+
+ if "error" in resp:
+ st.error(resp["error"])
+ else:
+ msg_data = {
+ "role": "assistant",
+ "content": resp.get("answer"),
+ "intent": resp.get("intent", "FACT"),
+ "intent_source": resp.get("intent_source", "Unknown"), # Wichtig für Anzeige
+ "sources": resp.get("sources", []),
+ "query_id": resp.get("query_id")
+ }
+ st.session_state.messages.append(msg_data)
+ st.rerun()
+
+def render_creation_interface():
+ st.header("📝 Neuer Wissens-Eintrag (WP-07/11)")
+ st.info("Hier kannst du strukturierte Notizen erstellen, die direkt in den Obsidian Vault gespeichert werden.")
+
+ with st.form("new_entry"):
+ col1, col2 = st.columns([3, 1])
+ title = col1.text_input("Titel der Notiz", placeholder="z.B. Projekt Gamma Meeting")
+ n_type = col2.selectbox("Typ", ["concept", "meeting", "person", "project", "decision"])
+
+ content = st.text_area("Inhalt (Markdown)", height=300, placeholder="# Protokoll\n\n- Punkt 1...")
+
+ st.markdown("**Automatische Vernetzung:**")
+ st.caption("Verwende `[[Link]]` für Referenzen und `[[rel:depends_on X]]` für logische Kanten.")
+
+ submitted = st.form_submit_button("💾 Speichern & Indizieren")
+ if submitted:
+ st.success(f"Mockup: Notiz '{title}' ({n_type}) wäre jetzt gespeichert worden!")
+ st.balloons()
+
+# --- MAIN LOOP ---
+mode, top_k, explain = render_sidebar()
+
+if mode == "💬 Chat":
+ render_chat_interface(top_k, explain)
+else:
+ render_creation_interface()
\ No newline at end of file
diff --git a/app/models/dto.py b/app/models/dto.py
index 85767f8..22e4cff 100644
--- a/app/models/dto.py
+++ b/app/models/dto.py
@@ -6,7 +6,7 @@ Zweck:
WP-06 Update: Intent & Intent-Source in ChatResponse.
Version:
- 0.6.1 (WP-06: Decision Engine Transparency)
+ 0.6.2 (WP-06: Decision Engine Transparency, Erweiterung des Feeback Request)
Stand:
2025-12-09
"""
@@ -64,11 +64,14 @@ class QueryRequest(BaseModel):
class FeedbackRequest(BaseModel):
"""
- User-Feedback zu einem spezifischen Treffer.
+ User-Feedback zu einem spezifischen Treffer oder der Gesamtantwort.
"""
query_id: str = Field(..., description="ID der ursprünglichen Suche")
- node_id: str = Field(..., description="ID des bewerteten Treffers")
- score: int = Field(..., ge=0, le=1, description="1 (Positiv) oder 0 (Negativ/Irrelevant)")
+ # node_id ist optional: Wenn leer oder "generated_answer", gilt es für die Antwort.
+ # Wenn eine echte Chunk-ID, gilt es für die Quelle.
+ node_id: str = Field(..., description="ID des bewerteten Treffers oder 'generated_answer'")
+ # Update: Range auf 1-5 erweitert für differenziertes Tuning
+ score: int = Field(..., ge=1, le=5, description="1 (Irrelevant/Falsch) bis 5 (Perfekt)")
comment: Optional[str] = None
@@ -152,4 +155,6 @@ class ChatResponse(BaseModel):
sources: List[QueryHit] = Field(..., description="Die für die Antwort genutzten Quellen")
latency_ms: int
intent: Optional[str] = Field("FACT", description="WP-06: Erkannter Intent (FACT/DECISION)")
- intent_source: Optional[str] = Field("Unknown", description="WP-06: Quelle der Intent-Erkennung (Keyword vs. LLM)")
\ No newline at end of file
+ intent_source: Optional[str] = Field("Unknown", description="WP-06: Quelle der Intent-Erkennung (Keyword vs. LLM)")
+
+
\ No newline at end of file
diff --git a/app/routers/chat.py b/app/routers/chat.py
index 58f5c82..5ab2d3a 100644
--- a/app/routers/chat.py
+++ b/app/routers/chat.py
@@ -1,6 +1,12 @@
"""
-app/routers/chat.py — RAG Endpunkt (WP-06 Hybrid Router v3)
-Update: Transparenz über Intent-Source (Keyword vs. LLM).
+app/routers/chat.py — RAG Endpunkt (WP-06 Hybrid Router + WP-04c Feedback)
+Version: 2.3.2 (Merged Stability Patch)
+
+Features:
+- Hybrid Intent Router (Keyword + LLM)
+- Strategic Retrieval (Late Binding via Config)
+- Context Enrichment (Payload/Source Fallback)
+- Data Flywheel (Feedback Logging Integration)
"""
from fastapi import APIRouter, HTTPException, Depends
@@ -15,6 +21,8 @@ from app.config import get_settings
from app.models.dto import ChatRequest, ChatResponse, QueryRequest, QueryHit
from app.services.llm_service import LLMService
from app.core.retriever import Retriever
+# [MERGE] Integration Feedback Service (WP-04c)
+from app.services.feedback_service import log_search
router = APIRouter()
logger = logging.getLogger(__name__)
@@ -77,7 +85,7 @@ def _build_enriched_context(hits: List[QueryHit]) -> str:
)
title = hit.note_id or "Unbekannt"
- # FIX: Wir holen den Typ aus Payload oder Source (Fallback)
+ # [FIX] Robustes Auslesen des Typs (Payload > Source > Unknown)
payload = hit.payload or {}
note_type = payload.get("type") or source.get("type", "unknown")
note_type = str(note_type).upper()
@@ -173,7 +181,7 @@ async def chat_endpoint(
retrieve_result = await retriever.search(query_req)
hits = retrieve_result.results
- # 3. Strategic Retrieval
+ # 3. Strategic Retrieval (WP-06 Kernfeature)
if inject_types:
logger.info(f"[{query_id}] Executing Strategic Retrieval for types: {inject_types}...")
strategy_req = QueryRequest(
@@ -207,18 +215,37 @@ async def chat_endpoint(
logger.info(f"[{query_id}] Sending to LLM (Intent: {intent}, Template: {prompt_key})...")
- # System-Prompt separat übergeben
+ # System-Prompt separat übergeben (WP-06a Fix)
answer_text = await llm.generate_raw_response(prompt=final_prompt, system=system_prompt)
duration_ms = int((time.time() - start_time) * 1000)
+ # 6. Logging (Fire & Forget) - [MERGE POINT]
+ # Wir loggen alles für das Data Flywheel (WP-08 Self-Tuning)
+ try:
+ log_search(
+ query_id=query_id,
+ query_text=request.message,
+ results=hits,
+ mode="chat_rag",
+ metadata={
+ "intent": intent,
+ "intent_source": intent_source,
+ "generated_answer": answer_text,
+ "model": llm.settings.LLM_MODEL
+ }
+ )
+ except Exception as e:
+ logger.error(f"Logging failed: {e}")
+
+ # 7. Response
return ChatResponse(
query_id=query_id,
answer=answer_text,
sources=hits,
latency_ms=duration_ms,
intent=intent,
- intent_source=intent_source # Source durchreichen
+ intent_source=intent_source
)
except Exception as e:
diff --git a/app/services/feedback_service.py b/app/services/feedback_service.py
index 6e945fe..99bbca2 100644
--- a/app/services/feedback_service.py
+++ b/app/services/feedback_service.py
@@ -2,13 +2,18 @@
app/services/feedback_service.py
Service zum Loggen von Suchanfragen und Feedback (WP-04c).
Speichert Daten als JSONL für späteres Self-Tuning (WP-08).
+
+Version: 1.1 (Chat-Support)
"""
import json
import os
import time
+import logging
from pathlib import Path
-from typing import Dict, Any, List
-from app.models.dto import QueryRequest, QueryResponse, FeedbackRequest
+from typing import Dict, Any, List, Union
+from app.models.dto import QueryRequest, QueryResponse, FeedbackRequest, QueryHit
+
+logger = logging.getLogger(__name__)
# Pfad für Logs (lokal auf dem Beelink/PC)
LOG_DIR = Path("data/logs")
@@ -19,18 +24,35 @@ def _ensure_log_dir():
if not LOG_DIR.exists():
os.makedirs(LOG_DIR, exist_ok=True)
-def log_search(req: QueryRequest, res: QueryResponse):
+def _append_jsonl(file_path: Path, data: dict):
+ try:
+ with open(file_path, "a", encoding="utf-8") as f:
+ f.write(json.dumps(data, ensure_ascii=False) + "\n")
+ except Exception as e:
+ logger.error(f"Failed to write log: {e}")
+
+def log_search(
+ query_id: str,
+ query_text: str,
+ results: List[QueryHit],
+ mode: str = "unknown",
+ metadata: Dict[str, Any] = None
+):
"""
- Speichert den "Snapshot" der Suche.
- WICHTIG: Wir speichern die Scores (Breakdown), damit wir später wissen,
- warum das System so entschieden hat.
+ Generische Logging-Funktion für Suche UND Chat.
+
+ Args:
+ query_id: UUID der Anfrage.
+ query_text: User-Eingabe.
+ results: Liste der Treffer (QueryHit Objekte).
+ mode: z.B. "semantic", "hybrid", "chat_rag".
+ metadata: Zusätzliche Infos (z.B. generierte Antwort, Intent).
"""
_ensure_log_dir()
- # Wir reduzieren die Datenmenge etwas (z.B. keine vollen Texte)
hits_summary = []
- for hit in res.results:
- # Falls Explanation an war, speichern wir den Breakdown, sonst die Scores
+ for hit in results:
+ # Pydantic Model Dump für saubere Serialisierung
breakdown = None
if hit.explanation and hit.explanation.breakdown:
breakdown = hit.explanation.breakdown.model_dump()
@@ -39,25 +61,24 @@ def log_search(req: QueryRequest, res: QueryResponse):
"node_id": hit.node_id,
"note_id": hit.note_id,
"total_score": hit.total_score,
- "breakdown": breakdown, # Wichtig für Training!
+ "breakdown": breakdown,
"rank_semantic": hit.semantic_score,
- "rank_edge": hit.edge_bonus
+ "rank_edge": hit.edge_bonus,
+ "type": hit.source.get("type") if hit.source else "unknown"
})
entry = {
"timestamp": time.time(),
- "query_id": res.query_id,
- "query_text": req.query,
- "mode": req.mode,
- "top_k": req.top_k,
- "hits": hits_summary
+ "query_id": query_id,
+ "query_text": query_text,
+ "mode": mode,
+ "hits_count": len(hits_summary),
+ "hits": hits_summary,
+ "metadata": metadata or {}
}
- try:
- with open(SEARCH_LOG_FILE, "a", encoding="utf-8") as f:
- f.write(json.dumps(entry, ensure_ascii=False) + "\n")
- except Exception as e:
- print(f"ERROR logging search: {e}")
+ _append_jsonl(SEARCH_LOG_FILE, entry)
+ logger.info(f"Logged search/chat interaction {query_id}")
def log_feedback(fb: FeedbackRequest):
"""
@@ -73,8 +94,5 @@ def log_feedback(fb: FeedbackRequest):
"comment": fb.comment
}
- try:
- with open(FEEDBACK_LOG_FILE, "a", encoding="utf-8") as f:
- f.write(json.dumps(entry, ensure_ascii=False) + "\n")
- except Exception as e:
- print(f"ERROR logging feedback: {e}")
\ No newline at end of file
+ _append_jsonl(FEEDBACK_LOG_FILE, entry)
+ logger.info(f"Logged feedback for {fb.query_id}")
\ No newline at end of file
diff --git a/docs/Knowledge_Design_Manual.md b/docs/Knowledge_Design_Manual.md
index b3f39c0..1175003 100644
--- a/docs/Knowledge_Design_Manual.md
+++ b/docs/Knowledge_Design_Manual.md
@@ -1,7 +1,7 @@
# mindnet v2.2 – Knowledge Design Manual
**Datei:** `docs/mindnet_knowledge_design_manual_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Integrierter Stand WP01–WP06)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Integrierter Stand WP01–WP10)
**Quellen:** `knowledge_design.md`, `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_functional_architecture.md`.
---
@@ -27,6 +27,7 @@ Mindnet ist mehr als eine Dokumentablage. Es ist ein vernetztes System, das dein
Seit Version 2.3.1 verfügt Mindnet über:
* **Hybrid Router:** Das System erkennt, ob du Fakten, Entscheidungen oder Empathie brauchst.
* **Context Intelligence:** Das System lädt je nach Situation unterschiedliche Notiz-Typen (z.B. Werte bei Entscheidungen).
+* **Web UI (WP10):** Du kannst direkt sehen, welche Quellen genutzt wurden.
### 1.2 Der Vault als „Source of Truth“
Die Markdown-Dateien in deinem Vault sind die **einzige Quelle der Wahrheit**.
@@ -194,6 +195,11 @@ Erstelle Notizen mit `type: experience`. Nutze im Text **emotionale Brückenwör
*Effekt:* Wenn du im Chat jammerst ("Alles ist sinnlos"), findet das System diese Notiz und spiegelt dir deine eigene Erfahrung zurück.
+### 5.3 Schreiben für den Chat (UI Optimization)
+Da deine Notizen im Web-Interface (WP10) angezeigt werden:
+* **Kurze Absätze:** Das LLM liest besser, und der Mensch scannt schneller.
+* **Klare Headings:** Nutze H1/H2, um dem Chunker logische Trennlinien zu geben.
+
---
## 6. Best Practices & Beispiele (Klassik)
diff --git a/docs/Overview.md b/docs/Overview.md
index 7a760a4..1162ee4 100644
--- a/docs/Overview.md
+++ b/docs/Overview.md
@@ -1,7 +1,7 @@
# Mindnet v2.2 – Overview & Einstieg
**Datei:** `docs/mindnet_overview_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Post-WP06 Release)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Post-WP10 Release)
**Version:** 2.3.1
---
@@ -39,7 +39,8 @@ Mindnet arbeitet auf drei Schichten, die aufeinander aufbauen:
### Ebene 3: Identität (Die Persönlichkeit)
* **Funktion:** Interaktion und Bewertung. Das System nimmt eine Haltung ein.
* **Logik:** "Ich empfehle Lösung X, weil sie unserem Wert 'Datensparsamkeit' entspricht."
-* **Technik:** * **Intent Router:** Erkennt Absichten (Fakt vs. Gefühl vs. Entscheidung).
+* **Technik:**
+ * **Intent Router:** Erkennt Absichten (Fakt vs. Gefühl vs. Entscheidung).
* **Strategic Retrieval:** Lädt gezielt Werte oder Erfahrungen nach.
* **Multi-Persona:** Passt den Tonfall an.
* **Status:** 🟢 Live (WP05–WP06).
@@ -61,7 +62,7 @@ Der Datenfluss in Mindnet ist zyklisch ("Data Flywheel"):
* **Backend:** Python 3.12, FastAPI.
* **Datenbank:** Qdrant (Vektor & Graph).
* **KI:** Ollama (Phi-3 Mini / Mistral) – 100% lokal.
-* **Frontend:** Terminal (aktuell) / Web-UI (geplant WP10).
+* **Frontend:** Streamlit Web-UI (v2.3.1).
---
@@ -91,5 +92,5 @@ Wo findest du was?
## 6. Aktueller Fokus
-Wir haben **Phase C (Persönlichkeit)** mit WP06 (Decision Engine) abgeschlossen.
-Das System kann nun strategisch denken und fühlen. Als Nächstes folgt **Phase D (Interaktion)** mit dem **Chat Interface (WP10)** für bessere Usability.
\ No newline at end of file
+Wir haben **Phase D (Interaktion)** mit WP10 (Chat Interface) begonnen und die UI erfolgreich deployed.
+Das System ist nun für Endnutzer bedienbar. Als Nächstes folgt der **Interview-Assistent (WP07)**, um Wissen dialogisch zu erfassen.
\ No newline at end of file
diff --git a/docs/admin_guide.md b/docs/admin_guide.md
index 8936df7..8603b3e 100644
--- a/docs/admin_guide.md
+++ b/docs/admin_guide.md
@@ -1,19 +1,19 @@
# Mindnet v2.2 – Admin Guide
**Datei:** `docs/mindnet_admin_guide_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Inkl. RAG, Decision Engine & LLM Ops)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Inkl. Frontend Deployment)
**Quellen:** `Handbuch.md`, `mindnet_developer_guide_v2.2.md`.
-> Dieses Handbuch richtet sich an **Administratoren**. Es beschreibt Installation, Konfiguration, Backup-Strategien, Monitoring und den sicheren Betrieb der Mindnet-Instanz (API + DB + LLM).
+> Dieses Handbuch richtet sich an **Administratoren**. Es beschreibt Installation, Konfiguration, Backup-Strategien, Monitoring und den sicheren Betrieb der Mindnet-Instanz (API + UI + DB).
---
## 1. Zielgruppe & Scope
-Mindnet ist als **Single-Node System** konzipiert, das lokal (z.B. Laptop) oder auf einem privaten Server (Homelab, Intranet) läuft.
+Mindnet ist als **Multi-Service-Architektur** konzipiert, die lokal oder auf einem privaten Server läuft.
Wir unterscheiden strikt zwischen:
-* **Production (Port 8001):** Stabiler `main` Branch.
-* **Development (Port 8002):** Experimentelle Feature-Branches.
+* **Production:** Backend (8001) + Frontend (8501). Stabiler `main` Branch.
+* **Development:** Backend (8002) + Frontend (8502). Experimentelle Feature-Branches.
---
@@ -36,9 +36,11 @@ Wir unterscheiden strikt zwischen:
# 2. Umgebung einrichten
python3 -m venv .venv
source .venv/bin/activate
+
+ # 3. Dependencies installieren (inkl. Streamlit)
pip install -r requirements.txt
- # 3. Verzeichnisse anlegen
+ # 4. Verzeichnisse anlegen
mkdir -p logs qdrant_storage data/logs
### 2.3 Qdrant Setup (Docker)
@@ -55,7 +57,7 @@ Wir nutzen Qdrant als Vektor-Datenbank. Persistenz ist wichtig.
Mindnet benötigt einen lokalen LLM-Server für den Chat.
# 1. Installieren (Linux Script)
- curl -fsSL https://ollama.com/install.sh | sh
+ curl -fsSL [https://ollama.com/install.sh](https://ollama.com/install.sh) | sh
# 2. Modell laden (Phi-3 Mini für CPU-Performance)
ollama pull phi3:mini
@@ -75,24 +77,64 @@ Erstelle eine `.env` Datei im Root-Verzeichnis. Die neuen Settings für WP-06 (T
# LLM / RAG Settings
MINDNET_LLM_MODEL="phi3:mini"
- MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
+ MINDNET_OLLAMA_URL="[http://127.0.0.1:11434](http://127.0.0.1:11434)"
- # NEU in v2.3: Config & Timeouts
- # Pfad zu Prompts
+ # Config & Timeouts
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
- # Pfad zur Decision Engine Config
MINDNET_DECISION_CONFIG="./config/decision_engine.yaml"
- # Timeout in Sekunden (300s = 5min fuer Cold Starts)
MINDNET_LLM_TIMEOUT=300.0
-### 2.6 Deployment via Systemd
-Mindnet wird als Systemdienst gestartet. Ollama läuft meist als eigener Dienst (`ollama.service`).
+### 2.6 Deployment via Systemd (Backend & Frontend)
-**Production Service (`/etc/systemd/system/mindnet-prod.service`):**
-* Läuft auf Port 8001.
-* Autostart (`enabled`).
-* Restart Policy: `always`.
-* Abhängigkeit: Sollte nach `docker` und `ollama` starten.
+Mindnet benötigt zwei Services pro Umgebung: API (Uvicorn) und UI (Streamlit).
+
+**Production Backend (`/etc/systemd/system/mindnet-prod.service`):**
+
+ [Unit]
+ Description=Mindnet API Prod (8001)
+ After=network.target
+
+ [Service]
+ User=llmadmin
+ Group=llmadmin
+ WorkingDirectory=/home/llmadmin/mindnet
+ ExecStart=/home/llmadmin/mindnet/.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8001 --env-file .env
+ Restart=always
+ RestartSec=5
+
+ [Install]
+ WantedBy=multi-user.target
+
+**Production Frontend (`/etc/systemd/system/mindnet-ui-prod.service`):**
+
+ [Unit]
+ Description=Mindnet UI Prod (8501)
+ After=mindnet-prod.service
+
+ [Service]
+ User=llmadmin
+ Group=llmadmin
+ WorkingDirectory=/home/llmadmin/mindnet
+
+ # Environment Variables
+ Environment="MINDNET_API_URL=http://localhost:8001"
+ Environment="MINDNET_API_TIMEOUT=300"
+ Environment="STREAMLIT_SERVER_PORT=8501"
+ Environment="STREAMLIT_SERVER_ADDRESS=0.0.0.0"
+ Environment="STREAMLIT_SERVER_HEADLESS=true"
+
+ ExecStart=/home/llmadmin/mindnet/.venv/bin/streamlit run app/frontend/ui.py
+ Restart=always
+ RestartSec=5
+
+ [Install]
+ WantedBy=multi-user.target
+
+**Firewall (UFW):**
+Öffne die Ports für den Zugriff:
+
+ sudo ufw allow 8501/tcp # Prod UI
+ sudo ufw allow 8502/tcp # Dev UI (falls gewünscht)
---
@@ -106,27 +148,19 @@ Der Vault-Zustand sollte regelmäßig (z.B. stündlich per Cronjob) nach Qdrant
0 * * * * cd /home/llmadmin/mindnet && .venv/bin/python3 -m scripts.import_markdown --vault /path/to/vault --prefix "mindnet" --apply --purge-before-upsert --sync-deletes >> ./logs/import.log 2>&1
### 3.2 Health-Checks
-Prüfe regelmäßig, ob alle drei Komponenten (API, DB, LLM) laufen.
-
-**Status prüfen:**
+Prüfe regelmäßig, ob alle Komponenten laufen.
sudo systemctl status mindnet-prod
+ sudo systemctl status mindnet-ui-prod
sudo systemctl status ollama
-**Logischer Smoke-Test:**
-
- python3 scripts/test_retriever_smoke.py --mode hybrid --url http://localhost:8001/query
-
### 3.3 Logs & Monitoring
-* **Technische Fehler (API):** `journalctl -u mindnet-prod -f`
- * Achte auf: `LLM Router Raw Output`. Hier siehst du, wie die Decision Engine entscheidet.
-* **LLM Fehler (Ollama):** `journalctl -u ollama -f`
+* **Backend Fehler:** `journalctl -u mindnet-prod -f`
+* **Frontend Fehler:** `journalctl -u mindnet-ui-prod -f`
+ * Achte auf "Timeout"-Meldungen im Frontend, wenn das Backend zu langsam antwortet.
+* **LLM Fehler:** `journalctl -u ollama -f`
* **Fachliche Logs:** `data/logs/search_history.jsonl`
-**Troubleshooting Chat:**
-* Wenn `/chat` in den Timeout läuft (>300s): Prüfe `MINDNET_LLM_TIMEOUT` in `.env` und ob das Modell im RAM liegt.
-* Wenn `/chat` halluziniert: Prüfe `config/prompts.yaml` und ob der Import aktuell ist.
-
---
## 4. Update-Prozess
@@ -143,9 +177,10 @@ Wenn neue Versionen ausgerollt werden (Deployment):
source .venv/bin/activate
pip install -r requirements.txt
-3. **Dienst neustarten (Zwingend!):**
+3. **Dienste neustarten (Zwingend!):**
sudo systemctl restart mindnet-prod
+ sudo systemctl restart mindnet-ui-prod
4. **Schema-Migration (falls nötig):**
@@ -158,7 +193,7 @@ Wenn neue Versionen ausgerollt werden (Deployment):
Datensicherheit ruht auf drei Säulen: Vault (Source), Qdrant (Index), JSONL-Logs (Lern-Daten).
### 5.1 Vault-Backup (Priorität 1)
-Der Markdown-Vault ist die **Single Source of Truth**. Er muss klassisch gesichert werden (Git/NAS).
+Der Markdown-Vault ist die **Single Source of Truth**.
### 5.2 Qdrant-Snapshots (Priorität 2)
Für schnelle Wiederherstellung des Suchindex.
@@ -168,7 +203,7 @@ Für schnelle Wiederherstellung des Suchindex.
docker start mindnet_qdrant
### 5.3 Log-Daten (Priorität 3)
-Sichere den Ordner `data/logs/`. Verlust dieser Daten bedeutet, dass das System vergisst, welche Antworten Nutzer hilfreich fanden.
+Sichere den Ordner `data/logs/`. Verlust dieser Daten bedeutet Verlust des Trainingsmaterials für Self-Tuning.
### 5.4 Notfall-Wiederherstellung (Rebuild)
Wenn die Datenbank korrupt ist:
@@ -184,10 +219,9 @@ Wenn die Datenbank korrupt ist:
### 6.1 Zugriffsschutz
Mindnet hat aktuell **keine integrierte Authentifizierung**.
-* **API:** Muss hinter einem Reverse Proxy (Nginx) mit Basic Auth laufen.
-* **Qdrant:** Sollte via Firewall (ufw) auf `127.0.0.1` beschränkt sein.
-* **Ollama:** Standardmäßig hört Ollama nur auf `localhost`. Das ist sicher.
+* **Frontend:** Streamlit auf Port 8501 ist offen. Nutze Nginx Basic Auth oder VPN.
+* **API:** Sollte nicht direkt im öffentlichen Netz stehen.
+* **Qdrant:** Auf `127.0.0.1` beschränken.
### 6.2 Typen-Governance
-Änderungen an der `types.yaml` (z.B. neue Gewichte) wirken global.
-* **Prozess:** Änderungen sollten getestet werden (Smoke-Test), bevor sie produktiv gehen.
\ No newline at end of file
+Änderungen an der `types.yaml` (z.B. neue Gewichte) wirken global und erfordern Tests.
\ No newline at end of file
diff --git a/docs/appendix.md b/docs/appendix.md
index 4bdcea2..091d832 100644
--- a/docs/appendix.md
+++ b/docs/appendix.md
@@ -1,7 +1,7 @@
# Mindnet v2.2 – Appendices & Referenzen
**Datei:** `docs/mindnet_appendices_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Integrierter Stand WP01–WP06)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Integrierter Stand WP01–WP10)
**Quellen:** `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_technical_architecture.md`, `Handbuch.md`.
> Dieses Dokument bündelt Tabellen, Schemata und technische Referenzen, die in den Prozess-Dokumenten (Playbook, Guides) den Lesefluss stören würden.
@@ -128,7 +128,7 @@ Diese Variablen steuern das Verhalten der Skripte und Container.
---
-## Anhang F: Workpackage Status (v2.3.1)
+## Anhang F: Workpackage Status (v2.3.2)
Aktueller Implementierungsstand der Module.
@@ -142,5 +142,7 @@ Aktueller Implementierungsstand der Module.
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Chat mit Context Enrichment. |
| **WP06** | Decision Engine | 🟢 Live | Hybrid Router, Strategic Retrieval, Multi-Persona. |
+| **WP07** | Interview Assistent | 🟡 Geplant | Dialog-Modus (Nächster Schritt). |
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
-| **WP10** | Chat Interface | 🟡 Geplant | Nächster Schritt (Frontend). |
\ No newline at end of file
+| **WP10** | Chat Interface | 🟢 Live | Web-Interface (Streamlit). |
+| **WP10a**| GUI Evolution | 🔴 Geplant | Interaktive Tools & Editor. |
\ No newline at end of file
diff --git a/docs/dev_workflow.md b/docs/dev_workflow.md
index a1362d6..513aa98 100644
--- a/docs/dev_workflow.md
+++ b/docs/dev_workflow.md
@@ -1,6 +1,6 @@
# Mindnet v2.2 – Entwickler-Workflow
**Datei:** `DEV_WORKFLOW.md`
-**Stand:** 2025-12-09 (Aktualisiert: LLM Timeouts & Systemd)
+**Stand:** 2025-12-10 (Aktualisiert: Inkl. Frontend WP10)
Dieses Handbuch beschreibt den Entwicklungszyklus zwischen **Windows PC** (IDE), **Raspberry Pi** (Gitea) und **Beelink** (Runtime/Server).
@@ -11,8 +11,12 @@ Dieses Handbuch beschreibt den Entwicklungszyklus zwischen **Windows PC** (IDE),
* **Windows 11 (VS Code):** Hier schreibst du Code. **Nie** direkt auf `main` arbeiten!
* **Raspberry Pi (Gitea):** Der Tresor. Speichert den Code und verwaltet Versionen.
* **Beelink (Runtime):** Hier läuft die Software. Wir nutzen **Systemd-Services**:
- * **PROD (`mindnet-prod`):** Läuft stabil auf `main`. Ordner: `~/mindnet`. **Port 8001**.
- * **DEV (`mindnet-dev`):** Deine Spielwiese. Ordner: `~/mindnet_dev`. **Port 8002**.
+ * **PROD:**
+ * API: `mindnet-prod` (Port 8001). Ordner: `~/mindnet`.
+ * UI: `mindnet-ui-prod` (Port 8501).
+ * **DEV:**
+ * API: `mindnet-dev` (Port 8002). Ordner: `~/mindnet_dev`.
+ * UI: `mindnet-ui-dev` (Port 8502).
---
@@ -71,45 +75,53 @@ Hier prüfst du, ob dein neuer Code auf dem echten Server läuft.
```
5. **Test-Server aktualisieren (WICHTIG):**
- Der Code ist da, aber der Prozess im RAM ist noch alt. Wir müssen den Service neustarten.
+ Der Code ist da, aber die Prozesse im RAM sind noch alt. Wir müssen die Services neustarten.
**Option A: Standard (Als Service laufen lassen)**
Ideal, wenn du nur testen willst, ob es läuft.
```bash
+ # 1. API neustarten
sudo systemctl restart mindnet-dev
+ # 2. UI neustarten (falls Frontend-Änderungen)
+ sudo systemctl restart mindnet-ui-dev
# Logs prüfen (um Fehler zu sehen):
journalctl -u mindnet-dev -f
+ # Oder Frontend Logs:
+ journalctl -u mindnet-ui-dev -f
```
**Option B: Manuell Debuggen (Direct Output)**
Ideal, wenn du Print-Ausgaben direkt sehen willst oder der Service dauernd crasht.
```bash
- # 1. Service stoppen (wichtig, sonst ist Port 8002 belegt!)
+ # 1. Services stoppen (wichtig, sonst sind Ports 8002/8502 belegt!)
sudo systemctl stop mindnet-dev
+ sudo systemctl stop mindnet-ui-dev
- # 2. Manuell starten
+ # 2. Manuell starten (z.B. API)
uvicorn app.main:app --host 0.0.0.0 --port 8002 --env-file .env
# ... Testen ...
- # 3. Wenn fertig: Service wieder anschalten (Optional)
+ # 3. Wenn fertig: Services wieder anschalten (Optional)
# Strg+C drücken
sudo systemctl start mindnet-dev
+ sudo systemctl start mindnet-ui-dev
```
6. **Validieren:**
- Führe deine Tests in einem **zweiten Terminal** aus:
- ```bash
- # Beispiel für Decision Engine Test
- python tests/test_wp06_decision.py -p 8002 -q "Soll ich...?"
- ```
+ * **Browser:** Öffne `http://:8502` um die UI zu testen.
+ * **CLI:** Führe Testskripte in einem **zweiten Terminal** aus:
+ ```bash
+ # Beispiel für Decision Engine Test
+ python tests/test_wp06_decision.py -p 8002 -q "Soll ich...?"
+ ```
---
### Phase 3: Release (Gitea / Raspberry Pi)
-Wenn der Test auf Port 8002 erfolgreich war:
+Wenn der Test auf Port 8002 / 8502 erfolgreich war:
1. Öffne Gitea im Browser.
2. Erstelle einen **Pull Request** (Dein Branch -> `main`).
@@ -119,7 +131,7 @@ Wenn der Test auf Port 8002 erfolgreich war:
### Phase 4: Deployment (Beelink / `mindnet`)
-Jetzt bringen wir die Änderung in das Live-System (Port 8001).
+Jetzt bringen wir die Änderung in das Live-System (Port 8001 / 8501).
1. **Deploy-Agent (Automatisch):**
Wenn dein `deploy.yml` aktiv ist, passiert das jetzt von selbst!
@@ -129,8 +141,13 @@ Jetzt bringen wir die Änderung in das Live-System (Port 8001).
cd /home/llmadmin/mindnet
git pull origin main
- # Produktions-Service neustarten
+ # Dependencies updaten
+ source .venv/bin/activate
+ pip install -r requirements.txt
+
+ # Produktions-Services neustarten
sudo systemctl restart mindnet-prod
+ sudo systemctl restart mindnet-ui-prod
# Kurz prüfen, ob er läuft
sudo systemctl status mindnet-prod
@@ -163,8 +180,10 @@ Damit das Chaos nicht wächst, löschen wir den fertigen Branch.
| :--- | :--- | :--- |
| **VS Code** | `Sync (auf main)` | **WICHTIG:** Holt neuesten Code vom Server. |
| **Beelink** | `git fetch` | Aktualisiert Liste der Remote-Branches. |
-| **Beelink** | `sudo systemctl restart mindnet-dev` | **Neustart Dev-Server (Port 8002).** |
-| **Beelink** | `journalctl -u mindnet-dev -f` | **Live-Logs vom Dev-Server sehen.** |
+| **Beelink** | `sudo systemctl restart mindnet-dev` | **Neustart Dev-Backend (Port 8002).** |
+| **Beelink** | `sudo systemctl restart mindnet-ui-dev` | **Neustart Dev-Frontend (Port 8502).** |
+| **Beelink** | `journalctl -u mindnet-dev -f` | **Live-Logs Backend.** |
+| **Beelink** | `journalctl -u mindnet-ui-dev -f` | **Live-Logs Frontend.** |
---
@@ -173,13 +192,13 @@ Damit das Chaos nicht wächst, löschen wir den fertigen Branch.
**"Read timed out (120s)" / 500 Error beim Chat**
* **Ursache:** Das LLM (Ollama) braucht zu lange zum Laden ("Cold Start").
* **Lösung:**
- 1. Erhöhe in `.env` den Wert: `MINDNET_LLM_TIMEOUT=300.0`.
- 2. Starte den Server neu (`sudo systemctl restart mindnet-dev`).
+ 1. Erhöhe in `.env` den Wert: `MINDNET_LLM_TIMEOUT=300.0` (Backend) oder `MINDNET_API_TIMEOUT` (Frontend).
+ 2. Starte die Server neu.
3. Stelle sicher, dass dein Test-Skript (Client) auch ein hohes Timeout hat.
-**"Port 8002 already in use"**
-* **Ursache:** Du willst `uvicorn` manuell starten, aber der Service läuft noch.
-* **Lösung:** `sudo systemctl stop mindnet-dev`.
+**"Port 8002 / 8502 already in use"**
+* **Ursache:** Du willst `uvicorn` oder `streamlit` manuell starten, aber der Service läuft noch.
+* **Lösung:** `sudo systemctl stop mindnet-dev` bzw. `mindnet-ui-dev`.
**"UnicodeDecodeError in .env"**
* **Ursache:** Umlaute oder Sonderzeichen in der `.env` Datei.
diff --git a/docs/developer_guide.md b/docs/developer_guide.md
index a6758ce..14e33d9 100644
--- a/docs/developer_guide.md
+++ b/docs/developer_guide.md
@@ -1,7 +1,7 @@
# Mindnet v2.2 – Developer Guide
**Datei:** `docs/mindnet_developer_guide_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Inkl. RAG, Decision Engine & AI-Teaching)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Inkl. RAG, Decision Engine & Frontend WP10)
**Quellen:** `mindnet_technical_architecture.md`, `Handbuch.md`, `DEV_WORKFLOW.md`.
> **Zielgruppe:** Entwickler:innen.
@@ -9,16 +9,17 @@
---
- [Mindnet v2.2 – Developer Guide](#mindnet-v22--developer-guide)
- - [1. Projektstruktur (Post-WP06)](#1-projektstruktur-post-wp06)
+ - [1. Projektstruktur (Post-WP10)](#1-projektstruktur-post-wp10)
- [2. Lokales Setup (Development)](#2-lokales-setup-development)
- [2.1 Voraussetzungen](#21-voraussetzungen)
- [2.2 Installation](#22-installation)
- [2.3 Konfiguration (Environment)](#23-konfiguration-environment)
- - [2.4 Dienste starten (Systemd bevorzugt)](#24-dienste-starten-systemd-bevorzugt)
+ - [2.4 Dienste starten (API \& UI)](#24-dienste-starten-api--ui)
- [3. Core-Module \& Entwicklung](#3-core-module--entwicklung)
- [3.1 Der Importer (`scripts.import_markdown`)](#31-der-importer-scriptsimport_markdown)
- [3.2 Der Hybrid Router (`app.routers.chat`)](#32-der-hybrid-router-approuterschat)
- [3.3 Der Retriever (`app.core.retriever`)](#33-der-retriever-appcoreretriever)
+ - [3.4 Das Frontend (`app.frontend.ui`)](#34-das-frontend-appfrontendui)
- [4. Tests \& Debugging](#4-tests--debugging)
- [4.1 Unit Tests (Pytest)](#41-unit-tests-pytest)
- [4.2 Integration / Pipeline Tests](#42-integration--pipeline-tests)
@@ -31,7 +32,7 @@
---
-## 1. Projektstruktur (Post-WP06)
+## 1. Projektstruktur (Post-WP10)
Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung) getrennt.
@@ -54,6 +55,8 @@ Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung)
│ │ ├── llm_service.py # Ollama Client (Mit Timeout & Raw-Mode)
│ │ ├── feedback_service.py # Logging (JSONL Writer)
│ │ └── embeddings_client.py
+ │ ├── frontend/ # NEU (WP10)
+ │ │ └── ui.py # Streamlit Application
│ └── main.py # Entrypoint der API
├── config/ # YAML-Konfigurationen (Single Source of Truth)
│ ├── types.yaml # Import-Regeln
@@ -86,7 +89,7 @@ Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung)
python3 -m venv .venv
source .venv/bin/activate
- # 3. Abhängigkeiten installieren
+ # 3. Abhängigkeiten installieren (inkl. Streamlit)
pip install -r requirements.txt
# 4. Ollama Setup (Modell laden)
@@ -94,7 +97,7 @@ Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung)
ollama pull phi3:mini
### 2.3 Konfiguration (Environment)
-Erstelle eine `.env` Datei im Root-Verzeichnis. Die Timeout-Settings sind kritisch für CPU-Inference.
+Erstelle eine `.env` Datei im Root-Verzeichnis.
# Qdrant Verbindung
QDRANT_URL="http://localhost:6333"
@@ -112,28 +115,28 @@ Erstelle eine `.env` Datei im Root-Verzeichnis. Die Timeout-Settings sind kritis
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
MINDNET_DECISION_CONFIG="./config/decision_engine.yaml"
+ # Frontend Settings (WP10)
+ MINDNET_API_URL="http://localhost:8002"
+
# Import-Strategie
MINDNET_HASH_COMPARE="Body"
MINDNET_HASH_SOURCE="parsed"
-### 2.4 Dienste starten (Systemd bevorzugt)
-Auf dem Entwicklungsserver (Beelink) nutzen wir Systemd.
+### 2.4 Dienste starten (API & UI)
- # Starten / Neustarten
- sudo systemctl restart mindnet-dev
-
- # Logs prüfen (Wichtig für LLM Debugging)
- journalctl -u mindnet-dev -f
+Wir entwickeln mit zwei Services. Du kannst sie manuell in zwei Terminals starten oder die Systemd-Services nutzen (siehe `admin_guide.md`).
-Falls du lokal auf Windows entwickelst:
+**Terminal A: Backend (API)**
- # 1. Qdrant starten
- docker run -p 6333:6333 qdrant/qdrant
- # 2. Ollama starten
- ollama serve
- # 3. API starten
+ # Startet auf Port 8002 (Dev Standard)
uvicorn app.main:app --host 0.0.0.0 --port 8002 --env-file .env --reload
+**Terminal B: Frontend (UI)**
+
+ # Startet auf Port 8502 (Dev Standard)
+ # --server.port 8502 verhindert Konflikte mit Prod (8501)
+ streamlit run app/frontend/ui.py --server.port 8502
+
---
## 3. Core-Module & Entwicklung
@@ -155,6 +158,12 @@ Hier passiert das Scoring.
* **Hybrid Search:** Der Chat-Endpoint erzwingt `mode="hybrid"`.
* **Strategic Retrieval:** In `chat.py` wird der Retriever *zweimal* aufgerufen, wenn ein Intent (z.B. `DECISION`) eine Injection (`value`) erfordert.
+### 3.4 Das Frontend (`app.frontend.ui`)
+Eine Streamlit-App (WP10).
+* **State:** Nutzt `st.session_state` für Chat-History und Drafts.
+* **Logik:** Ruft `/chat` und `/feedback` Endpoints der API auf.
+* **Anpassung:** CSS Styles sind direkt in `ui.py` eingebettet.
+
---
## 4. Tests & Debugging
@@ -179,20 +188,16 @@ Prüfen den Datenfluss von Markdown bis Qdrant-JSON.
python3 -m scripts.edges_full_check
### 4.3 Smoke Tests (E2E)
-Prüfen das laufende System (API) gegen eine echte Qdrant-Instanz und Ollama.
+Prüfen das laufende System gegen eine echte Qdrant-Instanz und Ollama.
- # 1. Retriever Test (Hybrid + Explanation)
- python scripts/test_retriever_smoke.py --query "Test" --mode hybrid --top-k 5 --explain
-
- # 2. Decision Engine Test (WP06)
- # Prüft Intent, Retrieval und Reasoning (mit Timeout-Handling)
+ # 1. API Test (Decision Engine)
python tests/test_wp06_decision.py -p 8002 -e DECISION -q "Soll ich X tun?"
- # 3. Empathy Test (WP06)
- # Prüft LLM-Router Fallback
- python tests/test_wp06_decision.py -p 8002 -e EMPATHY -q "Alles ist grau"
+ # 2. UI Test (Manuell)
+ # Öffne http://localhost:8502
+ # Stelle eine Frage und prüfe Intent-Badge und Quellen-Anzeige.
- # 4. Feedback Test (WP04c)
+ # 3. Feedback Test
python tests/test_feedback_smoke.py --url http://localhost:8002/query
---
@@ -260,6 +265,9 @@ Standardmäßig werden alle expliziten Kanten gleich behandelt. Wenn Kausalität
python3 tests/inspect_one_note.py --file ./vault/MeinFile.md
-**Live-Logs sehen (Beelink) - inkl. LLM Thoughts:**
+**Live-Logs sehen (Systemd):**
- journalctl -u mindnet-dev -f
\ No newline at end of file
+ # Backend
+ journalctl -u mindnet-dev -f
+ # Frontend
+ journalctl -u mindnet-ui-dev -f
\ No newline at end of file
diff --git a/docs/mindnet_functional_architecture.md b/docs/mindnet_functional_architecture.md
index aa93f76..a9b683f 100644
--- a/docs/mindnet_functional_architecture.md
+++ b/docs/mindnet_functional_architecture.md
@@ -1,9 +1,9 @@
# Mindnet v2.2 – Fachliche Architektur
**Datei:** `docs/mindnet_functional_architecture_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Integrierter Stand WP01–WP06)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Integrierter Stand WP01–WP10)
-> Dieses Dokument beschreibt **was** Mindnet fachlich tut und **warum** – mit Fokus auf die Erzeugung und Nutzung von **Edges** (Kanten), die Logik des Retrievers und den neuen **RAG-Chat** (Decision Engine & Persönlichkeit). Die technische Umsetzung wird im technischen Dokument detailliert.
+> Dieses Dokument beschreibt **was** Mindnet fachlich tut und **warum** – mit Fokus auf die Erzeugung und Nutzung von **Edges** (Kanten), die Logik des Retrievers und den **RAG-Chat** (Decision Engine & Persönlichkeit). Die technische Umsetzung wird im technischen Dokument detailliert.
---
@@ -38,7 +38,7 @@
- [8) Erweiterbarkeit \& Teaching (Context Intelligence)](#8-erweiterbarkeit--teaching-context-intelligence)
- [A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`)](#a-workflow-einen-neuen-typ-implementieren-z-b-type-risk)
- [B. Workflow: Neue Beziehungen nutzen (z. B. `beeinflusst_von`)](#b-workflow-neue-beziehungen-nutzen-z-b-beeinflusst_von)
- - [9) Feedback \& Lernen – WP04c](#9-feedback--lernen--wp04c)
+ - [9) Feedback \& Lernen – WP04c/WP10](#9-feedback--lernen--wp04cwp10)
- [9.1 Der Feedback-Loop](#91-der-feedback-loop)
- [10) Confidence \& Provenance – wozu?](#10-confidence--provenance--wozu)
- [11) Semantik ausgewählter `kind`-Werte](#11-semantik-ausgewählter-kind-werte)
@@ -46,7 +46,7 @@
- [13) Lösch-/Update-Garantien (Idempotenz)](#13-lösch-update-garantien-idempotenz)
- [14) Beispiel – Von Markdown zu Kanten (v2.2)](#14-beispiel--von-markdown-zu-kanten-v22)
- [15) Referenzen (Projektdateien \& Leitlinien)](#15-referenzen-projektdateien--leitlinien)
- - [16) Workpackage Status (v2.3.1)](#16-workpackage-status-v231)
+ - [16) Workpackage Status (v2.3.2)](#16-workpackage-status-v232)
---
@@ -273,7 +273,7 @@ Mindnet lernt nicht durch klassisches Training (Fine-Tuning), sondern durch **Ko
Steuere, wie schwer der Inhalt wiegt und wie er vernetzt wird.
```yaml
risk:
- chunk_profile: short # Risiken sind prägnant
+ chunk_profile: short # Risiken sind oft kurze Statements
retriever_weight: 0.90 # Hohe Priorität im Ranking
edge_defaults: ["blocks"] # Automatische Kante zu verlinkten Projekten
```
@@ -308,11 +308,13 @@ Beziehungen sind der Klebstoff für logische Schlussfolgerungen.
---
-## 9) Feedback & Lernen – WP04c
+## 9) Feedback & Lernen – WP04c/WP10
Das System verfügt nun über ein **Kurzzeitgedächtnis für Interaktionen**, das die Basis für zukünftiges Lernen bildet.
### 9.1 Der Feedback-Loop
+Die Interaktion erfolgt primär über das **Web-Interface (WP10)**.
+
1. **Suche (Situation):**
Wenn ein Nutzer eine Anfrage stellt, loggt Mindnet die "Situation":
* Den Query-Text.
@@ -321,8 +323,8 @@ Das System verfügt nun über ein **Kurzzeitgedächtnis für Interaktionen**, da
* Eine eindeutige `query_id` wird generiert.
2. **Bewertung (Label):**
- Der Nutzer (oder ein Agent) bewertet einen spezifischen Treffer (`node_id`) positiv oder negativ (Score 1-5).
- Dieses Feedback wird unter Referenzierung der `query_id` gespeichert.
+ Der Nutzer bewertet die Antwort (**Sterne**) oder einzelne Quellen (**Faces**) im Frontend.
+ Dieses Feedback wird unter Referenzierung der `query_id` in `feedback.jsonl` gespeichert.
3. **Lernen (Perspektive WP08):**
Durch die Verknüpfung von Situation und Bewertung entstehen Trainingsdaten. Mindnet kann später analysieren: *"Nutzer bevorzugen Treffer mit hohem Edge-Bonus, auch wenn der Text weniger passt."* -> Konsequenz: `edge_weight` erhöhen.
@@ -402,7 +404,7 @@ Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
---
-## 16) Workpackage Status (v2.3.1)
+## 16) Workpackage Status (v2.3.2)
Aktueller Implementierungsstand der Module.
@@ -416,4 +418,7 @@ Aktueller Implementierungsstand der Module.
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
| **WP06** | Decision Engine | 🟢 Live | Intent-Router & Strategic Retrieval. |
-| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
\ No newline at end of file
+| **WP07** | Interview Assistent | 🟡 Geplant | Dialog-Modus (Nächster Schritt). |
+| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
+| **WP10** | Chat Interface | 🟢 Live | Web-UI mit Feedback & Intents. |
+| **WP10a**| GUI Evolution | 🔴 Geplant | Erweiterte Interaktion. |
\ No newline at end of file
diff --git a/docs/mindnet_technical_architecture.md b/docs/mindnet_technical_architecture.md
index b913eac..dcb3312 100644
--- a/docs/mindnet_technical_architecture.md
+++ b/docs/mindnet_technical_architecture.md
@@ -1,11 +1,11 @@
# Mindnet v2.2 – Technische Architektur
**Datei:** `docs/mindnet_technical_architecture_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Integrierter Stand WP01–WP06)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Integrierter Stand WP01–WP10)
**Quellen:** `Programmplan_V2.2.md`, `Handbuch.md`, `chunking_strategy.md`, `wp04_retriever_scoring.md`.
> **Ziel dieses Dokuments:**
-> Vollständige Beschreibung der technischen Architektur inkl. Graph-Datenbank, Retrieval-Logik und der **neuen RAG-Komponenten (Decision Engine & Hybrid Router)**.
+> Vollständige Beschreibung der technischen Architektur inkl. Graph-Datenbank, Retrieval-Logik, der **neuen RAG-Komponenten (Decision Engine & Hybrid Router)** und dem **Frontend (Streamlit)**.
---
@@ -15,7 +15,7 @@
- [](#)
- [1. Systemüberblick](#1-systemüberblick)
- [1.1 Architektur-Zielbild](#11-architektur-zielbild)
- - [1.2 Verzeichnisstruktur \& Komponenten (Post-WP06)](#12-verzeichnisstruktur--komponenten-post-wp06)
+ - [1.2 Verzeichnisstruktur \& Komponenten (Post-WP10)](#12-verzeichnisstruktur--komponenten-post-wp10)
- [2. Datenmodell \& Collections (Qdrant)](#2-datenmodell--collections-qdrant)
- [2.1 Notes Collection (`_notes`)](#21-notes-collection-prefix_notes)
- [2.2 Chunks Collection (`_chunks`)](#22-chunks-collection-prefix_chunks)
@@ -39,12 +39,16 @@
- [6.3 Schritt 2: Strategy Resolution (Late Binding)](#63-schritt-2-strategy-resolution-late-binding)
- [6.4 Schritt 3: Multi-Stage Retrieval](#64-schritt-3-multi-stage-retrieval)
- [6.5 Schritt 4: Generation \& Response](#65-schritt-4-generation--response)
- - [7. Feedback \& Logging Architektur (WP04c)](#7-feedback--logging-architektur-wp04c)
- - [7.1 Komponenten](#71-komponenten)
- - [7.2 Log-Dateien](#72-log-dateien)
- - [7.3 Traceability](#73-traceability)
- - [8. Indizes \& Performance](#8-indizes--performance)
- - [9. Offene Punkte / Known Limitations](#9-offene-punkte--known-limitations)
+ - [7. Frontend Architektur (WP10)](#7-frontend-architektur-wp10)
+ - [7.1 Kommunikation](#71-kommunikation)
+ - [7.2 Features \& UI-Logik](#72-features--ui-logik)
+ - [7.3 Deployment Ports](#73-deployment-ports)
+ - [8. Feedback \& Logging Architektur (WP04c)](#8-feedback--logging-architektur-wp04c)
+ - [8.1 Komponenten](#81-komponenten)
+ - [8.2 Log-Dateien](#82-log-dateien)
+ - [8.3 Traceability](#83-traceability)
+ - [9. Indizes \& Performance](#9-indizes--performance)
+ - [10. Offene Punkte / Known Limitations](#10-offene-punkte--known-limitations)
@@ -53,18 +57,19 @@
## 1. Systemüberblick
### 1.1 Architektur-Zielbild
-Mindnet ist ein **lokales RAG-System (Retrieval Augmented Generation)**.
+Mindnet ist ein **lokales RAG-System (Retrieval Augmented Generation)** mit Web-Interface.
1. **Source:** Markdown-Notizen in einem Vault (Obsidian-kompatibel).
2. **Pipeline:** Ein Python-Importer transformiert diese in **Notes**, **Chunks** und **Edges**.
3. **Storage:**
* **Qdrant:** Vektor-Datenbank für Graph und Semantik (Collections: notes, chunks, edges).
* **Local Files (JSONL):** Append-Only Logs für Feedback und Search-History (Data Flywheel).
-4. **Service:** Eine FastAPI-Anwendung stellt Endpunkte für **Semantische** und **Hybride Suche** sowie **Feedback** bereit.
-5. **Inference:** Lokales LLM (Ollama: Phi-3 Mini) für RAG-Chat und Antwortgenerierung.
+4. **Backend:** Eine FastAPI-Anwendung stellt Endpunkte für **Semantische** und **Hybride Suche** sowie **Feedback** bereit.
+5. **Frontend:** Streamlit-App (`ui.py`) für Interaktion und Visualisierung.
+6. **Inference:** Lokales LLM (Ollama: Phi-3 Mini) für RAG-Chat und Antwortgenerierung.
Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsgetrieben** (`types.yaml`, `retriever.yaml`, `decision_engine.yaml`, `prompts.yaml`).
-### 1.2 Verzeichnisstruktur & Komponenten (Post-WP06)
+### 1.2 Verzeichnisstruktur & Komponenten (Post-WP10)
/mindnet/
├── app/
@@ -89,6 +94,8 @@ Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsge
│ │ ├── llm_service.py # Ollama Client mit Timeout & Raw-Mode
│ │ ├── feedback_service.py # JSONL Logging (WP04c)
│ │ └── embeddings_client.py
+ │ ├── frontend/ # NEU (WP10)
+ │ └── ui.py # Streamlit Application
├── config/
│ ├── types.yaml # Typ-Definitionen (Import-Zeit)
│ ├── retriever.yaml # Scoring-Gewichte (Laufzeit)
@@ -308,15 +315,44 @@ Basierend auf dem Intent lädt der Router die Parameter:
---
-## 7. Feedback & Logging Architektur (WP04c)
+## 7. Frontend Architektur (WP10)
+
+Das Frontend ist eine **Streamlit-Anwendung**, die als separater Prozess läuft und via HTTP mit dem Backend kommuniziert.
+
+### 7.1 Kommunikation
+* **Backend-URL:** Konfiguriert via `MINDNET_API_URL` (Default: `http://localhost:8002`).
+* **Endpoints:** Nutzt `/chat` für Interaktion und `/feedback` für Bewertungen.
+* **Resilienz:** Das Frontend implementiert eigene Timeouts (`MINDNET_API_TIMEOUT`, Default 300s), um lange Wartezeiten lokaler LLMs abzufangen.
+
+### 7.2 Features & UI-Logik
+* **State Management:** Session-State speichert Chat-Verlauf und `query_id` für Feedback.
+* **Visualisierung:**
+ * **Intent Badges:** Zeigt Router-Entscheidung (`DECISION`, `FACT`, etc.) und Quelle (`Keyword` vs. `LLM`).
+ * **Source Expanders:** Zeigt verwendete Chunks inkl. Score und "Why"-Explanation.
+ * **Sidebar:** Zeigt Suchhistorie (Log-basiert) und Konfiguration.
+* **Feedback:**
+ * Global (Antwort): 1-5 Sterne Rating.
+ * Granular (Quellen): Faces-Rating (Mapped auf 1-5 Score).
+
+### 7.3 Deployment Ports
+Zur sauberen Trennung von Prod und Dev laufen Frontend und Backend auf dedizierten Ports:
+
+| Umgebung | Backend (FastAPI) | Frontend (Streamlit) |
+| :--- | :--- | :--- |
+| **Production** | 8001 | 8501 |
+| **Development** | 8002 | 8502 |
+
+---
+
+## 8. Feedback & Logging Architektur (WP04c)
Mindnet implementiert ein "Data Flywheel" zur späteren Optimierung (Self-Tuning).
-### 7.1 Komponenten
+### 8.1 Komponenten
* **Feedback Service (`app/services/feedback_service.py`):** Kapselt die Schreibzugriffe.
* **Storage:** Lokales Dateisystem (`data/logs/`), Format JSONL (Line-delimited JSON).
-### 7.2 Log-Dateien
+### 8.2 Log-Dateien
1. **`search_history.jsonl`**:
* Speichert jede Anfrage an `/query` und `/chat`.
* Enthält: `query_id`, `query_text`, `timestamp`, `hits` (inkl. `score_breakdown` Snapshots).
@@ -324,14 +360,15 @@ Mindnet implementiert ein "Data Flywheel" zur späteren Optimierung (Self-Tuning
2. **`feedback.jsonl`**:
* Speichert User-Reaktionen an `/feedback`.
* Enthält: `query_id`, `node_id`, `score` (1-5), `comment`.
+ * **Granularität:** Kann sich auf `generated_answer` (Global) oder eine spezifische `node_id` (Quelle) beziehen.
* Zweck: Labels ("War es gut?").
-### 7.3 Traceability
+### 8.3 Traceability
Die `query_id` (UUIDv4) wird im `/query` Response generiert und muss vom Client beim `/feedback` Aufruf mitgesendet werden. Dies ermöglicht den Join zwischen Snapshot und Bewertung.
---
-## 8. Indizes & Performance
+## 9. Indizes & Performance
Damit Qdrant performant bleibt, sind Payload-Indizes essenziell.
@@ -344,7 +381,7 @@ Validierung erfolgt über `tests/ensure_indexes_and_show.py`.
---
-## 9. Offene Punkte / Known Limitations
+## 10. Offene Punkte / Known Limitations
1. **Multi-Target Inline-Relations:**
* `rel: similar_to [[A]] [[B]]` wird aktuell parser-seitig nicht unterstützt.
diff --git a/docs/pipeline_playbook.md b/docs/pipeline_playbook.md
index dcd3c40..1930cfe 100644
--- a/docs/pipeline_playbook.md
+++ b/docs/pipeline_playbook.md
@@ -1,7 +1,7 @@
# mindnet v2.2 – Pipeline Playbook
**Datei:** `docs/mindnet_pipeline_playbook_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Inkl. WP06 Decision Engine)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Inkl. WP10 Frontend)
**Quellen:** `mindnet_v2_implementation_playbook.md`, `Handbuch.md`, `chunking_strategy.md`, `docs_mindnet_retriever.md`, `mindnet_admin_guide_v2.2.md`.
---
@@ -33,6 +33,7 @@
- [7.2 Smoke-Test (E2E)](#72-smoke-test-e2e)
- [8. Ausblick \& Roadmap (Technische Skizzen)](#8-ausblick--roadmap-technische-skizzen)
- [8.1 WP-08: Self-Tuning (Skizze)](#81-wp-08-self-tuning-skizze)
+ - [16. Workpackage Status (v2.3.2)](#16-workpackage-status-v232)
---
@@ -43,7 +44,7 @@ Dieses Playbook ist das zentrale operative Handbuch für die **mindnet-Pipeline*
**Zielgruppe:** Dev/Ops, Tech-Leads.
**Scope:**
-* **Ist-Stand (WP01–WP06):** Import, Chunking, Edge-Erzeugung, Hybrider Retriever, RAG-Chat (Hybrid Router), Feedback Loop.
+* **Ist-Stand (WP01–WP10):** Import, Chunking, Edge-Erzeugung, Hybrider Retriever, RAG-Chat (Hybrid Router), Feedback Loop, Frontend.
* **Roadmap (Ausblick):** Technische Skizze für Self-Tuning (WP08).
---
@@ -88,10 +89,11 @@ Für regelmäßige Updates (z.B. Cronjob). Erkennt Änderungen via Hash.
* `--sync-deletes`: Entfernt Notizen aus Qdrant, die im Vault gelöscht wurden.
### 2.3 Deployment & Restart (Systemd)
-Nach einem Import oder Code-Update muss der API-Prozess neu gestartet werden.
+Nach einem Import oder Code-Update müssen die API-Prozesse neu gestartet werden.
- # Neustart des Produktions-Services
+ # Neustart des Produktions-Services (API + UI)
sudo systemctl restart mindnet-prod
+ sudo systemctl restart mindnet-ui-prod
# Prüfung
sudo systemctl status mindnet-prod
@@ -203,7 +205,7 @@ Prüft am laufenden System (Prod oder Dev), ob Semantik, Graph und Feedback funk
# Retriever Test
python scripts/test_retriever_smoke.py --mode hybrid --top-k 5
- # Chat / Decision Engine Test (Neu WP06)
+ # Decision Engine Test (WP06)
python tests/test_wp06_decision.py -p 8002 -e EMPATHY -q "Alles ist grau"
# Feedback Test
@@ -220,4 +222,25 @@ Wie entwickeln wir die Pipeline weiter?
**Ansatz:** Ein Offline-Learning-Skript `scripts/optimize_weights.py`.
1. **Load:** Liest `search_history.jsonl` und joint mit `feedback.jsonl` via `query_id`.
2. **Analyze:** Korrelation Scores vs. User-Rating.
-3. **Optimize:** Vorschlag neuer Gewichte für `retriever.yaml`.
\ No newline at end of file
+3. **Optimize:** Vorschlag neuer Gewichte für `retriever.yaml`.
+
+---
+
+## 16. Workpackage Status (v2.3.2)
+
+Aktueller Implementierungsstand der Module.
+
+| WP | Titel | Status | Anmerkung |
+| :--- | :--- | :--- | :--- |
+| **WP01** | Knowledge Design | 🟢 Live | Typen, Frontmatter definiert. |
+| **WP02** | Chunking Strategy | 🟢 Live | Profilbasiertes Chunking aktiv. |
+| **WP03** | Edge Logic / Import | 🟢 Live | Neue Importer-Pipeline mit Provenance. |
+| **WP04a**| Retriever Scoring | 🟢 Live | Hybrider Score (Semantik + Graph). |
+| **WP04b**| Explanation Layer | 🟢 Live | API liefert Reasons & Breakdown. |
+| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
+| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
+| **WP06** | Decision Engine | 🟢 Live | Hybrid Router, Strategic Retrieval. |
+| **WP07** | Interview Assistent | 🟡 Geplant | Nächster Schritt (Dialog-Modus). |
+| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
+| **WP10** | Chat Interface | 🟢 Live | Streamlit Web-UI mit Feedback & Intents. |
+| **WP10a**| GUI Evolution | 🔴 Geplant | Draft-Editor & Interaktionstools. |
\ No newline at end of file
diff --git a/docs/user_guide.md b/docs/user_guide.md
index 9bab874..10bec25 100644
--- a/docs/user_guide.md
+++ b/docs/user_guide.md
@@ -1,7 +1,7 @@
# Mindnet v2.2 – User Guide
**Datei:** `docs/mindnet_user_guide_v2.2.md`
-**Stand:** 2025-12-09
-**Status:** **FINAL** (Inkl. RAG & Multi-Personality Chat)
+**Stand:** 2025-12-10
+**Status:** **FINAL** (Inkl. RAG & Web-Interface)
**Quellen:** `knowledge_design.md`, `wp04_retriever_scoring.md`, `Programmplan_V2.2.md`, `Handbuch.md`.
> **Willkommen bei Mindnet.**
@@ -20,7 +20,7 @@ Wenn du nach "Projekt Alpha" suchst, findet Mindnet nicht nur das Dokument. Es f
* **Ähnliches:** "Projekt Beta war ähnlich".
### 1.2 Der Zwilling (Die Personas)
-Seit Version 2.3.1 passt Mindnet seinen Charakter dynamisch an deine Frage an:
+Mindnet passt seinen Charakter dynamisch an deine Frage an:
1. **Der Bibliothekar (FACT):** Liefert präzise Fakten und Definitionen.
2. **Der Berater (DECISION):** Hilft dir beim Abwägen, basierend auf deinen Werten und Zielen.
3. **Der Spiegel (EMPATHY):** Hört zu und antwortet basierend auf deinen Erfahrungen ("Ich"-Perspektive).
@@ -28,11 +28,32 @@ Seit Version 2.3.1 passt Mindnet seinen Charakter dynamisch an deine Frage an:
---
-## 2. Den Chat steuern (Intents)
+## 2. Die Oberfläche (Web UI)
+
+Seit Version 2.3.1 bedienst du Mindnet über eine grafische Oberfläche im Browser.
+
+### 2.1 Der Chat-Bereich
+* **Eingabe:** Unten findest du das Textfeld.
+* **Intent-Badge:** Über jeder Antwort zeigt ein kleines Label (z.B. **⚖️ Intent: DECISION**), in welchem Modus das System arbeitet und ob dies durch ein Schlüsselwort oder die KI erkannt wurde.
+* **Quellen-Karten:** Unter der Antwort findest du ausklappbare Karten ("Expanders").
+ * **Grüner Punkt:** Hohe Relevanz (Score > 0.8).
+ * **Gelber Punkt:** Mittlere Relevanz.
+ * **Klick darauf:** Zeigt den Textauszug und die **Begründung** ("Warum wurde das gefunden?").
+
+### 2.2 Die Sidebar (Einstellungen & Verlauf)
+* **Modus-Wahl:** Umschalten zwischen "💬 Chat" und "📝 Neuer Eintrag" (Vorbereitung für WP07).
+* **Verlauf:** Die letzten Suchanfragen sind hier gelistet. Ein Klick führt die Suche erneut aus.
+* **Settings:**
+ * **Top-K:** Wie viele Quellen sollen gelesen werden? (Standard: 5).
+ * **Explanation Layer:** Schaltet die "Warum"-Erklärungen an/aus.
+
+---
+
+## 3. Den Chat steuern (Intents)
Du steuerst die Persönlichkeit von Mindnet durch deine Wortwahl. Das System nutzt einen **Hybrid Router**, der sowohl auf Schlüsselwörter als auch auf die Bedeutung achtet.
-### 2.1 Modus: Entscheidung ("Der Berater")
+### 3.1 Modus: Entscheidung ("Der Berater")
Wenn du vor einer Wahl stehst, hilft Mindnet dir, konform zu deinen Prinzipien zu bleiben.
* **Auslöser (Keywords):** "Soll ich...", "Was ist deine Meinung?", "Strategie für...", "Vor- und Nachteile".
@@ -41,68 +62,57 @@ Wenn du vor einer Wahl stehst, hilft Mindnet dir, konform zu deinen Prinzipien z
* *Du:* "Soll ich Tool X nutzen?"
* *Mindnet:* "Nein. Tool X speichert Daten in den USA. Das verstößt gegen dein Prinzip 'Privacy First' und dein Ziel 'Digitale Autarkie'."
-### 2.2 Modus: Empathie ("Der Spiegel")
+### 3.2 Modus: Empathie ("Der Spiegel")
Wenn du frustriert bist oder reflektieren willst, wechselt Mindnet in den "Ich"-Modus.
* **Auslöser (Keywords & Semantik):** "Ich fühle mich...", "Traurig", "Gestresst", "Alles ist sinnlos", "Ich bin überfordert".
* **Was passiert:** Mindnet lädt deine **Erfahrungen** (`type: experience`) und **Glaubenssätze** (`type: belief`). Es antwortet verständnisvoll und zitiert deine eigenen Lektionen.
-* **Beispiel-Dialog:**
- * *Du:* "Ich bin total überfordert, nichts funktioniert."
- * *Mindnet:* "Das Gefühl kenne ich. Erinnere dich an die Situation im Projekt X ('Der Durchbruch nach der Krise'). Damals hat uns das Mantra 'Einfach weitermachen, der Nebel lichtet sich' geholfen."
-### 2.3 Modus: Coding ("Der Techniker")
-* **Auslöser:** "Code", "Python", "Funktion", "Syntax".
-* **Was passiert:** Mindnet antwortet kurz, prägnant und liefert Code-Blöcke. Smalltalk wird reduziert.
-
-### 2.4 Modus: Fakten (Standard)
+### 3.3 Modus: Fakten (Standard)
* **Auslöser:** Alles andere. "Was ist Qdrant?", "Zusammenfassung von X".
* **Was passiert:** Standard-Suche nach Wissen ohne spezielle Filter.
---
-## 3. Ergebnisse interpretieren (Explanation Layer)
+## 4. Ergebnisse interpretieren (Explanation Layer)
Mindnet liefert nicht einfach nur Treffer. Es liefert eine **Begründung** (Explanation), warum es etwas gefunden hat.
-### 3.1 Die Gründe ("Reasons")
-Das System sagt dir in natürlicher Sprache, warum ein Treffer relevant ist:
+### 4.1 Die Gründe ("Reasons")
+Öffne eine Quellen-Karte, um zu sehen:
* *"Hohe textuelle Übereinstimmung."* (Semantik)
* *"Bevorzugt aufgrund des Typs 'decision'."* (Wichtigkeit)
* *"Verweist auf 'Projekt X' via 'depends_on'."* (Graph-Kontext)
-### 3.2 Der Score Breakdown
-Wenn du es genau wissen willst, schau auf die Aufschlüsselung:
-
- Score = (Text) + (Typ-Bonus) + (Vernetzungs-Bonus)
-
----
-
-## 4. Neues Wissen beisteuern (Authoring)
-
-Mindnet lebt von deinem Input. Du musst kein Techniker sein, um gutes Wissen zu designen. Siehe dazu das **Knowledge Design Manual** für Details.
-
-### 4.1 Die Goldene Regel: "Verlinke semantisch"
-Statt einfach nur `[[Link]]` zu schreiben, versuche zu sagen, *wie* es zusammenhängt.
-* Hängt es davon ab? -> `[[rel:depends_on Ziel]]`
-* Ist es ähnlich? -> `[[rel:similar_to Ziel]]`
-
-### 4.2 Typen nutzen (Wichtig!)
-Setze im Frontmatter deiner Notizen den richtigen Typ. Das ist der wichtigste Hebel für den Chat:
-* Willst du, dass Mindnet etwas als **Regel** nutzt? -> `type: principle`
-* Willst du, dass Mindnet dich an eine **Lektion** erinnert? -> `type: experience`
-
---
## 5. Feedback & Lernen
-Mindnet wird schlauer, wenn du es pflegst.
+Mindnet wird schlauer, wenn du es pflegst. Nutze die Feedback-Funktionen im Chat:
-### 5.1 Feedback geben (Data Flywheel)
-Das System zeichnet auf, welche Ergebnisse es liefert. Du kannst Treffer bewerten (geplant für WP-10 UI).
-In Zukunft analysiert das System diese Daten, um seine Gewichte selbstständig anzupassen (Self-Tuning).
+### 5.1 Globales Feedback (Antwort-Qualität)
+* **Wie:** Klicke auf die **Sterne (1-5)** unter der Antwort.
+* **Bedeutung:** Bewertet, wie gut die generierte Antwort war (Prompting, Tonfall).
-### 5.2 Ergebnis fehlt? Troubleshooting
-Wenn Mindnet etwas nicht findet:
-1. **Existiert** die Notiz im Vault? (Dateiname korrekt?)
-2. **Typ korrekt?** (Eine Erfahrung als `concept` getaggt wird im Empathie-Modus vielleicht übersehen).
-3. **Keywords?** (Wenn du "grau" sagst, aber in der Notiz nur "schlecht" steht, füge das Wort "grau" zur Notiz hinzu).
\ No newline at end of file
+### 5.2 Granulares Feedback (Quellen-Relevanz)
+* **Wie:** Klicke innerhalb einer Quellen-Karte auf die **Smileys (Faces)**.
+* **Bedeutung:**
+ * 😞 (Sad): Diese Quelle ist irrelevant/falsch. (Senkt zukünftig das Gewicht).
+ * 😐 (Neutral): Okay, aber nicht entscheidend.
+ * 😀 (Grin): Das ist der perfekte Treffer! (Stärkt diesen Typ/Kante).
+
+---
+
+## 6. Neues Wissen beisteuern (Authoring)
+
+Mindnet lebt von deinem Input. Du musst kein Techniker sein, um gutes Wissen zu designen. Siehe dazu das **Knowledge Design Manual** für Details.
+
+### 6.1 Die Goldene Regel: "Verlinke semantisch"
+Statt einfach nur `[[Link]]` zu schreiben, versuche zu sagen, *wie* es zusammenhängt.
+* Hängt es davon ab? -> `[[rel:depends_on Ziel]]`
+* Ist es ähnlich? -> `[[rel:similar_to Ziel]]`
+
+### 6.2 Typen nutzen (Wichtig!)
+Setze im Frontmatter deiner Notizen den richtigen Typ. Das ist der wichtigste Hebel für den Chat:
+* Willst du, dass Mindnet etwas als **Regel** nutzt? -> `type: principle`
+* Willst du, dass Mindnet dich an eine **Lektion** erinnert? -> `type: experience`
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index d896285..1828b3d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,25 +11,23 @@ qdrant-client>=1.15.1
pydantic>=2.11.7
numpy>=2.3.2
-# --- Markdown & Parsing (Hier fehlten Pakete!) ---
+# --- Markdown & Parsing ---
python-frontmatter>=1.1.0
-# WICHTIG: Das fehlte und verursachte den Fehler
markdown-it-py>=3.0.0
-# WICHTIG: Für types.yaml und retriever.yaml
PyYAML>=6.0.2
python-slugify>=8.0.4
# --- KI & Embeddings ---
sentence-transformers>=5.1.0
-# Torch wird meist durch sentence-transformers geholt,
-# aber wir listen es explizit für Stabilität
torch>=2.0.0
# --- Utilities ---
-# WICHTIG: Damit .env Dateien gelesen werden
python-dotenv>=1.1.1
requests>=2.32.5
tqdm>=4.67.1
# --- Testing ---
pytest>=8.4.2
+
+# --- Frontend (WP-10) ---
+streamlit>=1.39.0
\ No newline at end of file