@cartisien/engram 0.2.0 → 0.3.0
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 +78 -211
- package/dist/index.d.ts +68 -118
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +304 -437
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/dist/example/temporal-demo.js +0 -91
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Engram
|
|
2
2
|
|
|
3
|
-
> **Persistent memory for AI
|
|
3
|
+
> **Persistent semantic memory for AI agents.**
|
|
4
4
|
|
|
5
5
|
```typescript
|
|
6
6
|
import { Engram } from '@cartisien/engram';
|
|
@@ -8,11 +8,11 @@ import { Engram } from '@cartisien/engram';
|
|
|
8
8
|
const memory = new Engram({ dbPath: './memory.db' });
|
|
9
9
|
|
|
10
10
|
// Store
|
|
11
|
-
await memory.remember('user_123', '
|
|
11
|
+
await memory.remember('user_123', 'User prefers TypeScript and dark mode', 'user');
|
|
12
12
|
|
|
13
|
-
// Recall
|
|
14
|
-
const
|
|
15
|
-
|
|
13
|
+
// Recall semantically — finds the right memory even without exact keyword match
|
|
14
|
+
const context = await memory.recall('user_123', 'what are the user\'s preferences?', 5);
|
|
15
|
+
// [{ content: 'User prefers TypeScript and dark mode', similarity: 0.82, ... }]
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
---
|
|
@@ -21,16 +21,16 @@ const lastWeek = await memory.recallByTime('user_123', 'last week');
|
|
|
21
21
|
|
|
22
22
|
AI assistants are amnesiacs. Every conversation starts fresh. Context windows fill up. Important details get lost.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Stuffing everything into the system prompt wastes tokens and still misses things. You need a retrieval layer — not a dump.
|
|
25
25
|
|
|
26
26
|
## The Solution
|
|
27
27
|
|
|
28
|
-
Engram gives your
|
|
28
|
+
Engram gives your agents **persistent, semantically searchable memory** — SQLite-backed, TypeScript-first, zero config.
|
|
29
29
|
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
33
|
-
- **
|
|
30
|
+
- **Semantic search:** Finds relevant memories by meaning, not just keywords (via local Ollama embeddings)
|
|
31
|
+
- **Zero config:** Works out of the box, falls back to keyword search without Ollama
|
|
32
|
+
- **Local-first:** Your data stays on your machine. No API keys, no cloud required
|
|
33
|
+
- **MCP-native:** Drop into Claude Desktop or Cursor via [`@cartisien/engram-mcp`](https://github.com/Cartisien/engram-mcp)
|
|
34
34
|
- **Typed:** Full TypeScript support
|
|
35
35
|
|
|
36
36
|
## Installation
|
|
@@ -39,195 +39,79 @@ Engram gives your assistants **persistent, queryable memory** — backed by SQLi
|
|
|
39
39
|
npm install @cartisien/engram
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
### Optional: Local Embeddings (Recommended)
|
|
43
|
+
|
|
44
|
+
For semantic search, install [Ollama](https://ollama.ai) and pull the embedding model:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
ollama pull nomic-embed-text
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Without Ollama, Engram falls back to keyword search automatically.
|
|
51
|
+
|
|
42
52
|
## Quick Start
|
|
43
53
|
|
|
44
54
|
```typescript
|
|
45
55
|
import { Engram } from '@cartisien/engram';
|
|
46
56
|
|
|
47
57
|
const memory = new Engram({
|
|
48
|
-
dbPath: './bot-memory.db'
|
|
58
|
+
dbPath: './bot-memory.db',
|
|
59
|
+
embeddingUrl: 'http://localhost:11434', // Ollama default
|
|
49
60
|
});
|
|
50
61
|
|
|
51
|
-
// In your chat handler
|
|
52
|
-
async function
|
|
53
|
-
// 1.
|
|
54
|
-
await memory.remember(sessionId, message, 'user');
|
|
55
|
-
|
|
56
|
-
// 2. Retrieve relevant context
|
|
62
|
+
// In your agent/chat handler
|
|
63
|
+
async function handleMessage(sessionId: string, message: string) {
|
|
64
|
+
// 1. Recall relevant context semantically
|
|
57
65
|
const context = await memory.recall(sessionId, message, 5);
|
|
58
|
-
|
|
59
|
-
//
|
|
66
|
+
|
|
67
|
+
// 2. Build prompt with memory
|
|
60
68
|
const prompt = buildPrompt(context, message);
|
|
61
|
-
|
|
62
|
-
// 4. Get AI response
|
|
63
|
-
const response = await openai.chat.completions.create({ messages: prompt });
|
|
64
|
-
|
|
65
|
-
// 5. Store the response
|
|
66
|
-
await memory.remember(sessionId, response.choices[0].message.content, 'assistant');
|
|
67
|
-
|
|
68
|
-
return response;
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
// 3. Get AI response
|
|
71
|
+
const response = await llm.chat(prompt);
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
// 4. Store both sides
|
|
74
|
+
await memory.remember(sessionId, message, 'user');
|
|
75
|
+
await memory.remember(sessionId, response, 'assistant');
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const yesterday = await memory.recallByTime('session_123', 'yesterday');
|
|
79
|
-
const lastWeek = await memory.recallByTime('session_123', 'last week');
|
|
80
|
-
const threeDaysAgo = await memory.recallByTime('session_123', '3 days ago');
|
|
81
|
-
|
|
82
|
-
// Combined with keyword search
|
|
83
|
-
const meetingsLastWeek = await memory.recallByTime(
|
|
84
|
-
'session_123',
|
|
85
|
-
'last week',
|
|
86
|
-
'meeting' // Only entries containing "meeting"
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
// Recent memories (last 7 days)
|
|
90
|
-
const recent = await memory.recallRecent('session_123', 7);
|
|
91
|
-
|
|
92
|
-
// Since a specific date
|
|
93
|
-
const sinceLaunch = await memory.recallSince('session_123', new Date('2024-01-01'));
|
|
94
|
-
|
|
95
|
-
// Daily summaries
|
|
96
|
-
const lastWeekByDay = await memory.dailySummary('session_123', 7);
|
|
97
|
-
// Returns: [{ date, entries: [...], count }, ...]
|
|
77
|
+
return response;
|
|
78
|
+
}
|
|
98
79
|
```
|
|
99
80
|
|
|
100
|
-
### Supported Temporal Expressions
|
|
101
|
-
|
|
102
|
-
| Expression | Meaning |
|
|
103
|
-
|------------|---------|
|
|
104
|
-
| `today` | From midnight to now |
|
|
105
|
-
| `yesterday` | Full previous day |
|
|
106
|
-
| `tomorrow` | Next day (useful for scheduled items) |
|
|
107
|
-
| `3 days ago` | Specific day 3 days back |
|
|
108
|
-
| `a week ago` | 7 days ago |
|
|
109
|
-
| `2 weeks ago` | 14 days ago |
|
|
110
|
-
| `last monday` | Most recent Monday |
|
|
111
|
-
| `last week` | Previous full week (Sun-Sat) |
|
|
112
|
-
| `last month` | Previous full month |
|
|
113
|
-
| `this week` | Current week (Sun-today) |
|
|
114
|
-
| `this month` | Current month |
|
|
115
|
-
| `last 3 days` | Last 72 hours |
|
|
116
|
-
| `last 7 days` | Last week (rolling) |
|
|
117
|
-
| `january 15` | Specific date |
|
|
118
|
-
| `3/15` | March 15 (current year) |
|
|
119
|
-
| `jan 15 to jan 20` | Date range |
|
|
120
|
-
| `recent`, `lately` | Last 7 days |
|
|
121
|
-
|
|
122
81
|
## API
|
|
123
82
|
|
|
124
83
|
### `new Engram(config?)`
|
|
125
84
|
|
|
126
|
-
Create a memory instance.
|
|
127
|
-
|
|
128
85
|
```typescript
|
|
129
86
|
const memory = new Engram({
|
|
130
|
-
dbPath: './memory.db',
|
|
131
|
-
maxContextLength: 4000
|
|
87
|
+
dbPath: './memory.db', // SQLite file path (default: ':memory:')
|
|
88
|
+
maxContextLength: 4000, // Max chars per entry (default: 4000)
|
|
89
|
+
embeddingUrl: 'http://localhost:11434', // Ollama base URL
|
|
90
|
+
embeddingModel: 'nomic-embed-text', // Embedding model
|
|
91
|
+
semanticSearch: true, // Enable semantic search (default: true)
|
|
132
92
|
});
|
|
133
93
|
```
|
|
134
94
|
|
|
135
95
|
### `remember(sessionId, content, role?, metadata?)`
|
|
136
96
|
|
|
137
|
-
Store a memory
|
|
97
|
+
Store a memory. Embedding is generated automatically.
|
|
138
98
|
|
|
139
99
|
```typescript
|
|
140
|
-
await memory.remember('session_abc', 'User loves Thai food', 'user'
|
|
141
|
-
source: 'preference_extraction'
|
|
142
|
-
});
|
|
100
|
+
await memory.remember('session_abc', 'User loves Thai food', 'user');
|
|
143
101
|
```
|
|
144
102
|
|
|
145
103
|
### `recall(sessionId, query?, limit?, options?)`
|
|
146
104
|
|
|
147
|
-
Retrieve memories
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
// Recent memories
|
|
151
|
-
const recent = await memory.recall('session_abc', undefined, 10);
|
|
152
|
-
|
|
153
|
-
// Keyword search
|
|
154
|
-
const relevant = await memory.recall('session_abc', 'food preferences', 5);
|
|
155
|
-
|
|
156
|
-
// Temporal + keyword
|
|
157
|
-
const yesterdayMeetings = await memory.recall(
|
|
158
|
-
'session_abc',
|
|
159
|
-
'meeting',
|
|
160
|
-
10,
|
|
161
|
-
{ temporalQuery: 'yesterday' }
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
// Filtered by role
|
|
165
|
-
const userOnly = await memory.recall('session_abc', undefined, 10, { role: 'user' });
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### `recallByTime(sessionId, temporalQuery, keyword?, limit?, options?)`
|
|
169
|
-
|
|
170
|
-
Recall memories by natural language time expression.
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
const { entries, range } = await memory.recallByTime(
|
|
174
|
-
'session_abc',
|
|
175
|
-
'last week',
|
|
176
|
-
'project update' // optional keyword filter
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
console.log(`Found ${entries.length} entries from ${range.description}`);
|
|
180
|
-
console.log(`Range: ${range.start.toDateString()} to ${range.end.toDateString()}`);
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### `recallRecent(sessionId, days?, keyword?, limit?, options?)`
|
|
184
|
-
|
|
185
|
-
Get memories from the last N days.
|
|
105
|
+
Retrieve relevant memories. Uses semantic search when available, keyword fallback otherwise. Returns entries sorted by similarity score.
|
|
186
106
|
|
|
187
107
|
```typescript
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### `recallSince(sessionId, since, keyword?, limit?, options?)`
|
|
193
|
-
|
|
194
|
-
Get memories since a specific date.
|
|
195
|
-
|
|
196
|
-
```typescript
|
|
197
|
-
const { entries, count } = await memory.recallSince(
|
|
198
|
-
'session_abc',
|
|
199
|
-
new Date('2024-01-01')
|
|
200
|
-
);
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### `recallBetween(sessionId, start, end, keyword?, limit?, options?)`
|
|
204
|
-
|
|
205
|
-
Get memories between two dates.
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
|
-
const { entries, count } = await memory.recallBetween(
|
|
209
|
-
'session_abc',
|
|
210
|
-
new Date('2024-01-01'),
|
|
211
|
-
new Date('2024-01-31')
|
|
212
|
-
);
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### `dailySummary(sessionId, days?)`
|
|
216
|
-
|
|
217
|
-
Get memories grouped by day.
|
|
218
|
-
|
|
219
|
-
```typescript
|
|
220
|
-
const summary = await memory.dailySummary('session_abc', 7);
|
|
221
|
-
// [
|
|
222
|
-
// { date: Date, entries: MemoryEntry[], count: 5 },
|
|
223
|
-
// { date: Date, entries: MemoryEntry[], count: 3 },
|
|
224
|
-
// ...
|
|
225
|
-
// ]
|
|
108
|
+
const results = await memory.recall('session_abc', 'food preferences', 5);
|
|
109
|
+
// [{ content: '...', similarity: 0.84, ... }]
|
|
226
110
|
```
|
|
227
111
|
|
|
228
112
|
### `history(sessionId, limit?)`
|
|
229
113
|
|
|
230
|
-
|
|
114
|
+
Chronological conversation history.
|
|
231
115
|
|
|
232
116
|
```typescript
|
|
233
117
|
const chat = await memory.history('session_abc', 20);
|
|
@@ -238,86 +122,69 @@ const chat = await memory.history('session_abc', 20);
|
|
|
238
122
|
Delete memories.
|
|
239
123
|
|
|
240
124
|
```typescript
|
|
241
|
-
//
|
|
242
|
-
await memory.forget('session_abc');
|
|
243
|
-
|
|
244
|
-
// Delete specific entry
|
|
245
|
-
await memory.forget('session_abc', { id: 'entry_id' });
|
|
246
|
-
|
|
247
|
-
// Delete before a date
|
|
248
|
-
await memory.forget('session_abc', { before: new Date('2024-01-01') });
|
|
249
|
-
|
|
250
|
-
// Delete in a date range
|
|
251
|
-
await memory.forget('session_abc', {
|
|
252
|
-
after: new Date('2024-01-01'),
|
|
253
|
-
before: new Date('2024-02-01')
|
|
254
|
-
});
|
|
125
|
+
await memory.forget('session_abc'); // all
|
|
126
|
+
await memory.forget('session_abc', { id: 'entry_id' }); // one
|
|
127
|
+
await memory.forget('session_abc', { before: new Date() }); // old entries
|
|
255
128
|
```
|
|
256
129
|
|
|
257
130
|
### `stats(sessionId)`
|
|
258
131
|
|
|
259
|
-
Get memory statistics.
|
|
260
|
-
|
|
261
132
|
```typescript
|
|
262
133
|
const stats = await memory.stats('session_abc');
|
|
263
|
-
// { total: 42, byRole: { user: 21, assistant: 21 },
|
|
134
|
+
// { total: 42, byRole: { user: 21, assistant: 21 }, withEmbeddings: 42, ... }
|
|
264
135
|
```
|
|
265
136
|
|
|
266
|
-
|
|
137
|
+
## MCP Server
|
|
267
138
|
|
|
268
|
-
|
|
139
|
+
Use Engram directly in Claude Desktop, Cursor, or any MCP client:
|
|
269
140
|
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
// [
|
|
273
|
-
// { date: '2024-01-15', count: 5, byRole: { user: 3, assistant: 2 } },
|
|
274
|
-
// ...
|
|
275
|
-
// ]
|
|
141
|
+
```bash
|
|
142
|
+
npx -y @cartisien/engram-mcp
|
|
276
143
|
```
|
|
277
144
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const range = parser.parse('last week');
|
|
287
|
-
|
|
288
|
-
if (range) {
|
|
289
|
-
console.log(range.description); // "last week"
|
|
290
|
-
console.log(range.start); // Sun, Jan 07 2024 00:00:00
|
|
291
|
-
console.log(range.end); // Sat, Jan 13 2024 23:59:59
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"mcpServers": {
|
|
148
|
+
"engram": {
|
|
149
|
+
"command": "npx",
|
|
150
|
+
"args": ["-y", "@cartisien/engram-mcp"]
|
|
151
|
+
}
|
|
152
|
+
}
|
|
292
153
|
}
|
|
293
154
|
```
|
|
294
155
|
|
|
156
|
+
→ [`@cartisien/engram-mcp`](https://github.com/Cartisien/engram-mcp) on GitHub
|
|
157
|
+
|
|
295
158
|
## Philosophy
|
|
296
159
|
|
|
297
|
-
> *"The trace precedes presence."*
|
|
160
|
+
> *"The trace precedes presence."*
|
|
298
161
|
|
|
299
162
|
Memory isn't storage. It's the substrate of self.
|
|
300
163
|
|
|
301
|
-
Engram doesn't just persist data
|
|
164
|
+
Engram doesn't just persist data — it gives your agents **continuity**. The ability to learn, reference, and grow across conversations.
|
|
302
165
|
|
|
303
|
-
|
|
166
|
+
## Roadmap
|
|
304
167
|
|
|
305
|
-
|
|
168
|
+
- **v0.1** ✅ SQLite persistence, keyword search
|
|
169
|
+
- **v0.2** ✅ Semantic search via local Ollama embeddings
|
|
170
|
+
- **v0.3** 🚧 Graph memory — entity relationships, connected context
|
|
171
|
+
- **v0.4** 📋 Memory consolidation, long-term summarization
|
|
306
172
|
|
|
307
|
-
|
|
173
|
+
## The Cartisien Memory Suite
|
|
308
174
|
|
|
309
175
|
| Package | Purpose |
|
|
310
176
|
|---------|---------|
|
|
311
|
-
| `@cartisien/engram` |
|
|
312
|
-
| `@cartisien/
|
|
313
|
-
| `@cartisien/
|
|
177
|
+
| [`@cartisien/engram`](https://github.com/Cartisien/engram) | Persistent memory SDK — **this package** |
|
|
178
|
+
| [`@cartisien/engram-mcp`](https://github.com/Cartisien/engram-mcp) | MCP server for Claude Desktop / Cursor |
|
|
179
|
+
| `@cartisien/extensa` | Vector infrastructure *(coming soon)* |
|
|
180
|
+
| `@cartisien/cogito` | Agent identity & lifecycle *(coming soon)* |
|
|
314
181
|
|
|
315
182
|
*Res cogitans meets res extensa.*
|
|
316
183
|
|
|
317
184
|
## License
|
|
318
185
|
|
|
319
|
-
MIT © Cartisien Interactive
|
|
186
|
+
MIT © [Cartisien Interactive](https://cartisien.com)
|
|
320
187
|
|
|
321
188
|
---
|
|
322
189
|
|
|
323
|
-
**Built
|
|
190
|
+
**Built for people who think forgetting is a bug.**
|
package/dist/index.d.ts
CHANGED
|
@@ -5,69 +5,60 @@ export interface MemoryEntry {
|
|
|
5
5
|
role: 'user' | 'assistant' | 'system';
|
|
6
6
|
timestamp: Date;
|
|
7
7
|
metadata?: Record<string, unknown>;
|
|
8
|
+
similarity?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface GraphNode {
|
|
11
|
+
entity: string;
|
|
12
|
+
type?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface GraphEdge {
|
|
15
|
+
from: string;
|
|
16
|
+
relation: string;
|
|
17
|
+
to: string;
|
|
18
|
+
confidence?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface GraphResult {
|
|
21
|
+
entity: string;
|
|
22
|
+
relationships: Array<{
|
|
23
|
+
type: 'outgoing' | 'incoming';
|
|
24
|
+
relation: string;
|
|
25
|
+
target: string;
|
|
26
|
+
confidence?: number;
|
|
27
|
+
}>;
|
|
28
|
+
relatedMemories: MemoryEntry[];
|
|
8
29
|
}
|
|
9
30
|
export interface RecallOptions {
|
|
10
31
|
limit?: number;
|
|
11
32
|
before?: Date;
|
|
12
33
|
after?: Date;
|
|
13
34
|
role?: 'user' | 'assistant' | 'system';
|
|
14
|
-
|
|
15
|
-
export interface TemporalRecallOptions extends RecallOptions {
|
|
16
|
-
/** Natural language time expression: 'yesterday', 'last week', '3 days ago', etc. */
|
|
17
|
-
temporalQuery?: string;
|
|
18
|
-
/** Timezone offset in minutes from UTC (default: local timezone) */
|
|
19
|
-
timezoneOffset?: number;
|
|
20
|
-
}
|
|
21
|
-
export interface TimeRange {
|
|
22
|
-
start: Date;
|
|
23
|
-
end: Date;
|
|
24
|
-
description: string;
|
|
35
|
+
includeGraph?: boolean;
|
|
25
36
|
}
|
|
26
37
|
export interface EngramConfig {
|
|
27
38
|
dbPath?: string;
|
|
28
39
|
maxContextLength?: number;
|
|
40
|
+
embeddingUrl?: string;
|
|
41
|
+
embeddingModel?: string;
|
|
42
|
+
semanticSearch?: boolean;
|
|
43
|
+
graphMemory?: boolean;
|
|
44
|
+
graphModel?: string;
|
|
29
45
|
}
|
|
30
46
|
/**
|
|
31
|
-
*
|
|
32
|
-
*/
|
|
33
|
-
export declare class TemporalQuery {
|
|
34
|
-
private referenceDate;
|
|
35
|
-
private timezoneOffset;
|
|
36
|
-
constructor(referenceDate?: Date, timezoneOffset?: number);
|
|
37
|
-
/**
|
|
38
|
-
* Parse a natural language time expression into a concrete time range
|
|
39
|
-
*
|
|
40
|
-
* Supports:
|
|
41
|
-
* - Relative: 'today', 'yesterday', 'tomorrow'
|
|
42
|
-
* - Days ago: '3 days ago', 'a week ago', '2 weeks ago'
|
|
43
|
-
* - Last: 'last monday', 'last week', 'last month'
|
|
44
|
-
* - This: 'this week', 'this month', 'this year'
|
|
45
|
-
* - Recent: 'recent', 'lately', 'recently' (last 7 days)
|
|
46
|
-
* - Between: 'january 15 to january 20', '3/1 to 3/15'
|
|
47
|
-
*/
|
|
48
|
-
parse(expression: string): TimeRange | null;
|
|
49
|
-
private parseDate;
|
|
50
|
-
private startOfDay;
|
|
51
|
-
private endOfDay;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Engram - Persistent memory for AI assistants
|
|
47
|
+
* Engram - Persistent semantic memory for AI agents
|
|
55
48
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
49
|
+
* v0.3 adds graph memory — entity relationships extracted from memories
|
|
50
|
+
* using a local LLM, enabling richer contextual recall.
|
|
58
51
|
*
|
|
59
52
|
* @example
|
|
60
53
|
* ```typescript
|
|
61
54
|
* import { Engram } from '@cartisien/engram';
|
|
62
55
|
*
|
|
63
|
-
* const memory = new Engram({ dbPath: './memory.db' });
|
|
64
|
-
*
|
|
65
|
-
* // Store a memory
|
|
66
|
-
* await memory.remember('user_123', 'Jeff loves Triumph motorcycles', 'user');
|
|
56
|
+
* const memory = new Engram({ dbPath: './memory.db', graphMemory: true });
|
|
67
57
|
*
|
|
68
|
-
*
|
|
69
|
-
* const
|
|
70
|
-
* const
|
|
58
|
+
* await memory.remember('session_1', 'Jeff is building GovScout in React 19', 'user');
|
|
59
|
+
* const context = await memory.recall('session_1', 'what is Jeff building?', 5);
|
|
60
|
+
* const graph = await memory.graph('session_1', 'GovScout');
|
|
61
|
+
* // → { entity: 'GovScout', relationships: [{ relation: 'built_with', target: 'React 19' }], ... }
|
|
71
62
|
* ```
|
|
72
63
|
*/
|
|
73
64
|
export declare class Engram {
|
|
@@ -75,113 +66,72 @@ export declare class Engram {
|
|
|
75
66
|
private maxContextLength;
|
|
76
67
|
private dbPath;
|
|
77
68
|
private initialized;
|
|
69
|
+
private embeddingUrl;
|
|
70
|
+
private embeddingModel;
|
|
71
|
+
private semanticSearch;
|
|
72
|
+
private graphMemory;
|
|
73
|
+
private graphModel;
|
|
78
74
|
constructor(config?: EngramConfig);
|
|
79
75
|
private init;
|
|
80
76
|
/**
|
|
81
|
-
*
|
|
77
|
+
* Fetch embedding vector from Ollama
|
|
82
78
|
*/
|
|
83
|
-
|
|
79
|
+
private embed;
|
|
84
80
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* Supports temporal queries via options.temporalQuery:
|
|
88
|
-
* - 'yesterday', 'today', 'tomorrow'
|
|
89
|
-
* - '3 days ago', 'a week ago', '2 weeks ago'
|
|
90
|
-
* - 'last monday', 'last week', 'last month'
|
|
91
|
-
* - 'this week', 'this month'
|
|
92
|
-
* - 'last 3 days', 'last week'
|
|
93
|
-
* - 'january 15', '3/15', '2024-01-15'
|
|
94
|
-
* - 'jan 15 to jan 20', '3/1 to 3/15'
|
|
81
|
+
* Extract entity-relationship triples from text using a local LLM
|
|
95
82
|
*/
|
|
96
|
-
|
|
83
|
+
private extractGraph;
|
|
97
84
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```typescript
|
|
102
|
-
* // Get yesterday's memories
|
|
103
|
-
* const yesterday = await memory.recallByTime('session_123', 'yesterday');
|
|
104
|
-
*
|
|
105
|
-
* // Get last week's memories
|
|
106
|
-
* const lastWeek = await memory.recallByTime('session_123', 'last week');
|
|
107
|
-
*
|
|
108
|
-
* // Get memories from 3 days ago
|
|
109
|
-
* const threeDaysAgo = await memory.recallByTime('session_123', '3 days ago');
|
|
110
|
-
* ```
|
|
85
|
+
* Upsert a graph node
|
|
111
86
|
*/
|
|
112
|
-
|
|
113
|
-
entries: MemoryEntry[];
|
|
114
|
-
range: TimeRange;
|
|
115
|
-
}>;
|
|
87
|
+
private upsertNode;
|
|
116
88
|
/**
|
|
117
|
-
*
|
|
89
|
+
* Store a graph edge
|
|
118
90
|
*/
|
|
119
|
-
|
|
120
|
-
entries: MemoryEntry[];
|
|
121
|
-
days: number;
|
|
122
|
-
since: Date;
|
|
123
|
-
}>;
|
|
91
|
+
private storeEdge;
|
|
124
92
|
/**
|
|
125
|
-
*
|
|
93
|
+
* Cosine similarity between two vectors
|
|
126
94
|
*/
|
|
127
|
-
|
|
128
|
-
entries: MemoryEntry[];
|
|
129
|
-
since: Date;
|
|
130
|
-
count: number;
|
|
131
|
-
}>;
|
|
95
|
+
private cosineSimilarity;
|
|
132
96
|
/**
|
|
133
|
-
*
|
|
97
|
+
* Store a memory entry
|
|
134
98
|
*/
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}>;
|
|
99
|
+
remember(sessionId: string, content: string, role?: 'user' | 'assistant' | 'system', metadata?: Record<string, unknown>): Promise<MemoryEntry>;
|
|
100
|
+
/**
|
|
101
|
+
* Recall memories with optional graph traversal
|
|
102
|
+
*/
|
|
103
|
+
recall(sessionId: string, query?: string, limit?: number, options?: RecallOptions): Promise<MemoryEntry[]>;
|
|
141
104
|
/**
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* Returns memories grouped by day, useful for "what happened each day" views
|
|
105
|
+
* Augment recall results with graph-connected memories
|
|
145
106
|
*/
|
|
146
|
-
|
|
147
|
-
date: Date;
|
|
148
|
-
entries: MemoryEntry[];
|
|
149
|
-
count: number;
|
|
150
|
-
}[]>;
|
|
107
|
+
private augmentWithGraph;
|
|
151
108
|
/**
|
|
152
|
-
*
|
|
109
|
+
* v0.3: Query the knowledge graph for an entity
|
|
110
|
+
*/
|
|
111
|
+
graph(sessionId: string, entity: string): Promise<GraphResult>;
|
|
112
|
+
/**
|
|
113
|
+
* Get recent conversation history
|
|
153
114
|
*/
|
|
154
115
|
history(sessionId: string, limit?: number): Promise<MemoryEntry[]>;
|
|
155
116
|
/**
|
|
156
|
-
*
|
|
117
|
+
* Delete memories
|
|
157
118
|
*/
|
|
158
119
|
forget(sessionId: string, options?: {
|
|
159
120
|
before?: Date;
|
|
160
|
-
after?: Date;
|
|
161
121
|
id?: string;
|
|
162
122
|
}): Promise<number>;
|
|
163
123
|
/**
|
|
164
|
-
*
|
|
124
|
+
* Memory statistics
|
|
165
125
|
*/
|
|
166
126
|
stats(sessionId: string): Promise<{
|
|
167
127
|
total: number;
|
|
168
128
|
byRole: Record<string, number>;
|
|
169
129
|
oldest: Date | null;
|
|
170
130
|
newest: Date | null;
|
|
131
|
+
withEmbeddings: number;
|
|
132
|
+
graphNodes?: number;
|
|
133
|
+
graphEdges?: number;
|
|
171
134
|
}>;
|
|
172
|
-
/**
|
|
173
|
-
* Get temporal statistics for a session
|
|
174
|
-
*
|
|
175
|
-
* Returns memory counts grouped by day, useful for activity visualization
|
|
176
|
-
*/
|
|
177
|
-
temporalStats(sessionId: string, days?: number): Promise<{
|
|
178
|
-
date: string;
|
|
179
|
-
count: number;
|
|
180
|
-
byRole: Record<string, number>;
|
|
181
|
-
}[]>;
|
|
182
|
-
/**
|
|
183
|
-
* Close the database connection
|
|
184
|
-
*/
|
|
185
135
|
close(): Promise<void>;
|
|
186
136
|
}
|
|
187
137
|
export default Engram;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|