@mnemoai/core 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +136 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/{index.ts → dist/index.js} +537 -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
@@ -0,0 +1,407 @@
1
+ import {
2
+ extractReflectionSliceItems,
3
+ extractReflectionSlices,
4
+ sanitizeReflectionSliceLines
5
+ } from "./reflection-slices.js";
6
+ import { parseReflectionMetadata } from "./reflection-metadata.js";
7
+ import { buildReflectionEventPayload, createReflectionEventId } from "./reflection-event-store.js";
8
+ import {
9
+ buildReflectionItemPayloads,
10
+ getReflectionItemDecayDefaults,
11
+ REFLECTION_DERIVED_DECAY_K,
12
+ REFLECTION_DERIVED_DECAY_MIDPOINT_DAYS,
13
+ REFLECTION_INVARIANT_DECAY_K,
14
+ REFLECTION_INVARIANT_DECAY_MIDPOINT_DAYS
15
+ } from "./reflection-item-store.js";
16
+ import { getReflectionMappedDecayDefaults } from "./reflection-mapped-metadata.js";
17
+ import { computeReflectionScore, normalizeReflectionLineForAggregation } from "./reflection-ranking.js";
18
+ const REFLECTION_DERIVE_LOGISTIC_MIDPOINT_DAYS = 3;
19
+ const REFLECTION_DERIVE_LOGISTIC_K = 1.2;
20
+ const REFLECTION_DERIVE_FALLBACK_BASE_WEIGHT = 0.35;
21
+ const DEFAULT_REFLECTION_DERIVED_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1e3;
22
+ const DEFAULT_REFLECTION_MAPPED_MAX_AGE_MS = 60 * 24 * 60 * 60 * 1e3;
23
+ function buildReflectionStorePayloads(params) {
24
+ const slices = extractReflectionSlices(params.reflectionText);
25
+ const eventId = params.eventId || createReflectionEventId({
26
+ runAt: params.runAt,
27
+ sessionKey: params.sessionKey,
28
+ sessionId: params.sessionId,
29
+ agentId: params.agentId,
30
+ command: params.command
31
+ });
32
+ const payloads = [
33
+ buildReflectionEventPayload({
34
+ eventId,
35
+ scope: params.scope,
36
+ sessionKey: params.sessionKey,
37
+ sessionId: params.sessionId,
38
+ agentId: params.agentId,
39
+ command: params.command,
40
+ toolErrorSignals: params.toolErrorSignals,
41
+ runAt: params.runAt,
42
+ usedFallback: params.usedFallback,
43
+ sourceReflectionPath: params.sourceReflectionPath
44
+ })
45
+ ];
46
+ const itemPayloads = buildReflectionItemPayloads({
47
+ items: extractReflectionSliceItems(params.reflectionText),
48
+ eventId,
49
+ agentId: params.agentId,
50
+ sessionKey: params.sessionKey,
51
+ sessionId: params.sessionId,
52
+ runAt: params.runAt,
53
+ usedFallback: params.usedFallback,
54
+ toolErrorSignals: params.toolErrorSignals,
55
+ sourceReflectionPath: params.sourceReflectionPath
56
+ });
57
+ payloads.push(...itemPayloads);
58
+ if (params.writeLegacyCombined !== false && (slices.invariants.length > 0 || slices.derived.length > 0)) {
59
+ payloads.push(buildLegacyCombinedPayload({
60
+ slices,
61
+ scope: params.scope,
62
+ sessionKey: params.sessionKey,
63
+ sessionId: params.sessionId,
64
+ agentId: params.agentId,
65
+ command: params.command,
66
+ toolErrorSignals: params.toolErrorSignals,
67
+ runAt: params.runAt,
68
+ usedFallback: params.usedFallback,
69
+ sourceReflectionPath: params.sourceReflectionPath
70
+ }));
71
+ }
72
+ return { eventId, slices, payloads };
73
+ }
74
+ function buildLegacyCombinedPayload(params) {
75
+ const dateYmd = new Date(params.runAt).toISOString().split("T")[0];
76
+ const deriveQuality = computeDerivedLineQuality(params.slices.derived.length);
77
+ const deriveBaseWeight = params.usedFallback ? REFLECTION_DERIVE_FALLBACK_BASE_WEIGHT : 1;
78
+ return {
79
+ kind: "combined-legacy",
80
+ text: [
81
+ `reflection \xB7 ${params.scope} \xB7 ${dateYmd}`,
82
+ `Session Reflection (${new Date(params.runAt).toISOString()})`,
83
+ `Session Key: ${params.sessionKey}`,
84
+ `Session ID: ${params.sessionId}`,
85
+ "",
86
+ "Invariants:",
87
+ ...params.slices.invariants.length > 0 ? params.slices.invariants.map((x) => `- ${x}`) : ["- (none captured)"],
88
+ "",
89
+ "Derived:",
90
+ ...params.slices.derived.length > 0 ? params.slices.derived.map((x) => `- ${x}`) : ["- (none captured)"]
91
+ ].join("\n"),
92
+ metadata: {
93
+ type: "memory-reflection",
94
+ stage: "reflect-store",
95
+ reflectionVersion: 3,
96
+ sessionKey: params.sessionKey,
97
+ sessionId: params.sessionId,
98
+ agentId: params.agentId,
99
+ command: params.command,
100
+ storedAt: params.runAt,
101
+ invariants: params.slices.invariants,
102
+ derived: params.slices.derived,
103
+ usedFallback: params.usedFallback,
104
+ errorSignals: params.toolErrorSignals.map((s) => s.signatureHash),
105
+ decayModel: "logistic",
106
+ decayMidpointDays: REFLECTION_DERIVE_LOGISTIC_MIDPOINT_DAYS,
107
+ decayK: REFLECTION_DERIVE_LOGISTIC_K,
108
+ deriveBaseWeight,
109
+ deriveQuality,
110
+ deriveSource: params.usedFallback ? "fallback" : "normal",
111
+ ...params.sourceReflectionPath ? { sourceReflectionPath: params.sourceReflectionPath } : {}
112
+ }
113
+ };
114
+ }
115
+ async function storeReflectionToLanceDB(params) {
116
+ const { eventId, slices, payloads } = buildReflectionStorePayloads(params);
117
+ const storedKinds = [];
118
+ const dedupeThreshold = Number.isFinite(params.dedupeThreshold) ? Number(params.dedupeThreshold) : 0.97;
119
+ for (const payload of payloads) {
120
+ const vector = await params.embedPassage(payload.text);
121
+ if (payload.kind === "combined-legacy") {
122
+ const existing = await params.vectorSearch(vector, 1, 0.1, [params.scope]);
123
+ if (existing.length > 0 && existing[0].score > dedupeThreshold) {
124
+ continue;
125
+ }
126
+ }
127
+ await params.store({
128
+ text: payload.text,
129
+ vector,
130
+ category: "reflection",
131
+ scope: params.scope,
132
+ importance: resolveReflectionImportance(payload.kind),
133
+ metadata: JSON.stringify(payload.metadata)
134
+ });
135
+ storedKinds.push(payload.kind);
136
+ }
137
+ return { stored: storedKinds.length > 0, eventId, slices, storedKinds };
138
+ }
139
+ function resolveReflectionImportance(kind) {
140
+ if (kind === "event") return 0.55;
141
+ if (kind === "item-invariant") return 0.82;
142
+ if (kind === "item-derived") return 0.78;
143
+ return 0.75;
144
+ }
145
+ function loadAgentReflectionSlicesFromEntries(params) {
146
+ const now = Number.isFinite(params.now) ? Number(params.now) : Date.now();
147
+ const deriveMaxAgeMs = Number.isFinite(params.deriveMaxAgeMs) ? Math.max(0, Number(params.deriveMaxAgeMs)) : DEFAULT_REFLECTION_DERIVED_MAX_AGE_MS;
148
+ const invariantMaxAgeMs = Number.isFinite(params.invariantMaxAgeMs) ? Math.max(0, Number(params.invariantMaxAgeMs)) : void 0;
149
+ const reflectionRows = params.entries.map((entry) => ({ entry, metadata: parseReflectionMetadata(entry.metadata) })).filter(({ metadata }) => isReflectionMetadataType(metadata.type) && isOwnedByAgent(metadata, params.agentId)).sort((a, b) => b.entry.timestamp - a.entry.timestamp).slice(0, 160);
150
+ const itemRows = reflectionRows.filter(({ metadata }) => metadata.type === "memory-reflection-item");
151
+ const legacyRows = reflectionRows.filter(({ metadata }) => metadata.type === "memory-reflection");
152
+ const invariantCandidates = buildInvariantCandidates(itemRows, legacyRows);
153
+ const derivedCandidates = buildDerivedCandidates(itemRows, legacyRows);
154
+ const invariants = rankReflectionLines(invariantCandidates, {
155
+ now,
156
+ maxAgeMs: invariantMaxAgeMs,
157
+ limit: 8
158
+ });
159
+ const derived = rankReflectionLines(derivedCandidates, {
160
+ now,
161
+ maxAgeMs: deriveMaxAgeMs,
162
+ limit: 10
163
+ });
164
+ return { invariants, derived };
165
+ }
166
+ function buildInvariantCandidates(itemRows, legacyRows) {
167
+ const itemCandidates = itemRows.filter(({ metadata }) => metadata.itemKind === "invariant").flatMap(({ entry, metadata }) => {
168
+ const lines = sanitizeReflectionSliceLines([entry.text]);
169
+ if (lines.length === 0) return [];
170
+ const defaults = getReflectionItemDecayDefaults("invariant");
171
+ const timestamp = metadataTimestamp(metadata, entry.timestamp);
172
+ return lines.map((line) => ({
173
+ line,
174
+ timestamp,
175
+ midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),
176
+ k: readPositiveNumber(metadata.decayK, defaults.k),
177
+ baseWeight: readPositiveNumber(metadata.baseWeight, defaults.baseWeight),
178
+ quality: readClampedNumber(metadata.quality, defaults.quality, 0.2, 1),
179
+ usedFallback: metadata.usedFallback === true
180
+ }));
181
+ });
182
+ if (itemCandidates.length > 0) return itemCandidates;
183
+ return legacyRows.flatMap(({ entry, metadata }) => {
184
+ const defaults = getReflectionItemDecayDefaults("invariant");
185
+ const timestamp = metadataTimestamp(metadata, entry.timestamp);
186
+ const lines = sanitizeReflectionSliceLines(toStringArray(metadata.invariants));
187
+ return lines.map((line) => ({
188
+ line,
189
+ timestamp,
190
+ midpointDays: defaults.midpointDays,
191
+ k: defaults.k,
192
+ baseWeight: defaults.baseWeight,
193
+ quality: defaults.quality,
194
+ usedFallback: metadata.usedFallback === true
195
+ }));
196
+ });
197
+ }
198
+ function buildDerivedCandidates(itemRows, legacyRows) {
199
+ const itemCandidates = itemRows.filter(({ metadata }) => metadata.itemKind === "derived").flatMap(({ entry, metadata }) => {
200
+ const lines = sanitizeReflectionSliceLines([entry.text]);
201
+ if (lines.length === 0) return [];
202
+ const defaults = getReflectionItemDecayDefaults("derived");
203
+ const timestamp = metadataTimestamp(metadata, entry.timestamp);
204
+ return lines.map((line) => ({
205
+ line,
206
+ timestamp,
207
+ midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),
208
+ k: readPositiveNumber(metadata.decayK, defaults.k),
209
+ baseWeight: readPositiveNumber(metadata.baseWeight, defaults.baseWeight),
210
+ quality: readClampedNumber(metadata.quality, defaults.quality, 0.2, 1),
211
+ usedFallback: metadata.usedFallback === true
212
+ }));
213
+ });
214
+ if (itemCandidates.length > 0) return itemCandidates;
215
+ return legacyRows.flatMap(({ entry, metadata }) => {
216
+ const timestamp = metadataTimestamp(metadata, entry.timestamp);
217
+ const lines = sanitizeReflectionSliceLines(toStringArray(metadata.derived));
218
+ if (lines.length === 0) return [];
219
+ const defaults = {
220
+ midpointDays: REFLECTION_DERIVE_LOGISTIC_MIDPOINT_DAYS,
221
+ k: REFLECTION_DERIVE_LOGISTIC_K,
222
+ baseWeight: resolveLegacyDeriveBaseWeight(metadata),
223
+ quality: computeDerivedLineQuality(lines.length)
224
+ };
225
+ return lines.map((line) => ({
226
+ line,
227
+ timestamp,
228
+ midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),
229
+ k: readPositiveNumber(metadata.decayK, defaults.k),
230
+ baseWeight: readPositiveNumber(metadata.deriveBaseWeight, defaults.baseWeight),
231
+ quality: readClampedNumber(metadata.deriveQuality, defaults.quality, 0.2, 1),
232
+ usedFallback: metadata.usedFallback === true
233
+ }));
234
+ });
235
+ }
236
+ function rankReflectionLines(candidates, options) {
237
+ const lineScores = /* @__PURE__ */ new Map();
238
+ for (const candidate of candidates) {
239
+ const timestamp = Number.isFinite(candidate.timestamp) ? candidate.timestamp : options.now;
240
+ if (Number.isFinite(options.maxAgeMs) && options.maxAgeMs >= 0 && options.now - timestamp > options.maxAgeMs) {
241
+ continue;
242
+ }
243
+ const ageDays = Math.max(0, (options.now - timestamp) / 864e5);
244
+ const score = computeReflectionScore({
245
+ ageDays,
246
+ midpointDays: candidate.midpointDays,
247
+ k: candidate.k,
248
+ baseWeight: candidate.baseWeight,
249
+ quality: candidate.quality,
250
+ usedFallback: candidate.usedFallback
251
+ });
252
+ if (!Number.isFinite(score) || score <= 0) continue;
253
+ const key = normalizeReflectionLineForAggregation(candidate.line);
254
+ if (!key) continue;
255
+ const current = lineScores.get(key);
256
+ if (!current) {
257
+ lineScores.set(key, { line: candidate.line, score, latestTs: timestamp });
258
+ continue;
259
+ }
260
+ current.score += score;
261
+ if (timestamp > current.latestTs) {
262
+ current.latestTs = timestamp;
263
+ current.line = candidate.line;
264
+ }
265
+ }
266
+ return [...lineScores.values()].sort((a, b) => {
267
+ if (b.score !== a.score) return b.score - a.score;
268
+ if (b.latestTs !== a.latestTs) return b.latestTs - a.latestTs;
269
+ return a.line.localeCompare(b.line);
270
+ }).slice(0, options.limit).map((item) => item.line);
271
+ }
272
+ function isReflectionMetadataType(type) {
273
+ return type === "memory-reflection-item" || type === "memory-reflection";
274
+ }
275
+ function isOwnedByAgent(metadata, agentId) {
276
+ const owner = typeof metadata.agentId === "string" ? metadata.agentId.trim() : "";
277
+ if (!owner) return true;
278
+ return owner === agentId || owner === "main";
279
+ }
280
+ function toStringArray(value) {
281
+ if (!Array.isArray(value)) return [];
282
+ return value.map((item) => String(item).trim()).filter(Boolean);
283
+ }
284
+ function metadataTimestamp(metadata, fallbackTs) {
285
+ const storedAt = Number(metadata.storedAt);
286
+ if (Number.isFinite(storedAt) && storedAt > 0) return storedAt;
287
+ return Number.isFinite(fallbackTs) ? fallbackTs : Date.now();
288
+ }
289
+ function readPositiveNumber(value, fallback) {
290
+ const num = Number(value);
291
+ if (!Number.isFinite(num) || num <= 0) return fallback;
292
+ return num;
293
+ }
294
+ function readClampedNumber(value, fallback, min, max) {
295
+ const num = Number(value);
296
+ const resolved = Number.isFinite(num) ? num : fallback;
297
+ return Math.max(min, Math.min(max, resolved));
298
+ }
299
+ function computeDerivedLineQuality(nonPlaceholderLineCount) {
300
+ const n = Number.isFinite(nonPlaceholderLineCount) ? Math.max(0, Math.floor(nonPlaceholderLineCount)) : 0;
301
+ if (n <= 0) return 0.2;
302
+ return Math.min(1, 0.55 + Math.min(6, n) * 0.075);
303
+ }
304
+ function resolveLegacyDeriveBaseWeight(metadata) {
305
+ const explicit = Number(metadata.deriveBaseWeight);
306
+ if (Number.isFinite(explicit) && explicit > 0) {
307
+ return Math.max(0.1, Math.min(1.2, explicit));
308
+ }
309
+ if (metadata.usedFallback === true) {
310
+ return REFLECTION_DERIVE_FALLBACK_BASE_WEIGHT;
311
+ }
312
+ return 1;
313
+ }
314
+ function loadReflectionMappedRowsFromEntries(params) {
315
+ const now = Number.isFinite(params.now) ? Number(params.now) : Date.now();
316
+ const maxAgeMs = Number.isFinite(params.maxAgeMs) ? Math.max(0, Number(params.maxAgeMs)) : DEFAULT_REFLECTION_MAPPED_MAX_AGE_MS;
317
+ const maxPerKind = Number.isFinite(params.maxPerKind) ? Math.max(1, Math.floor(Number(params.maxPerKind))) : 10;
318
+ const weighted = params.entries.map((entry) => ({ entry, metadata: parseReflectionMetadata(entry.metadata) })).filter(({ metadata }) => metadata.type === "memory-reflection-mapped" && isOwnedByAgent(metadata, params.agentId)).flatMap(({ entry, metadata }) => {
319
+ const mappedKind = parseMappedKind(metadata.mappedKind);
320
+ if (!mappedKind) return [];
321
+ const lines = sanitizeReflectionSliceLines([entry.text]);
322
+ if (lines.length === 0) return [];
323
+ const defaults = getReflectionMappedDecayDefaults(mappedKind);
324
+ const timestamp = metadataTimestamp(metadata, entry.timestamp);
325
+ return lines.map((line) => ({
326
+ text: line,
327
+ mappedKind,
328
+ timestamp,
329
+ midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),
330
+ k: readPositiveNumber(metadata.decayK, defaults.k),
331
+ baseWeight: readPositiveNumber(metadata.baseWeight, defaults.baseWeight),
332
+ quality: readClampedNumber(metadata.quality, defaults.quality, 0.2, 1),
333
+ usedFallback: metadata.usedFallback === true
334
+ }));
335
+ });
336
+ const grouped = /* @__PURE__ */ new Map();
337
+ for (const item of weighted) {
338
+ if (now - item.timestamp > maxAgeMs) continue;
339
+ const ageDays = Math.max(0, (now - item.timestamp) / 864e5);
340
+ const score = computeReflectionScore({
341
+ ageDays,
342
+ midpointDays: item.midpointDays,
343
+ k: item.k,
344
+ baseWeight: item.baseWeight,
345
+ quality: item.quality,
346
+ usedFallback: item.usedFallback
347
+ });
348
+ if (!Number.isFinite(score) || score <= 0) continue;
349
+ const normalized = normalizeReflectionLineForAggregation(item.text);
350
+ if (!normalized) continue;
351
+ const key = `${item.mappedKind}::${normalized}`;
352
+ const current = grouped.get(key);
353
+ if (!current) {
354
+ grouped.set(key, { text: item.text, score, latestTs: item.timestamp, kind: item.mappedKind });
355
+ continue;
356
+ }
357
+ current.score += score;
358
+ if (item.timestamp > current.latestTs) {
359
+ current.latestTs = item.timestamp;
360
+ current.text = item.text;
361
+ }
362
+ }
363
+ const sortedByKind = (kind) => [...grouped.values()].filter((row) => row.kind === kind).sort((a, b) => {
364
+ if (b.score !== a.score) return b.score - a.score;
365
+ if (b.latestTs !== a.latestTs) return b.latestTs - a.latestTs;
366
+ return a.text.localeCompare(b.text);
367
+ }).slice(0, maxPerKind).map((row) => row.text);
368
+ return {
369
+ userModel: sortedByKind("user-model"),
370
+ agentModel: sortedByKind("agent-model"),
371
+ lesson: sortedByKind("lesson"),
372
+ decision: sortedByKind("decision")
373
+ };
374
+ }
375
+ function parseMappedKind(value) {
376
+ if (value === "user-model" || value === "agent-model" || value === "lesson" || value === "decision") {
377
+ return value;
378
+ }
379
+ return null;
380
+ }
381
+ function getReflectionDerivedDecayDefaults() {
382
+ return {
383
+ midpointDays: REFLECTION_DERIVED_DECAY_MIDPOINT_DAYS,
384
+ k: REFLECTION_DERIVED_DECAY_K
385
+ };
386
+ }
387
+ function getReflectionInvariantDecayDefaults() {
388
+ return {
389
+ midpointDays: REFLECTION_INVARIANT_DECAY_MIDPOINT_DAYS,
390
+ k: REFLECTION_INVARIANT_DECAY_K
391
+ };
392
+ }
393
+ export {
394
+ DEFAULT_REFLECTION_DERIVED_MAX_AGE_MS,
395
+ DEFAULT_REFLECTION_MAPPED_MAX_AGE_MS,
396
+ REFLECTION_DERIVE_FALLBACK_BASE_WEIGHT,
397
+ REFLECTION_DERIVE_LOGISTIC_K,
398
+ REFLECTION_DERIVE_LOGISTIC_MIDPOINT_DAYS,
399
+ buildReflectionStorePayloads,
400
+ computeDerivedLineQuality,
401
+ getReflectionDerivedDecayDefaults,
402
+ getReflectionInvariantDecayDefaults,
403
+ loadAgentReflectionSlicesFromEntries,
404
+ loadReflectionMappedRowsFromEntries,
405
+ storeReflectionToLanceDB
406
+ };
407
+ //# sourceMappingURL=reflection-store.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/reflection-store.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: LicenseRef-Mnemo-Pro\nimport type { MemoryEntry, MemorySearchResult } from \"./store.js\";\nimport {\n extractReflectionSliceItems,\n extractReflectionSlices,\n sanitizeReflectionSliceLines,\n type ReflectionSlices,\n} from \"./reflection-slices.js\";\nimport { parseReflectionMetadata } from \"./reflection-metadata.js\";\nimport { buildReflectionEventPayload, createReflectionEventId } from \"./reflection-event-store.js\";\nimport {\n buildReflectionItemPayloads,\n getReflectionItemDecayDefaults,\n REFLECTION_DERIVED_DECAY_K,\n REFLECTION_DERIVED_DECAY_MIDPOINT_DAYS,\n REFLECTION_INVARIANT_DECAY_K,\n REFLECTION_INVARIANT_DECAY_MIDPOINT_DAYS,\n} from \"./reflection-item-store.js\";\nimport { getReflectionMappedDecayDefaults, type ReflectionMappedKind } from \"./reflection-mapped-metadata.js\";\nimport { computeReflectionScore, normalizeReflectionLineForAggregation } from \"./reflection-ranking.js\";\n\nexport const REFLECTION_DERIVE_LOGISTIC_MIDPOINT_DAYS = 3;\nexport const REFLECTION_DERIVE_LOGISTIC_K = 1.2;\nexport const REFLECTION_DERIVE_FALLBACK_BASE_WEIGHT = 0.35;\n\nexport const DEFAULT_REFLECTION_DERIVED_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000;\nexport const DEFAULT_REFLECTION_MAPPED_MAX_AGE_MS = 60 * 24 * 60 * 60 * 1000;\n\ntype ReflectionStoreKind = \"event\" | \"item-invariant\" | \"item-derived\" | \"combined-legacy\";\n\ntype ReflectionErrorSignalLike = {\n signatureHash: string;\n};\n\ninterface ReflectionStorePayload {\n text: string;\n metadata: Record<string, unknown>;\n kind: ReflectionStoreKind;\n}\n\ninterface BuildReflectionStorePayloadsParams {\n reflectionText: string;\n sessionKey: string;\n sessionId: string;\n agentId: string;\n command: string;\n scope: string;\n toolErrorSignals: ReflectionErrorSignalLike[];\n runAt: number;\n usedFallback: boolean;\n eventId?: string;\n sourceReflectionPath?: string;\n writeLegacyCombined?: boolean;\n}\n\nexport function buildReflectionStorePayloads(params: BuildReflectionStorePayloadsParams): {\n eventId: string;\n slices: ReflectionSlices;\n payloads: ReflectionStorePayload[];\n} {\n const slices = extractReflectionSlices(params.reflectionText);\n const eventId = params.eventId || createReflectionEventId({\n runAt: params.runAt,\n sessionKey: params.sessionKey,\n sessionId: params.sessionId,\n agentId: params.agentId,\n command: params.command,\n });\n\n const payloads: ReflectionStorePayload[] = [\n buildReflectionEventPayload({\n eventId,\n scope: params.scope,\n sessionKey: params.sessionKey,\n sessionId: params.sessionId,\n agentId: params.agentId,\n command: params.command,\n toolErrorSignals: params.toolErrorSignals,\n runAt: params.runAt,\n usedFallback: params.usedFallback,\n sourceReflectionPath: params.sourceReflectionPath,\n }),\n ];\n\n const itemPayloads = buildReflectionItemPayloads({\n items: extractReflectionSliceItems(params.reflectionText),\n eventId,\n agentId: params.agentId,\n sessionKey: params.sessionKey,\n sessionId: params.sessionId,\n runAt: params.runAt,\n usedFallback: params.usedFallback,\n toolErrorSignals: params.toolErrorSignals,\n sourceReflectionPath: params.sourceReflectionPath,\n });\n payloads.push(...itemPayloads);\n\n if (params.writeLegacyCombined !== false && (slices.invariants.length > 0 || slices.derived.length > 0)) {\n payloads.push(buildLegacyCombinedPayload({\n slices,\n scope: params.scope,\n sessionKey: params.sessionKey,\n sessionId: params.sessionId,\n agentId: params.agentId,\n command: params.command,\n toolErrorSignals: params.toolErrorSignals,\n runAt: params.runAt,\n usedFallback: params.usedFallback,\n sourceReflectionPath: params.sourceReflectionPath,\n }));\n }\n\n return { eventId, slices, payloads };\n}\n\nfunction buildLegacyCombinedPayload(params: {\n slices: ReflectionSlices;\n sessionKey: string;\n sessionId: string;\n agentId: string;\n command: string;\n scope: string;\n toolErrorSignals: ReflectionErrorSignalLike[];\n runAt: number;\n usedFallback: boolean;\n sourceReflectionPath?: string;\n}): ReflectionStorePayload {\n const dateYmd = new Date(params.runAt).toISOString().split(\"T\")[0];\n const deriveQuality = computeDerivedLineQuality(params.slices.derived.length);\n const deriveBaseWeight = params.usedFallback ? REFLECTION_DERIVE_FALLBACK_BASE_WEIGHT : 1;\n\n return {\n kind: \"combined-legacy\",\n text: [\n `reflection \u00B7 ${params.scope} \u00B7 ${dateYmd}`,\n `Session Reflection (${new Date(params.runAt).toISOString()})`,\n `Session Key: ${params.sessionKey}`,\n `Session ID: ${params.sessionId}`,\n \"\",\n \"Invariants:\",\n ...(params.slices.invariants.length > 0 ? params.slices.invariants.map((x) => `- ${x}`) : [\"- (none captured)\"]),\n \"\",\n \"Derived:\",\n ...(params.slices.derived.length > 0 ? params.slices.derived.map((x) => `- ${x}`) : [\"- (none captured)\"]),\n ].join(\"\\n\"),\n metadata: {\n type: \"memory-reflection\",\n stage: \"reflect-store\",\n reflectionVersion: 3,\n sessionKey: params.sessionKey,\n sessionId: params.sessionId,\n agentId: params.agentId,\n command: params.command,\n storedAt: params.runAt,\n invariants: params.slices.invariants,\n derived: params.slices.derived,\n usedFallback: params.usedFallback,\n errorSignals: params.toolErrorSignals.map((s) => s.signatureHash),\n decayModel: \"logistic\",\n decayMidpointDays: REFLECTION_DERIVE_LOGISTIC_MIDPOINT_DAYS,\n decayK: REFLECTION_DERIVE_LOGISTIC_K,\n deriveBaseWeight,\n deriveQuality,\n deriveSource: params.usedFallback ? \"fallback\" : \"normal\",\n ...(params.sourceReflectionPath ? { sourceReflectionPath: params.sourceReflectionPath } : {}),\n },\n };\n}\n\ninterface ReflectionStoreDeps {\n embedPassage: (text: string) => Promise<number[]>;\n vectorSearch: (\n vector: number[],\n limit?: number,\n minScore?: number,\n scopeFilter?: string[]\n ) => Promise<MemorySearchResult[]>;\n store: (entry: Omit<MemoryEntry, \"id\" | \"timestamp\">) => Promise<MemoryEntry>;\n}\n\ninterface StoreReflectionToLanceDBParams extends BuildReflectionStorePayloadsParams, ReflectionStoreDeps {\n dedupeThreshold?: number;\n}\n\nexport async function storeReflectionToLanceDB(params: StoreReflectionToLanceDBParams): Promise<{\n stored: boolean;\n eventId: string;\n slices: ReflectionSlices;\n storedKinds: ReflectionStoreKind[];\n}> {\n const { eventId, slices, payloads } = buildReflectionStorePayloads(params);\n const storedKinds: ReflectionStoreKind[] = [];\n const dedupeThreshold = Number.isFinite(params.dedupeThreshold) ? Number(params.dedupeThreshold) : 0.97;\n\n for (const payload of payloads) {\n const vector = await params.embedPassage(payload.text);\n\n if (payload.kind === \"combined-legacy\") {\n const existing = await params.vectorSearch(vector, 1, 0.1, [params.scope]);\n if (existing.length > 0 && existing[0].score > dedupeThreshold) {\n continue;\n }\n }\n\n await params.store({\n text: payload.text,\n vector,\n category: \"reflection\",\n scope: params.scope,\n importance: resolveReflectionImportance(payload.kind),\n metadata: JSON.stringify(payload.metadata),\n });\n storedKinds.push(payload.kind);\n }\n\n return { stored: storedKinds.length > 0, eventId, slices, storedKinds };\n}\n\nfunction resolveReflectionImportance(kind: ReflectionStoreKind): number {\n if (kind === \"event\") return 0.55;\n if (kind === \"item-invariant\") return 0.82;\n if (kind === \"item-derived\") return 0.78;\n return 0.75;\n}\n\nexport interface LoadReflectionSlicesParams {\n entries: MemoryEntry[];\n agentId: string;\n now?: number;\n deriveMaxAgeMs?: number;\n invariantMaxAgeMs?: number;\n}\n\nexport function loadAgentReflectionSlicesFromEntries(params: LoadReflectionSlicesParams): {\n invariants: string[];\n derived: string[];\n} {\n const now = Number.isFinite(params.now) ? Number(params.now) : Date.now();\n const deriveMaxAgeMs = Number.isFinite(params.deriveMaxAgeMs)\n ? Math.max(0, Number(params.deriveMaxAgeMs))\n : DEFAULT_REFLECTION_DERIVED_MAX_AGE_MS;\n const invariantMaxAgeMs = Number.isFinite(params.invariantMaxAgeMs)\n ? Math.max(0, Number(params.invariantMaxAgeMs))\n : undefined;\n\n const reflectionRows = params.entries\n .map((entry) => ({ entry, metadata: parseReflectionMetadata(entry.metadata) }))\n .filter(({ metadata }) => isReflectionMetadataType(metadata.type) && isOwnedByAgent(metadata, params.agentId))\n .sort((a, b) => b.entry.timestamp - a.entry.timestamp)\n .slice(0, 160);\n\n const itemRows = reflectionRows.filter(({ metadata }) => metadata.type === \"memory-reflection-item\");\n const legacyRows = reflectionRows.filter(({ metadata }) => metadata.type === \"memory-reflection\");\n\n const invariantCandidates = buildInvariantCandidates(itemRows, legacyRows);\n const derivedCandidates = buildDerivedCandidates(itemRows, legacyRows);\n\n const invariants = rankReflectionLines(invariantCandidates, {\n now,\n maxAgeMs: invariantMaxAgeMs,\n limit: 8,\n });\n\n const derived = rankReflectionLines(derivedCandidates, {\n now,\n maxAgeMs: deriveMaxAgeMs,\n limit: 10,\n });\n\n return { invariants, derived };\n}\n\ntype WeightedLineCandidate = {\n line: string;\n timestamp: number;\n midpointDays: number;\n k: number;\n baseWeight: number;\n quality: number;\n usedFallback: boolean;\n};\n\nfunction buildInvariantCandidates(\n itemRows: Array<{ entry: MemoryEntry; metadata: Record<string, unknown> }>,\n legacyRows: Array<{ entry: MemoryEntry; metadata: Record<string, unknown> }>\n): WeightedLineCandidate[] {\n const itemCandidates = itemRows\n .filter(({ metadata }) => metadata.itemKind === \"invariant\")\n .flatMap(({ entry, metadata }) => {\n const lines = sanitizeReflectionSliceLines([entry.text]);\n if (lines.length === 0) return [];\n\n const defaults = getReflectionItemDecayDefaults(\"invariant\");\n const timestamp = metadataTimestamp(metadata, entry.timestamp);\n return lines.map((line) => ({\n line,\n timestamp,\n midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),\n k: readPositiveNumber(metadata.decayK, defaults.k),\n baseWeight: readPositiveNumber(metadata.baseWeight, defaults.baseWeight),\n quality: readClampedNumber(metadata.quality, defaults.quality, 0.2, 1),\n usedFallback: metadata.usedFallback === true,\n }));\n });\n\n if (itemCandidates.length > 0) return itemCandidates;\n\n return legacyRows.flatMap(({ entry, metadata }) => {\n const defaults = getReflectionItemDecayDefaults(\"invariant\");\n const timestamp = metadataTimestamp(metadata, entry.timestamp);\n const lines = sanitizeReflectionSliceLines(toStringArray(metadata.invariants));\n return lines.map((line) => ({\n line,\n timestamp,\n midpointDays: defaults.midpointDays,\n k: defaults.k,\n baseWeight: defaults.baseWeight,\n quality: defaults.quality,\n usedFallback: metadata.usedFallback === true,\n }));\n });\n}\n\nfunction buildDerivedCandidates(\n itemRows: Array<{ entry: MemoryEntry; metadata: Record<string, unknown> }>,\n legacyRows: Array<{ entry: MemoryEntry; metadata: Record<string, unknown> }>\n): WeightedLineCandidate[] {\n const itemCandidates = itemRows\n .filter(({ metadata }) => metadata.itemKind === \"derived\")\n .flatMap(({ entry, metadata }) => {\n const lines = sanitizeReflectionSliceLines([entry.text]);\n if (lines.length === 0) return [];\n\n const defaults = getReflectionItemDecayDefaults(\"derived\");\n const timestamp = metadataTimestamp(metadata, entry.timestamp);\n return lines.map((line) => ({\n line,\n timestamp,\n midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),\n k: readPositiveNumber(metadata.decayK, defaults.k),\n baseWeight: readPositiveNumber(metadata.baseWeight, defaults.baseWeight),\n quality: readClampedNumber(metadata.quality, defaults.quality, 0.2, 1),\n usedFallback: metadata.usedFallback === true,\n }));\n });\n\n if (itemCandidates.length > 0) return itemCandidates;\n\n return legacyRows.flatMap(({ entry, metadata }) => {\n const timestamp = metadataTimestamp(metadata, entry.timestamp);\n const lines = sanitizeReflectionSliceLines(toStringArray(metadata.derived));\n if (lines.length === 0) return [];\n\n const defaults = {\n midpointDays: REFLECTION_DERIVE_LOGISTIC_MIDPOINT_DAYS,\n k: REFLECTION_DERIVE_LOGISTIC_K,\n baseWeight: resolveLegacyDeriveBaseWeight(metadata),\n quality: computeDerivedLineQuality(lines.length),\n };\n\n return lines.map((line) => ({\n line,\n timestamp,\n midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),\n k: readPositiveNumber(metadata.decayK, defaults.k),\n baseWeight: readPositiveNumber(metadata.deriveBaseWeight, defaults.baseWeight),\n quality: readClampedNumber(metadata.deriveQuality, defaults.quality, 0.2, 1),\n usedFallback: metadata.usedFallback === true,\n }));\n });\n}\n\nfunction rankReflectionLines(\n candidates: WeightedLineCandidate[],\n options: { now: number; maxAgeMs?: number; limit: number }\n): string[] {\n type WeightedLine = { line: string; score: number; latestTs: number };\n const lineScores = new Map<string, WeightedLine>();\n\n for (const candidate of candidates) {\n const timestamp = Number.isFinite(candidate.timestamp) ? candidate.timestamp : options.now;\n if (Number.isFinite(options.maxAgeMs) && options.maxAgeMs! >= 0 && options.now - timestamp > options.maxAgeMs!) {\n continue;\n }\n\n const ageDays = Math.max(0, (options.now - timestamp) / 86_400_000);\n const score = computeReflectionScore({\n ageDays,\n midpointDays: candidate.midpointDays,\n k: candidate.k,\n baseWeight: candidate.baseWeight,\n quality: candidate.quality,\n usedFallback: candidate.usedFallback,\n });\n if (!Number.isFinite(score) || score <= 0) continue;\n\n const key = normalizeReflectionLineForAggregation(candidate.line);\n if (!key) continue;\n\n const current = lineScores.get(key);\n if (!current) {\n lineScores.set(key, { line: candidate.line, score, latestTs: timestamp });\n continue;\n }\n\n current.score += score;\n if (timestamp > current.latestTs) {\n current.latestTs = timestamp;\n current.line = candidate.line;\n }\n }\n\n return [...lineScores.values()]\n .sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n if (b.latestTs !== a.latestTs) return b.latestTs - a.latestTs;\n return a.line.localeCompare(b.line);\n })\n .slice(0, options.limit)\n .map((item) => item.line);\n}\n\nfunction isReflectionMetadataType(type: unknown): boolean {\n return type === \"memory-reflection-item\" || type === \"memory-reflection\";\n}\n\nfunction isOwnedByAgent(metadata: Record<string, unknown>, agentId: string): boolean {\n const owner = typeof metadata.agentId === \"string\" ? metadata.agentId.trim() : \"\";\n if (!owner) return true;\n return owner === agentId || owner === \"main\";\n}\n\nfunction toStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value\n .map((item) => String(item).trim())\n .filter(Boolean);\n}\n\nfunction metadataTimestamp(metadata: Record<string, unknown>, fallbackTs: number): number {\n const storedAt = Number(metadata.storedAt);\n if (Number.isFinite(storedAt) && storedAt > 0) return storedAt;\n return Number.isFinite(fallbackTs) ? fallbackTs : Date.now();\n}\n\nfunction readPositiveNumber(value: unknown, fallback: number): number {\n const num = Number(value);\n if (!Number.isFinite(num) || num <= 0) return fallback;\n return num;\n}\n\nfunction readClampedNumber(value: unknown, fallback: number, min: number, max: number): number {\n const num = Number(value);\n const resolved = Number.isFinite(num) ? num : fallback;\n return Math.max(min, Math.min(max, resolved));\n}\n\nexport function computeDerivedLineQuality(nonPlaceholderLineCount: number): number {\n const n = Number.isFinite(nonPlaceholderLineCount) ? Math.max(0, Math.floor(nonPlaceholderLineCount)) : 0;\n if (n <= 0) return 0.2;\n return Math.min(1, 0.55 + Math.min(6, n) * 0.075);\n}\n\nfunction resolveLegacyDeriveBaseWeight(metadata: Record<string, unknown>): number {\n const explicit = Number(metadata.deriveBaseWeight);\n if (Number.isFinite(explicit) && explicit > 0) {\n return Math.max(0.1, Math.min(1.2, explicit));\n }\n if (metadata.usedFallback === true) {\n return REFLECTION_DERIVE_FALLBACK_BASE_WEIGHT;\n }\n return 1;\n}\n\nexport interface LoadReflectionMappedRowsParams {\n entries: MemoryEntry[];\n agentId: string;\n now?: number;\n maxAgeMs?: number;\n maxPerKind?: number;\n}\n\nexport interface ReflectionMappedSlices {\n userModel: string[];\n agentModel: string[];\n lesson: string[];\n decision: string[];\n}\n\nexport function loadReflectionMappedRowsFromEntries(params: LoadReflectionMappedRowsParams): ReflectionMappedSlices {\n const now = Number.isFinite(params.now) ? Number(params.now) : Date.now();\n const maxAgeMs = Number.isFinite(params.maxAgeMs)\n ? Math.max(0, Number(params.maxAgeMs))\n : DEFAULT_REFLECTION_MAPPED_MAX_AGE_MS;\n const maxPerKind = Number.isFinite(params.maxPerKind) ? Math.max(1, Math.floor(Number(params.maxPerKind))) : 10;\n\n type WeightedMapped = {\n text: string;\n mappedKind: ReflectionMappedKind;\n timestamp: number;\n midpointDays: number;\n k: number;\n baseWeight: number;\n quality: number;\n usedFallback: boolean;\n };\n\n const weighted: WeightedMapped[] = params.entries\n .map((entry) => ({ entry, metadata: parseReflectionMetadata(entry.metadata) }))\n .filter(({ metadata }) => metadata.type === \"memory-reflection-mapped\" && isOwnedByAgent(metadata, params.agentId))\n .flatMap(({ entry, metadata }) => {\n const mappedKind = parseMappedKind(metadata.mappedKind);\n if (!mappedKind) return [];\n\n const lines = sanitizeReflectionSliceLines([entry.text]);\n if (lines.length === 0) return [];\n\n const defaults = getReflectionMappedDecayDefaults(mappedKind);\n const timestamp = metadataTimestamp(metadata, entry.timestamp);\n\n return lines.map((line) => ({\n text: line,\n mappedKind,\n timestamp,\n midpointDays: readPositiveNumber(metadata.decayMidpointDays, defaults.midpointDays),\n k: readPositiveNumber(metadata.decayK, defaults.k),\n baseWeight: readPositiveNumber(metadata.baseWeight, defaults.baseWeight),\n quality: readClampedNumber(metadata.quality, defaults.quality, 0.2, 1),\n usedFallback: metadata.usedFallback === true,\n }));\n });\n\n const grouped = new Map<string, { text: string; score: number; latestTs: number; kind: ReflectionMappedKind }>();\n\n for (const item of weighted) {\n if (now - item.timestamp > maxAgeMs) continue;\n const ageDays = Math.max(0, (now - item.timestamp) / 86_400_000);\n const score = computeReflectionScore({\n ageDays,\n midpointDays: item.midpointDays,\n k: item.k,\n baseWeight: item.baseWeight,\n quality: item.quality,\n usedFallback: item.usedFallback,\n });\n if (!Number.isFinite(score) || score <= 0) continue;\n\n const normalized = normalizeReflectionLineForAggregation(item.text);\n if (!normalized) continue;\n\n const key = `${item.mappedKind}::${normalized}`;\n const current = grouped.get(key);\n if (!current) {\n grouped.set(key, { text: item.text, score, latestTs: item.timestamp, kind: item.mappedKind });\n continue;\n }\n\n current.score += score;\n if (item.timestamp > current.latestTs) {\n current.latestTs = item.timestamp;\n current.text = item.text;\n }\n }\n\n const sortedByKind = (kind: ReflectionMappedKind) => [...grouped.values()]\n .filter((row) => row.kind === kind)\n .sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n if (b.latestTs !== a.latestTs) return b.latestTs - a.latestTs;\n return a.text.localeCompare(b.text);\n })\n .slice(0, maxPerKind)\n .map((row) => row.text);\n\n return {\n userModel: sortedByKind(\"user-model\"),\n agentModel: sortedByKind(\"agent-model\"),\n lesson: sortedByKind(\"lesson\"),\n decision: sortedByKind(\"decision\"),\n };\n}\n\nfunction parseMappedKind(value: unknown): ReflectionMappedKind | null {\n if (value === \"user-model\" || value === \"agent-model\" || value === \"lesson\" || value === \"decision\") {\n return value;\n }\n return null;\n}\n\nexport function getReflectionDerivedDecayDefaults(): { midpointDays: number; k: number } {\n return {\n midpointDays: REFLECTION_DERIVED_DECAY_MIDPOINT_DAYS,\n k: REFLECTION_DERIVED_DECAY_K,\n };\n}\n\nexport function getReflectionInvariantDecayDefaults(): { midpointDays: number; k: number } {\n return {\n midpointDays: REFLECTION_INVARIANT_DECAY_MIDPOINT_DAYS,\n k: REFLECTION_INVARIANT_DECAY_K,\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Adaptive Resonance Threshold
3
+ *
4
+ * Maintains a sliding window of recent auto-recall top-1 cosine scores
5
+ * to compute an adaptive resonance gate threshold (P25 of the window).
6
+ * Persisted to ~/.openclaw/memory/resonance-state.json.
7
+ */
8
+ /**
9
+ * Get the adaptive resonance threshold.
10
+ * - Cold start (< 20 samples): returns default 0.45
11
+ * - Otherwise: P25 of sliding window, clamped to [0.30, 0.60]
12
+ */
13
+ export declare function getAdaptiveThreshold(): number;
14
+ /**
15
+ * Record a top-1 cosine score from an auto-recall probe.
16
+ * Appends to the sliding window and persists.
17
+ */
18
+ export declare function recordResonanceScore(score: number): void;
19
+ //# sourceMappingURL=resonance-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resonance-state.d.ts","sourceRoot":"","sources":["../../src/resonance-state.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AA4CH;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAY7C;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAUxD"}
@@ -1,85 +1,56 @@
1
- // SPDX-License-Identifier: MIT
2
- /**
3
- * Adaptive Resonance Threshold
4
- *
5
- * Maintains a sliding window of recent auto-recall top-1 cosine scores
6
- * to compute an adaptive resonance gate threshold (P25 of the window).
7
- * Persisted to ~/.openclaw/memory/resonance-state.json.
8
- */
9
-
10
1
  import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
11
2
  import { homedir } from "node:os";
12
3
  import { join, dirname } from "node:path";
13
-
14
4
  const STATE_PATH = join(homedir(), ".openclaw", "memory", "resonance-state.json");
15
5
  const WINDOW_SIZE = 100;
16
6
  const COLD_START_MIN = 20;
17
7
  const DEFAULT_THRESHOLD = 0.45;
18
- const THRESHOLD_FLOOR = 0.30;
19
- const THRESHOLD_CEILING = 0.60;
20
-
21
- interface ResonanceStateData {
22
- scores: number[];
23
- }
24
-
25
- let cached: ResonanceStateData | null = null;
26
-
27
- function loadState(): ResonanceStateData {
8
+ const THRESHOLD_FLOOR = 0.3;
9
+ const THRESHOLD_CEILING = 0.6;
10
+ let cached = null;
11
+ function loadState() {
28
12
  if (cached) return cached;
29
13
  try {
30
14
  const raw = readFileSync(STATE_PATH, "utf8");
31
15
  const parsed = JSON.parse(raw);
32
16
  if (parsed && Array.isArray(parsed.scores)) {
33
- cached = { scores: parsed.scores.filter((s: unknown) => typeof s === "number" && Number.isFinite(s as number)).slice(-WINDOW_SIZE) };
17
+ cached = { scores: parsed.scores.filter((s) => typeof s === "number" && Number.isFinite(s)).slice(-WINDOW_SIZE) };
34
18
  return cached;
35
19
  }
36
20
  } catch {
37
- // file doesn't exist or is corrupted — start fresh
38
21
  }
39
22
  cached = { scores: [] };
40
23
  return cached;
41
24
  }
42
-
43
- function saveState(state: ResonanceStateData): void {
25
+ function saveState(state) {
44
26
  try {
45
27
  mkdirSync(dirname(STATE_PATH), { recursive: true });
46
28
  writeFileSync(STATE_PATH, JSON.stringify(state), "utf8");
47
29
  } catch {
48
- // best-effort persistence
49
30
  }
50
31
  }
51
-
52
- /**
53
- * Get the adaptive resonance threshold.
54
- * - Cold start (< 20 samples): returns default 0.45
55
- * - Otherwise: P25 of sliding window, clamped to [0.30, 0.60]
56
- */
57
- export function getAdaptiveThreshold(): number {
32
+ function getAdaptiveThreshold() {
58
33
  const state = loadState();
59
34
  if (state.scores.length < COLD_START_MIN) {
60
35
  return DEFAULT_THRESHOLD;
61
36
  }
62
-
63
- // Compute P25 (25th percentile)
64
37
  const sorted = [...state.scores].sort((a, b) => a - b);
65
38
  const idx = Math.floor(sorted.length * 0.25);
66
39
  const p25 = sorted[idx];
67
-
68
40
  return Math.min(THRESHOLD_CEILING, Math.max(THRESHOLD_FLOOR, p25));
69
41
  }
70
-
71
- /**
72
- * Record a top-1 cosine score from an auto-recall probe.
73
- * Appends to the sliding window and persists.
74
- */
75
- export function recordResonanceScore(score: number): void {
42
+ function recordResonanceScore(score) {
76
43
  if (!Number.isFinite(score)) return;
77
44
  const state = loadState();
78
45
  state.scores.push(score);
79
- // Trim to window size
80
46
  if (state.scores.length > WINDOW_SIZE) {
81
47
  state.scores = state.scores.slice(-WINDOW_SIZE);
82
48
  }
83
49
  cached = state;
84
50
  saveState(state);
85
51
  }
52
+ export {
53
+ getAdaptiveThreshold,
54
+ recordResonanceScore
55
+ };
56
+ //# sourceMappingURL=resonance-state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/resonance-state.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\n/**\n * Adaptive Resonance Threshold\n *\n * Maintains a sliding window of recent auto-recall top-1 cosine scores\n * to compute an adaptive resonance gate threshold (P25 of the window).\n * Persisted to ~/.openclaw/memory/resonance-state.json.\n */\n\nimport { readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, dirname } from \"node:path\";\n\nconst STATE_PATH = join(homedir(), \".openclaw\", \"memory\", \"resonance-state.json\");\nconst WINDOW_SIZE = 100;\nconst COLD_START_MIN = 20;\nconst DEFAULT_THRESHOLD = 0.45;\nconst THRESHOLD_FLOOR = 0.30;\nconst THRESHOLD_CEILING = 0.60;\n\ninterface ResonanceStateData {\n scores: number[];\n}\n\nlet cached: ResonanceStateData | null = null;\n\nfunction loadState(): ResonanceStateData {\n if (cached) return cached;\n try {\n const raw = readFileSync(STATE_PATH, \"utf8\");\n const parsed = JSON.parse(raw);\n if (parsed && Array.isArray(parsed.scores)) {\n cached = { scores: parsed.scores.filter((s: unknown) => typeof s === \"number\" && Number.isFinite(s as number)).slice(-WINDOW_SIZE) };\n return cached;\n }\n } catch {\n // file doesn't exist or is corrupted \u2014 start fresh\n }\n cached = { scores: [] };\n return cached;\n}\n\nfunction saveState(state: ResonanceStateData): void {\n try {\n mkdirSync(dirname(STATE_PATH), { recursive: true });\n writeFileSync(STATE_PATH, JSON.stringify(state), \"utf8\");\n } catch {\n // best-effort persistence\n }\n}\n\n/**\n * Get the adaptive resonance threshold.\n * - Cold start (< 20 samples): returns default 0.45\n * - Otherwise: P25 of sliding window, clamped to [0.30, 0.60]\n */\nexport function getAdaptiveThreshold(): number {\n const state = loadState();\n if (state.scores.length < COLD_START_MIN) {\n return DEFAULT_THRESHOLD;\n }\n\n // Compute P25 (25th percentile)\n const sorted = [...state.scores].sort((a, b) => a - b);\n const idx = Math.floor(sorted.length * 0.25);\n const p25 = sorted[idx];\n\n return Math.min(THRESHOLD_CEILING, Math.max(THRESHOLD_FLOOR, p25));\n}\n\n/**\n * Record a top-1 cosine score from an auto-recall probe.\n * Appends to the sliding window and persists.\n */\nexport function recordResonanceScore(score: number): void {\n if (!Number.isFinite(score)) return;\n const state = loadState();\n state.scores.push(score);\n // Trim to window size\n if (state.scores.length > WINDOW_SIZE) {\n state.scores = state.scores.slice(-WINDOW_SIZE);\n }\n cached = state;\n saveState(state);\n}\n"],
5
+ "mappings": "AASA,SAAS,cAAc,eAAe,iBAAiB;AACvD,SAAS,eAAe;AACxB,SAAS,MAAM,eAAe;AAE9B,MAAM,aAAa,KAAK,QAAQ,GAAG,aAAa,UAAU,sBAAsB;AAChF,MAAM,cAAc;AACpB,MAAM,iBAAiB;AACvB,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAM1B,IAAI,SAAoC;AAExC,SAAS,YAAgC;AACvC,MAAI,OAAQ,QAAO;AACnB,MAAI;AACF,UAAM,MAAM,aAAa,YAAY,MAAM;AAC3C,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,UAAU,MAAM,QAAQ,OAAO,MAAM,GAAG;AAC1C,eAAS,EAAE,QAAQ,OAAO,OAAO,OAAO,CAAC,MAAe,OAAO,MAAM,YAAY,OAAO,SAAS,CAAW,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE;AACnI,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AACA,WAAS,EAAE,QAAQ,CAAC,EAAE;AACtB,SAAO;AACT;AAEA,SAAS,UAAU,OAAiC;AAClD,MAAI;AACF,cAAU,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,kBAAc,YAAY,KAAK,UAAU,KAAK,GAAG,MAAM;AAAA,EACzD,QAAQ;AAAA,EAER;AACF;AAOO,SAAS,uBAA+B;AAC7C,QAAM,QAAQ,UAAU;AACxB,MAAI,MAAM,OAAO,SAAS,gBAAgB;AACxC,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,CAAC,GAAG,MAAM,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACrD,QAAM,MAAM,KAAK,MAAM,OAAO,SAAS,IAAI;AAC3C,QAAM,MAAM,OAAO,GAAG;AAEtB,SAAO,KAAK,IAAI,mBAAmB,KAAK,IAAI,iBAAiB,GAAG,CAAC;AACnE;AAMO,SAAS,qBAAqB,OAAqB;AACxD,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG;AAC7B,QAAM,QAAQ,UAAU;AACxB,QAAM,OAAO,KAAK,KAAK;AAEvB,MAAI,MAAM,OAAO,SAAS,aAAa;AACrC,UAAM,SAAS,MAAM,OAAO,MAAM,CAAC,WAAW;AAAA,EAChD;AACA,WAAS;AACT,YAAU,KAAK;AACjB;",
6
+ "names": []
7
+ }