mr-memory 3.9.0 → 3.9.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.js +3 -35
- package/index.ts +4 -36
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -55,7 +55,6 @@ function stripOldMemory(text) {
|
|
|
55
55
|
function jsonToolResult(payload) {
|
|
56
56
|
return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }], details: payload };
|
|
57
57
|
}
|
|
58
|
-
const NUDGE_INTERVAL_MS = 24 * 60 * 60 * 1000; // at most one nudge per 24h
|
|
59
58
|
function buildDebtNudgeLine(reflection) {
|
|
60
59
|
if (!reflection || !reflection.suggestion)
|
|
61
60
|
return null;
|
|
@@ -63,7 +62,7 @@ function buildDebtNudgeLine(reflection) {
|
|
|
63
62
|
const tier2Tokens = reflection.unconsolidated?.tier2?.est_tokens ?? 0;
|
|
64
63
|
const totalTokens = rawTokens + tier2Tokens;
|
|
65
64
|
const kTokens = Math.max(1, Math.round(totalTokens / 1000));
|
|
66
|
-
return `[MemoryRouter] Consolidation
|
|
65
|
+
return `[MemoryRouter] Consolidation suggested: ${kTokens}k unconsolidated tokens. Use the memory_reflect tool to consolidate them now.`;
|
|
67
66
|
}
|
|
68
67
|
// ── memory_get helpers (copied from OpenClaw source — pure filesystem, no embeddings)
|
|
69
68
|
function isFileMissingError(err) {
|
|
@@ -311,37 +310,6 @@ async function writeOpenClawConfigFile(config) {
|
|
|
311
310
|
await writeFile(configPath, `${JSON.stringify(config, null, 2)}
|
|
312
311
|
`, "utf8");
|
|
313
312
|
}
|
|
314
|
-
// Nudge rate-limit state lives beside the OpenClaw config so it survives restarts
|
|
315
|
-
// without churning the main config file.
|
|
316
|
-
function nudgeStatePath() {
|
|
317
|
-
return join(dirname(openClawConfigPath()), "mr-memory-state.json");
|
|
318
|
-
}
|
|
319
|
-
async function consumeNudgeBudget() {
|
|
320
|
-
const now = Date.now();
|
|
321
|
-
let state = {};
|
|
322
|
-
try {
|
|
323
|
-
state = JSON.parse(await readFile(nudgeStatePath(), "utf8"));
|
|
324
|
-
}
|
|
325
|
-
catch { /* missing or unreadable state: treat as never nudged */ }
|
|
326
|
-
if (typeof state.lastNudgeAt === "number" && now - state.lastNudgeAt < NUDGE_INTERVAL_MS) {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
try {
|
|
330
|
-
await writeFile(nudgeStatePath(), `${JSON.stringify({ ...state, lastNudgeAt: now }, null, 2)}\n`, "utf8");
|
|
331
|
-
}
|
|
332
|
-
catch { /* state write failure must never break prepare */ }
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
|
-
/** One-line, rate-limited debt nudge for prepare injections. Returns null when
|
|
336
|
-
* there is no suggestion or the 24h budget is spent. */
|
|
337
|
-
async function maybeDebtNudge(reflection) {
|
|
338
|
-
const line = buildDebtNudgeLine(reflection);
|
|
339
|
-
if (!line)
|
|
340
|
-
return null;
|
|
341
|
-
if (!(await consumeNudgeBudget()))
|
|
342
|
-
return null;
|
|
343
|
-
return line;
|
|
344
|
-
}
|
|
345
313
|
// ──────────────────────────────────────────────────────
|
|
346
314
|
// Full-replace: disable OpenClaw's native memory search so MemoryRouter
|
|
347
315
|
// owns the memory_search tool (no name conflict, no native embeddings 429).
|
|
@@ -773,7 +741,7 @@ If setting up MemoryRouter for another agent:
|
|
|
773
741
|
if (elapsed > 2000 && data.metrics)
|
|
774
742
|
log(`memoryrouter: prepare metrics ${JSON.stringify(data.metrics)}`);
|
|
775
743
|
let contextText = data.context;
|
|
776
|
-
const nudge =
|
|
744
|
+
const nudge = buildDebtNudgeLine(data.reflection);
|
|
777
745
|
if (nudge)
|
|
778
746
|
contextText = `${contextText}\n\n${nudge}`;
|
|
779
747
|
const wrapped = wrapForInjection(contextText);
|
|
@@ -882,7 +850,7 @@ If setting up MemoryRouter for another agent:
|
|
|
882
850
|
if (elapsed > 2000 && data.metrics)
|
|
883
851
|
log(`memoryrouter: prepare metrics ${JSON.stringify(data.metrics)}`);
|
|
884
852
|
let contextText = data.context;
|
|
885
|
-
const nudge =
|
|
853
|
+
const nudge = buildDebtNudgeLine(data.reflection);
|
|
886
854
|
if (nudge)
|
|
887
855
|
contextText = `${contextText}\n\n${nudge}`;
|
|
888
856
|
const wrapped = wrapForInjection(contextText);
|
package/index.ts
CHANGED
|
@@ -65,7 +65,7 @@ function jsonToolResult(payload: unknown) {
|
|
|
65
65
|
return { content: [{ type: "text" as const, text: JSON.stringify(payload, null, 2) }], details: payload };
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
// ── Reflection debt nudge (
|
|
68
|
+
// ── Reflection debt nudge (one line, appended to prepare injections whenever the server suggests it)
|
|
69
69
|
type ReflectionDebt = {
|
|
70
70
|
suggestion?: string | null;
|
|
71
71
|
unconsolidated?: {
|
|
@@ -75,15 +75,13 @@ type ReflectionDebt = {
|
|
|
75
75
|
threshold_tokens?: number;
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
const NUDGE_INTERVAL_MS = 24 * 60 * 60 * 1000; // at most one nudge per 24h
|
|
79
|
-
|
|
80
78
|
function buildDebtNudgeLine(reflection: ReflectionDebt | undefined): string | null {
|
|
81
79
|
if (!reflection || !reflection.suggestion) return null;
|
|
82
80
|
const rawTokens = reflection.unconsolidated?.raw?.est_tokens ?? 0;
|
|
83
81
|
const tier2Tokens = reflection.unconsolidated?.tier2?.est_tokens ?? 0;
|
|
84
82
|
const totalTokens = rawTokens + tier2Tokens;
|
|
85
83
|
const kTokens = Math.max(1, Math.round(totalTokens / 1000));
|
|
86
|
-
return `[MemoryRouter] Consolidation
|
|
84
|
+
return `[MemoryRouter] Consolidation suggested: ${kTokens}k unconsolidated tokens. Use the memory_reflect tool to consolidate them now.`;
|
|
87
85
|
}
|
|
88
86
|
|
|
89
87
|
// ── memory_get helpers (copied from OpenClaw source — pure filesystem, no embeddings)
|
|
@@ -354,36 +352,6 @@ async function writeOpenClawConfigFile(config: JsonObject): Promise<void> {
|
|
|
354
352
|
`, "utf8");
|
|
355
353
|
}
|
|
356
354
|
|
|
357
|
-
// Nudge rate-limit state lives beside the OpenClaw config so it survives restarts
|
|
358
|
-
// without churning the main config file.
|
|
359
|
-
function nudgeStatePath(): string {
|
|
360
|
-
return join(dirname(openClawConfigPath()), "mr-memory-state.json");
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
async function consumeNudgeBudget(): Promise<boolean> {
|
|
364
|
-
const now = Date.now();
|
|
365
|
-
let state: { lastNudgeAt?: number } = {};
|
|
366
|
-
try {
|
|
367
|
-
state = JSON.parse(await readFile(nudgeStatePath(), "utf8"));
|
|
368
|
-
} catch { /* missing or unreadable state: treat as never nudged */ }
|
|
369
|
-
if (typeof state.lastNudgeAt === "number" && now - state.lastNudgeAt < NUDGE_INTERVAL_MS) {
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
try {
|
|
373
|
-
await writeFile(nudgeStatePath(), `${JSON.stringify({ ...state, lastNudgeAt: now }, null, 2)}\n`, "utf8");
|
|
374
|
-
} catch { /* state write failure must never break prepare */ }
|
|
375
|
-
return true;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/** One-line, rate-limited debt nudge for prepare injections. Returns null when
|
|
379
|
-
* there is no suggestion or the 24h budget is spent. */
|
|
380
|
-
async function maybeDebtNudge(reflection: ReflectionDebt | undefined): Promise<string | null> {
|
|
381
|
-
const line = buildDebtNudgeLine(reflection);
|
|
382
|
-
if (!line) return null;
|
|
383
|
-
if (!(await consumeNudgeBudget())) return null;
|
|
384
|
-
return line;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
355
|
// ──────────────────────────────────────────────────────
|
|
388
356
|
// Full-replace: disable OpenClaw's native memory search so MemoryRouter
|
|
389
357
|
// owns the memory_search tool (no name conflict, no native embeddings 429).
|
|
@@ -827,7 +795,7 @@ If setting up MemoryRouter for another agent:
|
|
|
827
795
|
api.logger.info?.(`memoryrouter: injected ${data.memories_found || 0} memories (${data.memory_tokens || 0} tokens, ${elapsed}ms) [llm_input]`);
|
|
828
796
|
if (elapsed > 2000 && data.metrics) log(`memoryrouter: prepare metrics ${JSON.stringify(data.metrics)}`);
|
|
829
797
|
let contextText = data.context;
|
|
830
|
-
const nudge =
|
|
798
|
+
const nudge = buildDebtNudgeLine(data.reflection);
|
|
831
799
|
if (nudge) contextText = `${contextText}\n\n${nudge}`;
|
|
832
800
|
const wrapped = wrapForInjection(contextText);
|
|
833
801
|
return { appendSystemContext: wrapped };
|
|
@@ -948,7 +916,7 @@ If setting up MemoryRouter for another agent:
|
|
|
948
916
|
api.logger.info?.(`memoryrouter: injected ${data.memories_found || 0} memories (${data.memory_tokens || 0} tokens, ${elapsed}ms)`);
|
|
949
917
|
if (elapsed > 2000 && data.metrics) log(`memoryrouter: prepare metrics ${JSON.stringify(data.metrics)}`);
|
|
950
918
|
let contextText = data.context;
|
|
951
|
-
const nudge =
|
|
919
|
+
const nudge = buildDebtNudgeLine(data.reflection);
|
|
952
920
|
if (nudge) contextText = `${contextText}\n\n${nudge}`;
|
|
953
921
|
const wrapped = wrapForInjection(contextText);
|
|
954
922
|
return { appendSystemContext: wrapped };
|
package/package.json
CHANGED