🌙 luminary-memory
A lightweight, self-hosted memory layer for AI agents.
Self-hosted · Private · Budget-aware · Self-maintaining
What your agent remembers is what it becomes.
Agents are only as good as what they remember. A stateless agent re-learns the same context every session, paying the same tokens, making the same mistakes. luminary-memory closes that gap with a local memory store that persists between runs, retrieves the right context on demand, and keeps itself tidy over time.
Four retrieval strategies. One fused result. Local by default.
- Semantic, ONNX embeddings (384-dim, CPU, no GPU needed)
- Keyword, FTS5 BM25 (SQLite, zero config)
- Temporal, recency decay × access count
- Graph, entity co-occurrence with automatic curation
- Active-task session continuity, exact-session episodes preserve short-term context when durable recall abstains without promoting raw turns into semantic memory or widening scope across users, agents, or sessions.
Strategies fuse via weighted RRF (semantic 0.4, keyword 0.3, graph 0.2, temporal 0.1) → scope/status/time filtering → conservative confidence and abstention → adaptive cutoff → Jaccard deduplication → token budget. Short queries may be expanded with graph entities or stored content tokens before embedding; there is no language-specific alias classifier.
Important rules always in context. Durable rules tagged core are auto-loaded into the system prompt every session (the DB-backed MEMORY.md). All other durable memories are surfaced through query retrieval: relevant facts are recalled on demand (ranked by query relevance) and merged with the core block under anti-duplication. When durable recall abstains, the Hermes provider can also expose a bounded exact-session continuity block so an ambiguous follow-up stays attached to its active task without turning raw conversation into durable memory.
Quickstart
pip install luminary-memory
from luminary_memory import MemoryClient
client = MemoryClient(db_path="memory.db")
# store a durable fact
client.ingest("The deploy target is the staging cluster", tags=["deploy", "infra"])
# recall, four strategies fused into one ranked answer
result = client.recall("where do we deploy?")
for memory, score in zip(result.memories, result.scores):
print(f"{score:.3f} {memory.content}")
# → 0.942 The deploy target is the staging cluster
# CLI
luminary-memory add "deploy target is staging" --tags deploy
luminary-memory recall "where do we deploy?" --json
luminary-memory activity --limit 5
luminary-memory list
luminary-memory lifecycle
luminary-memory stats
Hermes Agent, first-class memory provider
Luminary integrates through Hermes' public MemoryProvider entry point. The
installer selects Luminary and disables Hermes' two native persistent-memory
surfaces (MEMORY.md and USER.md) using their existing config switches, so
the agent has one durable memory authority without a Hermes source patch or a
version-specific fork.
For a new install, use bash hermes/install.sh. If configuring Hermes
manually, set the provider and the two native switches together:
memory:
provider: luminary
memory_enabled: false
user_profile_enabled: false
This is capability-based integration, not a version pin. Hermes must expose the
MemoryProvider entry-point contract and lifecycle; when it does not, setup
should stop with a visible diagnostic rather than silently running two memory
systems. No Hermes version number is embedded in Luminary's runtime path.
From the next session: auto-recall injects relevant memories every turn,
the auto-retain hook evaluates completed turns for durable storage and
serialized self-improvement review, and the model can call
luminary_recall / luminary_ingest / luminary_list on demand.
Two optional LLM-powered features keep the store sharp:
ingest_llm, curates automatic turn batches before storage, then reconciles the current turn against exact-scope candidates. It can save a grounded new fact or explicitly version/retract a claim; it cannot mutate from similarity alone. Without curation, automatic transcript batches are not promoted into durable memory, but remain available in the exact-session continuity ledger; explicit memory/core writes remain available.auto_maintain, reviews the store at session end: keeps current facts, updates changed ones, deletes stale or duplicate ones.
Provider settings are exposed in the Hermes dashboard for tuning. See docs/config-reference.md for the complete reference and hermes/README.md for the one-shot installer.
Audit-grade behavior
Exact active-memory deduplication is enforced by the database for the full
user/workspace/agent/session scope, so concurrent writers converge on one
row instead of racing through a read-then-insert check. Evidence-required
recall fails closed when a quote is not grounded in the stored content, and
MemoryClient.count() reports the same active, scope-visible view as
list().
Hermes writes scoped JSONL troubleshooting events to
~/.hermes/luminary/luminary.log. Events include trace_id, operation,
status/reason, counts, confidence, and latency; prompt text, memory content,
Telegram tokens, and API keys are omitted. Inspect it with:
tail -f ~/.hermes/luminary/luminary.log | jq
The documentation map below is the public source of truth for the library, provider, operator, and integration guides. The benchmark notes keep the boundary around Mem0/Hindsight comparisons explicit: matched local measurements, not a universal superiority claim.
Configuration
Every setting has a LUMINARY_* env var or a Settings object.
| Setting | Env var | Default |
|---|---|---|
backend |
LUMINARY_BACKEND |
sqlite |
db_path |
LUMINARY_DB_PATH |
luminary_memory.db |
pg_dsn |
LUMINARY_PG_DSN |
postgresql://localhost/luminary_memory (pgvector only) |
pg_hnsw_index |
LUMINARY_PG_HNSW_INDEX |
false |
pg_hnsw_m |
LUMINARY_PG_HNSW_M |
16 |
pg_hnsw_ef_construction |
LUMINARY_PG_HNSW_EF_CONSTRUCTION |
64 |
embedding_model |
LUMINARY_EMBEDDING_MODEL |
BAAI/bge-small-en-v1.5 |
embedding_dim |
LUMINARY_EMBEDDING_DIM |
384 |
ingest_llm |
LUMINARY_INGEST_LLM |
false |
rrf_k |
LUMINARY_RRF_K |
60 |
strategy_weights |
LUMINARY_WEIGHT_{SEMANTIC,KEYWORD,GRAPH,TEMPORAL} |
0.4 / 0.3 / 0.2 / 0.1 |
recall_cliff_threshold |
LUMINARY_RECALL_CLIFF_THRESHOLD |
0.45 |
dedup_jaccard_threshold |
LUMINARY_DEDUP_JACCARD_THRESHOLD |
0.85 |
token_budget |
LUMINARY_TOKEN_BUDGET |
4096 |
max_memories |
LUMINARY_MAX_MEMORIES |
1000 |
ttl_default_seconds |
LUMINARY_TTL_DEFAULT_SECONDS |
null |
prune_min_importance |
LUMINARY_PRUNE_MIN_IMPORTANCE |
0.2 |
consolidate_jaccard_threshold |
LUMINARY_CONSOLIDATE_JACCARD_THRESHOLD |
0.9 |
consolidate_semantic |
LUMINARY_CONSOLIDATE_SEMANTIC |
true |
importance_auto |
LUMINARY_IMPORTANCE_AUTO |
true |
importance_recall_boost |
LUMINARY_IMPORTANCE_RECALL_BOOST |
1.0 |
rule_auto_replace |
LUMINARY_RULE_AUTO_REPLACE |
true (legacy library default; requires explicit supersession) |
rule_auto_replace_threshold |
LUMINARY_RULE_AUTO_REPLACE_THRESHOLD |
0.85 |
rule_importance |
LUMINARY_RULE_IMPORTANCE |
0.9 |
core_tag |
LUMINARY_CORE_TAG |
core |
core_top_n |
LUMINARY_CORE_TOP_N |
12 |
core_budget |
LUMINARY_CORE_BUDGET |
8000 |
query_planner |
LUMINARY_QUERY_PLANNER |
true |
query_planner_keyword_threshold |
LUMINARY_QUERY_PLANNER_KEYWORD_THRESHOLD |
0.9 |
ingest_whitelist |
LUMINARY_INGEST_WHITELIST |
[] |
llm_base_url |
LUMINARY_LLM_BASE_URL |
"" |
llm_api_key |
LUMINARY_LLM_API_KEY |
"" |
llm_model |
LUMINARY_LLM_MODEL |
gpt-4o-mini |
llm_timeout |
LUMINARY_LLM_TIMEOUT |
10 |
llm_max_tokens |
LUMINARY_LLM_MAX_TOKENS |
512 |
rule_keywords |
LUMINARY_RULE_KEYWORDS |
"" (compatibility only; not used for durability classification) |
The direct library client keeps
rule_auto_replace=truefor compatibility, but replacement still requires an explicitsupersedes_id. The accuracy-facing CLI and Hermes provider disable replacement unless that relationship is supplied and preserve conflicting claims for auditability.rule_keywordsis retained only for callers that already depend on the compatibility matcher; it does not classify memory by language or vocabulary.
Provider-specific settings (Hermes dashboard):
max_memories,mode,recall_limit,auto_recall,recall_sync,auto_retain,retain_every_n_turns,retain_user_prefix/retain_assistant_prefix,ingest_llm,auto_maintain,consolidate_semantic,importance_auto,core_tag,core_top_n,core_budget,importance_recall_boost,recall_min_score,extract_on_session_end(compatibility flag),recall_indicator,retain_indicator(live in~/.hermes/luminary/config.json). The exact defaults and dashboard schema are maintained in docs/config-reference.md. See hermes/SKILL.md for the full provider config table.
Architecture
Memory is a loop, not a pipeline you run once. Every turn, luminary recalls what is relevant before the agent answers, then ingests what mattered after, and a background lifecycle keeps the store lean.
┌───────────────────────────── LOOP ─────────────────────────────┐
│ │
recall(query) ──► scoped strategy candidates ──► weighted RRF ──► confidence/abstention ──► ranked results
▲ semantic │ keyword │ temporal │ graph (per-strategy weights) (cliff detection)
│ │
└── inject into agent context ◄── token budget (4096) ◄── dedup (Jaccard 0.85)
│ │
core memory ──► auto-loaded every session (tag 'core') ─┘ (merged, anti-duplicated)
│
ingest(text) ──► whitelist ──► (LLM curation) ──► embed (ONNX 384-d) ─┘
Hermes sync_turn ──► exact-session episode ledger ──► serialized retain ──► incremental review ──► capture / supersede / retract
│
lifecycle() ──► cleanup (TTL) ──► consolidate (semantic + Jaccard, pinned exempt) ──► prune (importance, pinned exempt)
maintenance() ──► LLM reviews store ──► keep │ update │ delete stale facts
Accuracy safeguards:
| Stage | Mechanism |
|---|---|
| 4 strategies | Semantic (ONNX cosine, vectorized matmul) + keyword (FTS5 BM25) + temporal (recency × access, batched fetch) + graph (entity co-occurrence, SQL aggregation) |
| Scope isolation | User/workspace/agent/session predicates are applied before fusion and fallback |
| Abstention | Strict provider/CLI paths can return abstain when support is weak or ambiguous |
| Evidence | Stored claims retain evidence quote, source, validity time, and audit provenance |
| Conflict safety | Conflicting claim keys remain versioned/conflicted until explicit supersession or resolution |
| Core memory | Rules tagged core are auto-loaded into the system prompt every session (the DB-backed MEMORY.md), independent of query match |
| Weighted fusion | Each strategy carries a tunable weight (semantic 0.4, keyword 0.3, graph 0.2, temporal 0.1), so high-signal strategies dominate the ranking |
| Query expansion | Short queries are expanded with co-occurring graph entities before embedding; when the graph is empty, content tokens from a topically related important memory may be appended (v0.2.15). No language-specific alias list is used. |
| Importance boost | Memories at importance ≥ 0.8 get a ranking bonus, lifting durable rules above weak-but-recent noise |
| Adaptive cutoff | Cliff detection keeps only the relevant cluster: a sparse store returns 3 strong matches instead of padding to 20, while a dense relevant store keeps everything (no over-filtering) |
| Token budget | Hard cap so memory injection never blows up the context window |
| Session continuity | Hermes may inject only a bounded, untrusted recent-episode block from the exact active session when durable recall has no usable result |
Why it stays clean:
| Stage | Mechanism |
|---|---|
| Lifecycle | TTL cleanup, semantic consolidation (embedding cosine, fallback Jaccard), importance-based pruning (all batched at the backend level) |
| Rule pinning | Memories at importance ≥ 0.9 are pinned: never pruned, never deleted by consolidation |
| Rule replacement | Hermes/CLI disable destructive replacement by default; legacy direct-client behavior remains compatibility-controlled |
| Store hygiene | Automatic transcript batches require a curated summary before entering durable memory; malformed or uncurated batches stay only in the exact-session ledger, while explicit writes preserve their supplied provenance. Durability is not inferred from language-specific keywords. |
| Auto importance | Every memory is scored by recency + access + graph centrality; prune and health use live values. On recall, frequently-used memories are re-estimated immediately so they rank higher in the next turn's query recall (v0.2.15, LUMINARY_IMPORTANCE_AUTO) |
| Max memories cap | max_memories (default 1000) prunes the oldest/lowest-importance when the store exceeds it |
| LLM maintenance | ingest_llm adds a grounded post-turn review; optional auto_maintain reviews the store at session end: keep, update, or delete stale facts |
| Health score | health_score() gives a 0-100 checkup with actionable recommendations; core-tagged rows are recognized as always-loaded prompt data rather than false “never accessed” recall rows |
| Content-level anti-dup | Core and recall share one dedup set (ids + content hashes), so a rule stored both as core and as a plain memory appears exactly once per turn (v0.2.15) |
health_score() gives you a 0-100 checkup with actionable recommendations.
Documentation
| Section | |
|---|---|
| Quickstart | Install and first use |
| Architecture | Pipelines and data flow |
| Python API | MemoryClient reference |
| Agent Tools | 6 tools reference + parameter schema |
| CLI | All subcommands |
| Recall | Four strategies + fusion |
| Lifecycle | Cleanup, consolidation, pruning, LLM maintenance |
| Backends | SQLite vs pgvector |
| Configuration reference | Library env vars + provider config |
| Hermes integration | Provider, config, installer |
| Hermes install kit | Capability-based install, upgrade, repair utility |
| Debugging Guide | Gateway envelopes, hook internals, verification |
| Benchmarks | Pipeline smoke + independent gold-set metrics (not a competitor proof) |
License
Apache-2.0 © 2026 Dwiky Candra
Metadata
Release files for luminary-memory 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| luminary_memory-0.3.0.tar.gz | 622.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| luminary_memory-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 756.4 kB
Release files / luminary_memory-0.3.0.tar.gz
| Download URL | luminary_memory-0.3.0.tar.gz |
|---|---|
| Size | 622.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9a450cd10c9e95ecf2d4b792fa03563aa65ecbee54d09fc13870eb781e6e8ec4
|
|
BLAKE2b-256 checksum How to use checksums |
1c8d64ded0a2ee3fcd661e51ec8a0ee31a6475f7df71d585680828013990a2d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logRelease files / luminary_memory-0.3.0-py3-none-any.whl
| Download URL | luminary_memory-0.3.0-py3-none-any.whl |
|---|---|
| Size | 133.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2e37315632ba1b0d398b14df983750fb8a9322629c7f9fa8a70227b1733080b6
|
|
BLAKE2b-256 checksum How to use checksums |
30bf2c8f8b82a6f72121adcb01bfeee112abceb3b31c9797ba9926475786f14b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logSecurity for luminary-memory 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for luminary_memory-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.