@mnemoai/core 1.1.0 → 1.1.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 (220) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +7 -0
  4. package/dist/cli.js.map +7 -0
  5. package/dist/index.d.ts +128 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/{index.ts → dist/index.js} +526 -1333
  8. package/dist/index.js.map +7 -0
  9. package/dist/src/access-tracker.d.ts +97 -0
  10. package/dist/src/access-tracker.d.ts.map +1 -0
  11. package/dist/src/access-tracker.js +184 -0
  12. package/dist/src/access-tracker.js.map +7 -0
  13. package/dist/src/adapters/chroma.d.ts +31 -0
  14. package/dist/src/adapters/chroma.d.ts.map +1 -0
  15. package/{src/adapters/chroma.ts → dist/src/adapters/chroma.js} +45 -107
  16. package/dist/src/adapters/chroma.js.map +7 -0
  17. package/dist/src/adapters/lancedb.d.ts +29 -0
  18. package/dist/src/adapters/lancedb.d.ts.map +1 -0
  19. package/{src/adapters/lancedb.ts → dist/src/adapters/lancedb.js} +41 -109
  20. package/dist/src/adapters/lancedb.js.map +7 -0
  21. package/dist/src/adapters/pgvector.d.ts +33 -0
  22. package/dist/src/adapters/pgvector.d.ts.map +1 -0
  23. package/{src/adapters/pgvector.ts → dist/src/adapters/pgvector.js} +42 -104
  24. package/dist/src/adapters/pgvector.js.map +7 -0
  25. package/dist/src/adapters/qdrant.d.ts +34 -0
  26. package/dist/src/adapters/qdrant.d.ts.map +1 -0
  27. package/dist/src/adapters/qdrant.js +132 -0
  28. package/dist/src/adapters/qdrant.js.map +7 -0
  29. package/dist/src/adaptive-retrieval.d.ts +14 -0
  30. package/dist/src/adaptive-retrieval.d.ts.map +1 -0
  31. package/dist/src/adaptive-retrieval.js +52 -0
  32. package/dist/src/adaptive-retrieval.js.map +7 -0
  33. package/dist/src/audit-log.d.ts +56 -0
  34. package/dist/src/audit-log.d.ts.map +1 -0
  35. package/dist/src/audit-log.js +139 -0
  36. package/dist/src/audit-log.js.map +7 -0
  37. package/dist/src/chunker.d.ts +45 -0
  38. package/dist/src/chunker.d.ts.map +1 -0
  39. package/dist/src/chunker.js +157 -0
  40. package/dist/src/chunker.js.map +7 -0
  41. package/dist/src/config.d.ts +70 -0
  42. package/dist/src/config.d.ts.map +1 -0
  43. package/dist/src/config.js +142 -0
  44. package/dist/src/config.js.map +7 -0
  45. package/dist/src/decay-engine.d.ts +73 -0
  46. package/dist/src/decay-engine.d.ts.map +1 -0
  47. package/dist/src/decay-engine.js +119 -0
  48. package/dist/src/decay-engine.js.map +7 -0
  49. package/dist/src/embedder.d.ts +94 -0
  50. package/dist/src/embedder.d.ts.map +1 -0
  51. package/{src/embedder.ts → dist/src/embedder.js} +119 -317
  52. package/dist/src/embedder.js.map +7 -0
  53. package/dist/src/extraction-prompts.d.ts +12 -0
  54. package/dist/src/extraction-prompts.d.ts.map +1 -0
  55. package/dist/src/extraction-prompts.js +311 -0
  56. package/dist/src/extraction-prompts.js.map +7 -0
  57. package/dist/src/license.d.ts +29 -0
  58. package/dist/src/license.d.ts.map +1 -0
  59. package/{src/license.ts → dist/src/license.js} +42 -113
  60. package/dist/src/license.js.map +7 -0
  61. package/dist/src/llm-client.d.ts +23 -0
  62. package/dist/src/llm-client.d.ts.map +1 -0
  63. package/{src/llm-client.ts → dist/src/llm-client.js} +22 -55
  64. package/dist/src/llm-client.js.map +7 -0
  65. package/dist/src/logger.d.ts +33 -0
  66. package/dist/src/logger.d.ts.map +1 -0
  67. package/dist/src/logger.js +35 -0
  68. package/dist/src/logger.js.map +7 -0
  69. package/dist/src/mcp-server.d.ts +16 -0
  70. package/dist/src/mcp-server.d.ts.map +1 -0
  71. package/{src/mcp-server.ts → dist/src/mcp-server.js} +81 -181
  72. package/dist/src/mcp-server.js.map +7 -0
  73. package/dist/src/memory-categories.d.ts +40 -0
  74. package/dist/src/memory-categories.d.ts.map +1 -0
  75. package/dist/src/memory-categories.js +33 -0
  76. package/dist/src/memory-categories.js.map +7 -0
  77. package/dist/src/memory-upgrader.d.ts +71 -0
  78. package/dist/src/memory-upgrader.d.ts.map +1 -0
  79. package/dist/src/memory-upgrader.js +238 -0
  80. package/dist/src/memory-upgrader.js.map +7 -0
  81. package/dist/src/migrate.d.ts +47 -0
  82. package/dist/src/migrate.d.ts.map +1 -0
  83. package/{src/migrate.ts → dist/src/migrate.js} +57 -165
  84. package/dist/src/migrate.js.map +7 -0
  85. package/dist/src/mnemo.d.ts +67 -0
  86. package/dist/src/mnemo.d.ts.map +1 -0
  87. package/dist/src/mnemo.js +66 -0
  88. package/dist/src/mnemo.js.map +7 -0
  89. package/dist/src/noise-filter.d.ts +23 -0
  90. package/dist/src/noise-filter.d.ts.map +1 -0
  91. package/dist/src/noise-filter.js +62 -0
  92. package/dist/src/noise-filter.js.map +7 -0
  93. package/dist/src/noise-prototypes.d.ts +40 -0
  94. package/dist/src/noise-prototypes.d.ts.map +1 -0
  95. package/dist/src/noise-prototypes.js +116 -0
  96. package/dist/src/noise-prototypes.js.map +7 -0
  97. package/dist/src/observability.d.ts +16 -0
  98. package/dist/src/observability.d.ts.map +1 -0
  99. package/dist/src/observability.js +53 -0
  100. package/dist/src/observability.js.map +7 -0
  101. package/dist/src/query-tracker.d.ts +27 -0
  102. package/dist/src/query-tracker.d.ts.map +1 -0
  103. package/dist/src/query-tracker.js +32 -0
  104. package/dist/src/query-tracker.js.map +7 -0
  105. package/dist/src/reflection-event-store.d.ts +44 -0
  106. package/dist/src/reflection-event-store.d.ts.map +1 -0
  107. package/dist/src/reflection-event-store.js +50 -0
  108. package/dist/src/reflection-event-store.js.map +7 -0
  109. package/dist/src/reflection-item-store.d.ts +58 -0
  110. package/dist/src/reflection-item-store.d.ts.map +1 -0
  111. package/dist/src/reflection-item-store.js +69 -0
  112. package/dist/src/reflection-item-store.js.map +7 -0
  113. package/dist/src/reflection-mapped-metadata.d.ts +47 -0
  114. package/dist/src/reflection-mapped-metadata.d.ts.map +1 -0
  115. package/dist/src/reflection-mapped-metadata.js +40 -0
  116. package/dist/src/reflection-mapped-metadata.js.map +7 -0
  117. package/dist/src/reflection-metadata.d.ts +11 -0
  118. package/dist/src/reflection-metadata.d.ts.map +1 -0
  119. package/dist/src/reflection-metadata.js +24 -0
  120. package/dist/src/reflection-metadata.js.map +7 -0
  121. package/dist/src/reflection-ranking.d.ts +13 -0
  122. package/dist/src/reflection-ranking.d.ts.map +1 -0
  123. package/{src/reflection-ranking.ts → dist/src/reflection-ranking.js} +12 -21
  124. package/dist/src/reflection-ranking.js.map +7 -0
  125. package/dist/src/reflection-retry.d.ts +30 -0
  126. package/dist/src/reflection-retry.d.ts.map +1 -0
  127. package/{src/reflection-retry.ts → dist/src/reflection-retry.js} +24 -64
  128. package/dist/src/reflection-retry.js.map +7 -0
  129. package/dist/src/reflection-slices.d.ts +42 -0
  130. package/dist/src/reflection-slices.d.ts.map +1 -0
  131. package/{src/reflection-slices.ts → dist/src/reflection-slices.js} +60 -136
  132. package/dist/src/reflection-slices.js.map +7 -0
  133. package/dist/src/reflection-store.d.ts +85 -0
  134. package/dist/src/reflection-store.d.ts.map +1 -0
  135. package/dist/src/reflection-store.js +407 -0
  136. package/dist/src/reflection-store.js.map +7 -0
  137. package/dist/src/resonance-state.d.ts +19 -0
  138. package/dist/src/resonance-state.d.ts.map +1 -0
  139. package/{src/resonance-state.ts → dist/src/resonance-state.js} +13 -42
  140. package/dist/src/resonance-state.js.map +7 -0
  141. package/dist/src/retriever.d.ts +228 -0
  142. package/dist/src/retriever.d.ts.map +1 -0
  143. package/dist/src/retriever.js +1006 -0
  144. package/dist/src/retriever.js.map +7 -0
  145. package/dist/src/scopes.d.ts +58 -0
  146. package/dist/src/scopes.d.ts.map +1 -0
  147. package/dist/src/scopes.js +252 -0
  148. package/dist/src/scopes.js.map +7 -0
  149. package/dist/src/self-improvement-files.d.ts +20 -0
  150. package/dist/src/self-improvement-files.d.ts.map +1 -0
  151. package/{src/self-improvement-files.ts → dist/src/self-improvement-files.js} +24 -49
  152. package/dist/src/self-improvement-files.js.map +7 -0
  153. package/dist/src/semantic-gate.d.ts +24 -0
  154. package/dist/src/semantic-gate.d.ts.map +1 -0
  155. package/dist/src/semantic-gate.js +86 -0
  156. package/dist/src/semantic-gate.js.map +7 -0
  157. package/dist/src/session-recovery.d.ts +9 -0
  158. package/dist/src/session-recovery.d.ts.map +1 -0
  159. package/{src/session-recovery.ts → dist/src/session-recovery.js} +40 -57
  160. package/dist/src/session-recovery.js.map +7 -0
  161. package/dist/src/smart-extractor.d.ts +107 -0
  162. package/dist/src/smart-extractor.d.ts.map +1 -0
  163. package/{src/smart-extractor.ts → dist/src/smart-extractor.js} +130 -383
  164. package/dist/src/smart-extractor.js.map +7 -0
  165. package/dist/src/smart-metadata.d.ts +103 -0
  166. package/dist/src/smart-metadata.d.ts.map +1 -0
  167. package/dist/src/smart-metadata.js +361 -0
  168. package/dist/src/smart-metadata.js.map +7 -0
  169. package/dist/src/storage-adapter.d.ts +102 -0
  170. package/dist/src/storage-adapter.d.ts.map +1 -0
  171. package/dist/src/storage-adapter.js +22 -0
  172. package/dist/src/storage-adapter.js.map +7 -0
  173. package/dist/src/store.d.ts +108 -0
  174. package/dist/src/store.d.ts.map +1 -0
  175. package/dist/src/store.js +939 -0
  176. package/dist/src/store.js.map +7 -0
  177. package/dist/src/tier-manager.d.ts +57 -0
  178. package/dist/src/tier-manager.d.ts.map +1 -0
  179. package/dist/src/tier-manager.js +80 -0
  180. package/dist/src/tier-manager.js.map +7 -0
  181. package/dist/src/tools.d.ts +43 -0
  182. package/dist/src/tools.d.ts.map +1 -0
  183. package/dist/src/tools.js +1075 -0
  184. package/dist/src/tools.js.map +7 -0
  185. package/dist/src/wal-recovery.d.ts +30 -0
  186. package/dist/src/wal-recovery.d.ts.map +1 -0
  187. package/{src/wal-recovery.ts → dist/src/wal-recovery.js} +26 -79
  188. package/dist/src/wal-recovery.js.map +7 -0
  189. package/package.json +21 -2
  190. package/openclaw.plugin.json +0 -815
  191. package/src/access-tracker.ts +0 -341
  192. package/src/adapters/README.md +0 -78
  193. package/src/adapters/qdrant.ts +0 -191
  194. package/src/adaptive-retrieval.ts +0 -90
  195. package/src/audit-log.ts +0 -238
  196. package/src/chunker.ts +0 -254
  197. package/src/config.ts +0 -271
  198. package/src/decay-engine.ts +0 -238
  199. package/src/extraction-prompts.ts +0 -339
  200. package/src/memory-categories.ts +0 -71
  201. package/src/memory-upgrader.ts +0 -388
  202. package/src/mnemo.ts +0 -142
  203. package/src/noise-filter.ts +0 -97
  204. package/src/noise-prototypes.ts +0 -164
  205. package/src/observability.ts +0 -81
  206. package/src/query-tracker.ts +0 -57
  207. package/src/reflection-event-store.ts +0 -98
  208. package/src/reflection-item-store.ts +0 -112
  209. package/src/reflection-mapped-metadata.ts +0 -84
  210. package/src/reflection-metadata.ts +0 -23
  211. package/src/reflection-store.ts +0 -602
  212. package/src/retriever.ts +0 -1510
  213. package/src/scopes.ts +0 -375
  214. package/src/semantic-gate.ts +0 -121
  215. package/src/smart-metadata.ts +0 -561
  216. package/src/storage-adapter.ts +0 -153
  217. package/src/store.ts +0 -1330
  218. package/src/tier-manager.ts +0 -189
  219. package/src/tools.ts +0 -1292
  220. package/test/core.test.mjs +0 -301
@@ -1,30 +1,24 @@
1
- // SPDX-License-Identifier: LicenseRef-Mnemo-Pro
2
1
  import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
3
2
  import { join } from "node:path";
4
-
5
- export const DEFAULT_LEARNINGS_TEMPLATE = `# Learnings
3
+ const DEFAULT_LEARNINGS_TEMPLATE = `# Learnings
6
4
 
7
5
  Append structured entries:
8
6
  - LRN-YYYYMMDD-XXX for corrections / best practices / knowledge gaps
9
7
  - Include summary, details, suggested action, metadata, and status`;
10
-
11
- export const DEFAULT_ERRORS_TEMPLATE = `# Errors
8
+ const DEFAULT_ERRORS_TEMPLATE = `# Errors
12
9
 
13
10
  Append structured entries:
14
11
  - ERR-YYYYMMDD-XXX for command/tool/integration failures
15
12
  - Include symptom, context, probable cause, and prevention`;
16
-
17
- const fileWriteQueues = new Map<string, Promise<void>>();
18
-
19
- async function withFileWriteQueue<T>(filePath: string, action: () => Promise<T>): Promise<T> {
13
+ const fileWriteQueues = /* @__PURE__ */ new Map();
14
+ async function withFileWriteQueue(filePath, action) {
20
15
  const previous = fileWriteQueues.get(filePath) ?? Promise.resolve();
21
- let release: (() => void) | undefined;
22
- const lock = new Promise<void>((resolve) => {
16
+ let release;
17
+ const lock = new Promise((resolve) => {
23
18
  release = resolve;
24
19
  });
25
20
  const next = previous.then(() => lock);
26
21
  fileWriteQueues.set(filePath, next);
27
-
28
22
  await previous;
29
23
  try {
30
24
  return await action();
@@ -35,12 +29,10 @@ async function withFileWriteQueue<T>(filePath: string, action: () => Promise<T>)
35
29
  }
36
30
  }
37
31
  }
38
-
39
- function todayYmd(): string {
40
- return new Date().toISOString().slice(0, 10).replace(/-/g, "");
32
+ function todayYmd() {
33
+ return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10).replace(/-/g, "");
41
34
  }
42
-
43
- async function nextLearningId(filePath: string, prefix: "LRN" | "ERR"): Promise<string> {
35
+ async function nextLearningId(filePath, prefix) {
44
36
  const date = todayYmd();
45
37
  let count = 0;
46
38
  try {
@@ -48,46 +40,25 @@ async function nextLearningId(filePath: string, prefix: "LRN" | "ERR"): Promise<
48
40
  const matches = content.match(new RegExp(`\\[${prefix}-${date}-\\d{3}\\]`, "g"));
49
41
  count = matches?.length ?? 0;
50
42
  } catch {
51
- // ignore
52
43
  }
53
44
  return `${prefix}-${date}-${String(count + 1).padStart(3, "0")}`;
54
45
  }
55
-
56
- export async function ensureSelfImprovementLearningFiles(baseDir: string): Promise<void> {
46
+ async function ensureSelfImprovementLearningFiles(baseDir) {
57
47
  const learningsDir = join(baseDir, ".learnings");
58
48
  await mkdir(learningsDir, { recursive: true });
59
-
60
- const ensureFile = async (filePath: string, content: string) => {
49
+ const ensureFile = async (filePath, content) => {
61
50
  try {
62
51
  const existing = await readFile(filePath, "utf-8");
63
52
  if (existing.trim().length > 0) return;
64
53
  } catch {
65
- // write default below
66
54
  }
67
- await writeFile(filePath, `${content.trim()}\n`, "utf-8");
55
+ await writeFile(filePath, `${content.trim()}
56
+ `, "utf-8");
68
57
  };
69
-
70
58
  await ensureFile(join(learningsDir, "LEARNINGS.md"), DEFAULT_LEARNINGS_TEMPLATE);
71
59
  await ensureFile(join(learningsDir, "ERRORS.md"), DEFAULT_ERRORS_TEMPLATE);
72
60
  }
73
-
74
- export interface AppendSelfImprovementEntryParams {
75
- baseDir: string;
76
- type: "learning" | "error";
77
- summary: string;
78
- details?: string;
79
- suggestedAction?: string;
80
- category?: string;
81
- area?: string;
82
- priority?: string;
83
- status?: string;
84
- source?: string;
85
- }
86
-
87
- export async function appendSelfImprovementEntry(params: AppendSelfImprovementEntryParams): Promise<{
88
- id: string;
89
- filePath: string;
90
- }> {
61
+ async function appendSelfImprovementEntry(params) {
91
62
  const {
92
63
  baseDir,
93
64
  type,
@@ -98,18 +69,16 @@ export async function appendSelfImprovementEntry(params: AppendSelfImprovementEn
98
69
  area = "config",
99
70
  priority = "medium",
100
71
  status = "pending",
101
- source = "mnemo/self_improvement_log",
72
+ source = "mnemo/self_improvement_log"
102
73
  } = params;
103
-
104
74
  await ensureSelfImprovementLearningFiles(baseDir);
105
75
  const learningsDir = join(baseDir, ".learnings");
106
76
  const fileName = type === "learning" ? "LEARNINGS.md" : "ERRORS.md";
107
77
  const filePath = join(learningsDir, fileName);
108
78
  const idPrefix = type === "learning" ? "LRN" : "ERR";
109
-
110
79
  const id = await withFileWriteQueue(filePath, async () => {
111
80
  const entryId = await nextLearningId(filePath, idPrefix);
112
- const nowIso = new Date().toISOString();
81
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
113
82
  const titleSuffix = type === "learning" ? ` ${category}` : "";
114
83
  const entry = [
115
84
  `## [${entryId}]${titleSuffix}`,
@@ -131,13 +100,19 @@ export async function appendSelfImprovementEntry(params: AppendSelfImprovementEn
131
100
  "### Metadata",
132
101
  `- Source: ${source}`,
133
102
  "---",
134
- "",
103
+ ""
135
104
  ].join("\n");
136
105
  const prev = await readFile(filePath, "utf-8").catch(() => "");
137
106
  const separator = prev.trimEnd().length > 0 ? "\n\n" : "";
138
107
  await appendFile(filePath, `${separator}${entry}`, "utf-8");
139
108
  return entryId;
140
109
  });
141
-
142
110
  return { id, filePath };
143
111
  }
112
+ export {
113
+ DEFAULT_ERRORS_TEMPLATE,
114
+ DEFAULT_LEARNINGS_TEMPLATE,
115
+ appendSelfImprovementEntry,
116
+ ensureSelfImprovementLearningFiles
117
+ };
118
+ //# sourceMappingURL=self-improvement-files.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/self-improvement-files.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: LicenseRef-Mnemo-Pro\nimport { appendFile, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport const DEFAULT_LEARNINGS_TEMPLATE = `# Learnings\n\nAppend structured entries:\n- LRN-YYYYMMDD-XXX for corrections / best practices / knowledge gaps\n- Include summary, details, suggested action, metadata, and status`;\n\nexport const DEFAULT_ERRORS_TEMPLATE = `# Errors\n\nAppend structured entries:\n- ERR-YYYYMMDD-XXX for command/tool/integration failures\n- Include symptom, context, probable cause, and prevention`;\n\nconst fileWriteQueues = new Map<string, Promise<void>>();\n\nasync function withFileWriteQueue<T>(filePath: string, action: () => Promise<T>): Promise<T> {\n const previous = fileWriteQueues.get(filePath) ?? Promise.resolve();\n let release: (() => void) | undefined;\n const lock = new Promise<void>((resolve) => {\n release = resolve;\n });\n const next = previous.then(() => lock);\n fileWriteQueues.set(filePath, next);\n\n await previous;\n try {\n return await action();\n } finally {\n release?.();\n if (fileWriteQueues.get(filePath) === next) {\n fileWriteQueues.delete(filePath);\n }\n }\n}\n\nfunction todayYmd(): string {\n return new Date().toISOString().slice(0, 10).replace(/-/g, \"\");\n}\n\nasync function nextLearningId(filePath: string, prefix: \"LRN\" | \"ERR\"): Promise<string> {\n const date = todayYmd();\n let count = 0;\n try {\n const content = await readFile(filePath, \"utf-8\");\n const matches = content.match(new RegExp(`\\\\[${prefix}-${date}-\\\\d{3}\\\\]`, \"g\"));\n count = matches?.length ?? 0;\n } catch {\n // ignore\n }\n return `${prefix}-${date}-${String(count + 1).padStart(3, \"0\")}`;\n}\n\nexport async function ensureSelfImprovementLearningFiles(baseDir: string): Promise<void> {\n const learningsDir = join(baseDir, \".learnings\");\n await mkdir(learningsDir, { recursive: true });\n\n const ensureFile = async (filePath: string, content: string) => {\n try {\n const existing = await readFile(filePath, \"utf-8\");\n if (existing.trim().length > 0) return;\n } catch {\n // write default below\n }\n await writeFile(filePath, `${content.trim()}\\n`, \"utf-8\");\n };\n\n await ensureFile(join(learningsDir, \"LEARNINGS.md\"), DEFAULT_LEARNINGS_TEMPLATE);\n await ensureFile(join(learningsDir, \"ERRORS.md\"), DEFAULT_ERRORS_TEMPLATE);\n}\n\nexport interface AppendSelfImprovementEntryParams {\n baseDir: string;\n type: \"learning\" | \"error\";\n summary: string;\n details?: string;\n suggestedAction?: string;\n category?: string;\n area?: string;\n priority?: string;\n status?: string;\n source?: string;\n}\n\nexport async function appendSelfImprovementEntry(params: AppendSelfImprovementEntryParams): Promise<{\n id: string;\n filePath: string;\n}> {\n const {\n baseDir,\n type,\n summary,\n details = \"\",\n suggestedAction = \"\",\n category = \"best_practice\",\n area = \"config\",\n priority = \"medium\",\n status = \"pending\",\n source = \"mnemo/self_improvement_log\",\n } = params;\n\n await ensureSelfImprovementLearningFiles(baseDir);\n const learningsDir = join(baseDir, \".learnings\");\n const fileName = type === \"learning\" ? \"LEARNINGS.md\" : \"ERRORS.md\";\n const filePath = join(learningsDir, fileName);\n const idPrefix = type === \"learning\" ? \"LRN\" : \"ERR\";\n\n const id = await withFileWriteQueue(filePath, async () => {\n const entryId = await nextLearningId(filePath, idPrefix);\n const nowIso = new Date().toISOString();\n const titleSuffix = type === \"learning\" ? ` ${category}` : \"\";\n const entry = [\n `## [${entryId}]${titleSuffix}`,\n \"\",\n `**Logged**: ${nowIso}`,\n `**Priority**: ${priority}`,\n `**Status**: ${status}`,\n `**Area**: ${area}`,\n \"\",\n \"### Summary\",\n summary.trim(),\n \"\",\n \"### Details\",\n details.trim() || \"-\",\n \"\",\n \"### Suggested Action\",\n suggestedAction.trim() || \"-\",\n \"\",\n \"### Metadata\",\n `- Source: ${source}`,\n \"---\",\n \"\",\n ].join(\"\\n\");\n const prev = await readFile(filePath, \"utf-8\").catch(() => \"\");\n const separator = prev.trimEnd().length > 0 ? \"\\n\\n\" : \"\";\n await appendFile(filePath, `${separator}${entry}`, \"utf-8\");\n return entryId;\n });\n\n return { id, filePath };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Semantic Noise Gate
3
+ *
4
+ * Pre-filters memory candidates by checking their embedding similarity against
5
+ * domain-relevant anchor texts. Fragments that are too far from any anchor are
6
+ * rejected as noise before reaching the dedup or store pipeline.
7
+ */
8
+ import type { Embedder } from "./embedder.js";
9
+ export declare class SemanticGate {
10
+ private readonly embedder;
11
+ private anchorEmbeddings;
12
+ private initPromise;
13
+ private readonly threshold;
14
+ constructor(embedder: Embedder, threshold?: number);
15
+ private ensureInitialized;
16
+ private computeAnchors;
17
+ /**
18
+ * Check whether a memory vector passes the semantic gate.
19
+ * Returns true if the memory is relevant enough to persist.
20
+ */
21
+ shouldPass(vector: number[], text: string): Promise<boolean>;
22
+ private logFiltered;
23
+ }
24
+ //# sourceMappingURL=semantic-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-gate.d.ts","sourceRoot":"","sources":["../../src/semantic-gate.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAuC9C,qBAAa,YAAY;IAMrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAL3B,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGhB,QAAQ,EAAE,QAAQ,EACnC,SAAS,SAAO;YAKJ,iBAAiB;YAWjB,cAAc;IAS5B;;;OAGG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YA2BpD,WAAW;CAS1B"}
@@ -0,0 +1,86 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join, dirname } from "node:path";
4
+ const ANCHOR_TEXTS = [
5
+ "\u6295\u8D44\u51B3\u7B56 \u4F30\u503C\u5206\u6790 \u6301\u4ED3\u7BA1\u7406 \u5C3D\u804C\u8C03\u67E5",
6
+ "\u4E2A\u4EBA\u504F\u597D \u65E5\u5E38\u4E60\u60EF \u4EBA\u9645\u5173\u7CFB \u751F\u6D3B\u65B9\u5F0F",
7
+ "\u6280\u672F\u67B6\u6784 \u7CFB\u7EDF\u8BBE\u8BA1 \u4EE3\u7801\u5B9E\u73B0 \u5DE5\u7A0B\u4F18\u5316"
8
+ ];
9
+ function cosineSimilarity(a, b) {
10
+ if (a.length !== b.length || a.length === 0) return 0;
11
+ let dot = 0;
12
+ let normA = 0;
13
+ let normB = 0;
14
+ for (let i = 0; i < a.length; i++) {
15
+ dot += a[i] * b[i];
16
+ normA += a[i] * a[i];
17
+ normB += b[i] * b[i];
18
+ }
19
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
20
+ return denom === 0 ? 0 : dot / denom;
21
+ }
22
+ const FILTER_LOG_PATH = join(homedir(), ".openclaw", "memory", "store-filtered.log");
23
+ class SemanticGate {
24
+ constructor(embedder, threshold = 0.2) {
25
+ this.embedder = embedder;
26
+ this.threshold = threshold;
27
+ }
28
+ anchorEmbeddings = null;
29
+ initPromise = null;
30
+ threshold;
31
+ async ensureInitialized() {
32
+ if (this.anchorEmbeddings) return;
33
+ if (this.initPromise) return this.initPromise;
34
+ this.initPromise = this.computeAnchors().catch((err) => {
35
+ this.initPromise = null;
36
+ throw err;
37
+ });
38
+ return this.initPromise;
39
+ }
40
+ async computeAnchors() {
41
+ const embeddings = [];
42
+ for (const text of ANCHOR_TEXTS) {
43
+ const vec = await this.embedder.embed(text);
44
+ embeddings.push(vec);
45
+ }
46
+ this.anchorEmbeddings = embeddings;
47
+ }
48
+ /**
49
+ * Check whether a memory vector passes the semantic gate.
50
+ * Returns true if the memory is relevant enough to persist.
51
+ */
52
+ async shouldPass(vector, text) {
53
+ try {
54
+ await this.ensureInitialized();
55
+ } catch {
56
+ return true;
57
+ }
58
+ if (!this.anchorEmbeddings || this.anchorEmbeddings.length === 0) {
59
+ return true;
60
+ }
61
+ let maxSim = 0;
62
+ for (const anchor of this.anchorEmbeddings) {
63
+ const sim = cosineSimilarity(vector, anchor);
64
+ if (sim > maxSim) maxSim = sim;
65
+ }
66
+ if (maxSim < this.threshold) {
67
+ this.logFiltered(text, maxSim).catch(() => {
68
+ });
69
+ return false;
70
+ }
71
+ return true;
72
+ }
73
+ async logFiltered(text, maxSim) {
74
+ try {
75
+ await mkdir(dirname(FILTER_LOG_PATH), { recursive: true });
76
+ const line = `${(/* @__PURE__ */ new Date()).toISOString()} maxSim=${maxSim.toFixed(4)} text=${text.slice(0, 200).replace(/\n/g, " ")}
77
+ `;
78
+ await appendFile(FILTER_LOG_PATH, line, "utf8");
79
+ } catch {
80
+ }
81
+ }
82
+ }
83
+ export {
84
+ SemanticGate
85
+ };
86
+ //# sourceMappingURL=semantic-gate.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/semantic-gate.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\n/**\n * Semantic Noise Gate\n *\n * Pre-filters memory candidates by checking their embedding similarity against\n * domain-relevant anchor texts. Fragments that are too far from any anchor are\n * rejected as noise before reaching the dedup or store pipeline.\n */\n\nimport type { Embedder } from \"./embedder.js\";\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join, dirname } from \"node:path\";\n\n// ============================================================================\n// Anchor Texts\n// ============================================================================\n\nconst ANCHOR_TEXTS = [\n \"\u6295\u8D44\u51B3\u7B56 \u4F30\u503C\u5206\u6790 \u6301\u4ED3\u7BA1\u7406 \u5C3D\u804C\u8C03\u67E5\",\n \"\u4E2A\u4EBA\u504F\u597D \u65E5\u5E38\u4E60\u60EF \u4EBA\u9645\u5173\u7CFB \u751F\u6D3B\u65B9\u5F0F\",\n \"\u6280\u672F\u67B6\u6784 \u7CFB\u7EDF\u8BBE\u8BA1 \u4EE3\u7801\u5B9E\u73B0 \u5DE5\u7A0B\u4F18\u5316\",\n] as const;\n\n// ============================================================================\n// Cosine Similarity\n// ============================================================================\n\nfunction cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length || a.length === 0) return 0;\n let dot = 0;\n let normA = 0;\n let normB = 0;\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n const denom = Math.sqrt(normA) * Math.sqrt(normB);\n return denom === 0 ? 0 : dot / denom;\n}\n\n// ============================================================================\n// Semantic Gate\n// ============================================================================\n\nconst FILTER_LOG_PATH = join(homedir(), \".openclaw\", \"memory\", \"store-filtered.log\");\n\nexport class SemanticGate {\n private anchorEmbeddings: number[][] | null = null;\n private initPromise: Promise<void> | null = null;\n private readonly threshold: number;\n\n constructor(\n private readonly embedder: Embedder,\n threshold = 0.20,\n ) {\n this.threshold = threshold;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.anchorEmbeddings) return;\n if (this.initPromise) return this.initPromise;\n\n this.initPromise = this.computeAnchors().catch((err) => {\n this.initPromise = null;\n throw err;\n });\n return this.initPromise;\n }\n\n private async computeAnchors(): Promise<void> {\n const embeddings: number[][] = [];\n for (const text of ANCHOR_TEXTS) {\n const vec = await this.embedder.embed(text);\n embeddings.push(vec);\n }\n this.anchorEmbeddings = embeddings;\n }\n\n /**\n * Check whether a memory vector passes the semantic gate.\n * Returns true if the memory is relevant enough to persist.\n */\n async shouldPass(vector: number[], text: string): Promise<boolean> {\n try {\n await this.ensureInitialized();\n } catch {\n // If anchor computation fails, pass everything through\n return true;\n }\n\n if (!this.anchorEmbeddings || this.anchorEmbeddings.length === 0) {\n return true;\n }\n\n let maxSim = 0;\n for (const anchor of this.anchorEmbeddings) {\n const sim = cosineSimilarity(vector, anchor);\n if (sim > maxSim) maxSim = sim;\n }\n\n if (maxSim < this.threshold) {\n // Log filtered content\n this.logFiltered(text, maxSim).catch(() => {});\n return false;\n }\n\n return true;\n }\n\n private async logFiltered(text: string, maxSim: number): Promise<void> {\n try {\n await mkdir(dirname(FILTER_LOG_PATH), { recursive: true });\n const line = `${new Date().toISOString()} maxSim=${maxSim.toFixed(4)} text=${text.slice(0, 200).replace(/\\n/g, \" \")}\\n`;\n await appendFile(FILTER_LOG_PATH, line, \"utf8\");\n } catch {\n // Non-critical\n }\n }\n}\n"],
5
+ "mappings": "AAUA,SAAS,YAAY,aAAa;AAClC,SAAS,eAAe;AACxB,SAAS,MAAM,eAAe;AAM9B,MAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF;AAMA,SAAS,iBAAiB,GAAa,GAAqB;AAC1D,MAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAG,QAAO;AACpD,MAAI,MAAM;AACV,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,WAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AACjB,aAAS,EAAE,CAAC,IAAI,EAAE,CAAC;AACnB,aAAS,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACrB;AACA,QAAM,QAAQ,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK;AAChD,SAAO,UAAU,IAAI,IAAI,MAAM;AACjC;AAMA,MAAM,kBAAkB,KAAK,QAAQ,GAAG,aAAa,UAAU,oBAAoB;AAE5E,MAAM,aAAa;AAAA,EAKxB,YACmB,UACjB,YAAY,KACZ;AAFiB;AAGjB,SAAK,YAAY;AAAA,EACnB;AAAA,EATQ,mBAAsC;AAAA,EACtC,cAAoC;AAAA,EAC3B;AAAA,EASjB,MAAc,oBAAmC;AAC/C,QAAI,KAAK,iBAAkB;AAC3B,QAAI,KAAK,YAAa,QAAO,KAAK;AAElC,SAAK,cAAc,KAAK,eAAe,EAAE,MAAM,CAAC,QAAQ;AACtD,WAAK,cAAc;AACnB,YAAM;AAAA,IACR,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,iBAAgC;AAC5C,UAAM,aAAyB,CAAC;AAChC,eAAW,QAAQ,cAAc;AAC/B,YAAM,MAAM,MAAM,KAAK,SAAS,MAAM,IAAI;AAC1C,iBAAW,KAAK,GAAG;AAAA,IACrB;AACA,SAAK,mBAAmB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,QAAkB,MAAgC;AACjE,QAAI;AACF,YAAM,KAAK,kBAAkB;AAAA,IAC/B,QAAQ;AAEN,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,KAAK,oBAAoB,KAAK,iBAAiB,WAAW,GAAG;AAChE,aAAO;AAAA,IACT;AAEA,QAAI,SAAS;AACb,eAAW,UAAU,KAAK,kBAAkB;AAC1C,YAAM,MAAM,iBAAiB,QAAQ,MAAM;AAC3C,UAAI,MAAM,OAAQ,UAAS;AAAA,IAC7B;AAEA,QAAI,SAAS,KAAK,WAAW;AAE3B,WAAK,YAAY,MAAM,MAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAC7C,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,YAAY,MAAc,QAA+B;AACrE,QAAI;AACF,YAAM,MAAM,QAAQ,eAAe,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,YAAM,OAAO,IAAG,oBAAI,KAAK,GAAE,YAAY,CAAC,WAAW,OAAO,QAAQ,CAAC,CAAC,SAAS,KAAK,MAAM,GAAG,GAAG,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA;AACnH,YAAM,WAAW,iBAAiB,MAAM,MAAM;AAAA,IAChD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,9 @@
1
+ export declare function stripResetSuffix(fileName: string): string;
2
+ export declare function resolveReflectionSessionSearchDirs(params: {
3
+ context: Record<string, unknown>;
4
+ cfg: unknown;
5
+ workspaceDir: string;
6
+ currentSessionFile?: string;
7
+ sourceAgentId?: string;
8
+ }): string[];
9
+ //# sourceMappingURL=session-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-recovery.d.ts","sourceRoot":"","sources":["../../src/session-recovery.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzD;AAuCD,wBAAgB,kCAAkC,CAAC,MAAM,EAAE;IACzD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,GAAG,EAAE,OAAO,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,MAAM,EAAE,CAgFX"}
@@ -1,46 +1,39 @@
1
- // SPDX-License-Identifier: LicenseRef-Mnemo-Pro
2
1
  import { dirname, join } from "node:path";
3
-
4
- function asNonEmptyString(value: unknown): string | undefined {
5
- if (typeof value !== "string") return undefined;
2
+ function asNonEmptyString(value) {
3
+ if (typeof value !== "string") return void 0;
6
4
  const trimmed = value.trim();
7
- return trimmed.length ? trimmed : undefined;
5
+ return trimmed.length ? trimmed : void 0;
8
6
  }
9
-
10
- export function stripResetSuffix(fileName: string): string {
7
+ function stripResetSuffix(fileName) {
11
8
  const resetIndex = fileName.indexOf(".reset.");
12
9
  return resetIndex === -1 ? fileName : fileName.slice(0, resetIndex);
13
10
  }
14
-
15
- function deriveOpenClawHomeFromWorkspacePath(workspacePath: string): string | undefined {
11
+ function deriveOpenClawHomeFromWorkspacePath(workspacePath) {
16
12
  const normalized = workspacePath.trim().replace(/[\\/]+$/, "");
17
- if (!normalized) return undefined;
13
+ if (!normalized) return void 0;
18
14
  const matched = normalized.match(/^(.*?)[\\/]workspace(?:[\\/].*)?$/);
19
- if (!matched || !matched[1]) return undefined;
15
+ if (!matched || !matched[1]) return void 0;
20
16
  const home = matched[1].trim();
21
- return home.length ? home : undefined;
17
+ return home.length ? home : void 0;
22
18
  }
23
-
24
- function deriveOpenClawHomeFromSessionFilePath(sessionFilePath: string): string | undefined {
19
+ function deriveOpenClawHomeFromSessionFilePath(sessionFilePath) {
25
20
  const normalized = sessionFilePath.trim();
26
- if (!normalized) return undefined;
21
+ if (!normalized) return void 0;
27
22
  const matched = normalized.match(/^(.*?)[\\/]agents[\\/][^\\/]+[\\/]sessions(?:[\\/][^\\/]+)?$/);
28
- if (!matched || !matched[1]) return undefined;
23
+ if (!matched || !matched[1]) return void 0;
29
24
  const home = matched[1].trim();
30
- return home.length ? home : undefined;
25
+ return home.length ? home : void 0;
31
26
  }
32
-
33
- function listConfiguredAgentIds(cfg: unknown): string[] {
27
+ function listConfiguredAgentIds(cfg) {
34
28
  try {
35
- const root = cfg as Record<string, unknown>;
36
- const agents = root.agents as Record<string, unknown> | undefined;
37
- const list = agents?.list as unknown;
29
+ const root = cfg;
30
+ const agents = root.agents;
31
+ const list = agents?.list;
38
32
  if (!Array.isArray(list)) return [];
39
-
40
- const ids: string[] = [];
33
+ const ids = [];
41
34
  for (const item of list) {
42
35
  if (!item || typeof item !== "object") continue;
43
- const id = asNonEmptyString((item as Record<string, unknown>).id);
36
+ const id = asNonEmptyString(item.id);
44
37
  if (id) ids.push(id);
45
38
  }
46
39
  return ids;
@@ -48,37 +41,28 @@ function listConfiguredAgentIds(cfg: unknown): string[] {
48
41
  return [];
49
42
  }
50
43
  }
51
-
52
- export function resolveReflectionSessionSearchDirs(params: {
53
- context: Record<string, unknown>;
54
- cfg: unknown;
55
- workspaceDir: string;
56
- currentSessionFile?: string;
57
- sourceAgentId?: string;
58
- }): string[] {
59
- const out: string[] = [];
60
- const seen = new Set<string>();
61
- const addDir = (value: string | undefined) => {
44
+ function resolveReflectionSessionSearchDirs(params) {
45
+ const out = [];
46
+ const seen = /* @__PURE__ */ new Set();
47
+ const addDir = (value) => {
62
48
  const dir = asNonEmptyString(value);
63
49
  if (!dir || seen.has(dir)) return;
64
50
  seen.add(dir);
65
51
  out.push(dir);
66
52
  };
67
- const addHome = (homes: string[], value: string | undefined) => {
53
+ const addHome = (homes, value) => {
68
54
  const home = asNonEmptyString(value);
69
55
  if (!home || homes.includes(home)) return;
70
56
  homes.push(home);
71
57
  };
72
- const addAgentId = (agentIds: string[], value: string | undefined) => {
58
+ const addAgentId = (agentIds2, value) => {
73
59
  const agentId = asNonEmptyString(value);
74
- if (!agentId || agentId.includes("/") || agentId.includes("\\") || agentIds.includes(agentId)) return;
75
- agentIds.push(agentId);
60
+ if (!agentId || agentId.includes("/") || agentId.includes("\\") || agentIds2.includes(agentId)) return;
61
+ agentIds2.push(agentId);
76
62
  };
77
-
78
- const previousSessionEntry = (params.context.previousSessionEntry || {}) as Record<string, unknown>;
79
- const sessionEntry = (params.context.sessionEntry || {}) as Record<string, unknown>;
63
+ const previousSessionEntry = params.context.previousSessionEntry || {};
64
+ const sessionEntry = params.context.sessionEntry || {};
80
65
  const sessionEntries = [previousSessionEntry, sessionEntry];
81
-
82
66
  if (params.currentSessionFile) addDir(dirname(params.currentSessionFile));
83
67
  for (const entry of sessionEntries) {
84
68
  const file = asNonEmptyString(entry.sessionFile);
@@ -87,8 +71,7 @@ export function resolveReflectionSessionSearchDirs(params: {
87
71
  addDir(asNonEmptyString(entry.sessionDir));
88
72
  }
89
73
  addDir(join(params.workspaceDir, "sessions"));
90
-
91
- const openclawHomes: string[] = [];
74
+ const openclawHomes = [];
92
75
  addHome(openclawHomes, asNonEmptyString(process.env.OPENCLAW_HOME));
93
76
  addHome(openclawHomes, deriveOpenClawHomeFromWorkspacePath(params.workspaceDir));
94
77
  if (params.currentSessionFile) {
@@ -99,25 +82,22 @@ export function resolveReflectionSessionSearchDirs(params: {
99
82
  if (entryFile) addHome(openclawHomes, deriveOpenClawHomeFromSessionFilePath(entryFile));
100
83
  }
101
84
  try {
102
- const root = params.cfg as Record<string, unknown>;
103
- const agents = root.agents as Record<string, unknown> | undefined;
104
- const defaults = agents?.defaults as Record<string, unknown> | undefined;
85
+ const root = params.cfg;
86
+ const agents = root.agents;
87
+ const defaults = agents?.defaults;
105
88
  const defaultWorkspace = asNonEmptyString(defaults?.workspace);
106
89
  if (defaultWorkspace) addHome(openclawHomes, deriveOpenClawHomeFromWorkspacePath(defaultWorkspace));
107
-
108
- const list = agents?.list as unknown;
90
+ const list = agents?.list;
109
91
  if (Array.isArray(list)) {
110
92
  for (const item of list) {
111
93
  if (!item || typeof item !== "object") continue;
112
- const workspace = asNonEmptyString((item as Record<string, unknown>).workspace);
94
+ const workspace = asNonEmptyString(item.workspace);
113
95
  if (workspace) addHome(openclawHomes, deriveOpenClawHomeFromWorkspacePath(workspace));
114
96
  }
115
97
  }
116
98
  } catch {
117
- // ignore
118
99
  }
119
-
120
- const agentIds: string[] = [];
100
+ const agentIds = [];
121
101
  addAgentId(agentIds, params.sourceAgentId);
122
102
  addAgentId(agentIds, asNonEmptyString(params.context.agentId));
123
103
  for (const entry of sessionEntries) {
@@ -127,12 +107,15 @@ export function resolveReflectionSessionSearchDirs(params: {
127
107
  addAgentId(agentIds, configuredId);
128
108
  }
129
109
  addAgentId(agentIds, "main");
130
-
131
110
  for (const home of openclawHomes) {
132
111
  for (const agentId of agentIds) {
133
112
  addDir(join(home, "agents", agentId, "sessions"));
134
113
  }
135
114
  }
136
-
137
115
  return out;
138
116
  }
117
+ export {
118
+ resolveReflectionSessionSearchDirs,
119
+ stripResetSuffix
120
+ };
121
+ //# sourceMappingURL=session-recovery.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/session-recovery.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: LicenseRef-Mnemo-Pro\nimport { dirname, join } from \"node:path\";\n\nfunction asNonEmptyString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length ? trimmed : undefined;\n}\n\nexport function stripResetSuffix(fileName: string): string {\n const resetIndex = fileName.indexOf(\".reset.\");\n return resetIndex === -1 ? fileName : fileName.slice(0, resetIndex);\n}\n\nfunction deriveOpenClawHomeFromWorkspacePath(workspacePath: string): string | undefined {\n const normalized = workspacePath.trim().replace(/[\\\\/]+$/, \"\");\n if (!normalized) return undefined;\n const matched = normalized.match(/^(.*?)[\\\\/]workspace(?:[\\\\/].*)?$/);\n if (!matched || !matched[1]) return undefined;\n const home = matched[1].trim();\n return home.length ? home : undefined;\n}\n\nfunction deriveOpenClawHomeFromSessionFilePath(sessionFilePath: string): string | undefined {\n const normalized = sessionFilePath.trim();\n if (!normalized) return undefined;\n const matched = normalized.match(/^(.*?)[\\\\/]agents[\\\\/][^\\\\/]+[\\\\/]sessions(?:[\\\\/][^\\\\/]+)?$/);\n if (!matched || !matched[1]) return undefined;\n const home = matched[1].trim();\n return home.length ? home : undefined;\n}\n\nfunction listConfiguredAgentIds(cfg: unknown): string[] {\n try {\n const root = cfg as Record<string, unknown>;\n const agents = root.agents as Record<string, unknown> | undefined;\n const list = agents?.list as unknown;\n if (!Array.isArray(list)) return [];\n\n const ids: string[] = [];\n for (const item of list) {\n if (!item || typeof item !== \"object\") continue;\n const id = asNonEmptyString((item as Record<string, unknown>).id);\n if (id) ids.push(id);\n }\n return ids;\n } catch {\n return [];\n }\n}\n\nexport function resolveReflectionSessionSearchDirs(params: {\n context: Record<string, unknown>;\n cfg: unknown;\n workspaceDir: string;\n currentSessionFile?: string;\n sourceAgentId?: string;\n}): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n const addDir = (value: string | undefined) => {\n const dir = asNonEmptyString(value);\n if (!dir || seen.has(dir)) return;\n seen.add(dir);\n out.push(dir);\n };\n const addHome = (homes: string[], value: string | undefined) => {\n const home = asNonEmptyString(value);\n if (!home || homes.includes(home)) return;\n homes.push(home);\n };\n const addAgentId = (agentIds: string[], value: string | undefined) => {\n const agentId = asNonEmptyString(value);\n if (!agentId || agentId.includes(\"/\") || agentId.includes(\"\\\\\") || agentIds.includes(agentId)) return;\n agentIds.push(agentId);\n };\n\n const previousSessionEntry = (params.context.previousSessionEntry || {}) as Record<string, unknown>;\n const sessionEntry = (params.context.sessionEntry || {}) as Record<string, unknown>;\n const sessionEntries = [previousSessionEntry, sessionEntry];\n\n if (params.currentSessionFile) addDir(dirname(params.currentSessionFile));\n for (const entry of sessionEntries) {\n const file = asNonEmptyString(entry.sessionFile);\n if (file) addDir(dirname(file));\n addDir(asNonEmptyString(entry.sessionsDir));\n addDir(asNonEmptyString(entry.sessionDir));\n }\n addDir(join(params.workspaceDir, \"sessions\"));\n\n const openclawHomes: string[] = [];\n addHome(openclawHomes, asNonEmptyString(process.env.OPENCLAW_HOME));\n addHome(openclawHomes, deriveOpenClawHomeFromWorkspacePath(params.workspaceDir));\n if (params.currentSessionFile) {\n addHome(openclawHomes, deriveOpenClawHomeFromSessionFilePath(params.currentSessionFile));\n }\n for (const entry of sessionEntries) {\n const entryFile = asNonEmptyString(entry.sessionFile);\n if (entryFile) addHome(openclawHomes, deriveOpenClawHomeFromSessionFilePath(entryFile));\n }\n try {\n const root = params.cfg as Record<string, unknown>;\n const agents = root.agents as Record<string, unknown> | undefined;\n const defaults = agents?.defaults as Record<string, unknown> | undefined;\n const defaultWorkspace = asNonEmptyString(defaults?.workspace);\n if (defaultWorkspace) addHome(openclawHomes, deriveOpenClawHomeFromWorkspacePath(defaultWorkspace));\n\n const list = agents?.list as unknown;\n if (Array.isArray(list)) {\n for (const item of list) {\n if (!item || typeof item !== \"object\") continue;\n const workspace = asNonEmptyString((item as Record<string, unknown>).workspace);\n if (workspace) addHome(openclawHomes, deriveOpenClawHomeFromWorkspacePath(workspace));\n }\n }\n } catch {\n // ignore\n }\n\n const agentIds: string[] = [];\n addAgentId(agentIds, params.sourceAgentId);\n addAgentId(agentIds, asNonEmptyString(params.context.agentId));\n for (const entry of sessionEntries) {\n addAgentId(agentIds, asNonEmptyString(entry.agentId));\n }\n for (const configuredId of listConfiguredAgentIds(params.cfg)) {\n addAgentId(agentIds, configuredId);\n }\n addAgentId(agentIds, \"main\");\n\n for (const home of openclawHomes) {\n for (const agentId of agentIds) {\n addDir(join(home, \"agents\", agentId, \"sessions\"));\n }\n }\n\n return out;\n}\n"],
5
+ "mappings": "AACA,SAAS,SAAS,YAAY;AAE9B,SAAS,iBAAiB,OAAoC;AAC5D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,UAAU;AACpC;AAEO,SAAS,iBAAiB,UAA0B;AACzD,QAAM,aAAa,SAAS,QAAQ,SAAS;AAC7C,SAAO,eAAe,KAAK,WAAW,SAAS,MAAM,GAAG,UAAU;AACpE;AAEA,SAAS,oCAAoC,eAA2C;AACtF,QAAM,aAAa,cAAc,KAAK,EAAE,QAAQ,WAAW,EAAE;AAC7D,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,UAAU,WAAW,MAAM,mCAAmC;AACpE,MAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAG,QAAO;AACpC,QAAM,OAAO,QAAQ,CAAC,EAAE,KAAK;AAC7B,SAAO,KAAK,SAAS,OAAO;AAC9B;AAEA,SAAS,sCAAsC,iBAA6C;AAC1F,QAAM,aAAa,gBAAgB,KAAK;AACxC,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,UAAU,WAAW,MAAM,8DAA8D;AAC/F,MAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAG,QAAO;AACpC,QAAM,OAAO,QAAQ,CAAC,EAAE,KAAK;AAC7B,SAAO,KAAK,SAAS,OAAO;AAC9B;AAEA,SAAS,uBAAuB,KAAwB;AACtD,MAAI;AACF,UAAM,OAAO;AACb,UAAM,SAAS,KAAK;AACpB,UAAM,OAAO,QAAQ;AACrB,QAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,QAAO,CAAC;AAElC,UAAM,MAAgB,CAAC;AACvB,eAAW,QAAQ,MAAM;AACvB,UAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,YAAM,KAAK,iBAAkB,KAAiC,EAAE;AAChE,UAAI,GAAI,KAAI,KAAK,EAAE;AAAA,IACrB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,mCAAmC,QAMtC;AACX,QAAM,MAAgB,CAAC;AACvB,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAS,CAAC,UAA8B;AAC5C,UAAM,MAAM,iBAAiB,KAAK;AAClC,QAAI,CAAC,OAAO,KAAK,IAAI,GAAG,EAAG;AAC3B,SAAK,IAAI,GAAG;AACZ,QAAI,KAAK,GAAG;AAAA,EACd;AACA,QAAM,UAAU,CAAC,OAAiB,UAA8B;AAC9D,UAAM,OAAO,iBAAiB,KAAK;AACnC,QAAI,CAAC,QAAQ,MAAM,SAAS,IAAI,EAAG;AACnC,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,QAAM,aAAa,CAACA,WAAoB,UAA8B;AACpE,UAAM,UAAU,iBAAiB,KAAK;AACtC,QAAI,CAAC,WAAW,QAAQ,SAAS,GAAG,KAAK,QAAQ,SAAS,IAAI,KAAKA,UAAS,SAAS,OAAO,EAAG;AAC/F,IAAAA,UAAS,KAAK,OAAO;AAAA,EACvB;AAEA,QAAM,uBAAwB,OAAO,QAAQ,wBAAwB,CAAC;AACtE,QAAM,eAAgB,OAAO,QAAQ,gBAAgB,CAAC;AACtD,QAAM,iBAAiB,CAAC,sBAAsB,YAAY;AAE1D,MAAI,OAAO,mBAAoB,QAAO,QAAQ,OAAO,kBAAkB,CAAC;AACxE,aAAW,SAAS,gBAAgB;AAClC,UAAM,OAAO,iBAAiB,MAAM,WAAW;AAC/C,QAAI,KAAM,QAAO,QAAQ,IAAI,CAAC;AAC9B,WAAO,iBAAiB,MAAM,WAAW,CAAC;AAC1C,WAAO,iBAAiB,MAAM,UAAU,CAAC;AAAA,EAC3C;AACA,SAAO,KAAK,OAAO,cAAc,UAAU,CAAC;AAE5C,QAAM,gBAA0B,CAAC;AACjC,UAAQ,eAAe,iBAAiB,QAAQ,IAAI,aAAa,CAAC;AAClE,UAAQ,eAAe,oCAAoC,OAAO,YAAY,CAAC;AAC/E,MAAI,OAAO,oBAAoB;AAC7B,YAAQ,eAAe,sCAAsC,OAAO,kBAAkB,CAAC;AAAA,EACzF;AACA,aAAW,SAAS,gBAAgB;AAClC,UAAM,YAAY,iBAAiB,MAAM,WAAW;AACpD,QAAI,UAAW,SAAQ,eAAe,sCAAsC,SAAS,CAAC;AAAA,EACxF;AACA,MAAI;AACF,UAAM,OAAO,OAAO;AACpB,UAAM,SAAS,KAAK;AACpB,UAAM,WAAW,QAAQ;AACzB,UAAM,mBAAmB,iBAAiB,UAAU,SAAS;AAC7D,QAAI,iBAAkB,SAAQ,eAAe,oCAAoC,gBAAgB,CAAC;AAElG,UAAM,OAAO,QAAQ;AACrB,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,iBAAW,QAAQ,MAAM;AACvB,YAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,cAAM,YAAY,iBAAkB,KAAiC,SAAS;AAC9E,YAAI,UAAW,SAAQ,eAAe,oCAAoC,SAAS,CAAC;AAAA,MACtF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,QAAM,WAAqB,CAAC;AAC5B,aAAW,UAAU,OAAO,aAAa;AACzC,aAAW,UAAU,iBAAiB,OAAO,QAAQ,OAAO,CAAC;AAC7D,aAAW,SAAS,gBAAgB;AAClC,eAAW,UAAU,iBAAiB,MAAM,OAAO,CAAC;AAAA,EACtD;AACA,aAAW,gBAAgB,uBAAuB,OAAO,GAAG,GAAG;AAC7D,eAAW,UAAU,YAAY;AAAA,EACnC;AACA,aAAW,UAAU,MAAM;AAE3B,aAAW,QAAQ,eAAe;AAChC,eAAW,WAAW,UAAU;AAC9B,aAAO,KAAK,MAAM,UAAU,SAAS,UAAU,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,SAAO;AACT;",
6
+ "names": ["agentIds"]
7
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Smart Memory Extractor — LLM-powered extraction pipeline
3
+ * Replaces regex-triggered capture with intelligent 6-category extraction.
4
+ *
5
+ * Pipeline: conversation → LLM extract → candidates → dedup → persist
6
+ *
7
+ */
8
+ import type { MemoryStore } from "./store.js";
9
+ import type { Embedder } from "./embedder.js";
10
+ import type { LlmClient } from "./llm-client.js";
11
+ import { type ExtractionStats } from "./memory-categories.js";
12
+ import type { NoisePrototypeBank } from "./noise-prototypes.js";
13
+ export interface SmartExtractorConfig {
14
+ /** User identifier for extraction prompt. */
15
+ user?: string;
16
+ /** Minimum conversation messages before extraction triggers. */
17
+ extractMinMessages?: number;
18
+ /** Maximum characters of conversation text to process. */
19
+ extractMaxChars?: number;
20
+ /** Default scope for new memories. */
21
+ defaultScope?: string;
22
+ /** Logger function. */
23
+ log?: (msg: string) => void;
24
+ /** Debug logger function. */
25
+ debugLog?: (msg: string) => void;
26
+ /** Optional embedding-based noise prototype bank for language-agnostic noise filtering. */
27
+ noiseBank?: NoisePrototypeBank;
28
+ }
29
+ export interface ExtractPersistOptions {
30
+ /** Target scope for newly created memories. */
31
+ scope?: string;
32
+ /** Scopes visible to the current agent for dedup/merge. */
33
+ scopeFilter?: string[];
34
+ }
35
+ export declare class SmartExtractor {
36
+ private store;
37
+ private embedder;
38
+ private llm;
39
+ private config;
40
+ private log;
41
+ private debugLog;
42
+ constructor(store: MemoryStore, embedder: Embedder, llm: LlmClient, config?: SmartExtractorConfig);
43
+ /**
44
+ * Extract memories from a conversation text and persist them.
45
+ * Returns extraction statistics.
46
+ */
47
+ extractAndPersist(conversationText: string, sessionKey?: string, options?: ExtractPersistOptions): Promise<ExtractionStats>;
48
+ /**
49
+ * Filter out texts that match noise prototypes by embedding similarity.
50
+ * Long texts (>300 chars) are passed through without checking.
51
+ * Only active when noiseBank is configured and initialized.
52
+ */
53
+ filterNoiseByEmbedding(texts: string[]): Promise<string[]>;
54
+ /**
55
+ * Feed back conversation text to the noise prototype bank.
56
+ * Called when LLM extraction returns zero candidates (strongest noise signal).
57
+ */
58
+ private learnAsNoise;
59
+ /**
60
+ * Call LLM to extract candidate memories from conversation text.
61
+ */
62
+ private extractCandidates;
63
+ /**
64
+ * Process a single candidate memory: dedup → merge/create → store
65
+ */
66
+ private processCandidate;
67
+ /**
68
+ * Two-stage dedup: vector similarity search → LLM decision.
69
+ */
70
+ private deduplicate;
71
+ private llmDedupDecision;
72
+ /**
73
+ * Profile always-merge: read existing profile, merge with LLM, upsert.
74
+ */
75
+ private handleProfileMerge;
76
+ /**
77
+ * Merge a candidate into an existing memory using LLM.
78
+ */
79
+ private handleMerge;
80
+ /**
81
+ * Handle SUPPORT: update support stats on existing memory for a specific context.
82
+ */
83
+ private handleSupport;
84
+ /**
85
+ * Handle CONTEXTUALIZE: create a new entry that adds situational nuance,
86
+ * linked to the original via a relation in metadata.
87
+ */
88
+ private handleContextualize;
89
+ /**
90
+ * Handle CONTRADICT: create contradicting entry + record contradiction evidence
91
+ * on the original memory's support stats.
92
+ */
93
+ private handleContradict;
94
+ /**
95
+ * Store a candidate memory as a new entry with L0/L1/L2 metadata.
96
+ */
97
+ private storeCandidate;
98
+ /**
99
+ * Map 6-category to existing 5-category store type for backward compatibility.
100
+ */
101
+ private mapToStoreCategory;
102
+ /**
103
+ * Get default importance score by category.
104
+ */
105
+ private getDefaultImportance;
106
+ }
107
+ //# sourceMappingURL=smart-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-extractor.d.ts","sourceRoot":"","sources":["../../src/smart-extractor.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,YAAY,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAOjD,OAAO,EAIL,KAAK,eAAe,EAMrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAmChE,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,2FAA2F;IAC3F,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,cAAc;IAKvB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;IAPhB,OAAO,CAAC,GAAG,CAAwB;IACnC,OAAO,CAAC,QAAQ,CAAwB;gBAG9B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,SAAS,EACd,MAAM,GAAE,oBAAyB;IAU3C;;;OAGG;IACG,iBAAiB,CACrB,gBAAgB,EAAE,MAAM,EACxB,UAAU,GAAE,MAAkB,EAC9B,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,eAAe,CAAC;IA8C3B;;;;OAIG;IACG,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiChE;;;OAGG;YACW,YAAY;IAoB1B;;OAEG;YACW,iBAAiB;IAyF/B;;OAEG;YACW,gBAAgB;IAqG9B;;OAEG;YACW,WAAW;YAqBX,gBAAgB;IA0E9B;;OAEG;YACW,kBAAkB;IAuChC;;OAEG;YACW,WAAW;IA4GzB;;OAEG;YACW,aAAa;IA0B3B;;;OAGG;YACW,mBAAmB;IAsCjC;;;OAGG;YACW,gBAAgB;IAyF9B;;OAEG;YACW,cAAc;IA0C5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAkB7B"}