Update story summary recall and prompt

This commit is contained in:
2026-02-05 00:22:02 +08:00
parent 12db08abe0
commit 8137e206f9
18 changed files with 708 additions and 406 deletions

View File

@@ -5,10 +5,11 @@ import { getContext, saveMetadataDebounced } from "../../../../../../extensions.
import { chat_metadata } from "../../../../../../../script.js";
import { EXT_ID } from "../../../core/constants.js";
import { xbLog } from "../../../core/debug-core.js";
import { clearEventVectors, deleteEventVectorsByIds } from "../vector/chunk-store.js";
import { clearEventTextIndex } from '../vector/text-search.js';
import { clearEventVectors, deleteEventVectorsByIds } from "../vector/storage/chunk-store.js";
import { clearEventTextIndex } from '../vector/retrieval/text-search.js';
const MODULE_ID = 'summaryStore';
const FACTS_LIMIT_PER_SUBJECT = 10;
// ═══════════════════════════════════════════════════════════════════════════
// 基础存取
@@ -125,32 +126,26 @@ function getNextFactId(existingFacts) {
export function mergeFacts(existingFacts, updates, floor) {
const map = new Map();
// 加载现有 facts
for (const f of existingFacts || []) {
if (!f.retracted) {
map.set(factKey(f), f);
}
}
// 获取下一个 ID
let nextId = getNextFactId(existingFacts);
// 应用更新
for (const u of updates || []) {
if (!u.s || !u.p) continue;
const key = factKey(u);
// 删除操作
if (u.retracted === true) {
map.delete(key);
continue;
}
// 无 o 则跳过
if (!u.o || !String(u.o).trim()) continue;
// 覆盖或新增
const existing = map.get(key);
const newFact = {
id: existing?.id || `f-${nextId++}`,
@@ -158,14 +153,13 @@ export function mergeFacts(existingFacts, updates, floor) {
p: u.p.trim(),
o: String(u.o).trim(),
since: floor,
_isState: existing?._isState ?? !!u.isState,
};
// 关系类保留 trend
if (isRelationFact(newFact) && u.trend) {
newFact.trend = u.trend;
}
// 保留原始 _addedAt如果是更新
if (existing?._addedAt != null) {
newFact._addedAt = existing._addedAt;
} else {
@@ -175,9 +169,28 @@ export function mergeFacts(existingFacts, updates, floor) {
map.set(key, newFact);
}
return Array.from(map.values());
const factsBySubject = new Map();
for (const f of map.values()) {
if (f._isState) continue;
const arr = factsBySubject.get(f.s) || [];
arr.push(f);
factsBySubject.set(f.s, arr);
}
const toRemove = new Set();
for (const arr of factsBySubject.values()) {
if (arr.length > FACTS_LIMIT_PER_SUBJECT) {
arr.sort((a, b) => (a._addedAt || 0) - (b._addedAt || 0));
for (let i = 0; i < arr.length - FACTS_LIMIT_PER_SUBJECT; i++) {
toRemove.add(factKey(arr[i]));
}
}
}
return Array.from(map.values()).filter(f => !toRemove.has(factKey(f)));
}
// ═══════════════════════════════════════════════════════════════════════════
// 旧数据迁移
// ═══════════════════════════════════════════════════════════════════════════