openclaw-memory-alibaba-local 0.1.9-beta.21 → 0.1.9-beta.22
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/capture-state.ts +1 -2
- package/db.ts +2 -3
- package/index.ts +27 -53
- package/package.json +1 -1
- package/prompts.ts +5 -1
package/capture-state.ts
CHANGED
|
@@ -166,7 +166,6 @@ function getMessageRoleRaw(msg: unknown): string {
|
|
|
166
166
|
export function resolveRoleCountsForSession(
|
|
167
167
|
entry: CursorFileEntry | undefined,
|
|
168
168
|
messages: unknown[],
|
|
169
|
-
log: { info: (m: string) => void },
|
|
170
169
|
): { roleCounts: Record<string, number>; lastMessagesLength: number } {
|
|
171
170
|
if (isV2Entry(entry)) {
|
|
172
171
|
return {
|
|
@@ -176,7 +175,7 @@ export function resolveRoleCountsForSession(
|
|
|
176
175
|
}
|
|
177
176
|
if (isLegacyEntry(entry)) {
|
|
178
177
|
const end = Math.min(Math.max(0, entry.lastEndExclusive), messages.length);
|
|
179
|
-
log
|
|
178
|
+
console.log("[openclaw-memory-alibaba-local] migrated legacy full-context cursor to per-role counts");
|
|
180
179
|
return {
|
|
181
180
|
roleCounts: countRolesInMessagesPrefix(messages, end),
|
|
182
181
|
lastMessagesLength: end,
|
package/db.ts
CHANGED
|
@@ -1328,7 +1328,6 @@ export class MemoryDB {
|
|
|
1328
1328
|
agentId: string,
|
|
1329
1329
|
maxRows: number,
|
|
1330
1330
|
maxAgeMs: number,
|
|
1331
|
-
log?: { info: (m: string) => void },
|
|
1332
1331
|
): Promise<void> {
|
|
1333
1332
|
await this.ensureInitialized();
|
|
1334
1333
|
const a = sqlEscapeLiteral(agentId);
|
|
@@ -1343,7 +1342,7 @@ export class MemoryDB {
|
|
|
1343
1342
|
// 2. Count remaining; if over maxRows, trim oldest
|
|
1344
1343
|
const remaining = await this.table!.countRows(base);
|
|
1345
1344
|
if (remaining <= maxRows) {
|
|
1346
|
-
log
|
|
1345
|
+
console.log(`[openclaw-memory-alibaba-local] gcFullContext agent=${agentId} remaining=${remaining} (within limit)`);
|
|
1347
1346
|
return;
|
|
1348
1347
|
}
|
|
1349
1348
|
const excess = remaining - maxRows;
|
|
@@ -1357,6 +1356,6 @@ export class MemoryDB {
|
|
|
1357
1356
|
const cutoff = Number(oldest[excess - 1]!.createdAt);
|
|
1358
1357
|
await this.table!.delete(`${base} AND createdAt <= ${Math.floor(cutoff)}`);
|
|
1359
1358
|
}
|
|
1360
|
-
log
|
|
1359
|
+
console.log(`[openclaw-memory-alibaba-local] gcFullContext agent=${agentId} deleted ${excess} excess rows (was ${remaining}, cap ${maxRows})`);
|
|
1361
1360
|
}
|
|
1362
1361
|
}
|
package/index.ts
CHANGED
|
@@ -175,26 +175,22 @@ function getThresholdForCategory(cfg: MemoryConfig, category: MemoryCategory): n
|
|
|
175
175
|
return cfg.similarityThresholdSelfImproving;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
/** 可选:给 LLM / 衰减诊断日志(与 OpenClaw api.logger 兼容,仅用 info)。 */
|
|
179
|
-
type MemoryDiagnosticLog = { info: (m: string) => void } | undefined;
|
|
180
|
-
|
|
181
178
|
/** 精简日志:仅记录 tag + prompt 字符数,不贴原文。 */
|
|
182
|
-
function logLlmCall(tag: string, promptChars: number
|
|
183
|
-
log
|
|
179
|
+
function logLlmCall(tag: string, promptChars: number): void {
|
|
180
|
+
console.log(`[openclaw-memory-alibaba-local] llm ${tag} prompt (${promptChars} chars)`);
|
|
184
181
|
}
|
|
185
182
|
|
|
186
183
|
/** 记录 merge 结果统计。 */
|
|
187
|
-
function logMergeResult(total: number, actions: ReadonlyArray<{ action: string }
|
|
188
|
-
if (!log) return;
|
|
184
|
+
function logMergeResult(total: number, actions: ReadonlyArray<{ action: string }>): void {
|
|
189
185
|
const counts: Record<string, number> = {};
|
|
190
186
|
for (const a of actions) counts[a.action] = (counts[a.action] ?? 0) + 1;
|
|
191
187
|
const parts = Object.entries(counts).map(([k, v]) => `${v} ${k}`).join(", ");
|
|
192
|
-
log
|
|
188
|
+
console.log(`[openclaw-memory-alibaba-local] batchMerge result: ${total} items → ${parts}`);
|
|
193
189
|
}
|
|
194
190
|
|
|
195
191
|
/** 记忆衰减为纯公式,不向模型发提示词;仍打日志避免与「冲突检测 LLM」混淆。 */
|
|
196
|
-
function logMemoryDecayNoLlm(phase: string,
|
|
197
|
-
log
|
|
192
|
+
function logMemoryDecayNoLlm(phase: string, detail: string): void {
|
|
193
|
+
console.log(`[openclaw-memory-alibaba-local] memoryDecay ${phase} (no LLM; formula-only) ${detail}`);
|
|
198
194
|
}
|
|
199
195
|
|
|
200
196
|
/** Apply time decay to recall results: effectiveScore = score * decay(createdAt). Returns new array sorted by effectiveScore desc. */
|
|
@@ -234,7 +230,6 @@ async function runRecall(
|
|
|
234
230
|
agentId: string,
|
|
235
231
|
queryVectors: number[][],
|
|
236
232
|
options: { limitUser: number; limitSelf: number; minScore: number },
|
|
237
|
-
log?: MemoryDiagnosticLog,
|
|
238
233
|
): Promise<MemorySearchResult[]> {
|
|
239
234
|
if (queryVectors.length === 0) {
|
|
240
235
|
return [];
|
|
@@ -271,7 +266,6 @@ async function runRecall(
|
|
|
271
266
|
);
|
|
272
267
|
logMemoryDecayNoLlm(
|
|
273
268
|
"vectorRecall",
|
|
274
|
-
log,
|
|
275
269
|
`strategy=${cfg.memoryDecayStrategy} halfLifeDays=${cfg.memoryDecayHalfLifeDays} agentId=${agentId} inputRows=${decayIn}`,
|
|
276
270
|
);
|
|
277
271
|
}
|
|
@@ -288,7 +282,6 @@ async function bm25SupplementRecall(
|
|
|
288
282
|
queryText: string,
|
|
289
283
|
vectorResults: MemorySearchResult[],
|
|
290
284
|
maxAdd: number,
|
|
291
|
-
log?: MemoryDiagnosticLog,
|
|
292
285
|
): Promise<MemorySearchResult[]> {
|
|
293
286
|
const q = queryText.trim();
|
|
294
287
|
if (q.length < 2 || maxAdd <= 0) {
|
|
@@ -353,7 +346,6 @@ async function bm25SupplementRecall(
|
|
|
353
346
|
ranked = applyMemoryDecay(ranked, Date.now(), cfg.memoryDecayStrategy, cfg.memoryDecayHalfLifeDays);
|
|
354
347
|
logMemoryDecayNoLlm(
|
|
355
348
|
"bm25Pool",
|
|
356
|
-
log,
|
|
357
349
|
`strategy=${cfg.memoryDecayStrategy} halfLifeDays=${cfg.memoryDecayHalfLifeDays} agentId=${agentId} inputRows=${decayIn}`,
|
|
358
350
|
);
|
|
359
351
|
}
|
|
@@ -379,12 +371,11 @@ async function runHybridRecall(
|
|
|
379
371
|
queryText: string,
|
|
380
372
|
queryVectors: number[][],
|
|
381
373
|
options: { limitUser: number; limitSelf: number; minScore: number },
|
|
382
|
-
log?: MemoryDiagnosticLog,
|
|
383
374
|
): Promise<MemorySearchResult[]> {
|
|
384
|
-
const vector = await runRecall(db, cfg, agentId, queryVectors, options
|
|
375
|
+
const vector = await runRecall(db, cfg, agentId, queryVectors, options);
|
|
385
376
|
const extra =
|
|
386
377
|
queryText.trim().length >= 2
|
|
387
|
-
? await bm25SupplementRecall(db, cfg, agentId, queryText, vector, RECALL_BM25_MAX
|
|
378
|
+
? await bm25SupplementRecall(db, cfg, agentId, queryText, vector, RECALL_BM25_MAX)
|
|
388
379
|
: [];
|
|
389
380
|
return [...vector, ...extra].slice(0, RECALL_FINAL_MAX);
|
|
390
381
|
}
|
|
@@ -434,7 +425,6 @@ async function extractUserMemoriesWithLLM(
|
|
|
434
425
|
llmConfig: LLMConfig,
|
|
435
426
|
userMessages: string[],
|
|
436
427
|
_maxExtractions = Infinity,
|
|
437
|
-
log?: MemoryDiagnosticLog,
|
|
438
428
|
): Promise<LLMExtractionItem[]> {
|
|
439
429
|
if (userMessages.length === 0) return [];
|
|
440
430
|
const combined = userMessages
|
|
@@ -444,7 +434,7 @@ async function extractUserMemoriesWithLLM(
|
|
|
444
434
|
|
|
445
435
|
const extractionPrompt = buildMemoryExtractionPrompt() + combined;
|
|
446
436
|
|
|
447
|
-
logLlmCall("memoryExtraction", extractionPrompt.length
|
|
437
|
+
logLlmCall("memoryExtraction", extractionPrompt.length);
|
|
448
438
|
|
|
449
439
|
const openai = new OpenAI({
|
|
450
440
|
apiKey: llmConfig.apiKey,
|
|
@@ -468,7 +458,7 @@ async function extractUserMemoriesWithLLM(
|
|
|
468
458
|
}
|
|
469
459
|
return out;
|
|
470
460
|
} catch (err: unknown) {
|
|
471
|
-
|
|
461
|
+
console.warn(`[openclaw-memory-alibaba-local] memoryExtraction JSON parse failed: ${err}`);
|
|
472
462
|
return [];
|
|
473
463
|
}
|
|
474
464
|
};
|
|
@@ -479,13 +469,13 @@ async function extractUserMemoriesWithLLM(
|
|
|
479
469
|
temperature: 0,
|
|
480
470
|
max_tokens: 8192,
|
|
481
471
|
}).catch((err: unknown) => {
|
|
482
|
-
|
|
472
|
+
console.warn(`[openclaw-memory-alibaba-local] memoryExtraction LLM call failed: ${err}`);
|
|
483
473
|
return null;
|
|
484
474
|
});
|
|
485
475
|
|
|
486
476
|
const raw = completion?.choices[0]?.message?.content?.trim() ?? "";
|
|
487
477
|
const items = parseExtractions(raw);
|
|
488
|
-
log
|
|
478
|
+
console.log(`[openclaw-memory-alibaba-local] memoryExtraction extracted ${items.length} items`);
|
|
489
479
|
return items;
|
|
490
480
|
}
|
|
491
481
|
|
|
@@ -534,11 +524,10 @@ async function extractSelfImprovingWithLLM(
|
|
|
534
524
|
llmConfig: LLMConfig,
|
|
535
525
|
conversationText: string,
|
|
536
526
|
maxExtractions = MAX_AUTO_CAPTURE_SELF_IMPROVING,
|
|
537
|
-
log?: MemoryDiagnosticLog,
|
|
538
527
|
): Promise<SelfImprovingExtractionItem[]> {
|
|
539
528
|
if (conversationText.length < 20) return [];
|
|
540
529
|
const prompt = SELF_IMPROVING_EXTRACTION_INSTRUCTIONS + "\n" + conversationText;
|
|
541
|
-
logLlmCall("selfImprovingExtraction", prompt.length
|
|
530
|
+
logLlmCall("selfImprovingExtraction", prompt.length);
|
|
542
531
|
const openai = new OpenAI({
|
|
543
532
|
apiKey: llmConfig.apiKey,
|
|
544
533
|
baseURL: llmConfig.baseUrl,
|
|
@@ -574,7 +563,7 @@ async function extractSelfImprovingWithLLM(
|
|
|
574
563
|
}
|
|
575
564
|
return out;
|
|
576
565
|
} catch (err: unknown) {
|
|
577
|
-
|
|
566
|
+
console.warn(`[openclaw-memory-alibaba-local] selfImprovingExtraction JSON parse failed: ${err}`);
|
|
578
567
|
return [];
|
|
579
568
|
}
|
|
580
569
|
}
|
|
@@ -597,7 +586,6 @@ async function mergeMemoriesWithLLM(
|
|
|
597
586
|
llmConfig: LLMConfig,
|
|
598
587
|
newItems: LLMExtractionItem[],
|
|
599
588
|
existingCandidates: MemorySearchResult[],
|
|
600
|
-
log?: MemoryDiagnosticLog,
|
|
601
589
|
): Promise<MergeAction[]> {
|
|
602
590
|
if (newItems.length === 0) return [];
|
|
603
591
|
|
|
@@ -624,7 +612,7 @@ async function mergeMemoriesWithLLM(
|
|
|
624
612
|
}));
|
|
625
613
|
|
|
626
614
|
const prompt = buildMemoryMergePrompt(newForPrompt, existingForPrompt);
|
|
627
|
-
logLlmCall("batchMerge", prompt.length
|
|
615
|
+
logLlmCall("batchMerge", prompt.length);
|
|
628
616
|
|
|
629
617
|
const openai = new OpenAI({
|
|
630
618
|
apiKey: llmConfig.apiKey,
|
|
@@ -714,7 +702,7 @@ async function mergeMemoriesWithLLM(
|
|
|
714
702
|
return result;
|
|
715
703
|
} catch (err: unknown) {
|
|
716
704
|
// On parse failure, fallback: insert everything
|
|
717
|
-
|
|
705
|
+
console.warn(`[openclaw-memory-alibaba-local] batchMerge JSON parse failed, fallback insert all: ${err}`);
|
|
718
706
|
return newItems.map((item) => ({
|
|
719
707
|
action: "insert" as const,
|
|
720
708
|
text: item.text,
|
|
@@ -899,7 +887,6 @@ async function runAgentEndCapture(
|
|
|
899
887
|
userId: string | null,
|
|
900
888
|
messages: unknown[],
|
|
901
889
|
lancedbDir: string,
|
|
902
|
-
log: { info: (m: string) => void; warn: (m: string) => void },
|
|
903
890
|
): Promise<void> {
|
|
904
891
|
if (messages.length === 0) {
|
|
905
892
|
return;
|
|
@@ -908,10 +895,10 @@ async function runAgentEndCapture(
|
|
|
908
895
|
const key = getFullContextCursorKey(agentId, sessionKey);
|
|
909
896
|
const map = loadAgentEndCursorMap(lancedbDir);
|
|
910
897
|
const entry = map[key];
|
|
911
|
-
let { roleCounts: saved, lastMessagesLength } = resolveRoleCountsForSession(entry, messages
|
|
898
|
+
let { roleCounts: saved, lastMessagesLength } = resolveRoleCountsForSession(entry, messages);
|
|
912
899
|
|
|
913
900
|
if (messages.length < lastMessagesLength) {
|
|
914
|
-
log
|
|
901
|
+
console.log("[openclaw-memory-alibaba-local] transcript shrank; reset per-role capture cursors");
|
|
915
902
|
saved = {};
|
|
916
903
|
}
|
|
917
904
|
|
|
@@ -971,7 +958,7 @@ async function runAgentEndCapture(
|
|
|
971
958
|
const batchId = randomUUID();
|
|
972
959
|
const sid = sessionKey;
|
|
973
960
|
|
|
974
|
-
log
|
|
961
|
+
console.log(`[openclaw-memory-alibaba-local] agentEndCapture fullRows=${fullRows.length} userTexts=${userRawTexts.length} uaLines=${uaLines.length}`);
|
|
975
962
|
|
|
976
963
|
if (fullRows.length > 0) {
|
|
977
964
|
await db.storeMany(
|
|
@@ -989,12 +976,12 @@ async function runAgentEndCapture(
|
|
|
989
976
|
})),
|
|
990
977
|
);
|
|
991
978
|
// GC: 删除超过 50000 条或超过 1 个月的全文记忆
|
|
992
|
-
await db.gcFullContext(agentId, 50_000, 30 * 24 * 60 * 60 * 1000
|
|
979
|
+
await db.gcFullContext(agentId, 50_000, 30 * 24 * 60 * 60 * 1000);
|
|
993
980
|
}
|
|
994
981
|
|
|
995
982
|
await Promise.all([
|
|
996
|
-
captureUserMemoryFromInboundTexts(cfg, db, backend, agentId, sid, userId, userRawTexts
|
|
997
|
-
captureSelfImprovingFromLines(cfg, db, backend, agentId, sid, userId, uaLines
|
|
983
|
+
captureUserMemoryFromInboundTexts(cfg, db, backend, agentId, sid, userId, userRawTexts),
|
|
984
|
+
captureSelfImprovingFromLines(cfg, db, backend, agentId, sid, userId, uaLines),
|
|
998
985
|
]);
|
|
999
986
|
|
|
1000
987
|
map[key] = {
|
|
@@ -1014,7 +1001,6 @@ async function captureUserMemoryFromInboundTexts(
|
|
|
1014
1001
|
sessionKey: string,
|
|
1015
1002
|
userId: string | null,
|
|
1016
1003
|
inboundTexts: string[],
|
|
1017
|
-
log: { info: (m: string) => void },
|
|
1018
1004
|
): Promise<void> {
|
|
1019
1005
|
if (inboundTexts.length === 0) {
|
|
1020
1006
|
return;
|
|
@@ -1044,7 +1030,6 @@ async function captureUserMemoryFromInboundTexts(
|
|
|
1044
1030
|
await storeOneCaptureItem(agentId, { ...item, text }, cfg, db, backend, {
|
|
1045
1031
|
userId,
|
|
1046
1032
|
sessionId: sessionKey,
|
|
1047
|
-
log,
|
|
1048
1033
|
});
|
|
1049
1034
|
}
|
|
1050
1035
|
return;
|
|
@@ -1058,9 +1043,8 @@ async function captureUserMemoryFromInboundTexts(
|
|
|
1058
1043
|
cfg.llm,
|
|
1059
1044
|
toSend,
|
|
1060
1045
|
MAX_AUTO_CAPTURE_LLM,
|
|
1061
|
-
log,
|
|
1062
1046
|
).catch((err: unknown) => {
|
|
1063
|
-
|
|
1047
|
+
console.warn(`[openclaw-memory-alibaba-local] memoryExtraction pipeline failed: ${err}`);
|
|
1064
1048
|
return [] as LLMExtractionItem[];
|
|
1065
1049
|
});
|
|
1066
1050
|
if (extractions.length === 0) return;
|
|
@@ -1083,15 +1067,14 @@ async function captureUserMemoryFromInboundTexts(
|
|
|
1083
1067
|
: [];
|
|
1084
1068
|
|
|
1085
1069
|
// 3. Call batch merge LLM
|
|
1086
|
-
log
|
|
1070
|
+
console.log(`[openclaw-memory-alibaba-local] batchMerge input: ${extractions.length} extractions, ${existingCandidates.length} existing candidates`);
|
|
1087
1071
|
const mergeActions = await mergeMemoriesWithLLM(
|
|
1088
1072
|
cfg.llm,
|
|
1089
1073
|
embeddingResults.map((r) => r.item),
|
|
1090
1074
|
existingCandidates,
|
|
1091
|
-
log,
|
|
1092
1075
|
).catch((err: unknown) => {
|
|
1093
1076
|
// Fallback: insert all
|
|
1094
|
-
|
|
1077
|
+
console.warn(`[openclaw-memory-alibaba-local] batchMerge LLM failed, fallback insert all: ${err}`);
|
|
1095
1078
|
return embeddingResults.map((r): MergeAction => ({
|
|
1096
1079
|
action: "insert" as const,
|
|
1097
1080
|
text: r.item.text,
|
|
@@ -1101,7 +1084,7 @@ async function captureUserMemoryFromInboundTexts(
|
|
|
1101
1084
|
});
|
|
1102
1085
|
|
|
1103
1086
|
// 4. Log & execute merge actions
|
|
1104
|
-
logMergeResult(extractions.length, mergeActions
|
|
1087
|
+
logMergeResult(extractions.length, mergeActions);
|
|
1105
1088
|
for (const action of mergeActions) {
|
|
1106
1089
|
if (action.action === "skip") continue;
|
|
1107
1090
|
|
|
@@ -1150,7 +1133,6 @@ async function captureUserMemoryFromInboundTexts(
|
|
|
1150
1133
|
await storeOneCaptureItem(agentId, { category: e.category, text, importance: e.importance }, cfg, db, backend, {
|
|
1151
1134
|
userId,
|
|
1152
1135
|
sessionId: sessionKey,
|
|
1153
|
-
log,
|
|
1154
1136
|
});
|
|
1155
1137
|
}
|
|
1156
1138
|
}
|
|
@@ -1164,7 +1146,6 @@ async function captureSelfImprovingFromLines(
|
|
|
1164
1146
|
sessionKey: string,
|
|
1165
1147
|
userId: string | null,
|
|
1166
1148
|
lines: string[],
|
|
1167
|
-
log: { info: (m: string) => void },
|
|
1168
1149
|
): Promise<void> {
|
|
1169
1150
|
if (!cfg.enableSelfImprovingMemory || lines.length === 0) {
|
|
1170
1151
|
return;
|
|
@@ -1185,9 +1166,8 @@ async function captureSelfImprovingFromLines(
|
|
|
1185
1166
|
cfg.llm,
|
|
1186
1167
|
combined,
|
|
1187
1168
|
MAX_AUTO_CAPTURE_SELF_IMPROVING,
|
|
1188
|
-
log,
|
|
1189
1169
|
).catch((err: unknown) => {
|
|
1190
|
-
|
|
1170
|
+
console.warn(`[openclaw-memory-alibaba-local] selfImprovingExtraction pipeline failed: ${err}`);
|
|
1191
1171
|
return [] as SelfImprovingExtractionItem[];
|
|
1192
1172
|
});
|
|
1193
1173
|
for (const e of extractions) {
|
|
@@ -1215,7 +1195,6 @@ async function captureSelfImprovingFromLines(
|
|
|
1215
1195
|
await storeOneCaptureItem(agentId, item, cfg, db, backend, {
|
|
1216
1196
|
userId,
|
|
1217
1197
|
sessionId: sessionKey,
|
|
1218
|
-
log,
|
|
1219
1198
|
});
|
|
1220
1199
|
}
|
|
1221
1200
|
}
|
|
@@ -1294,7 +1273,6 @@ async function storeOneCaptureItem(
|
|
|
1294
1273
|
sessionId?: string | null;
|
|
1295
1274
|
batchId?: string | null;
|
|
1296
1275
|
seqInBatch?: number | null;
|
|
1297
|
-
log?: { info: (m: string) => void };
|
|
1298
1276
|
},
|
|
1299
1277
|
): Promise<StoreOneResult> {
|
|
1300
1278
|
if (isFullContextStoredWithoutEmbedding(item.category)) {
|
|
@@ -1511,7 +1489,6 @@ const memoryPlugin = {
|
|
|
1511
1489
|
limitSelf,
|
|
1512
1490
|
minScore: RECALL_MIN_SCORE_RELAXED,
|
|
1513
1491
|
},
|
|
1514
|
-
api.logger,
|
|
1515
1492
|
);
|
|
1516
1493
|
|
|
1517
1494
|
// Respect the user-requested limit after hybrid recall (vector + BM25 may exceed it).
|
|
@@ -1627,7 +1604,6 @@ const memoryPlugin = {
|
|
|
1627
1604
|
const { action, entry } = await storeOneCaptureItem(agentId, item, cfg, db, backend, {
|
|
1628
1605
|
userId,
|
|
1629
1606
|
sessionId,
|
|
1630
|
-
log: api.logger,
|
|
1631
1607
|
});
|
|
1632
1608
|
const preview = text.length > 100 ? text.slice(0, 100) + "..." : text;
|
|
1633
1609
|
return {
|
|
@@ -1778,7 +1754,6 @@ const memoryPlugin = {
|
|
|
1778
1754
|
limitSelf: cfg.enableSelfImprovingMemory ? RECALL_LIMIT_SELF : 0,
|
|
1779
1755
|
minScore: RECALL_MIN_SCORE_HOOK,
|
|
1780
1756
|
},
|
|
1781
|
-
api.logger,
|
|
1782
1757
|
);
|
|
1783
1758
|
const searchMs = Date.now() - tSearch0;
|
|
1784
1759
|
const totalMs = Date.now() - tRecall0;
|
|
@@ -1852,7 +1827,6 @@ const memoryPlugin = {
|
|
|
1852
1827
|
userId,
|
|
1853
1828
|
event.messages,
|
|
1854
1829
|
resolvedDbPath,
|
|
1855
|
-
api.logger,
|
|
1856
1830
|
);
|
|
1857
1831
|
api.logger.info(
|
|
1858
1832
|
`openclaw-memory-alibaba-local: agent_end capture done totalHookMs=${Date.now() - tCap0} messages=${event.messages.length}`,
|
package/package.json
CHANGED
package/prompts.ts
CHANGED
|
@@ -193,7 +193,7 @@ Do NOT merge items that merely share the same person but cover different topics.
|
|
|
193
193
|
- **DELETE** (memoryId): A batch item directly contradicts and fully replaces a Store item. Delete the Store item; handle the batch item as INSERT.
|
|
194
194
|
- Only when info DIRECTLY contradicts (e.g. "moved to Shanghai" vs stored "lives in Beijing").
|
|
195
195
|
|
|
196
|
-
# Category
|
|
196
|
+
# Category & Relevance Filter
|
|
197
197
|
|
|
198
198
|
For every INSERT or UPDATE, assign a category based on content:
|
|
199
199
|
- **profile**: User identity (name, age, location, job, relationships, background)
|
|
@@ -203,6 +203,10 @@ For every INSERT or UPDATE, assign a category based on content:
|
|
|
203
203
|
|
|
204
204
|
Only memories about "User" → profile/preferences/decisions. Others → "fact".
|
|
205
205
|
|
|
206
|
+
**User-category filter**: For profile/preferences/decisions, only keep **durable personal information** — identity, traits, relationships, beliefs, preferences, life events, long-term goals. SKIP one-time operational requests, transient commands, debugging queries, or ephemeral task instructions (e.g. "User asked to run command X", "User requested to search logs", "User asked which files were viewed"). These reveal nothing lasting about the person.
|
|
207
|
+
|
|
208
|
+
**Fact-category**: ZERO information loss. All events, activities, and third-party info must be kept.
|
|
209
|
+
|
|
206
210
|
# Output format
|
|
207
211
|
|
|
208
212
|
Reply with ONLY a JSON object:
|