@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,327 @@
1
+ import { SOURCE_LABELS } from '../../memory/types.js';
2
+ import { configError } from '../../utils/errors.js';
3
+ import { logger } from '../../logging/logger.js';
4
+ import { RECALL_LIMIT_MULTIPLIER, VECTOR_SCORE_WEIGHT, MEMORY_SCORE_WEIGHT, } from '../../memory/recall.js';
5
+ // QC-R2-11:sourceHealth() + suggest() 已提取到 MemoryAdvisor
6
+ import { MemoryAdvisor } from '../../agent/managers/memoryAdvisor.js';
7
+ // ─── 常量 ────────────────────────────────────────────────
8
+ /** 工作记忆预览条数(最近 N 条) */
9
+ const WORKING_PREVIEW = 5;
10
+ /** 内容预览字符数(快照层) */
11
+ const CONTENT_PREVIEW_LEN = 80;
12
+ /** 搜索结果内容预览字符数(比快照层略长,便于用户判断相关性) */
13
+ const SEARCH_PREVIEW_LEN = 120;
14
+ // ─── 类 ──────────────────────────────────────────────────
15
+ export class MemoryInspector {
16
+ index;
17
+ loop;
18
+ history;
19
+ /** 向量存储(可选,提供时 searchHybrid 启用语义搜索) */
20
+ vectorStore = null;
21
+ /** 关系存储(可选,ADR-014 侧车,未注入时跳过关系查询) */
22
+ relationStore;
23
+ /** 记忆顾问(QC-R2-11:sourceHealth + suggest 委托) */
24
+ advisor;
25
+ /**
26
+ * @param index - 记忆存储(用于搜索 + 统计)
27
+ * @param loop - AgentLoop(用于获取工作记忆)
28
+ * @param history - MessageHistory(用于获取当前会话信息)
29
+ * @param relationStore - 关系存储侧车(可选,ADR-014,未注入时关系相关方法降级返回空)
30
+ */
31
+ constructor(index, loop, history, relationStore = null) {
32
+ this.index = index;
33
+ this.loop = loop;
34
+ this.history = history;
35
+ this.relationStore = relationStore;
36
+ // QC-R2-11:记忆顾问共享 index 引用(只读访问)
37
+ this.advisor = new MemoryAdvisor(index);
38
+ }
39
+ /**
40
+ * 注入向量存储(由 Agent 在初始化后调用,解决构造时序)
41
+ */
42
+ setVectorStore(vs) {
43
+ this.vectorStore = vs;
44
+ }
45
+ // ─── 写操作代理 ───────────────────────────────────────
46
+ // 宿主项目通过 agent.memory 访问写操作,
47
+ // 无需绕过 inspector 直接访问 agent.storage(分层违规)。
48
+ // 代理方法内部委托给 this.index(IMemoryStorage 实例)。
49
+ /**
50
+ * 插入或更新记忆
51
+ *
52
+ * @param memory 完整记忆对象
53
+ */
54
+ upsert(memory) {
55
+ this.index.upsert(memory);
56
+ }
57
+ /**
58
+ * 删除记忆
59
+ *
60
+ * @param id 记忆唯一标识(${source}:${name} 格式)
61
+ */
62
+ delete(id) {
63
+ this.index.delete(id);
64
+ }
65
+ /**
66
+ * 按 ID 获取单条记忆
67
+ *
68
+ * @param id 记忆唯一标识
69
+ * @returns 记忆对象,不存在时返回 null
70
+ */
71
+ getById(id) {
72
+ return this.index.getById(id);
73
+ }
74
+ /**
75
+ * 按来源标签获取记忆列表
76
+ *
77
+ * @param source 来源标签(如 'persona'、'rule'、'insight')
78
+ * @returns 该来源的所有记忆
79
+ */
80
+ getBySource(source) {
81
+ return this.index.getBySource(source);
82
+ }
83
+ /**
84
+ * 列出所有记忆(用于宿主项目的记忆管理面板)
85
+ *
86
+ * 与 search() 不同,本方法允许空查询,返回按 score 降序排列的记忆列表。
87
+ * search() 拒绝空查询是为了防止"静默全量返回"的误用;
88
+ * list() 则是显式声明"我要列出所有记忆"的意图。
89
+ *
90
+ * @param limit 返回数量上限(默认 50)
91
+ * @returns 记忆列表(按 score 降序)
92
+ */
93
+ list(limit = 50) {
94
+ return this.index.search('', limit);
95
+ }
96
+ // ─── 快照 ─────────────────────────────────────────────
97
+ /**
98
+ * 统一查看记忆快照(3 层)
99
+ *
100
+ * 简化为 3 层(工作记忆 / Bootstrap / 归档记忆)。
101
+ *
102
+ * 设计原则:
103
+ * - **纯只读**——不动任何组件状态
104
+ * - **同步返回**——避免数据不一致(不调 LLM、不调 SQLite)
105
+ * - **轻量**——每层只返回前 N 条 + 总数
106
+ */
107
+ snapshot() {
108
+ // 第 1 层:工作记忆(AgentLoop 的 messages 数组)
109
+ const workingFull = this.loop.getMessages();
110
+ const workingTotal = workingFull.length;
111
+ const working = workingFull.slice(-WORKING_PREVIEW);
112
+ // 第 2 层:Bootstrap 记忆(永驻 + 领域)
113
+ // 直接按 source 查询,避免 search('', 50) 全量扫描
114
+ const rules = this.index.getBySource(SOURCE_LABELS.RULE);
115
+ const personas = this.index.getBySource(SOURCE_LABELS.PERSONA);
116
+ const skills = this.index.getBySource(SOURCE_LABELS.SKILL);
117
+ const bootstrap = [...rules, ...personas, ...skills];
118
+ // 第 3 层:归档记忆计数(insight + profile + work-projection)
119
+ const insightCount = this.index.countBySource(SOURCE_LABELS.INSIGHT);
120
+ const profileCount = this.index.countBySource(SOURCE_LABELS.PROFILE);
121
+ const workProjectionCount = this.index.countBySource(SOURCE_LABELS.WORK_PROJECTION);
122
+ const archiveTotal = insightCount + profileCount + workProjectionCount;
123
+ return {
124
+ working: {
125
+ total: workingTotal,
126
+ preview: working.map((m) => ({
127
+ role: m.role,
128
+ contentPreview: m.content.slice(0, CONTENT_PREVIEW_LEN),
129
+ contentLength: m.content.length,
130
+ })),
131
+ },
132
+ bootstrap: {
133
+ total: bootstrap.length,
134
+ items: bootstrap.map((m) => ({
135
+ id: m.id,
136
+ source: m.source,
137
+ name: m.name,
138
+ contentPreview: m.content.slice(0, CONTENT_PREVIEW_LEN),
139
+ score: m.score,
140
+ })),
141
+ },
142
+ archive: {
143
+ archiveCount: archiveTotal,
144
+ // ADR-014 关系边总数(relationStore 未注入时为 0)
145
+ relationCount: this.countRelations(),
146
+ currentSession: this.history.session ?? '(none)',
147
+ currentSessionName: this.history.currentSessionName ?? '(none)',
148
+ hint: '调 listAllSessions() 获取文件清单',
149
+ stats: {
150
+ insight: insightCount,
151
+ profile: profileCount,
152
+ 'work-projection': workProjectionCount,
153
+ },
154
+ },
155
+ };
156
+ }
157
+ // ─── 搜索 ─────────────────────────────────────────────
158
+ /**
159
+ * 搜索记忆(关键词 + FTS5 索引)
160
+ *
161
+ * 返回 CLI 友好的扁平结构(已处理内容截断)
162
+ */
163
+ search(query, limit = 10) {
164
+ // 空 query 会让 search() 退化为"返回所有",对宿主程序是静默误导
165
+ if (!query || query.trim() === '') {
166
+ throw configError('搜索关键词为空', 'search() 需要非空 query', [
167
+ '传入非空字符串关键词',
168
+ '使用 snapshot().bootstrap.items 列出所有引导记忆',
169
+ ]);
170
+ }
171
+ if (limit <= 0 || !Number.isInteger(limit)) {
172
+ throw configError('无效 limit', `limit 必须是正整数,收到 ${limit}`, [
173
+ '使用 limit = 10(默认值)',
174
+ ]);
175
+ }
176
+ const hits = this.index.search(query, limit);
177
+ return hits.map((m) => ({
178
+ id: m.id,
179
+ name: m.name,
180
+ source: m.source,
181
+ score: m.score,
182
+ // 截断长内容到搜索预览长度
183
+ contentPreview: m.content.length > SEARCH_PREVIEW_LEN ? m.content.slice(0, SEARCH_PREVIEW_LEN) + '...' : m.content,
184
+ createdAt: m.createdAt,
185
+ }));
186
+ }
187
+ /**
188
+ * 混合搜索记忆(语义 + 关键词双通道)
189
+ *
190
+ * V-101:当 VectorStore 可用时,启用语义搜索通道,补强关键词召回的语义缺口。
191
+ * 向量搜索失败时静默降级到纯关键词(降级优先原则)。
192
+ *
193
+ * @returns 混合排序后的搜索结果(含相似度分数)
194
+ */
195
+ async searchHybrid(query, limit = 10) {
196
+ if (!query || query.trim() === '') {
197
+ throw configError('搜索关键词为空', 'searchHybrid() 需要非空 query', [
198
+ '传入非空字符串关键词',
199
+ ]);
200
+ }
201
+ if (limit <= 0 || !Number.isInteger(limit)) {
202
+ throw configError('无效 limit', `limit 必须是正整数,收到 ${limit}`, [
203
+ '使用 limit = 10(默认值)',
204
+ ]);
205
+ }
206
+ const merged = new Map();
207
+ // ── 通道 1:语义搜索(VectorStore 可用时) ──
208
+ if (this.vectorStore && this.vectorStore.size > 0) {
209
+ try {
210
+ const vectorResults = await this.vectorStore.search(query, limit * RECALL_LIMIT_MULTIPLIER, 0.3);
211
+ for (const vr of vectorResults) {
212
+ const memory = this.index.getById(vr.id);
213
+ if (memory) {
214
+ merged.set(memory.id, { memory, vectorScore: vr.similarity });
215
+ }
216
+ }
217
+ }
218
+ catch (err) {
219
+ logger.debug({ err }, '语义搜索失败,降级到关键词');
220
+ }
221
+ }
222
+ // ── 通道 2:关键词搜索(补齐语义通道未覆盖的) ──
223
+ const keywordResults = this.index.search(query, limit * RECALL_LIMIT_MULTIPLIER);
224
+ for (const m of keywordResults) {
225
+ if (!merged.has(m.id)) {
226
+ merged.set(m.id, { memory: m, vectorScore: 0 });
227
+ }
228
+ }
229
+ // ── 综合排序:vectorScore(语义相关度)+ memory.score(权重) ──
230
+ const sorted = [...merged.values()].sort((a, b) => {
231
+ const scoreA = a.vectorScore * VECTOR_SCORE_WEIGHT + a.memory.score * MEMORY_SCORE_WEIGHT;
232
+ const scoreB = b.vectorScore * VECTOR_SCORE_WEIGHT + b.memory.score * MEMORY_SCORE_WEIGHT;
233
+ return scoreB - scoreA;
234
+ });
235
+ return sorted.slice(0, limit).map(({ memory, vectorScore }) => ({
236
+ id: memory.id,
237
+ name: memory.name,
238
+ source: memory.source,
239
+ score: memory.score,
240
+ similarity: vectorScore,
241
+ contentPreview: memory.content.length > SEARCH_PREVIEW_LEN ? memory.content.slice(0, SEARCH_PREVIEW_LEN) + '...' : memory.content,
242
+ createdAt: memory.createdAt,
243
+ }));
244
+ }
245
+ // ─── 统计 ─────────────────────────────────────────────
246
+ /**
247
+ * 记忆库统计
248
+ *
249
+ * 返回记忆来源分布、数据库大小等关键指标。
250
+ * P2-2 优化:使用 getAllSources() 一次查询替代多次 countBySource + 全量 search,
251
+ * 复杂度从 O(n*knownSources + n) 降为 O(distinctSources)。
252
+ */
253
+ stats() {
254
+ const total = this.index.count();
255
+ // P2-2 直接使用 getAllSources() 获取所有 source 分布(含宿主自定义标签)
256
+ const sourceMap = this.index.getAllSources();
257
+ const bySource = {};
258
+ for (const [source, count] of sourceMap) {
259
+ if (count > 0)
260
+ bySource[source] = count;
261
+ }
262
+ return { bySource, total, relationCount: this.countRelations() };
263
+ }
264
+ // ─── 关系查询(ADR-014 侧车) ───────────────────────────
265
+ /**
266
+ * 查询指定记忆的关系边
267
+ *
268
+ * ADR-014 侧车模型:关系数据独立于 Memory 7 字段基元,存储在 IMemoryRelationStore。
269
+ * relationStore 未注入时返回空数组(向后兼容)。
270
+ *
271
+ * @param memoryId - 记忆 ID
272
+ * @param direction - 方向过滤:'outgoing'(出边)/ 'incoming'(入边)/ 'both'(双向,默认)
273
+ * @returns 关系边数组,按 createdAt 降序
274
+ */
275
+ getRelations(memoryId, direction = 'both') {
276
+ if (!this.relationStore)
277
+ return [];
278
+ return this.relationStore.getRelations(memoryId, direction);
279
+ }
280
+ /**
281
+ * 查询全部关系边
282
+ *
283
+ * 用于宿主 UI 渲染拓扑可视化(阶段 2.4)。
284
+ * relationStore 未注入时返回空数组(向后兼容)。
285
+ *
286
+ * @returns 全部关系边数组
287
+ */
288
+ getAllRelations() {
289
+ if (!this.relationStore)
290
+ return [];
291
+ return this.relationStore.getAllRelations();
292
+ }
293
+ /**
294
+ * 统计关系边总数
295
+ *
296
+ * 用于 stats() 和 snapshot() 的 relationCount 字段。
297
+ * relationStore 未注入时返回 0(向后兼容)。
298
+ */
299
+ countRelations() {
300
+ if (!this.relationStore)
301
+ return 0;
302
+ return this.relationStore.getAllRelations().length;
303
+ }
304
+ // ─── 源健康诊断 + 关联推荐(QC-R2-11:委托给 MemoryAdvisor) ───
305
+ /**
306
+ * 记忆源健康诊断(委托给 MemoryAdvisor)
307
+ *
308
+ * 为每个 source 计算健康指标(数量、平均 score、新鲜度、状态)。
309
+ * 实现已迁移至 MemoryAdvisor(QC-R2-11),此处保留委托以维持 API 契约。
310
+ */
311
+ sourceHealth() {
312
+ return this.advisor.sourceHealth();
313
+ }
314
+ /**
315
+ * 关联推荐(委托给 MemoryAdvisor)
316
+ *
317
+ * 基于 score + 时效性 + source 多样性推荐记忆。
318
+ * 实现已迁移至 MemoryAdvisor(QC-R2-11),此处保留委托以维持 API 契约。
319
+ *
320
+ * @param query - 可选的搜索关键词(提供时结合搜索结果推荐,省略时基于全局热度推荐)
321
+ * @param options - 推荐选项
322
+ */
323
+ suggest(query, options) {
324
+ return this.advisor.suggest(query, options);
325
+ }
326
+ }
327
+ //# sourceMappingURL=memoryInspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryInspector.js","sourceRoot":"","sources":["../../../src/agent/managers/memoryInspector.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAQlD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,yDAAyD;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAgBlE,0DAA0D;AAE1D,uBAAuB;AACvB,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,mBAAmB;AACnB,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,oCAAoC;AACpC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAoF/B,2DAA2D;AAE3D,MAAM,OAAO,eAAe;IAeP;IACA;IACA;IAhBnB,uCAAuC;IAC/B,WAAW,GAAuB,IAAI,CAAC;IAC/C,qCAAqC;IACpB,aAAa,CAA8B;IAC5D,+CAA+C;IAC9B,OAAO,CAAgB;IAExC;;;;;OAKG;IACH,YACmB,KAAqB,EACrB,IAAe,EACf,OAAuB,EACxC,gBAA6C,IAAI;QAHhC,UAAK,GAAL,KAAK,CAAgB;QACrB,SAAI,GAAJ,IAAI,CAAW;QACf,YAAO,GAAP,OAAO,CAAgB;QAGxC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,iCAAiC;QACjC,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,EAAsB;QACnC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACxB,CAAC;IAED,oDAAoD;IACpD,6BAA6B;IAC7B,2CAA2C;IAC3C,2CAA2C;IAE3C;;;;OAIG;IACH,MAAM,CAAC,MAAc;QACnB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,EAAU;QACf,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;;OASG;IACH,IAAI,CAAC,KAAK,GAAG,EAAE;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,uDAAuD;IAEvD;;;;;;;;;OASG;IACH,QAAQ;QACN,sCAAsC;QACtC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC;QACxC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,CAAC;QAEpD,8BAA8B;QAC9B,uCAAuC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC;QAErD,oDAAoD;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACrE,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACrE,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;QACpF,MAAM,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,mBAAmB,CAAC;QAEvE,OAAO;YACL,OAAO,EAAE;gBACP,KAAK,EAAE,YAAY;gBACnB,OAAO,EAAE,OAAO,CAAC,GAAG,CAClB,CAAC,CAAsE,EAAE,EAAE,CAAC,CAAC;oBAC3E,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;oBACvD,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM;iBAChC,CAAC,CACH;aACF;YACD,SAAS,EAAE;gBACT,KAAK,EAAE,SAAS,CAAC,MAAM;gBACvB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC;oBACnC,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC;oBACvD,KAAK,EAAE,CAAC,CAAC,KAAK;iBACf,CAAC,CAAC;aACJ;YACD,OAAO,EAAE;gBACP,YAAY,EAAE,YAAY;gBAC1B,uCAAuC;gBACvC,aAAa,EAAE,IAAI,CAAC,cAAc,EAAE;gBACpC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,QAAQ;gBAChD,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,kBAAkB,IAAI,QAAQ;gBAC/D,IAAI,EAAE,4BAA4B;gBAClC,KAAK,EAAE;oBACL,OAAO,EAAE,YAAY;oBACrB,OAAO,EAAE,YAAY;oBACrB,iBAAiB,EAAE,mBAAmB;iBACvC;aACF;SACF,CAAC;IACJ,CAAC;IAED,uDAAuD;IAEvD;;;;OAIG;IACH,MAAM,CAAC,KAAa,EAAE,KAAK,GAAG,EAAE;QAC9B,2CAA2C;QAC3C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAClC,MAAM,WAAW,CAAC,SAAS,EAAE,qBAAqB,EAAE;gBAClD,YAAY;gBACZ,wCAAwC;aACzC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,MAAM,WAAW,CAAC,UAAU,EAAE,mBAAmB,KAAK,EAAE,EAAE;gBACxD,oBAAoB;aACrB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC;YAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,eAAe;YACf,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;YAClH,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,KAAK,GAAG,EAAE;QAC1C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAClC,MAAM,WAAW,CAAC,SAAS,EAAE,2BAA2B,EAAE;gBACxD,YAAY;aACb,CAAC,CAAC;QACL,CAAC;QACD,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,MAAM,WAAW,CAAC,UAAU,EAAE,mBAAmB,KAAK,EAAE,EAAE;gBACxD,oBAAoB;aACrB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmD,CAAC;QAE1E,mCAAmC;QACnC,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,uBAAuB,EAAE,GAAG,CAAC,CAAC;gBACjG,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;oBAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;oBACzC,IAAI,MAAM,EAAE,CAAC;wBACX,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;oBAChE,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,uBAAuB,CAAC,CAAC;QACjF,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;QAED,kDAAkD;QAClD,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAChD,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,GAAG,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC1F,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,GAAG,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,mBAAmB,CAAC;YAC1F,OAAO,MAAM,GAAG,MAAM,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;YAC9D,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,UAAU,EAAE,WAAW;YACvB,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO;YACjI,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,uDAAuD;IAEvD;;;;;;OAMG;IACH,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAEjC,qDAAqD;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;YACxC,IAAI,KAAK,GAAG,CAAC;gBAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;QAC1C,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;IACnE,CAAC;IAED,mDAAmD;IAEnD;;;;;;;;;OASG;IACH,YAAY,CAAC,QAAgB,EAAE,YAA+B,MAAM;QAClE,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;;;OAOG;IACH,eAAe;QACb,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACK,cAAc;QACpB,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC;IACrD,CAAC;IAED,mDAAmD;IAEnD;;;;;OAKG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;IACrC,CAAC;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,KAAc,EAAE,OAAwB;QAC9C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * 会话管理器
3
+ *
4
+ * 从 Agent 类中提取会话管理职责(ADR-010 §Agent 类拆分)。
5
+ * 负责会话切换、分叉、恢复和消息加载,通过回调函数访问 Agent 的当前组件状态,
6
+ * 避免与 Agent 的 history/loop 引用生命周期耦合。
7
+ *
8
+ * Agent 通过组合方式持有 SessionManager 实例,将会话相关操作委托给它。
9
+ */
10
+ import type { AgentLoop } from '../../agent/loop.js';
11
+ import type { MessageHistory } from '../../agent/messageHistory.js';
12
+ import type { SessionMessage } from '../../memory/sessionStore.js';
13
+ import type { ISessionStore } from '../../memory/sessionStore.js';
14
+ /**
15
+ * Agent.forkSession() 返回值类型
16
+ *
17
+ * 注意:与 MessageHistory.forkSession() 的内部返回类型 ForkResult 不同,
18
+ * Agent 层做了简化封装,只暴露宿主需要的 newSession 和 messageCount。
19
+ */
20
+ export interface AgentForkResult {
21
+ /** 新分支会话名(不含日期前缀的简短名,可直接传给 switchSession()) */
22
+ newSession: string;
23
+ /** 分叉时复制的消息数量 */
24
+ messageCount: number;
25
+ }
26
+ /**
27
+ * 会话管理器
28
+ *
29
+ * 通过回调函数访问 Agent 的当前组件状态,支持 Agent 重建组件后自动获取最新引用。
30
+ */
31
+ export declare class SessionManager {
32
+ /** 获取当前 MessageHistory 实例的回调 */
33
+ private getHistory;
34
+ /** 获取当前 AgentLoop 实例的回调 */
35
+ private getLoop;
36
+ /** 会话存储(可选,由宿主注入) */
37
+ private sessionStore;
38
+ /** 检查对话是否繁忙的回调 */
39
+ private isChatBusy;
40
+ /** 发射事件(委托给 Agent 的 TypedEventEmitter) */
41
+ private emitEvent;
42
+ constructor(getHistory: () => MessageHistory, getLoop: () => AgentLoop, sessionStore: ISessionStore | undefined, isChatBusy: () => boolean, emitEvent: (event: string, data: Record<string, unknown>) => void);
43
+ /**
44
+ * 切换当前会话
45
+ *
46
+ * 与 forkSession() 对齐:底层 MessageHistory.switchSession 是纯同步操作(字段赋值),
47
+ * Agent 层不引入无意义的 async 包装。返回新会话名。
48
+ */
49
+ switchSession(newSession: string): string;
50
+ /**
51
+ * 分叉当前会话:复制完整消息历史到新分支,切换到新分支继续对话
52
+ *
53
+ * 分叉后:
54
+ * - 原会话完整保留,可随时通过 switchSession() 切回(用原会话简短名)
55
+ * - 新分支拥有独立的消息历史,后续对话互不干扰
56
+ * - 记忆索引(IMemoryStorage)全局共享,不受分叉影响
57
+ *
58
+ * **注意**:fork 不隔离记忆。分支 A 中提取的 insight 会在分支 B
59
+ * 的召回中出现,反之亦然。如需要完全独立的记忆空间(如多用户场景),
60
+ * 应创建独立 Agent 实例 + 独立 dataDir,而非 fork。
61
+ *
62
+ * @param targetSession - 自定义新分支名(可选,不传则自动生成)
63
+ * @returns { newSession, messageCount }
64
+ */
65
+ forkSession(targetSession?: string): AgentForkResult;
66
+ /**
67
+ * 恢复最近的会话对话
68
+ *
69
+ * 通过 ISessionStore 加载最近的会话消息,恢复到 AgentLoop 工作记忆。
70
+ * 宿主项目需注入 ISessionStore 实现,否则返回 0。
71
+ */
72
+ restoreMostRecentSession(preferredSession?: string): Promise<number>;
73
+ /**
74
+ * 恢复指定会话的对话
75
+ */
76
+ restoreSession(date: string, session: string): Promise<number>;
77
+ /**
78
+ * 对外暴露的 loadSessionMessages 委托
79
+ *
80
+ * **注意:此方法会切换当前会话**(更新 currentDate/currentSession)。
81
+ * 加载后,下一次 chat() 的消息会写入被加载的会话。
82
+ */
83
+ loadSessionMessages(date: string, session: string): Promise<SessionMessage[]>;
84
+ /**
85
+ * 将会话消息恢复到 AgentLoop 工作记忆
86
+ */
87
+ private applySessionToLoop;
88
+ }
89
+ //# sourceMappingURL=sessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.d.ts","sourceRoot":"","sources":["../../../src/agent/managers/sessionManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG9D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,gCAAgC;IAChC,OAAO,CAAC,UAAU,CAAuB;IACzC,2BAA2B;IAC3B,OAAO,CAAC,OAAO,CAAkB;IACjC,qBAAqB;IACrB,OAAO,CAAC,YAAY,CAA4B;IAChD,kBAAkB;IAClB,OAAO,CAAC,UAAU,CAAgB;IAClC,0CAA0C;IAC1C,OAAO,CAAC,SAAS,CAAyD;gBAGxE,UAAU,EAAE,MAAM,cAAc,EAChC,OAAO,EAAE,MAAM,SAAS,EACxB,YAAY,EAAE,aAAa,GAAG,SAAS,EACvC,UAAU,EAAE,MAAM,OAAO,EACzB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI;IASnE;;;;;OAKG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAWzC;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,eAAe;IA+BpD;;;;;OAKG;IACG,wBAAwB,CAAC,gBAAgB,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAiD1E;;OAEG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBpE;;;;;OAKG;IACG,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAWnF;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAS3B"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * 会话管理器
3
+ *
4
+ * 从 Agent 类中提取会话管理职责(ADR-010 §Agent 类拆分)。
5
+ * 负责会话切换、分叉、恢复和消息加载,通过回调函数访问 Agent 的当前组件状态,
6
+ * 避免与 Agent 的 history/loop 引用生命周期耦合。
7
+ *
8
+ * Agent 通过组合方式持有 SessionManager 实例,将会话相关操作委托给它。
9
+ */
10
+ import { logger } from '../../logging/logger.js';
11
+ import { configError } from '../../utils/errors.js';
12
+ /**
13
+ * 会话管理器
14
+ *
15
+ * 通过回调函数访问 Agent 的当前组件状态,支持 Agent 重建组件后自动获取最新引用。
16
+ */
17
+ export class SessionManager {
18
+ /** 获取当前 MessageHistory 实例的回调 */
19
+ getHistory;
20
+ /** 获取当前 AgentLoop 实例的回调 */
21
+ getLoop;
22
+ /** 会话存储(可选,由宿主注入) */
23
+ sessionStore;
24
+ /** 检查对话是否繁忙的回调 */
25
+ isChatBusy;
26
+ /** 发射事件(委托给 Agent 的 TypedEventEmitter) */
27
+ emitEvent;
28
+ constructor(getHistory, getLoop, sessionStore, isChatBusy, emitEvent) {
29
+ this.getHistory = getHistory;
30
+ this.getLoop = getLoop;
31
+ this.sessionStore = sessionStore;
32
+ this.isChatBusy = isChatBusy;
33
+ this.emitEvent = emitEvent;
34
+ }
35
+ /**
36
+ * 切换当前会话
37
+ *
38
+ * 与 forkSession() 对齐:底层 MessageHistory.switchSession 是纯同步操作(字段赋值),
39
+ * Agent 层不引入无意义的 async 包装。返回新会话名。
40
+ */
41
+ switchSession(newSession) {
42
+ // FD-31: 对话进行中切换会话会导致消息持久化分散
43
+ if (this.isChatBusy()) {
44
+ throw configError('对话繁忙', '上一轮对话尚未完成,请等待其结束后再切换会话', [
45
+ '等待上一轮 chat() 的 AsyncGenerator 耗尽',
46
+ ]);
47
+ }
48
+ return this.getHistory().switchSession(newSession);
49
+ }
50
+ /**
51
+ * 分叉当前会话:复制完整消息历史到新分支,切换到新分支继续对话
52
+ *
53
+ * 分叉后:
54
+ * - 原会话完整保留,可随时通过 switchSession() 切回(用原会话简短名)
55
+ * - 新分支拥有独立的消息历史,后续对话互不干扰
56
+ * - 记忆索引(IMemoryStorage)全局共享,不受分叉影响
57
+ *
58
+ * **注意**:fork 不隔离记忆。分支 A 中提取的 insight 会在分支 B
59
+ * 的召回中出现,反之亦然。如需要完全独立的记忆空间(如多用户场景),
60
+ * 应创建独立 Agent 实例 + 独立 dataDir,而非 fork。
61
+ *
62
+ * @param targetSession - 自定义新分支名(可选,不传则自动生成)
63
+ * @returns { newSession, messageCount }
64
+ */
65
+ forkSession(targetSession) {
66
+ if (this.isChatBusy()) {
67
+ throw configError('对话繁忙', '上一轮对话尚未完成,请等待其结束后再分叉', [
68
+ '等待上一轮 chat() 的 AsyncGenerator 耗尽',
69
+ ]);
70
+ }
71
+ const history = this.getHistory();
72
+ // 记录源会话名(用于事件,含日期前缀的完整名)
73
+ const sourceSessionName = history.currentSessionName;
74
+ // 委托 MessageHistory 完成分叉
75
+ const result = history.forkSession(targetSession);
76
+ // 将消息恢复到 AgentLoop 的工作记忆
77
+ this.applySessionToLoop(result.messages);
78
+ // 发射事件(供 UI 响应)
79
+ this.emitEvent('sessionForked', {
80
+ from: sourceSessionName,
81
+ to: `${result.date}-${result.newSession}`,
82
+ messageCount: result.messages.length,
83
+ });
84
+ return {
85
+ newSession: result.newSession,
86
+ messageCount: result.messages.length,
87
+ };
88
+ }
89
+ /**
90
+ * 恢复最近的会话对话
91
+ *
92
+ * 通过 ISessionStore 加载最近的会话消息,恢复到 AgentLoop 工作记忆。
93
+ * 宿主项目需注入 ISessionStore 实现,否则返回 0。
94
+ */
95
+ async restoreMostRecentSession(preferredSession = 'main') {
96
+ // FD-21: 对话进行中恢复会话会导致 loop 工作记忆被替换
97
+ if (this.isChatBusy()) {
98
+ throw configError('对话繁忙', '上一轮对话尚未完成,请等待其结束后再恢复会话', [
99
+ '等待上一轮 chat() 的 AsyncGenerator 耗尽',
100
+ ]);
101
+ }
102
+ if (!this.sessionStore) {
103
+ logger.debug({ hasSessionStore: false }, '未注入 ISessionStore,无法恢复会话');
104
+ return 0;
105
+ }
106
+ // 从 sessionStore 列出所有会话,找到最近的
107
+ const sessions = this.sessionStore.listSessions();
108
+ if (sessions.length === 0) {
109
+ logger.debug({ sessionCount: 0 }, '没有找到可恢复的历史会话');
110
+ return 0;
111
+ }
112
+ // 优先匹配 preferredSession,否则取最后一个
113
+ const today = new Date().toISOString().slice(0, 10);
114
+ const preferred = sessions.find((s) => s === `${today}-${preferredSession}`) ?? sessions[sessions.length - 1];
115
+ // 解析 "YYYY-MM-DD-session" 格式
116
+ const match = (preferred ?? '').match(/^(\d{4}-\d{2}-\d{2})-(.+)$/);
117
+ if (!match) {
118
+ logger.debug({ session: preferred }, '会话标识格式不匹配');
119
+ return 0;
120
+ }
121
+ const [, date, session] = match;
122
+ // match 已经保证 date 和 session 存在(正则匹配两个捕获组),但 TypeScript 类型收窄有限
123
+ if (!date || !session) {
124
+ logger.debug({ session: preferred }, '会话标识解析失败');
125
+ return 0;
126
+ }
127
+ const sessionMessages = this.sessionStore.loadMessages(date, session);
128
+ if (sessionMessages.length === 0) {
129
+ logger.debug({ messageCount: 0 }, '没有找到可恢复的历史会话');
130
+ return 0;
131
+ }
132
+ this.applySessionToLoop(sessionMessages);
133
+ return sessionMessages.length;
134
+ }
135
+ /**
136
+ * 恢复指定会话的对话
137
+ */
138
+ async restoreSession(date, session) {
139
+ // FD-21: 对话进行中恢复会话会导致 loop 工作记忆被替换
140
+ if (this.isChatBusy()) {
141
+ throw configError('对话繁忙', '上一轮对话尚未完成,请等待其结束后再恢复会话', [
142
+ '等待上一轮 chat() 的 AsyncGenerator 耗尽',
143
+ ]);
144
+ }
145
+ const sessionMessages = await this.getHistory().loadSessionMessages(date, session);
146
+ if (sessionMessages.length === 0) {
147
+ return 0;
148
+ }
149
+ this.applySessionToLoop(sessionMessages);
150
+ return sessionMessages.length;
151
+ }
152
+ /**
153
+ * 对外暴露的 loadSessionMessages 委托
154
+ *
155
+ * **注意:此方法会切换当前会话**(更新 currentDate/currentSession)。
156
+ * 加载后,下一次 chat() 的消息会写入被加载的会话。
157
+ */
158
+ async loadSessionMessages(date, session) {
159
+ // FD-34: 对话进行中加载会话会切换 currentDate/currentSession,导致消息持久化分散
160
+ if (this.isChatBusy()) {
161
+ throw configError('对话繁忙', '上一轮对话尚未完成,请等待其结束后再加载会话', [
162
+ '等待上一轮 chat() 的 AsyncGenerator 耗尽',
163
+ ]);
164
+ }
165
+ return this.getHistory().loadSessionMessages(date, session);
166
+ }
167
+ /**
168
+ * 将会话消息恢复到 AgentLoop 工作记忆
169
+ */
170
+ applySessionToLoop(sessionMessages) {
171
+ const messages = sessionMessages.map((tm) => ({
172
+ role: tm.role,
173
+ content: tm.content,
174
+ }));
175
+ this.getLoop().restoreHistory(messages);
176
+ }
177
+ }
178
+ //# sourceMappingURL=sessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.js","sourceRoot":"","sources":["../../../src/agent/managers/sessionManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * 用户事实提取器 — 从对话输入中提取结构化用户画像
3
+ *
4
+ * 职责:
5
+ * - 正则 + 关键词规则提取用户身份、偏好、专长等事实
6
+ * - 输出结构化 ExtractedFact,供 UserProfile 归档
7
+ *
8
+ * 设计原则:
9
+ * - 语义解析属于 agent/ 层,memory/ 只做存储
10
+ * - 兼顾阶段一低成本需求(正则规则),后续可升级为 LLM 提取
11
+ */
12
+ import type { ExtractedFact } from '../../memory/userProfile.js';
13
+ export type { ExtractedFact } from '../../memory/userProfile.js';
14
+ /**
15
+ * 从用户输入中提取事实
16
+ *
17
+ * 使用正则 + 关键词规则,兼顾阶段一的低成本需求。
18
+ * 高置信度规则(≥0.9)→ 直接归档
19
+ * 中置信度(0.7-0.8)→ 标记待确认
20
+ *
21
+ * @param input 用户原始输入
22
+ * @param turnIndex 当前轮次标识
23
+ */
24
+ export declare function extractUserFacts(input: string, turnIndex: string): ExtractedFact[];
25
+ //# sourceMappingURL=userFactExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userFactExtractor.d.ts","sourceRoot":"","sources":["../../../src/agent/managers/userFactExtractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAgFlF"}