@pencil-agent/nano-mem 0.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.
Files changed (93) hide show
  1. package/CLAUDE.md +258 -0
  2. package/README.md +146 -0
  3. package/dist/cli.d.ts +8 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +90 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +46 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +48 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/consolidation.d.ts +13 -0
  12. package/dist/consolidation.d.ts.map +1 -0
  13. package/dist/consolidation.js +111 -0
  14. package/dist/consolidation.js.map +1 -0
  15. package/dist/engine.d.ts +67 -0
  16. package/dist/engine.d.ts.map +1 -0
  17. package/dist/engine.js +492 -0
  18. package/dist/engine.js.map +1 -0
  19. package/dist/eviction.d.ts +16 -0
  20. package/dist/eviction.d.ts.map +1 -0
  21. package/dist/eviction.js +22 -0
  22. package/dist/eviction.js.map +1 -0
  23. package/dist/extension.d.ts +11 -0
  24. package/dist/extension.d.ts.map +1 -0
  25. package/dist/extension.js +264 -0
  26. package/dist/extension.js.map +1 -0
  27. package/dist/extraction.d.ts +10 -0
  28. package/dist/extraction.d.ts.map +1 -0
  29. package/dist/extraction.js +136 -0
  30. package/dist/extraction.js.map +1 -0
  31. package/dist/full-insights-html.d.ts +8 -0
  32. package/dist/full-insights-html.d.ts.map +1 -0
  33. package/dist/full-insights-html.js +311 -0
  34. package/dist/full-insights-html.js.map +1 -0
  35. package/dist/full-insights.d.ts +21 -0
  36. package/dist/full-insights.d.ts.map +1 -0
  37. package/dist/full-insights.js +327 -0
  38. package/dist/full-insights.js.map +1 -0
  39. package/dist/i18n.d.ts +50 -0
  40. package/dist/i18n.d.ts.map +1 -0
  41. package/dist/i18n.js +169 -0
  42. package/dist/i18n.js.map +1 -0
  43. package/dist/index.d.ts +18 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +14 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/insights-html.d.ts +8 -0
  48. package/dist/insights-html.d.ts.map +1 -0
  49. package/dist/insights-html.js +431 -0
  50. package/dist/insights-html.js.map +1 -0
  51. package/dist/linking.d.ts +11 -0
  52. package/dist/linking.d.ts.map +1 -0
  53. package/dist/linking.js +40 -0
  54. package/dist/linking.js.map +1 -0
  55. package/dist/privacy.d.ts +16 -0
  56. package/dist/privacy.d.ts.map +1 -0
  57. package/dist/privacy.js +52 -0
  58. package/dist/privacy.js.map +1 -0
  59. package/dist/scoring.d.ts +25 -0
  60. package/dist/scoring.d.ts.map +1 -0
  61. package/dist/scoring.js +63 -0
  62. package/dist/scoring.js.map +1 -0
  63. package/dist/store.d.ts +16 -0
  64. package/dist/store.d.ts.map +1 -0
  65. package/dist/store.js +68 -0
  66. package/dist/store.js.map +1 -0
  67. package/dist/types.d.ts +191 -0
  68. package/dist/types.d.ts.map +1 -0
  69. package/dist/types.js +7 -0
  70. package/dist/types.js.map +1 -0
  71. package/dist/update.d.ts +14 -0
  72. package/dist/update.d.ts.map +1 -0
  73. package/dist/update.js +126 -0
  74. package/dist/update.js.map +1 -0
  75. package/package.json +60 -0
  76. package/src/cli.ts +99 -0
  77. package/src/config.ts +72 -0
  78. package/src/consolidation.ts +127 -0
  79. package/src/engine.ts +699 -0
  80. package/src/eviction.ts +30 -0
  81. package/src/extension.ts +290 -0
  82. package/src/extraction.ts +152 -0
  83. package/src/full-insights-html.ts +342 -0
  84. package/src/full-insights.ts +396 -0
  85. package/src/i18n.ts +233 -0
  86. package/src/index.ts +50 -0
  87. package/src/insights-html.ts +476 -0
  88. package/src/linking.ts +43 -0
  89. package/src/privacy.ts +52 -0
  90. package/src/scoring.ts +94 -0
  91. package/src/store.ts +84 -0
  92. package/src/types.ts +209 -0
  93. package/src/update.ts +141 -0
@@ -0,0 +1,63 @@
1
+ /**
2
+ * [INPUT]: MemoryEntry/Episode/WorkEntry, project, context tags, config weights
3
+ * [OUTPUT]: retrieval score (Stanford: Recency + Importance + Relevance)
4
+ * [POS]: Core ranking algorithm — used by engine for injection budget allocation
5
+ *
6
+ * Key innovation: uses per-entry adaptive strength (not global half-life)
7
+ * for Recency, implementing Ebbinghaus spaced repetition.
8
+ */
9
+ export function daysSince(iso) {
10
+ return Math.max(0, (Date.now() - new Date(iso).getTime()) / 86_400_000);
11
+ }
12
+ /** Ebbinghaus decay: R = e^(-t * ln2 / S) where S = per-entry strength */
13
+ export function decay(ageDays, strength) {
14
+ return Math.exp((-ageDays * Math.LN2) / Math.max(1, strength));
15
+ }
16
+ export function extractTags(text) {
17
+ return [...new Set(text.toLowerCase().match(/[a-z0-9\u4e00-\u9fff_.-]{2,}/g) || [])].slice(0, 30);
18
+ }
19
+ export function tagOverlap(a, b) {
20
+ if (!a.length || !b.length)
21
+ return 0;
22
+ const setB = new Set(b);
23
+ return a.filter((t) => setB.has(t)).length / Math.max(a.length, b.length);
24
+ }
25
+ export function scoreEntry(e, project, ctx, defaultHalfLife, weights) {
26
+ const strength = e.strength || defaultHalfLife[e.type] || 30;
27
+ const recency = decay(daysSince(e.created), strength);
28
+ const importanceNorm = Math.min(1, e.importance / 10);
29
+ const projectMatch = e.project === project ? 1 : 0.5;
30
+ const relevance = projectMatch * (0.3 + 0.7 * tagOverlap(e.tags, ctx));
31
+ return weights.recency * recency + weights.importance * importanceNorm + weights.relevance * relevance;
32
+ }
33
+ export function scoreEpisode(ep, project, ctx, defaultHalfLife, weights) {
34
+ const strength = defaultHalfLife.episode || 14;
35
+ const recency = decay(daysSince(ep.date), strength);
36
+ const importanceNorm = Math.min(1, ep.importance / 10);
37
+ const projectMatch = ep.project === project ? 1 : 0.5;
38
+ const relevance = projectMatch * (0.3 + 0.7 * tagOverlap(ep.tags, ctx));
39
+ return weights.recency * recency + weights.importance * importanceNorm + weights.relevance * relevance;
40
+ }
41
+ export function scoreWorkEntry(w, project, ctx, defaultHalfLife, weights) {
42
+ const strength = w.strength || defaultHalfLife.work || 45;
43
+ const recency = decay(daysSince(w.created), strength);
44
+ const importanceNorm = Math.min(1, w.importance / 10);
45
+ const projectMatch = w.project === project ? 1 : 0.5;
46
+ const relevance = projectMatch * (0.3 + 0.7 * tagOverlap(w.tags, ctx));
47
+ return weights.recency * recency + weights.importance * importanceNorm + weights.relevance * relevance;
48
+ }
49
+ /** Budget-constrained top-k selection by score */
50
+ export function pickTop(items, scoreFn, lenFn, budget) {
51
+ const scored = items.map((t) => ({ item: t, score: scoreFn(t) })).sort((a, b) => b.score - a.score);
52
+ const result = [];
53
+ let used = 0;
54
+ for (const { item } of scored) {
55
+ const len = lenFn(item);
56
+ if (used + len > budget)
57
+ continue;
58
+ used += len;
59
+ result.push(item);
60
+ }
61
+ return result;
62
+ }
63
+ //# sourceMappingURL=scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../src/scoring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * [INPUT]: file paths, data objects
3
+ * [OUTPUT]: async JSON read/write with directory auto-creation
4
+ * [POS]: Persistence layer — all other modules go through here
5
+ */
6
+ import type { Episode, MemoryEntry, Meta, WorkEntry } from "./types.js";
7
+ export declare function readJson<T>(path: string, fallback: T): Promise<T>;
8
+ export declare function writeJson(path: string, data: unknown): Promise<void>;
9
+ export declare function loadEntries(path: string): Promise<MemoryEntry[]>;
10
+ export declare function saveEntries(path: string, entries: MemoryEntry[], max: number, utilityFn: (e: MemoryEntry) => number): Promise<void>;
11
+ export declare function loadEpisodes(episodesDir: string): Promise<Episode[]>;
12
+ export declare function saveEpisode(episodesDir: string, ep: Episode): Promise<void>;
13
+ export declare function loadWork(path: string): Promise<WorkEntry[]>;
14
+ export declare function saveWork(path: string, entries: WorkEntry[], max: number, utilityFn: (w: WorkEntry) => number): Promise<void>;
15
+ export declare function loadMeta(path: string): Promise<Meta>;
16
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMxE,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAQvE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAEtE;AAED,wBAAsB,WAAW,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,EAAE,EACtB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,MAAM,GACnC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAU1E;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAEjE;AAED,wBAAsB,QAAQ,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,EAAE,EACpB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,MAAM,GACjC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D"}
package/dist/store.js ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * [INPUT]: file paths, data objects
3
+ * [OUTPUT]: async JSON read/write with directory auto-creation
4
+ * [POS]: Persistence layer — all other modules go through here
5
+ */
6
+ import { existsSync } from "node:fs";
7
+ import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
8
+ import { dirname, join } from "node:path";
9
+ async function ensureDir(dir) {
10
+ if (!existsSync(dir))
11
+ await mkdir(dir, { recursive: true });
12
+ }
13
+ export async function readJson(path, fallback) {
14
+ try {
15
+ if (!existsSync(path))
16
+ return fallback;
17
+ const raw = await readFile(path, "utf-8");
18
+ return JSON.parse(raw);
19
+ }
20
+ catch {
21
+ return fallback;
22
+ }
23
+ }
24
+ export async function writeJson(path, data) {
25
+ await ensureDir(dirname(path));
26
+ await writeFile(path, JSON.stringify(data, null, 2), "utf-8");
27
+ }
28
+ export async function loadEntries(path) {
29
+ return readJson(path, []);
30
+ }
31
+ export async function saveEntries(path, entries, max, utilityFn) {
32
+ if (entries.length > max) {
33
+ entries.sort((a, b) => utilityFn(b) - utilityFn(a));
34
+ entries.length = max;
35
+ }
36
+ await writeJson(path, entries);
37
+ }
38
+ export async function loadEpisodes(episodesDir) {
39
+ await ensureDir(episodesDir);
40
+ const files = await readdir(episodesDir);
41
+ const results = [];
42
+ for (const f of files) {
43
+ if (!f.endsWith(".json"))
44
+ continue;
45
+ const ep = await readJson(join(episodesDir, f), null);
46
+ if (ep)
47
+ results.push(ep);
48
+ }
49
+ return results;
50
+ }
51
+ export async function saveEpisode(episodesDir, ep) {
52
+ await ensureDir(episodesDir);
53
+ await writeJson(join(episodesDir, `${ep.date}-${ep.sessionId.slice(0, 8)}.json`), ep);
54
+ }
55
+ export async function loadWork(path) {
56
+ return readJson(path, []);
57
+ }
58
+ export async function saveWork(path, entries, max, utilityFn) {
59
+ if (entries.length > max) {
60
+ entries.sort((a, b) => utilityFn(b) - utilityFn(a));
61
+ entries.length = max;
62
+ }
63
+ await writeJson(path, entries);
64
+ }
65
+ export async function loadMeta(path) {
66
+ return readJson(path, { totalSessions: 0, version: 1 });
67
+ }
68
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * [INPUT]: None (pure type definitions)
3
+ * [OUTPUT]: All core data types for NanoMem
4
+ * [POS]: Foundation layer — every other module imports from here
5
+ */
6
+ /** Pluggable LLM function: system prompt + user message → raw text response */
7
+ export type LlmFn = (systemPrompt: string, userMessage: string) => Promise<string>;
8
+ export interface MemoryScope {
9
+ userId?: string;
10
+ agentId?: string;
11
+ }
12
+ /** Structured data for Facets (Pattern/Struggle) memory types */
13
+ export type FacetData = {
14
+ kind: "pattern";
15
+ trigger: string;
16
+ behavior: string;
17
+ } | {
18
+ kind: "struggle";
19
+ problem: string;
20
+ attempts: string[];
21
+ solution: string;
22
+ };
23
+ export interface MemoryEntry {
24
+ id: string;
25
+ type: "fact" | "lesson" | "preference" | "decision" | "entity" | "pattern" | "struggle";
26
+ content: string;
27
+ tags: string[];
28
+ project: string;
29
+ importance: number;
30
+ /** Adaptive memory strength (days). Grows with each successful recall — Ebbinghaus spaced repetition. */
31
+ strength?: number;
32
+ /** Ingestion time: when the system recorded this entry */
33
+ created: string;
34
+ /** Event time: when the fact actually occurred (bi-temporal, defaults to created) */
35
+ eventTime?: string;
36
+ lastAccessed?: string;
37
+ accessCount: number;
38
+ /** A-MEM style links to related memory entries */
39
+ relatedIds?: string[];
40
+ /** TTL in days — auto-evicted after expiry. undefined = permanent */
41
+ ttl?: number;
42
+ scope?: MemoryScope;
43
+ /** Structured data for pattern/struggle types (Facets) */
44
+ facetData?: FacetData;
45
+ }
46
+ export interface Episode {
47
+ sessionId: string;
48
+ project: string;
49
+ date: string;
50
+ summary: string;
51
+ userGoal?: string;
52
+ filesModified: string[];
53
+ toolsUsed: Record<string, number>;
54
+ keyObservations: string[];
55
+ errors: string[];
56
+ tags: string[];
57
+ importance: number;
58
+ consolidated: boolean;
59
+ scope?: MemoryScope;
60
+ }
61
+ export interface WorkEntry {
62
+ id: string;
63
+ goal: string;
64
+ summary: string;
65
+ project: string;
66
+ tags: string[];
67
+ importance: number;
68
+ strength?: number;
69
+ created: string;
70
+ eventTime?: string;
71
+ lastAccessed?: string;
72
+ accessCount: number;
73
+ relatedIds?: string[];
74
+ ttl?: number;
75
+ scope?: MemoryScope;
76
+ }
77
+ export interface Meta {
78
+ totalSessions: number;
79
+ lastConsolidation?: string;
80
+ version: number;
81
+ }
82
+ /** Mem0-style update operations */
83
+ export type UpdateAction = "add" | "update" | "delete" | "noop";
84
+ export interface ExtractedItem {
85
+ type: "preference" | "fact" | "lesson" | "decision" | "retract" | "pattern" | "struggle";
86
+ content: string;
87
+ /** Structured data for pattern/struggle types (populated by LLM extraction) */
88
+ facetData?: FacetData;
89
+ }
90
+ export interface ExtractedWork {
91
+ goal: string;
92
+ summary: string;
93
+ }
94
+ export interface PatternInsight {
95
+ entry: MemoryEntry;
96
+ weight: number;
97
+ trigger: string;
98
+ behavior: string;
99
+ }
100
+ export interface StruggleInsight {
101
+ entry: MemoryEntry;
102
+ weight: number;
103
+ problem: string;
104
+ attempts: string[];
105
+ solution: string;
106
+ resolved: boolean;
107
+ }
108
+ export interface InsightsReport {
109
+ patterns: PatternInsight[];
110
+ struggles: StruggleInsight[];
111
+ topLessons: MemoryEntry[];
112
+ topKnowledge: MemoryEntry[];
113
+ preferences: MemoryEntry[];
114
+ stats: {
115
+ knowledge: number;
116
+ lessons: number;
117
+ preferences: number;
118
+ facets: number;
119
+ episodes: number;
120
+ work: number;
121
+ totalSessions: number;
122
+ };
123
+ recommendations: string[];
124
+ generatedAt: string;
125
+ }
126
+ export interface FullInsightsAtAGlance {
127
+ working: string;
128
+ hindering: string;
129
+ quickWins: string;
130
+ ambitious: string;
131
+ }
132
+ export interface FullInsightsProjectArea {
133
+ name: string;
134
+ sessionCount: number;
135
+ description: string;
136
+ }
137
+ export interface FullInsightsChartRow {
138
+ label: string;
139
+ value: number;
140
+ }
141
+ export interface FullInsightsChart {
142
+ id: string;
143
+ title: string;
144
+ rows: FullInsightsChartRow[];
145
+ }
146
+ export interface FullInsightsWin {
147
+ title: string;
148
+ description: string;
149
+ }
150
+ export interface FullInsightsFriction {
151
+ title: string;
152
+ description: string;
153
+ examples?: string[];
154
+ }
155
+ export interface FullInsightsFeatureToTry {
156
+ title: string;
157
+ oneLiner: string;
158
+ whyForYou: string;
159
+ exampleCode?: string;
160
+ }
161
+ export interface FullInsightsUsagePattern {
162
+ title: string;
163
+ summary: string;
164
+ detail: string;
165
+ pastePrompt?: string;
166
+ }
167
+ export interface FullInsightsReport {
168
+ stats: {
169
+ knowledge: number;
170
+ lessons: number;
171
+ preferences: number;
172
+ facets: number;
173
+ episodes: number;
174
+ work: number;
175
+ totalSessions: number;
176
+ aggregateToolCount?: number;
177
+ aggregateFileCount?: number;
178
+ };
179
+ atAGlance: FullInsightsAtAGlance;
180
+ projectAreas: FullInsightsProjectArea[];
181
+ charts: FullInsightsChart[];
182
+ wins: FullInsightsWin[];
183
+ frictions: FullInsightsFriction[];
184
+ patterns: PatternInsight[];
185
+ recommendations: string[];
186
+ featuresToTry: FullInsightsFeatureToTry[];
187
+ usagePatterns: FullInsightsUsagePattern[];
188
+ generatedAt: string;
189
+ locale: string;
190
+ }
191
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * [INPUT]: None (pure type definitions)
3
+ * [OUTPUT]: All core data types for NanoMem
4
+ * [POS]: Foundation layer — every other module imports from here
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * [INPUT]: extracted items, existing entries
3
+ * [OUTPUT]: entries mutated via Mem0 four-operation pipeline (ADD/UPDATE/DELETE/NOOP)
4
+ * [POS]: Implements Mem0 update semantics — slot-based, tag-overlap, and retract
5
+ *
6
+ * Key improvements over basic approach:
7
+ * - UPDATE generalized: any entry type, tag overlap > 0.7 triggers content replacement
8
+ * - DELETE: retract-type extractions find and remove matching entries
9
+ */
10
+ import type { NanomemConfig } from "./config.js";
11
+ import type { ExtractedItem, MemoryEntry } from "./types.js";
12
+ /** Process a single extracted item through the Mem0 pipeline */
13
+ export declare function applyExtraction(entries: MemoryEntry[], item: ExtractedItem, project: string, cfg: NanomemConfig): void;
14
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA2C7D,gEAAgE;AAChE,wBAAgB,eAAe,CAC9B,OAAO,EAAE,WAAW,EAAE,EACtB,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,aAAa,GAChB,IAAI,CAoDN"}
package/dist/update.js ADDED
@@ -0,0 +1,126 @@
1
+ /**
2
+ * [INPUT]: extracted items, existing entries
3
+ * [OUTPUT]: entries mutated via Mem0 four-operation pipeline (ADD/UPDATE/DELETE/NOOP)
4
+ * [POS]: Implements Mem0 update semantics — slot-based, tag-overlap, and retract
5
+ *
6
+ * Key improvements over basic approach:
7
+ * - UPDATE generalized: any entry type, tag overlap > 0.7 triggers content replacement
8
+ * - DELETE: retract-type extractions find and remove matching entries
9
+ */
10
+ import { linkNewEntry } from "./linking.js";
11
+ import { filterPII } from "./privacy.js";
12
+ import { extractTags, tagOverlap } from "./scoring.js";
13
+ const UPDATE_OVERLAP_THRESHOLD = 0.7;
14
+ const NOOP_SIMILARITY_THRESHOLD = 0.8;
15
+ const CONTENT_SIMILARITY_THRESHOLD = 0.85;
16
+ function makeId() {
17
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
18
+ }
19
+ /** Simple content similarity check using character overlap */
20
+ function contentSimilarity(a, b) {
21
+ const aLower = a.toLowerCase().trim();
22
+ const bLower = b.toLowerCase().trim();
23
+ if (aLower === bLower)
24
+ return 1;
25
+ const shorter = aLower.length < bLower.length ? aLower : bLower;
26
+ const longer = aLower.length >= bLower.length ? aLower : bLower;
27
+ if (longer.includes(shorter))
28
+ return shorter.length / longer.length;
29
+ // Simple word overlap
30
+ const aWords = new Set(aLower.split(/\s+/).filter((w) => w.length > 2));
31
+ const bWords = new Set(bLower.split(/\s+/).filter((w) => w.length > 2));
32
+ if (aWords.size === 0 || bWords.size === 0)
33
+ return 0;
34
+ let overlap = 0;
35
+ for (const w of aWords)
36
+ if (bWords.has(w))
37
+ overlap++;
38
+ return (2 * overlap) / (aWords.size + bWords.size);
39
+ }
40
+ /** Check if new content is too similar to an existing entry of same type */
41
+ function isDuplicate(entries, type, tags, content) {
42
+ return entries.some((e) => {
43
+ if (e.type !== type)
44
+ return false;
45
+ // Check both tag overlap and content similarity
46
+ const tagMatch = tagOverlap(e.tags, tags) >= NOOP_SIMILARITY_THRESHOLD;
47
+ const contentMatch = contentSimilarity(e.content, content) >= CONTENT_SIMILARITY_THRESHOLD;
48
+ return tagMatch || contentMatch;
49
+ });
50
+ }
51
+ /** Find existing entry with high tag overlap for UPDATE */
52
+ function findUpdateCandidate(entries, type, tags) {
53
+ return entries.findIndex((e) => e.type === type && tagOverlap(e.tags, tags) >= UPDATE_OVERLAP_THRESHOLD);
54
+ }
55
+ /** Process a single extracted item through the Mem0 pipeline */
56
+ export function applyExtraction(entries, item, project, cfg) {
57
+ if (item.type === "retract") {
58
+ applyDelete(entries, item.content);
59
+ return;
60
+ }
61
+ const memType = mapType(item.type);
62
+ const content = filterPII(item.content);
63
+ const tags = extractTags(content);
64
+ if (isDuplicate(entries, memType, tags, content))
65
+ return;
66
+ const updateIdx = findUpdateCandidate(entries, memType, tags);
67
+ if (updateIdx >= 0) {
68
+ const existing = entries[updateIdx];
69
+ entries[updateIdx] = {
70
+ ...existing,
71
+ content,
72
+ tags,
73
+ lastAccessed: new Date().toISOString(),
74
+ };
75
+ return;
76
+ }
77
+ const now = new Date().toISOString();
78
+ const newEntry = {
79
+ id: makeId(),
80
+ type: memType,
81
+ content,
82
+ tags,
83
+ project,
84
+ importance: item.type === "struggle"
85
+ ? 9
86
+ : item.type === "lesson"
87
+ ? 8
88
+ : item.type === "pattern"
89
+ ? 7
90
+ : item.type === "preference"
91
+ ? 6
92
+ : 5,
93
+ strength: cfg.halfLife[memType] ?? 30,
94
+ created: now,
95
+ eventTime: now,
96
+ accessCount: 0,
97
+ relatedIds: [],
98
+ scope: cfg.defaultScope,
99
+ facetData: item.facetData,
100
+ };
101
+ linkNewEntry(newEntry, entries);
102
+ entries.push(newEntry);
103
+ }
104
+ function applyDelete(entries, content) {
105
+ const tags = extractTags(content);
106
+ const idx = entries.findIndex((e) => (e.type === "fact" || e.type === "preference") && tagOverlap(e.tags, tags) >= UPDATE_OVERLAP_THRESHOLD);
107
+ if (idx >= 0)
108
+ entries.splice(idx, 1);
109
+ }
110
+ function mapType(t) {
111
+ switch (t) {
112
+ case "preference":
113
+ return "preference";
114
+ case "lesson":
115
+ return "lesson";
116
+ case "decision":
117
+ return "decision";
118
+ case "pattern":
119
+ return "pattern";
120
+ case "struggle":
121
+ return "struggle";
122
+ default:
123
+ return "fact";
124
+ }
125
+ }
126
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AACtC,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAE1C,SAAS,MAAM;IACd,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAClE,CAAC;AAED,8DAA8D;AAC9D,SAAS,iBAAiB,CAAC,CAAS,EAAE,CAAS;IAC9C,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAChE,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACpE,sBAAsB;IACtB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACrD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IACrD,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,4EAA4E;AAC5E,SAAS,WAAW,CAAC,OAAsB,EAAE,IAAY,EAAE,IAAc,EAAE,OAAe;IACzF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACzB,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAClC,gDAAgD;QAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,yBAAyB,CAAC;QACvE,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,4BAA4B,CAAC;QAC3F,OAAO,QAAQ,IAAI,YAAY,CAAC;IACjC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,SAAS,mBAAmB,CAAC,OAAsB,EAAE,IAAY,EAAE,IAAc;IAChF,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,wBAAwB,CAAC,CAAC;AAC1G,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,eAAe,CAC9B,OAAsB,EACtB,IAAmB,EACnB,OAAe,EACf,GAAkB;IAElB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO;IACR,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAElC,IAAI,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC;QAAE,OAAO;IAEzD,MAAM,SAAS,GAAG,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9D,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAE,CAAC;QACrC,OAAO,CAAC,SAAS,CAAC,GAAG;YACpB,GAAG,QAAQ;YACX,OAAO;YACP,IAAI;YACJ,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QACF,OAAO;IACR,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAgB;QAC7B,EAAE,EAAE,MAAM,EAAE;QACZ,IAAI,EAAE,OAAO;QACb,OAAO;QACP,IAAI;QACJ,OAAO;QACP,UAAU,EACT,IAAI,CAAC,IAAI,KAAK,UAAU;YACvB,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ;gBACvB,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS;oBACxB,CAAC,CAAC,CAAC;oBACH,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY;wBAC3B,CAAC,CAAC,CAAC;wBACH,CAAC,CAAC,CAAC;QACR,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE;QACrC,OAAO,EAAE,GAAG;QACZ,SAAS,EAAE,GAAG;QACd,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,EAAE;QACd,KAAK,EAAE,GAAG,CAAC,YAAY;QACvB,SAAS,EAAE,IAAI,CAAC,SAAS;KACzB,CAAC;IAEF,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,WAAW,CAAC,OAAsB,EAAE,OAAe;IAC3D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAC5B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,wBAAwB,CAC7G,CAAC;IACF,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,OAAO,CAAC,CAAwB;IACxC,QAAQ,CAAC,EAAE,CAAC;QACX,KAAK,YAAY;YAChB,OAAO,YAAY,CAAC;QACrB,KAAK,QAAQ;YACZ,OAAO,QAAQ,CAAC;QACjB,KAAK,UAAU;YACd,OAAO,UAAU,CAAC;QACnB,KAAK,SAAS;YACb,OAAO,SAAS,CAAC;QAClB,KAAK,UAAU;YACd,OAAO,UAAU,CAAC;QACnB;YACC,OAAO,MAAM,CAAC;IAChB,CAAC;AACF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@pencil-agent/nano-mem",
3
+ "version": "0.0.1",
4
+ "description": "Persistent memory engine for AI coding agents with consolidation, scoring, and insights",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./extension": {
14
+ "import": "./dist/extension.js",
15
+ "types": "./dist/extension.d.ts"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "src",
21
+ "README.md",
22
+ "CLAUDE.md"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "dev": "tsc --watch",
27
+ "clean": "rm -rf dist",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "keywords": [
31
+ "nanomem",
32
+ "memory",
33
+ "ai",
34
+ "llm",
35
+ "persistent-memory",
36
+ "consolidation",
37
+ "spaced-repetition",
38
+ "a-mem",
39
+ "mem0"
40
+ ],
41
+ "author": "NanoPencil Team",
42
+ "license": "MIT",
43
+ "engines": {
44
+ "node": ">=20"
45
+ },
46
+ "dependencies": {},
47
+ "devDependencies": {
48
+ "@pencil-agent/nano-pencil": "^1.10.1",
49
+ "@types/node": "^20.11.0",
50
+ "typescript": "^5.3.3"
51
+ },
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "https://codeup.aliyun.com/67d1a8677564dc59f36547a9/nanoPencil.git",
55
+ "directory": "packages/nanomem"
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
59
+ }
60
+ }