true-mem 1.0.1 → 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/index.d.ts.map +1 -1
- package/dist/index.js +106 -12
- 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/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
|
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
|
@@ -844,6 +844,16 @@ var init_database = __esm(() => {
|
|
|
844
844
|
function isAIMetaTalk(text) {
|
|
845
845
|
return AI_META_TALK_PATTERNS.some((pattern) => pattern.test(text.trim()));
|
|
846
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
|
+
}
|
|
847
857
|
function matchesNegativePattern(text, classification) {
|
|
848
858
|
if (isAIMetaTalk(text)) {
|
|
849
859
|
return true;
|
|
@@ -869,7 +879,12 @@ var init_negative_patterns = __esm(() => {
|
|
|
869
879
|
/^Here('s| is) (the|a)/i,
|
|
870
880
|
/^Based on (the|my) analysis/i,
|
|
871
881
|
/^After (reviewing|analyzing|examining)/i,
|
|
872
|
-
/^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
|
|
873
888
|
];
|
|
874
889
|
NEGATIVE_PATTERNS = {
|
|
875
890
|
bugfix: [
|
|
@@ -907,6 +922,13 @@ var init_negative_patterns = __esm(() => {
|
|
|
907
922
|
/database\s+constraint/i,
|
|
908
923
|
/foreign\s+key\s+constraint/i,
|
|
909
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
|
|
910
932
|
]
|
|
911
933
|
};
|
|
912
934
|
});
|
|
@@ -967,19 +989,34 @@ function calculateClassificationScore(text, classification) {
|
|
|
967
989
|
const keywords = CLASSIFICATION_KEYWORDS[classification];
|
|
968
990
|
if (!keywords)
|
|
969
991
|
return 0;
|
|
970
|
-
const
|
|
971
|
-
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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)
|
|
977
1009
|
return 0.4;
|
|
978
|
-
|
|
979
|
-
const boosterScore = Math.min(0.3, boosterMatches * 0.15);
|
|
980
|
-
return Math.min(1, 0.3 + primaryScore + boosterScore);
|
|
1010
|
+
return bestSentenceScore;
|
|
981
1011
|
}
|
|
982
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
|
+
}
|
|
983
1020
|
if (matchesNegativePattern(text, classification)) {
|
|
984
1021
|
return {
|
|
985
1022
|
store: false,
|
|
@@ -2872,6 +2909,63 @@ var init_opencode = __esm(() => {
|
|
|
2872
2909
|
|
|
2873
2910
|
// src/index.ts
|
|
2874
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
|
|
2875
2969
|
var state = {
|
|
2876
2970
|
initialized: false,
|
|
2877
2971
|
initPromise: null,
|
|
@@ -2879,7 +2973,7 @@ var state = {
|
|
|
2879
2973
|
realHooks: null
|
|
2880
2974
|
};
|
|
2881
2975
|
var TrueMemory = async (ctx) => {
|
|
2882
|
-
console.log(
|
|
2976
|
+
console.log(`True-Mem v${package_default.version}: Plugin loading...`);
|
|
2883
2977
|
state.ctx = ctx;
|
|
2884
2978
|
state.initPromise = (async () => {
|
|
2885
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"}
|