fix(recall): skip pre-recall recovery on reroll reuse

This commit is contained in:
opencode
2026-05-15 19:17:30 +00:00
parent 06e92cda7c
commit a5c4e12a76
2 changed files with 37 additions and 21 deletions

View File

@@ -513,26 +513,6 @@ export async function runRecallController(runtime, options = {}) {
reason: "召回功能未启用", reason: "召回功能未启用",
}); });
} }
const isReadableForRecall =
typeof runtime.isGraphReadableForRecall === "function"
? runtime.isGraphReadableForRecall()
: runtime.isGraphReadable();
if (!isReadableForRecall) {
const reason = runtime.getGraphMutationBlockReason("召回");
runtime.setLastRecallStatus("等待图谱加载", reason, "warning", {
syncRuntime: true,
});
return runtime.createRecallRunResult("skipped", {
reason,
});
}
if (runtime.isGraphMetadataWriteAllowed()) {
if (!(await runtime.recoverHistoryIfNeeded("pre-recall"))) {
return runtime.createRecallRunResult("skipped", {
reason: "历史恢复未就绪",
});
}
}
const context = runtime.getContext(); const context = runtime.getContext();
const chat = context.chat; const chat = context.chat;
@@ -690,6 +670,27 @@ export async function runRecallController(runtime, options = {}) {
}); });
} }
const isReadableForRecall =
typeof runtime.isGraphReadableForRecall === "function"
? runtime.isGraphReadableForRecall()
: runtime.isGraphReadable();
if (!isReadableForRecall) {
const reason = runtime.getGraphMutationBlockReason("召回");
runtime.setLastRecallStatus("等待图谱加载", reason, "warning", {
syncRuntime: true,
});
return runtime.createRecallRunResult("skipped", {
reason,
});
}
if (runtime.isGraphMetadataWriteAllowed()) {
if (!(await runtime.recoverHistoryIfNeeded("pre-recall"))) {
return runtime.createRecallRunResult("skipped", {
reason: "历史恢复未就绪",
});
}
}
const runId = runtime.nextRecallRunSequence(); const runId = runtime.nextRecallRunSequence();
let recallPromise = null; let recallPromise = null;
recallPromise = (async () => { recallPromise = (async () => {

View File

@@ -313,6 +313,7 @@ writePersistedRecallToUserMessage(rerollChat, 0, validRecord);
let retrieveCalled = false; let retrieveCalled = false;
let rerollEnsureVectorReadyCalled = false; let rerollEnsureVectorReadyCalled = false;
let rerollRecoverHistoryCalled = false;
const rerollStatusLabels = []; const rerollStatusLabels = [];
const rerollRuntime = { const rerollRuntime = {
getIsRecalling: () => false, getIsRecalling: () => false,
@@ -325,7 +326,10 @@ const rerollRuntime = {
}), }),
isGraphReadableForRecall: () => true, isGraphReadableForRecall: () => true,
isGraphMetadataWriteAllowed: () => true, isGraphMetadataWriteAllowed: () => true,
recoverHistoryIfNeeded: async () => true, recoverHistoryIfNeeded: async () => {
rerollRecoverHistoryCalled = true;
return true;
},
getContext: () => ({ chat: rerollChat, chatId: "chat-reroll" }), getContext: () => ({ chat: rerollChat, chatId: "chat-reroll" }),
nextRecallRunSequence: () => 1, nextRecallRunSequence: () => 1,
beginStageAbortController: () => ({ signal: { aborted: false } }), beginStageAbortController: () => ({ signal: { aborted: false } }),
@@ -435,6 +439,11 @@ assert.equal(
false, false,
"persisted reroll reuse should not even prepare vectors before reusing the user-floor record", "persisted reroll reuse should not even prepare vectors before reusing the user-floor record",
); );
assert.equal(
rerollRecoverHistoryCalled,
false,
"persisted reroll reuse should not trigger pre-recall history recovery",
);
assert.equal( assert.equal(
rerollStatusLabels.includes("召回中"), rerollStatusLabels.includes("召回中"),
false, false,
@@ -599,6 +608,7 @@ assert.equal(
console.log(" ✓ runRecallController does not reuse unbound record for active input"); console.log(" ✓ runRecallController does not reuse unbound record for active input");
rerollRecoverHistoryCalled = false;
const activeInputBoundChat = [ const activeInputBoundChat = [
{ is_user: true, mes: "主动新输入绑定记录也不应复用" }, { is_user: true, mes: "主动新输入绑定记录也不应复用" },
{ is_user: false, mes: "上一条回复。", is_system: false }, { is_user: false, mes: "上一条回复。", is_system: false },
@@ -642,6 +652,11 @@ assert.equal(
true, true,
"active send-intent input should not reuse even a bound target user-floor record", "active send-intent input should not reuse even a bound target user-floor record",
); );
assert.equal(
rerollRecoverHistoryCalled,
true,
"active send-intent input should still run normal pre-recall history recovery before fresh recall",
);
assert.equal( assert.equal(
activeInputBoundResult.injectionText, activeInputBoundResult.injectionText,
"新召回:主动新输入绑定记录也不应复用", "新召回:主动新输入绑定记录也不应复用",