@cartisien/engram 0.2.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.
Files changed (40) hide show
  1. package/README.md +104 -203
  2. package/dist/adapters/base.d.ts +2 -0
  3. package/dist/adapters/base.d.ts.map +1 -0
  4. package/dist/adapters/base.js +2 -0
  5. package/dist/adapters/base.js.map +1 -0
  6. package/dist/adapters/memory.d.ts +17 -0
  7. package/dist/adapters/memory.d.ts.map +1 -0
  8. package/dist/adapters/memory.js +58 -0
  9. package/dist/adapters/memory.js.map +1 -0
  10. package/dist/adapters/postgres.d.ts +33 -0
  11. package/dist/adapters/postgres.d.ts.map +1 -0
  12. package/dist/adapters/postgres.js +47 -0
  13. package/dist/adapters/postgres.js.map +1 -0
  14. package/dist/adapters/sqlite.d.ts +19 -0
  15. package/dist/adapters/sqlite.d.ts.map +1 -0
  16. package/dist/adapters/sqlite.js +33 -0
  17. package/dist/adapters/sqlite.js.map +1 -0
  18. package/dist/engram.d.ts +57 -0
  19. package/dist/engram.d.ts.map +1 -0
  20. package/dist/engram.js +148 -0
  21. package/dist/engram.js.map +1 -0
  22. package/dist/index.d.ts +99 -122
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +458 -468
  25. package/dist/index.js.map +1 -1
  26. package/dist/types.d.ts +48 -0
  27. package/dist/types.d.ts.map +1 -0
  28. package/dist/types.js +8 -0
  29. package/dist/types.js.map +1 -0
  30. package/dist/utils/embeddings.d.ts +20 -0
  31. package/dist/utils/embeddings.d.ts.map +1 -0
  32. package/dist/utils/embeddings.js +28 -0
  33. package/dist/utils/embeddings.js.map +1 -0
  34. package/dist/utils/similarity.d.ts +10 -0
  35. package/dist/utils/similarity.d.ts.map +1 -0
  36. package/dist/utils/similarity.js +31 -0
  37. package/dist/utils/similarity.js.map +1 -0
  38. package/package.json +4 -3
  39. package/LICENSE +0 -21
  40. package/dist/example/temporal-demo.js +0 -91
@@ -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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"}
package/dist/index.d.ts CHANGED
@@ -1,73 +1,89 @@
1
+ export type MemoryTier = 'working' | 'long_term' | 'archived';
1
2
  export interface MemoryEntry {
2
3
  id: string;
3
4
  sessionId: string;
4
5
  content: string;
5
6
  role: 'user' | 'assistant' | 'system';
6
7
  timestamp: Date;
8
+ tier: MemoryTier;
9
+ consolidatedFrom?: string[];
7
10
  metadata?: Record<string, unknown>;
11
+ similarity?: number;
12
+ }
13
+ export interface GraphNode {
14
+ entity: string;
15
+ type?: string;
16
+ }
17
+ export interface GraphEdge {
18
+ from: string;
19
+ relation: string;
20
+ to: string;
21
+ confidence?: number;
22
+ }
23
+ export interface GraphResult {
24
+ entity: string;
25
+ relationships: Array<{
26
+ type: 'outgoing' | 'incoming';
27
+ relation: string;
28
+ target: string;
29
+ confidence?: number;
30
+ }>;
31
+ relatedMemories: MemoryEntry[];
8
32
  }
9
33
  export interface RecallOptions {
10
34
  limit?: number;
11
35
  before?: Date;
12
36
  after?: Date;
13
37
  role?: 'user' | 'assistant' | 'system';
38
+ includeGraph?: boolean;
39
+ tiers?: MemoryTier[];
14
40
  }
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;
41
+ export interface ConsolidateOptions {
42
+ batch?: number;
43
+ keep?: number;
44
+ model?: string;
45
+ dryRun?: boolean;
20
46
  }
21
- export interface TimeRange {
22
- start: Date;
23
- end: Date;
24
- description: string;
47
+ export interface ConsolidationResult {
48
+ summarized: number;
49
+ created: number;
50
+ archived: number;
51
+ previews?: string[];
25
52
  }
26
53
  export interface EngramConfig {
27
54
  dbPath?: string;
28
55
  maxContextLength?: number;
56
+ embeddingUrl?: string;
57
+ embeddingModel?: string;
58
+ semanticSearch?: boolean;
59
+ graphMemory?: boolean;
60
+ graphModel?: string;
61
+ autoConsolidate?: boolean;
62
+ consolidateThreshold?: number;
63
+ consolidateKeep?: number;
64
+ consolidateBatch?: number;
65
+ consolidateModel?: string;
29
66
  }
30
67
  /**
31
- * Temporal query parser for natural language time expressions
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
68
+ * Engram - Persistent semantic memory for AI agents
55
69
  *
56
- * A lightweight, SQLite-backed memory system that gives your AI assistants
57
- * the ability to remember conversations across sessions.
70
+ * v0.4 adds memory consolidation working memories are periodically
71
+ * summarized into long-term memories by a local LLM, keeping context
72
+ * dense and relevant as conversations grow.
58
73
  *
59
74
  * @example
60
75
  * ```typescript
61
76
  * import { Engram } from '@cartisien/engram';
62
77
  *
63
- * const memory = new Engram({ dbPath: './memory.db' });
78
+ * const memory = new Engram({
79
+ * dbPath: './memory.db',
80
+ * autoConsolidate: true,
81
+ * consolidateThreshold: 100,
82
+ * });
64
83
  *
65
- * // Store a memory
66
- * await memory.remember('user_123', 'Jeff loves Triumph motorcycles', 'user');
67
- *
68
- * // Retrieve with temporal query
69
- * const yesterday = await memory.recallByTime('user_123', 'yesterday');
70
- * const lastWeek = await memory.recallByTime('user_123', 'last week');
84
+ * // Manual consolidation
85
+ * const result = await memory.consolidate('session_1');
86
+ * // → { summarized: 50, created: 4, archived: 50 }
71
87
  * ```
72
88
  */
73
89
  export declare class Engram {
@@ -75,113 +91,74 @@ export declare class Engram {
75
91
  private maxContextLength;
76
92
  private dbPath;
77
93
  private initialized;
94
+ private embeddingUrl;
95
+ private embeddingModel;
96
+ private semanticSearch;
97
+ private graphMemory;
98
+ private graphModel;
99
+ private autoConsolidate;
100
+ private consolidateThreshold;
101
+ private consolidateKeep;
102
+ private consolidateBatch;
103
+ private consolidateModel;
78
104
  constructor(config?: EngramConfig);
79
105
  private init;
106
+ private embed;
107
+ private extractGraph;
108
+ private upsertNode;
109
+ private storeEdge;
110
+ private cosineSimilarity;
80
111
  /**
81
- * Store a memory entry
112
+ * Call LLM to summarize a batch of memories into consolidated entries.
113
+ * Returns an array of summary strings (typically 2-5 per batch).
82
114
  */
83
- remember(sessionId: string, content: string, role?: 'user' | 'assistant' | 'system', metadata?: Record<string, unknown>): Promise<MemoryEntry>;
115
+ private summarizeMemories;
84
116
  /**
85
- * Recall memories for a session
117
+ * v0.4: Consolidate working memories into long-term summaries.
86
118
  *
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'
95
- */
96
- recall(sessionId: string, query?: string, limit?: number, options?: TemporalRecallOptions): Promise<MemoryEntry[]>;
97
- /**
98
- * Recall memories by natural language time expression
119
+ * Takes the oldest `batch` working memories (excluding the `keep` most recent),
120
+ * summarizes them via LLM, stores summaries as `long_term` tier, and archives
121
+ * the originals.
99
122
  *
100
123
  * @example
101
124
  * ```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');
125
+ * const result = await memory.consolidate('session_1');
126
+ * // { summarized: 50, created: 4, archived: 50 }
107
127
  *
108
- * // Get memories from 3 days ago
109
- * const threeDaysAgo = await memory.recallByTime('session_123', '3 days ago');
128
+ * // Preview without writing
129
+ * const preview = await memory.consolidate('session_1', { dryRun: true });
130
+ * // → { summarized: 50, created: 0, archived: 0, previews: ['...', '...'] }
110
131
  * ```
111
132
  */
112
- recallByTime(sessionId: string, temporalQuery: string, query?: string, limit?: number, options?: Omit<TemporalRecallOptions, 'temporalQuery'>): Promise<{
113
- entries: MemoryEntry[];
114
- range: TimeRange;
115
- }>;
116
- /**
117
- * Get memories from the last N days
118
- */
119
- recallRecent(sessionId: string, days?: number, query?: string, limit?: number, options?: Omit<TemporalRecallOptions, 'after' | 'before'>): Promise<{
120
- entries: MemoryEntry[];
121
- days: number;
122
- since: Date;
123
- }>;
133
+ consolidate(sessionId: string, options?: ConsolidateOptions): Promise<ConsolidationResult>;
124
134
  /**
125
- * Get memories since a specific date
135
+ * Store a memory entry. With autoConsolidate enabled, triggers consolidation
136
+ * when working memory count exceeds the configured threshold.
126
137
  */
127
- recallSince(sessionId: string, since: Date, query?: string, limit?: number, options?: Omit<TemporalRecallOptions, 'after'>): Promise<{
128
- entries: MemoryEntry[];
129
- since: Date;
130
- count: number;
131
- }>;
132
- /**
133
- * Get memories between two dates
134
- */
135
- recallBetween(sessionId: string, start: Date, end: Date, query?: string, limit?: number, options?: Omit<TemporalRecallOptions, 'after' | 'before'>): Promise<{
136
- entries: MemoryEntry[];
137
- start: Date;
138
- end: Date;
139
- count: number;
140
- }>;
141
- /**
142
- * Get a daily summary of memories
143
- *
144
- * Returns memories grouped by day, useful for "what happened each day" views
145
- */
146
- dailySummary(sessionId: string, days?: number): Promise<{
147
- date: Date;
148
- entries: MemoryEntry[];
149
- count: number;
150
- }[]>;
138
+ remember(sessionId: string, content: string, role?: 'user' | 'assistant' | 'system', metadata?: Record<string, unknown>): Promise<MemoryEntry>;
151
139
  /**
152
- * Get recent conversation history for a session
140
+ * Recall memories. Searches working and long_term tiers by default.
141
+ * Archived memories (consolidated originals) are excluded unless explicitly requested.
153
142
  */
143
+ recall(sessionId: string, query?: string, limit?: number, options?: RecallOptions): Promise<MemoryEntry[]>;
144
+ private augmentWithGraph;
145
+ graph(sessionId: string, entity: string): Promise<GraphResult>;
154
146
  history(sessionId: string, limit?: number): Promise<MemoryEntry[]>;
155
- /**
156
- * Forget (delete) memories
157
- */
158
147
  forget(sessionId: string, options?: {
159
148
  before?: Date;
160
- after?: Date;
161
149
  id?: string;
150
+ includeLongTerm?: boolean;
162
151
  }): Promise<number>;
163
- /**
164
- * Get memory statistics for a session
165
- */
166
152
  stats(sessionId: string): Promise<{
167
153
  total: number;
168
154
  byRole: Record<string, number>;
155
+ byTier: Record<MemoryTier, number>;
169
156
  oldest: Date | null;
170
157
  newest: Date | null;
158
+ withEmbeddings: number;
159
+ graphNodes?: number;
160
+ graphEdges?: number;
171
161
  }>;
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
162
  close(): Promise<void>;
186
163
  }
187
164
  export default Engram;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;CACxC;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,IAAI,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;IACV,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAO;IAC5B,OAAO,CAAC,cAAc,CAAS;gBAEnB,aAAa,GAAE,IAAiB,EAAE,cAAc,GAAE,MAA2C;IAKzG;;;;;;;;;;OAUG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IA0L3C,OAAO,CAAC,SAAS;IA2CjB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,QAAQ;CAKjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAkB;gBAEzB,MAAM,GAAE,YAAiB;YAKvB,IAAI;IAuClB;;OAEG;IACG,QAAQ,CACZ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,GAAG,WAAW,GAAG,QAAiB,EAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,WAAW,CAAC;IAuCvB;;;;;;;;;;;OAWG;IACG,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,GAAE,MAAW,EAClB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,WAAW,EAAE,CAAC;IA2DzB;;;;;;;;;;;;;;OAcG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,GAAE,MAAW,EAClB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,eAAe,CAAM,GACzD,OAAO,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;IAiBxD;;OAEG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,MAAU,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,GAAE,MAAW,EAClB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,QAAQ,CAAM,GAC5D,OAAO,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,IAAI,CAAA;KAAE,CAAC;IAajE;;OAEG;IACG,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,IAAI,EACX,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,GAAE,MAAW,EAClB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,CAAM,GACjD,OAAO,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QAAC,KAAK,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IASlE;;OAEG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,IAAI,EACX,GAAG,EAAE,IAAI,EACT,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,GAAE,MAAW,EAClB,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,OAAO,GAAG,QAAQ,CAAM,GAC5D,OAAO,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QAAC,KAAK,EAAE,IAAI,CAAC;QAAC,GAAG,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAU7E;;;;OAIG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,MAAU,GACf,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IA8BnE;;OAEG;IACG,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC;IAIzB;;OAEG;IACG,MAAM,CACV,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,IAAI,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,MAAM,CAAC;IA4BlB;;OAEG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QACtC,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;QACpB,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;KACrB,CAAC;IA+BF;;;;OAIG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,MAAW,GAChB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE,CAAC;IAmC7E;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAM7B;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}