@mingxy/cerebro 1.18.10 → 1.18.12

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,56 +1,56 @@
1
- {
2
- "name": "@mingxy/cerebro",
3
- "version": "1.18.10",
4
- "description": "Cerebro persistent memory plugin for OpenCode auto-recall, auto-capture, 9 memory tools with clustering, project-scoped memory isolation",
5
- "type": "module",
6
- "main": "src/index.ts",
7
- "exports": {
8
- ".": {
9
- "types": "./src/index.ts",
10
- "default": "./src/index.ts"
11
- },
12
- "./tui": {
13
- "types": "./src/tui.tsx",
14
- "default": "./src/tui.tsx"
15
- }
16
- },
17
- "oc-plugin": [
18
- "server",
19
- "tui"
20
- ],
21
- "scripts": {
22
- "build:web": "bash ../../scripts/build-plugin-web.sh",
23
- "prepublishOnly": "npm run build:web && npx tsc --noEmit"
24
- },
25
- "keywords": [
26
- "opencode",
27
- "memory",
28
- "ai-agent",
29
- "persistent-memory",
30
- "cerebro",
31
- "clustering",
32
- "project-isolation"
33
- ],
34
- "author": "mingxy-cerebro",
35
- "files": [
36
- "src/",
37
- "web/"
38
- ],
39
- "license": "Apache-2.0",
40
- "homepage": "https://github.com/mingxy-cerebro/cerebro-server",
41
- "repository": {
42
- "type": "git",
43
- "url": "https://github.com/mingxy-cerebro/cerebro-server.git",
44
- "directory": "plugins/opencode"
45
- },
46
- "dependencies": {
47
- "@opencode-ai/plugin": "^1.0.162",
48
- "@opentui/core": "^0.1.92",
49
- "@opentui/solid": "^0.1.92",
50
- "solid-js": "^1.9.10"
51
- },
52
- "devDependencies": {
53
- "@types/node": "^25.5.0",
54
- "typescript": "^5.7.0"
55
- }
56
- }
1
+ {
2
+ "name": "@mingxy/cerebro",
3
+ "version": "1.18.12",
4
+ "description": "Cerebro persistent memory plugin for OpenCode \u2014 auto-recall, auto-capture, 9 memory tools with clustering, project-scoped memory isolation",
5
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./src/index.ts",
10
+ "default": "./src/index.ts"
11
+ },
12
+ "./tui": {
13
+ "types": "./src/tui.tsx",
14
+ "default": "./src/tui.tsx"
15
+ }
16
+ },
17
+ "oc-plugin": [
18
+ "server",
19
+ "tui"
20
+ ],
21
+ "scripts": {
22
+ "build:web": "bash ../../scripts/build-plugin-web.sh",
23
+ "prepublishOnly": "npm run build:web && npx tsc --noEmit"
24
+ },
25
+ "keywords": [
26
+ "opencode",
27
+ "memory",
28
+ "ai-agent",
29
+ "persistent-memory",
30
+ "cerebro",
31
+ "clustering",
32
+ "project-isolation"
33
+ ],
34
+ "author": "mingxy-cerebro",
35
+ "files": [
36
+ "src/",
37
+ "web/"
38
+ ],
39
+ "license": "Apache-2.0",
40
+ "homepage": "https://github.com/mingxy-cerebro/cerebro-server",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/mingxy-cerebro/cerebro-server.git",
44
+ "directory": "plugins/opencode"
45
+ },
46
+ "dependencies": {
47
+ "@opencode-ai/plugin": "^1.0.162",
48
+ "@opentui/core": "^0.1.92",
49
+ "@opentui/solid": "^0.1.92",
50
+ "solid-js": "^1.9.10"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^25.5.0",
54
+ "typescript": "^5.7.0"
55
+ }
56
+ }
package/src/client.ts CHANGED
@@ -42,19 +42,6 @@ export interface ListResponse {
42
42
  offset: number;
43
43
  }
44
44
 
45
- export interface ClusterSummary {
46
- cluster_id: string;
47
- title: string;
48
- summary: string;
49
- member_count: number;
50
- relevance_score: number;
51
- key_memories: MemoryDto[];
52
- }
53
-
54
- export interface ClusteredRecallResult {
55
- cluster_summaries: ClusterSummary[];
56
- standalone_memories: MemoryDto[];
57
- }
58
45
 
59
46
  export interface DiscardedItem {
60
47
  memory_id: string;
@@ -72,7 +59,6 @@ export interface ShouldRecallResponse {
72
59
  confidence?: number;
73
60
  memories?: SearchResult[];
74
61
  discarded?: DiscardedItem[];
75
- clustered?: ClusteredRecallResult;
76
62
  }
77
63
 
78
64
  export interface PreferenceDto {
package/src/config.ts CHANGED
@@ -75,7 +75,7 @@ const DEFAULTS: OmemPluginConfig = {
75
75
  mmrPenaltyFactor: 0.5,
76
76
  phase2Multiplier: 2,
77
77
  llmMaxEval: 15,
78
- refineStrategy: "balanced",
78
+ refineStrategy: "loose",
79
79
  },
80
80
  logging: {
81
81
  logEnabled: true,
package/src/hooks.ts CHANGED
@@ -290,76 +290,6 @@ function buildContextBlock(
290
290
  };
291
291
  }
292
292
 
293
- function buildClusteredContextBlock(
294
- clustered: import("./client.js").ClusteredRecallResult,
295
- budget: number,
296
- maxContentLength: number = 500,
297
- minItemChars: number = MIN_ITEM_CONTENT_CHARS,
298
- ): ContextBlockResult {
299
- const sections: string[] = [];
300
- const injectedIds: string[] = [];
301
-
302
- if (clustered.cluster_summaries.length > 0) {
303
- const totalClusterScore = clustered.cluster_summaries.reduce((sum, cs) => sum + cs.relevance_score, 0);
304
-
305
- sections.push("## 📋 主题簇(聚合记忆)");
306
- for (const cs of clustered.cluster_summaries) {
307
- const scoreIndicator = cs.relevance_score >= 0.8 ? "★★★" : cs.relevance_score >= 0.6 ? "★★" : "★";
308
- const clusterMaxLen = totalClusterScore > 0
309
- ? Math.min(maxContentLength, Math.max(minItemChars, Math.floor((cs.relevance_score / totalClusterScore) * budget)))
310
- : Math.min(maxContentLength, Math.max(minItemChars, Math.floor(budget / clustered.cluster_summaries.length)));
311
- sections.push(`\n### ${cs.title} (整合自${cs.member_count}条记忆) ${scoreIndicator}`);
312
- sections.push(`> ${cs.summary}`);
313
- if (cs.key_memories.length > 0) {
314
- sections.push("**核心要点:**");
315
- for (const mem of cs.key_memories) {
316
- const idTag = mem.id ? ` [id:${mem.id}]` : "";
317
- const relTag = mem.relations && mem.relations.length > 0
318
- ? ` [rel:${mem.relations.map((rel) => rel.target_id).join(",")}]`
319
- : "";
320
- const importanceBar = mem.importance >= 0.7 ? "●" : mem.importance >= 0.4 ? "◐" : "○";
321
- const content = truncate(mem.content, clusterMaxLen);
322
- sections.push(`- ${importanceBar}${idTag}${relTag} ${content}`);
323
- if (mem.id) injectedIds.push(mem.id);
324
- }
325
- }
326
- }
327
- }
328
-
329
- if (clustered.standalone_memories.length > 0) {
330
- const standaloneBudget = clustered.cluster_summaries.length === 0
331
- ? budget
332
- : Math.floor(budget * 0.3);
333
- const standaloneMaxLen = Math.min(maxContentLength, Math.max(minItemChars, Math.floor(standaloneBudget / clustered.standalone_memories.length)));
334
-
335
- sections.push("\n## 📌 补充信息");
336
- for (const mem of clustered.standalone_memories) {
337
- const idTag = mem.id ? ` [id:${mem.id}]` : "";
338
- const relTag = mem.relations && mem.relations.length > 0
339
- ? ` [rel:${mem.relations.map((rel) => rel.target_id).join(",")}]`
340
- : "";
341
- const content = truncate(mem.content, standaloneMaxLen);
342
- sections.push(`-${idTag}${relTag} ${content}`);
343
- if (mem.id) injectedIds.push(mem.id);
344
- }
345
- }
346
-
347
- const totalInjected = clustered.cluster_summaries.reduce((s, cs) => s + cs.member_count, 0) + clustered.standalone_memories.length;
348
-
349
- return {
350
- text: sections.length > 0
351
- ? [
352
- "<cerebro-context>",
353
- "",
354
- ...sections,
355
- "</cerebro-context>",
356
- ].join("\n")
357
- : "",
358
- injectedMemoryIds: injectedIds,
359
- injectedCount: totalInjected,
360
- };
361
- }
362
-
363
293
  export function autoRecallHook(client: CerebroClient, containerTags: string[], tui: any, config: Partial<OmemPluginConfig> = {}, getAgentName?: () => string, directory?: string) {
364
294
  const similarityThreshold = config.recall?.similarityThreshold ?? 0.4;
365
295
  const maxRecallResults = config.recall?.maxRecallResults ?? 10;
@@ -474,7 +404,7 @@ export function autoRecallHook(client: CerebroClient, containerTags: string[], t
474
404
  showToast(tui, "🧠 Cerebro Service Unavailable", "Unable to reach memory API · check connection", "error", toastDelayMs);
475
405
  return;
476
406
  }
477
- logDebug("autoRecallHook shouldRecall result", { shouldRecall: shouldRecallRes.should_recall, confidence: shouldRecallRes.confidence, memCount: shouldRecallRes.memories?.length ?? 0, discardedCount: shouldRecallRes.discarded?.length ?? 0, clustered: !!shouldRecallRes.clustered });
407
+ logDebug("autoRecallHook shouldRecall result", { shouldRecall: shouldRecallRes.should_recall, confidence: shouldRecallRes.confidence, memCount: shouldRecallRes.memories?.length ?? 0, discardedCount: shouldRecallRes.discarded?.length ?? 0 });
478
408
 
479
409
  const storedMemoryIds = shouldRecallRes.memories?.map((r) => r.memory.id) ?? [];
480
410
  const storedDiscardedIds = shouldRecallRes.discarded?.map((d) => d.memory_id) ?? [];
@@ -494,38 +424,7 @@ export function autoRecallHook(client: CerebroClient, containerTags: string[], t
494
424
  },
495
425
  ): Promise<string | undefined> => {
496
426
  try {
497
- const memoryLookup = new Map<string, SearchResult>();
498
- if (shouldRecallRes.memories) {
499
- for (const r of shouldRecallRes.memories) {
500
- memoryLookup.set(r.memory.id, r);
501
- }
502
- }
503
- const items = clustered
504
- ? [
505
- ...clustered.cluster_summaries.flatMap((cs) =>
506
- cs.key_memories.map((mem) => {
507
- const sr = memoryLookup.get(mem.id ?? "");
508
- return {
509
- memory_id: mem.id ?? "",
510
- score: cs.relevance_score,
511
- refine_relevance: sr?.refine_relevance,
512
- refine_reasoning: sr?.refine_reasoning,
513
- is_kept: opts.injectedMemoryIds.includes(mem.id ?? ""),
514
- };
515
- })
516
- ),
517
- ...clustered.standalone_memories.map((mem) => {
518
- const sr = memoryLookup.get(mem.id ?? "");
519
- return {
520
- memory_id: mem.id ?? "",
521
- score: sr?.score ?? 0,
522
- refine_relevance: sr?.refine_relevance,
523
- refine_reasoning: sr?.refine_reasoning,
524
- is_kept: opts.injectedMemoryIds.includes(mem.id ?? ""),
525
- };
526
- }),
527
- ]
528
- : [
427
+ const items = [
529
428
  ...(shouldRecallRes.memories?.map((r) => ({
530
429
  memory_id: r.memory.id,
531
430
  score: r.score,
@@ -583,7 +482,6 @@ export function autoRecallHook(client: CerebroClient, containerTags: string[], t
583
482
  }
584
483
 
585
484
  const results = shouldRecallRes.memories ?? [];
586
- const clustered = shouldRecallRes.clustered;
587
485
 
588
486
  // --- Token Budget Calculation ---
589
487
  const profileChars = profileBlock ? profileBlock.length : 0;
@@ -596,9 +494,7 @@ export function autoRecallHook(client: CerebroClient, containerTags: string[], t
596
494
  configuredMax: maxContentLength,
597
495
  });
598
496
 
599
- const ctxResult = clustered
600
- ? buildClusteredContextBlock(clustered, budgetRemaining, maxContentLength, MIN_ITEM_CONTENT_CHARS)
601
- : buildContextBlock(results, budgetRemaining, maxContentLength, MIN_ITEM_CONTENT_CHARS);
497
+ const ctxResult = buildContextBlock(results, budgetRemaining, maxContentLength, MIN_ITEM_CONTENT_CHARS);
602
498
  if (ctxResult.text) {
603
499
  appendToSystem(output.system, ctxResult.text);
604
500
  appendToSystem(output.system, FETCH_POLICY);
@@ -616,7 +512,7 @@ export function autoRecallHook(client: CerebroClient, containerTags: string[], t
616
512
  logDebug("autoRecallHook profile injected after context", { sessionId: input.sessionID, outputSystemLength: output.system.length });
617
513
  }
618
514
 
619
- logDebug("autoRecallHook injection complete", { clustered: !!clustered, sessionId: input.sessionID });
515
+ logDebug("autoRecallHook injection complete", { sessionId: input.sessionID });
620
516
 
621
517
  const didInjectProfile = !!profileBlock;
622
518
  const didInjectContext = !!ctxResult.text;