openclaw-memory-alibaba-local 0.1.9-beta.21 → 0.1.9-beta.23

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 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.info("openclaw-memory-alibaba-local: migrated legacy full-context cursor to per-role counts");
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?.info(`openclaw-memory-alibaba-local: gcFullContext agent=${agentId} remaining=${remaining} (within limit)`);
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?.info(`openclaw-memory-alibaba-local: gcFullContext agent=${agentId} deleted ${excess} excess rows (was ${remaining}, cap ${maxRows})`);
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
@@ -86,6 +86,13 @@ const MAX_AUTO_CAPTURE_REGEX = 3;
86
86
  const MAX_AUTO_CAPTURE_LLM = Infinity;
87
87
  const DEFAULT_IMPORTANCE = 0.7;
88
88
 
89
+ /** Strip markdown code fences (```json ... ```) that some LLMs wrap around JSON output. */
90
+ function stripMarkdownJsonFence(raw: string): string {
91
+ const trimmed = raw.trim();
92
+ const m = /^```(?:json)?\s*\n?([\s\S]*?)\n?```\s*$/.exec(trimmed);
93
+ return m ? m[1]!.trim() : trimmed;
94
+ }
95
+
89
96
  async function embedQueryVectors(backend: EmbeddingBackend, text: string): Promise<number[][]> {
90
97
  const t = text.trim();
91
98
  if (!t) {
@@ -175,26 +182,22 @@ function getThresholdForCategory(cfg: MemoryConfig, category: MemoryCategory): n
175
182
  return cfg.similarityThresholdSelfImproving;
176
183
  }
177
184
 
178
- /** 可选:给 LLM / 衰减诊断日志(与 OpenClaw api.logger 兼容,仅用 info)。 */
179
- type MemoryDiagnosticLog = { info: (m: string) => void } | undefined;
180
-
181
185
  /** 精简日志:仅记录 tag + prompt 字符数,不贴原文。 */
182
- function logLlmCall(tag: string, promptChars: number, log: MemoryDiagnosticLog): void {
183
- log?.info(`openclaw-memory-alibaba-local: llm ${tag} prompt (${promptChars} chars)`);
186
+ function logLlmCall(tag: string, promptChars: number): void {
187
+ console.log(`[openclaw-memory-alibaba-local] llm ${tag} prompt (${promptChars} chars)`);
184
188
  }
185
189
 
186
190
  /** 记录 merge 结果统计。 */
187
- function logMergeResult(total: number, actions: ReadonlyArray<{ action: string }>, log: MemoryDiagnosticLog): void {
188
- if (!log) return;
191
+ function logMergeResult(total: number, actions: ReadonlyArray<{ action: string }>): void {
189
192
  const counts: Record<string, number> = {};
190
193
  for (const a of actions) counts[a.action] = (counts[a.action] ?? 0) + 1;
191
194
  const parts = Object.entries(counts).map(([k, v]) => `${v} ${k}`).join(", ");
192
- log.info(`openclaw-memory-alibaba-local: batchMerge result: ${total} items → ${parts}`);
195
+ console.log(`[openclaw-memory-alibaba-local] batchMerge result: ${total} items → ${parts}`);
193
196
  }
194
197
 
195
198
  /** 记忆衰减为纯公式,不向模型发提示词;仍打日志避免与「冲突检测 LLM」混淆。 */
196
- function logMemoryDecayNoLlm(phase: string, log: MemoryDiagnosticLog, detail: string): void {
197
- log?.info(`openclaw-memory-alibaba-local: memoryDecay ${phase} (no LLM; formula-only) ${detail}`);
199
+ function logMemoryDecayNoLlm(phase: string, detail: string): void {
200
+ console.log(`[openclaw-memory-alibaba-local] memoryDecay ${phase} (no LLM; formula-only) ${detail}`);
198
201
  }
199
202
 
200
203
  /** Apply time decay to recall results: effectiveScore = score * decay(createdAt). Returns new array sorted by effectiveScore desc. */
@@ -234,7 +237,6 @@ async function runRecall(
234
237
  agentId: string,
235
238
  queryVectors: number[][],
236
239
  options: { limitUser: number; limitSelf: number; minScore: number },
237
- log?: MemoryDiagnosticLog,
238
240
  ): Promise<MemorySearchResult[]> {
239
241
  if (queryVectors.length === 0) {
240
242
  return [];
@@ -271,7 +273,6 @@ async function runRecall(
271
273
  );
272
274
  logMemoryDecayNoLlm(
273
275
  "vectorRecall",
274
- log,
275
276
  `strategy=${cfg.memoryDecayStrategy} halfLifeDays=${cfg.memoryDecayHalfLifeDays} agentId=${agentId} inputRows=${decayIn}`,
276
277
  );
277
278
  }
@@ -288,7 +289,6 @@ async function bm25SupplementRecall(
288
289
  queryText: string,
289
290
  vectorResults: MemorySearchResult[],
290
291
  maxAdd: number,
291
- log?: MemoryDiagnosticLog,
292
292
  ): Promise<MemorySearchResult[]> {
293
293
  const q = queryText.trim();
294
294
  if (q.length < 2 || maxAdd <= 0) {
@@ -353,7 +353,6 @@ async function bm25SupplementRecall(
353
353
  ranked = applyMemoryDecay(ranked, Date.now(), cfg.memoryDecayStrategy, cfg.memoryDecayHalfLifeDays);
354
354
  logMemoryDecayNoLlm(
355
355
  "bm25Pool",
356
- log,
357
356
  `strategy=${cfg.memoryDecayStrategy} halfLifeDays=${cfg.memoryDecayHalfLifeDays} agentId=${agentId} inputRows=${decayIn}`,
358
357
  );
359
358
  }
@@ -379,12 +378,11 @@ async function runHybridRecall(
379
378
  queryText: string,
380
379
  queryVectors: number[][],
381
380
  options: { limitUser: number; limitSelf: number; minScore: number },
382
- log?: MemoryDiagnosticLog,
383
381
  ): Promise<MemorySearchResult[]> {
384
- const vector = await runRecall(db, cfg, agentId, queryVectors, options, log);
382
+ const vector = await runRecall(db, cfg, agentId, queryVectors, options);
385
383
  const extra =
386
384
  queryText.trim().length >= 2
387
- ? await bm25SupplementRecall(db, cfg, agentId, queryText, vector, RECALL_BM25_MAX, log)
385
+ ? await bm25SupplementRecall(db, cfg, agentId, queryText, vector, RECALL_BM25_MAX)
388
386
  : [];
389
387
  return [...vector, ...extra].slice(0, RECALL_FINAL_MAX);
390
388
  }
@@ -434,7 +432,6 @@ async function extractUserMemoriesWithLLM(
434
432
  llmConfig: LLMConfig,
435
433
  userMessages: string[],
436
434
  _maxExtractions = Infinity,
437
- log?: MemoryDiagnosticLog,
438
435
  ): Promise<LLMExtractionItem[]> {
439
436
  if (userMessages.length === 0) return [];
440
437
  const combined = userMessages
@@ -444,7 +441,7 @@ async function extractUserMemoriesWithLLM(
444
441
 
445
442
  const extractionPrompt = buildMemoryExtractionPrompt() + combined;
446
443
 
447
- logLlmCall("memoryExtraction", extractionPrompt.length, log);
444
+ logLlmCall("memoryExtraction", extractionPrompt.length);
448
445
 
449
446
  const openai = new OpenAI({
450
447
  apiKey: llmConfig.apiKey,
@@ -453,7 +450,7 @@ async function extractUserMemoriesWithLLM(
453
450
 
454
451
  const parseExtractions = (raw: string): LLMExtractionItem[] => {
455
452
  try {
456
- const parsed = JSON.parse(raw) as {
453
+ const parsed = JSON.parse(stripMarkdownJsonFence(raw)) as {
457
454
  extractions?: Array<{ text?: string }>;
458
455
  };
459
456
  const list = Array.isArray(parsed.extractions) ? parsed.extractions : [];
@@ -468,7 +465,7 @@ async function extractUserMemoriesWithLLM(
468
465
  }
469
466
  return out;
470
467
  } catch (err: unknown) {
471
- log?.info(`openclaw-memory-alibaba-local: memoryExtraction JSON parse failed: ${err}`);
468
+ console.warn(`[openclaw-memory-alibaba-local] memoryExtraction JSON parse failed: ${err}`);
472
469
  return [];
473
470
  }
474
471
  };
@@ -479,13 +476,13 @@ async function extractUserMemoriesWithLLM(
479
476
  temperature: 0,
480
477
  max_tokens: 8192,
481
478
  }).catch((err: unknown) => {
482
- log?.info(`openclaw-memory-alibaba-local: memoryExtraction LLM call failed: ${err}`);
479
+ console.warn(`[openclaw-memory-alibaba-local] memoryExtraction LLM call failed: ${err}`);
483
480
  return null;
484
481
  });
485
482
 
486
483
  const raw = completion?.choices[0]?.message?.content?.trim() ?? "";
487
484
  const items = parseExtractions(raw);
488
- log?.info(`openclaw-memory-alibaba-local: memoryExtraction extracted ${items.length} items`);
485
+ console.log(`[openclaw-memory-alibaba-local] memoryExtraction extracted ${items.length} items`);
489
486
  return items;
490
487
  }
491
488
 
@@ -534,11 +531,10 @@ async function extractSelfImprovingWithLLM(
534
531
  llmConfig: LLMConfig,
535
532
  conversationText: string,
536
533
  maxExtractions = MAX_AUTO_CAPTURE_SELF_IMPROVING,
537
- log?: MemoryDiagnosticLog,
538
534
  ): Promise<SelfImprovingExtractionItem[]> {
539
535
  if (conversationText.length < 20) return [];
540
536
  const prompt = SELF_IMPROVING_EXTRACTION_INSTRUCTIONS + "\n" + conversationText;
541
- logLlmCall("selfImprovingExtraction", prompt.length, log);
537
+ logLlmCall("selfImprovingExtraction", prompt.length);
542
538
  const openai = new OpenAI({
543
539
  apiKey: llmConfig.apiKey,
544
540
  baseURL: llmConfig.baseUrl,
@@ -552,7 +548,7 @@ async function extractSelfImprovingWithLLM(
552
548
  const raw = completion.choices[0]?.message?.content?.trim() ?? "";
553
549
  const validCategories = new Set(SELF_IMPROVING_CATEGORIES);
554
550
  try {
555
- const parsed = JSON.parse(raw) as {
551
+ const parsed = JSON.parse(stripMarkdownJsonFence(raw)) as {
556
552
  extractions?: Array<{ category?: string; text?: string; importance?: unknown }>;
557
553
  };
558
554
  const list = Array.isArray(parsed.extractions) ? parsed.extractions : [];
@@ -574,7 +570,7 @@ async function extractSelfImprovingWithLLM(
574
570
  }
575
571
  return out;
576
572
  } catch (err: unknown) {
577
- log?.info(`openclaw-memory-alibaba-local: selfImprovingExtraction JSON parse failed: ${err}`);
573
+ console.warn(`[openclaw-memory-alibaba-local] selfImprovingExtraction JSON parse failed: ${err}`);
578
574
  return [];
579
575
  }
580
576
  }
@@ -597,7 +593,6 @@ async function mergeMemoriesWithLLM(
597
593
  llmConfig: LLMConfig,
598
594
  newItems: LLMExtractionItem[],
599
595
  existingCandidates: MemorySearchResult[],
600
- log?: MemoryDiagnosticLog,
601
596
  ): Promise<MergeAction[]> {
602
597
  if (newItems.length === 0) return [];
603
598
 
@@ -624,7 +619,7 @@ async function mergeMemoriesWithLLM(
624
619
  }));
625
620
 
626
621
  const prompt = buildMemoryMergePrompt(newForPrompt, existingForPrompt);
627
- logLlmCall("batchMerge", prompt.length, log);
622
+ logLlmCall("batchMerge", prompt.length);
628
623
 
629
624
  const openai = new OpenAI({
630
625
  apiKey: llmConfig.apiKey,
@@ -643,7 +638,7 @@ async function mergeMemoriesWithLLM(
643
638
  const allValidCategories = new Set(Object.keys(PROMPT_CATEGORY_TO_STORAGE));
644
639
 
645
640
  try {
646
- const parsed = JSON.parse(raw) as {
641
+ const parsed = JSON.parse(stripMarkdownJsonFence(raw)) as {
647
642
  actions?: Array<{
648
643
  index?: number;
649
644
  action?: string;
@@ -714,7 +709,7 @@ async function mergeMemoriesWithLLM(
714
709
  return result;
715
710
  } catch (err: unknown) {
716
711
  // On parse failure, fallback: insert everything
717
- log?.info(`openclaw-memory-alibaba-local: batchMerge JSON parse failed, fallback insert all: ${err}`);
712
+ console.warn(`[openclaw-memory-alibaba-local] batchMerge JSON parse failed, fallback insert all: ${err}`);
718
713
  return newItems.map((item) => ({
719
714
  action: "insert" as const,
720
715
  text: item.text,
@@ -899,7 +894,6 @@ async function runAgentEndCapture(
899
894
  userId: string | null,
900
895
  messages: unknown[],
901
896
  lancedbDir: string,
902
- log: { info: (m: string) => void; warn: (m: string) => void },
903
897
  ): Promise<void> {
904
898
  if (messages.length === 0) {
905
899
  return;
@@ -908,10 +902,10 @@ async function runAgentEndCapture(
908
902
  const key = getFullContextCursorKey(agentId, sessionKey);
909
903
  const map = loadAgentEndCursorMap(lancedbDir);
910
904
  const entry = map[key];
911
- let { roleCounts: saved, lastMessagesLength } = resolveRoleCountsForSession(entry, messages, log);
905
+ let { roleCounts: saved, lastMessagesLength } = resolveRoleCountsForSession(entry, messages);
912
906
 
913
907
  if (messages.length < lastMessagesLength) {
914
- log.info("openclaw-memory-alibaba-local: transcript shrank; reset per-role capture cursors");
908
+ console.log("[openclaw-memory-alibaba-local] transcript shrank; reset per-role capture cursors");
915
909
  saved = {};
916
910
  }
917
911
 
@@ -971,7 +965,7 @@ async function runAgentEndCapture(
971
965
  const batchId = randomUUID();
972
966
  const sid = sessionKey;
973
967
 
974
- log.info(`openclaw-memory-alibaba-local: agentEndCapture fullRows=${fullRows.length} userTexts=${userRawTexts.length} uaLines=${uaLines.length}`);
968
+ console.log(`[openclaw-memory-alibaba-local] agentEndCapture fullRows=${fullRows.length} userTexts=${userRawTexts.length} uaLines=${uaLines.length}`);
975
969
 
976
970
  if (fullRows.length > 0) {
977
971
  await db.storeMany(
@@ -989,12 +983,12 @@ async function runAgentEndCapture(
989
983
  })),
990
984
  );
991
985
  // GC: 删除超过 50000 条或超过 1 个月的全文记忆
992
- await db.gcFullContext(agentId, 50_000, 30 * 24 * 60 * 60 * 1000, log);
986
+ await db.gcFullContext(agentId, 50_000, 30 * 24 * 60 * 60 * 1000);
993
987
  }
994
988
 
995
989
  await Promise.all([
996
- captureUserMemoryFromInboundTexts(cfg, db, backend, agentId, sid, userId, userRawTexts, log),
997
- captureSelfImprovingFromLines(cfg, db, backend, agentId, sid, userId, uaLines, log),
990
+ captureUserMemoryFromInboundTexts(cfg, db, backend, agentId, sid, userId, userRawTexts),
991
+ captureSelfImprovingFromLines(cfg, db, backend, agentId, sid, userId, uaLines),
998
992
  ]);
999
993
 
1000
994
  map[key] = {
@@ -1014,7 +1008,6 @@ async function captureUserMemoryFromInboundTexts(
1014
1008
  sessionKey: string,
1015
1009
  userId: string | null,
1016
1010
  inboundTexts: string[],
1017
- log: { info: (m: string) => void },
1018
1011
  ): Promise<void> {
1019
1012
  if (inboundTexts.length === 0) {
1020
1013
  return;
@@ -1044,7 +1037,6 @@ async function captureUserMemoryFromInboundTexts(
1044
1037
  await storeOneCaptureItem(agentId, { ...item, text }, cfg, db, backend, {
1045
1038
  userId,
1046
1039
  sessionId: sessionKey,
1047
- log,
1048
1040
  });
1049
1041
  }
1050
1042
  return;
@@ -1058,9 +1050,8 @@ async function captureUserMemoryFromInboundTexts(
1058
1050
  cfg.llm,
1059
1051
  toSend,
1060
1052
  MAX_AUTO_CAPTURE_LLM,
1061
- log,
1062
1053
  ).catch((err: unknown) => {
1063
- log?.info(`openclaw-memory-alibaba-local: memoryExtraction pipeline failed: ${err}`);
1054
+ console.warn(`[openclaw-memory-alibaba-local] memoryExtraction pipeline failed: ${err}`);
1064
1055
  return [] as LLMExtractionItem[];
1065
1056
  });
1066
1057
  if (extractions.length === 0) return;
@@ -1083,15 +1074,14 @@ async function captureUserMemoryFromInboundTexts(
1083
1074
  : [];
1084
1075
 
1085
1076
  // 3. Call batch merge LLM
1086
- log?.info(`openclaw-memory-alibaba-local: batchMerge input: ${extractions.length} extractions, ${existingCandidates.length} existing candidates`);
1077
+ console.log(`[openclaw-memory-alibaba-local] batchMerge input: ${extractions.length} extractions, ${existingCandidates.length} existing candidates`);
1087
1078
  const mergeActions = await mergeMemoriesWithLLM(
1088
1079
  cfg.llm,
1089
1080
  embeddingResults.map((r) => r.item),
1090
1081
  existingCandidates,
1091
- log,
1092
1082
  ).catch((err: unknown) => {
1093
1083
  // Fallback: insert all
1094
- log?.info(`openclaw-memory-alibaba-local: batchMerge LLM failed, fallback insert all: ${err}`);
1084
+ console.warn(`[openclaw-memory-alibaba-local] batchMerge LLM failed, fallback insert all: ${err}`);
1095
1085
  return embeddingResults.map((r): MergeAction => ({
1096
1086
  action: "insert" as const,
1097
1087
  text: r.item.text,
@@ -1101,7 +1091,7 @@ async function captureUserMemoryFromInboundTexts(
1101
1091
  });
1102
1092
 
1103
1093
  // 4. Log & execute merge actions
1104
- logMergeResult(extractions.length, mergeActions, log);
1094
+ logMergeResult(extractions.length, mergeActions);
1105
1095
  for (const action of mergeActions) {
1106
1096
  if (action.action === "skip") continue;
1107
1097
 
@@ -1150,7 +1140,6 @@ async function captureUserMemoryFromInboundTexts(
1150
1140
  await storeOneCaptureItem(agentId, { category: e.category, text, importance: e.importance }, cfg, db, backend, {
1151
1141
  userId,
1152
1142
  sessionId: sessionKey,
1153
- log,
1154
1143
  });
1155
1144
  }
1156
1145
  }
@@ -1164,7 +1153,6 @@ async function captureSelfImprovingFromLines(
1164
1153
  sessionKey: string,
1165
1154
  userId: string | null,
1166
1155
  lines: string[],
1167
- log: { info: (m: string) => void },
1168
1156
  ): Promise<void> {
1169
1157
  if (!cfg.enableSelfImprovingMemory || lines.length === 0) {
1170
1158
  return;
@@ -1185,9 +1173,8 @@ async function captureSelfImprovingFromLines(
1185
1173
  cfg.llm,
1186
1174
  combined,
1187
1175
  MAX_AUTO_CAPTURE_SELF_IMPROVING,
1188
- log,
1189
1176
  ).catch((err: unknown) => {
1190
- log.info(`openclaw-memory-alibaba-local: selfImprovingExtraction pipeline failed: ${err}`);
1177
+ console.warn(`[openclaw-memory-alibaba-local] selfImprovingExtraction pipeline failed: ${err}`);
1191
1178
  return [] as SelfImprovingExtractionItem[];
1192
1179
  });
1193
1180
  for (const e of extractions) {
@@ -1215,7 +1202,6 @@ async function captureSelfImprovingFromLines(
1215
1202
  await storeOneCaptureItem(agentId, item, cfg, db, backend, {
1216
1203
  userId,
1217
1204
  sessionId: sessionKey,
1218
- log,
1219
1205
  });
1220
1206
  }
1221
1207
  }
@@ -1294,7 +1280,6 @@ async function storeOneCaptureItem(
1294
1280
  sessionId?: string | null;
1295
1281
  batchId?: string | null;
1296
1282
  seqInBatch?: number | null;
1297
- log?: { info: (m: string) => void };
1298
1283
  },
1299
1284
  ): Promise<StoreOneResult> {
1300
1285
  if (isFullContextStoredWithoutEmbedding(item.category)) {
@@ -1360,8 +1345,8 @@ const memoryPlugin = {
1360
1345
  ? createEmbeddingBackend(cfg.embedding)
1361
1346
  : null;
1362
1347
  if (embeddingBackendPromise) {
1363
- api.logger.info(
1364
- "openclaw-memory-alibaba-local: embedding backend load started (async; local node-llama-cpp may compile native code)",
1348
+ console.log(
1349
+ "[openclaw-memory-alibaba-local] embedding backend load started (async; local node-llama-cpp may compile native code)",
1365
1350
  );
1366
1351
  }
1367
1352
 
@@ -1387,16 +1372,16 @@ const memoryPlugin = {
1387
1372
  api.logger,
1388
1373
  );
1389
1374
  } else {
1390
- api.logger.warn(
1391
- "openclaw-memory-alibaba-local: registerGatewayMethod missing — memory admin WS RPC disabled",
1375
+ console.warn(
1376
+ "[openclaw-memory-alibaba-local] registerGatewayMethod missing — memory admin WS RPC disabled",
1392
1377
  );
1393
1378
  }
1394
1379
 
1395
1380
  if (typeof api.registerHttpRoute === "function") {
1396
1381
  registerMemoryPanelRoutes(api.registerHttpRoute.bind(api), getMemoryAdminOpsContext, api.logger);
1397
1382
  } else {
1398
- api.logger.warn(
1399
- "openclaw-memory-alibaba-local: registerHttpRoute missing — /plugins/memory HTML shell disabled",
1383
+ console.warn(
1384
+ "[openclaw-memory-alibaba-local] registerHttpRoute missing — /plugins/memory HTML shell disabled",
1400
1385
  );
1401
1386
  }
1402
1387
 
@@ -1429,8 +1414,8 @@ const memoryPlugin = {
1429
1414
  opts: { vectorDim: db.getEmbeddingVectorDim() },
1430
1415
  };
1431
1416
  ensureAdminWaitDone();
1432
- api.logger.info(
1433
- "openclaw-memory-alibaba-local: memory admin API unlocked (LanceDB open; local embedding may still be compiling)",
1417
+ console.log(
1418
+ "[openclaw-memory-alibaba-local] memory admin API unlocked (LanceDB open; local embedding may still be compiling)",
1434
1419
  );
1435
1420
 
1436
1421
  if (cfg.embedding && embeddingBackendPromise) {
@@ -1444,12 +1429,12 @@ const memoryPlugin = {
1444
1429
  mode === "remote"
1445
1430
  ? cfg.embedding.model
1446
1431
  : (cfg.embedding.modelPath?.trim() || "~/.openclaw/embedding_model/embeddinggemma-300M-Q8_0.gguf");
1447
- api.logger.info(
1448
- `openclaw-memory-alibaba-local: registered (db: ${resolvedDbPath}, table: ${LANCEDB_TABLE_NAME}, embedMode: ${mode}, model: ${modelHint}, vectorDim: ${backend.vectorDim})`,
1432
+ console.log(
1433
+ `[openclaw-memory-alibaba-local] registered (db: ${resolvedDbPath}, table: ${LANCEDB_TABLE_NAME}, embedMode: ${mode}, model: ${modelHint}, vectorDim: ${backend.vectorDim})`,
1449
1434
  );
1450
1435
  } else {
1451
- api.logger.info(
1452
- "openclaw-memory-alibaba-local: registered without embedding (recall/store tools no-op; admin UI can still open LanceDB)",
1436
+ console.log(
1437
+ "[openclaw-memory-alibaba-local] registered without embedding (recall/store tools no-op; admin UI can still open LanceDB)",
1453
1438
  );
1454
1439
  }
1455
1440
 
@@ -1511,7 +1496,6 @@ const memoryPlugin = {
1511
1496
  limitSelf,
1512
1497
  minScore: RECALL_MIN_SCORE_RELAXED,
1513
1498
  },
1514
- api.logger,
1515
1499
  );
1516
1500
 
1517
1501
  // Respect the user-requested limit after hybrid recall (vector + BM25 may exceed it).
@@ -1627,7 +1611,6 @@ const memoryPlugin = {
1627
1611
  const { action, entry } = await storeOneCaptureItem(agentId, item, cfg, db, backend, {
1628
1612
  userId,
1629
1613
  sessionId,
1630
- log: api.logger,
1631
1614
  });
1632
1615
  const preview = text.length > 100 ? text.slice(0, 100) + "..." : text;
1633
1616
  return {
@@ -1738,8 +1721,8 @@ const memoryPlugin = {
1738
1721
  { name: "memory_forget" },
1739
1722
  );
1740
1723
  } else {
1741
- api.logger.info(
1742
- "openclaw-memory-alibaba-local: autoRecall is false — memory_recall / memory_store / memory_forget tools not registered",
1724
+ console.log(
1725
+ "[openclaw-memory-alibaba-local] autoRecall is false — memory_recall / memory_store / memory_forget tools not registered",
1743
1726
  );
1744
1727
  }
1745
1728
 
@@ -1753,8 +1736,8 @@ const memoryPlugin = {
1753
1736
  try {
1754
1737
  const extracted = extractUserQueryForRecall(event.prompt);
1755
1738
  if (extracted.query.length < 5) {
1756
- api.logger.info(
1757
- `openclaw-memory-alibaba-local: recall skip (extracted query too short) rawLen=${event.prompt.length} queryLen=${extracted.query.length} removed=${extracted.removedLabels.join(",") || "none"}`,
1739
+ console.log(
1740
+ `[openclaw-memory-alibaba-local] recall skip (extracted query too short) rawLen=${event.prompt.length} queryLen=${extracted.query.length} removed=${extracted.removedLabels.join(",") || "none"}`,
1758
1741
  );
1759
1742
  return;
1760
1743
  }
@@ -1778,17 +1761,16 @@ const memoryPlugin = {
1778
1761
  limitSelf: cfg.enableSelfImprovingMemory ? RECALL_LIMIT_SELF : 0,
1779
1762
  minScore: RECALL_MIN_SCORE_HOOK,
1780
1763
  },
1781
- api.logger,
1782
1764
  );
1783
1765
  const searchMs = Date.now() - tSearch0;
1784
1766
  const totalMs = Date.now() - tRecall0;
1785
- api.logger.info(
1786
- `openclaw-memory-alibaba-local: recall timing embedMs=${embedMs} lancedbSearchMs=${searchMs} totalMs=${totalMs} results=${results.length} (vector≤${RECALL_VECTOR_MAX}+bm25≤${RECALL_BM25_MAX}, cap ${RECALL_FINAL_MAX})`,
1767
+ console.log(
1768
+ `[openclaw-memory-alibaba-local] recall timing embedMs=${embedMs} lancedbSearchMs=${searchMs} totalMs=${totalMs} results=${results.length} (vector≤${RECALL_VECTOR_MAX}+bm25≤${RECALL_BM25_MAX}, cap ${RECALL_FINAL_MAX})`,
1787
1769
  );
1788
1770
  if (results.length === 0) return;
1789
1771
 
1790
- api.logger.info(
1791
- `openclaw-memory-alibaba-local: injecting ${results.length} memories into context`,
1772
+ console.log(
1773
+ `[openclaw-memory-alibaba-local] injecting ${results.length} memories into context`,
1792
1774
  );
1793
1775
  return {
1794
1776
  prependContext: formatRelevantMemoriesContext(
@@ -1817,7 +1799,7 @@ const memoryPlugin = {
1817
1799
  ),
1818
1800
  };
1819
1801
  } catch (err) {
1820
- api.logger.warn(`openclaw-memory-alibaba-local: recall failed: ${String(err)}`);
1802
+ console.warn(`[openclaw-memory-alibaba-local] recall failed: ${String(err)}`);
1821
1803
  }
1822
1804
  });
1823
1805
  }
@@ -1835,8 +1817,8 @@ const memoryPlugin = {
1835
1817
  const tCap0 = Date.now();
1836
1818
  const storageSessionKey = resolveStorageSessionKey(ctx);
1837
1819
  if (!storageSessionKey) {
1838
- api.logger.warn(
1839
- "openclaw-memory-alibaba-local: agent_end skip capture (no sessionKey/sessionId)",
1820
+ console.warn(
1821
+ "[openclaw-memory-alibaba-local] agent_end skip capture (no sessionKey/sessionId)",
1840
1822
  );
1841
1823
  return;
1842
1824
  }
@@ -1852,13 +1834,12 @@ const memoryPlugin = {
1852
1834
  userId,
1853
1835
  event.messages,
1854
1836
  resolvedDbPath,
1855
- api.logger,
1856
1837
  );
1857
- api.logger.info(
1858
- `openclaw-memory-alibaba-local: agent_end capture done totalHookMs=${Date.now() - tCap0} messages=${event.messages.length}`,
1838
+ console.log(
1839
+ `[openclaw-memory-alibaba-local] agent_end capture done totalHookMs=${Date.now() - tCap0} messages=${event.messages.length}`,
1859
1840
  );
1860
1841
  } catch (err) {
1861
- api.logger.warn(`openclaw-memory-alibaba-local: agent_end capture failed: ${String(err)}`);
1842
+ console.warn(`[openclaw-memory-alibaba-local] agent_end capture failed: ${String(err)}`);
1862
1843
  }
1863
1844
  });
1864
1845
  }
@@ -1868,21 +1849,21 @@ const memoryPlugin = {
1868
1849
  start: () => {
1869
1850
  if (cfg.embedding) {
1870
1851
  const em = cfg.embedding;
1871
- api.logger.info(
1872
- `openclaw-memory-alibaba-local: started (db: ${resolvedDbPath}, embedMode: ${em.mode}${em.mode === "remote" ? `, model: ${em.model}` : ""})`,
1852
+ console.log(
1853
+ `[openclaw-memory-alibaba-local] started (db: ${resolvedDbPath}, embedMode: ${em.mode}${em.mode === "remote" ? `, model: ${em.model}` : ""})`,
1873
1854
  );
1874
1855
  } else {
1875
- api.logger.info("openclaw-memory-alibaba-local: started (memory not configured)");
1856
+ console.log("[openclaw-memory-alibaba-local] started (memory not configured)");
1876
1857
  }
1877
1858
  },
1878
1859
  stop: async () => {
1879
1860
  await backend?.close();
1880
1861
  if (db) await db.close();
1881
- api.logger.info("openclaw-memory-alibaba-local: stopped");
1862
+ console.log("[openclaw-memory-alibaba-local] stopped");
1882
1863
  },
1883
1864
  });
1884
1865
  } catch (err) {
1885
- api.logger.error(`openclaw-memory-alibaba-local: failed to initialize: ${String(err)}`);
1866
+ console.error(`[openclaw-memory-alibaba-local] failed to initialize: ${String(err)}`);
1886
1867
  const dimRaw = cfg.embedding ? embeddingVectorDim(cfg.embedding) : 0;
1887
1868
  const fallbackDim = dimRaw > 0 ? dimRaw : 768;
1888
1869
  try {
@@ -1898,28 +1879,28 @@ const memoryPlugin = {
1898
1879
  api.registerService({
1899
1880
  id: "openclaw-memory-alibaba-local",
1900
1881
  start: () => {
1901
- api.logger.warn(
1902
- "openclaw-memory-alibaba-local: running in degraded mode (embedding failed; admin UI only)",
1882
+ console.warn(
1883
+ "[openclaw-memory-alibaba-local] running in degraded mode (embedding failed; admin UI only)",
1903
1884
  );
1904
1885
  },
1905
1886
  stop: async () => {
1906
1887
  await backend?.close();
1907
1888
  await dbDegraded.close();
1908
- api.logger.info("openclaw-memory-alibaba-local: stopped");
1889
+ console.log("[openclaw-memory-alibaba-local] stopped");
1909
1890
  },
1910
1891
  });
1911
- api.logger.warn(
1912
- `openclaw-memory-alibaba-local: /plugins/memory registered in degraded mode (vectorDim=${fallbackDim}); fix local embedding or switch to embedding.mode=remote`,
1892
+ console.warn(
1893
+ `[openclaw-memory-alibaba-local] /plugins/memory registered in degraded mode (vectorDim=${fallbackDim}); fix local embedding or switch to embedding.mode=remote`,
1913
1894
  );
1914
1895
  } catch (err2) {
1915
- api.logger.error(`openclaw-memory-alibaba-local: degraded admin registration failed: ${String(err2)}`);
1896
+ console.error(`[openclaw-memory-alibaba-local] degraded admin registration failed: ${String(err2)}`);
1916
1897
  }
1917
1898
  }
1918
1899
  } finally {
1919
1900
  ensureAdminWaitDone();
1920
1901
  }
1921
1902
  })().catch((err) => {
1922
- api.logger.error(`openclaw-memory-alibaba-local: unexpected init failure: ${String(err)}`);
1903
+ console.error(`[openclaw-memory-alibaba-local] unexpected init failure: ${String(err)}`);
1923
1904
  });
1924
1905
  },
1925
1906
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-memory-alibaba-local",
3
- "version": "0.1.9-beta.21",
3
+ "version": "0.1.9-beta.23",
4
4
  "description": "OpenClaw memory plugin: local LanceDB + DashScope-compatible embeddings",
5
5
  "type": "module",
6
6
  "engines": {
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 Evolution
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: