@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.
- package/ARCHITECTURE.md +30 -38
- package/README.md +83 -35
- package/dist/background-indexer.d.ts +14 -3
- package/dist/background-indexer.d.ts.map +1 -1
- package/dist/background-indexer.js +126 -18
- package/dist/budget-policy.d.ts +22 -0
- package/dist/budget-policy.d.ts.map +1 -0
- package/dist/budget-policy.js +27 -0
- package/dist/cache.d.ts +11 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/compositor-utils.d.ts +31 -0
- package/dist/compositor-utils.d.ts.map +1 -0
- package/dist/compositor-utils.js +47 -0
- package/dist/compositor.d.ts +163 -1
- package/dist/compositor.d.ts.map +1 -1
- package/dist/compositor.js +862 -130
- package/dist/content-hash.d.ts +43 -0
- package/dist/content-hash.d.ts.map +1 -0
- package/dist/content-hash.js +75 -0
- package/dist/context-store.d.ts +54 -0
- package/dist/context-store.d.ts.map +1 -1
- package/dist/context-store.js +102 -0
- package/dist/contradiction-audit-store.d.ts +54 -0
- package/dist/contradiction-audit-store.d.ts.map +1 -0
- package/dist/contradiction-audit-store.js +88 -0
- package/dist/contradiction-resolution-policy.d.ts +21 -0
- package/dist/contradiction-resolution-policy.d.ts.map +1 -0
- package/dist/contradiction-resolution-policy.js +17 -0
- package/dist/degradation.d.ts +102 -0
- package/dist/degradation.d.ts.map +1 -0
- package/dist/degradation.js +141 -0
- package/dist/dreaming-promoter.d.ts +38 -0
- package/dist/dreaming-promoter.d.ts.map +1 -1
- package/dist/dreaming-promoter.js +68 -2
- package/dist/index.d.ts +68 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +402 -26
- package/dist/knowledge-lint.d.ts +2 -0
- package/dist/knowledge-lint.d.ts.map +1 -1
- package/dist/knowledge-lint.js +40 -1
- package/dist/library-schema.d.ts +7 -2
- package/dist/library-schema.d.ts.map +1 -1
- package/dist/library-schema.js +236 -1
- package/dist/message-store.d.ts +64 -1
- package/dist/message-store.d.ts.map +1 -1
- package/dist/message-store.js +137 -1
- package/dist/open-domain.js +1 -1
- package/dist/proactive-pass.d.ts +2 -2
- package/dist/proactive-pass.d.ts.map +1 -1
- package/dist/proactive-pass.js +66 -12
- package/dist/replay-recovery.d.ts +29 -0
- package/dist/replay-recovery.d.ts.map +1 -0
- package/dist/replay-recovery.js +82 -0
- package/dist/reranker.d.ts +95 -0
- package/dist/reranker.d.ts.map +1 -0
- package/dist/reranker.js +308 -0
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +46 -1
- package/dist/session-flusher.d.ts +2 -2
- package/dist/session-flusher.d.ts.map +1 -1
- package/dist/session-flusher.js +1 -1
- package/dist/temporal-store.js +2 -2
- package/dist/tool-artifact-store.d.ts +98 -0
- package/dist/tool-artifact-store.d.ts.map +1 -0
- package/dist/tool-artifact-store.js +244 -0
- package/dist/topic-detector.js +2 -2
- package/dist/topic-store.d.ts +6 -0
- package/dist/topic-store.d.ts.map +1 -1
- package/dist/topic-store.js +39 -0
- package/dist/types.d.ts +233 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-store.d.ts +2 -1
- package/dist/vector-store.d.ts.map +1 -1
- package/dist/vector-store.js +3 -0
- package/dist/version.d.ts +10 -10
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +10 -10
- 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
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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:
|
|
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:**
|
|
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 →
|
|
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 +
|
|
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
|
-
│
|
|
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
|
-
─→
|
|
214
|
-
─→ write
|
|
215
|
-
─→ write
|
|
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.
|
|
221
|
-
2.
|
|
222
|
-
3.
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
| `
|
|
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 |
|
|
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 |
|
|
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
|
-
-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
###
|
|
109
|
+
### OpenClaw default vs. hypercompositor
|
|
108
110
|
|
|
109
111
|
```
|
|
110
|
-
|
|
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:
|
|
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
|
-
| |
|
|
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
|
|
168
|
-
- **Corrections
|
|
169
|
-
- **Task overrides
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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, //
|
|
403
|
-
LIBRARY_SCHEMA_VERSION_EXPORT, //
|
|
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
|
|
415
|
-
cd
|
|
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
|
-
|
|
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
|
-
|
|
460
|
+
Interactive: detects hardware, selects embedding tier, writes config, registers plugins.
|
|
434
461
|
|
|
435
|
-
Full guide with
|
|
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
|
|
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
|
-
|
|
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
|
|
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":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAiB,aAAa,EAAe,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"background-indexer.d.ts","sourceRoot":"","sources":["../src/background-indexer.ts"],"names":[],"mappings":"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"}
|