@smyslenny/agent-memory 4.1.0-alpha.1 → 4.2.0
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 +38 -0
- package/dist/bin/agent-memory.js +9 -6
- package/dist/bin/agent-memory.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +35 -6
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +35 -6
- package/dist/mcp/server.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.2.0 (2026-03-19)
|
|
4
|
+
|
|
5
|
+
### 🛡️ Anti-Noise Hardening
|
|
6
|
+
|
|
7
|
+
This release addresses the "heartbeat flood" problem where memory-sync cron
|
|
8
|
+
ingested hundreds of low-value status observations (e.g. "HEARTBEAT_OK",
|
|
9
|
+
"安静模式", "PR 无变化") into the curated memory store.
|
|
10
|
+
|
|
11
|
+
#### Guard improvements
|
|
12
|
+
- **Raised specificity threshold** for P2/P3 memories from 8 to 20 effective
|
|
13
|
+
characters
|
|
14
|
+
- **CJK-aware length calculation**: CJK characters count as 3 effective chars
|
|
15
|
+
(reflecting their higher information density vs ASCII), preventing false
|
|
16
|
+
rejections of legitimate Chinese content
|
|
17
|
+
|
|
18
|
+
#### Ingest noise filter
|
|
19
|
+
- Added `isIngestNoise()` pre-filter in `extractIngestItems()` that skips lines
|
|
20
|
+
matching known noise patterns before they reach the Write Guard:
|
|
21
|
+
- Heartbeat status: `HEARTBEAT_OK`, `安静模式`, `不打扰`, `继续安静待命`
|
|
22
|
+
- Empty deltas: `无新 delta`, `无变化`, `无紧急`, `无新进展`
|
|
23
|
+
- System dumps: `openclaw status`, `openclaw gateway status`, `session_status`
|
|
24
|
+
- Stale PR observations: `PR #NNN 无变化`, `基线未变`, `轻量复查`
|
|
25
|
+
- Cron noise: `cron 会话`, `距上次心跳`, `危险区协议`
|
|
26
|
+
|
|
27
|
+
#### Tidy expansion
|
|
28
|
+
- `getDecayedMemories()` now includes **P2 (knowledge)** in cleanup candidates
|
|
29
|
+
(previously only P3 event). This means decayed low-vitality knowledge entries
|
|
30
|
+
will be cleaned up during sleep tidy, not just events.
|
|
31
|
+
|
|
32
|
+
#### Govern env config
|
|
33
|
+
- `maxMemories` can now be set via `AGENT_MEMORY_MAX_MEMORIES` environment
|
|
34
|
+
variable (default: 200)
|
|
35
|
+
|
|
36
|
+
### ✅ Tests
|
|
37
|
+
- 66 tests passing (19 files)
|
|
38
|
+
- Added `tests/ingest/noise-filter.test.ts` covering heartbeat noise rejection,
|
|
39
|
+
meaningful content preservation, and mixed signal/noise handling
|
|
40
|
+
|
|
3
41
|
## 4.0.0-alpha.1 (2026-03-09)
|
|
4
42
|
|
|
5
43
|
### 🚀 Repositioning
|
package/dist/bin/agent-memory.js
CHANGED
|
@@ -2187,9 +2187,11 @@ function fourCriterionGate(input) {
|
|
|
2187
2187
|
const content = input.content.trim();
|
|
2188
2188
|
const failed = [];
|
|
2189
2189
|
const priority = input.priority ?? (input.type === "identity" ? 0 : input.type === "emotion" ? 1 : input.type === "knowledge" ? 2 : 3);
|
|
2190
|
-
const
|
|
2191
|
-
const
|
|
2192
|
-
|
|
2190
|
+
const cjkCount = (content.match(/[\u4e00-\u9fff\u3400-\u4dbf]/g) ?? []).length;
|
|
2191
|
+
const effectiveLength = content.length + cjkCount * 2;
|
|
2192
|
+
const minLength = priority <= 1 ? 4 : 20;
|
|
2193
|
+
const specificity = effectiveLength >= minLength ? Math.min(1, effectiveLength / 50) : 0;
|
|
2194
|
+
if (specificity === 0) failed.push(`specificity (too short: effective ${effectiveLength} < ${minLength} chars)`);
|
|
2193
2195
|
const tokens = tokenize(content);
|
|
2194
2196
|
const novelty = tokens.length >= 1 ? Math.min(1, tokens.length / 5) : 0;
|
|
2195
2197
|
if (novelty === 0) failed.push("novelty (no meaningful tokens after filtering)");
|
|
@@ -2420,9 +2422,9 @@ function getDecayedMemories(db, threshold = 0.05, opts) {
|
|
|
2420
2422
|
const agentId = opts?.agent_id;
|
|
2421
2423
|
return db.prepare(
|
|
2422
2424
|
agentId ? `SELECT id, content, vitality, priority FROM memories
|
|
2423
|
-
WHERE vitality < ? AND priority >=
|
|
2425
|
+
WHERE vitality < ? AND priority >= 2 AND agent_id = ?
|
|
2424
2426
|
ORDER BY vitality ASC` : `SELECT id, content, vitality, priority FROM memories
|
|
2425
|
-
WHERE vitality < ? AND priority >=
|
|
2427
|
+
WHERE vitality < ? AND priority >= 2
|
|
2426
2428
|
ORDER BY vitality ASC`
|
|
2427
2429
|
).all(...agentId ? [threshold, agentId] : [threshold]);
|
|
2428
2430
|
}
|
|
@@ -2520,7 +2522,8 @@ function rankEvictionCandidates(db, opts) {
|
|
|
2520
2522
|
}
|
|
2521
2523
|
function runGovern(db, opts) {
|
|
2522
2524
|
const agentId = opts?.agent_id;
|
|
2523
|
-
const
|
|
2525
|
+
const envMax = Number.parseInt(process.env.AGENT_MEMORY_MAX_MEMORIES ?? "", 10);
|
|
2526
|
+
const maxMemories = opts?.maxMemories ?? (Number.isFinite(envMax) && envMax > 0 ? envMax : 200);
|
|
2524
2527
|
let orphanPaths = 0;
|
|
2525
2528
|
let emptyMemories = 0;
|
|
2526
2529
|
let evicted = 0;
|