fix: preserve fact metadata and trend on manual edits
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user