mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
Add debug log toggle and silence diagnostic logs
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// ST-BME: 层级压缩引擎
|
||||
// 超过阈值的节点被 LLM 总结为更高层级的压缩节点
|
||||
|
||||
import { debugLog } from "./debug-logging.js";
|
||||
import { embedText } from "./embedding.js";
|
||||
import {
|
||||
addEdge,
|
||||
@@ -517,7 +518,7 @@ export function sleepCycle(graph, settings) {
|
||||
}
|
||||
|
||||
if (forgotten > 0) {
|
||||
console.log(`[ST-BME] 主动遗忘: ${forgotten} 个低价值节点已归档`);
|
||||
debugLog(`[ST-BME] 主动遗忘: ${forgotten} 个低价值节点已归档`);
|
||||
}
|
||||
|
||||
return { forgotten };
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 合并 Mem0 精确对照 + A-MEM 记忆进化为单一阶段
|
||||
// 批量 embed + 批量查近邻 + 单次 LLM 调用
|
||||
|
||||
import { debugLog } from "./debug-logging.js";
|
||||
import { embedBatch, searchSimilar } from "./embedding.js";
|
||||
import { addEdge, createEdge, getActiveNodes, getNode } from "./graph.js";
|
||||
import { callLLMForJSON } from "./llm.js";
|
||||
@@ -301,7 +302,7 @@ export async function consolidateMemories({
|
||||
|
||||
if (!newNodeIds || newNodeIds.length === 0) return stats;
|
||||
if (!validateVectorConfig(embeddingConfig).valid) {
|
||||
console.log("[ST-BME] 记忆整合跳过:向量配置不可用");
|
||||
debugLog("[ST-BME] 记忆整合跳过:向量配置不可用");
|
||||
return stats;
|
||||
}
|
||||
|
||||
@@ -331,7 +332,7 @@ export async function consolidateMemories({
|
||||
}
|
||||
|
||||
throwIfAborted(signal);
|
||||
console.log(`[ST-BME] 记忆整合开始: ${newEntries.length} 个新节点`);
|
||||
debugLog(`[ST-BME] 记忆整合开始: ${newEntries.length} 个新节点`);
|
||||
|
||||
// ══════════════════════════════════════════════
|
||||
// Phase 1 + 2: 批量 Embed + 查近邻
|
||||
@@ -571,7 +572,7 @@ export async function consolidateMemories({
|
||||
if (stats.updates > 0) actionSummary.push(`回溯更新 ${stats.updates}`);
|
||||
|
||||
if (actionSummary.length > 0) {
|
||||
console.log(`[ST-BME] 记忆整合完成: ${actionSummary.join(", ")}`);
|
||||
debugLog(`[ST-BME] 记忆整合完成: ${actionSummary.join(", ")}`);
|
||||
}
|
||||
|
||||
return stats;
|
||||
@@ -586,7 +587,7 @@ function processOneResult(graph, entry, result, stats) {
|
||||
// ── 处理 action ──
|
||||
switch (result.action) {
|
||||
case "skip": {
|
||||
console.log(`[ST-BME] 记忆整合: skip (重复) — ${newId}`);
|
||||
debugLog(`[ST-BME] 记忆整合: skip (重复) — ${newId}`);
|
||||
newNode.archived = true;
|
||||
stats.skipped++;
|
||||
break;
|
||||
@@ -601,7 +602,7 @@ function processOneResult(graph, entry, result, stats) {
|
||||
!targetNode.archived &&
|
||||
canMergeScopedMemories(newNode, targetNode)
|
||||
) {
|
||||
console.log(`[ST-BME] 记忆整合: merge ${newId} → ${targetId}`);
|
||||
debugLog(`[ST-BME] 记忆整合: merge ${newId} → ${targetId}`);
|
||||
|
||||
if (result.merged_fields && typeof result.merged_fields === "object") {
|
||||
for (const [key, value] of Object.entries(result.merged_fields)) {
|
||||
@@ -658,7 +659,7 @@ function processOneResult(graph, entry, result, stats) {
|
||||
const evolution = result.evolution;
|
||||
if (evolution?.should_evolve && !newNode.archived) {
|
||||
stats.evolved++;
|
||||
console.log(`[ST-BME] 记忆整合/进化触发: ${result.reason || "(无理由)"}`);
|
||||
debugLog(`[ST-BME] 记忆整合/进化触发: ${result.reason || "(无理由)"}`);
|
||||
|
||||
if (Array.isArray(evolution.connections)) {
|
||||
for (const targetId of evolution.connections) {
|
||||
|
||||
59
debug-logging.js
Normal file
59
debug-logging.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const MODULE_NAME = "st_bme";
|
||||
const GLOBAL_DEBUG_FLAG_KEY = "__stBmeDebugLoggingEnabled";
|
||||
|
||||
function resolveModuleSettings(settings = null) {
|
||||
if (settings && typeof settings === "object") {
|
||||
return settings;
|
||||
}
|
||||
|
||||
const moduleSettings =
|
||||
globalThis?.extension_settings?.[MODULE_NAME] ||
|
||||
globalThis?.__p0ExtensionSettings?.[MODULE_NAME] ||
|
||||
globalThis?.SillyTavern?.getContext?.()?.extensionSettings?.[MODULE_NAME] ||
|
||||
null;
|
||||
return moduleSettings && typeof moduleSettings === "object"
|
||||
? moduleSettings
|
||||
: null;
|
||||
}
|
||||
|
||||
export function isDebugLoggingEnabled(settings = null) {
|
||||
if (
|
||||
settings &&
|
||||
typeof settings === "object" &&
|
||||
Object.prototype.hasOwnProperty.call(settings, "debugLoggingEnabled")
|
||||
) {
|
||||
return Boolean(settings.debugLoggingEnabled);
|
||||
}
|
||||
|
||||
if (typeof globalThis[GLOBAL_DEBUG_FLAG_KEY] === "boolean") {
|
||||
return globalThis[GLOBAL_DEBUG_FLAG_KEY];
|
||||
}
|
||||
|
||||
return Boolean(resolveModuleSettings(settings)?.debugLoggingEnabled);
|
||||
}
|
||||
|
||||
function emitDebugLog(method, args, settings = null) {
|
||||
if (!isDebugLoggingEnabled(settings)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target =
|
||||
typeof console?.[method] === "function" ? console[method] : console.log;
|
||||
Reflect.apply(target, console, args);
|
||||
}
|
||||
|
||||
export function debugLog(...args) {
|
||||
emitDebugLog("log", args);
|
||||
}
|
||||
|
||||
export function debugInfo(...args) {
|
||||
emitDebugLog("info", args);
|
||||
}
|
||||
|
||||
export function debugWarn(...args) {
|
||||
emitDebugLog("warn", args);
|
||||
}
|
||||
|
||||
export function debugDebug(...args) {
|
||||
emitDebugLog("debug", args);
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { extension_settings } from '../../../../extensions.js';
|
||||
import { getRequestHeaders, saveSettingsDebounced, substituteParamsExtended } from '../../../../../script.js';
|
||||
import { EnaPlannerStorage, migrateFromLWBIfNeeded } from './ena-planner-storage.js';
|
||||
import { DEFAULT_PROMPT_BLOCKS, BUILTIN_TEMPLATES } from './ena-planner-presets.js';
|
||||
import { debugLog } from '../debug-logging.js';
|
||||
import jsyaml from '../vendor/js-yaml.mjs';
|
||||
|
||||
const EXT_NAME = 'ena-planner';
|
||||
@@ -199,7 +200,7 @@ async function saveConfigNow() {
|
||||
|
||||
function toastInfo(msg) {
|
||||
if (window.toastr?.info) return window.toastr.info(msg);
|
||||
console.log('[EnaPlanner]', msg);
|
||||
debugLog('[EnaPlanner]', msg);
|
||||
}
|
||||
function toastErr(msg) {
|
||||
if (window.toastr?.error) return window.toastr.error(msg);
|
||||
@@ -505,7 +506,7 @@ async function getCharacterWorldbooks() {
|
||||
}
|
||||
} catch { }
|
||||
|
||||
console.log('[EnaPlanner] Character worldbook names found:', worldNames);
|
||||
debugLog('[EnaPlanner] Character worldbook names found:', worldNames);
|
||||
return worldNames.filter(Boolean);
|
||||
}
|
||||
|
||||
@@ -618,11 +619,11 @@ async function buildWorldbookBlock(scanText) {
|
||||
const allWorldNames = [...new Set([...charWorldNames, ...globalWorldNames])];
|
||||
|
||||
if (!allWorldNames.length) {
|
||||
console.log('[EnaPlanner] No worldbooks to load');
|
||||
debugLog('[EnaPlanner] No worldbooks to load');
|
||||
return '';
|
||||
}
|
||||
|
||||
console.log('[EnaPlanner] Loading worldbooks:', allWorldNames);
|
||||
debugLog('[EnaPlanner] Loading worldbooks:', allWorldNames);
|
||||
|
||||
// Fetch all worldbook data
|
||||
const worldbookResults = await Promise.all(allWorldNames.map(name => getWorldbookData(name)));
|
||||
@@ -1155,7 +1156,7 @@ async function buildPlannerMessages(rawUserInput) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
}
|
||||
console.log(`[Ena] Memory source: ${memorySource}`);
|
||||
debugLog(`[Ena] Memory source: ${memorySource}`);
|
||||
|
||||
// --- Chat history: last 2 AI messages (floors N-1 & N-3) ---
|
||||
// Two messages instead of one to avoid cross-device cache miss:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { debugWarn } from "./debug-logging.js";
|
||||
|
||||
function getTimerApi(runtime) {
|
||||
const rawSetTimeout =
|
||||
typeof runtime?.setTimeout === "function"
|
||||
@@ -38,14 +40,14 @@ export function registerBeforeCombinePromptsController(runtime, listener) {
|
||||
export function registerGenerationAfterCommandsController(runtime, listener) {
|
||||
const makeFirst = runtime.getEventMakeFirst();
|
||||
const eventName = runtime.eventTypes.GENERATION_AFTER_COMMANDS;
|
||||
console.warn("[ST-BME:DIAG] Registering GENERATION_AFTER_COMMANDS:", {
|
||||
debugWarn("[ST-BME:DIAG] Registering GENERATION_AFTER_COMMANDS:", {
|
||||
eventName,
|
||||
hasMakeFirst: typeof makeFirst === "function",
|
||||
hasListener: typeof listener === "function",
|
||||
});
|
||||
if (typeof makeFirst === "function") {
|
||||
const cleanup = makeFirst(eventName, listener);
|
||||
console.warn("[ST-BME:DIAG] Registered via makeFirst, cleanup:", typeof cleanup);
|
||||
debugWarn("[ST-BME:DIAG] Registered via makeFirst, cleanup:", typeof cleanup);
|
||||
return cleanup;
|
||||
}
|
||||
|
||||
@@ -406,9 +408,9 @@ export async function onGenerationAfterCommandsController(
|
||||
params = {},
|
||||
dryRun = false,
|
||||
) {
|
||||
console.warn("[ST-BME:DIAG] GENERATION_AFTER_COMMANDS fired", { type, dryRun, paramsKeys: Object.keys(params || {}) });
|
||||
debugWarn("[ST-BME:DIAG] GENERATION_AFTER_COMMANDS fired", { type, dryRun, paramsKeys: Object.keys(params || {}) });
|
||||
if (dryRun) {
|
||||
console.warn("[ST-BME:DIAG] EXIT: dryRun=true");
|
||||
debugWarn("[ST-BME:DIAG] EXIT: dryRun=true");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -418,11 +420,11 @@ export async function onGenerationAfterCommandsController(
|
||||
? runtime.consumeHostGenerationInputSnapshot?.({ preserve: true }) ||
|
||||
runtime.consumeHostGenerationInputSnapshot?.()
|
||||
: null;
|
||||
console.warn("[ST-BME:DIAG] frozenInputSnapshot:", frozenInputSnapshot?.text ? `"${frozenInputSnapshot.text.slice(0,50)}"` : "(empty)", "fresh:", !!frozenInputSnapshot?.at);
|
||||
debugWarn("[ST-BME:DIAG] frozenInputSnapshot:", frozenInputSnapshot?.text ? `"${frozenInputSnapshot.text.slice(0,50)}"` : "(empty)", "fresh:", !!frozenInputSnapshot?.at);
|
||||
|
||||
const context = runtime.getContext();
|
||||
const chat = context?.chat;
|
||||
console.warn("[ST-BME:DIAG] chat length:", chat?.length, "last msg:", chat?.length ? { is_user: chat[chat.length-1]?.is_user, mes: (chat[chat.length-1]?.mes||"").slice(0,50) } : "(no chat)");
|
||||
debugWarn("[ST-BME:DIAG] chat length:", chat?.length, "last msg:", chat?.length ? { is_user: chat[chat.length-1]?.is_user, mes: (chat[chat.length-1]?.mes||"").slice(0,50) } : "(no chat)");
|
||||
|
||||
const recallOptions = runtime.buildGenerationAfterCommandsRecallInput(
|
||||
type,
|
||||
@@ -433,14 +435,14 @@ export async function onGenerationAfterCommandsController(
|
||||
chat,
|
||||
);
|
||||
if (!recallOptions) {
|
||||
console.warn("[ST-BME:DIAG] EXIT: buildGenerationAfterCommandsRecallInput returned null");
|
||||
debugWarn("[ST-BME:DIAG] EXIT: buildGenerationAfterCommandsRecallInput returned null");
|
||||
return;
|
||||
}
|
||||
if (recallOptions?.__trivialSkip) {
|
||||
console.warn("[ST-BME:DIAG] EXIT: trivial-input-skip");
|
||||
debugWarn("[ST-BME:DIAG] EXIT: trivial-input-skip");
|
||||
return;
|
||||
}
|
||||
console.warn("[ST-BME:DIAG] recallOptions:", { generationType: recallOptions.generationType, overrideUserMessage: recallOptions.overrideUserMessage?.slice(0,50), overrideSource: recallOptions.overrideSource, targetIdx: recallOptions.targetUserMessageIndex });
|
||||
debugWarn("[ST-BME:DIAG] recallOptions:", { generationType: recallOptions.generationType, overrideUserMessage: recallOptions.overrideUserMessage?.slice(0,50), overrideSource: recallOptions.overrideSource, targetIdx: recallOptions.targetUserMessageIndex });
|
||||
|
||||
const recallContext = runtime.createGenerationRecallContext({
|
||||
hookName: "GENERATION_AFTER_COMMANDS",
|
||||
@@ -448,10 +450,10 @@ export async function onGenerationAfterCommandsController(
|
||||
recallOptions,
|
||||
});
|
||||
if (!recallContext.shouldRun && !recallContext.transaction) {
|
||||
console.warn("[ST-BME:DIAG] EXIT: shouldRun=false, no transaction. guardReason:", recallContext.guardReason);
|
||||
debugWarn("[ST-BME:DIAG] EXIT: shouldRun=false, no transaction. guardReason:", recallContext.guardReason);
|
||||
return;
|
||||
}
|
||||
console.warn("[ST-BME:DIAG] recallContext:", { shouldRun: recallContext.shouldRun, guardReason: recallContext.guardReason, transactionId: recallContext.transaction?.id });
|
||||
debugWarn("[ST-BME:DIAG] recallContext:", { shouldRun: recallContext.shouldRun, guardReason: recallContext.guardReason, transactionId: recallContext.transaction?.id });
|
||||
|
||||
const runtimeRecallOptions =
|
||||
recallContext.recallOptions || recallOptions || {};
|
||||
@@ -464,7 +466,7 @@ export async function onGenerationAfterCommandsController(
|
||||
let recallResult = runtime.getGenerationRecallTransactionResult?.(
|
||||
recallContext.transaction,
|
||||
);
|
||||
console.warn("[ST-BME:DIAG] deliveryMode:", deliveryMode, "shouldRun:", recallContext.shouldRun);
|
||||
debugWarn("[ST-BME:DIAG] deliveryMode:", deliveryMode, "shouldRun:", recallContext.shouldRun);
|
||||
|
||||
if (recallContext.shouldRun) {
|
||||
runtime.markGenerationRecallTransactionHookState(
|
||||
@@ -475,7 +477,7 @@ export async function onGenerationAfterCommandsController(
|
||||
if (deliveryMode === "deferred") {
|
||||
runtime.clearLiveRecallInjectionPromptForRewrite?.();
|
||||
}
|
||||
console.warn("[ST-BME:DIAG] >>> Starting runRecall...");
|
||||
debugWarn("[ST-BME:DIAG] >>> Starting runRecall...");
|
||||
recallResult = await runtime.runRecall({
|
||||
...runtimeRecallOptions,
|
||||
deliveryMode,
|
||||
@@ -483,7 +485,7 @@ export async function onGenerationAfterCommandsController(
|
||||
hookName: recallContext.hookName,
|
||||
signal: params?.signal,
|
||||
});
|
||||
console.warn("[ST-BME:DIAG] <<< runRecall finished:", { status: recallResult?.status, ok: recallResult?.ok, reason: recallResult?.reason, injectionText: recallResult?.injectionText?.slice(0,80) });
|
||||
debugWarn("[ST-BME:DIAG] <<< runRecall finished:", { status: recallResult?.status, ok: recallResult?.ok, reason: recallResult?.reason, injectionText: recallResult?.injectionText?.slice(0,80) });
|
||||
runtime.storeGenerationRecallTransactionResult?.(
|
||||
recallContext.transaction,
|
||||
recallResult,
|
||||
@@ -516,7 +518,7 @@ export async function onGenerationAfterCommandsController(
|
||||
// 上面的兜底补写会把 fresh recall 绑定回最终 user 楼层。
|
||||
// 这里再补一次 UI 刷新,避免需要等到消息编辑/历史恢复后才看到 Recall Card。
|
||||
runtime.refreshPersistedRecallMessageUi?.();
|
||||
console.warn("[ST-BME:DIAG] DONE: immediate mode, injection via setExtensionPrompt in runRecall");
|
||||
debugWarn("[ST-BME:DIAG] DONE: immediate mode, injection via setExtensionPrompt in runRecall");
|
||||
return recallResult;
|
||||
}
|
||||
|
||||
@@ -550,7 +552,7 @@ export async function onBeforeCombinePromptsController(
|
||||
frozenInputSnapshot,
|
||||
});
|
||||
if (normalInput?.__trivialSkip) {
|
||||
console.warn("[ST-BME:DIAG] EXIT: trivial-input-skip");
|
||||
debugWarn("[ST-BME:DIAG] EXIT: trivial-input-skip");
|
||||
return {
|
||||
skipped: true,
|
||||
reason: `trivial:${normalInput.trivialReason || ""}`,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// ST-BME: 提取编排控制器(纯函数)
|
||||
// 通过 runtime 依赖注入,避免直接访问 index.js 模块级状态。
|
||||
|
||||
import { debugLog } from "./debug-logging.js";
|
||||
|
||||
export async function executeExtractionBatchController(
|
||||
runtime,
|
||||
{
|
||||
@@ -25,7 +27,7 @@ export async function executeExtractionBatchController(
|
||||
extractionCountBefore,
|
||||
});
|
||||
|
||||
runtime.console.log(
|
||||
debugLog(
|
||||
`[ST-BME] 开始提取: 楼层 ${startIdx}-${endIdx}` +
|
||||
(smartTriggerDecision?.triggered
|
||||
? ` [智能触发 score=${smartTriggerDecision.score}; ${smartTriggerDecision.reasons.join(" / ")}]`
|
||||
@@ -504,7 +506,7 @@ export async function onRerollController(runtime, { fromFloor } = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
runtime.console.log(`[ST-BME] 重 Roll 开始,目标楼层: ${targetFloor}`);
|
||||
debugLog(`[ST-BME] 重 Roll 开始,目标楼层: ${targetFloor}`);
|
||||
let rollbackResult;
|
||||
try {
|
||||
rollbackResult = await runtime.rollbackGraphForReroll(targetFloor, context);
|
||||
|
||||
19
extractor.js
19
extractor.js
@@ -3,6 +3,7 @@
|
||||
// v2: 融合 Mem0 精确对照 + Graphiti 时序边 + MemoRAG 全局概要
|
||||
|
||||
import { embedBatch } from "./embedding.js";
|
||||
import { debugLog, debugWarn } from "./debug-logging.js";
|
||||
import {
|
||||
addEdge,
|
||||
addNode,
|
||||
@@ -345,7 +346,7 @@ export async function extractMemories({
|
||||
activeUserOwner: stContext?.prompt?.userName || "",
|
||||
};
|
||||
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME] 提取开始: chat[${effectiveStartSeq}..${effectiveEndSeq}], ${messages.length} 条消息`,
|
||||
);
|
||||
|
||||
@@ -416,7 +417,7 @@ export async function extractMemories({
|
||||
const pm = Array.isArray(promptPayload.promptMessages) ? promptPayload.promptMessages : [];
|
||||
const pmUser = pm.filter((m) => m?.role === "user");
|
||||
const am = Array.isArray(promptPayload.additionalMessages) ? promptPayload.additionalMessages : [];
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] resolveTaskPromptPayload: ` +
|
||||
`promptMessages=${pm.length} (user=${pmUser.length}), ` +
|
||||
`additionalMessages=${am.length}, ` +
|
||||
@@ -426,13 +427,13 @@ export async function extractMemories({
|
||||
);
|
||||
if (pmUser.length > 0) {
|
||||
for (const m of pmUser) {
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] user msg: contentLen=${String(m.content || "").length}, ` +
|
||||
`blockName="${m.blockName || ""}", preview="${String(m.content || "").slice(0, 60)}..."`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.warn(
|
||||
debugWarn(
|
||||
`[ST-BME][prompt-diag] NO user messages in promptMessages! Fallback userPrompt will be used.`,
|
||||
);
|
||||
}
|
||||
@@ -537,7 +538,7 @@ export async function extractMemories({
|
||||
);
|
||||
updateRuntimeScopeState(graph, newNodeIds, scopeRuntime);
|
||||
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME] 提取完成: 新建 ${stats.newNodes}, 更新 ${stats.updatedNodes}, 新边 ${stats.newEdges}, lastProcessedSeq=${graph.lastProcessedSeq}`,
|
||||
);
|
||||
|
||||
@@ -863,7 +864,7 @@ async function generateNodeEmbeddings(graph, embeddingConfig, signal) {
|
||||
(node) => buildNodeVectorText(node) || node.type,
|
||||
);
|
||||
|
||||
console.log(`[ST-BME] 为 ${texts.length} 个节点生成 embedding`);
|
||||
debugLog(`[ST-BME] 为 ${texts.length} 个节点生成 embedding`);
|
||||
|
||||
const embeddings = await embedBatch(texts, embeddingConfig, { signal });
|
||||
|
||||
@@ -1089,7 +1090,7 @@ export async function generateSynopsis({
|
||||
Math.max(existingSynopsis.seqRange?.[1] ?? currentSeq, currentSeq),
|
||||
];
|
||||
existingSynopsis.embedding = null;
|
||||
console.log("[ST-BME] 全局概要已更新");
|
||||
debugLog("[ST-BME] 全局概要已更新");
|
||||
} else {
|
||||
const node = createNode({
|
||||
type: "synopsis",
|
||||
@@ -1098,7 +1099,7 @@ export async function generateSynopsis({
|
||||
importance: 9.0,
|
||||
});
|
||||
addNode(graph, node);
|
||||
console.log("[ST-BME] 全局概要已创建");
|
||||
debugLog("[ST-BME] 全局概要已创建");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1238,6 +1239,6 @@ export async function generateReflection({
|
||||
addEdge(graph, edge);
|
||||
}
|
||||
|
||||
console.log("[ST-BME] 反思条目已生成");
|
||||
debugLog("[ST-BME] 反思条目已生成");
|
||||
return reflectionNode.id;
|
||||
}
|
||||
|
||||
3
graph.js
3
graph.js
@@ -14,6 +14,7 @@ import {
|
||||
normalizeNodeMemoryScope,
|
||||
isSameLatestScopeBucket,
|
||||
} from "./memory-scope.js";
|
||||
import { debugLog } from "./debug-logging.js";
|
||||
|
||||
/**
|
||||
* 图状态版本号
|
||||
@@ -546,7 +547,7 @@ export function deserializeGraph(json) {
|
||||
}
|
||||
|
||||
if (data.version < GRAPH_VERSION) {
|
||||
console.log(`[ST-BME] 图版本迁移 v${data.version} → v${GRAPH_VERSION}`);
|
||||
debugLog(`[ST-BME] 图版本迁移 v${data.version} → v${GRAPH_VERSION}`);
|
||||
|
||||
if (data.version < 2 && data.edges) {
|
||||
for (const edge of data.edges) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { getContext as extensionGetContext } from "../../../../extensions.js";
|
||||
|
||||
import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js";
|
||||
import { debugDebug } from "../debug-logging.js";
|
||||
|
||||
function resolveContextGetter(providedGetter = null) {
|
||||
if (typeof providedGetter === "function") {
|
||||
@@ -55,7 +56,7 @@ export function createContextHostFacade(options = {}) {
|
||||
try {
|
||||
return getContext(...args);
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
"[ST-BME] host-adapter/context getContext 调用失败",
|
||||
error,
|
||||
);
|
||||
@@ -71,7 +72,7 @@ export function createContextHostFacade(options = {}) {
|
||||
const context = getContext(...args);
|
||||
return context && typeof context === "object" ? context : null;
|
||||
} catch (error) {
|
||||
console.debug("[ST-BME] host-adapter/context 读取上下文失败", error);
|
||||
debugDebug("[ST-BME] host-adapter/context 读取上下文失败", error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js";
|
||||
import { createContextHostFacade } from "./context.js";
|
||||
import { debugDebug } from "../debug-logging.js";
|
||||
|
||||
function resolvePromptSetter(providedSetter = null, contextHost = null) {
|
||||
if (typeof providedSetter === "function") {
|
||||
@@ -75,7 +76,7 @@ export function createInjectionHostFacade(options = {}) {
|
||||
liveSetterRecord.setter(...args);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
"[ST-BME] host-adapter/injection setExtensionPrompt 调用失败",
|
||||
error,
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js";
|
||||
import { createContextHostFacade } from "./context.js";
|
||||
import { debugDebug } from "../debug-logging.js";
|
||||
|
||||
const REGEX_API_NAMES = ["getTavernRegexes", "isCharacterTavernRegexesEnabled"];
|
||||
|
||||
@@ -36,7 +37,7 @@ function resolveProviderCandidate(candidate, options = {}) {
|
||||
const resolved = candidate(options);
|
||||
return isObjectLike(resolved) ? resolved : null;
|
||||
} catch (error) {
|
||||
console.debug("[ST-BME] host-adapter/regex provider 解析失败", error);
|
||||
debugDebug("[ST-BME] host-adapter/regex provider 解析失败", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { buildCapabilityStatus, mergeVersionHints } from "./capabilities.js";
|
||||
import { createContextHostFacade } from "./context.js";
|
||||
import { debugDebug } from "../debug-logging.js";
|
||||
|
||||
const WORLDBOOK_API_NAMES = [
|
||||
"getWorldbook",
|
||||
@@ -40,7 +41,7 @@ function resolveProviderCandidate(candidate, options = {}) {
|
||||
const resolved = candidate(options);
|
||||
return isObjectLike(resolved) ? resolved : null;
|
||||
} catch (error) {
|
||||
console.debug("[ST-BME] host-adapter/worldbook provider 解析失败", error);
|
||||
debugDebug("[ST-BME] host-adapter/worldbook provider 解析失败", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
41
index.js
41
index.js
@@ -72,6 +72,10 @@ import {
|
||||
onRerollController,
|
||||
runExtractionController,
|
||||
} from "./extraction-controller.js";
|
||||
import {
|
||||
debugDebug,
|
||||
debugLog,
|
||||
} from "./debug-logging.js";
|
||||
import {
|
||||
extractMemories,
|
||||
generateReflection,
|
||||
@@ -371,6 +375,7 @@ function readRuntimeDebugSnapshot() {
|
||||
|
||||
const defaultSettings = {
|
||||
enabled: true,
|
||||
debugLoggingEnabled: false,
|
||||
timeoutMs: 300000,
|
||||
hideOldMessagesEnabled: false,
|
||||
hideOldMessagesKeepLastN: 12,
|
||||
@@ -1486,6 +1491,7 @@ function getMessageRecallRecord(messageIndex) {
|
||||
}
|
||||
|
||||
function debugWithThrottle(cache, key, ...args) {
|
||||
if (!globalThis.__stBmeDebugLoggingEnabled) return;
|
||||
const now = Date.now();
|
||||
const lastAt = cache.get(key) || 0;
|
||||
if (now - lastAt < PERSISTED_RECALL_UI_DIAGNOSTIC_THROTTLE_MS) return;
|
||||
@@ -2952,6 +2958,9 @@ function getSettings() {
|
||||
mergedSettings.taskProfilesVersion = migrated.taskProfilesVersion;
|
||||
mergedSettings.taskProfiles = migrated.taskProfiles;
|
||||
extension_settings[MODULE_NAME] = mergedSettings;
|
||||
globalThis.__stBmeDebugLoggingEnabled = Boolean(
|
||||
mergedSettings.debugLoggingEnabled,
|
||||
);
|
||||
return mergedSettings;
|
||||
}
|
||||
|
||||
@@ -2989,7 +2998,7 @@ async function applyMessageHideNow(reason = "manual-apply") {
|
||||
getMessageHideSettings(),
|
||||
getHideRuntimeAdapters(),
|
||||
);
|
||||
console.log("[ST-BME] 已应用旧楼层隐藏:", reason, result);
|
||||
debugLog("[ST-BME] 已应用旧楼层隐藏:", reason, result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.warn("[ST-BME] 应用旧楼层隐藏失败:", reason, error);
|
||||
@@ -3019,7 +3028,7 @@ async function runIncrementalMessageHide(reason = "incremental") {
|
||||
getHideRuntimeAdapters(),
|
||||
);
|
||||
if (result?.active) {
|
||||
console.log("[ST-BME] 已增量更新旧楼层隐藏:", reason, result);
|
||||
debugLog("[ST-BME] 已增量更新旧楼层隐藏:", reason, result);
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
@@ -3034,7 +3043,7 @@ async function runIncrementalMessageHide(reason = "incremental") {
|
||||
function clearMessageHideState(reason = "reset") {
|
||||
try {
|
||||
resetHideState(getHideRuntimeAdapters());
|
||||
console.log("[ST-BME] 已重置旧楼层隐藏状态:", reason);
|
||||
debugLog("[ST-BME] 已重置旧楼层隐藏状态:", reason);
|
||||
} catch (error) {
|
||||
console.warn("[ST-BME] 重置旧楼层隐藏状态失败:", reason, error);
|
||||
}
|
||||
@@ -3043,7 +3052,7 @@ function clearMessageHideState(reason = "reset") {
|
||||
async function clearAllHiddenMessages(reason = "manual-clear") {
|
||||
try {
|
||||
const result = await unhideAll(getHideRuntimeAdapters());
|
||||
console.log("[ST-BME] 已取消全部旧楼层隐藏:", reason, result);
|
||||
debugLog("[ST-BME] 已取消全部旧楼层隐藏:", reason, result);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.warn("[ST-BME] 取消全部旧楼层隐藏失败:", reason, error);
|
||||
@@ -3485,7 +3494,7 @@ async function syncBmeChatManagerWithCurrentChat(
|
||||
|
||||
if (!chatId) {
|
||||
await manager.closeCurrent();
|
||||
console.debug("[ST-BME] IndexedDB 会话已关闭(无活动聊天)", {
|
||||
debugDebug("[ST-BME] IndexedDB 会话已关闭(无活动聊天)", {
|
||||
source,
|
||||
});
|
||||
return {
|
||||
@@ -3496,7 +3505,7 @@ async function syncBmeChatManagerWithCurrentChat(
|
||||
}
|
||||
|
||||
const db = await manager.switchChat(chatId);
|
||||
console.debug("[ST-BME] IndexedDB 会话已同步", {
|
||||
debugDebug("[ST-BME] IndexedDB 会话已同步", {
|
||||
source,
|
||||
chatId,
|
||||
});
|
||||
@@ -3715,7 +3724,7 @@ async function maybeMigrateLegacyGraphToIndexedDb(
|
||||
|
||||
const postMigrationSnapshot = await targetDb.exportSnapshot();
|
||||
cacheIndexedDbSnapshot(normalizedChatId, postMigrationSnapshot);
|
||||
console.debug("[ST-BME] legacy chat_metadata 图谱迁移完成", {
|
||||
debugDebug("[ST-BME] legacy chat_metadata 图谱迁移完成", {
|
||||
source,
|
||||
chatId: normalizedChatId,
|
||||
revision:
|
||||
@@ -3990,7 +3999,7 @@ function applyIndexedDbSnapshotToRuntime(
|
||||
removeGraphShadowSnapshot(normalizedChatId);
|
||||
refreshPanelLiveState();
|
||||
schedulePersistedRecallMessageUiRefresh(30);
|
||||
console.debug("[ST-BME] 已从 IndexedDB 加载图谱", {
|
||||
debugDebug("[ST-BME] 已从 IndexedDB 加载图谱", {
|
||||
chatId: normalizedChatId,
|
||||
source,
|
||||
revision,
|
||||
@@ -4766,7 +4775,7 @@ function scheduleGraphLoadRetry(
|
||||
clearPendingGraphLoadRetry({ resetChatId: false });
|
||||
pendingGraphLoadRetryChatId =
|
||||
normalizedChatId || (allowPendingChat ? GRAPH_LOAD_PENDING_CHAT_ID : "");
|
||||
console.debug(
|
||||
debugDebug(
|
||||
`[ST-BME] 图谱元数据尚未就绪,${delayMs}ms 后重试加载(chat=${normalizedChatId || "pending"},attempt=${attemptIndex + 1},reason=${reason})`,
|
||||
);
|
||||
|
||||
@@ -5543,7 +5552,7 @@ async function ensureVectorReadyIfNeeded(
|
||||
|
||||
currentGraph.vectorIndexState.lastWarning = "";
|
||||
saveGraphToChat({ reason: "vector-auto-repair-succeeded" });
|
||||
console.log("[ST-BME] 向量状态已自动修复:", reason, result.stats);
|
||||
debugLog("[ST-BME] 向量状态已自动修复:", reason, result.stats);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5610,6 +5619,9 @@ async function loadServerSettings() {
|
||||
const loaded = await response.json();
|
||||
if (loaded && typeof loaded === "object" && !Array.isArray(loaded)) {
|
||||
extension_settings[MODULE_NAME] = mergePersistedSettings(loaded);
|
||||
globalThis.__stBmeDebugLoggingEnabled = Boolean(
|
||||
extension_settings[MODULE_NAME]?.debugLoggingEnabled,
|
||||
);
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -5670,6 +5682,9 @@ function updateModuleSettings(patch = {}) {
|
||||
const settings = getSettings();
|
||||
Object.assign(settings, patch);
|
||||
extension_settings[MODULE_NAME] = settings;
|
||||
globalThis.__stBmeDebugLoggingEnabled = Boolean(
|
||||
settings.debugLoggingEnabled,
|
||||
);
|
||||
saveSettingsDebounced();
|
||||
|
||||
if (
|
||||
@@ -9834,11 +9849,11 @@ async function onReembedDirect() {
|
||||
getExtensionPath: () => `scripts/extensions/third-party/${MODULE_NAME}`,
|
||||
isTrivialUserInput,
|
||||
preparePlannerRecallHandoff,
|
||||
runPlannerRecallForEna,
|
||||
runPlannerRecallForEna,
|
||||
});
|
||||
console.log("[ST-BME] Ena Planner module loaded");
|
||||
debugLog("[ST-BME] Ena Planner module loaded");
|
||||
} catch (error) {
|
||||
console.warn("[ST-BME] Ena Planner module load failed:", error);
|
||||
}
|
||||
console.log("[ST-BME] 初始化完成");
|
||||
debugLog("[ST-BME] 初始化完成");
|
||||
})();
|
||||
|
||||
11
llm.js
11
llm.js
@@ -4,6 +4,7 @@
|
||||
import { getRequestHeaders } from "../../../../script.js";
|
||||
import { extension_settings } from "../../../extensions.js";
|
||||
import { chat_completion_sources, sendOpenAIRequest } from "../../../openai.js";
|
||||
import { debugLog, debugWarn } from "./debug-logging.js";
|
||||
import { resolveTaskGenerationOptions } from "./generation-options.js";
|
||||
import { resolveConfiguredTimeoutMs } from "./request-timeout.js";
|
||||
import { applyTaskRegex } from "./task-regex.js";
|
||||
@@ -1585,13 +1586,13 @@ export async function callLLMForJSON({
|
||||
);
|
||||
{
|
||||
const asmUser = assembledMessages.filter((m) => m?.role === "user");
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] buildJsonAttemptMessages: ` +
|
||||
`total=${assembledMessages.length}, user=${asmUser.length}, ` +
|
||||
`roles=[${assembledMessages.map((m) => m?.role).join(",")}]`,
|
||||
);
|
||||
for (const m of asmUser) {
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] assembled user: len=${String(m.content || "").length}, ` +
|
||||
`preview="${String(m.content || "").slice(0, 80)}..."`,
|
||||
);
|
||||
@@ -1605,18 +1606,18 @@ export async function callLLMForJSON({
|
||||
const rcMsgs = Array.isArray(requestCleaning.messages) ? requestCleaning.messages : [];
|
||||
const rcUser = rcMsgs.filter((m) => m?.role === "user");
|
||||
const dbg = requestCleaning.debug || {};
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] applyTaskFinalInputRegex: ` +
|
||||
`total=${rcMsgs.length}, user=${rcUser.length}, ` +
|
||||
`changed=${dbg.changed}, applied=${dbg.applied}, ` +
|
||||
`roles=[${rcMsgs.map((m) => m?.role).join(",")}]`,
|
||||
);
|
||||
if (rcUser.length === 0 && assembledMessages.filter((m) => m?.role === "user").length > 0) {
|
||||
console.warn(
|
||||
debugWarn(
|
||||
`[ST-BME][prompt-diag] *** USER MESSAGES LOST during applyTaskFinalInputRegex! ***`,
|
||||
);
|
||||
for (const rule of dbg.appliedRules || []) {
|
||||
console.warn(`[ST-BME][prompt-diag] applied rule: ${JSON.stringify(rule)}`);
|
||||
debugWarn(`[ST-BME][prompt-diag] applied rule: ${JSON.stringify(rule)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { debugLog } from "./debug-logging.js";
|
||||
|
||||
function resolvePanelTheme(settings) {
|
||||
return settings?.panelTheme || "crimson";
|
||||
}
|
||||
@@ -83,7 +85,7 @@ export async function initializePanelBridgeController(runtime) {
|
||||
});
|
||||
|
||||
injectOptionsMenuEntry(runtime);
|
||||
runtime.console.log("[ST-BME] 操控面板初始化完成");
|
||||
debugLog("[ST-BME] 操控面板初始化完成");
|
||||
} catch (panelError) {
|
||||
runtime.console.error(
|
||||
"[ST-BME] 操控面板加载失败(核心功能不受影响):",
|
||||
|
||||
26
panel.html
26
panel.html
@@ -1079,6 +1079,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bme-config-card">
|
||||
<div class="bme-config-card-head">
|
||||
<div>
|
||||
<div class="bme-config-card-title">调试日志</div>
|
||||
<div class="bme-config-card-subtitle">
|
||||
默认关闭,需要排查问题时再临时打开浏览器控制台日志。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label
|
||||
class="bme-toggle-item"
|
||||
for="bme-setting-debug-logging-enabled"
|
||||
>
|
||||
<span class="bme-toggle-copy">
|
||||
<span class="bme-toggle-title">启用调试日志</span>
|
||||
<span class="bme-toggle-desc">
|
||||
只在开启后输出内部诊断日志与流程跟踪,可能包含脱敏后的 prompt 组装摘要。
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
id="bme-setting-debug-logging-enabled"
|
||||
type="checkbox"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="bme-config-card">
|
||||
<div class="bme-config-card-head">
|
||||
<div>
|
||||
|
||||
7
panel.js
7
panel.js
@@ -1580,6 +1580,10 @@ function _refreshConfigTab() {
|
||||
_refreshPlannerLauncher();
|
||||
|
||||
_setCheckboxValue("bme-setting-enabled", settings.enabled ?? true);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-debug-logging-enabled",
|
||||
settings.debugLoggingEnabled ?? false,
|
||||
);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-hide-old-messages-enabled",
|
||||
settings.hideOldMessagesEnabled ?? false,
|
||||
@@ -1920,6 +1924,9 @@ function _bindConfigControls() {
|
||||
_patchSettings({ enabled: checked });
|
||||
_refreshGuardedConfigStates();
|
||||
});
|
||||
bindCheckbox("bme-setting-debug-logging-enabled", (checked) => {
|
||||
_patchSettings({ debugLoggingEnabled: checked });
|
||||
});
|
||||
bindCheckbox("bme-setting-hide-old-messages-enabled", (checked) => {
|
||||
_patchSettings({ hideOldMessagesEnabled: checked });
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// ST-BME: Prompt Builder
|
||||
// 统一负责任务预设块排序、变量渲染,以及世界书/EJS 上下文接入。
|
||||
|
||||
import { debugLog, debugWarn } from "./debug-logging.js";
|
||||
import { getActiveTaskProfile, getLegacyPromptForTask } from "./prompt-profiles.js";
|
||||
import { sanitizeMvuContent } from "./mvu-compat.js";
|
||||
import { resolveTaskWorldInfo } from "./task-worldinfo.js";
|
||||
@@ -1098,7 +1099,7 @@ export async function buildTaskPrompt(settings = {}, taskType, context = {}) {
|
||||
let assistantRoleBlockCount = 0;
|
||||
let systemRoleBlockCount = 0;
|
||||
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] buildTaskPrompt: taskType=${taskType}, ` +
|
||||
`total blocks=${blocks.length}, ` +
|
||||
`block roles=[${blocks.map((b) => `${b.name}(${b.role},${b.enabled !== false ? "on" : "off"})`).join(", ")}]`,
|
||||
@@ -1125,7 +1126,7 @@ export async function buildTaskPrompt(settings = {}, taskType, context = {}) {
|
||||
}
|
||||
|
||||
if (role === "user") {
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] user block "${block.name || block.id}": ` +
|
||||
`type=${block.type}, contentLen=${String(content || "").length}, ` +
|
||||
`rawContentLen=${String(block.content || "").length}, ` +
|
||||
@@ -1154,7 +1155,7 @@ export async function buildTaskPrompt(settings = {}, taskType, context = {}) {
|
||||
|
||||
if (!String(content || "").trim()) {
|
||||
if (role === "user" && String(block.content || "").trim()) {
|
||||
console.warn(
|
||||
debugWarn(
|
||||
`[ST-BME] buildTaskPrompt: user block "${block.name || block.id}" ` +
|
||||
`content emptied during sanitization! ` +
|
||||
`original length=${String(block.content || "").length}, ` +
|
||||
@@ -1220,7 +1221,7 @@ export async function buildTaskPrompt(settings = {}, taskType, context = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME][prompt-diag] buildTaskPrompt done: ` +
|
||||
`executionMessages=${executionMessages.length}, ` +
|
||||
`userBlocks=${userRoleBlockCount}, systemBlocks=${systemRoleBlockCount}, ` +
|
||||
@@ -1405,7 +1406,7 @@ export function buildTaskLlmPayload(promptBuild = null, fallbackUserPrompt = "")
|
||||
const userBlocksAfterSanitize = executionMessages.filter(
|
||||
(m) => m?.role === "user",
|
||||
);
|
||||
console.warn(
|
||||
debugWarn(
|
||||
`[ST-BME] buildTaskLlmPayload fallback triggered: ` +
|
||||
`user blocks in promptBuild=${userBlocksBefore.length}, ` +
|
||||
`after recreate=${userBlocksAfterRaw.length}, ` +
|
||||
@@ -1415,7 +1416,7 @@ export function buildTaskLlmPayload(promptBuild = null, fallbackUserPrompt = "")
|
||||
);
|
||||
if (userBlocksBefore.length > 0) {
|
||||
for (const block of userBlocksBefore) {
|
||||
console.warn(
|
||||
debugWarn(
|
||||
`[ST-BME] user block "${block.blockName || block.blockId}": ` +
|
||||
`content length=${String(block.content || "").length}, ` +
|
||||
`content preview="${String(block.content || "").slice(0, 80)}..."`,
|
||||
@@ -1423,7 +1424,7 @@ export function buildTaskLlmPayload(promptBuild = null, fallbackUserPrompt = "")
|
||||
}
|
||||
}
|
||||
if (blockedContents.length > 0) {
|
||||
console.warn(
|
||||
debugWarn(
|
||||
`[ST-BME] blockedContents lengths: [${blockedContents.map((c) => String(c || "").length).join(", ")}]`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// ST-BME: 召回输入解析与注入控制器(纯函数)
|
||||
|
||||
import { debugLog, debugWarn } from "./debug-logging.js";
|
||||
|
||||
export function buildRecallRecentMessagesController(
|
||||
chat,
|
||||
limit,
|
||||
@@ -174,7 +176,7 @@ export function applyRecallInjectionController(
|
||||
|
||||
if (injectionText) {
|
||||
const tokens = runtime.estimateTokens(injectionText);
|
||||
runtime.console.log(
|
||||
debugLog(
|
||||
`[ST-BME] 注入 ${tokens} 估算 tokens, Core=${result.stats.coreCount}, Recall=${result.stats.recallCount}`,
|
||||
);
|
||||
runtime.persistRecallInjectionRecord?.({
|
||||
@@ -287,12 +289,12 @@ export function applyRecallInjectionController(
|
||||
}
|
||||
|
||||
export async function runRecallController(runtime, options = {}) {
|
||||
console.warn("[ST-BME:DIAG:RECALL] runRecallController entered");
|
||||
debugWarn("[ST-BME:DIAG:RECALL] runRecallController entered");
|
||||
if (runtime.getIsRecalling()) {
|
||||
runtime.abortRecallStageWithReason("旧召回已取消,正在启动新的召回");
|
||||
const settle = await runtime.waitForActiveRecallToSettle();
|
||||
if (!settle.settled && runtime.getIsRecalling()) {
|
||||
console.warn("[ST-BME:DIAG:RECALL] EXIT: 上一轮召回仍在清理");
|
||||
debugWarn("[ST-BME:DIAG:RECALL] EXIT: 上一轮召回仍在清理");
|
||||
runtime.setLastRecallStatus(
|
||||
"召回忙",
|
||||
"上一轮召回仍在清理,请稍后重试",
|
||||
@@ -308,18 +310,18 @@ export async function runRecallController(runtime, options = {}) {
|
||||
}
|
||||
|
||||
const hasGraph = !!runtime.getCurrentGraph();
|
||||
console.warn("[ST-BME:DIAG:RECALL] hasGraph:", hasGraph);
|
||||
debugWarn("[ST-BME:DIAG:RECALL] hasGraph:", hasGraph);
|
||||
if (!hasGraph) {
|
||||
console.warn("[ST-BME:DIAG:RECALL] EXIT: 当前无图谱");
|
||||
debugWarn("[ST-BME:DIAG:RECALL] EXIT: 当前无图谱");
|
||||
return runtime.createRecallRunResult("skipped", {
|
||||
reason: "当前无图谱",
|
||||
});
|
||||
}
|
||||
|
||||
const settings = runtime.getSettings();
|
||||
console.warn("[ST-BME:DIAG:RECALL] settings.enabled:", settings.enabled, "recallEnabled:", settings.recallEnabled);
|
||||
debugWarn("[ST-BME:DIAG:RECALL] settings.enabled:", settings.enabled, "recallEnabled:", settings.recallEnabled);
|
||||
if (!settings.enabled || !settings.recallEnabled) {
|
||||
console.warn("[ST-BME:DIAG:RECALL] EXIT: 召回功能未启用");
|
||||
debugWarn("[ST-BME:DIAG:RECALL] EXIT: 召回功能未启用");
|
||||
return runtime.createRecallRunResult("skipped", {
|
||||
reason: "召回功能未启用",
|
||||
});
|
||||
@@ -330,10 +332,10 @@ export async function runRecallController(runtime, options = {}) {
|
||||
: runtime.isGraphReadable();
|
||||
const chatId = typeof runtime.getCurrentChatId === "function" ? runtime.getCurrentChatId() : "(no fn)";
|
||||
const loadState = runtime.getGraphPersistenceLoadState?.() || "(no fn)";
|
||||
console.warn("[ST-BME:DIAG:RECALL] isReadableForRecall:", isReadableForRecall, "chatId:", chatId, "loadState:", loadState);
|
||||
debugWarn("[ST-BME:DIAG:RECALL] isReadableForRecall:", isReadableForRecall, "chatId:", chatId, "loadState:", loadState);
|
||||
if (!isReadableForRecall) {
|
||||
const reason = runtime.getGraphMutationBlockReason("召回");
|
||||
console.warn("[ST-BME:DIAG:RECALL] EXIT: 图谱不可读 -", reason);
|
||||
debugWarn("[ST-BME:DIAG:RECALL] EXIT: 图谱不可读 -", reason);
|
||||
runtime.setLastRecallStatus("等待图谱加载", reason, "warning", {
|
||||
syncRuntime: true,
|
||||
});
|
||||
@@ -407,7 +409,7 @@ export async function runRecallController(runtime, options = {}) {
|
||||
recallInput.deliveryMode =
|
||||
String(options.deliveryMode || "immediate").trim() || "immediate";
|
||||
|
||||
runtime.console.log("[ST-BME] 开始召回", {
|
||||
debugLog("[ST-BME] 开始召回", {
|
||||
source: recallInput.source,
|
||||
sourceLabel: recallInput.sourceLabel,
|
||||
hookName: recallInput.hookName,
|
||||
|
||||
15
retriever.js
15
retriever.js
@@ -2,6 +2,7 @@
|
||||
// 融合向量预筛(PeroCore)+ 图扩散(PeroCore PEDSA)+ 可选 LLM 精确召回
|
||||
// v2: + 认知边界过滤(RoleRAG) + 双记忆交叉检索(AriGraph) + 概率触发
|
||||
|
||||
import { debugLog } from "./debug-logging.js";
|
||||
import { diffuseAndRank } from "./diffusion.js";
|
||||
import { hybridScore, reinforceAccessBatch } from "./dynamics.js";
|
||||
import {
|
||||
@@ -838,7 +839,7 @@ export async function retrieve({
|
||||
maxSegments: multiIntentMaxSegments,
|
||||
},
|
||||
);
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME] 检索开始: ${nodeCount} 个活跃节点${enableVisibility ? " (认知边界已启用)" : ""}`,
|
||||
);
|
||||
|
||||
@@ -877,7 +878,7 @@ export async function retrieve({
|
||||
|
||||
const vectorStartedAt = nowMs();
|
||||
if (enableVectorPrefilter && vectorValidation.valid) {
|
||||
console.log("[ST-BME] 第1层: 向量预筛");
|
||||
debugLog("[ST-BME] 第1层: 向量预筛");
|
||||
const queryPlan = buildVectorQueryPlan(contextQueryBlend, {
|
||||
enableMultiIntent,
|
||||
maxSegments: multiIntentMaxSegments,
|
||||
@@ -958,7 +959,7 @@ export async function retrieve({
|
||||
|
||||
const diffusionStartedAt = nowMs();
|
||||
if (enableGraphDiffusion) {
|
||||
console.log("[ST-BME] 第2层: PEDSA 图扩散");
|
||||
debugLog("[ST-BME] 第2层: PEDSA 图扩散");
|
||||
const seeds = [
|
||||
...vectorResults.map((v) => ({ id: v.nodeId, energy: v.score })),
|
||||
...exactEntityAnchors.map((item) => ({ id: item.nodeId, energy: 2.0 })),
|
||||
@@ -1016,7 +1017,7 @@ export async function retrieve({
|
||||
retrievalMeta.diffusionHits = diffusionResults.length;
|
||||
retrievalMeta.timings.diffusion = roundMs(nowMs() - diffusionStartedAt);
|
||||
|
||||
console.log("[ST-BME] 第3层: 混合评分");
|
||||
debugLog("[ST-BME] 第3层: 混合评分");
|
||||
|
||||
const scoreMap = new Map();
|
||||
|
||||
@@ -1168,7 +1169,7 @@ export async function retrieve({
|
||||
let llmDurationMs = 0;
|
||||
|
||||
if (enableLLMRecall && nodeCount > 0) {
|
||||
console.log("[ST-BME] LLM 精确召回");
|
||||
debugLog("[ST-BME] LLM 精确召回");
|
||||
llmCandidates = resolveCandidatePool(
|
||||
scoredNodes,
|
||||
normalizedLlmCandidatePool,
|
||||
@@ -1247,7 +1248,7 @@ export async function retrieve({
|
||||
|
||||
reinforceAccessBatch(selectedNodes);
|
||||
|
||||
console.log(`[ST-BME] 检索完成: 选中 ${selectedNodeIds.length} 个节点`);
|
||||
debugLog(`[ST-BME] 检索完成: 选中 ${selectedNodeIds.length} 个节点`);
|
||||
|
||||
if (enableProbRecall && probRecallChance > 0) {
|
||||
const selectedSet = new Set(selectedNodeIds);
|
||||
@@ -1265,7 +1266,7 @@ export async function retrieve({
|
||||
for (const c of candidates) {
|
||||
if (Math.random() < probability) {
|
||||
selectedNodeIds.push(c.id);
|
||||
console.log(
|
||||
debugLog(
|
||||
`[ST-BME] 概率触发: ${c.fields?.name || c.fields?.summary || c.id}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// 同时叠加任务本地规则,并按任务阶段执行。
|
||||
|
||||
import { extension_settings, getContext } from "../../../extensions.js";
|
||||
import { debugDebug } from "./debug-logging.js";
|
||||
import { getHostAdapter } from "./host-adapter/index.js";
|
||||
import {
|
||||
getActiveTaskProfile,
|
||||
@@ -236,7 +237,7 @@ function getRegexHost() {
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
"[ST-BME] task-regex 读取 regex bridge 失败,回退到 legacy 宿主接口",
|
||||
error,
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
isMvuTaggedWorldInfoNameOrComment,
|
||||
sanitizeMvuContent,
|
||||
} from "./mvu-compat.js";
|
||||
import { debugDebug } from "./debug-logging.js";
|
||||
|
||||
const WI_POSITION = {
|
||||
before: 0,
|
||||
@@ -249,7 +250,7 @@ async function getWorldbookHost() {
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
"[ST-BME] task-worldinfo 读取 worldbook bridge 失败,回退到 legacy 宿主接口",
|
||||
error,
|
||||
);
|
||||
@@ -759,7 +760,7 @@ async function loadNormalizedWorldbookEntries(
|
||||
]),
|
||||
);
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
`[ST-BME] task-worldinfo 读取 lorebook comment 失败: ${normalizedName}`,
|
||||
error,
|
||||
);
|
||||
@@ -827,7 +828,7 @@ async function collectAllWorldbookEntries(worldbookHost = null) {
|
||||
capabilityStatus?.supplementedCapabilities || [];
|
||||
const missingCapabilities = capabilityStatus?.missingCapabilities || [];
|
||||
if (supplementedCapabilities.length > 0) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
`[ST-BME] task-worldinfo worldbook bridge 已通过 legacy 补齐关键能力: ${supplementedCapabilities.join(", ")} [${sourceTag}]`,
|
||||
);
|
||||
}
|
||||
@@ -849,7 +850,7 @@ async function collectAllWorldbookEntries(worldbookHost = null) {
|
||||
? resolved.additional.map((name) => normalizeKey(name)).filter(Boolean)
|
||||
: [];
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
`[ST-BME] task-worldinfo 读取角色世界书失败 [${sourceTag}]`,
|
||||
error,
|
||||
);
|
||||
@@ -928,7 +929,7 @@ async function collectAllWorldbookEntries(worldbookHost = null) {
|
||||
);
|
||||
allEntries.push(...entries);
|
||||
} catch (error) {
|
||||
console.debug(
|
||||
debugDebug(
|
||||
`[ST-BME] task-worldinfo 读取世界书失败: ${normalizedName} [${sourceTag}]`,
|
||||
error,
|
||||
);
|
||||
|
||||
@@ -40,10 +40,10 @@ async function loadSettingsCompatHelpers() {
|
||||
const source = await fs.readFile(indexPath, "utf8");
|
||||
const settingsMatch = source.match(/const defaultSettings = \{[\s\S]*?^\};/m);
|
||||
const compatMatch = source.match(
|
||||
/function migrateLegacyAutoMaintenanceSettings\(loaded = \{\}\) \{[\s\S]*?^}\n/m,
|
||||
/function migrateLegacyAutoMaintenanceSettings\(loaded = \{\}\) \{[\s\S]*?^}\r?\n/m,
|
||||
);
|
||||
const mergeMatch = source.match(
|
||||
/function mergePersistedSettings\(loaded = \{\}\) \{[\s\S]*?^}\n/m,
|
||||
/function mergePersistedSettings\(loaded = \{\}\) \{[\s\S]*?^}\r?\n/m,
|
||||
);
|
||||
|
||||
if (!settingsMatch || !compatMatch || !mergeMatch) {
|
||||
@@ -124,6 +124,7 @@ assert.equal(defaultSettings.injectUserPovMemory, true);
|
||||
assert.equal(defaultSettings.injectObjectiveGlobalMemory, true);
|
||||
assert.equal(defaultSettings.injectDepth, 9999);
|
||||
assert.equal(defaultSettings.enabled, true);
|
||||
assert.equal(defaultSettings.debugLoggingEnabled, false);
|
||||
assert.equal(defaultSettings.enableReflection, true);
|
||||
assert.equal(defaultSettings.consolidationAutoMinNewNodes, 2);
|
||||
assert.equal(defaultSettings.enableAutoCompression, true);
|
||||
|
||||
Reference in New Issue
Block a user