@cartisien/engram 0.3.0 → 0.4.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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  > **Persistent semantic memory for AI agents.**
4
4
 
5
+ ![Engram demo](assets/demo.gif)
6
+
5
7
  ```typescript
6
8
  import { Engram } from '@cartisien/engram';
7
9
 
@@ -127,11 +129,43 @@ await memory.forget('session_abc', { id: 'entry_id' }); // one
127
129
  await memory.forget('session_abc', { before: new Date() }); // old entries
128
130
  ```
129
131
 
132
+ ### `graph(sessionId, entity)`
133
+
134
+ Returns a one-hop relationship map for a named entity — all connected entities and the memories that link them.
135
+
136
+ Requires `graphMemory: true` in config and a running Ollama instance with `qwen2.5:32b` (or override via `graphModel`).
137
+
138
+ ```typescript
139
+ const memory = new Engram({
140
+ dbPath: './memory.db',
141
+ graphMemory: true,
142
+ graphModel: 'qwen2.5:32b', // default
143
+ });
144
+
145
+ const graph = await memory.graph('session_abc', 'GovScout');
146
+ // {
147
+ // entity: 'GovScout',
148
+ // edges: [
149
+ // { relation: 'uses', target: 'MUI', sourceMemoryId: '...' },
150
+ // { relation: 'built_by', target: 'Jeff', sourceMemoryId: '...' },
151
+ // ],
152
+ // memories: [ { content: '...', ... } ]
153
+ // }
154
+ ```
155
+
156
+ ### `recall()` with graph augmentation
157
+
158
+ ```typescript
159
+ const results = await memory.recall('session_abc', 'what is GovScout?', 5, {
160
+ includeGraph: true, // augment top results with graph-connected memories
161
+ });
162
+ ```
163
+
130
164
  ### `stats(sessionId)`
131
165
 
132
166
  ```typescript
133
167
  const stats = await memory.stats('session_abc');
134
- // { total: 42, byRole: { user: 21, assistant: 21 }, withEmbeddings: 42, ... }
168
+ // { total: 42, byRole: { user: 21, assistant: 21 }, withEmbeddings: 42, graphNodes: 18, graphEdges: 31 }
135
169
  ```
136
170
 
137
171
  ## MCP Server
@@ -167,7 +201,7 @@ Engram doesn't just persist data — it gives your agents **continuity**. The ab
167
201
 
168
202
  - **v0.1** ✅ SQLite persistence, keyword search
169
203
  - **v0.2** ✅ Semantic search via local Ollama embeddings
170
- - **v0.3** 🚧 Graph memory — entity relationships, connected context
204
+ - **v0.3** Graph memory — entity relationships, connected context
171
205
  - **v0.4** 📋 Memory consolidation, long-term summarization
172
206
 
173
207
  ## The Cartisien Memory Suite
@@ -0,0 +1,2 @@
1
+ export type { IMemoryAdapter } from '../types.js';
2
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import type { IMemoryAdapter, Memory, SearchOptions, SearchResult } from '../types.js';
2
+ /**
3
+ * In-process MemoryAdapter — no persistence, ideal for testing and ephemeral agents.
4
+ * The simplest possible trace: exists only as long as the process lives.
5
+ */
6
+ export declare class MemoryAdapter implements IMemoryAdapter {
7
+ private _cache;
8
+ init(): Promise<void>;
9
+ store(memory: Memory): Promise<Memory>;
10
+ get(id: string): Promise<Memory | null>;
11
+ search(embedding: number[], options: Required<SearchOptions>): Promise<SearchResult[]>;
12
+ forget(id: string): Promise<void>;
13
+ list(agentId: string, limit?: number): Promise<Memory[]>;
14
+ close(): Promise<void>;
15
+ get size(): number;
16
+ }
17
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/adapters/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGtF;;;GAGG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,MAAM,CAA4B;IAEpC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKtC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAcvC,MAAM,CACV,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC/B,OAAO,CAAC,YAAY,EAAE,CAAC;IAepB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAOpD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -0,0 +1,58 @@
1
+ import { cosineSimilarity } from '../utils/similarity.js';
2
+ /**
3
+ * In-process MemoryAdapter — no persistence, ideal for testing and ephemeral agents.
4
+ * The simplest possible trace: exists only as long as the process lives.
5
+ */
6
+ export class MemoryAdapter {
7
+ constructor() {
8
+ this._cache = new Map();
9
+ }
10
+ async init() {
11
+ // nothing to set up
12
+ }
13
+ async store(memory) {
14
+ this._cache.set(memory.id, memory);
15
+ return memory;
16
+ }
17
+ async get(id) {
18
+ const memory = this._cache.get(id) ?? null;
19
+ if (memory) {
20
+ const updated = {
21
+ ...memory,
22
+ accessedAt: new Date(),
23
+ accessCount: memory.accessCount + 1,
24
+ };
25
+ this._cache.set(id, updated);
26
+ return updated;
27
+ }
28
+ return null;
29
+ }
30
+ async search(embedding, options) {
31
+ const results = [];
32
+ for (const memory of this._cache.values()) {
33
+ const score = cosineSimilarity(embedding, memory.embedding);
34
+ if (score >= options.threshold) {
35
+ results.push({ memory, score });
36
+ }
37
+ }
38
+ return results
39
+ .sort((a, b) => b.score - a.score)
40
+ .slice(0, options.limit);
41
+ }
42
+ async forget(id) {
43
+ this._cache.delete(id);
44
+ }
45
+ async list(agentId, limit = 50) {
46
+ return [...this._cache.values()]
47
+ .filter((m) => m.agentId === agentId)
48
+ .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
49
+ .slice(0, limit);
50
+ }
51
+ async close() {
52
+ this._cache.clear();
53
+ }
54
+ get size() {
55
+ return this._cache.size;
56
+ }
57
+ }
58
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/adapters/memory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAEzD;;;GAGG;AACH,MAAM,OAAO,aAAa;IAA1B;QACU,WAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;IA6D5C,CAAC;IA3DC,KAAK,CAAC,IAAI;QACR,oBAAoB;IACtB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAc;QACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;QAClC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAA;QAC1C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,OAAO,GAAW;gBACtB,GAAG,MAAM;gBACT,UAAU,EAAE,IAAI,IAAI,EAAE;gBACtB,WAAW,EAAE,MAAM,CAAC,WAAW,GAAG,CAAC;aACpC,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;YAC5B,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAC,MAAM,CACV,SAAmB,EACnB,OAAgC;QAEhC,MAAM,OAAO,GAAmB,EAAE,CAAA;QAElC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,gBAAgB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAA;YAC3D,IAAI,KAAK,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;YACjC,CAAC;QACH,CAAC;QAED,OAAO,OAAO;aACX,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,KAAK,GAAG,EAAE;QACpC,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;aAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC;aACpC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;aAC7D,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACpB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAA;IACzB,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import type { IMemoryAdapter, Memory, SearchOptions, SearchResult } from '../types.js';
2
+ /**
3
+ * PostgresAdapter — uses pgvector for semantic similarity search.
4
+ *
5
+ * TODO: implement with `pg` + pgvector extension.
6
+ * Requires: CREATE EXTENSION IF NOT EXISTS vector;
7
+ *
8
+ * Schema:
9
+ * CREATE TABLE engram_memories (
10
+ * id TEXT PRIMARY KEY,
11
+ * agent_id TEXT NOT NULL,
12
+ * content TEXT NOT NULL,
13
+ * embedding vector(1536),
14
+ * importance FLOAT NOT NULL DEFAULT 0.5,
15
+ * metadata JSONB NOT NULL DEFAULT '{}',
16
+ * created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
17
+ * accessed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
18
+ * access_count INT NOT NULL DEFAULT 0
19
+ * );
20
+ * CREATE INDEX ON engram_memories USING ivfflat (embedding vector_cosine_ops);
21
+ */
22
+ export declare class PostgresAdapter implements IMemoryAdapter {
23
+ private readonly connectionString;
24
+ constructor(connectionString: string);
25
+ init(): Promise<void>;
26
+ store(_memory: Memory): Promise<Memory>;
27
+ get(_id: string): Promise<Memory | null>;
28
+ search(_embedding: number[], _options: Required<SearchOptions>): Promise<SearchResult[]>;
29
+ forget(_id: string): Promise<void>;
30
+ list(_agentId: string, _limit?: number): Promise<Memory[]>;
31
+ close(): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/adapters/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEtF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAgB,YAAW,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAAhB,gBAAgB,EAAE,MAAM;IAE/C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIxC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAIxF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * PostgresAdapter — uses pgvector for semantic similarity search.
3
+ *
4
+ * TODO: implement with `pg` + pgvector extension.
5
+ * Requires: CREATE EXTENSION IF NOT EXISTS vector;
6
+ *
7
+ * Schema:
8
+ * CREATE TABLE engram_memories (
9
+ * id TEXT PRIMARY KEY,
10
+ * agent_id TEXT NOT NULL,
11
+ * content TEXT NOT NULL,
12
+ * embedding vector(1536),
13
+ * importance FLOAT NOT NULL DEFAULT 0.5,
14
+ * metadata JSONB NOT NULL DEFAULT '{}',
15
+ * created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
16
+ * accessed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
17
+ * access_count INT NOT NULL DEFAULT 0
18
+ * );
19
+ * CREATE INDEX ON engram_memories USING ivfflat (embedding vector_cosine_ops);
20
+ */
21
+ export class PostgresAdapter {
22
+ constructor(connectionString) {
23
+ this.connectionString = connectionString;
24
+ }
25
+ async init() {
26
+ throw new Error('PostgresAdapter not yet implemented. Use MemoryAdapter for now.');
27
+ }
28
+ async store(_memory) {
29
+ throw new Error('Not implemented');
30
+ }
31
+ async get(_id) {
32
+ throw new Error('Not implemented');
33
+ }
34
+ async search(_embedding, _options) {
35
+ throw new Error('Not implemented');
36
+ }
37
+ async forget(_id) {
38
+ throw new Error('Not implemented');
39
+ }
40
+ async list(_agentId, _limit) {
41
+ throw new Error('Not implemented');
42
+ }
43
+ async close() {
44
+ // no-op until implemented
45
+ }
46
+ }
47
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/adapters/postgres.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,eAAe;IAC1B,YAA6B,gBAAwB;QAAxB,qBAAgB,GAAhB,gBAAgB,CAAQ;IAAG,CAAC;IAEzD,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;IACpF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAe;QACzB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAoB,EAAE,QAAiC;QAClE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,MAAe;QAC1C,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,0BAA0B;IAC5B,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import type { IMemoryAdapter, Memory, SearchOptions, SearchResult } from '../types.js';
2
+ /**
3
+ * SqliteAdapter — local file-backed persistence with vector search.
4
+ *
5
+ * TODO: implement with `better-sqlite3` + manual cosine similarity
6
+ * (sqlite-vss or sqlite-vec extension optional).
7
+ */
8
+ export declare class SqliteAdapter implements IMemoryAdapter {
9
+ private readonly filePath;
10
+ constructor(filePath: string);
11
+ init(): Promise<void>;
12
+ store(_memory: Memory): Promise<Memory>;
13
+ get(_id: string): Promise<Memory | null>;
14
+ search(_embedding: number[], _options: Required<SearchOptions>): Promise<SearchResult[]>;
15
+ forget(_id: string): Promise<void>;
16
+ list(_agentId: string, _limit?: number): Promise<Memory[]>;
17
+ close(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEtF;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,cAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEvC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIxC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAIxF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * SqliteAdapter — local file-backed persistence with vector search.
3
+ *
4
+ * TODO: implement with `better-sqlite3` + manual cosine similarity
5
+ * (sqlite-vss or sqlite-vec extension optional).
6
+ */
7
+ export class SqliteAdapter {
8
+ constructor(filePath) {
9
+ this.filePath = filePath;
10
+ }
11
+ async init() {
12
+ throw new Error('SqliteAdapter not yet implemented. Use MemoryAdapter for now.');
13
+ }
14
+ async store(_memory) {
15
+ throw new Error('Not implemented');
16
+ }
17
+ async get(_id) {
18
+ throw new Error('Not implemented');
19
+ }
20
+ async search(_embedding, _options) {
21
+ throw new Error('Not implemented');
22
+ }
23
+ async forget(_id) {
24
+ throw new Error('Not implemented');
25
+ }
26
+ async list(_agentId, _limit) {
27
+ throw new Error('Not implemented');
28
+ }
29
+ async close() {
30
+ // no-op until implemented
31
+ }
32
+ }
33
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IACxB,YAA6B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAEjD,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAA;IAClF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAe;QACzB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAoB,EAAE,QAAiC;QAClE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,MAAe;QAC1C,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,0BAA0B;IAC5B,CAAC;CACF"}
@@ -0,0 +1,57 @@
1
+ import type { EngramConfig, Memory, MemoryInput, SearchOptions, SearchResult } from './types.js';
2
+ /**
3
+ * Engram — persistent semantic memory for AI agents.
4
+ *
5
+ * "We no longer live in the age of cogito. We live in the age of the trace."
6
+ * — Derrida (via Orlo Rodriguez, "I Compute, Therefore Am I?")
7
+ *
8
+ * Usage:
9
+ * const mem = new Engram({ adapter: 'memory', agentId: 'my-agent' })
10
+ * await mem.wake()
11
+ * await mem.store({ content: 'The user prefers dark mode' })
12
+ * const results = await mem.search('user preferences')
13
+ * await mem.sleep()
14
+ */
15
+ export declare class Engram {
16
+ private adapter;
17
+ private readonly config;
18
+ private initialized;
19
+ private sessionStart;
20
+ constructor(config: EngramConfig);
21
+ /**
22
+ * Initialize the adapter and record session start.
23
+ * Call this at agent startup.
24
+ */
25
+ wake(): Promise<void>;
26
+ /**
27
+ * Persist state and close connections.
28
+ * Call this at agent shutdown.
29
+ */
30
+ sleep(): Promise<void>;
31
+ /**
32
+ * Store a memory. Embeds content automatically.
33
+ */
34
+ store(input: MemoryInput): Promise<Memory>;
35
+ /**
36
+ * Store multiple memories in parallel.
37
+ */
38
+ storeMany(inputs: MemoryInput[]): Promise<Memory[]>;
39
+ /**
40
+ * Semantic search over stored memories.
41
+ */
42
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
43
+ /**
44
+ * Retrieve a memory by ID.
45
+ */
46
+ get(id: string): Promise<Memory | null>;
47
+ /**
48
+ * Delete a memory permanently.
49
+ */
50
+ forget(id: string): Promise<void>;
51
+ /**
52
+ * List recent memories for this agent.
53
+ */
54
+ list(limit?: number): Promise<Memory[]>;
55
+ private ensureReady;
56
+ }
57
+ //# sourceMappingURL=engram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engram.d.ts","sourceRoot":"","sources":["../src/engram.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EAEZ,MAAM,EACN,WAAW,EACX,aAAa,EACb,YAAY,EACb,MAAM,YAAY,CAAA;AAMnB;;;;;;;;;;;;GAYG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,YAAY,CAAoB;gBAE5B,MAAM,EAAE,YAAY;IAiChC;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5B;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBhD;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIzD;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAWjF;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAK7C;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvC;;OAEG;IACG,IAAI,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAS3B,WAAW;CAK1B"}
package/dist/engram.js ADDED
@@ -0,0 +1,148 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { MemoryAdapter } from './adapters/memory.js';
3
+ import { PostgresAdapter } from './adapters/postgres.js';
4
+ import { SqliteAdapter } from './adapters/sqlite.js';
5
+ import { embedText, DEFAULT_DIMENSIONS } from './utils/embeddings.js';
6
+ /**
7
+ * Engram — persistent semantic memory for AI agents.
8
+ *
9
+ * "We no longer live in the age of cogito. We live in the age of the trace."
10
+ * — Derrida (via Orlo Rodriguez, "I Compute, Therefore Am I?")
11
+ *
12
+ * Usage:
13
+ * const mem = new Engram({ adapter: 'memory', agentId: 'my-agent' })
14
+ * await mem.wake()
15
+ * await mem.store({ content: 'The user prefers dark mode' })
16
+ * const results = await mem.search('user preferences')
17
+ * await mem.sleep()
18
+ */
19
+ export class Engram {
20
+ constructor(config) {
21
+ this.initialized = false;
22
+ this.sessionStart = null;
23
+ this.config = {
24
+ adapter: config.adapter,
25
+ agentId: config.agentId,
26
+ connectionString: config.connectionString ?? '',
27
+ embeddingDimensions: config.embeddingDimensions ?? DEFAULT_DIMENSIONS,
28
+ };
29
+ switch (config.adapter) {
30
+ case 'memory':
31
+ this.adapter = new MemoryAdapter();
32
+ break;
33
+ case 'postgres':
34
+ if (!config.connectionString) {
35
+ throw new Error('connectionString required for postgres adapter');
36
+ }
37
+ this.adapter = new PostgresAdapter(config.connectionString);
38
+ break;
39
+ case 'sqlite':
40
+ if (!config.connectionString) {
41
+ throw new Error('connectionString (file path) required for sqlite adapter');
42
+ }
43
+ this.adapter = new SqliteAdapter(config.connectionString);
44
+ break;
45
+ default:
46
+ throw new Error(`Unknown adapter: ${config.adapter}`);
47
+ }
48
+ }
49
+ // ---------------------------------------------------------------------------
50
+ // Lifecycle
51
+ // ---------------------------------------------------------------------------
52
+ /**
53
+ * Initialize the adapter and record session start.
54
+ * Call this at agent startup.
55
+ */
56
+ async wake() {
57
+ if (!this.initialized) {
58
+ await this.adapter.init();
59
+ this.initialized = true;
60
+ }
61
+ this.sessionStart = new Date();
62
+ }
63
+ /**
64
+ * Persist state and close connections.
65
+ * Call this at agent shutdown.
66
+ */
67
+ async sleep() {
68
+ if (this.sessionStart) {
69
+ const duration = Date.now() - this.sessionStart.getTime();
70
+ // TODO: emit session summary to a "session" memory
71
+ void duration;
72
+ this.sessionStart = null;
73
+ }
74
+ await this.adapter.close();
75
+ this.initialized = false;
76
+ }
77
+ // ---------------------------------------------------------------------------
78
+ // Core API
79
+ // ---------------------------------------------------------------------------
80
+ /**
81
+ * Store a memory. Embeds content automatically.
82
+ */
83
+ async store(input) {
84
+ await this.ensureReady();
85
+ const embedding = await embedText(input.content, this.config.embeddingDimensions);
86
+ const now = new Date();
87
+ const memory = {
88
+ id: randomUUID(),
89
+ agentId: this.config.agentId,
90
+ content: input.content,
91
+ embedding,
92
+ importance: input.importance ?? 0.5,
93
+ metadata: input.metadata ?? {},
94
+ createdAt: now,
95
+ accessedAt: now,
96
+ accessCount: 0,
97
+ };
98
+ return this.adapter.store(memory);
99
+ }
100
+ /**
101
+ * Store multiple memories in parallel.
102
+ */
103
+ async storeMany(inputs) {
104
+ return Promise.all(inputs.map((input) => this.store(input)));
105
+ }
106
+ /**
107
+ * Semantic search over stored memories.
108
+ */
109
+ async search(query, options = {}) {
110
+ await this.ensureReady();
111
+ const embedding = await embedText(query, this.config.embeddingDimensions);
112
+ return this.adapter.search(embedding, {
113
+ limit: options.limit ?? 10,
114
+ threshold: options.threshold ?? 0.0,
115
+ filter: options.filter ?? {},
116
+ });
117
+ }
118
+ /**
119
+ * Retrieve a memory by ID.
120
+ */
121
+ async get(id) {
122
+ await this.ensureReady();
123
+ return this.adapter.get(id);
124
+ }
125
+ /**
126
+ * Delete a memory permanently.
127
+ */
128
+ async forget(id) {
129
+ await this.ensureReady();
130
+ return this.adapter.forget(id);
131
+ }
132
+ /**
133
+ * List recent memories for this agent.
134
+ */
135
+ async list(limit = 50) {
136
+ await this.ensureReady();
137
+ return this.adapter.list(this.config.agentId, limit);
138
+ }
139
+ // ---------------------------------------------------------------------------
140
+ // Internals
141
+ // ---------------------------------------------------------------------------
142
+ async ensureReady() {
143
+ if (!this.initialized) {
144
+ await this.wake();
145
+ }
146
+ }
147
+ }
148
+ //# sourceMappingURL=engram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engram.js","sourceRoot":"","sources":["../src/engram.ts"],"names":[],"mappings":"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"}