@psiclawops/hypermem 0.7.0 → 0.8.1

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 (79) hide show
  1. package/ARCHITECTURE.md +30 -38
  2. package/README.md +83 -35
  3. package/dist/background-indexer.d.ts +14 -3
  4. package/dist/background-indexer.d.ts.map +1 -1
  5. package/dist/background-indexer.js +126 -18
  6. package/dist/budget-policy.d.ts +22 -0
  7. package/dist/budget-policy.d.ts.map +1 -0
  8. package/dist/budget-policy.js +27 -0
  9. package/dist/cache.d.ts +11 -0
  10. package/dist/cache.d.ts.map +1 -1
  11. package/dist/compositor-utils.d.ts +31 -0
  12. package/dist/compositor-utils.d.ts.map +1 -0
  13. package/dist/compositor-utils.js +47 -0
  14. package/dist/compositor.d.ts +163 -1
  15. package/dist/compositor.d.ts.map +1 -1
  16. package/dist/compositor.js +862 -130
  17. package/dist/content-hash.d.ts +43 -0
  18. package/dist/content-hash.d.ts.map +1 -0
  19. package/dist/content-hash.js +75 -0
  20. package/dist/context-store.d.ts +54 -0
  21. package/dist/context-store.d.ts.map +1 -1
  22. package/dist/context-store.js +102 -0
  23. package/dist/contradiction-audit-store.d.ts +54 -0
  24. package/dist/contradiction-audit-store.d.ts.map +1 -0
  25. package/dist/contradiction-audit-store.js +88 -0
  26. package/dist/contradiction-resolution-policy.d.ts +21 -0
  27. package/dist/contradiction-resolution-policy.d.ts.map +1 -0
  28. package/dist/contradiction-resolution-policy.js +17 -0
  29. package/dist/degradation.d.ts +102 -0
  30. package/dist/degradation.d.ts.map +1 -0
  31. package/dist/degradation.js +141 -0
  32. package/dist/dreaming-promoter.d.ts +38 -0
  33. package/dist/dreaming-promoter.d.ts.map +1 -1
  34. package/dist/dreaming-promoter.js +68 -2
  35. package/dist/index.d.ts +68 -6
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +402 -26
  38. package/dist/knowledge-lint.d.ts +2 -0
  39. package/dist/knowledge-lint.d.ts.map +1 -1
  40. package/dist/knowledge-lint.js +40 -1
  41. package/dist/library-schema.d.ts +7 -2
  42. package/dist/library-schema.d.ts.map +1 -1
  43. package/dist/library-schema.js +236 -1
  44. package/dist/message-store.d.ts +64 -1
  45. package/dist/message-store.d.ts.map +1 -1
  46. package/dist/message-store.js +137 -1
  47. package/dist/open-domain.js +1 -1
  48. package/dist/proactive-pass.d.ts +2 -2
  49. package/dist/proactive-pass.d.ts.map +1 -1
  50. package/dist/proactive-pass.js +66 -12
  51. package/dist/replay-recovery.d.ts +29 -0
  52. package/dist/replay-recovery.d.ts.map +1 -0
  53. package/dist/replay-recovery.js +82 -0
  54. package/dist/reranker.d.ts +95 -0
  55. package/dist/reranker.d.ts.map +1 -0
  56. package/dist/reranker.js +308 -0
  57. package/dist/schema.d.ts +1 -1
  58. package/dist/schema.d.ts.map +1 -1
  59. package/dist/schema.js +46 -1
  60. package/dist/session-flusher.d.ts +2 -2
  61. package/dist/session-flusher.d.ts.map +1 -1
  62. package/dist/session-flusher.js +1 -1
  63. package/dist/temporal-store.js +2 -2
  64. package/dist/tool-artifact-store.d.ts +98 -0
  65. package/dist/tool-artifact-store.d.ts.map +1 -0
  66. package/dist/tool-artifact-store.js +244 -0
  67. package/dist/topic-detector.js +2 -2
  68. package/dist/topic-store.d.ts +6 -0
  69. package/dist/topic-store.d.ts.map +1 -1
  70. package/dist/topic-store.js +39 -0
  71. package/dist/types.d.ts +233 -1
  72. package/dist/types.d.ts.map +1 -1
  73. package/dist/vector-store.d.ts +2 -1
  74. package/dist/vector-store.d.ts.map +1 -1
  75. package/dist/vector-store.js +3 -0
  76. package/dist/version.d.ts +10 -10
  77. package/dist/version.d.ts.map +1 -1
  78. package/dist/version.js +10 -10
  79. package/package.json +6 -4
package/ARCHITECTURE.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # hypermem Architecture
2
2
 
3
- _Agent-centric memory that outlives sessions._
3
+ _Agent-centric memory that outlives sessions, backed by SQLite memory databases._
4
4
 
5
5
  ---
6
6
 
7
7
  ## Memory Layers
8
8
 
9
9
  ```
10
- L1 Redis (Hot) Active session working memory
10
+ L1 SQLite Cache (Hot) Active session working memory
11
11
  │ Slots: system, identity, messages, facts, context
12
12
  │ Sub-millisecond reads, evicts on session end
13
13
  │ Fleet cache: agent profiles, fleet summary
@@ -28,9 +28,13 @@ L4 Library DB Fleet-wide structured knowledge
28
28
  Knowledge graph (DAG links between entities)
29
29
  ```
30
30
 
31
+ > Note: some internal method names and telemetry reasons still contain `redis`
32
+ > for backward compatibility. The runtime hot layer is SQLite `:memory:` cache,
33
+ > not an external Redis service.
34
+
31
35
  ## Database Schema
32
36
 
33
- ### messages.db (per agent, schema v3)
37
+ ### messages.db (per agent, schema v10)
34
38
  - `agent_meta` — agent metadata
35
39
  - `conversations` — session tracking
36
40
  - `messages` — raw message log (text, tool calls, tool results)
@@ -46,7 +50,7 @@ L4 Library DB Fleet-wide structured knowledge
46
50
  - `vec_index_map` — tracks what's been indexed (source_table, source_id, source_db)
47
51
  - `embedding_cache` — avoids redundant Ollama API calls
48
52
 
49
- ### library.db (shared, schema v5)
53
+ ### library.db (shared, schema v19)
50
54
  - `facts` — verifiable claims with confidence, domain, expiry, supersedes chains
51
55
  - `knowledge` — domain/key/value structured data
52
56
  - `knowledge_links` — DAG edges between entities (fact↔fact, fact↔knowledge, etc.)
@@ -70,7 +74,7 @@ Assembles LLM prompts from all four layers with token budgeting:
70
74
  ```
71
75
  User message arrives
72
76
 
73
- ├── L1 Redis: system prompt, identity, cached slots
77
+ ├── L1 Hot cache: system prompt, identity, cached slots
74
78
  ├── L2 Messages: recent conversation history (budget-truncated)
75
79
  ├── L3 Vectors: KNN semantic recall on user's latest message
76
80
  │ └── Related facts/knowledge/episodes with relevance scores
@@ -104,14 +108,14 @@ Compositor behavior is tuned via parameters tracked in `tune/TUNING_REGISTRY.md`
104
108
  - **Compaction fence:** Per-conversation boundary protecting the LLM's recent tail from compaction. Only moves forward (monotone progress). No fence = no compaction (explicit opt-in).
105
109
  - **Preservation gate:** Nomic-space geometric verification that summaries stay faithful to source content. Centroid alignment + source coverage → combined score (threshold: 0.65).
106
110
 
107
- ## Fleet Cache (Redis Hot Layer)
111
+ ## Fleet Cache (Hot Cache Layer)
108
112
 
109
113
  ```
110
114
  fleet:agent:{id} — Composite profile: registry + capabilities + desired state
111
115
  fleet:summary — Fleet-wide stats: agent count, drift count, tier breakdown
112
116
  ```
113
117
 
114
- - **Cache-aside** on reads: Redis first, SQLite fallback, warm on miss
118
+ - **Cache-aside** on reads: hot cache first, SQLite fallback, warm on miss
115
119
  - **Write-through invalidation** on fleet mutations
116
120
  - **Hydration** on gateway startup: bulk-populate from library.db
117
121
  - TTL: agent profiles 10min, summary 2min
@@ -148,7 +152,7 @@ Visibility-tiered access model for cross-agent knowledge queries:
148
152
 
149
153
  `visibilityFilter()` resolves access levels using an `OrgRegistry` — a mapping of agents to tiers, orgs, and capabilities. Currently loaded from a hardcoded `defaultOrgRegistry()` in `cross-agent.ts`.
150
154
 
151
- **Known limitation:** This duplicates fleet structure that lives authoritatively in `fleet_agents` + `fleet_orgs` in library.db. Near-term roadmap item: replace with live-loaded registry from library.db, with the hardcoded version as cold-start fallback only.
155
+ **Known limitation:** `defaultOrgRegistry()` duplicates fleet structure that lives authoritatively in `fleet_agents` + `fleet_orgs` in library.db. See [docs/ROADMAP.md](docs/ROADMAP.md) for the planned live-load migration.
152
156
 
153
157
  ### Unknown Agent Fallback (Restrictive Default)
154
158
 
@@ -164,10 +168,10 @@ This means:
164
168
  `plugin/src/index.ts` — OpenClaw context engine plugin (`hypercompositor`, fills `contextEngine` slot):
165
169
 
166
170
  ```
167
- gateway:startup → Init hypermem, auto-rotate DBs, hydrate fleet cache
168
- agent:bootstrap → Warm session (history, facts, profile → Redis)
171
+ gateway:startup → Init hypermem, auto-rotate DBs, seed fleet registry from workspace identities, hydrate fleet cache
172
+ agent:bootstrap → Warm session (history, facts, profile → hot cache)
169
173
  context:assemble → Full four-layer prompt assembly within token budget
170
- agent:afterTurn → Ingest new messages to SQLite + Redis, trigger background indexer
174
+ agent:afterTurn → Ingest new messages to SQLite + hot cache, trigger background indexer
171
175
  ```
172
176
 
173
177
  Registers with `ownsCompaction: true` — runtime skips legacy compaction entirely.
@@ -185,7 +189,7 @@ Registers with `ownsCompaction: true` — runtime skips legacy compaction entire
185
189
 
186
190
  ```
187
191
  ┌──────────────────────────────────────────────────┐
188
- REDIS (L1 Hot Layer)
192
+ HOT CACHE (SQLite :memory: CacheLayer)
189
193
  │ │
190
194
  │ hm:{a}:{s}:history ── Session archive (250 cap │
191
195
  │ (append-only) at bootstrap, 1000 soft │
@@ -210,34 +214,22 @@ Data Flow (current — P0 stabilized, window/cursor active):
210
214
  ▸ sessionExists() → skip if hot compose() slice(prePromptCount)
211
215
  ▸ SQLite ─→ warmSession() ─→ getHistory(limit) ✅ ─→ record*Message()
212
216
  ─→ pushHistory(250) ─→ dedup by id ─→ pushHistory(1, dedup)
213
- ─→ Redis :history ─→ budget assembly ─→ Redis :history
214
- ─→ write :window (120s) ─→ invalidateWindow()
215
- ─→ write :cursor (24h) ─→ background indexer
217
+ ─→ cache history ─→ budget assembly ─→ cache history
218
+ ─→ write window bundle ─→ invalidateWindow()
219
+ ─→ write cursor metadata ─→ background indexer
216
220
  ─→ → runtime → provider
217
221
 
218
222
  ### Key Invariants
219
223
 
220
- 1. Redis `history` is the warm archive. Append-only. Nothing reads it for direct submission.
221
- 2. Redis `window` is the compositor's output cache. Written ONLY by `compose()`. Read ONLY by `assemble()`. Invalidated by `afterTurn`.
222
- 3. Redis `cursor` tracks the newest message in the last window. Used by background indexer for high-signal mining.
224
+ 1. Hot-cache `history` is the warm archive. Append-only. Nothing reads it for direct submission.
225
+ 2. Hot-cache `window` is the compositor's output cache. Written ONLY by `compose()`. Read ONLY by `assemble()`. Invalidated by `afterTurn`.
226
+ 3. Hot-cache `cursor` tracks the newest message in the last window. Used by background indexer for high-signal mining.
223
227
  4. `warmSession()` seeds `history` only (capped at 250). Never writes `window`.
224
- 5. `pushHistory()` tail-checks before append (no duplicate IDs in Redis list).
228
+ 5. `pushHistory()` tail-checks before append (no duplicate IDs in the hot-cache history list).
225
229
  6. `compose()` deduplicates history by `id` before budget assembly.
226
- 7. `getHistory()` honors its `limit` parameter on BOTH Redis and SQLite paths.
227
-
228
- Design spec: `specs/HYPERMEM_QUEUE_SPLIT.md`
229
- Incident history: `specs/HYPERMEM_INCIDENT_HISTORY.md`
230
+ 7. `getHistory()` honors its `limit` parameter on BOTH hot-cache and SQLite paths.
230
231
 
231
- ### Open Items (Tracked)
232
-
233
- | Item | WQ | Status | Notes |
234
- |---|---|---|---|
235
- | Cross-session context boundary markers | WQ-20260402-001 | 🟡 OPEN | `buildCrossSessionContext()` renders flat previews, no per-message boundaries or sender identity. Incident 6. |
236
- | Cursor durability (SQLite dual-write) | — | 🟡 DEFERRED | Cursor TTL = 24h. Dual-write to SQLite required before background indexer reads cursor. Gate 2. |
237
- | Plugin type unification | — | 🟡 DEFERRED | Plugin uses dynamic imports; can't use TS types from core. Shims are intentional. Structural change needed. |
238
- | Strict topic mode: legacy NULL backfill | — | 🟡 DEFERRED | After ≥2 weeks of topic detection in production, run backfill to assign `topic_id` to legacy NULL messages, then narrow `getRecentMessagesByTopic()` to exclude NULL. Gate: topic detection must be stable and coverage >80% of new messages before narrowing. Tracked in `specs/DEFERRED.md`. |
239
- | ACA Step 4 — retrieval stubs replace static files | — | 🔲 PENDING | `systemPromptAddition` carries governance doc chunks instead of embedding full workspace files. Blocked on Step 3 ✅ |
240
- | ACA Step 5 — governance context assembly | — | 🔲 PENDING | Full on-demand assembly replaces static prompt injection. Requires Step 4. |
232
+ For open and deferred items, see [docs/ROADMAP.md](docs/ROADMAP.md).
241
233
 
242
234
  ### Runtime Contract
243
235
 
@@ -251,14 +243,14 @@ Incident history: `specs/HYPERMEM_INCIDENT_HISTORY.md`
251
243
  |---|---|---|---|
252
244
  | `index.ts` | ~1,340 | All | Facade — all public API |
253
245
  | `compositor.ts` | ~1,140 | L1-L4 | Prompt assembly + token budgeting + safety valve + window/cursor write |
254
- | `library-schema.ts` | ~780 | L4 | Library schema v5 + migrations |
246
+ | `library-schema.ts` | ~780 | L4 | Library schema v19 + migrations |
255
247
  | `background-indexer.ts` | ~680 | L2-L4 | LLM-powered extraction framework |
256
248
  | `vector-store.ts` | ~600 | L3 | Semantic search + embedding |
257
249
  | `hybrid-retrieval.ts` | ~450 | L3-L4 | FTS5 + KNN with Reciprocal Rank Fusion |
258
250
  | `fleet-store.ts` | ~440 | L4 | Fleet registry + capabilities |
259
251
  | `db.ts` | ~440 | - | Database manager + rotation |
260
252
  | `knowledge-graph.ts` | ~420 | L4 | DAG traversal + shortest path |
261
- | `redis.ts` | ~530 | L1 | Redis operations, window cache, cursor, fleet cache |
253
+ | `cache.ts` | ~700 | L1 | SQLite `:memory:` hot-cache operations, window cache, cursor, fleet cache |
262
254
  | `doc-chunker.ts` | ~400 | - | Section-aware markdown/file parser |
263
255
  | `work-store.ts` | ~400 | L4 | Work queue + FTS5 |
264
256
  | `provider-translator.ts` | ~390 | - | Neutral ↔ provider format conversion |
@@ -287,12 +279,12 @@ _Test count reflects assertions, not individual test blocks. Suites contain inli
287
279
  | Suite | Key coverage |
288
280
  |---|---|
289
281
  | smoke | End-to-end create/write/read/close, provider translation |
290
- | redis-integration | Redis ops, slots, history limits, window cache, cursor, warming, dedup |
282
+ | redis-integration | Legacy suite name, covers hot-cache ops, slots, history limits, window cache, cursor, warming, dedup |
291
283
  | cross-agent | Cross-agent queries, fleet search, visibility tiers |
292
284
  | vector-search | Embedding, KNN, batch indexing |
293
285
  | library | All L4 collections (facts → desired state) |
294
286
  | compositor | Four-layer composition, budgets, providers, safety valve, Gate 1 |
295
- | fleet-cache | Redis fleet cache, hydration, cache-aside |
287
+ | fleet-cache | Fleet hot-cache hydration and cache-aside behavior |
296
288
  | rotation | DB rotation, auto-rotate, collision handling |
297
289
  | knowledge-graph | DAG traversal, shortest path, analytics |
298
290
  | rate-limiter | Token bucket, priority, timeout, embedder |
@@ -301,6 +293,6 @@ _Test count reflects assertions, not individual test blocks. Suites contain inli
301
293
  ## Dependencies
302
294
 
303
295
  - `node:sqlite` (Node 22+ built-in) — zero-dependency SQLite
304
- - `ioredis`Redis client
296
+ - No external cache service dependency hot cache is SQLite `:memory:`
305
297
  - `sqlite-vec` — optional, vector search extension
306
298
  - Ollama (localhost:11434) — optional, embedding generation
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ---
8
8
 
9
- hypermem is a runtime context engine for OpenClaw agents.
9
+ hypermem is a SQLite-backed runtime context engine for OpenClaw agents.
10
10
 
11
11
  ```bash
12
12
  curl -fsSL https://raw.githubusercontent.com/PsiClawOps/hypermem/main/install.sh | bash
@@ -32,6 +32,8 @@ The difference isn't intelligence. It's what was in the prompt. Two failure mode
32
32
 
33
33
  **Compaction crunch.** Long sessions fill the context window. The runtime summarizes to make room. Specifics (tool output, exact decisions, file paths) are lost in the summary. The agent keeps running, but degraded.
34
34
 
35
+ **Bloated context.** 128k tokens doesn't mean 128k of useful prompt. Without active curation, agents fill the window with stale history, redundant instructions, and memory that isn't relevant to this turn. A bigger context window just means more room to waste. The information is in the prompt somewhere, buried under content irrelevant to this turn.
36
+
35
37
  ---
36
38
 
37
39
  ## What OpenClaw provides today
@@ -53,18 +55,18 @@ OpenClaw also ships compaction safeguards and hybrid file search. That's a solid
53
55
 
54
56
  ## hypermem
55
57
 
56
- Four storage layers, sub-millisecond retrieval, no external database services required. Runs in-process with local SQLite storage and local Nomic embeddings by default, with optional hosted embeddings for L3.
58
+ Four SQLite-backed memory databases, sub-millisecond retrieval, no external database services required. Runs in-process with local SQLite storage and local Nomic embeddings by default, with optional hosted embeddings for L3.
57
59
 
58
60
  | Layer | What it holds | Speed |
59
61
  |---|---|---|
60
- | **L1 In-memory** | What the agent needs right now. Identity, recent history, active state. | 0.08ms |
62
+ | **L1 SQLite `:memory:`** | What the agent needs right now. Identity, recent history, active state. | 0.08ms |
61
63
  | **L2 History** | Every conversation, queryable and concurrent-safe. Per-agent. | 0.13ms |
62
64
  | **L3 Semantic** | Finds related content even when the words don't match. | 0.29ms |
63
65
  | **L4 Knowledge** | Facts, wiki pages, episodes, preferences. Shared across agents. | 0.09ms |
64
66
 
65
67
  Everything is retained. Storage survives session boundaries. The retry logic decision from last week, the deployment preferences from last month, the architecture choices from day one: all queryable, all available for composition.
66
68
 
67
- **Session warming.** Before the first turn fires, hypermem pre-loads the agent's full working state from the in-memory SQLite cache: recent history, facts ranked by confidence and recency, active topic context, cached embeddings for fast semantic recall. The agent's first reply draws from everything that was in scope at the end of the last session. The agent picks up where it left off.
69
+ **Session warming.** Before the first turn fires, hypermem pre-loads the agent's full working state from its SQLite-backed memory stores and hot `:memory:` cache: recent history, facts ranked by confidence and recency, active topic context, cached embeddings for fast semantic recall. The agent's first reply draws from everything that was in scope at the end of the last session. The agent picks up where it left off.
68
70
 
69
71
  ---
70
72
 
@@ -77,7 +79,7 @@ Your agent has four layers of stored context, but what shows up in the prompt? H
77
79
  The hypercompositor queries all four layers in parallel on every turn and composes context within a fixed token budget. No transcript accumulates. No lossy transcript summarization. Amnesia isn't a storage problem; the memories exist, but nobody composed them into a coherent prompt. Compaction isn't inevitable; content that doesn't fit this turn stays in storage instead of being destroyed.
78
80
 
79
81
  **Bigger context windows don't help if you fill them with stale history.**
80
- 128k tokens of stale history and irrelevant memory is worse than 32k of precisely selected content. 10 budget categories, priority-ordered, greedy-fill. Every token in the prompt earned its spot.
82
+ 128k tokens of stale history and irrelevant memory is worse than 32k of precisely selected content. 9 budget categories, priority-ordered, greedy-fill. Every token in the prompt earned its spot.
81
83
 
82
84
  ### What the model actually sees
83
85
 
@@ -104,14 +106,14 @@ What's in storage, not in this prompt:
104
106
  Change the topic, and the next turn pulls different content from the same storage.
105
107
  ```
106
108
 
107
- ### Standard context engine vs. hypercompositor
109
+ ### OpenClaw default vs. hypercompositor
108
110
 
109
111
  ```
110
- Standard hypercompositor
112
+ OpenClaw default hypercompositor
111
113
  ──────────────────────────────── ────────────────────────────────
112
114
  message → append to transcript message → detect active topic
113
115
  transcript full → trim oldest query 4 storage layers in parallel
114
- trimmed content → summarize (lossy) budget allocator: 10 slots, fixed cap
116
+ trimmed content → summarize (lossy) budget allocator: 9 slots, fixed cap
115
117
  send transcript to model tool compression by turn age
116
118
  model responds → append again keystone guard + hyperform profile
117
119
  composed prompt → model
@@ -125,7 +127,7 @@ When it fills: When budget is exceeded:
125
127
  no recovery path change topic back → retrieved again
126
128
  ```
127
129
 
128
- | | Standard | hypercompositor |
130
+ | | OpenClaw default | hypercompositor |
129
131
  |---|---|---|
130
132
  | Context source | Growing transcript only | Transcript + 3 additional storage layers |
131
133
  | When context fills | Trim + summarize (lossy) | Budget allocation (lossless storage) |
@@ -164,9 +166,9 @@ Different models have different default behaviors. GPT-5.4 tends toward 2x verbo
164
166
 
165
167
  Adaptation entries are stored in the `model_output_directives` table and matched by model ID using exact match, then glob pattern (longest wins), then wildcard fallback. Each entry contains:
166
168
 
167
- - **Calibration** known model tendencies and specific adjustments (e.g., "2x verbosity: cut first drafts in half")
168
- - **Corrections** hard/medium/soft severity rules applied in order (e.g., "No preamble before the answer")
169
- - **Task overrides** per-task-type adjustments
169
+ - **Calibration:** known model tendencies and specific adjustments (e.g., "2x verbosity: cut first drafts in half")
170
+ - **Corrections:** hard/medium/soft severity rules applied in order (e.g., "No preamble before the answer")
171
+ - **Task overrides:** per-task-type adjustments
170
172
 
171
173
  Model adaptation is only active at the `full` tier. At `light` and `standard`, model-specific corrections are suppressed.
172
174
 
@@ -196,7 +198,7 @@ Would you like me to go deeper on any of these?
196
198
  WITH outputProfile: "light":
197
199
  For a 128k window: reserve 14k for identity/system, target 46k for history, 10k for recent
198
200
  tool context, and leave ~30k as allocator reserve. hypermem handles slot competition
199
- automatically set `reserveFraction` to your preferred floor and let the compositor fill.
201
+ automatically. Set `reserveFraction` to your preferred floor and let the compositor fill.
200
202
  ```
201
203
 
202
204
  **Confabulation resistance** checks output against stored facts before claims are recorded. No LLM call. Pattern matching against the fact corpus, with confidence scoring and contradiction detection. Unsupported claims are flagged, contradictions surface in diagnostics, and a confabulation risk score is attached to the stored episode.
@@ -217,7 +219,7 @@ Most memory systems store what was said. hypermem synthesizes what was learned.
217
219
 
218
220
  When a topic goes quiet, hypermem compiles the thread into a structured wiki page: decisions, open questions, artifacts, participants. When the topic resurfaces, the agent gets a compact structured summary rather than a raw history replay.
219
221
 
220
- OpenClaw 2026.4.7 ships memory wiki for structured storage. hypermem goes further: wiki pages are synthesized automatically and injected by the compositor within token budget.
222
+ OpenClaw 2026.4.7 ships memory wiki for structured storage. hypermem goes further: wiki pages are synthesized automatically and injected by the compositor within token budget, backed by SQLite memory databases instead of an external cache service.
221
223
 
222
224
  ### Subagents that hit the ground running
223
225
 
@@ -241,16 +243,7 @@ SQL queries that interpolate datetime values are fully parameterized. FTS5 trigg
241
243
 
242
244
  ## Pressure management
243
245
 
244
- hypermem composes context fresh on every turn, but a long-running session still accumulates history in its JSONL transcript. When that grows large enough, incoming tool results have nowhere to land and get silently stripped. Four automatic paths handle this:
245
-
246
- | Path | Trigger | Action |
247
- |---|---|---|
248
- | **Pressure-tiered tool-loop trim** | Any tool-loop turn | Measures projected occupancy before results land; trims large results at 80%+ and truncates the messages[] array for the current turn |
249
- | **AfterTurn trim** | Every turn at >80% | Pre-emptive headroom cut after the assistant replies, before the next turn arrives |
250
- | **Deep compaction** | compact() at >85% | Cuts in-memory cache to 25% budget and truncates JSONL to ~20% depth. Bypasses the normal reshape guard |
251
- | **Reshape guard** | Structured tool history on downshift | `canPersistReshapedHistory()` blocks a lower-context snapshot from overwriting the full JSONL history |
252
-
253
- **The one thing these paths cannot fix:** a session whose JSONL transcript on disk is already at 98% when the gateway restarts. The JSONL loads into runtime context before any compaction runs. Check `session_status` on startup. If you're above 85%, start a fresh session.
246
+ hypermem manages context pressure automatically through four escalating paths. Most sessions never need manual intervention. For trigger thresholds and path details, see [Pressure management](#pressure-management-1) below.
254
247
 
255
248
  ---
256
249
 
@@ -383,7 +376,7 @@ Slot-level budget allocation is shown in the [hypercompositor diagram](#what-the
383
376
 
384
377
  ## Requirements
385
378
 
386
- **Current release: hypermem 0.5.6.** Changelog: [CHANGELOG.md](./CHANGELOG.md)
379
+ **Current release: hypermem 0.8.1.** Changelog: [CHANGELOG.md](./CHANGELOG.md)
387
380
 
388
381
  | Requirement | Version | Notes |
389
382
  |---|---|---|
@@ -396,11 +389,11 @@ SQLite is a library, not a service. All four layers run in-process with no exter
396
389
  **Runtime version constants** (importable from the package):
397
390
  ```typescript
398
391
  import {
399
- ENGINE_VERSION, // '0.5.6'
392
+ ENGINE_VERSION, // '0.8.1'
400
393
  MIN_NODE_VERSION, // '22.0.0'
401
394
  SQLITE_VEC_VERSION, // '0.1.9'
402
- MAIN_SCHEMA_VERSION, // 6 (hypermem.db)
403
- LIBRARY_SCHEMA_VERSION_EXPORT, // 12 (library.db)
395
+ MAIN_SCHEMA_VERSION, // 10 (messages.db)
396
+ LIBRARY_SCHEMA_VERSION_EXPORT, // 19 (library.db)
404
397
  } from '@psiclawops/hypermem';
405
398
  ```
406
399
 
@@ -410,29 +403,63 @@ Schema versions are stamped into each database on startup and checked on open. A
410
403
 
411
404
  ## Installation
412
405
 
406
+ **Requirements:** Node.js 22+, OpenClaw with context engine plugin support. No standalone SQLite install needed (uses Node 22 built-in `node:sqlite`). Embedding provider is optional for first install.
407
+
408
+ ### From source
409
+
413
410
  ```bash
414
- git clone https://github.com/PsiClawOps/hypermem.git ~/.openclaw/workspace/repo/hypermem
415
- cd ~/.openclaw/workspace/repo/hypermem
411
+ git clone https://github.com/PsiClawOps/hypermem.git
412
+ cd hypermem
416
413
  npm install && npm run build
417
414
  npm --prefix plugin install && npm --prefix plugin run build
418
415
  npm --prefix memory-plugin install && npm --prefix memory-plugin run build
416
+ npm run install:runtime
417
+ ```
418
+
419
+ `install:runtime` stages the runtime payload into `~/.openclaw/plugins/hypermem` and prints the exact config commands to wire the plugins. Before running them, create the data directory and config:
420
+
421
+ ```bash
422
+ mkdir -p ~/.openclaw/hypermem
423
+ cat > ~/.openclaw/hypermem/config.json <<'JSON'
424
+ {
425
+ "embedding": {
426
+ "provider": "none"
427
+ }
428
+ }
429
+ JSON
430
+ ```
431
+
432
+ This sets lightweight mode (FTS5 keyword search, no embedding provider needed). Add an embedding provider later for semantic search without losing stored data. See [INSTALL.md](./INSTALL.md#embedding-providers) for options.
433
+
434
+ Wire the plugins into OpenClaw:
419
435
 
436
+ ```bash
437
+ openclaw config set plugins.load.paths "[\"$HOME/.openclaw/plugins/hypermem/plugin\",\"$HOME/.openclaw/plugins/hypermem/memory-plugin\"]" --strict-json
420
438
  openclaw config set plugins.slots.contextEngine hypercompositor
421
439
  openclaw config set plugins.slots.memory hypermem
422
- openclaw config set plugins.load.paths '["~/.openclaw/workspace/repo/hypermem/plugin","~/.openclaw/workspace/repo/hypermem/memory-plugin"]' --strict-json
423
440
  openclaw config set plugins.allow '["hypercompositor","hypermem"]' --strict-json
424
441
  openclaw gateway restart
425
442
  ```
426
443
 
427
- Or use the one-line installer:
444
+ Verify (run from the repo clone directory):
445
+
446
+ ```bash
447
+ openclaw plugins list # hypercompositor and hypermem should show as loaded
448
+ node bin/hypermem-status.mjs --health # confirms database initialization
449
+ openclaw logs --limit 50 | grep hypermem # should show "hypermem initialized"
450
+ ```
451
+
452
+ If you see `falling back to default engine "legacy"` in the logs, the install is not active. Check [INSTALL.md troubleshooting](./INSTALL.md#troubleshooting-clean-installs).
453
+
454
+ ### One-line installer
428
455
 
429
456
  ```bash
430
457
  curl -fsSL https://raw.githubusercontent.com/PsiClawOps/hypermem/main/install.sh | bash
431
458
  ```
432
459
 
433
- **Requirements:** Node.js 22+, OpenClaw with context engine plugin support, and either Ollama (local) or an OpenRouter API key (hosted) for embeddings. No standalone SQLite install is required for the documented repo install: hypermem uses the SQLite bundled with Node 22 via `node:sqlite`, and `sqlite-vec` provides the platform-specific extension through npm dependencies.
460
+ Interactive: detects hardware, selects embedding tier, writes config, registers plugins.
434
461
 
435
- Full guide with deployment-specific options: **[INSTALL.md](./INSTALL.md)**
462
+ Full guide with embedding tiers, reranker setup, fleet config, and tuning: **[INSTALL.md](./INSTALL.md)**
436
463
 
437
464
  ### Agent-assisted install
438
465
 
@@ -440,9 +467,15 @@ If you prefer, hand the install to your OpenClaw agent:
440
467
 
441
468
  > "Install hypermem following INSTALL.md. I'm running a [solo / multi-agent] setup."
442
469
 
470
+ ### Operator guides
471
+
472
+ - **[docs/MEMORY_MD_AUTHORING.md](./docs/MEMORY_MD_AUTHORING.md)**, how to keep `MEMORY.md` compact, durable, and reviewable
473
+ - **[docs/TUNING.md](./docs/TUNING.md)**, context assembly and output shaping profiles
474
+ - **[docs/MIGRATION_GUIDE.md](./docs/MIGRATION_GUIDE.md)**, moving data in from existing memory systems
475
+
443
476
  ### Tuning
444
477
 
445
- Two independent surfaces: **context assembly** (what fills the context window) and **output shaping** (how the model writes). Pick a profile first most deployments adjust one or two settings on top.
478
+ Two independent surfaces: **context assembly** (what fills the context window) and **output shaping** (how the model writes). Pick a profile first. Most deployments adjust one or two settings on top.
446
479
 
447
480
  | Profile | Target window | Best for |
448
481
  |---|---|---|
@@ -550,6 +583,21 @@ node bin/hypermem-status.mjs --health # health checks only (exit 1 on fai
550
583
 
551
584
  ---
552
585
 
586
+ ## Pressure management
587
+
588
+ hypermem composes context fresh on every turn, but a long-running session still accumulates history in its JSONL transcript. When that grows large enough, incoming tool results have nowhere to land and get silently stripped. Four automatic paths handle this:
589
+
590
+ | Path | Trigger | Action |
591
+ |---|---|---|
592
+ | **Pressure-tiered tool-loop trim** | Any tool-loop turn | Measures projected occupancy before results land; trims large results at 80%+ and truncates the messages[] array for the current turn |
593
+ | **AfterTurn trim** | Every turn at >80% | Pre-emptive headroom cut after the assistant replies, before the next turn arrives |
594
+ | **Deep compaction** | compact() at >85% | Cuts in-memory cache to 25% budget and truncates JSONL to ~20% depth. Bypasses the normal reshape guard |
595
+ | **Reshape guard** | Structured tool history on downshift | `canPersistReshapedHistory()` blocks a lower-context snapshot from overwriting the full JSONL history |
596
+
597
+ **The one thing these paths cannot fix:** a session whose JSONL transcript on disk is already at 98% when the gateway restarts. The JSONL loads into runtime context before any compaction runs. Check `session_status` on startup. If you're above 85%, start a fresh session.
598
+
599
+ ---
600
+
553
601
  ## Data directory
554
602
 
555
603
  ```text
@@ -17,8 +17,9 @@
17
17
  * - Observable: logs extraction stats for monitoring
18
18
  */
19
19
  import type { DatabaseSync } from 'node:sqlite';
20
- import type { IndexerConfig, SessionCursor } from './types.js';
20
+ import type { IndexerConfig, SessionCursor, MaintenanceTickDiagnostics } from './types.js';
21
21
  import { type DreamerConfig } from './dreaming-promoter.js';
22
+ import { type ContradictionResolutionPolicy } from './contradiction-resolution-policy.js';
22
23
  import type { VectorStore } from './vector-store.js';
23
24
  export interface IndexerStats {
24
25
  agentId: string;
@@ -29,6 +30,12 @@ export interface IndexerStats {
29
30
  knowledgeUpserted: number;
30
31
  /** Number of superseded fact vectors tombstoned from the vector index this tick. */
31
32
  tombstoned: number;
33
+ /** Number of contradiction audits recorded for review this tick. */
34
+ contradictionAuditsLogged: number;
35
+ /** Number of old facts auto-superseded via contradiction policy this tick. */
36
+ contradictionsAutoSuperseded: number;
37
+ /** Number of old facts auto-invalidated via contradiction policy this tick. */
38
+ contradictionsAutoInvalidated: number;
32
39
  elapsedMs: number;
33
40
  /** Number of messages that were post-cursor (unseen by model, high-signal priority). */
34
41
  postCursorMessages: number;
@@ -51,6 +58,8 @@ export declare class BackgroundIndexer {
51
58
  private getCursor?;
52
59
  private readonly config;
53
60
  private readonly dreamerConfig;
61
+ private readonly globalWritePolicy;
62
+ private readonly contradictionPolicy;
54
63
  private intervalHandle;
55
64
  private running;
56
65
  private vectorStore;
@@ -60,7 +69,9 @@ export declare class BackgroundIndexer {
60
69
  private consecutiveFailures;
61
70
  /** True when the indexer is running in backoff mode due to repeated failures. */
62
71
  private inBackoff;
63
- constructor(config?: Partial<IndexerConfig>, getMessageDb?: ((agentId: string) => DatabaseSync) | undefined, getLibraryDb?: (() => DatabaseSync) | undefined, listAgents?: (() => string[]) | undefined, getCursor?: CursorFetcher | undefined, dreamerConfig?: Partial<DreamerConfig>);
72
+ private readonly _conversationLastProcessed;
73
+ lastMaintenanceDiagnostics: MaintenanceTickDiagnostics | null;
74
+ constructor(config?: Partial<IndexerConfig>, getMessageDb?: ((agentId: string) => DatabaseSync) | undefined, getLibraryDb?: (() => DatabaseSync) | undefined, listAgents?: (() => string[]) | undefined, getCursor?: CursorFetcher | undefined, dreamerConfig?: Partial<DreamerConfig>, globalWritePolicy?: import('./types.js').GlobalWritePolicy, contradictionPolicy?: ContradictionResolutionPolicy);
64
75
  /**
65
76
  * Set the vector store for embedding new facts/episodes at index time.
66
77
  * Optional — if not set, indexer runs without embedding (FTS5-only mode).
@@ -146,5 +157,5 @@ export declare class BackgroundIndexer {
146
157
  * Create and start a background indexer connected to hypermem databases.
147
158
  * Used by the hook or a standalone daemon.
148
159
  */
149
- export declare function createIndexer(getMessageDb: (agentId: string) => DatabaseSync, getLibraryDb: () => DatabaseSync, listAgents: () => string[], config?: Partial<IndexerConfig>, getCursor?: CursorFetcher, vectorStore?: VectorStore, dreamerConfig?: Partial<DreamerConfig>): BackgroundIndexer;
160
+ export declare function createIndexer(getMessageDb: (agentId: string) => DatabaseSync, getLibraryDb: () => DatabaseSync, listAgents: () => string[], config?: Partial<IndexerConfig>, getCursor?: CursorFetcher, vectorStore?: VectorStore, dreamerConfig?: Partial<DreamerConfig>, globalWritePolicy?: import('./types.js').GlobalWritePolicy): BackgroundIndexer;
150
161
  //# sourceMappingURL=background-indexer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"background-indexer.d.ts","sourceRoot":"","sources":["../src/background-indexer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"background-indexer.d.ts","sourceRoot":"","sources":["../src/background-indexer.ts"],"names":[],"mappings":"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"}