memory-lancedb-pro 1.0.27 → 1.0.29

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.md CHANGED
@@ -780,29 +780,31 @@ Config-only changes do NOT need cache clearing.
780
780
 
781
781
  ## Contributors
782
782
 
783
- Top contributors (from GitHubs contributors list, sorted by commit contributions; bots excluded):
783
+ Top contributors (from GitHub's contributors list, sorted by commit contributions; bots excluded):
784
784
 
785
785
  <p>
786
786
  <a href="https://github.com/win4r"><img src="https://avatars.githubusercontent.com/u/42172631?v=4" width="48" height="48" alt="@win4r" /></a>
787
787
  <a href="https://github.com/kctony"><img src="https://avatars.githubusercontent.com/u/1731141?v=4" width="48" height="48" alt="@kctony" /></a>
788
788
  <a href="https://github.com/Akatsuki-Ryu"><img src="https://avatars.githubusercontent.com/u/8062209?v=4" width="48" height="48" alt="@Akatsuki-Ryu" /></a>
789
+ <a href="https://github.com/AliceLJY"><img src="https://avatars.githubusercontent.com/u/136287420?v=4" width="48" height="48" alt="@AliceLJY" /></a>
789
790
  <a href="https://github.com/JasonSuz"><img src="https://avatars.githubusercontent.com/u/612256?v=4" width="48" height="48" alt="@JasonSuz" /></a>
790
791
  <a href="https://github.com/Minidoracat"><img src="https://avatars.githubusercontent.com/u/11269639?v=4" width="48" height="48" alt="@Minidoracat" /></a>
792
+ <a href="https://github.com/rwmjhb"><img src="https://avatars.githubusercontent.com/u/91475811?v=4" width="48" height="48" alt="@rwmjhb" /></a>
791
793
  <a href="https://github.com/furedericca-lab"><img src="https://avatars.githubusercontent.com/u/263020793?v=4" width="48" height="48" alt="@furedericca-lab" /></a>
792
794
  <a href="https://github.com/joe2643"><img src="https://avatars.githubusercontent.com/u/19421931?v=4" width="48" height="48" alt="@joe2643" /></a>
793
- <a href="https://github.com/AliceLJY"><img src="https://avatars.githubusercontent.com/u/136287420?v=4" width="48" height="48" alt="@AliceLJY" /></a>
794
795
  <a href="https://github.com/chenjiyong"><img src="https://avatars.githubusercontent.com/u/8199522?v=4" width="48" height="48" alt="@chenjiyong" /></a>
795
796
  </p>
796
797
 
797
- - [@win4r](https://github.com/win4r) (3 commits)
798
+ - [@win4r](https://github.com/win4r) (4 commits)
798
799
  - [@kctony](https://github.com/kctony) (2 commits)
799
800
  - [@Akatsuki-Ryu](https://github.com/Akatsuki-Ryu) (1 commit)
800
801
  - [@AliceLJY](https://github.com/AliceLJY) (1 commit)
801
- - [@chenjiyong](https://github.com/chenjiyong) (1 commit)
802
802
  - [@JasonSuz](https://github.com/JasonSuz) (1 commit)
803
803
  - [@Minidoracat](https://github.com/Minidoracat) (1 commit)
804
+ - [@rwmjhb](https://github.com/rwmjhb) (1 commit)
804
805
  - [@furedericca-lab](https://github.com/furedericca-lab) (1 commit)
805
806
  - [@joe2643](https://github.com/joe2643) (1 commit)
807
+ - [@chenjiyong](https://github.com/chenjiyong) (1 commit)
806
808
 
807
809
  Full list: https://github.com/win4r/memory-lancedb-pro/graphs/contributors
808
810
 
package/README_CN.md CHANGED
@@ -660,23 +660,25 @@ Config-only changes do NOT need cache clearing.
660
660
  <a href="https://github.com/win4r"><img src="https://avatars.githubusercontent.com/u/42172631?v=4" width="48" height="48" alt="@win4r" /></a>
661
661
  <a href="https://github.com/kctony"><img src="https://avatars.githubusercontent.com/u/1731141?v=4" width="48" height="48" alt="@kctony" /></a>
662
662
  <a href="https://github.com/Akatsuki-Ryu"><img src="https://avatars.githubusercontent.com/u/8062209?v=4" width="48" height="48" alt="@Akatsuki-Ryu" /></a>
663
+ <a href="https://github.com/AliceLJY"><img src="https://avatars.githubusercontent.com/u/136287420?v=4" width="48" height="48" alt="@AliceLJY" /></a>
663
664
  <a href="https://github.com/JasonSuz"><img src="https://avatars.githubusercontent.com/u/612256?v=4" width="48" height="48" alt="@JasonSuz" /></a>
664
665
  <a href="https://github.com/Minidoracat"><img src="https://avatars.githubusercontent.com/u/11269639?v=4" width="48" height="48" alt="@Minidoracat" /></a>
666
+ <a href="https://github.com/rwmjhb"><img src="https://avatars.githubusercontent.com/u/91475811?v=4" width="48" height="48" alt="@rwmjhb" /></a>
665
667
  <a href="https://github.com/furedericca-lab"><img src="https://avatars.githubusercontent.com/u/263020793?v=4" width="48" height="48" alt="@furedericca-lab" /></a>
666
668
  <a href="https://github.com/joe2643"><img src="https://avatars.githubusercontent.com/u/19421931?v=4" width="48" height="48" alt="@joe2643" /></a>
667
- <a href="https://github.com/AliceLJY"><img src="https://avatars.githubusercontent.com/u/136287420?v=4" width="48" height="48" alt="@AliceLJY" /></a>
668
669
  <a href="https://github.com/chenjiyong"><img src="https://avatars.githubusercontent.com/u/8199522?v=4" width="48" height="48" alt="@chenjiyong" /></a>
669
670
  </p>
670
671
 
671
- - [@win4r](https://github.com/win4r)(3 次提交)
672
+ - [@win4r](https://github.com/win4r)(4 次提交)
672
673
  - [@kctony](https://github.com/kctony)(2 次提交)
673
674
  - [@Akatsuki-Ryu](https://github.com/Akatsuki-Ryu)(1 次提交)
674
675
  - [@AliceLJY](https://github.com/AliceLJY)(1 次提交)
675
- - [@chenjiyong](https://github.com/chenjiyong)(1 次提交)
676
676
  - [@JasonSuz](https://github.com/JasonSuz)(1 次提交)
677
677
  - [@Minidoracat](https://github.com/Minidoracat)(1 次提交)
678
+ - [@rwmjhb](https://github.com/rwmjhb)(1 次提交)
678
679
  - [@furedericca-lab](https://github.com/furedericca-lab)(1 次提交)
679
680
  - [@joe2643](https://github.com/joe2643)(1 次提交)
681
+ - [@chenjiyong](https://github.com/chenjiyong)(1 次提交)
680
682
 
681
683
  完整列表:https://github.com/win4r/memory-lancedb-pro/graphs/contributors
682
684
 
package/index.ts CHANGED
@@ -416,6 +416,13 @@ const memoryLanceDBProPlugin = {
416
416
 
417
417
  const pluginVersion = getPluginVersion();
418
418
 
419
+ // Session-based recall history to prevent redundant injections
420
+ // Map<sessionId, Map<memoryId, turnIndex>>
421
+ const recallHistory = new Map<string, Map<string, number>>();
422
+
423
+ // Map<sessionId, turnCounter> - manual turn tracking per session
424
+ const turnCounter = new Map<string, number>();
425
+
419
426
  api.logger.info(
420
427
  `memory-lancedb-pro@${pluginVersion}: plugin registered (db: ${resolvedDbPath}, model: ${config.embedding.model || "text-embedding-3-small"})`,
421
428
  );
@@ -468,6 +475,11 @@ const memoryLanceDBProPlugin = {
468
475
  return;
469
476
  }
470
477
 
478
+ // Manually increment turn counter for this session
479
+ const sessionId = ctx?.sessionId || "default";
480
+ const currentTurn = (turnCounter.get(sessionId) || 0) + 1;
481
+ turnCounter.set(sessionId, currentTurn);
482
+
471
483
  try {
472
484
  // Determine agent ID and accessible scopes
473
485
  const agentId = ctx?.agentId || "main";
@@ -484,7 +496,46 @@ const memoryLanceDBProPlugin = {
484
496
  return;
485
497
  }
486
498
 
487
- const memoryContext = results
499
+ // Filter out redundant memories based on session history
500
+ const minRepeated = config.autoRecallMinRepeated ?? 0;
501
+
502
+ // Only enable dedup logic when minRepeated > 0
503
+ let finalResults = results;
504
+
505
+ if (minRepeated > 0) {
506
+ const sessionHistory = recallHistory.get(sessionId) || new Map<string, number>();
507
+ const filteredResults = results.filter((r) => {
508
+ const lastTurn = sessionHistory.get(r.entry.id) ?? -999;
509
+ const diff = currentTurn - lastTurn;
510
+ const isRedundant = diff < minRepeated;
511
+
512
+ if (isRedundant) {
513
+ api.logger.debug?.(
514
+ `memory-lancedb-pro: skipping redundant memory ${r.entry.id.slice(0, 8)} (last seen at turn ${lastTurn}, current turn ${currentTurn}, min ${minRepeated})`,
515
+ );
516
+ }
517
+ return !isRedundant;
518
+ });
519
+
520
+ if (filteredResults.length === 0) {
521
+ if (results.length > 0) {
522
+ api.logger.info?.(
523
+ `memory-lancedb-pro: all ${results.length} memories were filtered out due to redundancy policy`,
524
+ );
525
+ }
526
+ return;
527
+ }
528
+
529
+ // Update history with successfully injected memories
530
+ for (const r of filteredResults) {
531
+ sessionHistory.set(r.entry.id, currentTurn);
532
+ }
533
+ recallHistory.set(sessionId, sessionHistory);
534
+
535
+ finalResults = filteredResults;
536
+ }
537
+
538
+ const memoryContext = finalResults
488
539
  .map(
489
540
  (r) =>
490
541
  `- [${r.entry.category}:${r.entry.scope}] ${sanitizeForContext(r.entry.text)} (${(r.score * 100).toFixed(0)}%${r.sources?.bm25 ? ", vector+BM25" : ""}${r.sources?.reranked ? "+reranked" : ""})`,
@@ -492,7 +543,7 @@ const memoryLanceDBProPlugin = {
492
543
  .join("\n");
493
544
 
494
545
  api.logger.info?.(
495
- `memory-lancedb-pro: injecting ${results.length} memories into context for agent ${agentId}`,
546
+ `memory-lancedb-pro: injecting ${finalResults.length} memories into context for agent ${agentId}`,
496
547
  );
497
548
 
498
549
  return {
@@ -87,6 +87,13 @@
87
87
  "default": 15,
88
88
  "description": "Minimum prompt length (in characters) to trigger auto-recall. Prompts shorter than this are skipped. Default: 15 for English, 6 for CJK."
89
89
  },
90
+ "autoRecallMinRepeated": {
91
+ "type": "integer",
92
+ "minimum": 0,
93
+ "maximum": 100,
94
+ "default": 0,
95
+ "description": "Minimum number of turns before the same memory can be recalled again in the same session. Set to 0 to disable deduplication (default behavior: inject all memories)."
96
+ },
90
97
  "captureAssistant": {
91
98
  "type": "boolean"
92
99
  },
@@ -334,6 +341,11 @@
334
341
  "help": "Minimum prompt length to trigger auto-recall (shorter prompts are skipped). Default: 15 chars for English, 6 for CJK.",
335
342
  "advanced": true
336
343
  },
344
+ "autoRecallMinRepeated": {
345
+ "label": "Auto-Recall Min Repeated",
346
+ "help": "Minimum number of conversation turns before a specific memory can be re-injected in the same session.",
347
+ "advanced": true
348
+ },
337
349
  "captureAssistant": {
338
350
  "label": "Capture Assistant Messages",
339
351
  "help": "Also auto-capture assistant messages (default false to reduce memory pollution)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memory-lancedb-pro",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "OpenClaw enhanced LanceDB memory plugin with hybrid retrieval (Vector + BM25), cross-encoder rerank, multi-scope isolation, long-context chunking, and management CLI",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -46,21 +46,24 @@ const FORCE_RETRIEVE_PATTERNS = [
46
46
  function normalizeQuery(query: string): string {
47
47
  let s = query.trim();
48
48
 
49
- // Strip OpenClaw cron wrapper prefix.
50
- s = s.replace(/^\[cron:[^\]]+\]\s*/i, "");
51
-
52
- // Strip OpenClaw timestamp prefix [Mon 2026-03-02 04:21 GMT+8].
53
- s = s.replace(/^\[[A-Za-z]{3}\s\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s[^\]]+\]\s*/, "");
54
-
55
- // Strip OpenClaw injected metadata header used in some transcripts.
56
- if (/^Conversation info \(untrusted metadata\):/i.test(s)) {
57
- s = s.replace(/^Conversation info \(untrusted metadata\):\s*/i, "");
58
- // If there is a blank-line separator, keep only the part after it.
49
+ // 1. Strip OpenClaw injected metadata header (Conversation info or Sender).
50
+ if (/^(Conversation info|Sender) \(untrusted metadata\):/i.test(s)) {
51
+ s = s.replace(/^(Conversation info|Sender) \(untrusted metadata\):\s*/i, "");
52
+ // If there is a blank-line separator (after JSON block), keep only the part after it.
59
53
  const parts = s.split(/\n\s*\n/, 2);
60
- if (parts.length === 2) s = parts[1];
54
+ if (parts.length === 2) {
55
+ s = parts[1].trim();
56
+ }
61
57
  }
62
58
 
63
- return s.trim();
59
+ // 2. Strip OpenClaw cron wrapper prefix.
60
+ s = s.trim().replace(/^\[cron:[^\]]+\]\s*/i, "");
61
+
62
+ // 3. Strip OpenClaw timestamp prefix [Mon 2026-03-02 04:21 GMT+8].
63
+ s = s.trim().replace(/^\[[A-Za-z]{3}\s\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s[^\]]+\]\s*/, "");
64
+
65
+ const result = s.trim();
66
+ return result;
64
67
  }
65
68
 
66
69
  /**