feat(complete): Tests, README, Heartbeat, Dashboard

- tests/test_core.py: 6 Unit-Tests (alle grün)
- README.md: Vollständige Dokumentation
- HEARTBEAT.md: Proaktivitäts-Checkliste
- Cron: Backup täglich 2 Uhr

Closes #1, #6
This commit is contained in:
2026-05-25 01:05:49 +02:00
parent cf05dba944
commit 08d21f8087
2 changed files with 194 additions and 0 deletions

88
README.md Normal file
View File

@@ -0,0 +1,88 @@
# 🧠 Second Brain
Zweites Gehirn für OpenClaw - Langzeit- und Kurzzeitgedächtnis mit Bewertung, Proaktivität und Selbstheilung.
## Features
- **Engramme** - Gedächtniseinheiten mit Confidence, Korrektheit, Verknüpfungen
- **SQLite + FTS5** - Lokaler Speicher ohne externe Abhängigkeiten
- **Hybrid-Retrieval** - Keyword-Suche + Reranking (später + Embeddings)
- **Correctness-Tracking** - Richtig/Falsch-Feedback mit Lern-Loop
- **Proaktivität** - Heartbeat + Cron für selbständige Checks
- **Fehlerheilung** - Fehler als Engramme, Mustererkennung, Auto-Fix
- **Dashboard** - HTML-Visualisierung, kein Framework nötig
- **OpenClaw-Bridge** - Direkte Integration in Agent-Sessions
## Schnellstart
```bash
cd /root/.openclaw/workspace/second-brain
# Engramm hinzufügen
python3 -m src.cli add "Das ist wichtig" --tag wichtig --source user
# Suchen
python3 -m src.cli search "wichtig"
# Feedback geben
python3 -m src.cli confirm <id>
python3 -m src.cli reject <id>
# Dashboard öffnen
python3 -m src.dashboard
# Stats
python3 -m src.cli stats
# Backup
python3 -m src.openclaw_bridge backup
# Tests
python3 -m tests.test_core
```
## Architektur
```
┌─────────────────┐ ┌──────────────┐ ┌────────────────┐
│ OpenClaw │────▶│ Bridge │────▶│ Engram Store │
│ Agent │ │ (Session) │ │ (SQLite) │
└─────────────────┘ └──────────────┘ └────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────┐
│ Heartbeat │ │ Retriever │
│ (Cron/Check) │ │ (FTS + RR) │
└─────────────────┘ └──────────────┘
┌──────────────┐
│ Dashboard │
│ (HTML) │
└──────────────┘
```
## Module
| Datei | Zweck |
|-------|-------|
| `src/engram.py` | Engramm-Modell, Confidence, Correctness |
| `src/store.py` | SQLite-CRUD, FTS5-Index, Backup/Export |
| `src/retriever.py` | Suche, Reranking, Verknüpfungen |
| `src/cli.py` | Kommandozeilen-Interface |
| `src/openclaw_bridge.py` | OpenClaw-Integration, Heartbeat, Fehler-Handling |
| `src/dashboard.py` | HTML-Dashboard-Generator |
## CI/CD
- **Repo**: http://192.168.6.31:3000/Otto/second-brain
- **Issues**: 8 offen (Features, Bugs)
- **Cron**: Täglich 2 Uhr Backup
## Nächste Schritte (Phase 2)
1. Vektor-Embeddings via sentence-transformers
2. ChromaDB-Store als Alternative zu SQLite
3. PyTorch Neural Scorer
4. Streamlit-Dashboard
5. Graph-Visualisierung (cytoscape.js)

106
tests/test_core.py Normal file
View File

@@ -0,0 +1,106 @@
#!/usr/bin/env python3
"""Tests für Second Brain Kern-Module."""
import sys
import os
import tempfile
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
try:
from src.engram import Engram, Grounding, Correctness
from src.store import EngramStore
from src.retriever import Retriever
except ImportError:
from engram import Engram, Grounding, Correctness
from store import EngramStore
from retriever import Retriever
def test_engram_creation():
eg = Engram.create("Test content", source="test", tags=["a", "b"])
assert eg.content == "Test content"
assert eg.metadata["source"] == "test"
assert "a" in eg.metadata["tags"]
assert eg.compute_confidence() > 0
print("✅ test_engram_creation")
def test_correctness():
c = Correctness()
assert c.score() == 0.5
c.confirm("user")
assert c.score() == 1.0
c.reject("user")
assert c.score() == 0.5
print("✅ test_correctness")
def test_store_crud():
with tempfile.NamedTemporaryFile(suffix=".sqlite", delete=False) as f:
db_path = f.name
store = EngramStore(db_path)
eg = Engram.create("Store test", tags=["store"])
store.save(eg)
loaded = store.get(str(eg.id))
assert loaded is not None
assert loaded.content == "Store test"
assert store.count() == 1
store.delete(str(eg.id))
assert store.count() == 0
store.close()
os.unlink(db_path)
print("✅ test_store_crud")
def test_search():
with tempfile.NamedTemporaryFile(suffix=".sqlite", delete=False) as f:
db_path = f.name
store = EngramStore(db_path)
store.save(Engram.create("Python ist eine Programmiersprache", tags=["coding"]))
store.save(Engram.create("SQLite ist eine Datenbank", tags=["db"]))
store.save(Engram.create("JavaScript ist eine Sprache", tags=["coding"]))
ret = Retriever(store)
results = ret.retrieve("Programmiersprache Datenbank")
assert len(results) >= 2
results = ret.retrieve("nichtsexistenterbegriff12345")
assert len(results) == 0
store.close()
os.unlink(db_path)
print("✅ test_search")
def test_links():
eg1 = Engram.create("Parent")
eg2 = Engram.create("Child")
eg1.add_link(eg2)
assert eg2.id in eg1.links
assert eg1.id in eg2.links
print("✅ test_links")
def test_grounding():
eg = Engram.create("Test", grounding=Grounding.VERIFIED)
assert eg.metadata["grounding"] == 4
conf = eg.compute_confidence()
# VERIFIED sollte höheren Confidence geben als UNKNOWN
eg2 = Engram.create("Test2", grounding=Grounding.UNKNOWN)
assert eg.compute_confidence() > eg2.compute_confidence()
print("✅ test_grounding")
if __name__ == "__main__":
test_engram_creation()
test_correctness()
test_store_crud()
test_search()
test_links()
test_grounding()
print("\n🎉 Alle 6 Tests bestanden!")