prism-mcp-server 8.0.0 → 8.0.1
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/dist/storage/sqlite.js +5 -1
- package/dist/storage/supabase.js +5 -1
- package/dist/tools/graphHandlers.js +14 -120
- package/package.json +1 -1
package/dist/storage/sqlite.js
CHANGED
|
@@ -1642,7 +1642,7 @@ export class SqliteStorage {
|
|
|
1642
1642
|
if (missingIds.length > 0) {
|
|
1643
1643
|
const placeholders = missingIds.map(() => '?').join(',');
|
|
1644
1644
|
const missingQuery = `
|
|
1645
|
-
SELECT id, project, summary, session_date, decisions, files_changed
|
|
1645
|
+
SELECT id, project, summary, session_date, decisions, files_changed, keywords, is_rollup, importance, last_accessed_at
|
|
1646
1646
|
FROM session_ledger
|
|
1647
1647
|
WHERE id IN (${placeholders}) AND deleted_at IS NULL AND user_id = ?
|
|
1648
1648
|
`;
|
|
@@ -1655,6 +1655,9 @@ export class SqliteStorage {
|
|
|
1655
1655
|
session_date: row.session_date,
|
|
1656
1656
|
decisions: this.parseJsonColumn(row.decisions),
|
|
1657
1657
|
files_changed: this.parseJsonColumn(row.files_changed),
|
|
1658
|
+
is_rollup: Boolean(row.is_rollup),
|
|
1659
|
+
importance: Number(row.importance) || 0,
|
|
1660
|
+
last_accessed_at: row.last_accessed_at || null,
|
|
1658
1661
|
similarity: 0.0,
|
|
1659
1662
|
});
|
|
1660
1663
|
}
|
|
@@ -1666,6 +1669,7 @@ export class SqliteStorage {
|
|
|
1666
1669
|
const normEnergy = normalizeActivationEnergy(r.activationEnergy);
|
|
1667
1670
|
node.activationScore = normEnergy;
|
|
1668
1671
|
node.rawActivationEnergy = r.activationEnergy;
|
|
1672
|
+
node.isDiscovered = r.isDiscovered;
|
|
1669
1673
|
// Hybrid blend: 70% original match relevance, 30% structural energy
|
|
1670
1674
|
node.hybridScore = (node.similarity * 0.7) + (normEnergy * 0.3);
|
|
1671
1675
|
finalResults.push(node);
|
package/dist/storage/supabase.js
CHANGED
|
@@ -374,7 +374,7 @@ export class SupabaseStorage {
|
|
|
374
374
|
id: `in.(${missingIds.join(",")})`,
|
|
375
375
|
user_id: `eq.${userId}`,
|
|
376
376
|
deleted_at: "is.null",
|
|
377
|
-
select: "id,project,summary,session_date,decisions,files_changed",
|
|
377
|
+
select: "id,project,summary,session_date,decisions,files_changed,is_rollup,importance,last_accessed_at",
|
|
378
378
|
});
|
|
379
379
|
for (const row of (Array.isArray(rows) ? rows : [])) {
|
|
380
380
|
fullNodeMap.set(row.id, {
|
|
@@ -384,6 +384,9 @@ export class SupabaseStorage {
|
|
|
384
384
|
session_date: row.session_date,
|
|
385
385
|
decisions: Array.isArray(row.decisions) ? row.decisions : [],
|
|
386
386
|
files_changed: Array.isArray(row.files_changed) ? row.files_changed : [],
|
|
387
|
+
is_rollup: Boolean(row.is_rollup),
|
|
388
|
+
importance: Number(row.importance) || 0,
|
|
389
|
+
last_accessed_at: row.last_accessed_at || null,
|
|
387
390
|
similarity: 0.0,
|
|
388
391
|
});
|
|
389
392
|
}
|
|
@@ -400,6 +403,7 @@ export class SupabaseStorage {
|
|
|
400
403
|
const normEnergy = normalizeActivationEnergy(r.activationEnergy);
|
|
401
404
|
node.activationScore = normEnergy;
|
|
402
405
|
node.rawActivationEnergy = r.activationEnergy;
|
|
406
|
+
node.isDiscovered = r.isDiscovered;
|
|
403
407
|
// Hybrid blend: 70% original match relevance, 30% structural energy
|
|
404
408
|
node.hybridScore = (node.similarity * 0.7) + (normEnergy * 0.3);
|
|
405
409
|
finalResults.push(node);
|
|
@@ -146,67 +146,9 @@ export async function knowledgeSearchHandler(args) {
|
|
|
146
146
|
});
|
|
147
147
|
contentBlocks.push(traceToContentBlock(trace));
|
|
148
148
|
}
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
// Graph-expanded results are BONUS — don't consume limit slots.
|
|
153
|
-
try {
|
|
154
|
-
// Extract IDs from the knowledge search results
|
|
155
|
-
const directIds = new Set();
|
|
156
|
-
if (data.results && Array.isArray(data.results)) {
|
|
157
|
-
for (const entry of data.results) {
|
|
158
|
-
if (entry?.id)
|
|
159
|
-
directIds.add(entry.id);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (directIds.size > 0) {
|
|
163
|
-
const enrichedIds = new Set();
|
|
164
|
-
const maxGraphResults = Math.min(limit, 10);
|
|
165
|
-
for (const directId of directIds) {
|
|
166
|
-
if (enrichedIds.size >= maxGraphResults)
|
|
167
|
-
break;
|
|
168
|
-
const links = await storage.getLinksFrom(directId, PRISM_USER_ID, 0.3, 5);
|
|
169
|
-
for (const link of links) {
|
|
170
|
-
if (!directIds.has(link.target_id) && !enrichedIds.has(link.target_id)) {
|
|
171
|
-
enrichedIds.add(link.target_id);
|
|
172
|
-
if (enrichedIds.size >= maxGraphResults)
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (enrichedIds.size > 0) {
|
|
178
|
-
const enrichedEntries = await storage.getLedgerEntries({
|
|
179
|
-
user_id: `eq.${PRISM_USER_ID}`,
|
|
180
|
-
ids: [...enrichedIds],
|
|
181
|
-
select: "id,summary,project,created_at",
|
|
182
|
-
});
|
|
183
|
-
if (enrichedEntries.length > 0) {
|
|
184
|
-
const graphFormatted = enrichedEntries.map((e) => `[🔗] ${e.created_at?.split("T")[0] || "unknown"} — ${e.project || "unknown"}\n` +
|
|
185
|
-
` Summary: ${e.summary}`).join("\n");
|
|
186
|
-
contentBlocks[0] = {
|
|
187
|
-
type: "text",
|
|
188
|
-
text: contentBlocks[0].text +
|
|
189
|
-
`\n\n🔗 Graph-connected memories (${enrichedEntries.length} via 1-hop expansion):\n\n${graphFormatted}`,
|
|
190
|
-
};
|
|
191
|
-
// Fire-and-forget: reinforce traversed links
|
|
192
|
-
for (const directId of directIds) {
|
|
193
|
-
storage.getLinksFrom(directId, PRISM_USER_ID, 0.3, 5)
|
|
194
|
-
.then(links => {
|
|
195
|
-
for (const link of links) {
|
|
196
|
-
if (enrichedIds.has(link.target_id)) {
|
|
197
|
-
storage.reinforceLink(directId, link.target_id, link.link_type).catch(() => { });
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
})
|
|
201
|
-
.catch(() => { });
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
catch (graphErr) {
|
|
208
|
-
debugLog(`[knowledge_search] Graph expansion failed (non-fatal): ${graphErr instanceof Error ? graphErr.message : String(graphErr)}`);
|
|
209
|
-
}
|
|
149
|
+
// v8.0: Legacy v6.0 1-Hop Graph Expansion has been removed.
|
|
150
|
+
// The Synapse Engine now handles multi-hop traversal at the storage layer,
|
|
151
|
+
// integrating discovered nodes into the main ranked result array.
|
|
210
152
|
return { content: contentBlocks, isError: false };
|
|
211
153
|
}
|
|
212
154
|
export async function knowledgeForgetHandler(args) {
|
|
@@ -437,9 +379,12 @@ export async function sessionSearchMemoryHandler(args) {
|
|
|
437
379
|
// They should decay 50% slower than raw episodic chatter to retain long-term context.
|
|
438
380
|
const decayRate = r.is_rollup ? PRISM_ACTR_DECAY * 0.5 : PRISM_ACTR_DECAY;
|
|
439
381
|
const Bi = baseLevelActivation(timestamps, now, decayRate);
|
|
440
|
-
// S_i:
|
|
382
|
+
// S_i: Normalized structural activation energy from Synapse logic
|
|
441
383
|
// (computed during applySynapse in storage layer)
|
|
442
|
-
|
|
384
|
+
// v8.0: Use normalized 0-1 activationScore, NOT unbounded rawActivationEnergy.
|
|
385
|
+
// Raw energy can reach 15+ for hub nodes, which saturates the sigmoid
|
|
386
|
+
// and erases Bi (recency/frequency) from the composite score.
|
|
387
|
+
const Si = (typeof r.activationScore === 'number') ? r.activationScore : 0;
|
|
443
388
|
// Composite retrieval score
|
|
444
389
|
const composite = compositeRetrievalScore(typeof r.similarity === "number" ? r.similarity : 0, Bi + Si, PRISM_ACTR_WEIGHT_SIMILARITY, PRISM_ACTR_WEIGHT_ACTIVATION, PRISM_ACTR_SIGMOID_MIDPOINT, PRISM_ACTR_SIGMOID_STEEPNESS);
|
|
445
390
|
// Attach to result for re-sorting and display
|
|
@@ -510,7 +455,9 @@ export async function sessionSearchMemoryHandler(args) {
|
|
|
510
455
|
const actrStr = r._actr_composite !== undefined
|
|
511
456
|
? ` ACT-R: composite=${r._actr_composite.toFixed(3)} (B=${r._actr_Bi?.toFixed(2)}, S=${r._actr_Si?.toFixed(3)})\n`
|
|
512
457
|
: "";
|
|
513
|
-
|
|
458
|
+
// v8.0: Tag nodes discovered via Synapse multi-hop traversal
|
|
459
|
+
const synapseTag = r.isDiscovered ? " [🌐 Synapse]" : "";
|
|
460
|
+
return `[${i + 1}] ${simScore} similar${synapseTag} — ${r.session_date || "unknown date"}\n` +
|
|
514
461
|
` Project: ${r.project}\n` +
|
|
515
462
|
` Summary: ${r.summary}\n` +
|
|
516
463
|
importanceStr +
|
|
@@ -551,62 +498,9 @@ export async function sessionSearchMemoryHandler(args) {
|
|
|
551
498
|
});
|
|
552
499
|
contentBlocks.push(traceToContentBlock(trace));
|
|
553
500
|
}
|
|
554
|
-
//
|
|
555
|
-
//
|
|
556
|
-
//
|
|
557
|
-
// don't consume limit slots. Hard-capped at `limit` additional results
|
|
558
|
-
// to protect LLM context windows.
|
|
559
|
-
//
|
|
560
|
-
// Fire-and-forget: errors degrade gracefully to just direct hits.
|
|
561
|
-
try {
|
|
562
|
-
const directIds = new Set(results.map((r) => r.id).filter(Boolean));
|
|
563
|
-
const enrichedIds = new Set();
|
|
564
|
-
const maxGraphResults = Math.min(limit, 10); // Hard cap
|
|
565
|
-
for (const directId of directIds) {
|
|
566
|
-
if (enrichedIds.size >= maxGraphResults)
|
|
567
|
-
break;
|
|
568
|
-
const links = await storage.getLinksFrom(directId, PRISM_USER_ID, 0.3, 5);
|
|
569
|
-
for (const link of links) {
|
|
570
|
-
if (!directIds.has(link.target_id) && !enrichedIds.has(link.target_id)) {
|
|
571
|
-
enrichedIds.add(link.target_id);
|
|
572
|
-
if (enrichedIds.size >= maxGraphResults)
|
|
573
|
-
break;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
if (enrichedIds.size > 0) {
|
|
578
|
-
// Fetch the actual entries for enriched IDs
|
|
579
|
-
const enrichedEntries = await storage.getLedgerEntries({
|
|
580
|
-
user_id: `eq.${PRISM_USER_ID}`,
|
|
581
|
-
ids: [...enrichedIds],
|
|
582
|
-
select: "id,summary,project,created_at",
|
|
583
|
-
});
|
|
584
|
-
if (enrichedEntries.length > 0) {
|
|
585
|
-
const graphFormatted = enrichedEntries.map((e) => `[🔗] ${e.created_at?.split("T")[0] || "unknown"} — ${e.project || "unknown"}\n` +
|
|
586
|
-
` Summary: ${e.summary}`).join("\n");
|
|
587
|
-
contentBlocks[0] = {
|
|
588
|
-
type: "text",
|
|
589
|
-
text: contentBlocks[0].text +
|
|
590
|
-
`\n\n🔗 Graph-connected memories (${enrichedEntries.length} via 1-hop expansion):\n\n${graphFormatted}`,
|
|
591
|
-
};
|
|
592
|
-
// Fire-and-forget: reinforce traversed links
|
|
593
|
-
for (const directId of directIds) {
|
|
594
|
-
storage.getLinksFrom(directId, PRISM_USER_ID, 0.3, 5)
|
|
595
|
-
.then(links => {
|
|
596
|
-
for (const link of links) {
|
|
597
|
-
if (enrichedIds.has(link.target_id)) {
|
|
598
|
-
storage.reinforceLink(directId, link.target_id, link.link_type).catch(() => { });
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
})
|
|
602
|
-
.catch(() => { });
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
catch (graphErr) {
|
|
608
|
-
debugLog(`[session_search_memory] Graph expansion failed (non-fatal): ${graphErr instanceof Error ? graphErr.message : String(graphErr)}`);
|
|
609
|
-
}
|
|
501
|
+
// v8.0: Legacy v6.0 1-Hop Graph Expansion has been removed.
|
|
502
|
+
// The Synapse Engine now handles multi-hop traversal at the storage layer,
|
|
503
|
+
// integrating discovered nodes into the main ranked result array.
|
|
610
504
|
return { content: contentBlocks, isError: false };
|
|
611
505
|
}
|
|
612
506
|
catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prism-mcp-server",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.1",
|
|
4
4
|
"mcpName": "io.github.dcostenco/prism-mcp",
|
|
5
5
|
"description": "The Mind Palace for AI Agents — a true Cognitive Architecture with Hebbian learning (episodic→semantic consolidation), ACT-R spreading activation (multi-hop causal reasoning), uncertainty-aware rejection gates (agents that know when they don't know), adversarial evaluation (anti-sycophancy), fail-closed Dark Factory pipelines, persistent memory (SQLite/Supabase), multi-agent Hivemind, time travel & visual dashboard. Zero-config local mode.",
|
|
6
6
|
"module": "index.ts",
|