@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
|
@@ -0,0 +1,1235 @@
|
|
|
1
|
+
# Memora 内核 API 参考手册(v2.0.3)
|
|
2
|
+
|
|
3
|
+
> **核心定位**:Memora 是一个**无法独立运行**的智能大脑内核——它只有接口,没有"形态"。CLI、WebUI、桌面精灵、小说生成器都是它的"宿主",宿主负责给它身体(UI)、血管(Provider)、神经网络(事件回路)。
|
|
4
|
+
>
|
|
5
|
+
> **本文件用途**:列出当前 Agent 对外暴露的**全部公开 API**。
|
|
6
|
+
>
|
|
7
|
+
> **版本**:v2.0.3(最后更新:2026-08-01,对应内核 v2.0.3)
|
|
8
|
+
>
|
|
9
|
+
> **1.0.0 之前:核心能力演进**(原内部里程碑 v3.0–v3.3,于 npm 0.2.0 前后完成):
|
|
10
|
+
> - **Agent God Object 拆分(原 v3.0)**:记忆、配置、Insight、工具、角色等方法从 Agent 面类迁移到专职 Manager,通过 `agent.<manager>.xxx()` 访问。详见各章节。
|
|
11
|
+
> - **可观测性与护栏(原 v3.1)**:新增 ITracer/ISpan 可观测性接口、ToolErrorCode 错误码、Guardrails 护栏、Reflection 反思机制。
|
|
12
|
+
> - **关系图谱与画像(原 v3.2)**:新增 ADR-014 记忆关系图谱(IMemoryRelationStore 侧车接口)、UserProfile 用户画像管理、WorkProjectionManager 作品投影、AutoConfigRefiner 自进化配置建议。
|
|
13
|
+
> - **npm 正式包与基础工具(原 v3.3)**:内核发布 v0.2.0(npm 正式包)。Phase 1-4 全部核心完成。新增 EmbeddingProvider、安全定时器(safeSetTimeout/safeSetInterval)、Frontmatter 工具(parseFrontmatter/serializeFrontmatter)、事件系统(TypedEventEmitter)、记忆关系常量(RELATION_TYPES/RELATION_WEIGHTS)、审计类型(AuditEvent 等)、评估框架(collectAgentChunks/evaluateResult)。
|
|
14
|
+
>
|
|
15
|
+
> **v1.0.0 变更**:1.0 正式发布。P0 阻塞修复全量收敛:DEFAULT_CONFIG 由 `config/loader.ts` 常量声明单一真理源(不再维护独立 schema)、IVectorStore 接口提取(JsonVectorStore 为内置实现)、AbortSignal 合并工具(mergeSignals)、Logger 懒初始化(移除模块顶层 pino 副作用,改为首次日志调用时 maybeUpgradeToPino 懒触发)、评估框架结构化信号(AgentChunk.guardrailBlocked 替代中文文案匹配)、文档全量对齐(包名 @zooique/memora、config.example.json 补全 providers/embedding 段)。
|
|
16
|
+
>
|
|
17
|
+
> **v2.0.0 变更**:版本号提升(维护性质,无破坏性 API 变更)。
|
|
18
|
+
>
|
|
19
|
+
> **v2.0.1 变更**:文档版本号对齐(v1.0.2 → v2.0.1)。无 API 破坏性变更,仅同步文档与版本戳。
|
|
20
|
+
>
|
|
21
|
+
> **v2.0.3 变更**:npm 发布配置修复与质量加固。新增 `publishConfig.access = "public"`、`exports` 增加 `default` 回退条件、`keywords` 扩充至 18 个。无 API 破坏性变更。
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 一、设计哲学
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
┌────────────────────────────────────────────────────────────┐
|
|
29
|
+
│ 宿主程序(CLI / 桌面精灵 / 小说生成器 / WebUI) │
|
|
30
|
+
│ ┌─────────────────┐ ┌──────────────────┐ │
|
|
31
|
+
│ │ LLM Provider 实例 │◄───│ API Key / baseUrl │ ← 宿主职责 │
|
|
32
|
+
│ └────────┬────────┘ └──────────────────┘ │
|
|
33
|
+
│ │ 注入 │
|
|
34
|
+
│ ▼ │
|
|
35
|
+
│ ┌──────────────────────────────────────────┐ │
|
|
36
|
+
│ │ Memora 内核(Agent) │ │
|
|
37
|
+
│ │ ┌──────────────────────────────────────┐│ │
|
|
38
|
+
│ │ │ Agent 面类(编排层) ││ │
|
|
39
|
+
│ │ │ - init/close · chat · switchProject ││ │
|
|
40
|
+
│ │ │ - .persona / .tools / .skills ││ │
|
|
41
|
+
│ │ │ - .config / .insight / .memory ││ │
|
|
42
|
+
│ │ └──────────┬───────────────────────────┘│ │
|
|
43
|
+
│ │ │ 委托 │ │
|
|
44
|
+
│ │ ┌──────────┼───────────────────────────┐│ │
|
|
45
|
+
│ │ │ PersonaManager / ToolExecutor ││ │
|
|
46
|
+
│ │ │ SkillManager / ConfigManager ││ │
|
|
47
|
+
│ │ │ InsightExtractor / MemoryInspector ││ │
|
|
48
|
+
│ │ └──────────────────────────────────────┘│ │
|
|
49
|
+
│ │ ⚠️ 不包含:UI / LLM 配置 / 用户配置模板 │ │
|
|
50
|
+
│ └──────────────────────────────────────────┘ │
|
|
51
|
+
└────────────────────────────────────────────────────────────┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**设计原则**:
|
|
55
|
+
- **零运行时依赖**(核心层零 npm 运行时依赖;`pino` 为可选 peer 依赖,通过动态 `import('pino')` 懒加载,加载失败时静默降级为内置 console logger;持久化由宿主通过 `IMemoryStorage` 接口注入)
|
|
56
|
+
- **零控制台输出**(核心库不调用 `console.*`)
|
|
57
|
+
- **零写用户文件**(配置文件是真理源,Agent 只读)
|
|
58
|
+
- **零 LLM 配置加载**(Agent 不知道 `apiKey`,宿主传入 `LlmProvider` 实例)
|
|
59
|
+
- **Manager 委托模式**:Agent 面类只做编排,领域操作委托给专职 Manager
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 二、构造与生命周期
|
|
64
|
+
|
|
65
|
+
### 2.1 构造选项 `AgentOptions`
|
|
66
|
+
|
|
67
|
+
| 字段 | 类型 | 必须 | 说明 |
|
|
68
|
+
|------|------|------|------|
|
|
69
|
+
| `projectPath` | `string` | ✅ | 项目路径(必须) |
|
|
70
|
+
| `provider` | `LlmProvider` | ✅ | 前台 LLM Provider(必须) |
|
|
71
|
+
| `backgroundProvider` | `LlmProvider` | ❌ | 后台 Provider(投影等后台操作) |
|
|
72
|
+
| `configDir` | `string` | ❌ | 配置目录(personas/rules/skills) |
|
|
73
|
+
| `dataDir` | `string` | ❌ | 记忆数据目录(默认 ~/.memora) |
|
|
74
|
+
| `registryDir` | `string` | ❌ | 项目注册表目录(默认与 dataDir 相同) |
|
|
75
|
+
| `maxContextTokens` | `number` | ❌ | 上下文窗口上限(默认 120000) |
|
|
76
|
+
| `persona` | `string` | ❌ | 默认角色名 |
|
|
77
|
+
| `permission` | `'owner' \| 'guest'` | ❌ | 安全权限(默认 'owner') |
|
|
78
|
+
| `allowedPaths` | `string[]` | ❌ | 路径白名单(默认 [] = 全部允许) |
|
|
79
|
+
| `confirmWrites` | `boolean` | ❌ | 写入确认(默认 false) |
|
|
80
|
+
| `storage` | `IMemoryStorage` | ❌ | 存储层注入(默认 InMemoryStorage) |
|
|
81
|
+
| `vectorStore` | `IVectorStore` | ❌ | 向量存储接口(提供时启用语义搜索召回;内置实现 JsonVectorStore) |
|
|
82
|
+
| `recallExcludeSources` | `string[]` | ❌ | 召回时排除的 source 标签(默认 `['persona', 'rule', 'skill']`,设定记忆不参与语义召回,双重防御) |
|
|
83
|
+
| `sessionStore` | `ISessionStore` | ❌ | 会话存储注入 |
|
|
84
|
+
| `relationStore` | `IMemoryRelationStore` | ❌ | 记忆关系存储(ADR-014 侧车,不传则跳过关系构建) |
|
|
85
|
+
| `tracer` | `ITracer` | ❌ | 可观测性 Tracer 注入(不传则使用 NoopTracer 静默丢弃所有 span) |
|
|
86
|
+
| `messages` | `UIMessages` | ❌ | 宿主可覆盖的 UI 消息文本(默认英文,宿主覆盖为中文等) |
|
|
87
|
+
| `enableContextSummary` | `boolean` | ❌ | 上下文超限时是否自动生成摘要(默认 true,开启后首次截断时增加 ~1-2s 延迟) |
|
|
88
|
+
| `archiveMode` | `ArchiveMode` | ❌ | 归档模式(ADR-015,默认 `'full'`)。`'full'`:profile+insight 自动归档;`'insights-only'`:仅 profile+insight 自动,内容需手动;`'manual'`:全部手动 |
|
|
89
|
+
|
|
90
|
+
> **Logger 注入方式**:v1.0 起 `AgentOptions` 不再含 `logger` 字段。日志通过全局 `setLogger(customLogger)` 注入(详见 §十八 类型导出),pino 升级为懒初始化(首次日志调用时触发,import 零副作用)。
|
|
91
|
+
|
|
92
|
+
### 2.2 生命周期方法
|
|
93
|
+
|
|
94
|
+
| 方法 | 用途 |
|
|
95
|
+
|------|------|
|
|
96
|
+
| `new Agent(opts)` | 构造函数(无副作用,不连接 LLM) |
|
|
97
|
+
| `init(projectPathOverride?)` → `Promise<ProjectContext>` | 初始化:建立存储、加载配置、组装组件 |
|
|
98
|
+
| `close()` → `Promise<void>` | 关闭:释放项目锁、关闭数据库 |
|
|
99
|
+
|
|
100
|
+
### 2.3 Agent 只读访问器
|
|
101
|
+
|
|
102
|
+
| 访问器 | 类型 | 说明 |
|
|
103
|
+
|--------|------|------|
|
|
104
|
+
| `agent.initialized` | `boolean` | 是否已初始化 |
|
|
105
|
+
| `agent.context` | `AgentContext \| null` | 当前项目上下文 |
|
|
106
|
+
| `agent.provider` | `LlmProvider` | 当前前台 Provider |
|
|
107
|
+
| `agent.isBusy` | `boolean` | 是否正在对话中 |
|
|
108
|
+
| `agent.lastInteractionAt` | `Date \| null` | 最近一次 `chat()` 调用时间 |
|
|
109
|
+
|
|
110
|
+
### 2.4 Manager 访问器(委托模式)
|
|
111
|
+
|
|
112
|
+
Agent 通过一组 getter 暴露专职 Manager 与组件。详见后续章节。
|
|
113
|
+
|
|
114
|
+
| 访问器 | 类型 | 职责 |
|
|
115
|
+
|--------|------|------|
|
|
116
|
+
| `agent.persona` | `PersonaManager \| null` | 角色管理 |
|
|
117
|
+
| `agent.tools` | `ToolExecutor \| null` | 工具注册与执行 |
|
|
118
|
+
| `agent.skills` | `SkillManager \| null` | 技能匹配与注入 |
|
|
119
|
+
| `agent.config` | `ConfigManager \| null` | 规则/技能注入 + 配置建议 |
|
|
120
|
+
| `agent.insight` | `InsightExtractor \| null` | 输入分类 + 记忆提取 |
|
|
121
|
+
| `agent.memory` | `MemoryInspector \| null` | 记忆查询 + 写入(`writeXxx` 前缀) |
|
|
122
|
+
| `agent.userProfile` | `UserProfile \| null` | 用户画像管理(事实提取 + 确认/拒绝) |
|
|
123
|
+
| `agent.works` | `WorkProjectionManager \| null` | 作品投影(工作内容摘要) |
|
|
124
|
+
| `agent.polish` | `TextPolishManager \| null` | 文本润色(LLM 语法修正 + 表达优化) |
|
|
125
|
+
|
|
126
|
+
> **读写统一入口**:`agent.memory`(MemoryInspector)同时负责记忆的查询与写入——只读方法(snapshot/search/searchHybrid/stats/list/getById/getBySource/listDeleted/relations 等)与写方法(`writeXxx` 前缀:writeUpsert/writeDelete/writeRestore/writePurge/writePurgeExpired/writeBoost/writeAddRelation/writeRemoveRelation/writeRemoveRelationsByMemoryId)。旧的 `memoryMutator`/`MemoryMutator` 拆分已在后续迭代中合并回 `MemoryInspector`,二者均不再存在。
|
|
127
|
+
|
|
128
|
+
### 2.5 内部组件访问器(高级)
|
|
129
|
+
|
|
130
|
+
| 访问器 | 类型 | 说明 |
|
|
131
|
+
|--------|------|------|
|
|
132
|
+
| `agent.agentLoop` | `AgentLoop \| null` | Agent 循环体(`getMessages()` / `getRecentHistory()`) |
|
|
133
|
+
| `agent.agentHistory` | `MessageHistory \| null` | 消息历史(`listAllSessions()` 等) |
|
|
134
|
+
|
|
135
|
+
### 2.6 `ProjectContext` 字段(`init()` 返回值)
|
|
136
|
+
|
|
137
|
+
| 字段 | 类型 | 说明 |
|
|
138
|
+
|------|------|------|
|
|
139
|
+
| `projectPath` | `string` | 项目根目录的绝对路径 |
|
|
140
|
+
| `projectName` | `string` | 项目名称(从注册表读取,或取目录名) |
|
|
141
|
+
| `memoraDir` | `string` | `.memora/` 目录的绝对路径 |
|
|
142
|
+
| `dbPath` | `string` | memora.db 路径 |
|
|
143
|
+
| `fileStore` | `FileStore` | 文件存储 |
|
|
144
|
+
| `index` | `IMemoryStorage` | 记忆存储接口 |
|
|
145
|
+
| `security` | `SecurityGuard` | 安全守卫 |
|
|
146
|
+
| `bootstrapMemories` | `Memory[]` | 启动时加载的必召记忆 |
|
|
147
|
+
| `loadResult` | `LoadResult` | 加载结果(成功数 / 失败数) |
|
|
148
|
+
|
|
149
|
+
### 2.7 事件订阅(`agent.on()` / `agent.off()` / `agent.once()`)
|
|
150
|
+
|
|
151
|
+
Agent 继承 `TypedEventEmitter<AgentEventMap>`,向宿主项目广播对话外事件。
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
agent.on<K extends AgentEventName>(event: K, handler: (payload: AgentEventMap[K]) => void): void
|
|
155
|
+
agent.off<K extends AgentEventName>(event: K, handler: (payload: AgentEventMap[K]) => void): void
|
|
156
|
+
agent.once<K extends AgentEventName>(event: K, handler: (payload: AgentEventMap[K]) => void): void
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
| 事件名 | 载荷 | 触发时机 |
|
|
160
|
+
|--------|------|----------|
|
|
161
|
+
| `memoryAdded` | `{ id, source, name }` | 记忆被写入存储(insight 提取、rule 注入等) |
|
|
162
|
+
| `personaSwitched` | `{ from: string \| null, to }` | 角色被切换(自动匹配或手动指定) |
|
|
163
|
+
| `decayCompleted` | `{ decayedCount }` | 记忆衰减完成(init 首次 + 每小时定时) |
|
|
164
|
+
| `memoryRecalled` | `{ count, query }` | 记忆被召回(用于 UI 展示) |
|
|
165
|
+
| `sessionForked` | `{ from, to, messageCount }` | 会话被分叉(创建新分支) |
|
|
166
|
+
| `insightExtracted` | `{ source: string; insight: string }` | 洞察被提取 |
|
|
167
|
+
| `conflictDetected` | `{ newMemoryId, newInsight, targetId, targetContent }` | 记忆冲突被检测到(`contradicts` 关系写入时触发,宿主可通知用户) |
|
|
168
|
+
| `projectSwitched` | `{ from: string \| null, to: string, projectName: string }` | 项目切换(宿主 UI 可据此刷新项目相关界面) |
|
|
169
|
+
| `skillMatched` | `{ skill: string, score: number }` | 技能被匹配(宿主 UI 可据此展示当前激活技能) |
|
|
170
|
+
| `archiveFailed` | `{ stage: 'profile' \| 'insight' \| 'content'; message: string }` | 归档操作失败(任一阶段失败,fire-and-forget catch 分支发射,宿主可通知用户) |
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// 使用示例
|
|
174
|
+
agent.on('memoryAdded', (e) => console.log(`新记忆: ${e.source}:${e.name}`));
|
|
175
|
+
agent.on('decayCompleted', (e) => console.log(`衰减 ${e.decayedCount} 条记忆`));
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
> `close()` 自动移除所有事件监听器。
|
|
179
|
+
|
|
180
|
+
**状态机**:
|
|
181
|
+
```
|
|
182
|
+
[构造] --init()--> [已初始化] --chat()/其他方法...--> [已初始化]
|
|
183
|
+
--close()--> [已关闭]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
未初始化时调用任何方法**抛 `configError`**。Manager 访问器在 `init()` 前返回 `null`。
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 三、对话 API
|
|
191
|
+
|
|
192
|
+
### 3.1 `chat(input, signal?)` — 流式对话(唯一入口)
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
async *chat(input: string, signal?: AbortSignal): AsyncGenerator<AgentChunk, void, unknown>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
流式返回 `AgentChunk` 事件,可选传入 `signal` 支持取消。
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
type AgentChunk =
|
|
202
|
+
| { type: 'recall'; memories: RecalledMemorySummary[] } // 记忆召回(携带摘要列表)
|
|
203
|
+
| { type: 'thinking'; phase: ThinkingPhase } // 推理阶段
|
|
204
|
+
| { type: 'text'; content: string; guardrailBlocked?: boolean } // LLM 文本片段(护栏阻断时 guardrailBlocked=true)
|
|
205
|
+
| { type: 'tool_start'; toolCallId: string; name: string; args?: string } // 工具调用开始
|
|
206
|
+
| { type: 'tool_result'; toolCallId: string; name: string; ok: boolean; summary?: string } // 工具调用结果
|
|
207
|
+
| { type: 'aborted'; reason: string } // 对话被取消
|
|
208
|
+
| { type: 'error'; message: string } // 流式过程中发生错误(LLM 超时/连接断开)
|
|
209
|
+
| { type: 'retry'; attempt: number; maxRetries: number; delayMs: number; error: string } // 指数退避重试
|
|
210
|
+
| { type: 'done' }; // 结束标记
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`ThinkingPhase` 取值:`'recalling' | 'processing' | 'archiving'`
|
|
214
|
+
|
|
215
|
+
#### `RecalledMemorySummary` 类型(recall chunk 载荷)
|
|
216
|
+
|
|
217
|
+
仅暴露 UI 展示所需字段,不包含 `content`(避免向 UI 层泄露完整记忆内容):
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
interface RecalledMemorySummary {
|
|
221
|
+
id: string; // 记忆唯一标识(source:name 格式,用于前端精准跳转详情)
|
|
222
|
+
name: string; // 记忆可读名称(点击跳转记忆详情用)
|
|
223
|
+
score: number; // 相似度分数(0-1)
|
|
224
|
+
source: string; // 来源标签(开放字符串,如 'rule'、'insight'、'profile')
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
> **guardrailBlocked 结构化信号**:v1.0 起用结构化字段替代中文文案匹配,eval 框架和宿主 UI 可通过 `chunk.guardrailBlocked === true` 判断护栏触发,无需依赖文案子串匹配。
|
|
229
|
+
|
|
230
|
+
### 3.2 `chatSync(input, signal?)` — 同步版(仅供测试用)
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
async chatSync(input: string, signal?: AbortSignal): Promise<string>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
收集所有 `text` 事件拼接成完整字符串返回。
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 四、记忆查询与写入(`agent.memory` · MemoryInspector)
|
|
241
|
+
|
|
242
|
+
> Manager 访问路径:`agent.memory.xxx()`。`init()` 前返回 `null`。
|
|
243
|
+
|
|
244
|
+
### 4.1 `snapshot()` — 3 层记忆快照
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
agent.memory.snapshot(): MemorySnapshot
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
同步返回当前 3 层记忆快照(纯只读、无副作用):
|
|
251
|
+
|
|
252
|
+
| 层 | 键 | 内容 |
|
|
253
|
+
|----|-----|------|
|
|
254
|
+
| 第 1 层 | `snapshot.working` | `WorkingMemorySnapshot` — 当前 AgentLoop 消息(最近 5 条预览 + 总数) |
|
|
255
|
+
| 第 2 层 | `snapshot.bootstrap` | `BootstrapSnapshot` — 规则记忆(名称 + 来源 + 权重,Persona/Skill 已解耦为设定记忆,不进 bootstrap) |
|
|
256
|
+
| 第 3 层 | `snapshot.archive` | `ArchiveSnapshot` — 归档记忆计数(insight + profile + work-projection)+ 当前会话信息 |
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
interface MemorySnapshot {
|
|
260
|
+
working: WorkingMemorySnapshot;
|
|
261
|
+
bootstrap: BootstrapSnapshot;
|
|
262
|
+
archive: ArchiveSnapshot;
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 4.2 `search(query, limit?)` — 记忆搜索
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
agent.memory.search(query: string, limit?: number): AgentSearchHit[]
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
interface AgentSearchHit {
|
|
274
|
+
id: string; // 记忆唯一标识(source:name 格式,供 showMemory/deleteMemory 等操作使用)
|
|
275
|
+
name: string; // 记忆名称
|
|
276
|
+
source: string; // 来源标签
|
|
277
|
+
score: number; // 权重(0-1)
|
|
278
|
+
contentPreview: string; // 内容预览(截断到 120 字符)
|
|
279
|
+
similarity?: number; // 语义相似度(0-1,仅 searchHybrid 返回;纯关键词搜索时无此字段)
|
|
280
|
+
createdAt?: string; // 创建时间(ISO 8601,供 UI 层时间筛选/排序使用)
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### 4.3 `stats()` — 记忆库统计
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
agent.memory.stats(): AgentStats
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
interface AgentStats {
|
|
292
|
+
bySource: Record<string, number>; // 按来源标签分组的记忆数量
|
|
293
|
+
total: number; // 记忆总数
|
|
294
|
+
relationCount: number; // 关系边总数(relationStore 未注入时为 0)
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### 4.4 `agent.agentLoop.getMessages()` — 工作记忆原始消息
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
agent.agentLoop.getMessages(): readonly Message[]
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### 4.5 写入与关系方法(P1-2 合并回 MemoryInspector)
|
|
305
|
+
|
|
306
|
+
记忆的写入与关系操作统一收口在 `agent.memory`,写方法以 `writeXxx` 前缀命名(同步返回、不调 LLM、不触发异步 IO):
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
// ─── 写入(writeXxx 前缀) ───
|
|
310
|
+
agent.memory.writeUpsert(memory: Memory): void; // 插入或更新记忆
|
|
311
|
+
agent.memory.writeBoost(id: string, increment?: number): boolean; // 提升 score(用户采纳反哺,默认 +0.05)
|
|
312
|
+
agent.memory.writeDelete(id: string): void; // 软删除(写入 deletedAt)
|
|
313
|
+
agent.memory.writeRestore(id: string): void; // 恢复软删除
|
|
314
|
+
agent.memory.writePurge(id: string): void; // 物理删除(不可恢复)
|
|
315
|
+
agent.memory.writePurgeExpired(before: Date): number; // 清理过期回收站(并清理孤儿关系边)
|
|
316
|
+
agent.memory.writeAddRelation(relation: MemoryRelation): void; // 添加关系边
|
|
317
|
+
agent.memory.writeRemoveRelation(sourceId: string, targetId: string, type: string): void;
|
|
318
|
+
agent.memory.writeRemoveRelationsByMemoryId(memoryId: string): number; // 删除某记忆的所有关系边
|
|
319
|
+
|
|
320
|
+
// ─── 只读扩展查询 ───
|
|
321
|
+
agent.memory.list(limit?: number): Memory[]; // 列出所有记忆(按 score 降序)
|
|
322
|
+
agent.memory.getById(id: string): Memory | null; // 按 ID 获取活跃记忆
|
|
323
|
+
agent.memory.getBySource(source: string): Memory[]; // 按 source 获取
|
|
324
|
+
agent.memory.listDeleted(limit?: number): Memory[]; // 回收站(软删除记忆)
|
|
325
|
+
agent.memory.getDeletedById(id: string): Memory | null;
|
|
326
|
+
agent.memory.searchHybrid(query: string, limit?: number): Promise<AgentSearchHit[]>; // 语义 + 关键词双通道
|
|
327
|
+
|
|
328
|
+
// ─── 关系查询(relationStore 未注入时静默返回空/0) ───
|
|
329
|
+
agent.memory.getRelations(memoryId: string, direction?: RelationDirection): MemoryRelation[];
|
|
330
|
+
agent.memory.getAllRelations(): MemoryRelation[];
|
|
331
|
+
agent.memory.getRelationPath(memoryId: string, maxDepth?: number, direction?: RelationDirection): RelationPath[];
|
|
332
|
+
agent.memory.getRelationNeighbors(memoryId: string, limit?: number): RelationNeighbor[];
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
> **注意**:`suggest()` / `sourceHealth()` 已上移至 Agent 层(`agent.suggest()` / `agent.sourceHealth()`),不再挂在 `agent.memory` 下,避免经 MemoryInspector 转发产生多余代理层。
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 五、Memory 模型(基元驱动)
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
interface Memory {
|
|
343
|
+
id: string; // 唯一标识(source:name 格式,如 'rule:core')
|
|
344
|
+
content: string; // 记忆内容(Markdown 文本)
|
|
345
|
+
source: string; // 来源标签(开放字符串,非枚举)
|
|
346
|
+
name: string; // 可读名称
|
|
347
|
+
createdAt: string; // 创建时间(ISO 8601)
|
|
348
|
+
accessedAt: string; // 最后访问时间(每次召回时刷新)
|
|
349
|
+
score: number; // 权重(0-1,召回时用于排序)
|
|
350
|
+
deletedAt?: string; // 软删除时间(ISO 8601,可选;非 undefined 表示已软删除,回收站保留 30 天后自动物理清理)
|
|
351
|
+
metadata?: Record<string, string>; // 配置文件 frontmatter 额外元数据(仅配置文件写入时使用,SQLite 不存储此字段)
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
> **8 字段基元**(v2.1 软删除扩展):7 个基础字段 + 1 个可选 `deletedAt`。所有查询方法(getById/getBySource/search/count/countBySource/decayScores/getAllSources)自动过滤 `deletedAt != undefined` 的记忆。详见 ADR-004 GAP-6 + ADR-002 §IMemoryStorage。
|
|
356
|
+
|
|
357
|
+
**常用 source 标签(`SOURCE_LABELS` 常量):**
|
|
358
|
+
|
|
359
|
+
| 常量 | 值 | 用途 |
|
|
360
|
+
|------|----|------|
|
|
361
|
+
| `SOURCE_LABELS.PERSONA` | `'persona'` | 角色人格 |
|
|
362
|
+
| `SOURCE_LABELS.RULE` | `'rule'` | 创作规则 |
|
|
363
|
+
| `SOURCE_LABELS.SKILL` | `'skill'` | 技能定义 |
|
|
364
|
+
| `SOURCE_LABELS.INSIGHT` | `'insight'` | 对话洞察 |
|
|
365
|
+
| `SOURCE_LABELS.PROFILE` | `'profile'` | 用户画像 |
|
|
366
|
+
| `SOURCE_LABELS.WORK_PROJECTION` | `'work-projection'` | 作品投影 |
|
|
367
|
+
| `SOURCE_LABELS.GUARDRAIL` | `'guardrail'` | 内容护栏规则 |
|
|
368
|
+
|
|
369
|
+
> source 是开放字符串,宿主可自定义新标签。`validateSource()` 可检测常见 typo(基于 Levenshtein 距离)。
|
|
370
|
+
|
|
371
|
+
### 5.2 `IMemoryStorage` 接口
|
|
372
|
+
|
|
373
|
+
宿主实现此接口注入 Agent,替代默认的 `InMemoryStorage`。共 **15 方法**(含可选 `close`),所有方法同步(与 better-sqlite3 API 对齐,`await` 同步值安全)。所有查询方法自动过滤已软删除的记忆(`deletedAt != undefined`)。
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
interface IMemoryStorage {
|
|
377
|
+
// ─── 基础 CRUD(6 方法) ───
|
|
378
|
+
upsert(memory: Memory): void;
|
|
379
|
+
getById(id: string): Memory | null;
|
|
380
|
+
getBySource(source: string): Memory[];
|
|
381
|
+
search(query: string, limit?: number): Memory[];
|
|
382
|
+
count(): number;
|
|
383
|
+
countBySource(source: string): number;
|
|
384
|
+
|
|
385
|
+
// ─── 软删除 / 回收站(6 方法,ADR-004 GAP-6 扩展) ───
|
|
386
|
+
delete(id: string): void; // 软删除(写入 deletedAt,不物理移除;对已软删除的 no-op)
|
|
387
|
+
restore(id: string): void; // 恢复软删除记忆(清除 deletedAt;对活跃记忆 no-op)
|
|
388
|
+
purge(id: string): void; // 物理删除(不可恢复,用于回收站"彻底删除")
|
|
389
|
+
listDeleted(limit?: number): Memory[]; // 列出回收站(按 deletedAt 降序,默认 50)
|
|
390
|
+
getDeletedById(id: string): Memory | null; // 按 ID 获取单条软删除记忆(restore/purge 前存在性校验)
|
|
391
|
+
purgeExpired(before: Date): number; // 清理过期回收站(物理删除 deletedAt 早于 before 的,返回清理数量)
|
|
392
|
+
|
|
393
|
+
// ─── 统计与维护(2 方法) ───
|
|
394
|
+
decayScores(sources: string[], now: Date): number; // 批量衰减指定 source 的 score(宿主实现批量 SQL UPDATE)
|
|
395
|
+
getAllSources(): Map<string, number>; // 获取所有 source 标签及其活跃记忆数量
|
|
396
|
+
|
|
397
|
+
// ─── 可选(1 方法) ───
|
|
398
|
+
close?(): void;
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
> 宿主实现应使用 `COUNT(*)` / `UPDATE ... WHERE` 等数据库原生操作,避免全量加载数据。`decayScores` 和 `getAllSources` 是性能优化方法,避免逐条遍历。详见 ADR-002 §IMemoryStorage 接口方法。
|
|
403
|
+
|
|
404
|
+
### 5.3 `ISessionStore` 接口
|
|
405
|
+
|
|
406
|
+
宿主实现此接口提供会话消息的持久化能力。
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
interface ISessionStore {
|
|
410
|
+
appendMessage(date: string, session: string, message: SessionMessage): void;
|
|
411
|
+
loadMessages(date: string, session: string): SessionMessage[];
|
|
412
|
+
listSessions(): string[];
|
|
413
|
+
copySession?(sourceDate: string, sourceSession: string, targetDate: string, targetSession: string): void;
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**`copySession` 实现要求**:
|
|
418
|
+
- 原子操作:要么全部复制成功,要么不产生副作用
|
|
419
|
+
- 保留时间戳:消息的 timestamp 不修改
|
|
420
|
+
- 幂等:若目标会话已存在,覆盖(而非追加)
|
|
421
|
+
- 若源会话不存在,静默返回(不抛出)
|
|
422
|
+
|
|
423
|
+
### 5.4 记忆关系图谱(ADR-014 侧车模型)
|
|
424
|
+
|
|
425
|
+
记忆关系是独立的侧车数据结构,与 Memory 平行存在,互不侵入。关系类型是开放字符串(非枚举),遵循 ADR-004 基元驱动原则。
|
|
426
|
+
|
|
427
|
+
#### `MemoryRelation` 类型
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
interface MemoryRelation {
|
|
431
|
+
sourceId: string; // 关系起点(Memory.id)
|
|
432
|
+
targetId: string; // 关系终点(Memory.id)
|
|
433
|
+
type: string; // 关系类型(开放字符串,非枚举)
|
|
434
|
+
weight: number; // 关系强度 0-1
|
|
435
|
+
createdAt: string; // 创建时间(ISO 8601)
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
#### 预设关系类型常量(`RELATION_TYPES`)
|
|
440
|
+
|
|
441
|
+
| 常量 | 值 | 方向 | 说明 |
|
|
442
|
+
|------|------|------|------|
|
|
443
|
+
| `CONTRADICTS` | `'contradicts'` | 双向对称 | 矛盾关系 |
|
|
444
|
+
| `SUPPORTS` | `'supports'` | 有向 | 支持关系 |
|
|
445
|
+
| `FOLLOWS` | `'follows'` | 有向 | 时间先后 |
|
|
446
|
+
| `REFINES` | `'refines'` | 有向 | 细化/演化 |
|
|
447
|
+
| `CAUSED` | `'caused'` | 有向 | 因果关系 |
|
|
448
|
+
| `RELATED` | `'related'` | 双向对称 | 泛相关 |
|
|
449
|
+
|
|
450
|
+
#### 关系强度常量(`RELATION_WEIGHTS`)
|
|
451
|
+
|
|
452
|
+
| 常量 | 值 | 说明 |
|
|
453
|
+
|------|------|------|
|
|
454
|
+
| `NONE` | 0.0 | 几乎无关 |
|
|
455
|
+
| `WEAK` | 0.3 | 弱相关 |
|
|
456
|
+
| `UNDEFINED` | 0.5 | 未判断(代码默认兜底) |
|
|
457
|
+
| `STRONG` | 0.7 | 强相关 |
|
|
458
|
+
| `CERTAIN` | 1.0 | 确定关系(矛盾/等价) |
|
|
459
|
+
|
|
460
|
+
#### `IMemoryRelationStore` 接口
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
interface IMemoryRelationStore {
|
|
464
|
+
/** 添加关系(三元组 sourceId+targetId+type 唯一约束,重复添加幂等更新 weight/createdAt) */
|
|
465
|
+
addRelation(relation: MemoryRelation): void;
|
|
466
|
+
/** 查询关系(direction 默认 'both',合并两方向并去重) */
|
|
467
|
+
getRelations(memoryId: string, direction?: RelationDirection): MemoryRelation[];
|
|
468
|
+
/** 按类型查询(如 getRelationsByType('contradicts') 获取所有矛盾关系) */
|
|
469
|
+
getRelationsByType(type: string): MemoryRelation[];
|
|
470
|
+
/** 获取全部关系(用于拓扑可视化构建节点+边图谱) */
|
|
471
|
+
getAllRelations(): MemoryRelation[];
|
|
472
|
+
/** 删除关系(用于关系修正,用户确认冲突后删除误判关系) */
|
|
473
|
+
removeRelation(sourceId: string, targetId: string, type: string): void;
|
|
474
|
+
/** 删除某记忆的所有关系边(不论方向,用于记忆删除/物理清除场景,防止孤儿边残留) */
|
|
475
|
+
removeRelationsByMemoryId(memoryId: string): number;
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**`RelationDirection` 类型**:`'outgoing' | 'incoming' | 'both'`
|
|
480
|
+
|
|
481
|
+
#### 注入方式
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
import { Agent, InMemoryRelationStore } from '@zooique/memora';
|
|
485
|
+
import type { IMemoryRelationStore } from '@zooique/memora';
|
|
486
|
+
|
|
487
|
+
// 测试用:InMemoryRelationStore(纯内存,零 IO)
|
|
488
|
+
const relationStore: IMemoryRelationStore = new InMemoryRelationStore();
|
|
489
|
+
|
|
490
|
+
// 生产用:宿主实现 SqliteRelationStore
|
|
491
|
+
const agent = new Agent({
|
|
492
|
+
// ...其他配置
|
|
493
|
+
relationStore,
|
|
494
|
+
});
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
> **不注入时**:跳过关系构建,InsightExtractor 不会检测冲突,不生成关系数据。
|
|
498
|
+
|
|
499
|
+
#### `InMemoryRelationStore` 测试实现
|
|
500
|
+
|
|
501
|
+
纯内存实现,零 IO,所有方法返回深拷贝(防止外部篡改内部状态)。供单元测试使用,生产环境宿主应实现 `SqliteRelationStore` 等持久化实现。
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## 六、项目 / 会话管理
|
|
506
|
+
|
|
507
|
+
> **方法归属**(v1.0 P1-4 拆分后):项目相关方法在 `agent.projects`(ProjectManager),会话相关方法在 `agent.sessionManager`(SessionManager),仅 `switchProject` / `rebuildComponents` / `forkSession` 保留在 Agent 面类作为常用入口。
|
|
508
|
+
|
|
509
|
+
> **switch* 返回值约定**:各 switch 操作返回与其操作语义最匹配的值 ——
|
|
510
|
+
> `switchSession` 返回新会话名(string)、`switchProject` 返回完整项目上下文(AgentContext,含 bootstrap 记忆等)、
|
|
511
|
+
> `personaManager.switchPersona` 返回 system prompt 文本(string)。这是设计性差异,非 bug。
|
|
512
|
+
|
|
513
|
+
### 6.1 Agent 面类方法(项目/会话入口)
|
|
514
|
+
|
|
515
|
+
| 方法 | 用途 |
|
|
516
|
+
|------|------|
|
|
517
|
+
| `switchProject(nameOrPath)` → `Promise<AgentContext>` | 切换到指定项目(保留 Agent 级记忆,自动 rebuild) |
|
|
518
|
+
| `rebuildComponents()` → `Promise<void>` | 重建 history / loop(通常不需要手动调用,switchProject 已自动执行) |
|
|
519
|
+
| `forkSession(targetSession?)` → `AgentForkResult` | 分叉当前会话(同步,复制完整消息历史到新分支) |
|
|
520
|
+
|
|
521
|
+
### 6.2 `agent.projects` — ProjectManager
|
|
522
|
+
|
|
523
|
+
| 方法 | 用途 |
|
|
524
|
+
|------|------|
|
|
525
|
+
| `projects.list` | 所有已注册项目(getter) |
|
|
526
|
+
| `projects.listProjects()` → `ProjectEntry[]` | 列出所有已注册项目 |
|
|
527
|
+
|
|
528
|
+
### 6.3 `agent.sessionManager` — SessionManager
|
|
529
|
+
|
|
530
|
+
| 方法 | 用途 |
|
|
531
|
+
|------|------|
|
|
532
|
+
| `sessionManager.switchSession(newName)` → `string` | 切换到指定会话(chatBusy 时抛 configError) |
|
|
533
|
+
| `sessionManager.forkSession(targetSession?)` → `AgentForkResult` | 分叉当前会话 |
|
|
534
|
+
| `sessionManager.loadSessionMessages(date, session)` → `Promise<SessionMessage[]>` | 加载指定日期/会话的消息(含时间戳) |
|
|
535
|
+
| `sessionManager.restoreMostRecentSession(preferredSession='main')` → `Promise<number>` | 启动时恢复最近一次会话 |
|
|
536
|
+
| `sessionManager.restoreSession(date, session)` → `Promise<number>` | 恢复指定日期/会话 |
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
// 项目列表
|
|
540
|
+
const projects = agent.projects.list;
|
|
541
|
+
|
|
542
|
+
// 会话分叉示例(Agent 面类入口,等价于 agent.sessionManager.forkSession())
|
|
543
|
+
const forkResult = agent.forkSession();
|
|
544
|
+
console.log(`分叉到 ${forkResult.newSession},复制了 ${forkResult.messageCount} 条消息`);
|
|
545
|
+
|
|
546
|
+
// 自定义分支名
|
|
547
|
+
const customFork = agent.forkSession('experiment');
|
|
548
|
+
|
|
549
|
+
// listAllSessions 通过 agentHistory 访问
|
|
550
|
+
const sessions = await agent.agentHistory?.listAllSessions();
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### `AgentForkResult` / `ForkResult` 类型
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
// Agent.forkSession() / sessionManager.forkSession() 返回值
|
|
557
|
+
interface AgentForkResult {
|
|
558
|
+
newSession: string;
|
|
559
|
+
messageCount: number;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// MessageHistory.forkSession() 内部类型(从 memora 导出)
|
|
563
|
+
export interface ForkResult {
|
|
564
|
+
date: string;
|
|
565
|
+
newSession: string;
|
|
566
|
+
messages: SessionMessage[];
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## 七、角色管理(`agent.persona` · PersonaManager)
|
|
573
|
+
|
|
574
|
+
> Manager 访问路径:`agent.persona.xxx`。`init()` 前返回 `null`。
|
|
575
|
+
|
|
576
|
+
| 成员 | 类型 | 说明 |
|
|
577
|
+
|------|------|------|
|
|
578
|
+
| `persona.list` | `Persona[]`(getter) | 所有可用角色列表 |
|
|
579
|
+
| `persona.activeName` | `string`(getter) | 当前激活的角色名 |
|
|
580
|
+
| `persona.currentMode` | `PersonaMode`(getter) | 当前匹配模式(`'auto'` / `'manual'`) |
|
|
581
|
+
| `persona.active` | `Persona \| null`(getter) | 当前激活的完整角色对象 |
|
|
582
|
+
| `persona.switchPersona(name)` | 方法 → `string` | 手动切换到指定角色(返回新角色的 system prompt) |
|
|
583
|
+
| `persona.setMode(mode)` | 方法 | 设置匹配模式(`'auto'` / `'manual'`) |
|
|
584
|
+
|
|
585
|
+
```typescript
|
|
586
|
+
// 使用示例
|
|
587
|
+
const names = agent.persona.list.map(p => p.name); // 列出角色
|
|
588
|
+
agent.persona.switchPersona('作家'); // 切换角色
|
|
589
|
+
agent.persona.setMode('manual'); // 锁定手动模式
|
|
590
|
+
console.log(agent.persona.activeName); // 当前角色名
|
|
591
|
+
console.log(agent.persona.currentMode); // 当前模式
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## 八、工具注册(`agent.tools` · ToolExecutor + `agent.insight`)
|
|
597
|
+
|
|
598
|
+
> 工具注册/执行走 `agent.tools.xxx()`,写入扩展/记忆关键词走 `agent.insight.xxx()`。
|
|
599
|
+
|
|
600
|
+
### 8.1 内置工具(4 个)
|
|
601
|
+
|
|
602
|
+
| 工具名 | 用途 | 参数 |
|
|
603
|
+
|--------|------|------|
|
|
604
|
+
| `read_file` | 读取项目内文件内容 | `path` |
|
|
605
|
+
| `write_file` | 写入/创建文件(支持 overwrite/append/insert 三种模式) | `path`, `content`, `mode?`, `insert_line?` |
|
|
606
|
+
| `list_dir` | 列出目录内容(递归深度 ≤ 3) | `path?`, `recursive?`, `maxDepth?` |
|
|
607
|
+
| `search_memories` | 在记忆索引中搜索(支持 match/near 两种模式) | `query`, `limit?`, `mode?` |
|
|
608
|
+
|
|
609
|
+
### 8.2 `agent.tools` — ToolExecutor
|
|
610
|
+
|
|
611
|
+
| 方法 | 用途 |
|
|
612
|
+
|------|------|
|
|
613
|
+
| `tools.registerTool(definition, handler)` | 注册自定义工具(会话级) |
|
|
614
|
+
| `tools.list` | 所有工具定义(getter,`ToolDefinition[]`) |
|
|
615
|
+
| `tools.execute(name, argsJson, extensions?)` → `Promise<string>` | 执行工具调用 |
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
// 工具定义
|
|
619
|
+
interface ToolDefinition {
|
|
620
|
+
name: string;
|
|
621
|
+
description: string;
|
|
622
|
+
parameters: {
|
|
623
|
+
type: 'object';
|
|
624
|
+
properties: Record<string, { type: string; description: string }>;
|
|
625
|
+
required: string[]; // 必填参数列表(不可省略)
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// 宿主注册领域工具示例
|
|
630
|
+
agent.tools.registerTool(
|
|
631
|
+
{
|
|
632
|
+
name: 'web_search',
|
|
633
|
+
description: '搜索互联网,返回结构化结果',
|
|
634
|
+
parameters: {
|
|
635
|
+
type: 'object',
|
|
636
|
+
properties: {
|
|
637
|
+
query: { type: 'string', description: '搜索关键词' },
|
|
638
|
+
limit: { type: 'number', description: '最大返回条数', default: 5 },
|
|
639
|
+
},
|
|
640
|
+
required: ['query'],
|
|
641
|
+
},
|
|
642
|
+
},
|
|
643
|
+
async (args) => {
|
|
644
|
+
const res = await fetch(`https://api.example.com/search?q=${encodeURIComponent(args.query)}`);
|
|
645
|
+
return await res.json();
|
|
646
|
+
},
|
|
647
|
+
);
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### 8.3 `agent.insight` — InsightExtractor(写入扩展 + 关键词)
|
|
651
|
+
|
|
652
|
+
| 方法 | 用途 |
|
|
653
|
+
|------|------|
|
|
654
|
+
| `insight.setWriteExtensions(ext)` | 注入写入扩展回调(diff 对比确认) |
|
|
655
|
+
| `insight.setKeywords(keywords)` | 设置记忆关键词(domain / personal 两类) |
|
|
656
|
+
| `insight.classify(input)` → `'skip' \| 'extract'` | 输入分类(判断是否需要提取记忆) |
|
|
657
|
+
| `insight.extract(userInput, assistantContent)` | 异步提取对话 insight(fire-and-forget) |
|
|
658
|
+
|
|
659
|
+
```typescript
|
|
660
|
+
// 写入扩展回调
|
|
661
|
+
agent.insight.setWriteExtensions({
|
|
662
|
+
onBeforeWrite: async (path, before, after) => {
|
|
663
|
+
// 展示 diff,返回 true 允许写入 / false 拒绝
|
|
664
|
+
return confirmDialog(`确认写入 ${path}?`);
|
|
665
|
+
},
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
// 记忆关键词(用于输入分类 Layer 2)
|
|
669
|
+
agent.insight.setKeywords({
|
|
670
|
+
domain: ['主角', '角色', '情节', '设定'], // 领域关键词
|
|
671
|
+
personal: ['我', '我的', '记住', '帮我'], // 用户专属关键词
|
|
672
|
+
});
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
---
|
|
676
|
+
|
|
677
|
+
## 九、规则与技能注入(`agent.config` · ConfigManager)
|
|
678
|
+
|
|
679
|
+
> Manager 访问路径:`agent.config.xxx()`。`init()` 前返回 `null`。
|
|
680
|
+
|
|
681
|
+
### 9.1 规则注入
|
|
682
|
+
|
|
683
|
+
| 方法 | 用途 | 写到哪里 |
|
|
684
|
+
|------|------|----------|
|
|
685
|
+
| `config.addRule(memory)` | 添加规则(需 `source='rule'`) | SQLite + System Prompt |
|
|
686
|
+
| `config.addSimpleRule(name, content)` | 同上,简化版(自动填充字段) | SQLite + System Prompt |
|
|
687
|
+
|
|
688
|
+
```typescript
|
|
689
|
+
// 注入规则
|
|
690
|
+
await agent.config.addSimpleRule(
|
|
691
|
+
'世界观规则',
|
|
692
|
+
'这是一个东方玄幻世界,修真等级分为炼气、筑基、金丹……',
|
|
693
|
+
);
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
### 9.2 技能注入
|
|
697
|
+
|
|
698
|
+
| 方法 | 用途 | 写到哪里 |
|
|
699
|
+
|------|------|----------|
|
|
700
|
+
| `config.addSkill(memory)` | 添加技能(需 `source='skill'`,session-only) | SkillManager |
|
|
701
|
+
| `config.addSimpleSkill(name, content, keywords?)` | 同上,简化版(session-only) | SQLite + SkillManager |
|
|
702
|
+
|
|
703
|
+
```typescript
|
|
704
|
+
// 注入技能(session-only,注入 SkillManager 内存缓存,重启后丢失)
|
|
705
|
+
await agent.config.addSimpleSkill(
|
|
706
|
+
'大纲生成',
|
|
707
|
+
'当用户说“生成大纲”时,按三幕结构生成章节大纲……',
|
|
708
|
+
['大纲', '结构', '章节'], // 可选:触发关键词
|
|
709
|
+
);
|
|
710
|
+
|
|
711
|
+
// 如需跨会话持久化,写入配置文件
|
|
712
|
+
await agent.config.confirmConfigSuggestion({
|
|
713
|
+
type: 'skill',
|
|
714
|
+
name: '大纲生成',
|
|
715
|
+
content: '当用户说“生成大纲”时……',
|
|
716
|
+
confidence: 0.9,
|
|
717
|
+
});
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
### 9.3 配置建议(模式 3:AutoConfigRefiner 自进化)
|
|
721
|
+
|
|
722
|
+
Agent 在对话后自动分析用户输入和助手回复,提取潜在的配置建议(规则/角色/技能),通过回调通知宿主。这是"三种接入模式"中的模式 3(Agent 智能总结接口)。
|
|
723
|
+
|
|
724
|
+
#### `AutoConfigRefinerOptions` 配置
|
|
725
|
+
|
|
726
|
+
```typescript
|
|
727
|
+
interface AutoConfigRefinerOptions {
|
|
728
|
+
minConfidence?: number; // 最低置信度阈值(0-1),低于此值的建议被丢弃(默认 0.6)
|
|
729
|
+
maxSuggestions?: number; // 单次对话最大建议数(默认 3)
|
|
730
|
+
}
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
#### 工作流程
|
|
734
|
+
|
|
735
|
+
```
|
|
736
|
+
对话结束 → Agent.postProcess 异步调用 autoConfigRefiner.analyze()
|
|
737
|
+
→ 有后台 Provider:LLM 分析提取建议
|
|
738
|
+
→ 无后台 Provider:启发式规则降级提取
|
|
739
|
+
→ 短对话(<20 字)跳过
|
|
740
|
+
→ 通过 onConfigSuggestion 回调通知 ConfigManager
|
|
741
|
+
→ ConfigManager 转发给宿主注册的 handler
|
|
742
|
+
→ 宿主 UI 展示建议卡片
|
|
743
|
+
→ 用户确认 → config.confirmConfigSuggestion() 写入配置文件
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
#### `config` 公开方法
|
|
747
|
+
|
|
748
|
+
| 方法 | 用途 |
|
|
749
|
+
|------|------|
|
|
750
|
+
| `config.onConfigSuggestion(handler)` | 注册配置建议回调(宿主 UI 展示建议卡片) |
|
|
751
|
+
| `config.confirmConfigSuggestion(suggestion)` | 确认建议,写入配置文件(持久化) |
|
|
752
|
+
|
|
753
|
+
#### `ConfigSuggestion` 类型
|
|
754
|
+
|
|
755
|
+
```typescript
|
|
756
|
+
interface ConfigSuggestion {
|
|
757
|
+
type: 'rule' | 'persona' | 'skill';
|
|
758
|
+
name: string;
|
|
759
|
+
content: string;
|
|
760
|
+
confidence: number; // 0-1
|
|
761
|
+
source: string; // 建议来源描述
|
|
762
|
+
}
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
**双写机制**:
|
|
766
|
+
- `config.addRule()` → 写 SQLite(会话级,临时)
|
|
767
|
+
- `config.addSkill()` → 写 SQLite + SkillManager(session-only,运行时注入)
|
|
768
|
+
- `config.confirmConfigSuggestion()` → 写配置文件(真理源,重启后自动加载,适用于 rule/persona/skill 三种类型)
|
|
769
|
+
|
|
770
|
+
> **降级策略**:无后台 Provider 时,AutoConfigRefiner 使用启发式规则提取建议(非 LLM),建议质量较低但仍可用。单条建议回调失败时记日志并继续处理下一条,避免一条失败导致后续全部丢失。
|
|
771
|
+
|
|
772
|
+
---
|
|
773
|
+
|
|
774
|
+
## 十、用户画像(`agent.userProfile` · UserProfile)
|
|
775
|
+
|
|
776
|
+
用户画像从对话中自动提取用户事实(姓名、偏好、技能等),用于个性化 system prompt 注入。高置信度事实直接归档,低置信度事实标记为待确认,由宿主 UI 展示给用户确认。
|
|
777
|
+
|
|
778
|
+
### 类型定义
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
/** 用户画像子分类 */
|
|
782
|
+
type ProfileCategory = 'identity' | 'preference' | 'expertise' | 'habit' | 'history';
|
|
783
|
+
|
|
784
|
+
/** 用户画像条目 */
|
|
785
|
+
interface UserProfileEntry {
|
|
786
|
+
id: string; // 画像唯一 ID(格式:profile:user-profile-{category}-{slug})
|
|
787
|
+
category: ProfileCategory;
|
|
788
|
+
fieldName: string; // 显式字段名(如 "姓名"/"住址",冲突检测基于 category+fieldName)
|
|
789
|
+
value: string; // 事实值(如 "姓名: 张三")
|
|
790
|
+
source: string; // 来源(哪一轮对话提到)
|
|
791
|
+
weight: number; // 权重(0-1)
|
|
792
|
+
confirmed: boolean; // 是否已确认(false 表示首次召回时需用户确认)
|
|
793
|
+
updatedAt: string; // 最后更新时间(ISO 8601)
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/** 事实提取的原始结果 */
|
|
797
|
+
interface ExtractedFact {
|
|
798
|
+
category: ProfileCategory;
|
|
799
|
+
fieldName: string; // 显式字段名(由提取器填充,冲突检测基于 category+fieldName)
|
|
800
|
+
value: string;
|
|
801
|
+
sourceTurn: string;
|
|
802
|
+
confidence: number; // 置信度 0-1(≥0.8 直接归档,否则标记待确认)
|
|
803
|
+
}
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
### `agent.userProfile` 公开方法
|
|
807
|
+
|
|
808
|
+
| 方法 | 用途 |
|
|
809
|
+
|------|------|
|
|
810
|
+
| `agent.userProfile.load()` | 启动时从存储加载所有已确认的画像条目 |
|
|
811
|
+
| `agent.userProfile.archiveFacts(facts)` | 实时归档:将提取的用户事实写入存储(高置信度直接归档,低置信度标记待确认) |
|
|
812
|
+
| `agent.userProfile.getConfirmed()` | 获取所有已确认的画像条目(system prompt 注入用) |
|
|
813
|
+
| `agent.userProfile.getPending()` | 获取所有待确认的画像条目(供宿主 UI 展示确认/拒绝操作) |
|
|
814
|
+
| `agent.userProfile.buildSystemPrompt()` | 构建 system prompt 中的用户画像段 |
|
|
815
|
+
| `agent.userProfile.confirm(id)` | 确认待确认条目(确认后写入存储) |
|
|
816
|
+
| `agent.userProfile.reject(id)` | 拒绝待确认条目(从缓存和存储中删除) |
|
|
817
|
+
|
|
818
|
+
> **注意**:`agent.userProfile` 在 `init()` 前返回 `null`。待确认条目仅存内存缓存,进程重启后丢失——宿主应定期查询 `getPending()` 展示给用户确认。
|
|
819
|
+
|
|
820
|
+
### 宿主接入示例
|
|
821
|
+
|
|
822
|
+
```typescript
|
|
823
|
+
// 启动后查询待确认条目,展示给用户
|
|
824
|
+
const pending = agent.userProfile?.getPending() ?? [];
|
|
825
|
+
for (const entry of pending) {
|
|
826
|
+
// 宿主 UI 展示确认对话框
|
|
827
|
+
const confirmed = await showConfirmDialog({
|
|
828
|
+
title: '确认用户画像',
|
|
829
|
+
message: `检测到:${entry.value}(${entry.category})`,
|
|
830
|
+
});
|
|
831
|
+
if (confirmed) {
|
|
832
|
+
await agent.userProfile?.confirm(entry.id);
|
|
833
|
+
} else {
|
|
834
|
+
await agent.userProfile?.reject(entry.id);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
---
|
|
840
|
+
|
|
841
|
+
## 十一、作品投影(`agent.works` · WorkProjectionManager)
|
|
842
|
+
|
|
843
|
+
作品投影是文件内容的轻量级摘要(50-100 字概要 + 结构 + 关键决策),存储在 SQLite 中供 Agent 快速召回,避免每次对话都读取完整文件。原始文件内容不进 SQLite,Agent 通过工具按需读取。
|
|
844
|
+
|
|
845
|
+
### 类型定义
|
|
846
|
+
|
|
847
|
+
```typescript
|
|
848
|
+
interface WorkProjectionEntry {
|
|
849
|
+
id: string; // 唯一 ID(work-proj-<slug>)
|
|
850
|
+
sourcePath: string; // 文件路径
|
|
851
|
+
fileHash: string; // 文件 hash(SHA-256,用于变更检测)
|
|
852
|
+
summary: string; // 概要(50-100 字)
|
|
853
|
+
structure: string[]; // 结构(章节/模块列表,2-8 个)
|
|
854
|
+
keyDecisions: string[];// 关键决策(1-3 个)
|
|
855
|
+
updatedAt: string; // 最后更新时间
|
|
856
|
+
}
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
### `agent.works` 公开方法
|
|
860
|
+
|
|
861
|
+
| 方法 | 用途 |
|
|
862
|
+
|------|------|
|
|
863
|
+
| `agent.works.ensureProjection(filePath, content, fileName?)` | 检查并更新作品投影(核心方法)。计算 hash → 查询已有投影 → 无则生成 / hash 变则重新生成 / hash 同则跳过。同文件并发调用时复用 in-flight Promise,避免重复 LLM 调用 |
|
|
864
|
+
| `agent.works.getProjection(filePath)` | 获取已有的作品投影(不触发生成) |
|
|
865
|
+
| `agent.works.loadAll()` | 加载所有作品投影(按 source 标签 `'work-projection'` 召回) |
|
|
866
|
+
|
|
867
|
+
> **注意**:`agent.works` 在 `init()` 前返回 `null`。`ensureProjection` 依赖后台 LLM Provider 生成摘要,未注入 `backgroundProvider` 时使用前台 Provider。
|
|
868
|
+
|
|
869
|
+
### 宿主接入示例
|
|
870
|
+
|
|
871
|
+
```typescript
|
|
872
|
+
// 宿主工具读取文件后,调用 ensureProjection 生成/更新投影
|
|
873
|
+
agent.tools.registerTool(
|
|
874
|
+
{
|
|
875
|
+
name: 'read_file',
|
|
876
|
+
description: '读取文件内容',
|
|
877
|
+
parameters: { /* ... */ },
|
|
878
|
+
},
|
|
879
|
+
async (args) => {
|
|
880
|
+
const content = await fs.readFile(args.path, 'utf-8');
|
|
881
|
+
// 异步生成投影(fire-and-forget,不阻塞工具返回)
|
|
882
|
+
void agent.works?.ensureProjection(args.path, content);
|
|
883
|
+
return content;
|
|
884
|
+
},
|
|
885
|
+
);
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
---
|
|
889
|
+
|
|
890
|
+
## 十二、Provider 管理
|
|
891
|
+
|
|
892
|
+
| 方法 | 用途 |
|
|
893
|
+
|------|------|
|
|
894
|
+
| `setProvider(provider)` | 运行时切换前台 Provider |
|
|
895
|
+
| `setBackgroundProvider(provider)` | 运行时切换后台 Provider |
|
|
896
|
+
|
|
897
|
+
Agent 不再管理 Provider 映射表,宿主自行管理。
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
## 十三、内部调试
|
|
902
|
+
|
|
903
|
+
> v1.0 起已移除 `getBuildCtx()` 和 `inspect()` 方法。宿主项目可通过以下渠道观察内核状态:
|
|
904
|
+
>
|
|
905
|
+
> - **事件系统**(§2.7):订阅 `memoryAdded` / `memoryRecalled` / `skillMatched` 等事件获取运行时动态
|
|
906
|
+
> - **可观测性 Tracer**(§十五):注入 `ITracer` 实现获取 AgentLoop 关键 span(RECALL / LLM_CALL / TOOL_EXEC / RESPONSE)
|
|
907
|
+
> - **`agent.memory.snapshot()`**(§4.1):获取 3 层记忆快照(working / bootstrap / archive)
|
|
908
|
+
> - **`agent.agentLoop.getMessages()`**(§4.4):获取工作记忆原始消息列表
|
|
909
|
+
|
|
910
|
+
---
|
|
911
|
+
|
|
912
|
+
## 十四、完整 API 一览
|
|
913
|
+
|
|
914
|
+
### Agent 面类直接方法
|
|
915
|
+
|
|
916
|
+
| 分组 | 方法 |
|
|
917
|
+
|------|------|
|
|
918
|
+
| 生命周期 | `init(projectPathOverride?)` / `close()` |
|
|
919
|
+
| 对话 | `chat(input, signal?)` / `chatSync(input, signal?)` / `forceReleaseChatLock()` |
|
|
920
|
+
| 事件 | `on()` / `off()` / `once()`(继承自 TypedEventEmitter) |
|
|
921
|
+
| 项目 / 会话 | `switchProject(nameOrPath)` / `rebuildComponents()` / `forkSession(targetSession?)` |
|
|
922
|
+
| Provider | `setProvider(provider)` / `setBackgroundProvider(provider)` |
|
|
923
|
+
| 归档模式 | `setArchiveMode(mode)` / `getArchiveMode()` |
|
|
924
|
+
| 角色 | `switchPersona(name)` / `getPersonaSwitchLockStatus()` / `injectAffect(affectString)` |
|
|
925
|
+
| 手动归档 | `archiveProfileFacts(input, options?)` / `archiveInsight(input, assistantContent, options?)` / `archiveSessionContent(date, session, options?)` |
|
|
926
|
+
| 配置热更新 | `reloadConfig(source?)` |
|
|
927
|
+
| 记忆治理 | `deduplicateMemories(signal?)` / `evaluateTimeliness(signal?)` / `runMemoryDecayOnce()` / `sourceHealth()` / `suggest(query?, options?)` / `detectConflicts(signal?)` |
|
|
928
|
+
| 指标 | `getMetrics()` |
|
|
929
|
+
|
|
930
|
+
### Agent 面类只读访问器
|
|
931
|
+
|
|
932
|
+
`initialized` / `context` / `provider` / `isBusy` / `lastInteractionAt` / `agentLoop` / `agentHistory` / `projects` / `security` / `sessionManager` / `persona` / `tools` / `skills` / `config` / `insight` / `memory` / `userProfile` / `works` / `polish`
|
|
933
|
+
|
|
934
|
+
### 各 Manager / 组件公开成员
|
|
935
|
+
|
|
936
|
+
| 访问器 | 类型 | 公开成员 |
|
|
937
|
+
|---------|---------|---------|
|
|
938
|
+
| `agent.persona` | `PersonaManager` | `.list` / `.activeName` / `.currentMode` / `.active` / `.switchPersona()` / `.setMode()` |
|
|
939
|
+
| `agent.tools` | `ToolExecutor` | `.list` / `.registerTool()` / `.execute()` |
|
|
940
|
+
| `agent.skills` | `SkillManager` | `.list` / `.match()` / `.register()` / `.buildSystemPrompt()` |
|
|
941
|
+
| `agent.config` | `ConfigManager` | `.addRule()` / `.addSimpleRule()` / `.addSkill()` / `.addSimpleSkill()` / `.onConfigSuggestion()` / `.confirmConfigSuggestion()` |
|
|
942
|
+
| `agent.insight` | `InsightExtractor` | `.classify(input)` / `.extract(userInput, assistantContent)` / `.setKeywords(keywords)` / `.setWriteExtensions(ext)` |
|
|
943
|
+
| `agent.memory` | `MemoryInspector` | 读:`.snapshot()` / `.search()` / `.searchHybrid()` / `.stats()` / `.list()` / `.getById()` / `.getBySource()` / `.listDeleted()` / `.getRelations()` / `.getAllRelations()` / `.getRelationPath()` / `.getRelationNeighbors()`;写:`.writeUpsert()` / `.writeBoost()` / `.writeDelete()` / `.writeRestore()` / `.writePurge()` / `.writePurgeExpired()` / `.writeAddRelation()` / `.writeRemoveRelation()` / `.writeRemoveRelationsByMemoryId()` |
|
|
944
|
+
| `agent.userProfile` | `UserProfile` | `.load()` / `.archiveFacts(facts)` / `.getConfirmed()` / `.getPending()` / `.buildSystemPrompt()` / `.confirm(id)` / `.reject(id)` |
|
|
945
|
+
| `agent.works` | `WorkProjectionManager` | `.ensureProjection(filePath, content, fileName?)` / `.getProjection(filePath)` / `.loadAll()` |
|
|
946
|
+
| `agent.polish` | `TextPolishManager` | `.polish(...)`(文本润色:LLM 语法修正 + 表达优化) |
|
|
947
|
+
|
|
948
|
+
> **说明**:`suggest()` / `sourceHealth()` 现为 Agent 层方法(`agent.suggest()` / `agent.sourceHealth()`),不再挂在 `agent.memory` 下。旧的 `memoryMutator` 访问器与 `MemoryMutator` 类已合并回 `MemoryInspector`,请勿再使用。
|
|
949
|
+
|
|
950
|
+
---
|
|
951
|
+
|
|
952
|
+
## 十五、可观测性(ITracer / ISpan)
|
|
953
|
+
|
|
954
|
+
Memora 内置轻量 Span/Trace 抽象,宿主注入实现后可观测 AgentLoop 行为。
|
|
955
|
+
|
|
956
|
+
### 15.1 ITracer 接口
|
|
957
|
+
|
|
958
|
+
```typescript
|
|
959
|
+
interface ITracer {
|
|
960
|
+
startSpan(name: string, attributes?: Record<string, string | number | boolean>): ISpan;
|
|
961
|
+
}
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
### 15.2 ISpan 接口
|
|
965
|
+
|
|
966
|
+
```typescript
|
|
967
|
+
interface ISpan {
|
|
968
|
+
setAttribute(key: string, value: string | number | boolean): void;
|
|
969
|
+
end(): void;
|
|
970
|
+
recordException(error: Error): void;
|
|
971
|
+
}
|
|
972
|
+
```
|
|
973
|
+
|
|
974
|
+
### 15.3 NoopTracer(默认实现)
|
|
975
|
+
|
|
976
|
+
```typescript
|
|
977
|
+
import { NOOP_TRACER } from '@zooique/memora';
|
|
978
|
+
|
|
979
|
+
// 不注入 tracer 时自动使用 NOOP_TRACER,零运行时开销
|
|
980
|
+
// NOOP_TRACER.startSpan() 返回共享的 NoopSpan 单例,所有方法为空操作
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
### 15.4 TRACE_SPANS 常量
|
|
984
|
+
|
|
985
|
+
```typescript
|
|
986
|
+
import { TRACE_SPANS } from '@zooique/memora';
|
|
987
|
+
|
|
988
|
+
TRACE_SPANS.RECALL // 'recall.recall' — 记忆召回阶段
|
|
989
|
+
TRACE_SPANS.LLM_CALL // 'llm.call' — LLM API 调用
|
|
990
|
+
TRACE_SPANS.TOOL_EXEC // 'tool.execute' — 工具执行
|
|
991
|
+
TRACE_SPANS.RESPONSE // 'response.generate' — 整轮响应
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
---
|
|
995
|
+
|
|
996
|
+
## 十六、工具错误码(ToolErrorCode)
|
|
997
|
+
|
|
998
|
+
工具执行失败时,错误结果包含 `[ERR:TOOL:code]` 前缀,供 Reflection 逻辑和宿主项目解析。
|
|
999
|
+
|
|
1000
|
+
### 16.1 错误码枚举
|
|
1001
|
+
|
|
1002
|
+
| 错误码 | 可重试 | 说明 |
|
|
1003
|
+
|--------|--------|------|
|
|
1004
|
+
| `PATH_NOT_ALLOWED` | ❌ | 路径不在白名单内 |
|
|
1005
|
+
| `FILE_NOT_FOUND` | ✅ | 文件不存在(LLM 可能用错路径) |
|
|
1006
|
+
| `PERMISSION_DENIED` | ❌ | 权限不足 |
|
|
1007
|
+
| `ARGUMENT_ERROR` | ✅ | 工具参数错误(LLM 可修正参数格式) |
|
|
1008
|
+
| `TOOL_TIMEOUT` | ✅ | 工具执行超时 |
|
|
1009
|
+
| `WRITE_REJECTED` | ❌ | 用户拒绝写入 |
|
|
1010
|
+
| `DIR_NOT_FOUND` | ✅ | 目录不存在 |
|
|
1011
|
+
| `UNKNOWN_TOOL` | ❌ | 未知工具 |
|
|
1012
|
+
| `CUSTOM_TOOL_FAILED` | ✅ | 自定义工具执行失败 |
|
|
1013
|
+
| `UNKNOWN` | ❌ | 通用错误 |
|
|
1014
|
+
|
|
1015
|
+
### 16.2 isRetryableErrorCode()
|
|
1016
|
+
|
|
1017
|
+
```typescript
|
|
1018
|
+
import { ToolErrorCode, isRetryableErrorCode } from '@zooique/memora';
|
|
1019
|
+
|
|
1020
|
+
isRetryableErrorCode(ToolErrorCode.FILE_NOT_FOUND); // true
|
|
1021
|
+
isRetryableErrorCode(ToolErrorCode.PATH_NOT_ALLOWED); // false
|
|
1022
|
+
```
|
|
1023
|
+
|
|
1024
|
+
---
|
|
1025
|
+
|
|
1026
|
+
## 十七、内容护栏(Guardrails)
|
|
1027
|
+
|
|
1028
|
+
### 17.1 护栏规则格式
|
|
1029
|
+
|
|
1030
|
+
护栏规则以 `source: "guardrail"` 记忆形式存储,放在 `configDir/rules/guardrails/` 目录下:
|
|
1031
|
+
|
|
1032
|
+
```markdown
|
|
1033
|
+
---
|
|
1034
|
+
name: 禁止执行代码
|
|
1035
|
+
source: guardrail
|
|
1036
|
+
---
|
|
1037
|
+
|
|
1038
|
+
pattern: /执行|运行|eval|exec/
|
|
1039
|
+
action: block
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
### 17.2 护栏行为
|
|
1043
|
+
|
|
1044
|
+
- **输入护栏**:用户输入注入上下文前检查,命中 `block` 时阻断对话
|
|
1045
|
+
- **输出护栏**:LLM 响应返回用户前检查,命中 `block` 时替换输出
|
|
1046
|
+
- **降级策略**:护栏自身异常时降级为"放行 + 记日志",永远不阻断对话
|
|
1047
|
+
|
|
1048
|
+
### 17.3 工具错误反思(Reflection)
|
|
1049
|
+
|
|
1050
|
+
当工具执行失败且错误码为 retryable 时,AgentLoop 自动注入 `[REFLECTION_HINT]` 系统消息,引导 LLM 修正参数后重试。默认最多重试 2 次(`maxReflectionRetries`)。
|
|
1051
|
+
|
|
1052
|
+
---
|
|
1053
|
+
|
|
1054
|
+
## 十八、类型导出
|
|
1055
|
+
|
|
1056
|
+
> 以下导出与 `src/index.ts` 完全对齐(v2.0.3)。`RecalledMemorySummary` 已在 P1-1 补齐导出。
|
|
1057
|
+
|
|
1058
|
+
```typescript
|
|
1059
|
+
// Agent 与流式事件
|
|
1060
|
+
export { Agent } from '@zooique/memora';
|
|
1061
|
+
export type {
|
|
1062
|
+
AgentChunk,
|
|
1063
|
+
ThinkingPhase,
|
|
1064
|
+
UIMessages,
|
|
1065
|
+
ArchiveMode,
|
|
1066
|
+
} from '@zooique/memora';
|
|
1067
|
+
export type {
|
|
1068
|
+
AgentOptions,
|
|
1069
|
+
AgentContext,
|
|
1070
|
+
AgentProjectEntry,
|
|
1071
|
+
} from '@zooique/memora';
|
|
1072
|
+
export { type AgentForkResult } from '@zooique/memora';
|
|
1073
|
+
export type { RecalledMemorySummary } from '@zooique/memora';
|
|
1074
|
+
|
|
1075
|
+
// 记忆快照与搜索(MemoryInspector)
|
|
1076
|
+
export type {
|
|
1077
|
+
MemorySnapshot,
|
|
1078
|
+
WorkingMemorySnapshot,
|
|
1079
|
+
BootstrapSnapshot,
|
|
1080
|
+
ArchiveSnapshot,
|
|
1081
|
+
AgentSearchHit,
|
|
1082
|
+
AgentStats,
|
|
1083
|
+
SuggestOptions,
|
|
1084
|
+
SuggestHit,
|
|
1085
|
+
SourceHealthStatus,
|
|
1086
|
+
SourceHealthEntry,
|
|
1087
|
+
SourceHealthReport,
|
|
1088
|
+
} from '@zooique/memora';
|
|
1089
|
+
// 记忆治理 / 健康度(Agent 层方法返回的报告类型)
|
|
1090
|
+
export type { DedupPair, DedupVerdict, DedupVerdictSummary, DedupReport } from '@zooique/memora';
|
|
1091
|
+
export type { TimelinessVerdict, TimelinessReport } from '@zooique/memora';
|
|
1092
|
+
export type { ConflictVerdict, ConflictReport } from '@zooique/memora';
|
|
1093
|
+
// 记忆治理统一门面
|
|
1094
|
+
export { MemoryGovernance } from '@zooique/memora';
|
|
1095
|
+
// 文本润色
|
|
1096
|
+
export type { PolishResult } from '@zooique/memora';
|
|
1097
|
+
export { AGENT_CONSTANTS, LOOP_CONSTANTS } from '@zooique/memora';
|
|
1098
|
+
|
|
1099
|
+
// 工具
|
|
1100
|
+
export type { ToolDefinition, ToolHandler, ToolContext, WriteExtensions } from '@zooique/memora';
|
|
1101
|
+
|
|
1102
|
+
// 配置建议
|
|
1103
|
+
export type { ConfigSuggestion, ConfigSuggestionHandler } from '@zooique/memora';
|
|
1104
|
+
|
|
1105
|
+
// Insight
|
|
1106
|
+
export type { MemoryKeywords } from '@zooique/memora';
|
|
1107
|
+
// RelationBuilder(P1-3 拆分,封装 ADR-014 关系构建逻辑)
|
|
1108
|
+
export { RelationBuilder } from '@zooique/memora';
|
|
1109
|
+
export type { ConflictInfo } from '@zooique/memora';
|
|
1110
|
+
|
|
1111
|
+
// 会话归档
|
|
1112
|
+
export type { SessionArchiveResult } from '@zooique/memora';
|
|
1113
|
+
// 作品投影
|
|
1114
|
+
export type { WorkProjectionEntry } from '@zooique/memora';
|
|
1115
|
+
// AutoConfigRefiner
|
|
1116
|
+
export type { AutoConfigRefinerOptions } from '@zooique/memora';
|
|
1117
|
+
|
|
1118
|
+
// 记忆
|
|
1119
|
+
export { SOURCE_LABELS } from '@zooique/memora';
|
|
1120
|
+
export type { Memory } from '@zooique/memora';
|
|
1121
|
+
export { inferSource, escapeLike, validateSource } from '@zooique/memora';
|
|
1122
|
+
export type { SourceValidationSeverity } from '@zooique/memora';
|
|
1123
|
+
export type { IMemoryStorage } from '@zooique/memora';
|
|
1124
|
+
export { InMemoryStorage } from '@zooique/memora';
|
|
1125
|
+
// 治理共享常量(衰减/提升/上限)
|
|
1126
|
+
export { BOOST_INCREMENT, SCORE_CEILING, DECAY_FLOOR, DECAY_AGE_DAYS, DECAY_AMOUNT } from '@zooique/memora';
|
|
1127
|
+
export type { ISessionStore, SessionMessage } from '@zooique/memora';
|
|
1128
|
+
export type { ForkResult } from '@zooique/memora';
|
|
1129
|
+
|
|
1130
|
+
// 记忆关系(ADR-014 侧车模型)
|
|
1131
|
+
export { RELATION_TYPES, RELATION_WEIGHTS } from '@zooique/memora';
|
|
1132
|
+
export type { MemoryRelation, RelationDirection, RelationPath, RelationNeighbor } from '@zooique/memora';
|
|
1133
|
+
export type { IMemoryRelationStore } from '@zooique/memora';
|
|
1134
|
+
export { InMemoryRelationStore } from '@zooique/memora';
|
|
1135
|
+
|
|
1136
|
+
// 项目注册表 + 锁文件管理(P1-4 拆分)
|
|
1137
|
+
export { ProjectRegistry } from '@zooique/memora';
|
|
1138
|
+
export type { ProjectEntry } from '@zooique/memora';
|
|
1139
|
+
export { LockManager } from '@zooique/memora';
|
|
1140
|
+
|
|
1141
|
+
// 用户画像
|
|
1142
|
+
export type { UserProfileEntry, ProfileCategory, ExtractedFact } from '@zooique/memora';
|
|
1143
|
+
|
|
1144
|
+
// 向量存储
|
|
1145
|
+
export { JsonVectorStore } from '@zooique/memora';
|
|
1146
|
+
export type { IVectorStore, EmbeddingService } from '@zooique/memora';
|
|
1147
|
+
export { EmbeddingProvider } from '@zooique/memora';
|
|
1148
|
+
export type { EmbeddingConfig, EmbeddingResult, EmbeddingOptions } from '@zooique/memora';
|
|
1149
|
+
|
|
1150
|
+
// 事件系统
|
|
1151
|
+
export { TypedEventEmitter } from '@zooique/memora';
|
|
1152
|
+
export type { AgentEventMap, AgentEventName, AgentEventHandler } from '@zooique/memora';
|
|
1153
|
+
|
|
1154
|
+
// 可观测性
|
|
1155
|
+
export type { ITracer, ISpan, AgentMetrics } from '@zooique/memora';
|
|
1156
|
+
export { NOOP_TRACER, TRACE_SPANS } from '@zooique/memora';
|
|
1157
|
+
|
|
1158
|
+
// 错误码
|
|
1159
|
+
export { MemoraError, ToolErrorCode, isRetryableErrorCode } from '@zooique/memora';
|
|
1160
|
+
export { toError } from '@zooique/memora';
|
|
1161
|
+
export type { ToolErrorCodeValue } from '@zooique/memora';
|
|
1162
|
+
|
|
1163
|
+
// 日志
|
|
1164
|
+
export type { ILogger } from '@zooique/memora';
|
|
1165
|
+
export { setLogger, logger } from '@zooique/memora';
|
|
1166
|
+
|
|
1167
|
+
// 召回
|
|
1168
|
+
export { recall, extractKeywords } from '@zooique/memora';
|
|
1169
|
+
export type { RecallOptions } from '@zooique/memora';
|
|
1170
|
+
|
|
1171
|
+
// 角色
|
|
1172
|
+
export type { PersonaMode, Persona } from '@zooique/memora';
|
|
1173
|
+
|
|
1174
|
+
// 技能
|
|
1175
|
+
export type { SkillEntry, SkillMatch } from '@zooique/memora';
|
|
1176
|
+
|
|
1177
|
+
// LLM
|
|
1178
|
+
export { createLlmProvider, createProviderFromConfig } from '@zooique/memora';
|
|
1179
|
+
export type { ProviderConfig } from '@zooique/memora';
|
|
1180
|
+
export type { LlmProvider, ChatOptions } from '@zooique/memora';
|
|
1181
|
+
export type { LlmChunk } from '@zooique/memora';
|
|
1182
|
+
export { OpenAICompatibleProvider } from '@zooique/memora';
|
|
1183
|
+
export type { OpenAICompatibleConfig } from '@zooique/memora';
|
|
1184
|
+
|
|
1185
|
+
// 配置
|
|
1186
|
+
export { loadConfig } from '@zooique/memora';
|
|
1187
|
+
export type { Config } from '@zooique/memora';
|
|
1188
|
+
|
|
1189
|
+
// 工具函数
|
|
1190
|
+
export { segmentText, segmentLower } from '@zooique/memora';
|
|
1191
|
+
export { parseFrontmatter, serializeFrontmatter } from '@zooique/memora';
|
|
1192
|
+
export { safeSetTimeout, safeSetInterval, clearSafeTimeout, clearSafeInterval } from '@zooique/memora';
|
|
1193
|
+
export { isPlainObject } from '@zooique/memora';
|
|
1194
|
+
export { truncate } from '@zooique/memora';
|
|
1195
|
+
export { formatDateKey, todayDate } from '@zooique/memora';
|
|
1196
|
+
|
|
1197
|
+
// 安全
|
|
1198
|
+
export type {
|
|
1199
|
+
AuditEvent,
|
|
1200
|
+
AuditListener,
|
|
1201
|
+
Permission,
|
|
1202
|
+
WriteDecision,
|
|
1203
|
+
WriteConfirmationInfo,
|
|
1204
|
+
WriteConfirmationRequest,
|
|
1205
|
+
} from '@zooique/memora';
|
|
1206
|
+
|
|
1207
|
+
// 评估
|
|
1208
|
+
export type { EvalScenario, EvalExpectation, EvalResult } from '@zooique/memora';
|
|
1209
|
+
export { collectAgentChunks, evaluateResult } from '@zooique/memora';
|
|
1210
|
+
export { EVAL_SCENARIOS, EvalRunner } from '@zooique/memora';
|
|
1211
|
+
export type { EvalRunnerOptions, EvalSummary } from '@zooique/memora';
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1214
|
+
---
|
|
1215
|
+
|
|
1216
|
+
## 十九、安全与约束
|
|
1217
|
+
|
|
1218
|
+
### 核心库零越界
|
|
1219
|
+
|
|
1220
|
+
| 检查项 | 结论 |
|
|
1221
|
+
|--------|------|
|
|
1222
|
+
| 核心库 `console.*` 调用 | 0 处 |
|
|
1223
|
+
| 核心库 `process.stdin/stdout` | 0 处 |
|
|
1224
|
+
| 核心库写配置文件 | 0 处 |
|
|
1225
|
+
| 核心库 `readFileSync/writeFileSync` 写宿主业务文件 | 0 处 |
|
|
1226
|
+
|
|
1227
|
+
### 内部数据写入(不越界)
|
|
1228
|
+
|
|
1229
|
+
Agent 内部维护 `projects.json`(项目注册表)和 `.lock`(项目锁),路径在 `~/.memora/`,属于 Agent 自己的状态管理。
|
|
1230
|
+
|
|
1231
|
+
---
|
|
1232
|
+
|
|
1233
|
+
**版本**:v2.0.3
|
|
1234
|
+
**最后更新**:2026-08-01
|
|
1235
|
+
**配套文档**:[memora-接入指南.md](./memora-接入指南.md)(步骤式教程)
|