@mingxy/cerebro 2.3.6 → 2.3.8

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mingxy/cerebro",
3
- "version": "2.3.6",
3
+ "version": "2.3.8",
4
4
  "description": "Cerebro persistent memory plugin for OpenCode — auto-recall, auto-capture, 9 memory tools with clustering, project-scoped memory isolation",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/config.ts CHANGED
@@ -24,6 +24,10 @@ export interface CerebroPluginConfig {
24
24
  recentTimeoutMs: number;
25
25
  searchTimeoutMs: number;
26
26
  profileTimeoutMs: number;
27
+ /** digestMode(spec 刀5):注入只给 id+l0+l1 摘要,详情按需 memory_get。默认关。 */
28
+ digestMode?: boolean;
29
+ /** digestMode 提示行,用户可覆写自家口味(不改代码不重发插件)。 */
30
+ digestPrompt?: string;
27
31
  };
28
32
  ingest: {
29
33
  autoCaptureThreshold: number;
@@ -68,6 +72,9 @@ const DEFAULTS: CerebroPluginConfig = {
68
72
  recentTimeoutMs: 3000,
69
73
  searchTimeoutMs: 5000,
70
74
  profileTimeoutMs: 2000,
75
+ digestMode: false,
76
+ digestPrompt:
77
+ "Digest mode: memory entries above are one-line summaries (id + title). When an entry matters to the task, call the memory_get tool with its id to load the full content.",
71
78
  },
72
79
  ingest: {
73
80
  autoCaptureThreshold: 5,
package/src/hooks.ts CHANGED
@@ -284,6 +284,24 @@ export async function buildMemoryInjection(
284
284
  : Promise.resolve([]),
285
285
  ]);
286
286
 
287
+ // digestMode(spec 刀5):注入只给 id+l0+l1 一行,详情按需 memory_get——
288
+ // 被动注入给摘要、主动 search 给全文的不对称是原则。
289
+ const digestMode = ic.digestMode === true;
290
+ const digestPrompt =
291
+ typeof ic.digestPrompt === "string" && ic.digestPrompt.trim()
292
+ ? ic.digestPrompt.trim()
293
+ : DEFAULTS.injection.digestPrompt!;
294
+ const renderLine = (age: string, m: { id: string; content: string; l0_abstract?: string; l1_overview?: string } | null | undefined, truncateChars = 0): string => {
295
+ if (!m) return "";
296
+ const content = truncateChars > 0 ? truncate(m.content, truncateChars) : m.content;
297
+ if (!digestMode) return `- (${age}) ${content}`;
298
+ // l0/l1 过 \s+→" ":l1 源自 content 截断带换行,断行可伪造注入条目行
299
+ const l0 = (m.l0_abstract || "").replace(/\s+/g, " ").trim();
300
+ const l1 = (m.l1_overview || "").replace(/\s+/g, " ").trim();
301
+ const title = l0 || (m.content || "").replace(/\s+/g, " ").slice(0, 60);
302
+ return `- (${age}) id=${m.id} ${title}${l1 ? ` — ${l1}` : ""}`;
303
+ };
304
+
287
305
  const sections: string[] = ["[CEREBRO-MEMORY]", ""];
288
306
 
289
307
  if (profile?.content) {
@@ -298,8 +316,7 @@ export async function buildMemoryInjection(
298
316
  sections.push("## Global Memories");
299
317
  for (const r of dedupedGlobal) {
300
318
  seenIds.add(r.memory.id);
301
- const age = formatRelativeAge(r.memory.created_at) || "unknown";
302
- sections.push(`- (${age}) ${r.memory.content}`);
319
+ sections.push(renderLine(formatRelativeAge(r.memory.created_at) || "unknown", r.memory));
303
320
  }
304
321
  sections.push("");
305
322
  }
@@ -308,9 +325,7 @@ export async function buildMemoryInjection(
308
325
  sections.push("## Recent Project Activity");
309
326
  for (const m of projectMemories) {
310
327
  seenIds.add(m.id);
311
- const age = formatRelativeAge(m.updated_at || m.created_at) || "unknown";
312
- const content = recentTruncate > 0 ? truncate(m.content, recentTruncate) : m.content;
313
- sections.push(`- (${age}) ${content}`);
328
+ sections.push(renderLine(formatRelativeAge(m.updated_at || m.created_at) || "unknown", m, recentTruncate));
314
329
  }
315
330
  sections.push("");
316
331
  }
@@ -319,13 +334,16 @@ export async function buildMemoryInjection(
319
334
  if (dedupedResults.length > 0) {
320
335
  sections.push("## Relevant Memories");
321
336
  for (const r of dedupedResults) {
322
- const age = formatRelativeAge(r.memory.created_at) || "unknown";
323
- const content = searchTruncate > 0 ? truncate(r.memory.content, searchTruncate) : r.memory.content;
324
- sections.push(`- (${age}) ${content}`);
337
+ sections.push(renderLine(formatRelativeAge(r.memory.created_at) || "unknown", r.memory, searchTruncate));
325
338
  }
326
339
  sections.push("");
327
340
  }
328
341
 
342
+ if (digestMode) {
343
+ sections.push(digestPrompt);
344
+ sections.push("");
345
+ }
346
+
329
347
  sections.push("[/CEREBRO-MEMORY]");
330
348
 
331
349
  let text = sections.join("\n");