true-mem 1.0.0 → 1.0.2
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/README.md +1 -2
- package/dist/adapters/opencode/index.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +169 -20
- package/dist/memory/classifier.d.ts.map +1 -1
- package/dist/memory/negative-patterns.d.ts +4 -0
- package/dist/memory/negative-patterns.d.ts.map +1 -1
- package/dist/memory/patterns.d.ts.map +1 -1
- package/dist/memory/reconsolidate.d.ts +6 -6
- package/dist/memory/reconsolidate.d.ts.map +1 -1
- package/dist/storage/database.d.ts +4 -0
- package/dist/storage/database.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ What makes True-Mem different from a simple database? It's modeled after how hum
|
|
|
57
57
|
|
|
58
58
|
**Dual-Store Architecture (STM/LTM)** - Short-term and long-term memory stores with automatic promotion. High-strength memories get promoted to LTM; weak ones stay in STM or decay.
|
|
59
59
|
|
|
60
|
-
**Four-Layer Defense System** - Prevents false positives with Negative Pattern filtering (including AI meta-talk detection), Multi-Keyword Scoring, Confidence Thresholds, and Role Validation (only Human messages for user-level preferences).
|
|
60
|
+
**Four-Layer Defense System** - Prevents false positives with Question Detection (filters questions before classification), Negative Pattern filtering (including AI meta-talk detection), Multi-Keyword Scoring with sentence-level isolation, Confidence Thresholds, and Role Validation (only Human messages for user-level preferences).
|
|
61
61
|
|
|
62
62
|
**Reconsolidation** - When new information conflicts with existing memories, the system detects similarity and handles it intelligently (merge duplicates, keep both complements, or resolve conflicts).
|
|
63
63
|
|
|
@@ -212,6 +212,5 @@ sqlite3 ~/.true-mem/memory.db "SELECT classification, summary, strength FROM mem
|
|
|
212
212
|
|
|
213
213
|
---
|
|
214
214
|
|
|
215
|
-
**Version**: 1.0.0
|
|
216
215
|
**License**: MIT
|
|
217
216
|
**Status**: Production-ready, actively maintained
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/opencode/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAwB,MAAM,gBAAgB,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAA4D,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/opencode/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAwB,MAAM,gBAAgB,CAAC;AAC/E,OAAO,KAAK,EAAE,cAAc,EAA4D,MAAM,gBAAgB,CAAC;AA4F/G;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,WAAW,EAChB,eAAe,GAAE,OAAO,CAAC,cAAc,CAAM,GAC5C,OAAO,CAAC,KAAK,CAAC,CAwKhB;AAylBD,eAAe,sBAAsB,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAkBzD,QAAA,MAAM,UAAU,EAAE,MAgGjB,CAAC;AAEF,eAAe,UAAU,CAAC;AAG1B,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -266,9 +266,9 @@ function isRelevant(similarity) {
|
|
|
266
266
|
var SIMILARITY_THRESHOLDS;
|
|
267
267
|
var init_reconsolidate = __esm(() => {
|
|
268
268
|
SIMILARITY_THRESHOLDS = {
|
|
269
|
-
DUPLICATE: 0.
|
|
270
|
-
CONFLICT: 0.
|
|
271
|
-
MIN_RELEVANT: 0.
|
|
269
|
+
DUPLICATE: 0.85,
|
|
270
|
+
CONFLICT: 0.7,
|
|
271
|
+
MIN_RELEVANT: 0.5
|
|
272
272
|
};
|
|
273
273
|
});
|
|
274
274
|
|
|
@@ -276,6 +276,7 @@ var init_reconsolidate = __esm(() => {
|
|
|
276
276
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
277
277
|
import { homedir as homedir2 } from "os";
|
|
278
278
|
import { dirname, join as join2 } from "path";
|
|
279
|
+
import { createHash } from "crypto";
|
|
279
280
|
function resolveDbPath(dbPath) {
|
|
280
281
|
if (dbPath.startsWith("~/")) {
|
|
281
282
|
return join2(homedir2(), dbPath.slice(2));
|
|
@@ -288,6 +289,10 @@ function ensureDbDirectory(dbPath) {
|
|
|
288
289
|
mkdirSync2(dir, { recursive: true });
|
|
289
290
|
}
|
|
290
291
|
}
|
|
292
|
+
function generateContentHash(text) {
|
|
293
|
+
const normalized = text.toLowerCase().trim();
|
|
294
|
+
return createHash("sha256").update(normalized).digest("hex");
|
|
295
|
+
}
|
|
291
296
|
|
|
292
297
|
class MemoryDatabase {
|
|
293
298
|
db;
|
|
@@ -378,6 +383,7 @@ class MemoryDatabase {
|
|
|
378
383
|
summary TEXT NOT NULL,
|
|
379
384
|
source_event_ids TEXT NOT NULL,
|
|
380
385
|
project_scope TEXT,
|
|
386
|
+
content_hash TEXT,
|
|
381
387
|
|
|
382
388
|
created_at TEXT NOT NULL,
|
|
383
389
|
updated_at TEXT NOT NULL,
|
|
@@ -414,6 +420,7 @@ class MemoryDatabase {
|
|
|
414
420
|
CREATE INDEX IF NOT EXISTS idx_memory_session ON memory_units(session_id);
|
|
415
421
|
CREATE INDEX IF NOT EXISTS idx_memory_project_scope ON memory_units(project_scope);
|
|
416
422
|
CREATE INDEX IF NOT EXISTS idx_memory_status_strength ON memory_units(status, strength);
|
|
423
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_hash ON memory_units(content_hash);
|
|
417
424
|
`);
|
|
418
425
|
this.db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (?, ?)").run(1, new Date().toISOString());
|
|
419
426
|
this.db.exec("COMMIT");
|
|
@@ -428,7 +435,34 @@ class MemoryDatabase {
|
|
|
428
435
|
throw error;
|
|
429
436
|
}
|
|
430
437
|
} else {
|
|
431
|
-
log("Schema already initialized,
|
|
438
|
+
log("Schema already initialized, applying migrations if needed...");
|
|
439
|
+
this.applyMigrations(currentVersion);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
applyMigrations(currentVersion) {
|
|
443
|
+
if (currentVersion < 2) {
|
|
444
|
+
log("Applying migration v2: Adding content_hash column...");
|
|
445
|
+
this.db.exec("BEGIN TRANSACTION");
|
|
446
|
+
try {
|
|
447
|
+
const tableInfo = this.db.prepare("PRAGMA table_info(memory_units)").all();
|
|
448
|
+
const hasContentHash = tableInfo.some((col) => col.name === "content_hash");
|
|
449
|
+
if (!hasContentHash) {
|
|
450
|
+
this.db.exec("ALTER TABLE memory_units ADD COLUMN content_hash TEXT");
|
|
451
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_memory_content_hash ON memory_units(content_hash)");
|
|
452
|
+
log("content_hash column added successfully");
|
|
453
|
+
}
|
|
454
|
+
this.db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (?, ?)").run(2, new Date().toISOString());
|
|
455
|
+
this.db.exec("COMMIT");
|
|
456
|
+
log("Migration v2 completed successfully");
|
|
457
|
+
} catch (error) {
|
|
458
|
+
try {
|
|
459
|
+
this.db.exec("ROLLBACK");
|
|
460
|
+
log("Migration v2 failed, rolled back", error);
|
|
461
|
+
} catch (rollbackError) {
|
|
462
|
+
log("Failed to rollback migration v2", rollbackError);
|
|
463
|
+
}
|
|
464
|
+
throw error;
|
|
465
|
+
}
|
|
432
466
|
}
|
|
433
467
|
}
|
|
434
468
|
createSession(id, project, metadata, transcriptPath) {
|
|
@@ -495,8 +529,17 @@ class MemoryDatabase {
|
|
|
495
529
|
}
|
|
496
530
|
async createMemory(store, classification, summary, sourceEventIds, features = {}) {
|
|
497
531
|
this.ensureInit();
|
|
532
|
+
const contentHash = generateContentHash(summary);
|
|
498
533
|
this.db.exec("BEGIN TRANSACTION");
|
|
499
534
|
try {
|
|
535
|
+
const exactDuplicate = this.db.prepare(`SELECT * FROM memory_units WHERE content_hash = ? AND status = 'active' LIMIT 1`).get(contentHash);
|
|
536
|
+
if (exactDuplicate) {
|
|
537
|
+
log(`Found exact duplicate by content hash: ${contentHash.substring(0, 8)}...`);
|
|
538
|
+
this.incrementFrequency(exactDuplicate.id);
|
|
539
|
+
const updatedMemory = this.getMemory(exactDuplicate.id);
|
|
540
|
+
this.db.exec("COMMIT");
|
|
541
|
+
return updatedMemory;
|
|
542
|
+
}
|
|
500
543
|
const similarMemories = await this.vectorSearch(summary, features.projectScope ?? undefined, 1);
|
|
501
544
|
if (similarMemories.length > 0) {
|
|
502
545
|
const existingMemory = similarMemories[0];
|
|
@@ -564,12 +607,12 @@ class MemoryDatabase {
|
|
|
564
607
|
};
|
|
565
608
|
this.db.prepare(`
|
|
566
609
|
INSERT INTO memory_units (
|
|
567
|
-
id, session_id, store, classification, summary, source_event_ids, project_scope,
|
|
610
|
+
id, session_id, store, classification, summary, source_event_ids, project_scope, content_hash,
|
|
568
611
|
created_at, updated_at, last_accessed_at,
|
|
569
612
|
recency, frequency, importance, utility, novelty, confidence, interference,
|
|
570
613
|
strength, decay_rate, tags, associations, status, version, embedding
|
|
571
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
572
|
-
`).run(memory.id, memory.sessionId ?? null, memory.store, memory.classification, memory.summary, JSON.stringify(memory.sourceEventIds), memory.projectScope ?? null, memory.createdAt.toISOString(), memory.updatedAt.toISOString(), memory.lastAccessedAt.toISOString(), memory.recency, memory.frequency, memory.importance, memory.utility, memory.novelty, memory.confidence, memory.interference, memory.strength, memory.decayRate, JSON.stringify(memory.tags), JSON.stringify(memory.associations), memory.status, memory.version, null);
|
|
614
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
615
|
+
`).run(memory.id, memory.sessionId ?? null, memory.store, memory.classification, memory.summary, JSON.stringify(memory.sourceEventIds), memory.projectScope ?? null, contentHash, memory.createdAt.toISOString(), memory.updatedAt.toISOString(), memory.lastAccessedAt.toISOString(), memory.recency, memory.frequency, memory.importance, memory.utility, memory.novelty, memory.confidence, memory.interference, memory.strength, memory.decayRate, JSON.stringify(memory.tags), JSON.stringify(memory.associations), memory.status, memory.version, null);
|
|
573
616
|
this.db.exec("COMMIT");
|
|
574
617
|
return memory;
|
|
575
618
|
} catch (error) {
|
|
@@ -801,6 +844,16 @@ var init_database = __esm(() => {
|
|
|
801
844
|
function isAIMetaTalk(text) {
|
|
802
845
|
return AI_META_TALK_PATTERNS.some((pattern) => pattern.test(text.trim()));
|
|
803
846
|
}
|
|
847
|
+
function isQuestion(text) {
|
|
848
|
+
const trimmed = text.trim();
|
|
849
|
+
if (trimmed.endsWith("?"))
|
|
850
|
+
return true;
|
|
851
|
+
const questionPatterns = [
|
|
852
|
+
/\b(?:cosa|come|quando|dove|perch\u00E9|chi|quale|quanto)\s+(?:devo|posso|dovrei|potrei|conviene)\b/i,
|
|
853
|
+
/\b(?:potr\u00F2|dovr\u00F2|posso|devo)\s+\w+/i
|
|
854
|
+
];
|
|
855
|
+
return questionPatterns.some((p) => p.test(trimmed));
|
|
856
|
+
}
|
|
804
857
|
function matchesNegativePattern(text, classification) {
|
|
805
858
|
if (isAIMetaTalk(text)) {
|
|
806
859
|
return true;
|
|
@@ -826,7 +879,12 @@ var init_negative_patterns = __esm(() => {
|
|
|
826
879
|
/^Here('s| is) (the|a)/i,
|
|
827
880
|
/^Based on (the|my) analysis/i,
|
|
828
881
|
/^After (reviewing|analyzing|examining)/i,
|
|
829
|
-
/^Looking at (the|this)/i
|
|
882
|
+
/^Looking at (the|this)/i,
|
|
883
|
+
/^\|[^|]+\|[^|]+\|/i,
|
|
884
|
+
/^[\s]*\|[^\n]+\|[^\n]*$/im,
|
|
885
|
+
/^[\s]*\/.*\/[gimsuvy]*\s*$/i,
|
|
886
|
+
/\|\w+\|.*\.\.\./i,
|
|
887
|
+
/^\|.+\|$/i
|
|
830
888
|
];
|
|
831
889
|
NEGATIVE_PATTERNS = {
|
|
832
890
|
bugfix: [
|
|
@@ -864,6 +922,13 @@ var init_negative_patterns = __esm(() => {
|
|
|
864
922
|
/database\s+constraint/i,
|
|
865
923
|
/foreign\s+key\s+constraint/i,
|
|
866
924
|
/unique\s+constraint/i
|
|
925
|
+
],
|
|
926
|
+
preference: [
|
|
927
|
+
/\b(preferisco|scelgo|voglio|prendo|opto)\s+(?:la\s+)?[0-9]+(?:a|o)?\b/i,
|
|
928
|
+
/\b(preferisco|scelgo|voglio|prendo|opto)\s+(?:la\s+)?(prima|seconda|terza|quarta|quinta|primo|secondo|terzo)\b/i,
|
|
929
|
+
/\b(preferisco|scelgo|voglio|prendo|opto)\s+(?:l'|il\s+)?(?:opzione\s+)?[0-9]+\b/i,
|
|
930
|
+
/\b(?:option|opzione)\s+[0-9]+\b/i,
|
|
931
|
+
/\b(preferisco|scelgo|voglio)\s+[0-9]\s*[,.\n]/i
|
|
867
932
|
]
|
|
868
933
|
};
|
|
869
934
|
});
|
|
@@ -924,19 +989,34 @@ function calculateClassificationScore(text, classification) {
|
|
|
924
989
|
const keywords = CLASSIFICATION_KEYWORDS[classification];
|
|
925
990
|
if (!keywords)
|
|
926
991
|
return 0;
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
const
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
992
|
+
const sentences = text.split(/[.!?\n]+/).filter((s) => s.trim().length > 0);
|
|
993
|
+
let bestSentenceScore = 0;
|
|
994
|
+
for (const sentence of sentences) {
|
|
995
|
+
const sentenceLower = sentence.toLowerCase();
|
|
996
|
+
const { primary, boosters } = keywords;
|
|
997
|
+
const primaryMatches = primary.filter((k) => sentenceLower.includes(k.toLowerCase())).length;
|
|
998
|
+
const boosterMatches = boosters.filter((k) => sentenceLower.includes(k.toLowerCase())).length;
|
|
999
|
+
if (primaryMatches === 0)
|
|
1000
|
+
continue;
|
|
1001
|
+
const primaryScore = Math.min(0.5, primaryMatches * 0.2);
|
|
1002
|
+
const boosterScore = Math.min(0.3, boosterMatches * 0.15);
|
|
1003
|
+
const sentenceScore = Math.min(1, 0.3 + primaryScore + boosterScore);
|
|
1004
|
+
if (sentenceScore > bestSentenceScore) {
|
|
1005
|
+
bestSentenceScore = sentenceScore;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
if (bestSentenceScore === 0.3)
|
|
934
1009
|
return 0.4;
|
|
935
|
-
|
|
936
|
-
const boosterScore = Math.min(0.3, boosterMatches * 0.15);
|
|
937
|
-
return Math.min(1, 0.3 + primaryScore + boosterScore);
|
|
1010
|
+
return bestSentenceScore;
|
|
938
1011
|
}
|
|
939
1012
|
function shouldStoreMemory(text, classification, baseSignalScore) {
|
|
1013
|
+
if (isQuestion(text)) {
|
|
1014
|
+
return {
|
|
1015
|
+
store: false,
|
|
1016
|
+
confidence: 0,
|
|
1017
|
+
reason: "is_question_not_statement"
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
940
1020
|
if (matchesNegativePattern(text, classification)) {
|
|
941
1021
|
return {
|
|
942
1022
|
store: false,
|
|
@@ -2312,6 +2392,15 @@ __export(exports_opencode, {
|
|
|
2312
2392
|
default: () => opencode_default,
|
|
2313
2393
|
createTrueMemoryPlugin: () => createTrueMemoryPlugin
|
|
2314
2394
|
});
|
|
2395
|
+
function canExtract() {
|
|
2396
|
+
const now = Date.now();
|
|
2397
|
+
if (now - lastExtractionTime < MIN_EXTRACTION_INTERVAL) {
|
|
2398
|
+
log(`Skipping extraction: too soon after last extraction (${now - lastExtractionTime}ms < ${MIN_EXTRACTION_INTERVAL}ms)`);
|
|
2399
|
+
return false;
|
|
2400
|
+
}
|
|
2401
|
+
lastExtractionTime = now;
|
|
2402
|
+
return true;
|
|
2403
|
+
}
|
|
2315
2404
|
function getSessionIdFromEvent(properties) {
|
|
2316
2405
|
if (!properties)
|
|
2317
2406
|
return;
|
|
@@ -2490,6 +2579,9 @@ async function processSessionIdle(state, sessionId) {
|
|
|
2490
2579
|
log(`Skipping extraction: sub-agent session detected (${effectiveSessionId})`);
|
|
2491
2580
|
return;
|
|
2492
2581
|
}
|
|
2582
|
+
if (!canExtract()) {
|
|
2583
|
+
return;
|
|
2584
|
+
}
|
|
2493
2585
|
const watermark = state.db.getMessageWatermark(effectiveSessionId);
|
|
2494
2586
|
let messages;
|
|
2495
2587
|
try {
|
|
@@ -2802,7 +2894,7 @@ Write a structured summary: task, accomplishments, remaining work, critical cont
|
|
|
2802
2894
|
|
|
2803
2895
|
`);
|
|
2804
2896
|
}
|
|
2805
|
-
var BUILD_TIME = "2026-02-23T09:45:00.000Z", messageDebounceTimer = null, pendingMessageEvent = null, opencode_default;
|
|
2897
|
+
var BUILD_TIME = "2026-02-23T09:45:00.000Z", messageDebounceTimer = null, pendingMessageEvent = null, lastExtractionTime = 0, MIN_EXTRACTION_INTERVAL = 2000, opencode_default;
|
|
2806
2898
|
var init_opencode = __esm(() => {
|
|
2807
2899
|
init_config();
|
|
2808
2900
|
init_database();
|
|
@@ -2817,6 +2909,63 @@ var init_opencode = __esm(() => {
|
|
|
2817
2909
|
|
|
2818
2910
|
// src/index.ts
|
|
2819
2911
|
init_logger();
|
|
2912
|
+
// package.json
|
|
2913
|
+
var package_default = {
|
|
2914
|
+
name: "true-mem",
|
|
2915
|
+
version: "1.0.2",
|
|
2916
|
+
description: "Persistent memory plugin for OpenCode with cognitive psychology-based memory management",
|
|
2917
|
+
main: "dist/index.js",
|
|
2918
|
+
types: "dist/index.d.ts",
|
|
2919
|
+
type: "module",
|
|
2920
|
+
exports: {
|
|
2921
|
+
".": {
|
|
2922
|
+
types: "./dist/index.d.ts",
|
|
2923
|
+
import: "./dist/index.js"
|
|
2924
|
+
}
|
|
2925
|
+
},
|
|
2926
|
+
scripts: {
|
|
2927
|
+
build: "bun build src/index.ts --outdir dist --target bun --format esm && tsc --emitDeclarationOnly",
|
|
2928
|
+
dev: "bun build src/index.ts --outdir dist --target bun --format esm --watch",
|
|
2929
|
+
typecheck: "tsc --noEmit"
|
|
2930
|
+
},
|
|
2931
|
+
keywords: [
|
|
2932
|
+
"opencode",
|
|
2933
|
+
"ai",
|
|
2934
|
+
"memory",
|
|
2935
|
+
"plugin",
|
|
2936
|
+
"persistent",
|
|
2937
|
+
"cognitive",
|
|
2938
|
+
"coding-assistant"
|
|
2939
|
+
],
|
|
2940
|
+
author: "rizal72",
|
|
2941
|
+
license: "MIT",
|
|
2942
|
+
repository: {
|
|
2943
|
+
type: "git",
|
|
2944
|
+
url: "git+https://github.com/rizal72/true-mem.git"
|
|
2945
|
+
},
|
|
2946
|
+
bugs: {
|
|
2947
|
+
url: "https://github.com/rizal72/true-mem/issues"
|
|
2948
|
+
},
|
|
2949
|
+
homepage: "https://github.com/rizal72/true-mem#readme",
|
|
2950
|
+
files: [
|
|
2951
|
+
"dist/",
|
|
2952
|
+
"README.md",
|
|
2953
|
+
"LICENSE"
|
|
2954
|
+
],
|
|
2955
|
+
dependencies: {
|
|
2956
|
+
"@opencode-ai/plugin": "^1.2.6",
|
|
2957
|
+
"@opencode-ai/sdk": "^1.2.6",
|
|
2958
|
+
uuid: "^13.0.0"
|
|
2959
|
+
},
|
|
2960
|
+
devDependencies: {
|
|
2961
|
+
"@types/node": "^25.0.0",
|
|
2962
|
+
"@types/uuid": "^10.0.0",
|
|
2963
|
+
"bun-types": "^1.3.0",
|
|
2964
|
+
typescript: "^5.9.3"
|
|
2965
|
+
}
|
|
2966
|
+
};
|
|
2967
|
+
|
|
2968
|
+
// src/index.ts
|
|
2820
2969
|
var state = {
|
|
2821
2970
|
initialized: false,
|
|
2822
2971
|
initPromise: null,
|
|
@@ -2824,7 +2973,7 @@ var state = {
|
|
|
2824
2973
|
realHooks: null
|
|
2825
2974
|
};
|
|
2826
2975
|
var TrueMemory = async (ctx) => {
|
|
2827
|
-
console.log(
|
|
2976
|
+
console.log(`True-Mem v${package_default.version}: Plugin loading...`);
|
|
2828
2977
|
state.ctx = ctx;
|
|
2829
2978
|
state.initPromise = (async () => {
|
|
2830
2979
|
log("Phase 1: Initializing plugin (lightweight)...");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../src/memory/classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoCjE,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../src/memory/classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoCjE,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAkCzF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,GACtB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA0DxD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc/D;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,GAAG,EAAE,GACb;IAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CA4FhF;AAMD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,WAAW,GACvB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA8CpC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,GAAG,EAAE,EACd,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,GACxC;IACD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAsEA;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,MAAM,GACX,MAAM,CAWR"}
|
|
@@ -19,6 +19,10 @@ export declare const AI_META_TALK_PATTERNS: RegExp[];
|
|
|
19
19
|
* Check if text appears to be AI-generated meta-talk
|
|
20
20
|
*/
|
|
21
21
|
export declare function isAIMetaTalk(text: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if text is a question (should NOT be stored as a statement)
|
|
24
|
+
*/
|
|
25
|
+
export declare function isQuestion(text: string): boolean;
|
|
22
26
|
export declare const NEGATIVE_PATTERNS: Record<string, RegExp[]>;
|
|
23
27
|
/**
|
|
24
28
|
* Check if text matches any negative pattern for the given classification
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negative-patterns.d.ts","sourceRoot":"","sources":["../../src/memory/negative-patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"negative-patterns.d.ts","sourceRoot":"","sources":["../../src/memory/negative-patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAmCzC,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAahD;AAGD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CA0DtD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAUpF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB1F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/memory/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAM1E,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,oBAAoB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,eA0C/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,eA8C1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,eA+CxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,eA8CxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,eAuCtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,eAwCxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,eA0CrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,eAgDtB,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,eAAe,EASzC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/memory/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAM1E,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,oBAAoB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,eA0C/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,eA8C1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,eA+CxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,eA8CxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,eAuCtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,eAwCxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,eA0CrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,eAgDtB,CAAC;AAMF,eAAO,MAAM,YAAY,EAAE,eAAe,EASzC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;CAyFnC,CAAC;AAqCF;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,gBAAgB,GAAG,IAAI,CA2B7F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAWjE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA6B9D;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,EAAE,CAEtD"}
|
|
@@ -23,8 +23,8 @@ export type ReconsolidationAction = {
|
|
|
23
23
|
* Handle memory reconsolidation based on similarity
|
|
24
24
|
*
|
|
25
25
|
* This function determines how to handle a new memory compared to an existing one:
|
|
26
|
-
* - similarity > 0.
|
|
27
|
-
* - similarity > 0.
|
|
26
|
+
* - similarity > 0.85: Duplicate (increment frequency, update timestamp)
|
|
27
|
+
* - similarity > 0.7: Conflict (newer wins - replace existing)
|
|
28
28
|
* - otherwise: Complement (store as new memory)
|
|
29
29
|
*
|
|
30
30
|
* @param db - The database instance
|
|
@@ -43,15 +43,15 @@ export declare function handleReconsolidation(db: MemoryDatabase, newMemoryData:
|
|
|
43
43
|
* Check if similarity is above minimum relevance threshold
|
|
44
44
|
*
|
|
45
45
|
* @param similarity - The similarity score
|
|
46
|
-
* @returns True if similarity >= 0.
|
|
46
|
+
* @returns True if similarity >= 0.5
|
|
47
47
|
*/
|
|
48
48
|
export declare function isRelevant(similarity: number): boolean;
|
|
49
49
|
/**
|
|
50
50
|
* Get similarity thresholds for configuration or debugging
|
|
51
51
|
*/
|
|
52
52
|
export declare function getSimilarityThresholds(): {
|
|
53
|
-
DUPLICATE: 0.
|
|
54
|
-
CONFLICT: 0.
|
|
55
|
-
MIN_RELEVANT: 0.
|
|
53
|
+
DUPLICATE: 0.85;
|
|
54
|
+
CONFLICT: 0.7;
|
|
55
|
+
MIN_RELEVANT: 0.5;
|
|
56
56
|
};
|
|
57
57
|
//# sourceMappingURL=reconsolidate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconsolidate.d.ts","sourceRoot":"","sources":["../../src/memory/reconsolidate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,UAAU,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,iBAAiB,EAAE,UAAU,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,UAAU,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"reconsolidate.d.ts","sourceRoot":"","sources":["../../src/memory/reconsolidate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,UAAU,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,iBAAiB,EAAE,UAAU,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,UAAU,CAAA;CAAE,CAAC;AAYlD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,cAAc,EAClB,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC7C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CAC5B,EACD,cAAc,EAAE,UAAU,EAC1B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,qBAAqB,CAAC,CAgBhC;AAuDD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,uBAAuB;;;;EAEtC"}
|
|
@@ -15,6 +15,10 @@ export declare class MemoryDatabase {
|
|
|
15
15
|
init(): Promise<void>;
|
|
16
16
|
private ensureInit;
|
|
17
17
|
private initializeSchema;
|
|
18
|
+
/**
|
|
19
|
+
* Apply database migrations for schema updates
|
|
20
|
+
*/
|
|
21
|
+
private applyMigrations;
|
|
18
22
|
createSession(id: string, project: string, metadata?: Record<string, unknown>, transcriptPath?: string): Session;
|
|
19
23
|
endSession(sessionId: string, status?: 'completed' | 'abandoned'): void;
|
|
20
24
|
getSession(sessionId: string): Session | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"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"}
|