@jungjaehoon/mama-core 1.3.3 → 1.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 (50) hide show
  1. package/README.md +67 -19
  2. package/db/migrations/001-initial-decision-graph.sql +5 -0
  3. package/db/migrations/014-add-is-static-column.sql +5 -0
  4. package/db/migrations/015-add-fts5-search.sql +34 -0
  5. package/db/migrations/016-add-memory-v2-columns.sql +14 -0
  6. package/db/migrations/017-create-memory-scopes.sql +10 -0
  7. package/db/migrations/018-create-memory-scope-bindings.sql +15 -0
  8. package/db/migrations/019-create-memory-events.sql +18 -0
  9. package/db/migrations/020-create-audit-findings.sql +18 -0
  10. package/db/migrations/021-create-memory-truth.sql +20 -0
  11. package/db/migrations/022-create-channel-summaries.sql +9 -0
  12. package/db/migrations/023-create-channel-summary-state.sql +9 -0
  13. package/db/migrations/024-add-event-date.sql +9 -0
  14. package/dist/db-adapter/base-adapter.d.ts +1 -1
  15. package/dist/db-adapter/index.js +2 -8
  16. package/dist/db-adapter/node-sqlite-adapter.d.ts +6 -1
  17. package/dist/db-adapter/node-sqlite-adapter.js +99 -45
  18. package/dist/db-manager.d.ts +30 -2
  19. package/dist/db-manager.js +131 -6
  20. package/dist/decision-formatter.d.ts +2 -0
  21. package/dist/embedding-server/mobile/session-manager.js +22 -7
  22. package/dist/index.d.ts +5 -1
  23. package/dist/index.js +31 -3
  24. package/dist/mama-api.d.ts +67 -2
  25. package/dist/mama-api.js +295 -80
  26. package/dist/memory/api.d.ts +81 -0
  27. package/dist/memory/api.js +972 -0
  28. package/dist/memory/bootstrap-builder.d.ts +10 -0
  29. package/dist/memory/bootstrap-builder.js +66 -0
  30. package/dist/memory/channel-summary-state-store.d.ts +19 -0
  31. package/dist/memory/channel-summary-state-store.js +223 -0
  32. package/dist/memory/channel-summary-store.d.ts +8 -0
  33. package/dist/memory/channel-summary-store.js +41 -0
  34. package/dist/memory/event-store.d.ts +5 -0
  35. package/dist/memory/event-store.js +72 -0
  36. package/dist/memory/evolution-engine.d.ts +22 -0
  37. package/dist/memory/evolution-engine.js +133 -0
  38. package/dist/memory/extraction-prompt.d.ts +4 -0
  39. package/dist/memory/extraction-prompt.js +89 -0
  40. package/dist/memory/finding-store.d.ts +5 -0
  41. package/dist/memory/finding-store.js +75 -0
  42. package/dist/memory/profile-builder.d.ts +3 -0
  43. package/dist/memory/profile-builder.js +23 -0
  44. package/dist/memory/scope-store.d.ts +5 -0
  45. package/dist/memory/scope-store.js +13 -0
  46. package/dist/memory/truth-store.d.ts +11 -0
  47. package/dist/memory/truth-store.js +102 -0
  48. package/dist/memory/types.d.ts +267 -0
  49. package/dist/memory/types.js +74 -0
  50. package/package.json +4 -1
@@ -26,8 +26,9 @@ export interface DatabaseAdapter {
26
26
  prepare: (sql: string) => PreparedStatement;
27
27
  transaction: <T>(fn: () => T) => T;
28
28
  insertEmbedding: (rowid: number, embedding: Float32Array | number[]) => void;
29
- vectorSearch: (embedding: Float32Array | number[], limit: number) => Promise<VectorSearchResult[] | null>;
29
+ vectorSearch: (embedding: Float32Array | number[], limit: number, topicPrefix?: string) => Promise<VectorSearchResult[] | null> | VectorSearchResult[] | null;
30
30
  vectorSearchEnabled: boolean;
31
+ reloadVectorCache?: () => void;
31
32
  getDbPath?: () => string;
32
33
  dbPath?: string;
33
34
  constructor: {
@@ -54,6 +55,8 @@ export interface DecisionRecord {
54
55
  created_at: number;
55
56
  updated_at?: number;
56
57
  edges?: DecisionEdgeRow[];
58
+ /** ISO 8601 date when the event actually occurred. Null if not set. */
59
+ event_date?: string | null;
57
60
  }
58
61
  export interface OutcomeData {
59
62
  outcome?: string | null;
@@ -67,6 +70,7 @@ export interface VectorSearchParams {
67
70
  limit?: number;
68
71
  threshold?: number;
69
72
  timeWindow?: number;
73
+ includeSuperseded?: boolean;
70
74
  }
71
75
  export interface DecisionEdgeRow {
72
76
  from_id: string;
@@ -140,6 +144,12 @@ export declare function getAdapter(): DatabaseAdapter;
140
144
  * Call this on process exit
141
145
  */
142
146
  export declare function closeDB(): Promise<void>;
147
+ export declare function ensureMemoryScope(kind: string, externalId: string): Promise<string>;
148
+ export declare function bindMemoryToScope(memoryId: string, scopeId: string, isPrimary?: boolean): Promise<void>;
149
+ export declare function listScopesForMemory(memoryId: string): Promise<Array<{
150
+ kind: string;
151
+ id: string;
152
+ }>>;
143
153
  /**
144
154
  * Insert embedding into vector search table
145
155
  *
@@ -159,7 +169,7 @@ export declare function insertEmbedding(decisionRowid: number, embedding: Float3
159
169
  * @param threshold - Minimum similarity threshold (default: 0.7)
160
170
  * @returns Array of decisions with similarity scores, or empty array
161
171
  */
162
- export declare function vectorSearch(queryEmbedding: Float32Array | number[], limit?: number, threshold?: number): Promise<DecisionRecord[]>;
172
+ export declare function vectorSearch(queryEmbedding: Float32Array | number[], limit?: number, threshold?: number, topicPrefix?: string): Promise<DecisionRecord[]>;
163
173
  /**
164
174
  * Decision input for storage
165
175
  */
@@ -190,6 +200,8 @@ export interface DecisionInput {
190
200
  evidence?: string | null;
191
201
  alternatives?: string | null;
192
202
  risks?: string | null;
203
+ /** ISO 8601 date string for when the event actually occurred (e.g. "2023-01-15") */
204
+ event_date?: string | null;
193
205
  }
194
206
  /**
195
207
  * Insert decision with embedding
@@ -271,4 +283,20 @@ export declare function resetDBState(options?: {
271
283
  * Returns true if MAMA_TEST_MODE or VITEST env vars are set
272
284
  */
273
285
  export declare function isTestMode(): boolean;
286
+ /**
287
+ * FTS5 keyword search on decisions table.
288
+ * Returns matching decision IDs with BM25 rank scores.
289
+ */
290
+ export declare function fts5Search(query: string, limit?: number): Promise<{
291
+ id: string;
292
+ rank: number;
293
+ }[]>;
294
+ /**
295
+ * Re-generate all embeddings using the currently configured model.
296
+ * Call this after changing the embedding model in config.json.
297
+ *
298
+ * @param onProgress - Optional callback with (completed, total) counts
299
+ * @returns Number of embeddings regenerated
300
+ */
301
+ export declare function reindexEmbeddings(onProgress?: (completed: number, total: number) => void): Promise<number>;
274
302
  //# sourceMappingURL=db-manager.d.ts.map
@@ -26,6 +26,9 @@ exports.initDB = initDB;
26
26
  exports.getDB = getDB;
27
27
  exports.getAdapter = getAdapter;
28
28
  exports.closeDB = closeDB;
29
+ exports.ensureMemoryScope = ensureMemoryScope;
30
+ exports.bindMemoryToScope = bindMemoryToScope;
31
+ exports.listScopesForMemory = listScopesForMemory;
29
32
  exports.insertEmbedding = insertEmbedding;
30
33
  exports.vectorSearch = vectorSearch;
31
34
  exports.insertDecisionWithEmbedding = insertDecisionWithEmbedding;
@@ -37,6 +40,8 @@ exports.getPreparedStmt = getPreparedStmt;
37
40
  exports.getDbPath = getDbPath;
38
41
  exports.resetDBState = resetDBState;
39
42
  exports.isTestMode = isTestMode;
43
+ exports.fts5Search = fts5Search;
44
+ exports.reindexEmbeddings = reindexEmbeddings;
40
45
  const path_1 = __importDefault(require("path"));
41
46
  const debug_logger_js_1 = require("./debug-logger.js");
42
47
  const progress_indicator_js_1 = require("./progress-indicator.js");
@@ -78,6 +83,10 @@ async function initDB() {
78
83
  dbConnection = await dbAdapter.connect();
79
84
  // Run migrations (includes 012-create-checkpoints-table.sql)
80
85
  await dbAdapter.runMigrations(MIGRATIONS_DIR);
86
+ // Reload vector cache after migrations (new tables/rows may now exist)
87
+ if (typeof dbAdapter.reloadVectorCache === 'function') {
88
+ dbAdapter.reloadVectorCache();
89
+ }
81
90
  isInitialized = true;
82
91
  (0, debug_logger_js_1.info)(`[db-manager] Database initialized (${dbAdapter.constructor.name})`);
83
92
  (0, progress_indicator_js_1.logComplete)('Database ready');
@@ -124,6 +133,9 @@ function getAdapter() {
124
133
  }
125
134
  return dbAdapter;
126
135
  }
136
+ function buildMemoryScopeId(kind, externalId) {
137
+ return `scope_${kind}_${Buffer.from(externalId).toString('base64url')}`;
138
+ }
127
139
  /**
128
140
  * Close database connection
129
141
  *
@@ -139,6 +151,38 @@ async function closeDB() {
139
151
  (0, debug_logger_js_1.info)('[db-manager] Database connection closed');
140
152
  }
141
153
  }
154
+ async function ensureMemoryScope(kind, externalId) {
155
+ const adapter = getAdapter();
156
+ const id = buildMemoryScopeId(kind, externalId);
157
+ adapter
158
+ .prepare(`
159
+ INSERT OR IGNORE INTO memory_scopes (id, kind, external_id)
160
+ VALUES (?, ?, ?)
161
+ `)
162
+ .run(id, kind, externalId);
163
+ return id;
164
+ }
165
+ async function bindMemoryToScope(memoryId, scopeId, isPrimary = false) {
166
+ const adapter = getAdapter();
167
+ adapter
168
+ .prepare(`
169
+ INSERT OR REPLACE INTO memory_scope_bindings (memory_id, scope_id, is_primary)
170
+ VALUES (?, ?, ?)
171
+ `)
172
+ .run(memoryId, scopeId, isPrimary ? 1 : 0);
173
+ }
174
+ async function listScopesForMemory(memoryId) {
175
+ const adapter = getAdapter();
176
+ return adapter
177
+ .prepare(`
178
+ SELECT ms.kind, ms.external_id AS id
179
+ FROM memory_scope_bindings msb
180
+ JOIN memory_scopes ms ON ms.id = msb.scope_id
181
+ WHERE msb.memory_id = ?
182
+ ORDER BY msb.is_primary DESC, ms.created_at ASC
183
+ `)
184
+ .all(memoryId);
185
+ }
142
186
  /**
143
187
  * Insert embedding into vector search table
144
188
  *
@@ -168,11 +212,11 @@ async function insertEmbedding(decisionRowid, embedding) {
168
212
  * @param threshold - Minimum similarity threshold (default: 0.7)
169
213
  * @returns Array of decisions with similarity scores, or empty array
170
214
  */
171
- async function vectorSearch(queryEmbedding, limit = 5, threshold = 0.7) {
215
+ async function vectorSearch(queryEmbedding, limit = 5, threshold = 0.7, topicPrefix) {
172
216
  const adapter = getAdapter();
173
217
  try {
174
- // Brute-force cosine similarity over all embeddings
175
- const results = await adapter.vectorSearch(queryEmbedding, limit * 3);
218
+ // Brute-force cosine similarity over all embeddings (with optional topic pre-filter)
219
+ const results = await adapter.vectorSearch(queryEmbedding, limit * 3, topicPrefix);
176
220
  if (!results || results.length === 0) {
177
221
  return []; // No keyword fallback - fast fail
178
222
  }
@@ -216,6 +260,13 @@ async function vectorSearch(queryEmbedding, limit = 5, threshold = 0.7) {
216
260
  async function insertDecisionWithEmbedding(decision) {
217
261
  const adapter = getAdapter();
218
262
  const { generateEnhancedEmbedding } = await import('./embeddings.js');
263
+ // Validate event_date before any DB operations
264
+ if (decision.event_date !== null && decision.event_date !== undefined) {
265
+ const d = decision.event_date;
266
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(d) || isNaN(new Date(d).getTime())) {
267
+ throw new Error(`Invalid event_date: must be ISO 8601 YYYY-MM-DD (got: ${d})`);
268
+ }
269
+ }
219
270
  try {
220
271
  // Generate embedding BEFORE transaction (required for SQLite's sync transaction)
221
272
  // Note: Redact topic for privacy - only log length
@@ -248,14 +299,14 @@ async function insertDecisionWithEmbedding(decision) {
248
299
  confidence, created_at, updated_at,
249
300
  needs_validation, validation_attempts, last_validated_at, usage_count,
250
301
  trust_context, usage_success, usage_failure, time_saved,
251
- evidence, alternatives, risks
252
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
302
+ evidence, alternatives, risks, event_date
303
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
253
304
  `);
254
305
  const insertResult = stmt.run(decision.id, decision.topic, decision.decision, decision.reasoning || null, decision.outcome || null, decision.failure_reason || null, decision.limitation || null, decision.user_involvement || null, decision.session_id || null, decision.supersedes || null, decision.superseded_by || null, decision.refined_from ? JSON.stringify(decision.refined_from) : null, decision.confidence !== undefined ? decision.confidence : 0.5,
255
306
  // IMPORTANT: All timestamps are stored in milliseconds (Date.now()).
256
307
  // The schema DEFAULT uses unixepoch() (seconds) but is never used
257
308
  // since all inserts go through this function which always provides ms.
258
- decision.created_at || Date.now(), decision.updated_at || Date.now(), decision.needs_validation !== undefined ? decision.needs_validation : 0, decision.validation_attempts || 0, decision.last_validated_at || null, decision.usage_count || 0, decision.trust_context || null, decision.usage_success || 0, decision.usage_failure || 0, decision.time_saved || 0, decision.evidence || null, decision.alternatives || null, decision.risks || null);
309
+ decision.created_at || Date.now(), decision.updated_at || Date.now(), decision.needs_validation !== undefined ? decision.needs_validation : 0, decision.validation_attempts || 0, decision.last_validated_at || null, decision.usage_count || 0, decision.trust_context || null, decision.usage_success || 0, decision.usage_failure || 0, decision.time_saved || 0, decision.evidence || null, decision.alternatives || null, decision.risks || null, decision.event_date || null);
259
310
  const rowid = Number(insertResult.lastInsertRowid);
260
311
  // Insert embedding in same transaction to ensure rowid matching
261
312
  (0, debug_logger_js_1.info)(`[db-manager] Vector search enabled: ${adapter.vectorSearchEnabled}`);
@@ -485,6 +536,10 @@ async function queryVectorSearch(params) {
485
536
  if (similarity < threshold) {
486
537
  continue;
487
538
  }
539
+ // Filter out superseded decisions unless explicitly requested
540
+ if (!params.includeSuperseded && decision.superseded_by) {
541
+ continue;
542
+ }
488
543
  results.push({
489
544
  ...decision,
490
545
  similarity,
@@ -618,4 +673,74 @@ function resetDBState(options = {}) {
618
673
  function isTestMode() {
619
674
  return !!(process.env.MAMA_TEST_MODE || process.env.VITEST);
620
675
  }
676
+ /**
677
+ * FTS5 keyword search on decisions table.
678
+ * Returns matching decision IDs with BM25 rank scores.
679
+ */
680
+ async function fts5Search(query, limit = 10) {
681
+ const adapter = getAdapter();
682
+ // Check if FTS5 table exists (swallow errors — table may not exist yet)
683
+ let tableCheck;
684
+ try {
685
+ tableCheck = adapter
686
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='decisions_fts'")
687
+ .get();
688
+ }
689
+ catch {
690
+ return [];
691
+ }
692
+ if (!tableCheck)
693
+ return [];
694
+ // Query execution — let errors propagate to the caller
695
+ const stmt = adapter.prepare(`
696
+ SELECT d.id, rank
697
+ FROM decisions_fts
698
+ JOIN decisions d ON decisions_fts.rowid = d.rowid
699
+ WHERE decisions_fts MATCH ?
700
+ ORDER BY rank
701
+ LIMIT ?
702
+ `);
703
+ return stmt.all(query, limit);
704
+ }
705
+ /**
706
+ * Re-generate all embeddings using the currently configured model.
707
+ * Call this after changing the embedding model in config.json.
708
+ *
709
+ * @param onProgress - Optional callback with (completed, total) counts
710
+ * @returns Number of embeddings regenerated
711
+ */
712
+ async function reindexEmbeddings(onProgress) {
713
+ const adapter = getAdapter();
714
+ const { generateEnhancedEmbedding } = await import('./embeddings.js');
715
+ const decisions = adapter
716
+ .prepare('SELECT rowid, topic, decision, reasoning, outcome, confidence FROM decisions')
717
+ .all();
718
+ if (typeof adapter.insertEmbedding !== 'function') {
719
+ throw new Error('Embedding insertion is not available on this adapter');
720
+ }
721
+ const total = decisions.length;
722
+ let completed = 0;
723
+ for (const row of decisions) {
724
+ try {
725
+ const embedding = await generateEnhancedEmbedding({
726
+ topic: row.topic,
727
+ decision: row.decision,
728
+ reasoning: row.reasoning || undefined,
729
+ outcome: row.outcome || undefined,
730
+ confidence: row.confidence ?? undefined,
731
+ });
732
+ adapter.insertEmbedding(row.rowid, embedding);
733
+ completed++;
734
+ if (onProgress && completed % 50 === 0) {
735
+ onProgress(completed, total);
736
+ }
737
+ }
738
+ catch (e) {
739
+ (0, debug_logger_js_1.error)(`[db-manager] Failed to reindex rowid ${row.rowid}: ${e}`);
740
+ }
741
+ }
742
+ onProgress?.(completed, total);
743
+ (0, debug_logger_js_1.info)(`[db-manager] Reindexed ${completed}/${total} embeddings`);
744
+ return completed;
745
+ }
621
746
  //# sourceMappingURL=db-manager.js.map
@@ -36,6 +36,8 @@ export interface DecisionForFormat {
36
36
  evidence?: string | string[] | unknown;
37
37
  alternatives?: string | string[] | unknown;
38
38
  risks?: string;
39
+ /** ISO 8601 date when the event actually occurred. Null if not set. */
40
+ event_date?: string | null;
39
41
  }
40
42
  /**
41
43
  * Trust context object
@@ -31,7 +31,7 @@ exports.DEFAULT_DB_PATH = process.env.MAMA_DB_PATH || path_1.default.join(os_1.d
31
31
  exports.CREATE_SESSIONS_TABLE = `
32
32
  CREATE TABLE IF NOT EXISTS sessions (
33
33
  id TEXT PRIMARY KEY,
34
- project_dir TEXT NOT NULL,
34
+ project_path TEXT,
35
35
  created_at TEXT DEFAULT (datetime('now')),
36
36
  last_active TEXT DEFAULT (datetime('now')),
37
37
  status TEXT DEFAULT 'active',
@@ -83,6 +83,21 @@ class SessionManager {
83
83
  // Create sessions table if not exists
84
84
  this.db.exec(exports.CREATE_SESSIONS_TABLE);
85
85
  this.db.exec(CREATE_STATUS_INDEX);
86
+ // Add missing columns for older databases
87
+ for (const col of [
88
+ 'pid INTEGER',
89
+ 'client_id TEXT',
90
+ "status TEXT DEFAULT 'active'",
91
+ 'last_active TEXT',
92
+ 'created_at TEXT',
93
+ ]) {
94
+ try {
95
+ this.db.exec(`ALTER TABLE sessions ADD COLUMN ${col}`);
96
+ }
97
+ catch {
98
+ // Column already exists
99
+ }
100
+ }
86
101
  // Mark any orphaned 'active' sessions as 'terminated'
87
102
  // (from previous server crashes)
88
103
  this.db
@@ -121,7 +136,7 @@ class SessionManager {
121
136
  await daemon.spawn();
122
137
  // Insert into database
123
138
  const stmt = this.db.prepare(`
124
- INSERT INTO sessions (id, project_dir, status, pid)
139
+ INSERT INTO sessions (id, project_path, status, pid)
125
140
  VALUES (?, ?, 'active', ?)
126
141
  `);
127
142
  stmt.run(sessionId, projectDir, daemon.getPid());
@@ -154,10 +169,10 @@ class SessionManager {
154
169
  await this.initDB();
155
170
  }
156
171
  const stmt = this.db.prepare(`
157
- SELECT id, project_dir, started_at, last_active_at, status, pid, client_id
172
+ SELECT id, project_path, created_at, last_active, status, pid, client_id
158
173
  FROM sessions
159
174
  WHERE status = 'active'
160
- ORDER BY started_at DESC
175
+ ORDER BY created_at DESC
161
176
  `);
162
177
  const rows = stmt.all();
163
178
  // Enrich with in-memory data
@@ -165,9 +180,9 @@ class SessionManager {
165
180
  const memSession = this.sessions.get(row.id);
166
181
  return {
167
182
  id: row.id,
168
- projectDir: row.project_dir,
169
- createdAt: row.started_at,
170
- lastActive: row.last_active_at,
183
+ projectDir: row.project_path ?? '',
184
+ createdAt: row.created_at,
185
+ lastActive: row.last_active,
171
186
  status: row.status,
172
187
  pid: row.pid,
173
188
  clientId: row.client_id,
package/dist/index.d.ts CHANGED
@@ -10,11 +10,15 @@
10
10
  export { generateEmbedding, generateEnhancedEmbedding, generateBatchEmbeddings, cosineSimilarity, embeddingCache, EMBEDDING_DIM, MODEL_NAME, } from './embeddings.js';
11
11
  export { EmbeddingCache } from './embedding-cache.js';
12
12
  export { getEmbeddingFromServer, getServerStatus, isServerRunning, getServerPort, DEFAULT_PORT, HOST, TIMEOUT_MS, type ServerStatus, } from './embedding-client.js';
13
- export { initDB, getDB, getAdapter, closeDB, insertEmbedding, vectorSearch, queryVectorSearch, insertDecisionWithEmbedding, queryDecisionGraph, querySemanticEdges, updateDecisionOutcome, getPreparedStmt, getDbPath, type DatabaseAdapter as DBManagerAdapter, type PreparedStatement, type DecisionRecord, type OutcomeData, type VectorSearchParams, type SemanticEdges, type SemanticEdgeItem, type DecisionInput, } from './db-manager.js';
13
+ export { initDB, getDB, getAdapter, closeDB, insertEmbedding, vectorSearch, queryVectorSearch, insertDecisionWithEmbedding, queryDecisionGraph, querySemanticEdges, updateDecisionOutcome, getPreparedStmt, getDbPath, fts5Search, reindexEmbeddings, type DatabaseAdapter as DBManagerAdapter, type PreparedStatement, type DecisionRecord, type OutcomeData, type VectorSearchParams, type SemanticEdges, type SemanticEdgeItem, type DecisionInput, } from './db-manager.js';
14
14
  export { createAdapter, DatabaseAdapter, SQLiteAdapter, type AdapterConfig, type Statement, type VectorSearchResult, type RunResult, } from './db-adapter/index.js';
15
15
  export { getSessionDecisions, incrementUsageSuccess, incrementUsageFailure, getDecisionById, traverseDecisionChain, DB_PATH, DB_DIR, LEGACY_DB_PATH, DEFAULT_DB_PATH, } from './memory-store.js';
16
16
  import mama from './mama-api.js';
17
17
  export { mama };
18
+ export { MEMORY_SCOPE_KINDS, MEMORY_KINDS, MEMORY_STATUSES, MEMORY_EDGE_TYPES, createEmptyRecallBundle, type MemoryScopeKind, type MemoryKind, type MemoryStatus, type MemoryEdgeType, type MemoryScopeRef, type MemoryRecord, type MemoryEdge, type ProfileSnapshot, type RecallBundle, type ConversationMessage, type IngestConversationInput, type ExtractedMemoryUnit, type IngestConversationResult, } from './memory/types.js';
19
+ export { saveMemory, recallMemory, buildProfile, ingestMemory, evolveMemory, buildMemoryBootstrap, createAuditAck, recordMemoryAudit, ingestConversation, setExtractionFn, upsertChannelSummary, getChannelSummary, } from './memory/api.js';
20
+ export { buildExtractionPrompt, parseExtractionResponse } from './memory/extraction-prompt.js';
21
+ export { listRecentMemoryEvents } from './memory/event-store.js';
18
22
  export { loadConfig, getModelName, getEmbeddingDim, getCacheDir, updateConfig, getConfigPath, DEFAULT_CONFIG, type MAMAConfig, type ConfigUpdates, } from './config-loader.js';
19
23
  export { calculateRelevance, selectTopDecisions, formatTopNContext, testRelevanceScoring, type DecisionWithEmbedding, type QueryContext, type FormattedContext, type TestResult, } from './relevance-scorer.js';
20
24
  export { learnDecision, generateDecisionId, getPreviousDecision, createEdge, createSupersedesEdge, markSuperseded, calculateCombinedConfidence, detectRefinement, parseReasoningForRelationships, createEdgesFromReasoning, getSupersededChainDepth, updateConfidence, VALID_EDGE_TYPES, type EdgeType, type DecisionDetection, type ToolExecution, type SessionContext, type LearnDecisionResult, type ParsedRelationship, type EvidenceItem, } from './decision-tracker.js';
package/dist/index.js CHANGED
@@ -12,9 +12,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.selectTopDecisions = exports.calculateRelevance = exports.DEFAULT_CONFIG = exports.getConfigPath = exports.updateConfig = exports.getCacheDir = exports.getEmbeddingDim = exports.getModelName = exports.loadConfig = exports.mama = exports.DEFAULT_DB_PATH = exports.LEGACY_DB_PATH = exports.DB_DIR = exports.DB_PATH = exports.traverseDecisionChain = exports.getDecisionById = exports.incrementUsageFailure = exports.incrementUsageSuccess = exports.getSessionDecisions = exports.SQLiteAdapter = exports.DatabaseAdapter = exports.createAdapter = exports.getDbPath = exports.getPreparedStmt = exports.updateDecisionOutcome = exports.querySemanticEdges = exports.queryDecisionGraph = exports.insertDecisionWithEmbedding = exports.queryVectorSearch = exports.vectorSearch = exports.insertEmbedding = exports.closeDB = exports.getAdapter = exports.getDB = exports.initDB = exports.TIMEOUT_MS = exports.HOST = exports.DEFAULT_PORT = exports.getServerPort = exports.isServerRunning = exports.getServerStatus = exports.getEmbeddingFromServer = exports.EmbeddingCache = exports.MODEL_NAME = exports.EMBEDDING_DIM = exports.embeddingCache = exports.cosineSimilarity = exports.generateBatchEmbeddings = exports.generateEnhancedEmbedding = exports.generateEmbedding = void 0;
16
- exports.formatRecall = exports.formatLegacyContext = exports.formatContext = exports.isMAMAError = exports.wrapError = exports.ErrorCodes = exports.TimeoutError = exports.RateLimitError = exports.LinkError = exports.ConfigurationError = exports.EmbeddingError = exports.DatabaseError = exports.ValidationError = exports.NotFoundError = exports.MAMAError = exports.formatTimeAgo = exports.DebugLogger = exports.error = exports.warn = exports.info = exports.debug = exports.logSearching = exports.logLoading = exports.logInfo = exports.logError = exports.logFailed = exports.logComplete = exports.logProgress = exports.getTierBanner = exports.getTierDescription = exports.checkDatabase = exports.checkEmbeddings = exports.checkSQLite = exports.checkNodeVersion = exports.validateTier = exports.VALID_EDGE_TYPES = exports.updateConfidence = exports.getSupersededChainDepth = exports.createEdgesFromReasoning = exports.parseReasoningForRelationships = exports.detectRefinement = exports.calculateCombinedConfidence = exports.markSuperseded = exports.createSupersedesEdge = exports.createEdge = exports.getPreviousDecision = exports.generateDecisionId = exports.learnDecision = exports.testRelevanceScoring = exports.formatTopNContext = void 0;
17
- exports.notifyInsight = exports.FALLBACK_MODEL = exports.DEFAULT_MODEL = exports.listModels = exports.isAvailable = exports.analyzeQueryIntent = exports.analyzeDecision = exports.generate = exports.extractTopicKeywords = exports.analyzeIntent = exports.injectDecisionContext = exports.RECENT_WINDOW_MS = exports.PARTIAL_INDICATORS = exports.SUCCESS_INDICATORS = exports.FAILURE_INDICATORS = exports.onUserPromptSubmit = exports.markOutcome = exports.getEvidenceImpact = exports.calculateDurationDays = exports.getRecentDecision = exports.extractFailureReason = exports.matchesPartialIndicators = exports.matchesSuccessIndicators = exports.matchesFailureIndicators = exports.analyzeOutcome = exports.extractCodeExample = exports.extractQuickAnswer = exports.estimateTokens = exports.ensureTokenBudget = exports.formatTrustContext = exports.formatInstantAnswer = exports.formatTeaser = exports.formatList = void 0;
15
+ exports.recallMemory = exports.saveMemory = exports.createEmptyRecallBundle = exports.MEMORY_EDGE_TYPES = exports.MEMORY_STATUSES = exports.MEMORY_KINDS = exports.MEMORY_SCOPE_KINDS = exports.mama = exports.DEFAULT_DB_PATH = exports.LEGACY_DB_PATH = exports.DB_DIR = exports.DB_PATH = exports.traverseDecisionChain = exports.getDecisionById = exports.incrementUsageFailure = exports.incrementUsageSuccess = exports.getSessionDecisions = exports.SQLiteAdapter = exports.DatabaseAdapter = exports.createAdapter = exports.reindexEmbeddings = exports.fts5Search = exports.getDbPath = exports.getPreparedStmt = exports.updateDecisionOutcome = exports.querySemanticEdges = exports.queryDecisionGraph = exports.insertDecisionWithEmbedding = exports.queryVectorSearch = exports.vectorSearch = exports.insertEmbedding = exports.closeDB = exports.getAdapter = exports.getDB = exports.initDB = exports.TIMEOUT_MS = exports.HOST = exports.DEFAULT_PORT = exports.getServerPort = exports.isServerRunning = exports.getServerStatus = exports.getEmbeddingFromServer = exports.EmbeddingCache = exports.MODEL_NAME = exports.EMBEDDING_DIM = exports.embeddingCache = exports.cosineSimilarity = exports.generateBatchEmbeddings = exports.generateEnhancedEmbedding = exports.generateEmbedding = void 0;
16
+ exports.logLoading = exports.logInfo = exports.logError = exports.logFailed = exports.logComplete = exports.logProgress = exports.getTierBanner = exports.getTierDescription = exports.checkDatabase = exports.checkEmbeddings = exports.checkSQLite = exports.checkNodeVersion = exports.validateTier = exports.VALID_EDGE_TYPES = exports.updateConfidence = exports.getSupersededChainDepth = exports.createEdgesFromReasoning = exports.parseReasoningForRelationships = exports.detectRefinement = exports.calculateCombinedConfidence = exports.markSuperseded = exports.createSupersedesEdge = exports.createEdge = exports.getPreviousDecision = exports.generateDecisionId = exports.learnDecision = exports.testRelevanceScoring = exports.formatTopNContext = exports.selectTopDecisions = exports.calculateRelevance = exports.DEFAULT_CONFIG = exports.getConfigPath = exports.updateConfig = exports.getCacheDir = exports.getEmbeddingDim = exports.getModelName = exports.loadConfig = exports.listRecentMemoryEvents = exports.parseExtractionResponse = exports.buildExtractionPrompt = exports.getChannelSummary = exports.upsertChannelSummary = exports.setExtractionFn = exports.ingestConversation = exports.recordMemoryAudit = exports.createAuditAck = exports.buildMemoryBootstrap = exports.evolveMemory = exports.ingestMemory = exports.buildProfile = void 0;
17
+ exports.analyzeQueryIntent = exports.analyzeDecision = exports.generate = exports.extractTopicKeywords = exports.analyzeIntent = exports.injectDecisionContext = exports.RECENT_WINDOW_MS = exports.PARTIAL_INDICATORS = exports.SUCCESS_INDICATORS = exports.FAILURE_INDICATORS = exports.onUserPromptSubmit = exports.markOutcome = exports.getEvidenceImpact = exports.calculateDurationDays = exports.getRecentDecision = exports.extractFailureReason = exports.matchesPartialIndicators = exports.matchesSuccessIndicators = exports.matchesFailureIndicators = exports.analyzeOutcome = exports.extractCodeExample = exports.extractQuickAnswer = exports.estimateTokens = exports.ensureTokenBudget = exports.formatTrustContext = exports.formatInstantAnswer = exports.formatTeaser = exports.formatList = exports.formatRecall = exports.formatLegacyContext = exports.formatContext = exports.isMAMAError = exports.wrapError = exports.ErrorCodes = exports.TimeoutError = exports.RateLimitError = exports.LinkError = exports.ConfigurationError = exports.EmbeddingError = exports.DatabaseError = exports.ValidationError = exports.NotFoundError = exports.MAMAError = exports.formatTimeAgo = exports.DebugLogger = exports.error = exports.warn = exports.info = exports.debug = exports.logSearching = void 0;
18
+ exports.notifyInsight = exports.FALLBACK_MODEL = exports.DEFAULT_MODEL = exports.listModels = exports.isAvailable = void 0;
18
19
  // Embeddings
19
20
  var embeddings_js_1 = require("./embeddings.js");
20
21
  Object.defineProperty(exports, "generateEmbedding", { enumerable: true, get: function () { return embeddings_js_1.generateEmbedding; } });
@@ -51,6 +52,8 @@ Object.defineProperty(exports, "querySemanticEdges", { enumerable: true, get: fu
51
52
  Object.defineProperty(exports, "updateDecisionOutcome", { enumerable: true, get: function () { return db_manager_js_1.updateDecisionOutcome; } });
52
53
  Object.defineProperty(exports, "getPreparedStmt", { enumerable: true, get: function () { return db_manager_js_1.getPreparedStmt; } });
53
54
  Object.defineProperty(exports, "getDbPath", { enumerable: true, get: function () { return db_manager_js_1.getDbPath; } });
55
+ Object.defineProperty(exports, "fts5Search", { enumerable: true, get: function () { return db_manager_js_1.fts5Search; } });
56
+ Object.defineProperty(exports, "reindexEmbeddings", { enumerable: true, get: function () { return db_manager_js_1.reindexEmbeddings; } });
54
57
  // Database adapter
55
58
  var index_js_1 = require("./db-adapter/index.js");
56
59
  Object.defineProperty(exports, "createAdapter", { enumerable: true, get: function () { return index_js_1.createAdapter; } });
@@ -70,6 +73,31 @@ Object.defineProperty(exports, "DEFAULT_DB_PATH", { enumerable: true, get: funct
70
73
  // MAMA API
71
74
  const mama_api_js_1 = __importDefault(require("./mama-api.js"));
72
75
  exports.mama = mama_api_js_1.default;
76
+ // Memory V2
77
+ var types_js_1 = require("./memory/types.js");
78
+ Object.defineProperty(exports, "MEMORY_SCOPE_KINDS", { enumerable: true, get: function () { return types_js_1.MEMORY_SCOPE_KINDS; } });
79
+ Object.defineProperty(exports, "MEMORY_KINDS", { enumerable: true, get: function () { return types_js_1.MEMORY_KINDS; } });
80
+ Object.defineProperty(exports, "MEMORY_STATUSES", { enumerable: true, get: function () { return types_js_1.MEMORY_STATUSES; } });
81
+ Object.defineProperty(exports, "MEMORY_EDGE_TYPES", { enumerable: true, get: function () { return types_js_1.MEMORY_EDGE_TYPES; } });
82
+ Object.defineProperty(exports, "createEmptyRecallBundle", { enumerable: true, get: function () { return types_js_1.createEmptyRecallBundle; } });
83
+ var api_js_1 = require("./memory/api.js");
84
+ Object.defineProperty(exports, "saveMemory", { enumerable: true, get: function () { return api_js_1.saveMemory; } });
85
+ Object.defineProperty(exports, "recallMemory", { enumerable: true, get: function () { return api_js_1.recallMemory; } });
86
+ Object.defineProperty(exports, "buildProfile", { enumerable: true, get: function () { return api_js_1.buildProfile; } });
87
+ Object.defineProperty(exports, "ingestMemory", { enumerable: true, get: function () { return api_js_1.ingestMemory; } });
88
+ Object.defineProperty(exports, "evolveMemory", { enumerable: true, get: function () { return api_js_1.evolveMemory; } });
89
+ Object.defineProperty(exports, "buildMemoryBootstrap", { enumerable: true, get: function () { return api_js_1.buildMemoryBootstrap; } });
90
+ Object.defineProperty(exports, "createAuditAck", { enumerable: true, get: function () { return api_js_1.createAuditAck; } });
91
+ Object.defineProperty(exports, "recordMemoryAudit", { enumerable: true, get: function () { return api_js_1.recordMemoryAudit; } });
92
+ Object.defineProperty(exports, "ingestConversation", { enumerable: true, get: function () { return api_js_1.ingestConversation; } });
93
+ Object.defineProperty(exports, "setExtractionFn", { enumerable: true, get: function () { return api_js_1.setExtractionFn; } });
94
+ Object.defineProperty(exports, "upsertChannelSummary", { enumerable: true, get: function () { return api_js_1.upsertChannelSummary; } });
95
+ Object.defineProperty(exports, "getChannelSummary", { enumerable: true, get: function () { return api_js_1.getChannelSummary; } });
96
+ var extraction_prompt_js_1 = require("./memory/extraction-prompt.js");
97
+ Object.defineProperty(exports, "buildExtractionPrompt", { enumerable: true, get: function () { return extraction_prompt_js_1.buildExtractionPrompt; } });
98
+ Object.defineProperty(exports, "parseExtractionResponse", { enumerable: true, get: function () { return extraction_prompt_js_1.parseExtractionResponse; } });
99
+ var event_store_js_1 = require("./memory/event-store.js");
100
+ Object.defineProperty(exports, "listRecentMemoryEvents", { enumerable: true, get: function () { return event_store_js_1.listRecentMemoryEvents; } });
73
101
  // Config loader
74
102
  var config_loader_js_1 = require("./config-loader.js");
75
103
  Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_loader_js_1.loadConfig; } });
@@ -19,6 +19,9 @@
19
19
  */
20
20
  import { DecisionRecord } from './db-manager.js';
21
21
  import { SemanticEdges } from './decision-formatter.js';
22
+ import { saveMemory, recallMemory, buildProfile, ingestMemory, evolveMemory, buildMemoryBootstrap, createAuditAck, recordMemoryAudit, upsertChannelSummary, getChannelSummary } from './memory/api.js';
23
+ import { listOpenAuditFindings } from './memory/finding-store.js';
24
+ import { listRecentMemoryEvents } from './memory/event-store.js';
22
25
  /**
23
26
  * Parameters for mama.save()
24
27
  */
@@ -32,6 +35,13 @@ interface SaveParams {
32
35
  failure_reason?: string | null;
33
36
  limitation?: string | null;
34
37
  trust_context?: Record<string, unknown> | null;
38
+ is_static?: number;
39
+ scopes?: Array<{
40
+ kind: 'global' | 'user' | 'channel' | 'project';
41
+ id: string;
42
+ }>;
43
+ /** ISO 8601 date string for when the event actually occurred (e.g. "2023-01-15") */
44
+ event_date?: string | null;
35
45
  }
36
46
  /**
37
47
  * Similar decision result from search
@@ -43,6 +53,7 @@ interface SimilarDecision {
43
53
  reasoning?: string;
44
54
  similarity?: number;
45
55
  created_at?: number | string;
56
+ event_date?: string | null;
46
57
  }
47
58
  /**
48
59
  * Search result from mama.search()
@@ -394,7 +405,7 @@ export interface QualityReport {
394
405
  * outcome: 'success'
395
406
  * });
396
407
  */
397
- declare function save({ topic, decision, reasoning, confidence, type, outcome, failure_reason, limitation, trust_context, }: SaveParams): Promise<SaveResult>;
408
+ declare function save({ topic, decision, reasoning, confidence, type, outcome, failure_reason, limitation, trust_context: _trust_context, is_static, scopes: inputScopes, event_date, }: SaveParams): Promise<SaveResult>;
398
409
  /**
399
410
  * Recall decisions by topic
400
411
  *
@@ -485,6 +496,38 @@ interface UpdateOutcomeParams {
485
496
  limitation?: string | null;
486
497
  }
487
498
  declare function updateOutcome(decisionId: string, { outcome, failure_reason, limitation }: UpdateOutcomeParams): Promise<void>;
499
+ /**
500
+ * Expand search results with graph context (Phase 1 - Graph-Enhanced Retrieval)
501
+ *
502
+ * For each candidate decision:
503
+ * 1. Add supersedes chain (evolution history)
504
+ * 2. Add semantic edges (refines, contradicts)
505
+ * 3. Deduplicate by ID
506
+ * 4. Re-rank by relevance (primary candidates ranked higher)
507
+ *
508
+ * @param {Array} candidates - Initial search results from vector/keyword search
509
+ * @returns {Promise<Array>} Graph-enhanced results with evolution context
510
+ */
511
+ interface SearchCandidate {
512
+ id: string;
513
+ topic: string;
514
+ decision: string;
515
+ reasoning?: string | null;
516
+ confidence?: number;
517
+ similarity?: number;
518
+ created_at?: number | string;
519
+ graph_source?: string;
520
+ graph_rank?: number;
521
+ related_to?: string | null;
522
+ edge_reason?: string | null;
523
+ recency_score?: number;
524
+ recency_age_days?: number;
525
+ final_score?: number;
526
+ outcome?: string | null;
527
+ failure_reason?: string | null;
528
+ is_static?: number;
529
+ }
530
+ declare function expandWithGraph(candidates: SearchCandidate[]): Promise<SearchCandidate[]>;
488
531
  /**
489
532
  * Suggest relevant decisions based on user question
490
533
  *
@@ -520,6 +563,11 @@ interface SuggestFunctionOptions {
520
563
  recencyScale?: number;
521
564
  recencyDecay?: number;
522
565
  disableRecency?: boolean;
566
+ topicPrefix?: string;
567
+ scopes?: Array<{
568
+ kind: 'global' | 'user' | 'channel' | 'project';
569
+ id: string;
570
+ }>;
523
571
  }
524
572
  declare function suggest(userQuestion: string, options?: SuggestFunctionOptions): Promise<any>;
525
573
  /**
@@ -536,6 +584,10 @@ declare function suggest(userQuestion: string, options?: SuggestFunctionOptions)
536
584
  interface ListDecisionsOptions {
537
585
  limit?: number;
538
586
  format?: 'json' | 'markdown';
587
+ scopes?: Array<{
588
+ kind: 'global' | 'user' | 'channel' | 'project';
589
+ id: string;
590
+ }>;
539
591
  }
540
592
  declare function listDecisions(options?: ListDecisionsOptions): Promise<DecisionRecord[] | string>;
541
593
  /**
@@ -978,9 +1030,21 @@ declare function generateQualityReport(options?: QualityReportOptions): string |
978
1030
  declare const mama: {
979
1031
  save: typeof save;
980
1032
  suggest: typeof suggest;
1033
+ saveMemory: typeof saveMemory;
1034
+ recallMemory: typeof recallMemory;
981
1035
  list: typeof listDecisions;
982
1036
  listCheckpoints: typeof listCheckpoints;
983
1037
  updateOutcome: typeof updateOutcome;
1038
+ buildProfile: typeof buildProfile;
1039
+ ingestMemory: typeof ingestMemory;
1040
+ evolveMemory: typeof evolveMemory;
1041
+ buildMemoryBootstrap: typeof buildMemoryBootstrap;
1042
+ createAuditAck: typeof createAuditAck;
1043
+ recordMemoryAudit: typeof recordMemoryAudit;
1044
+ upsertChannelSummary: typeof upsertChannelSummary;
1045
+ getChannelSummary: typeof getChannelSummary;
1046
+ listAuditFindings: typeof listOpenAuditFindings;
1047
+ listRecentMemoryEvents: typeof listRecentMemoryEvents;
984
1048
  saveCheckpoint: typeof saveCheckpoint;
985
1049
  loadCheckpoint: typeof loadCheckpoint;
986
1050
  recall: typeof recall;
@@ -1003,7 +1067,8 @@ declare const mama: {
1003
1067
  verifyBackupExists: typeof verifyBackupExists;
1004
1068
  deleteAutoLinks: typeof deleteAutoLinks;
1005
1069
  validateCleanupResult: typeof validateCleanupResult;
1070
+ expandWithGraph: typeof expandWithGraph;
1006
1071
  };
1007
- export { save, suggest, listDecisions as list, listCheckpoints, updateOutcome, saveCheckpoint, loadCheckpoint, recall, proposeLink, approveLink, rejectLink, getPendingLinks, deprecateAutoLinks, calculateCoverage, calculateQuality, generateQualityReport, logRestartAttempt, calculateRestartSuccessRate, calculateRestartLatency, getRestartMetrics, scanAutoLinks, createLinkBackup, generatePreCleanupReport, restoreLinkBackup, verifyBackupExists, deleteAutoLinks, validateCleanupResult, };
1072
+ export { save, suggest, saveMemory, recallMemory, listDecisions as list, listCheckpoints, updateOutcome, buildProfile, ingestMemory, evolveMemory, buildMemoryBootstrap, createAuditAck, recordMemoryAudit, upsertChannelSummary, getChannelSummary, listOpenAuditFindings, listRecentMemoryEvents, saveCheckpoint, loadCheckpoint, recall, proposeLink, approveLink, rejectLink, getPendingLinks, deprecateAutoLinks, calculateCoverage, calculateQuality, generateQualityReport, logRestartAttempt, calculateRestartSuccessRate, calculateRestartLatency, getRestartMetrics, scanAutoLinks, createLinkBackup, generatePreCleanupReport, restoreLinkBackup, verifyBackupExists, deleteAutoLinks, validateCleanupResult, };
1008
1073
  export default mama;
1009
1074
  //# sourceMappingURL=mama-api.d.ts.map