openclaw-mem 1.0.0 → 1.0.2
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 +5 -5
- package/lib/context-builder.js +46 -32
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -116,12 +116,12 @@ Add your preferences to `~/.openclaw/workspace/MEMORY.md`:
|
|
|
116
116
|
- Current project: Building a chat application
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
### Topic
|
|
119
|
+
### Dynamic Topic Detection
|
|
120
120
|
|
|
121
|
-
The system automatically
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
121
|
+
The system automatically extracts topics from your actual conversations:
|
|
122
|
+
- Concepts mentioned frequently are detected automatically
|
|
123
|
+
- No hardcoded keywords - everything comes from your data
|
|
124
|
+
- Topics evolve as your discussions change
|
|
125
125
|
|
|
126
126
|
## 🔧 Troubleshooting
|
|
127
127
|
|
package/lib/context-builder.js
CHANGED
|
@@ -186,49 +186,63 @@ function buildRetrievalInstructions() {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
/**
|
|
189
|
-
* Build topic summaries from
|
|
189
|
+
* Build topic summaries from user's actual recorded concepts
|
|
190
|
+
* Dynamically extracts topics from what the user has discussed
|
|
190
191
|
*/
|
|
191
192
|
function buildTopicSummaries() {
|
|
192
|
-
//
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
try {
|
|
205
|
-
const results = database.searchObservations(kw, 2);
|
|
206
|
-
for (const r of results) {
|
|
207
|
-
// Avoid duplicates
|
|
208
|
-
if (!topicResults.find(t => t.id === r.id)) {
|
|
209
|
-
topicResults.push(r);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
} catch (e) {
|
|
213
|
-
// Search might fail, continue
|
|
193
|
+
// Get all recent observations to extract actual concepts
|
|
194
|
+
const recentObs = database.getRecentObservations(null, 100);
|
|
195
|
+
|
|
196
|
+
// Extract and count concepts from user's actual data
|
|
197
|
+
const conceptCounts = {};
|
|
198
|
+
for (const obs of recentObs) {
|
|
199
|
+
if (obs.concepts) {
|
|
200
|
+
const concepts = obs.concepts.split(',').map(c => c.trim()).filter(c => c.length > 1);
|
|
201
|
+
for (const concept of concepts) {
|
|
202
|
+
// Skip generic tool names
|
|
203
|
+
if (['edit', 'bash', 'read', 'grep', 'write', 'glob'].includes(concept.toLowerCase())) continue;
|
|
204
|
+
conceptCounts[concept] = (conceptCounts[concept] || 0) + 1;
|
|
214
205
|
}
|
|
215
206
|
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Get top concepts (mentioned at least twice)
|
|
210
|
+
const topConcepts = Object.entries(conceptCounts)
|
|
211
|
+
.filter(([_, count]) => count >= 2)
|
|
212
|
+
.sort((a, b) => b[1] - a[1])
|
|
213
|
+
.slice(0, 10)
|
|
214
|
+
.map(([concept, _]) => concept);
|
|
215
|
+
|
|
216
|
+
if (topConcepts.length === 0) return '';
|
|
216
217
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
218
|
+
const sections = [];
|
|
219
|
+
const seenIds = new Set();
|
|
220
|
+
|
|
221
|
+
// Search for each top concept
|
|
222
|
+
for (const concept of topConcepts.slice(0, 5)) {
|
|
223
|
+
try {
|
|
224
|
+
const results = database.searchObservations(concept, 3);
|
|
225
|
+
const newResults = results.filter(r => !seenIds.has(r.id));
|
|
226
|
+
|
|
227
|
+
if (newResults.length > 0) {
|
|
228
|
+
sections.push(`### ${concept}`);
|
|
229
|
+
sections.push('');
|
|
230
|
+
for (const r of newResults.slice(0, 2)) {
|
|
231
|
+
seenIds.add(r.id);
|
|
232
|
+
const summary = r.summary || '';
|
|
233
|
+
if (summary.length > 20) {
|
|
234
|
+
sections.push(`- **#${r.id}**: ${summary.slice(0, 150)}${summary.length > 150 ? '...' : ''}`);
|
|
235
|
+
}
|
|
224
236
|
}
|
|
237
|
+
sections.push('');
|
|
225
238
|
}
|
|
226
|
-
|
|
239
|
+
} catch (e) {
|
|
240
|
+
// Search might fail, continue
|
|
227
241
|
}
|
|
228
242
|
}
|
|
229
243
|
|
|
230
244
|
if (sections.length > 0) {
|
|
231
|
-
return '## 历史话题讨论\n\n' + sections.join('\n');
|
|
245
|
+
return '## 历史话题讨论\n\n基于您的实际对话自动提取的主题:\n\n' + sections.join('\n');
|
|
232
246
|
}
|
|
233
247
|
return '';
|
|
234
248
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-mem",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Persistent memory system for OpenClaw - Give your AI agent long-term memory",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/handler.js",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "git+https://github.com/
|
|
33
|
+
"url": "git+https://github.com/wenyupapa-sys/openclaw-mem.git"
|
|
34
34
|
},
|
|
35
|
-
"homepage": "https://github.com/
|
|
35
|
+
"homepage": "https://github.com/wenyupapa-sys/openclaw-mem#readme",
|
|
36
36
|
"bugs": {
|
|
37
|
-
"url": "https://github.com/
|
|
37
|
+
"url": "https://github.com/wenyupapa-sys/openclaw-mem/issues"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
40
40
|
"node": ">=18.0.0"
|