@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
package/dist/memory/store.js
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { readFile, writeFile, mkdir, readdir, stat } from 'node:fs/promises';
|
|
8
8
|
import { join, dirname } from 'node:path';
|
|
9
|
-
import { SOURCE_LABELS } from '../memory/types.js';
|
|
10
|
-
import { inferSource } from '../memory/sourceValidation.js';
|
|
9
|
+
import { SOURCE_LABELS, DEFAULT_MEMORY_SCORE } from '../memory/types.js';
|
|
10
|
+
import { inferSource, validateSource } from '../memory/sourceValidation.js';
|
|
11
11
|
import { parseFrontmatter, serializeFrontmatter as serializeFm } from '../utils/frontmatter.js';
|
|
12
12
|
import { logger } from '../logging/logger.js';
|
|
13
13
|
import { toError } from '../utils/toError.js';
|
|
14
|
+
import { configError } from '../utils/errors.js';
|
|
14
15
|
/**
|
|
15
16
|
* 已知 source 到文件系统目录的映射
|
|
16
17
|
*
|
|
@@ -22,8 +23,6 @@ const SOURCE_TO_DIR = {
|
|
|
22
23
|
[SOURCE_LABELS.RULE]: 'rules',
|
|
23
24
|
[SOURCE_LABELS.SKILL]: 'skills',
|
|
24
25
|
};
|
|
25
|
-
/** 无 frontmatter 或 score 缺失时的默认 score */
|
|
26
|
-
const DEFAULT_MEMORY_SCORE = 0.5;
|
|
27
26
|
/**
|
|
28
27
|
* 文件存储类
|
|
29
28
|
*
|
|
@@ -43,7 +42,8 @@ export class FileStore {
|
|
|
43
42
|
*/
|
|
44
43
|
async read(source, name) {
|
|
45
44
|
const filePath = this.getFilePath(source, name);
|
|
46
|
-
// 异步读取:文件不存在时 readFile 抛 ENOENT
|
|
45
|
+
// 异步读取:文件不存在时 readFile 抛 ENOENT,handleFsError 对 ENOENT 静默返回(read 返回 null)
|
|
46
|
+
// 其他错误(EACCES/EISDIR 等)由 handleFsError 重新抛出,让调用方感知故障
|
|
47
47
|
let content;
|
|
48
48
|
let fileStat;
|
|
49
49
|
try {
|
|
@@ -51,23 +51,32 @@ export class FileStore {
|
|
|
51
51
|
fileStat = await stat(filePath);
|
|
52
52
|
}
|
|
53
53
|
catch (err) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (error.code !== 'ENOENT') {
|
|
57
|
-
logger.warn({ path: filePath, code: error.code, err: error.message }, '记忆文件读取失败');
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
54
|
+
this.handleFsError(err, filePath, '记忆文件读取失败');
|
|
55
|
+
return null; // 仅 ENOENT 到达此处(其他错误已在 handleFsError 抛出)
|
|
60
56
|
}
|
|
61
57
|
// 从文件路径推断 source(frontmatter 可覆盖)
|
|
62
58
|
return this.parseMemory(source, name, content, filePath, fileStat.mtime);
|
|
63
59
|
}
|
|
64
60
|
/**
|
|
65
61
|
* 写入记忆文件
|
|
62
|
+
*
|
|
63
|
+
* frontmatter 包含标准字段(id/source/score/createdAt/accessedAt)
|
|
64
|
+
* 和 memory.metadata 中的额外元数据(如 keywords/description)。
|
|
66
65
|
*/
|
|
67
66
|
async write(memory) {
|
|
68
67
|
const filePath = this.getFilePath(memory.source, memory.name);
|
|
69
68
|
await mkdir(dirname(filePath), { recursive: true });
|
|
69
|
+
// 标准字段必须优先于 metadata:metadata 中可能含同名键(如恶意的 source='evil'),
|
|
70
|
+
// 若后展开则劫持 source 语义绕过 sourceValidation。先展开 metadata,再显式覆盖标准字段;
|
|
71
|
+
// 并过滤掉与标准字段同名的 metadata 键,避免写入重复行(如 source: evil\n source: normal)。
|
|
72
|
+
const STANDARD_KEYS = new Set(['id', 'source', 'score', 'createdAt', 'accessedAt']);
|
|
73
|
+
const safeMeta = {};
|
|
74
|
+
for (const [k, v] of Object.entries(memory.metadata ?? {})) {
|
|
75
|
+
if (!STANDARD_KEYS.has(k))
|
|
76
|
+
safeMeta[k] = v;
|
|
77
|
+
}
|
|
70
78
|
const frontmatter = serializeFm({
|
|
79
|
+
...safeMeta,
|
|
71
80
|
id: memory.id,
|
|
72
81
|
source: memory.source,
|
|
73
82
|
score: String(memory.score),
|
|
@@ -85,18 +94,15 @@ export class FileStore {
|
|
|
85
94
|
*/
|
|
86
95
|
async list(source) {
|
|
87
96
|
const dir = join(this.dataDir, this.sourceToDir(source));
|
|
88
|
-
// 异步读取:目录不存在时 readdir 抛 ENOENT
|
|
97
|
+
// 异步读取:目录不存在时 readdir 抛 ENOENT,handleFsError 对 ENOENT 静默返回(list 返回 [])
|
|
98
|
+
// 其他错误由 handleFsError 重新抛出,让调用方感知故障
|
|
89
99
|
let files;
|
|
90
100
|
try {
|
|
91
101
|
files = await readdir(dir);
|
|
92
102
|
}
|
|
93
103
|
catch (err) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (error.code !== 'ENOENT') {
|
|
97
|
-
logger.warn({ dir, code: error.code, err: error.message }, '记忆目录读取失败');
|
|
98
|
-
}
|
|
99
|
-
return [];
|
|
104
|
+
this.handleFsError(err, dir, '记忆目录读取失败');
|
|
105
|
+
return []; // 仅 ENOENT 到达此处(其他错误已在 handleFsError 抛出)
|
|
100
106
|
}
|
|
101
107
|
return files.filter((f) => f.endsWith('.md')).map((f) => f.replace(/\.md$/, ''));
|
|
102
108
|
}
|
|
@@ -109,11 +115,43 @@ export class FileStore {
|
|
|
109
115
|
/**
|
|
110
116
|
* source 到目录名的映射
|
|
111
117
|
*
|
|
112
|
-
* 已知 source 使用预定义目录,未知 source 直接用 source
|
|
118
|
+
* 已知 source 使用预定义目录,未知 source 直接用 source 字符串作目录名。
|
|
119
|
+
* 安全校验:调用 validateSource 拒绝路径遍历(`..`)、null 字节等危险字符,
|
|
120
|
+
* 防止未知 source 被构造为恶意路径绕过 SOURCE_TO_DIR 白名单。
|
|
113
121
|
*/
|
|
114
122
|
sourceToDir(source) {
|
|
123
|
+
const result = validateSource(source);
|
|
124
|
+
if (result.severity === 'block') {
|
|
125
|
+
// 路径遍历 / null 字节 / 空字符串等安全边界违规,必须拒绝
|
|
126
|
+
throw configError('source 校验失败,拒绝映射到目录', result.warning, ['检查 source 字段是否包含路径遍历序列或特殊字符']);
|
|
127
|
+
}
|
|
115
128
|
return SOURCE_TO_DIR[source] ?? source;
|
|
116
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* 文件系统错误统一处理
|
|
132
|
+
*
|
|
133
|
+
* 区分两类错误:
|
|
134
|
+
* - ENOENT(文件/目录不存在):正常情况,静默返回
|
|
135
|
+
* - 其他错误(EACCES/EISDIR 等):真实故障,抛出异常让调用方感知
|
|
136
|
+
*
|
|
137
|
+
* 之前所有错误统一返回 null/[],导致磁盘故障伪装成"无数据",
|
|
138
|
+
* 用户感知不到数据丢失。现区分:ENOENT 静默,其他抛错。
|
|
139
|
+
*
|
|
140
|
+
* @param err 捕获的异常
|
|
141
|
+
* @param path 文件/目录路径(用于日志上下文)
|
|
142
|
+
* @param label 日志标签(中文,如 "记忆文件读取失败")
|
|
143
|
+
* @throws {NodeJS.ErrnoException} 非 ENOENT 错误时重新抛出
|
|
144
|
+
*/
|
|
145
|
+
handleFsError(err, path, label) {
|
|
146
|
+
const error = toError(err);
|
|
147
|
+
if (error.code === 'ENOENT') {
|
|
148
|
+
// 文件/目录不存在是正常情况(首次启动、新项目等),静默返回
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// 非 ENOENT 错误:记录警告并重新抛出,让调用方区分"无数据"与"故障"
|
|
152
|
+
logger.warn({ path, code: error.code, err: error.message }, label);
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
117
155
|
/**
|
|
118
156
|
* 解析记忆文件为 Memory 对象
|
|
119
157
|
*
|
|
@@ -141,7 +179,7 @@ export class FileStore {
|
|
|
141
179
|
};
|
|
142
180
|
}
|
|
143
181
|
const now = mtime.toISOString();
|
|
144
|
-
// 修复 #34:校验 score,防止 NaN
|
|
182
|
+
// 修复 #34:校验 score,防止 NaN/越界值违反校验规则(min(0).max(1))
|
|
145
183
|
// frontmatter 中 score 字段若为非数字字符串(如 "abc"),Number 返回 NaN 会破坏后续写入
|
|
146
184
|
const rawScore = Number(meta['score'] ?? DEFAULT_MEMORY_SCORE);
|
|
147
185
|
const score = Number.isFinite(rawScore) && rawScore >= 0 && rawScore <= 1
|
package/dist/memory/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAe,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"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"}
|
package/dist/memory/types.d.ts
CHANGED
|
@@ -4,51 +4,62 @@
|
|
|
4
4
|
* 设计哲学:万物皆是记忆,用 source 开放字符串替代封闭枚举
|
|
5
5
|
* 详见 ADR-004 · 记忆统一模型
|
|
6
6
|
*/
|
|
7
|
-
import { z } from 'zod';
|
|
8
7
|
/**
|
|
9
|
-
*
|
|
8
|
+
* 记忆基元接口
|
|
10
9
|
*
|
|
11
10
|
* 8 个核心字段(v2.1 软删除扩展),无封闭枚举
|
|
12
11
|
* - 7 个基础字段:id/content/source/name/createdAt/accessedAt/score
|
|
13
12
|
* - 1 个可选字段:deletedAt(软删除时间,undefined 表示活跃记忆)
|
|
14
13
|
*/
|
|
15
|
-
export
|
|
14
|
+
export interface Memory {
|
|
16
15
|
/** 唯一标识(source:name,如 'rule:core'、'insight:1718083200000') */
|
|
17
|
-
id: z.ZodString;
|
|
18
|
-
/** 记忆内容(Markdown 文本) */
|
|
19
|
-
content: z.ZodString;
|
|
20
|
-
/** 来源标签(开放字符串,非枚举) */
|
|
21
|
-
source: z.ZodString;
|
|
22
|
-
/** 可读名称(文件名或摘要标题) */
|
|
23
|
-
name: z.ZodString;
|
|
24
|
-
/** 创建时间(ISO 8601) */
|
|
25
|
-
createdAt: z.ZodString;
|
|
26
|
-
/** 最后访问时间(每次召回时刷新) */
|
|
27
|
-
accessedAt: z.ZodString;
|
|
28
|
-
/** 权重(0-1,召回时用于排序) */
|
|
29
|
-
score: z.ZodDefault<z.ZodNumber>;
|
|
30
|
-
/** 软删除时间(ISO 8601,可选;非 undefined 表示已软删除,回收站保留 30 天后自动物理清理) */
|
|
31
|
-
deletedAt: z.ZodOptional<z.ZodString>;
|
|
32
|
-
}, "strip", z.ZodTypeAny, {
|
|
33
16
|
id: string;
|
|
17
|
+
/** 记忆内容(Markdown 文本) */
|
|
34
18
|
content: string;
|
|
19
|
+
/** 来源标签(开放字符串,非枚举) */
|
|
35
20
|
source: string;
|
|
21
|
+
/** 可读名称(文件名或摘要标题) */
|
|
36
22
|
name: string;
|
|
23
|
+
/** 创建时间(ISO 8601) */
|
|
37
24
|
createdAt: string;
|
|
25
|
+
/** 最后访问时间(每次召回时刷新) */
|
|
38
26
|
accessedAt: string;
|
|
27
|
+
/** 权重(0-1,召回时用于排序) */
|
|
39
28
|
score: number;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
29
|
+
/** 软删除时间(ISO 8601,可选;非 undefined 表示已软删除,回收站保留 30 天后自动物理清理) */
|
|
30
|
+
deletedAt?: string;
|
|
31
|
+
/**
|
|
32
|
+
* 可选:配置文件 frontmatter 的额外元数据
|
|
33
|
+
*
|
|
34
|
+
* 仅在写入配置文件时使用(FileStore.write 合并到 frontmatter)。
|
|
35
|
+
* SQLite index 不存储此字段(运行时检索不需要)。
|
|
36
|
+
* 典型场景:persona 的 keywords/description,供 PersonaManager 加载时解析。
|
|
37
|
+
*/
|
|
38
|
+
metadata?: Record<string, string>;
|
|
39
|
+
}
|
|
40
|
+
/** 默认记忆权重(parseMemory 的默认值行为) */
|
|
41
|
+
export declare const DEFAULT_MEMORY_SCORE = 0.5;
|
|
42
|
+
/**
|
|
43
|
+
* 记忆解析器 — 验证原始数据并转换为 Memory 类型
|
|
44
|
+
*
|
|
45
|
+
* 提供与原 MemorySchema.parse() 等效的运行时验证能力:
|
|
46
|
+
* - 非空对象检查
|
|
47
|
+
* - 字段类型验证(string/number)
|
|
48
|
+
* - ISO 8601 日期格式验证
|
|
49
|
+
* - score 范围检查(0-1)
|
|
50
|
+
* - 默认值填充(score = 0.5)
|
|
51
|
+
*
|
|
52
|
+
* @param raw - 原始数据(通常来自 JSON 解析或数据库查询)
|
|
53
|
+
* @returns 验证通过的 Memory 对象
|
|
54
|
+
* @throws Error 当数据不符合 Memory 接口定义时
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseMemory(raw: unknown): Memory;
|
|
57
|
+
/**
|
|
58
|
+
* 兼容性别名 — 保持原有测试代码 (MemorySchema.parse(...)) 无需修改
|
|
59
|
+
*/
|
|
60
|
+
export declare const MemorySchema: {
|
|
61
|
+
parse: typeof parseMemory;
|
|
62
|
+
};
|
|
52
63
|
/**
|
|
53
64
|
* 泊文当前使用的 source 标签约定
|
|
54
65
|
*
|
|
@@ -70,6 +81,8 @@ export declare const SOURCE_LABELS: {
|
|
|
70
81
|
readonly WORK_PROJECTION: "work-projection";
|
|
71
82
|
/** 内容护栏规则(configDir/rules/guardrails/ 下的规则文件) */
|
|
72
83
|
readonly GUARDRAIL: "guardrail";
|
|
84
|
+
/** 未知来源(inferSource 兜底值,文件路径未匹配已知目录时的默认标签) */
|
|
85
|
+
readonly UNKNOWN: "unknown";
|
|
73
86
|
};
|
|
74
87
|
/**
|
|
75
88
|
* 记忆关系基元 — 独立于 Memory 7 字段的侧车数据结构
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;;;;GAMG;AACH,MAAM,WAAW,MAAM;IACrB,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,iCAAiC;AACjC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAoEhD;AAED;;GAEG;AACH,eAAO,MAAM,YAAY;;CAAyB,CAAC;AAInD;;;;;GAKG;AACH,eAAO,MAAM,aAAa;IACxB,uCAAuC;;IAEvC,yDAAyD;;IAEzD,qCAAqC;;IAErC,2BAA2B;;IAE3B,2BAA2B;;IAE3B,+BAA+B;;IAE/B,iDAAiD;;IAEjD,8CAA8C;;CAEtC,CAAC;AASX;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cAAc;IAC7B,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;IAC3B,wBAAwB;;IAExB,oBAAoB;;IAEpB,8BAA8B;;IAE9B,oBAAoB;;IAEpB,sBAAsB;;CAEd,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,cAAc;IACzB,eAAe;;IAEf,aAAa;;IAEb,eAAe;;IAEf,gBAAgB;;IAEhB,aAAa;;IAEb,gBAAgB;;CAER,CAAC;AAIX;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gCAAgC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,SAAS,EAAE,UAAU,GAAG,UAAU,CAAC;CACpC"}
|
package/dist/memory/types.js
CHANGED
|
@@ -4,33 +4,70 @@
|
|
|
4
4
|
* 设计哲学:万物皆是记忆,用 source 开放字符串替代封闭枚举
|
|
5
5
|
* 详见 ADR-004 · 记忆统一模型
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import { configError } from '../utils/errors.js';
|
|
8
|
+
/** 默认记忆权重(parseMemory 的默认值行为) */
|
|
9
|
+
export const DEFAULT_MEMORY_SCORE = 0.5;
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* 记忆解析器 — 验证原始数据并转换为 Memory 类型
|
|
11
12
|
*
|
|
12
|
-
*
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
13
|
+
* 提供与原 MemorySchema.parse() 等效的运行时验证能力:
|
|
14
|
+
* - 非空对象检查
|
|
15
|
+
* - 字段类型验证(string/number)
|
|
16
|
+
* - ISO 8601 日期格式验证
|
|
17
|
+
* - score 范围检查(0-1)
|
|
18
|
+
* - 默认值填充(score = 0.5)
|
|
19
|
+
*
|
|
20
|
+
* @param raw - 原始数据(通常来自 JSON 解析或数据库查询)
|
|
21
|
+
* @returns 验证通过的 Memory 对象
|
|
22
|
+
* @throws Error 当数据不符合 Memory 接口定义时
|
|
23
|
+
*/
|
|
24
|
+
export function parseMemory(raw) {
|
|
25
|
+
if (raw === null || typeof raw !== 'object') {
|
|
26
|
+
throw configError('Memory 解析失败', '输入必须是非空对象', ['检查数据源(JSON 文件 / 数据库查询)是否返回了有效对象']);
|
|
27
|
+
}
|
|
28
|
+
const obj = raw;
|
|
29
|
+
// 验证必需的 string 字段
|
|
30
|
+
const stringFields = ['id', 'content', 'source', 'name'];
|
|
31
|
+
for (const field of stringFields) {
|
|
32
|
+
if (typeof obj[field] !== 'string') {
|
|
33
|
+
throw configError('Memory 解析失败', `${field} 必须是字符串`, [`检查数据源中 ${field} 字段的类型(当前为 ${typeof obj[field]})`]);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// 验证 ISO 8601 日期字段
|
|
37
|
+
const dateFields = ['createdAt', 'accessedAt'];
|
|
38
|
+
for (const field of dateFields) {
|
|
39
|
+
if (typeof obj[field] !== 'string' || isNaN(Date.parse(obj[field]))) {
|
|
40
|
+
throw configError('Memory 解析失败', `${field} 必须是有效的 ISO 8601 日期字符串`, [`检查数据源中 ${field} 字段的格式(当前值: ${JSON.stringify(obj[field])})`]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 验证 score 字段(可选,有默认值)
|
|
44
|
+
// Number.isFinite 同时排除 NaN/Infinity(对齐 zod z.number() 行为)
|
|
45
|
+
if (obj.score !== undefined && obj.score !== null) {
|
|
46
|
+
if (typeof obj.score !== 'number' || !Number.isFinite(obj.score) || obj.score < 0 || obj.score > 1) {
|
|
47
|
+
throw configError('Memory 解析失败', `score 必须是 0-1 之间的数字(当前值: ${String(obj.score)})`, ['将 score 调整为 0-1 之间的有效数字']);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 验证可选的 deletedAt 字段
|
|
51
|
+
if (obj.deletedAt !== undefined && obj.deletedAt !== null) {
|
|
52
|
+
if (typeof obj.deletedAt !== 'string' || isNaN(Date.parse(obj.deletedAt))) {
|
|
53
|
+
throw configError('Memory 解析失败', `deletedAt 必须是有效的 ISO 8601 日期字符串(当前值: ${JSON.stringify(obj.deletedAt)})`, ['检查数据源中 deletedAt 字段的格式']);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
id: obj.id,
|
|
58
|
+
content: obj.content,
|
|
59
|
+
source: obj.source,
|
|
60
|
+
name: obj.name,
|
|
61
|
+
createdAt: obj.createdAt,
|
|
62
|
+
accessedAt: obj.accessedAt,
|
|
63
|
+
score: obj.score ?? DEFAULT_MEMORY_SCORE,
|
|
64
|
+
deletedAt: obj.deletedAt,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 兼容性别名 — 保持原有测试代码 (MemorySchema.parse(...)) 无需修改
|
|
15
69
|
*/
|
|
16
|
-
export const MemorySchema =
|
|
17
|
-
/** 唯一标识(source:name,如 'rule:core'、'insight:1718083200000') */
|
|
18
|
-
id: z.string(),
|
|
19
|
-
/** 记忆内容(Markdown 文本) */
|
|
20
|
-
content: z.string(),
|
|
21
|
-
/** 来源标签(开放字符串,非枚举) */
|
|
22
|
-
source: z.string(),
|
|
23
|
-
/** 可读名称(文件名或摘要标题) */
|
|
24
|
-
name: z.string(),
|
|
25
|
-
/** 创建时间(ISO 8601) */
|
|
26
|
-
createdAt: z.string().datetime(),
|
|
27
|
-
/** 最后访问时间(每次召回时刷新) */
|
|
28
|
-
accessedAt: z.string().datetime(),
|
|
29
|
-
/** 权重(0-1,召回时用于排序) */
|
|
30
|
-
score: z.number().min(0).max(1).default(0.5),
|
|
31
|
-
/** 软删除时间(ISO 8601,可选;非 undefined 表示已软删除,回收站保留 30 天后自动物理清理) */
|
|
32
|
-
deletedAt: z.string().datetime().optional(),
|
|
33
|
-
});
|
|
70
|
+
export const MemorySchema = { parse: parseMemory };
|
|
34
71
|
// ─── source 标签约定(非枚举,仅为泊文当前使用的约定) ──────
|
|
35
72
|
/**
|
|
36
73
|
* 泊文当前使用的 source 标签约定
|
|
@@ -53,6 +90,8 @@ export const SOURCE_LABELS = {
|
|
|
53
90
|
WORK_PROJECTION: 'work-projection',
|
|
54
91
|
/** 内容护栏规则(configDir/rules/guardrails/ 下的规则文件) */
|
|
55
92
|
GUARDRAIL: 'guardrail',
|
|
93
|
+
/** 未知来源(inferSource 兜底值,文件路径未匹配已知目录时的默认标签) */
|
|
94
|
+
UNKNOWN: 'unknown',
|
|
56
95
|
};
|
|
57
96
|
/**
|
|
58
97
|
* weight 四档离散值常量(LLM 输出约束)
|
package/dist/memory/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,13 @@ export interface UserProfileEntry {
|
|
|
23
23
|
id: string;
|
|
24
24
|
/** 子分类 */
|
|
25
25
|
category: ProfileCategory;
|
|
26
|
+
/**
|
|
27
|
+
* 显式字段名
|
|
28
|
+
*
|
|
29
|
+
* 标识同 category 下的具体字段(如 identity 下 "姓名"/"住址"/"职业"),
|
|
30
|
+
* 用于冲突检测——同 category + 同 fieldName 视为同一字段的更新。
|
|
31
|
+
*/
|
|
32
|
+
fieldName: string;
|
|
26
33
|
/** 事实值(如 "姓名: 张三") */
|
|
27
34
|
value: string;
|
|
28
35
|
/** 来源(哪一轮对话提到) */
|
|
@@ -37,6 +44,14 @@ export interface UserProfileEntry {
|
|
|
37
44
|
/** extractUserFacts 的原始提取结果 */
|
|
38
45
|
export interface ExtractedFact {
|
|
39
46
|
category: ProfileCategory;
|
|
47
|
+
/**
|
|
48
|
+
* 显式字段名
|
|
49
|
+
*
|
|
50
|
+
* 由提取器显式填充(如 "姓名"/"住址"/"职业"/"偏好"/"工具"/"专长"),
|
|
51
|
+
* 冲突检测基于 category + fieldName,即使 value 格式变化(如 LLM 输出无前缀),
|
|
52
|
+
* 仍能正确识别冲突。
|
|
53
|
+
*/
|
|
54
|
+
fieldName: string;
|
|
40
55
|
value: string;
|
|
41
56
|
sourceTurn: string;
|
|
42
57
|
/** 置信度 0-1(≥0.8 直接归档,否则标记待确认) */
|
|
@@ -118,13 +133,16 @@ export declare class UserProfile {
|
|
|
118
133
|
*/
|
|
119
134
|
private upsertFact;
|
|
120
135
|
/**
|
|
121
|
-
*
|
|
136
|
+
* 删除同分类同字段的旧条目(用户更新了信息)
|
|
137
|
+
*
|
|
138
|
+
* 当用户说"我叫李四"替换之前的"我叫张三"时,移除旧的 identity/姓名 条目。
|
|
122
139
|
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
140
|
+
* 冲突判定基于 `category + fieldName`:
|
|
141
|
+
* - 新数据:fact.fieldName 由提取器显式填充,parseContentField 返回 parsed.fieldName
|
|
142
|
+
* - 旧数据:parseContentField 降级从 value 前缀提取 fieldName(兼容历史持久化数据)
|
|
143
|
+
* - 同 category + 同 fieldName + 不同 value = 用户更新了该字段,删除旧条目
|
|
125
144
|
*
|
|
126
|
-
*
|
|
127
|
-
* 构建 contentPrefix → entry 的 Map 索引,冲突检测从 O(n*m) 降为 O(m)。
|
|
145
|
+
* 构建 `category:fieldName` → Memory[] 的 Map 索引,冲突检测从 O(n*m) 降为 O(m)。
|
|
128
146
|
*
|
|
129
147
|
* @param fact 当前提取到的新事实
|
|
130
148
|
*/
|
|
@@ -132,20 +150,26 @@ export declare class UserProfile {
|
|
|
132
150
|
/**
|
|
133
151
|
* 将 UserProfileEntry 转为 Memory(用于写入 SQLite)
|
|
134
152
|
*
|
|
135
|
-
* content 字段使用 JSON 编码存储 category + value 元数据,
|
|
153
|
+
* content 字段使用 JSON 编码存储 category + value + fieldName 元数据,
|
|
136
154
|
* name 字段为固定可读标签,category 通过 content 的 JSON 元数据显式编码。
|
|
137
155
|
* 确认状态:仅已确认条目调用此方法(待确认条目不写入存储)
|
|
138
156
|
*/
|
|
139
157
|
private toMemory;
|
|
140
158
|
/**
|
|
141
|
-
* 从 content 字段解析 category
|
|
159
|
+
* 从 content 字段解析 category / value / fieldName
|
|
142
160
|
*
|
|
143
161
|
* 优先从 content JSON 解码元数据,降级到旧格式 name 字段解析,
|
|
144
162
|
* 确保已有 SQLite 数据(旧格式 name="${category}: ${value}")兼容加载。
|
|
145
163
|
*
|
|
164
|
+
* fieldName 解析优先级:
|
|
165
|
+
* 1. content JSON 含 fieldName → 直接返回(新数据)
|
|
166
|
+
* 2. content JSON 无 fieldName → 从 value 前缀提取(旧 JSON 数据,无 fieldName 字段)
|
|
167
|
+
* 3. name 字段旧格式 → 从 value 前缀提取
|
|
168
|
+
* 4. 最终降级 → fieldName = 'unknown'(无法识别字段名,冲突检测会跳过)
|
|
169
|
+
*
|
|
146
170
|
* @param content Memory 的 content 字段(新格式为 JSON,旧格式为纯 value)
|
|
147
171
|
* @param name Memory 的 name 字段(旧格式为 "${category}: ${value}")
|
|
148
|
-
* @returns 解析出的 category
|
|
172
|
+
* @returns 解析出的 category / value / fieldName
|
|
149
173
|
*/
|
|
150
174
|
private parseContentField;
|
|
151
175
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userProfile.d.ts","sourceRoot":"","sources":["../../src/memory/userProfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAOnE,cAAc;AACd,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"userProfile.d.ts","sourceRoot":"","sources":["../../src/memory/userProfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAOnE,cAAc;AACd,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;AAqD5F,aAAa;AACb,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAC;IACX,UAAU;IACV,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,+BAA+B;AAC/B,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,WAAW;IAIV,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,4BAA4B;IAC5B,OAAO,CAAC,KAAK,CAA4C;gBAE5B,KAAK,EAAE,cAAc;IAElD;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAmCzC;;;;;;;;OAQG;IACG,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAYvE;;OAEG;IACH,YAAY,IAAI,gBAAgB,EAAE;IAIlC;;;;;OAKG;IACH,UAAU,IAAI,gBAAgB,EAAE;IAIhC;;;;;;;;;OASG;IACH,iBAAiB,IAAI,MAAM;IA0B3B;;;;;;OAMG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxC;;;;OAIG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAavC;;;;;;;;;OASG;YACW,UAAU;IAoDxB;;;;;;;;;;;;;OAaG;YACW,wBAAwB;IA2CtC;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;IAmBhB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAoCzB;;OAEG;IACH,OAAO,CAAC,aAAa;CAUtB"}
|