A Hermes agent memory plugin with sentence-transformers embeddings + semantic dedup + trust scoring + temporal decay.
- sentence-transformers (
all-MiniLM-L6-v2) instead of ChromaDB default embeddings - Semantic deduplication — duplicate content above 0.88 cosine similarity is merged
- Trust scoring — repeated facts gain higher trust (0.5 → 1.0)
- Temporal decay — memories fade with a 30-day half-life
- Composite ranking — semantic × trust × recency + keyword overlap
- BM25 keyword scoring (from scratch, no dependencies)
- ChromaDB persistent semantic search
- Keyword overlap as a third retrieval signal
- RRF late fusion combines all three signals
- Auto-sync —
sync_turn()saves every conversation turn automatically - Wing/room organization — like MemPalace
- Live lesson synthesis — detects corrections, self-corrections, and good outcomes in real-time
- Self-improvement — nightly consolidation generates lessons from recent sessions
Problem: Nightly consolidation v2.0 generated meta-metrics about itself (trust distributions, self-improvement scores, etc.) instead of actual lessons learned from user corrections.
Fix: Complete rewrite of nightly_consolidation.py:
| Before (v2.0) | After (v2.2) |
|---|---|
| Analyzed Nexus memory patterns only | Reads corrections from sessions.db directly |
| Generated 16 meta-metrics (0 useful) | Synthesized 7 real lessons from 59 corrections |
| "Self-improvement score: 46/100" | "GitHub: ALL docs in ENGLISH" |
| "No corrections stored" | Actually extracts corrections from chat history |
New lessons synthesized from Marius's corrections:
- GitHub: ALL public docs, release notes, commit msgs in ENGLISH
- Always respond in bokmål Norwegian unless user speaks English
- Restart gateway: only use
Hermes gateway restart - After code changes: new release + changelog + gateway restart
- Verify fixes work before declaring done
- Browser Use Cloud configured as default browser
Technical changes:
extract_corrections_from_sessions()— reads~/.hermes/state.dbdirectlysynthesize_lessons_from_corrections()— distills corrections into actionable rules (no LLM)- Removed: self-referential score tracking, trust distribution reports
- Kept: stale memory pruning, suspicious memory detection
Bugs fixed:
| # | Severity | Issue | Fix |
|---|---|---|---|
| 1 | 🟠 Høy | _CORRECTION_PATTERNS could not detect real Norwegian corrections |
Replaced 5 narrow patterns with 5 language-specific lists: _NB_CORRECTION, _NB_BLAME, _NB_PHRASES, _EN_CORRECTION, _EN_BLAME (19 total) |
| 2 | 🟠 Høy | Corrections never stored with is_correction=True |
Added is_correction=True + trust_score=1.0 on storage; dedicated wing=corrections entry for accurate nightly counting |
| 3 | 🟠 Høy | MemoryStore.add() lacked is_correction and trust_score params |
Added both params; corrections get trust_score=1.0 automatically |
| 4 | 🟡 Medium | Nightly could not count corrections accurately | Corrections now stored with is_correction=True metadata + wing=corrections |
Pattern coverage (v2.1):
| Language | Category | Count | Examples |
|---|---|---|---|
| Norwegian | Direct correction | 6 | nei, feil, tar feil, misforstår, det stemmer ikke, korrekt |
| Norwegian | Blame | 2 | "du blander", "du forvirrer" |
| Norwegian | Corrective phrases | 3 | hold kje, husk på, hallå |
| English | Direct correction | 8 | no, wrong, I meant, not quite, I disagree |
| English | Blame | 2 | you're confusing, you got it wrong |
| Total | 21 |
- sentence-transformers/all-MiniLM-L6-v2 embeddings
- Semantic deduplication (0.88 cosine threshold)
- Trust scoring with temporal decay
- Skip-dedup mode for lessons (always store fresh)
- Live lesson synthesis via
_live_lesson_synthesize() - Self-verification with contradiction detection
- Tool success confirmation system
cd ~/.hermes/hermes-agent
./venv/bin/python3 -m pip install sentence-transformers chromadbmkdir -p ~/.hermes/hermes-agent/plugins/memory/nexus/Copy these files to ~/.hermes/hermes-agent/plugins/memory/nexus/:
__init__.py— the complete plugin (MemoryStore + NexusProvider)plugin.yaml— plugin manifest
In ~/.hermes/config.yaml:
memory:
provider: nexus
plugins:
nexus:
palace_path: ~/.hermes/nexus# Find the gateway PID
cat ~/.hermes/gateway.pid
# Kill and restart
kill <PID>
cd ~/.hermes/hermes-agent && ./venv/bin/python -m hermes_cli.main gateway run --replacecd ~/.hermes/hermes-agent/plugins/memory/nexus
python3 -c "
import sys; sys.path.insert(0, '.')
import importlib.util
spec = importlib.util.spec_from_file_location('nexus', '__init__.py')
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
s = m.MemoryStore('~/.hermes/nexus')
s.load()
print('Docs:', s.stats()['total'])
print('Avg trust:', s.stats().get('avg_trust', 'N/A'))
print('Embedding:', s.stats().get('embedding_model', 'N/A'))
"add(text):
1. embed text → 384-dim vector
2. compare to all existing embeddings (cosine sim)
3. if sim >= 0.88 → UPDATE existing doc (boost trust, bump timestamp)
4. else → ADD new doc with trust=0.5 (or 1.0 if is_correction=True)
search(query):
1. embed query
2. semantic similarity to all docs
3. keyword overlap (secondary signal, 20% weight)
4. temporal decay (30-day half-life)
5. trust score (repeated facts rank higher)
6. composite = semantic × (0.5 + trust) × (0.5 + decay) + keyword × 0.2
composite[i] = sem[i] × (0.5 + trust[i]) × (0.5 + decay[i]) × 0.5
+ keyword_overlap(query, doc[i]) × 0.2
Where:
trust[i]= 0.5 (initial) → 1.0 (max after repeats, or 1.0 immediately ifis_correction=True)decay[i]= exp(-ln(2) × age_days / 30)
SIM_THRESHOLD = 0.88 — cosine similarity above this merges entries instead of creating duplicates.
__init__.py — Everything: embeddings, MemoryStore, NexusProvider, register()
plugin.yaml — Plugin manifest
README.md — This file
LICENSE — MIT
MIT