@whenmoon-afk/memory-mcp 2.0.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +263 -0
  3. package/dist/database/connection.d.ts +47 -0
  4. package/dist/database/connection.d.ts.map +1 -0
  5. package/dist/database/connection.js +151 -0
  6. package/dist/database/connection.js.map +1 -0
  7. package/dist/database/schema.d.ts +33 -0
  8. package/dist/database/schema.d.ts.map +1 -0
  9. package/dist/database/schema.js +293 -0
  10. package/dist/database/schema.js.map +1 -0
  11. package/dist/extractors/entity-extractor.d.ts +25 -0
  12. package/dist/extractors/entity-extractor.d.ts.map +1 -0
  13. package/dist/extractors/entity-extractor.js +195 -0
  14. package/dist/extractors/entity-extractor.js.map +1 -0
  15. package/dist/extractors/fact-extractor.d.ts +38 -0
  16. package/dist/extractors/fact-extractor.d.ts.map +1 -0
  17. package/dist/extractors/fact-extractor.js +172 -0
  18. package/dist/extractors/fact-extractor.js.map +1 -0
  19. package/dist/extractors/summary-generator.d.ts +28 -0
  20. package/dist/extractors/summary-generator.d.ts.map +1 -0
  21. package/dist/extractors/summary-generator.js +149 -0
  22. package/dist/extractors/summary-generator.js.map +1 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +229 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/scoring/importance.d.ts +39 -0
  28. package/dist/scoring/importance.d.ts.map +1 -0
  29. package/dist/scoring/importance.js +150 -0
  30. package/dist/scoring/importance.js.map +1 -0
  31. package/dist/scoring/ttl-manager.d.ts +33 -0
  32. package/dist/scoring/ttl-manager.d.ts.map +1 -0
  33. package/dist/scoring/ttl-manager.js +99 -0
  34. package/dist/scoring/ttl-manager.js.map +1 -0
  35. package/dist/search/semantic-search.d.ts +15 -0
  36. package/dist/search/semantic-search.d.ts.map +1 -0
  37. package/dist/search/semantic-search.js +236 -0
  38. package/dist/search/semantic-search.js.map +1 -0
  39. package/dist/tools/memory-forget.d.ts +10 -0
  40. package/dist/tools/memory-forget.d.ts.map +1 -0
  41. package/dist/tools/memory-forget.js +34 -0
  42. package/dist/tools/memory-forget.js.map +1 -0
  43. package/dist/tools/memory-recall.d.ts +12 -0
  44. package/dist/tools/memory-recall.d.ts.map +1 -0
  45. package/dist/tools/memory-recall.js +106 -0
  46. package/dist/tools/memory-recall.js.map +1 -0
  47. package/dist/tools/memory-store.d.ts +13 -0
  48. package/dist/tools/memory-store.d.ts.map +1 -0
  49. package/dist/tools/memory-store.js +279 -0
  50. package/dist/tools/memory-store.js.map +1 -0
  51. package/dist/tools/response-formatter.d.ts +71 -0
  52. package/dist/tools/response-formatter.d.ts.map +1 -0
  53. package/dist/tools/response-formatter.js +180 -0
  54. package/dist/tools/response-formatter.js.map +1 -0
  55. package/dist/types/index.d.ts +244 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/types/index.js +29 -0
  58. package/dist/types/index.js.map +1 -0
  59. package/dist/utils/token-estimator.d.ts +33 -0
  60. package/dist/utils/token-estimator.d.ts.map +1 -0
  61. package/dist/utils/token-estimator.js +54 -0
  62. package/dist/utils/token-estimator.js.map +1 -0
  63. package/package.json +71 -0
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Importance scoring system for memories
3
+ */
4
+ import { calculateComplexity, isUserPreference, isExplicit } from '../extractors/fact-extractor.js';
5
+ /**
6
+ * Calculate importance score automatically (0-10)
7
+ */
8
+ export function calculateImportance(content, type, entities, metadata, hasProvenance) {
9
+ const factors = analyzeImportanceFactors(content, type, entities, metadata, hasProvenance);
10
+ return calculateImportanceFromFactors(factors);
11
+ }
12
+ /**
13
+ * Analyze factors that contribute to importance
14
+ */
15
+ export function analyzeImportanceFactors(content, type, entities, metadata, hasProvenance) {
16
+ return {
17
+ contentComplexity: calculateComplexity(content),
18
+ entityCount: entities.length,
19
+ isUserPreference: isUserPreference(content),
20
+ hasProvenance,
21
+ hasMetadata: Object.keys(metadata).length > 0,
22
+ isExplicit: isExplicit(content),
23
+ typeBonus: calculateTypeBonus(type),
24
+ };
25
+ }
26
+ /**
27
+ * Calculate importance from analyzed factors
28
+ */
29
+ export function calculateImportanceFromFactors(factors) {
30
+ // Start with baseline
31
+ let score = 3.0;
32
+ // Content complexity (0-3 points)
33
+ score += factors.contentComplexity * 3;
34
+ // Entity connections (0-2 points, max out at 4 entities)
35
+ score += Math.min(factors.entityCount * 0.5, 2.0);
36
+ // User preference boost (0 or 2 points)
37
+ if (factors.isUserPreference) {
38
+ score += 2.0;
39
+ }
40
+ // Provenance tracking (0 or 0.5 points)
41
+ if (factors.hasProvenance) {
42
+ score += 0.5;
43
+ }
44
+ // Rich metadata (0 or 0.5 points)
45
+ if (factors.hasMetadata) {
46
+ score += 0.5;
47
+ }
48
+ // Explicit facts are more trustworthy (0 or 1 point)
49
+ if (factors.isExplicit) {
50
+ score += 1.0;
51
+ }
52
+ // Type-specific bonus
53
+ score += factors.typeBonus;
54
+ // Clamp to 0-10 range
55
+ return Math.max(0, Math.min(10, Math.round(score * 10) / 10));
56
+ }
57
+ /**
58
+ * Calculate type-specific importance bonus
59
+ */
60
+ function calculateTypeBonus(type) {
61
+ switch (type) {
62
+ case 'relationship':
63
+ return 1.0; // Relationships connect knowledge
64
+ case 'entity':
65
+ return 0.5; // Entities are moderately important
66
+ case 'fact':
67
+ return 0.0; // Facts use default importance
68
+ default:
69
+ return 0.0;
70
+ }
71
+ }
72
+ /**
73
+ * Adjust importance based on context signals
74
+ */
75
+ export function adjustImportanceForContext(baseImportance, signals) {
76
+ let adjusted = baseImportance;
77
+ // Security-sensitive: max importance
78
+ if (signals.isSecuritySensitive) {
79
+ adjusted = Math.max(adjusted, 10);
80
+ }
81
+ // User identity: very high importance
82
+ if (signals.isUserIdentity) {
83
+ adjusted = Math.max(adjusted, 9);
84
+ }
85
+ // Project requirement: high importance
86
+ if (signals.isProjectRequirement) {
87
+ adjusted = Math.max(adjusted, 7);
88
+ }
89
+ // Deprecated: low importance
90
+ if (signals.isDeprecated) {
91
+ adjusted = Math.min(adjusted, 2);
92
+ }
93
+ // User explicitly marked: boost by 2 points
94
+ if (signals.userExplicitlyMarked) {
95
+ adjusted += 2;
96
+ }
97
+ return Math.max(0, Math.min(10, adjusted));
98
+ }
99
+ /**
100
+ * Get recommended TTL for importance level
101
+ */
102
+ export function getRecommendedTTL(importance) {
103
+ if (importance >= 10)
104
+ return null; // Permanent
105
+ if (importance >= 8)
106
+ return 365; // 1 year
107
+ if (importance >= 6)
108
+ return 180; // 6 months
109
+ if (importance >= 4)
110
+ return 90; // 3 months
111
+ if (importance >= 2)
112
+ return 30; // 1 month
113
+ return 7; // 1 week
114
+ }
115
+ /**
116
+ * Calculate effective importance (with decay over time)
117
+ */
118
+ export function calculateEffectiveImportance(baseImportance, lastAccessed, now) {
119
+ const daysSinceAccess = (now - lastAccessed) / (1000 * 60 * 60 * 24);
120
+ if (baseImportance < 6) {
121
+ // Low-importance memories decay faster (1% per day)
122
+ const decayRate = 0.01;
123
+ const decayFactor = 1 - daysSinceAccess * decayRate * 2;
124
+ return baseImportance * Math.max(decayFactor, 0.5);
125
+ }
126
+ else {
127
+ // High-importance memories resist decay (0.5% per day)
128
+ const decayRate = 0.005;
129
+ const decayFactor = 1 - daysSinceAccess * decayRate;
130
+ return baseImportance * Math.max(decayFactor, 0.8);
131
+ }
132
+ }
133
+ /**
134
+ * Boost importance on repeated access
135
+ */
136
+ export function boostImportanceOnAccess(currentImportance, accessCount, daysSinceCreated) {
137
+ // If accessed multiple times in short period, boost importance
138
+ const accessRate = accessCount / Math.max(daysSinceCreated, 1);
139
+ if (accessRate > 0.1) {
140
+ // Accessed frequently (>10% of days)
141
+ return Math.min(currentImportance + 1, 10);
142
+ }
143
+ else if (accessRate > 0.05) {
144
+ // Accessed moderately (>5% of days)
145
+ return Math.min(currentImportance + 0.5, 10);
146
+ }
147
+ // No boost
148
+ return currentImportance;
149
+ }
150
+ //# sourceMappingURL=importance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importance.js","sourceRoot":"","sources":["../../src/scoring/importance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * TTL (Time-To-Live) management for memories
3
+ */
4
+ import type { TTLConfig } from '../types/index.js';
5
+ /**
6
+ * Default TTL configuration
7
+ */
8
+ export declare const DEFAULT_TTL_CONFIG: TTLConfig;
9
+ /**
10
+ * Calculate TTL in days based on importance
11
+ */
12
+ export declare function calculateTTLDays(importance: number, config?: TTLConfig): number | null;
13
+ /**
14
+ * Calculate expiration timestamp
15
+ */
16
+ export declare function calculateExpiresAt(ttlDays: number | null, importance: number, createdAt?: number): number | null;
17
+ /**
18
+ * Check if memory should be refreshed on access
19
+ */
20
+ export declare function shouldRefreshTTL(importance: number, lastAccessed: number, now?: number, config?: TTLConfig): boolean;
21
+ /**
22
+ * Calculate new TTL on access (refresh)
23
+ */
24
+ export declare function refreshTTL(originalTTLDays: number | null, importance: number, lastAccessed: number, now?: number, config?: TTLConfig): number | null;
25
+ /**
26
+ * Check if memory is expired
27
+ */
28
+ export declare function isExpired(expiresAt: number | null, now?: number): boolean;
29
+ /**
30
+ * Calculate time until expiration
31
+ */
32
+ export declare function getTimeUntilExpiration(expiresAt: number | null, now?: number): number | null;
33
+ //# sourceMappingURL=ttl-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ttl-manager.d.ts","sourceRoot":"","sources":["../../src/scoring/ttl-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAKhC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,GAAE,SAA8B,GAAG,MAAM,GAAG,IAAI,CAa1G;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAmB,GAC7B,MAAM,GAAG,IAAI,CAWf;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,GAAE,MAAmB,EACxB,MAAM,GAAE,SAA8B,GACrC,OAAO,CAeT;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,GAAE,MAAmB,EACxB,MAAM,GAAE,SAA8B,GACrC,MAAM,GAAG,IAAI,CAwBf;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAMrF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,GAAG,IAAI,CAOxG"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * TTL (Time-To-Live) management for memories
3
+ */
4
+ import { getRecommendedTTL } from './importance.js';
5
+ /**
6
+ * Default TTL configuration
7
+ */
8
+ export const DEFAULT_TTL_CONFIG = {
9
+ defaultDays: 90,
10
+ importanceMultiplier: 0.7, // Multiply base TTL by this factor based on importance
11
+ accessBonusDays: 30, // Bonus days added on access for important memories
12
+ refreshThresholdDays: 7, // Minimum days since last access before refresh
13
+ };
14
+ /**
15
+ * Calculate TTL in days based on importance
16
+ */
17
+ export function calculateTTLDays(importance, config = DEFAULT_TTL_CONFIG) {
18
+ // Use recommended TTL from importance tier
19
+ const recommended = getRecommendedTTL(importance);
20
+ if (recommended === null) {
21
+ return null; // Permanent
22
+ }
23
+ // Apply importance multiplier to base TTL
24
+ const importanceFactor = (importance / 10) * config.importanceMultiplier;
25
+ const adjusted = Math.round(recommended * (1 + importanceFactor));
26
+ return Math.max(1, adjusted);
27
+ }
28
+ /**
29
+ * Calculate expiration timestamp
30
+ */
31
+ export function calculateExpiresAt(ttlDays, importance, createdAt = Date.now()) {
32
+ if (ttlDays === null) {
33
+ return null; // Permanent memory
34
+ }
35
+ const baseTTL = ttlDays * 24 * 60 * 60 * 1000;
36
+ // Add importance bonus (up to 7 extra days for importance 10)
37
+ const importanceBonus = (importance / 10) * 7 * 24 * 60 * 60 * 1000;
38
+ return createdAt + baseTTL + importanceBonus;
39
+ }
40
+ /**
41
+ * Check if memory should be refreshed on access
42
+ */
43
+ export function shouldRefreshTTL(importance, lastAccessed, now = Date.now(), config = DEFAULT_TTL_CONFIG) {
44
+ const daysSinceAccess = (now - lastAccessed) / (1000 * 60 * 60 * 24);
45
+ // Important memories (>=6): refresh if accessed after 7+ days
46
+ if (importance >= 6 && daysSinceAccess > config.refreshThresholdDays) {
47
+ return true;
48
+ }
49
+ // Moderately important (4-5): refresh if accessed after 30+ days
50
+ if (importance >= 4 && daysSinceAccess > 30) {
51
+ return true;
52
+ }
53
+ // Low importance (1-3): don't refresh, let it expire
54
+ return false;
55
+ }
56
+ /**
57
+ * Calculate new TTL on access (refresh)
58
+ */
59
+ export function refreshTTL(originalTTLDays, importance, lastAccessed, now = Date.now(), config = DEFAULT_TTL_CONFIG) {
60
+ if (originalTTLDays === null) {
61
+ return null; // Permanent memory, no refresh needed
62
+ }
63
+ if (!shouldRefreshTTL(importance, lastAccessed, now, config)) {
64
+ return null; // No refresh
65
+ }
66
+ // Calculate access bonus
67
+ const accessBonus = (importance / 10) * config.accessBonusDays * 24 * 60 * 60 * 1000;
68
+ // Base TTL + access bonus
69
+ const baseTTL = originalTTLDays * 24 * 60 * 60 * 1000;
70
+ if (importance >= 6) {
71
+ // Important memories: full refresh + bonus
72
+ return now + baseTTL + accessBonus;
73
+ }
74
+ else if (importance >= 4) {
75
+ // Moderately important: refresh + half bonus
76
+ return now + baseTTL + accessBonus / 2;
77
+ }
78
+ return null;
79
+ }
80
+ /**
81
+ * Check if memory is expired
82
+ */
83
+ export function isExpired(expiresAt, now = Date.now()) {
84
+ if (expiresAt === null) {
85
+ return false; // Permanent memory never expires
86
+ }
87
+ return expiresAt <= now;
88
+ }
89
+ /**
90
+ * Calculate time until expiration
91
+ */
92
+ export function getTimeUntilExpiration(expiresAt, now = Date.now()) {
93
+ if (expiresAt === null) {
94
+ return null; // Permanent memory
95
+ }
96
+ const timeLeft = expiresAt - now;
97
+ return Math.max(0, timeLeft);
98
+ }
99
+ //# sourceMappingURL=ttl-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ttl-manager.js","sourceRoot":"","sources":["../../src/scoring/ttl-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Full-text search implementation using SQLite FTS5
3
+ * Replaces vector embeddings with lightweight keyword/phrase matching
4
+ */
5
+ import type Database from 'better-sqlite3';
6
+ import type { MemorySearchResult, SearchOptionsInternal } from '../types/index.js';
7
+ /**
8
+ * Perform full-text search on memories using FTS5
9
+ * Returns: { results: MemorySearchResult[], totalCount: number }
10
+ */
11
+ export declare function semanticSearch(db: Database.Database, options: SearchOptionsInternal): {
12
+ results: MemorySearchResult[];
13
+ totalCount: number;
14
+ };
15
+ //# sourceMappingURL=semantic-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../src/search/semantic-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAEV,kBAAkB,EAClB,qBAAqB,EAKtB,MAAM,mBAAmB,CAAC;AA2B3B;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,qBAAqB,GAC7B;IAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAmDvD"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Full-text search implementation using SQLite FTS5
3
+ * Replaces vector embeddings with lightweight keyword/phrase matching
4
+ */
5
+ import { deserializeMetadata } from '../database/connection.js';
6
+ /**
7
+ * Perform full-text search on memories using FTS5
8
+ * Returns: { results: MemorySearchResult[], totalCount: number }
9
+ */
10
+ export function semanticSearch(db, options) {
11
+ const { query, type, entities, limit = 10, offset = 0, minImportance, includeExpired = false, } = options;
12
+ // Build FTS5 query (use simple keyword matching)
13
+ // FTS5 syntax: "phrase search" OR keyword1 keyword2
14
+ const ftsQuery = query.trim();
15
+ // Pre-filter candidates using FTS5
16
+ const filters = { includeExpired };
17
+ if (type !== undefined)
18
+ filters.type = type;
19
+ if (entities !== undefined)
20
+ filters.entities = entities;
21
+ if (minImportance !== undefined)
22
+ filters.minImportance = minImportance;
23
+ const candidates = getFilteredCandidates(db, ftsQuery, filters);
24
+ // Calculate hybrid scores (FTS rank + importance + recency)
25
+ const scoredResults = candidates.map((memory) => {
26
+ const hybridScore = calculateHybridScore(memory);
27
+ return {
28
+ ...memory,
29
+ score: hybridScore,
30
+ entities: [], // Will be populated later
31
+ provenance: [], // Will be populated later
32
+ };
33
+ });
34
+ // Sort by score
35
+ scoredResults.sort((a, b) => b.score - a.score);
36
+ // Total count before pagination
37
+ const totalCount = scoredResults.length;
38
+ // Apply pagination
39
+ const paginatedResults = scoredResults.slice(offset, offset + limit);
40
+ // Enrich with entities and provenance
41
+ const enrichedResults = enrichResults(db, paginatedResults);
42
+ return {
43
+ results: enrichedResults,
44
+ totalCount,
45
+ };
46
+ }
47
+ /**
48
+ * Get filtered candidate memories using FTS5
49
+ */
50
+ function getFilteredCandidates(db, ftsQuery, filters) {
51
+ const { type, entities, minImportance, includeExpired } = filters;
52
+ // Use FTS5 for keyword search
53
+ let query = `
54
+ SELECT m.*
55
+ FROM memories m
56
+ JOIN memories_fts fts ON m.id = fts.memory_id
57
+ WHERE fts.memories_fts MATCH ?
58
+ AND m.is_deleted = 0
59
+ `;
60
+ const params = [ftsQuery];
61
+ // Type filter
62
+ if (type) {
63
+ query += ` AND m.type = ?`;
64
+ params.push(type);
65
+ }
66
+ // Importance filter
67
+ if (minImportance !== undefined) {
68
+ query += ` AND m.importance >= ?`;
69
+ params.push(minImportance);
70
+ }
71
+ // Expiration filter
72
+ if (!includeExpired) {
73
+ query += ` AND (m.expires_at IS NULL OR m.expires_at > ?)`;
74
+ params.push(Date.now());
75
+ }
76
+ // Entity filter (if specified)
77
+ if (entities && entities.length > 0) {
78
+ query += `
79
+ AND m.id IN (
80
+ SELECT memory_id FROM memory_entities
81
+ WHERE entity_id IN (
82
+ SELECT id FROM entities WHERE name IN (${entities.map(() => '?').join(',')})
83
+ )
84
+ )
85
+ `;
86
+ params.push(...entities);
87
+ }
88
+ // Order by importance and recency (FTS match is implicit by MATCH clause)
89
+ // Actual ranking happens in calculateHybridScore()
90
+ query += ` ORDER BY m.importance DESC, m.last_accessed DESC`;
91
+ const stmt = db.prepare(query);
92
+ const rows = stmt.all(...params);
93
+ return rows.map(rowToMemory);
94
+ }
95
+ /**
96
+ * Calculate hybrid score (FTS rank + importance + recency)
97
+ */
98
+ function calculateHybridScore(memory) {
99
+ const now = Date.now();
100
+ // Importance component (0-1)
101
+ const importanceScore = memory.importance / 10;
102
+ // Recency component (0-1)
103
+ const recencyScore = calculateRecencyScore(memory.last_accessed, now);
104
+ // Frequency component (0-1)
105
+ const frequencyScore = Math.min(memory.access_count / 100, 1.0);
106
+ // Weighted combination
107
+ return (importanceScore * 0.4 + // 40% importance
108
+ recencyScore * 0.3 + // 30% recency
109
+ frequencyScore * 0.2 + // 20% frequency
110
+ 0.1 // 10% base score
111
+ );
112
+ }
113
+ /**
114
+ * Calculate recency score (0-1)
115
+ */
116
+ function calculateRecencyScore(lastAccessed, now) {
117
+ const hoursAgo = (now - lastAccessed) / (1000 * 60 * 60);
118
+ if (hoursAgo < 1)
119
+ return 1.0;
120
+ if (hoursAgo < 6)
121
+ return 0.8;
122
+ if (hoursAgo < 24)
123
+ return 0.6;
124
+ if (hoursAgo < 168)
125
+ return 0.4;
126
+ if (hoursAgo < 720)
127
+ return 0.2;
128
+ return 0.0;
129
+ }
130
+ /**
131
+ * Enrich results with entities and provenance
132
+ */
133
+ function enrichResults(db, results) {
134
+ if (results.length === 0) {
135
+ return results;
136
+ }
137
+ // Batch fetch entities
138
+ const memoryIds = results.map((r) => r.id);
139
+ const entitiesMap = batchFetchEntities(db, memoryIds);
140
+ // Batch fetch provenance (last 3 records per memory)
141
+ const provenanceMap = batchFetchProvenance(db, memoryIds);
142
+ return results.map((result) => ({
143
+ ...result,
144
+ entities: entitiesMap.get(result.id) || [],
145
+ provenance: provenanceMap.get(result.id) || [],
146
+ }));
147
+ }
148
+ /**
149
+ * Batch fetch entities for memories
150
+ */
151
+ function batchFetchEntities(db, memoryIds) {
152
+ const entitiesMap = new Map();
153
+ if (memoryIds.length === 0) {
154
+ return entitiesMap;
155
+ }
156
+ const placeholders = memoryIds.map(() => '?').join(',');
157
+ const query = `
158
+ SELECT me.memory_id, e.*
159
+ FROM memory_entities me
160
+ JOIN entities e ON me.entity_id = e.id
161
+ WHERE me.memory_id IN (${placeholders})
162
+ ORDER BY e.name
163
+ `;
164
+ const rows = db.prepare(query).all(...memoryIds);
165
+ for (const row of rows) {
166
+ const memoryId = row.memory_id;
167
+ if (!entitiesMap.has(memoryId)) {
168
+ entitiesMap.set(memoryId, []);
169
+ }
170
+ entitiesMap.get(memoryId)?.push({
171
+ id: row.id,
172
+ name: row.name,
173
+ type: row.type,
174
+ metadata: deserializeMetadata(row.metadata),
175
+ created_at: row.created_at,
176
+ });
177
+ }
178
+ return entitiesMap;
179
+ }
180
+ /**
181
+ * Batch fetch provenance for memories
182
+ */
183
+ function batchFetchProvenance(db, memoryIds) {
184
+ const provenanceMap = new Map();
185
+ if (memoryIds.length === 0) {
186
+ return provenanceMap;
187
+ }
188
+ const placeholders = memoryIds.map(() => '?').join(',');
189
+ const query = `
190
+ SELECT *
191
+ FROM provenance
192
+ WHERE memory_id IN (${placeholders})
193
+ ORDER BY memory_id, timestamp DESC
194
+ `;
195
+ const rows = db.prepare(query).all(...memoryIds);
196
+ for (const row of rows) {
197
+ const memoryId = row.memory_id;
198
+ if (!provenanceMap.has(memoryId)) {
199
+ provenanceMap.set(memoryId, []);
200
+ }
201
+ const provenance = provenanceMap.get(memoryId);
202
+ if (provenance && provenance.length < 3) {
203
+ // Only keep last 3 provenance records
204
+ provenance.push({
205
+ id: row.id,
206
+ memory_id: row.memory_id,
207
+ operation: row.operation,
208
+ timestamp: row.timestamp,
209
+ source: row.source,
210
+ context: row.context,
211
+ user_id: row.user_id,
212
+ changes: row.changes ? deserializeMetadata(row.changes) : null,
213
+ });
214
+ }
215
+ }
216
+ return provenanceMap;
217
+ }
218
+ /**
219
+ * Convert database row to Memory object
220
+ */
221
+ function rowToMemory(row) {
222
+ return {
223
+ id: row.id,
224
+ content: row.content,
225
+ summary: row.summary,
226
+ type: row.type,
227
+ importance: row.importance,
228
+ created_at: row.created_at,
229
+ last_accessed: row.last_accessed,
230
+ access_count: row.access_count,
231
+ expires_at: row.expires_at,
232
+ metadata: deserializeMetadata(row.metadata),
233
+ is_deleted: row.is_deleted === 1,
234
+ };
235
+ }
236
+ //# sourceMappingURL=semantic-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../src/search/semantic-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Memory forget tool - Soft delete memories
3
+ */
4
+ import type Database from 'better-sqlite3';
5
+ import type { ForgetResponse } from '../types/index.js';
6
+ /**
7
+ * Forget (soft delete) a memory
8
+ */
9
+ export declare function memoryForget(db: Database.Database, id: string, reason?: string): Promise<ForgetResponse>;
10
+ //# sourceMappingURL=memory-forget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-forget.d.ts","sourceRoot":"","sources":["../../src/tools/memory-forget.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAIxD;;GAEG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,CAAC,CAwCzB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Memory forget tool - Soft delete memories
3
+ */
4
+ import { now, generateId, serializeMetadata } from '../database/connection.js';
5
+ import { ValidationError } from '../types/index.js';
6
+ /**
7
+ * Forget (soft delete) a memory
8
+ */
9
+ export async function memoryForget(db, id, reason) {
10
+ // Check if memory exists
11
+ const existing = db
12
+ .prepare('SELECT id FROM memories WHERE id = ? AND is_deleted = 0')
13
+ .get(id);
14
+ if (!existing) {
15
+ throw new ValidationError(`Memory ${id} not found or already deleted`);
16
+ }
17
+ // Soft delete (mark as deleted)
18
+ const currentTime = now();
19
+ db.prepare('UPDATE memories SET is_deleted = 1 WHERE id = ?').run(id);
20
+ // Create provenance record
21
+ const provenanceId = generateId('prov');
22
+ db.prepare(`
23
+ INSERT INTO provenance (
24
+ id, memory_id, operation, timestamp, source, context, user_id, changes
25
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
26
+ `).run(provenanceId, id, 'delete', currentTime, 'user', reason || 'User requested deletion', null, serializeMetadata({ soft_delete: true }));
27
+ const response = {
28
+ success: true,
29
+ memory_id: id,
30
+ message: `Memory soft-deleted successfully. Reason: ${reason || 'Not specified'}`,
31
+ };
32
+ return response;
33
+ }
34
+ //# sourceMappingURL=memory-forget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-forget.js","sourceRoot":"","sources":["../../src/tools/memory-forget.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,EAAqB,EACrB,EAAU,EACV,MAAe;IAEf,yBAAyB;IACzB,MAAM,QAAQ,GAAG,EAAE;SAChB,OAAO,CAAC,yDAAyD,CAAC;SAClE,GAAG,CAAC,EAAE,CAA+B,CAAC;IAEzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,eAAe,CAAC,UAAU,EAAE,+BAA+B,CAAC,CAAC;IACzE,CAAC;IAED,gCAAgC;IAChC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;IAC1B,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEtE,2BAA2B;IAC3B,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACxC,EAAE,CAAC,OAAO,CACR;;;;GAID,CACA,CAAC,GAAG,CACH,YAAY,EACZ,EAAE,EACF,QAAQ,EACR,WAAW,EACX,MAAM,EACN,MAAM,IAAI,yBAAyB,EACnC,IAAI,EACJ,iBAAiB,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CACzC,CAAC;IAEF,MAAM,QAAQ,GAAmB;QAC/B,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,6CAA6C,MAAM,IAAI,eAAe,EAAE;KAClF,CAAC;IAEF,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Memory recall tool - Token-aware semantic search
3
+ * v3.0: Dual-response pattern (index + details) for skill-like progressive loading
4
+ */
5
+ import type Database from 'better-sqlite3';
6
+ import type { SearchOptions, RecallResponse } from '../types/index.js';
7
+ /**
8
+ * Recall memories using semantic search with intelligent token budgeting
9
+ * Returns: index (all matches as summaries) + details (top matches with full content)
10
+ */
11
+ export declare function memoryRecall(db: Database.Database, options: SearchOptions): Promise<RecallResponse>;
12
+ //# sourceMappingURL=memory-recall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-recall.d.ts","sourceRoot":"","sources":["../../src/tools/memory-recall.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EACV,aAAa,EAEb,cAAc,EAMf,MAAM,mBAAmB,CAAC;AAM3B;;;GAGG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC,CAwGzB"}