@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.
- package/LICENSE +21 -0
- package/README.md +148 -0
- package/dist/agent/agent.d.ts +343 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +893 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/assembler.d.ts +77 -0
- package/dist/agent/assembler.d.ts.map +1 -0
- package/dist/agent/assembler.js +115 -0
- package/dist/agent/assembler.js.map +1 -0
- package/dist/agent/builtinToolHandlers.d.ts +96 -0
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -0
- package/dist/agent/builtinToolHandlers.js +388 -0
- package/dist/agent/builtinToolHandlers.js.map +1 -0
- package/dist/agent/builtinTools.d.ts +35 -0
- package/dist/agent/builtinTools.d.ts.map +1 -0
- package/dist/agent/builtinTools.js +75 -0
- package/dist/agent/builtinTools.js.map +1 -0
- package/dist/agent/constants.d.ts +67 -0
- package/dist/agent/constants.d.ts.map +1 -0
- package/dist/agent/constants.js +67 -0
- package/dist/agent/constants.js.map +1 -0
- package/dist/agent/contextManager.d.ts +130 -0
- package/dist/agent/contextManager.d.ts.map +1 -0
- package/dist/agent/contextManager.js +287 -0
- package/dist/agent/contextManager.js.map +1 -0
- package/dist/agent/loop.d.ts +288 -0
- package/dist/agent/loop.d.ts.map +1 -0
- package/dist/agent/loop.js +756 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/managers/autoConfigRefiner.d.ts +39 -0
- package/dist/agent/managers/autoConfigRefiner.d.ts.map +1 -0
- package/dist/agent/managers/autoConfigRefiner.js +150 -0
- package/dist/agent/managers/autoConfigRefiner.js.map +1 -0
- package/dist/agent/managers/configManager.d.ts +114 -0
- package/dist/agent/managers/configManager.d.ts.map +1 -0
- package/dist/agent/managers/configManager.js +186 -0
- package/dist/agent/managers/configManager.js.map +1 -0
- package/dist/agent/managers/insightExtractor.d.ts +141 -0
- package/dist/agent/managers/insightExtractor.d.ts.map +1 -0
- package/dist/agent/managers/insightExtractor.js +420 -0
- package/dist/agent/managers/insightExtractor.js.map +1 -0
- package/dist/agent/managers/memoryAdvisor.d.ts +96 -0
- package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -0
- package/dist/agent/managers/memoryAdvisor.js +198 -0
- package/dist/agent/managers/memoryAdvisor.js.map +1 -0
- package/dist/agent/managers/memoryInspector.d.ts +231 -0
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -0
- package/dist/agent/managers/memoryInspector.js +327 -0
- package/dist/agent/managers/memoryInspector.js.map +1 -0
- package/dist/agent/managers/sessionManager.d.ts +89 -0
- package/dist/agent/managers/sessionManager.d.ts.map +1 -0
- package/dist/agent/managers/sessionManager.js +178 -0
- package/dist/agent/managers/sessionManager.js.map +1 -0
- package/dist/agent/managers/userFactExtractor.d.ts +25 -0
- package/dist/agent/managers/userFactExtractor.d.ts.map +1 -0
- package/dist/agent/managers/userFactExtractor.js +81 -0
- package/dist/agent/managers/userFactExtractor.js.map +1 -0
- package/dist/agent/managers/workProjection.d.ts +117 -0
- package/dist/agent/managers/workProjection.d.ts.map +1 -0
- package/dist/agent/managers/workProjection.js +290 -0
- package/dist/agent/managers/workProjection.js.map +1 -0
- package/dist/agent/messageHistory.d.ts +157 -0
- package/dist/agent/messageHistory.d.ts.map +1 -0
- package/dist/agent/messageHistory.js +288 -0
- package/dist/agent/messageHistory.js.map +1 -0
- package/dist/agent/toolExecutor.d.ts +137 -0
- package/dist/agent/toolExecutor.d.ts.map +1 -0
- package/dist/agent/toolExecutor.js +209 -0
- package/dist/agent/toolExecutor.js.map +1 -0
- package/dist/agent/tracer.d.ts +122 -0
- package/dist/agent/tracer.d.ts.map +1 -0
- package/dist/agent/tracer.js +64 -0
- package/dist/agent/tracer.js.map +1 -0
- package/dist/agent/types.d.ts +98 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +19 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/config/loader.d.ts +229 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +194 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/eval/evalTypes.d.ts +118 -0
- package/dist/eval/evalTypes.d.ts.map +1 -0
- package/dist/eval/evalTypes.js +102 -0
- package/dist/eval/evalTypes.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/embedding.d.ts +62 -0
- package/dist/llm/embedding.d.ts.map +1 -0
- package/dist/llm/embedding.js +162 -0
- package/dist/llm/embedding.js.map +1 -0
- package/dist/llm/factory.d.ts +39 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +108 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/openaiCompatible.d.ts +63 -0
- package/dist/llm/openaiCompatible.d.ts.map +1 -0
- package/dist/llm/openaiCompatible.js +340 -0
- package/dist/llm/openaiCompatible.js.map +1 -0
- package/dist/llm/provider.d.ts +91 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +14 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/types.d.ts +25 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +7 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/logging/logger.d.ts +39 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +279 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/loggerInterface.d.ts +33 -0
- package/dist/logging/loggerInterface.d.ts.map +1 -0
- package/dist/logging/loggerInterface.js +2 -0
- package/dist/logging/loggerInterface.js.map +1 -0
- package/dist/memory/inMemoryRelationStore.d.ts +51 -0
- package/dist/memory/inMemoryRelationStore.d.ts.map +1 -0
- package/dist/memory/inMemoryRelationStore.js +65 -0
- package/dist/memory/inMemoryRelationStore.js.map +1 -0
- package/dist/memory/inMemoryStorage.d.ts +97 -0
- package/dist/memory/inMemoryStorage.d.ts.map +1 -0
- package/dist/memory/inMemoryStorage.js +177 -0
- package/dist/memory/inMemoryStorage.js.map +1 -0
- package/dist/memory/loader.d.ts +49 -0
- package/dist/memory/loader.d.ts.map +1 -0
- package/dist/memory/loader.js +93 -0
- package/dist/memory/loader.js.map +1 -0
- package/dist/memory/projectManager.d.ts +182 -0
- package/dist/memory/projectManager.d.ts.map +1 -0
- package/dist/memory/projectManager.js +441 -0
- package/dist/memory/projectManager.js.map +1 -0
- package/dist/memory/recall.d.ts +77 -0
- package/dist/memory/recall.d.ts.map +1 -0
- package/dist/memory/recall.js +147 -0
- package/dist/memory/recall.js.map +1 -0
- package/dist/memory/relationStore.d.ts +78 -0
- package/dist/memory/relationStore.d.ts.map +1 -0
- package/dist/memory/relationStore.js +2 -0
- package/dist/memory/relationStore.js.map +1 -0
- package/dist/memory/sessionStore.d.ts +84 -0
- package/dist/memory/sessionStore.d.ts.map +1 -0
- package/dist/memory/sessionStore.js +2 -0
- package/dist/memory/sessionStore.js.map +1 -0
- package/dist/memory/storageInterface.d.ts +107 -0
- package/dist/memory/storageInterface.d.ts.map +1 -0
- package/dist/memory/storageInterface.js +2 -0
- package/dist/memory/storageInterface.js.map +1 -0
- package/dist/memory/store.d.ts +50 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +160 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/types.d.ts +189 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +230 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/memory/userProfile.d.ts +156 -0
- package/dist/memory/userProfile.d.ts.map +1 -0
- package/dist/memory/userProfile.js +315 -0
- package/dist/memory/userProfile.js.map +1 -0
- package/dist/memory/vectorStore.d.ts +75 -0
- package/dist/memory/vectorStore.d.ts.map +1 -0
- package/dist/memory/vectorStore.js +144 -0
- package/dist/memory/vectorStore.js.map +1 -0
- package/dist/persona/personaManager.d.ts +121 -0
- package/dist/persona/personaManager.d.ts.map +1 -0
- package/dist/persona/personaManager.js +349 -0
- package/dist/persona/personaManager.js.map +1 -0
- package/dist/persona/types.d.ts +32 -0
- package/dist/persona/types.d.ts.map +1 -0
- package/dist/persona/types.js +5 -0
- package/dist/persona/types.js.map +1 -0
- package/dist/security/pathGuard.d.ts +121 -0
- package/dist/security/pathGuard.d.ts.map +1 -0
- package/dist/security/pathGuard.js +276 -0
- package/dist/security/pathGuard.js.map +1 -0
- package/dist/skill/skillManager.d.ts +82 -0
- package/dist/skill/skillManager.d.ts.map +1 -0
- package/dist/skill/skillManager.js +198 -0
- package/dist/skill/skillManager.js.map +1 -0
- package/dist/skill/types.d.ts +28 -0
- package/dist/skill/types.d.ts.map +1 -0
- package/dist/skill/types.js +5 -0
- package/dist/skill/types.js.map +1 -0
- package/dist/utils/errors.d.ts +86 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +143 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/eventEmitter.d.ts +87 -0
- package/dist/utils/eventEmitter.d.ts.map +1 -0
- package/dist/utils/eventEmitter.js +79 -0
- package/dist/utils/eventEmitter.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +24 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +44 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/json.d.ts +20 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +65 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/loggerHolder.d.ts +37 -0
- package/dist/utils/loggerHolder.d.ts.map +1 -0
- package/dist/utils/loggerHolder.js +49 -0
- package/dist/utils/loggerHolder.js.map +1 -0
- package/dist/utils/math.d.ts +5 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +19 -0
- package/dist/utils/math.js.map +1 -0
- package/dist/utils/path.d.ts +28 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +33 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/safeTimer.d.ts +26 -0
- package/dist/utils/safeTimer.d.ts.map +1 -0
- package/dist/utils/safeTimer.js +49 -0
- package/dist/utils/safeTimer.js.map +1 -0
- package/dist/utils/scanner.d.ts +54 -0
- package/dist/utils/scanner.d.ts.map +1 -0
- package/dist/utils/scanner.js +115 -0
- package/dist/utils/scanner.js.map +1 -0
- package/dist/utils/segmenter.d.ts +30 -0
- package/dist/utils/segmenter.d.ts.map +1 -0
- package/dist/utils/segmenter.js +80 -0
- package/dist/utils/segmenter.js.map +1 -0
- package/dist/utils/strings.d.ts +18 -0
- package/dist/utils/strings.d.ts.map +1 -0
- package/dist/utils/strings.js +25 -0
- package/dist/utils/strings.js.map +1 -0
- package/dist/utils/time.d.ts +23 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +31 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/toError.d.ts +13 -0
- package/dist/utils/toError.d.ts.map +1 -0
- package/dist/utils/toError.js +22 -0
- package/dist/utils/toError.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 从用户输入中提取事实
|
|
3
|
+
*
|
|
4
|
+
* 使用正则 + 关键词规则,兼顾阶段一的低成本需求。
|
|
5
|
+
* 高置信度规则(≥0.9)→ 直接归档
|
|
6
|
+
* 中置信度(0.7-0.8)→ 标记待确认
|
|
7
|
+
*
|
|
8
|
+
* @param input 用户原始输入
|
|
9
|
+
* @param turnIndex 当前轮次标识
|
|
10
|
+
*/
|
|
11
|
+
export function extractUserFacts(input, turnIndex) {
|
|
12
|
+
const facts = [];
|
|
13
|
+
// ── 高置信度:身份声明 ──
|
|
14
|
+
// "我叫张三" "我是张三" "我的名字是张三"
|
|
15
|
+
// 排除问句关键词(谁/哪/什/吗),防止 "我是谁" "我是哪个" 误匹配
|
|
16
|
+
const identityMatch = input.match(/我(?:叫|是|的名字是)\s*([^\s,。,\.!!??\n谁哪什吗]{1,15})/);
|
|
17
|
+
if (identityMatch) {
|
|
18
|
+
facts.push({
|
|
19
|
+
category: 'identity',
|
|
20
|
+
value: `姓名: ${identityMatch[1]}`,
|
|
21
|
+
sourceTurn: turnIndex,
|
|
22
|
+
confidence: 0.95,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// "我住在北京" "我家在上海"
|
|
26
|
+
const locationMatch = input.match(/(?:我住在?|我家在)\s*([^\s,。,\.!!??\n]{1,15})/);
|
|
27
|
+
if (locationMatch) {
|
|
28
|
+
facts.push({
|
|
29
|
+
category: 'identity',
|
|
30
|
+
value: `住址: ${locationMatch[1]}`,
|
|
31
|
+
sourceTurn: turnIndex,
|
|
32
|
+
confidence: 0.9,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// "我(是|当|做).*?(的)" —— 职业声明
|
|
36
|
+
const jobMatch = input.match(/我(?:是|当|做)(?:一[个名位])?\s*([^\s,。,\.!!??\n谁哪什吗]{1,10})(?:的)?/);
|
|
37
|
+
if (jobMatch && !identityMatch) {
|
|
38
|
+
// 避免与 identityMatch 重复
|
|
39
|
+
facts.push({
|
|
40
|
+
category: 'identity',
|
|
41
|
+
value: `职业: ${jobMatch[1]}`,
|
|
42
|
+
sourceTurn: turnIndex,
|
|
43
|
+
confidence: 0.85,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// ── 高置信度:偏好声明 ──
|
|
47
|
+
// "我喜欢TS" "我更喜欢Python" "我习惯用VS Code"
|
|
48
|
+
const prefMatch = input.match(/(?:我(?:很|非常|最|更)?(?:喜欢|爱|习惯|偏好)(?:用|写|做|的))\s*([^\s,。,\.!!??\n]{1,20})/);
|
|
49
|
+
if (prefMatch) {
|
|
50
|
+
facts.push({
|
|
51
|
+
category: 'preference',
|
|
52
|
+
value: `偏好: ${prefMatch[1]}`,
|
|
53
|
+
sourceTurn: turnIndex,
|
|
54
|
+
confidence: 0.85,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// ── 中置信度:工具/环境声明 ──
|
|
58
|
+
// "我用VS Code" "我的环境是Windows"
|
|
59
|
+
const toolMatch = input.match(/我(?:用|使用|的环境是)\s*([^\s,。,\.!!??\n]{1,20})/);
|
|
60
|
+
if (toolMatch && !prefMatch) {
|
|
61
|
+
facts.push({
|
|
62
|
+
category: 'preference',
|
|
63
|
+
value: `工具: ${toolMatch[1]}`,
|
|
64
|
+
sourceTurn: turnIndex,
|
|
65
|
+
confidence: 0.8,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// ── 较低置信度:专长声明 ──
|
|
69
|
+
// "我熟悉React" "我擅长后端"
|
|
70
|
+
const expertiseMatch = input.match(/我(?:熟悉|擅长|精通|会)\s*([^\s,。,\.!!??\n]{1,20})/);
|
|
71
|
+
if (expertiseMatch) {
|
|
72
|
+
facts.push({
|
|
73
|
+
category: 'expertise',
|
|
74
|
+
value: `专长: ${expertiseMatch[1]}`,
|
|
75
|
+
sourceTurn: turnIndex,
|
|
76
|
+
confidence: 0.75,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return facts;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=userFactExtractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userFactExtractor.js","sourceRoot":"","sources":["../../../src/agent/managers/userFactExtractor.ts"],"names":[],"mappings":"AAeA;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,SAAiB;IAC/D,MAAM,KAAK,GAAoB,EAAE,CAAC;IAElC,kBAAkB;IAClB,0BAA0B;IAC1B,uCAAuC;IACzC,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAChF,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,EAAE;YAChC,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB;IAClB,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7E,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,EAAE;YAChC,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IAED,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAC1B,4DAA4D,CAC7D,CAAC;IACF,IAAI,QAAQ,IAAI,CAAC,aAAa,EAAE,CAAC;QAC/B,uBAAuB;QACvB,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE;YAC3B,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB;IAClB,qCAAqC;IACrC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAC3B,wEAAwE,CACzE,CAAC;IACF,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ,EAAE,YAAY;YACtB,KAAK,EAAE,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE;YAC5B,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,qBAAqB;IACrB,6BAA6B;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC3E,IAAI,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ,EAAE,YAAY;YACtB,KAAK,EAAE,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE;YAC5B,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IAED,mBAAmB;IACnB,qBAAqB;IACrB,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;IACjF,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC;YACT,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,OAAO,cAAc,CAAC,CAAC,CAAC,EAAE;YACjC,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { LlmProvider } from '../../llm/provider.js';
|
|
2
|
+
import type { IMemoryStorage } from '../../memory/storageInterface.js';
|
|
3
|
+
/** 作品投影的持久化结构 */
|
|
4
|
+
export interface WorkProjectionEntry {
|
|
5
|
+
/** 唯一 ID(work-proj-<slug>) */
|
|
6
|
+
id: string;
|
|
7
|
+
/** 文件路径 */
|
|
8
|
+
sourcePath: string;
|
|
9
|
+
/** 文件 hash(用于变更检测) */
|
|
10
|
+
fileHash: string;
|
|
11
|
+
/** 概要 */
|
|
12
|
+
summary: string;
|
|
13
|
+
/** 结构(章节/模块列表) */
|
|
14
|
+
structure: string[];
|
|
15
|
+
/** 关键决策 */
|
|
16
|
+
keyDecisions: string[];
|
|
17
|
+
/** 最后更新时间 */
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 作品投影管理器
|
|
22
|
+
*
|
|
23
|
+
* 分层:agent/ 层 — 调用 LLM 生成投影内容,通过 IMemoryStorage 写入存储。
|
|
24
|
+
* 属于"作品 → 记忆投影"的桥梁组件,不属于 memory/ 的纯存储/召回职责。
|
|
25
|
+
*/
|
|
26
|
+
export declare class WorkProjectionManager {
|
|
27
|
+
private readonly index;
|
|
28
|
+
private readonly provider;
|
|
29
|
+
constructor(index: IMemoryStorage, provider: LlmProvider);
|
|
30
|
+
/**
|
|
31
|
+
* in-flight Promise 缓存,防止同文件并发读取时重复调用 LLM
|
|
32
|
+
* key: sourcePath(同一文件路径只会有一个未完成的生成 Promise)
|
|
33
|
+
*/
|
|
34
|
+
private readonly inflight;
|
|
35
|
+
/**
|
|
36
|
+
* 检查并更新作品投影
|
|
37
|
+
*
|
|
38
|
+
* 核心逻辑:
|
|
39
|
+
* 1. 计算文件 hash
|
|
40
|
+
* 2. 查询 SQLite 中是否有该文件的投影(by sourcePath)
|
|
41
|
+
* 3. 无投影 → 首次读取 → 生成
|
|
42
|
+
* 4. 有投影但 hash 不同 → 文件已修改 → 重新生成
|
|
43
|
+
* 5. 有投影且 hash 相同 → 跳过
|
|
44
|
+
*
|
|
45
|
+
* 同文件并发调用时复用同一 in-flight Promise,避免重复 LLM 调用。
|
|
46
|
+
*
|
|
47
|
+
* @param filePath 作品文件路径
|
|
48
|
+
* @param content 文件内容
|
|
49
|
+
* @param fileName 文件名(用于生成标题)
|
|
50
|
+
* @returns 投影条目,跳过生成返回已有投影
|
|
51
|
+
*/
|
|
52
|
+
ensureProjection(filePath: string, content: string, fileName?: string): Promise<WorkProjectionEntry | null>;
|
|
53
|
+
/**
|
|
54
|
+
* 实际生成投影的核心逻辑
|
|
55
|
+
*/
|
|
56
|
+
private doEnsureProjection;
|
|
57
|
+
/**
|
|
58
|
+
* 获取已有的作品投影(不触发生成)
|
|
59
|
+
*
|
|
60
|
+
* @param filePath 文件路径
|
|
61
|
+
* @returns 投影条目,不存在返回 null
|
|
62
|
+
*/
|
|
63
|
+
getProjection(filePath: string): Promise<WorkProjectionEntry | null>;
|
|
64
|
+
/**
|
|
65
|
+
* 加载所有作品投影(按 source 标签召回)
|
|
66
|
+
*/
|
|
67
|
+
loadAll(): Promise<WorkProjectionEntry[]>;
|
|
68
|
+
/**
|
|
69
|
+
* 调用 LLM 生成作品投影
|
|
70
|
+
*
|
|
71
|
+
* @param name 文件名
|
|
72
|
+
* @param content 文件内容
|
|
73
|
+
* @returns { summary, structure, keyDecisions }
|
|
74
|
+
*/
|
|
75
|
+
private generate;
|
|
76
|
+
/**
|
|
77
|
+
* 计算文件 SHA-256 hash
|
|
78
|
+
*/
|
|
79
|
+
private computeHash;
|
|
80
|
+
/**
|
|
81
|
+
* 从 Memory content 中解析 hash
|
|
82
|
+
*
|
|
83
|
+
* 复用 decodeContent,避免重复 JSON 解析与 HTML 注释匹配逻辑。
|
|
84
|
+
* content 格式:JSON 元数据行 + 空行 + summary(旧格式:HTML 注释兼容)
|
|
85
|
+
*/
|
|
86
|
+
private parseHash;
|
|
87
|
+
/**
|
|
88
|
+
* 将 WorkProjectionEntry 转为 Memory(用于写入存储)
|
|
89
|
+
*
|
|
90
|
+
* 元数据(hash / structure / keyDecisions)编码为 content 首行 JSON,
|
|
91
|
+
* summary 保持为可见内容。source = 'work-projection'。
|
|
92
|
+
*/
|
|
93
|
+
private toMemory;
|
|
94
|
+
/**
|
|
95
|
+
* 从 Memory 恢复 WorkProjectionEntry
|
|
96
|
+
*
|
|
97
|
+
* 从 content 的 HTML 注释中解码 hash / structure / keyDecisions
|
|
98
|
+
*/
|
|
99
|
+
private fromMemory;
|
|
100
|
+
/**
|
|
101
|
+
* 将投影元数据编码为 content(JSON 元数据行 + 空行 + summary)
|
|
102
|
+
*
|
|
103
|
+
* 格式:
|
|
104
|
+
* {"hash":"...","structure":["..."],"decisions":["..."]}
|
|
105
|
+
* (空行)
|
|
106
|
+
* <summary>
|
|
107
|
+
*/
|
|
108
|
+
private encodeContent;
|
|
109
|
+
/**
|
|
110
|
+
* 从 content 中解码投影元数据
|
|
111
|
+
*
|
|
112
|
+
* 新格式:首行 JSON + 空行 + summary
|
|
113
|
+
* 旧格式(HTML 注释)兼容解析
|
|
114
|
+
*/
|
|
115
|
+
private decodeContent;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=workProjection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workProjection.d.ts","sourceRoot":"","sources":["../../../src/agent/managers/workProjection.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AASnE,iBAAiB;AACjB,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS;IACT,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW;IACX,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,WAAW;IAGxC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+D;IAExF;;;;;;;;;;;;;;;;OAgBG;IACG,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAgBtC;;OAEG;YACW,kBAAkB;IAiDhC;;;;;OAKG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAO1E;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAO/C;;;;;;OAMG;YACW,QAAQ;IAuDtB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAIjB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAchB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAalB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;CAyCtB"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 作品投影管理 — 用户作品的文件级感知
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* - Agent 读取用户作品时生成"作品投影"(概要 + 结构 + 关键决策)
|
|
6
|
+
* - 基于文件 hash 判断是否需要重新生成
|
|
7
|
+
* - 不复制作品全文——只存概要,文件本体归用户
|
|
8
|
+
*
|
|
9
|
+
* 触发规则(architecture_philosophy_rules.md §1 万物皆记忆 · 第 2 层作品投影):
|
|
10
|
+
* - 首次读取(文件 hash 无记录)→ 生成投影
|
|
11
|
+
* - hash 变更(文件被修改)→ 重新生成
|
|
12
|
+
* - hash 未变(重复读取)→ 跳过
|
|
13
|
+
*
|
|
14
|
+
* 设计原则:
|
|
15
|
+
* - 作品 = 用户的产出物(小说、代码),不归 Agent 管
|
|
16
|
+
* - 作品投影 = Agent 记住"作品的形象",source = 'work-projection'
|
|
17
|
+
* - 文件变化由用户负责
|
|
18
|
+
*
|
|
19
|
+
* 分层说明:
|
|
20
|
+
* 本模块位于 agent/ 层(非 memory/ 层),因为它依赖 LlmProvider 做内容生成。
|
|
21
|
+
* memory/ 层只做存储和召回,不做 LLM 调用(EmbeddingService 接口注入除外)。
|
|
22
|
+
*/
|
|
23
|
+
import { createHash } from 'node:crypto';
|
|
24
|
+
import { SOURCE_LABELS } from '../../memory/types.js';
|
|
25
|
+
import { logger } from '../../logging/logger.js';
|
|
26
|
+
import { slugify } from '../../utils/strings.js';
|
|
27
|
+
import { basename } from '../../utils/path.js';
|
|
28
|
+
import { toError } from '../../utils/errors.js';
|
|
29
|
+
import { parseLlmJson } from '../../utils/json.js';
|
|
30
|
+
/**
|
|
31
|
+
* 作品投影管理器
|
|
32
|
+
*
|
|
33
|
+
* 分层:agent/ 层 — 调用 LLM 生成投影内容,通过 IMemoryStorage 写入存储。
|
|
34
|
+
* 属于"作品 → 记忆投影"的桥梁组件,不属于 memory/ 的纯存储/召回职责。
|
|
35
|
+
*/
|
|
36
|
+
export class WorkProjectionManager {
|
|
37
|
+
index;
|
|
38
|
+
provider;
|
|
39
|
+
constructor(index, provider) {
|
|
40
|
+
this.index = index;
|
|
41
|
+
this.provider = provider;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* in-flight Promise 缓存,防止同文件并发读取时重复调用 LLM
|
|
45
|
+
* key: sourcePath(同一文件路径只会有一个未完成的生成 Promise)
|
|
46
|
+
*/
|
|
47
|
+
inflight = new Map();
|
|
48
|
+
/**
|
|
49
|
+
* 检查并更新作品投影
|
|
50
|
+
*
|
|
51
|
+
* 核心逻辑:
|
|
52
|
+
* 1. 计算文件 hash
|
|
53
|
+
* 2. 查询 SQLite 中是否有该文件的投影(by sourcePath)
|
|
54
|
+
* 3. 无投影 → 首次读取 → 生成
|
|
55
|
+
* 4. 有投影但 hash 不同 → 文件已修改 → 重新生成
|
|
56
|
+
* 5. 有投影且 hash 相同 → 跳过
|
|
57
|
+
*
|
|
58
|
+
* 同文件并发调用时复用同一 in-flight Promise,避免重复 LLM 调用。
|
|
59
|
+
*
|
|
60
|
+
* @param filePath 作品文件路径
|
|
61
|
+
* @param content 文件内容
|
|
62
|
+
* @param fileName 文件名(用于生成标题)
|
|
63
|
+
* @returns 投影条目,跳过生成返回已有投影
|
|
64
|
+
*/
|
|
65
|
+
async ensureProjection(filePath, content, fileName) {
|
|
66
|
+
const inflight = this.inflight.get(filePath);
|
|
67
|
+
if (inflight) {
|
|
68
|
+
return inflight;
|
|
69
|
+
}
|
|
70
|
+
const promise = this.doEnsureProjection(filePath, content, fileName);
|
|
71
|
+
this.inflight.set(filePath, promise);
|
|
72
|
+
try {
|
|
73
|
+
return await promise;
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
// 不论成功失败都清理占位(让下一次调用重新走流程)
|
|
77
|
+
this.inflight.delete(filePath);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 实际生成投影的核心逻辑
|
|
82
|
+
*/
|
|
83
|
+
async doEnsureProjection(filePath, content, fileName) {
|
|
84
|
+
const hash = this.computeHash(content);
|
|
85
|
+
const name = fileName ?? (basename(filePath) || 'unknown');
|
|
86
|
+
// 查询已有投影
|
|
87
|
+
const existingId = `work-proj-${slugify(name)}`;
|
|
88
|
+
const existing = this.index.getById(existingId);
|
|
89
|
+
if (existing) {
|
|
90
|
+
// 检查 hash 是否变化
|
|
91
|
+
const existingHash = this.parseHash(existing);
|
|
92
|
+
if (existingHash === hash) {
|
|
93
|
+
// hash 未变 → 跳过
|
|
94
|
+
return this.fromMemory(existing);
|
|
95
|
+
}
|
|
96
|
+
// hash 变了 → 重新生成(不删除旧投影,upsert 覆盖)
|
|
97
|
+
}
|
|
98
|
+
// 生成新投影
|
|
99
|
+
try {
|
|
100
|
+
const projection = await this.generate(name, content);
|
|
101
|
+
const entry = {
|
|
102
|
+
id: `work-proj-${slugify(name)}`,
|
|
103
|
+
sourcePath: filePath,
|
|
104
|
+
fileHash: hash,
|
|
105
|
+
summary: projection.summary,
|
|
106
|
+
structure: projection.structure,
|
|
107
|
+
keyDecisions: projection.keyDecisions,
|
|
108
|
+
updatedAt: new Date().toISOString(),
|
|
109
|
+
};
|
|
110
|
+
// 写入存储(source = 'work-projection',语义独立)
|
|
111
|
+
this.index.upsert(this.toMemory(entry, hash));
|
|
112
|
+
logger.info({ file: filePath, hash, summaryLen: projection.summary.length }, '作品投影已生成');
|
|
113
|
+
return entry;
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
logger.warn({ err, file: filePath }, '作品投影生成失败');
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 获取已有的作品投影(不触发生成)
|
|
122
|
+
*
|
|
123
|
+
* @param filePath 文件路径
|
|
124
|
+
* @returns 投影条目,不存在返回 null
|
|
125
|
+
*/
|
|
126
|
+
async getProjection(filePath) {
|
|
127
|
+
const name = basename(filePath) || 'unknown';
|
|
128
|
+
const id = `work-proj-${slugify(name)}`;
|
|
129
|
+
const existing = this.index.getById(id);
|
|
130
|
+
return existing ? this.fromMemory(existing) : null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 加载所有作品投影(按 source 标签召回)
|
|
134
|
+
*/
|
|
135
|
+
async loadAll() {
|
|
136
|
+
const memories = this.index.getBySource(SOURCE_LABELS.WORK_PROJECTION);
|
|
137
|
+
return memories.map((m) => this.fromMemory(m));
|
|
138
|
+
}
|
|
139
|
+
// ── 私有方法 ──────────────────────────────────────
|
|
140
|
+
/**
|
|
141
|
+
* 调用 LLM 生成作品投影
|
|
142
|
+
*
|
|
143
|
+
* @param name 文件名
|
|
144
|
+
* @param content 文件内容
|
|
145
|
+
* @returns { summary, structure, keyDecisions }
|
|
146
|
+
*/
|
|
147
|
+
async generate(name, content) {
|
|
148
|
+
// 截断内容到 3000 字(控制 token 消耗)
|
|
149
|
+
const truncated = content.slice(0, 3000);
|
|
150
|
+
const promptMessages = [
|
|
151
|
+
{
|
|
152
|
+
role: 'system',
|
|
153
|
+
content: `你是作品分析助手。阅读用户的作品,生成一个"投影"——完整的作品概要、结构和关键决策。
|
|
154
|
+
|
|
155
|
+
输出格式(严格 JSON,不含 markdown 代码块标记):
|
|
156
|
+
{
|
|
157
|
+
"summary": "50-100字的作品概要",
|
|
158
|
+
"structure": ["模块1", "模块2", "..."],
|
|
159
|
+
"keyDecisions": ["关键决策1", "关键决策2", "..."]
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
要求:
|
|
163
|
+
- summary 控制在 50-100 字
|
|
164
|
+
- structure 列出 2-8 个模块名称
|
|
165
|
+
- keyDecisions 列出 1-3 个关键决策(如有)
|
|
166
|
+
- 不评价优劣,只客观描述`,
|
|
167
|
+
},
|
|
168
|
+
{ role: 'user', content: `# ${name}\n\n${truncated}` },
|
|
169
|
+
];
|
|
170
|
+
let result = '';
|
|
171
|
+
for await (const chunk of this.provider.chat(promptMessages, { maxTokens: 400 })) {
|
|
172
|
+
if (chunk.content)
|
|
173
|
+
result += chunk.content;
|
|
174
|
+
}
|
|
175
|
+
const parsed = parseLlmJson(result.trim());
|
|
176
|
+
if (parsed) {
|
|
177
|
+
return {
|
|
178
|
+
summary: parsed.summary ?? `${name}(无法获取概要)`,
|
|
179
|
+
structure: parsed.structure ?? [],
|
|
180
|
+
keyDecisions: parsed.keyDecisions ?? [],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// JSON 解析失败,降级为全文摘要
|
|
184
|
+
return {
|
|
185
|
+
summary: result.trim().slice(0, 100),
|
|
186
|
+
structure: [name],
|
|
187
|
+
keyDecisions: [],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 计算文件 SHA-256 hash
|
|
192
|
+
*/
|
|
193
|
+
computeHash(content) {
|
|
194
|
+
return createHash('sha256').update(content, 'utf-8').digest('hex');
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* 从 Memory content 中解析 hash
|
|
198
|
+
*
|
|
199
|
+
* 复用 decodeContent,避免重复 JSON 解析与 HTML 注释匹配逻辑。
|
|
200
|
+
* content 格式:JSON 元数据行 + 空行 + summary(旧格式:HTML 注释兼容)
|
|
201
|
+
*/
|
|
202
|
+
parseHash(memory) {
|
|
203
|
+
return this.decodeContent(memory.content).hash;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* 将 WorkProjectionEntry 转为 Memory(用于写入存储)
|
|
207
|
+
*
|
|
208
|
+
* 元数据(hash / structure / keyDecisions)编码为 content 首行 JSON,
|
|
209
|
+
* summary 保持为可见内容。source = 'work-projection'。
|
|
210
|
+
*/
|
|
211
|
+
toMemory(entry, hash) {
|
|
212
|
+
const now = new Date().toISOString();
|
|
213
|
+
const fileName = basename(entry.sourcePath);
|
|
214
|
+
return {
|
|
215
|
+
id: entry.id,
|
|
216
|
+
content: this.encodeContent(hash, entry.structure, entry.keyDecisions, entry.summary),
|
|
217
|
+
source: SOURCE_LABELS.WORK_PROJECTION,
|
|
218
|
+
name: `作品投影: ${fileName}`,
|
|
219
|
+
createdAt: now,
|
|
220
|
+
accessedAt: entry.updatedAt || now,
|
|
221
|
+
score: 0.8,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* 从 Memory 恢复 WorkProjectionEntry
|
|
226
|
+
*
|
|
227
|
+
* 从 content 的 HTML 注释中解码 hash / structure / keyDecisions
|
|
228
|
+
*/
|
|
229
|
+
fromMemory(m) {
|
|
230
|
+
const { hash, structure, keyDecisions, summary } = this.decodeContent(m.content);
|
|
231
|
+
return {
|
|
232
|
+
id: m.id,
|
|
233
|
+
sourcePath: '',
|
|
234
|
+
fileHash: hash ?? '',
|
|
235
|
+
summary,
|
|
236
|
+
structure,
|
|
237
|
+
keyDecisions,
|
|
238
|
+
updatedAt: m.accessedAt,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* 将投影元数据编码为 content(JSON 元数据行 + 空行 + summary)
|
|
243
|
+
*
|
|
244
|
+
* 格式:
|
|
245
|
+
* {"hash":"...","structure":["..."],"decisions":["..."]}
|
|
246
|
+
* (空行)
|
|
247
|
+
* <summary>
|
|
248
|
+
*/
|
|
249
|
+
encodeContent(hash, structure, keyDecisions, summary) {
|
|
250
|
+
const meta = JSON.stringify({ hash, structure, decisions: keyDecisions });
|
|
251
|
+
return `${meta}\n\n${summary}`;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 从 content 中解码投影元数据
|
|
255
|
+
*
|
|
256
|
+
* 新格式:首行 JSON + 空行 + summary
|
|
257
|
+
* 旧格式(HTML 注释)兼容解析
|
|
258
|
+
*/
|
|
259
|
+
decodeContent(content) {
|
|
260
|
+
// 新格式:首行 JSON
|
|
261
|
+
const firstLine = content.split('\n')[0] ?? '';
|
|
262
|
+
if (firstLine.startsWith('{')) {
|
|
263
|
+
try {
|
|
264
|
+
const meta = JSON.parse(firstLine);
|
|
265
|
+
const summary = content.slice(firstLine.length).trim();
|
|
266
|
+
return {
|
|
267
|
+
hash: meta.hash ?? null,
|
|
268
|
+
structure: meta.structure ?? [],
|
|
269
|
+
keyDecisions: meta.decisions ?? [],
|
|
270
|
+
summary,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
logger.debug({ err: toError(err).message }, '作品投影 JSON 解析失败,降级到旧格式');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// 旧格式兼容:HTML 注释
|
|
278
|
+
const hashMatch = content.match(/<!--\s*wp:hash:(\S+)\s*-->/);
|
|
279
|
+
const structureMatch = content.match(/<!--\s*wp:structure:(.+?)\s*-->/);
|
|
280
|
+
const decisionsMatch = content.match(/<!--\s*wp:decisions:(.+?)\s*-->/);
|
|
281
|
+
const summary = content.replace(/<!--\s*wp:\S+\s*-->\n?/g, '').trim();
|
|
282
|
+
return {
|
|
283
|
+
hash: hashMatch?.[1] ?? null,
|
|
284
|
+
structure: structureMatch?.[1]?.split('|') ?? [],
|
|
285
|
+
keyDecisions: decisionsMatch?.[1]?.split('|') ?? [],
|
|
286
|
+
summary,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=workProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workProjection.js","sourceRoot":"","sources":["../../../src/agent/managers/workProjection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 消息历史:Agent 对话过程中的消息持久化
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* - 封装"用户输入 → 会话存储"的追加操作
|
|
6
|
+
* - 封装"Agent 回复 → 会话存储"的追加操作
|
|
7
|
+
* - 维护当前会话上下文(date + session)
|
|
8
|
+
* - 通过 ISessionStore 接口实现会话持久化
|
|
9
|
+
*/
|
|
10
|
+
import type { ISessionStore, SessionMessage } from '../memory/sessionStore.js';
|
|
11
|
+
/**
|
|
12
|
+
* 分叉结果
|
|
13
|
+
*/
|
|
14
|
+
export interface ForkResult {
|
|
15
|
+
/** 新会话标识(不含日期前缀,如 "main-b1") */
|
|
16
|
+
newSession: string;
|
|
17
|
+
/** 会话日期 */
|
|
18
|
+
date: string;
|
|
19
|
+
/** 从源会话复制的消息列表 */
|
|
20
|
+
messages: SessionMessage[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 消息历史类
|
|
24
|
+
*/
|
|
25
|
+
export declare class MessageHistory {
|
|
26
|
+
/**
|
|
27
|
+
* 会话存储(可选)
|
|
28
|
+
* 注入后,消息会持久化到宿主提供的存储实现。
|
|
29
|
+
* 不注入则仅在内存中保存(AgentLoop.messages[])。
|
|
30
|
+
*/
|
|
31
|
+
private readonly sessionStore?;
|
|
32
|
+
/**
|
|
33
|
+
* 临时记忆最小窗口轮次(记忆减法方案 v1.0 · 排雷修正 L2)
|
|
34
|
+
*
|
|
35
|
+
* 上下文压缩时,最少保留的对话轮次。即使上下文利用率 ≥ 85%,
|
|
36
|
+
* 也不压缩到少于此轮次,保证基本上下文连贯性。
|
|
37
|
+
* 默认 3 轮,不可在运行时突破。
|
|
38
|
+
*/
|
|
39
|
+
private readonly minWindowRounds;
|
|
40
|
+
/** 当前日期 YYYY-MM-DD */
|
|
41
|
+
private currentDate;
|
|
42
|
+
/** 当前会话标识(不含日期前缀) */
|
|
43
|
+
private currentSession;
|
|
44
|
+
/**
|
|
45
|
+
* 挂起的归档企划集合,Agent.close() 等待它们完成
|
|
46
|
+
* 容纳 Promise<void>(fire-and-forget 内部)
|
|
47
|
+
*/
|
|
48
|
+
private pendingArchives;
|
|
49
|
+
constructor(
|
|
50
|
+
/**
|
|
51
|
+
* 会话存储(可选)
|
|
52
|
+
* 注入后,消息会持久化到宿主提供的存储实现。
|
|
53
|
+
* 不注入则仅在内存中保存(AgentLoop.messages[])。
|
|
54
|
+
*/
|
|
55
|
+
sessionStore?: ISessionStore | undefined,
|
|
56
|
+
/**
|
|
57
|
+
* 临时记忆最小窗口轮次(记忆减法方案 v1.0 · 排雷修正 L2)
|
|
58
|
+
*
|
|
59
|
+
* 上下文压缩时,最少保留的对话轮次。即使上下文利用率 ≥ 85%,
|
|
60
|
+
* 也不压缩到少于此轮次,保证基本上下文连贯性。
|
|
61
|
+
* 默认 3 轮,不可在运行时突破。
|
|
62
|
+
*/
|
|
63
|
+
minWindowRounds?: number, initialDate?: string, initialSession?: string);
|
|
64
|
+
/**
|
|
65
|
+
* 获取当前会话名(日期-会话组合名)
|
|
66
|
+
*/
|
|
67
|
+
get currentSessionName(): string;
|
|
68
|
+
/** 获取当前日期 YYYY-MM-DD(只读,供 agent 层使用) */
|
|
69
|
+
get currentDateValue(): string;
|
|
70
|
+
/** 获取当前会话标识(只读,供 agent 层使用) */
|
|
71
|
+
get currentSessionValue(): string;
|
|
72
|
+
/**
|
|
73
|
+
* 获取当前会话标识
|
|
74
|
+
*/
|
|
75
|
+
get session(): string;
|
|
76
|
+
/**
|
|
77
|
+
* 获取最小窗口轮次(记忆减法方案 v1.0)
|
|
78
|
+
* 上下文压缩时的下限保护
|
|
79
|
+
*/
|
|
80
|
+
get minWindowRoundsValue(): number;
|
|
81
|
+
/**
|
|
82
|
+
* 切换会话
|
|
83
|
+
* @param newSession - 新会话标识
|
|
84
|
+
* @returns 新会话的全名
|
|
85
|
+
*/
|
|
86
|
+
switchSession(newSession: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* 自动生成分支名
|
|
89
|
+
*
|
|
90
|
+
* 算法:扫描已存在会话,找到以 sourceSession-b 为前缀的最大序号,+1
|
|
91
|
+
*
|
|
92
|
+
* @param sourceSession - 源会话标识
|
|
93
|
+
* @returns 自动生成的分支名(如 "main-b1")
|
|
94
|
+
*/
|
|
95
|
+
private autoBranchName;
|
|
96
|
+
/**
|
|
97
|
+
* 分叉当前会话
|
|
98
|
+
*
|
|
99
|
+
* 流程:
|
|
100
|
+
* 1. 从 sessionStore 加载当前会话全部消息
|
|
101
|
+
* 2. 生成唯一新会话名
|
|
102
|
+
* 3. 通过 sessionStore.copySession() 复制到新会话
|
|
103
|
+
* 4. switchSession() 切换当前会话标识到新会话
|
|
104
|
+
*
|
|
105
|
+
* @param targetSession - 自定义目标会话名(可选,不传则自动生成)
|
|
106
|
+
* @returns 分叉结果
|
|
107
|
+
* @throws 若 sessionStore 未注入、copySession 未实现或当前会话无消息
|
|
108
|
+
*/
|
|
109
|
+
forkSession(targetSession?: string): ForkResult;
|
|
110
|
+
/**
|
|
111
|
+
* 追加 user 消息到当前会话
|
|
112
|
+
* 失败不抛出(消息持久化失败不应阻塞对话)
|
|
113
|
+
*
|
|
114
|
+
* 日期使用 todayDate() 动态获取,而非缓存的 this.currentDate,
|
|
115
|
+
* 确保跨日后消息写入当天目录。
|
|
116
|
+
*/
|
|
117
|
+
appendUser(content: string): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* 追加 assistant 消息到当前会话
|
|
120
|
+
* 失败不抛出
|
|
121
|
+
*
|
|
122
|
+
* 日期使用 todayDate() 动态获取,确保跨日后消息写入当天目录。
|
|
123
|
+
*/
|
|
124
|
+
appendAssistant(content: string): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* 列出所有会话标识
|
|
127
|
+
*
|
|
128
|
+
* @returns 会话标识列表(格式:YYYY-MM-DD-session),未注入 ISessionStore 则返回空
|
|
129
|
+
*/
|
|
130
|
+
listAllSessions(): Promise<string[]>;
|
|
131
|
+
/**
|
|
132
|
+
* 从会话存储恢复历史消息
|
|
133
|
+
* 用于重启后恢复之前的对话
|
|
134
|
+
*
|
|
135
|
+
* @param date - 会话日期 YYYY-MM-DD
|
|
136
|
+
* @param session - 会话标识
|
|
137
|
+
* @returns 会话中的消息列表,未注入 ISessionStore 则返回空数组
|
|
138
|
+
*/
|
|
139
|
+
loadSessionMessages(date: string, session: string): Promise<SessionMessage[]>;
|
|
140
|
+
/**
|
|
141
|
+
* 把外部 fire-and-forget 归档注册到 pendingArchives
|
|
142
|
+
* 供 Agent.chat() 触发 signal 归档时使用
|
|
143
|
+
*/
|
|
144
|
+
registerPendingArchive(p: Promise<unknown>): void;
|
|
145
|
+
/**
|
|
146
|
+
* 等待所有挂起的归档完成(Agent.close() 时调用)
|
|
147
|
+
* 防止 fire-and-forget 还在写 SQLite 时 db 已被 close
|
|
148
|
+
*
|
|
149
|
+
* 重要:会捕获**等待期间新加入**的归档(解决 init() → archiveMissingSessions() 的 race)
|
|
150
|
+
* 实现:用 50ms 间隔轮询检查新加入的 promise,直到所有归档完成或超时
|
|
151
|
+
*
|
|
152
|
+
* @param timeoutMs 单次等待超时(默认 5000ms)
|
|
153
|
+
* @returns 是否所有归档都完成(false 表示有超时)
|
|
154
|
+
*/
|
|
155
|
+
awaitPendingArchives(timeoutMs?: number): Promise<boolean>;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=messageHistory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messageHistory.d.ts","sourceRoot":"","sources":["../../src/agent/messageHistory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAK9E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,qBAAa,cAAc;IAavB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC9B;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe;IAzBlC,sBAAsB;IACtB,OAAO,CAAC,WAAW,CAAS;IAC5B,qBAAqB;IACrB,OAAO,CAAC,cAAc,CAAS;IAE/B;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAoC;;IAGzD;;;;OAIG;IACc,YAAY,CAAC,EAAE,aAAa,YAAA;IAC7C;;;;;;OAMG;IACc,eAAe,SAAI,EACpC,WAAW,CAAC,EAAE,MAAM,EACpB,cAAc,SAAS;IAMzB;;OAEG;IACH,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED,wCAAwC;IACxC,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,+BAA+B;IAC/B,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;;OAGG;IACH,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAED;;;;OAIG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAKzC;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IA0BtB;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,UAAU;IAuD/C;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBhD;;;;;OAKG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBrD;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQ1C;;;;;;;OAOG;IACG,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAenF;;;OAGG;IACH,sBAAsB,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAOjD;;;;;;;;;OASG;IACG,oBAAoB,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CA4B/D"}
|