luminary-memory 0.2.1__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/.github/workflows/publish.yml +0 -1
  2. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/.gitignore +3 -0
  3. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/CHANGELOG.md +29 -1
  4. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/PKG-INFO +38 -3
  5. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/README.md +36 -2
  6. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/ROADMAP.md +9 -8
  7. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/hermes-integration.md +23 -2
  8. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/index.md +1 -0
  9. luminary_memory-0.2.2/hermes/README.md +104 -0
  10. luminary_memory-0.2.2/hermes/SKILL.md +171 -0
  11. luminary_memory-0.2.2/hermes/hooks/luminary-activity/HOOK.yaml +4 -0
  12. luminary_memory-0.2.2/hermes/hooks/luminary-activity/README.md +47 -0
  13. luminary_memory-0.2.2/hermes/hooks/luminary-activity/handler.py +90 -0
  14. luminary_memory-0.2.2/hermes/install.sh +126 -0
  15. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/pyproject.toml +4 -1
  16. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/__init__.py +1 -1
  17. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/hermes/config_schema.py +16 -4
  18. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/hermes/provider.py +66 -7
  19. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/ingest/llm.py +24 -5
  20. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/website/index.html +13 -1
  21. luminary_memory-0.2.1/hermes/README.md +0 -36
  22. luminary_memory-0.2.1/hermes/SKILL.md +0 -92
  23. luminary_memory-0.2.1/website/plan.md +0 -366
  24. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  25. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  26. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  27. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/.github/workflows/ci.yml +0 -0
  28. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/.github/workflows/pages.yml +0 -0
  29. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/CODE_OF_CONDUCT.md +0 -0
  30. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/CONTRIBUTING.md +0 -0
  31. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/LICENSE +0 -0
  32. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/PLAN-v0.2.0.md +0 -0
  33. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/PLAN-v0.2.1.md +0 -0
  34. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/PLAN.md +0 -0
  35. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/SECURITY.md +0 -0
  36. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/benchmarks/README.md +0 -0
  37. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/benchmarks/RESULTS.md +0 -0
  38. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/benchmarks/__init__.py +0 -0
  39. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/benchmarks/hermes_provider_bench.py +0 -0
  40. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/benchmarks/metrics.py +0 -0
  41. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/benchmarks/run_benchmarks.py +0 -0
  42. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/benchmarks/synthetic.py +0 -0
  43. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/api.md +0 -0
  44. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/architecture.md +0 -0
  45. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/backends.md +0 -0
  46. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/cli.md +0 -0
  47. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/lifecycle.md +0 -0
  48. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/quickstart.md +0 -0
  49. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/docs/recall.md +0 -0
  50. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/api.py +0 -0
  51. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/backends/__init__.py +0 -0
  52. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/backends/base.py +0 -0
  53. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/backends/pgvector.py +0 -0
  54. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/backends/sqlite.py +0 -0
  55. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/budget.py +0 -0
  56. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/cli.py +0 -0
  57. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/config.py +0 -0
  58. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/embeddings/__init__.py +0 -0
  59. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/embeddings/fastembed.py +0 -0
  60. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/export.py +0 -0
  61. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/hermes/__init__.py +0 -0
  62. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/hermes/config.py +0 -0
  63. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/hermes/plugin.yaml +0 -0
  64. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/ingest/__init__.py +0 -0
  65. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/ingest/whitelist.py +0 -0
  66. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/lifecycle/__init__.py +0 -0
  67. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/lifecycle/cleanup.py +0 -0
  68. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/lifecycle/consolidate.py +0 -0
  69. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/lifecycle/prune.py +0 -0
  70. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/lifecycle/runner.py +0 -0
  71. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/__init__.py +0 -0
  72. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/dedup.py +0 -0
  73. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/fusion.py +0 -0
  74. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/graph.py +0 -0
  75. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/keyword.py +0 -0
  76. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/planner.py +0 -0
  77. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/semantic.py +0 -0
  78. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/snippets.py +0 -0
  79. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/recall/temporal.py +0 -0
  80. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/schema.py +0 -0
  81. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/src/luminary_memory/types.py +0 -0
  82. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/__init__.py +0 -0
  83. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/conftest.py +0 -0
  84. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_backup_paths.py +0 -0
  85. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_config.py +0 -0
  86. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_entrypoint.py +0 -0
  87. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_hooks.py +0 -0
  88. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_lifecycle.py +0 -0
  89. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_provider_import.py +0 -0
  90. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_recall.py +0 -0
  91. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_session_boundaries.py +0 -0
  92. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_sync_turn.py +0 -0
  93. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_system_prompt.py +0 -0
  94. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes/test_tools.py +0 -0
  95. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/hermes_stubs/agent/memory_provider.py +0 -0
  96. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_api.py +0 -0
  97. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_api_extended.py +0 -0
  98. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_backend_pgvector.py +0 -0
  99. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_backend_sqlite.py +0 -0
  100. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_budget.py +0 -0
  101. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_cli.py +0 -0
  102. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_dedup_jaccard.py +0 -0
  103. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_embeddings.py +0 -0
  104. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_fusion_rrf.py +0 -0
  105. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_ingest_whitelist.py +0 -0
  106. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_lifecycle.py +0 -0
  107. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_recall_graph.py +0 -0
  108. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_recall_keyword.py +0 -0
  109. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_recall_orchestrator.py +0 -0
  110. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_recall_semantic.py +0 -0
  111. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_recall_temporal.py +0 -0
  112. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_schema.py +0 -0
  113. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t10_export.py +0 -0
  114. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t11_limit_zero.py +0 -0
  115. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t1_hnsw.py +0 -0
  116. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t3_planner.py +0 -0
  117. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t4_batch.py +0 -0
  118. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t5_enricher.py +0 -0
  119. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t6_tag_scoped.py +0 -0
  120. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t7_updated_at.py +0 -0
  121. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t8_snippets.py +0 -0
  122. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/tests/test_t9_cli_json.py +0 -0
  123. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/website/.nojekyll +0 -0
  124. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/website/css/luminary.css +0 -0
  125. {luminary_memory-0.2.1 → luminary_memory-0.2.2}/website/js/luminary.js +0 -0
@@ -42,4 +42,3 @@ jobs:
42
42
  uses: softprops/action-gh-release@v2
43
43
  with:
44
44
  files: skill_asset/luminary-memory-skill.zip
45
- generate_release_notes: true
@@ -102,3 +102,6 @@ docs/api/
102
102
  website/screenshot_*.png
103
103
  website/test_*.png
104
104
  website/*.png
105
+
106
+ # ---- Internal plan files ----
107
+ website/plan.md
@@ -2,7 +2,23 @@
2
2
 
3
3
  All notable changes to this project are documented in this file. The format follows [Keep a Changelog](https://keepachangelog.com/), and the project adheres to [Semantic Versioning](https://semver.org/).
4
4
 
5
- ## [0.2.1] - Unreleased
5
+ ## [0.2.2] - 2026-08-18
6
+
7
+ ### Added
8
+
9
+ - **LLM memory curation** — with `ingest_llm: true`, the provider's enricher evaluates every retained turn:
10
+ - `worth_saving` — chit-chat, greetings, and trivial turns are **dropped** instead of polluting the store.
11
+ - `summary` — kept turns are stored as concise factual summaries (e.g. `"Deploy target is the staging cluster."`) instead of raw `User: ... / Assistant: ...` transcripts.
12
+ - `entities` / `tags` — attached for richer recall.
13
+ - **Transparency log** — provider writes `$HERMES_HOME/luminary/luminary.log` recording initialize/recall/retain/errors.
14
+ - **`OpenAICompatibleEnricher` User-Agent header** — required by some OpenAI-compatible gateways (e.g. Command Code 403s without it).
15
+
16
+ ### Fixed
17
+
18
+ - **Shutdown SQLite thread-affinity crash** — the writer thread now closes its own client (closing from the main thread raised `sqlite3.ProgrammingError`).
19
+ - **Hermes installer** — `hermes/install.sh` gains `--llm` (enables memory curation), handles a missing `config.yaml`, and no longer warns about the missing `[hermes]` extra (now declared).
20
+
21
+ ## [0.2.1] - 2026-08-18
6
22
 
7
23
  ### Added
8
24
 
@@ -18,6 +34,18 @@ All notable changes to this project are documented in this file. The format foll
18
34
  - **Test harness** — `tests/hermes_stubs/agent/memory_provider.py` ABC stub injected via `tests/conftest.py` so tests run without a hermes-agent install.
19
35
  - **`MemoryClient.ingest(metadata=...)`** — optional metadata dict merged into stored memory metadata (backward compatible).
20
36
 
37
+ ### Performance (identical results, no approximation)
38
+
39
+ - **Vectorized cosine similarity** — per-row numpy loop → single matmul; recall @ 5k memories **3,400 ms → 832 ms (4.1×)**.
40
+ - **SQL graph aggregation** — 210k relation rows → `SUM/COUNT ... GROUP BY` in the database.
41
+ - **`temporal_scan()`** — temporal recall fetches only `(id, created_at, access_count)`; **486 ms → 62 ms (7.8×)**.
42
+ - **Relation cap (8/memory) + indexes** — dense graph (280k rows) → sparse (80k); store 3.5× smaller; ingest 1.6× faster.
43
+
44
+ ### Fixed
45
+
46
+ - `config_schema.py` import fallback — module now imports standalone (no hermes runtime) so CI is green on 3.11/3.12.
47
+ - Publish workflow — skill zip moved out of `dist/` (invalid distribution); dropped `generate_release_notes` (permission).
48
+
21
49
  ## [0.2.0] - 2026-08-18
22
50
 
23
51
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: luminary-memory
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A lightweight, self-hosted memory layer for AI agents
5
5
  Project-URL: Homepage, https://github.com/alertxsto/luminary-memory
6
6
  Project-URL: Repository, https://github.com/alertxsto/luminary-memory
@@ -29,6 +29,7 @@ Requires-Dist: pdoc>=14; extra == 'dev'
29
29
  Requires-Dist: pytest-cov>=5.0; extra == 'dev'
30
30
  Requires-Dist: pytest>=8.0; extra == 'dev'
31
31
  Requires-Dist: ruff>=0.4; extra == 'dev'
32
+ Provides-Extra: hermes
32
33
  Description-Content-Type: text/markdown
33
34
 
34
35
  <div align="center">
@@ -41,8 +42,8 @@ Description-Content-Type: text/markdown
41
42
  [![Python](https://img.shields.io/pypi/pyversions/luminary-memory?color=8ab4e8&logo=python&logoColor=white)](https://pypi.org/project/luminary-memory)
42
43
  [![License](https://img.shields.io/github/license/alertxsto/luminary-memory?color=8ab4e8)](https://github.com/alertxsto/luminary-memory/blob/main/LICENSE)
43
44
  [![CI](https://img.shields.io/github/actions/workflow/status/alertxsto/luminary-memory/ci.yml?color=8ab4e8&label=CI&logo=github)](https://github.com/alertxsto/luminary-memory/actions)
44
- [![Tests](https://img.shields.io/badge/tests-101%20passing-8ab4e8)](https://github.com/alertxsto/luminary-memory/actions)
45
- [![Coverage](https://img.shields.io/badge/coverage-89%25-8ab4e8)](https://github.com/alertxsto/luminary-memory)
45
+ [![Tests](https://img.shields.io/badge/tests-168%20passing-8ab4e8)](https://github.com/alertxsto/luminary-memory/actions)
46
+ [![Coverage](https://img.shields.io/badge/coverage-85%25-8ab4e8)](https://github.com/alertxsto/luminary-memory)
46
47
  [![Stars](https://img.shields.io/github/stars/alertxsto/luminary-memory?color=8ab4e8&logo=github)](https://github.com/alertxsto/luminary-memory)
47
48
 
48
49
  **Self-hosted · Private · Budget-aware · Self-maintaining**
@@ -68,6 +69,40 @@ Agents are only as good as what they remember. A stateless agent re-learns the s
68
69
 
69
70
  ---
70
71
 
72
+ ## Hermes Agent — first-class memory provider
73
+
74
+ luminary-memory ships a native **Hermes Agent memory provider** (`luminary-memory[hermes]`): drop-in, auto-recall every turn, auto-save every session — with **zero LLM tokens per turn**.
75
+
76
+ ```bash
77
+ pip install "luminary-memory[hermes]"
78
+ ```
79
+
80
+ Enable it in your Hermes `config.yaml`:
81
+
82
+ ```yaml
83
+ memory:
84
+ provider: luminary
85
+ ```
86
+
87
+ That's it. From the next session:
88
+
89
+ - 🌙 **Auto-recall** — relevant memories are retrieved in the background and injected into agent context every turn
90
+ - 💾 **Auto-save** — completed turns are persisted automatically; session boundaries flush buffered turns
91
+ - 🛠️ **Explicit tools** — the model can call `luminary_recall` / `luminary_ingest` / `luminary_list` on demand
92
+ - 📋 **Deterministic indicator** — a `🌙 Luminary — recalled N memories` status line surfaces memory use
93
+
94
+ Registers via the standard `hermes_agent.memory_providers` entry point — no Hermes source changes, no cloud, no LLM API keys. See `docs/hermes-integration.md` for the full configuration table.
95
+
96
+ **LLM memory curation (optional):** set `ingest_llm: true` in
97
+ `~/.hermes/luminary/config.json` (plus `llm_base_url` / `llm_model` /
98
+ `llm_api_key`) to have the provider evaluate every turn before saving —
99
+ chit-chat and trivial turns are dropped, and kept turns are stored as concise
100
+ factual summaries (e.g. `"Deploy target is the staging cluster."`) instead of
101
+ raw `User: ... / Assistant: ...` transcripts. One small LLM call per retained
102
+ turn; any OpenAI-compatible endpoint works.
103
+
104
+ ---
105
+
71
106
  ## Quickstart
72
107
 
73
108
  ### Install
@@ -8,8 +8,8 @@
8
8
  [![Python](https://img.shields.io/pypi/pyversions/luminary-memory?color=8ab4e8&logo=python&logoColor=white)](https://pypi.org/project/luminary-memory)
9
9
  [![License](https://img.shields.io/github/license/alertxsto/luminary-memory?color=8ab4e8)](https://github.com/alertxsto/luminary-memory/blob/main/LICENSE)
10
10
  [![CI](https://img.shields.io/github/actions/workflow/status/alertxsto/luminary-memory/ci.yml?color=8ab4e8&label=CI&logo=github)](https://github.com/alertxsto/luminary-memory/actions)
11
- [![Tests](https://img.shields.io/badge/tests-101%20passing-8ab4e8)](https://github.com/alertxsto/luminary-memory/actions)
12
- [![Coverage](https://img.shields.io/badge/coverage-89%25-8ab4e8)](https://github.com/alertxsto/luminary-memory)
11
+ [![Tests](https://img.shields.io/badge/tests-168%20passing-8ab4e8)](https://github.com/alertxsto/luminary-memory/actions)
12
+ [![Coverage](https://img.shields.io/badge/coverage-85%25-8ab4e8)](https://github.com/alertxsto/luminary-memory)
13
13
  [![Stars](https://img.shields.io/github/stars/alertxsto/luminary-memory?color=8ab4e8&logo=github)](https://github.com/alertxsto/luminary-memory)
14
14
 
15
15
  **Self-hosted · Private · Budget-aware · Self-maintaining**
@@ -35,6 +35,40 @@ Agents are only as good as what they remember. A stateless agent re-learns the s
35
35
 
36
36
  ---
37
37
 
38
+ ## Hermes Agent — first-class memory provider
39
+
40
+ luminary-memory ships a native **Hermes Agent memory provider** (`luminary-memory[hermes]`): drop-in, auto-recall every turn, auto-save every session — with **zero LLM tokens per turn**.
41
+
42
+ ```bash
43
+ pip install "luminary-memory[hermes]"
44
+ ```
45
+
46
+ Enable it in your Hermes `config.yaml`:
47
+
48
+ ```yaml
49
+ memory:
50
+ provider: luminary
51
+ ```
52
+
53
+ That's it. From the next session:
54
+
55
+ - 🌙 **Auto-recall** — relevant memories are retrieved in the background and injected into agent context every turn
56
+ - 💾 **Auto-save** — completed turns are persisted automatically; session boundaries flush buffered turns
57
+ - 🛠️ **Explicit tools** — the model can call `luminary_recall` / `luminary_ingest` / `luminary_list` on demand
58
+ - 📋 **Deterministic indicator** — a `🌙 Luminary — recalled N memories` status line surfaces memory use
59
+
60
+ Registers via the standard `hermes_agent.memory_providers` entry point — no Hermes source changes, no cloud, no LLM API keys. See `docs/hermes-integration.md` for the full configuration table.
61
+
62
+ **LLM memory curation (optional):** set `ingest_llm: true` in
63
+ `~/.hermes/luminary/config.json` (plus `llm_base_url` / `llm_model` /
64
+ `llm_api_key`) to have the provider evaluate every turn before saving —
65
+ chit-chat and trivial turns are dropped, and kept turns are stored as concise
66
+ factual summaries (e.g. `"Deploy target is the staging cluster."`) instead of
67
+ raw `User: ... / Assistant: ...` transcripts. One small LLM call per retained
68
+ turn; any OpenAI-compatible endpoint works.
69
+
70
+ ---
71
+
38
72
  ## Quickstart
39
73
 
40
74
  ### Install
@@ -121,17 +121,18 @@ Post-MVP audit hardening.
121
121
 
122
122
  ---
123
123
 
124
- ### v0.2.1 — Hermes Memory Provider
124
+ ### v0.2.1 — Hermes Memory Provider ✅ released
125
125
 
126
126
  **Goal:** Luminary becomes a first-class Hermes memory provider — auto-recall every turn, auto-save every session, matching (and beating) Hindsight's integration with a fraction of the resources.
127
127
 
128
- - [ ] Implement `MemoryProvider` ABC as a Hermes plugin (`plugins/memory/luminary/`)
129
- - [ ] `prefetch()` / `queue_prefetch()` — auto-recall into agent context each turn
130
- - [ ] `on_session_end()` — auto-save conversation turns
131
- - [ ] `get_tool_schemas()` — expose `luminary_recall` / `luminary_ingest` tools
132
- - [ ] `system_prompt_block()` — provider context injection
133
- - [ ] Register provider: `memory.provider = luminary`
134
- - [ ] Benchmark vs Hindsight: resource usage, recall latency, recall quality
128
+ - [x] Implement `MemoryProvider` ABC as a standalone pip entry-point provider (`luminary_memory.hermes`)
129
+ - [x] `prefetch()` / `queue_prefetch()` — auto-recall into agent context each turn
130
+ - [x] `on_session_end()` — auto-save conversation turns (buffered `sync_turn`, session-boundary flush)
131
+ - [x] `get_tool_schemas()` — expose `luminary_recall` / `luminary_ingest` / `luminary_list` tools
132
+ - [x] `system_prompt_block()` — provider context injection
133
+ - [x] Register provider: `memory.provider = luminary`
134
+ - [x] Benchmark — 230 ms recall p50 @ 5k, 179 MB RSS, **0 LLM tokens** (see `benchmarks/RESULTS.md`)
135
+ - [x] Performance: recall 4.1× faster, temporal 7.8×, graph store 3.5× smaller
135
136
 
136
137
  ---
137
138
 
@@ -42,14 +42,35 @@ The provider reads `$HERMES_HOME/luminary/config.json` (created on first save wi
42
42
  | `recall_sync` | `false` | Synchronous (live) recall instead of warm prefetch |
43
43
  | `auto_retain` | `true` | Enable per-turn auto-save |
44
44
  | `retain_every_n_turns` | `1` | Batch N turns into one store write |
45
- | `ingest_llm` | `false` | Opt-in LLM enrichment on retain |
45
+ | `ingest_llm` | `false` | **LLM memory curation on retain** — the enricher decides whether a turn is worth saving (drops chit-chat) and stores a factual summary instead of the raw transcript |
46
+ | `llm_base_url` | `""` | OpenAI-compatible endpoint for the enricher (e.g. `https://api.commandcode.ai/provider/v1`) |
47
+ | `llm_model` | `""` | Enricher model (e.g. `deepseek/deepseek-v4-flash`) |
48
+ | `llm_api_key` | `""` | Enricher API key |
49
+ | `llm_timeout` | `60` | Enricher request timeout (seconds) |
50
+ | `recall_indicator` | `true` | Show `🌙 Luminary — recalled N memories` |
51
+ | `retain_indicator` | `true` | Show `🌙 Luminary — memory saved` |
52
+
53
+ ### LLM memory curation (v0.2.2+)
54
+
55
+ With `ingest_llm: true`, every retained turn is sent to the enricher, which
56
+ returns:
57
+
58
+ - **`worth_saving`** — `false` drops the turn entirely (chit-chat, greetings,
59
+ trivial acknowledgements never reach the store).
60
+ - **`summary`** — a concise factual summary in the turn's language that
61
+ becomes the stored content, instead of the raw `User: ... / Assistant: ...`
62
+ transcript.
63
+ - **`entities` / `tags`** — attached as metadata/tags for richer recall.
64
+
65
+ Without `ingest_llm` (default), turns are stored verbatim — zero LLM cost.
46
66
 
47
67
  ### Store layout
48
68
 
49
69
  ```
50
70
  $HERMES_HOME/luminary/
51
71
  ├── config.json # provider config — 0600
52
- └── memory.db # SQLite store (created by MemoryClient)
72
+ ├── memory.db # SQLite store (created by MemoryClient)
73
+ └── luminary.log # transparency log (initialize/recall/retain/errors)
53
74
  ```
54
75
 
55
76
  The store is profile-scoped and picked up by `hermes backup` automatically. If you
@@ -11,6 +11,7 @@ A lightweight, self-hosted memory layer for AI agents.
11
11
  ## Key features
12
12
 
13
13
  - Four retrieval strategies fused into one ranked recall (semantic, keyword, temporal, graph).
14
+ - **First-class Hermes Agent memory provider** — auto-recall every turn, auto-save every session, zero LLM tokens per turn (`memory.provider: luminary`).
14
15
  - SQLite out of the box, optional pgvector for scale.
15
16
  - Local CPU embeddings via ONNX — no GPU, no cloud.
16
17
  - Configurable token budget so memory never overflows the agent's context.
@@ -0,0 +1,104 @@
1
+ # luminary-memory — Hermes integration
2
+
3
+ One-shot installer for using luminary-memory as a first-class Hermes Agent
4
+ memory provider: auto-recall every turn, auto-save every session, zero LLM
5
+ tokens per turn — plus an optional chat-activity hook and a skill.
6
+
7
+ ## Quick install
8
+
9
+ ```bash
10
+ git clone https://github.com/alertxsto/luminary-memory.git
11
+ cd luminary-memory
12
+ bash hermes/install.sh
13
+ ```
14
+
15
+ That installs everything:
16
+
17
+ | Component | What it does |
18
+ |-----------|--------------|
19
+ | **Provider** | `pip install luminary-memory[hermes]` + `memory.provider: luminary` in Hermes config |
20
+ | **Hook** | `luminary-activity` — posts `🌙 Luminary — N memories recalled/stored` to chat |
21
+ | **Skill** | `luminary-memory` skill for agent use |
22
+
23
+ Then restart your gateway:
24
+
25
+ ```bash
26
+ bash ~/.hermes/scripts/restart-bots.sh
27
+ ```
28
+
29
+ ## Installer options
30
+
31
+ ```bash
32
+ bash hermes/install.sh --hook # hook only
33
+ bash hermes/install.sh --skill # skill only
34
+ bash hermes/install.sh --llm # also enable LLM memory curation (ingest_llm)
35
+ bash hermes/install.sh --no-hook --no-skill # provider only
36
+ ```
37
+
38
+ ## LLM memory curation (optional but recommended)
39
+
40
+ By default the provider stores every turn verbatim (zero LLM cost). With LLM
41
+ curation enabled, an enricher evaluates each turn and:
42
+
43
+ - **Drops chit-chat** — greetings, "ok", trivial acknowledgements never reach
44
+ the store (`worth_saving: false`).
45
+ - **Stores factual summaries** — kept turns are saved as concise facts (e.g.
46
+ `"Deploy target is the staging cluster."`) instead of raw transcripts.
47
+
48
+ Enable it (after `bash hermes/install.sh --llm`, edit
49
+ `~/.hermes/luminary/config.json`):
50
+
51
+ ```json
52
+ {
53
+ "ingest_llm": true,
54
+ "llm_base_url": "https://api.commandcode.ai/provider/v1",
55
+ "llm_model": "deepseek/deepseek-v4-flash",
56
+ "llm_api_key": "<your key>"
57
+ }
58
+ ```
59
+
60
+ Any OpenAI-compatible endpoint works. Costs one small LLM call per retained
61
+ turn (temperature 0, strict JSON). If the enricher fails, the provider falls
62
+ back to storing the turn verbatim — it never blocks.
63
+
64
+ ## Manual install (no script)
65
+
66
+ ```bash
67
+ pip install "luminary-memory[hermes]>=0.2.1"
68
+
69
+ # config.yaml — add under memory:
70
+ # provider: luminary
71
+
72
+ # hook
73
+ mkdir -p ~/.hermes/hooks/luminary-activity
74
+ cp hermes/hooks/luminary-activity/handler.py ~/.hermes/hooks/luminary-activity/
75
+ cp hermes/hooks/luminary-activity/HOOK.yaml ~/.hermes/hooks/luminary-activity/
76
+
77
+ # skill
78
+ mkdir -p ~/.hermes/skills/luminary-memory
79
+ cp hermes/SKILL.md ~/.hermes/skills/luminary-memory/SKILL.md
80
+ ```
81
+
82
+ ## What you get
83
+
84
+ - 🌙 **Auto-recall** — relevant memories retrieved in the background and
85
+ injected into agent context every turn.
86
+ - 💾 **Auto-save** — completed turns persisted automatically; session
87
+ boundaries flush buffered turns.
88
+ - 🛠️ **Explicit tools** — `luminary_recall` / `luminary_ingest` /
89
+ `luminary_list` on demand.
90
+ - 📋 **Deterministic indicator** — `🌙 Luminary — recalled N memories` in the
91
+ agent UI.
92
+ - 🔔 **Chat activity hook** — optional mirror of store activity to your chat.
93
+ - 🧠 **Skill** — agent-side guidance for store usage.
94
+ - 📜 **Transparency log** — `~/.hermes/luminary/luminary.log` records every
95
+ recall, retain, and error (initialize/recall/retain lines), so you can see
96
+ exactly what the provider is doing and whether anything failed.
97
+
98
+ ## Requirements
99
+
100
+ - Python 3.11+ (Hermes venv recommended)
101
+ - Hermes Agent with `memory.provider` support (external providers)
102
+
103
+ See `docs/hermes-integration.md` in the repo root for the full configuration
104
+ table and the legacy standalone-skill path.
@@ -0,0 +1,171 @@
1
+ ---
2
+ name: luminary-memory
3
+ description: "Use luminary-memory for agent memory: auto-recall context, auto-save turns, explicit recall/ingest/list tools, config tweaks."
4
+ version: 2.0.0
5
+ author: Dwiky Candra
6
+ license: Apache-2.0
7
+ platforms: [linux, macos, windows]
8
+ metadata:
9
+ hermes:
10
+ tags: [memory, recall, self-hosted, sqlite, pgvector, provider]
11
+ ---
12
+
13
+ # luminary-memory (Hermes integration)
14
+
15
+ **luminary-memory** is a self-hosted memory layer that plugs into Hermes as a
16
+ first-class memory provider. It gives agents durable cross-session memory:
17
+ auto-recall relevant context every turn, auto-save completed turns, and
18
+ explicit tools for on-demand memory access — all local, zero LLM tokens.
19
+
20
+ **What your agent remembers is what it becomes.**
21
+
22
+ ## When to Use
23
+
24
+ - **Recall context** — when the current task depends on things said or done in
25
+ earlier sessions (preferences, decisions, environment details, past fixes).
26
+ - **Store durable facts** — after learning something that will matter later
27
+ (a user preference, a project convention, a config decision).
28
+ - **Inspect the store** — list what luminary currently remembers, or check
29
+ whether a fact is already known before storing it again.
30
+ - **Troubleshoot** — when memory seems stale or missing, check the store and
31
+ the transparency log.
32
+
33
+ ## How It Works (3 ways to interact)
34
+
35
+ | Path | When | Trigger |
36
+ |------|------|---------|
37
+ | **Auto-recall** | Every turn | `memory.provider: luminary` — background recall injected into context (🌙 indicator) |
38
+ | **Auto-retain** | After each turn | provider saves `User: ... / Assistant: ...` to the store |
39
+ | **Explicit tools** | On demand | `luminary_recall` / `luminary_ingest` / `luminary_list` |
40
+
41
+ ## Agent Usage — Explicit Tools
42
+
43
+ ### Recall relevant memories
44
+
45
+ ```python
46
+ # when the task needs earlier context
47
+ result = client.recall("what deploy target do we use?", limit=5)
48
+ for memory, score in zip(result.memories, result.scores):
49
+ print(f"[{score:.2f}] {memory.content}")
50
+ ```
51
+
52
+ Prefer the injected auto-recall context when present; use the tool when you
53
+ need a targeted query the auto-recall didn't cover.
54
+
55
+ ### Store a durable fact
56
+
57
+ ```python
58
+ # after learning something that will matter across sessions
59
+ client.ingest(
60
+ "The deploy target is the staging cluster",
61
+ tags=["deploy", "infra"],
62
+ source="hermes",
63
+ )
64
+ ```
65
+
66
+ Good candidates: user preferences, project conventions, environment details,
67
+ decisions with reasons. Skip: one-off trivia, content already in context that
68
+ will not matter later.
69
+
70
+ ### List what's stored
71
+
72
+ ```python
73
+ client.list(limit=20) # most recent first
74
+ ```
75
+
76
+ Use this before re-ingesting — if a fact is already stored, update instead of
77
+ duplicating.
78
+
79
+ ## Configuration — Tweaks
80
+
81
+ Provider config lives in `~/.hermes/luminary/config.json` (auto-created,
82
+ 0600 perms). Defaults work out of the box; tweak only what you need.
83
+
84
+ | Key | Default | What it does |
85
+ |-----|---------|--------------|
86
+ | `mode` | `hybrid` | `context` (auto-inject only) · `tools` (tools only) · `hybrid` (both) |
87
+ | `auto_recall` | `true` | Auto-recall every turn (background) |
88
+ | `recall_sync` | `false` | `true` = recall synchronously against the current message (higher relevance, adds latency) |
89
+ | `recall_limit` | `10` | Max memories injected per recall |
90
+ | `token_budget` | `2048` | Max tokens of injected memory |
91
+ | `auto_retain` | `true` | Auto-save turns to the store |
92
+ | `retain_every_n_turns` | `1` | Save every N turns (higher = fewer, batched saves) |
93
+ | `ingest_llm` | `false` | **LLM memory curation** — drops chit-chat, stores factual summary instead of raw transcript |
94
+ | `llm_base_url` / `llm_model` / `llm_api_key` | `""` | OpenAI-compatible enricher endpoint/model/key |
95
+ | `recall_indicator` | `true` | Show `🌙 Luminary — recalled N memories` |
96
+ | `retain_indicator` | `true` | Show `🌙 Luminary — memory saved` |
97
+ | `backend` | `sqlite` | `sqlite` (zero config) or `pgvector` (scale) |
98
+
99
+ **LLM memory curation:** with `ingest_llm: true`, the enricher evaluates each
100
+ turn and keeps only durable facts — greetings, chit-chat, and trivial
101
+ acknowledgements are dropped, and kept turns are stored as concise factual
102
+ summaries (e.g. `"Deploy target is the staging cluster."`) instead of raw
103
+ `User: ... / Assistant: ...` transcripts. Without it (default), turns are
104
+ stored verbatim with zero LLM cost.
105
+
106
+ Example — save less often, no indicators:
107
+
108
+ ```json
109
+ {
110
+ "retain_every_n_turns": 5,
111
+ "recall_indicator": false,
112
+ "retain_indicator": false
113
+ }
114
+ ```
115
+
116
+ ### Env vars
117
+
118
+ | Var | Purpose |
119
+ |-----|---------|
120
+ | `LUMINARY_BACKEND` | `sqlite` / `pgvector` |
121
+ | `LUMINARY_EMBEDDING_MODEL` | ONNX model (default `BAAI/bge-small-en-v1.5`) |
122
+ | `LUMINARY_HOOK_CHAT_ID` | Chat for the activity hook (defaults to home channel) |
123
+ | `LUMINARY_DB_PATH` | Override store location (hook) |
124
+
125
+ ## Transparency Log
126
+
127
+ `~/.hermes/luminary/luminary.log` records every recall, retain, and error:
128
+
129
+ ```
130
+ 2026-08-18 04:26:37 INFO initialize session=... platform=telegram agent=default
131
+ 2026-08-18 04:26:40 INFO recall query='deploy target' limit=10 -> 5 memories (142ms)
132
+ 2026-08-18 04:26:45 INFO retain stored len=312 tags=['session:...', 'platform:telegram']
133
+ ```
134
+
135
+ Check this first when memory seems wrong or missing.
136
+
137
+ ## Troubleshooting
138
+
139
+ | Symptom | Cause / Fix |
140
+ |---------|-------------|
141
+ | No 🌙 indicator | `recall_indicator` off, or store empty, or provider not active (`hermes memory status`) |
142
+ | Recall returns nothing | Store empty; or `auto_recall` / mode `tools` disables auto-injection (use the tool) |
143
+ | Turns not saved | `auto_retain` off, or `retain_every_n_turns` batching — wait N turns |
144
+ | Slow first recall | ONNX model loads on first use (one-time cost) |
145
+ | Errors | Check `~/.hermes/luminary/luminary.log` |
146
+
147
+ ## Install
148
+
149
+ ### One-shot (recommended)
150
+
151
+ ```bash
152
+ git clone https://github.com/alertxsto/luminary-memory.git
153
+ cd luminary-memory && bash hermes/install.sh
154
+ bash ~/.hermes/scripts/restart-bots.sh
155
+ ```
156
+
157
+ ### Manual
158
+
159
+ ```bash
160
+ pip install "luminary-memory[hermes]>=0.2.1"
161
+ # config.yaml → memory: provider: luminary
162
+ mkdir -p ~/.hermes/hooks/luminary-activity
163
+ cp hermes/hooks/luminary-activity/*.py hermes/hooks/luminary-activity/HOOK.yaml ~/.hermes/hooks/luminary-activity/
164
+ mkdir -p ~/.hermes/skills/luminary-memory && cp hermes/SKILL.md ~/.hermes/skills/luminary-memory/
165
+ ```
166
+
167
+ ## Notes
168
+
169
+ - Default backend SQLite (zero config); pgvector via `LUMINARY_BACKEND=pgvector`.
170
+ - Recall runs four strategies (semantic, keyword, temporal, graph) fused by RRF.
171
+ - The store is local; no data leaves the machine. Zero LLM tokens per turn.
@@ -0,0 +1,4 @@
1
+ name: luminary-activity
2
+ description: Surface luminary-memory activity (recalls, stores) to the chat as a compact status line
3
+ events:
4
+ - agent:end
@@ -0,0 +1,47 @@
1
+ # Luminary Activity Hook
2
+
3
+ Surfaces what luminary-memory is doing — recalls, stores, lifecycle — as a
4
+ compact status line in your chat, so you can *see* the memory layer working.
5
+
6
+ ```
7
+ 🌙 Luminary — 12 memories recalled
8
+ 🌙 Luminary — 3 memories stored
9
+ ```
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ # 1. copy the hook into your Hermes hooks directory
15
+ mkdir -p ~/.hermes/hooks/luminary-activity
16
+ cp hermes/hooks/luminary-activity/handler.py ~/.hermes/hooks/luminary-activity/
17
+ cp hermes/hooks/luminary-activity/HOOK.yaml ~/.hermes/hooks/luminary-activity/
18
+
19
+ # 2. env vars (in ~/.hermes/.env)
20
+ echo "LUMINARY_HOOK_CHAT_ID=<your chat id>" >> ~/.hermes/.env
21
+ # TELEGRAM_BOT_TOKEN + TELEGRAM_HOME_CHANNEL are usually already set
22
+
23
+ # 3. restart your Hermes gateway
24
+ bash ~/.hermes/scripts/restart-bots.sh
25
+ ```
26
+
27
+ ## What it shows
28
+
29
+ - **agent:end** — after a turn, if the luminary store was touched in the last
30
+ 30s (a recall updated access timestamps, or an ingest added a memory), a
31
+ one-line status is posted.
32
+
33
+ ## Configuration (env vars)
34
+
35
+ | Var | Default | Description |
36
+ |-----|---------|-------------|
37
+ | `LUMINARY_HOOK_CHAT_ID` | `TELEGRAM_HOME_CHANNEL` | Chat to post activity to |
38
+ | `LUMINARY_DB_PATH` | `~/.hermes/luminary/memory.db` | Luminary store to watch |
39
+
40
+ ## Notes
41
+
42
+ - **Non-blocking** — hooks never block the agent; failures are logged to
43
+ `~/.hermes/hooks/luminary-activity/hook.log` and swallowed.
44
+ - **Quiet by default** — only posts when the store was actually active.
45
+ - The provider's built-in indicators (`recall_indicator`, `retain_indicator`,
46
+ `recall_status()`) already surface a `🌙` status line in the agent UI; this
47
+ hook is the opt-in *chat* mirror for group/DM workflows.