@mingxy/cerebro 1.16.9 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -1
- package/src/config.ts +19 -4
- package/src/hooks.ts +25 -13
- package/src/index.ts +30 -0
- package/src/web-server.ts +180 -0
- package/web/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
- package/web/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
- package/web/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
- package/web/assets/index-B-0ucKQF.js +119 -0
- package/web/assets/index-Dxd5Um3O.css +1 -0
- package/web/favicon.svg +1 -0
- package/web/icons.svg +24 -0
- package/web/index.html +15 -0
- package/.omo/evidence/f1-verification.txt +0 -44
- package/INJECTION_FLOW.md +0 -434
- package/cerebro.example.jsonc +0 -72
- package/dist/client.d.ts +0 -165
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -222
- package/dist/client.js.map +0 -1
- package/dist/config.d.ts +0 -46
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -201
- package/dist/config.js.map +0 -1
- package/dist/hooks.d.ts +0 -41
- package/dist/hooks.d.ts.map +0 -1
- package/dist/hooks.js +0 -1066
- package/dist/hooks.js.map +0 -1
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -118
- package/dist/index.js.map +0 -1
- package/dist/keywords.d.ts +0 -3
- package/dist/keywords.d.ts.map +0 -1
- package/dist/keywords.js +0 -21
- package/dist/keywords.js.map +0 -1
- package/dist/logger.d.ts +0 -5
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -62
- package/dist/logger.js.map +0 -1
- package/dist/privacy.d.ts +0 -3
- package/dist/privacy.d.ts.map +0 -1
- package/dist/privacy.js +0 -10
- package/dist/privacy.js.map +0 -1
- package/dist/tags.d.ts +0 -3
- package/dist/tags.d.ts.map +0 -1
- package/dist/tags.js +0 -13
- package/dist/tags.js.map +0 -1
- package/dist/tools.d.ts +0 -209
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js +0 -344
- package/dist/tools.js.map +0 -1
- package/dist/tui.d.ts +0 -7
- package/dist/tui.d.ts.map +0 -1
- package/dist/tui.js +0 -63
- package/dist/tui.js.map +0 -1
- package/mingxy-omem-0.1.6.tgz +0 -0
- package/schema.json +0 -225
- package/tsconfig.json +0 -26
package/INJECTION_FLOW.md
DELETED
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
# Cerebro Plugin 记忆注入全流程
|
|
2
|
-
|
|
3
|
-
> 版本: v1.10.8 | 文件: `plugins/opencode/src/`
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 一、全局状态(模块级变量)
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
11
|
-
│ hooks.ts 模块级状态(所有hook共享) │
|
|
12
|
-
├─────────────────────────────────────────────────────────────┤
|
|
13
|
-
│ keywordDetectedSessions: Set<sessionID> │
|
|
14
|
-
│ → 标记检测到记忆关键词的session(注入时追加KEYWORD_NUDGE) │
|
|
15
|
-
│ │
|
|
16
|
-
│ injectedMemoryIds: Map<sessionID, Set<memoryID>> │
|
|
17
|
-
│ → 增量去重:跟踪每个session已注入的记忆ID │
|
|
18
|
-
│ │
|
|
19
|
-
│ firstMessages: Map<sessionID, string> │
|
|
20
|
-
│ → 记录每个session的第一条用户消息 │
|
|
21
|
-
│ │
|
|
22
|
-
│ sessionMessages: Map<sessionID, {role,content}[]> │
|
|
23
|
-
│ → 消息累积缓冲区(keywordDetection写入,compacting消费) │
|
|
24
|
-
│ │
|
|
25
|
-
│ profileInjectedSessions: Set<sessionID> │
|
|
26
|
-
│ → 每session只注入一次Profile │
|
|
27
|
-
│ │
|
|
28
|
-
│ processedMessageIds: Set<msgID> │
|
|
29
|
-
│ → sessionIdleHook防止重复处理已消费的消息 │
|
|
30
|
-
│ │
|
|
31
|
-
│ pluginStartTime: number │
|
|
32
|
-
│ → 插件启动时间戳,跳过启动前的历史消息 │
|
|
33
|
-
└─────────────────────────────────────────────────────────────┘
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## 二、四条Hook链路总览
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
用户消息 → OpenCode SDK → 触发Hook链
|
|
42
|
-
│
|
|
43
|
-
┌───────────────────────────┼─────────────────────────────┐
|
|
44
|
-
▼ ▼ ▼
|
|
45
|
-
chat.message chat.system.transform session.idle
|
|
46
|
-
(每条消息) (每次LLM调用前) (session空闲)
|
|
47
|
-
│ │ │
|
|
48
|
-
▼ ▼ ▼
|
|
49
|
-
keywordDetectionHook autoRecallHook sessionIdleHook
|
|
50
|
-
│ │ │
|
|
51
|
-
│ │ │
|
|
52
|
-
│ ┌────┘ │
|
|
53
|
-
▼ ▼ │
|
|
54
|
-
session.compacting │
|
|
55
|
-
(session压缩时) │
|
|
56
|
-
│ │
|
|
57
|
-
▼ │
|
|
58
|
-
compactingHook ───────────────────────────────────────────────┘
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## 三、Hook ①: keywordDetectionHook — 消息收集
|
|
64
|
-
|
|
65
|
-
**触发时机**: `chat.message`(每条用户消息)
|
|
66
|
-
**作用**: 收集用户消息到内存缓冲区 + 检测记忆关键词
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
用户消息到达
|
|
70
|
-
│
|
|
71
|
-
▼
|
|
72
|
-
[1] 提取文本内容(text parts拼接)
|
|
73
|
-
│
|
|
74
|
-
▼
|
|
75
|
-
[2] 记录第一条消息 → firstMessages[sessionID] = text
|
|
76
|
-
│
|
|
77
|
-
▼
|
|
78
|
-
[3] 关键词检测: detectKeyword(text)
|
|
79
|
-
│ │
|
|
80
|
-
├─ 命中 ────────→ keywordDetectedSessions.add(sessionID)
|
|
81
|
-
│ (autoRecallHook注入时会追加KEYWORD_NUDGE)
|
|
82
|
-
│
|
|
83
|
-
▼
|
|
84
|
-
[4] Policy检查: resolveAgentPolicy(agentId, config)
|
|
85
|
-
│
|
|
86
|
-
├─ "none" ──→ return(不收集消息)
|
|
87
|
-
│
|
|
88
|
-
▼
|
|
89
|
-
[5] 消息入缓冲: sessionMessages[sessionID].push({role:"user", content:text})
|
|
90
|
-
│
|
|
91
|
-
▼
|
|
92
|
-
[6] 消息数 ≥ threshold?
|
|
93
|
-
│
|
|
94
|
-
└─ 是 → 标记"待处理"(等session.idle时消费)
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**关键点**:
|
|
98
|
-
- `policy="none"` 时不收集,`readonly`/`readwrite` 都收集
|
|
99
|
-
- 消息存在内存Map中,等 `compactingHook` 或 `sessionIdleHook` 消费
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## 四、Hook ②: autoRecallHook — 记忆召回+注入(核心)
|
|
104
|
-
|
|
105
|
-
**触发时机**: `experimental.chat.system.transform`(每次LLM调用前,transform system prompt时)
|
|
106
|
-
**作用**: 召回相关记忆 + 注入到system prompt
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
LLM调用前触发
|
|
110
|
-
│
|
|
111
|
-
▼
|
|
112
|
-
[1] Policy检查: resolveAgentPolicy(agentId, config)
|
|
113
|
-
│
|
|
114
|
-
├─ "none" ──→ return(不召回)
|
|
115
|
-
│
|
|
116
|
-
▼
|
|
117
|
-
[2] 提取查询: 最后一条用户消息 → extractUserRequest() → query_text
|
|
118
|
-
│
|
|
119
|
-
▼
|
|
120
|
-
[3] 调用 shouldRecall API ──────────────────────→ POST /v1/should-recall
|
|
121
|
-
│ 参数: query_text, last_query_text, session_id, │
|
|
122
|
-
│ similarity_threshold(0.6), │
|
|
123
|
-
│ max_results(10), project_tags │
|
|
124
|
-
│ 超时: 20秒 │
|
|
125
|
-
│ │
|
|
126
|
-
│ ◄────────────────────────────────────────────┘
|
|
127
|
-
│ 返回: ShouldRecallResponse
|
|
128
|
-
│ { should_recall, confidence, memories[], clustered? }
|
|
129
|
-
│
|
|
130
|
-
▼
|
|
131
|
-
[4] API不可达? ──→ Toast "Service Unavailable" → return
|
|
132
|
-
│
|
|
133
|
-
▼
|
|
134
|
-
[5] 注入Profile(每session仅一次)
|
|
135
|
-
│
|
|
136
|
-
├─ GET /v1/profile → profile数据
|
|
137
|
-
│
|
|
138
|
-
├─ profileInjectedSessions.has(sessionID)?
|
|
139
|
-
│ ├─ 否 → output.system.push("<cerebro-profile>...")
|
|
140
|
-
│ │ profileInjectedSessions.add(sessionID)
|
|
141
|
-
│ │ profileInjected = true
|
|
142
|
-
│ └─ 是 → 跳过
|
|
143
|
-
│
|
|
144
|
-
▼
|
|
145
|
-
[6] should_recall === false?
|
|
146
|
-
│
|
|
147
|
-
├─ 是 ──→ 仅Profile注入?
|
|
148
|
-
│ ├─ 是 → Toast "👨 Profile Injected"
|
|
149
|
-
│ └─ return
|
|
150
|
-
│
|
|
151
|
-
▼
|
|
152
|
-
[7] 增量去重: results过滤掉 injectedMemoryIds[sessionID] 中已有的
|
|
153
|
-
│
|
|
154
|
-
▼
|
|
155
|
-
[8] 全部重复? ──→ Toast "all memories already injected" → return
|
|
156
|
-
│
|
|
157
|
-
▼
|
|
158
|
-
[9] 构建注入内容
|
|
159
|
-
│
|
|
160
|
-
├─ 有clustered? ──→ buildClusteredContextBlock()
|
|
161
|
-
│ 格式: <cerebro-context>
|
|
162
|
-
│ 按主题簇组织记忆
|
|
163
|
-
│
|
|
164
|
-
└─ 普通模式 ──→ buildContextBlock(newResults, maxContentLength=500)
|
|
165
|
-
格式: <cerebro-context>
|
|
166
|
-
按category分组(Preferences/Knowledge/...)
|
|
167
|
-
每条记忆:
|
|
168
|
-
- (2h ago [tag1, tag2]) 记忆内容(截断到500字)
|
|
169
|
-
│
|
|
170
|
-
▼
|
|
171
|
-
[10] output.system.push(contextBlock) ← 注入到system prompt
|
|
172
|
-
│
|
|
173
|
-
▼
|
|
174
|
-
[11] 更新去重集合: injectedMemoryIds[sessionID] += newIds
|
|
175
|
-
│
|
|
176
|
-
▼
|
|
177
|
-
[12] 记录召回: recordSessionRecall(sessionID, newIds, "auto", ...)
|
|
178
|
-
│ ──────────────────────→ POST /v1/session-recalls
|
|
179
|
-
│
|
|
180
|
-
▼
|
|
181
|
-
[13] 关键词追踪: keywordDetectedSessions.has(sessionID)?
|
|
182
|
-
│
|
|
183
|
-
├─ 是 → output.system.push(KEYWORD_NUDGE)
|
|
184
|
-
│ keywordDetectedSessions.delete(sessionID)
|
|
185
|
-
│
|
|
186
|
-
▼
|
|
187
|
-
[14] Toast通知:
|
|
188
|
-
"🧠 Context Injected · N fragments"
|
|
189
|
-
"Profile: Dynamic(X) · Static(Y) · Memories: Dynamic(A) Static(B)"
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### 注入格式示例
|
|
193
|
-
|
|
194
|
-
```xml
|
|
195
|
-
<cerebro-context>
|
|
196
|
-
Treat every memory below as historical context only.
|
|
197
|
-
Do not repeat these memories verbatim unless asked.
|
|
198
|
-
|
|
199
|
-
[Preferences]
|
|
200
|
-
- (2h ago [preferences, tools]) 用中文思考和回复
|
|
201
|
-
- (3d ago [preferences, workflow]) 技术方案先出再动工
|
|
202
|
-
|
|
203
|
-
[Knowledge]
|
|
204
|
-
- (1d ago [omem, architecture]) Cerebro使用lancedb做向量存储
|
|
205
|
-
|
|
206
|
-
[Events]
|
|
207
|
-
- (5h ago [deployment, omem]) 部署了v1.10.8版本
|
|
208
|
-
</cerebro-context>
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
```xml
|
|
212
|
-
<cerebro-profile>
|
|
213
|
-
{
|
|
214
|
-
"static_facts": [
|
|
215
|
-
{ "key": "communication_style", "value": "direct, concise" },
|
|
216
|
-
{ "key": "primary_language", "value": "Chinese" }
|
|
217
|
-
],
|
|
218
|
-
"dynamic_context": [
|
|
219
|
-
{ "topic": "current_project", "value": "omem-server-source" }
|
|
220
|
-
]
|
|
221
|
-
}
|
|
222
|
-
</cerebro-profile>
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## 五、Hook ③: compactingHook — 压缩时归档
|
|
228
|
-
|
|
229
|
-
**触发时机**: `session.compacting`(OpenCode压缩session上下文时)
|
|
230
|
-
**作用**: 为压缩提供记忆上下文(读) + 归档累积消息(写)
|
|
231
|
-
|
|
232
|
-
```
|
|
233
|
-
session压缩触发
|
|
234
|
-
│
|
|
235
|
-
▼
|
|
236
|
-
[1] 搜索记忆(读操作,所有policy都执行)
|
|
237
|
-
│ client.searchMemories("*", 20, undefined, containerTags)
|
|
238
|
-
│ ──────────────────────→ GET /v1/memories/search?q=*&limit=20
|
|
239
|
-
│
|
|
240
|
-
├─ 有结果 → buildContextBlock(results)
|
|
241
|
-
│ output.context.push(contextBlock)
|
|
242
|
-
│ (为压缩后的LLM提供记忆上下文)
|
|
243
|
-
│
|
|
244
|
-
▼
|
|
245
|
-
[2] Policy检查: resolveAgentPolicy(agentId, config)
|
|
246
|
-
│
|
|
247
|
-
├─ 非"readwrite" ──→ logInfo "blocked by policy"
|
|
248
|
-
│ sessionMessages.delete(sessionID)
|
|
249
|
-
│ return
|
|
250
|
-
│
|
|
251
|
-
▼
|
|
252
|
-
[3] 检查autoStore开关: isAutoStoreEnabled(sessionID)?
|
|
253
|
-
│
|
|
254
|
-
├─ 关闭 → sessionMessages.delete(sessionID) → return
|
|
255
|
-
│
|
|
256
|
-
▼
|
|
257
|
-
[4] 消费sessionMessages缓冲区
|
|
258
|
-
│
|
|
259
|
-
├─ 缓冲区空? → return
|
|
260
|
-
│
|
|
261
|
-
▼
|
|
262
|
-
[5] 检测项目名: detectProjectName(rootPath)
|
|
263
|
-
│ AGENTS.md → package.json → Cargo.toml → go.mod → pyproject.toml
|
|
264
|
-
│
|
|
265
|
-
▼
|
|
266
|
-
[6] 归档消息(写入记忆)
|
|
267
|
-
│ client.ingestMessages(messages, {mode, tags, sessionId, projectName})
|
|
268
|
-
│ ──────────────────────→ POST /v1/memories
|
|
269
|
-
│ body: { messages: [...], mode: "smart", tags, session_id, project_name }
|
|
270
|
-
│ 每条消息内容先 sanitizeContent(text, maxContentChars=3000)
|
|
271
|
-
│ → 去XML标签 → 压缩空白 → 超长截断
|
|
272
|
-
│
|
|
273
|
-
▼
|
|
274
|
-
[7] 清理缓冲区: sessionMessages.delete(sessionID)
|
|
275
|
-
│
|
|
276
|
-
▼
|
|
277
|
-
[8] Toast: "📦 Session Archived · N dialogues archived"
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
---
|
|
281
|
-
|
|
282
|
-
## 六、Hook ④: sessionIdleHook — 空闲时归档
|
|
283
|
-
|
|
284
|
-
**触发时机**: `session.idle`(session空闲10秒后)
|
|
285
|
-
**作用**: 从SDK获取完整对话历史并归档
|
|
286
|
-
|
|
287
|
-
```
|
|
288
|
-
session空闲事件
|
|
289
|
-
│
|
|
290
|
-
▼
|
|
291
|
-
[1] event.type === "session.idle"? ── 否 → return
|
|
292
|
-
│
|
|
293
|
-
▼
|
|
294
|
-
[2] 提取sessionID
|
|
295
|
-
│
|
|
296
|
-
▼
|
|
297
|
-
[3] isAutoStoreEnabled(sessionID)? ── 关闭 → return
|
|
298
|
-
│
|
|
299
|
-
▼
|
|
300
|
-
[4] 非主session? (sessionID !== getMainSessionId()) ── return
|
|
301
|
-
│
|
|
302
|
-
▼
|
|
303
|
-
[5] 延迟10秒执行(防抖)
|
|
304
|
-
│
|
|
305
|
-
▼
|
|
306
|
-
[6] 从SDK获取session消息: sdkClient.session.messages({id: sessionID})
|
|
307
|
-
│
|
|
308
|
-
▼
|
|
309
|
-
[7] 过滤消息:
|
|
310
|
-
│ ├─ 跳过 processedMessageIds 中已处理的
|
|
311
|
-
│ ├─ 跳过 pluginStartTime 之前的(防历史重放)
|
|
312
|
-
│ ├─ 只保留 user/assistant 角色
|
|
313
|
-
│ └─ 提取text parts
|
|
314
|
-
│
|
|
315
|
-
▼
|
|
316
|
-
[8] 消息数 < threshold? ── return
|
|
317
|
-
│
|
|
318
|
-
▼
|
|
319
|
-
[9] Policy检查: resolveAgentPolicy(agentId, config)
|
|
320
|
-
│
|
|
321
|
-
├─ 非"readwrite" ──→ logInfo "blocked by policy" → return
|
|
322
|
-
│
|
|
323
|
-
▼
|
|
324
|
-
[10] 检测项目名: detectProjectName(rootPath)
|
|
325
|
-
│
|
|
326
|
-
▼
|
|
327
|
-
[11] sessionIngest(写入记忆)
|
|
328
|
-
│ client.sessionIngest(messages, sessionID, agentId, title, projectName)
|
|
329
|
-
│ ──────────────────────→ POST /v1/memories/session-ingest
|
|
330
|
-
│ body: { messages, session_id, agent_id, session_title, project_name }
|
|
331
|
-
│ 超时60秒
|
|
332
|
-
│
|
|
333
|
-
▼
|
|
334
|
-
[12] 标记已处理: processedMessageIds += newMessageIds
|
|
335
|
-
│
|
|
336
|
-
▼
|
|
337
|
-
[13] Toast: "🧠 Memory Sealed · N dialogues captured"
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
---
|
|
341
|
-
|
|
342
|
-
## 七、数据流全景图
|
|
343
|
-
|
|
344
|
-
```
|
|
345
|
-
┌─────────────────────────────────┐
|
|
346
|
-
│ 用户消息输入 │
|
|
347
|
-
└──────────┬──────────────────────┘
|
|
348
|
-
│
|
|
349
|
-
┌──────────────┼──────────────────┐
|
|
350
|
-
▼ ▼ ▼
|
|
351
|
-
keywordDetection autoRecall session.idle
|
|
352
|
-
(chat.message) (chat.system (空闲10s)
|
|
353
|
-
.transform)
|
|
354
|
-
│ │ │
|
|
355
|
-
│ ┌────┘ │
|
|
356
|
-
▼ ▼ │
|
|
357
|
-
sessionMessages System Prompt │
|
|
358
|
-
(内存缓冲) 注入区 │
|
|
359
|
-
│ ▲ │
|
|
360
|
-
│ │ │
|
|
361
|
-
▼ │ ▼
|
|
362
|
-
compacting ─────┘ sessionIdleHook
|
|
363
|
-
(session压缩) │
|
|
364
|
-
│ │
|
|
365
|
-
▼ ▼
|
|
366
|
-
┌───────────────────────────────────────────────┐
|
|
367
|
-
│ Cerebro REST API │
|
|
368
|
-
│ │
|
|
369
|
-
│ 读: POST /v1/should-recall (召回决策) │
|
|
370
|
-
│ 读: GET /v1/profile (用户画像) │
|
|
371
|
-
│ 读: GET /v1/memories/search (记忆搜索) │
|
|
372
|
-
│ 写: POST /v1/memories (消息归档) │
|
|
373
|
-
│ 写: POST /v1/memories/session-ingest (session归档) │
|
|
374
|
-
│ 写: POST /v1/session-recalls (召回记录) │
|
|
375
|
-
│ │
|
|
376
|
-
└──────────────────┬───────────────────────────┘
|
|
377
|
-
│
|
|
378
|
-
▼
|
|
379
|
-
┌─────────────────────┐
|
|
380
|
-
│ LanceDB 向量存储 │
|
|
381
|
-
│ (omem-server) │
|
|
382
|
-
└─────────────────────┘
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
---
|
|
386
|
-
|
|
387
|
-
## 八、Policy门控规则
|
|
388
|
-
|
|
389
|
-
| Hook | "none" | "readonly" | "readwrite" |
|
|
390
|
-
|------|--------|------------|-------------|
|
|
391
|
-
| keywordDetection | ❌ 不收集消息 | ✅ 收集消息 | ✅ 收集消息 |
|
|
392
|
-
| autoRecall | ❌ 不召回 | ✅ 召回+注入 | ✅ 召回+注入 |
|
|
393
|
-
| compacting | ✅ 搜索(读) | ✅ 搜索(读) | ✅ 搜索+写入 |
|
|
394
|
-
| sessionIdle | N/A | ❌ 不写入 | ✅ 写入 |
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
## 九、关键配置参数
|
|
399
|
-
|
|
400
|
-
| 参数 | 位置 | 默认值 | 作用 |
|
|
401
|
-
|------|------|--------|------|
|
|
402
|
-
| `content.maxContentLength` | config.ts L49 | 500 | **读取侧**截断:每条注入记忆最大字符数 |
|
|
403
|
-
| `content.maxContentChars` | config.ts L48 | 30000→3000 | **写入侧**截断:归档时单条消息最大字符数 |
|
|
404
|
-
| `content.maxQueryLength` | config.ts L47 | 200 | 召回查询最大字符数 |
|
|
405
|
-
| `recall.similarityThreshold` | config.ts L56 | 0.4 | 召回相似度阈值 |
|
|
406
|
-
| `recall.maxRecallResults` | config.ts L57 | 10 | 最大召回结果数 |
|
|
407
|
-
| `ingest.autoCaptureThreshold` | config.ts L51 | 5 | 消息累积到N条才触发归档 |
|
|
408
|
-
| `ui.toastDelayMs` | config.ts L65 | 7000 | Toast显示时长(ms) |
|
|
409
|
-
| `agentMemoryPolicy` | config.ts L34 | - | 各agent的读写权限 |
|
|
410
|
-
| `defaultPolicy` | config.ts L35 | "readwrite" | 未配置agent的默认权限 |
|
|
411
|
-
|
|
412
|
-
---
|
|
413
|
-
|
|
414
|
-
## 十、写入侧 vs 读取侧截断对比
|
|
415
|
-
|
|
416
|
-
```
|
|
417
|
-
写入路径 读取路径
|
|
418
|
-
(归档到服务端) (注入到system prompt)
|
|
419
|
-
|
|
420
|
-
消息内容 sanitizeContent() truncate()
|
|
421
|
-
client.ts L4-10 hooks.ts L147-150
|
|
422
|
-
|
|
423
|
-
处理流程 去XML标签 → 压缩空白 → 截断 直接截断
|
|
424
|
-
|
|
425
|
-
配置参数 maxContentChars (3000) maxContentLength (500)
|
|
426
|
-
|
|
427
|
-
截断标记 "…[truncated]" "…"
|
|
428
|
-
|
|
429
|
-
触发点 createMemory() L182 buildContextBlock() L178
|
|
430
|
-
ingestMessages() L238
|
|
431
|
-
|
|
432
|
-
调用方 compactingHook autoRecallHook
|
|
433
|
-
sessionIdleHook
|
|
434
|
-
```
|
package/cerebro.example.jsonc
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "./schema.json",
|
|
3
|
-
// ── Connection ───────────────────────────────────────────────
|
|
4
|
-
// API endpoint and authentication for the Cerebro server.
|
|
5
|
-
"connection": {
|
|
6
|
-
// Cerebro server URL (env: OMEM_API_URL takes priority)
|
|
7
|
-
"apiUrl": "https://www.mengxy.cc",
|
|
8
|
-
// Your tenant API key (env: OMEM_API_KEY takes priority)
|
|
9
|
-
"apiKey": "",
|
|
10
|
-
// HTTP request timeout in milliseconds
|
|
11
|
-
"requestTimeoutMs": 15000
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
// ── Content ──────────────────────────────────────────────────
|
|
15
|
-
// Limits for content processing and ingestion.
|
|
16
|
-
"content": {
|
|
17
|
-
// Max characters for recall queries
|
|
18
|
-
"maxQueryLength": 200,
|
|
19
|
-
// Max content chars sent to the server per ingestion
|
|
20
|
-
"maxContentChars": 30000,
|
|
21
|
-
// Max single content item length for auto-capture
|
|
22
|
-
"maxContentLength": 500
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
// ── Ingest ───────────────────────────────────────────────────
|
|
26
|
-
// Controls how memories are captured and stored.
|
|
27
|
-
"ingest": {
|
|
28
|
-
// Minimum number of messages before auto-capture triggers
|
|
29
|
-
"autoCaptureThreshold": 5,
|
|
30
|
-
// "smart" = LLM-powered extraction | "raw" = store as-is
|
|
31
|
-
"ingestMode": "smart"
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
// ── Recall ───────────────────────────────────────────────────
|
|
35
|
-
// Tuning for memory retrieval relevance.
|
|
36
|
-
"recall": {
|
|
37
|
-
// Minimum cosine similarity to include a result (0.0–1.0)
|
|
38
|
-
"similarityThreshold": 0.4,
|
|
39
|
-
// Maximum number of memories returned per recall
|
|
40
|
-
"maxRecallResults": 10
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
// ── Logging ──────────────────────────────────────────────────
|
|
44
|
-
// Diagnostic logging for debugging plugin behavior.
|
|
45
|
-
"logging": {
|
|
46
|
-
// Enable/disable file logging
|
|
47
|
-
"logEnabled": true,
|
|
48
|
-
// Log verbosity: "DEBUG" | "INFO" | "WARN" | "ERROR"
|
|
49
|
-
"logLevel": "INFO",
|
|
50
|
-
// Directory for log files (default: ~/.config/cerebro)
|
|
51
|
-
"logDir": "~/.config/cerebro"
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
// ── UI ───────────────────────────────────────────────────────
|
|
55
|
-
// Terminal UI behavior tuning.
|
|
56
|
-
"ui": {
|
|
57
|
-
// Delay in ms before toast notifications auto-dismiss
|
|
58
|
-
"toastDelayMs": 7000
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// ── Agent Memory Policy ──────────────────────────────────────
|
|
62
|
-
// Control which sub-agents can read/write memories.
|
|
63
|
-
// Values: "none" | "readonly" | "readwrite"
|
|
64
|
-
"agentMemoryPolicy": {
|
|
65
|
-
// Examples: restrict exploration agents to read-only
|
|
66
|
-
// "explore": "readonly",
|
|
67
|
-
// "librarian": "readonly"
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
// Default policy for agents not listed above.
|
|
71
|
-
// "defaultPolicy": "readonly"
|
|
72
|
-
}
|
package/dist/client.d.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import type { OmemPluginConfig } from "./config.js";
|
|
2
|
-
export interface IngestOptions {
|
|
3
|
-
mode?: "smart" | "raw";
|
|
4
|
-
agentId?: string;
|
|
5
|
-
sessionId?: string;
|
|
6
|
-
entityContext?: string;
|
|
7
|
-
tags?: string[];
|
|
8
|
-
projectName?: string;
|
|
9
|
-
projectPath?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface SearchResult {
|
|
12
|
-
memory: MemoryDto;
|
|
13
|
-
score: number;
|
|
14
|
-
refine_relevance?: string;
|
|
15
|
-
refine_reasoning?: string;
|
|
16
|
-
}
|
|
17
|
-
export interface SearchResponse {
|
|
18
|
-
results: SearchResult[];
|
|
19
|
-
trace?: unknown;
|
|
20
|
-
}
|
|
21
|
-
export interface ListResponse {
|
|
22
|
-
memories: MemoryDto[];
|
|
23
|
-
limit: number;
|
|
24
|
-
offset: number;
|
|
25
|
-
}
|
|
26
|
-
export interface ClusterSummary {
|
|
27
|
-
cluster_id: string;
|
|
28
|
-
title: string;
|
|
29
|
-
summary: string;
|
|
30
|
-
member_count: number;
|
|
31
|
-
relevance_score: number;
|
|
32
|
-
key_memories: MemoryDto[];
|
|
33
|
-
}
|
|
34
|
-
export interface ClusteredRecallResult {
|
|
35
|
-
cluster_summaries: ClusterSummary[];
|
|
36
|
-
standalone_memories: MemoryDto[];
|
|
37
|
-
}
|
|
38
|
-
export interface DiscardedItem {
|
|
39
|
-
memory_id: string;
|
|
40
|
-
content: string;
|
|
41
|
-
score: number;
|
|
42
|
-
refine_relevance?: string;
|
|
43
|
-
refine_reasoning?: string;
|
|
44
|
-
}
|
|
45
|
-
export interface ShouldRecallResponse {
|
|
46
|
-
should_recall: boolean;
|
|
47
|
-
query?: string;
|
|
48
|
-
reason?: string;
|
|
49
|
-
similarity_score?: number;
|
|
50
|
-
confidence?: number;
|
|
51
|
-
memories?: SearchResult[];
|
|
52
|
-
discarded?: DiscardedItem[];
|
|
53
|
-
clustered?: ClusteredRecallResult;
|
|
54
|
-
}
|
|
55
|
-
export interface PreferenceDto {
|
|
56
|
-
id: string;
|
|
57
|
-
slot: string;
|
|
58
|
-
value: string;
|
|
59
|
-
confidence: number;
|
|
60
|
-
scope: string;
|
|
61
|
-
project_path?: string;
|
|
62
|
-
source: string;
|
|
63
|
-
status: string;
|
|
64
|
-
created_at: string;
|
|
65
|
-
updated_at: string;
|
|
66
|
-
}
|
|
67
|
-
export interface MemoryRelation {
|
|
68
|
-
relation_type: string;
|
|
69
|
-
target_id: string;
|
|
70
|
-
context_label?: string;
|
|
71
|
-
}
|
|
72
|
-
export interface MemoryDto {
|
|
73
|
-
id: string;
|
|
74
|
-
content: string;
|
|
75
|
-
l2_content?: string;
|
|
76
|
-
category: string;
|
|
77
|
-
memory_type: string;
|
|
78
|
-
state: string;
|
|
79
|
-
tags: string[];
|
|
80
|
-
relations?: MemoryRelation[];
|
|
81
|
-
source?: string;
|
|
82
|
-
tenant_id: string;
|
|
83
|
-
agent_id?: string;
|
|
84
|
-
importance: number;
|
|
85
|
-
created_at: string;
|
|
86
|
-
updated_at: string;
|
|
87
|
-
}
|
|
88
|
-
export declare class CerebroClient {
|
|
89
|
-
private baseUrl;
|
|
90
|
-
private apiKey;
|
|
91
|
-
private config?;
|
|
92
|
-
constructor(baseUrl: string, apiKey: string, config?: Partial<OmemPluginConfig> | undefined);
|
|
93
|
-
private getCfg;
|
|
94
|
-
private request;
|
|
95
|
-
private post;
|
|
96
|
-
private put;
|
|
97
|
-
private patch;
|
|
98
|
-
private del;
|
|
99
|
-
createMemory(content: string, tags?: string[], source?: string, scope?: string, agentId?: string, sessionId?: string, visibility?: string, category?: string, projectPath?: string): Promise<MemoryDto | null>;
|
|
100
|
-
searchMemories(query: string, limit?: number, scope?: string, tags?: string[], projectPath?: string): Promise<SearchResult[]>;
|
|
101
|
-
getMemory(id: string): Promise<MemoryDto | null>;
|
|
102
|
-
updateMemory(id: string, content: string, tags?: string[]): Promise<MemoryDto | null>;
|
|
103
|
-
deleteMemory(id: string): Promise<void>;
|
|
104
|
-
ingestMessages(messages: Array<{
|
|
105
|
-
role: string;
|
|
106
|
-
content: string;
|
|
107
|
-
}>, opts?: IngestOptions): Promise<unknown>;
|
|
108
|
-
getProfile(projectPath?: string): Promise<PreferenceDto[]>;
|
|
109
|
-
getInjection(projectPath?: string): Promise<{
|
|
110
|
-
content: string;
|
|
111
|
-
preference_count: number;
|
|
112
|
-
estimated_tokens: number;
|
|
113
|
-
} | null>;
|
|
114
|
-
getStats(): Promise<unknown>;
|
|
115
|
-
getProfileStats(): Promise<unknown>;
|
|
116
|
-
listRecent(limit?: number): Promise<MemoryDto[]>;
|
|
117
|
-
createSpace(name: string, spaceType: string, members?: Array<{
|
|
118
|
-
user_id: string;
|
|
119
|
-
role: string;
|
|
120
|
-
}>): Promise<unknown>;
|
|
121
|
-
listSpaces(): Promise<unknown[]>;
|
|
122
|
-
addSpaceMember(spaceId: string, userId: string, role: string): Promise<unknown>;
|
|
123
|
-
shareMemory(memoryId: string, targetSpace: string): Promise<unknown>;
|
|
124
|
-
pullMemory(memoryId: string, sourceSpace: string, visibility?: string): Promise<unknown>;
|
|
125
|
-
reshareMemory(memoryId: string, targetSpace?: string): Promise<unknown>;
|
|
126
|
-
shouldRecall(query_text: string, last_query_text: string | undefined, session_id: string, similarity_threshold?: number, max_results?: number, project_tags?: string[], conversation_context?: string[], recall_overrides?: {
|
|
127
|
-
fetch_multiplier?: number;
|
|
128
|
-
topk_cap_multiplier?: number;
|
|
129
|
-
mmr_jaccard_threshold?: number;
|
|
130
|
-
mmr_penalty_factor?: number;
|
|
131
|
-
phase2_multiplier?: number;
|
|
132
|
-
llm_max_eval?: number;
|
|
133
|
-
refine_strategy?: string;
|
|
134
|
-
skip_llm_gate?: boolean;
|
|
135
|
-
}, projectPath?: string): Promise<ShouldRecallResponse | null>;
|
|
136
|
-
updateProfileInjected(event_id: string, profile_injected: boolean, profile_content?: string): Promise<unknown | null>;
|
|
137
|
-
createRecallEvent(params: {
|
|
138
|
-
session_id: string;
|
|
139
|
-
recall_type?: string;
|
|
140
|
-
query_text: string;
|
|
141
|
-
max_score: number;
|
|
142
|
-
llm_confidence: number;
|
|
143
|
-
profile_injected: boolean;
|
|
144
|
-
kept_count: number;
|
|
145
|
-
discarded_count: number;
|
|
146
|
-
injected_count: number;
|
|
147
|
-
profile_content?: string;
|
|
148
|
-
injected_content?: string;
|
|
149
|
-
items?: Array<{
|
|
150
|
-
memory_id: string;
|
|
151
|
-
score: number;
|
|
152
|
-
refine_relevance?: string;
|
|
153
|
-
refine_reasoning?: string;
|
|
154
|
-
is_kept: boolean;
|
|
155
|
-
}>;
|
|
156
|
-
}): Promise<{
|
|
157
|
-
ok: boolean;
|
|
158
|
-
event_id?: string;
|
|
159
|
-
} | null>;
|
|
160
|
-
sessionIngest(messages: Array<{
|
|
161
|
-
role: string;
|
|
162
|
-
content: string;
|
|
163
|
-
}>, sessionId?: string, agentId?: string, sessionTitle?: string, projectName?: string, projectPath?: string): Promise<unknown>;
|
|
164
|
-
}
|
|
165
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|