fix: preserve fact metadata and trend on manual edits

This commit is contained in:
2026-02-24 16:40:04 +08:00
parent 1f3880d1d9
commit 6805308737

View File

@@ -1092,6 +1092,57 @@ function mergeCharacterRelationshipsIntoFacts(existingFacts, relationships, floo
return [...nonRelationFacts, ...newRelationFacts]; return [...nonRelationFacts, ...newRelationFacts];
} }
function getCurrentFloorHint() {
const { chat } = getContext();
const lastFloor = (Array.isArray(chat) ? chat.length : 0) - 1;
return Math.max(0, lastFloor);
}
function factKeyBySubjectPredicate(fact) {
const s = String(fact?.s || "").trim();
const p = String(fact?.p || "").trim();
return `${s}::${p}`;
}
function mergeEditedFactsWithTimestamps(existingFacts, editedFacts, floorHint = 0) {
const currentFacts = Array.isArray(existingFacts) ? existingFacts : [];
const incomingFacts = Array.isArray(editedFacts) ? editedFacts : [];
const oldMap = new Map(currentFacts.map((f) => [factKeyBySubjectPredicate(f), f]));
let nextFactId = getNextFactIdValue(currentFacts);
const merged = [];
for (const fact of incomingFacts) {
const s = String(fact?.s || "").trim();
const p = String(fact?.p || "").trim();
const o = String(fact?.o || "").trim();
if (!s || !p || !o) continue;
const key = `${s}::${p}`;
const oldFact = oldMap.get(key);
const since = oldFact?.since ?? fact?.since ?? floorHint;
const addedAt = oldFact?._addedAt ?? fact?._addedAt ?? floorHint;
const out = {
id: oldFact?.id || fact?.id || `f-${nextFactId++}`,
s,
p,
o,
since,
_addedAt: addedAt,
};
if (oldFact?._isState != null) out._isState = oldFact._isState;
const mergedTrend = fact?.trend ?? oldFact?.trend;
if (mergedTrend != null && String(mergedTrend).trim()) {
out.trend = String(mergedTrend).trim();
}
merged.push(out);
}
return merged;
}
function openPanelForMessage(mesId) { function openPanelForMessage(mesId) {
createOverlay(); createOverlay();
showOverlay(); showOverlay();
@@ -1428,13 +1479,17 @@ async function handleFrameMessage(event) {
// 如果是 events先记录旧数据用于同步向量 // 如果是 events先记录旧数据用于同步向量
const oldEvents = data.section === "events" ? [...(store.json.events || [])] : null; const oldEvents = data.section === "events" ? [...(store.json.events || [])] : null;
const oldFacts = data.section === "facts" ? [...(store.json.facts || [])] : null;
if (VALID_SECTIONS.includes(data.section)) { if (VALID_SECTIONS.includes(data.section)) {
store.json[data.section] = data.data; store.json[data.section] = data.data;
} }
if (data.section === "facts") {
store.json.facts = mergeEditedFactsWithTimestamps(oldFacts, data.data, getCurrentFloorHint());
}
if (data.section === "characters") { if (data.section === "characters") {
const rels = data?.data?.relationships || []; const rels = data?.data?.relationships || [];
const floorHint = Math.max(0, Number(store.lastSummarizedMesId) || 0); const floorHint = getCurrentFloorHint();
store.json.facts = mergeCharacterRelationshipsIntoFacts(store.json.facts, rels, floorHint); store.json.facts = mergeCharacterRelationshipsIntoFacts(store.json.facts, rels, floorHint);
} }
store.updatedAt = Date.now(); store.updatedAt = Date.now();