mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-06-14 02:40:45 +08:00
fix(history): pause recovery for render-limited chat slices
This commit is contained in:
127
index.js
127
index.js
@@ -5060,6 +5060,102 @@ function applyMessageRenderLimit(settings = null, options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function getActiveMessageRenderLimitForHistoryGuard(settings = null) {
|
||||
const normalized = getMessageRenderLimitSettings(settings);
|
||||
const configuredLimit =
|
||||
normalized.enabled && normalized.render_last_n > 0
|
||||
? normalized.render_last_n
|
||||
: 0;
|
||||
let hostLimit = 0;
|
||||
try {
|
||||
const powerUserSettings = getHostPowerUserSettings();
|
||||
hostLimit = Math.max(
|
||||
0,
|
||||
Math.trunc(Number(powerUserSettings?.chat_truncation ?? 0) || 0),
|
||||
);
|
||||
} catch {
|
||||
hostLimit = 0;
|
||||
}
|
||||
|
||||
if (configuredLimit > 0 && hostLimit > 0) {
|
||||
return Math.min(configuredLimit, hostLimit);
|
||||
}
|
||||
return Math.max(configuredLimit, hostLimit);
|
||||
}
|
||||
|
||||
function getHighestTrackedProcessedHistoryFloor(historyState = {}) {
|
||||
const lastProcessed = Number.isFinite(
|
||||
Number(historyState?.lastProcessedAssistantFloor),
|
||||
)
|
||||
? Math.floor(Number(historyState.lastProcessedAssistantFloor))
|
||||
: -1;
|
||||
const hashes =
|
||||
historyState?.processedMessageHashes &&
|
||||
typeof historyState.processedMessageHashes === "object" &&
|
||||
!Array.isArray(historyState.processedMessageHashes)
|
||||
? historyState.processedMessageHashes
|
||||
: {};
|
||||
const maxHashFloor = Object.keys(hashes).reduce((maxFloor, key) => {
|
||||
const floor = Number.parseInt(key, 10);
|
||||
return Number.isFinite(floor) ? Math.max(maxFloor, floor) : maxFloor;
|
||||
}, -1);
|
||||
|
||||
return Math.max(lastProcessed, maxHashFloor);
|
||||
}
|
||||
|
||||
function getRenderLimitedHistoryRecoveryGuard(
|
||||
chat,
|
||||
{ settings = null, historyState = currentGraph?.historyState } = {},
|
||||
) {
|
||||
const renderLimit = getActiveMessageRenderLimitForHistoryGuard(settings);
|
||||
if (!Array.isArray(chat) || renderLimit <= 0) {
|
||||
return { blocked: false };
|
||||
}
|
||||
|
||||
const chatLength = chat.length;
|
||||
const highestProcessedFloor =
|
||||
getHighestTrackedProcessedHistoryFloor(historyState);
|
||||
const renderWindowTolerance = renderLimit + 1;
|
||||
if (
|
||||
chatLength > renderWindowTolerance ||
|
||||
highestProcessedFloor < chatLength
|
||||
) {
|
||||
return { blocked: false };
|
||||
}
|
||||
|
||||
return {
|
||||
blocked: true,
|
||||
chatLength,
|
||||
highestProcessedFloor,
|
||||
renderLimit,
|
||||
reason: "render-limited-chat-slice",
|
||||
message:
|
||||
`当前聊天区最多只渲染最近 ${renderLimit} 条消息,当前可见 ${chatLength} 条;` +
|
||||
`图谱已处理到楼层 ${highestProcessedFloor}。为避免把截断视图误判为历史删除并清空运行时图谱,已暂停历史恢复。` +
|
||||
"请临时关闭“限制聊天区渲染楼层”或调大渲染数量并刷新后再提取。",
|
||||
};
|
||||
}
|
||||
|
||||
function notifyRenderLimitedHistoryRecoveryBlocked(guard, trigger = "") {
|
||||
if (!guard?.blocked) return;
|
||||
console.warn?.("[ST-BME] 历史恢复因聊天渲染限制暂停:", {
|
||||
trigger,
|
||||
chatLength: guard.chatLength,
|
||||
highestProcessedFloor: guard.highestProcessedFloor,
|
||||
renderLimit: guard.renderLimit,
|
||||
});
|
||||
updateStageNotice(
|
||||
"history",
|
||||
"历史恢复已暂停",
|
||||
guard.message,
|
||||
"warning",
|
||||
{
|
||||
busy: false,
|
||||
persist: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
function getHideRuntimeAdapters() {
|
||||
return {
|
||||
$,
|
||||
@@ -16900,6 +16996,17 @@ function inspectHistoryMutation(
|
||||
ensureCurrentGraphRuntimeState();
|
||||
const context = getContext();
|
||||
const chat = context?.chat;
|
||||
const renderLimitedGuard = getRenderLimitedHistoryRecoveryGuard(chat);
|
||||
if (renderLimitedGuard.blocked) {
|
||||
notifyRenderLimitedHistoryRecoveryBlocked(renderLimitedGuard, trigger);
|
||||
return {
|
||||
dirty: false,
|
||||
earliestAffectedFloor: null,
|
||||
reason: renderLimitedGuard.reason,
|
||||
source: "render-limit-guard",
|
||||
skipped: true,
|
||||
};
|
||||
}
|
||||
if (
|
||||
Array.isArray(chat) &&
|
||||
currentGraph.historyState?.processedMessageHashesNeedRefresh === true
|
||||
@@ -17479,6 +17586,26 @@ async function recoverHistoryIfNeeded(trigger = "history-recovery") {
|
||||
const context = getContext();
|
||||
const chat = context?.chat;
|
||||
if (!Array.isArray(chat)) return true;
|
||||
const renderLimitedGuard = getRenderLimitedHistoryRecoveryGuard(chat);
|
||||
if (renderLimitedGuard.blocked) {
|
||||
currentGraph.historyState.lastRecoveryResult = buildRecoveryResult(
|
||||
"paused",
|
||||
{
|
||||
fromFloor: currentGraph.historyState?.historyDirtyFrom ?? null,
|
||||
path: "render-limit-guard",
|
||||
detectionSource:
|
||||
currentGraph.historyState?.lastMutationSource || "render-limit-guard",
|
||||
reason: renderLimitedGuard.message,
|
||||
resultCode: "history.recovery.paused.render-limit",
|
||||
chatLength: renderLimitedGuard.chatLength,
|
||||
renderLimit: renderLimitedGuard.renderLimit,
|
||||
highestProcessedFloor: renderLimitedGuard.highestProcessedFloor,
|
||||
},
|
||||
);
|
||||
notifyRenderLimitedHistoryRecoveryBlocked(renderLimitedGuard, trigger);
|
||||
refreshPanelLiveState();
|
||||
return false;
|
||||
}
|
||||
|
||||
const detection = inspectHistoryMutation(trigger);
|
||||
const dirtyFrom = currentGraph?.historyState?.historyDirtyFrom;
|
||||
|
||||
Reference in New Issue
Block a user