@zooique/memora 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -0
  3. package/dist/agent/agent.d.ts +343 -0
  4. package/dist/agent/agent.d.ts.map +1 -0
  5. package/dist/agent/agent.js +893 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/assembler.d.ts +77 -0
  8. package/dist/agent/assembler.d.ts.map +1 -0
  9. package/dist/agent/assembler.js +115 -0
  10. package/dist/agent/assembler.js.map +1 -0
  11. package/dist/agent/builtinToolHandlers.d.ts +96 -0
  12. package/dist/agent/builtinToolHandlers.d.ts.map +1 -0
  13. package/dist/agent/builtinToolHandlers.js +388 -0
  14. package/dist/agent/builtinToolHandlers.js.map +1 -0
  15. package/dist/agent/builtinTools.d.ts +35 -0
  16. package/dist/agent/builtinTools.d.ts.map +1 -0
  17. package/dist/agent/builtinTools.js +75 -0
  18. package/dist/agent/builtinTools.js.map +1 -0
  19. package/dist/agent/constants.d.ts +67 -0
  20. package/dist/agent/constants.d.ts.map +1 -0
  21. package/dist/agent/constants.js +67 -0
  22. package/dist/agent/constants.js.map +1 -0
  23. package/dist/agent/contextManager.d.ts +130 -0
  24. package/dist/agent/contextManager.d.ts.map +1 -0
  25. package/dist/agent/contextManager.js +287 -0
  26. package/dist/agent/contextManager.js.map +1 -0
  27. package/dist/agent/loop.d.ts +288 -0
  28. package/dist/agent/loop.d.ts.map +1 -0
  29. package/dist/agent/loop.js +756 -0
  30. package/dist/agent/loop.js.map +1 -0
  31. package/dist/agent/managers/autoConfigRefiner.d.ts +39 -0
  32. package/dist/agent/managers/autoConfigRefiner.d.ts.map +1 -0
  33. package/dist/agent/managers/autoConfigRefiner.js +150 -0
  34. package/dist/agent/managers/autoConfigRefiner.js.map +1 -0
  35. package/dist/agent/managers/configManager.d.ts +114 -0
  36. package/dist/agent/managers/configManager.d.ts.map +1 -0
  37. package/dist/agent/managers/configManager.js +186 -0
  38. package/dist/agent/managers/configManager.js.map +1 -0
  39. package/dist/agent/managers/insightExtractor.d.ts +141 -0
  40. package/dist/agent/managers/insightExtractor.d.ts.map +1 -0
  41. package/dist/agent/managers/insightExtractor.js +420 -0
  42. package/dist/agent/managers/insightExtractor.js.map +1 -0
  43. package/dist/agent/managers/memoryAdvisor.d.ts +96 -0
  44. package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -0
  45. package/dist/agent/managers/memoryAdvisor.js +198 -0
  46. package/dist/agent/managers/memoryAdvisor.js.map +1 -0
  47. package/dist/agent/managers/memoryInspector.d.ts +231 -0
  48. package/dist/agent/managers/memoryInspector.d.ts.map +1 -0
  49. package/dist/agent/managers/memoryInspector.js +327 -0
  50. package/dist/agent/managers/memoryInspector.js.map +1 -0
  51. package/dist/agent/managers/sessionManager.d.ts +89 -0
  52. package/dist/agent/managers/sessionManager.d.ts.map +1 -0
  53. package/dist/agent/managers/sessionManager.js +178 -0
  54. package/dist/agent/managers/sessionManager.js.map +1 -0
  55. package/dist/agent/managers/userFactExtractor.d.ts +25 -0
  56. package/dist/agent/managers/userFactExtractor.d.ts.map +1 -0
  57. package/dist/agent/managers/userFactExtractor.js +81 -0
  58. package/dist/agent/managers/userFactExtractor.js.map +1 -0
  59. package/dist/agent/managers/workProjection.d.ts +117 -0
  60. package/dist/agent/managers/workProjection.d.ts.map +1 -0
  61. package/dist/agent/managers/workProjection.js +290 -0
  62. package/dist/agent/managers/workProjection.js.map +1 -0
  63. package/dist/agent/messageHistory.d.ts +157 -0
  64. package/dist/agent/messageHistory.d.ts.map +1 -0
  65. package/dist/agent/messageHistory.js +288 -0
  66. package/dist/agent/messageHistory.js.map +1 -0
  67. package/dist/agent/toolExecutor.d.ts +137 -0
  68. package/dist/agent/toolExecutor.d.ts.map +1 -0
  69. package/dist/agent/toolExecutor.js +209 -0
  70. package/dist/agent/toolExecutor.js.map +1 -0
  71. package/dist/agent/tracer.d.ts +122 -0
  72. package/dist/agent/tracer.d.ts.map +1 -0
  73. package/dist/agent/tracer.js +64 -0
  74. package/dist/agent/tracer.js.map +1 -0
  75. package/dist/agent/types.d.ts +98 -0
  76. package/dist/agent/types.d.ts.map +1 -0
  77. package/dist/agent/types.js +19 -0
  78. package/dist/agent/types.js.map +1 -0
  79. package/dist/config/loader.d.ts +229 -0
  80. package/dist/config/loader.d.ts.map +1 -0
  81. package/dist/config/loader.js +194 -0
  82. package/dist/config/loader.js.map +1 -0
  83. package/dist/eval/evalTypes.d.ts +118 -0
  84. package/dist/eval/evalTypes.d.ts.map +1 -0
  85. package/dist/eval/evalTypes.js +102 -0
  86. package/dist/eval/evalTypes.js.map +1 -0
  87. package/dist/index.d.ts +61 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +44 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/llm/embedding.d.ts +62 -0
  92. package/dist/llm/embedding.d.ts.map +1 -0
  93. package/dist/llm/embedding.js +162 -0
  94. package/dist/llm/embedding.js.map +1 -0
  95. package/dist/llm/factory.d.ts +39 -0
  96. package/dist/llm/factory.d.ts.map +1 -0
  97. package/dist/llm/factory.js +108 -0
  98. package/dist/llm/factory.js.map +1 -0
  99. package/dist/llm/openaiCompatible.d.ts +63 -0
  100. package/dist/llm/openaiCompatible.d.ts.map +1 -0
  101. package/dist/llm/openaiCompatible.js +340 -0
  102. package/dist/llm/openaiCompatible.js.map +1 -0
  103. package/dist/llm/provider.d.ts +91 -0
  104. package/dist/llm/provider.d.ts.map +1 -0
  105. package/dist/llm/provider.js +14 -0
  106. package/dist/llm/provider.js.map +1 -0
  107. package/dist/llm/types.d.ts +25 -0
  108. package/dist/llm/types.d.ts.map +1 -0
  109. package/dist/llm/types.js +7 -0
  110. package/dist/llm/types.js.map +1 -0
  111. package/dist/logging/logger.d.ts +39 -0
  112. package/dist/logging/logger.d.ts.map +1 -0
  113. package/dist/logging/logger.js +279 -0
  114. package/dist/logging/logger.js.map +1 -0
  115. package/dist/logging/loggerInterface.d.ts +33 -0
  116. package/dist/logging/loggerInterface.d.ts.map +1 -0
  117. package/dist/logging/loggerInterface.js +2 -0
  118. package/dist/logging/loggerInterface.js.map +1 -0
  119. package/dist/memory/inMemoryRelationStore.d.ts +51 -0
  120. package/dist/memory/inMemoryRelationStore.d.ts.map +1 -0
  121. package/dist/memory/inMemoryRelationStore.js +65 -0
  122. package/dist/memory/inMemoryRelationStore.js.map +1 -0
  123. package/dist/memory/inMemoryStorage.d.ts +97 -0
  124. package/dist/memory/inMemoryStorage.d.ts.map +1 -0
  125. package/dist/memory/inMemoryStorage.js +177 -0
  126. package/dist/memory/inMemoryStorage.js.map +1 -0
  127. package/dist/memory/loader.d.ts +49 -0
  128. package/dist/memory/loader.d.ts.map +1 -0
  129. package/dist/memory/loader.js +93 -0
  130. package/dist/memory/loader.js.map +1 -0
  131. package/dist/memory/projectManager.d.ts +182 -0
  132. package/dist/memory/projectManager.d.ts.map +1 -0
  133. package/dist/memory/projectManager.js +441 -0
  134. package/dist/memory/projectManager.js.map +1 -0
  135. package/dist/memory/recall.d.ts +77 -0
  136. package/dist/memory/recall.d.ts.map +1 -0
  137. package/dist/memory/recall.js +147 -0
  138. package/dist/memory/recall.js.map +1 -0
  139. package/dist/memory/relationStore.d.ts +78 -0
  140. package/dist/memory/relationStore.d.ts.map +1 -0
  141. package/dist/memory/relationStore.js +2 -0
  142. package/dist/memory/relationStore.js.map +1 -0
  143. package/dist/memory/sessionStore.d.ts +84 -0
  144. package/dist/memory/sessionStore.d.ts.map +1 -0
  145. package/dist/memory/sessionStore.js +2 -0
  146. package/dist/memory/sessionStore.js.map +1 -0
  147. package/dist/memory/storageInterface.d.ts +107 -0
  148. package/dist/memory/storageInterface.d.ts.map +1 -0
  149. package/dist/memory/storageInterface.js +2 -0
  150. package/dist/memory/storageInterface.js.map +1 -0
  151. package/dist/memory/store.d.ts +50 -0
  152. package/dist/memory/store.d.ts.map +1 -0
  153. package/dist/memory/store.js +160 -0
  154. package/dist/memory/store.js.map +1 -0
  155. package/dist/memory/types.d.ts +189 -0
  156. package/dist/memory/types.d.ts.map +1 -0
  157. package/dist/memory/types.js +230 -0
  158. package/dist/memory/types.js.map +1 -0
  159. package/dist/memory/userProfile.d.ts +156 -0
  160. package/dist/memory/userProfile.d.ts.map +1 -0
  161. package/dist/memory/userProfile.js +315 -0
  162. package/dist/memory/userProfile.js.map +1 -0
  163. package/dist/memory/vectorStore.d.ts +75 -0
  164. package/dist/memory/vectorStore.d.ts.map +1 -0
  165. package/dist/memory/vectorStore.js +144 -0
  166. package/dist/memory/vectorStore.js.map +1 -0
  167. package/dist/persona/personaManager.d.ts +121 -0
  168. package/dist/persona/personaManager.d.ts.map +1 -0
  169. package/dist/persona/personaManager.js +349 -0
  170. package/dist/persona/personaManager.js.map +1 -0
  171. package/dist/persona/types.d.ts +32 -0
  172. package/dist/persona/types.d.ts.map +1 -0
  173. package/dist/persona/types.js +5 -0
  174. package/dist/persona/types.js.map +1 -0
  175. package/dist/security/pathGuard.d.ts +121 -0
  176. package/dist/security/pathGuard.d.ts.map +1 -0
  177. package/dist/security/pathGuard.js +276 -0
  178. package/dist/security/pathGuard.js.map +1 -0
  179. package/dist/skill/skillManager.d.ts +82 -0
  180. package/dist/skill/skillManager.d.ts.map +1 -0
  181. package/dist/skill/skillManager.js +198 -0
  182. package/dist/skill/skillManager.js.map +1 -0
  183. package/dist/skill/types.d.ts +28 -0
  184. package/dist/skill/types.d.ts.map +1 -0
  185. package/dist/skill/types.js +5 -0
  186. package/dist/skill/types.js.map +1 -0
  187. package/dist/utils/errors.d.ts +86 -0
  188. package/dist/utils/errors.d.ts.map +1 -0
  189. package/dist/utils/errors.js +143 -0
  190. package/dist/utils/errors.js.map +1 -0
  191. package/dist/utils/eventEmitter.d.ts +87 -0
  192. package/dist/utils/eventEmitter.d.ts.map +1 -0
  193. package/dist/utils/eventEmitter.js +79 -0
  194. package/dist/utils/eventEmitter.js.map +1 -0
  195. package/dist/utils/frontmatter.d.ts +24 -0
  196. package/dist/utils/frontmatter.d.ts.map +1 -0
  197. package/dist/utils/frontmatter.js +44 -0
  198. package/dist/utils/frontmatter.js.map +1 -0
  199. package/dist/utils/json.d.ts +20 -0
  200. package/dist/utils/json.d.ts.map +1 -0
  201. package/dist/utils/json.js +65 -0
  202. package/dist/utils/json.js.map +1 -0
  203. package/dist/utils/loggerHolder.d.ts +37 -0
  204. package/dist/utils/loggerHolder.d.ts.map +1 -0
  205. package/dist/utils/loggerHolder.js +49 -0
  206. package/dist/utils/loggerHolder.js.map +1 -0
  207. package/dist/utils/math.d.ts +5 -0
  208. package/dist/utils/math.d.ts.map +1 -0
  209. package/dist/utils/math.js +19 -0
  210. package/dist/utils/math.js.map +1 -0
  211. package/dist/utils/path.d.ts +28 -0
  212. package/dist/utils/path.d.ts.map +1 -0
  213. package/dist/utils/path.js +33 -0
  214. package/dist/utils/path.js.map +1 -0
  215. package/dist/utils/safeTimer.d.ts +26 -0
  216. package/dist/utils/safeTimer.d.ts.map +1 -0
  217. package/dist/utils/safeTimer.js +49 -0
  218. package/dist/utils/safeTimer.js.map +1 -0
  219. package/dist/utils/scanner.d.ts +54 -0
  220. package/dist/utils/scanner.d.ts.map +1 -0
  221. package/dist/utils/scanner.js +115 -0
  222. package/dist/utils/scanner.js.map +1 -0
  223. package/dist/utils/segmenter.d.ts +30 -0
  224. package/dist/utils/segmenter.d.ts.map +1 -0
  225. package/dist/utils/segmenter.js +80 -0
  226. package/dist/utils/segmenter.js.map +1 -0
  227. package/dist/utils/strings.d.ts +18 -0
  228. package/dist/utils/strings.d.ts.map +1 -0
  229. package/dist/utils/strings.js +25 -0
  230. package/dist/utils/strings.js.map +1 -0
  231. package/dist/utils/time.d.ts +23 -0
  232. package/dist/utils/time.d.ts.map +1 -0
  233. package/dist/utils/time.js +31 -0
  234. package/dist/utils/time.js.map +1 -0
  235. package/dist/utils/toError.d.ts +13 -0
  236. package/dist/utils/toError.d.ts.map +1 -0
  237. package/dist/utils/toError.js +22 -0
  238. package/dist/utils/toError.js.map +1 -0
  239. package/package.json +73 -0
@@ -0,0 +1,279 @@
1
+ import { statSync, truncateSync } from 'node:fs';
2
+ import { toError } from '../utils/toError.js';
3
+ // 桥接 utils 层 loggerHolder:utils 运行时不依赖 logging/,
4
+ // 由本模块在加载和 setLogger 时反向注入 logger 实例。
5
+ import { setLogger as setUtilsLogger } from '../utils/loggerHolder.js';
6
+ /**
7
+ * 从 unknown 值提取错误消息(复用零依赖的 toError,避免类型断言)
8
+ */
9
+ function errMsg(err) {
10
+ return toError(err).message;
11
+ }
12
+ /** 日志级别(从环境变量读取,默认 info) */
13
+ const level = process.env['MEMORA_LOG_LEVEL'] ?? 'info';
14
+ /** 敏感键模式(匹配时值被替换为 [REDACTED]) */
15
+ const SENSITIVE_KEY_PATTERN = /api[_-]?key|token|password|secret|authorization|credential/i;
16
+ /**
17
+ * pino redact 路径配置(与 console fallback 的 SENSITIVE_KEY_PATTERN 保持一致)
18
+ *
19
+ * 支持嵌套对象脱敏:`*.apiKey` 匹配任意层级的 apiKey 字段
20
+ */
21
+ const PINO_REDACT_PATHS = [
22
+ 'apiKey', 'token', 'password', 'secret', 'authorization', 'credential',
23
+ '*.apiKey', '*.token', '*.password', '*.secret',
24
+ '*.authorization', '*.credential',
25
+ '*.*.apiKey', '*.*.token', '*.*.password', '*.*.secret',
26
+ ];
27
+ /**
28
+ * 对象脱敏:深拷贝对象并将敏感键的值替换为 [REDACTED]
29
+ *
30
+ * 仅用于 console fallback logger 的 JSON.stringify 路径,
31
+ * 防止 API Key 等敏感数据泄漏到 stderr。
32
+ */
33
+ function redactSensitiveKeys(obj) {
34
+ const redacted = {};
35
+ for (const [key, value] of Object.entries(obj)) {
36
+ if (SENSITIVE_KEY_PATTERN.test(key)) {
37
+ redacted[key] = '[REDACTED]';
38
+ }
39
+ else if (value && typeof value === 'object' && !Array.isArray(value)) {
40
+ redacted[key] = redactSensitiveKeys(value);
41
+ }
42
+ else {
43
+ redacted[key] = value;
44
+ }
45
+ }
46
+ return redacted;
47
+ }
48
+ /** 是否生产环境 */
49
+ const isProd = process.env['NODE_ENV'] === 'production';
50
+ /** 是否启用文件日志 */
51
+ const fileEnabled = process.env['MEMORA_LOG_FILE'] !== '0';
52
+ /** 日志级别优先级(用于 console fallback 的级别过滤) */
53
+ const LEVEL_PRIORITY = {
54
+ trace: 0,
55
+ debug: 1,
56
+ info: 2,
57
+ warn: 3,
58
+ error: 4,
59
+ fatal: 5,
60
+ silent: 6,
61
+ };
62
+ /** 判断目标级别是否满足最低级别要求 */
63
+ function shouldLog(targetLevel) {
64
+ return (LEVEL_PRIORITY[targetLevel] ?? 2) >= (LEVEL_PRIORITY[level] ?? 2);
65
+ }
66
+ /**
67
+ * Console 零依赖 fallback logger
68
+ *
69
+ * pino 不可用时使用。仅输出到 stderr,不写文件。
70
+ * 满足 ILogger 接口,所有内核模块透明使用。
71
+ */
72
+ function createConsoleLogger() {
73
+ return {
74
+ info: (objOrMsg, msg) => {
75
+ if (!shouldLog('info'))
76
+ return;
77
+ const text = typeof objOrMsg === 'string' ? objOrMsg : msg ?? '';
78
+ if (typeof objOrMsg === 'object') {
79
+ console.error(`[INFO] ${text}`, JSON.stringify(redactSensitiveKeys(objOrMsg)));
80
+ }
81
+ else {
82
+ console.error(`[INFO] ${text}`);
83
+ }
84
+ },
85
+ warn: (objOrMsg, msg) => {
86
+ if (!shouldLog('warn'))
87
+ return;
88
+ const text = typeof objOrMsg === 'string' ? objOrMsg : msg ?? '';
89
+ if (typeof objOrMsg === 'object') {
90
+ console.error(`[WARN] ${text}`, JSON.stringify(redactSensitiveKeys(objOrMsg)));
91
+ }
92
+ else {
93
+ console.error(`[WARN] ${text}`);
94
+ }
95
+ },
96
+ error: (objOrMsg, msg) => {
97
+ if (!shouldLog('error'))
98
+ return;
99
+ const text = typeof objOrMsg === 'string' ? objOrMsg : msg ?? '';
100
+ if (typeof objOrMsg === 'object') {
101
+ console.error(`[ERROR] ${text}`, JSON.stringify(redactSensitiveKeys(objOrMsg)));
102
+ }
103
+ else {
104
+ console.error(`[ERROR] ${text}`);
105
+ }
106
+ },
107
+ debug: (objOrMsg, msg) => {
108
+ if (!shouldLog('debug'))
109
+ return;
110
+ const text = typeof objOrMsg === 'string' ? objOrMsg : msg ?? '';
111
+ if (typeof objOrMsg === 'object') {
112
+ console.error(`[DEBUG] ${text}`, JSON.stringify(redactSensitiveKeys(objOrMsg)));
113
+ }
114
+ else {
115
+ console.error(`[DEBUG] ${text}`);
116
+ }
117
+ },
118
+ };
119
+ }
120
+ /**
121
+ * pino → ILogger 包装器
122
+ *
123
+ * pino 通过动态 import 加载,实例类型未知。
124
+ * 包装器显式提取 4 个日志方法,避免 as unknown as ILogger 双重断言。
125
+ *
126
+ * @param pinoInst pino 实例(动态导入)
127
+ * @returns ILogger 兼容对象
128
+ */
129
+ function wrapPinoAsLogger(pinoInst) {
130
+ return {
131
+ info: pinoInst.info.bind(pinoInst),
132
+ warn: pinoInst.warn.bind(pinoInst),
133
+ error: pinoInst.error.bind(pinoInst),
134
+ debug: pinoInst.debug.bind(pinoInst),
135
+ };
136
+ }
137
+ /**
138
+ * 尝试创建 Pino logger
139
+ *
140
+ * pino 为可选 peerDependency,通过动态 import 加载。
141
+ * 加载失败(宿主未安装 pino)则回退到 console logger。
142
+ *
143
+ * @returns Pino logger 实例,或 null(pino 不可用)
144
+ */
145
+ async function tryCreatePinoLogger() {
146
+ try {
147
+ const pino = (await import('pino')).default;
148
+ const { resolve } = await import('node:path');
149
+ const { mkdirSync, createWriteStream } = await import('node:fs');
150
+ const { expandHome } = await import('../utils/path.js');
151
+ const dataDir = process.env['MEMORA_DATA_DIR'] ?? '~/.memora';
152
+ const resolvedDataDir = resolve(expandHome(dataDir));
153
+ // pino.StreamEntry 类型在 pino 未安装时不可用,用内联类型
154
+ const streams = [];
155
+ // stderr 流(开发环境友好显示)
156
+ if (!isProd) {
157
+ streams.push({ level: 'info', stream: process.stderr });
158
+ }
159
+ // 文件流(结构化 JSON,方便后续分析)
160
+ // SEC-06: 日志轮转保护——超过 10MB 时截断重写,防止长期运行生成巨大文件
161
+ if (fileEnabled) {
162
+ try {
163
+ const logsDir = resolve(resolvedDataDir, 'logs');
164
+ mkdirSync(logsDir, { recursive: true });
165
+ const logFilePath = resolve(logsDir, 'memora.log');
166
+ // 检查文件大小,超过 10MB 时截断
167
+ const LOG_MAX_BYTES = 10 * 1024 * 1024; // 10MB
168
+ try {
169
+ const stat = statSync(logFilePath);
170
+ if (stat.size > LOG_MAX_BYTES) {
171
+ truncateSync(logFilePath, 0);
172
+ process.stderr.write(`[memora] 日志文件超过 10MB,已截断:${logFilePath}\n`);
173
+ }
174
+ }
175
+ catch (err) {
176
+ // 文件不存在或无法 stat,正常——首次写入
177
+ if (process.env['MEMORA_DEBUG'])
178
+ process.stderr.write(`[memora] stat 日志文件失败:${errMsg(err)}\n`);
179
+ }
180
+ streams.push({
181
+ level: 'info',
182
+ stream: createWriteStream(logFilePath, { flags: 'a' }),
183
+ });
184
+ }
185
+ catch (err) {
186
+ process.stderr.write(`[memora] 日志文件创建失败:${errMsg(err)}\n`);
187
+ }
188
+ }
189
+ if (streams.length === 0) {
190
+ // 通过包装器适配 ILogger 接口,避免 as unknown as ILogger 双重断言
191
+ // SEC-AUDIT: 配置 redact 防止敏感信息写入日志文件
192
+ return wrapPinoAsLogger(pino({ level, redact: PINO_REDACT_PATHS }));
193
+ }
194
+ // 通过包装器适配 ILogger 接口
195
+ // SEC-AUDIT: 配置 redact 防止敏感信息写入日志文件
196
+ return wrapPinoAsLogger(pino({ level, redact: PINO_REDACT_PATHS }, pino.multistream(streams)));
197
+ }
198
+ catch (err) {
199
+ // pino 未安装,回退到 console logger
200
+ if (process.env['MEMORA_DEBUG'])
201
+ process.stderr.write(`[memora] pino 加载失败:${errMsg(err)}\n`);
202
+ return null;
203
+ }
204
+ }
205
+ /**
206
+ * 全局日志单例
207
+ *
208
+ * 初始化为 console fallback,模块顶层异步尝试加载 pino。
209
+ * 宿主通过 setLogger() 注入后自动替换。
210
+ */
211
+ let _logger = createConsoleLogger();
212
+ /** 标记 _logger 是否已被宿主注入(用于 setLogger 覆盖检测) */
213
+ let _loggerInjected = false;
214
+ // 同步初始化 utils 层 logger 桥接(确保 utils 在 pino 异步加载前就有 console fallback)
215
+ setUtilsLogger(_logger);
216
+ // 模块加载时异步尝试升级到 pino(不阻塞模块导入)
217
+ void tryCreatePinoLogger().then((pinoLogger) => {
218
+ if (pinoLogger) {
219
+ _logger = pinoLogger;
220
+ _logger.info({ level, prod: isProd, fileEnabled }, 'logger 启动(pino)');
221
+ }
222
+ else {
223
+ _logger.info({ level, prod: isProd }, 'logger 启动(console fallback,pino 未安装)');
224
+ }
225
+ // 桥接注入到 utils 层(utils 运行时不依赖 logging/)
226
+ setUtilsLogger(_logger);
227
+ });
228
+ /**
229
+ * 全局日志访问器
230
+ *
231
+ * 20+ 个内核模块统一通过此变量输出日志。
232
+ * 宿主注入自定义 logger 后,所有模块自动使用新实现。
233
+ */
234
+ export const logger = {
235
+ get info() {
236
+ return _logger.info.bind(_logger);
237
+ },
238
+ get warn() {
239
+ return _logger.warn.bind(_logger);
240
+ },
241
+ get error() {
242
+ return _logger.error.bind(_logger);
243
+ },
244
+ get debug() {
245
+ return _logger.debug.bind(_logger);
246
+ },
247
+ };
248
+ /**
249
+ * 替换全局日志实现
250
+ *
251
+ * 宿主项目在 Agent 初始化前调用此函数注入自定义 logger。
252
+ * 传入 undefined 则恢复为默认(pino 或 console fallback)。
253
+ *
254
+ * 注意:此函数修改全局状态。在单 Agent 模型下(ADR-011),
255
+ * 同一进程只有一个 Agent 实例,不会冲突。若同一进程创建多个
256
+ * Agent 实例并分别注入 logger,后者会覆盖前者——此时会输出警告。
257
+ */
258
+ export function setLogger(newLogger) {
259
+ if (newLogger) {
260
+ // 检测覆盖:如果当前 logger 已被宿主注入,且新 logger 不是同一个,说明有多处注入
261
+ if (_loggerInjected && _logger !== newLogger) {
262
+ _logger.warn('setLogger 覆盖了已有的自定义 logger(单 Agent 模型下不应出现此情况)');
263
+ }
264
+ _loggerInjected = true;
265
+ _logger = newLogger;
266
+ }
267
+ else {
268
+ // 恢复默认:尝试 pino,否则 console
269
+ _loggerInjected = false;
270
+ void tryCreatePinoLogger().then((pinoLogger) => {
271
+ _logger = pinoLogger ?? createConsoleLogger();
272
+ // 桥接注入到 utils 层
273
+ setUtilsLogger(_logger);
274
+ });
275
+ }
276
+ // 同步桥接注入到 utils 层(覆盖异步路径,确保 setLogger 后立即生效)
277
+ setUtilsLogger(_logger);
278
+ }
279
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logging/logger.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,iDAAiD;AACjD,sCAAsC;AACtC,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEtE;;GAEG;AACH,SAAS,MAAM,CAAC,GAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;AAC9B,CAAC;AAED,4BAA4B;AAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,MAAM,CAAC;AAExD,iCAAiC;AACjC,MAAM,qBAAqB,GAAG,6DAA6D,CAAC;AAE5F;;;;GAIG;AACH,MAAM,iBAAiB,GAAG;IACxB,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY;IACtE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU;IAC/C,iBAAiB,EAAE,cAAc;IACjC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY;CACxD,CAAC;AAEF;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,GAA4B;IACvD,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;QAC/B,CAAC;aAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvE,QAAQ,CAAC,GAAG,CAAC,GAAG,mBAAmB,CAAC,KAAgC,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AACD,aAAa;AACb,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,CAAC;AACxD,eAAe;AACf,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,GAAG,CAAC;AAE3D,yCAAyC;AACzC,MAAM,cAAc,GAA2B;IAC7C,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,uBAAuB;AACvB,SAAS,SAAS,CAAC,WAAmB;IACpC,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB;IAC1B,OAAO;QACL,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;YACtB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;gBAAE,OAAO;YAC/B,MAAM,IAAI,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;YACjE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;YACtB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;gBAAE,OAAO;YAC/B,MAAM,IAAI,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;YACjE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,KAAK,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;YACvB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAAE,OAAO;YAChC,MAAM,IAAI,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;YACjE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QACD,KAAK,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;YACvB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAAE,OAAO;YAChC,MAAM,IAAI,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;YACjE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAClF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,gBAAgB,CAAC,QAKzB;IACC,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QAClC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QAClC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;QACpC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;KACrC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,mBAAmB;IAChC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACjE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAEvD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,WAAW,CAAC;QAC9D,MAAM,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAErD,0CAA0C;QAC1C,MAAM,OAAO,GAA4D,EAAE,CAAC;QAE5E,qBAAqB;QACrB,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,uBAAuB;QACvB,6CAA6C;QAC7C,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;gBACjD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACxC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;gBAEnD,qBAAqB;gBACrB,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO;gBAC/C,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;oBACnC,IAAI,IAAI,CAAC,IAAI,GAAG,aAAa,EAAE,CAAC;wBAC9B,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;wBAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,WAAW,IAAI,CAAC,CAAC;oBACpE,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,yBAAyB;oBACzB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;wBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACjG,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC;oBACX,KAAK,EAAE,MAAM;oBACb,MAAM,EAAE,iBAAiB,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;iBACvD,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,mDAAmD;YACnD,oCAAoC;YACpC,OAAO,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,qBAAqB;QACrB,oCAAoC;QACpC,OAAO,gBAAgB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjG,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,8BAA8B;QAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;YAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7F,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,IAAI,OAAO,GAAY,mBAAmB,EAAE,CAAC;AAE7C,6CAA6C;AAC7C,IAAI,eAAe,GAAG,KAAK,CAAC;AAE5B,oEAAoE;AACpE,cAAc,CAAC,OAAO,CAAC,CAAC;AAExB,6BAA6B;AAC7B,KAAK,mBAAmB,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE;IAC7C,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,GAAG,UAAU,CAAC;QACrB,OAAO,CAAC,IAAI,CACV,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,EACpC,iBAAiB,CAClB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CACV,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EACvB,sCAAsC,CACvC,CAAC;IACJ,CAAC;IACD,uCAAuC;IACvC,cAAc,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAY;IAC7B,IAAI,IAAI;QACN,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,IAAI;QACN,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,KAAK;QACP,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,KAAK;QACP,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;CACF,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,SAA8B;IACtD,IAAI,SAAS,EAAE,CAAC;QACd,kDAAkD;QAClD,IAAI,eAAe,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,CAAC,IAAI,CACV,gDAAgD,CACjD,CAAC;QACJ,CAAC;QACD,eAAe,GAAG,IAAI,CAAC;QACvB,OAAO,GAAG,SAAS,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,0BAA0B;QAC1B,eAAe,GAAG,KAAK,CAAC;QACxB,KAAK,mBAAmB,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE;YAC7C,OAAO,GAAG,UAAU,IAAI,mBAAmB,EAAE,CAAC;YAC9C,gBAAgB;YAChB,cAAc,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IACD,6CAA6C;IAC7C,cAAc,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 日志接口 — Memora 内核与日志实现的解耦边界
3
+ *
4
+ * 设计目标:
5
+ * - 宿主项目可注入自定义日志实现(如 Electron 的 winston/pino 实例)
6
+ * - 不注入时使用默认 PinoLogger(零配置)
7
+ * - 21 个内核模块通过全局单例 `logger` 访问,无需每次传参
8
+ *
9
+ * 日志级别语义(与 pino 对齐):
10
+ * - debug:调试信息(默认不输出)
11
+ * - info:正常运行信息
12
+ * - warn:非致命警告
13
+ * - error:错误(含堆栈信息)
14
+ *
15
+ * 签名兼容 pino:支持 `logger.info('msg')` 和 `logger.info({ ctx }, 'msg')`
16
+ */
17
+ export type LogFn = (objOrMsg: Record<string, unknown> | string, msg?: string) => void;
18
+ /**
19
+ * 日志接口
20
+ *
21
+ * 方法签名与 pino 兼容,实现者可以是:
22
+ * - pino 实例(默认)
23
+ * - console 包装
24
+ * - 自定义日志框架
25
+ * - 测试 mock
26
+ */
27
+ export interface ILogger {
28
+ info: LogFn;
29
+ warn: LogFn;
30
+ error: LogFn;
31
+ debug: LogFn;
32
+ }
33
+ //# sourceMappingURL=loggerInterface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loggerInterface.d.ts","sourceRoot":"","sources":["../../src/logging/loggerInterface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAEvF;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;CACd"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=loggerInterface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loggerInterface.js","sourceRoot":"","sources":["../../src/logging/loggerInterface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * InMemoryRelationStore — 内存关系存储测试用实现
3
+ *
4
+ * 职责:
5
+ * - 实现 IMemoryRelationStore 接口,纯内存数组存储
6
+ * - 用于单元测试和开发环境验证,不持久化
7
+ * - 与 InMemoryStorage 对齐,提供零 IO 的测试基座
8
+ *
9
+ * 设计原则(ADR-014):
10
+ * - 零 native 依赖:纯 JS 数组操作
11
+ * - 幂等添加:sourceId+targetId+type 三元组唯一,重复添加更新 weight/createdAt
12
+ * - 方向过滤:getRelations 按 direction 参数过滤 sourceId/targetId
13
+ *
14
+ * 宿主项目应实现 SqliteRelationStore(依赖 better-sqlite3)用于生产环境。
15
+ */
16
+ import type { MemoryRelation, RelationDirection } from '../memory/types.js';
17
+ import type { IMemoryRelationStore } from '../memory/relationStore.js';
18
+ export declare class InMemoryRelationStore implements IMemoryRelationStore {
19
+ /** 关系列表(内存数组,不持久化) */
20
+ private readonly relations;
21
+ /**
22
+ * 添加关系
23
+ *
24
+ * 三元组唯一约束:sourceId+targetId+type 已存在时更新 weight/createdAt(幂等)。
25
+ */
26
+ addRelation(relation: MemoryRelation): void;
27
+ /**
28
+ * 查询某记忆的关系
29
+ *
30
+ * direction 控制方向过滤:
31
+ * - 'outgoing':sourceId = memoryId
32
+ * - 'incoming':targetId = memoryId
33
+ * - 'both':合并两个方向并去重(基于对象引用)
34
+ */
35
+ getRelations(memoryId: string, direction?: RelationDirection): MemoryRelation[];
36
+ /**
37
+ * 按关系类型查询
38
+ */
39
+ getRelationsByType(type: string): MemoryRelation[];
40
+ /**
41
+ * 获取全部关系
42
+ */
43
+ getAllRelations(): MemoryRelation[];
44
+ /**
45
+ * 删除指定关系
46
+ *
47
+ * sourceId+targetId+type 唯一定位,删除单条关系。
48
+ */
49
+ removeRelation(sourceId: string, targetId: string, type: string): void;
50
+ }
51
+ //# sourceMappingURL=inMemoryRelationStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inMemoryRelationStore.d.ts","sourceRoot":"","sources":["../../src/memory/inMemoryRelationStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,qBAAa,qBAAsB,YAAW,oBAAoB;IAChE,sBAAsB;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAElD;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAe3C;;;;;;;OAOG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAE,iBAA0B,GAAG,cAAc,EAAE;IAavF;;OAEG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE;IAIlD;;OAEG;IACH,eAAe,IAAI,cAAc,EAAE;IAInC;;;;OAIG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAQvE"}
@@ -0,0 +1,65 @@
1
+ export class InMemoryRelationStore {
2
+ /** 关系列表(内存数组,不持久化) */
3
+ relations = [];
4
+ /**
5
+ * 添加关系
6
+ *
7
+ * 三元组唯一约束:sourceId+targetId+type 已存在时更新 weight/createdAt(幂等)。
8
+ */
9
+ addRelation(relation) {
10
+ const existingIdx = this.relations.findIndex((r) => r.sourceId === relation.sourceId &&
11
+ r.targetId === relation.targetId &&
12
+ r.type === relation.type);
13
+ if (existingIdx >= 0) {
14
+ // 幂等更新:保留原位置,覆盖 weight 和 createdAt
15
+ this.relations[existingIdx] = { ...relation };
16
+ }
17
+ else {
18
+ this.relations.push({ ...relation });
19
+ }
20
+ }
21
+ /**
22
+ * 查询某记忆的关系
23
+ *
24
+ * direction 控制方向过滤:
25
+ * - 'outgoing':sourceId = memoryId
26
+ * - 'incoming':targetId = memoryId
27
+ * - 'both':合并两个方向并去重(基于对象引用)
28
+ */
29
+ getRelations(memoryId, direction = 'both') {
30
+ if (direction === 'outgoing') {
31
+ return this.relations.filter((r) => r.sourceId === memoryId).map((r) => ({ ...r }));
32
+ }
33
+ if (direction === 'incoming') {
34
+ return this.relations.filter((r) => r.targetId === memoryId).map((r) => ({ ...r }));
35
+ }
36
+ // 'both':合并两个方向(每条关系最多匹配一次,无需去重)
37
+ return this.relations
38
+ .filter((r) => r.sourceId === memoryId || r.targetId === memoryId)
39
+ .map((r) => ({ ...r }));
40
+ }
41
+ /**
42
+ * 按关系类型查询
43
+ */
44
+ getRelationsByType(type) {
45
+ return this.relations.filter((r) => r.type === type).map((r) => ({ ...r }));
46
+ }
47
+ /**
48
+ * 获取全部关系
49
+ */
50
+ getAllRelations() {
51
+ return this.relations.map((r) => ({ ...r }));
52
+ }
53
+ /**
54
+ * 删除指定关系
55
+ *
56
+ * sourceId+targetId+type 唯一定位,删除单条关系。
57
+ */
58
+ removeRelation(sourceId, targetId, type) {
59
+ const idx = this.relations.findIndex((r) => r.sourceId === sourceId && r.targetId === targetId && r.type === type);
60
+ if (idx >= 0) {
61
+ this.relations.splice(idx, 1);
62
+ }
63
+ }
64
+ }
65
+ //# sourceMappingURL=inMemoryRelationStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inMemoryRelationStore.js","sourceRoot":"","sources":["../../src/memory/inMemoryRelationStore.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,qBAAqB;IAChC,sBAAsB;IACL,SAAS,GAAqB,EAAE,CAAC;IAElD;;;;OAIG;IACH,WAAW,CAAC,QAAwB;QAClC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAC1C,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;YAChC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ;YAChC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAC3B,CAAC;QACF,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;YACrB,mCAAmC;YACnC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,QAAgB,EAAE,YAA+B,MAAM;QAClE,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF,CAAC;QACD,iCAAiC;QACjC,OAAO,IAAI,CAAC,SAAS;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC;aACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,QAAgB,EAAE,QAAgB,EAAE,IAAY;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAC7E,CAAC;QACF,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * 内存存储实现 — IMemoryStorage 的纯 JS 内存实现
3
+ *
4
+ * 零依赖、零 IO,适用于:
5
+ * - 单元测试(不需要 better-sqlite3,不需要文件系统)
6
+ * - 宿主项目注入前的临时占位
7
+ * - 沙箱/演示环境
8
+ *
9
+ * 注意:此实现不持久化,进程退出后数据丢失。
10
+ * ⚠️ 仅限测试/开发使用,生产环境请注入 SqliteStorage(宿主项目提供)。
11
+ */
12
+ import type { IMemoryStorage } from '../memory/storageInterface.js';
13
+ import type { Memory } from '../memory/types.js';
14
+ /**
15
+ * 内存存储实现
16
+ *
17
+ * 使用 Map 存储记忆,核心操作 O(1)~O(log n)。
18
+ * P2-2 优化:维护 source→count 增量缓存,stats()/sourceHealth() 无需全量遍历。
19
+ */
20
+ export declare class InMemoryStorage implements IMemoryStorage {
21
+ /** 记忆存储(id → Memory) */
22
+ private memories;
23
+ /** P2-2 source→count 增量缓存(upsert/delete 时维护,getAllSources 时直接读取) */
24
+ private sourceCountCache;
25
+ /**
26
+ * 插入或更新记忆
27
+ *
28
+ * 自动校验 source 字段,对疑似 typo 发出警告日志。
29
+ * P2-2 增量维护 sourceCountCache:更新时旧 source 减 1、新 source 加 1。
30
+ */
31
+ upsert(memory: Memory): void;
32
+ /**
33
+ * 删除记忆
34
+ *
35
+ * P2-2 增量维护 sourceCountCache:删除时对应 source 减 1。
36
+ */
37
+ delete(id: string): void;
38
+ /**
39
+ * 按 ID 获取单条记忆
40
+ *
41
+ * 返回浅拷贝,避免调用方修改污染存储内部对象(接口契约:读取隔离)
42
+ */
43
+ getById(id: string): Memory | null;
44
+ /**
45
+ * 按来源标签获取记忆
46
+ *
47
+ * 返回浅拷贝数组,避免调用方修改污染存储内部对象。
48
+ *
49
+ * @param source - 来源标签(如 'persona'、'rule'、'insight')
50
+ * @returns 该来源的所有记忆(副本),按 score 降序排列
51
+ */
52
+ getBySource(source: string): Memory[];
53
+ /**
54
+ * 文本搜索(内存版)
55
+ *
56
+ * 使用 segmentText() 规范分词,与 SqliteStorage 行为一致。
57
+ * 搜索 content 和 name 字段,按 score 降序排列。
58
+ *
59
+ * @param query - 搜索查询文本
60
+ * @param limit - 返回数量上限(默认 10)
61
+ * @returns 匹配的记忆列表
62
+ */
63
+ search(query: string, limit?: number): Memory[];
64
+ /**
65
+ * 统计记忆总数
66
+ */
67
+ count(): number;
68
+ /**
69
+ * 按来源标签统计记忆数量
70
+ *
71
+ * P2-2 优化:直接读取 sourceCountCache,O(1) 复杂度(与 getAllSources 一致)
72
+ * 原实现 O(n) 遍历所有记忆,与增量缓存设计不一致
73
+ */
74
+ countBySource(source: string): number;
75
+ /**
76
+ * 衰减指定来源的记忆 score
77
+ *
78
+ * 遍历所有匹配 source 的记忆,按时间衰减。
79
+ * 生产环境宿主(SqliteStorage)应重写为 SQL UPDATE 批量操作。
80
+ */
81
+ decayScores(sources: string[], now: Date): number;
82
+ /**
83
+ * 获取所有 source 标签及其记忆数量
84
+ *
85
+ * P2-2 优化:直接读取增量维护的 sourceCountCache,O(1) 复杂度。
86
+ */
87
+ getAllSources(): Map<string, number>;
88
+ /**
89
+ * 关闭(内存实现无需关闭)
90
+ */
91
+ close(): void;
92
+ /** source 计数 +1 */
93
+ private incrementSourceCount;
94
+ /** source 计数 -1(减至 0 时移除键) */
95
+ private decrementSourceCount;
96
+ }
97
+ //# sourceMappingURL=inMemoryStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inMemoryStorage.d.ts","sourceRoot":"","sources":["../../src/memory/inMemoryStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAMhD;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,cAAc;IACpD,wBAAwB;IACxB,OAAO,CAAC,QAAQ,CAAkC;IAElD,oEAAoE;IACpE,OAAO,CAAC,gBAAgB,CAAkC;IAE1D;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAqB5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAQxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKlC;;;;;;;OAOG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAOrC;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE;IAiC3C;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIrC;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM;IAWjD;;;;OAIG;IACH,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIpC;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb,mBAAmB;IACnB,OAAO,CAAC,oBAAoB;IAI5B,8BAA8B;IAC9B,OAAO,CAAC,oBAAoB;CAS7B"}