Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2436460b27 |
1
.streamlit/secrets.toml
Normal file
1
.streamlit/secrets.toml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[default]
|
||||||
@@ -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!")
|
||||||
|
|||||||
Reference in New Issue
Block a user