mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
Harden panel entry initialization
This commit is contained in:
108
index.js
108
index.js
@@ -11228,59 +11228,6 @@ async function onReembedDirect() {
|
||||
await loadServerSettings();
|
||||
syncGraphPersistenceDebugState();
|
||||
|
||||
ensureBmeChatManager();
|
||||
scheduleBmeIndexedDbWarmup("init");
|
||||
initializeHostCapabilityBridge();
|
||||
installSendIntentHooks();
|
||||
autoSyncOnVisibility(buildBmeSyncRuntimeOptions());
|
||||
scheduleMessageHideApply("init", 180);
|
||||
|
||||
// 注册事件钩子
|
||||
registerCoreEventHooksController({
|
||||
console,
|
||||
eventSource,
|
||||
eventTypes: event_types,
|
||||
getCoreEventBindingState,
|
||||
handlers: {
|
||||
onBeforeCombinePrompts,
|
||||
onCharacterMessageRendered,
|
||||
onChatChanged,
|
||||
onChatLoaded,
|
||||
onGenerationAfterCommands,
|
||||
onGenerationEnded,
|
||||
onGenerationStarted,
|
||||
onMessageDeleted,
|
||||
onMessageEdited,
|
||||
onMessageReceived,
|
||||
onMessageSent,
|
||||
onMessageSwiped,
|
||||
onUserMessageRendered,
|
||||
},
|
||||
registerBeforeCombinePrompts,
|
||||
registerGenerationAfterCommands,
|
||||
setCoreEventBindingState,
|
||||
});
|
||||
|
||||
// 加载当前聊天的图谱
|
||||
scheduleBmeIndexedDbTask(async () => {
|
||||
const syncResult = await syncBmeChatManagerWithCurrentChat("initial-load");
|
||||
if (!syncResult?.chatId) {
|
||||
syncGraphLoadFromLiveContext({
|
||||
source: "initial-load:no-chat",
|
||||
force: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
await runBmeAutoSyncForChat("initial-load", syncResult.chatId);
|
||||
await loadGraphFromIndexedDb(syncResult.chatId, {
|
||||
source: "initial-load",
|
||||
allowOverride: true,
|
||||
applyEmptyState: true,
|
||||
});
|
||||
});
|
||||
|
||||
// ==================== 操控面板初始化 ====================
|
||||
|
||||
await initializePanelBridgeController({
|
||||
$,
|
||||
actions: {
|
||||
@@ -11341,6 +11288,61 @@ async function onReembedDirect() {
|
||||
updateSettings: updateModuleSettings,
|
||||
});
|
||||
|
||||
try {
|
||||
ensureBmeChatManager();
|
||||
scheduleBmeIndexedDbWarmup("init");
|
||||
initializeHostCapabilityBridge();
|
||||
installSendIntentHooks();
|
||||
autoSyncOnVisibility(buildBmeSyncRuntimeOptions());
|
||||
scheduleMessageHideApply("init", 180);
|
||||
|
||||
// 注册事件钩子
|
||||
registerCoreEventHooksController({
|
||||
console,
|
||||
eventSource,
|
||||
eventTypes: event_types,
|
||||
getCoreEventBindingState,
|
||||
handlers: {
|
||||
onBeforeCombinePrompts,
|
||||
onCharacterMessageRendered,
|
||||
onChatChanged,
|
||||
onChatLoaded,
|
||||
onGenerationAfterCommands,
|
||||
onGenerationEnded,
|
||||
onGenerationStarted,
|
||||
onMessageDeleted,
|
||||
onMessageEdited,
|
||||
onMessageReceived,
|
||||
onMessageSent,
|
||||
onMessageSwiped,
|
||||
onUserMessageRendered,
|
||||
},
|
||||
registerBeforeCombinePrompts,
|
||||
registerGenerationAfterCommands,
|
||||
setCoreEventBindingState,
|
||||
});
|
||||
|
||||
// 加载当前聊天的图谱
|
||||
scheduleBmeIndexedDbTask(async () => {
|
||||
const syncResult = await syncBmeChatManagerWithCurrentChat("initial-load");
|
||||
if (!syncResult?.chatId) {
|
||||
syncGraphLoadFromLiveContext({
|
||||
source: "initial-load:no-chat",
|
||||
force: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
await runBmeAutoSyncForChat("initial-load", syncResult.chatId);
|
||||
await loadGraphFromIndexedDb(syncResult.chatId, {
|
||||
source: "initial-load",
|
||||
allowOverride: true,
|
||||
applyEmptyState: true,
|
||||
});
|
||||
});
|
||||
} catch (bootError) {
|
||||
console.error("[ST-BME] 核心初始化阶段失败(面板入口已保留):", bootError);
|
||||
}
|
||||
|
||||
schedulePersistedRecallMessageUiRefresh(120);
|
||||
try {
|
||||
const { initEnaPlanner } = await import("./ena-planner/ena-planner.js");
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { debugLog } from "../runtime/debug-logging.js";
|
||||
|
||||
const MENU_ENTRY_RETRY_MS = 400;
|
||||
const MENU_ENTRY_MAX_ATTEMPTS = 30;
|
||||
|
||||
function resolvePanelTheme(settings) {
|
||||
return settings?.panelTheme || "crimson";
|
||||
}
|
||||
@@ -25,7 +28,7 @@ export function openPanelController(runtime) {
|
||||
|
||||
function injectOptionsMenuEntry(runtime) {
|
||||
if (runtime.document.getElementById("option_st_bme_panel")) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
const $menuItem = runtime.$(`
|
||||
@@ -33,7 +36,8 @@ function injectOptionsMenuEntry(runtime) {
|
||||
<i class="fa-lg fa-solid fa-brain"></i>
|
||||
<span>记忆图谱</span>
|
||||
</a>
|
||||
`).on("click", () => {
|
||||
`).on("click", async () => {
|
||||
await ensurePanelBridgeReady(runtime);
|
||||
openPanelController(runtime);
|
||||
runtime.$("#options").hide();
|
||||
});
|
||||
@@ -43,48 +47,82 @@ function injectOptionsMenuEntry(runtime) {
|
||||
|
||||
if ($anchor.length > 0) {
|
||||
$anchor.after($menuItem);
|
||||
return true;
|
||||
} else if ($optionsContent.length > 0) {
|
||||
$optionsContent.append($menuItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function scheduleOptionsMenuInjection(runtime, attempt = 0) {
|
||||
if (injectOptionsMenuEntry(runtime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attempt >= MENU_ENTRY_MAX_ATTEMPTS) {
|
||||
runtime.console.warn(
|
||||
"[ST-BME] 操控面板菜单入口注入失败:宿主 options DOM 长时间未就绪",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
globalThis.setTimeout(() => {
|
||||
scheduleOptionsMenuInjection(runtime, attempt + 1);
|
||||
}, MENU_ENTRY_RETRY_MS);
|
||||
}
|
||||
|
||||
async function ensurePanelBridgeReady(runtime) {
|
||||
const hasPanelDom = Boolean(
|
||||
runtime.document.getElementById("st-bme-panel-overlay") &&
|
||||
runtime.document.getElementById("st-bme-panel"),
|
||||
);
|
||||
if (runtime.getPanelModule()?.openPanel && hasPanelDom) {
|
||||
return runtime.getPanelModule();
|
||||
}
|
||||
|
||||
const panelModule = await runtime.importPanelModule();
|
||||
const themesModule = await runtime.importThemesModule();
|
||||
runtime.setPanelModule(panelModule);
|
||||
runtime.setThemesModule(themesModule);
|
||||
|
||||
const settings = runtime.getSettings();
|
||||
const theme = resolvePanelTheme(settings);
|
||||
themesModule.applyTheme(theme);
|
||||
|
||||
await panelModule.initPanel({
|
||||
getGraph: runtime.getGraph,
|
||||
getSettings: runtime.getSettings,
|
||||
getLastExtract: runtime.getLastExtract,
|
||||
getLastRecall: runtime.getLastRecall,
|
||||
getRuntimeStatus: runtime.getRuntimeStatus,
|
||||
getLastExtractionStatus: runtime.getLastExtractionStatus,
|
||||
getLastVectorStatus: runtime.getLastVectorStatus,
|
||||
getLastRecallStatus: runtime.getLastRecallStatus,
|
||||
getLastBatchStatus: runtime.getLastBatchStatus,
|
||||
getLastInjection: runtime.getLastInjection,
|
||||
getRuntimeDebugSnapshot: runtime.getRuntimeDebugSnapshot,
|
||||
getGraphPersistenceState: runtime.getGraphPersistenceState,
|
||||
updateSettings: (patch) => {
|
||||
const nextSettings = runtime.updateSettings(patch);
|
||||
if (Object.prototype.hasOwnProperty.call(patch || {}, "panelTheme")) {
|
||||
const nextTheme = resolvePanelTheme(nextSettings);
|
||||
runtime.getThemesModule()?.applyTheme?.(nextTheme);
|
||||
runtime.getPanelModule()?.updatePanelTheme?.(nextTheme);
|
||||
}
|
||||
return nextSettings;
|
||||
},
|
||||
actions: runtime.actions,
|
||||
});
|
||||
|
||||
return panelModule;
|
||||
}
|
||||
|
||||
export async function initializePanelBridgeController(runtime) {
|
||||
try {
|
||||
const panelModule = await runtime.importPanelModule();
|
||||
const themesModule = await runtime.importThemesModule();
|
||||
runtime.setPanelModule(panelModule);
|
||||
runtime.setThemesModule(themesModule);
|
||||
|
||||
const settings = runtime.getSettings();
|
||||
const theme = resolvePanelTheme(settings);
|
||||
themesModule.applyTheme(theme);
|
||||
|
||||
await panelModule.initPanel({
|
||||
getGraph: runtime.getGraph,
|
||||
getSettings: runtime.getSettings,
|
||||
getLastExtract: runtime.getLastExtract,
|
||||
getLastRecall: runtime.getLastRecall,
|
||||
getRuntimeStatus: runtime.getRuntimeStatus,
|
||||
getLastExtractionStatus: runtime.getLastExtractionStatus,
|
||||
getLastVectorStatus: runtime.getLastVectorStatus,
|
||||
getLastRecallStatus: runtime.getLastRecallStatus,
|
||||
getLastBatchStatus: runtime.getLastBatchStatus,
|
||||
getLastInjection: runtime.getLastInjection,
|
||||
getRuntimeDebugSnapshot: runtime.getRuntimeDebugSnapshot,
|
||||
getGraphPersistenceState: runtime.getGraphPersistenceState,
|
||||
updateSettings: (patch) => {
|
||||
const nextSettings = runtime.updateSettings(patch);
|
||||
if (Object.prototype.hasOwnProperty.call(patch || {}, "panelTheme")) {
|
||||
const nextTheme = resolvePanelTheme(nextSettings);
|
||||
runtime.getThemesModule()?.applyTheme?.(nextTheme);
|
||||
runtime.getPanelModule()?.updatePanelTheme?.(nextTheme);
|
||||
}
|
||||
return nextSettings;
|
||||
},
|
||||
actions: runtime.actions,
|
||||
});
|
||||
|
||||
injectOptionsMenuEntry(runtime);
|
||||
scheduleOptionsMenuInjection(runtime);
|
||||
await ensurePanelBridgeReady(runtime);
|
||||
debugLog("[ST-BME] 操控面板初始化完成");
|
||||
} catch (panelError) {
|
||||
runtime.console.error(
|
||||
|
||||
@@ -254,7 +254,7 @@ function mountPanelHtml(html) {
|
||||
}
|
||||
|
||||
if (document.body?.insertAdjacentHTML) {
|
||||
document.body.insertAdjacentHTML("beforebegin", markup);
|
||||
document.body.insertAdjacentHTML("beforeend", markup);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user