@postnesia/mcp 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/dist/access.d.ts +0 -22
- package/dist/access.js +0 -63
- package/dist/importance.d.ts +0 -44
- package/dist/importance.js +0 -145
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postnesia/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "An MCP server to interact with the Postnesia database",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"typescript": "^5.7.3"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"build": "pnpm clean && tsc -p tsconfig.json",
|
|
25
|
+
"clean": "rm -rf ./dist",
|
|
25
26
|
"start": "tsx src/index.ts"
|
|
26
27
|
}
|
|
27
28
|
}
|
package/dist/access.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Access Tracking System
|
|
3
|
-
* Logs when memories are retrieved and updates last_accessed on the memory row.
|
|
4
|
-
* Feeds into L1 decay calculations.
|
|
5
|
-
*/
|
|
6
|
-
export interface AccessLogEntry {
|
|
7
|
-
memory_id: number;
|
|
8
|
-
context?: string;
|
|
9
|
-
accessed_at: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Record that a memory was accessed (updates both access_log and memory.last_accessed)
|
|
13
|
-
*/
|
|
14
|
-
export declare function logAccess(memory_id: number, context?: string): void;
|
|
15
|
-
export declare function getAccessCount(memory_id: number, daysBack?: number): number;
|
|
16
|
-
export declare function getRecentlyAccessed(limit?: number): number[];
|
|
17
|
-
export declare function getAccessHistory(memory_id: number): AccessLogEntry[];
|
|
18
|
-
/**
|
|
19
|
-
* Calculate relevance boost based on access patterns
|
|
20
|
-
* Recent access + frequency = higher relevance
|
|
21
|
-
*/
|
|
22
|
-
export declare function calculateAccessBoost(memory_id: number): number;
|
package/dist/access.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Access Tracking System
|
|
3
|
-
* Logs when memories are retrieved and updates last_accessed on the memory row.
|
|
4
|
-
* Feeds into L1 decay calculations.
|
|
5
|
-
*/
|
|
6
|
-
import { getDb, recordAccess } from '@postnesia/db';
|
|
7
|
-
/**
|
|
8
|
-
* Record that a memory was accessed (updates both access_log and memory.last_accessed)
|
|
9
|
-
*/
|
|
10
|
-
export function logAccess(memory_id, context) {
|
|
11
|
-
try {
|
|
12
|
-
const db = getDb(false);
|
|
13
|
-
recordAccess(db, memory_id, context);
|
|
14
|
-
}
|
|
15
|
-
catch (error) {
|
|
16
|
-
console.error(`[access-tracker] Warning: Could not log access for #${memory_id}:`, error?.message);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export function getAccessCount(memory_id, daysBack = 30) {
|
|
20
|
-
const db = getDb(true);
|
|
21
|
-
const result = db.prepare(`
|
|
22
|
-
SELECT COUNT(*) as count
|
|
23
|
-
FROM access_log
|
|
24
|
-
WHERE memory_id = ?
|
|
25
|
-
AND accessed_at > datetime('now', '-${daysBack} days')
|
|
26
|
-
`).get(memory_id);
|
|
27
|
-
return result.count;
|
|
28
|
-
}
|
|
29
|
-
export function getRecentlyAccessed(limit = 20) {
|
|
30
|
-
const db = getDb(true);
|
|
31
|
-
const results = db.prepare(`
|
|
32
|
-
SELECT memory_id, COUNT(*) as access_count
|
|
33
|
-
FROM access_log
|
|
34
|
-
WHERE accessed_at > datetime('now', '-7 days')
|
|
35
|
-
GROUP BY memory_id
|
|
36
|
-
ORDER BY access_count DESC, MAX(accessed_at) DESC
|
|
37
|
-
LIMIT ?
|
|
38
|
-
`).all(limit);
|
|
39
|
-
return results.map(r => r.memory_id);
|
|
40
|
-
}
|
|
41
|
-
export function getAccessHistory(memory_id) {
|
|
42
|
-
const db = getDb(true);
|
|
43
|
-
return db.prepare(`
|
|
44
|
-
SELECT memory_id, accessed_at, context
|
|
45
|
-
FROM access_log
|
|
46
|
-
WHERE memory_id = ?
|
|
47
|
-
ORDER BY accessed_at DESC
|
|
48
|
-
LIMIT 50
|
|
49
|
-
`).all(memory_id);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Calculate relevance boost based on access patterns
|
|
53
|
-
* Recent access + frequency = higher relevance
|
|
54
|
-
*/
|
|
55
|
-
export function calculateAccessBoost(memory_id) {
|
|
56
|
-
const last7Days = getAccessCount(memory_id, 7);
|
|
57
|
-
const last30Days = getAccessCount(memory_id, 30);
|
|
58
|
-
const recentWeight = last7Days * 2;
|
|
59
|
-
const olderWeight = (last30Days - last7Days);
|
|
60
|
-
const totalScore = recentWeight + olderWeight;
|
|
61
|
-
// Normalize to 0-2 range
|
|
62
|
-
return Math.min(2, totalScore / 5);
|
|
63
|
-
}
|
package/dist/importance.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Importance Dynamics
|
|
3
|
-
* Adjust memory importance based on age, access patterns, and relationships
|
|
4
|
-
*/
|
|
5
|
-
export interface ImportanceFactors {
|
|
6
|
-
baseImportance: number;
|
|
7
|
-
ageDecay: number;
|
|
8
|
-
accessBoost: number;
|
|
9
|
-
relationshipBoost: number;
|
|
10
|
-
finalScore: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Calculate age decay factor
|
|
14
|
-
* Recent memories maintain importance, old ones decay unless accessed
|
|
15
|
-
*/
|
|
16
|
-
export declare function calculateAgeDecay(timestamp: string): number;
|
|
17
|
-
/**
|
|
18
|
-
* Calculate dynamic importance score
|
|
19
|
-
* Base importance + access boost - age decay
|
|
20
|
-
*/
|
|
21
|
-
export declare function calculateDynamicImportance(memory_id: number): ImportanceFactors;
|
|
22
|
-
/**
|
|
23
|
-
* Get memories eligible for L1 based on dynamic scoring.
|
|
24
|
-
* Uses the decay query from PHILOSOPHY.md: importance penalized by last_accessed staleness,
|
|
25
|
-
* superseded memories excluded.
|
|
26
|
-
*/
|
|
27
|
-
export declare function getL1Candidates(limit?: number): Array<{
|
|
28
|
-
id: number;
|
|
29
|
-
type: string;
|
|
30
|
-
content_l1: string;
|
|
31
|
-
timestamp: string;
|
|
32
|
-
last_accessed: string;
|
|
33
|
-
baseImportance: number;
|
|
34
|
-
dynamicScore: number;
|
|
35
|
-
}>;
|
|
36
|
-
/**
|
|
37
|
-
* Consolidation: Review and adjust importances based on access patterns
|
|
38
|
-
*/
|
|
39
|
-
export declare function runConsolidation(): {
|
|
40
|
-
reviewed: number;
|
|
41
|
-
boosted: number;
|
|
42
|
-
decayed: number;
|
|
43
|
-
unchanged: number;
|
|
44
|
-
};
|
package/dist/importance.js
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Importance Dynamics
|
|
3
|
-
* Adjust memory importance based on age, access patterns, and relationships
|
|
4
|
-
*/
|
|
5
|
-
import { getDb, queries } from '@postnesia/db';
|
|
6
|
-
import { calculateAccessBoost } from './access.js';
|
|
7
|
-
/**
|
|
8
|
-
* Calculate relationship boost based on graph connectivity
|
|
9
|
-
* Memories that are hubs in the relationship graph are more valuable
|
|
10
|
-
*/
|
|
11
|
-
function calculateRelationshipBoost(memory_id) {
|
|
12
|
-
const db = getDb(true);
|
|
13
|
-
// Count total connections
|
|
14
|
-
const connections = db.prepare(`
|
|
15
|
-
SELECT COUNT(*) as count
|
|
16
|
-
FROM relationship
|
|
17
|
-
WHERE from_id = ? OR to_id = ?
|
|
18
|
-
`).get(memory_id, memory_id);
|
|
19
|
-
// Count connections to high-importance memories (4+)
|
|
20
|
-
const importantConnections = db.prepare(`
|
|
21
|
-
SELECT COUNT(*) as count
|
|
22
|
-
FROM relationship r
|
|
23
|
-
JOIN memory m ON (
|
|
24
|
-
CASE
|
|
25
|
-
WHEN r.from_id = ? THEN m.id = r.to_id
|
|
26
|
-
ELSE m.id = r.from_id
|
|
27
|
-
END
|
|
28
|
-
)
|
|
29
|
-
WHERE (r.from_id = ? OR r.to_id = ?)
|
|
30
|
-
AND m.importance >= 4
|
|
31
|
-
`).get(memory_id, memory_id, memory_id);
|
|
32
|
-
// Boost calculation:
|
|
33
|
-
// - Base: 0.1 per connection (up to +1.0 for 10 connections)
|
|
34
|
-
// - Bonus: +0.2 per important connection
|
|
35
|
-
const baseBoost = Math.min(1.0, connections.count * 0.1);
|
|
36
|
-
const importantBonus = importantConnections.count * 0.2;
|
|
37
|
-
return Math.min(2.0, baseBoost + importantBonus);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Calculate age decay factor
|
|
41
|
-
* Recent memories maintain importance, old ones decay unless accessed
|
|
42
|
-
*/
|
|
43
|
-
export function calculateAgeDecay(timestamp) {
|
|
44
|
-
const now = Date.now();
|
|
45
|
-
const memoryDate = new Date(timestamp).getTime();
|
|
46
|
-
const ageInDays = (now - memoryDate) / (1000 * 60 * 60 * 24);
|
|
47
|
-
// No decay for first 7 days
|
|
48
|
-
if (ageInDays <= 7)
|
|
49
|
-
return 0;
|
|
50
|
-
// Gradual decay: -0.1 per week after first week
|
|
51
|
-
const weeksOld = Math.floor((ageInDays - 7) / 7);
|
|
52
|
-
const decay = Math.min(2, weeksOld * 0.1); // Max -2 importance
|
|
53
|
-
return -decay;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Calculate dynamic importance score
|
|
57
|
-
* Base importance + access boost - age decay
|
|
58
|
-
*/
|
|
59
|
-
export function calculateDynamicImportance(memory_id) {
|
|
60
|
-
const db = getDb(true);
|
|
61
|
-
const memory = db.prepare(`
|
|
62
|
-
SELECT importance, timestamp
|
|
63
|
-
FROM memory
|
|
64
|
-
WHERE id = ?
|
|
65
|
-
`).get(memory_id);
|
|
66
|
-
if (!memory) {
|
|
67
|
-
return {
|
|
68
|
-
baseImportance: 0,
|
|
69
|
-
ageDecay: 0,
|
|
70
|
-
accessBoost: 0,
|
|
71
|
-
relationshipBoost: 0,
|
|
72
|
-
finalScore: 0,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
const baseImportance = memory.importance;
|
|
76
|
-
const ageDecay = calculateAgeDecay(memory.timestamp);
|
|
77
|
-
const accessBoost = calculateAccessBoost(memory_id);
|
|
78
|
-
const relationshipBoost = calculateRelationshipBoost(memory_id);
|
|
79
|
-
// Final score: base + boosts + decay (decay is negative)
|
|
80
|
-
const finalScore = Math.max(1, Math.min(5, baseImportance + accessBoost + relationshipBoost + ageDecay));
|
|
81
|
-
return {
|
|
82
|
-
baseImportance,
|
|
83
|
-
ageDecay,
|
|
84
|
-
accessBoost,
|
|
85
|
-
relationshipBoost,
|
|
86
|
-
finalScore: Math.round(finalScore * 10) / 10, // Round to 1 decimal
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Get memories eligible for L1 based on dynamic scoring.
|
|
91
|
-
* Uses the decay query from PHILOSOPHY.md: importance penalized by last_accessed staleness,
|
|
92
|
-
* superseded memories excluded.
|
|
93
|
-
*/
|
|
94
|
-
export function getL1Candidates(limit = 50) {
|
|
95
|
-
const db = getDb(true);
|
|
96
|
-
// Use the L1 decay query from db.ts (matches PHILOSOPHY.md)
|
|
97
|
-
const memories = queries.getL1Summaries(db).all();
|
|
98
|
-
return memories.slice(0, limit).map(m => ({
|
|
99
|
-
id: m.id,
|
|
100
|
-
type: m.type,
|
|
101
|
-
content_l1: m.content_l1,
|
|
102
|
-
timestamp: m.timestamp,
|
|
103
|
-
last_accessed: m.last_accessed,
|
|
104
|
-
baseImportance: m.importance,
|
|
105
|
-
dynamicScore: m.effective_importance,
|
|
106
|
-
}));
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Consolidation: Review and adjust importances based on access patterns
|
|
110
|
-
*/
|
|
111
|
-
export function runConsolidation() {
|
|
112
|
-
const db = getDb(false);
|
|
113
|
-
let reviewed = 0;
|
|
114
|
-
let boosted = 0;
|
|
115
|
-
let decayed = 0;
|
|
116
|
-
let unchanged = 0;
|
|
117
|
-
// Get all memories from last 60 days
|
|
118
|
-
const memories = db.prepare(`
|
|
119
|
-
SELECT id, importance, timestamp
|
|
120
|
-
FROM memory
|
|
121
|
-
WHERE timestamp > datetime('now', '-60 days')
|
|
122
|
-
`).all();
|
|
123
|
-
for (const memory of memories) {
|
|
124
|
-
reviewed++;
|
|
125
|
-
const factors = calculateDynamicImportance(memory.id);
|
|
126
|
-
const newImportance = Math.round(factors.finalScore);
|
|
127
|
-
if (newImportance !== memory.importance) {
|
|
128
|
-
db.prepare(`
|
|
129
|
-
UPDATE memory
|
|
130
|
-
SET importance = ?
|
|
131
|
-
WHERE id = ?
|
|
132
|
-
`).run(newImportance, memory.id);
|
|
133
|
-
if (newImportance > memory.importance) {
|
|
134
|
-
boosted++;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
decayed++;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
unchanged++;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return { reviewed, boosted, decayed, unchanged };
|
|
145
|
-
}
|