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.
Files changed (199) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +30 -0
  3. package/THIRD_PARTY_NOTICES.md +8 -0
  4. package/dist/browser-fs.d.ts +14 -0
  5. package/dist/browser-fs.d.ts.map +1 -0
  6. package/dist/browser-fs.js +69 -0
  7. package/dist/browser-fs.js.map +1 -0
  8. package/dist/config.d.ts +81 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +82 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/consolidate-v2.d.ts +15 -0
  13. package/dist/consolidate-v2.d.ts.map +1 -0
  14. package/dist/consolidate-v2.js +125 -0
  15. package/dist/consolidate-v2.js.map +1 -0
  16. package/dist/consolidation.d.ts +12 -0
  17. package/dist/consolidation.d.ts.map +1 -0
  18. package/dist/consolidation.js +199 -0
  19. package/dist/consolidation.js.map +1 -0
  20. package/dist/dedup.d.ts +18 -0
  21. package/dist/dedup.d.ts.map +1 -0
  22. package/dist/dedup.js +85 -0
  23. package/dist/dedup.js.map +1 -0
  24. package/dist/diagnostics.d.ts +24 -0
  25. package/dist/diagnostics.d.ts.map +1 -0
  26. package/dist/diagnostics.js +53 -0
  27. package/dist/diagnostics.js.map +1 -0
  28. package/dist/embedding-index.d.ts +27 -0
  29. package/dist/embedding-index.d.ts.map +1 -0
  30. package/dist/embedding-index.js +111 -0
  31. package/dist/embedding-index.js.map +1 -0
  32. package/dist/engine-archive.d.ts +37 -0
  33. package/dist/engine-archive.d.ts.map +1 -0
  34. package/dist/engine-archive.js +155 -0
  35. package/dist/engine-archive.js.map +1 -0
  36. package/dist/engine-episode-sync.d.ts +19 -0
  37. package/dist/engine-episode-sync.d.ts.map +1 -0
  38. package/dist/engine-episode-sync.js +186 -0
  39. package/dist/engine-episode-sync.js.map +1 -0
  40. package/dist/engine-injection-text.d.ts +46 -0
  41. package/dist/engine-injection-text.d.ts.map +1 -0
  42. package/dist/engine-injection-text.js +271 -0
  43. package/dist/engine-injection-text.js.map +1 -0
  44. package/dist/engine-insights.d.ts +22 -0
  45. package/dist/engine-insights.d.ts.map +1 -0
  46. package/dist/engine-insights.js +127 -0
  47. package/dist/engine-insights.js.map +1 -0
  48. package/dist/engine-links.d.ts +43 -0
  49. package/dist/engine-links.d.ts.map +1 -0
  50. package/dist/engine-links.js +223 -0
  51. package/dist/engine-links.js.map +1 -0
  52. package/dist/engine-recall-select.d.ts +84 -0
  53. package/dist/engine-recall-select.d.ts.map +1 -0
  54. package/dist/engine-recall-select.js +127 -0
  55. package/dist/engine-recall-select.js.map +1 -0
  56. package/dist/engine-reinforce.d.ts +18 -0
  57. package/dist/engine-reinforce.d.ts.map +1 -0
  58. package/dist/engine-reinforce.js +116 -0
  59. package/dist/engine-reinforce.js.map +1 -0
  60. package/dist/engine-scoring-v2.d.ts +35 -0
  61. package/dist/engine-scoring-v2.d.ts.map +1 -0
  62. package/dist/engine-scoring-v2.js +178 -0
  63. package/dist/engine-scoring-v2.js.map +1 -0
  64. package/dist/engine-v2-mapping.d.ts +17 -0
  65. package/dist/engine-v2-mapping.d.ts.map +1 -0
  66. package/dist/engine-v2-mapping.js +190 -0
  67. package/dist/engine-v2-mapping.js.map +1 -0
  68. package/dist/engine.d.ts +339 -0
  69. package/dist/engine.d.ts.map +1 -0
  70. package/dist/engine.js +1964 -0
  71. package/dist/engine.js.map +1 -0
  72. package/dist/eviction.d.ts +14 -0
  73. package/dist/eviction.d.ts.map +1 -0
  74. package/dist/eviction.js +26 -0
  75. package/dist/eviction.js.map +1 -0
  76. package/dist/extraction.d.ts +11 -0
  77. package/dist/extraction.d.ts.map +1 -0
  78. package/dist/extraction.js +261 -0
  79. package/dist/extraction.js.map +1 -0
  80. package/dist/full-insights-html.d.ts +9 -0
  81. package/dist/full-insights-html.d.ts.map +1 -0
  82. package/dist/full-insights-html.js +422 -0
  83. package/dist/full-insights-html.js.map +1 -0
  84. package/dist/full-insights-sections.d.ts +48 -0
  85. package/dist/full-insights-sections.d.ts.map +1 -0
  86. package/dist/full-insights-sections.js +231 -0
  87. package/dist/full-insights-sections.js.map +1 -0
  88. package/dist/full-insights.d.ts +22 -0
  89. package/dist/full-insights.d.ts.map +1 -0
  90. package/dist/full-insights.js +370 -0
  91. package/dist/full-insights.js.map +1 -0
  92. package/dist/hash-embedding.d.ts +9 -0
  93. package/dist/hash-embedding.d.ts.map +1 -0
  94. package/dist/hash-embedding.js +44 -0
  95. package/dist/hash-embedding.js.map +1 -0
  96. package/dist/human-insights.d.ts +28 -0
  97. package/dist/human-insights.d.ts.map +1 -0
  98. package/dist/human-insights.js +260 -0
  99. package/dist/human-insights.js.map +1 -0
  100. package/dist/i18n.d.ts +64 -0
  101. package/dist/i18n.d.ts.map +1 -0
  102. package/dist/i18n.js +367 -0
  103. package/dist/i18n.js.map +1 -0
  104. package/dist/index.d.ts +27 -0
  105. package/dist/index.d.ts.map +1 -0
  106. package/dist/index.js +21 -0
  107. package/dist/index.js.map +1 -0
  108. package/dist/insights-html.d.ts +9 -0
  109. package/dist/insights-html.d.ts.map +1 -0
  110. package/dist/insights-html.js +432 -0
  111. package/dist/insights-html.js.map +1 -0
  112. package/dist/linking.d.ts +22 -0
  113. package/dist/linking.d.ts.map +1 -0
  114. package/dist/linking.js +192 -0
  115. package/dist/linking.js.map +1 -0
  116. package/dist/llm-json.d.ts +10 -0
  117. package/dist/llm-json.d.ts.map +1 -0
  118. package/dist/llm-json.js +193 -0
  119. package/dist/llm-json.js.map +1 -0
  120. package/dist/privacy.d.ts +17 -0
  121. package/dist/privacy.d.ts.map +1 -0
  122. package/dist/privacy.js +53 -0
  123. package/dist/privacy.js.map +1 -0
  124. package/dist/procedural-v2.d.ts +9 -0
  125. package/dist/procedural-v2.d.ts.map +1 -0
  126. package/dist/procedural-v2.js +123 -0
  127. package/dist/procedural-v2.js.map +1 -0
  128. package/dist/reconsolidate-v2.d.ts +19 -0
  129. package/dist/reconsolidate-v2.d.ts.map +1 -0
  130. package/dist/reconsolidate-v2.js +115 -0
  131. package/dist/reconsolidate-v2.js.map +1 -0
  132. package/dist/scoring.d.ts +32 -0
  133. package/dist/scoring.d.ts.map +1 -0
  134. package/dist/scoring.js +108 -0
  135. package/dist/scoring.js.map +1 -0
  136. package/dist/store-v2.d.ts +35 -0
  137. package/dist/store-v2.d.ts.map +1 -0
  138. package/dist/store-v2.js +98 -0
  139. package/dist/store-v2.js.map +1 -0
  140. package/dist/store.d.ts +22 -0
  141. package/dist/store.d.ts.map +1 -0
  142. package/dist/store.js +116 -0
  143. package/dist/store.js.map +1 -0
  144. package/dist/turn-context.d.ts +37 -0
  145. package/dist/turn-context.d.ts.map +1 -0
  146. package/dist/turn-context.js +31 -0
  147. package/dist/turn-context.js.map +1 -0
  148. package/dist/types-v2.d.ts +190 -0
  149. package/dist/types-v2.d.ts.map +1 -0
  150. package/dist/types-v2.js +8 -0
  151. package/dist/types-v2.js.map +1 -0
  152. package/dist/types.d.ts +330 -0
  153. package/dist/types.d.ts.map +1 -0
  154. package/dist/types.js +8 -0
  155. package/dist/types.js.map +1 -0
  156. package/dist/update.d.ts +31 -0
  157. package/dist/update.d.ts.map +1 -0
  158. package/dist/update.js +250 -0
  159. package/dist/update.js.map +1 -0
  160. package/package.json +34 -0
  161. package/src/browser-fs.ts +67 -0
  162. package/src/config.ts +138 -0
  163. package/src/consolidate-v2.ts +158 -0
  164. package/src/consolidation.ts +229 -0
  165. package/src/dedup.ts +91 -0
  166. package/src/diagnostics.ts +81 -0
  167. package/src/embedding-index.ts +138 -0
  168. package/src/engine-archive.ts +167 -0
  169. package/src/engine-episode-sync.ts +237 -0
  170. package/src/engine-injection-text.ts +334 -0
  171. package/src/engine-insights.ts +182 -0
  172. package/src/engine-links.ts +311 -0
  173. package/src/engine-recall-select.ts +298 -0
  174. package/src/engine-reinforce.ts +154 -0
  175. package/src/engine-scoring-v2.ts +188 -0
  176. package/src/engine-v2-mapping.ts +204 -0
  177. package/src/engine.ts +2499 -0
  178. package/src/eviction.ts +38 -0
  179. package/src/extraction.ts +300 -0
  180. package/src/full-insights-html.ts +474 -0
  181. package/src/full-insights-sections.ts +305 -0
  182. package/src/full-insights.ts +423 -0
  183. package/src/hash-embedding.ts +48 -0
  184. package/src/human-insights.ts +345 -0
  185. package/src/i18n.ts +455 -0
  186. package/src/index.ts +117 -0
  187. package/src/insights-html.ts +478 -0
  188. package/src/linking.ts +228 -0
  189. package/src/llm-json.ts +194 -0
  190. package/src/privacy.ts +54 -0
  191. package/src/procedural-v2.ts +142 -0
  192. package/src/reconsolidate-v2.ts +145 -0
  193. package/src/scoring.ts +156 -0
  194. package/src/store-v2.ts +138 -0
  195. package/src/store.ts +137 -0
  196. package/src/turn-context.ts +56 -0
  197. package/src/types-v2.ts +244 -0
  198. package/src/types.ts +372 -0
  199. package/src/update.ts +271 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ * [WHO]: GraphNeighbor, linkNewEntry, getRelatedSummaries, getGraphNeighborhood, getGraphContextSummaries, reinforceRelations
3
+ * [FROM]: Depends on ./scoring.js, ./types.js
4
+ * [TO]: Consumed by packages/mem-core/src/index.ts
5
+ * [HERE]: packages/mem-core/src/linking.ts - A-MEM style Zettelkasten linking, atomic storage + dynamic associations
6
+ */
7
+ import { tagOverlap } from "./scoring.js";
8
+ const LINK_THRESHOLD = 0.5;
9
+ const MAX_LINKS = 5;
10
+ const GRAPH_TAG_THRESHOLD = 0.35;
11
+ const GRAPH_MAX_HOPS = 2;
12
+ function upsertRelation(source, targetId, kind, weight) {
13
+ if (!source.relations)
14
+ source.relations = [];
15
+ const existing = source.relations.find((relation) => relation.id === targetId && relation.kind === kind);
16
+ if (existing) {
17
+ existing.weight = Math.min(1.5, Math.max(existing.weight, weight));
18
+ return;
19
+ }
20
+ source.relations.push({ id: targetId, kind, weight });
21
+ }
22
+ /** Find related entries by tag overlap and establish bidirectional links */
23
+ export function linkNewEntry(newEntry, allEntries) {
24
+ if (!newEntry.relatedIds)
25
+ newEntry.relatedIds = [];
26
+ if (!newEntry.relations)
27
+ newEntry.relations = [];
28
+ const candidates = allEntries
29
+ .filter((e) => e.id !== newEntry.id)
30
+ .map((e) => ({ entry: e, overlap: tagOverlap(newEntry.tags, e.tags) }))
31
+ .filter((c) => c.overlap >= LINK_THRESHOLD)
32
+ .sort((a, b) => b.overlap - a.overlap)
33
+ .slice(0, MAX_LINKS);
34
+ for (const { entry } of candidates) {
35
+ if (!newEntry.relatedIds.includes(entry.id)) {
36
+ newEntry.relatedIds.push(entry.id);
37
+ }
38
+ const relationKind = inferRelationKind(newEntry, entry, true);
39
+ upsertRelation(newEntry, entry.id, relationKind, 0.7);
40
+ if (!entry.relatedIds)
41
+ entry.relatedIds = [];
42
+ if (!entry.relations)
43
+ entry.relations = [];
44
+ if (!entry.relatedIds.includes(newEntry.id)) {
45
+ entry.relatedIds.push(newEntry.id);
46
+ }
47
+ const reverseRelationKind = inferRelationKind(entry, newEntry, true);
48
+ upsertRelation(entry, newEntry.id, reverseRelationKind, 0.7);
49
+ }
50
+ }
51
+ /** Get content summaries for related entries (for injection enrichment) */
52
+ export function getRelatedSummaries(entry, allEntries, maxCount = 3) {
53
+ if (!entry.relatedIds?.length)
54
+ return [];
55
+ const idSet = new Set(entry.relatedIds);
56
+ return allEntries
57
+ .filter((e) => idSet.has(e.id))
58
+ .slice(0, maxCount)
59
+ .map((e) => e.summary || e.content?.slice(0, 80) || e.name || "");
60
+ }
61
+ function buildGraphScore(seed, candidate, hop, explicit) {
62
+ const overlap = tagOverlap(seed.tags, candidate.tags);
63
+ const salience = (candidate.salience ?? candidate.importance ?? 0) / 10;
64
+ const retentionBoost = candidate.retention === "core" ? 0.35 : candidate.retention === "key-event" ? 0.45 : 0.1;
65
+ const sameProjectBoost = seed.project === candidate.project ? 0.15 : 0;
66
+ const eventBoost = candidate.type === "event" ? 0.25 : 0;
67
+ const explicitBoost = explicit ? 0.35 : 0;
68
+ return overlap + salience + retentionBoost + sameProjectBoost + eventBoost + explicitBoost - hop * 0.18;
69
+ }
70
+ function inferRelationKind(seed, candidate, explicit) {
71
+ if (seed.type === "event" && (candidate.type === "lesson" || candidate.type === "decision"))
72
+ return "cause-of";
73
+ if ((seed.type === "lesson" || seed.type === "decision") && candidate.type === "event")
74
+ return "caused-by";
75
+ if (seed.type === "preference" && (candidate.type === "pattern" || candidate.type === "decision")) {
76
+ return "preference-shapes";
77
+ }
78
+ if (seed.project === candidate.project && explicit)
79
+ return "same-project";
80
+ if (seed.type === candidate.type || seed.retention === candidate.retention)
81
+ return "repeated-pattern";
82
+ return "tag-overlap";
83
+ }
84
+ function getImplicitNeighbors(entry, allEntries) {
85
+ return allEntries.filter((candidate) => candidate.id !== entry.id &&
86
+ candidate.project === entry.project &&
87
+ tagOverlap(entry.tags, candidate.tags) >= GRAPH_TAG_THRESHOLD);
88
+ }
89
+ export function getGraphNeighborhood(entry, allEntries, maxCount = 4) {
90
+ const byId = new Map(allEntries.map((candidate) => [candidate.id, candidate]));
91
+ const visited = new Set([entry.id]);
92
+ const scored = new Map();
93
+ let frontier = [{ entry, hop: 0 }];
94
+ for (let hop = 1; hop <= GRAPH_MAX_HOPS; hop++) {
95
+ const nextFrontier = [];
96
+ for (const current of frontier) {
97
+ const explicit = current.entry.relatedIds
98
+ ?.map((id) => byId.get(id))
99
+ .filter((candidate) => candidate !== undefined) ?? [];
100
+ const implicit = getImplicitNeighbors(current.entry, allEntries);
101
+ for (const candidate of explicit) {
102
+ if (visited.has(candidate.id))
103
+ continue;
104
+ visited.add(candidate.id);
105
+ const score = buildGraphScore(entry, candidate, hop, true);
106
+ scored.set(candidate.id, {
107
+ entry: candidate,
108
+ score,
109
+ relation: inferRelationKind(entry, candidate, true),
110
+ explicit: true,
111
+ });
112
+ nextFrontier.push({ entry: candidate, hop });
113
+ }
114
+ for (const candidate of implicit) {
115
+ if (visited.has(candidate.id))
116
+ continue;
117
+ visited.add(candidate.id);
118
+ const score = buildGraphScore(entry, candidate, hop, false);
119
+ scored.set(candidate.id, {
120
+ entry: candidate,
121
+ score,
122
+ relation: inferRelationKind(entry, candidate, false),
123
+ explicit: false,
124
+ });
125
+ nextFrontier.push({ entry: candidate, hop });
126
+ }
127
+ }
128
+ frontier = nextFrontier;
129
+ if (!frontier.length)
130
+ break;
131
+ }
132
+ return [...scored.values()]
133
+ .sort((a, b) => b.score - a.score)
134
+ .slice(0, maxCount);
135
+ }
136
+ export function getGraphContextSummaries(entry, allEntries, maxCount = 4) {
137
+ return getGraphNeighborhood(entry, allEntries, maxCount).map((candidate) => `[${candidate.relation}] [${candidate.entry.type}] ${candidate.entry.summary || candidate.entry.name || candidate.entry.content?.slice(0, 80) || ""}`);
138
+ }
139
+ export function getGraphNeighborhoodBySeeds(seeds, allEntries, maxCount = 8) {
140
+ const scored = new Map();
141
+ const seedIds = new Set(seeds.map((seed) => seed.id));
142
+ for (const seed of seeds) {
143
+ for (const candidate of getGraphNeighborhood(seed, allEntries, maxCount * 2)) {
144
+ if (seedIds.has(candidate.entry.id))
145
+ continue;
146
+ const overlap = tagOverlap(seed.tags, candidate.entry.tags);
147
+ const existing = scored.get(candidate.entry.id);
148
+ const score = overlap +
149
+ (candidate.entry.salience ?? candidate.entry.importance ?? 0) / 10 +
150
+ (candidate.entry.retention === "core" ? 0.25 : candidate.entry.retention === "key-event" ? 0.3 : 0);
151
+ if (!existing || score > existing.score) {
152
+ scored.set(candidate.entry.id, { ...candidate, score });
153
+ }
154
+ }
155
+ }
156
+ return [...scored.values()]
157
+ .sort((a, b) => b.score - a.score)
158
+ .slice(0, maxCount);
159
+ }
160
+ export function reinforceRelations(recalled, allEntries) {
161
+ const recalledIds = new Set(recalled.map((entry) => entry.id));
162
+ const byId = new Map(allEntries.map((entry) => [entry.id, entry]));
163
+ for (const entry of recalled) {
164
+ const neighbors = getGraphNeighborhood(entry, allEntries, 6);
165
+ for (const neighbor of neighbors) {
166
+ const sourceKind = neighbor.relation;
167
+ upsertRelation(entry, neighbor.entry.id, sourceKind, Math.min(1.5, 0.75 + neighbor.score * 0.12));
168
+ const reverse = byId.get(neighbor.entry.id);
169
+ if (!reverse)
170
+ continue;
171
+ const reverseKind = inferRelationKind(reverse, entry, neighbor.explicit);
172
+ upsertRelation(reverse, entry.id, reverseKind, Math.min(1.5, 0.72 + neighbor.score * 0.1));
173
+ if (!entry.relatedIds?.includes(neighbor.entry.id)) {
174
+ entry.relatedIds = [...(entry.relatedIds ?? []), neighbor.entry.id];
175
+ }
176
+ if (!reverse.relatedIds?.includes(entry.id)) {
177
+ reverse.relatedIds = [...(reverse.relatedIds ?? []), entry.id];
178
+ }
179
+ }
180
+ }
181
+ for (const entry of allEntries) {
182
+ if (!entry.relations?.length)
183
+ continue;
184
+ entry.relations = entry.relations
185
+ .map((relation) => ({
186
+ ...relation,
187
+ weight: recalledIds.has(entry.id) || recalledIds.has(relation.id) ? relation.weight : relation.weight * 0.995,
188
+ }))
189
+ .filter((relation) => relation.weight >= 0.2);
190
+ }
191
+ }
192
+ //# sourceMappingURL=linking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linking.js","sourceRoot":"","sources":["../src/linking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * [WHO]: parseLlmJson, extractLlmJsonText
3
+ * [FROM]: No internal dependencies; uses JSON.parse and balanced-brace scanning
4
+ * [TO]: Consumed by mem-core LLM extraction, consolidation, insights, and extension diagnostics
5
+ * [HERE]: packages/mem-core/src/llm-json.ts - tolerant JSON boundary normalizer for structured LLM responses
6
+ */
7
+ export declare function parseLlmJson<T>(raw: string): T;
8
+ export declare function extractLlmJsonText(raw: string): string;
9
+ export declare function hasParseableLlmJson(raw: string): boolean;
10
+ //# sourceMappingURL=llm-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-json.d.ts","sourceRoot":"","sources":["../src/llm-json.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAG9C;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOxD"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * [WHO]: parseLlmJson, extractLlmJsonText
3
+ * [FROM]: No internal dependencies; uses JSON.parse and balanced-brace scanning
4
+ * [TO]: Consumed by mem-core LLM extraction, consolidation, insights, and extension diagnostics
5
+ * [HERE]: packages/mem-core/src/llm-json.ts - tolerant JSON boundary normalizer for structured LLM responses
6
+ */
7
+ export function parseLlmJson(raw) {
8
+ const text = extractLlmJsonText(raw);
9
+ return JSON.parse(text);
10
+ }
11
+ export function extractLlmJsonText(raw) {
12
+ const trimmed = raw.trim();
13
+ if (!trimmed)
14
+ throw new SyntaxError("LLM returned empty output");
15
+ for (const fenced of extractFencedJsonCandidates(trimmed)) {
16
+ if (canParseJson(fenced))
17
+ return fenced.trim();
18
+ }
19
+ if (canParseJson(trimmed))
20
+ return trimmed;
21
+ const balanced = extractFirstBalancedJson(trimmed);
22
+ if (balanced)
23
+ return balanced;
24
+ // Last resort: try to repair truncated JSON (common with smaller models hitting token limits)
25
+ const repaired = repairTruncatedJson(trimmed);
26
+ if (repaired)
27
+ return repaired;
28
+ return trimmed;
29
+ }
30
+ export function hasParseableLlmJson(raw) {
31
+ try {
32
+ parseLlmJson(raw);
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ function extractFencedJsonCandidates(value) {
40
+ const candidates = [];
41
+ const fencePattern = /```(?:json)?\s*([\s\S]*?)```/gi;
42
+ for (const match of value.matchAll(fencePattern)) {
43
+ if (typeof match[1] === "string")
44
+ candidates.push(match[1]);
45
+ }
46
+ return candidates;
47
+ }
48
+ function canParseJson(value) {
49
+ try {
50
+ JSON.parse(value.trim());
51
+ return true;
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ function extractFirstBalancedJson(value) {
58
+ for (let start = 0; start < value.length; start++) {
59
+ const first = value[start];
60
+ if (first !== "{" && first !== "[")
61
+ continue;
62
+ const closeForOpen = new Map([
63
+ ["{", "}"],
64
+ ["[", "]"],
65
+ ]);
66
+ const stack = [closeForOpen.get(first)];
67
+ let inString = false;
68
+ let escaped = false;
69
+ for (let index = start + 1; index < value.length; index++) {
70
+ const ch = value[index];
71
+ if (inString) {
72
+ if (escaped) {
73
+ escaped = false;
74
+ }
75
+ else if (ch === "\\") {
76
+ escaped = true;
77
+ }
78
+ else if (ch === "\"") {
79
+ inString = false;
80
+ }
81
+ continue;
82
+ }
83
+ if (ch === "\"") {
84
+ inString = true;
85
+ continue;
86
+ }
87
+ const close = closeForOpen.get(ch);
88
+ if (close) {
89
+ stack.push(close);
90
+ continue;
91
+ }
92
+ if (ch === stack[stack.length - 1]) {
93
+ stack.pop();
94
+ if (stack.length === 0) {
95
+ const candidate = value.slice(start, index + 1).trim();
96
+ if (canParseJson(candidate))
97
+ return candidate;
98
+ break;
99
+ }
100
+ }
101
+ }
102
+ }
103
+ return undefined;
104
+ }
105
+ /**
106
+ * Attempt to repair truncated JSON by closing open braces/brackets and
107
+ * terminating unterminated strings. Common with smaller models that hit
108
+ * token limits mid-JSON output.
109
+ */
110
+ function repairTruncatedJson(value) {
111
+ // Find the start of JSON
112
+ const jsonStart = findJsonStart(value);
113
+ if (jsonStart < 0)
114
+ return undefined;
115
+ let s = value.slice(jsonStart);
116
+ if (s.length < 2)
117
+ return undefined;
118
+ // Track state
119
+ const stack = [];
120
+ let inString = false;
121
+ let escaped = false;
122
+ let lastKeyEnd = -1; // track if we're mid-value (after a colon)
123
+ for (let i = 0; i < s.length; i++) {
124
+ const ch = s[i];
125
+ if (inString) {
126
+ if (escaped) {
127
+ escaped = false;
128
+ }
129
+ else if (ch === "\\") {
130
+ escaped = true;
131
+ }
132
+ else if (ch === "\"") {
133
+ inString = false;
134
+ }
135
+ continue;
136
+ }
137
+ if (ch === "\"") {
138
+ inString = true;
139
+ continue;
140
+ }
141
+ if (ch === "{") {
142
+ stack.push("}");
143
+ continue;
144
+ }
145
+ if (ch === "[") {
146
+ stack.push("]");
147
+ continue;
148
+ }
149
+ if (ch === ":") {
150
+ lastKeyEnd = i;
151
+ continue;
152
+ }
153
+ if ((ch === "}" || ch === "]") && stack.length > 0 && stack[stack.length - 1] === ch) {
154
+ stack.pop();
155
+ }
156
+ }
157
+ // Nothing open — not truncated
158
+ if (!inString && stack.length === 0)
159
+ return undefined;
160
+ // Build repair suffix
161
+ let repair = "";
162
+ // Close unterminated string
163
+ if (inString) {
164
+ // Escape any trailing backslash
165
+ if (escaped)
166
+ repair += "\\";
167
+ repair += '"';
168
+ }
169
+ // If we were mid-value (after colon), add a null placeholder
170
+ if (lastKeyEnd >= 0) {
171
+ // Check if there's anything after the last colon that looks like a value
172
+ const afterColon = s.slice(lastKeyEnd + 1).trim();
173
+ if (!afterColon || afterColon === '"' || afterColon === "null") {
174
+ repair += "null";
175
+ }
176
+ }
177
+ // Close all open structures
178
+ while (stack.length > 0) {
179
+ repair += stack.pop();
180
+ }
181
+ const candidate = s + repair;
182
+ return canParseJson(candidate) ? candidate : undefined;
183
+ }
184
+ /** Find the index of the first { or [ that starts a JSON value, skipping noise. */
185
+ function findJsonStart(value) {
186
+ for (let i = 0; i < value.length; i++) {
187
+ const ch = value[i];
188
+ if (ch === "{" || ch === "[")
189
+ return i;
190
+ }
191
+ return -1;
192
+ }
193
+ //# sourceMappingURL=llm-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-json.js","sourceRoot":"","sources":["../src/llm-json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * [WHO]: filterPII, filterByScope, evictExpiredEntries, evictExpiredWork
3
+ * [FROM]: Depends on ./scoring.js, ./types.js
4
+ * [TO]: Consumed by packages/mem-core/src/index.ts
5
+ * [HERE]: packages/mem-core/src/privacy.ts - scope isolation, TTL enforcement, PII filtering
6
+ */
7
+ import type { MemoryEntry, MemoryScope, WorkEntry } from "./types.js";
8
+ export declare function filterPII(text: string): string;
9
+ export declare function matchesScope(entry: {
10
+ scope?: MemoryScope;
11
+ }, required?: MemoryScope): boolean;
12
+ export declare function filterByScope<T extends {
13
+ scope?: MemoryScope;
14
+ }>(entries: T[], scope?: MemoryScope): T[];
15
+ export declare function evictExpiredEntries(entries: MemoryEntry[]): MemoryEntry[];
16
+ export declare function evictExpiredWork(entries: WorkEntry[]): WorkEntry[];
17
+ //# sourceMappingURL=privacy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAWtE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAM5F;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,KAAK,CAAC,EAAE,WAAW,CAAA;CAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,CAAC,EAAE,CAGvG;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAKzE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAKlE"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * [WHO]: filterPII, filterByScope, evictExpiredEntries, evictExpiredWork
3
+ * [FROM]: Depends on ./scoring.js, ./types.js
4
+ * [TO]: Consumed by packages/mem-core/src/index.ts
5
+ * [HERE]: packages/mem-core/src/privacy.ts - scope isolation, TTL enforcement, PII filtering
6
+ */
7
+ import { daysSince } from "./scoring.js";
8
+ const PII_PATTERNS = [
9
+ /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, // email
10
+ /\b(?:\+?1[-.]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g, // US phone
11
+ /\b1[3-9]\d{9}\b/g, // CN mobile
12
+ /\b\d{3}-\d{2}-\d{4}\b/g, // US SSN
13
+ /\b[1-9]\d{5}(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dXx]\b/g, // CN ID
14
+ /\b(?:4\d{3}|5[1-5]\d{2}|6011|3[47]\d{2})[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g, // credit card
15
+ ];
16
+ export function filterPII(text) {
17
+ let result = text;
18
+ for (const pattern of PII_PATTERNS) {
19
+ result = result.replace(pattern, "[REDACTED]");
20
+ }
21
+ return result;
22
+ }
23
+ export function matchesScope(entry, required) {
24
+ if (!required)
25
+ return true;
26
+ if (!entry.scope)
27
+ return true;
28
+ if (required.userId && entry.scope.userId && entry.scope.userId !== required.userId)
29
+ return false;
30
+ if (required.agentId && entry.scope.agentId && entry.scope.agentId !== required.agentId)
31
+ return false;
32
+ return true;
33
+ }
34
+ export function filterByScope(entries, scope) {
35
+ if (!scope)
36
+ return entries;
37
+ return entries.filter((e) => matchesScope(e, scope));
38
+ }
39
+ export function evictExpiredEntries(entries) {
40
+ return entries.filter((e) => {
41
+ if (e.ttl === undefined)
42
+ return true;
43
+ return daysSince(e.created) < e.ttl;
44
+ });
45
+ }
46
+ export function evictExpiredWork(entries) {
47
+ return entries.filter((w) => {
48
+ if (w.ttl === undefined)
49
+ return true;
50
+ return daysSince(w.created) < w.ttl;
51
+ });
52
+ }
53
+ //# sourceMappingURL=privacy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privacy.js","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,MAAM,YAAY,GAAG;IACpB,sDAAsD,EAAE,QAAQ;IAChE,wDAAwD,EAAE,WAAW;IACrE,kBAAkB,EAAE,YAAY;IAChC,wBAAwB,EAAE,SAAS;IACnC,kFAAkF,EAAE,QAAQ;IAC5F,8EAA8E,EAAE,cAAc;CAC9F,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,IAAY;IACrC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAA8B,EAAE,QAAsB;IAClF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,QAAQ,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAClG,IAAI,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IACtG,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAoC,OAAY,EAAE,KAAmB;IACjG,IAAI,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAsB;IACzD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACpD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;IACrC,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * [WHO]: compileProceduralFromEpisode, extractProceduresFromEpisodes
3
+ * [FROM]: Depends on ./scoring.js, ./types-v2.js
4
+ * [TO]: Consumed by packages/mem-core/src/index.ts
5
+ * [HERE]: packages/mem-core/src/procedural-v2.ts - procedural bridge, turns lived episodes into reusable how-to memory
6
+ */
7
+ import type { EpisodeFacet, EpisodeMemory, ProceduralMemory } from "./types-v2.js";
8
+ export declare function compileProcedureFromEpisode(episode: EpisodeMemory, facets: EpisodeFacet[], now?: string): ProceduralMemory | null;
9
+ //# sourceMappingURL=procedural-v2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedural-v2.d.ts","sourceRoot":"","sources":["../src/procedural-v2.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAkB,MAAM,eAAe,CAAC;AA4BnG,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,YAAY,EAAE,EACtB,GAAG,SAA2B,GAC5B,gBAAgB,GAAG,IAAI,CAqGzB"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * [WHO]: compileProceduralFromEpisode, extractProceduresFromEpisodes
3
+ * [FROM]: Depends on ./scoring.js, ./types-v2.js
4
+ * [TO]: Consumed by packages/mem-core/src/index.ts
5
+ * [HERE]: packages/mem-core/src/procedural-v2.ts - procedural bridge, turns lived episodes into reusable how-to memory
6
+ */
7
+ import { extractTags } from "./scoring.js";
8
+ function normalizeLine(text) {
9
+ return text.replace(/\s+/g, " ").trim();
10
+ }
11
+ function uniqueLines(lines) {
12
+ const seen = new Set();
13
+ const result = [];
14
+ for (const line of lines) {
15
+ const normalized = normalizeLine(line ?? "");
16
+ if (!normalized || seen.has(normalized.toLowerCase()))
17
+ continue;
18
+ seen.add(normalized.toLowerCase());
19
+ result.push(normalized);
20
+ }
21
+ return result;
22
+ }
23
+ function makeProcedureId(episode) {
24
+ return `procedure:${episode.sessionId}`;
25
+ }
26
+ function classifyProcedureStatus(episode, hasErrors) {
27
+ if (hasErrors)
28
+ return "draft";
29
+ if (episode.importance >= 7)
30
+ return "active";
31
+ return "draft";
32
+ }
33
+ export function compileProcedureFromEpisode(episode, facets, now = new Date().toISOString()) {
34
+ const goalFacet = facets.find((facet) => facet.facetType === "goal");
35
+ const insightFacets = facets.filter((facet) => facet.facetType === "insight");
36
+ const errorFacets = facets.filter((facet) => facet.facetType === "error");
37
+ const outcomeFacet = facets.find((facet) => facet.facetType === "outcome");
38
+ const goalText = normalizeLine(goalFacet?.searchText || episode.userGoal || "");
39
+ const insightTexts = uniqueLines(insightFacets.map((facet) => facet.searchText));
40
+ const errorTexts = uniqueLines(errorFacets.map((facet) => facet.searchText));
41
+ const outcomeText = normalizeLine(outcomeFacet?.anchorText || episode.summary);
42
+ const shouldCompile = Boolean(goalText && insightTexts.length > 0) ||
43
+ Boolean(goalText && errorTexts.length > 0) ||
44
+ Boolean(episode.importance >= 8 && outcomeText);
45
+ if (!shouldCompile)
46
+ return null;
47
+ const name = goalText ||
48
+ normalizeLine(outcomeText.split(/[.!?。!?\n]/)[0] || "") ||
49
+ `Procedure from ${episode.sessionId.slice(0, 8)}`;
50
+ const summary = uniqueLines([
51
+ goalText ? `When working on ${goalText}` : undefined,
52
+ insightTexts[0] ? `remember ${insightTexts[0]}` : undefined,
53
+ errorTexts[0] ? `watch for ${errorTexts[0]}` : undefined,
54
+ ]).join("; ");
55
+ const steps = [];
56
+ let stepIndex = 0;
57
+ if (goalText) {
58
+ stepIndex += 1;
59
+ steps.push({
60
+ id: `${makeProcedureId(episode)}:step:${stepIndex}`,
61
+ text: `Start from the concrete goal: ${goalText}`,
62
+ kind: "precondition",
63
+ });
64
+ }
65
+ for (const insight of insightTexts.slice(0, 4)) {
66
+ stepIndex += 1;
67
+ steps.push({
68
+ id: `${makeProcedureId(episode)}:step:${stepIndex}`,
69
+ text: insight,
70
+ kind: "step",
71
+ });
72
+ }
73
+ for (const error of errorTexts.slice(0, 3)) {
74
+ stepIndex += 1;
75
+ steps.push({
76
+ id: `${makeProcedureId(episode)}:step:${stepIndex}`,
77
+ text: `Validate against failure mode: ${error}`,
78
+ kind: "warning",
79
+ });
80
+ }
81
+ if (outcomeText) {
82
+ stepIndex += 1;
83
+ steps.push({
84
+ id: `${makeProcedureId(episode)}:step:${stepIndex}`,
85
+ text: `Use this success signal as the expected outcome: ${outcomeText}`,
86
+ kind: "validation",
87
+ });
88
+ }
89
+ if (steps.length === 0)
90
+ return null;
91
+ const tags = extractTags(`${episode.summary} ${goalText} ${insightTexts.join(" ")} ${errorTexts.join(" ")}`);
92
+ return {
93
+ id: makeProcedureId(episode),
94
+ kind: "procedural",
95
+ name,
96
+ summary: summary || outcomeText || name,
97
+ searchText: goalText || name,
98
+ applicability: goalText || undefined,
99
+ boundaries: errorTexts.length > 0 ? errorTexts.join("; ") : undefined,
100
+ contextText: outcomeText || episode.summary,
101
+ steps,
102
+ status: classifyProcedureStatus(episode, errorTexts.length > 0),
103
+ version: 1,
104
+ sourceFacetIds: facets.map((facet) => facet.id),
105
+ sourceSemanticIds: [],
106
+ supersedesIds: [],
107
+ supersededById: undefined,
108
+ accessCount: 0,
109
+ importance: Math.max(1, Math.min(10, episode.importance)),
110
+ salience: Math.max(1, Math.min(10, episode.salience)),
111
+ confidence: insightTexts.length > 0 ? 0.8 : 0.65,
112
+ retention: episode.importance >= 8 ? "key-event" : "ambient",
113
+ stability: errorTexts.length > 0 ? "situational" : "stable",
114
+ tags,
115
+ sourceEpisodeIds: [episode.id],
116
+ evidence: episode.evidence ?? [],
117
+ scope: episode.scope,
118
+ createdAt: now,
119
+ updatedAt: now,
120
+ structuralAnchor: episode.structuralAnchor,
121
+ };
122
+ }
123
+ //# sourceMappingURL=procedural-v2.js.map