@199-bio/engram 0.5.1 → 0.6.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/README.md +127 -168
- package/dist/consolidation/consolidator.d.ts.map +1 -1
- package/dist/index.js +89 -4
- package/dist/retrieval/hybrid.d.ts.map +1 -1
- package/dist/storage/database.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/consolidation/consolidator.ts +245 -5
- package/src/index.ts +96 -3
- package/src/retrieval/hybrid.ts +83 -7
- package/src/storage/database.ts +198 -8
package/README.md
CHANGED
|
@@ -2,275 +2,235 @@
|
|
|
2
2
|
|
|
3
3
|
**Give your AI a perfect memory.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Every conversation you have with your AI disappears the moment it ends. Names you've mentioned, preferences you've shared, the context of your life—all gone. You find yourself repeating the same information, re-explaining who people are, reminding it of things you've already said.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Engram changes that.
|
|
8
|
+
|
|
9
|
+
It gives your AI the ability to remember. Not just store text, but truly remember—the way you do. Important things stick. Trivial things fade. And everything connects to everything else.
|
|
8
10
|
|
|
9
11
|
> *An engram is a unit of cognitive information imprinted in a physical substance—the biological basis of memory.*
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
13
|
-
##
|
|
15
|
+
## How It Works
|
|
14
16
|
|
|
15
|
-
Tell your AI
|
|
17
|
+
Tell your AI something once:
|
|
16
18
|
|
|
17
19
|
> "My colleague Sarah is allergic to shellfish and prefers window seats. She's leading the Q1 product launch."
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
Weeks later, ask:
|
|
20
22
|
|
|
21
23
|
> "I'm booking a team lunch and flights for the offsite—what should I know?"
|
|
22
24
|
|
|
23
|
-
Engram connects the dots
|
|
25
|
+
Engram connects the dots. It remembers Sarah, her allergy, her seating preference, and her current workload. Your AI can now actually help—suggesting restaurants without shellfish, booking her a window seat, and noting she might be busy with the launch.
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
This isn't keyword matching. It's understanding.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Memory That Feels Real
|
|
32
|
+
|
|
33
|
+
Engram models memory the way your brain does.
|
|
34
|
+
|
|
35
|
+
**Things fade.** A memory from six months ago that you've never thought about becomes harder to find. But something important—a name, a birthday, a preference—stays accessible even as time passes.
|
|
36
|
+
|
|
37
|
+
**Recall strengthens.** Every time a memory surfaces, it becomes more permanent. The things you think about often become the things you'll never forget.
|
|
38
|
+
|
|
39
|
+
**Everything connects.** People link to places. Places link to events. When you ask about one thing, related things come along for the ride. Ask about Sarah, and her company, her projects, and her preferences all surface together.
|
|
26
40
|
|
|
27
41
|
---
|
|
28
42
|
|
|
29
43
|
## Quick Start
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
Install globally:
|
|
32
46
|
|
|
33
47
|
```bash
|
|
34
48
|
npm install -g @199-bio/engram
|
|
35
49
|
```
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
**Claude Desktop** — add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
51
|
+
Add to **Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
40
52
|
|
|
41
53
|
```json
|
|
42
54
|
{
|
|
43
55
|
"mcpServers": {
|
|
44
56
|
"engram": {
|
|
45
57
|
"command": "npx",
|
|
46
|
-
"args": ["-y", "@199-bio/engram"]
|
|
58
|
+
"args": ["-y", "@199-bio/engram"],
|
|
59
|
+
"env": {
|
|
60
|
+
"ANTHROPIC_API_KEY": "sk-ant-..."
|
|
61
|
+
}
|
|
47
62
|
}
|
|
48
63
|
}
|
|
49
64
|
}
|
|
50
65
|
```
|
|
51
66
|
|
|
52
|
-
**Claude Code
|
|
67
|
+
Or with **Claude Code**:
|
|
53
68
|
|
|
54
69
|
```bash
|
|
55
70
|
claude mcp add engram -- npx -y @199-bio/engram
|
|
56
71
|
```
|
|
57
72
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
That's it. Your AI now has memory.
|
|
73
|
+
That's it. Your AI now remembers.
|
|
61
74
|
|
|
62
75
|
---
|
|
63
76
|
|
|
64
|
-
##
|
|
65
|
-
|
|
66
|
-
Just talk naturally. Your AI will remember what matters.
|
|
67
|
-
|
|
68
|
-
### Storing Memories
|
|
77
|
+
## What You Can Do
|
|
69
78
|
|
|
70
|
-
|
|
71
|
-
- "Remember that Sarah is allergic to shellfish"
|
|
72
|
-
- "My anniversary is March 15th"
|
|
73
|
-
- "I prefer morning meetings, never schedule anything before 9am"
|
|
79
|
+
Just talk naturally. Your AI handles the rest.
|
|
74
80
|
|
|
75
|
-
|
|
81
|
+
**Store memories** by mentioning things:
|
|
82
|
+
- "Remember that my anniversary is March 15th"
|
|
83
|
+
- "Sarah prefers async communication"
|
|
84
|
+
- "I'm allergic to penicillin"
|
|
76
85
|
|
|
77
|
-
|
|
86
|
+
**Recall memories** by asking:
|
|
78
87
|
- "What do you know about Sarah?"
|
|
88
|
+
- "What are my allergies?"
|
|
79
89
|
- "When is my anniversary?"
|
|
80
|
-
- "What are my meeting preferences?"
|
|
81
|
-
|
|
82
|
-
Your AI automatically searches its memory and uses what's relevant.
|
|
83
|
-
|
|
84
|
-
### The Knowledge Graph
|
|
85
|
-
|
|
86
|
-
Engram doesn't just store text—it understands relationships:
|
|
87
|
-
|
|
88
|
-
- **People**: Sarah, John, Dr. Martinez
|
|
89
|
-
- **Places**: Office, Conference Room A, Seattle HQ
|
|
90
|
-
- **Organizations**: Acme Corp, Stanford, FDA
|
|
91
|
-
- **Connections**: Sarah → works at → Acme Corp
|
|
92
|
-
- **Observations**: Sarah is allergic to shellfish
|
|
93
90
|
|
|
94
|
-
|
|
91
|
+
**Build a knowledge graph** of your world:
|
|
92
|
+
- People, places, organizations, and how they connect
|
|
93
|
+
- Observations about each entity
|
|
94
|
+
- Relationships that span your entire life
|
|
95
95
|
|
|
96
96
|
---
|
|
97
97
|
|
|
98
|
-
##
|
|
98
|
+
## Privacy
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|---------|----------------|
|
|
102
|
-
| **Hybrid Search** | Finds memories by keywords AND meaning |
|
|
103
|
-
| **Knowledge Graph** | Understands relationships between people, places, things |
|
|
104
|
-
| **100% Local** | Your memories never leave your computer |
|
|
105
|
-
| **No API Keys** | Works offline, no subscriptions |
|
|
106
|
-
| **Fast** | ~50ms to recall, feels instant |
|
|
100
|
+
Your memories stay on your machine. Everything is stored locally in `~/.engram/`. The only external call is optional—if you provide an API key, Engram can periodically compress old memories into summaries. But the core functionality works entirely offline.
|
|
107
101
|
|
|
108
102
|
---
|
|
109
103
|
|
|
110
|
-
## The
|
|
104
|
+
## The Details
|
|
111
105
|
|
|
112
|
-
|
|
106
|
+
<details>
|
|
107
|
+
<summary><strong>Available Tools</strong></summary>
|
|
113
108
|
|
|
114
|
-
|
|
115
|
-
|------|--------------|
|
|
116
|
-
| `remember` | Store something new |
|
|
117
|
-
| `recall` | Find relevant memories |
|
|
118
|
-
| `forget` | Remove a memory |
|
|
119
|
-
| `create_entity` | Add a person, place, or concept |
|
|
120
|
-
| `observe` | Note something about an entity |
|
|
121
|
-
| `relate` | Connect two entities |
|
|
122
|
-
| `query_entity` | Get everything about someone/something |
|
|
123
|
-
| `list_entities` | See all people, places, etc. |
|
|
124
|
-
| `stats` | Check memory statistics |
|
|
109
|
+
Your AI gets these capabilities:
|
|
125
110
|
|
|
126
|
-
|
|
111
|
+
| Tool | Purpose |
|
|
112
|
+
|------|---------|
|
|
113
|
+
| `remember` | Store new information with importance, emotions, and timing |
|
|
114
|
+
| `recall` | Find relevant memories ranked by relevance and recency |
|
|
115
|
+
| `forget` | Remove a specific memory |
|
|
116
|
+
| `create_entity` | Add a person, place, or concept to the knowledge graph |
|
|
117
|
+
| `observe` | Record a fact about an entity |
|
|
118
|
+
| `relate` | Connect two entities (e.g., "works at", "married to") |
|
|
119
|
+
| `query_entity` | Get everything known about someone or something |
|
|
120
|
+
| `list_entities` | See all tracked people, places, and things |
|
|
121
|
+
| `stats` | View memory statistics |
|
|
122
|
+
| `consolidate` | Compress old memories and detect contradictions |
|
|
123
|
+
| `engram_web` | Launch a visual memory browser |
|
|
127
124
|
|
|
128
|
-
|
|
125
|
+
</details>
|
|
129
126
|
|
|
130
|
-
|
|
127
|
+
<details>
|
|
128
|
+
<summary><strong>How Search Works</strong></summary>
|
|
131
129
|
|
|
132
|
-
|
|
133
|
-
You: "Remember that my anniversary is March 15th and my partner loves Italian food"
|
|
134
|
-
AI: ✓ Stored. I've noted this as an important date with preferences.
|
|
130
|
+
Engram uses three search methods simultaneously:
|
|
135
131
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
```
|
|
132
|
+
1. **Keywords** — SQLite FTS5 finds exact matches for names, dates, and phrases
|
|
133
|
+
2. **Meaning** — Neural embeddings find conceptually related content
|
|
134
|
+
3. **Connections** — The knowledge graph expands to related entities
|
|
140
135
|
|
|
141
|
-
|
|
136
|
+
Results are fused together, then adjusted for how recent and important each memory is. Fresh memories surface first. Important memories resist fading.
|
|
142
137
|
|
|
143
|
-
|
|
144
|
-
You: "My friend David lives in Austin and always recommends great coffee shops."
|
|
145
|
-
AI: ✓ Stored. Created entity: David (person), with observation about Austin and coffee expertise.
|
|
138
|
+
</details>
|
|
146
139
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
Want me to remind you to ask him?
|
|
150
|
-
```
|
|
140
|
+
<details>
|
|
141
|
+
<summary><strong>How Forgetting Works</strong></summary>
|
|
151
142
|
|
|
152
|
-
|
|
143
|
+
Memories follow an exponential decay curve:
|
|
153
144
|
|
|
154
145
|
```
|
|
155
|
-
|
|
156
|
-
Claude: ✓ Stored. Created entity: John Chen (person, VP of Engineering).
|
|
157
|
-
|
|
158
|
-
You: "I need to schedule a sync with John"
|
|
159
|
-
Claude: Given John's preferences, I'd suggest a late morning slot, maybe 11:30am,
|
|
160
|
-
or an async Loom video if it doesn't require real-time discussion.
|
|
146
|
+
Retention = e^(-time / stability)
|
|
161
147
|
```
|
|
162
148
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
## Privacy
|
|
149
|
+
- **Time** is days since the memory was last accessed
|
|
150
|
+
- **Stability** is memory strength, which increases each time you recall something
|
|
166
151
|
|
|
167
|
-
|
|
152
|
+
High-importance and emotionally significant memories decay slower. Frequently accessed memories become essentially permanent.
|
|
168
153
|
|
|
169
|
-
|
|
170
|
-
- No cloud services, no external APIs
|
|
171
|
-
- No telemetry, no tracking
|
|
172
|
-
- You own your data completely
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## Technical Details
|
|
154
|
+
</details>
|
|
177
155
|
|
|
178
156
|
<details>
|
|
179
|
-
<summary>How
|
|
157
|
+
<summary><strong>How Consolidation Works</strong></summary>
|
|
180
158
|
|
|
181
|
-
Engram
|
|
159
|
+
With an API key, Engram can compress old memories—like how sleep consolidates your experiences into long-term storage.
|
|
182
160
|
|
|
183
|
-
1.
|
|
184
|
-
2.
|
|
185
|
-
3.
|
|
161
|
+
1. Groups related low-importance memories together
|
|
162
|
+
2. Creates AI-generated summaries (digests)
|
|
163
|
+
3. Detects contradictory information
|
|
164
|
+
4. Archives the originals
|
|
186
165
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
```
|
|
190
|
-
Query: "What should I know about Sarah?"
|
|
191
|
-
│
|
|
192
|
-
├── BM25 → finds "Sarah" in memories
|
|
193
|
-
├── ColBERT → finds semantically related content
|
|
194
|
-
└── Graph → Sarah → works at → Acme Corp → Q1 launch
|
|
195
|
-
│
|
|
196
|
-
└── RRF Fusion → Best combined results
|
|
197
|
-
```
|
|
166
|
+
This keeps storage efficient while preserving everything important.
|
|
198
167
|
|
|
199
168
|
</details>
|
|
200
169
|
|
|
201
170
|
<details>
|
|
202
|
-
<summary>Architecture</summary>
|
|
171
|
+
<summary><strong>Architecture</strong></summary>
|
|
203
172
|
|
|
204
173
|
```
|
|
205
174
|
engram/
|
|
206
175
|
├── src/
|
|
207
|
-
│ ├── index.ts
|
|
208
|
-
│ ├── storage/
|
|
209
|
-
│
|
|
210
|
-
│ ├──
|
|
211
|
-
│ │ ├──
|
|
212
|
-
│ │ └──
|
|
213
|
-
│
|
|
214
|
-
│
|
|
215
|
-
│ ├── colbert-bridge.py # Python RAGatouille
|
|
216
|
-
│ └── hybrid.ts # RRF fusion
|
|
176
|
+
│ ├── index.ts # MCP server
|
|
177
|
+
│ ├── storage/database.ts # SQLite with temporal fields
|
|
178
|
+
│ ├── graph/knowledge-graph.ts
|
|
179
|
+
│ ├── retrieval/
|
|
180
|
+
│ │ ├── colbert.ts # Semantic search
|
|
181
|
+
│ │ └── hybrid.ts # Fusion + decay + salience
|
|
182
|
+
│ ├── consolidation/consolidator.ts
|
|
183
|
+
│ └── web/server.ts # Visual browser
|
|
217
184
|
```
|
|
218
185
|
|
|
219
186
|
</details>
|
|
220
187
|
|
|
221
188
|
<details>
|
|
222
|
-
<summary>
|
|
189
|
+
<summary><strong>Configuration</strong></summary>
|
|
190
|
+
|
|
191
|
+
Environment variables:
|
|
192
|
+
|
|
193
|
+
| Variable | Purpose | Default |
|
|
194
|
+
|----------|---------|---------|
|
|
195
|
+
| `ENGRAM_DB_PATH` | Where to store data | `~/.engram/` |
|
|
196
|
+
| `ANTHROPIC_API_KEY` | Enable consolidation | None (optional) |
|
|
197
|
+
|
|
198
|
+
</details>
|
|
199
|
+
|
|
200
|
+
<details>
|
|
201
|
+
<summary><strong>Building from Source</strong></summary>
|
|
223
202
|
|
|
224
203
|
```bash
|
|
225
204
|
git clone https://github.com/199-biotechnologies/engram.git
|
|
226
205
|
cd engram
|
|
227
206
|
npm install
|
|
228
207
|
npm run build
|
|
229
|
-
|
|
230
|
-
# Install globally from local build
|
|
231
208
|
npm install -g .
|
|
232
209
|
```
|
|
233
210
|
|
|
234
|
-
|
|
211
|
+
For semantic search, install Python dependencies:
|
|
212
|
+
|
|
235
213
|
```bash
|
|
236
214
|
pip install ragatouille torch
|
|
237
215
|
```
|
|
238
216
|
|
|
239
|
-
If
|
|
240
|
-
|
|
241
|
-
</details>
|
|
242
|
-
|
|
243
|
-
<details>
|
|
244
|
-
<summary>Configuration</summary>
|
|
245
|
-
|
|
246
|
-
Environment variables:
|
|
247
|
-
- `ENGRAM_DB_PATH`: Database location (default: `~/.engram/engram.db`)
|
|
248
|
-
|
|
249
|
-
Claude Desktop full config:
|
|
250
|
-
```json
|
|
251
|
-
{
|
|
252
|
-
"mcpServers": {
|
|
253
|
-
"engram": {
|
|
254
|
-
"command": "engram",
|
|
255
|
-
"env": {
|
|
256
|
-
"ENGRAM_DB_PATH": "/custom/path/engram.db"
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
```
|
|
217
|
+
If unavailable, Engram falls back to keyword-only search automatically.
|
|
262
218
|
|
|
263
219
|
</details>
|
|
264
220
|
|
|
265
221
|
<details>
|
|
266
|
-
<summary>Performance</summary>
|
|
222
|
+
<summary><strong>Performance</strong></summary>
|
|
267
223
|
|
|
268
224
|
On M1 MacBook Air:
|
|
269
|
-
- **remember**: ~100ms
|
|
270
|
-
- **recall**: ~50ms
|
|
271
|
-
- **graph queries**: ~5ms
|
|
272
225
|
|
|
273
|
-
|
|
226
|
+
| Operation | Time |
|
|
227
|
+
|-----------|------|
|
|
228
|
+
| Remember | ~100ms |
|
|
229
|
+
| Recall | ~50ms |
|
|
230
|
+
| Graph queries | ~5ms |
|
|
231
|
+
| Consolidate | ~2-5s per batch |
|
|
232
|
+
|
|
233
|
+
Storage: ~1KB per memory.
|
|
274
234
|
|
|
275
235
|
</details>
|
|
276
236
|
|
|
@@ -278,14 +238,13 @@ Database size: ~1KB per memory (text + embeddings + graph data)
|
|
|
278
238
|
|
|
279
239
|
## Roadmap
|
|
280
240
|
|
|
281
|
-
- [x]
|
|
282
|
-
- [x]
|
|
283
|
-
- [x]
|
|
284
|
-
- [x]
|
|
285
|
-
- [
|
|
286
|
-
- [ ]
|
|
287
|
-
- [ ]
|
|
288
|
-
- [ ] Web dashboard
|
|
241
|
+
- [x] Hybrid search (keywords + semantics)
|
|
242
|
+
- [x] Knowledge graph with relationships
|
|
243
|
+
- [x] Memory decay and strengthening
|
|
244
|
+
- [x] Consolidation with contradiction detection
|
|
245
|
+
- [x] Web interface
|
|
246
|
+
- [ ] Export and import
|
|
247
|
+
- [ ] Scheduled consolidation
|
|
289
248
|
|
|
290
249
|
---
|
|
291
250
|
|
|
@@ -296,10 +255,10 @@ Founder, [199 Biotechnologies](https://199bio.com)
|
|
|
296
255
|
|
|
297
256
|
## License
|
|
298
257
|
|
|
299
|
-
MIT
|
|
258
|
+
MIT
|
|
300
259
|
|
|
301
260
|
---
|
|
302
261
|
|
|
303
262
|
<p align="center">
|
|
304
|
-
<i>Built
|
|
263
|
+
<i>Built by <a href="https://github.com/199-biotechnologies">199 Biotechnologies</a></i>
|
|
305
264
|
</p>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consolidator.d.ts","sourceRoot":"","sources":["../../src/consolidation/consolidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,cAAc,EAAU,MAAM,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"consolidator.d.ts","sourceRoot":"","sources":["../../src/consolidation/consolidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,cAAc,EAAU,MAAM,EAAW,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AA0FtD,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,MAAM,CAA6B;gBAGzC,EAAE,EAAE,cAAc,EAClB,KAAK,CAAC,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,YAAY;IAYvB,YAAY,IAAI,OAAO;IAIvB;;;OAGG;IACG,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC;QAC3D,cAAc,EAAE,MAAM,CAAC;QACvB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IAwEF;;OAEG;YACW,gBAAgB;IAoE9B;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAuHjE;;OAEG;IACH,SAAS,IAAI;QACX,UAAU,EAAE,OAAO,CAAC;QACpB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC;QACrB,wBAAwB,EAAE,MAAM,CAAC;KAClC;IAeD;;;OAGG;IACG,mBAAmB,CAAC,OAAO,GAAE;QACjC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC;QACf,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IAwFF;;OAEG;YACW,2BAA2B;IAqDzC;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;CAkBH"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { KnowledgeGraph } from "./graph/knowledge-graph.js";
|
|
|
15
15
|
import { createRetriever } from "./retrieval/colbert.js";
|
|
16
16
|
import { HybridSearch } from "./retrieval/hybrid.js";
|
|
17
17
|
import { EngramWebServer } from "./web/server.js";
|
|
18
|
+
import { Consolidator } from "./consolidation/consolidator.js";
|
|
18
19
|
// ============ Configuration ============
|
|
19
20
|
const DB_PATH = process.env.ENGRAM_DB_PATH
|
|
20
21
|
? path.resolve(process.env.ENGRAM_DB_PATH.replace("~", os.homedir()))
|
|
@@ -24,6 +25,7 @@ const DB_FILE = path.join(DB_PATH, "engram.db");
|
|
|
24
25
|
let db;
|
|
25
26
|
let graph;
|
|
26
27
|
let search;
|
|
28
|
+
let consolidator;
|
|
27
29
|
let webServer = null;
|
|
28
30
|
async function initialize() {
|
|
29
31
|
console.error(`[Engram] Initializing with database at ${DB_FILE}`);
|
|
@@ -31,6 +33,7 @@ async function initialize() {
|
|
|
31
33
|
graph = new KnowledgeGraph(db);
|
|
32
34
|
const retriever = await createRetriever(DB_PATH);
|
|
33
35
|
search = new HybridSearch(db, graph, retriever);
|
|
36
|
+
consolidator = new Consolidator(db, graph, search);
|
|
34
37
|
// Rebuild index with existing memories
|
|
35
38
|
const stats = db.getStats();
|
|
36
39
|
if (stats.memories > 0) {
|
|
@@ -38,11 +41,14 @@ async function initialize() {
|
|
|
38
41
|
await search.rebuildIndex();
|
|
39
42
|
}
|
|
40
43
|
console.error(`[Engram] Ready. Stats: ${JSON.stringify(stats)}`);
|
|
44
|
+
if (consolidator.isConfigured()) {
|
|
45
|
+
console.error(`[Engram] Consolidation enabled (ANTHROPIC_API_KEY found)`);
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
48
|
// ============ MCP Server ============
|
|
43
49
|
const server = new Server({
|
|
44
50
|
name: "engram",
|
|
45
|
-
version: "0.
|
|
51
|
+
version: "0.6.0",
|
|
46
52
|
}, {
|
|
47
53
|
capabilities: {
|
|
48
54
|
tools: {},
|
|
@@ -68,6 +74,17 @@ const TOOLS = [
|
|
|
68
74
|
maximum: 1,
|
|
69
75
|
default: 0.5,
|
|
70
76
|
},
|
|
77
|
+
emotional_weight: {
|
|
78
|
+
type: "number",
|
|
79
|
+
description: "0-1 emotional significance. Use 0.8+ for emotionally charged content, celebrations, losses. Affects memory retention.",
|
|
80
|
+
minimum: 0,
|
|
81
|
+
maximum: 1,
|
|
82
|
+
default: 0.5,
|
|
83
|
+
},
|
|
84
|
+
event_time: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "When the event actually happened (ISO 8601), if different from now. E.g., 'Last week I went to Paris' → set event_time to that date.",
|
|
87
|
+
},
|
|
71
88
|
entities: {
|
|
72
89
|
type: "array",
|
|
73
90
|
description: "Key entities mentioned (people, organizations, places). Only include clear, specific named entities.",
|
|
@@ -177,6 +194,28 @@ const TOOLS = [
|
|
|
177
194
|
openWorldHint: true,
|
|
178
195
|
},
|
|
179
196
|
},
|
|
197
|
+
{
|
|
198
|
+
name: "consolidate",
|
|
199
|
+
description: "Run memory consolidation to compress episodes into memories and memories into digests. Like sleep for the memory system. Use periodically or when requested.",
|
|
200
|
+
inputSchema: {
|
|
201
|
+
type: "object",
|
|
202
|
+
properties: {
|
|
203
|
+
mode: {
|
|
204
|
+
type: "string",
|
|
205
|
+
enum: ["full", "episodes_only", "memories_only"],
|
|
206
|
+
description: "What to consolidate: 'full' (default) runs everything, 'episodes_only' just processes conversation history, 'memories_only' creates digests",
|
|
207
|
+
default: "full",
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
annotations: {
|
|
212
|
+
title: "Consolidate Memories",
|
|
213
|
+
readOnlyHint: false,
|
|
214
|
+
destructiveHint: false,
|
|
215
|
+
idempotentHint: false,
|
|
216
|
+
openWorldHint: false,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
180
219
|
];
|
|
181
220
|
// List available tools
|
|
182
221
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
@@ -188,9 +227,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
188
227
|
try {
|
|
189
228
|
switch (name) {
|
|
190
229
|
case "remember": {
|
|
191
|
-
const { content, source = "conversation", importance = 0.5, entities: providedEntities = [], relationships: providedRelationships = [], } = args;
|
|
192
|
-
// Create memory
|
|
193
|
-
const memory = db.createMemory(content, source, importance
|
|
230
|
+
const { content, source = "conversation", importance = 0.5, emotional_weight = 0.5, event_time, entities: providedEntities = [], relationships: providedRelationships = [], } = args;
|
|
231
|
+
// Create memory with new temporal and salience fields
|
|
232
|
+
const memory = db.createMemory(content, source, importance, {
|
|
233
|
+
eventTime: event_time ? new Date(event_time) : undefined,
|
|
234
|
+
emotionalWeight: emotional_weight,
|
|
235
|
+
});
|
|
194
236
|
// Index for semantic search
|
|
195
237
|
await search.indexMemory(memory);
|
|
196
238
|
// Store Claude-provided entities and link to memory
|
|
@@ -241,6 +283,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
241
283
|
source: r.memory.source,
|
|
242
284
|
timestamp: r.memory.timestamp.toISOString(),
|
|
243
285
|
relevance_score: r.score.toFixed(4),
|
|
286
|
+
retention: r.retention.toFixed(2), // How well-retained (0-1)
|
|
244
287
|
matched_via: Object.entries(r.sources)
|
|
245
288
|
.filter(([, v]) => v !== undefined)
|
|
246
289
|
.map(([k]) => k)
|
|
@@ -305,6 +348,48 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
305
348
|
],
|
|
306
349
|
};
|
|
307
350
|
}
|
|
351
|
+
case "consolidate": {
|
|
352
|
+
const { mode = "full" } = args;
|
|
353
|
+
if (!consolidator.isConfigured()) {
|
|
354
|
+
return {
|
|
355
|
+
content: [
|
|
356
|
+
{
|
|
357
|
+
type: "text",
|
|
358
|
+
text: JSON.stringify({
|
|
359
|
+
success: false,
|
|
360
|
+
error: "Consolidation requires ANTHROPIC_API_KEY environment variable",
|
|
361
|
+
}),
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
isError: true,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
let result;
|
|
368
|
+
switch (mode) {
|
|
369
|
+
case "episodes_only":
|
|
370
|
+
result = await consolidator.consolidateEpisodes();
|
|
371
|
+
break;
|
|
372
|
+
case "memories_only":
|
|
373
|
+
result = await consolidator.consolidate();
|
|
374
|
+
break;
|
|
375
|
+
case "full":
|
|
376
|
+
default:
|
|
377
|
+
result = await consolidator.runSleepCycle();
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
return {
|
|
381
|
+
content: [
|
|
382
|
+
{
|
|
383
|
+
type: "text",
|
|
384
|
+
text: JSON.stringify({
|
|
385
|
+
success: true,
|
|
386
|
+
mode,
|
|
387
|
+
...result,
|
|
388
|
+
}, null, 2),
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
};
|
|
392
|
+
}
|
|
308
393
|
default:
|
|
309
394
|
throw new Error(`Unknown tool: ${name}`);
|
|
310
395
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/retrieval/hybrid.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hybrid.d.ts","sourceRoot":"","sources":["../../src/retrieval/hybrid.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAA0B,MAAM,cAAc,CAAC;AAEzF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAwDD,qBAAa,YAAY;IAErB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,SAAS;gBAFT,EAAE,EAAE,cAAc,EAClB,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,gBAAgB,GAAG,eAAe;IAGvD;;;;;OAKG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,OAAO,CAAC;KACnB,GACL,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAyIhC;;OAEG;YACW,UAAU;IASxB;;OAEG;YACW,cAAc;IAS5B;;OAEG;YACW,WAAW;IAmBzB;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAYhD;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGvD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"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"}
|