@digitalforgestudios/openclaw-sulcus 1.1.0 → 1.1.1
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/index.ts +62 -0
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -214,6 +214,23 @@ function shouldCapture(text: string): boolean {
|
|
|
214
214
|
// Reject if stripping removed >60% of the content (mostly metadata)
|
|
215
215
|
if (cleaned.length < text.length * 0.4) return false;
|
|
216
216
|
|
|
217
|
+
// Reject system prompts and OpenClaw operational messages that caused 1,000+ dupes
|
|
218
|
+
const rejectPatterns = [
|
|
219
|
+
/^Pre-compaction memory flush/i,
|
|
220
|
+
/^A new session was started via/i,
|
|
221
|
+
/^\[cron:[0-9a-f-]+/i,
|
|
222
|
+
/^To send an image back, prefer the message tool/i,
|
|
223
|
+
/^Heartbeat prompt:/i,
|
|
224
|
+
/^Read HEARTBEAT\.md/i,
|
|
225
|
+
/^Run your Session Startup sequence/i,
|
|
226
|
+
/^You are \w+\. T/i, // cron job identity preambles
|
|
227
|
+
/^Gateway restart/i,
|
|
228
|
+
/^System: \[/,
|
|
229
|
+
/^HEARTBEAT_OK$/i,
|
|
230
|
+
/^NO_REPLY$/i,
|
|
231
|
+
];
|
|
232
|
+
if (rejectPatterns.some((r) => r.test(cleaned))) return false;
|
|
233
|
+
|
|
217
234
|
const triggers = [
|
|
218
235
|
/remember|zapamatuj/i,
|
|
219
236
|
/prefer|like|love|hate|want/i,
|
|
@@ -558,6 +575,51 @@ const sulcusMemoryPlugin = {
|
|
|
558
575
|
});
|
|
559
576
|
}
|
|
560
577
|
|
|
578
|
+
// ========================================================================
|
|
579
|
+
// Lifecycle — Preserve memories before compaction
|
|
580
|
+
// ========================================================================
|
|
581
|
+
|
|
582
|
+
api.on("before_compaction", async (event) => {
|
|
583
|
+
if (!event.messages || event.messages.length === 0) return;
|
|
584
|
+
|
|
585
|
+
try {
|
|
586
|
+
// Scan messages being compacted for important content worth preserving
|
|
587
|
+
const toPreserve: string[] = [];
|
|
588
|
+
for (const msg of event.messages) {
|
|
589
|
+
if (!msg || typeof msg !== "object") continue;
|
|
590
|
+
const msgObj = msg as Record<string, unknown>;
|
|
591
|
+
const content = typeof msgObj.content === "string" ? msgObj.content : "";
|
|
592
|
+
if (!content || content.length < 30) continue;
|
|
593
|
+
|
|
594
|
+
const cleaned = stripMetadataEnvelope(content);
|
|
595
|
+
if (cleaned.length < 30) continue;
|
|
596
|
+
if (!shouldCapture(cleaned)) continue;
|
|
597
|
+
|
|
598
|
+
toPreserve.push(cleaned);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (toPreserve.length === 0) return;
|
|
602
|
+
|
|
603
|
+
// Store up to 5 important memories before compaction discards them
|
|
604
|
+
let stored = 0;
|
|
605
|
+
for (const text of toPreserve.slice(0, 5)) {
|
|
606
|
+
const type = detectMemoryType(text);
|
|
607
|
+
try {
|
|
608
|
+
await client.store(text.slice(0, 2000), type);
|
|
609
|
+
stored++;
|
|
610
|
+
} catch {
|
|
611
|
+
// 409 (dedup) or other — continue
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if (stored > 0) {
|
|
616
|
+
api.logger.info(`openclaw-sulcus: preserved ${stored} memories before compaction`);
|
|
617
|
+
}
|
|
618
|
+
} catch (err) {
|
|
619
|
+
api.logger.warn(`openclaw-sulcus: before_compaction failed: ${String(err)}`);
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
|
|
561
623
|
// ========================================================================
|
|
562
624
|
// Lifecycle — Auto-capture
|
|
563
625
|
// ========================================================================
|
package/package.json
CHANGED