mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-06-13 18:31:16 +08:00
fix(history): pause recovery for render-limited chat slices
This commit is contained in:
@@ -33,6 +33,7 @@ let powerUser = { chat_truncation: 0 };
|
||||
let reloadCount = 0;
|
||||
let inputValue = "";
|
||||
let counterValue = "";
|
||||
let currentGraph = null;
|
||||
const triggeredEvents = [];
|
||||
|
||||
function getContext() {
|
||||
@@ -83,10 +84,16 @@ function getState() {
|
||||
};
|
||||
}
|
||||
|
||||
function setCurrentGraph(graph) {
|
||||
currentGraph = graph;
|
||||
}
|
||||
|
||||
export {
|
||||
applyMessageRenderLimit,
|
||||
getRenderLimitedHistoryRecoveryGuard,
|
||||
getMessageRenderLimitSettings,
|
||||
getState,
|
||||
setCurrentGraph,
|
||||
};
|
||||
`,
|
||||
"utf8",
|
||||
@@ -133,6 +140,51 @@ try {
|
||||
reloadCount: 1,
|
||||
triggeredEvents: ["change"],
|
||||
});
|
||||
const guarded = module.getRenderLimitedHistoryRecoveryGuard(
|
||||
new Array(10).fill({ mes: "visible" }),
|
||||
{
|
||||
settings: {
|
||||
enabled: true,
|
||||
hideOldMessagesRenderLimitEnabled: true,
|
||||
hideOldMessagesRenderLimit: 10,
|
||||
},
|
||||
historyState: {
|
||||
lastProcessedAssistantFloor: 30,
|
||||
processedMessageHashes: { 0: "a", 30: "b" },
|
||||
},
|
||||
},
|
||||
);
|
||||
assert.equal(guarded.blocked, true);
|
||||
assert.equal(guarded.renderLimit, 10);
|
||||
assert.equal(guarded.highestProcessedFloor, 30);
|
||||
|
||||
const notGuardedWhenFullerThanRenderWindow =
|
||||
module.getRenderLimitedHistoryRecoveryGuard(new Array(20).fill({}), {
|
||||
settings: {
|
||||
enabled: true,
|
||||
hideOldMessagesRenderLimitEnabled: true,
|
||||
hideOldMessagesRenderLimit: 10,
|
||||
},
|
||||
historyState: {
|
||||
lastProcessedAssistantFloor: 30,
|
||||
processedMessageHashes: { 30: "b" },
|
||||
},
|
||||
});
|
||||
assert.equal(notGuardedWhenFullerThanRenderWindow.blocked, false);
|
||||
|
||||
const notGuardedWhenHistoryFitsVisibleChat =
|
||||
module.getRenderLimitedHistoryRecoveryGuard(new Array(10).fill({}), {
|
||||
settings: {
|
||||
enabled: true,
|
||||
hideOldMessagesRenderLimitEnabled: true,
|
||||
hideOldMessagesRenderLimit: 10,
|
||||
},
|
||||
historyState: {
|
||||
lastProcessedAssistantFloor: 5,
|
||||
processedMessageHashes: { 5: "b" },
|
||||
},
|
||||
});
|
||||
assert.equal(notGuardedWhenHistoryFitsVisibleChat.blocked, false);
|
||||
|
||||
const skipped = module.applyMessageRenderLimit({
|
||||
enabled: true,
|
||||
|
||||
@@ -358,6 +358,7 @@ function createHistoryRecoveryHarness() {
|
||||
prepareVectorStateCalls: [],
|
||||
saveGraphToChatCalls: 0,
|
||||
refreshPanelCalls: 0,
|
||||
renderLimitBlockedCalls: [],
|
||||
notices: [],
|
||||
toastCalls: {
|
||||
success: [],
|
||||
@@ -471,6 +472,12 @@ function createHistoryRecoveryHarness() {
|
||||
getSettings() {
|
||||
return {};
|
||||
},
|
||||
getRenderLimitedHistoryRecoveryGuard() {
|
||||
return context.renderLimitedGuard || { blocked: false };
|
||||
},
|
||||
notifyRenderLimitedHistoryRecoveryBlocked(guard, trigger) {
|
||||
context.renderLimitBlockedCalls.push({ guard, trigger });
|
||||
},
|
||||
isBackendVectorConfig(config) {
|
||||
return config?.mode === "backend";
|
||||
},
|
||||
@@ -6324,6 +6331,56 @@ async function testHistoryRecoveryStandardSuffixReplayDoesNotEmitCompletionToast
|
||||
assert.equal(harness.toastCalls.error.length, 0);
|
||||
}
|
||||
|
||||
async function testHistoryRecoveryPausesWhenRenderLimitedChatSlice() {
|
||||
const harness = await createHistoryRecoveryHarness();
|
||||
harness.chat = new Array(10).fill(null).map((_, index) => ({
|
||||
is_user: index % 2 === 0,
|
||||
mes: `visible-${index}`,
|
||||
}));
|
||||
harness.currentGraph = {
|
||||
historyState: {
|
||||
lastProcessedAssistantFloor: 30,
|
||||
processedMessageHashes: { 30: "hash-30" },
|
||||
historyDirtyFrom: 10,
|
||||
lastMutationSource: "hash-recheck",
|
||||
lastMutationReason: "已处理楼层超出当前聊天长度,检测到历史截断",
|
||||
extractionCount: 8,
|
||||
},
|
||||
vectorIndexState: {
|
||||
collectionId: "col-1",
|
||||
dirty: false,
|
||||
dirtyReason: "",
|
||||
pendingRepairFromFloor: null,
|
||||
replayRequiredNodeIds: [],
|
||||
lastWarning: "",
|
||||
lastIntegrityIssue: null,
|
||||
},
|
||||
batchJournal: [],
|
||||
lastProcessedSeq: 30,
|
||||
};
|
||||
harness.renderLimitedGuard = {
|
||||
blocked: true,
|
||||
chatLength: 10,
|
||||
renderLimit: 10,
|
||||
highestProcessedFloor: 30,
|
||||
reason: "render-limited-chat-slice",
|
||||
message: "render limited",
|
||||
};
|
||||
|
||||
const result = await harness.result.recoverFromHistoryMutation("manual-extract");
|
||||
|
||||
assert.equal(result, false);
|
||||
assert.equal(harness.prepareVectorStateCalls.length, 0);
|
||||
assert.equal(harness.saveGraphToChatCalls, 0);
|
||||
assert.equal(harness.refreshPanelCalls, 1);
|
||||
assert.equal(harness.renderLimitBlockedCalls.length, 1);
|
||||
assert.equal(
|
||||
harness.currentGraph.historyState.lastRecoveryResult?.resultCode,
|
||||
"history.recovery.paused.render-limit",
|
||||
);
|
||||
assert.equal(harness.currentGraph.historyState.lastProcessedAssistantFloor, 30);
|
||||
}
|
||||
|
||||
async function testHistoryRecoveryFullRebuildStillWarnsUser() {
|
||||
const harness = await createHistoryRecoveryHarness();
|
||||
harness.chat = [
|
||||
@@ -7525,6 +7582,7 @@ await testRecallSubGraphAndDataLayerEntryPoints();
|
||||
await testRerollUsesBatchBoundaryRollbackAndPersistsState();
|
||||
await testNotifyHistoryDirtyUsesStageNoticeWithoutGenericWarningToast();
|
||||
await testHistoryRecoveryStandardSuffixReplayDoesNotEmitCompletionToast();
|
||||
await testHistoryRecoveryPausesWhenRenderLimitedChatSlice();
|
||||
await testHistoryRecoveryFullRebuildStillWarnsUser();
|
||||
await testHistoryRecoveryAbortClearsVectorRepairState();
|
||||
await testHistoryRecoveryFallbackFullRebuildCarriesResultCode();
|
||||
|
||||
Reference in New Issue
Block a user