1 Commits

2 changed files with 33 additions and 39 deletions

1
.streamlit/secrets.toml Normal file
View File

@@ -0,0 +1 @@
[default]

View File

@@ -5,6 +5,7 @@ Seiten: Übersicht, Engramme, Suche, Graph, Heal-Log, Neural Scorer.
import json import json
import sys import sys
import os
from pathlib import Path from pathlib import Path
import streamlit as st import streamlit as st
@@ -25,33 +26,22 @@ _DEFAULT_DB = _root / "data" / "brain.sqlite"
@st.cache_resource @st.cache_resource
class _LazyDB: def _store():
"""Lazy-Initialisierung damit st.secrets erst bei Bedarf gelesen wird.""" return EngramStore(str(_DEFAULT_DB))
_store = None
_chroma = None
@staticmethod
def store():
if _LazyDB._store is None:
db = str(_DEFAULT_DB)
try:
db = st.secrets.get("db_path", str(_DEFAULT_DB))
except Exception:
pass
_LazyDB._store = EngramStore(db)
return _LazyDB._store
@staticmethod
def chroma():
if _LazyDB._chroma is None:
p = Path(str(_DEFAULT_DB)).parent / "chroma"
_LazyDB._chroma = ChromaStore(str(p))
return _LazyDB._chroma
@st.cache_resource @st.cache_resource
def _chroma():
p = Path(str(_DEFAULT_DB)).parent / "chroma"
return ChromaStore(str(p))
_retriever_cache = None
def _retriever(): def _retriever():
return Retriever(_LazyDB.store(), _LazyDB.chroma()) global _retriever_cache
if _retriever_cache is None:
_retriever_cache = Retriever(_store(), _chroma())
return _retriever_cache
@st.cache_resource @st.cache_resource
@@ -61,18 +51,18 @@ def _scorer():
@st.cache_resource @st.cache_resource
def _healer(): def _healer():
return ErrorHealer(_LazyDB.store()) return ErrorHealer(_store())
st.set_page_config(page_title="Second Brain Dashboard", layout="wide") st.set_page_config(page_title="Second Brain Dashboard", layout="wide")
st.title("🧠 2.Brain v0.3.0") st.title("🧠 2.Brain v0.3.1")
page = st.sidebar.radio("Seite", ["Übersicht", "Engramme", "Suche", "Graph", "Heal-Log", "Neural Scorer"]) page = st.sidebar.radio("Seite", ["Übersicht", "Engramme", "Suche", "Graph", "Heal-Log", "Neural Scorer"])
if page == "Übersicht": if page == "Übersicht":
store = _LazyDB.store() store = _store()
engrams = store.get_all(limit=1000) engrams = store.get_all(limit=10000)
confirmed = sum(1 for e in engrams if e.correctness.confirmed) confirmed = sum(1 for e in engrams if e.correctness.confirmed)
unconfirmed = len(engrams) - confirmed unconfirmed = len(engrams) - confirmed
avg_conf = sum(e.compute_confidence() for e in engrams) / max(1, len(engrams)) avg_conf = sum(e.compute_confidence() for e in engrams) / max(1, len(engrams))
@@ -100,12 +90,12 @@ if page == "Übersicht":
if st.button("Auto-Fix", key=f"af_{eg.id}"): if st.button("Auto-Fix", key=f"af_{eg.id}"):
eg.auto_fix_grounding() eg.auto_fix_grounding()
store.save(eg) store.save(eg)
st.success("Fixed!") st.experimental_rerun()
elif page == "Engramme": elif page == "Engramme":
store = _LazyDB.store() store = _store()
st.subheader("Alle Engramme") st.subheader("Alle Engramme (max 1000)")
tag_filter = st.text_input("Filter tags") tag_filter = st.text_input("Filter tags")
source_filter = st.selectbox("Source", ["alle", "user", "agent", "web", "file", "system"]) source_filter = st.selectbox("Source", ["alle", "user", "agent", "web", "file", "system"])
for eg in store.get_all(limit=1000): for eg in store.get_all(limit=1000):
@@ -135,34 +125,37 @@ elif page == "Engramme":
elif page == "Suche": elif page == "Suche":
st.subheader("Hybrid Search (Semantic + Keyword)") st.subheader("Hybrid Search (Semantic + Keyword)")
query = st.text_input("Query") query = st.text_input("Query", placeholder="Suchbegriff eingeben...")
mode = st.radio("Modus", ["Hybrid", "Keyword", "Semantic"], horizontal=True) mode = st.radio("Modus", ["Hybrid", "Keyword", "Semantic"], horizontal=True)
if st.button("Suchen") and query: if st.button("Suchen") and query:
ret = _retriever() ret = _retriever()
results = ret.hybrid_retrieve(query, limit=10) if mode == "Hybrid" else \ results = ret.hybrid_retrieve(query, limit=10) if mode == "Hybrid" else \
ret.semantic_retrieve(query, limit=10) if mode == "Semantic" else \ ret.semantic_retrieve(query, limit=10) if mode == "Semantic" else \
ret.retrieve(query, limit=10) ret.retrieve(query, limit=10)
if not results:
st.info("Keine Ergebnisse gefunden.")
for r in results: for r in results:
eg = r["engram"] eg = r["engram"]
with st.container(): with st.container():
st.markdown(f"**{eg.content[:200]}...**") st.markdown(f"**{eg.content[:200]}...**")
st.write(f"Score: {r['score']:.3f} | Match: {r['match_type']} | Conf: {eg.compute_confidence():.2f}") st.write(f"Score: `{r['score']:.3f}` | Match: `{r['match_type']}` | Conf: `{eg.compute_confidence():.2f}`")
c1, c2 = st.columns(2) c1, c2 = st.columns(2)
if c1.button("✅ Confirm", key=f"sc_{eg.id}"): if c1.button("✅ Confirm", key=f"sc_{eg.id}"):
eg.correctness.confirm("user") eg.correctness.confirm("user")
_LazyDB.store().save(eg) _store().save(eg)
c1.success("Confirmed") st.success("Confirmed")
if c2.button("❌ Reject", key=f"sr_{eg.id}"): if c2.button("❌ Reject", key=f"sr_{eg.id}"):
eg.correctness.reject("user") eg.correctness.reject("user")
_LazyDB.store().save(eg) _store().save(eg)
c2.warning("Rejected") st.warning("Rejected")
elif page == "Graph": elif page == "Graph":
st.subheader("Graph-Visualisierung") st.subheader("Graph-Visualisierung")
graph_html_path = Path(str(_DEFAULT_DB)).parent / "graph_view.html" graph_html_path = Path(str(_DEFAULT_DB)).parent / "graph_view.html"
if st.button("Graph neu generieren"): if st.button("Graph neu generieren"):
path = generate_graph_html(_LazyDB.store(), str(graph_html_path)) with st.spinner("Generiere Graph..."):
path = generate_graph_html(_store(), str(graph_html_path))
st.success(f"Graph generiert: {path}") st.success(f"Graph generiert: {path}")
if graph_html_path.exists(): if graph_html_path.exists():
with open(graph_html_path, "r", encoding="utf-8") as f: with open(graph_html_path, "r", encoding="utf-8") as f:
@@ -199,7 +192,7 @@ elif page == "Heal-Log":
elif page == "Neural Scorer": elif page == "Neural Scorer":
st.subheader("Neural Scorer Training") st.subheader("Neural Scorer Training")
scorer = _scorer() scorer = _scorer()
store = _LazyDB.store() store = _store()
engrams = store.get_all(limit=10000) engrams = store.get_all(limit=10000)
labeled = [e for e in engrams if e.correctness.confirmed or e.correctness.rejections > 0] labeled = [e for e in engrams if e.correctness.confirmed or e.correctness.rejections > 0]
st.write(f"Labelled Engramme: **{len(labeled)}**") st.write(f"Labelled Engramme: **{len(labeled)}**")
@@ -207,7 +200,7 @@ elif page == "Neural Scorer":
if len(labeled) < 2: if len(labeled) < 2:
st.error("Mindestens 2 labelierte Engramme nötig (confirm + reject).") st.error("Mindestens 2 labelierte Engramme nötig (confirm + reject).")
else: else:
with st.spinner("Training..."): with st.spinner("Training läuft..."):
result = scorer.train(labeled, epochs=30) result = scorer.train(labeled, epochs=30)
st.json(result) st.json(result)
st.success("Training abgeschlossen!") st.success("Training abgeschlossen!")