cortico-world-memory 0.1.3 → 0.1.4
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/package.json +1 -1
- package/src/world.ts +26 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cortico-world-memory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cortico World 扩展:五层记忆(事实库/知识库/反思/人格/档案)+ 三级记忆底座 + Hybrid Recall 向量混合检索(移植自 E:/qq_bot 的记忆系统与 memory_server 向量 sidecar,qq_bot 源码零改动)。",
|
|
6
6
|
"license": "MIT",
|
package/src/world.ts
CHANGED
|
@@ -31,6 +31,29 @@ function isInboundUser(e: EventEnvelope): boolean {
|
|
|
31
31
|
return true;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* 自动捕获的记忆域(scope):优先按「发送者 QQ 号」,做到私聊↔群聊按人统一——
|
|
36
|
+
* 同一个人无论是在私聊还是群聊发言,记忆都沉淀到同一个 `qq:<号>` 域,无缝衔接。
|
|
37
|
+
* 非 QQ 来源(没有 QQ 号)退化为会话地址(senderKey)→ 来源(source)→ main(世界无关,不报错)。
|
|
38
|
+
*/
|
|
39
|
+
function scopeOfEvent(e: EventEnvelope): string {
|
|
40
|
+
const meta = (e.meta ?? {}) as Record<string, any>;
|
|
41
|
+
// 1. world 提供的发送者 QQ 号(meta.user)
|
|
42
|
+
const u = meta.user;
|
|
43
|
+
if (typeof u === 'number' && Number.isFinite(u)) return `qq:${u}`;
|
|
44
|
+
if (typeof u === 'string' && /^\d{4,}$/.test(u.trim())) return `qq:${u.trim()}`;
|
|
45
|
+
// 2. 从 meta.sender 形如「昵称(QQ:123456)」里抠 QQ 号
|
|
46
|
+
const s = meta.sender;
|
|
47
|
+
if (typeof s === 'string') {
|
|
48
|
+
const m = s.match(/QQ[::]\s*(\d{4,})/);
|
|
49
|
+
if (m) return `qq:${m[1]}`;
|
|
50
|
+
}
|
|
51
|
+
// 3. 退化:会话地址 → 来源 → main
|
|
52
|
+
if (typeof e.senderKey === 'string' && e.senderKey.trim()) return e.senderKey.trim();
|
|
53
|
+
if (typeof e.source === 'string' && e.source) return e.source;
|
|
54
|
+
return 'main';
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
export class MemoryWorld implements World {
|
|
35
58
|
readonly id = 'memory';
|
|
36
59
|
private host: WorldHost | null = null;
|
|
@@ -160,10 +183,8 @@ export class MemoryWorld implements World {
|
|
|
160
183
|
if (!isInboundUser(e)) continue;
|
|
161
184
|
const text = cleanCaptureText(e.text ?? '');
|
|
162
185
|
if (text.length < (this.cfg.captureMinLength ?? 2)) continue;
|
|
163
|
-
// scope
|
|
164
|
-
const scope = (
|
|
165
|
-
? e.senderKey.trim()
|
|
166
|
-
: (typeof e.source === 'string' && e.source ? e.source : 'main');
|
|
186
|
+
// scope 优先按发送者 QQ 号(私聊↔群聊按人统一);非 QQ 来源退化为会话地址/来源。
|
|
187
|
+
const scope = scopeOfEvent(e);
|
|
167
188
|
this.facts!.add(scope, [text]);
|
|
168
189
|
const vec = this.cfg.embeddingProvider === 'off' ? null : await this.embedder!.embed(text);
|
|
169
190
|
this.vectors!.add(scope, text, vec, this.cfg.maxVectorsPerScope);
|
|
@@ -225,7 +246,7 @@ export class MemoryWorld implements World {
|
|
|
225
246
|
this.vectors!.add(scope, text, this.cfg.embeddingProvider === 'off' ? null : await this.embedder!.embed(text), this.cfg.maxVectorsPerScope);
|
|
226
247
|
return added ? `OK 已记住(${scope}): ${text.slice(0, 80)}` : `OK 已存在,跳过重复(${scope})`;
|
|
227
248
|
}),
|
|
228
|
-
mem_recall: mk('mem_recall', '按语义+关键词混合检索长期记忆(事实库全文 + BM25+向量+RRF 融合),找旧账/回忆约定时用。scope 留空或填 main = 跨全部记忆域(含自动捕获的对话);填具体 scope
|
|
249
|
+
mem_recall: mk('mem_recall', '按语义+关键词混合检索长期记忆(事实库全文 + BM25+向量+RRF 融合),找旧账/回忆约定时用。scope 留空或填 main = 跨全部记忆域(含自动捕获的对话);填具体 scope 只搜该域;可填某人的 qq:<QQ号> 来检索 TA 在私聊与群聊里统一沉淀的记忆(私聊↔群聊无缝衔接)。', { query: str('查询'), top_k: num('条数'), scope: str('记忆域(留空=全部)') }, ['query'], ['read'],
|
|
229
250
|
async (a) => {
|
|
230
251
|
const scope = scopeOf(a);
|
|
231
252
|
const topK = Math.min(20, Number(a.top_k) || this.cfg.vectorTopK);
|