@zooique/memora 1.0.1 → 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 +257 -115
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +747 -400
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/assembler.d.ts +32 -16
- package/dist/agent/assembler.d.ts.map +1 -1
- package/dist/agent/assembler.js +83 -47
- package/dist/agent/assembler.js.map +1 -1
- package/dist/agent/builtinToolHandlers.d.ts +27 -2
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
- package/dist/agent/builtinToolHandlers.js +78 -5
- 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 +137 -15
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +449 -270
- 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/chatLockManager.d.ts +116 -0
- package/dist/agent/managers/chatLockManager.d.ts.map +1 -0
- package/dist/agent/managers/chatLockManager.js +191 -0
- package/dist/agent/managers/chatLockManager.js.map +1 -0
- 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 +31 -3
- package/dist/agent/managers/insightExtractor.d.ts.map +1 -1
- package/dist/agent/managers/insightExtractor.js +130 -59
- 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 +102 -2
- package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -1
- package/dist/agent/managers/memoryAdvisor.js +254 -10
- package/dist/agent/managers/memoryAdvisor.js.map +1 -1
- package/dist/agent/managers/memoryDecayScheduler.d.ts +127 -1
- package/dist/agent/managers/memoryDecayScheduler.d.ts.map +1 -1
- package/dist/agent/managers/memoryDecayScheduler.js +283 -4
- 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 +113 -30
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
- package/dist/agent/managers/memoryInspector.js +165 -32
- package/dist/agent/managers/memoryInspector.js.map +1 -1
- package/dist/agent/managers/relationBuilder.d.ts +4 -4
- package/dist/agent/managers/relationBuilder.d.ts.map +1 -1
- package/dist/agent/managers/relationBuilder.js +5 -4
- package/dist/agent/managers/relationBuilder.js.map +1 -1
- package/dist/agent/managers/sessionArchiver.d.ts +12 -1
- package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
- package/dist/agent/managers/sessionArchiver.js +87 -30
- package/dist/agent/managers/sessionArchiver.js.map +1 -1
- package/dist/agent/managers/sessionManager.d.ts.map +1 -1
- package/dist/agent/managers/sessionManager.js +9 -17
- package/dist/agent/managers/sessionManager.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 +62 -0
- package/dist/agent/managers/textPolishManager.d.ts.map +1 -0
- package/dist/agent/managers/textPolishManager.js +96 -0
- package/dist/agent/managers/textPolishManager.js.map +1 -0
- 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/personaMatcher.d.ts +29 -0
- package/dist/agent/personaMatcher.d.ts.map +1 -0
- package/dist/agent/personaMatcher.js +60 -0
- package/dist/agent/personaMatcher.js.map +1 -0
- package/dist/agent/toolExecutor.d.ts +24 -4
- package/dist/agent/toolExecutor.d.ts.map +1 -1
- package/dist/agent/toolExecutor.js +30 -4
- package/dist/agent/toolExecutor.js.map +1 -1
- package/dist/agent/tracer.d.ts +31 -0
- package/dist/agent/tracer.d.ts.map +1 -1
- package/dist/agent/tracer.js +31 -0
- package/dist/agent/tracer.js.map +1 -1
- package/dist/agent/types.d.ts +133 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +38 -0
- package/dist/agent/types.js.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 +296 -118
- package/dist/config/loader.js.map +1 -1
- package/dist/eval/evalRunner.d.ts +94 -0
- package/dist/eval/evalRunner.d.ts.map +1 -0
- package/dist/eval/evalRunner.js +141 -0
- package/dist/eval/evalRunner.js.map +1 -0
- package/dist/eval/evalTypes.d.ts +21 -0
- package/dist/eval/evalTypes.d.ts.map +1 -1
- package/dist/eval/evalTypes.js +15 -0
- package/dist/eval/evalTypes.js.map +1 -1
- package/dist/eval/scenarios.d.ts +33 -0
- package/dist/eval/scenarios.d.ts.map +1 -0
- package/dist/eval/scenarios.js +109 -0
- package/dist/eval/scenarios.js.map +1 -0
- package/dist/index.d.ts +45 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -5
- package/dist/index.js.map +1 -1
- package/dist/llm/abortSignal.d.ts +27 -0
- package/dist/llm/abortSignal.d.ts.map +1 -0
- package/dist/llm/abortSignal.js +44 -0
- package/dist/llm/abortSignal.js.map +1 -0
- package/dist/llm/embedding.d.ts +13 -12
- package/dist/llm/embedding.d.ts.map +1 -1
- package/dist/llm/embedding.js +5 -17
- 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 +17 -34
- 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 +70 -19
- 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 +35 -17
- package/dist/memory/lockManager.js.map +1 -1
- package/dist/memory/projectManager.d.ts +8 -7
- package/dist/memory/projectManager.d.ts.map +1 -1
- package/dist/memory/projectManager.js +33 -15
- 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 +100 -31
- 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 +35 -20
- 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 +17 -0
- package/dist/memory/sourceValidation.d.ts.map +1 -1
- package/dist/memory/sourceValidation.js +27 -3
- 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 -8
- 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 +38 -63
- package/dist/persona/personaManager.d.ts.map +1 -1
- package/dist/persona/personaManager.js +136 -202
- 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 -141
- 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/array.d.ts +24 -0
- package/dist/utils/array.d.ts.map +1 -0
- package/dist/utils/array.js +24 -0
- package/dist/utils/array.js.map +1 -0
- 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 +27 -8
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +31 -9
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/eventEmitter.d.ts +88 -4
- 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/objects.d.ts +17 -0
- package/dist/utils/objects.d.ts.map +1 -0
- package/dist/utils/objects.js +19 -0
- package/dist/utils/objects.js.map +1 -0
- package/dist/utils/segmenter.d.ts +11 -10
- package/dist/utils/segmenter.d.ts.map +1 -1
- package/dist/utils/segmenter.js +23 -1
- package/dist/utils/segmenter.js.map +1 -1
- package/dist/utils/strings.d.ts +22 -1
- package/dist/utils/strings.d.ts.map +1 -1
- package/dist/utils/strings.js +29 -1
- package/dist/utils/strings.js.map +1 -1
- package/dist/utils/time.d.ts +18 -3
- package/dist/utils/time.d.ts.map +1 -1
- package/dist/utils/time.js +24 -8
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/toError.d.ts +8 -4
- package/dist/utils/toError.d.ts.map +1 -1
- package/dist/utils/toError.js +25 -5
- package/dist/utils/toError.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 +49 -22
- package/dist/agent/managers/memoryMutator.d.ts +0 -92
- package/dist/agent/managers/memoryMutator.d.ts.map +0 -1
- package/dist/agent/managers/memoryMutator.js +0 -94
- package/dist/agent/managers/memoryMutator.js.map +0 -1
|
@@ -2,26 +2,35 @@
|
|
|
2
2
|
* 归档协调器(从 agent.ts 拆分)
|
|
3
3
|
*
|
|
4
4
|
* 职责:
|
|
5
|
-
* 1.
|
|
6
|
-
* 2.
|
|
7
|
-
* 3.
|
|
8
|
-
* 4. 归档完成事件发射(memoryAdded / insightExtracted)
|
|
5
|
+
* 1. 归档用户画像事实(archiveProfileFacts)
|
|
6
|
+
* 2. 归档洞察记忆(archiveInsight)
|
|
7
|
+
* 3. 归档会话内容(archiveSessionContent)
|
|
8
|
+
* 4. 归档完成事件发射(memoryAdded / insightExtracted / archiveFailed)
|
|
9
|
+
* 5. archiveMode 三态控制集中判断(FIX-P1-4)
|
|
9
10
|
*
|
|
10
11
|
* 设计理由:
|
|
11
12
|
* agent.ts 原承担 15+ 职责,归档操作是独立的领域职责,
|
|
12
|
-
* 拆分后 Agent 聚焦对话编排,ArchiveCoordinator
|
|
13
|
+
* 拆分后 Agent 聚焦对话编排,ArchiveCoordinator 聚焦归档操作 + 模式判断。
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* FIX-P1-4(2026-07-24):archiveMode 三态控制集中到本类
|
|
16
|
+
* 原实现三态判断散落在 3 处:
|
|
17
|
+
* - Agent.postProcessInner 判断 'manual' 跳过 profile/insight 自动归档
|
|
18
|
+
* - 宿主 sessionHandlers.ts 判断 'full' 触发 content 自动归档
|
|
19
|
+
* - ArchiveCoordinator 名为"协调器"实为"执行器",不感知模式
|
|
20
|
+
* 修复后:
|
|
21
|
+
* - ArchiveCoordinator 构造时注入 getArchiveMode getter
|
|
22
|
+
* - 3 个归档方法新增 autoTriggered 参数区分自动/手动触发
|
|
23
|
+
* - 自动触发时由本类内部按模式判断是否跳过(统一协调点)
|
|
24
|
+
* - setArchiveMode/getArchiveMode 仍保留在 Agent(涉及 _chatBusy 和 #config)
|
|
17
25
|
*
|
|
18
26
|
* 自然生长原则:
|
|
19
|
-
* - 使用 getter 回调注入依赖(getUserProfile / getInsightExtractor / getSessionArchiver)
|
|
27
|
+
* - 使用 getter 回调注入依赖(getUserProfile / getInsightExtractor / getSessionArchiver / getArchiveMode)
|
|
20
28
|
* 避免 close 时额外清理,Agent null 化字段后 getter 自然返回 null
|
|
21
29
|
* - 通过回调发射事件(不继承 TypedEventEmitter)
|
|
22
30
|
* - 不做 assertInitialized 检查(由 Agent 在调用前保证)
|
|
23
31
|
*/
|
|
24
32
|
import { extractUserFacts } from '../../agent/userFactExtractor.js';
|
|
33
|
+
import { logger } from '../../logging/logger.js';
|
|
25
34
|
/**
|
|
26
35
|
* 归档协调器
|
|
27
36
|
*
|
|
@@ -30,98 +39,284 @@ import { extractUserFacts } from '../../agent/userFactExtractor.js';
|
|
|
30
39
|
* getUserProfile: () => this.#userProfile,
|
|
31
40
|
* getInsightExtractor: () => this.insightExtractor,
|
|
32
41
|
* getSessionArchiver: () => this.sessionArchiver,
|
|
42
|
+
* getArchiveMode: () => this.#config.archiveMode,
|
|
33
43
|
* emit: this.emit.bind(this),
|
|
34
44
|
* });
|
|
45
|
+
* // 手动触发(用户主动)
|
|
35
46
|
* await coordinator.archiveProfileFacts(input);
|
|
36
|
-
*
|
|
37
|
-
* await coordinator.
|
|
47
|
+
* // 自动触发(postProcess / 会话切换)
|
|
48
|
+
* await coordinator.archiveProfileFacts(input, { autoTriggered: true });
|
|
38
49
|
*/
|
|
39
50
|
export class ArchiveCoordinator {
|
|
51
|
+
/** pending 队列上限——超过则丢弃最旧项,避免 LLM 长时间不可用时无限增长 */
|
|
52
|
+
static MAX_PENDING = 50;
|
|
40
53
|
/** 获取 UserProfile 的回调 */
|
|
41
54
|
getUserProfile;
|
|
42
55
|
/** 获取 InsightExtractor 的回调 */
|
|
43
56
|
getInsightExtractor;
|
|
44
57
|
/** 获取 SessionArchiver 的回调 */
|
|
45
58
|
getSessionArchiver;
|
|
59
|
+
/** 获取当前 archiveMode 的回调(FIX-P1-4) */
|
|
60
|
+
getArchiveMode;
|
|
46
61
|
/** 事件发射回调 */
|
|
47
62
|
emit;
|
|
63
|
+
/**
|
|
64
|
+
* 待重试归档队列(MIND2-C3)
|
|
65
|
+
*
|
|
66
|
+
* 归档失败时入队,下次同阶段归档调用时先重试。
|
|
67
|
+
* 仅 profile/insight 阶段入队(content 从 session store 读取,可手动重试)。
|
|
68
|
+
*/
|
|
69
|
+
pendingArchives = [];
|
|
48
70
|
constructor(opts) {
|
|
49
71
|
this.getUserProfile = opts.getUserProfile;
|
|
50
72
|
this.getInsightExtractor = opts.getInsightExtractor;
|
|
51
73
|
this.getSessionArchiver = opts.getSessionArchiver;
|
|
74
|
+
this.getArchiveMode = opts.getArchiveMode;
|
|
52
75
|
this.emit = opts.emit;
|
|
53
76
|
}
|
|
54
77
|
/**
|
|
55
|
-
*
|
|
78
|
+
* 归档用户画像事实
|
|
56
79
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
80
|
+
* 模式判断(FIX-P1-4,集中到本类):
|
|
81
|
+
* - 自动触发 + manual 模式 → 跳过(返回空),用户需手动调用
|
|
82
|
+
* - 自动触发 + full/insights-only 模式 → 执行
|
|
83
|
+
* - 手动触发(任何模式) → 执行(用户意图优先)
|
|
59
84
|
*
|
|
60
85
|
* @param input 本轮用户输入
|
|
86
|
+
* @param options 触发选项(autoTriggered 默认 false)
|
|
61
87
|
* @returns 写入/更新的 UserProfileEntry 列表
|
|
62
88
|
*/
|
|
63
|
-
async archiveProfileFacts(input) {
|
|
89
|
+
async archiveProfileFacts(input, options) {
|
|
90
|
+
// FIX-P1-4:自动触发 + manual 模式 → 跳过(原 Agent.postProcessInner 的 skipAutoArchive 逻辑)
|
|
91
|
+
if (options?.autoTriggered && this.getArchiveMode() === 'manual') {
|
|
92
|
+
logger.debug({ mode: 'manual', stage: 'profile' }, 'manual 模式跳过自动 profile 归档');
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
64
95
|
const userProfile = this.getUserProfile();
|
|
65
96
|
if (!userProfile)
|
|
66
97
|
return [];
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
98
|
+
// MIND2-C3:先重试 pending 队列中同阶段的失败归档(LLM 恢复后自动补录)
|
|
99
|
+
await this.retryPendingArchives('profile');
|
|
100
|
+
try {
|
|
101
|
+
const turnIndex = `turn-${Date.now()}`;
|
|
102
|
+
const facts = extractUserFacts(input, turnIndex);
|
|
103
|
+
const entries = await userProfile.archiveFacts(facts);
|
|
104
|
+
// 发射 memoryAdded 事件:与自动归档路径一致,保持宿主 UI 行为统一
|
|
105
|
+
for (const entry of entries) {
|
|
106
|
+
if (entry.confirmed) {
|
|
107
|
+
this.emit('memoryAdded', { id: entry.id, source: 'profile', name: entry.value });
|
|
108
|
+
}
|
|
74
109
|
}
|
|
110
|
+
return entries;
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
this.handleArchiveError('profile', err);
|
|
114
|
+
// MIND2-C3:失败入队,下次同阶段归档时自动重试(不再永久丢失)
|
|
115
|
+
this.enqueuePending('profile', input);
|
|
116
|
+
return [];
|
|
75
117
|
}
|
|
76
|
-
return entries;
|
|
77
118
|
}
|
|
78
119
|
/**
|
|
79
|
-
*
|
|
120
|
+
* 提取并归档洞察记忆
|
|
121
|
+
*
|
|
122
|
+
* 模式判断(FIX-P1-4,集中到本类):
|
|
123
|
+
* - 自动触发 + manual 模式 → 跳过(返回空),用户需手动调用
|
|
124
|
+
* - 自动触发 + full/insights-only 模式 → 执行
|
|
125
|
+
* - 手动触发(任何模式) → 执行(用户意图优先)
|
|
80
126
|
*
|
|
81
|
-
* manual 模式下 postProcess 跳过自动归档,用户需通过此 API 主动归档。
|
|
82
127
|
* 内部仍走 classify 判断(避免无价值输入浪费 LLM 调用)。
|
|
83
128
|
*
|
|
84
129
|
* @param input 本轮用户输入
|
|
85
130
|
* @param assistantContent 本轮助手回复内容
|
|
131
|
+
* @param options 触发选项(autoTriggered 默认 false)
|
|
86
132
|
* @returns 写入/更新的 Memory 列表
|
|
87
133
|
*/
|
|
88
|
-
async archiveInsight(input, assistantContent) {
|
|
134
|
+
async archiveInsight(input, assistantContent, options) {
|
|
135
|
+
// FIX-P1-4:自动触发 + manual 模式 → 跳过(原 Agent.postProcessInner 的 skipAutoArchive 逻辑)
|
|
136
|
+
if (options?.autoTriggered && this.getArchiveMode() === 'manual') {
|
|
137
|
+
logger.debug({ mode: 'manual', stage: 'insight' }, 'manual 模式跳过自动 insight 归档');
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
89
140
|
const insightExtractor = this.getInsightExtractor();
|
|
90
141
|
if (!insightExtractor)
|
|
91
142
|
return [];
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
143
|
+
// MIND2-C3:先重试 pending 队列中同阶段的失败归档(LLM 恢复后自动补录)
|
|
144
|
+
await this.retryPendingArchives('insight');
|
|
145
|
+
try {
|
|
146
|
+
// 内部仍走 classify 判断,避免无价值输入浪费 LLM 调用
|
|
147
|
+
const shouldExtract = insightExtractor.classify(input);
|
|
148
|
+
if (shouldExtract !== 'extract')
|
|
149
|
+
return [];
|
|
150
|
+
const memories = await insightExtractor.extract(input, assistantContent);
|
|
151
|
+
// 发射 memoryAdded + insightExtracted 事件:与自动归档路径一致
|
|
152
|
+
for (const memory of memories) {
|
|
153
|
+
this.emit('memoryAdded', { id: memory.id, source: memory.source, name: memory.name });
|
|
154
|
+
this.emit('insightExtracted', { source: memory.source, insight: memory.content });
|
|
155
|
+
}
|
|
156
|
+
return memories;
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
this.handleArchiveError('insight', err);
|
|
160
|
+
// MIND2-C3:失败入队(含 assistantContent),下次同阶段归档时自动重试
|
|
161
|
+
this.enqueuePending('insight', input, assistantContent);
|
|
95
162
|
return [];
|
|
96
|
-
const memories = await insightExtractor.extract(input, assistantContent);
|
|
97
|
-
// 发射 memoryAdded + insightExtracted 事件:与自动归档路径一致
|
|
98
|
-
for (const memory of memories) {
|
|
99
|
-
this.emit('memoryAdded', { id: memory.id, source: memory.source, name: memory.name });
|
|
100
|
-
this.emit('insightExtracted', { source: memory.source, insight: memory.content });
|
|
101
163
|
}
|
|
102
|
-
return memories;
|
|
103
164
|
}
|
|
104
165
|
/**
|
|
105
|
-
*
|
|
166
|
+
* 归档会话内容(content 类记忆)
|
|
167
|
+
*
|
|
168
|
+
* 模式判断(FIX-P1-4,集中到本类):
|
|
169
|
+
* - 自动触发 + full 模式 → 执行(会话切换前自动归档)
|
|
170
|
+
* - 自动触发 + insights-only/manual 模式 → 跳过,用户需手动调用
|
|
171
|
+
* - 手动触发(任何模式) → 执行(用户意图优先,如"一键归档"按钮)
|
|
106
172
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
173
|
+
* 错误传播契约:
|
|
174
|
+
* - SessionArchiver LLM 异常 / 写入失败向上抛出(不内部吞掉)。
|
|
175
|
+
* - 本方法 catch 异常并发射 archiveFailed({ stage: 'content' }) 事件,
|
|
176
|
+
* 让宿主 UI 可感知会话内容归档失败。
|
|
177
|
+
* - archiveProfileFacts / archiveInsight 同样 catch 并发射 archiveFailed
|
|
178
|
+
* 事件(stage 分别为 'profile' / 'insight'),三阶段统一闭环。
|
|
179
|
+
* - 失败时返回空降级结果,保证调用方(如 SESSION_SWITCH 自动归档)不中断主流程。
|
|
109
180
|
*
|
|
110
181
|
* @param date 会话日期 YYYY-MM-DD
|
|
111
182
|
* @param session 会话标识(不含日期前缀)
|
|
183
|
+
* @param options 触发选项(autoTriggered 默认 false)
|
|
112
184
|
* @returns 归档结果(memories 可能为空,表示无归档价值或 LLM 失败)
|
|
113
185
|
*/
|
|
114
|
-
async archiveSessionContent(date, session) {
|
|
186
|
+
async archiveSessionContent(date, session, options) {
|
|
187
|
+
// FIX-P1-4:自动触发 + 非 full 模式 → 跳过(原 sessionHandlers.ts 的外部判断逻辑)
|
|
188
|
+
if (options?.autoTriggered && this.getArchiveMode() !== 'full') {
|
|
189
|
+
logger.debug({ mode: this.getArchiveMode(), stage: 'content' }, '非 full 模式跳过自动 content 归档');
|
|
190
|
+
return { memories: [], sessionLabel: `${date}-${session}`, messageCount: 0 };
|
|
191
|
+
}
|
|
115
192
|
const sessionArchiver = this.getSessionArchiver();
|
|
116
193
|
if (!sessionArchiver) {
|
|
117
194
|
return { memories: [], sessionLabel: `${date}-${session}`, messageCount: 0 };
|
|
118
195
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
196
|
+
try {
|
|
197
|
+
const result = await sessionArchiver.archiveSessionContent(date, session);
|
|
198
|
+
// 发射 memoryAdded 事件:与 insight 自动归档路径一致,宿主可据此刷新记忆面板
|
|
199
|
+
for (const memory of result.memories) {
|
|
200
|
+
this.emit('memoryAdded', { id: memory.id, source: memory.source, name: memory.name });
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
this.handleArchiveError('content', err);
|
|
206
|
+
return { memories: [], sessionLabel: `${date}-${session}`, messageCount: 0 };
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 统一处理归档异常:记录日志 + 发射 archiveFailed 事件
|
|
211
|
+
*
|
|
212
|
+
* 三段归档方法(profile/insight/content)的 catch 模板完全相同,
|
|
213
|
+
* 提取为私有方法消除重复(ADR-017 枝叶层 2 次提取原则,3 次阈值已满足)。
|
|
214
|
+
*
|
|
215
|
+
* @param stage 归档阶段标识(用于日志结构化字段 + archiveFailed 事件 payload)
|
|
216
|
+
* @param err 捕获的异常
|
|
217
|
+
*/
|
|
218
|
+
handleArchiveError(stage, err) {
|
|
219
|
+
// 记录根因到日志(UI 通知走 archiveFailed 事件,日志走 logger.error,两者不替代)
|
|
220
|
+
// 首字母大写拼接方法名(profile → Profile)保持日志可读性
|
|
221
|
+
const label = stage.charAt(0).toUpperCase() + stage.slice(1);
|
|
222
|
+
logger.error({ err, stage }, `archive${label} 异常`);
|
|
223
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
224
|
+
this.emit('archiveFailed', { stage, message: message.slice(0, 200) });
|
|
225
|
+
}
|
|
226
|
+
// ─── MIND2-C3:pending 队列管理 ──────────────────────────
|
|
227
|
+
/**
|
|
228
|
+
* 将失败的归档输入入队(MIND2-C3)
|
|
229
|
+
*
|
|
230
|
+
* 仅 profile/insight 阶段入队——content 从 session store 读取可手动重试。
|
|
231
|
+
* 队列满时丢弃最旧项(FIFO 淘汰),避免 LLM 长时间不可用时无限增长。
|
|
232
|
+
*
|
|
233
|
+
* @param stage 归档阶段(profile / insight)
|
|
234
|
+
* @param input 本轮用户输入
|
|
235
|
+
* @param assistantContent 助手回复(仅 insight 阶段)
|
|
236
|
+
*/
|
|
237
|
+
enqueuePending(stage, input, assistantContent) {
|
|
238
|
+
if (this.pendingArchives.length >= ArchiveCoordinator.MAX_PENDING) {
|
|
239
|
+
// 队列满,丢弃最旧项(shift 弹出队首)
|
|
240
|
+
const dropped = this.pendingArchives.shift();
|
|
241
|
+
logger.warn({ droppedStage: dropped?.stage, queueSize: this.pendingArchives.length }, 'pending 归档队列已满,丢弃最旧项');
|
|
242
|
+
}
|
|
243
|
+
this.pendingArchives.push({
|
|
244
|
+
stage,
|
|
245
|
+
input,
|
|
246
|
+
assistantContent,
|
|
247
|
+
enqueuedAt: Date.now(),
|
|
248
|
+
});
|
|
249
|
+
logger.info({ stage, queueSize: this.pendingArchives.length }, '归档失败已入 pending 队列,下次同阶段归档时自动重试');
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 重试 pending 队列中指定阶段的所有失败归档(MIND2-C3)
|
|
253
|
+
*
|
|
254
|
+
* 在 archiveProfileFacts / archiveInsight 入口调用,先清空同阶段 pending 项:
|
|
255
|
+
* - 成功 → 从队列移除(补录完成)
|
|
256
|
+
* - 失败 → 保留在队列(等下次再试,不无限重试——每次调用只重试一轮)
|
|
257
|
+
*
|
|
258
|
+
* 重试失败不发射 archiveFailed 事件(避免重复 toast 节流),仅 debug 日志。
|
|
259
|
+
* 重试成功正常发射 memoryAdded / insightExtracted 事件(与首次成功一致)。
|
|
260
|
+
*
|
|
261
|
+
* @param stage 要重试的阶段(profile / insight)
|
|
262
|
+
*/
|
|
263
|
+
async retryPendingArchives(stage) {
|
|
264
|
+
// 筛选同阶段的 pending 项(保留其他阶段的不动)
|
|
265
|
+
const pending = this.pendingArchives.filter((p) => p.stage === stage);
|
|
266
|
+
if (pending.length === 0)
|
|
267
|
+
return;
|
|
268
|
+
logger.debug({ stage, count: pending.length }, '开始重试 pending 归档');
|
|
269
|
+
for (const item of pending) {
|
|
270
|
+
try {
|
|
271
|
+
if (stage === 'profile') {
|
|
272
|
+
const userProfile = this.getUserProfile();
|
|
273
|
+
if (!userProfile)
|
|
274
|
+
continue; // UserProfile 仍不可用,保留在队列
|
|
275
|
+
const turnIndex = `turn-${item.enqueuedAt}`;
|
|
276
|
+
const facts = extractUserFacts(item.input, turnIndex);
|
|
277
|
+
const entries = await userProfile.archiveFacts(facts);
|
|
278
|
+
for (const entry of entries) {
|
|
279
|
+
if (entry.confirmed) {
|
|
280
|
+
this.emit('memoryAdded', { id: entry.id, source: 'profile', name: entry.value });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
// stage === 'insight'
|
|
286
|
+
const insightExtractor = this.getInsightExtractor();
|
|
287
|
+
if (!insightExtractor)
|
|
288
|
+
continue;
|
|
289
|
+
const shouldExtract = insightExtractor.classify(item.input);
|
|
290
|
+
if (shouldExtract !== 'extract')
|
|
291
|
+
continue;
|
|
292
|
+
const memories = await insightExtractor.extract(item.input, item.assistantContent ?? '');
|
|
293
|
+
for (const memory of memories) {
|
|
294
|
+
this.emit('memoryAdded', { id: memory.id, source: memory.source, name: memory.name });
|
|
295
|
+
this.emit('insightExtracted', { source: memory.source, insight: memory.content });
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// 重试成功 → 从队列移除
|
|
299
|
+
const idx = this.pendingArchives.indexOf(item);
|
|
300
|
+
if (idx !== -1)
|
|
301
|
+
this.pendingArchives.splice(idx, 1);
|
|
302
|
+
logger.info({ stage }, 'pending 归档重试成功,已从队列移除');
|
|
303
|
+
}
|
|
304
|
+
catch (err) {
|
|
305
|
+
// 重试失败 → 保留在队列,下次再试(仅 debug 日志,不重复发射 archiveFailed)
|
|
306
|
+
logger.debug({ err, stage }, 'pending 归档重试仍失败,保留在队列');
|
|
307
|
+
}
|
|
123
308
|
}
|
|
124
|
-
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* 获取 pending 归档队列长度(MIND2-C3)
|
|
312
|
+
*
|
|
313
|
+
* 供宿主 UI 查询是否有待补归档,展示"N 条待补"提示。
|
|
314
|
+
* Agent 不直接消费此值——通过 IPC 暴露给渲染层。
|
|
315
|
+
*
|
|
316
|
+
* @returns pending 队列中的待重试归档数
|
|
317
|
+
*/
|
|
318
|
+
getPendingArchiveCount() {
|
|
319
|
+
return this.pendingArchives.length;
|
|
125
320
|
}
|
|
126
321
|
}
|
|
127
322
|
//# sourceMappingURL=archiveCoordinator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiveCoordinator.js","sourceRoot":"","sources":["../../../src/agent/managers/archiveCoordinator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"archiveCoordinator.js","sourceRoot":"","sources":["../../../src/agent/managers/archiveCoordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoConfigRefiner.d.ts","sourceRoot":"","sources":["../../../src/agent/managers/autoConfigRefiner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"autoConfigRefiner.d.ts","sourceRoot":"","sources":["../../../src/agent/managers/autoConfigRefiner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAK1E,2BAA2B;AAC3B,MAAM,WAAW,wBAAwB;IACvC,8BAA8B;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiBD,qBAAa,iBAAiB;IAK1B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAJrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,kBAAkB,CAA4B;gBAGnC,kBAAkB,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,EAC3E,OAAO,CAAC,EAAE,wBAAwB;IAKpC,sDAAsD;IACtD,qBAAqB,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI;IAIzD;;;;OAIG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6CzE,oBAAoB;YACN,cAAc;IAgD5B,4BAA4B;IAC5B,OAAO,CAAC,qBAAqB;CAiD9B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { logger } from '../../logging/logger.js';
|
|
2
2
|
import { parseLlmJson } from '../../utils/json.js';
|
|
3
|
+
import { accumulateStream } from '../../agent/managers/streamAccumulator.js';
|
|
3
4
|
const DEFAULT_OPTIONS = {
|
|
4
5
|
minConfidence: 0.6,
|
|
5
6
|
maxSuggestions: 3,
|
|
@@ -82,15 +83,10 @@ export class AutoConfigRefiner {
|
|
|
82
83
|
},
|
|
83
84
|
];
|
|
84
85
|
try {
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
for await (const chunk of this.backgroundProvider.chat(messages, {
|
|
86
|
+
// 收集流式输出(复用 accumulateStream 工具函数)
|
|
87
|
+
const fullContent = await accumulateStream(this.backgroundProvider, messages, {
|
|
88
88
|
temperature: 0.3,
|
|
89
|
-
})
|
|
90
|
-
if (chunk.content) {
|
|
91
|
-
fullContent += chunk.content;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
89
|
+
});
|
|
94
90
|
const parsed = parseLlmJson(fullContent || '[]');
|
|
95
91
|
const items = Array.isArray(parsed) ? parsed : parsed?.suggestions ?? [];
|
|
96
92
|
return items.filter((s) => s.type && s.name && s.content && typeof s.confidence === 'number');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoConfigRefiner.js","sourceRoot":"","sources":["../../../src/agent/managers/autoConfigRefiner.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"autoConfigRefiner.js","sourceRoot":"","sources":["../../../src/agent/managers/autoConfigRefiner.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAoBzE,MAAM,eAAe,GAAuC;IAC1D,aAAa,EAAE,GAAG;IAClB,cAAc,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,OAAO,iBAAiB;IAKT;IAJF,OAAO,CAAqC;IACrD,kBAAkB,GAAuB,IAAI,CAAC;IAEtD,YACmB,kBAA0D,EAC3E,OAAkC;QADjB,uBAAkB,GAAlB,kBAAkB,CAAwC;QAG3E,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAC;IACpD,CAAC;IAED,sDAAsD;IACtD,qBAAqB,CAAC,QAA4B;QAChD,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,gBAAwB;QACvD,eAAe;QACf,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,IAAI,gBAAgB,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,IAAI,WAA4B,CAAC;QAEjC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QACtD,CAAC;QAED,gBAAgB;QAChB,MAAM,QAAQ,GAAG,WAAW;aACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;aACzD,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEzC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAqB;gBACnC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,MAAM,EAAE,qBAAqB;aAC9B,CAAC;YAEF,MAAM,CAAC,IAAI,CACT,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAClF,4BAA4B,CAC7B,CAAC;YAEF,sCAAsC;YACtC,IAAI,CAAC;gBACH,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CACT,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,CAAC,IAAI,EAAE,EAC3D,sCAAsC,CACvC,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,oBAAoB;IACZ,KAAK,CAAC,cAAc,CAAC,SAAiB,EAAE,gBAAwB;QACtE,IAAI,CAAC,IAAI,CAAC,kBAAkB;YAAE,OAAO,EAAE,CAAC;QAExC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;iBAcR,CAAC;QAEd,MAAM,QAAQ,GAAc;YAC1B,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;YACzC;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,QAAQ,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,YAAY,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;aACrF;SACF,CAAC;QAEF,IAAI,CAAC;YACH,mCAAmC;YACnC,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,kBAAkB,EAAE,QAAQ,EAAE;gBAC5E,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,YAAY,CACzB,WAAW,IAAI,IAAI,CACpB,CAAC;YACF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,CAAC;YAEzE,OAAO,KAAK,CAAC,MAAM,CACjB,CAAC,CAAgB,EAAE,EAAE,CACnB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CACpE,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,gCAAgC,CAAC,CAAC;YACvD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,4BAA4B;IACpB,qBAAqB,CAAC,SAAiB;QAC7C,MAAM,WAAW,GAAoB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAEtC,wCAAwC;QACxC,MAAM,kBAAkB,GAAG;YACzB,oCAAoC;YACpC,wEAAwE;SACzE,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAChC,IAAI,CAAC,QAAQ;oBAAE,SAAS;gBACxB,WAAW,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;oBACnC,OAAO,EAAE,QAAQ,QAAQ,EAAE;oBAC3B,UAAU,EAAE,IAAI;oBAChB,MAAM,EAAE,cAAc,QAAQ,EAAE;iBACjC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,YAAY;QACZ,MAAM,cAAc,GAA2B;YAC7C,0BAA0B,EAAE,OAAO;YACnC,mBAAmB,EAAE,OAAO;YAC5B,gBAAgB,EAAE,MAAM;YACxB,gBAAgB,EAAE,OAAO;SAC1B,CAAC;QAEF,KAAK,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YAC3E,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAC/C,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,WAAW,CAAC,IAAI,CAAC;oBACf,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,QAAQ,WAAW,iBAAiB;oBAC7C,UAAU,EAAE,GAAG;oBACf,MAAM,EAAE,MAAM,WAAW,OAAO;iBACjC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatLockManager — chat() 并发锁管理器
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* - chat() 并发锁(防止多轮 chat 同时执行)
|
|
6
|
+
* - token 校验(防止 race condition:超时释放后新调用获取锁,旧 finally 误清新调用者资源)
|
|
7
|
+
* - 超时保护(LLM 卡死时中断 generator + 释放锁)
|
|
8
|
+
* - 外部 signal 合并(外部 abort 时触发内部 abort)
|
|
9
|
+
*
|
|
10
|
+
* 从 agent.ts 提取(AUDIT-1-1,ADR-017 架构层先行原则首次实践)
|
|
11
|
+
*
|
|
12
|
+
* race condition 防护设计:
|
|
13
|
+
* 原锁是简单布尔值 `_chatBusy`,无 owner 校验。超时回调与 finally 块无差别清理,
|
|
14
|
+
* 导致 race condition:T=0 A 获取锁 → T=180s 超时释放 → T=181s B 获取锁
|
|
15
|
+
* → T=182s A 的 finally 误清 B 的锁/计时器/controller。
|
|
16
|
+
*
|
|
17
|
+
* 防护方案:
|
|
18
|
+
* - 获取锁时 token 递增:`const myToken = ++this._chatLockToken`
|
|
19
|
+
* - 超时回调校验 `this._chatLockToken === myToken` 后才释放
|
|
20
|
+
* - finally 块校验 `this._chatLockToken === myToken` 后才清理
|
|
21
|
+
* - 不匹配时跳过清理,避免误清新调用者的资源
|
|
22
|
+
*
|
|
23
|
+
* 选择 number 而非 Symbol:递增计数器可序列化、零依赖、足够唯一(同一 Agent 实例内)
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* chat() 并发锁管理器
|
|
27
|
+
*
|
|
28
|
+
* 使用方式:
|
|
29
|
+
* const mgr = new ChatLockManager();
|
|
30
|
+
* const { token, internalAbort } = mgr.acquire(180_000);
|
|
31
|
+
* const cleanup = mgr.attachExternalSignal(externalSignal, internalAbort);
|
|
32
|
+
* try {
|
|
33
|
+
* // ... 使用 internalAbort.signal 传递给 generator ...
|
|
34
|
+
* } finally {
|
|
35
|
+
* mgr.release(token);
|
|
36
|
+
* cleanup();
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* 强制释放(宿主兜底):
|
|
40
|
+
* mgr.forceRelease();
|
|
41
|
+
*
|
|
42
|
+
* 销毁(Agent.close 时):
|
|
43
|
+
* mgr.dispose();
|
|
44
|
+
*/
|
|
45
|
+
export declare class ChatLockManager {
|
|
46
|
+
/** chat() 是否正在执行(并发锁) */
|
|
47
|
+
private _chatBusy;
|
|
48
|
+
/**
|
|
49
|
+
* chat() 锁持有者 token(race condition 防护)
|
|
50
|
+
*
|
|
51
|
+
* 获取锁时递增,超时回调和 finally 块据此判断是否仍是当前持有者。
|
|
52
|
+
* 不匹配时跳过清理,避免误清新调用者的资源。
|
|
53
|
+
*/
|
|
54
|
+
private _chatLockToken;
|
|
55
|
+
/** 聊天锁超时计时器(防止 LLM 卡死时锁永久持有) */
|
|
56
|
+
private chatLockTimer;
|
|
57
|
+
/** chat() 内部 AbortController(超时时中断 generator,防止并发) */
|
|
58
|
+
private chatAbortController;
|
|
59
|
+
/** 当前是否持有锁 */
|
|
60
|
+
get isBusy(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* 获取锁,返回 token + 内部 AbortController
|
|
63
|
+
*
|
|
64
|
+
* @param timeoutMs 锁超时时间(LLM 卡死保护)
|
|
65
|
+
* @param onTimeout 超时回调(用于日志记录等)
|
|
66
|
+
* @returns token(用于 finally 校验)+ internalAbort(用于传递给 loop.processUserInput)
|
|
67
|
+
*/
|
|
68
|
+
acquire(timeoutMs: number, onTimeout?: () => void): {
|
|
69
|
+
token: number;
|
|
70
|
+
internalAbort: AbortController;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* 合并外部 signal:外部 abort 时触发内部 abort
|
|
74
|
+
*
|
|
75
|
+
* addEventListener 对已 aborted 的 signal 不触发回调,
|
|
76
|
+
* 需手动检查并触发 internalAbort,否则外部已取消的请求仍会进入主流程。
|
|
77
|
+
*
|
|
78
|
+
* @returns 清理函数(finally 块中调用 removeEventListener)
|
|
79
|
+
*/
|
|
80
|
+
attachExternalSignal(externalSignal: AbortSignal | undefined, internalAbort: AbortController): () => void;
|
|
81
|
+
/**
|
|
82
|
+
* finally 块清理(token 校验后)
|
|
83
|
+
*
|
|
84
|
+
* 仅当本调用仍是当前锁持有者时才清理资源。
|
|
85
|
+
* 若 token 已变(超时释放后被新调用者获取),跳过清理避免误清新调用者的状态。
|
|
86
|
+
*/
|
|
87
|
+
release(token: number): void;
|
|
88
|
+
/**
|
|
89
|
+
* 强制释放对话锁(宿主无进展超时兜底)
|
|
90
|
+
*
|
|
91
|
+
* 场景:宿主主进程"无进展超时"兜底后,generator 可能仍卡在不可中断的 await 点
|
|
92
|
+
* (executeToolCalls 和 generateContextSummary 已覆盖 signal 响应,但其他
|
|
93
|
+
* 第三方库或未来新增的 await 点仍可能不响应 signal)。
|
|
94
|
+
* 此时 _chatBusy 锁未释放,用户再发消息会被 chat() 的竞态保护拒绝,
|
|
95
|
+
* 表现为"UI 能操作但发不出消息",需等到 3 分钟锁超时才能恢复。
|
|
96
|
+
*
|
|
97
|
+
* 安全机制:
|
|
98
|
+
* - 递增 _chatLockToken,让原 chat() 的 finally 块检测到 token 不匹配后
|
|
99
|
+
* 跳过资源清理(避免误清新调用者的 _chatBusy/chatAbortController)
|
|
100
|
+
* - abort chatAbortController,让响应 signal 的 await 点(如 fetch)退出
|
|
101
|
+
* - 原 generator 仍可能在后台运行(无法真正中断不响应 signal 的 await),
|
|
102
|
+
* 但其 finally 块的 token 校验会阻止它影响新调用
|
|
103
|
+
*
|
|
104
|
+
* 幂等性:_chatBusy 已 false 时 no-op(多次调用安全)
|
|
105
|
+
*/
|
|
106
|
+
forceRelease(): void;
|
|
107
|
+
/**
|
|
108
|
+
* 销毁管理器(Agent.close 时调用)
|
|
109
|
+
*
|
|
110
|
+
* 与 forceRelease() 的区别:不记录 warn 日志(close 是正常生命周期,非异常场景)。
|
|
111
|
+
* 递增 token 使任何进行中的 chat() generator 的 finally 块检测到 token 变化后
|
|
112
|
+
* 跳过资源清理(close 已接管清理职责)。
|
|
113
|
+
*/
|
|
114
|
+
dispose(): void;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=chatLockManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatLockManager.d.ts","sourceRoot":"","sources":["../../../src/agent/managers/chatLockManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAe;IAC1B,yBAAyB;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAa;IACnC,gCAAgC;IAChC,OAAO,CAAC,aAAa,CAA8C;IACnE,sDAAsD;IACtD,OAAO,CAAC,mBAAmB,CAAgC;IAE3D,cAAc;IACd,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;;;;;;OAMG;IACH,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,IAAI,GACrB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,eAAe,CAAA;KAAE;IA8BpD;;;;;;;OAOG;IACH,oBAAoB,CAClB,cAAc,EAAE,WAAW,GAAG,SAAS,EACvC,aAAa,EAAE,eAAe,GAC7B,MAAM,IAAI;IAYb;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAY5B;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,IAAI,IAAI;IAkBpB;;;;;;OAMG;IACH,OAAO,IAAI,IAAI;CAchB"}
|