@zooique/memora 4.0.0 → 5.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/CHANGELOG.md +235 -1743
- package/README.en.md +43 -36
- package/README.md +308 -303
- package/dist/agent/agent.d.ts +46 -82
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +153 -220
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/assembler.d.ts +3 -16
- package/dist/agent/assembler.d.ts.map +1 -1
- package/dist/agent/assembler.js +76 -47
- package/dist/agent/assembler.js.map +1 -1
- package/dist/agent/backgroundTasks.d.ts +8 -1
- package/dist/agent/backgroundTasks.d.ts.map +1 -1
- package/dist/agent/backgroundTasks.js +8 -1
- package/dist/agent/backgroundTasks.js.map +1 -1
- package/dist/agent/budget.d.ts +23 -5
- package/dist/agent/budget.d.ts.map +1 -1
- package/dist/agent/budget.js +8 -2
- package/dist/agent/budget.js.map +1 -1
- package/dist/agent/builtinToolHandlers.d.ts +50 -10
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
- package/dist/agent/builtinToolHandlers.js +67 -20
- package/dist/agent/builtinToolHandlers.js.map +1 -1
- package/dist/agent/builtinTools.d.ts +16 -0
- package/dist/agent/builtinTools.d.ts.map +1 -1
- package/dist/agent/builtinTools.js +15 -4
- package/dist/agent/builtinTools.js.map +1 -1
- package/dist/agent/constants.d.ts +0 -6
- package/dist/agent/constants.d.ts.map +1 -1
- package/dist/agent/constants.js +7 -8
- 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 +45 -3
- package/dist/agent/contextManager.js.map +1 -1
- package/dist/agent/contextPreparer.d.ts +1 -1
- package/dist/agent/contextPreparer.d.ts.map +1 -1
- package/dist/agent/contextPreparer.js +15 -10
- package/dist/agent/contextPreparer.js.map +1 -1
- package/dist/agent/guardRail.d.ts +25 -10
- package/dist/agent/guardRail.d.ts.map +1 -1
- package/dist/agent/guardRail.js +154 -46
- package/dist/agent/guardRail.js.map +1 -1
- package/dist/agent/loop.d.ts +46 -13
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +145 -32
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/managers/archiveCoordinator.d.ts +15 -3
- package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -1
- package/dist/agent/managers/archiveCoordinator.js +13 -7
- package/dist/agent/managers/archiveCoordinator.js.map +1 -1
- package/dist/agent/managers/chatLockManager.d.ts +3 -9
- package/dist/agent/managers/chatLockManager.d.ts.map +1 -1
- package/dist/agent/managers/chatLockManager.js +7 -25
- package/dist/agent/managers/chatLockManager.js.map +1 -1
- package/dist/agent/managers/llmCaller.d.ts.map +1 -1
- package/dist/agent/managers/llmCaller.js +27 -1
- package/dist/agent/managers/llmCaller.js.map +1 -1
- package/dist/agent/managers/memoryInspector.d.ts +12 -7
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
- package/dist/agent/managers/memoryInspector.js +32 -19
- package/dist/agent/managers/memoryInspector.js.map +1 -1
- package/dist/agent/managers/roundSummaryGenerator.d.ts +3 -1
- package/dist/agent/managers/roundSummaryGenerator.d.ts.map +1 -1
- package/dist/agent/managers/roundSummaryGenerator.js +14 -4
- package/dist/agent/managers/roundSummaryGenerator.js.map +1 -1
- package/dist/agent/managers/sessionArchiver.d.ts +20 -6
- package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
- package/dist/agent/managers/sessionArchiver.js +19 -5
- package/dist/agent/managers/sessionArchiver.js.map +1 -1
- package/dist/agent/managers/sessionManager.d.ts +21 -88
- package/dist/agent/managers/sessionManager.d.ts.map +1 -1
- package/dist/agent/managers/sessionManager.js +77 -278
- package/dist/agent/managers/sessionManager.js.map +1 -1
- package/dist/agent/seed/orchestrator.d.ts.map +1 -1
- package/dist/agent/seed/orchestrator.js +3 -3
- package/dist/agent/seed/orchestrator.js.map +1 -1
- package/dist/agent/seed/prepare.d.ts.map +1 -1
- package/dist/agent/seed/prepare.js +9 -4
- package/dist/agent/seed/prepare.js.map +1 -1
- package/dist/agent/seed/types.d.ts +11 -4
- package/dist/agent/seed/types.d.ts.map +1 -1
- package/dist/agent/seed/types.js +2 -2
- package/dist/agent/toolExecutor.d.ts +69 -18
- package/dist/agent/toolExecutor.d.ts.map +1 -1
- package/dist/agent/toolExecutor.js +188 -28
- package/dist/agent/toolExecutor.js.map +1 -1
- package/dist/agent/toolResultCache.js +1 -1
- package/dist/agent/toolRunner.d.ts +4 -2
- package/dist/agent/toolRunner.d.ts.map +1 -1
- package/dist/agent/toolRunner.js +7 -4
- package/dist/agent/toolRunner.js.map +1 -1
- package/dist/agent/types.d.ts +8 -25
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/index.d.ts +9 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -32
- package/dist/index.js.map +1 -1
- package/dist/logging/logger.d.ts +4 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +5 -2
- package/dist/logging/logger.js.map +1 -1
- package/dist/memory/gcService.d.ts.map +1 -1
- package/dist/memory/gcService.js +3 -5
- package/dist/memory/gcService.js.map +1 -1
- package/dist/memory/inMemorySessionStore.d.ts +2 -2
- package/dist/memory/inMemorySessionStore.js +2 -2
- package/dist/memory/inMemoryStorage.d.ts +4 -3
- package/dist/memory/inMemoryStorage.d.ts.map +1 -1
- package/dist/memory/inMemoryStorage.js +2 -2
- package/dist/memory/inMemoryStorage.js.map +1 -1
- package/dist/memory/nodeSqliteStorage.d.ts +17 -0
- package/dist/memory/nodeSqliteStorage.d.ts.map +1 -0
- package/dist/memory/nodeSqliteStorage.js +393 -0
- package/dist/memory/nodeSqliteStorage.js.map +1 -0
- package/dist/memory/projectManager.d.ts +10 -20
- package/dist/memory/projectManager.d.ts.map +1 -1
- package/dist/memory/projectManager.js +27 -41
- package/dist/memory/projectManager.js.map +1 -1
- package/dist/memory/roundStore.d.ts +76 -1
- package/dist/memory/roundStore.d.ts.map +1 -1
- package/dist/memory/roundStore.js.map +1 -1
- package/dist/memory/roundSummaryLookup.d.ts +26 -0
- package/dist/memory/roundSummaryLookup.d.ts.map +1 -0
- package/dist/memory/roundSummaryLookup.js +19 -0
- package/dist/memory/roundSummaryLookup.js.map +1 -0
- package/dist/memory/sessionStore.d.ts +19 -2
- package/dist/memory/sessionStore.d.ts.map +1 -1
- package/dist/memory/sessionStore.js.map +1 -1
- package/dist/memory/sourceValidation.d.ts +2 -13
- package/dist/memory/sourceValidation.d.ts.map +1 -1
- package/dist/memory/sourceValidation.js +5 -16
- package/dist/memory/sourceValidation.js.map +1 -1
- package/dist/memory/storageInterface.d.ts +26 -16
- package/dist/memory/storageInterface.d.ts.map +1 -1
- package/dist/memory/supersedeResolve.d.ts +39 -0
- package/dist/memory/supersedeResolve.d.ts.map +1 -0
- package/dist/memory/supersedeResolve.js +16 -0
- package/dist/memory/supersedeResolve.js.map +1 -0
- package/dist/memory/types.d.ts +3 -2
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +2 -1
- package/dist/memory/types.js.map +1 -1
- package/dist/role-pack/rolePackManager.d.ts +33 -24
- package/dist/role-pack/rolePackManager.d.ts.map +1 -1
- package/dist/role-pack/rolePackManager.js +48 -42
- package/dist/role-pack/rolePackManager.js.map +1 -1
- package/dist/role-pack/strategyKeys.d.ts +8 -0
- package/dist/role-pack/strategyKeys.d.ts.map +1 -1
- package/dist/role-pack/strategyKeys.js +10 -0
- package/dist/role-pack/strategyKeys.js.map +1 -1
- package/dist/role-pack/strategyResolver.d.ts +6 -1
- package/dist/role-pack/strategyResolver.d.ts.map +1 -1
- package/dist/role-pack/strategyResolver.js +20 -2
- package/dist/role-pack/strategyResolver.js.map +1 -1
- package/dist/role-pack/types.d.ts +5 -1
- package/dist/role-pack/types.d.ts.map +1 -1
- package/dist/security/confirmEntries.d.ts +21 -6
- package/dist/security/confirmEntries.d.ts.map +1 -1
- package/dist/security/confirmEntries.js +21 -6
- package/dist/security/confirmEntries.js.map +1 -1
- package/dist/security/pathGuard.d.ts +44 -10
- package/dist/security/pathGuard.d.ts.map +1 -1
- package/dist/security/pathGuard.js +70 -10
- package/dist/security/pathGuard.js.map +1 -1
- package/dist/utils/backgroundTask.d.ts +56 -34
- package/dist/utils/backgroundTask.d.ts.map +1 -1
- package/dist/utils/backgroundTask.js +130 -99
- package/dist/utils/backgroundTask.js.map +1 -1
- package/dist/utils/errors.d.ts +3 -2
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +3 -2
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/eventEmitter.d.ts +20 -22
- package/dist/utils/eventEmitter.d.ts.map +1 -1
- package/dist/utils/eventEmitter.js +0 -3
- package/dist/utils/eventEmitter.js.map +1 -1
- package/dist/utils/time.d.ts +3 -3
- package/dist/utils/time.d.ts.map +1 -1
- package/dist/utils/time.js +3 -3
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/toError.d.ts +1 -1
- package/dist/utils/toError.js +1 -1
- package/dist/web-fetch/loginWall.d.ts +39 -0
- package/dist/web-fetch/loginWall.d.ts.map +1 -0
- package/dist/web-fetch/loginWall.js +78 -0
- package/dist/web-fetch/loginWall.js.map +1 -0
- package/dist/web-fetch/types.d.ts +8 -0
- package/dist/web-fetch/types.d.ts.map +1 -1
- package/dist/web-fetch/webFetchProvider.d.ts.map +1 -1
- package/dist/web-fetch/webFetchProvider.js +3 -1
- package/dist/web-fetch/webFetchProvider.js.map +1 -1
- package/dist/web-search/fetchWebSearchProvider.js +28 -23
- package/dist/web-search/fetchWebSearchProvider.js.map +1 -1
- package/docs/architecture/role-pack-authoring-guide.md +7 -1
- package/docs/architecture/role-pack-spec.md +11 -6
- package/docs/memora-api-reference.md +1354 -1276
- package/docs/memora-/345/215/207/347/272/247/346/214/207/345/215/227-4.x-/345/210/260-5.0.0.md +385 -0
- package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +89 -49
- package/docs/role-pack-/345/274/200/346/224/276/351/224/256/346/214/207/345/215/227.md +148 -148
- package/package.json +13 -4
- package/role-packs/README.md +41 -40
- package/role-packs/memora/345/212/251/346/211/213/rules.md +5 -4
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/manifest.json +1 -0
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/persona.md +46 -46
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/rules.md +17 -16
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/emotion-wave.md +46 -46
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/foreshadow.md +29 -29
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/outline-expand.md +73 -48
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/project-init/scripts/init-novel-project.mjs +445 -441
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-bible.md +62 -62
- package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/manifest.json +1 -0
- package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/rules.md +2 -1
- package/dist/agent/managers/dedupManager.d.ts +0 -85
- package/dist/agent/managers/dedupManager.d.ts.map +0 -1
- package/dist/agent/managers/dedupManager.js +0 -248
- package/dist/agent/managers/dedupManager.js.map +0 -1
- package/dist/agent/managers/goalConsistencyChecker.d.ts +0 -42
- package/dist/agent/managers/goalConsistencyChecker.d.ts.map +0 -1
- package/dist/agent/managers/goalConsistencyChecker.js +0 -178
- package/dist/agent/managers/goalConsistencyChecker.js.map +0 -1
- package/dist/agent/managers/llmJudgeHelper.d.ts +0 -21
- package/dist/agent/managers/llmJudgeHelper.d.ts.map +0 -1
- package/dist/agent/managers/llmJudgeHelper.js +0 -32
- package/dist/agent/managers/llmJudgeHelper.js.map +0 -1
- package/dist/agent/managers/memoryAdvisor.d.ts +0 -105
- package/dist/agent/managers/memoryAdvisor.d.ts.map +0 -1
- package/dist/agent/managers/memoryAdvisor.js +0 -322
- package/dist/agent/managers/memoryAdvisor.js.map +0 -1
- package/dist/agent/managers/memoryGovernance.d.ts +0 -24
- package/dist/agent/managers/memoryGovernance.d.ts.map +0 -1
- package/dist/agent/managers/memoryGovernance.js +0 -46
- package/dist/agent/managers/memoryGovernance.js.map +0 -1
- package/dist/memory/governance.d.ts +0 -17
- package/dist/memory/governance.d.ts.map +0 -1
- package/dist/memory/governance.js +0 -17
- package/dist/memory/governance.js.map +0 -1
- package/dist/memory/projectRegistry.d.ts +0 -47
- package/dist/memory/projectRegistry.d.ts.map +0 -1
- package/dist/memory/projectRegistry.js +0 -151
- package/dist/memory/projectRegistry.js.map +0 -1
- package/dist/utils/recallDefaults.d.ts +0 -16
- package/dist/utils/recallDefaults.d.ts.map +0 -1
- package/dist/utils/recallDefaults.js +0 -16
- package/dist/utils/recallDefaults.js.map +0 -1
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
# Memora · 接入指南
|
|
1
|
+
# Memora · 接入指南 v5.1.0
|
|
2
2
|
|
|
3
3
|
> 帮助宿主项目开发者快速理解 Memora 的设计理念和接入方法。
|
|
4
4
|
>
|
|
5
|
-
>
|
|
5
|
+
> **当前内核版本**:v5.1.0(对齐当前内核包版本 `package.json`)。各版完整变更见 [CHANGELOG](../CHANGELOG.md)。
|
|
6
|
+
>
|
|
7
|
+
> **最新已发布版本**:以 npm registry 为准(`npm view @zooique/memora dist-tags.latest`),不在包内复述。
|
|
6
8
|
>
|
|
7
9
|
> **对接入者有影响的迁移结论**(不含历史流水,细节见 [API 参考手册](./memora-api-reference.md)):
|
|
8
10
|
> - 1.0 为正式发布,API 已稳定;2.0 起设定记忆(persona/rules/skills)解耦为纯文件 + 内存缓存,唯一归角色包、不进记忆库(ADR-025),角色管理统一走 `agent.rolePack`。
|
|
9
|
-
> - 已移除:`SqliteStorage
|
|
11
|
+
> - 已移除:`SqliteStorage`(**原 better-sqlite3 实现**移出内核,由宿主实现 `IMemoryStorage`——注意这是 native 实现出内核,**不等于**内核不再提供任何 SQLite 实现;5.0.0 起内核另有基于 `node:*` 内建模块的 `createNodeSqliteStorage`)、洞察层(`insight.*`)、AutoConfigRefiner / ConfigManager、记忆关系图谱与用户画像层(偏好收敛为 round-summary,冲突改用 `supersededBy` 布尔标记)。
|
|
10
12
|
>
|
|
11
13
|
---
|
|
12
14
|
|
|
@@ -32,13 +34,13 @@
|
|
|
32
34
|
|
|
33
35
|
**摘要即记忆(memory-as-summary)。** Memora 的记忆只有单一轨道——**对话记忆**(round-summary 摘要,宿主持久化 + **纯关键词召回**,带 `summaryType` 语义标签);**设定**(角色包 persona/rules/skills)是 Agent 的骨骼,.md 文件 + 内存缓存,唯一归角色包、确定性注入不经过召回,不属记忆库(ADR-025)。二者边界一刀切:记忆系统只承载对话摘要、角色包承载设定;偏好类信息沉淀为摘要记忆,不设独立"用户画像"记忆层。
|
|
34
36
|
|
|
35
|
-
**单 Agent
|
|
37
|
+
**单 Agent 模型(一个项目一个 Agent)。** 一个 Agent 实例的对话与记忆由**同一组存储实例**承载(`storage` / `sessionStore` 均在构造时注入、实例级),**切会话不换存储、不丢记忆**。要按项目彼此隔离,就各自 `new Agent`——**隔离粒度由宿主决定,内核不规定**(形态与取舍见 [§8](#8-多项目一个项目一个-agent形态定案))。
|
|
36
38
|
|
|
37
39
|
**配置文件是真理源,对话记忆由宿主持久化。** 角色包(persona/rules/skills)为纯文件 + 内存缓存,设定记忆唯一归角色包、不进记忆库(ADR-025);对话记忆(round-summary 摘要记忆,带 `summaryType` 标签)经宿主注入的 `IMemoryStorage` 持久化——**后端由宿主自选**(SQLite / JSON 文件 / 内存皆可),检索为 **纯关键词召回**(向量语义通道已随 2026-09-18 B0 收编移除,见 [API 参考手册](./memora-api-reference.md) §〇.5 构造参数表)。
|
|
38
40
|
|
|
39
41
|
**内核零越界。** 核心库模块不直接调用 `console.*`(唯一日志出口为 `logging/` 单例,默认实现写 stderr)、不读 `process.stdin`、不管理 API Key、不写用户配置文件。
|
|
40
42
|
|
|
41
|
-
**Manager 委托模式。** Agent 面类只做编排,领域操作委托给专职 Manager:`agent.rolePack`(角色包)/ `agent.tools`(工具)/ `agent.skills`(技能)/ `agent.memory`(记忆查询+写入)/ `agent.
|
|
43
|
+
**Manager 委托模式。** Agent 面类只做编排,领域操作委托给专职 Manager:`agent.rolePack`(角色包)/ `agent.tools`(工具)/ `agent.skills`(技能)/ `agent.memory`(记忆查询+写入)/ `agent.works`(作品投影)/ `agent.polish`(文本润色)共 6 个业务 Manager(另有 `projects` / `security` / `sessionManager` 等)。
|
|
42
44
|
|
|
43
45
|
```
|
|
44
46
|
┌────────────────────────────────────────────────────────────┐
|
|
@@ -51,7 +53,7 @@
|
|
|
51
53
|
│ ┌──────────────────────────────────────────┐ │
|
|
52
54
|
│ │ Memora 内核(Agent) │ │
|
|
53
55
|
│ │ - chat(input) → 流式响应 │ │
|
|
54
|
-
│ │ -
|
|
56
|
+
│ │ - 6 个业务 Manager getter(rolePack/tools/skills/memory/works/polish,委托模式) │ │
|
|
55
57
|
│ │ ⚠️ 不包含:UI / LLM 配置 / 用户配置模板 │ │
|
|
56
58
|
│ └──────────────────────────────────────────┘ │
|
|
57
59
|
└────────────────────────────────────────────────────────────┘
|
|
@@ -71,11 +73,13 @@
|
|
|
71
73
|
```
|
|
72
74
|
小说项目/
|
|
73
75
|
├── .memora/ ← 项目级配置(rules + skills)+ 内核写入的 .lock
|
|
74
|
-
└── .memora-data/ ← dataDir
|
|
75
|
-
├── projects.json ← 内核写入:项目注册表
|
|
76
|
+
└── .memora-data/ ← dataDir 指向此处(Agent 级资源目录;宿主注入 storage 时内核不在此落文件)
|
|
76
77
|
└── <记忆库> ← 由宿主的 storage 决定形态与文件名
|
|
77
78
|
```
|
|
78
79
|
|
|
80
|
+
> **多项目怎么办**:一个 Agent 绑定一个项目,不做项目切换;多项目请为每个项目各创建一个
|
|
81
|
+
> Agent 实例。完整形态、取舍与代码示例见 [§8 多项目:一个项目一个 Agent](#8-多项目一个项目一个-agent形态定案)。
|
|
82
|
+
|
|
79
83
|
---
|
|
80
84
|
|
|
81
85
|
## 三、最小接入步骤
|
|
@@ -109,7 +113,8 @@ const backgroundProvider = createProviderFromConfig('background', {
|
|
|
109
113
|
model: 'deepseek-chat', // 可用更便宜的模型
|
|
110
114
|
});
|
|
111
115
|
|
|
112
|
-
//
|
|
116
|
+
// 可选:注入存储层(不传则用内核内置内存实现,仅内存不落盘;该类不挂公共面——PUB-API-PRUNE-2 收面)。
|
|
117
|
+
// 后端由宿主自选,二选一即可:
|
|
113
118
|
const storage: IMemoryStorage = new MySqliteStorage('/path/to/memora.db'); // SQLite(同步实现天然对齐)
|
|
114
119
|
// const storage: IMemoryStorage = new MyJsonStorage('/path/to/memories.json'); // JSON 文件(第一宿主 memora-vscode 的选法)
|
|
115
120
|
|
|
@@ -123,7 +128,7 @@ const agent = new Agent({
|
|
|
123
128
|
backgroundProvider, // 后台 Provider(可选)
|
|
124
129
|
configDir: '/path/to/agent-config',
|
|
125
130
|
dataDir: '/path/to/novel-project/.memora-data', // 必填;相对路径会以进程 cwd 为基准,建议传绝对路径
|
|
126
|
-
maxContextTokens: 120000,
|
|
131
|
+
maxContextTokens: 120000, // 示例值——缺省时以内核 AGENT_CONSTANTS.DEFAULT_MAX_CONTEXT_TOKENS 为真源,数字以该常量为准
|
|
127
132
|
activeRolePack: '作家',
|
|
128
133
|
permission: 'owner',
|
|
129
134
|
allowedPaths: ['.'],
|
|
@@ -161,7 +166,7 @@ Agent 向宿主广播对话外事件(记忆变更、角色切换、会话分
|
|
|
161
166
|
import type { AgentEventMap } from '@zooique/memora';
|
|
162
167
|
|
|
163
168
|
agent.on('memoryAdded', (e) => console.log(`新记忆: ${e.source}:${e.name}`));
|
|
164
|
-
agent.on('
|
|
169
|
+
agent.on('rolePackSwitched', (e) => console.log(`角色: ${e.from} → ${e.to}`));
|
|
165
170
|
agent.on('memoryRecalled', (e) => console.log(`想起 ${e.count} 条记忆`));
|
|
166
171
|
agent.on('sessionForked', (e) => console.log(`分叉: ${e.from} → ${e.to},${e.roundCount} 个问答闭环`));
|
|
167
172
|
|
|
@@ -263,22 +268,50 @@ if (rp) {
|
|
|
263
268
|
}
|
|
264
269
|
```
|
|
265
270
|
|
|
266
|
-
### 8.
|
|
271
|
+
### 8. 多项目:一个项目一个 Agent(形态定案)
|
|
272
|
+
|
|
273
|
+
**一个 Agent 绑定一个项目**,内核不做项目切换。多项目请为**每个项目各创建一个 Agent 实例**:
|
|
267
274
|
|
|
268
275
|
```typescript
|
|
269
|
-
//
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
//
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
// 项目 A
|
|
277
|
+
const agentA = new Agent({
|
|
278
|
+
projectPath: '/repo/app-a',
|
|
279
|
+
dataDir: '/repo/app-a/.memora',
|
|
280
|
+
storage: makeStorage('/repo/app-a'), // 宿主实现的 IMemoryStorage
|
|
281
|
+
sessionStore: makeSessionStore('/repo/app-a'),
|
|
282
|
+
provider, configDir,
|
|
283
|
+
});
|
|
284
|
+
await agentA.init();
|
|
285
|
+
|
|
286
|
+
// 项目 B:独立实例,与 A 并行运行、互不干扰
|
|
287
|
+
const agentB = new Agent({
|
|
288
|
+
projectPath: '/repo/app-b',
|
|
289
|
+
dataDir: '/repo/app-b/.memora',
|
|
290
|
+
storage: makeStorage('/repo/app-b'),
|
|
291
|
+
sessionStore: makeSessionStore('/repo/app-b'),
|
|
292
|
+
provider, configDir,
|
|
293
|
+
});
|
|
294
|
+
await agentB.init();
|
|
278
295
|
```
|
|
279
296
|
|
|
280
|
-
|
|
281
|
-
|
|
297
|
+
每个实例各自持有:记忆库(宿主注入的 storage)、会话存储、项目锁、安全守卫、角色包管理器。
|
|
298
|
+
项目数据天然隔离在项目自己的 `.memora/` 下。
|
|
299
|
+
|
|
300
|
+
| 维度 | 形态 |
|
|
301
|
+
|------|------|
|
|
302
|
+
| 并行度 | **按项目计** —— N 个项目 = N 个会话同时跑 |
|
|
303
|
+
| 项目内多会话 | 可拥有 N 个会话(`switchSession` / `switchToSession` / `forkSession`),**同一时刻只跑一个** |
|
|
304
|
+
| 项目内多会话的记忆 | **共享同一个记忆库**(`searchByKeyword` 无 sessionId 过滤)⇒ 经验跨会话连续 |
|
|
305
|
+
|
|
306
|
+
**取舍(明写,勿反复重议)**:本形态**不对标主流「一个会话 = 一个 Agent 实例」**。代价是
|
|
307
|
+
**同一项目内不能并行跑两个会话**(主流开两个终端各推各的任务即可)——已知并接受,登记
|
|
308
|
+
`MULTI-SESS-1`(观察,不修)。**理由**:记忆库归**项目**所有,会话只是项目内的对话线程;
|
|
309
|
+
把身份边界画在项目而非会话,才能让同一项目的经验跨会话连续。仅当出现「同一仓库要并行
|
|
310
|
+
两个任务」的真实需求时才重议形态。
|
|
311
|
+
|
|
312
|
+
> 历史留痕:5.0.0 前曾有 `agent.switchProject()` / `agent.projects.*` / `AgentOptions.registryDir`
|
|
313
|
+
> / `projects.json` 跨项目注册表整链,随形态定案一并删除(PR-SWITCH-1)。**勿按旧文档找回**——
|
|
314
|
+
> 内核既不切换项目,也不维护跨项目名单。
|
|
282
315
|
|
|
283
316
|
### 9. 关闭
|
|
284
317
|
|
|
@@ -323,7 +356,7 @@ const agent = new Agent({
|
|
|
323
356
|
**会话持久化特性:**
|
|
324
357
|
- 日期使用 `todayDate()` 动态获取,确保跨日后消息写入当天目录
|
|
325
358
|
- `appendUser()` / `appendAssistant()` 自动调用 `appendMessage()`
|
|
326
|
-
- `loadSessionMessages()
|
|
359
|
+
- `loadSessionMessages()`(内部方法,非公开 API)自动调用 `loadMessages()`
|
|
327
360
|
- `SessionMessage.role` 支持 `'user' | 'assistant' | 'system'`,宿主直接调用 `appendMessage()` 时可传入任意角色
|
|
328
361
|
|
|
329
362
|
---
|
|
@@ -454,7 +487,8 @@ app.put('/api/sessions/:id/archive', (req, res) => {
|
|
|
454
487
|
| 后台命令 | 内置工具 `run_command`(`background: true`)/ `agent.listBackgroundTasks()` / `agent.killBackgroundTask()` | §8.1 · §8.7 |
|
|
455
488
|
| 会话 | `agent.forkSession()` / `agent.sessionManager.*` | §六 |
|
|
456
489
|
|
|
457
|
-
>
|
|
490
|
+
> 记忆**写入期**治理由 `supersede`(写时取代)承担,无需宿主调用;写入入口统一是 `agent.memory.writeXxx()`。
|
|
491
|
+
> 订阅式事后治理(去重 / 冲突检测 / 关联推荐)已于 5.0.0 整链退役,`agent.governance` 不再存在——见参考手册 §四 注记。
|
|
458
492
|
|
|
459
493
|
---
|
|
460
494
|
|
|
@@ -464,33 +498,39 @@ app.put('/api/sessions/:id/archive', (req, res) => {
|
|
|
464
498
|
|
|
465
499
|
| 函数/类型 | 用途 |
|
|
466
500
|
|-----------|------|
|
|
467
|
-
| `createLlmProvider(config)` | 从完整 Config(`llm.providers` + `active`)创建激活 Provider(配合 `loadConfig`) |
|
|
468
501
|
| `createProviderFromConfig(name, config)` | 从命名配置创建单个 Provider 实例(扁平参数) |
|
|
469
502
|
| `loadConfig(path?)` | 加载 `.memora/config.json` 项目级配置文件(或传入显式 configPath) |
|
|
470
|
-
| `
|
|
503
|
+
| `createNodeSqliteStorage(dbPath[, options])` | 内核提供的 SQLite 落盘实现**工厂**(基于 `node:*` 内建模块,零第三方依赖)。不可用时抛专属错误(错误码 `NOT_AVAILABLE`)——「当前环境能否用 SQLite」的**唯一判据**(勿自行解析版本号)。第二参数 `{ readOnly: true }` 返回只读视图 |
|
|
504
|
+
| `ReadOnlyMemoryStorage` | 只读存储视图**类型**(`IMemoryStorage` 的读方法子集,结构上无写方法)。供只读宿主(如 MCP)复用同一实现,避免自写第二份 SQLite 语义 |
|
|
471
505
|
| `setLogger(logger)` | 替换全局日志实现 |
|
|
472
506
|
| `logger` | 全局日志实例 |
|
|
473
|
-
| `segmentText(text)` | 中文分词工具 |
|
|
474
507
|
| `parseFrontmatter(text)` | 解析 Markdown frontmatter |
|
|
475
|
-
| `serializeFrontmatter(fm, body)` | 序列化 frontmatter + body 为 Markdown |
|
|
476
|
-
| `safeSetTimeout(fn, ms)` | 安全定时器(可跟踪清理) |
|
|
477
|
-
| `safeSetInterval(fn, ms)` | 安全间隔器(可跟踪清理) |
|
|
478
|
-
| `clearSafeTimeout(id)` | 清除安全定时器 |
|
|
479
|
-
| `clearSafeInterval(id)` | 清除安全间隔器 |
|
|
480
508
|
| `extractKeywords(text)` | 提取关键词 |
|
|
481
509
|
| `SOURCE_LABELS` | source 标签常量(PERSONA / RULE / SKILL / WORK_PROJECTION / ROUND_SUMMARY / UNKNOWN) |
|
|
482
|
-
| `escapeLike(query)` | 转义 SQLite LIKE 通配符(`%` / `_` → `\%` / `\_`)。**SQL 必须写成 `LIKE ? ESCAPE '\'`**——不写 ESCAPE 子句则反斜杠被视为普通字符,转义后的模式匹配不到任何字面值,查询**静默返回空** |
|
|
483
|
-
| `escapeLikeSnippet(text, maxLen?)` | 截断至 maxLen(默认 50)后转义 LIKE 通配符——搜索输入防超长解析 + 防通配符被当模式符(SQL 后端检索的配套动作,同样须配 `ESCAPE '\'`) |
|
|
484
510
|
| `validateSource(source)` | 校验 source 标签是否为已知标签(返回 warning,不阻止写入) |
|
|
485
511
|
| `MemoraError` | 统一错误类型(结构化错误码 + 上下文) |
|
|
486
|
-
| `
|
|
487
|
-
| `NOOP_TRACER` | ITracer 的空实现(静默丢弃所有 span,零开销) |
|
|
512
|
+
| (无 Noop 导出) | 不注入 `tracer` 即自动降级为内核内部 Noop 实现(静默丢弃所有 span,零开销) |
|
|
488
513
|
| `TRACE_SPANS` | AgentLoop 预定义 Span 名称常量(RECALL / LLM_CALL / TOOL_EXEC / RESPONSE) |
|
|
489
514
|
| `ToolErrorCode` | 工具错误码枚举(10 种,含 PATH_NOT_ALLOWED / FILE_NOT_FOUND 等) |
|
|
490
515
|
| `isRetryableErrorCode(code)` | 判断错误码是否可重试(5 种 retryable) |
|
|
491
516
|
| `TypedEventEmitter` | 类型安全的事件发射器(Agent 继承此类) |
|
|
492
517
|
|
|
493
|
-
|
|
518
|
+
**注意**:基于 **better-sqlite3** 的 `SqliteStorage` 仍已移出到宿主项目(native 编译模块不入内核),宿主可继续自行实现 `IMemoryStorage`。**但自 5.0.0 起,内核另提供可选的 SQLite 实现**:`createNodeSqliteStorage(dbPath)`——基于 `node:*` 内建模块(不引入第三方/native 依赖),宿主**无需自写**即可接入 SQLite;也可选择不接(继续 JSON / 内存实现)。用法:
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
import { createNodeSqliteStorage, type IMemoryStorage } from '@zooique/memora';
|
|
522
|
+
|
|
523
|
+
// 读写:文件不存在则建库(路径由宿主决定,内核不拼目录)
|
|
524
|
+
let storage: IMemoryStorage;
|
|
525
|
+
try {
|
|
526
|
+
storage = createNodeSqliteStorage(join(dataDir, 'memory.db'));
|
|
527
|
+
} catch (err) {
|
|
528
|
+
// 唯一判据:工厂抛出的专属错误(errorCode = ToolErrorCode.NOT_AVAILABLE)→ 降级到 JSON/内存实现
|
|
529
|
+
storage = new MyJsonStorage(join(dataDir, 'memories.json'));
|
|
530
|
+
}
|
|
531
|
+
// 只读宿主:返回对象结构上不含写方法
|
|
532
|
+
// const readOnly = createNodeSqliteStorage(join(dataDir, 'memory.db'), { readOnly: true });
|
|
533
|
+
```
|
|
494
534
|
|
|
495
535
|
`IMemoryStorage` 接口要求实现 `count()` 和 `countBySource(source)` 方法,用于高效统计记忆数量(避免全量加载数据)。详见 [API 参考手册](./memora-api-reference.md)。
|
|
496
536
|
|
|
@@ -555,7 +595,7 @@ const agent = new Agent({
|
|
|
555
595
|
});
|
|
556
596
|
```
|
|
557
597
|
|
|
558
|
-
>
|
|
598
|
+
> **不注入时**:内核自动降级为内部 Noop 实现(静默丢弃所有 span,零运行时开销)——无需引用任何实现类。
|
|
559
599
|
|
|
560
600
|
---
|
|
561
601
|
|
|
@@ -600,20 +640,20 @@ for (const chapter of chapters) {
|
|
|
600
640
|
|
|
601
641
|
## 十、关键约束
|
|
602
642
|
|
|
603
|
-
**前提:存储方案由宿主自选,内核只定契约。** 内核只定义 `IMemoryStorage` / `ISessionStore` 接口,**不规定后端**——SQLite
|
|
643
|
+
**前提:存储方案由宿主自选,内核只定契约。** 内核只定义 `IMemoryStorage` / `ISessionStore` 接口,**不规定后端**——SQLite、JSON 文件、内存实现一视同仁,任何后端都不得被写进内核逻辑(5.0.0 起内核**提供**可选的 SQLite 实现 `createNodeSqliteStorage`,但那是「多一个可选实现」,**不是**把后端写进逻辑——选哪个仍归宿主,`Agent` 构造契约不变)。接口方法为**同步语义**(对齐 better-sqlite3),异步后端需另行扩展接口;JSON 落地实现在同步路径上做全量重写,记忆量增长时由宿主自行评估更优后端(阈值与权衡见 `storageInterface.ts` 头注释)。第一宿主 memora-vscode 当前用 JSON 文件,换成 SQLite **不需要改内核**。
|
|
604
644
|
|
|
605
645
|
1. **`provider` 是必填项** — Agent 无法独立运行
|
|
606
646
|
2. **configDir** 指向 Agent 级配置目录,所有项目共享
|
|
607
647
|
3. **项目级 `.memora/`** 放项目级配置(`rules/`、`skills/`)与内核写入的项目锁 `.lock`;`dataDir` 若指向此处(第一宿主 memora-vscode 即如此),记忆库与会话也落在这里
|
|
608
648
|
4. **角色包只能手动切换**(`agent.switchRolePack(name)` / `agent.rolePack.activate(name)`)——无输入自动匹配、无粘性锁存、无互斥触发;已激活的角色包在当前会话内保持固定(v0.13 已移除自动匹配全链)
|
|
609
|
-
5. **对话历史随 Agent 持久化** — `sessionStore`
|
|
649
|
+
5. **对话历史随 Agent 持久化** — `sessionStore` 是实例级注入的,**切会话不换存储**;未注入则仅内存保存
|
|
610
650
|
6. **Manager 访问器在 `init()` 前返回 `null`** — 所有 `agent.rolePack.xxx()` / `agent.memory.xxx()` 等调用必须在 `init()` 之后
|
|
611
651
|
7. **作品原始内容不进记忆库**,Agent 通过工具按需读取(大文本走 `read_file` 分段,提炼后只留情报,不全量入库 / 入上下文)
|
|
612
652
|
8. **配置文件是真理源**,`<configDir>/role-packs/` 下的角色包由 RolePackManager 启动时扫描加载
|
|
613
|
-
9. **一个 Agent = 一份记忆库** — `storage` 与 `dataDir` 都是 **Agent
|
|
614
|
-
10.
|
|
653
|
+
9. **一个 Agent = 一份记忆库** — `storage` 与 `dataDir` 都是 **Agent 实例级**的:切会话复用同一实例,不按会话 / 子项目分裂。**要按项目彼此隔离,就各自 `new Agent`**——隔离粒度归宿主决定,内核不规定(见 [§8](#8-多项目一个项目一个-agent形态定案))
|
|
654
|
+
10. **切会话不重建、不关闭存储** — 会话切换只换身份(`sessionId`),复用已注入的实例;只在 `close()` 时关闭(`ProjectManager` 在 Agent 生命周期内缓存)
|
|
615
655
|
11. **禁止把配置放进记忆库** — 配置(角色包 / persona / rules / skills)的真理源是文件(`configDir` / 角色包),设定记忆归角色包内容层、不进记忆库(ADR-025 / `memory-role-pack-boundary`)
|
|
616
|
-
12.
|
|
656
|
+
12. **组件重装配** 由内核在 `init()` / `reloadConfig()` 内部完成,无公开重建入口,宿主无需也无法手动触发
|
|
617
657
|
13. **Tracer 未注入时**自动降级为 NoopTracer,零运行时开销
|
|
618
658
|
|
|
619
659
|
---
|
|
@@ -694,15 +734,15 @@ chatProvider.setAgentFactory((projectPath) =>
|
|
|
694
734
|
|
|
695
735
|
> 本约束原仅存于宿主实现注释(`extension.ts` 的"杜绝双实例覆盖写";仓库内参考实现,**非随包产物**),现提升为宿主接入契约基线,避免新宿主对接踩坑。原子写实锤已具备(`atomicWriteFileSync`),单例 + 原子写已对齐主流硬化做法(grida / Chatbox 同款 tmp+rename);唯一真实残留为跨进程锁,已列入检查清单第 4 项。
|
|
696
736
|
|
|
697
|
-
## 十.7、策略键消费矩阵(
|
|
737
|
+
## 十.7、策略键消费矩阵(17 键 SSOT 落点)📌 参考
|
|
698
738
|
|
|
699
|
-
> 逐键矩阵(
|
|
739
|
+
> 逐键矩阵(17 键 × 内核消费位置 × UI 侧消费)为仓库内开发文档(SSOT:`src/role-pack/strategyKeys.ts`),**不随包发布**;宿主对接所需的键语义见 [role-pack-authoring-guide.md](./architecture/role-pack-authoring-guide.md) §三。此处只给新宿主对接必知的结论与边界。
|
|
700
740
|
|
|
701
|
-
- **
|
|
741
|
+
- **17 键全部被内核真实消费、零 `[草案]`**(prepare 1 / act 7 / reflect 3 / global 6)。解析层 `rolePackManager` + `strategyResolver` 测试守护,消费层跨 `contextPreparer` / `loop` / `agent` / `managers/llmCaller` / `toolRunner` / `orchestrator` / `prepare` 多文件覆盖。
|
|
702
742
|
- **三类流向,单一收口无镜像**:
|
|
703
|
-
1. act 5 键(`toolMode`/`toolStepLimit`/`providerRouting`/`multiStepReasoning`/`toolReadonly`)+ `selfReview` + global
|
|
743
|
+
1. act 5 键(`toolMode`/`toolStepLimit`/`providerRouting`/`multiStepReasoning`/`toolReadonly`)+ `selfReview` + **global 键中经聚合的 5 键**(`errorHandling`/`contextLimit`/`stepBudget`/`askLimit`/`webSearchLimit`)——此「5 键」是「**经 `resolveL2Strategy()` 聚合这一层**」的子集,global 第 6 键 `askOn` 不走聚合(归第 3 类);上列各键统一经 `resolveL2Strategy()` 聚合注入 `L2RuntimeStrategy`,loop 经 `this.strategy.<field>` 读取;`act.temperature`/`outputLimit` 由 `agent.ts` 直映射 `ChatOptions`(不经聚合);
|
|
704
744
|
2. prepare 键经 `resolveActiveStrategy()` 单一真理源流入 `contextPreparer` / `roundSummaryGenerator`;
|
|
705
|
-
3. persona 指令类(`userFollowup`/`askOn`/`askLimit`)由 `assembleRolePack()`
|
|
745
|
+
3. persona 指令类(`userFollowup`/`askOn`/`askLimit`)由 `assembleRolePack()` 单收口注入——**`askLimit` 是双面键**:既在第 1 类经聚合进 `L2RuntimeStrategy` 供 loop 硬护栏消费,又在此处随 persona prompt 注入,两处各占一面、**非重复计数**。
|
|
706
746
|
- **⚠️ 边界纠正:`toolReadonly` 内核已执行,非「无宿主执行方」**。`toolRunner.ts` 只剩两层闸:闸①(只读闸 `toolReadonly==='readonly'`)**由内核执行**;闸③(宿主 `preExecutionCheck` 注入点)当前 VS Code 宿主恒放行(`assemble.ts` 恒返回 `() => ({ skip: false })`)只是单用户信任模型下的显式让行(关联 十.5 / 设计纪律 D5),未来多用户/服务端须替换真实审批。原闸② `toolApproval` 审批链已随 3.0.0 删键(2026-09-11,故代码注释 ①/③ 编号保留):单用户本地无真实审批场景,原"通知宿主 + UI 需审批 chip"是展示性假承诺——整键删除,新宿主切勿再期待 `onToolApproval` 回调或 `toolApproval==='confirm'` 语义,审批须自行在 `preExecutionCheck` 实现。
|
|
707
747
|
- **UI 侧 6 键有呈现**:宿主角色列表视图渲染策略 chip 5 键(`toolReadonly` / `summaryFocus` / `outputLimit` / `temperature` / `multiStepReasoning`)+ `toolMode` 经对话视图 capability badge 渲染('纯 LLM' / '全部工具')。能力名映射与策略键无关,**勿混淆**。(上述 UI 实现均为仓库内宿主参考实现,**非随包产物**。)
|
|
708
748
|
|
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
# 角色包开放键使用指南(发布包版)
|
|
2
|
-
|
|
3
|
-
> **面向对象**:安装 `@zooique/memora` 后,编写 / 理解角色包(role pack)的开发者——既包括**宿主接入者**(要把角色包能力接进自己的产品),也包括**角色包作者**(要填写 `manifest.json`)。
|
|
4
|
-
> **定位**:本指南回答「manifest.json 里的开放键填什么、**被谁消费**、有什么上限」。它是 memora 发布包内的角色包使用入口。
|
|
5
|
-
> **相关文档**:
|
|
6
|
-
> - 中立规范(跨所有 Agent 实现的契约,随包发布):[role-pack-spec.md](./architecture/role-pack-spec.md)
|
|
7
|
-
> - 详细填写手册(含全部区间 / 错误修正 / 键的落实状态,随包发布):[role-pack-authoring-guide.md](./architecture/role-pack-authoring-guide.md)
|
|
8
|
-
> - 示例角色包(结构参考,随包发布、不参与宿主运行时装载):[role-packs/](../role-packs/README.md)
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## 一、角色包是什么
|
|
13
|
-
|
|
14
|
-
角色包 = 一个文件夹 + `manifest.json`(唯一核心控制文件)+ 内容文件:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
角色包名/
|
|
18
|
-
├── manifest.json # ★ 元数据 + strategy 策略 + capabilities + skills 白名单
|
|
19
|
-
├── persona.md # 角色身份设定(约定文件名,可缺省)
|
|
20
|
-
├── rules.md # 确定性规则(约定文件名,逐行解析)
|
|
21
|
-
└── skills/ # 技能目录(动态扫描,新增技能只写文件即可)
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
把角色包文件夹放进 `configDir/role-packs/` 即可装载。`manifest.json` 里的字段统称**开放键**——它们是内核、宿主、UI 三方协作的契约,本文档回答「谁在用它们」。
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 二、三层消费方逻辑(先理解"键被谁用")
|
|
29
|
-
|
|
30
|
-
所有开放键的消费方分三层,**不是所有键都是给宿主接入的**:
|
|
31
|
-
|
|
32
|
-
| 层 | 消费方 | 键 | 用途 |
|
|
33
|
-
|----|--------|-----|------|
|
|
34
|
-
| **① 内核直接消费** | memora 内核 | `skills` / `strategy` | 技能扫描、行为策略 |
|
|
35
|
-
| **② 中立接口(宿主接入点)** | 宿主 / 其他实现 | `capabilities` / `handoffPrompt` | 能力映射、接手话术 |
|
|
36
|
-
| **③ 元数据(UI 展示)** | 宿主 UI | `name` / `displayName` / `description` / `author` | 标识与展示 |
|
|
37
|
-
|
|
38
|
-
### 2.1 ① 内核直接消费层(memora 实现细节)
|
|
39
|
-
|
|
40
|
-
这些键由 memora 内核自己跑逻辑,**宿主不需要处理**:
|
|
41
|
-
|
|
42
|
-
- `skills`:内嵌技能白名单(目录动态扫描,声明项仅作白名单过滤;不声明则全量扫描 `skills/`)。
|
|
43
|
-
- `strategy`:L2 行为策略(`prepare` / `act` / `reflect` / `global` 四组),控制工具暴露、摘要视角、自审查、预算与提问等行为偏好。
|
|
44
|
-
|
|
45
|
-
> 这些键的**上限由内核统一守门**(见 §2.4),因为解析入口在内核。
|
|
46
|
-
|
|
47
|
-
### 2.2 ② 中立接口层(宿主接入点)
|
|
48
|
-
|
|
49
|
-
这一层是**为宿主 / 跨实现接入预留的中立契约**——角色包不绑具体实现,由各实现自己消费:
|
|
50
|
-
|
|
51
|
-
- **`capabilities`(能力声明)**:以**中立能力命名空间**声明(`域:动作`,如 `file:write` / `web:search`),不绑具体工具。**各实现(memora 是 reference implementation)自行映射到自有工具**:
|
|
52
|
-
- **特权声明模型(2026-09-08 定,2026-09-16 扩)**:memora 侧映射表在 `src/role-pack/capabilityMap.ts`(SSOT)——仅 `web:search` / `web:fetch` / `code:execute` 映射为**特权工具白名单**;`file:*` / `memory:recall` / **`task:plan`(对应任务表)** 属**默认常驻工具**(`toolExecutor.DEFAULT_EXPOSED_TOOLS`),声明与否都不影响可见性、不再映射。任务表系内核多步任务必要基建(2026-09-16 用户拍板),非角色包可选的领域深度能力;
|
|
53
|
-
- **宿主可以有自己的映射表**:例如 `code:execute` 需宿主注入 `ICodeExecutionProvider` 才真正暴露;
|
|
54
|
-
- 未知能力(不在映射表)跳过,不阻塞装载。
|
|
55
|
-
- 角色包声明 `capabilities` 后,工具暴露面 = 常驻豁免集 + 能力白名单内的特权工具(换角色 → 特权工具集切换)。
|
|
56
|
-
- **`handoffPrompt`(接手话术)**:该角色包**被宿主带入对话(激活 + 聚焦)时**预填输入框的特色衔接话术——作者为「这个角色接手任务时怎么说」定制的提示词,缺省由宿主回退通用话术。**宿主消费**(如 memora-vscode 在 `roles_handoff` 处理中读取 `listMeta().handoffPrompt` 预填);内核仅透传 + 校验(非字符串 warning 不阻塞装载)。
|
|
57
|
-
|
|
58
|
-
### 2.3 ③ 元数据层(UI 展示)
|
|
59
|
-
|
|
60
|
-
- `name`(唯一标识,缺失用文件夹名兜底)、`displayName`(UI 展示名,缺省回退 `name`)、`description`、`author`。
|
|
61
|
-
- 内核仅作标识/校验;真正消费是宿主的角色包清单 / UI 展示。
|
|
62
|
-
|
|
63
|
-
### 2.4 为什么上限由内核统一守门
|
|
64
|
-
|
|
65
|
-
**无论最终消费方是谁,`manifest.json` 的解析入口都在 memora 内核**(`validator.ts` 校验 + `rolePackManager.ts` 装载)。内核作为装载器在入口守门——对所有开放字段统一限长:
|
|
66
|
-
|
|
67
|
-
- 对**内核字段**:防资源失控(匹配词列表膨胀拖慢匹配、巨型内容占内存/上下文);
|
|
68
|
-
- 对**宿主字段**:防巨型数据透传给宿主(宿主收到的是已被内核约束过的安全数据)。
|
|
69
|
-
|
|
70
|
-
这正是「零依赖内核」哲学:**内核做守门,宿主做消费**。所以上表中所有字段的上限,全部由内核入口统一控制(见 §三),不区分消费方。
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## 三、开放键速查表(消费方 + 上限)
|
|
75
|
-
|
|
76
|
-
> 详细区间 / 错误修正 / 键的落实状态见 [role-pack-authoring-guide.md](./architecture/role-pack-authoring-guide.md)(仓库内文档)。下表是发布包内的精简速查。
|
|
77
|
-
> **上限 SSOT**:`src/role-pack/validator.ts`(非策略键)与 `src/role-pack/strategyKeys.ts`(策略键数值区间)。
|
|
78
|
-
|
|
79
|
-
### 3.1 元数据层
|
|
80
|
-
|
|
81
|
-
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
82
|
-
|----|------|--------|------|------|
|
|
83
|
-
| `name` | string | ③ UI / 内核标识 | ≤200 字符 | 唯一标识(缺失用文件夹名兜底) |
|
|
84
|
-
| `formatVersion` | string | ① 内核校验(可选,缺省 `1.0.0`) | semver(x.y.z) | 格式版本,绑定固定 schema URL,发布后不变;建议声明 |
|
|
85
|
-
| `displayName` | string | ③ UI | ≤200 字符 | UI 展示名,缺省回退 `name` |
|
|
86
|
-
| `description` | string | ③ UI | ≤200 字符 | 角色包描述 |
|
|
87
|
-
| `author` | string | ③ UI | ≤200 字符 | 作者/来源 |
|
|
88
|
-
| `version` | string | ③ 分发 | semver(x.y.z) | 角色包自身版本(可选) |
|
|
89
|
-
|
|
90
|
-
### 3.2 中立接口层(宿主接入)
|
|
91
|
-
|
|
92
|
-
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
93
|
-
|----|------|--------|------|------|
|
|
94
|
-
| `capabilities` | 对象数组 | ② 宿主 / 各实现映射 | ≤50 项 | `{ capability: "域:动作", description? }`;映射到各实现自有工具 |
|
|
95
|
-
| `handoffPrompt` | string | ② 宿主预填 | ≤2000 字符 | 被带入对话时预填的接手话术 |
|
|
96
|
-
|
|
97
|
-
### 3.3 内核消费层
|
|
98
|
-
|
|
99
|
-
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
100
|
-
|----|------|--------|------|------|
|
|
101
|
-
| `skills` | 对象数组 | ① 内核扫描 | ≤50 项 | 技能白名单(`{ file, name?, description? }`) |
|
|
102
|
-
| `strategy` | 嵌套对象 | ① 内核行为 | 各数值键有上下限(见 authoring-guide §四) | L2 行为策略(prepare/act/reflect/global) |
|
|
103
|
-
|
|
104
|
-
### 3.4 合规 / 分档层
|
|
105
|
-
|
|
106
|
-
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
107
|
-
|----|------|--------|------|------|
|
|
108
|
-
| `interactionType` | string 枚举 | ① 内核合规 | `tool_assistant` / `companion`(缺省 `tool_assistant`) | 交互类型:工具型(豁免区间)vs 拟人化陪伴(完整合规校验) |
|
|
109
|
-
| `aiIdentityDisclosure` | boolean | ① 内核合规 | `true`(缺省) | 是否向用户明确标注 AI 身份(companion 必须显式 true) |
|
|
110
|
-
| `minorProtection` | string 枚举 | ① 内核合规 | `required`(缺省) | 未成年人保护模式(当前仅支持 required) |
|
|
111
|
-
|
|
112
|
-
> **越界行为统一**:开发期 `validator` 校验报 error(拒绝装载提示);运行时按上限截断 / 回退默认(宽容容错)。
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## 四、内容文件约定(零声明)
|
|
117
|
-
|
|
118
|
-
`persona.md` / `rules.md` / `skills/` 全部**约定俗成**——manifest **不注册内容路径**(防路径写错静默丢内容):
|
|
119
|
-
|
|
120
|
-
| 文件 | 约定 | 说明 |
|
|
121
|
-
|------|------|------|
|
|
122
|
-
| `persona.md` | 约定名 | 角色身份设定(frontmatter 可声明 `traits.*` 数值 trait,clamp 0-1) |
|
|
123
|
-
| `rules.md` | 约定名 | 确定性规则(逐行解析 `- ` / `* ` / `n. ` 列表) |
|
|
124
|
-
| `skills/` | 目录动态扫描 | 新增技能只写文件即可,frontmatter 声明 `name` / `description`(渐进披露 L1) |
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
## 五、最小示例
|
|
129
|
-
|
|
130
|
-
```json
|
|
131
|
-
{
|
|
132
|
-
"name": "plain-designer",
|
|
133
|
-
"displayName": "白话方案设计师",
|
|
134
|
-
"description": "白话方案设计角色包",
|
|
135
|
-
"formatVersion": "1.0.0",
|
|
136
|
-
"interactionType": "tool_assistant",
|
|
137
|
-
"strategy": {
|
|
138
|
-
"prepare": { "summaryFocus": "以方案设计视角提炼要点" },
|
|
139
|
-
"act": { "toolMode": "allow", "temperature": 0.3 },
|
|
140
|
-
"global": { "contextLimit": 0 }
|
|
141
|
-
},
|
|
142
|
-
"capabilities": [
|
|
143
|
-
{ "capability": "file:write", "description": "写文件" },
|
|
144
|
-
{ "capability": "web:search", "description": "搜索" }
|
|
145
|
-
],
|
|
146
|
-
"handoffPrompt": "你好,我是白话方案设计师,请告诉我你想解决什么模糊想法或痛点。"
|
|
147
|
-
}
|
|
148
|
-
```
|
|
1
|
+
# 角色包开放键使用指南(发布包版)
|
|
2
|
+
|
|
3
|
+
> **面向对象**:安装 `@zooique/memora` 后,编写 / 理解角色包(role pack)的开发者——既包括**宿主接入者**(要把角色包能力接进自己的产品),也包括**角色包作者**(要填写 `manifest.json`)。
|
|
4
|
+
> **定位**:本指南回答「manifest.json 里的开放键填什么、**被谁消费**、有什么上限」。它是 memora 发布包内的角色包使用入口。
|
|
5
|
+
> **相关文档**:
|
|
6
|
+
> - 中立规范(跨所有 Agent 实现的契约,随包发布):[role-pack-spec.md](./architecture/role-pack-spec.md)
|
|
7
|
+
> - 详细填写手册(含全部区间 / 错误修正 / 键的落实状态,随包发布):[role-pack-authoring-guide.md](./architecture/role-pack-authoring-guide.md)
|
|
8
|
+
> - 示例角色包(结构参考,随包发布、不参与宿主运行时装载):[role-packs/](../role-packs/README.md)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 一、角色包是什么
|
|
13
|
+
|
|
14
|
+
角色包 = 一个文件夹 + `manifest.json`(唯一核心控制文件)+ 内容文件:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
角色包名/
|
|
18
|
+
├── manifest.json # ★ 元数据 + strategy 策略 + capabilities + skills 白名单
|
|
19
|
+
├── persona.md # 角色身份设定(约定文件名,可缺省)
|
|
20
|
+
├── rules.md # 确定性规则(约定文件名,逐行解析)
|
|
21
|
+
└── skills/ # 技能目录(动态扫描,新增技能只写文件即可)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
把角色包文件夹放进 `configDir/role-packs/` 即可装载。`manifest.json` 里的字段统称**开放键**——它们是内核、宿主、UI 三方协作的契约,本文档回答「谁在用它们」。
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 二、三层消费方逻辑(先理解"键被谁用")
|
|
29
|
+
|
|
30
|
+
所有开放键的消费方分三层,**不是所有键都是给宿主接入的**:
|
|
31
|
+
|
|
32
|
+
| 层 | 消费方 | 键 | 用途 |
|
|
33
|
+
|----|--------|-----|------|
|
|
34
|
+
| **① 内核直接消费** | memora 内核 | `skills` / `strategy` | 技能扫描、行为策略 |
|
|
35
|
+
| **② 中立接口(宿主接入点)** | 宿主 / 其他实现 | `capabilities` / `handoffPrompt` | 能力映射、接手话术 |
|
|
36
|
+
| **③ 元数据(UI 展示)** | 宿主 UI | `name` / `displayName` / `description` / `author` | 标识与展示 |
|
|
37
|
+
|
|
38
|
+
### 2.1 ① 内核直接消费层(memora 实现细节)
|
|
39
|
+
|
|
40
|
+
这些键由 memora 内核自己跑逻辑,**宿主不需要处理**:
|
|
41
|
+
|
|
42
|
+
- `skills`:内嵌技能白名单(目录动态扫描,声明项仅作白名单过滤;不声明则全量扫描 `skills/`)。
|
|
43
|
+
- `strategy`:L2 行为策略(`prepare` / `act` / `reflect` / `global` 四组),控制工具暴露、摘要视角、自审查、预算与提问等行为偏好。
|
|
44
|
+
|
|
45
|
+
> 这些键的**上限由内核统一守门**(见 §2.4),因为解析入口在内核。
|
|
46
|
+
|
|
47
|
+
### 2.2 ② 中立接口层(宿主接入点)
|
|
48
|
+
|
|
49
|
+
这一层是**为宿主 / 跨实现接入预留的中立契约**——角色包不绑具体实现,由各实现自己消费:
|
|
50
|
+
|
|
51
|
+
- **`capabilities`(能力声明)**:以**中立能力命名空间**声明(`域:动作`,如 `file:write` / `web:search`),不绑具体工具。**各实现(memora 是 reference implementation)自行映射到自有工具**:
|
|
52
|
+
- **特权声明模型(2026-09-08 定,2026-09-16 扩)**:memora 侧映射表在 `src/role-pack/capabilityMap.ts`(SSOT)——仅 `web:search` / `web:fetch` / `code:execute` 映射为**特权工具白名单**;`file:*` / `memory:recall` / **`task:plan`(对应任务表)** 属**默认常驻工具**(`toolExecutor.DEFAULT_EXPOSED_TOOLS`),声明与否都不影响可见性、不再映射。任务表系内核多步任务必要基建(2026-09-16 用户拍板),非角色包可选的领域深度能力;
|
|
53
|
+
- **宿主可以有自己的映射表**:例如 `code:execute` 需宿主注入 `ICodeExecutionProvider` 才真正暴露;
|
|
54
|
+
- 未知能力(不在映射表)跳过,不阻塞装载。
|
|
55
|
+
- 角色包声明 `capabilities` 后,工具暴露面 = 常驻豁免集 + 能力白名单内的特权工具(换角色 → 特权工具集切换)。
|
|
56
|
+
- **`handoffPrompt`(接手话术)**:该角色包**被宿主带入对话(激活 + 聚焦)时**预填输入框的特色衔接话术——作者为「这个角色接手任务时怎么说」定制的提示词,缺省由宿主回退通用话术。**宿主消费**(如 memora-vscode 在 `roles_handoff` 处理中读取 `listMeta().handoffPrompt` 预填);内核仅透传 + 校验(非字符串 warning 不阻塞装载)。
|
|
57
|
+
|
|
58
|
+
### 2.3 ③ 元数据层(UI 展示)
|
|
59
|
+
|
|
60
|
+
- `name`(唯一标识,缺失用文件夹名兜底)、`displayName`(UI 展示名,缺省回退 `name`)、`description`、`author`。
|
|
61
|
+
- 内核仅作标识/校验;真正消费是宿主的角色包清单 / UI 展示。
|
|
62
|
+
|
|
63
|
+
### 2.4 为什么上限由内核统一守门
|
|
64
|
+
|
|
65
|
+
**无论最终消费方是谁,`manifest.json` 的解析入口都在 memora 内核**(`validator.ts` 校验 + `rolePackManager.ts` 装载)。内核作为装载器在入口守门——对所有开放字段统一限长:
|
|
66
|
+
|
|
67
|
+
- 对**内核字段**:防资源失控(匹配词列表膨胀拖慢匹配、巨型内容占内存/上下文);
|
|
68
|
+
- 对**宿主字段**:防巨型数据透传给宿主(宿主收到的是已被内核约束过的安全数据)。
|
|
69
|
+
|
|
70
|
+
这正是「零依赖内核」哲学:**内核做守门,宿主做消费**。所以上表中所有字段的上限,全部由内核入口统一控制(见 §三),不区分消费方。
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 三、开放键速查表(消费方 + 上限)
|
|
75
|
+
|
|
76
|
+
> 详细区间 / 错误修正 / 键的落实状态见 [role-pack-authoring-guide.md](./architecture/role-pack-authoring-guide.md)(仓库内文档)。下表是发布包内的精简速查。
|
|
77
|
+
> **上限 SSOT**:`src/role-pack/validator.ts`(非策略键)与 `src/role-pack/strategyKeys.ts`(策略键数值区间)。
|
|
78
|
+
|
|
79
|
+
### 3.1 元数据层
|
|
80
|
+
|
|
81
|
+
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
82
|
+
|----|------|--------|------|------|
|
|
83
|
+
| `name` | string | ③ UI / 内核标识 | ≤200 字符 | 唯一标识(缺失用文件夹名兜底) |
|
|
84
|
+
| `formatVersion` | string | ① 内核校验(可选,缺省 `1.0.0`) | semver(x.y.z) | 格式版本,绑定固定 schema URL,发布后不变;建议声明 |
|
|
85
|
+
| `displayName` | string | ③ UI | ≤200 字符 | UI 展示名,缺省回退 `name` |
|
|
86
|
+
| `description` | string | ③ UI | ≤200 字符 | 角色包描述 |
|
|
87
|
+
| `author` | string | ③ UI | ≤200 字符 | 作者/来源 |
|
|
88
|
+
| `version` | string | ③ 分发 | semver(x.y.z) | 角色包自身版本(可选) |
|
|
89
|
+
|
|
90
|
+
### 3.2 中立接口层(宿主接入)
|
|
91
|
+
|
|
92
|
+
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
93
|
+
|----|------|--------|------|------|
|
|
94
|
+
| `capabilities` | 对象数组 | ② 宿主 / 各实现映射 | ≤50 项 | `{ capability: "域:动作", description? }`;映射到各实现自有工具 |
|
|
95
|
+
| `handoffPrompt` | string | ② 宿主预填 | ≤2000 字符 | 被带入对话时预填的接手话术 |
|
|
96
|
+
|
|
97
|
+
### 3.3 内核消费层
|
|
98
|
+
|
|
99
|
+
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
100
|
+
|----|------|--------|------|------|
|
|
101
|
+
| `skills` | 对象数组 | ① 内核扫描 | ≤50 项 | 技能白名单(`{ file, name?, description? }`) |
|
|
102
|
+
| `strategy` | 嵌套对象 | ① 内核行为 | 各数值键有上下限(见 authoring-guide §四) | L2 行为策略(prepare/act/reflect/global) |
|
|
103
|
+
|
|
104
|
+
### 3.4 合规 / 分档层
|
|
105
|
+
|
|
106
|
+
| 键 | 类型 | 消费方 | 上限 | 说明 |
|
|
107
|
+
|----|------|--------|------|------|
|
|
108
|
+
| `interactionType` | string 枚举 | ① 内核合规 | `tool_assistant` / `companion`(缺省 `tool_assistant`) | 交互类型:工具型(豁免区间)vs 拟人化陪伴(完整合规校验) |
|
|
109
|
+
| `aiIdentityDisclosure` | boolean | ① 内核合规 | `true`(缺省) | 是否向用户明确标注 AI 身份(companion 必须显式 true) |
|
|
110
|
+
| `minorProtection` | string 枚举 | ① 内核合规 | `required`(缺省) | 未成年人保护模式(当前仅支持 required) |
|
|
111
|
+
|
|
112
|
+
> **越界行为统一**:开发期 `validator` 校验报 error(拒绝装载提示);运行时按上限截断 / 回退默认(宽容容错)。
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 四、内容文件约定(零声明)
|
|
117
|
+
|
|
118
|
+
`persona.md` / `rules.md` / `skills/` 全部**约定俗成**——manifest **不注册内容路径**(防路径写错静默丢内容):
|
|
119
|
+
|
|
120
|
+
| 文件 | 约定 | 说明 |
|
|
121
|
+
|------|------|------|
|
|
122
|
+
| `persona.md` | 约定名 | 角色身份设定(frontmatter 可声明 `traits.*` 数值 trait,clamp 0-1) |
|
|
123
|
+
| `rules.md` | 约定名 | 确定性规则(逐行解析 `- ` / `* ` / `n. ` 列表) |
|
|
124
|
+
| `skills/` | 目录动态扫描 | 新增技能只写文件即可,frontmatter 声明 `name` / `description`(渐进披露 L1) |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 五、最小示例
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"name": "plain-designer",
|
|
133
|
+
"displayName": "白话方案设计师",
|
|
134
|
+
"description": "白话方案设计角色包",
|
|
135
|
+
"formatVersion": "1.0.0",
|
|
136
|
+
"interactionType": "tool_assistant",
|
|
137
|
+
"strategy": {
|
|
138
|
+
"prepare": { "summaryFocus": "以方案设计视角提炼要点" },
|
|
139
|
+
"act": { "toolMode": "allow", "temperature": 0.3 },
|
|
140
|
+
"global": { "contextLimit": 0 }
|
|
141
|
+
},
|
|
142
|
+
"capabilities": [
|
|
143
|
+
{ "capability": "file:write", "description": "写文件" },
|
|
144
|
+
{ "capability": "web:search", "description": "搜索" }
|
|
145
|
+
],
|
|
146
|
+
"handoffPrompt": "你好,我是白话方案设计师,请告诉我你想解决什么模糊想法或痛点。"
|
|
147
|
+
}
|
|
148
|
+
```
|