mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
fix: clean up residual mojibake strings in index.js
This commit is contained in:
94
index.js
94
index.js
@@ -1,5 +1,5 @@
|
||||
// ST-BME: 主入<EFBFBD><EFBFBD>?
|
||||
// 事件钩子、设置管理、流程调<EFBFBD><EFBFBD>?
|
||||
// ST-BME: 主入口
|
||||
// 事件钩子、设置管理、流程调度
|
||||
|
||||
import {
|
||||
eventSource,
|
||||
@@ -297,7 +297,7 @@ import {
|
||||
|
||||
export { DEFAULT_TRIGGER_KEYWORDS, getSmartTriggerDecision };
|
||||
|
||||
// 操控面板模块(动态加载,防止加载失败崩溃整个扩展<EFBFBD><EFBFBD>?
|
||||
// 操控面板模块(动态加载,防止加载失败崩溃整个扩展)
|
||||
let _panelModule = null;
|
||||
let _themesModule = null;
|
||||
|
||||
@@ -702,7 +702,7 @@ function readRuntimeDebugSnapshot() {
|
||||
);
|
||||
}
|
||||
|
||||
// ==================== 状<EFBFBD><EFBFBD>?====================
|
||||
// ==================== 状态 ====================
|
||||
|
||||
let currentGraph = null;
|
||||
let isExtracting = false;
|
||||
@@ -710,8 +710,8 @@ let isRecalling = false;
|
||||
let activeRecallPromise = null;
|
||||
let recallRunSequence = 0;
|
||||
let lastInjectionContent = "";
|
||||
let lastExtractedItems = []; // 最近提取的节点(面板展示用<EFBFBD><EFBFBD>?
|
||||
let lastRecalledItems = []; // 最近召回的节点(面板展示用<EFBFBD><EFBFBD>?
|
||||
let lastExtractedItems = []; // 最近提取的节点(面板展示用)
|
||||
let lastRecalledItems = []; // 最近召回的节点(面板展示用)
|
||||
let extractionCount = 0; // v2: 提取次数计数器(定期触发概要/遗忘/反思)
|
||||
let serverSettingsSaveTimer = null;
|
||||
let isRecoveringHistory = false;
|
||||
@@ -973,14 +973,14 @@ function hasReadableRuntimeGraphForRecall(chatId = getCurrentChatId()) {
|
||||
currentGraph.historyState.chatId,
|
||||
);
|
||||
|
||||
// chatId 匹配验证:如果两者都有,必须一<EFBFBD><EFBFBD>?
|
||||
// chatId 匹配验证:如果两者都有,必须一致
|
||||
if (activeChatId && runtimeChatId) {
|
||||
return runtimeChatId === activeChatId;
|
||||
}
|
||||
|
||||
// 兜底:chatId 不可用(ST 插件环境可能无法获取 chatId),
|
||||
// <EFBFBD><EFBFBD>?currentGraph 结构完整且有节点数据 <20><>?允许召回<EFBFBD><EFBFBD>?
|
||||
// 这对应用户能<EFBFBD><EFBFBD>?UI 看到图谱<EFBFBD><EFBFBD>?getCurrentChatId() 返回空的场景<EFBFBD><EFBFBD>?
|
||||
// 只要 currentGraph 结构完整且有节点数据,就允许召回。
|
||||
// 这对应用户能在 UI 看到图谱,但 getCurrentChatId() 返回空的场景。
|
||||
return currentGraph.nodes.length > 0 || currentGraph.edges.length > 0;
|
||||
}
|
||||
|
||||
@@ -992,10 +992,10 @@ function isGraphReadableForRecall(
|
||||
return true;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD>?loadState 不在正常可读状态时(如 NO_CHAT、LOADING),
|
||||
// 仍检查运行时图谱的实际结构。持久化状态机可能失同<EFBFBD><EFBFBD>?
|
||||
// (如 getCurrentChatId 在某<EFBFBD><EFBFBD>?ST 环境下返回空导致 loadState 卡在 NO_CHAT),
|
||||
// <EFBFBD><EFBFBD>?currentGraph 已经通过其他路径(IndexedDB probe / metadata fallback)加载了数据<EFBFBD><EFBFBD>?
|
||||
// 当 loadState 不在正常可读状态时(如 NO_CHAT、LOADING),
|
||||
// 仍检查运行时图谱的实际结构。持久化状态机可能失同步
|
||||
// (如 getCurrentChatId 在某些 ST 环境下返回空导致 loadState 卡在 NO_CHAT),
|
||||
// 但 currentGraph 已经通过其他路径(IndexedDB probe / metadata fallback)加载了数据。
|
||||
return hasReadableRuntimeGraphForRecall(chatId);
|
||||
}
|
||||
|
||||
@@ -1722,10 +1722,10 @@ function recordRecallSentUserMessage(messageId, text, source = "message-sent") {
|
||||
}
|
||||
|
||||
// 注意:不再在 MESSAGE_SENT 阶段清空 pendingRecallSendIntent /
|
||||
// pendingHostGenerationInputSnapshot / transactions<EFBFBD><EFBFBD>?
|
||||
// 这些数据<EFBFBD><EFBFBD>?GENERATION_AFTER_COMMANDS 中被消费;MESSAGE_SENT 先于
|
||||
// GENERATION_AFTER_COMMANDS 触发,提前清空会导致召回拿不到用户输入<EFBFBD><EFBFBD>?
|
||||
// 真正的消费发生在 recall 执行后(runRecallController 内部)<EFBFBD><EFBFBD>?
|
||||
// pendingHostGenerationInputSnapshot / transactions。
|
||||
// 这些数据在 GENERATION_AFTER_COMMANDS 中被消费;MESSAGE_SENT 先于
|
||||
// GENERATION_AFTER_COMMANDS 触发,提前清空会导致召回拿不到用户输入。
|
||||
// 真正的消费发生在 recall 执行后(runRecallController 内部)。
|
||||
|
||||
return lastRecallSentUserMessage;
|
||||
}
|
||||
@@ -1900,9 +1900,9 @@ function resolveRecallPersistenceTargetUserMessageIndex(
|
||||
}
|
||||
|
||||
// 正常生成阶段里,ST 可能会在真正发送前改写用户文本
|
||||
// (命令展开、包装显示、助<EFBFBD><EFBFBD>?UI 处理等),导<EFBFBD><EFBFBD>?hash 已无法精确匹配<EFBFBD><EFBFBD>?
|
||||
// 这时仍应优先回绑到“当前最<EFBFBD><EFBFBD>?user 楼层”,否则召回记录虽然生成了,
|
||||
// <EFBFBD><EFBFBD>?Recall Card 会因为找不到目标楼层而消失<EFBFBD><EFBFBD>?
|
||||
// (命令展开、包装显示、辅助 UI 处理等),导致 hash 已无法精确匹配。
|
||||
// 这时仍应优先回绑到“当前最新 user 楼层”,否则召回记录虽然生成了,
|
||||
// Recall Card 会因为找不到目标楼层而消失。
|
||||
if (
|
||||
normalizedGenerationType === "normal" &&
|
||||
Number.isFinite(latestUserIndex) &&
|
||||
@@ -3064,8 +3064,8 @@ function schedulePersistedRecallMessageUiRefresh(delayMs = 0) {
|
||||
summary.status === "missing_message_anchor") &&
|
||||
attemptIndex < retryDelays.length - 1;
|
||||
|
||||
// 勿在「已成功渲染」时长期<EFBFBD><EFBFBD>?MutationObserver<EFBFBD><EFBFBD>?chat <EFBFBD><EFBFBD>?class/流式更新会疯狂触<EFBFBD><EFBFBD>?
|
||||
// runAttempt,造成满屏刷新与日志;显式事件(USER_MESSAGE_RENDERED 等)仍会 schedule 刷新<EFBFBD><EFBFBD>?
|
||||
// 勿在「已成功渲染」时长期监听 MutationObserver:chat 的 class/流式更新会疯狂触发
|
||||
// runAttempt,造成满屏刷新与日志;显式事件(USER_MESSAGE_RENDERED 等)仍会 schedule 刷新。
|
||||
const shouldWatchForRepaint = false;
|
||||
|
||||
if (!shouldRetryForPending && !shouldWatchForRepaint) {
|
||||
@@ -3515,7 +3515,7 @@ function isHostChatMetadataReady(context = getContext()) {
|
||||
}
|
||||
|
||||
const metadata = context.chatMetadata;
|
||||
// 仅接受宿主“强信号”,避免把中间<EFBFBD><EFBFBD>?占位 metadata 误判<EFBFBD><EFBFBD>?ready<EFBFBD><EFBFBD>?
|
||||
// 仅接受宿主“强信号”,避免把中间态占位 metadata 误判为 ready。
|
||||
if (hasHostMetadataReadySignal(metadata)) return true;
|
||||
|
||||
return false;
|
||||
@@ -7691,7 +7691,7 @@ function clearInjectionState(options = {}) {
|
||||
try {
|
||||
applyModuleInjectionPrompt("", getSettings());
|
||||
} catch (error) {
|
||||
console.warn("[ST-BME] 清理旧注入失<EFBFBD><EFBFBD>?", error);
|
||||
console.warn("[ST-BME] 清理旧注入失败:", error);
|
||||
}
|
||||
|
||||
refreshPanelLiveState();
|
||||
@@ -7715,7 +7715,7 @@ function notifyStatusToast(key, kind, message, title = "ST-BME") {
|
||||
function setRuntimeStatus(text, meta, level = "info") {
|
||||
runtimeStatus = createUiStatus(text, meta, level);
|
||||
refreshPanelLiveState();
|
||||
// 同步悬浮球状<EFBFBD><EFBFBD>?
|
||||
// 同步悬浮球状态
|
||||
const fabStatus = level === "info" ? "idle" : level;
|
||||
_panelModule?.updateFloatingBallStatus?.(fabStatus, text || "BME 记忆图谱");
|
||||
}
|
||||
@@ -9463,7 +9463,7 @@ function buildGenerationAfterCommandsRecallInput(type, params = {}, chat) {
|
||||
generationType,
|
||||
});
|
||||
|
||||
// 对于 history 类型(continue/regenerate/swipe),必须<EFBFBD><EFBFBD>?chat 中的用户消息
|
||||
// 对于 history 类型(continue/regenerate/swipe),必须依赖 chat 中的用户消息
|
||||
if (generationType !== "normal") {
|
||||
if (!Number.isFinite(targetUserMessageIndex)) {
|
||||
return {
|
||||
@@ -9485,10 +9485,10 @@ function buildGenerationAfterCommandsRecallInput(type, params = {}, chat) {
|
||||
};
|
||||
}
|
||||
|
||||
// 对于 normal 类型:GENERATION_AFTER_COMMANDS 触发时用户消息可能不<EFBFBD><EFBFBD>?chat 末尾
|
||||
// (ST 可能已追加空 assistant 消息)。如<EFBFBD><EFBFBD>?chat 中存在任何用户消息,
|
||||
// 继续<EFBFBD><EFBFBD>?buildNormalGenerationRecallInput,它会通过 latestUserText 兜底找到<EFBFBD><EFBFBD>?
|
||||
// 如果 chat 中完全没有用户消息,则延迟到 BEFORE_COMBINE_PROMPTS 处理<EFBFBD><EFBFBD>?
|
||||
// 对于 normal 类型:GENERATION_AFTER_COMMANDS 触发时用户消息可能不在 chat 末尾
|
||||
// (ST 可能已追加空 assistant 消息)。如果 chat 中存在任何用户消息,
|
||||
// 继续走 buildNormalGenerationRecallInput,它会通过 latestUserText 兜底找到。
|
||||
// 如果 chat 中完全没有用户消息,则延迟到 BEFORE_COMBINE_PROMPTS 处理。
|
||||
if (!Number.isFinite(targetUserMessageIndex) && !getLatestUserChatMessage(chat)) {
|
||||
return {
|
||||
generationType,
|
||||
@@ -9514,9 +9514,9 @@ function buildNormalGenerationRecallInput(chat, options = {}) {
|
||||
const tailUserText = lastNonSystemMessage?.is_user
|
||||
? normalizeRecallInputText(lastNonSystemMessage?.mes || "")
|
||||
: "";
|
||||
// <EFBFBD><EFBFBD>?GENERATION_AFTER_COMMANDS 触发时,ST 可能已追加了<EFBFBD><EFBFBD>?assistant 消息<EFBFBD><EFBFBD>?
|
||||
// 当 GENERATION_AFTER_COMMANDS 触发时,ST 可能已追加了空 assistant 消息。
|
||||
// 导致 lastNonSystemMessage 不是 user。用 getLatestUserChatMessage 反向扫描
|
||||
// 定位真正的用户消息(<EFBFBD><EFBFBD>?shujuku 参考实现一致)<EFBFBD><EFBFBD>?
|
||||
// 定位真正的用户消息(与 shujuku 参考实现一致)。
|
||||
const latestUserMessage = !tailUserText ? getLatestUserChatMessage(chat) : null;
|
||||
const latestUserText = latestUserMessage
|
||||
? normalizeRecallInputText(latestUserMessage?.mes || "")
|
||||
@@ -9851,10 +9851,10 @@ function resolveGenerationRecallDeliveryMode(
|
||||
return "immediate";
|
||||
}
|
||||
|
||||
// GENERATION_AFTER_COMMANDS: immediate —<EFBFBD><EFBFBD>?await 完召回后直接通过
|
||||
// setExtensionPrompt 注入记忆,与 shujuku 参考实现一致<EFBFBD><EFBFBD>?
|
||||
// GENERATE_BEFORE_COMBINE_PROMPTS: deferred —<EFBFBD><EFBFBD>?作为兜底,通过 promptData
|
||||
// rewrite 补救注入<EFBFBD><EFBFBD>?
|
||||
// GENERATION_AFTER_COMMANDS: immediate —— await 完召回后直接通过
|
||||
// setExtensionPrompt 注入记忆,与 shujuku 参考实现一致。
|
||||
// GENERATE_BEFORE_COMBINE_PROMPTS: deferred —— 作为兜底,通过 promptData
|
||||
// rewrite 补救注入。
|
||||
if (hookName === "GENERATE_BEFORE_COMBINE_PROMPTS") {
|
||||
return "deferred";
|
||||
}
|
||||
@@ -13292,9 +13292,9 @@ async function onRestoreCurrentChatFromCloud() {
|
||||
|
||||
if (!result?.restored) {
|
||||
const reasonMap = {
|
||||
"not-found": "服务器上没有找到当前聊天的备浠?,
|
||||
"backup-missing": "服务器上没有找到当前聊天的备浠?,
|
||||
"backup-version-mismatch": "备份版本与当前运行时不兼瀹?,
|
||||
"not-found": "服务器上没有找到当前聊天的备份",
|
||||
"backup-missing": "服务器上没有找到当前聊天的备份",
|
||||
"backup-version-mismatch": "备份版本与当前运行时不兼容",
|
||||
"backup-chat-id-mismatch": "备份聊天 ID 与当前聊天不匹配",
|
||||
"snapshot-chat-id-mismatch": "备份内部快照与当前聊天不匹配",
|
||||
};
|
||||
@@ -13376,7 +13376,7 @@ async function onDeleteServerBackupEntry(payload = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
// ==================== 初始<EFBFBD><EFBFBD>?====================
|
||||
// ==================== 恢复快照 ====================
|
||||
|
||||
async function onGetRestoreSafetySnapshotStatus() {
|
||||
const chatId = getCurrentChatId();
|
||||
@@ -13405,18 +13405,18 @@ async function onRollbackLastRestore() {
|
||||
async () => {
|
||||
const chatId = getCurrentChatId();
|
||||
if (!chatId) {
|
||||
toastr.warning("当前没有聊天上下鏂?");
|
||||
toastr.warning("当前没有聊天上下文");
|
||||
return { handledToast: true };
|
||||
}
|
||||
|
||||
const safetyStatus = await onGetRestoreSafetySnapshotStatus();
|
||||
if (!safetyStatus?.exists) {
|
||||
toastr.info("当前聊天还没有可用的上次恢复回滚鐐?");
|
||||
toastr.info("当前聊天还没有可用的上次恢复回滚点");
|
||||
return { handledToast: true, result: safetyStatus };
|
||||
}
|
||||
|
||||
const confirmed = globalThis.confirm?.(
|
||||
"这会回滚到上次从云端恢复之前的本地状态。确定继续吗锛?,
|
||||
"这会回滚到上次从云端恢复之前的本地状态。确定继续吗?",
|
||||
);
|
||||
if (!confirmed) {
|
||||
return { cancelled: true };
|
||||
@@ -13437,7 +13437,7 @@ async function onRollbackLastRestore() {
|
||||
return { handledToast: true, result };
|
||||
}
|
||||
|
||||
toastr.success("已回滚到上次恢复前的本地状鎬?");
|
||||
toastr.success("已回滚到上次恢复前的本地状态");
|
||||
await syncIndexedDbMetaToPersistenceState(chatId, {
|
||||
syncState: "idle",
|
||||
lastSyncError: "",
|
||||
@@ -13462,12 +13462,12 @@ async function onRetryPendingPersist() {
|
||||
}
|
||||
|
||||
if (!hadPending && String(result?.reason || "") === "no-pending-persist") {
|
||||
toastr.info("当前没有待确认的持久化批次");
|
||||
toastr.info("当前没有待重试的持久化批次");
|
||||
return { handledToast: true, result };
|
||||
}
|
||||
|
||||
toastr.warning(
|
||||
`持久化仍未确认: ${result?.reason || result?.loadState || "未知原因"}`,
|
||||
`重试持久化仍未成功: ${result?.reason || result?.loadState || "未知原因"}`,
|
||||
);
|
||||
return { handledToast: true, result };
|
||||
}
|
||||
@@ -13617,7 +13617,7 @@ async function onProbeGraphLoad() {
|
||||
setCoreEventBindingState,
|
||||
});
|
||||
|
||||
// 加载当前聊天的图<EFBFBD><EFBFBD>?
|
||||
// 加载当前聊天的图谱
|
||||
scheduleBmeIndexedDbTask(async () => {
|
||||
const syncResult = await syncBmeChatManagerWithCurrentChat("initial-load");
|
||||
if (!syncResult?.chatId) {
|
||||
|
||||
Reference in New Issue
Block a user