@scotthuang/engram 0.3.27 → 0.4.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/dist/bm25.js +8 -7
- package/dist/bm25.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +9 -6
- package/dist/config.js.map +1 -1
- package/dist/index.js +73 -61
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +32 -0
- package/dist/logger.js +83 -0
- package/dist/logger.js.map +1 -0
- package/dist/profile.js +5 -4
- package/dist/profile.js.map +1 -1
- package/dist/recall.d.ts +6 -0
- package/dist/recall.js +62 -41
- package/dist/recall.js.map +1 -1
- package/dist/settle.d.ts +12 -3
- package/dist/settle.js +78 -44
- package/dist/settle.js.map +1 -1
- package/dist/vector.d.ts +21 -1
- package/dist/vector.js +129 -20
- package/dist/vector.js.map +1 -1
- package/openclaw.plugin.json +4 -0
- package/package.json +1 -1
package/dist/bm25.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* 纯 TypeScript 实现,不依赖外部 BM25 库
|
|
6
6
|
*/
|
|
7
7
|
import { promises as fs } from "node:fs";
|
|
8
|
+
import { logger } from "./logger.js";
|
|
8
9
|
import { join } from "node:path";
|
|
9
10
|
/**
|
|
10
11
|
* 获取本地日期字符串 (YYYY-MM-DD)
|
|
@@ -91,12 +92,12 @@ export class BM25Index {
|
|
|
91
92
|
this.docs.push(...entries);
|
|
92
93
|
mdFiles++;
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
+
logger.info(`[engram:bm25] Scanned ${mdFiles} valid MD files, skipped ${skippedFiles} expired`);
|
|
95
96
|
}
|
|
96
97
|
catch {
|
|
97
|
-
|
|
98
|
+
logger.info(`[engram:bm25] short-term directory not found at ${shortTermDir}, 0 entries`);
|
|
98
99
|
}
|
|
99
|
-
|
|
100
|
+
logger.info(`[engram:bm25] Built index: ${this.docs.length} entries from ${shortTermDir}`);
|
|
100
101
|
this.buildIDF();
|
|
101
102
|
}
|
|
102
103
|
/**
|
|
@@ -221,7 +222,7 @@ export class BM25Index {
|
|
|
221
222
|
// IDF = log((N - df + 0.5) / (df + 0.5) + 1)
|
|
222
223
|
this.idf.set(term, Math.log((N - freq + 0.5) / (freq + 0.5) + 1));
|
|
223
224
|
}
|
|
224
|
-
|
|
225
|
+
logger.info(`[engram:bm25] buildIDF: ${N} docs, ${df.size} unique terms, avgDl=${this.avgDl.toFixed(1)}`);
|
|
225
226
|
}
|
|
226
227
|
/**
|
|
227
228
|
* BM25 搜索
|
|
@@ -232,7 +233,7 @@ export class BM25Index {
|
|
|
232
233
|
const queryTokens = tokenize(query);
|
|
233
234
|
const k1 = 1.5; // 词频饱和参数
|
|
234
235
|
const b = 0.75; // 文档长度归一化参数
|
|
235
|
-
|
|
236
|
+
logger.info(`[engram:bm25] search: query="${query.slice(0, 80)}" tokens=[${queryTokens.join(", ")}] topK=${topK} docs=${this.docs.length} avgDl=${this.avgDl.toFixed(1)}`);
|
|
236
237
|
const scores = [];
|
|
237
238
|
for (const doc of this.docs) {
|
|
238
239
|
let score = 0;
|
|
@@ -253,7 +254,7 @@ export class BM25Index {
|
|
|
253
254
|
}
|
|
254
255
|
scores.sort((a, b) => b.score - a.score);
|
|
255
256
|
const result = scores.slice(0, topK);
|
|
256
|
-
|
|
257
|
+
logger.info(`[engram:bm25] search: ${scores.length} docs matched, returning top ${result.length}`);
|
|
257
258
|
return result;
|
|
258
259
|
}
|
|
259
260
|
/**
|
|
@@ -266,7 +267,7 @@ export class BM25Index {
|
|
|
266
267
|
tokens,
|
|
267
268
|
entry,
|
|
268
269
|
});
|
|
269
|
-
|
|
270
|
+
logger.info(`[engram:bm25] addEntry: "${entry.text.slice(0, 60)}" → ${tokens.length} tokens, total docs=${this.docs.length}`);
|
|
270
271
|
this.buildIDF();
|
|
271
272
|
}
|
|
272
273
|
get size() {
|
package/dist/bm25.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bm25.js","sourceRoot":"","sources":["../src/bm25.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bm25.js","sourceRoot":"","sources":["../src/bm25.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;GAEG;AACH,SAAS,kBAAkB;IACzB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;AACnC,CAAC;AAcD,IAAI,aAAa,GAAQ,IAAI,CAAC;AAE9B,yBAAyB;AACzB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAC5B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IACzC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAChC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAChD,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAC5C,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IACjC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI;IACnC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IACzD,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACvC,CAAC,CAAC;AAEH,SAAS,iBAAiB,CAAC,KAAa;IACtC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,aAAa;IACb,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACvC,aAAa,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC;IACpC,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAa,CAAC;QACnD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC/D,CAAC;IACD,mBAAmB;IACnB,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,qBAAqB,EAAE,GAAG,CAAC;SACnC,KAAK,CAAC,KAAK,CAAC;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,OAAO,SAAS;IACZ,IAAI,GAAc,EAAE,CAAC;IACrB,GAAG,GAAwB,IAAI,GAAG,EAAE,CAAC;IACrC,KAAK,GAAG,CAAC,CAAC;IAElB;;OAEG;IACH,KAAK,CAAC,kBAAkB,CAAC,GAAW,EAAE,aAAqB,CAAC;QAC1D,MAAM,SAAS,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC,CAAC;QAE9C,8BAA8B;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAE7C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAC7C,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,IAAI,YAAY,GAAG,CAAC,CAAC;YACrB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,QAAQ;gBACnD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAAE,SAAS;gBACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;gBAC1C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACrC,IAAI,IAAI,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC;oBACxB,YAAY,EAAE,CAAC;oBACf,SAAS;gBACX,CAAC;gBAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACrD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC3D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;gBAC3B,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,yBAAyB,OAAO,4BAA4B,YAAY,UAAU,CAAC,CAAC;QAClG,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,mDAAmD,YAAY,aAAa,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,IAAI,CAAC,MAAM,iBAAiB,YAAY,EAAE,CAAC,CAAC;QAC3F,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED;;;;;;;;;OASG;IACK,YAAY,CAAC,OAAe,EAAE,QAAgB,EAAE,QAAgB;QACtE,MAAM,OAAO,GAAc,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC;QAE7D,IAAI,eAAe,GAAG,IAAI,CAAC;QAC3B,IAAI,WAAW,GAAG,EAAE,CAAC;QAErB,gCAAgC;QAChC,8EAA8E;QAC9E,MAAM,iBAAiB,GAAG,2CAA2C,CAAC;QAEtE,yBAAyB;QACzB,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;QAEtD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACpE,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW;gBACX,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;oBACvB,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;gBACtH,CAAC;gBACD,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;gBACjC,WAAW,GAAG,EAAE,CAAC;YACnB,CAAC;iBAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpF,SAAS;YACX,CAAC;iBAAM,CAAC;gBACN,WAAW,IAAI,IAAI,GAAG,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,UAAU;QACV,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACvB,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;QACtH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CACtB,OAAkB,EAClB,IAAY,EACZ,QAAgB,EAChB,IAAY,EACZ,QAAgB,EAChB,iBAAyB,EACzB,kBAA0B;QAE1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAExD,6BAA6B;QAC7B,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;QAErE,IAAI,iBAAiB,EAAE,CAAC;YACtB,yBAAyB;YACzB,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;gBAClC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;oBAAE,SAAS;gBAC/B,yBAAyB;gBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa;gBAC/C,MAAM,KAAK,GAAmB;oBAC5B,IAAI,EAAE,IAAI,EAAE,cAAc;oBAC1B,IAAI;oBACJ,QAAQ,EAAE,MAAM;oBAChB,QAAQ;iBACT,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;aAAM,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpD,yBAAyB;YACzB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;oBAAE,SAAS;gBAClC,MAAM,KAAK,GAAmB;oBAC5B,IAAI,EAAE,CAAC;oBACP,IAAI;oBACJ,QAAQ;oBACR,QAAQ;iBACT,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,iBAAiB;YACjB,MAAM,KAAK,GAAmB;gBAC5B,IAAI,EAAE,OAAO;gBACb,IAAI;gBACJ,QAAQ;gBACR,QAAQ;aACT,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,QAAQ;QACd,MAAM,EAAE,GAAwB,IAAI,GAAG,EAAE,CAAC,CAAC,OAAO;QAClD,IAAI,QAAQ,GAAG,CAAC,CAAC;QAEjB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClC,CAAC;YACD,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpE,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9B,6CAA6C;YAC7C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,UAAU,EAAE,CAAC,IAAI,wBAAwB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5G,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAe,CAAC;QAC1C,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,SAAS;QACzB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,YAAY;QAE5B,MAAM,CAAC,IAAI,CAAC,gCAAgC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAE3K,MAAM,MAAM,GAAoD,EAAE,CAAC;QAEnE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,GAAG,KAAK,CAAC;oBAAE,SAAS;gBAExB,KAAK;gBACL,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC;gBACtD,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;gBAE7B,UAAU;gBACV,MAAM,WAAW,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAClF,KAAK,IAAI,GAAG,GAAG,WAAW,CAAC;YAC7B,CAAC;YAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,MAAM,gCAAgC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACnG,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAqB;QAClC,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACb,MAAM;YACN,KAAK;SACN,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,4BAA4B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,MAAM,uBAAuB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9H,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;CACF"}
|
package/dist/config.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export type MemorySystemConfig = {
|
|
|
36
36
|
/** LLM 调用超时(毫秒),默认 10000 */
|
|
37
37
|
timeoutMs: number;
|
|
38
38
|
};
|
|
39
|
+
/** 日志父目录路径,传入后在此目录下创建 engram/ 子目录按天写日志文件。不传则仅 console 输出 */
|
|
40
|
+
logDir?: string;
|
|
39
41
|
/** LanceDB 路径 */
|
|
40
42
|
lancedbDir?: string;
|
|
41
43
|
/** 是否保存中间文件(staging)供调试,默认 true */
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Memory System Plugin - Configuration
|
|
3
3
|
*/
|
|
4
|
+
import { logger } from "./logger.js";
|
|
4
5
|
export const DEFAULTS = {
|
|
5
6
|
shortTermDays: 7,
|
|
6
7
|
halfLifeDays: 30,
|
|
@@ -28,10 +29,10 @@ export const DEFAULTS = {
|
|
|
28
29
|
};
|
|
29
30
|
export function parseConfig(raw) {
|
|
30
31
|
if (!raw) {
|
|
31
|
-
|
|
32
|
+
logger.info(`[engram:config] No raw config provided, using defaults`);
|
|
32
33
|
return { ...DEFAULTS };
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
+
logger.info(`[engram:config] Parsing config, keys=[${Object.keys(raw).join(", ")}]`);
|
|
35
36
|
const embedding = typeof raw.embedding === "object" && raw.embedding !== null
|
|
36
37
|
? {
|
|
37
38
|
model: typeof raw.embedding.model === "string" ? raw.embedding.model : DEFAULTS.embedding.model,
|
|
@@ -69,12 +70,14 @@ export function parseConfig(raw) {
|
|
|
69
70
|
condense,
|
|
70
71
|
queryRewrite,
|
|
71
72
|
lancedbDir: typeof raw.lancedbDir === "string" ? raw.lancedbDir : undefined,
|
|
73
|
+
logDir: typeof raw.logDir === "string" ? raw.logDir : undefined,
|
|
72
74
|
saveStagingFile: typeof raw.saveStagingFile === "boolean" ? raw.saveStagingFile : true,
|
|
73
75
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
logger.info(`[engram:config] Parsed: shortTermDays=${config.shortTermDays} halfLifeDays=${config.halfLifeDays} recallTopK=${config.recallTopK} minScore=${config.minScore} vectorWeight=${config.vectorWeight} textWeight=${config.textWeight}`);
|
|
77
|
+
logger.info(`[engram:config] Embedding: model=${config.embedding.model} dims=${config.embedding.dimensions} hasApiKey=${!!config.embedding.apiKey} baseUrl=${config.embedding.baseUrl.slice(0, 40)}`);
|
|
78
|
+
logger.info(`[engram:config] Condense: model=${config.condense.model} hasApiKey=${!!config.condense.apiKey}`);
|
|
79
|
+
logger.info(`[engram:config] QueryRewrite: enabled=${config.queryRewrite.enabled} timeoutMs=${config.queryRewrite.timeoutMs}`);
|
|
80
|
+
logger.info(`[engram:config] LogDir: ${config.logDir || "(none, console only)"}`);
|
|
78
81
|
return config;
|
|
79
82
|
}
|
|
80
83
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { RecallEngine } from "./recall.js";
|
|
|
11
11
|
import { ProfileManager } from "./profile.js";
|
|
12
12
|
import { VectorStore } from "./vector.js";
|
|
13
13
|
import { runSettlement } from "./settle.js";
|
|
14
|
+
import { logger } from "./logger.js";
|
|
14
15
|
import { promises as fs } from "node:fs";
|
|
15
16
|
import path from "node:path";
|
|
16
17
|
// ---- 模块级单例(避免 OpenClaw 多次调用 register 时重复创建) ----
|
|
@@ -124,7 +125,7 @@ async function condenseChunk(content, apiKey, baseUrl, model) {
|
|
|
124
125
|
});
|
|
125
126
|
clearTimeout(timeoutId);
|
|
126
127
|
if (!response.ok) {
|
|
127
|
-
|
|
128
|
+
logger.error(`[engram] Condense chunk API error: ${response.status}`);
|
|
128
129
|
return null;
|
|
129
130
|
}
|
|
130
131
|
const data = await response.json();
|
|
@@ -135,10 +136,10 @@ async function condenseChunk(content, apiKey, baseUrl, model) {
|
|
|
135
136
|
catch (err) {
|
|
136
137
|
clearTimeout(timeoutId);
|
|
137
138
|
if (err instanceof Error && err.name === "AbortError") {
|
|
138
|
-
|
|
139
|
+
logger.error(`[engram] Condense chunk timeout after 30s`);
|
|
139
140
|
}
|
|
140
141
|
else {
|
|
141
|
-
|
|
142
|
+
logger.error(`[engram] Condense chunk failed: ${err}`);
|
|
142
143
|
}
|
|
143
144
|
return null;
|
|
144
145
|
}
|
|
@@ -153,24 +154,24 @@ async function condenseSessionContent(content, config) {
|
|
|
153
154
|
const baseUrl = config.condense.baseUrl || process.env.ARK_BASE_URL || "https://api.minimaxi.com/anthropic";
|
|
154
155
|
const model = config.condense.model || config.settleModel || "MiniMax-M2.7-highspeed";
|
|
155
156
|
if (!apiKey) {
|
|
156
|
-
|
|
157
|
+
logger.info("[engram] No API key for condense, skipping LLM condensation");
|
|
157
158
|
return null;
|
|
158
159
|
}
|
|
159
160
|
// 如果内容较短(<5000字符),直接处理
|
|
160
161
|
if (content.length < 5000) {
|
|
161
|
-
|
|
162
|
+
logger.info(`[engram] Content short (${content.length} chars), processing directly`);
|
|
162
163
|
return condenseChunk(content, apiKey, baseUrl, model);
|
|
163
164
|
}
|
|
164
165
|
// 长文本分段处理
|
|
165
166
|
const chunks = splitIntoChunks(content, 5000);
|
|
166
|
-
|
|
167
|
+
logger.info(`[engram] Content long (${content.length} chars), splitting into ${chunks.length} chunks`);
|
|
167
168
|
const results = [];
|
|
168
169
|
for (let i = 0; i < chunks.length; i++) {
|
|
169
|
-
|
|
170
|
+
logger.info(`[engram] Processing chunk ${i + 1}/${chunks.length} (${chunks[i].length} chars)`);
|
|
170
171
|
const result = await condenseChunk(chunks[i], apiKey, baseUrl, model);
|
|
171
172
|
if (result) {
|
|
172
173
|
results.push(result);
|
|
173
|
-
|
|
174
|
+
logger.info(`[engram] Chunk ${i + 1} condensed: ${result.split("\n").length} lines`);
|
|
174
175
|
}
|
|
175
176
|
// 避免请求过快
|
|
176
177
|
if (i < chunks.length - 1) {
|
|
@@ -178,13 +179,13 @@ async function condenseSessionContent(content, config) {
|
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
181
|
if (results.length === 0) {
|
|
181
|
-
|
|
182
|
+
logger.info("[engram] All chunks failed");
|
|
182
183
|
return null;
|
|
183
184
|
}
|
|
184
185
|
const combined = results.join("\n");
|
|
185
186
|
// 后处理去重
|
|
186
187
|
const deduplicated = deduplicateCondensedLines(combined);
|
|
187
|
-
|
|
188
|
+
logger.info(`[engram] Condensed ${content.length} chars → ${combined.length} chars → ${deduplicated.length} chars (dedup), ${deduplicated.split("\n").length} lines`);
|
|
188
189
|
return deduplicated;
|
|
189
190
|
}
|
|
190
191
|
/**
|
|
@@ -220,7 +221,7 @@ function deduplicateCondensedLines(content) {
|
|
|
220
221
|
const overlapRatio = overlap / Math.max(topicWords.length, seenWords.length, 1);
|
|
221
222
|
if (overlapRatio > 0.6) {
|
|
222
223
|
isDuplicate = true;
|
|
223
|
-
|
|
224
|
+
logger.info(`[engram] Dedup: skipping "${line.slice(0, 50)}..." (similar to existing)`);
|
|
224
225
|
break;
|
|
225
226
|
}
|
|
226
227
|
}
|
|
@@ -229,7 +230,7 @@ function deduplicateCondensedLines(content) {
|
|
|
229
230
|
seenTopics.add(topicKey);
|
|
230
231
|
}
|
|
231
232
|
}
|
|
232
|
-
|
|
233
|
+
logger.info(`[engram] Dedup: ${lines.length} lines → ${result.length} lines`);
|
|
233
234
|
return result.join("\n");
|
|
234
235
|
}
|
|
235
236
|
export default function register(api) {
|
|
@@ -239,7 +240,9 @@ export default function register(api) {
|
|
|
239
240
|
if (!singletonConfig) {
|
|
240
241
|
singletonConfig = parseConfig(rawConfig);
|
|
241
242
|
singletonWorkspaceDir = workspaceDir;
|
|
242
|
-
|
|
243
|
+
// 初始化日志系统:传入 logDir 则按天写文件,否则仅 console 输出
|
|
244
|
+
logger.init(singletonConfig.logDir);
|
|
245
|
+
logger.info(`[engram] Initializing singletons (first register call)`);
|
|
243
246
|
}
|
|
244
247
|
const config = singletonConfig;
|
|
245
248
|
if (!singletonRecallEngine) {
|
|
@@ -257,8 +260,9 @@ export default function register(api) {
|
|
|
257
260
|
dbDir: lancedbDir,
|
|
258
261
|
embedding: config.embedding,
|
|
259
262
|
tableName: "memories",
|
|
263
|
+
halfLifeDays: config.halfLifeDays,
|
|
260
264
|
});
|
|
261
|
-
|
|
265
|
+
logger.info(`[engram] VectorStore singleton created`);
|
|
262
266
|
}
|
|
263
267
|
const vectorStore = singletonVectorStore;
|
|
264
268
|
// 注入向量搜索(只在第一次时注入)
|
|
@@ -268,9 +272,15 @@ export default function register(api) {
|
|
|
268
272
|
return [];
|
|
269
273
|
return vectorStore.search(query, limit);
|
|
270
274
|
});
|
|
275
|
+
// 注入记忆强化回调
|
|
276
|
+
recallEngine.setReinforceCallback(async (ids) => {
|
|
277
|
+
if (!vectorStore)
|
|
278
|
+
return;
|
|
279
|
+
await vectorStore.reinforce(ids);
|
|
280
|
+
});
|
|
271
281
|
}
|
|
272
282
|
if (!vectorStore && !config.embedding.apiKey) {
|
|
273
|
-
|
|
283
|
+
logger.info("[engram] No embedding config, vector search disabled");
|
|
274
284
|
}
|
|
275
285
|
// ---- Agent Tools ----
|
|
276
286
|
api.registerTool({
|
|
@@ -352,7 +362,8 @@ export default function register(api) {
|
|
|
352
362
|
}
|
|
353
363
|
try {
|
|
354
364
|
if (vectorStore) {
|
|
355
|
-
|
|
365
|
+
// Agent 主动存储的记忆视为高重要度
|
|
366
|
+
const result = await vectorStore.store(text.trim(), category, 0.7);
|
|
356
367
|
if (result === "duplicate") {
|
|
357
368
|
return { content: [{ type: "text", text: "⚠️ Similar memory already exists, skipped." }] };
|
|
358
369
|
}
|
|
@@ -388,25 +399,25 @@ export default function register(api) {
|
|
|
388
399
|
}
|
|
389
400
|
api.on("before_agent_start", async (event) => {
|
|
390
401
|
const prompt = event.prompt || "";
|
|
391
|
-
|
|
402
|
+
logger.info(`[engram] before_agent_start triggered, prompt length=${prompt.length}`);
|
|
392
403
|
if (prompt.length < 5)
|
|
393
404
|
return;
|
|
394
405
|
// 检查黑名单:系统引导消息不需要召回
|
|
395
406
|
if (shouldSkipRecall(prompt)) {
|
|
396
|
-
|
|
407
|
+
logger.info(`[engram] Skipping recall for system startup prompt`);
|
|
397
408
|
return;
|
|
398
409
|
}
|
|
399
410
|
try {
|
|
400
411
|
const cleanPrompt = cleanMessageText(prompt);
|
|
401
|
-
|
|
412
|
+
logger.info(`[engram] recall query (cleaned): "${cleanPrompt.slice(0, 100)}"`);
|
|
402
413
|
const { results, memoryContext } = await recallEngine.recall(cleanPrompt);
|
|
403
|
-
|
|
414
|
+
logger.info(`[engram] recall result: ${results ? results.split("\n").length : 0} lines, memoryContext length=${memoryContext?.length || 0}`);
|
|
404
415
|
if (!memoryContext)
|
|
405
416
|
return;
|
|
406
417
|
return { prependContext: memoryContext };
|
|
407
418
|
}
|
|
408
419
|
catch (err) {
|
|
409
|
-
|
|
420
|
+
logger.error(`[engram] Recall failed: ${err}`);
|
|
410
421
|
}
|
|
411
422
|
}, { priority: 5 });
|
|
412
423
|
// ---- Hooks: command:new 即时沉淀 ----
|
|
@@ -429,7 +440,7 @@ export default function register(api) {
|
|
|
429
440
|
const stat = await fs.stat(lockFile);
|
|
430
441
|
const age = Date.now() - stat.mtimeMs;
|
|
431
442
|
if (age < COMMAND_NEW_COOLDOWN_MS) {
|
|
432
|
-
|
|
443
|
+
logger.info(`[engram] File lock active (${Math.round((COMMAND_NEW_COOLDOWN_MS - age) / 1000)}s left), skipping`);
|
|
433
444
|
return true; // 锁有效,跳过
|
|
434
445
|
}
|
|
435
446
|
}
|
|
@@ -447,7 +458,7 @@ export default function register(api) {
|
|
|
447
458
|
await fs.writeFile(lockFile, Date.now().toString(), "utf-8");
|
|
448
459
|
}
|
|
449
460
|
catch (err) {
|
|
450
|
-
|
|
461
|
+
logger.error(`[engram] Failed to create file lock: ${err}`);
|
|
451
462
|
}
|
|
452
463
|
}
|
|
453
464
|
/**
|
|
@@ -517,7 +528,7 @@ export default function register(api) {
|
|
|
517
528
|
}
|
|
518
529
|
async function extractMessagesFromSessionFile(sessionFilePath, messageCount = 50) {
|
|
519
530
|
try {
|
|
520
|
-
|
|
531
|
+
logger.info(`[engram] extractMessagesFromSessionFile: reading ${sessionFilePath}`);
|
|
521
532
|
const raw = await fs.readFile(sessionFilePath, "utf-8");
|
|
522
533
|
const lines = raw.trim().split("\n");
|
|
523
534
|
const messages = [];
|
|
@@ -559,7 +570,7 @@ export default function register(api) {
|
|
|
559
570
|
text.includes("Run your Session Startup sequence") ||
|
|
560
571
|
text.includes("read the required files before responding") ||
|
|
561
572
|
text.includes("greet the user in your configured persona")) {
|
|
562
|
-
|
|
573
|
+
logger.info(`[engram] Skipping system startup prompt message`);
|
|
563
574
|
continue;
|
|
564
575
|
}
|
|
565
576
|
// 连续同角色消息合并(保留第一条的时间戳)
|
|
@@ -575,7 +586,7 @@ export default function register(api) {
|
|
|
575
586
|
// skip malformed lines
|
|
576
587
|
}
|
|
577
588
|
}
|
|
578
|
-
|
|
589
|
+
logger.info(`[engram] extractMessagesFromSessionFile: parsed ${messages.length} messages from ${lines.length} lines`);
|
|
579
590
|
if (messages.length === 0)
|
|
580
591
|
return null;
|
|
581
592
|
const recent = messages.slice(-messageCount);
|
|
@@ -589,7 +600,7 @@ export default function register(api) {
|
|
|
589
600
|
return formatted;
|
|
590
601
|
}
|
|
591
602
|
catch (err) {
|
|
592
|
-
|
|
603
|
+
logger.error(`[engram] extractMessagesFromSessionFile: failed to read ${sessionFilePath}: ${err}`);
|
|
593
604
|
return null;
|
|
594
605
|
}
|
|
595
606
|
}
|
|
@@ -598,11 +609,11 @@ export default function register(api) {
|
|
|
598
609
|
* 参考 openclaw 内置 session-memory hook 的 fallback 逻辑
|
|
599
610
|
*/
|
|
600
611
|
async function getRecentSessionContentWithResetFallback(sessionFile, messageCount = 20) {
|
|
601
|
-
|
|
612
|
+
logger.info(`[engram] getRecentSessionContentWithResetFallback: sessionFile=${sessionFile}`);
|
|
602
613
|
// 先尝试主文件
|
|
603
614
|
const primary = await extractMessagesFromSessionFile(sessionFile, messageCount);
|
|
604
615
|
if (primary) {
|
|
605
|
-
|
|
616
|
+
logger.info(`[engram] getRecentSessionContentWithResetFallback: got content from primary file (${primary.length} chars)`);
|
|
606
617
|
return primary;
|
|
607
618
|
}
|
|
608
619
|
// fallback: 查找 .reset.* 后缀的备份文件
|
|
@@ -610,23 +621,23 @@ export default function register(api) {
|
|
|
610
621
|
const dir = path.dirname(sessionFile);
|
|
611
622
|
const base = path.basename(sessionFile);
|
|
612
623
|
const resetPrefix = `${base}.reset.`;
|
|
613
|
-
|
|
624
|
+
logger.info(`[engram] getRecentSessionContentWithResetFallback: looking for reset fallback in ${dir}, prefix=${resetPrefix}`);
|
|
614
625
|
const files = await fs.readdir(dir);
|
|
615
626
|
const resetCandidates = files.filter((n) => n.startsWith(resetPrefix)).sort();
|
|
616
627
|
if (resetCandidates.length === 0) {
|
|
617
|
-
|
|
628
|
+
logger.info(`[engram] getRecentSessionContentWithResetFallback: no reset fallback files found`);
|
|
618
629
|
return null;
|
|
619
630
|
}
|
|
620
631
|
const latestResetPath = path.join(dir, resetCandidates[resetCandidates.length - 1]);
|
|
621
|
-
|
|
632
|
+
logger.info(`[engram] getRecentSessionContentWithResetFallback: trying latest reset file: ${latestResetPath}`);
|
|
622
633
|
const fallback = await extractMessagesFromSessionFile(latestResetPath, messageCount);
|
|
623
634
|
if (fallback) {
|
|
624
|
-
|
|
635
|
+
logger.info(`[engram] getRecentSessionContentWithResetFallback: got content from reset fallback (${fallback.length} chars)`);
|
|
625
636
|
}
|
|
626
637
|
return fallback;
|
|
627
638
|
}
|
|
628
639
|
catch (fbErr) {
|
|
629
|
-
|
|
640
|
+
logger.error(`[engram] getRecentSessionContentWithResetFallback: reset fallback failed: ${fbErr}`);
|
|
630
641
|
return null;
|
|
631
642
|
}
|
|
632
643
|
}
|
|
@@ -640,7 +651,7 @@ export default function register(api) {
|
|
|
640
651
|
const shortTermDir = path.join(workspaceDir, "memory-engram", "short-term");
|
|
641
652
|
await fs.mkdir(shortTermDir, { recursive: true });
|
|
642
653
|
const filePath = path.join(shortTermDir, `${date}.md`);
|
|
643
|
-
|
|
654
|
+
logger.info(`[engram] command:new hook triggered, action=${event.action}, sessionKey=${event.sessionKey}`);
|
|
644
655
|
// ★★★ 文件锁:10秒内只处理一次(跨实例有效) ★★★
|
|
645
656
|
const lockFile = path.join(workspaceDir, "memory-engram", ".command-new.lock");
|
|
646
657
|
if (await checkFileLock(lockFile)) {
|
|
@@ -648,7 +659,7 @@ export default function register(api) {
|
|
|
648
659
|
}
|
|
649
660
|
// 立即创建锁,防止并发
|
|
650
661
|
await createFileLock(lockFile);
|
|
651
|
-
|
|
662
|
+
logger.info(`[engram] File lock acquired, processing...`);
|
|
652
663
|
// 从 event.context 获取 previousSessionEntry(/new 触发前的旧 session)
|
|
653
664
|
const ctx = event.context || {};
|
|
654
665
|
// 重要:只使用 previousSessionEntry,不要 fallback 到 sessionEntry
|
|
@@ -656,24 +667,24 @@ export default function register(api) {
|
|
|
656
667
|
const prevEntry = ctx.previousSessionEntry;
|
|
657
668
|
// 如果没有 previousSessionEntry,说明这是一个全新的 session(没有历史),跳过
|
|
658
669
|
if (!prevEntry) {
|
|
659
|
-
|
|
670
|
+
logger.info(`[engram] No previousSessionEntry, this is a fresh session start, skipping`);
|
|
660
671
|
return;
|
|
661
672
|
}
|
|
662
673
|
const sessionFile = prevEntry.sessionFile;
|
|
663
674
|
const sessionId = prevEntry.sessionId;
|
|
664
675
|
// 如果没有 sessionId,也跳过
|
|
665
676
|
if (!sessionId) {
|
|
666
|
-
|
|
677
|
+
logger.info(`[engram] No sessionId in previousSessionEntry, skipping`);
|
|
667
678
|
return;
|
|
668
679
|
}
|
|
669
680
|
// ★★★ 最强去重:检查 sessionFile 是否已处理过 ★★★
|
|
670
681
|
if (sessionFile && processedSessionFiles.has(sessionFile)) {
|
|
671
|
-
|
|
682
|
+
logger.info(`[engram] SessionFile ${sessionFile} already processed, skipping`);
|
|
672
683
|
return;
|
|
673
684
|
}
|
|
674
685
|
// 防重入:检查是否已经处理过这个 session
|
|
675
686
|
if (processedSessionIds.has(sessionId)) {
|
|
676
|
-
|
|
687
|
+
logger.info(`[engram] Session ${sessionId} already processed, skipping`);
|
|
677
688
|
return;
|
|
678
689
|
}
|
|
679
690
|
// ★ 关键修复:立即标记为已处理,防止重复触发
|
|
@@ -681,8 +692,8 @@ export default function register(api) {
|
|
|
681
692
|
if (sessionFile) {
|
|
682
693
|
processedSessionFiles.add(sessionFile);
|
|
683
694
|
}
|
|
684
|
-
|
|
685
|
-
|
|
695
|
+
logger.info(`[engram] Marked session ${sessionId} (file: ${sessionFile}) as processing (early lock)`);
|
|
696
|
+
logger.info(`[engram] context dump: previousSessionEntry=${JSON.stringify({
|
|
686
697
|
sessionId: sessionId,
|
|
687
698
|
sessionFile: sessionFile || null,
|
|
688
699
|
contextKeys: Object.keys(ctx),
|
|
@@ -692,7 +703,7 @@ export default function register(api) {
|
|
|
692
703
|
sessionContent = await getRecentSessionContentWithResetFallback(sessionFile);
|
|
693
704
|
}
|
|
694
705
|
else {
|
|
695
|
-
|
|
706
|
+
logger.info(`[engram] No sessionFile in previousSessionEntry, cannot extract session content`);
|
|
696
707
|
}
|
|
697
708
|
if (sessionContent) {
|
|
698
709
|
// 防重复:检查文件是否已包含相同内容
|
|
@@ -704,7 +715,7 @@ export default function register(api) {
|
|
|
704
715
|
// 取 sessionContent 前 100 字符作为指纹
|
|
705
716
|
const fingerprint = sessionContent.slice(0, 100);
|
|
706
717
|
if (existing.includes(fingerprint)) {
|
|
707
|
-
|
|
718
|
+
logger.info(`[engram] Duplicate detected, skipping write to short-term/${date}.md`);
|
|
708
719
|
}
|
|
709
720
|
else {
|
|
710
721
|
// ---- 保存中间文件(staging)供调试 ----
|
|
@@ -713,7 +724,7 @@ export default function register(api) {
|
|
|
713
724
|
await fs.mkdir(stagingDir, { recursive: true });
|
|
714
725
|
const stagingPath = path.join(stagingDir, `${date}-${timestamp.replace(/:/g, "")}.md`);
|
|
715
726
|
await fs.writeFile(stagingPath, sessionContent, "utf-8");
|
|
716
|
-
|
|
727
|
+
logger.info(`[engram] Saved staging file: ${stagingPath} (${sessionContent.length} chars)`);
|
|
717
728
|
}
|
|
718
729
|
// ---- 异步执行 LLM 精简 + 保存 + BM25 重建 ----
|
|
719
730
|
// 使用 fire-and-forget 模式,让钩子快速返回,避免阻塞 openclaw 事件循环
|
|
@@ -723,7 +734,7 @@ export default function register(api) {
|
|
|
723
734
|
const asyncFingerprint = fingerprint;
|
|
724
735
|
// ★ 异步任务启动前先检查指纹锁,防止并发任务
|
|
725
736
|
if (processingFingerprints.has(asyncFingerprint)) {
|
|
726
|
-
|
|
737
|
+
logger.info(`[engram] Content already being processed (fingerprint lock), skipping`);
|
|
727
738
|
}
|
|
728
739
|
else {
|
|
729
740
|
processingFingerprints.add(asyncFingerprint);
|
|
@@ -734,10 +745,10 @@ export default function register(api) {
|
|
|
734
745
|
const condensed = await condenseSessionContent(asyncSessionContent, config);
|
|
735
746
|
if (condensed) {
|
|
736
747
|
contentToSave = condensed;
|
|
737
|
-
|
|
748
|
+
logger.info(`[engram] [async] Using condensed content for short-term memory`);
|
|
738
749
|
}
|
|
739
750
|
else {
|
|
740
|
-
|
|
751
|
+
logger.info(`[engram] [async] Condense failed or disabled, saving raw content`);
|
|
741
752
|
}
|
|
742
753
|
// ★ 写入前再次检查文件,防止并发写入
|
|
743
754
|
let existingNow = "";
|
|
@@ -746,36 +757,36 @@ export default function register(api) {
|
|
|
746
757
|
}
|
|
747
758
|
catch { }
|
|
748
759
|
if (existingNow.includes(asyncFingerprint)) {
|
|
749
|
-
|
|
760
|
+
logger.info(`[engram] [async] Duplicate detected before write, skipping`);
|
|
750
761
|
return;
|
|
751
762
|
}
|
|
752
763
|
const entry = `\n### ${asyncTimestamp} [对话记录]\n${contentToSave}\n`;
|
|
753
764
|
await fs.appendFile(asyncFilePath, entry, "utf-8");
|
|
754
|
-
|
|
765
|
+
logger.info(`[engram] [async] Saved ${contentToSave.length} chars of session content to short-term memory`);
|
|
755
766
|
// Rebuild BM25 index after adding new entry
|
|
756
767
|
await recallEngine.rebuildBM25();
|
|
757
|
-
|
|
768
|
+
logger.info(`[engram] [async] BM25 index rebuilt after new entry added`);
|
|
758
769
|
}
|
|
759
770
|
catch (asyncErr) {
|
|
760
|
-
|
|
771
|
+
logger.error(`[engram] [async] Background processing failed: ${asyncErr}`);
|
|
761
772
|
}
|
|
762
773
|
finally {
|
|
763
774
|
// 无论成功失败,都释放指纹锁
|
|
764
775
|
processingFingerprints.delete(asyncFingerprint);
|
|
765
776
|
}
|
|
766
777
|
})();
|
|
767
|
-
|
|
778
|
+
logger.info(`[engram] Hook returning immediately, LLM condense + save running in background`);
|
|
768
779
|
}
|
|
769
780
|
}
|
|
770
781
|
}
|
|
771
782
|
else {
|
|
772
783
|
// 没有对话内容,跳过写入(不再写无意义的 "Session reset" 垃圾)
|
|
773
784
|
// session 已在前面标记,无需再处理
|
|
774
|
-
|
|
785
|
+
logger.info(`[engram] No session content to save, skipping write`);
|
|
775
786
|
}
|
|
776
787
|
}
|
|
777
788
|
catch (err) {
|
|
778
|
-
|
|
789
|
+
logger.error(`[engram] Hook command:new failed: ${err}`);
|
|
779
790
|
}
|
|
780
791
|
}, {
|
|
781
792
|
name: "engram.command-new",
|
|
@@ -791,10 +802,10 @@ export default function register(api) {
|
|
|
791
802
|
const timestamp = new Date().toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" });
|
|
792
803
|
const entry = `\n### ${timestamp} [系统]\nCompaction triggered, saving context at ${new Date().toISOString()}\n`;
|
|
793
804
|
await fs.appendFile(filePath, entry, "utf-8");
|
|
794
|
-
|
|
805
|
+
logger.info(`[engram] Pre-compaction save: ${date}`);
|
|
795
806
|
}
|
|
796
807
|
catch (err) {
|
|
797
|
-
|
|
808
|
+
logger.error(`[engram] Hook session:compact:before failed: ${err}`);
|
|
798
809
|
}
|
|
799
810
|
}, {
|
|
800
811
|
name: "engram.compact-before",
|
|
@@ -808,10 +819,10 @@ export default function register(api) {
|
|
|
808
819
|
await vectorStore.startup();
|
|
809
820
|
}
|
|
810
821
|
await recallEngine.startup();
|
|
811
|
-
|
|
822
|
+
logger.info(`[engram] Service started (workspace: ${workspaceDir})`);
|
|
812
823
|
},
|
|
813
824
|
async stop() {
|
|
814
|
-
|
|
825
|
+
logger.info("[engram] Service stopped");
|
|
815
826
|
},
|
|
816
827
|
});
|
|
817
828
|
// ---- CLI Commands ----
|
|
@@ -825,7 +836,8 @@ export default function register(api) {
|
|
|
825
836
|
console.log("LLM call needed - configure in plugin");
|
|
826
837
|
return "[]";
|
|
827
838
|
},
|
|
828
|
-
vectorStore: vectorStore ? (text, category) => vectorStore.store(text, category) : undefined,
|
|
839
|
+
vectorStore: vectorStore ? (text, category, importance) => vectorStore.store(text, category, importance) : undefined,
|
|
840
|
+
vectorPrune: vectorStore ? (threshold, maxPrune) => vectorStore.prune(threshold, maxPrune) : undefined,
|
|
829
841
|
});
|
|
830
842
|
results.forEach(r => console.log(` ${r}`));
|
|
831
843
|
});
|
|
@@ -843,6 +855,6 @@ export default function register(api) {
|
|
|
843
855
|
// 可扩展更多统计
|
|
844
856
|
});
|
|
845
857
|
}, { commands: ["memory-sys"] });
|
|
846
|
-
|
|
858
|
+
logger.info("[engram] Plugin registered");
|
|
847
859
|
}
|
|
848
860
|
//# sourceMappingURL=index.js.map
|