anno-extension 0.1.0
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/LICENSE +7 -0
- package/README.md +30 -0
- package/THIRD_PARTY_NOTICES.md +8 -0
- package/dist/browser-fs.d.ts +14 -0
- package/dist/browser-fs.d.ts.map +1 -0
- package/dist/browser-fs.js +69 -0
- package/dist/browser-fs.js.map +1 -0
- package/dist/config.d.ts +81 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +82 -0
- package/dist/config.js.map +1 -0
- package/dist/consolidate-v2.d.ts +15 -0
- package/dist/consolidate-v2.d.ts.map +1 -0
- package/dist/consolidate-v2.js +125 -0
- package/dist/consolidate-v2.js.map +1 -0
- package/dist/consolidation.d.ts +12 -0
- package/dist/consolidation.d.ts.map +1 -0
- package/dist/consolidation.js +199 -0
- package/dist/consolidation.js.map +1 -0
- package/dist/dedup.d.ts +18 -0
- package/dist/dedup.d.ts.map +1 -0
- package/dist/dedup.js +85 -0
- package/dist/dedup.js.map +1 -0
- package/dist/diagnostics.d.ts +24 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +53 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/embedding-index.d.ts +27 -0
- package/dist/embedding-index.d.ts.map +1 -0
- package/dist/embedding-index.js +111 -0
- package/dist/embedding-index.js.map +1 -0
- package/dist/engine-archive.d.ts +37 -0
- package/dist/engine-archive.d.ts.map +1 -0
- package/dist/engine-archive.js +155 -0
- package/dist/engine-archive.js.map +1 -0
- package/dist/engine-episode-sync.d.ts +19 -0
- package/dist/engine-episode-sync.d.ts.map +1 -0
- package/dist/engine-episode-sync.js +186 -0
- package/dist/engine-episode-sync.js.map +1 -0
- package/dist/engine-injection-text.d.ts +46 -0
- package/dist/engine-injection-text.d.ts.map +1 -0
- package/dist/engine-injection-text.js +271 -0
- package/dist/engine-injection-text.js.map +1 -0
- package/dist/engine-insights.d.ts +22 -0
- package/dist/engine-insights.d.ts.map +1 -0
- package/dist/engine-insights.js +127 -0
- package/dist/engine-insights.js.map +1 -0
- package/dist/engine-links.d.ts +43 -0
- package/dist/engine-links.d.ts.map +1 -0
- package/dist/engine-links.js +223 -0
- package/dist/engine-links.js.map +1 -0
- package/dist/engine-recall-select.d.ts +84 -0
- package/dist/engine-recall-select.d.ts.map +1 -0
- package/dist/engine-recall-select.js +127 -0
- package/dist/engine-recall-select.js.map +1 -0
- package/dist/engine-reinforce.d.ts +18 -0
- package/dist/engine-reinforce.d.ts.map +1 -0
- package/dist/engine-reinforce.js +116 -0
- package/dist/engine-reinforce.js.map +1 -0
- package/dist/engine-scoring-v2.d.ts +35 -0
- package/dist/engine-scoring-v2.d.ts.map +1 -0
- package/dist/engine-scoring-v2.js +178 -0
- package/dist/engine-scoring-v2.js.map +1 -0
- package/dist/engine-v2-mapping.d.ts +17 -0
- package/dist/engine-v2-mapping.d.ts.map +1 -0
- package/dist/engine-v2-mapping.js +190 -0
- package/dist/engine-v2-mapping.js.map +1 -0
- package/dist/engine.d.ts +339 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1964 -0
- package/dist/engine.js.map +1 -0
- package/dist/eviction.d.ts +14 -0
- package/dist/eviction.d.ts.map +1 -0
- package/dist/eviction.js +26 -0
- package/dist/eviction.js.map +1 -0
- package/dist/extraction.d.ts +11 -0
- package/dist/extraction.d.ts.map +1 -0
- package/dist/extraction.js +261 -0
- package/dist/extraction.js.map +1 -0
- package/dist/full-insights-html.d.ts +9 -0
- package/dist/full-insights-html.d.ts.map +1 -0
- package/dist/full-insights-html.js +422 -0
- package/dist/full-insights-html.js.map +1 -0
- package/dist/full-insights-sections.d.ts +48 -0
- package/dist/full-insights-sections.d.ts.map +1 -0
- package/dist/full-insights-sections.js +231 -0
- package/dist/full-insights-sections.js.map +1 -0
- package/dist/full-insights.d.ts +22 -0
- package/dist/full-insights.d.ts.map +1 -0
- package/dist/full-insights.js +370 -0
- package/dist/full-insights.js.map +1 -0
- package/dist/hash-embedding.d.ts +9 -0
- package/dist/hash-embedding.d.ts.map +1 -0
- package/dist/hash-embedding.js +44 -0
- package/dist/hash-embedding.js.map +1 -0
- package/dist/human-insights.d.ts +28 -0
- package/dist/human-insights.d.ts.map +1 -0
- package/dist/human-insights.js +260 -0
- package/dist/human-insights.js.map +1 -0
- package/dist/i18n.d.ts +64 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +367 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/insights-html.d.ts +9 -0
- package/dist/insights-html.d.ts.map +1 -0
- package/dist/insights-html.js +432 -0
- package/dist/insights-html.js.map +1 -0
- package/dist/linking.d.ts +22 -0
- package/dist/linking.d.ts.map +1 -0
- package/dist/linking.js +192 -0
- package/dist/linking.js.map +1 -0
- package/dist/llm-json.d.ts +10 -0
- package/dist/llm-json.d.ts.map +1 -0
- package/dist/llm-json.js +193 -0
- package/dist/llm-json.js.map +1 -0
- package/dist/privacy.d.ts +17 -0
- package/dist/privacy.d.ts.map +1 -0
- package/dist/privacy.js +53 -0
- package/dist/privacy.js.map +1 -0
- package/dist/procedural-v2.d.ts +9 -0
- package/dist/procedural-v2.d.ts.map +1 -0
- package/dist/procedural-v2.js +123 -0
- package/dist/procedural-v2.js.map +1 -0
- package/dist/reconsolidate-v2.d.ts +19 -0
- package/dist/reconsolidate-v2.d.ts.map +1 -0
- package/dist/reconsolidate-v2.js +115 -0
- package/dist/reconsolidate-v2.js.map +1 -0
- package/dist/scoring.d.ts +32 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +108 -0
- package/dist/scoring.js.map +1 -0
- package/dist/store-v2.d.ts +35 -0
- package/dist/store-v2.d.ts.map +1 -0
- package/dist/store-v2.js +98 -0
- package/dist/store-v2.js.map +1 -0
- package/dist/store.d.ts +22 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +116 -0
- package/dist/store.js.map +1 -0
- package/dist/turn-context.d.ts +37 -0
- package/dist/turn-context.d.ts.map +1 -0
- package/dist/turn-context.js +31 -0
- package/dist/turn-context.js.map +1 -0
- package/dist/types-v2.d.ts +190 -0
- package/dist/types-v2.d.ts.map +1 -0
- package/dist/types-v2.js +8 -0
- package/dist/types-v2.js.map +1 -0
- package/dist/types.d.ts +330 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/update.d.ts +31 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +250 -0
- package/dist/update.js.map +1 -0
- package/package.json +34 -0
- package/src/browser-fs.ts +67 -0
- package/src/config.ts +138 -0
- package/src/consolidate-v2.ts +158 -0
- package/src/consolidation.ts +229 -0
- package/src/dedup.ts +91 -0
- package/src/diagnostics.ts +81 -0
- package/src/embedding-index.ts +138 -0
- package/src/engine-archive.ts +167 -0
- package/src/engine-episode-sync.ts +237 -0
- package/src/engine-injection-text.ts +334 -0
- package/src/engine-insights.ts +182 -0
- package/src/engine-links.ts +311 -0
- package/src/engine-recall-select.ts +298 -0
- package/src/engine-reinforce.ts +154 -0
- package/src/engine-scoring-v2.ts +188 -0
- package/src/engine-v2-mapping.ts +204 -0
- package/src/engine.ts +2499 -0
- package/src/eviction.ts +38 -0
- package/src/extraction.ts +300 -0
- package/src/full-insights-html.ts +474 -0
- package/src/full-insights-sections.ts +305 -0
- package/src/full-insights.ts +423 -0
- package/src/hash-embedding.ts +48 -0
- package/src/human-insights.ts +345 -0
- package/src/i18n.ts +455 -0
- package/src/index.ts +117 -0
- package/src/insights-html.ts +478 -0
- package/src/linking.ts +228 -0
- package/src/llm-json.ts +194 -0
- package/src/privacy.ts +54 -0
- package/src/procedural-v2.ts +142 -0
- package/src/reconsolidate-v2.ts +145 -0
- package/src/scoring.ts +156 -0
- package/src/store-v2.ts +138 -0
- package/src/store.ts +137 -0
- package/src/turn-context.ts +56 -0
- package/src/types-v2.ts +244 -0
- package/src/types.ts +372 -0
- package/src/update.ts +271 -0
package/dist/update.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: contentSimilarity, applyExtraction, checkConsolidationEntry, checkWorkDuplicate, applyWorkExtraction
|
|
3
|
+
* [FROM]: Depends on ./config.js, ./linking.js, ./privacy.js, ./scoring.js, ./store.js, ./types.js
|
|
4
|
+
* [TO]: Consumed by packages/mem-core/src/index.ts
|
|
5
|
+
* [HERE]: packages/mem-core/src/update.ts - Mem0 four-operation pipeline (ADD/UPDATE/DELETE/NOOP)
|
|
6
|
+
*/
|
|
7
|
+
import type { NanomemConfig } from "./config.js";
|
|
8
|
+
import type { ExtractedItem, MemoryEntry, WorkEntry } from "./types.js";
|
|
9
|
+
/** Simple content similarity check using character overlap — exported for dedup/consolidation */
|
|
10
|
+
export declare function contentSimilarity(a: string, b: string): number;
|
|
11
|
+
/** Process a single extracted item through the Mem0 pipeline */
|
|
12
|
+
export declare function applyExtraction(entries: MemoryEntry[], item: ExtractedItem, project: string, cfg: NanomemConfig): void;
|
|
13
|
+
/** Check if consolidation candidate is duplicate or update of existing. Used before pushing to knowledge/lessons. */
|
|
14
|
+
export declare function checkConsolidationEntry(target: MemoryEntry[], candidate: MemoryEntry, allExisting: MemoryEntry[]): {
|
|
15
|
+
action: "skip";
|
|
16
|
+
} | {
|
|
17
|
+
action: "update";
|
|
18
|
+
index: number;
|
|
19
|
+
} | {
|
|
20
|
+
action: "add";
|
|
21
|
+
};
|
|
22
|
+
/** Check if work candidate is duplicate or update of existing work entries. */
|
|
23
|
+
export declare function checkWorkDuplicate(entries: WorkEntry[], candidate: WorkEntry): {
|
|
24
|
+
action: "skip";
|
|
25
|
+
} | {
|
|
26
|
+
action: "update";
|
|
27
|
+
index: number;
|
|
28
|
+
} | {
|
|
29
|
+
action: "add";
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAoC,SAAS,EAAE,MAAM,YAAY,CAAC;AAU1G,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAc9D;AA6ED,gEAAgE;AAChE,wBAAgB,eAAe,CAC9B,OAAO,EAAE,WAAW,EAAE,EACtB,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,aAAa,GAChB,IAAI,CAkFN;AAmCD,qHAAqH;AACrH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,WAAW,EAAE,EACrB,SAAS,EAAE,WAAW,EACtB,WAAW,EAAE,WAAW,EAAE,GACxB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,CAO9E;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,SAAS,EAAE,EACpB,SAAS,EAAE,SAAS,GAClB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,CAc9E"}
|
package/dist/update.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: contentSimilarity, applyExtraction, checkConsolidationEntry, checkWorkDuplicate, applyWorkExtraction
|
|
3
|
+
* [FROM]: Depends on ./config.js, ./linking.js, ./privacy.js, ./scoring.js, ./store.js, ./types.js
|
|
4
|
+
* [TO]: Consumed by packages/mem-core/src/index.ts
|
|
5
|
+
* [HERE]: packages/mem-core/src/update.ts - Mem0 four-operation pipeline (ADD/UPDATE/DELETE/NOOP)
|
|
6
|
+
*/
|
|
7
|
+
import { linkNewEntry } from "./linking.js";
|
|
8
|
+
import { filterPII } from "./privacy.js";
|
|
9
|
+
import { extractTags, tagOverlap } from "./scoring.js";
|
|
10
|
+
import { deriveNameFromContent, deriveSummaryFromContent } from "./store.js";
|
|
11
|
+
const UPDATE_OVERLAP_THRESHOLD = 0.7;
|
|
12
|
+
const NOOP_SIMILARITY_THRESHOLD = 0.8;
|
|
13
|
+
const CONTENT_SIMILARITY_THRESHOLD = 0.85;
|
|
14
|
+
function makeId() {
|
|
15
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
16
|
+
}
|
|
17
|
+
/** Simple content similarity check using character overlap — exported for dedup/consolidation */
|
|
18
|
+
export function contentSimilarity(a, b) {
|
|
19
|
+
const aLower = a.toLowerCase().trim();
|
|
20
|
+
const bLower = b.toLowerCase().trim();
|
|
21
|
+
if (aLower === bLower)
|
|
22
|
+
return 1;
|
|
23
|
+
const shorter = aLower.length < bLower.length ? aLower : bLower;
|
|
24
|
+
const longer = aLower.length >= bLower.length ? aLower : bLower;
|
|
25
|
+
if (longer.includes(shorter))
|
|
26
|
+
return shorter.length / longer.length;
|
|
27
|
+
// Simple word overlap
|
|
28
|
+
const aWords = new Set(aLower.split(/\s+/).filter((w) => w.length > 2));
|
|
29
|
+
const bWords = new Set(bLower.split(/\s+/).filter((w) => w.length > 2));
|
|
30
|
+
if (aWords.size === 0 || bWords.size === 0)
|
|
31
|
+
return 0;
|
|
32
|
+
let overlap = 0;
|
|
33
|
+
for (const w of aWords)
|
|
34
|
+
if (bWords.has(w))
|
|
35
|
+
overlap++;
|
|
36
|
+
return (2 * overlap) / (aWords.size + bWords.size);
|
|
37
|
+
}
|
|
38
|
+
/** Check if new content is too similar to an existing entry of same type */
|
|
39
|
+
function isDuplicate(entries, type, tags, nameSummary) {
|
|
40
|
+
return entries.some((e) => {
|
|
41
|
+
if (e.type !== type)
|
|
42
|
+
return false;
|
|
43
|
+
const existingNameSummary = `${e.name || ""} ${e.summary || e.content || ""}`.trim();
|
|
44
|
+
// Check both tag overlap and content similarity
|
|
45
|
+
const tagMatch = tagOverlap(e.tags, tags) >= NOOP_SIMILARITY_THRESHOLD;
|
|
46
|
+
const contentMatch = contentSimilarity(existingNameSummary, nameSummary) >= CONTENT_SIMILARITY_THRESHOLD;
|
|
47
|
+
return tagMatch || contentMatch;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** Find existing entry with high tag overlap for UPDATE */
|
|
51
|
+
function findUpdateCandidate(entries, type, tags) {
|
|
52
|
+
return entries.findIndex((e) => e.type === type && tagOverlap(e.tags, tags) >= UPDATE_OVERLAP_THRESHOLD);
|
|
53
|
+
}
|
|
54
|
+
function inferRetention(item) {
|
|
55
|
+
if (item.retention)
|
|
56
|
+
return item.retention;
|
|
57
|
+
if (item.stability === "situational" || item.stateData)
|
|
58
|
+
return "ambient";
|
|
59
|
+
switch (item.type) {
|
|
60
|
+
case "preference":
|
|
61
|
+
case "pattern":
|
|
62
|
+
return "core";
|
|
63
|
+
case "lesson":
|
|
64
|
+
case "struggle":
|
|
65
|
+
case "decision":
|
|
66
|
+
case "event":
|
|
67
|
+
return "key-event";
|
|
68
|
+
default:
|
|
69
|
+
return "ambient";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function inferStability(item) {
|
|
73
|
+
if (item.stability)
|
|
74
|
+
return item.stability;
|
|
75
|
+
if (item.stateData)
|
|
76
|
+
return "situational";
|
|
77
|
+
switch (item.type) {
|
|
78
|
+
case "preference":
|
|
79
|
+
case "pattern":
|
|
80
|
+
return "stable";
|
|
81
|
+
case "event":
|
|
82
|
+
return item.eventData?.kind === "milestone" ? "stable" : "situational";
|
|
83
|
+
default:
|
|
84
|
+
return "stable";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function inferSalience(item) {
|
|
88
|
+
if (typeof item.salience === "number") {
|
|
89
|
+
return Math.max(1, Math.min(10, item.salience));
|
|
90
|
+
}
|
|
91
|
+
switch (item.type) {
|
|
92
|
+
case "event":
|
|
93
|
+
case "struggle":
|
|
94
|
+
return 9;
|
|
95
|
+
case "lesson":
|
|
96
|
+
case "decision":
|
|
97
|
+
return 8;
|
|
98
|
+
case "pattern":
|
|
99
|
+
return 7;
|
|
100
|
+
case "preference":
|
|
101
|
+
return 6;
|
|
102
|
+
default:
|
|
103
|
+
return 4;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function inferTtl(item, cfg, retention, salience) {
|
|
107
|
+
if (item.stability === "situational" || item.stateData)
|
|
108
|
+
return Math.min(14, cfg.forgetting.ambientTtlDays);
|
|
109
|
+
if (retention !== "ambient")
|
|
110
|
+
return undefined;
|
|
111
|
+
if (item.type === "fact" && salience <= 5)
|
|
112
|
+
return cfg.forgetting.ambientTtlDays;
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
/** Process a single extracted item through the Mem0 pipeline */
|
|
116
|
+
export function applyExtraction(entries, item, project, cfg) {
|
|
117
|
+
if (item.type === "retract") {
|
|
118
|
+
applyDelete(entries, item.detail || item.content || item.summary || "");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const memType = mapType(item.type);
|
|
122
|
+
const rawDetail = item.detail || item.content || "";
|
|
123
|
+
const detail = filterPII(rawDetail);
|
|
124
|
+
const name = item.name || deriveNameFromContent(detail);
|
|
125
|
+
const summary = item.summary || deriveSummaryFromContent(detail);
|
|
126
|
+
const tags = extractTags(`${name} ${summary} ${detail}`);
|
|
127
|
+
const nameSummary = `${name} ${summary}`;
|
|
128
|
+
const retention = inferRetention(item);
|
|
129
|
+
const salience = inferSalience(item);
|
|
130
|
+
const stability = inferStability(item);
|
|
131
|
+
if (isDuplicate(entries, memType, tags, nameSummary))
|
|
132
|
+
return;
|
|
133
|
+
const updateIdx = findUpdateCandidate(entries, memType, tags);
|
|
134
|
+
if (updateIdx >= 0) {
|
|
135
|
+
const existing = entries[updateIdx];
|
|
136
|
+
entries[updateIdx] = {
|
|
137
|
+
...existing,
|
|
138
|
+
name,
|
|
139
|
+
summary,
|
|
140
|
+
detail,
|
|
141
|
+
content: detail,
|
|
142
|
+
tags,
|
|
143
|
+
lastAccessed: new Date().toISOString(),
|
|
144
|
+
retention: existing.retention === "core" || retention === "core"
|
|
145
|
+
? "core"
|
|
146
|
+
: existing.retention === "key-event" || retention === "key-event"
|
|
147
|
+
? "key-event"
|
|
148
|
+
: "ambient",
|
|
149
|
+
salience: Math.max(existing.salience ?? existing.importance, salience),
|
|
150
|
+
eventData: item.eventData ?? existing.eventData,
|
|
151
|
+
stateData: item.stateData ?? existing.stateData,
|
|
152
|
+
stability: existing.stability === "stable" || stability === "stable" ? "stable" : "situational",
|
|
153
|
+
ttl: inferTtl(item, cfg, retention, salience) ?? existing.ttl,
|
|
154
|
+
};
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const now = new Date().toISOString();
|
|
158
|
+
const newEntry = {
|
|
159
|
+
id: makeId(),
|
|
160
|
+
type: memType,
|
|
161
|
+
name,
|
|
162
|
+
summary,
|
|
163
|
+
detail,
|
|
164
|
+
content: detail,
|
|
165
|
+
tags,
|
|
166
|
+
project,
|
|
167
|
+
importance: item.type === "struggle"
|
|
168
|
+
? 9
|
|
169
|
+
: item.type === "lesson"
|
|
170
|
+
? 8
|
|
171
|
+
: item.type === "pattern"
|
|
172
|
+
? 7
|
|
173
|
+
: item.type === "preference"
|
|
174
|
+
? 6
|
|
175
|
+
: 5,
|
|
176
|
+
strength: cfg.halfLife[memType] ?? 30,
|
|
177
|
+
created: now,
|
|
178
|
+
eventTime: now,
|
|
179
|
+
accessCount: 0,
|
|
180
|
+
relatedIds: [],
|
|
181
|
+
scope: cfg.defaultScope,
|
|
182
|
+
facetData: item.facetData,
|
|
183
|
+
eventData: item.eventData,
|
|
184
|
+
retention,
|
|
185
|
+
salience,
|
|
186
|
+
stability,
|
|
187
|
+
stateData: item.stateData,
|
|
188
|
+
ttl: inferTtl(item, cfg, retention, salience),
|
|
189
|
+
};
|
|
190
|
+
linkNewEntry(newEntry, entries);
|
|
191
|
+
entries.push(newEntry);
|
|
192
|
+
}
|
|
193
|
+
function applyDelete(entries, text) {
|
|
194
|
+
const tags = extractTags(text);
|
|
195
|
+
const idx = entries.findIndex((e) => (e.type === "fact" || e.type === "preference") && tagOverlap(e.tags, tags) >= UPDATE_OVERLAP_THRESHOLD);
|
|
196
|
+
if (idx >= 0)
|
|
197
|
+
entries.splice(idx, 1);
|
|
198
|
+
}
|
|
199
|
+
function mapType(t) {
|
|
200
|
+
switch (t) {
|
|
201
|
+
case "preference":
|
|
202
|
+
return "preference";
|
|
203
|
+
case "lesson":
|
|
204
|
+
return "lesson";
|
|
205
|
+
case "decision":
|
|
206
|
+
return "decision";
|
|
207
|
+
case "pattern":
|
|
208
|
+
return "pattern";
|
|
209
|
+
case "struggle":
|
|
210
|
+
return "struggle";
|
|
211
|
+
case "event":
|
|
212
|
+
return "event";
|
|
213
|
+
default:
|
|
214
|
+
return "fact";
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// ─── Dedup helpers for consolidation & work ────────────────────────────────
|
|
218
|
+
const WORK_DEDUP_TAG_THRESHOLD = 0.75;
|
|
219
|
+
const WORK_DEDUP_CONTENT_THRESHOLD = 0.8;
|
|
220
|
+
const WORK_UPDATE_TAG_THRESHOLD = 0.65;
|
|
221
|
+
/** Check if consolidation candidate is duplicate or update of existing. Used before pushing to knowledge/lessons. */
|
|
222
|
+
export function checkConsolidationEntry(target, candidate, allExisting) {
|
|
223
|
+
const nameSummary = `${candidate.name || ""} ${candidate.summary || ""}`.trim();
|
|
224
|
+
const sameTypeExisting = allExisting.filter((e) => e.type === candidate.type);
|
|
225
|
+
if (isDuplicate(sameTypeExisting, candidate.type, candidate.tags, nameSummary))
|
|
226
|
+
return { action: "skip" };
|
|
227
|
+
const updateIdx = findUpdateCandidate(target, candidate.type, candidate.tags);
|
|
228
|
+
if (updateIdx >= 0)
|
|
229
|
+
return { action: "update", index: updateIdx };
|
|
230
|
+
return { action: "add" };
|
|
231
|
+
}
|
|
232
|
+
/** Check if work candidate is duplicate or update of existing work entries. */
|
|
233
|
+
export function checkWorkDuplicate(entries, candidate) {
|
|
234
|
+
const candidateText = `${candidate.goal} ${candidate.summary}`.trim();
|
|
235
|
+
for (let i = 0; i < entries.length; i++) {
|
|
236
|
+
const e = entries[i];
|
|
237
|
+
const existingText = `${e.goal} ${e.summary}`.trim();
|
|
238
|
+
const tagMatch = tagOverlap(e.tags, candidate.tags) >= WORK_DEDUP_TAG_THRESHOLD;
|
|
239
|
+
const contentMatch = contentSimilarity(existingText, candidateText) >= WORK_DEDUP_CONTENT_THRESHOLD;
|
|
240
|
+
if (tagMatch || contentMatch)
|
|
241
|
+
return { action: "skip" };
|
|
242
|
+
}
|
|
243
|
+
for (let i = 0; i < entries.length; i++) {
|
|
244
|
+
const e = entries[i];
|
|
245
|
+
if (tagOverlap(e.tags, candidate.tags) >= WORK_UPDATE_TAG_THRESHOLD)
|
|
246
|
+
return { action: "update", index: i };
|
|
247
|
+
}
|
|
248
|
+
return { action: "add" };
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "anno-extension",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser-native NanoMem engine with IndexedDB persistence and layered memory recall.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "GPL-3.0-only",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+ssh://git@gitlab.alibaba-inc.com/QoderDesign/ANNO.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/cunyu666/ANNO",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/cunyu666/ANNO/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist", "src", "README.md", "LICENSE", "THIRD_PARTY_NOTICES.md"],
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.build.json",
|
|
27
|
+
"prepublishOnly": "npm run build && npm pack --dry-run"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"registry": "https://registry.npmjs.org"
|
|
32
|
+
},
|
|
33
|
+
"engines": {"node": ">=18"}
|
|
34
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const DB_NAME = 'anno-nanomem-files-v1'
|
|
2
|
+
const STORE = 'files'
|
|
3
|
+
let databasePromise: Promise<IDBDatabase> | undefined
|
|
4
|
+
|
|
5
|
+
function database(): Promise<IDBDatabase> {
|
|
6
|
+
if (!databasePromise) databasePromise = new Promise((resolve, reject) => {
|
|
7
|
+
const request = indexedDB.open(DB_NAME, 1)
|
|
8
|
+
request.onupgradeneeded = () => request.result.createObjectStore(STORE)
|
|
9
|
+
request.onsuccess = () => resolve(request.result)
|
|
10
|
+
request.onerror = () => reject(request.error)
|
|
11
|
+
})
|
|
12
|
+
return databasePromise
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function transact<T>(mode: IDBTransactionMode, action: (store: IDBObjectStore) => IDBRequest<T>): Promise<T> {
|
|
16
|
+
return database().then(db => new Promise((resolve, reject) => {
|
|
17
|
+
const transaction = db.transaction(STORE, mode)
|
|
18
|
+
const request = action(transaction.objectStore(STORE))
|
|
19
|
+
let value: T
|
|
20
|
+
request.onsuccess = () => { value = request.result }
|
|
21
|
+
request.onerror = () => reject(request.error)
|
|
22
|
+
transaction.onerror = () => reject(transaction.error)
|
|
23
|
+
transaction.onabort = () => reject(transaction.error)
|
|
24
|
+
transaction.oncomplete = () => resolve(value)
|
|
25
|
+
}))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function join(...parts: string[]): string {
|
|
29
|
+
return parts.join('/').replace(/\/+/g, '/')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function dirname(path: string): string { return path.slice(0, path.lastIndexOf('/')) || '/' }
|
|
33
|
+
export async function mkdir(_path: string, _options?: { recursive?: boolean }): Promise<void> { /* IndexedDB has no directories. */ }
|
|
34
|
+
export async function readFile(path: string): Promise<string> {
|
|
35
|
+
const value = await transact<string | undefined>('readonly', store => store.get(path))
|
|
36
|
+
if (value === undefined) throw new Error(`File not found: ${path}`)
|
|
37
|
+
return value
|
|
38
|
+
}
|
|
39
|
+
export async function writeFile(path: string, text: string): Promise<void> { await transact('readwrite', store => store.put(text, path)) }
|
|
40
|
+
// Web Locks coordinate extension pages and the MV3 service worker.
|
|
41
|
+
export function withMemoryLock<T>(name: string, action: () => Promise<T>): Promise<T> {
|
|
42
|
+
return navigator.locks.request<Promise<T>>(`anno:${name}`, action).then(result => result)
|
|
43
|
+
}
|
|
44
|
+
export async function readdir(path: string): Promise<string[]> {
|
|
45
|
+
const keys = await transact<IDBValidKey[]>('readonly', store => store.getAllKeys())
|
|
46
|
+
const prefix = path.replace(/\/+$/, '') + '/'
|
|
47
|
+
return [...new Set(keys.map(String).filter(key => key.startsWith(prefix)).map(key => key.slice(prefix.length).split('/')[0]))]
|
|
48
|
+
}
|
|
49
|
+
export async function cp(source: string, target: string, options?: { recursive?: boolean }): Promise<void> {
|
|
50
|
+
const keys = await transact<IDBValidKey[]>('readonly', store => store.getAllKeys())
|
|
51
|
+
const matching = keys.map(String).filter(key => key === source || (options?.recursive && key.startsWith(source.replace(/\/+$/, '') + '/')))
|
|
52
|
+
if (!matching.length) throw new Error(`File not found: ${source}`)
|
|
53
|
+
for (const key of matching) await writeFile(target + key.slice(source.length), await readFile(key))
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function removeTree(path: string): Promise<void> {
|
|
57
|
+
const keys = await transact<IDBValidKey[]>('readonly', store => store.getAllKeys())
|
|
58
|
+
const prefix = path.replace(/\/+$/, '') + '/'
|
|
59
|
+
await database().then(db => new Promise<void>((resolve, reject) => {
|
|
60
|
+
const transaction = db.transaction(STORE, 'readwrite')
|
|
61
|
+
const store = transaction.objectStore(STORE)
|
|
62
|
+
for (const key of keys.map(String)) if (key === path || key.startsWith(prefix)) store.delete(key)
|
|
63
|
+
transaction.oncomplete = () => resolve()
|
|
64
|
+
transaction.onerror = () => reject(transaction.error)
|
|
65
|
+
transaction.onabort = () => reject(transaction.error)
|
|
66
|
+
}))
|
|
67
|
+
}
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [WHO]: ProgressiveRecallConfig, NanomemConfig, getConfig, BudgetConfig, ScoreWeights
|
|
3
|
+
* [FROM]: Depends on browser-fs.ts and ./types.js
|
|
4
|
+
* [TO]: Consumed by packages/mem-core/src/index.ts
|
|
5
|
+
* [HERE]: packages/mem-core/src/config.ts - configuration management for memory system
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
import { join } from "./browser-fs.js";
|
|
10
|
+
import type { MemoryScope } from "./types.js";
|
|
11
|
+
|
|
12
|
+
export interface ProgressiveRecallConfig {
|
|
13
|
+
/** Score threshold for Active tier — inject full detail */
|
|
14
|
+
thresholdActive: number;
|
|
15
|
+
/** Score threshold for Cue tier — inject name + summary + id */
|
|
16
|
+
thresholdCue: number;
|
|
17
|
+
/** Budget ratio for Active tier (default 0.15 = 15%) */
|
|
18
|
+
budgetActive: number;
|
|
19
|
+
/** Budget ratio for Cue tier (default 0.70 = 70%) */
|
|
20
|
+
budgetCue: number;
|
|
21
|
+
/** Force entries created within this many hours to Active tier */
|
|
22
|
+
forceRecentHours: number;
|
|
23
|
+
/** Force entries with importance >= this value to Active tier */
|
|
24
|
+
forceImportanceMin: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface EmbeddingConfig {
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
model: string;
|
|
30
|
+
dim: number;
|
|
31
|
+
autoSync: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface NanomemConfig {
|
|
35
|
+
memoryDir: string;
|
|
36
|
+
tokenBudget: number;
|
|
37
|
+
budget: { lessons: number; knowledge: number; events: number; episodes: number; preferences: number; work: number; facets: number };
|
|
38
|
+
halfLife: Record<string, number>;
|
|
39
|
+
maxEntries: { knowledge: number; lessons: number; events: number; preferences: number; work: number; facets: number };
|
|
40
|
+
consolidationThreshold: number;
|
|
41
|
+
/** Stanford-style retrieval scoring weights */
|
|
42
|
+
scoreWeights: { recency: number; importance: number; relevance: number };
|
|
43
|
+
/** Utility-weighted eviction: access frequency vs base impact */
|
|
44
|
+
evictionWeights: { accessFrequency: number; baseImpact: number };
|
|
45
|
+
/** Default scope for all operations */
|
|
46
|
+
defaultScope?: MemoryScope;
|
|
47
|
+
/** Locale for LLM prompts and injection templates */
|
|
48
|
+
locale: "en" | "zh";
|
|
49
|
+
/** Strength growth factor on each successful recall (spaced repetition) */
|
|
50
|
+
strengthGrowthFactor: number;
|
|
51
|
+
/** Progressive recall injection configuration */
|
|
52
|
+
progressiveRecall: ProgressiveRecallConfig;
|
|
53
|
+
/** Default forgetting windows for less important memories */
|
|
54
|
+
forgetting: { ambientTtlDays: number; workTtlDays: number; reviveCooldownDays: number };
|
|
55
|
+
/** Embedding configuration for semantic episodic/procedural recall */
|
|
56
|
+
embeddings: EmbeddingConfig;
|
|
57
|
+
/** Weight for SAL structural proximity boost in V2 recall scoring (0 = disabled). */
|
|
58
|
+
structuralWeight: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const DEFAULT_BUDGET = {
|
|
62
|
+
lessons: 0.18,
|
|
63
|
+
knowledge: 0.17,
|
|
64
|
+
events: 0.15,
|
|
65
|
+
episodes: 0.18,
|
|
66
|
+
preferences: 0.1,
|
|
67
|
+
work: 0.2,
|
|
68
|
+
facets: 0.12,
|
|
69
|
+
} as const;
|
|
70
|
+
|
|
71
|
+
const DEFAULT_HALF_LIFE: Record<string, number> = {
|
|
72
|
+
lesson: 90,
|
|
73
|
+
fact: 60,
|
|
74
|
+
episode: 14,
|
|
75
|
+
preference: 120,
|
|
76
|
+
decision: 45,
|
|
77
|
+
entity: 30,
|
|
78
|
+
event: 180,
|
|
79
|
+
work: 45,
|
|
80
|
+
pattern: 180,
|
|
81
|
+
struggle: 120,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const DEFAULT_MAX_ENTRIES = { knowledge: 1000, lessons: 500, events: 300, preferences: 200, work: 400, facets: 400 };
|
|
85
|
+
const DEFAULT_SCORE_WEIGHTS = { recency: 1, importance: 1, relevance: 1 };
|
|
86
|
+
const DEFAULT_EVICTION_WEIGHTS = { accessFrequency: 0.4, baseImpact: 0.6 };
|
|
87
|
+
const DEFAULT_PROGRESSIVE_RECALL: ProgressiveRecallConfig = {
|
|
88
|
+
thresholdActive: 0.7,
|
|
89
|
+
thresholdCue: 0.35,
|
|
90
|
+
budgetActive: 0.15,
|
|
91
|
+
budgetCue: 0.70,
|
|
92
|
+
forceRecentHours: 24,
|
|
93
|
+
forceImportanceMin: 9,
|
|
94
|
+
};
|
|
95
|
+
const DEFAULT_FORGETTING = {
|
|
96
|
+
ambientTtlDays: 45,
|
|
97
|
+
workTtlDays: 21,
|
|
98
|
+
reviveCooldownDays: 7,
|
|
99
|
+
} as const;
|
|
100
|
+
const DEFAULT_EMBEDDINGS: EmbeddingConfig = {
|
|
101
|
+
enabled: true,
|
|
102
|
+
model: "local-hash-v1",
|
|
103
|
+
dim: 256,
|
|
104
|
+
autoSync: true,
|
|
105
|
+
};
|
|
106
|
+
const DEFAULT_STRUCTURAL_WEIGHT = 0.15;
|
|
107
|
+
|
|
108
|
+
export function getConfig(overrides?: Partial<NanomemConfig>): NanomemConfig {
|
|
109
|
+
const tokenBudget = 6000;
|
|
110
|
+
const memoryDir = overrides?.memoryDir || join("anno", "memory");
|
|
111
|
+
const locale = overrides?.locale || "en";
|
|
112
|
+
const embeddingsDim = DEFAULT_EMBEDDINGS.dim;
|
|
113
|
+
const embeddingsModel = DEFAULT_EMBEDDINGS.model;
|
|
114
|
+
return {
|
|
115
|
+
memoryDir,
|
|
116
|
+
tokenBudget: overrides?.tokenBudget ?? tokenBudget,
|
|
117
|
+
budget: overrides?.budget ?? { ...DEFAULT_BUDGET },
|
|
118
|
+
halfLife: overrides?.halfLife ?? { ...DEFAULT_HALF_LIFE },
|
|
119
|
+
maxEntries: overrides?.maxEntries ?? { ...DEFAULT_MAX_ENTRIES },
|
|
120
|
+
consolidationThreshold: overrides?.consolidationThreshold ?? 10,
|
|
121
|
+
scoreWeights: overrides?.scoreWeights ?? { ...DEFAULT_SCORE_WEIGHTS },
|
|
122
|
+
evictionWeights: overrides?.evictionWeights ?? { ...DEFAULT_EVICTION_WEIGHTS },
|
|
123
|
+
defaultScope: overrides?.defaultScope,
|
|
124
|
+
locale,
|
|
125
|
+
strengthGrowthFactor: overrides?.strengthGrowthFactor ?? 1.5,
|
|
126
|
+
progressiveRecall: overrides?.progressiveRecall ?? { ...DEFAULT_PROGRESSIVE_RECALL },
|
|
127
|
+
forgetting: overrides?.forgetting ?? { ...DEFAULT_FORGETTING },
|
|
128
|
+
embeddings:
|
|
129
|
+
overrides?.embeddings ??
|
|
130
|
+
{
|
|
131
|
+
enabled: DEFAULT_EMBEDDINGS.enabled,
|
|
132
|
+
model: embeddingsModel,
|
|
133
|
+
dim: embeddingsDim,
|
|
134
|
+
autoSync: DEFAULT_EMBEDDINGS.autoSync,
|
|
135
|
+
},
|
|
136
|
+
structuralWeight: overrides?.structuralWeight ?? DEFAULT_STRUCTURAL_WEIGHT,
|
|
137
|
+
};
|
|
138
|
+
}
|