@zooique/memora 3.0.0 → 4.0.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.
Files changed (154) hide show
  1. package/CHANGELOG.md +721 -6
  2. package/README.en.md +6 -6
  3. package/README.md +303 -303
  4. package/config.example.json +1 -8
  5. package/dist/agent/agent.d.ts +48 -4
  6. package/dist/agent/agent.d.ts.map +1 -1
  7. package/dist/agent/agent.js +130 -12
  8. package/dist/agent/agent.js.map +1 -1
  9. package/dist/agent/assembler.d.ts +19 -5
  10. package/dist/agent/assembler.d.ts.map +1 -1
  11. package/dist/agent/assembler.js +79 -16
  12. package/dist/agent/assembler.js.map +1 -1
  13. package/dist/agent/backgroundTasks.d.ts +187 -0
  14. package/dist/agent/backgroundTasks.d.ts.map +1 -0
  15. package/dist/agent/backgroundTasks.js +307 -0
  16. package/dist/agent/backgroundTasks.js.map +1 -0
  17. package/dist/agent/builtinToolHandlers.d.ts +2 -1
  18. package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
  19. package/dist/agent/builtinToolHandlers.js +8 -4
  20. package/dist/agent/builtinToolHandlers.js.map +1 -1
  21. package/dist/agent/builtinTools.d.ts +15 -1
  22. package/dist/agent/builtinTools.d.ts.map +1 -1
  23. package/dist/agent/builtinTools.js +107 -27
  24. package/dist/agent/builtinTools.js.map +1 -1
  25. package/dist/agent/constants.d.ts +31 -0
  26. package/dist/agent/constants.d.ts.map +1 -1
  27. package/dist/agent/constants.js +31 -0
  28. package/dist/agent/constants.js.map +1 -1
  29. package/dist/agent/guardRail.d.ts +11 -0
  30. package/dist/agent/guardRail.d.ts.map +1 -1
  31. package/dist/agent/guardRail.js +36 -1
  32. package/dist/agent/guardRail.js.map +1 -1
  33. package/dist/agent/loop.d.ts +276 -24
  34. package/dist/agent/loop.d.ts.map +1 -1
  35. package/dist/agent/loop.js +593 -93
  36. package/dist/agent/loop.js.map +1 -1
  37. package/dist/agent/managers/archiveCoordinator.d.ts +5 -2
  38. package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -1
  39. package/dist/agent/managers/archiveCoordinator.js +17 -2
  40. package/dist/agent/managers/archiveCoordinator.js.map +1 -1
  41. package/dist/agent/managers/loopMetrics.d.ts +14 -0
  42. package/dist/agent/managers/loopMetrics.d.ts.map +1 -1
  43. package/dist/agent/managers/loopMetrics.js +15 -0
  44. package/dist/agent/managers/loopMetrics.js.map +1 -1
  45. package/dist/agent/managers/memoryInspector.d.ts +1 -8
  46. package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
  47. package/dist/agent/managers/memoryInspector.js +6 -30
  48. package/dist/agent/managers/memoryInspector.js.map +1 -1
  49. package/dist/agent/managers/roundSummaryGenerator.d.ts +28 -0
  50. package/dist/agent/managers/roundSummaryGenerator.d.ts.map +1 -1
  51. package/dist/agent/managers/roundSummaryGenerator.js +67 -2
  52. package/dist/agent/managers/roundSummaryGenerator.js.map +1 -1
  53. package/dist/agent/managers/sessionArchiver.d.ts +21 -3
  54. package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
  55. package/dist/agent/managers/sessionArchiver.js +20 -3
  56. package/dist/agent/managers/sessionArchiver.js.map +1 -1
  57. package/dist/agent/managers/sessionManager.d.ts.map +1 -1
  58. package/dist/agent/managers/sessionManager.js +17 -0
  59. package/dist/agent/managers/sessionManager.js.map +1 -1
  60. package/dist/agent/managers/toolCallHelpers.d.ts +109 -28
  61. package/dist/agent/managers/toolCallHelpers.d.ts.map +1 -1
  62. package/dist/agent/managers/toolCallHelpers.js +93 -37
  63. package/dist/agent/managers/toolCallHelpers.js.map +1 -1
  64. package/dist/agent/messageHistory.d.ts.map +1 -1
  65. package/dist/agent/messageHistory.js +9 -5
  66. package/dist/agent/messageHistory.js.map +1 -1
  67. package/dist/agent/seed/orchestrator.d.ts +12 -1
  68. package/dist/agent/seed/orchestrator.d.ts.map +1 -1
  69. package/dist/agent/seed/orchestrator.js +12 -1
  70. package/dist/agent/seed/orchestrator.js.map +1 -1
  71. package/dist/agent/textSanitize.d.ts +36 -0
  72. package/dist/agent/textSanitize.d.ts.map +1 -0
  73. package/dist/agent/textSanitize.js +55 -0
  74. package/dist/agent/textSanitize.js.map +1 -0
  75. package/dist/agent/toolExecutor.d.ts +48 -22
  76. package/dist/agent/toolExecutor.d.ts.map +1 -1
  77. package/dist/agent/toolExecutor.js +372 -71
  78. package/dist/agent/toolExecutor.js.map +1 -1
  79. package/dist/agent/toolLedger.d.ts +93 -41
  80. package/dist/agent/toolLedger.d.ts.map +1 -1
  81. package/dist/agent/toolLedger.js +114 -42
  82. package/dist/agent/toolLedger.js.map +1 -1
  83. package/dist/agent/toolResultOffload.d.ts +8 -0
  84. package/dist/agent/toolResultOffload.d.ts.map +1 -1
  85. package/dist/agent/toolResultOffload.js +10 -3
  86. package/dist/agent/toolResultOffload.js.map +1 -1
  87. package/dist/agent/toolRunner.d.ts +14 -7
  88. package/dist/agent/toolRunner.d.ts.map +1 -1
  89. package/dist/agent/toolRunner.js +71 -29
  90. package/dist/agent/toolRunner.js.map +1 -1
  91. package/dist/agent/tracer.d.ts +13 -1
  92. package/dist/agent/tracer.d.ts.map +1 -1
  93. package/dist/agent/types.d.ts +67 -6
  94. package/dist/agent/types.d.ts.map +1 -1
  95. package/dist/code-exec/types.d.ts +9 -0
  96. package/dist/code-exec/types.d.ts.map +1 -1
  97. package/dist/index.d.ts +21 -23
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +36 -28
  100. package/dist/index.js.map +1 -1
  101. package/dist/memory/roundStore.d.ts +67 -81
  102. package/dist/memory/roundStore.d.ts.map +1 -1
  103. package/dist/memory/roundStore.js +4 -15
  104. package/dist/memory/roundStore.js.map +1 -1
  105. package/dist/memory/types.d.ts +7 -0
  106. package/dist/memory/types.d.ts.map +1 -1
  107. package/dist/memory/types.js +4 -0
  108. package/dist/memory/types.js.map +1 -1
  109. package/dist/role-pack/rolePackManager.d.ts +42 -10
  110. package/dist/role-pack/rolePackManager.d.ts.map +1 -1
  111. package/dist/role-pack/rolePackManager.js +65 -12
  112. package/dist/role-pack/rolePackManager.js.map +1 -1
  113. package/dist/role-pack/strategyKeys.d.ts +36 -0
  114. package/dist/role-pack/strategyKeys.d.ts.map +1 -1
  115. package/dist/role-pack/strategyKeys.js +45 -0
  116. package/dist/role-pack/strategyKeys.js.map +1 -1
  117. package/dist/security/confirmEntries.d.ts +44 -0
  118. package/dist/security/confirmEntries.d.ts.map +1 -0
  119. package/dist/security/confirmEntries.js +59 -0
  120. package/dist/security/confirmEntries.js.map +1 -0
  121. package/dist/security/pathGuard.d.ts +41 -5
  122. package/dist/security/pathGuard.d.ts.map +1 -1
  123. package/dist/security/pathGuard.js +125 -4
  124. package/dist/security/pathGuard.js.map +1 -1
  125. package/dist/skill/skillScriptRunner.d.ts +147 -15
  126. package/dist/skill/skillScriptRunner.d.ts.map +1 -1
  127. package/dist/skill/skillScriptRunner.js +479 -68
  128. package/dist/skill/skillScriptRunner.js.map +1 -1
  129. package/dist/utils/configResourceManager.d.ts +6 -2
  130. package/dist/utils/configResourceManager.d.ts.map +1 -1
  131. package/dist/utils/configResourceManager.js +8 -2
  132. package/dist/utils/configResourceManager.js.map +1 -1
  133. package/dist/utils/errors.d.ts +9 -0
  134. package/dist/utils/errors.d.ts.map +1 -1
  135. package/dist/utils/errors.js +9 -0
  136. package/dist/utils/errors.js.map +1 -1
  137. package/dist/utils/eventEmitter.d.ts +57 -2
  138. package/dist/utils/eventEmitter.d.ts.map +1 -1
  139. package/dist/utils/eventEmitter.js +23 -0
  140. package/dist/utils/eventEmitter.js.map +1 -1
  141. package/dist/utils/time.d.ts +5 -2
  142. package/dist/utils/time.d.ts.map +1 -1
  143. package/dist/utils/time.js +5 -2
  144. package/dist/utils/time.js.map +1 -1
  145. package/docs/memora-api-reference.md +121 -20
  146. package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +6 -5
  147. package/package.json +4 -4
  148. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/persona.md +46 -46
  149. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/rules.md +16 -15
  150. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/emotion-wave.md +46 -46
  151. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/foreshadow.md +29 -29
  152. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/outline-expand.md +48 -46
  153. 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 +441 -441
  154. package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-bible.md +62 -60
package/README.md CHANGED
@@ -1,303 +1,303 @@
1
- # Memora
2
-
3
- > **带治理能力的 Agent 记忆内核** — 本地、私有、零依赖。不是框架,是内核。
4
-
5
- [![npm](https://img.shields.io/npm/v/@zooique/memora)](https://www.npmjs.com/package/@zooique/memora)
6
- [![Node.js](https://img.shields.io/badge/Node.js-22%20LTS-339933)](https://nodejs.org)
7
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org)
8
- [![Coverage](https://img.shields.io/badge/coverage-covered-brightgreen)](https://vitest.dev)
9
- [![Tests](https://img.shields.io/badge/tests-2700%2B%20passed-brightgreen)](https://vitest.dev)
10
- [![Dependencies](https://img.shields.io/badge/runtime%20deps-0-yellowgreen)](package.json)
11
- [![License](https://img.shields.io/badge/license-MIT-yellow)](LICENSE)
12
-
13
- **English** → [README.en.md](./README.en.md)
14
-
15
- ---
16
-
17
- ## 你遇到了什么问题?
18
-
19
- - **LLM 每次对话都从零开始** — 用户记得上次聊过什么,Agent 不记得
20
- - **现有记忆方案要么太重(框架绑定)要么太浅(只有 CRUD)** — 缺少去重、冲突检测、写时取代等治理能力
21
- - **记忆和角色混在一起** — 换个角色人格,历史记忆也跟着丢了
22
- - **数据不想上云** — 需要一个本地、私有、不依赖外部服务的记忆层
23
-
24
- ## Memora 怎么解决
25
-
26
- Memora 是一个 **Agent 记忆内核**——不绑定任何框架,不依赖任何云服务,专注于一件事:**让 Agent 拥有跨会话、跨话题的长期记忆,并且记忆是干净的。**
27
-
28
- "干净"意味着:语义去重、冲突检测、写时取代(supersede)、命中即刷新最近使用(`accessedAt`,参与排序)——**不对记忆做重要度加权**,也不是简单地把历史堆进上下文窗口。
29
-
30
- ```typescript
31
- import { Agent, createProviderFromConfig } from '@zooique/memora';
32
-
33
- const agent = new Agent({
34
- projectPath: '/your/project',
35
- dataDir: '/your/project/.memora-data', // 记忆数据目录(必填)
36
- provider: createProviderFromConfig('primary', {
37
- provider: 'openaiCompatible',
38
- apiKey: process.env.LLM_API_KEY!,
39
- baseUrl: 'https://api.openai.com/v1',
40
- model: 'gpt-4o',
41
- }),
42
- });
43
- await agent.init();
44
-
45
- // 对话 — 记忆自动沉淀
46
- for await (const chunk of agent.chat('我喜欢 TypeScript')) {
47
- process.stdout.write(chunk.content);
48
- }
49
-
50
- // 下次对话 — LLM 可自行调用 search_memories 取回这条记忆
51
- const reply = await agent.chatSync('我喜欢什么语言?');
52
-
53
- // 记忆治理 — 语义去重 / 冲突检测 / 来源健康诊断
54
- await agent.governance.deduplicate();
55
- await agent.governance.detectConflicts();
56
- const health = agent.governance.sourceHealth();
57
-
58
- await agent.close();
59
- ```
60
-
61
- > **边界声明**:memora 是**不可独立运行的纯逻辑内核**——持久化 / 沙箱 / 可观测 / CLI·UI 均由宿主注入。内核保证**接口契约 + 单测验证的逻辑正确性**,agent 级行为评估由宿主自行承担。
62
-
63
- > **零依赖如何成立(2026-09-21 审计)**:「零依赖」特指**零第三方运行时依赖**。内核仅使用 Node 内置模块(`node:fs` / `node:path` / `node:crypto` / `node:os` / `node:child_process`),6 类共见于 18 个生产文件,全部必要、无冗余。文件落盘(记忆 / 角色包 / 原子写 / 技能脚本执行)走**接口 + 内存默认实现**(如 `ISessionStore` → `InMemorySessionStore`),持久化 sink 交由宿主注入 `WorkspaceSessionStore` 等实现替换——这既支撑「本地、私有、零依赖」卖点,也遵守「持久化由宿主注入」边界。
64
-
65
- ---
66
-
67
- ## 为什么选择 Memora?
68
-
69
- | | Memora | 向量记忆库 (agent-memory, MemStack) | 框架内置记忆 (Mastra, LangGraph) |
70
- |---|---|---|---|
71
- | **记忆治理** | ✅ 去重+冲突+写时取代 | ⚠️ 仅衰减或无治理 | ⚠️ 部分支持 |
72
- | **框架绑定** | ✅ 零绑定,纯内核 | ✅ 独立 | ❌ 绑定特定框架 |
73
- | **数据隐私** | ✅ 100% 本地 | ✅ 本地 | ⚠️ 部分云端 |
74
- | **运行时依赖** | ✅ 零(仅 node:*) | ❌ SQLite / better-sqlite3 | ❌ 重依赖 |
75
- | **角色/记忆分离** | ✅ 角色包边界纪律 | ❌ 无角色概念 | ⚠️ 简单 prompt |
76
- | **Embeddable** | ✅ 任何 Node.js 宿主 | ✅ 独立库 | ❌ 框架内使用 |
77
-
78
- **一句话定位**:如果你想要一个**不绑定框架、有治理能力、零依赖**的 memory + agent 内核,Memora 有清晰的差异化——它不是一个记忆 server / CLI / MCP 工具,而是一个可嵌入宿主、含完整执行闭环(loop / 工具 / 上下文 / 角色包 / 记忆即摘要)的纯逻辑内核。
79
-
80
- > **生态定位(2026-09-21 实证)**:npm 上 agent 类包已分两轴——**引擎轴**(loop/工具执行:`@ownware/loom`、`@hbbio/nanoagent`、`@imzx/imzx`、`thoth-agent` 等)与**记忆层轴**(`@agentmemory/agentmemory`、`mem0`、`flair`、`honcho`、`engram`、`agentic-memory` 等)。Memora 同时触及两轴,但**具体组合无人占据**:① 引擎轴同等竞品均有运行时依赖或绑定特定 runtime(loom=7 deps、imzx=11 deps、nanoagent 绑定 bun),而 Memora 是**纯 Node 零第三方运行时依赖**;② 记忆层包(engram / agentic-memory 等)只做记忆,**不提供执行内核**;③ 引擎轴包(loom 等)只做**会话内**上下文 / checkpoint,**没有跨会话被治理的长期记忆**(内存治理:去重 / 冲突检测 / supersede 写时取代 / 角色包隔离)。**护城河 = 治理型长期记忆 + 角色包隔离,以纯 Node 零依赖、宿主内嵌形态交付**。引擎轴上有 [loom](https://www.npmjs.com/package/@ownware/loom) 这样的强对手,不应与其在「引擎」轴上对拼;竞争力聚焦在「被治理的记忆 + 角色包」这一 layer。
81
-
82
- > **可被复用去开发 Agent(是)**:Memora 生来就是**宿主注入型的内核库**——`Agent` 门面 + `loop` 执行闭环 + 工具注入接口(web_search / web_fetch / run_code / search_project)+ `createProviderFromConfig`(可接任意 OpenAI 兼容 LLM),任何 Node.js 宿主都能用它搭出**带记忆和角色的自有 Agent**(聊天框、桌面精灵、文档助理、运算 worker……)。这正是设计意图:它只有接口、没有形态,形态由宿主定义。唯一前提是宿主需提供持久化 / 沙箱 / UI 等外围(内核不内置 sink)。
83
-
84
- ---
85
-
86
- ## 设计哲学
87
-
88
- > **摘要即记忆(memory-as-summary)。**
89
- >
90
- > 对话即原料:每轮 turn 结束后异步生成一条轮次摘要(round-summary),它是唯一记忆单元;原始对话记录独立存储,经 `sessionName + roundId` 溯源可回溯。人格 / 规则 / 技能归角色包,不进记忆库(见 memory-role-pack-boundary-rules.md)。
91
-
92
- Memora 是一个**无法独立运行**的智能大脑内核——它只有接口,没有"形态"。CLI、WebUI、桌面精灵、小说生成器都是它的"宿主",宿主负责给它身体(UI)、血管(Provider)、神经网络(事件回路)。
93
-
94
- > **版本定位(v3.0.0)**:**Node.js 专属 · 零第三方运行时依赖的 Agent 内核**。3.0.0 是架构收敛后的第一个稳定基线,API 与结构以 3.0.0 为准。
95
-
96
- ---
97
-
98
- ## 核心能力
99
-
100
- | 能力 | 说明 |
101
- |------|------|
102
- | **长期记忆沉淀** | 跨会话、跨话题的记忆持久化 + 工具化召回(`search_memories`;**不自动注入**) |
103
- | **记忆检索工具** | 纯关键词检索(`search_memories`),命中刷新 `accessedAt`(语义向量通道已随 B0 收编,2026-09-18) |
104
- | **记忆治理** | supersede 写时取代 + 命中刷新(`accessedAt` 参与排序,**不做重要度加权**)+ 语义去重 + 冲突检测,经 `agent.governance` 门面暴露(去重 / 冲突由 LLM 判断) |
105
- | **Agent 与角色分离** | Agent 是纯记忆引擎,角色是人格载体。换角色不丢记忆 |
106
- | **统一记忆模型** | 一切统一为「记忆」,通过 `source` 开放字符串区分,无封闭枚举 |
107
- | **领域可插拔** | 同一套架构,加载不同记忆配置即可适配不同领域 |
108
- | **零第三方依赖内核** | 依赖 Node.js 内置 `node:*` 模块,持久化由宿主通过接口注入 |
109
- | **可观测性** | ITracer 接口 + 结构化 span,宿主可接入任意 APM |
110
- | **外部世界工具** | 条件性暴露 `web_search` / `web_fetch` / `run_code`——宿主注入对应 provider 才启用 |
111
-
112
- ## 快速开始
113
-
114
- ### 安装
115
-
116
- ```bash
117
- npm install @zooique/memora
118
- ```
119
-
120
- ### 创建 Agent
121
-
122
- ```typescript
123
- import { Agent, createProviderFromConfig } from '@zooique/memora';
124
-
125
- // 宿主职责:创建 LLM Provider(兼容所有 OpenAI Chat Completions 协议的服务)
126
- // createProviderFromConfig 是唯一规范入口(baseUrl+model+apiKey → 校验后创建,provider 选择策略归宿主);
127
- // createLlmProvider(loadConfig()) 仅当你把整份 Config 托管给内核时用作便利(active 选择在内核侧)。
128
- const provider = createProviderFromConfig('primary', {
129
- provider: 'openaiCompatible',
130
- apiKey: process.env.LLM_API_KEY!,
131
- baseUrl: 'https://api.xiaomimimo.com/v1',
132
- model: 'deepseek-chat',
133
- });
134
-
135
- // 创建 Agent
136
- const agent = new Agent({
137
- projectPath: '/path/to/project',
138
- provider,
139
- configDir: '/path/to/agent-config', // role-packs / skills
140
- dataDir: '/path/to/project/.memora-data', // 记忆数据存储目录(必填,建议绝对路径)
141
- });
142
-
143
- await agent.init();
144
- ```
145
-
146
- ### 对话(流式)
147
-
148
- ```typescript
149
- for await (const chunk of agent.chat('你好,记住我喜欢 TypeScript')) {
150
- if (chunk.type === 'text') {
151
- process.stdout.write(chunk.content);
152
- }
153
- }
154
-
155
- // 下一次对话,LLM 可自行调用 search_memories 取回"喜欢 TypeScript"这条记忆
156
- const reply = await agent.chatSync('我喜欢什么语言?');
157
- // → LLM 检索后基于召回结果回答
158
- ```
159
-
160
- ### 记忆管理
161
-
162
- ```typescript
163
- // 搜索记忆(limit 为数字)
164
- const hits = await agent.memory.searchByKeyword('TypeScript 偏好', 5);
165
-
166
- // 记忆治理(经 agent.governance 门面委托暴露,LLM 判断)
167
- const report = await agent.governance.deduplicate();
168
- console.log(`去重 ${report.deduplicatedCount} 条`);
169
-
170
- const conflicts = await agent.governance.detectConflicts();
171
-
172
- // 来源健康诊断(纯计算,不调 LLM):逐 source 统计数量 / 距最近访问天数(score 退役后仅存事实观测)
173
- const health = agent.governance.sourceHealth();
174
- console.log(health?.sources);
175
- ```
176
-
177
- ### 关闭
178
-
179
- ```typescript
180
- await agent.close();
181
- ```
182
-
183
- ## 架构
184
-
185
- ```
186
- ┌────────────────────────────────────────────────────────────┐
187
- │ 宿主程序(CLI / 桌面精灵 / 小说生成器 / WebUI) │
188
- │ ┌─────────────────┐ ┌──────────────────┐ │
189
- │ │ LLM Provider 实例 │◄───│ API Key / baseUrl │ ← 宿主职责 │
190
- │ └────────┬────────┘ └──────────────────┘ │
191
- │ │ 注入 │
192
- │ ▼ │
193
- │ ┌──────────────────────────────────────────┐ │
194
- │ │ Memora 内核(Agent) │ │
195
- │ │ - chat(input) → 流式响应 │ │
196
- │ │ - 纯关键词记忆检索(search_memories) │ │
197
- │ │ - 记忆治理机制(去重/冲突/写时取代) │ │
198
- │ │ - 角色 / 技能匹配(渐进披露) │ │
199
- │ │ - 工具注册 / 工具执行 / 反思重试 │ │
200
- │ │ - 会话归档 / 轮次持久化 │ │
201
- │ └──────────────────────────────────────────┘ │
202
- └────────────────────────────────────────────────────────────┘
203
- ```
204
-
205
- ### 五大注入接口
206
-
207
- 内核通过接口与外部世界交互,宿主按需注入:
208
-
209
- | 接口 | 职责 | 内置实现 | 宿主注意 |
210
- |------|------|----------|----------|
211
- | `IMemoryStorage` | 记忆 CRUD + 搜索 + 按 source 查询 | `InMemoryStorage`(**仅内存占位,不持久化**) | 生产须宿主实现持久化(如 SQLite);重启后数据依赖宿主实现 |
212
- | `ISessionStore` | 会话历史 + 标题元数据持久化 | 无(宿主实现) | **不含检查点持久化**(2026-09-10 减法:跨重启恢复链整体退役)——中止/断电一律把未完成 turn 补全为完整 turn 身份、下次会话按历史加载;运行时暂停是同 turn 内续跑(内存态),无需跨进程载体 |
213
- | `ILogger` | 日志输出 | console fallback | 无 |
214
- | `ITracer` | 可观测性 span | `NOOP_TRACER` | 无 |
215
-
216
- ## 项目结构
217
-
218
- ```
219
- src/
220
- ├── index.ts # 库导出入口(类型 + 接口 + 函数 + 类导出,无 CLI)
221
- ├── agent/ # Agent 门面 + AgentLoop + seed/(turn)
222
- │ ├── agent.ts # 门面类(宿主唯一入口)
223
- │ ├── loop.ts # 核心循环(推理 → 工具调用 → 反思重试)
224
- │ ├── assembler.ts # 组件组装器(纯工厂)
225
- │ ├── contextManager.ts / contextPreparer.ts / toolExecutor.ts / toolRunner.ts ···
226
- │ ├── seed/ # turn(prepare → act/difficulty → reflect,含多 turn 任务编排)
227
- │ └── managers/ # 16 个专职 Manager/服务类(memoryInspector / memoryGovernance / roundSummaryGenerator / sessionManager / sessionArchiver / archiveCoordinator / workProjection / textPolishManager / chatLockManager 等)
228
- ├── memory/ # 记忆引擎(IMemoryStorage + InMemoryStorage + 纯关键词召回 / 融合排序 / 治理常量)
229
- ├── role-pack/ # 角色包(manifest 解析 + validator + strategyResolver + 能力映射)
230
- ├── skill/ # 技能管理(全局池 + 角色包绑定,渐进披露 + skillScriptRunner)
231
- ├── llm/ # LLM 适配层(provider + openaiCompatible + factory)
232
- ├── security/ # 安全策略(路径守卫 / 写入确认)
233
- ├── config/ # 配置加载
234
- ├── code-exec/ # 通用代码执行抽象(条件暴露)
235
- ├── web-search/ # 网络搜索抽象(条件暴露)
236
- ├── web-fetch/ # 网页抓取抽象(条件暴露)
237
- ├── logging/ # 日志(ILogger 接口 + console fallback)
238
- └── utils/ # 工具函数(scanner / segmenter / 事件系统 / 原子写)
239
- ```
240
-
241
- ## 技术栈
242
-
243
- | 类别 | 选型 | 决策依据 |
244
- |------|------|----------|
245
- | 运行时 | Node.js ≥ 22 LTS + TypeScript 5 strict + ESM | ADR-001 |
246
- | 数据层 | IMemoryStorage 接口(宿主注入持久化实现) | ADR-002 |
247
- | LLM 协议 | OpenAI Chat Completions 兼容(流式 SSE + Tool Calling) | ADR-003 |
248
- | 记忆模型 | 摘要即记忆(round-summary 单轨,可溯源回原始对话);source 开放字符串基元 | ADR-004 · memory-as-summary.md |
249
- | 冲突消解 | Memory 冲突改用 supersededBy 布尔标记 | ADR-021 |
250
- | 形态 | 纯逻辑库(零 native 依赖,CLI/UI 由宿主提供) | ADR-002 |
251
- | 安全 | 两级权限 + 路径白名单 + 审计日志 | ADR-006 |
252
- | 测试 | Vitest + MSW Mock LLM + InMemoryStorage | ADR-007 |
253
-
254
- ## 工程质量
255
-
256
- | 指标 | 数值 |
257
- |------|------|
258
- | 源码 | 117 个生产文件(src/,零第三方运行时依赖) |
259
- | 测试 | 内核 + 宿主双套 vitest,根配置统一跑(100+ 文件) |
260
- | 测试通过 | 2700+ 通过 / 1 skip |
261
- | 语句覆盖 | 90.65% |
262
- | 分支覆盖 | 84.83% |
263
- | 函数覆盖 | 92.41% |
264
- | 行覆盖 | 91.79% |
265
- | 运行时依赖 | **0** |
266
- | 架构决策记录 | 26 个 ADR |
267
-
268
- ## 开发命令
269
-
270
- ```bash
271
- npm test # 运行测试
272
- npm run test:cov # 运行测试 + 覆盖率
273
- npm run typecheck # TypeScript 类型检查
274
- npm run lint # ESLint 检查
275
- npm run build # 编译到 dist/
276
- ```
277
-
278
- ## 文档
279
-
280
- - [接入指南](docs/memora-接入指南.md) — 宿主项目开发者完整接入手册
281
- - [API 参考](docs/memora-api-reference.md) — 公共 API 速查
282
- - [角色包开放键指南](docs/role-pack-开放键指南.md) — manifest.json 开放键使用指南(三层消费方 + 速查)
283
- - [配置示例](config.example.json) — LLM / 安全配置模板
284
-
285
- ## 示例角色包(随包发布)
286
-
287
- npm 包内置 `role-packs/` 示例角色库(`共鸣小说家` / `白话方案设计师`),每个包为文件夹形态(`manifest.json` 核心控制 + `persona.md` / `rules.md` / `skills/` 内容层)。复制到 `configDir/role-packs/` 即可装载,未声明角色包时 Agent 仍可正常对话(走默认策略)。开放键使用详见 [角色包开放键指南](docs/role-pack-开放键指南.md);中立规范见仓库内 [role-pack-spec](docs/architecture/role-pack-spec.md)。
288
-
289
- ## 宿主项目
290
-
291
- [memora-vscode](https://gitee.com/zooique/memora/tree/main/hosts/memora-vscode) — VS Code 插件宿主(第一宿主),展示 Memora 内核的完整接入方式:JSON 文件持久化(`.memora/memories.json`)、纯关键词召回、角色包管理与记忆视图。
292
-
293
- ## 反馈
294
-
295
- 遇到问题或有改进建议?请在 [Gitee Issues](https://gitee.com/zooique/memora/issues)(主仓库)或 [GitHub Issues](https://github.com/zooique/memora/issues)(镜像)提交反馈。
296
-
297
- ## 贡献
298
-
299
- 本项目遵循"大树模型"工程哲学。技术决策记录(ADR)位于仓库 [.trae/decisions/](https://gitee.com/zooique/memora/tree/main/.trae/decisions)。
300
-
301
- ## 许可证
302
-
303
- [MIT](LICENSE)
1
+ # Memora
2
+
3
+ > **带治理能力的 Agent 记忆内核** — 本地、私有、零依赖。不是框架,是内核。
4
+
5
+ [![npm](https://img.shields.io/npm/v/@zooique/memora)](https://www.npmjs.com/package/@zooique/memora)
6
+ [![Node.js](https://img.shields.io/badge/Node.js-22%20LTS-339933)](https://nodejs.org)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org)
8
+ [![Coverage](https://img.shields.io/badge/coverage-covered-brightgreen)](https://vitest.dev)
9
+ [![Tests](https://img.shields.io/badge/tests-2700%2B%20passed-brightgreen)](https://vitest.dev)
10
+ [![Dependencies](https://img.shields.io/badge/runtime%20deps-0-yellowgreen)](package.json)
11
+ [![License](https://img.shields.io/badge/license-MIT-yellow)](LICENSE)
12
+
13
+ **English** → [README.en.md](./README.en.md)
14
+
15
+ ---
16
+
17
+ ## 你遇到了什么问题?
18
+
19
+ - **LLM 每次对话都从零开始** — 用户记得上次聊过什么,Agent 不记得
20
+ - **现有记忆方案要么太重(框架绑定)要么太浅(只有 CRUD)** — 缺少去重、冲突检测、写时取代等治理能力
21
+ - **记忆和角色混在一起** — 换个角色人格,历史记忆也跟着丢了
22
+ - **数据不想上云** — 需要一个本地、私有、不依赖外部服务的记忆层
23
+
24
+ ## Memora 怎么解决
25
+
26
+ Memora 是一个 **Agent 记忆内核**——不绑定任何框架,不依赖任何云服务,专注于一件事:**让 Agent 拥有跨会话、跨话题的长期记忆,并且记忆是干净的。**
27
+
28
+ "干净"意味着:语义去重、冲突检测、写时取代(supersede)、命中即刷新最近使用(`accessedAt`,参与排序)——**不对记忆做重要度加权**,也不是简单地把历史堆进上下文窗口。
29
+
30
+ ```typescript
31
+ import { Agent, createProviderFromConfig } from '@zooique/memora';
32
+
33
+ const agent = new Agent({
34
+ projectPath: '/your/project',
35
+ dataDir: '/your/project/.memora-data', // 记忆数据目录(必填)
36
+ provider: createProviderFromConfig('primary', {
37
+ provider: 'openaiCompatible',
38
+ apiKey: process.env.LLM_API_KEY!,
39
+ baseUrl: 'https://api.openai.com/v1',
40
+ model: 'gpt-4o',
41
+ }),
42
+ });
43
+ await agent.init();
44
+
45
+ // 对话 — 记忆自动沉淀
46
+ for await (const chunk of agent.chat('我喜欢 TypeScript')) {
47
+ process.stdout.write(chunk.content);
48
+ }
49
+
50
+ // 下次对话 — LLM 可自行调用 search_memories 取回这条记忆
51
+ const reply = await agent.chatSync('我喜欢什么语言?');
52
+
53
+ // 记忆治理 — 语义去重 / 冲突检测 / 来源健康诊断
54
+ await agent.governance.deduplicate();
55
+ await agent.governance.detectConflicts();
56
+ const health = agent.governance.sourceHealth();
57
+
58
+ await agent.close();
59
+ ```
60
+
61
+ > **边界声明**:memora 是**不可独立运行的纯逻辑内核**——持久化 / 沙箱 / 可观测 / CLI·UI 均由宿主注入。内核保证**接口契约 + 单测验证的逻辑正确性**,agent 级行为评估由宿主自行承担。
62
+
63
+ > **零依赖如何成立(2026-09-21 审计)**:「零依赖」特指**零第三方运行时依赖**。内核仅使用 Node 内置模块(`node:fs` / `node:path` / `node:crypto` / `node:os` / `node:child_process`),6 类共见于 18 个生产文件,全部必要、无冗余。文件落盘(记忆 / 角色包 / 原子写 / 技能脚本执行)走**接口 + 内存默认实现**(如 `ISessionStore` → `InMemorySessionStore`),持久化 sink 交由宿主注入 `WorkspaceSessionStore` 等实现替换——这既支撑「本地、私有、零依赖」卖点,也遵守「持久化由宿主注入」边界。
64
+
65
+ ---
66
+
67
+ ## 为什么选择 Memora?
68
+
69
+ | | Memora | 向量记忆库 (agent-memory, MemStack) | 框架内置记忆 (Mastra, LangGraph) |
70
+ |---|---|---|---|
71
+ | **记忆治理** | ✅ 去重+冲突+写时取代 | ⚠️ 仅衰减或无治理 | ⚠️ 部分支持 |
72
+ | **框架绑定** | ✅ 零绑定,纯内核 | ✅ 独立 | ❌ 绑定特定框架 |
73
+ | **数据隐私** | ✅ 100% 本地 | ✅ 本地 | ⚠️ 部分云端 |
74
+ | **运行时依赖** | ✅ 零(仅 node:*) | ❌ SQLite / better-sqlite3 | ❌ 重依赖 |
75
+ | **角色/记忆分离** | ✅ 角色包边界纪律 | ❌ 无角色概念 | ⚠️ 简单 prompt |
76
+ | **Embeddable** | ✅ 任何 Node.js 宿主 | ✅ 独立库 | ❌ 框架内使用 |
77
+
78
+ **一句话定位**:如果你想要一个**不绑定框架、有治理能力、零依赖**的 memory + agent 内核,Memora 有清晰的差异化——它不是一个记忆 server / CLI / MCP 工具,而是一个可嵌入宿主、含完整执行闭环(loop / 工具 / 上下文 / 角色包 / 记忆即摘要)的纯逻辑内核。
79
+
80
+ > **生态定位(2026-09-21 实证)**:npm 上 agent 类包已分两轴——**引擎轴**(loop/工具执行:`@ownware/loom`、`@hbbio/nanoagent`、`@imzx/imzx`、`thoth-agent` 等)与**记忆层轴**(`@agentmemory/agentmemory`、`mem0`、`flair`、`honcho`、`engram`、`agentic-memory` 等)。Memora 同时触及两轴,但**具体组合无人占据**:① 引擎轴同等竞品均有运行时依赖或绑定特定 runtime(loom=7 deps、imzx=11 deps、nanoagent 绑定 bun),而 Memora 是**纯 Node 零第三方运行时依赖**;② 记忆层包(engram / agentic-memory 等)只做记忆,**不提供执行内核**;③ 引擎轴包(loom 等)只做**会话内**上下文 / checkpoint,**没有跨会话被治理的长期记忆**(内存治理:去重 / 冲突检测 / supersede 写时取代 / 角色包隔离)。**护城河 = 治理型长期记忆 + 角色包隔离,以纯 Node 零依赖、宿主内嵌形态交付**。引擎轴上有 [loom](https://www.npmjs.com/package/@ownware/loom) 这样的强对手,不应与其在「引擎」轴上对拼;竞争力聚焦在「被治理的记忆 + 角色包」这一 layer。
81
+
82
+ > **可被复用去开发 Agent(是)**:Memora 生来就是**宿主注入型的内核库**——`Agent` 门面 + `loop` 执行闭环 + 工具注入接口(web_search / web_fetch / run_code / search_project)+ `createProviderFromConfig`(可接任意 OpenAI 兼容 LLM),任何 Node.js 宿主都能用它搭出**带记忆和角色的自有 Agent**(聊天框、桌面精灵、文档助理、运算 worker……)。这正是设计意图:它只有接口、没有形态,形态由宿主定义。唯一前提是宿主需提供持久化 / 沙箱 / UI 等外围(内核不内置 sink)。
83
+
84
+ ---
85
+
86
+ ## 设计哲学
87
+
88
+ > **摘要即记忆(memory-as-summary)。**
89
+ >
90
+ > 对话即原料:每轮 turn 结束后异步生成一条轮次摘要(round-summary),它是唯一记忆单元;原始对话记录独立存储,经 `sessionName + roundId` 溯源可回溯。人格 / 规则 / 技能归角色包,不进记忆库(见 memory-role-pack-boundary-rules.md)。
91
+
92
+ Memora 是一个**无法独立运行**的智能大脑内核——它只有接口,没有"形态"。CLI、WebUI、桌面精灵、小说生成器都是它的"宿主",宿主负责给它身体(UI)、血管(Provider)、神经网络(事件回路)。
93
+
94
+ > **版本定位(v3.0.0)**:**Node.js 专属 · 零第三方运行时依赖的 Agent 内核**。3.0.0 是架构收敛后的第一个稳定基线,API 与结构以 3.0.0 为准。**4.0.0(首个 major)**:导出面收敛(移除 54 个公共导出,逐条清单见 [CHANGELOG](./CHANGELOG.md) 的 `[4.0.0]` 区)+ `agent.memory.search()` 退役(唯一入口 `searchByKeyword()`)。
95
+
96
+ ---
97
+
98
+ ## 核心能力
99
+
100
+ | 能力 | 说明 |
101
+ |------|------|
102
+ | **长期记忆沉淀** | 跨会话、跨话题的记忆持久化 + 工具化召回(`search_memories`;**不自动注入**) |
103
+ | **记忆检索工具** | 纯关键词检索(`search_memories`),命中刷新 `accessedAt`(语义向量通道已随 B0 收编,2026-09-18) |
104
+ | **记忆治理** | supersede 写时取代 + 命中刷新(`accessedAt` 参与排序,**不做重要度加权**)+ 语义去重 + 冲突检测,经 `agent.governance` 门面暴露(去重 / 冲突由 LLM 判断) |
105
+ | **Agent 与角色分离** | Agent 是纯记忆引擎,角色是人格载体。换角色不丢记忆 |
106
+ | **统一记忆模型** | 一切统一为「记忆」,通过 `source` 开放字符串区分,无封闭枚举 |
107
+ | **领域可插拔** | 同一套架构,加载不同记忆配置即可适配不同领域 |
108
+ | **零第三方依赖内核** | 依赖 Node.js 内置 `node:*` 模块,持久化由宿主通过接口注入 |
109
+ | **可观测性** | ITracer 接口 + 结构化 span,宿主可接入任意 APM |
110
+ | **外部世界工具** | 条件性暴露 `web_search` / `web_fetch` / `run_code`——宿主注入对应 provider 才启用 |
111
+
112
+ ## 快速开始
113
+
114
+ ### 安装
115
+
116
+ ```bash
117
+ npm install @zooique/memora
118
+ ```
119
+
120
+ ### 创建 Agent
121
+
122
+ ```typescript
123
+ import { Agent, createProviderFromConfig } from '@zooique/memora';
124
+
125
+ // 宿主职责:创建 LLM Provider(兼容所有 OpenAI Chat Completions 协议的服务)
126
+ // createProviderFromConfig 是唯一规范入口(baseUrl+model+apiKey → 校验后创建,provider 选择策略归宿主);
127
+ // createLlmProvider(loadConfig()) 仅当你把整份 Config 托管给内核时用作便利(active 选择在内核侧)。
128
+ const provider = createProviderFromConfig('primary', {
129
+ provider: 'openaiCompatible',
130
+ apiKey: process.env.LLM_API_KEY!,
131
+ baseUrl: 'https://api.xiaomimimo.com/v1',
132
+ model: 'deepseek-chat',
133
+ });
134
+
135
+ // 创建 Agent
136
+ const agent = new Agent({
137
+ projectPath: '/path/to/project',
138
+ provider,
139
+ configDir: '/path/to/agent-config', // role-packs / skills
140
+ dataDir: '/path/to/project/.memora-data', // 记忆数据存储目录(必填,建议绝对路径)
141
+ });
142
+
143
+ await agent.init();
144
+ ```
145
+
146
+ ### 对话(流式)
147
+
148
+ ```typescript
149
+ for await (const chunk of agent.chat('你好,记住我喜欢 TypeScript')) {
150
+ if (chunk.type === 'text') {
151
+ process.stdout.write(chunk.content);
152
+ }
153
+ }
154
+
155
+ // 下一次对话,LLM 可自行调用 search_memories 取回"喜欢 TypeScript"这条记忆
156
+ const reply = await agent.chatSync('我喜欢什么语言?');
157
+ // → LLM 检索后基于召回结果回答
158
+ ```
159
+
160
+ ### 记忆管理
161
+
162
+ ```typescript
163
+ // 搜索记忆(limit 为数字)
164
+ const hits = await agent.memory.searchByKeyword('TypeScript 偏好', 5);
165
+
166
+ // 记忆治理(经 agent.governance 门面委托暴露,LLM 判断)
167
+ const report = await agent.governance.deduplicate();
168
+ console.log(`去重 ${report.deduplicatedCount} 条`);
169
+
170
+ const conflicts = await agent.governance.detectConflicts();
171
+
172
+ // 来源健康诊断(纯计算,不调 LLM):逐 source 统计数量 / 距最近访问天数(score 退役后仅存事实观测)
173
+ const health = agent.governance.sourceHealth();
174
+ console.log(health?.sources);
175
+ ```
176
+
177
+ ### 关闭
178
+
179
+ ```typescript
180
+ await agent.close();
181
+ ```
182
+
183
+ ## 架构
184
+
185
+ ```
186
+ ┌────────────────────────────────────────────────────────────┐
187
+ │ 宿主程序(CLI / 桌面精灵 / 小说生成器 / WebUI) │
188
+ │ ┌─────────────────┐ ┌──────────────────┐ │
189
+ │ │ LLM Provider 实例 │◄───│ API Key / baseUrl │ ← 宿主职责 │
190
+ │ └────────┬────────┘ └──────────────────┘ │
191
+ │ │ 注入 │
192
+ │ ▼ │
193
+ │ ┌──────────────────────────────────────────┐ │
194
+ │ │ Memora 内核(Agent) │ │
195
+ │ │ - chat(input) → 流式响应 │ │
196
+ │ │ - 纯关键词记忆检索(search_memories) │ │
197
+ │ │ - 记忆治理机制(去重/冲突/写时取代) │ │
198
+ │ │ - 角色 / 技能匹配(渐进披露) │ │
199
+ │ │ - 工具注册 / 工具执行 / 反思重试 │ │
200
+ │ │ - 会话归档 / 轮次持久化 │ │
201
+ │ └──────────────────────────────────────────┘ │
202
+ └────────────────────────────────────────────────────────────┘
203
+ ```
204
+
205
+ ### 五大注入接口
206
+
207
+ 内核通过接口与外部世界交互,宿主按需注入:
208
+
209
+ | 接口 | 职责 | 内置实现 | 宿主注意 |
210
+ |------|------|----------|----------|
211
+ | `IMemoryStorage` | 记忆 CRUD + 搜索 + 按 source 查询 | `InMemoryStorage`(**仅内存占位,不持久化**) | 生产须宿主实现持久化(如 SQLite);重启后数据依赖宿主实现 |
212
+ | `ISessionStore` | 会话历史 + 标题元数据持久化 | 无(宿主实现) | **不含检查点持久化**(2026-09-10 减法:跨重启恢复链整体退役)——中止/断电一律把未完成 turn 补全为完整 turn 身份、下次会话按历史加载;运行时暂停是同 turn 内续跑(内存态),无需跨进程载体 |
213
+ | `ILogger` | 日志输出 | console fallback | 无 |
214
+ | `ITracer` | 可观测性 span | `NOOP_TRACER` | 无 |
215
+
216
+ ## 项目结构
217
+
218
+ ```
219
+ src/
220
+ ├── index.ts # 库导出入口(类型 + 接口 + 函数 + 类导出,无 CLI)
221
+ ├── agent/ # Agent 门面 + AgentLoop + seed/(turn)
222
+ │ ├── agent.ts # 门面类(宿主唯一入口)
223
+ │ ├── loop.ts # 核心循环(推理 → 工具调用 → 反思重试)
224
+ │ ├── assembler.ts # 组件组装器(纯工厂)
225
+ │ ├── contextManager.ts / contextPreparer.ts / toolExecutor.ts / toolRunner.ts ···
226
+ │ ├── seed/ # turn(prepare → act/difficulty → reflect,含多 turn 任务编排)
227
+ │ └── managers/ # 16 个专职 Manager/服务类(memoryInspector / memoryGovernance / roundSummaryGenerator / sessionManager / sessionArchiver / archiveCoordinator / workProjection / textPolishManager / chatLockManager 等)
228
+ ├── memory/ # 记忆引擎(IMemoryStorage + InMemoryStorage + 纯关键词召回 / 融合排序 / 治理常量)
229
+ ├── role-pack/ # 角色包(manifest 解析 + validator + strategyResolver + 能力映射)
230
+ ├── skill/ # 技能管理(全局池 + 角色包绑定,渐进披露 + skillScriptRunner)
231
+ ├── llm/ # LLM 适配层(provider + openaiCompatible + factory)
232
+ ├── security/ # 安全策略(路径守卫 / 写入确认)
233
+ ├── config/ # 配置加载
234
+ ├── code-exec/ # 通用代码执行抽象(条件暴露)
235
+ ├── web-search/ # 网络搜索抽象(条件暴露)
236
+ ├── web-fetch/ # 网页抓取抽象(条件暴露)
237
+ ├── logging/ # 日志(ILogger 接口 + console fallback)
238
+ └── utils/ # 工具函数(scanner / segmenter / 事件系统 / 原子写)
239
+ ```
240
+
241
+ ## 技术栈
242
+
243
+ | 类别 | 选型 | 决策依据 |
244
+ |------|------|----------|
245
+ | 运行时 | Node.js ≥ 22 LTS + TypeScript 5 strict + ESM | ADR-001 |
246
+ | 数据层 | IMemoryStorage 接口(宿主注入持久化实现) | ADR-002 |
247
+ | LLM 协议 | OpenAI Chat Completions 兼容(流式 SSE + Tool Calling) | ADR-003 |
248
+ | 记忆模型 | 摘要即记忆(round-summary 单轨,可溯源回原始对话);source 开放字符串基元 | ADR-004 · memory-as-summary.md |
249
+ | 冲突消解 | Memory 冲突改用 supersededBy 布尔标记 | ADR-021 |
250
+ | 形态 | 纯逻辑库(零 native 依赖,CLI/UI 由宿主提供) | ADR-002 |
251
+ | 安全 | 两级权限 + 路径白名单 + 审计日志 | ADR-006 |
252
+ | 测试 | Vitest + MSW Mock LLM + InMemoryStorage | ADR-007 |
253
+
254
+ ## 工程质量
255
+
256
+ | 指标 | 数值 |
257
+ |------|------|
258
+ | 源码 | 117 个生产文件(src/,零第三方运行时依赖) |
259
+ | 测试 | 内核 + 宿主双套 vitest,根配置统一跑(100+ 文件) |
260
+ | 测试通过 | 2700+ 通过 / 1 skip |
261
+ | 语句覆盖 | 90.65% |
262
+ | 分支覆盖 | 84.83% |
263
+ | 函数覆盖 | 92.41% |
264
+ | 行覆盖 | 91.79% |
265
+ | 运行时依赖 | **0** |
266
+ | 架构决策记录 | 仓库 `.trae/decisions/` 目录(索引见该目录下的 `README.md`;此处不登记条数——计数是时点快照,每次新增即过期) |
267
+
268
+ ## 开发命令
269
+
270
+ ```bash
271
+ npm test # 运行测试
272
+ npm run test:cov # 运行测试 + 覆盖率
273
+ npm run typecheck # TypeScript 类型检查
274
+ npm run lint # ESLint 检查
275
+ npm run build # 编译到 dist/
276
+ ```
277
+
278
+ ## 文档
279
+
280
+ - [接入指南](docs/memora-接入指南.md) — 宿主项目开发者完整接入手册
281
+ - [API 参考](docs/memora-api-reference.md) — 公共 API 速查
282
+ - [角色包开放键指南](docs/role-pack-开放键指南.md) — manifest.json 开放键使用指南(三层消费方 + 速查)
283
+ - [配置示例](config.example.json) — LLM / 安全配置模板
284
+
285
+ ## 示例角色包(随包发布)
286
+
287
+ npm 包内置 `role-packs/` 示例角色库(`共鸣小说家` / `白话方案设计师`),每个包为文件夹形态(`manifest.json` 核心控制 + `persona.md` / `rules.md` / `skills/` 内容层)。复制到 `configDir/role-packs/` 即可装载,未声明角色包时 Agent 仍可正常对话(走默认策略)。开放键使用详见 [角色包开放键指南](docs/role-pack-开放键指南.md);中立规范见仓库内 [role-pack-spec](docs/architecture/role-pack-spec.md)。
288
+
289
+ ## 宿主项目
290
+
291
+ [memora-vscode](https://github.com/zooique/memora/tree/main/hosts/memora-vscode) — VS Code 插件宿主(第一宿主),展示 Memora 内核的完整接入方式:JSON 文件持久化(`.memora/memories.json`)、纯关键词召回、角色包管理与记忆视图。
292
+
293
+ ## 反馈
294
+
295
+ 遇到问题或有改进建议?请在 [GitHub Issues](https://github.com/zooique/memora/issues)(主仓库)提交反馈;国内访问也可走 [Gitee Issues](https://gitee.com/zooique/memora/issues)(同步镜像,不定期查看)。
296
+
297
+ ## 贡献
298
+
299
+ 本项目遵循"大树模型"工程哲学。技术决策记录(ADR)位于仓库 [.trae/decisions/](https://github.com/zooique/memora/tree/main/.trae/decisions)。
300
+
301
+ ## 许可证
302
+
303
+ [MIT](LICENSE)
@@ -22,14 +22,7 @@
22
22
  "supportsStructuredOutput": true
23
23
  }
24
24
  },
25
- "active": "mimimo",
26
- "background": {
27
- "provider": "doubao",
28
- "model": "doubao-pro",
29
- "apiKey": "${MEMORA_BACKGROUND_API_KEY}",
30
- "baseUrl": "https://ark.cn-beijing.volces.com/api/v3",
31
- "temperature": 0.5
32
- }
25
+ "active": "mimimo"
33
26
  },
34
27
  "memory": {
35
28
  "dataDir": "~/.memora",