memory-lancedb-pro 1.0.18 → 1.0.20
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/CHANGELOG.md +20 -0
- package/README.md +3 -1
- package/cli.ts +5 -3
- package/index.ts +25 -8
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/tools.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
## 1.0.20
|
|
5
|
+
|
|
6
|
+
- Fix: reduce auto-capture noise by skipping memory-management prompts (delete/forget/cleanup memory entries).
|
|
7
|
+
- Improve: broaden English decision triggers so statements like "we decided / going forward we will use" are captured as decisions.
|
|
8
|
+
|
|
9
|
+
## 1.0.19
|
|
10
|
+
|
|
11
|
+
- UX: show memory IDs in `memory-pro list` and `memory-pro search` output, so users can delete entries without switching to JSON.
|
|
12
|
+
- UX: include IDs in agent tool outputs (`memory_recall`, `memory_list`) for easier debugging and `memory_forget` follow-ups.
|
|
13
|
+
|
|
14
|
+
## 1.0.18
|
|
15
|
+
|
|
16
|
+
- Fix: sync `openclaw.plugin.json` version with `package.json`, so the OpenClaw plugin info shows the correct version.
|
|
17
|
+
|
|
18
|
+
## 1.0.17
|
|
19
|
+
|
|
20
|
+
- Fix: adaptive-retrieval now strips OpenClaw-injected timestamp prefixes like `[Mon YYYY-MM-DD HH:MM ...] ...` to avoid skewing length-based heuristics.
|
|
21
|
+
- Improve: expanded SKIP/FORCE keyword patterns with Traditional Chinese variants.
|
|
22
|
+
|
|
3
23
|
## 1.0.16
|
|
4
24
|
|
|
5
25
|
- Feat: expand memory capture triggers to support Traditional Chinese (繁體中文) in addition to Simplified Chinese, and improve category detection keywords.
|
package/README.md
CHANGED
|
@@ -155,6 +155,7 @@ Filters out low-quality content at both auto-capture and tool-store stages:
|
|
|
155
155
|
### 8. Auto-Capture & Auto-Recall
|
|
156
156
|
|
|
157
157
|
- **Auto-Capture** (`agent_end` hook): Extracts preference/fact/decision/entity from conversations, deduplicates, stores up to 3 per turn
|
|
158
|
+
- Skips memory-management prompts (e.g. delete/forget/cleanup memory entries) to reduce noise
|
|
158
159
|
- **Auto-Recall** (`before_agent_start` hook): Injects `<relevant-memories>` context (up to 3 entries)
|
|
159
160
|
|
|
160
161
|
### Prevent memories from showing up in replies
|
|
@@ -613,7 +614,7 @@ This prevents cross-bot memory pollution.
|
|
|
613
614
|
## CLI Commands
|
|
614
615
|
|
|
615
616
|
```bash
|
|
616
|
-
# List memories
|
|
617
|
+
# List memories (output includes the memory id)
|
|
617
618
|
openclaw memory-pro list [--scope global] [--category fact] [--limit 20] [--json]
|
|
618
619
|
|
|
619
620
|
# Search memories
|
|
@@ -623,6 +624,7 @@ openclaw memory-pro search "query" [--scope global] [--limit 10] [--json]
|
|
|
623
624
|
openclaw memory-pro stats [--scope global] [--json]
|
|
624
625
|
|
|
625
626
|
# Delete a memory by ID (supports 8+ char prefix)
|
|
627
|
+
# Tip: copy the id shown by `memory-pro list` / `memory-pro search` (or use --json for full output)
|
|
626
628
|
openclaw memory-pro delete <id>
|
|
627
629
|
|
|
628
630
|
# Bulk delete with filters
|
package/cli.ts
CHANGED
|
@@ -42,9 +42,11 @@ function clampInt(value: number, min: number, max: number): number {
|
|
|
42
42
|
|
|
43
43
|
function formatMemory(memory: any, index?: number): string {
|
|
44
44
|
const prefix = index !== undefined ? `${index + 1}. ` : "";
|
|
45
|
+
const id = memory?.id ? String(memory.id) : "unknown";
|
|
45
46
|
const date = new Date(memory.timestamp || memory.createdAt || Date.now()).toISOString().split('T')[0];
|
|
46
|
-
const
|
|
47
|
-
|
|
47
|
+
const fullText = String(memory.text || "");
|
|
48
|
+
const text = fullText.slice(0, 100) + (fullText.length > 100 ? "..." : "");
|
|
49
|
+
return `${prefix}[${id}] [${memory.category}:${memory.scope}] ${text} (${date})`;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
function formatJson(obj: any): string {
|
|
@@ -150,7 +152,7 @@ export function registerMemoryCLI(program: Command, context: CLIContext): void {
|
|
|
150
152
|
if (result.sources.reranked) sources.push("reranked");
|
|
151
153
|
|
|
152
154
|
console.log(
|
|
153
|
-
`${i + 1}. [${result.entry.category}:${result.entry.scope}] ${result.entry.text} ` +
|
|
155
|
+
`${i + 1}. [${result.entry.id}] [${result.entry.category}:${result.entry.scope}] ${result.entry.text} ` +
|
|
154
156
|
`(${(result.score * 100).toFixed(0)}%, ${sources.join('+')})`
|
|
155
157
|
);
|
|
156
158
|
});
|
package/index.ts
CHANGED
|
@@ -107,6 +107,7 @@ const MEMORY_TRIGGERS = [
|
|
|
107
107
|
/zapamatuj si|pamatuj|remember/i,
|
|
108
108
|
/preferuji|radši|nechci|prefer/i,
|
|
109
109
|
/rozhodli jsme|budeme používat/i,
|
|
110
|
+
/\b(we )?decided\b|we'?ll use|we will use|switch(ed)? to|migrate(d)? to|going forward|from now on/i,
|
|
110
111
|
/\+\d{10,}/,
|
|
111
112
|
/[\w.-]+@[\w.-]+\.\w+/,
|
|
112
113
|
/můj\s+\w+\s+je|je\s+můj/i,
|
|
@@ -123,31 +124,47 @@ const MEMORY_TRIGGERS = [
|
|
|
123
124
|
/幫我|筆記|存檔|存起來|存一下|重點|原則|底線/,
|
|
124
125
|
];
|
|
125
126
|
|
|
127
|
+
const CAPTURE_EXCLUDE_PATTERNS = [
|
|
128
|
+
// Memory management / meta-ops: do not store as long-term memory
|
|
129
|
+
/\b(memory-pro|memory_store|memory_recall|memory_forget|memory_update)\b/i,
|
|
130
|
+
/\bopenclaw\s+memory-pro\b/i,
|
|
131
|
+
/\b(delete|remove|forget|purge|cleanup|clean up|clear)\b.*\b(memory|memories|entry|entries)\b/i,
|
|
132
|
+
/\b(memory|memories)\b.*\b(delete|remove|forget|purge|cleanup|clean up|clear)\b/i,
|
|
133
|
+
/\bhow do i\b.*\b(delete|remove|forget|purge|cleanup|clear)\b/i,
|
|
134
|
+
/(删除|刪除|清理|清除).{0,12}(记忆|記憶|memory)/i,
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
|
|
126
138
|
export function shouldCapture(text: string): boolean {
|
|
139
|
+
const s = text.trim();
|
|
140
|
+
|
|
127
141
|
// CJK characters carry more meaning per character, use lower minimum threshold
|
|
128
|
-
const hasCJK = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/.test(
|
|
142
|
+
const hasCJK = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/.test(s);
|
|
129
143
|
const minLen = hasCJK ? 4 : 10;
|
|
130
|
-
if (
|
|
144
|
+
if (s.length < minLen || s.length > 500) {
|
|
131
145
|
return false;
|
|
132
146
|
}
|
|
133
147
|
// Skip injected context from memory recall
|
|
134
|
-
if (
|
|
148
|
+
if (s.includes("<relevant-memories>")) {
|
|
135
149
|
return false;
|
|
136
150
|
}
|
|
137
151
|
// Skip system-generated content
|
|
138
|
-
if (
|
|
152
|
+
if (s.startsWith("<") && s.includes("</")) {
|
|
139
153
|
return false;
|
|
140
154
|
}
|
|
141
155
|
// Skip agent summary responses (contain markdown formatting)
|
|
142
|
-
if (
|
|
156
|
+
if (s.includes("**") && s.includes("\n-")) {
|
|
143
157
|
return false;
|
|
144
158
|
}
|
|
145
159
|
// Skip emoji-heavy responses (likely agent output)
|
|
146
|
-
const emojiCount = (
|
|
160
|
+
const emojiCount = (s.match(/[\u{1F300}-\u{1F9FF}]/gu) || []).length;
|
|
147
161
|
if (emojiCount > 3) {
|
|
148
162
|
return false;
|
|
149
163
|
}
|
|
150
|
-
|
|
164
|
+
// Exclude obvious memory-management prompts
|
|
165
|
+
if (CAPTURE_EXCLUDE_PATTERNS.some((r) => r.test(s))) return false;
|
|
166
|
+
|
|
167
|
+
return MEMORY_TRIGGERS.some((r) => r.test(s));
|
|
151
168
|
}
|
|
152
169
|
|
|
153
170
|
export function detectCategory(text: string): "preference" | "fact" | "decision" | "entity" | "other" {
|
|
@@ -155,7 +172,7 @@ export function detectCategory(text: string): "preference" | "fact" | "decision"
|
|
|
155
172
|
if (/prefer|radši|like|love|hate|want|偏好|喜歡|喜欢|討厭|讨厌|不喜歡|不喜欢|愛用|爱用|習慣|习惯/i.test(lower)) {
|
|
156
173
|
return "preference";
|
|
157
174
|
}
|
|
158
|
-
if (/rozhodli|decided|will use|budeme|決定|决定|選擇了|选择了|改用|換成|换成|以後用|以后用|規則|流程|SOP/i.test(lower)) {
|
|
175
|
+
if (/rozhodli|decided|we decided|will use|we will use|we'?ll use|switch(ed)? to|migrate(d)? to|going forward|from now on|budeme|決定|决定|選擇了|选择了|改用|換成|换成|以後用|以后用|規則|流程|SOP/i.test(lower)) {
|
|
159
176
|
return "decision";
|
|
160
177
|
}
|
|
161
178
|
if (/\+\d{10,}|@[\w.-]+\.\w+|is called|jmenuje se|我的\S+是|叫我|稱呼|称呼/i.test(lower)) {
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "memory-lancedb-pro",
|
|
3
3
|
"name": "Memory (LanceDB Pro)",
|
|
4
4
|
"description": "Enhanced LanceDB-backed long-term memory with hybrid retrieval, multi-scope isolation, and management CLI",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.20",
|
|
6
6
|
"kind": "memory",
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory-lancedb-pro",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"description": "OpenClaw enhanced LanceDB memory plugin with hybrid retrieval (Vector + BM25), cross-encoder rerank, multi-scope isolation, and management CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
package/src/tools.ts
CHANGED
|
@@ -113,7 +113,7 @@ export function registerMemoryRecallTool(api: OpenClawPluginApi, context: ToolCo
|
|
|
113
113
|
if (r.sources.bm25) sources.push("BM25");
|
|
114
114
|
if (r.sources.reranked) sources.push("reranked");
|
|
115
115
|
|
|
116
|
-
return `${i + 1}. [${r.entry.category}:${r.entry.scope}] ${r.entry.text} (${(r.score * 100).toFixed(0)}%${sources.length > 0 ? `, ${sources.join('+')}` : ''})`;
|
|
116
|
+
return `${i + 1}. [${r.entry.id}] [${r.entry.category}:${r.entry.scope}] ${r.entry.text} (${(r.score * 100).toFixed(0)}%${sources.length > 0 ? `, ${sources.join('+')}` : ''})`;
|
|
117
117
|
})
|
|
118
118
|
.join("\n");
|
|
119
119
|
|
|
@@ -583,7 +583,7 @@ export function registerMemoryListTool(api: OpenClawPluginApi, context: ToolCont
|
|
|
583
583
|
const text = entries
|
|
584
584
|
.map((entry, i) => {
|
|
585
585
|
const date = new Date(entry.timestamp).toISOString().split('T')[0];
|
|
586
|
-
return `${safeOffset + i + 1}. [${entry.category}:${entry.scope}] ${entry.text.slice(0, 100)}${entry.text.length > 100 ? '...' : ''} (${date})`;
|
|
586
|
+
return `${safeOffset + i + 1}. [${entry.id}] [${entry.category}:${entry.scope}] ${entry.text.slice(0, 100)}${entry.text.length > 100 ? '...' : ''} (${date})`;
|
|
587
587
|
})
|
|
588
588
|
.join('\n');
|
|
589
589
|
|