@zooique/memora 2.0.0 → 2.0.3
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.
- package/README.en.md +272 -0
- package/README.md +150 -38
- package/dist/agent/agent.d.ts +233 -58
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +651 -359
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/assembler.d.ts +29 -13
- package/dist/agent/assembler.d.ts.map +1 -1
- package/dist/agent/assembler.js +79 -44
- package/dist/agent/assembler.js.map +1 -1
- package/dist/agent/builtinToolHandlers.d.ts +26 -1
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
- package/dist/agent/builtinToolHandlers.js +73 -1
- package/dist/agent/builtinToolHandlers.js.map +1 -1
- package/dist/agent/constants.d.ts +4 -0
- package/dist/agent/constants.d.ts.map +1 -1
- package/dist/agent/constants.js +4 -0
- package/dist/agent/constants.js.map +1 -1
- package/dist/agent/contextManager.d.ts +8 -0
- package/dist/agent/contextManager.d.ts.map +1 -1
- package/dist/agent/contextManager.js +7 -2
- package/dist/agent/contextManager.js.map +1 -1
- package/dist/agent/guardrail.d.ts +4 -2
- package/dist/agent/guardrail.d.ts.map +1 -1
- package/dist/agent/guardrail.js +13 -5
- package/dist/agent/guardrail.js.map +1 -1
- package/dist/agent/loop.d.ts +58 -14
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +184 -131
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/managers/archiveCoordinator.d.ts +126 -22
- package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -1
- package/dist/agent/managers/archiveCoordinator.js +239 -44
- package/dist/agent/managers/archiveCoordinator.js.map +1 -1
- package/dist/agent/managers/autoConfigRefiner.d.ts.map +1 -1
- package/dist/agent/managers/autoConfigRefiner.js +4 -8
- package/dist/agent/managers/autoConfigRefiner.js.map +1 -1
- package/dist/agent/managers/configManager.d.ts +87 -3
- package/dist/agent/managers/configManager.d.ts.map +1 -1
- package/dist/agent/managers/configManager.js +139 -2
- package/dist/agent/managers/configManager.js.map +1 -1
- package/dist/agent/managers/dedupManager.d.ts +169 -0
- package/dist/agent/managers/dedupManager.d.ts.map +1 -0
- package/dist/agent/managers/dedupManager.js +336 -0
- package/dist/agent/managers/dedupManager.js.map +1 -0
- package/dist/agent/managers/insightExtractor.d.ts.map +1 -1
- package/dist/agent/managers/insightExtractor.js +11 -11
- package/dist/agent/managers/insightExtractor.js.map +1 -1
- package/dist/agent/managers/llmJudgeHelper.d.ts +38 -0
- package/dist/agent/managers/llmJudgeHelper.d.ts.map +1 -0
- package/dist/agent/managers/llmJudgeHelper.js +49 -0
- package/dist/agent/managers/llmJudgeHelper.js.map +1 -0
- package/dist/agent/managers/memoryAdvisor.d.ts +3 -3
- package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -1
- package/dist/agent/managers/memoryAdvisor.js +53 -67
- package/dist/agent/managers/memoryAdvisor.js.map +1 -1
- package/dist/agent/managers/memoryDecayScheduler.d.ts +46 -5
- package/dist/agent/managers/memoryDecayScheduler.d.ts.map +1 -1
- package/dist/agent/managers/memoryDecayScheduler.js +127 -63
- package/dist/agent/managers/memoryDecayScheduler.js.map +1 -1
- package/dist/agent/managers/memoryGovernance.d.ts +56 -0
- package/dist/agent/managers/memoryGovernance.d.ts.map +1 -0
- package/dist/agent/managers/memoryGovernance.js +63 -0
- package/dist/agent/managers/memoryGovernance.js.map +1 -0
- package/dist/agent/managers/memoryInspector.d.ts +32 -157
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
- package/dist/agent/managers/memoryInspector.js +70 -363
- package/dist/agent/managers/memoryInspector.js.map +1 -1
- package/dist/agent/managers/relationBuilder.js +2 -2
- package/dist/agent/managers/relationBuilder.js.map +1 -1
- package/dist/agent/managers/sessionArchiver.d.ts +6 -1
- package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
- package/dist/agent/managers/sessionArchiver.js +19 -22
- package/dist/agent/managers/sessionArchiver.js.map +1 -1
- package/dist/agent/managers/streamAccumulator.d.ts +45 -0
- package/dist/agent/managers/streamAccumulator.d.ts.map +1 -0
- package/dist/agent/managers/streamAccumulator.js +40 -0
- package/dist/agent/managers/streamAccumulator.js.map +1 -0
- package/dist/agent/managers/textPolishManager.d.ts.map +1 -1
- package/dist/agent/managers/textPolishManager.js +4 -7
- package/dist/agent/managers/textPolishManager.js.map +1 -1
- package/dist/agent/managers/workProjection.d.ts +16 -1
- package/dist/agent/managers/workProjection.d.ts.map +1 -1
- package/dist/agent/managers/workProjection.js +48 -24
- package/dist/agent/managers/workProjection.js.map +1 -1
- package/dist/agent/toolExecutor.d.ts +22 -2
- package/dist/agent/toolExecutor.d.ts.map +1 -1
- package/dist/agent/toolExecutor.js +28 -3
- package/dist/agent/toolExecutor.js.map +1 -1
- package/dist/agent/types.d.ts +10 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/userFactExtractor.d.ts.map +1 -1
- package/dist/agent/userFactExtractor.js +7 -0
- package/dist/agent/userFactExtractor.js.map +1 -1
- package/dist/config/loader.d.ts +124 -236
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +273 -117
- package/dist/config/loader.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/embedding.d.ts +13 -1
- package/dist/llm/embedding.d.ts.map +1 -1
- package/dist/llm/embedding.js.map +1 -1
- package/dist/llm/factory.d.ts +19 -5
- package/dist/llm/factory.d.ts.map +1 -1
- package/dist/llm/factory.js +19 -37
- package/dist/llm/factory.js.map +1 -1
- package/dist/llm/openaiCompatible.d.ts.map +1 -1
- package/dist/llm/openaiCompatible.js +2 -9
- package/dist/llm/openaiCompatible.js.map +1 -1
- package/dist/logging/logger.d.ts +3 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +47 -50
- package/dist/logging/logger.js.map +1 -1
- package/dist/memory/governance.d.ts +50 -0
- package/dist/memory/governance.d.ts.map +1 -0
- package/dist/memory/governance.js +70 -0
- package/dist/memory/governance.js.map +1 -0
- package/dist/memory/hybridMerge.d.ts +0 -4
- package/dist/memory/hybridMerge.d.ts.map +1 -1
- package/dist/memory/hybridMerge.js +19 -4
- package/dist/memory/hybridMerge.js.map +1 -1
- package/dist/memory/inMemoryRelationStore.d.ts +7 -0
- package/dist/memory/inMemoryRelationStore.d.ts.map +1 -1
- package/dist/memory/inMemoryRelationStore.js +15 -0
- package/dist/memory/inMemoryRelationStore.js.map +1 -1
- package/dist/memory/inMemoryStorage.d.ts +36 -1
- package/dist/memory/inMemoryStorage.d.ts.map +1 -1
- package/dist/memory/inMemoryStorage.js +66 -16
- package/dist/memory/inMemoryStorage.js.map +1 -1
- package/dist/memory/loader.d.ts +2 -0
- package/dist/memory/loader.d.ts.map +1 -1
- package/dist/memory/loader.js +8 -1
- package/dist/memory/loader.js.map +1 -1
- package/dist/memory/lockManager.d.ts +7 -2
- package/dist/memory/lockManager.d.ts.map +1 -1
- package/dist/memory/lockManager.js +31 -5
- package/dist/memory/lockManager.js.map +1 -1
- package/dist/memory/projectManager.d.ts +2 -1
- package/dist/memory/projectManager.d.ts.map +1 -1
- package/dist/memory/projectManager.js +21 -3
- package/dist/memory/projectManager.js.map +1 -1
- package/dist/memory/projectRegistry.d.ts +34 -1
- package/dist/memory/projectRegistry.d.ts.map +1 -1
- package/dist/memory/projectRegistry.js +99 -22
- package/dist/memory/projectRegistry.js.map +1 -1
- package/dist/memory/recall.d.ts +16 -0
- package/dist/memory/recall.d.ts.map +1 -1
- package/dist/memory/recall.js +33 -18
- package/dist/memory/recall.js.map +1 -1
- package/dist/memory/relationStore.d.ts +20 -3
- package/dist/memory/relationStore.d.ts.map +1 -1
- package/dist/memory/sourceValidation.d.ts +11 -0
- package/dist/memory/sourceValidation.d.ts.map +1 -1
- package/dist/memory/sourceValidation.js +24 -2
- package/dist/memory/sourceValidation.js.map +1 -1
- package/dist/memory/storageInterface.d.ts +26 -1
- package/dist/memory/storageInterface.d.ts.map +1 -1
- package/dist/memory/store.d.ts +22 -1
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +58 -20
- package/dist/memory/store.js.map +1 -1
- package/dist/memory/types.d.ts +44 -31
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +63 -24
- package/dist/memory/types.js.map +1 -1
- package/dist/memory/userProfile.d.ts +32 -8
- package/dist/memory/userProfile.d.ts.map +1 -1
- package/dist/memory/userProfile.js +105 -44
- package/dist/memory/userProfile.js.map +1 -1
- package/dist/memory/vectorStore.d.ts +16 -22
- package/dist/memory/vectorStore.d.ts.map +1 -1
- package/dist/memory/vectorStore.js +49 -22
- package/dist/memory/vectorStore.js.map +1 -1
- package/dist/persona/personaManager.d.ts +36 -87
- package/dist/persona/personaManager.d.ts.map +1 -1
- package/dist/persona/personaManager.js +131 -230
- package/dist/persona/personaManager.js.map +1 -1
- package/dist/skill/skillManager.d.ts +11 -57
- package/dist/skill/skillManager.d.ts.map +1 -1
- package/dist/skill/skillManager.js +46 -142
- package/dist/skill/skillManager.js.map +1 -1
- package/dist/skill/types.d.ts +2 -3
- package/dist/skill/types.d.ts.map +1 -1
- package/dist/utils/configResourceManager.d.ts +111 -0
- package/dist/utils/configResourceManager.d.ts.map +1 -0
- package/dist/utils/configResourceManager.js +148 -0
- package/dist/utils/configResourceManager.js.map +1 -0
- package/dist/utils/errors.d.ts +17 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +19 -0
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/eventEmitter.d.ts +83 -6
- package/dist/utils/eventEmitter.d.ts.map +1 -1
- package/dist/utils/eventEmitter.js +23 -0
- package/dist/utils/eventEmitter.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +4 -2
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/math.d.ts +11 -0
- package/dist/utils/math.d.ts.map +1 -1
- package/dist/utils/math.js +17 -0
- package/dist/utils/math.js.map +1 -1
- package/dist/utils/segmenter.d.ts +0 -10
- package/dist/utils/segmenter.d.ts.map +1 -1
- package/dist/utils/segmenter.js +10 -1
- package/dist/utils/segmenter.js.map +1 -1
- package/docs/memora-api-reference.md +1235 -0
- package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +808 -0
- package/package.json +39 -22
|
@@ -3,6 +3,43 @@ import { logger } from '../logging/logger.js';
|
|
|
3
3
|
import { slugify } from '../utils/strings.js';
|
|
4
4
|
import { toError } from '../utils/toError.js';
|
|
5
5
|
import { nowIso } from '../utils/time.js';
|
|
6
|
+
/** 有效的画像分类列表(模块级常量,消除 parseContentField 内 2 次重复数组) */
|
|
7
|
+
const VALID_PROFILE_CATEGORIES = ['identity', 'preference', 'expertise', 'habit', 'history'];
|
|
8
|
+
/**
|
|
9
|
+
* 从 value 字符串前缀提取字段名(兼容旧数据)
|
|
10
|
+
*
|
|
11
|
+
* 旧数据 value 格式为 "字段名: 值"(如 "姓名: 张三"),fieldName 未显式存储。
|
|
12
|
+
* 本函数从 value 前缀提取字段名,用于:
|
|
13
|
+
* - parseContentField 降级路径(旧 JSON 数据无 fieldName 字段)
|
|
14
|
+
* - removeConflictingEntries 兼容旧持久化数据
|
|
15
|
+
*
|
|
16
|
+
* @param value 事实值(可能含 "字段名: " 前缀)
|
|
17
|
+
* @returns 提取的字段名;无法提取时返回 'unknown'(冲突检测会跳过该条目)
|
|
18
|
+
*/
|
|
19
|
+
function extractFieldNameFromValue(value) {
|
|
20
|
+
const prefix = (value.split(':')[0] ?? '').trim();
|
|
21
|
+
return prefix || 'unknown';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 类型守卫:检查未知对象是否为合法的 profile content 结构
|
|
25
|
+
*
|
|
26
|
+
* 替代 `as { category?: string; value?: string }` 断言,
|
|
27
|
+
* 与 lockManager/projectRegistry 的类型守卫风格一致。
|
|
28
|
+
*
|
|
29
|
+
* fieldName 为可选字段(旧数据可能缺失),不参与结构校验,
|
|
30
|
+
* 由 parseContentField 决定降级策略。
|
|
31
|
+
*
|
|
32
|
+
* @param obj 从 JSON.parse 得到的未知对象
|
|
33
|
+
* @returns obj 是否为 { category: ProfileCategory; value: string } 结构
|
|
34
|
+
*/
|
|
35
|
+
function isProfileContent(obj) {
|
|
36
|
+
if (typeof obj !== 'object' || obj === null)
|
|
37
|
+
return false;
|
|
38
|
+
const record = obj;
|
|
39
|
+
return (typeof record.category === 'string' &&
|
|
40
|
+
typeof record.value === 'string' &&
|
|
41
|
+
VALID_PROFILE_CATEGORIES.includes(record.category));
|
|
42
|
+
}
|
|
6
43
|
/**
|
|
7
44
|
* 用户画像管理器
|
|
8
45
|
*/
|
|
@@ -31,10 +68,13 @@ export class UserProfile {
|
|
|
31
68
|
const entry = {
|
|
32
69
|
id: m.id,
|
|
33
70
|
category: parsed.category,
|
|
71
|
+
// fieldName 由 parseContentField 统一填充(新数据直接读,旧数据从 value 前缀降级提取)
|
|
72
|
+
fieldName: parsed.fieldName,
|
|
34
73
|
value: parsed.value,
|
|
35
74
|
source: '',
|
|
36
75
|
weight: m.score,
|
|
37
|
-
confirmed
|
|
76
|
+
// M10 修复:从 content 还原确认态(旧数据无 confirmed 字段 → 默认已确认,向后兼容)
|
|
77
|
+
confirmed: parsed.confirmed,
|
|
38
78
|
updatedAt: m.accessedAt,
|
|
39
79
|
};
|
|
40
80
|
this.cache.set(entry.id, entry);
|
|
@@ -158,25 +198,33 @@ export class UserProfile {
|
|
|
158
198
|
* @returns 成功写入的条目,或 null(写入失败)
|
|
159
199
|
*/
|
|
160
200
|
async upsertFact(fact) {
|
|
161
|
-
//
|
|
162
|
-
|
|
201
|
+
// M3 修复:id 维度纳入 fieldName,与冲突检测维度(category+fieldName)一致。
|
|
202
|
+
// 否则不同 fieldName 经 slugify 撞车时分配同一 id → 后写覆盖前写 → 跨字段记忆静默丢失。
|
|
203
|
+
const id = `profile:user-profile-${fact.category}-${slugify(fact.fieldName)}-${slugify(fact.value)}`;
|
|
163
204
|
// 同分类冲突解决 — 删除旧条目(相同子分类 + 不同值 = 用户更新了信息)
|
|
164
205
|
await this.removeConflictingEntries(fact);
|
|
165
206
|
const entry = {
|
|
166
207
|
id,
|
|
167
208
|
category: fact.category,
|
|
209
|
+
// 显式存储 fieldName,供冲突检测使用
|
|
210
|
+
fieldName: fact.fieldName,
|
|
168
211
|
value: fact.value,
|
|
169
212
|
source: fact.sourceTurn,
|
|
170
213
|
weight: 1.0,
|
|
171
214
|
confirmed: fact.confidence >= 0.8, // 高置信度直接确认
|
|
172
215
|
updatedAt: nowIso(),
|
|
173
216
|
};
|
|
217
|
+
// M2 修复:已确认条目不因同 value 的低置信度重提取而降级。
|
|
218
|
+
// 同一 id 若缓存中已是 confirmed=true,保留确认态(用户已确认该事实,低置信重提取不应撤销)。
|
|
219
|
+
const existingInCache = this.cache.get(id);
|
|
220
|
+
if (existingInCache?.confirmed && !entry.confirmed) {
|
|
221
|
+
entry.confirmed = true;
|
|
222
|
+
}
|
|
174
223
|
try {
|
|
175
|
-
//
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
224
|
+
// M10 修复:待确认条目也持久化(content 含 confirmed=false 标记),
|
|
225
|
+
// 重启后由 load() 恢复为 pending,消除"确认前无兜底"的不可逆损失点。
|
|
226
|
+
const memory = this.toMemory(entry);
|
|
227
|
+
this.index.upsert(memory);
|
|
180
228
|
this.cache.set(id, entry);
|
|
181
229
|
if (entry.confirmed) {
|
|
182
230
|
logger.info({ id, category: fact.category, value: fact.value, confidence: fact.confidence }, '用户画像实时归档(已确认)');
|
|
@@ -192,52 +240,51 @@ export class UserProfile {
|
|
|
192
240
|
}
|
|
193
241
|
}
|
|
194
242
|
/**
|
|
195
|
-
*
|
|
243
|
+
* 删除同分类同字段的旧条目(用户更新了信息)
|
|
244
|
+
*
|
|
245
|
+
* 当用户说"我叫李四"替换之前的"我叫张三"时,移除旧的 identity/姓名 条目。
|
|
196
246
|
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
247
|
+
* 冲突判定基于 `category + fieldName`:
|
|
248
|
+
* - 新数据:fact.fieldName 由提取器显式填充,parseContentField 返回 parsed.fieldName
|
|
249
|
+
* - 旧数据:parseContentField 降级从 value 前缀提取 fieldName(兼容历史持久化数据)
|
|
250
|
+
* - 同 category + 同 fieldName + 不同 value = 用户更新了该字段,删除旧条目
|
|
199
251
|
*
|
|
200
|
-
*
|
|
201
|
-
* 构建 contentPrefix → entry 的 Map 索引,冲突检测从 O(n*m) 降为 O(m)。
|
|
252
|
+
* 构建 `category:fieldName` → Memory[] 的 Map 索引,冲突检测从 O(n*m) 降为 O(m)。
|
|
202
253
|
*
|
|
203
254
|
* @param fact 当前提取到的新事实
|
|
204
255
|
*/
|
|
205
256
|
async removeConflictingEntries(fact) {
|
|
206
257
|
try {
|
|
207
258
|
const existing = this.index.getBySource(SOURCE_LABELS.PROFILE);
|
|
208
|
-
//
|
|
209
|
-
const
|
|
210
|
-
// 构建 contentPrefix → Memory 的 Map 索引,冲突检测降为 O(m)
|
|
211
|
-
const prefixIndex = new Map();
|
|
259
|
+
// 构建 `category:fieldName` → Memory[] 的 Map 索引,冲突检测降为 O(m)
|
|
260
|
+
const fieldIndex = new Map();
|
|
212
261
|
for (const m of existing) {
|
|
213
|
-
// 从 content JSON 解码 category,替代 parseNameField
|
|
214
262
|
const parsed = this.parseContentField(m.content, m.name);
|
|
215
263
|
if (parsed.category !== fact.category)
|
|
216
264
|
continue;
|
|
217
|
-
|
|
218
|
-
if (!oldPrefix)
|
|
265
|
+
if (!parsed.fieldName)
|
|
219
266
|
continue;
|
|
220
|
-
const key = `${parsed.category}:${
|
|
221
|
-
const list =
|
|
267
|
+
const key = `${parsed.category}:${parsed.fieldName}`;
|
|
268
|
+
const list = fieldIndex.get(key);
|
|
222
269
|
if (list) {
|
|
223
270
|
list.push(m);
|
|
224
271
|
}
|
|
225
272
|
else {
|
|
226
|
-
|
|
273
|
+
fieldIndex.set(key, [m]);
|
|
227
274
|
}
|
|
228
275
|
}
|
|
229
|
-
//
|
|
230
|
-
const conflictKey = `${fact.category}:${
|
|
231
|
-
const conflicts =
|
|
276
|
+
// 在索引中查找同 category + 同 fieldName 的冲突条目
|
|
277
|
+
const conflictKey = `${fact.category}:${fact.fieldName}`;
|
|
278
|
+
const conflicts = fieldIndex.get(conflictKey);
|
|
232
279
|
if (conflicts) {
|
|
233
280
|
for (const m of conflicts) {
|
|
234
281
|
const parsed = this.parseContentField(m.content, m.name);
|
|
235
282
|
if (parsed.value !== fact.value) {
|
|
236
283
|
this.index.delete(m.id);
|
|
237
|
-
//
|
|
238
|
-
// 导致 getConfirmed()
|
|
284
|
+
// 同步删除内存缓存中的旧条目,避免 storage 与 cache 不一致
|
|
285
|
+
// 导致 getConfirmed() 仍返回已被替换的旧值
|
|
239
286
|
this.cache.delete(m.id);
|
|
240
|
-
logger.info({ oldId: m.id, oldValue: parsed.value, newValue: fact.value }, '用户画像冲突已解决');
|
|
287
|
+
logger.info({ oldId: m.id, oldValue: parsed.value, newValue: fact.value, fieldName: fact.fieldName }, '用户画像冲突已解决');
|
|
241
288
|
}
|
|
242
289
|
}
|
|
243
290
|
}
|
|
@@ -250,7 +297,7 @@ export class UserProfile {
|
|
|
250
297
|
/**
|
|
251
298
|
* 将 UserProfileEntry 转为 Memory(用于写入 SQLite)
|
|
252
299
|
*
|
|
253
|
-
* content 字段使用 JSON 编码存储 category + value 元数据,
|
|
300
|
+
* content 字段使用 JSON 编码存储 category + value + fieldName 元数据,
|
|
254
301
|
* name 字段为固定可读标签,category 通过 content 的 JSON 元数据显式编码。
|
|
255
302
|
* 确认状态:仅已确认条目调用此方法(待确认条目不写入存储)
|
|
256
303
|
*/
|
|
@@ -258,7 +305,13 @@ export class UserProfile {
|
|
|
258
305
|
const now = nowIso();
|
|
259
306
|
return {
|
|
260
307
|
id: entry.id,
|
|
261
|
-
|
|
308
|
+
// 序列化 fieldName,与 parseContentField 反序列化对称
|
|
309
|
+
content: JSON.stringify({
|
|
310
|
+
category: entry.category,
|
|
311
|
+
value: entry.value,
|
|
312
|
+
fieldName: entry.fieldName,
|
|
313
|
+
confirmed: entry.confirmed,
|
|
314
|
+
}),
|
|
262
315
|
source: SOURCE_LABELS.PROFILE,
|
|
263
316
|
name: `用户画像-${entry.category}`,
|
|
264
317
|
createdAt: now,
|
|
@@ -267,24 +320,31 @@ export class UserProfile {
|
|
|
267
320
|
};
|
|
268
321
|
}
|
|
269
322
|
/**
|
|
270
|
-
* 从 content 字段解析 category
|
|
323
|
+
* 从 content 字段解析 category / value / fieldName
|
|
271
324
|
*
|
|
272
325
|
* 优先从 content JSON 解码元数据,降级到旧格式 name 字段解析,
|
|
273
326
|
* 确保已有 SQLite 数据(旧格式 name="${category}: ${value}")兼容加载。
|
|
274
327
|
*
|
|
328
|
+
* fieldName 解析优先级:
|
|
329
|
+
* 1. content JSON 含 fieldName → 直接返回(新数据)
|
|
330
|
+
* 2. content JSON 无 fieldName → 从 value 前缀提取(旧 JSON 数据,无 fieldName 字段)
|
|
331
|
+
* 3. name 字段旧格式 → 从 value 前缀提取
|
|
332
|
+
* 4. 最终降级 → fieldName = 'unknown'(无法识别字段名,冲突检测会跳过)
|
|
333
|
+
*
|
|
275
334
|
* @param content Memory 的 content 字段(新格式为 JSON,旧格式为纯 value)
|
|
276
335
|
* @param name Memory 的 name 字段(旧格式为 "${category}: ${value}")
|
|
277
|
-
* @returns 解析出的 category
|
|
336
|
+
* @returns 解析出的 category / value / fieldName
|
|
278
337
|
*/
|
|
279
338
|
parseContentField(content, name) {
|
|
280
339
|
// 优先尝试 JSON 解码(新格式)
|
|
281
340
|
try {
|
|
282
341
|
const parsed = JSON.parse(content);
|
|
283
|
-
if (parsed
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
342
|
+
if (isProfileContent(parsed)) {
|
|
343
|
+
// 新数据含 fieldName 直接返回;旧 JSON 数据无 fieldName 时从 value 前缀降级提取
|
|
344
|
+
const fieldName = parsed.fieldName ?? extractFieldNameFromValue(parsed.value);
|
|
345
|
+
// M10:confirmed 缺失(旧数据)默认 true,向后兼容;新数据按实际标记还原
|
|
346
|
+
const confirmed = typeof parsed.confirmed === 'boolean' ? parsed.confirmed : true;
|
|
347
|
+
return { category: parsed.category, value: parsed.value, fieldName, confirmed };
|
|
288
348
|
}
|
|
289
349
|
}
|
|
290
350
|
catch {
|
|
@@ -294,14 +354,15 @@ export class UserProfile {
|
|
|
294
354
|
const idx = name.indexOf(':');
|
|
295
355
|
if (idx >= 0) {
|
|
296
356
|
const category = name.slice(0, idx).trim();
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
return { category, value: value
|
|
357
|
+
if (VALID_PROFILE_CATEGORIES.includes(category)) {
|
|
358
|
+
const value = name.slice(idx + 1).trim() || content;
|
|
359
|
+
// 旧格式数据无 fieldName,从 value 前缀提取(如 "姓名: 张三" → "姓名")
|
|
360
|
+
return { category, value, fieldName: extractFieldNameFromValue(value), confirmed: true };
|
|
301
361
|
}
|
|
302
362
|
}
|
|
303
|
-
// 最终降级:默认 identity
|
|
304
|
-
|
|
363
|
+
// 最终降级:默认 history 分类(中性默认,避免 identity 高敏感类别污染画像)
|
|
364
|
+
// fieldName = 'unknown':无法识别字段名,removeConflictingEntries 会跳过该条目
|
|
365
|
+
return { category: 'history', value: content, fieldName: 'unknown', confirmed: true };
|
|
305
366
|
}
|
|
306
367
|
/**
|
|
307
368
|
* 分类标签
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userProfile.js","sourceRoot":"","sources":["../../src/memory/userProfile.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,aAAa,EAAe,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"userProfile.js","sourceRoot":"","sources":["../../src/memory/userProfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Embedding 调用选项(韧性补齐)
|
|
3
|
-
*
|
|
4
|
-
* 与 ChatOptions.signal/timeoutMs 同构,支持外部取消 + 超时中断。
|
|
5
|
-
* 宿主在用户取消对话时传入 AbortSignal,或设置 timeoutMs 覆盖默认超时。
|
|
6
|
-
*
|
|
7
|
-
* 类型归属:定义在 memory/(消费者),llm/embedding.ts(提供者)通过
|
|
8
|
-
* import type 引入,符合依赖倒置原则(消费者定义接口,提供者实现接口)。
|
|
9
|
-
*/
|
|
10
|
-
export interface EmbeddingOptions {
|
|
11
|
-
/** 外部取消信号(用户主动取消时传入) */
|
|
12
|
-
signal?: AbortSignal;
|
|
13
|
-
/** 超时毫秒数(超时自动 abort;默认 60s,可通过此字段覆盖) */
|
|
14
|
-
timeoutMs?: number;
|
|
15
|
-
}
|
|
1
|
+
import type { EmbeddingOptions } from '../llm/embedding.js';
|
|
16
2
|
/**
|
|
17
3
|
* 嵌入服务接口
|
|
18
4
|
* 向量存储依赖此接口生成文本嵌入向量
|
|
@@ -64,10 +50,14 @@ export interface IVectorStore {
|
|
|
64
50
|
text: string;
|
|
65
51
|
}>, options?: EmbeddingOptions): Promise<void>;
|
|
66
52
|
/**
|
|
67
|
-
*
|
|
53
|
+
* 删除向量并立即持久化
|
|
54
|
+
*
|
|
55
|
+
* 与 upsert(标记 dirty 由调用方 save)不同,delete 是低频操作,
|
|
56
|
+
* 立即 save 可防止崩溃后已删除向量在下次冷启动复活(FIX-P0-9)。
|
|
57
|
+
*
|
|
68
58
|
* @param id 待删除的记忆 ID
|
|
69
59
|
*/
|
|
70
|
-
delete(id: string): void
|
|
60
|
+
delete(id: string): Promise<void>;
|
|
71
61
|
/**
|
|
72
62
|
* 语义搜索:基于查询文本的向量,返回 topK 最相似的 ID
|
|
73
63
|
* @param query 查询文本
|
|
@@ -116,6 +106,11 @@ export declare class JsonVectorStore implements IVectorStore {
|
|
|
116
106
|
* 防止部分写入 / 手动编辑错误 / 版本不匹配的文件污染内存索引
|
|
117
107
|
*/
|
|
118
108
|
load(): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* 将损坏的向量索引文件备份为 .corrupt.<timestamp>,便于人工恢复或 re-embed,
|
|
111
|
+
* 避免 load 直接「从空开始」导致原始损坏数据被静默覆盖、不可逆丢失。
|
|
112
|
+
*/
|
|
113
|
+
private backupCorrupt;
|
|
119
114
|
/**
|
|
120
115
|
* 持久化向量索引到 JSON 文件
|
|
121
116
|
*
|
|
@@ -156,15 +151,14 @@ export declare class JsonVectorStore implements IVectorStore {
|
|
|
156
151
|
text: string;
|
|
157
152
|
}>, options?: EmbeddingOptions): Promise<void>;
|
|
158
153
|
/**
|
|
159
|
-
*
|
|
154
|
+
* 删除向量并立即持久化
|
|
160
155
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* 否则下次冷启动会重新加载已删除的向量。
|
|
156
|
+
* FIX-P0-9:原实现仅标记 dirty=true 不 save,崩溃时已删除向量会在下次冷启动复活。
|
|
157
|
+
* 现改为 async + 立即 save(与 upsert 不对称合理——delete 是低频操作,立即持久化代价可控)。
|
|
164
158
|
*
|
|
165
159
|
* @param id 待删除的记忆 ID
|
|
166
160
|
*/
|
|
167
|
-
delete(id: string): void
|
|
161
|
+
delete(id: string): Promise<void>;
|
|
168
162
|
/**
|
|
169
163
|
* 语义搜索:基于查询文本的向量,返回 topK 最相似的 ID
|
|
170
164
|
* @param query 查询文本
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vectorStore.d.ts","sourceRoot":"","sources":["../../src/memory/vectorStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vectorStore.d.ts","sourceRoot":"","sources":["../../src/memory/vectorStore.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC9B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACnE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC,CAAC;CAC9G;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,iBAAiB;IACjB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnG;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC;;;;;;;OAOG;IACH,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACtD,gBAAgB;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAuDD;;;;;;;;GAQG;AACH,qBAAa,eAAgB,YAAW,YAAY;IAmBhD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAnBpC,eAAe;IACf,OAAO,CAAC,OAAO,CAA+B;IAE9C,wBAAwB;IACxB,OAAO,CAAC,SAAS,CAAK;IAEtB,iBAAiB;IACjB,OAAO,CAAC,KAAK,CAAS;IAEtB;;;;;OAKG;IACH,OAAO,CAAC,WAAW,CAA8B;gBAG9B,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,gBAAgB;IAGtD;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B3B;;;OAGG;YACW,aAAa;IAQ3B;;;;;;;OAOG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;;;OAIG;YACW,MAAM;IAmBpB;;;;;;;;;OASG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjF;;;;;;;;OAQG;IACG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxG;;;;;;;OAOG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC;;;;;;;OAOG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,IAAI,SAAI,EACR,aAAa,SAAM,EACnB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAgBrD;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
* - load() 增加 schema 校验(防止损坏文件污染内存索引)
|
|
16
16
|
* - upsert/batchUpsert 增加维度一致性校验(防止维度错位导致相似度计算崩溃)
|
|
17
17
|
* - save() 串行化(防止并发 save 互相覆盖丢失数据)
|
|
18
|
-
* - delete()
|
|
18
|
+
* - delete() 立即 save(FIX-P0-9:防止崩溃后已删除向量复活)
|
|
19
19
|
*
|
|
20
20
|
* 详见 ADR-002 · 存储层抽象(向量检索备选方案)
|
|
21
21
|
* 详见 ADR-013 · 记忆归档三步价值过滤
|
|
22
22
|
*/
|
|
23
|
-
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
23
|
+
import { readFile, writeFile, mkdir, rename } from 'node:fs/promises';
|
|
24
24
|
import { dirname } from 'node:path';
|
|
25
25
|
import { logger } from '../logging/logger.js';
|
|
26
26
|
import { configError } from '../utils/errors.js';
|
|
@@ -101,12 +101,21 @@ export class JsonVectorStore {
|
|
|
101
101
|
* 防止部分写入 / 手动编辑错误 / 版本不匹配的文件污染内存索引
|
|
102
102
|
*/
|
|
103
103
|
async load() {
|
|
104
|
+
let content;
|
|
105
|
+
try {
|
|
106
|
+
content = await readFile(this.storePath, 'utf-8');
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// 文件不存在,从空开始(正常冷启动路径)
|
|
110
|
+
logger.info({ path: this.storePath }, '向量索引文件不存在,从空开始');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
104
113
|
try {
|
|
105
|
-
const content = await readFile(this.storePath, 'utf-8');
|
|
106
114
|
const data = JSON.parse(content);
|
|
107
|
-
// schema 校验:损坏 / 格式错误的文件视为"从空开始"
|
|
115
|
+
// schema 校验:损坏 / 格式错误的文件视为"从空开始",但先备份以免数据不可逆丢失
|
|
108
116
|
if (!isValidVectorStoreFile(data)) {
|
|
109
|
-
|
|
117
|
+
await this.backupCorrupt();
|
|
118
|
+
logger.warn({ path: this.storePath }, '向量索引文件格式无效,已从空开始并备份损坏文件');
|
|
110
119
|
return;
|
|
111
120
|
}
|
|
112
121
|
this.dimension = data.dimension;
|
|
@@ -118,8 +127,21 @@ export class JsonVectorStore {
|
|
|
118
127
|
logger.info({ count: this.entries.size, dimension: this.dimension }, '向量索引加载完成');
|
|
119
128
|
}
|
|
120
129
|
catch {
|
|
121
|
-
//
|
|
122
|
-
|
|
130
|
+
// JSON 解析失败(文件半写 / 手动损坏),从空开始并备份
|
|
131
|
+
await this.backupCorrupt();
|
|
132
|
+
logger.warn({ path: this.storePath }, '向量索引文件解析失败,已从空开始并备份损坏文件');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 将损坏的向量索引文件备份为 .corrupt.<timestamp>,便于人工恢复或 re-embed,
|
|
137
|
+
* 避免 load 直接「从空开始」导致原始损坏数据被静默覆盖、不可逆丢失。
|
|
138
|
+
*/
|
|
139
|
+
async backupCorrupt() {
|
|
140
|
+
try {
|
|
141
|
+
await rename(this.storePath, `${this.storePath}.corrupt.${Date.now()}`);
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
logger.warn({ err, path: this.storePath }, '备份损坏向量索引文件失败(不影响从空开始)');
|
|
123
145
|
}
|
|
124
146
|
}
|
|
125
147
|
/**
|
|
@@ -131,16 +153,16 @@ export class JsonVectorStore {
|
|
|
131
153
|
* @returns 等待所有挂起 save 完成的 Promise
|
|
132
154
|
*/
|
|
133
155
|
async save() {
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
156
|
+
// 串行化:将本次 save 追加到既有链尾(或开启新链),确保多个 save 严格顺序执行。
|
|
157
|
+
// 仅当本节点仍是链尾(未被更新的 save 取代)时才在完成后清空引用,
|
|
158
|
+
// 避免旧实现「.finally 直接置 null」把仍在飞行的后续 save 链引用截断,导致并发写。
|
|
159
|
+
const p = (this.savePromise ?? Promise.resolve()).then(() => this.doSave());
|
|
160
|
+
this.savePromise = p;
|
|
161
|
+
p.finally(() => {
|
|
162
|
+
if (this.savePromise === p)
|
|
163
|
+
this.savePromise = null;
|
|
142
164
|
});
|
|
143
|
-
return
|
|
165
|
+
return p;
|
|
144
166
|
}
|
|
145
167
|
/**
|
|
146
168
|
* 实际执行持久化的内部方法
|
|
@@ -156,7 +178,11 @@ export class JsonVectorStore {
|
|
|
156
178
|
entries: Array.from(this.entries.entries()).map(([id, vector]) => ({ id, vector })),
|
|
157
179
|
};
|
|
158
180
|
await mkdir(dirname(this.storePath), { recursive: true });
|
|
159
|
-
|
|
181
|
+
// M9 修复:先写临时文件再原子 rename,避免写一半崩溃导致 vectors.json 损坏、
|
|
182
|
+
// 下次加载 isValidVectorStoreFile 失败而整库向量静默清空(向量索引昂贵且只能重算)。
|
|
183
|
+
const tmpPath = `${this.storePath}.tmp`;
|
|
184
|
+
await writeFile(tmpPath, JSON.stringify(data), 'utf-8');
|
|
185
|
+
await rename(tmpPath, this.storePath);
|
|
160
186
|
this.dirty = false;
|
|
161
187
|
logger.info({ count: this.entries.size }, '向量索引持久化完成');
|
|
162
188
|
}
|
|
@@ -214,17 +240,18 @@ export class JsonVectorStore {
|
|
|
214
240
|
this.dirty = true;
|
|
215
241
|
}
|
|
216
242
|
/**
|
|
217
|
-
*
|
|
243
|
+
* 删除向量并立即持久化
|
|
218
244
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* 否则下次冷启动会重新加载已删除的向量。
|
|
245
|
+
* FIX-P0-9:原实现仅标记 dirty=true 不 save,崩溃时已删除向量会在下次冷启动复活。
|
|
246
|
+
* 现改为 async + 立即 save(与 upsert 不对称合理——delete 是低频操作,立即持久化代价可控)。
|
|
222
247
|
*
|
|
223
248
|
* @param id 待删除的记忆 ID
|
|
224
249
|
*/
|
|
225
|
-
delete(id) {
|
|
250
|
+
async delete(id) {
|
|
226
251
|
this.entries.delete(id);
|
|
227
252
|
this.dirty = true;
|
|
253
|
+
// 立即持久化,串行化由 save() 内部 savePromise 链保证
|
|
254
|
+
await this.save();
|
|
228
255
|
}
|
|
229
256
|
/**
|
|
230
257
|
* 语义搜索:基于查询文本的向量,返回 topK 最相似的 ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vectorStore.js","sourceRoot":"","sources":["../../src/memory/vectorStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"vectorStore.js","sourceRoot":"","sources":["../../src/memory/vectorStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AA+FnD;;;;;;;;;;;;;GAaG;AACH,SAAS,sBAAsB,CAAC,IAAa;IAC3C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC5D,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAC/F,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;QAC3C,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAChE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACtF,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,SAAS;YAAE,OAAO,KAAK,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,OAAO,eAAe;IAmBP;IACA;IAnBnB,eAAe;IACP,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE9C,wBAAwB;IAChB,SAAS,GAAG,CAAC,CAAC;IAEtB,iBAAiB;IACT,KAAK,GAAG,KAAK,CAAC;IAEtB;;;;;OAKG;IACK,WAAW,GAAyB,IAAI,CAAC;IAEjD,YACmB,SAAiB,EACjB,iBAAmC;QADnC,cAAS,GAAT,SAAS,CAAQ;QACjB,sBAAiB,GAAjB,iBAAiB,CAAkB;IACnD,CAAC;IAEJ;;;;;OAKG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;YACtB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,gBAAgB,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1C,+CAA+C;YAC/C,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,yBAAyB,CAAC,CAAC;gBACjE,OAAO;YACT,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC;QACnF,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;YACjC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,yBAAyB,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,YAAY,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,uBAAuB,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI;QACR,gDAAgD;QAChD,sCAAsC;QACtC,qDAAqD;QACrD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YACb,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC;gBAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACtD,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,MAAM;QAClB,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAExB,MAAM,IAAI,GAAoB;YAC5B,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;SACpF,CAAC;QAEF,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,oDAAoD;QACpD,wDAAwD;QACxD,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,SAAS,MAAM,CAAC;QACxC,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,IAAY,EAAE,OAA0B;QAC/D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;QACjC,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YAC5C,0CAA0C;YAC1C,yBAAyB;YACzB,sCAAsC;YACtC,MAAM,WAAW,CACf,SAAS,EACT,MAAM,IAAI,CAAC,SAAS,OAAO,MAAM,CAAC,MAAM,OAAO,EAAE,yBAAyB,EAC1E,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAC/C,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,WAAW,CAAC,KAA0C,EAAE,OAA0B;QACtF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAExE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI;gBAAE,SAAS;YAC/B,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YACxC,CAAC;iBAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnD,+BAA+B;gBAC/B,sCAAsC;gBACtC,MAAM,WAAW,CACf,aAAa,EACb,MAAM,IAAI,CAAC,SAAS,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,OAAO,IAAI,CAAC,EAAE,GAAG,EAChE,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAC/C,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,uCAAuC;QACvC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CACV,KAAa,EACb,IAAI,GAAG,CAAC,EACR,aAAa,GAAG,GAAG,EACnB,OAA0B;QAE1B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEvE,MAAM,MAAM,GAA8C,EAAE,CAAC;QAC7D,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACzD,IAAI,UAAU,IAAI,aAAa,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF"}
|