Fix vector recall pending user message
This commit is contained in:
@@ -1,17 +1,10 @@
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// Story Summary - Prompt Injection (Final Clean Version)
|
||||
// - 注入只在 GENERATION_STARTED 发生(由 story-summary.js 调用)
|
||||
// - 向量关闭:注入全量总结(世界/事件/弧光)
|
||||
// - 向量开启:召回 + 预算装配注入
|
||||
// - 没有“快速注入”写入 extension_prompts,避免覆盖/残留/竞态
|
||||
// - 仅负责“构建注入文本”,不负责写入 extension_prompts
|
||||
// - 注入发生在 story-summary.js 的 CHAT_COMPLETION_PROMPT_READY(最终 messages 已裁剪)
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
import { getContext } from "../../../../../../extensions.js";
|
||||
import {
|
||||
extension_prompts,
|
||||
extension_prompt_types,
|
||||
extension_prompt_roles,
|
||||
} from "../../../../../../../script.js";
|
||||
import { xbLog } from "../../../core/debug-core.js";
|
||||
import { getSummaryStore } from "../data/store.js";
|
||||
import { getVectorConfig, getSummaryPanelConfig, getSettings } from "../data/config.js";
|
||||
@@ -19,7 +12,6 @@ import { recallMemory, buildQueryText } from "../vector/recall.js";
|
||||
import { getChunksByFloors, getAllChunkVectors, getAllEventVectors, getMeta } from "../vector/chunk-store.js";
|
||||
|
||||
const MODULE_ID = "summaryPrompt";
|
||||
const SUMMARY_PROMPT_KEY = "LittleWhiteBox_StorySummary";
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// 召回失败提示节流(避免连续生成刷屏)
|
||||
@@ -137,7 +129,8 @@ function formatArcLine(a) {
|
||||
|
||||
// 完整 chunk 输出(不截断)
|
||||
function formatChunkFullLine(c) {
|
||||
const speaker = c.isUser ? "{{user}}" : "{{char}}";
|
||||
const { name1, name2 } = getContext();
|
||||
const speaker = c.isUser ? (name1 || "用户") : (name2 || "角色");
|
||||
return `› #${c.floor + 1} [${speaker}] ${String(c.text || "").trim()}`;
|
||||
}
|
||||
|
||||
@@ -299,23 +292,19 @@ function buildNonVectorPrompt(store) {
|
||||
);
|
||||
}
|
||||
|
||||
export async function injectNonVectorPrompt(postToFrame = null) {
|
||||
export function buildNonVectorPromptText() {
|
||||
if (!getSettings().storySummary?.enabled) {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return "";
|
||||
}
|
||||
|
||||
const { chat } = getContext();
|
||||
const store = getSummaryStore();
|
||||
if (!store?.json) {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return "";
|
||||
}
|
||||
|
||||
let text = buildNonVectorPrompt(store);
|
||||
if (!text.trim()) {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return "";
|
||||
}
|
||||
|
||||
// wrapper(沿用面板设置)
|
||||
@@ -323,21 +312,7 @@ export async function injectNonVectorPrompt(postToFrame = null) {
|
||||
if (cfg.trigger?.wrapperHead) text = cfg.trigger.wrapperHead + "\n" + text;
|
||||
if (cfg.trigger?.wrapperTail) text = text + "\n" + cfg.trigger.wrapperTail;
|
||||
|
||||
const lastIdx = store.lastSummarizedMesId ?? 0;
|
||||
let depth = (chat?.length || 0) - lastIdx - 1;
|
||||
if (depth < 0) depth = 0;
|
||||
if (cfg.trigger?.forceInsertAtEnd) depth = 10000;
|
||||
|
||||
extension_prompts[SUMMARY_PROMPT_KEY] = {
|
||||
value: text,
|
||||
position: extension_prompt_types.IN_CHAT,
|
||||
depth,
|
||||
role: extension_prompt_roles.SYSTEM,
|
||||
};
|
||||
|
||||
if (postToFrame) {
|
||||
postToFrame({ type: "RECALL_LOG", text: "\n[Non-vector] Injected full summary prompt.\n" });
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
@@ -706,19 +681,17 @@ async function attachEvidenceToCausalEvents(causalEvents, eventVectorMap, chunkV
|
||||
// ✅ 向量模式:召回 + 注入(供 story-summary.js 在 GENERATION_STARTED 调用)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
export async function recallAndInjectPrompt(excludeLastAi = false, hooks = {}) {
|
||||
const { postToFrame = null, echo = null } = hooks;
|
||||
export async function buildVectorPromptText(excludeLastAi = false, hooks = {}) {
|
||||
const { postToFrame = null, echo = null, pendingUserMessage = null } = hooks;
|
||||
if (!getSettings().storySummary?.enabled) {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return { text: "", logText: "" };
|
||||
}
|
||||
|
||||
const { chat } = getContext();
|
||||
const store = getSummaryStore();
|
||||
|
||||
if (!store?.json) {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return { text: "", logText: "" };
|
||||
}
|
||||
|
||||
const allEvents = store.json.events || [];
|
||||
@@ -726,14 +699,12 @@ export async function recallAndInjectPrompt(excludeLastAi = false, hooks = {}) {
|
||||
const length = chat?.length || 0;
|
||||
|
||||
if (lastIdx >= length) {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return { text: "", logText: "" };
|
||||
}
|
||||
|
||||
const vectorCfg = getVectorConfig();
|
||||
if (!vectorCfg?.enabled) {
|
||||
// 向量没开,不该走这条
|
||||
return;
|
||||
return { text: "", logText: "" };
|
||||
}
|
||||
|
||||
const { chatId } = getContext();
|
||||
@@ -745,7 +716,10 @@ export async function recallAndInjectPrompt(excludeLastAi = false, hooks = {}) {
|
||||
|
||||
try {
|
||||
const queryText = buildQueryText(chat, 2, excludeLastAi);
|
||||
recallResult = await recallMemory(queryText, allEvents, vectorCfg, { excludeLastAi });
|
||||
recallResult = await recallMemory(queryText, allEvents, vectorCfg, {
|
||||
excludeLastAi,
|
||||
pendingUserMessage,
|
||||
});
|
||||
|
||||
recallResult = {
|
||||
...recallResult,
|
||||
@@ -808,9 +782,7 @@ export async function recallAndInjectPrompt(excludeLastAi = false, hooks = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
// 清空本次注入,避免残留误导
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return { text: "", logText: `\n[Vector Recall Failed]\n${String(e?.stack || e?.message || e)}\n` };
|
||||
}
|
||||
|
||||
// 成功但结果为空:也提示,并清空注入(不降级)
|
||||
@@ -831,8 +803,7 @@ export async function recallAndInjectPrompt(excludeLastAi = false, hooks = {}) {
|
||||
text: "\n[Vector Recall Empty]\nNo recall candidates / vectors not ready.\n",
|
||||
});
|
||||
}
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
return { text: "", logText: "\n[Vector Recall Empty]\nNo recall candidates / vectors not ready.\n" };
|
||||
}
|
||||
|
||||
// 拼装向量 prompt
|
||||
@@ -844,50 +815,17 @@ export async function recallAndInjectPrompt(excludeLastAi = false, hooks = {}) {
|
||||
meta
|
||||
);
|
||||
|
||||
// 写入 extension_prompts(真正注入)
|
||||
await writePromptToExtensionPrompts(promptText, store, chat);
|
||||
// wrapper(沿用面板设置)——必须补回,否则语义回退
|
||||
const cfg = getSummaryPanelConfig();
|
||||
let finalText = String(promptText || "");
|
||||
if (cfg.trigger?.wrapperHead) finalText = cfg.trigger.wrapperHead + "\n" + finalText;
|
||||
if (cfg.trigger?.wrapperTail) finalText = finalText + "\n" + cfg.trigger.wrapperTail;
|
||||
|
||||
// 发给涌现窗口:召回报告 + 装配报告
|
||||
if (postToFrame) {
|
||||
const recallLog = recallResult.logText || "";
|
||||
postToFrame({ type: "RECALL_LOG", text: recallLog + (injectionLogText || "") });
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// 写入 extension_prompts(统一入口)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
async function writePromptToExtensionPrompts(text, store, chat) {
|
||||
const cfg = getSummaryPanelConfig();
|
||||
let finalText = String(text || "");
|
||||
|
||||
if (cfg.trigger?.wrapperHead) finalText = cfg.trigger.wrapperHead + "\n" + finalText;
|
||||
if (cfg.trigger?.wrapperTail) finalText = finalText + "\n" + cfg.trigger.wrapperTail;
|
||||
|
||||
if (!finalText.trim()) {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
return;
|
||||
}
|
||||
|
||||
const lastIdx = store.lastSummarizedMesId ?? 0;
|
||||
let depth = (chat?.length || 0) - lastIdx - 1;
|
||||
if (depth < 0) depth = 0;
|
||||
|
||||
if (cfg.trigger?.forceInsertAtEnd) depth = 10000;
|
||||
|
||||
extension_prompts[SUMMARY_PROMPT_KEY] = {
|
||||
value: finalText,
|
||||
position: extension_prompt_types.IN_CHAT,
|
||||
depth,
|
||||
role: extension_prompt_roles.SYSTEM,
|
||||
};
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// 清理 prompt(供 story-summary.js 调用)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
export function clearSummaryExtensionPrompt() {
|
||||
delete extension_prompts[SUMMARY_PROMPT_KEY];
|
||||
|
||||
return { text: finalText, logText: (recallResult.logText || "") + (injectionLogText || "") };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user