@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
|
@@ -1,51 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 角色管理器 —
|
|
2
|
+
* 角色管理器 — 继承 ConfigResourceManager,扩展角色特定逻辑
|
|
3
3
|
*
|
|
4
4
|
* 职责:
|
|
5
|
-
* - 从 configDir/personas/*.md
|
|
6
|
-
* - 解析 frontmatter(name / keywords / description
|
|
7
|
-
* - 写入 SQLite 索引(source: persona, score: 1.0)
|
|
5
|
+
* - 从 configDir/personas/*.md 加载角色文件(委托基类扫描)
|
|
6
|
+
* - 解析 frontmatter(name / keywords / description / traits.*)
|
|
8
7
|
* - 将激活角色注入到 system prompt 顶部
|
|
9
8
|
* - 支持运行时切换角色 + 关键词自动匹配
|
|
9
|
+
* - 角色切换时间窗口缓冲(防抖锁)
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
* - Persona 遵循"万物皆记忆"
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
16
|
-
* 目录约定:
|
|
17
|
-
* - 单层角色:只有宿主程序级 <configDir>/personas/*.md
|
|
18
|
-
* - 目录名 personas/ 与代码 Persona 术语一致,区别于用户身份信息
|
|
11
|
+
* 设计原则:
|
|
12
|
+
* - Persona 遵循"万物皆记忆"——角色提示作为 system prompt 注入
|
|
13
|
+
* - 与 SkillManager 共享 ConfigResourceManager 基类(消除重复扫描/匹配/生命周期)
|
|
14
|
+
* - 角色特有状态(activePersona/mode/切换缓冲)保留在子类
|
|
19
15
|
*/
|
|
20
|
-
import { scoreByKeywords } from '../utils/segmenter.js';
|
|
21
|
-
import { SOURCE_LABELS } from '../memory/types.js';
|
|
22
16
|
import { logger } from '../logging/logger.js';
|
|
23
|
-
import { byScoreDesc } from '../utils/array.js';
|
|
24
17
|
import { configError } from '../utils/errors.js';
|
|
25
|
-
import {
|
|
18
|
+
import { ConfigResourceManager } from '../utils/configResourceManager.js';
|
|
19
|
+
import { parseKeywords } from '../utils/scanner.js';
|
|
26
20
|
import { safeSetTimeout, clearSafeTimeout } from '../utils/safeTimer.js';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
/**
|
|
22
|
+
* 关键词匹配高置信度阈值:≥ 此值直接返回(低置信度由 agent 层决定是否调 LLM)
|
|
23
|
+
*/
|
|
24
|
+
const KEYWORD_HIGH_CONFIDENCE_THRESHOLD = 0.3;
|
|
30
25
|
/**
|
|
31
26
|
* 从 frontmatter 解析 traits.* 键值对
|
|
32
|
-
*
|
|
33
|
-
* 遍历 frontmatter 中以 "traits." 开头的键,提取数值。
|
|
34
|
-
* 非数值或超出 0-1 范围的值被静默忽略(防御性解析)。
|
|
35
|
-
*
|
|
36
|
-
* @param fm frontmatter 键值对映射
|
|
37
|
-
* @returns traits 对象,无有效键时返回 undefined
|
|
38
27
|
*/
|
|
39
28
|
function parseTraits(fm) {
|
|
40
29
|
const traits = {};
|
|
41
30
|
for (const [key, value] of Object.entries(fm)) {
|
|
42
31
|
if (!key.startsWith('traits.'))
|
|
43
32
|
continue;
|
|
44
|
-
const traitName = key.slice(7);
|
|
33
|
+
const traitName = key.slice(7);
|
|
45
34
|
if (!traitName)
|
|
46
35
|
continue;
|
|
47
36
|
const num = Number(value);
|
|
48
|
-
// 防御性校验:必须是有效数值且在 0-1 范围内
|
|
49
37
|
if (Number.isFinite(num) && num >= 0 && num <= 1) {
|
|
50
38
|
traits[traitName] = num;
|
|
51
39
|
}
|
|
@@ -53,93 +41,112 @@ function parseTraits(fm) {
|
|
|
53
41
|
return Object.keys(traits).length > 0 ? traits : undefined;
|
|
54
42
|
}
|
|
55
43
|
/**
|
|
56
|
-
*
|
|
44
|
+
* 角色管理器
|
|
57
45
|
*/
|
|
58
|
-
export class PersonaManager {
|
|
59
|
-
configDir;
|
|
60
|
-
index;
|
|
46
|
+
export class PersonaManager extends ConfigResourceManager {
|
|
61
47
|
/** 当前激活的角色 */
|
|
62
48
|
activePersona = null;
|
|
63
|
-
/** 角色列表缓存(启动时扫描一次) */
|
|
64
|
-
personaList = [];
|
|
65
49
|
/** 激活模式 */
|
|
66
50
|
mode = 'auto';
|
|
67
51
|
/** 角色切换时间戳列表(用于时间窗口缓冲) */
|
|
68
52
|
switchTimestamps = [];
|
|
69
|
-
/** 缓冲区开关(
|
|
53
|
+
/** 缓冲区开关(30s 内 5 次切换后锁定) */
|
|
70
54
|
switchLocked = false;
|
|
71
55
|
/** 锁定恢复计时器 */
|
|
72
56
|
unlockTimer = null;
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
static
|
|
77
|
-
/**
|
|
78
|
-
static
|
|
57
|
+
/** 锁定自动恢复时间戳(ms epoch) */
|
|
58
|
+
unlockAt = null;
|
|
59
|
+
/** 时间窗口:30 秒 */
|
|
60
|
+
static SWITCH_WINDOW_MS = 30_000;
|
|
61
|
+
/** 窗口内最大切换次数:5 次 */
|
|
62
|
+
static MAX_SWITCHES_IN_WINDOW = 5;
|
|
63
|
+
/** 锁定后自动恢复时间:2 分钟 */
|
|
64
|
+
static AUTO_UNLOCK_MS = 120_000;
|
|
79
65
|
/**
|
|
80
66
|
* @param configDir 配置目录(角色文件在 <configDir>/personas/ 下)
|
|
81
|
-
* @param index SQLite 索引(用于写入 persona 记忆)
|
|
82
67
|
*/
|
|
83
|
-
constructor(configDir
|
|
84
|
-
|
|
85
|
-
this.index = index;
|
|
68
|
+
constructor(configDir) {
|
|
69
|
+
super(configDir, 'personas');
|
|
86
70
|
}
|
|
71
|
+
// ── 生命周期 ───────────────────────────────────
|
|
87
72
|
/**
|
|
88
|
-
* 启动时加载:扫描目录 + 激活指定角色
|
|
73
|
+
* 启动时加载:扫描目录 + 激活指定角色
|
|
89
74
|
*
|
|
90
75
|
* @param activePersona 要激活的角色名(可选,不传则使用第一个找到的角色)
|
|
91
76
|
* @returns 激活角色的 system prompt 段
|
|
92
77
|
*/
|
|
93
78
|
async load(activePersona) {
|
|
94
|
-
|
|
95
|
-
|
|
79
|
+
await this.loadItems(activePersona);
|
|
80
|
+
logger.info({ persona: this.activePersona?.name }, '角色已激活');
|
|
81
|
+
return this.buildSystemPrompt();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 重载角色:清空内存缓存 + 重新扫描 + 保持当前激活角色
|
|
85
|
+
*/
|
|
86
|
+
async reload() {
|
|
87
|
+
const oldActiveName = this.activePersona?.name;
|
|
88
|
+
const count = await super.reload();
|
|
89
|
+
// 保持当前激活角色(若仍存在),否则回退到第一个
|
|
90
|
+
if (oldActiveName) {
|
|
91
|
+
const found = this.items.find((p) => p.name === oldActiveName);
|
|
92
|
+
if (found) {
|
|
93
|
+
this.activePersona = found;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.activePersona = this.items[0] ?? this.createDefaultPersona();
|
|
97
|
+
logger.warn({ oldActive: oldActiveName, newActive: this.activePersona.name }, '激活角色已被删除,回退到默认');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.activePersona = this.items[0] ?? this.createDefaultPersona();
|
|
102
|
+
}
|
|
103
|
+
logger.info({ count, active: this.activePersona.name }, '角色已重载');
|
|
104
|
+
return count;
|
|
105
|
+
}
|
|
106
|
+
// ── 加载后钩子(选择激活角色) ─────────────────────
|
|
107
|
+
/**
|
|
108
|
+
* load() 完成后选择激活角色
|
|
109
|
+
*
|
|
110
|
+
* @param _items 已加载的角色列表
|
|
111
|
+
* @param activeName 指定的激活角色名(options 参数)
|
|
112
|
+
*/
|
|
113
|
+
onAfterLoad(_items, activeName) {
|
|
114
|
+
if (this.items.length === 0) {
|
|
96
115
|
logger.warn({ personaCount: 0 }, '未找到任何角色文件,将使用默认角色');
|
|
97
116
|
this.activePersona = this.createDefaultPersona();
|
|
98
|
-
|
|
99
|
-
return this.buildSystemPrompt();
|
|
117
|
+
return;
|
|
100
118
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
this.writeAllToIndex();
|
|
104
|
-
// 激活指定角色
|
|
105
|
-
if (activePersona) {
|
|
106
|
-
const found = this.personaList.find((p) => p.name === activePersona);
|
|
119
|
+
if (activeName) {
|
|
120
|
+
const found = this.items.find((p) => p.name === activeName);
|
|
107
121
|
if (found) {
|
|
108
122
|
this.activePersona = found;
|
|
109
123
|
}
|
|
110
124
|
else {
|
|
111
|
-
logger.warn({ requested:
|
|
112
|
-
|
|
113
|
-
this.activePersona = this.personaList[0] ?? this.createDefaultPersona();
|
|
125
|
+
logger.warn({ requested: activeName }, '未找到指定角色,使用第一个');
|
|
126
|
+
this.activePersona = this.items[0] ?? this.createDefaultPersona();
|
|
114
127
|
}
|
|
115
128
|
}
|
|
116
129
|
else {
|
|
117
|
-
|
|
118
|
-
this.activePersona = this.personaList[0] ?? this.createDefaultPersona();
|
|
130
|
+
this.activePersona = this.items[0] ?? this.createDefaultPersona();
|
|
119
131
|
}
|
|
120
132
|
logger.info({ persona: this.activePersona.name }, '角色已激活');
|
|
121
|
-
return this.buildSystemPrompt();
|
|
122
133
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
*/
|
|
134
|
+
// ── 角色管理 ──────────────────────────────────────
|
|
135
|
+
/** 当前激活的角色名 */
|
|
126
136
|
get activeName() {
|
|
127
137
|
return this.activePersona?.name ?? 'default';
|
|
128
138
|
}
|
|
129
|
-
/**
|
|
130
|
-
* 获取当前激活角色对象(Phase 2.1:AffectController 需要 traits 字段)
|
|
131
|
-
*
|
|
132
|
-
* 返回 null 时表示未加载任何角色(使用默认行为)。
|
|
133
|
-
*/
|
|
139
|
+
/** 获取当前激活角色对象 */
|
|
134
140
|
getActive() {
|
|
135
141
|
return this.activePersona;
|
|
136
142
|
}
|
|
143
|
+
/** 获取角色列表(委托基类) */
|
|
144
|
+
get list() {
|
|
145
|
+
return this.items;
|
|
146
|
+
}
|
|
137
147
|
/**
|
|
138
148
|
* 切换角色(带时间窗口缓冲)
|
|
139
149
|
*
|
|
140
|
-
* 错误策略统一(IX-03):角色不存在时抛 MemoraError,与 switchProject 一致。
|
|
141
|
-
* 交换锁定时仍返回当前 prompt(非错误,是限流保护)。
|
|
142
|
-
*
|
|
143
150
|
* @param name 角色名
|
|
144
151
|
* @returns 新角色的 system prompt 段
|
|
145
152
|
* @throws MemoraError 如果角色不存在
|
|
@@ -147,19 +154,18 @@ export class PersonaManager {
|
|
|
147
154
|
switchPersona(name) {
|
|
148
155
|
// 缓冲区检查(限流保护,非错误)
|
|
149
156
|
if (this.switchLocked) {
|
|
150
|
-
logger.info({ persona: name }, '角色切换已锁定(
|
|
157
|
+
logger.info({ persona: name }, '角色切换已锁定(30s 内超过 5 次),保持当前');
|
|
151
158
|
return this.buildSystemPrompt();
|
|
152
159
|
}
|
|
153
|
-
const found = this.
|
|
160
|
+
const found = this.items.find((p) => p.name === name);
|
|
154
161
|
if (!found) {
|
|
155
|
-
// 统一错误策略:找不到目标时抛错,而非静默保持当前
|
|
156
162
|
throw configError('角色切换失败', `角色 "${name}" 不存在`, [
|
|
157
163
|
'使用 persona.list 查看可用角色',
|
|
158
164
|
'在 agent-config/personas/ 目录下创建该角色配置文件',
|
|
159
165
|
]);
|
|
160
166
|
}
|
|
161
167
|
if (this.activePersona?.name === name) {
|
|
162
|
-
return this.buildSystemPrompt();
|
|
168
|
+
return this.buildSystemPrompt();
|
|
163
169
|
}
|
|
164
170
|
this.activePersona = found;
|
|
165
171
|
this.recordSwitch();
|
|
@@ -169,148 +175,87 @@ export class PersonaManager {
|
|
|
169
175
|
/**
|
|
170
176
|
* 根据用户输入自动匹配最合适的角色(关键词高置信度匹配)
|
|
171
177
|
*
|
|
172
|
-
* 匹配策略:
|
|
173
|
-
* - 关键词匹配高置信度(≥ KEYWORD_HIGH_CONFIDENCE_THRESHOLD)→ 直接返回
|
|
174
|
-
* - 关键词低置信度/无匹配 → 返回 null(由 agent 层决定是否调用 LLM 辅助)
|
|
175
|
-
*
|
|
176
|
-
* LLM 辅助语义匹配已迁移到 agent 层(agent/personaMatcher.ts),
|
|
177
|
-
* 遵循 backend_layers_rules §分层职责:persona/ 不直接调 LLM。
|
|
178
|
-
*
|
|
179
|
-
* 匹配前置条件:
|
|
180
|
-
* - 当前模式为 'auto'(非手动锁定)
|
|
181
|
-
* - 缓冲区未锁定
|
|
182
|
-
* - 角色列表非空
|
|
183
|
-
* - 匹配的角色与当前角色不同
|
|
184
|
-
*
|
|
185
178
|
* @param userInput 用户输入文本
|
|
186
179
|
* @returns 匹配的角色名,无匹配返回 null
|
|
187
180
|
*/
|
|
188
|
-
|
|
181
|
+
autoMatch(userInput) {
|
|
189
182
|
if (this.mode !== 'auto')
|
|
190
183
|
return null;
|
|
191
184
|
if (this.switchLocked)
|
|
192
185
|
return null;
|
|
193
|
-
if (this.
|
|
186
|
+
if (this.items.length === 0)
|
|
194
187
|
return null;
|
|
195
|
-
const keywordBest = this.findBestKeywordMatch(userInput);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (this.activePersona?.name === keywordBest.name)
|
|
188
|
+
const keywordBest = this.findBestKeywordMatch(userInput, KEYWORD_HIGH_CONFIDENCE_THRESHOLD);
|
|
189
|
+
if (keywordBest) {
|
|
190
|
+
if (this.activePersona?.name === keywordBest.item.name)
|
|
199
191
|
return null;
|
|
200
|
-
return keywordBest.name;
|
|
192
|
+
return keywordBest.item.name;
|
|
201
193
|
}
|
|
202
|
-
// 低置信度/无匹配:返回 null,由 agent 层决定是否调用 LLM 辅助
|
|
203
194
|
return null;
|
|
204
195
|
}
|
|
205
196
|
/**
|
|
206
197
|
* 检查是否满足自动匹配的前置条件
|
|
207
|
-
*
|
|
208
|
-
* 供 agent 层在调用 matchPersonaByLlm 前判断是否值得尝试 LLM 辅助匹配。
|
|
209
|
-
* 前置条件与 autoMatch 内部检查一致:
|
|
210
|
-
* - 当前模式为 'auto'(非手动锁定)
|
|
211
|
-
* - 缓冲区未锁定
|
|
212
|
-
* - 角色列表非空
|
|
213
|
-
*
|
|
214
|
-
* @returns 是否满足自动匹配前置条件
|
|
215
198
|
*/
|
|
216
199
|
canAutoMatch() {
|
|
217
|
-
return this.mode === 'auto' && !this.switchLocked && this.
|
|
200
|
+
return this.mode === 'auto' && !this.switchLocked && this.items.length > 0;
|
|
218
201
|
}
|
|
219
|
-
/**
|
|
220
|
-
* 关键词匹配:遍历角色列表,返回得分最高的角色
|
|
221
|
-
*
|
|
222
|
-
* @param userInput 用户输入文本
|
|
223
|
-
* @returns 得分最高的角色和得分,无命中返回 null
|
|
224
|
-
*/
|
|
225
|
-
findBestKeywordMatch(userInput) {
|
|
226
|
-
const matches = [];
|
|
227
|
-
for (const persona of this.personaList) {
|
|
228
|
-
if (persona.keywords.length === 0)
|
|
229
|
-
continue;
|
|
230
|
-
const score = scoreByKeywords(userInput, persona.keywords);
|
|
231
|
-
if (score > 0) {
|
|
232
|
-
matches.push({ name: persona.name, score });
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (matches.length === 0)
|
|
236
|
-
return null;
|
|
237
|
-
matches.sort(byScoreDesc);
|
|
238
|
-
return matches[0] ?? null;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* 设置激活模式
|
|
242
|
-
*
|
|
243
|
-
* @param mode 'auto'(自动匹配)| 'manual'(手动固定)
|
|
244
|
-
*/
|
|
202
|
+
/** 设置激活模式 */
|
|
245
203
|
setMode(mode) {
|
|
246
204
|
this.mode = mode;
|
|
247
|
-
// 切回自动模式时清除锁定状态
|
|
248
205
|
if (mode === 'auto' && this.switchLocked) {
|
|
249
206
|
this.switchLocked = false;
|
|
250
207
|
this.switchTimestamps = [];
|
|
208
|
+
this.unlockAt = null;
|
|
251
209
|
logger.info({ mode: this.mode }, '角色切换锁定已解除(模式切回自动)');
|
|
252
210
|
}
|
|
253
211
|
}
|
|
212
|
+
/** 获取角色切换锁定状态 */
|
|
213
|
+
getSwitchLockStatus() {
|
|
214
|
+
return { locked: this.switchLocked, unlockAt: this.unlockAt };
|
|
215
|
+
}
|
|
254
216
|
/** 获取当前激活模式 */
|
|
255
217
|
get currentMode() {
|
|
256
218
|
return this.mode;
|
|
257
219
|
}
|
|
258
|
-
/**
|
|
259
|
-
* 获取角色列表
|
|
260
|
-
*/
|
|
261
|
-
get list() {
|
|
262
|
-
return this.personaList;
|
|
263
|
-
}
|
|
264
220
|
/**
|
|
265
221
|
* 清理定时器资源(Agent.close() 时调用)
|
|
266
|
-
*
|
|
267
|
-
* PersonaManager 持有 unlockTimer(角色切换防抖锁的自动恢复计时器),
|
|
268
|
-
* 若不清理,Agent 关闭后定时器仍会触发回调,在已关闭的实例上执行引发异常。
|
|
269
222
|
*/
|
|
270
223
|
close() {
|
|
271
224
|
if (this.unlockTimer) {
|
|
272
225
|
clearSafeTimeout(this.unlockTimer);
|
|
273
226
|
this.unlockTimer = null;
|
|
274
227
|
}
|
|
228
|
+
this.switchLocked = false;
|
|
229
|
+
this.unlockAt = null;
|
|
230
|
+
this.switchTimestamps = [];
|
|
275
231
|
}
|
|
276
232
|
/**
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
* 事件驱动重载:confirmConfigSuggestion 写入 persona 文件后或用户手动编辑
|
|
280
|
-
* personas/ 目录后,调用此方法使当前会话立即生效,无需重启 Agent。
|
|
233
|
+
* 删除角色
|
|
281
234
|
*
|
|
282
|
-
*
|
|
283
|
-
* - 若当前激活角色在重载后仍存在 → 更新为重载后的版本(内容可能已变更)
|
|
284
|
-
* - 若当前激活角色已被删除 → 回退到列表第一个角色(与 load() 默认行为一致)
|
|
235
|
+
* 若删除的是激活角色,自动回退到列表第一个或默认角色。
|
|
285
236
|
*
|
|
286
|
-
* @
|
|
237
|
+
* @param name 角色名
|
|
238
|
+
* @returns true 删除成功;false 角色不存在
|
|
287
239
|
*/
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
this.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
this.activePersona = this.personaList[0] ?? this.createDefaultPersona();
|
|
300
|
-
logger.warn({ oldActive: oldActiveName, newActive: this.activePersona.name }, '激活角色已被删除,回退到默认');
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
this.activePersona = this.personaList[0] ?? this.createDefaultPersona();
|
|
240
|
+
deletePersona(name) {
|
|
241
|
+
// 先检查是否为激活角色(删除前捕获,因 deleteItem 会改变 items)
|
|
242
|
+
const isActive = this.activePersona?.name === name;
|
|
243
|
+
const deleted = this.deleteItem(name);
|
|
244
|
+
if (!deleted)
|
|
245
|
+
return false;
|
|
246
|
+
// 若删除的是激活角色,回退
|
|
247
|
+
if (isActive) {
|
|
248
|
+
this.activePersona = this.items[0] ?? this.createDefaultPersona();
|
|
249
|
+
logger.warn({ deleted: name, newActive: this.activePersona.name }, '激活角色已被删除,回退到默认');
|
|
305
250
|
}
|
|
306
|
-
|
|
307
|
-
return this.personaList.length;
|
|
251
|
+
return true;
|
|
308
252
|
}
|
|
253
|
+
// ── 系统提示 ──────────────────────────────────────
|
|
309
254
|
/**
|
|
310
255
|
* 构建 system prompt 中的角色段
|
|
311
256
|
*/
|
|
312
257
|
buildSystemPrompt(name) {
|
|
313
|
-
const p = name ? this.
|
|
258
|
+
const p = name ? this.items.find((item) => item.name === name) : this.activePersona;
|
|
314
259
|
if (!p)
|
|
315
260
|
return '';
|
|
316
261
|
const meta = [`【当前角色】${p.name}`];
|
|
@@ -318,85 +263,41 @@ export class PersonaManager {
|
|
|
318
263
|
meta.push(p.description);
|
|
319
264
|
return `${meta.join(' · ')}\n\n${p.content}`;
|
|
320
265
|
}
|
|
266
|
+
// ── 基类抽象方法实现 ──────────────────────────────
|
|
267
|
+
createEntry(entry) {
|
|
268
|
+
const fm = entry.frontmatter;
|
|
269
|
+
return {
|
|
270
|
+
name: entry.name,
|
|
271
|
+
id: fm['id'] ?? `persona:${entry.name}`,
|
|
272
|
+
description: fm['description'],
|
|
273
|
+
keywords: parseKeywords(fm),
|
|
274
|
+
content: entry.body.trim(),
|
|
275
|
+
filePath: entry.filePath,
|
|
276
|
+
traits: parseTraits(fm),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
321
279
|
// ── 私有方法 ──────────────────────────────────────
|
|
322
280
|
/**
|
|
323
281
|
* 记录一次角色切换(时间窗口缓冲)
|
|
324
282
|
*/
|
|
325
283
|
recordSwitch() {
|
|
326
284
|
const now = Date.now();
|
|
327
|
-
// 清理过期记录
|
|
328
285
|
this.switchTimestamps = this.switchTimestamps.filter((t) => now - t < PersonaManager.SWITCH_WINDOW_MS);
|
|
329
286
|
this.switchTimestamps.push(now);
|
|
330
287
|
if (this.switchTimestamps.length >= PersonaManager.MAX_SWITCHES_IN_WINDOW) {
|
|
331
|
-
logger.warn({ count: this.switchTimestamps.length }, '角色切换过于频繁,锁定
|
|
288
|
+
logger.warn({ count: this.switchTimestamps.length }, '角色切换过于频繁,锁定 2 分钟');
|
|
332
289
|
this.switchLocked = true;
|
|
333
|
-
|
|
290
|
+
this.unlockAt = now + PersonaManager.AUTO_UNLOCK_MS;
|
|
334
291
|
if (this.unlockTimer)
|
|
335
292
|
clearSafeTimeout(this.unlockTimer);
|
|
336
293
|
this.unlockTimer = safeSetTimeout(() => {
|
|
337
294
|
this.switchLocked = false;
|
|
338
295
|
this.switchTimestamps = [];
|
|
296
|
+
this.unlockAt = null;
|
|
339
297
|
logger.info({ mode: this.mode }, '角色切换锁定已自动解除');
|
|
340
298
|
}, PersonaManager.AUTO_UNLOCK_MS);
|
|
341
299
|
}
|
|
342
300
|
}
|
|
343
|
-
/**
|
|
344
|
-
* 扫描单层目录,加载角色列表
|
|
345
|
-
*/
|
|
346
|
-
async scanPersonas() {
|
|
347
|
-
const list = [];
|
|
348
|
-
const personasDir = resolveSubdir(this.configDir, 'personas');
|
|
349
|
-
if (!personasDir)
|
|
350
|
-
return list;
|
|
351
|
-
const entries = await scanMarkdownDir(personasDir);
|
|
352
|
-
for (const entry of entries) {
|
|
353
|
-
const fm = entry.frontmatter;
|
|
354
|
-
list.push({
|
|
355
|
-
name: entry.name,
|
|
356
|
-
id: fm['id'] ?? `persona:${entry.name}`,
|
|
357
|
-
description: fm['description'],
|
|
358
|
-
keywords: parseKeywords(fm),
|
|
359
|
-
content: entry.body.trim(),
|
|
360
|
-
filePath: entry.filePath,
|
|
361
|
-
// Phase 2.1:解析 traits.* 键值对(如 traits.playfulness: 0.7)
|
|
362
|
-
traits: parseTraits(fm),
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
return list;
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* 将所有角色写入 SQLite 索引
|
|
369
|
-
*
|
|
370
|
-
* 本函数循环体内无 await,作为同步函数实现。
|
|
371
|
-
*/
|
|
372
|
-
writeAllToIndex() {
|
|
373
|
-
if (!this.index)
|
|
374
|
-
return;
|
|
375
|
-
for (const persona of this.personaList) {
|
|
376
|
-
this.writePersonaToIndex(persona);
|
|
377
|
-
}
|
|
378
|
-
logger.info({ count: this.personaList.length }, '角色记忆已写入 SQLite');
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* 将单个角色写入 SQLite 索引
|
|
382
|
-
*
|
|
383
|
-
* 函数体无 await,作为同步函数实现。index.upsert 是同步方法。
|
|
384
|
-
*/
|
|
385
|
-
writePersonaToIndex(persona) {
|
|
386
|
-
if (!this.index)
|
|
387
|
-
return;
|
|
388
|
-
const now = nowIso();
|
|
389
|
-
const memory = {
|
|
390
|
-
id: persona.id,
|
|
391
|
-
content: persona.content,
|
|
392
|
-
source: SOURCE_LABELS.PERSONA,
|
|
393
|
-
name: persona.name,
|
|
394
|
-
createdAt: now,
|
|
395
|
-
accessedAt: now,
|
|
396
|
-
score: 1.0,
|
|
397
|
-
};
|
|
398
|
-
this.index.upsert(memory);
|
|
399
|
-
}
|
|
400
301
|
/**
|
|
401
302
|
* 创建默认角色
|
|
402
303
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"personaManager.js","sourceRoot":"","sources":["../../src/persona/personaManager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"personaManager.js","sourceRoot":"","sources":["../../src/persona/personaManager.ts"],"names":[],"mappings":"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"}
|