mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
Integrate native rollout UI and tune hydrate gating
This commit is contained in:
193
ui/panel.html
193
ui/panel.html
@@ -1462,6 +1462,199 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="bme-config-card">
|
||||
<div class="bme-config-card-head">
|
||||
<div>
|
||||
<div class="bme-config-card-title">Native 性能加速</div>
|
||||
<div class="bme-config-card-subtitle">
|
||||
控制图布局、图谱增量写回与加载 hydrate 是否尝试使用 Worker / WASM 加速;默认按阈值自动命中。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label
|
||||
class="bme-toggle-item"
|
||||
for="bme-setting-graph-native-force-disable"
|
||||
>
|
||||
<span class="bme-toggle-copy">
|
||||
<span class="bme-toggle-title">全局强制关闭 Native</span>
|
||||
<span class="bme-toggle-desc">
|
||||
打开后会统一禁止 layout / persist / hydrate 的 native 路径,直接走 JS 回退。
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
id="bme-setting-graph-native-force-disable"
|
||||
type="checkbox"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
class="bme-toggle-item"
|
||||
for="bme-setting-native-engine-fail-open"
|
||||
>
|
||||
<span class="bme-toggle-copy">
|
||||
<span class="bme-toggle-title">Fail-open 回退</span>
|
||||
<span class="bme-toggle-desc">
|
||||
native 模块不可用或执行失败时,自动回退到 JS;关闭后会按严格模式抛错。
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
id="bme-setting-native-engine-fail-open"
|
||||
type="checkbox"
|
||||
/>
|
||||
</label>
|
||||
<label
|
||||
class="bme-inline-checkbox"
|
||||
for="bme-setting-graph-use-native-layout"
|
||||
>
|
||||
<input
|
||||
id="bme-setting-graph-use-native-layout"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span>图布局使用 native Worker / WASM</span>
|
||||
</label>
|
||||
<label
|
||||
class="bme-inline-checkbox"
|
||||
for="bme-setting-persist-use-native-delta"
|
||||
>
|
||||
<input
|
||||
id="bme-setting-persist-use-native-delta"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span>Persist Delta 使用 native 加速</span>
|
||||
</label>
|
||||
<label
|
||||
class="bme-inline-checkbox"
|
||||
for="bme-setting-load-use-native-hydrate"
|
||||
>
|
||||
<input
|
||||
id="bme-setting-load-use-native-hydrate"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span>快照 Hydrate 使用 native 加速</span>
|
||||
</label>
|
||||
<div class="bme-config-help" id="bme-native-rollout-status">
|
||||
当前会在这里显示 native rollout 总状态与最近一次命中/回退摘要。
|
||||
</div>
|
||||
<div
|
||||
class="bme-config-help"
|
||||
id="bme-native-layout-status"
|
||||
style="margin-top: 6px;"
|
||||
></div>
|
||||
<div
|
||||
class="bme-config-help"
|
||||
id="bme-native-persist-status"
|
||||
style="margin-top: 4px;"
|
||||
></div>
|
||||
<div
|
||||
class="bme-config-help"
|
||||
id="bme-native-hydrate-status"
|
||||
style="margin-top: 4px;"
|
||||
></div>
|
||||
<details
|
||||
class="bme-config-subdetails bme-collapsible-card"
|
||||
id="bme-native-rollout-threshold-settings"
|
||||
>
|
||||
<summary class="bme-collapsible-summary bme-config-subdetails-summary">
|
||||
<div>
|
||||
<div class="bme-config-subgroup-title">阈值与超时</div>
|
||||
<div class="bme-config-subgroup-desc">
|
||||
调整 layout / persist / hydrate 什么时候值得尝试 native;通常保持默认即可。
|
||||
</div>
|
||||
</div>
|
||||
<span class="bme-collapsible-indicator" aria-hidden="true">
|
||||
<i class="fa-solid fa-chevron-down"></i>
|
||||
</span>
|
||||
</summary>
|
||||
<div class="bme-config-subgroup">
|
||||
<div class="bme-config-row">
|
||||
<label for="bme-setting-graph-native-layout-threshold-nodes">
|
||||
布局节点阈值
|
||||
</label>
|
||||
<input
|
||||
id="bme-setting-graph-native-layout-threshold-nodes"
|
||||
class="bme-config-input"
|
||||
type="number"
|
||||
min="1"
|
||||
max="20000"
|
||||
/>
|
||||
</div>
|
||||
<div class="bme-config-row">
|
||||
<label for="bme-setting-graph-native-layout-threshold-edges">
|
||||
布局边阈值
|
||||
</label>
|
||||
<input
|
||||
id="bme-setting-graph-native-layout-threshold-edges"
|
||||
class="bme-config-input"
|
||||
type="number"
|
||||
min="1"
|
||||
max="50000"
|
||||
/>
|
||||
</div>
|
||||
<div class="bme-config-row">
|
||||
<label for="bme-setting-graph-native-layout-worker-timeout-ms">
|
||||
Layout Worker 超时(ms)
|
||||
</label>
|
||||
<input
|
||||
id="bme-setting-graph-native-layout-worker-timeout-ms"
|
||||
class="bme-config-input"
|
||||
type="number"
|
||||
min="40"
|
||||
max="15000"
|
||||
step="10"
|
||||
/>
|
||||
</div>
|
||||
<div class="bme-config-row">
|
||||
<label for="bme-setting-persist-native-delta-threshold-records">
|
||||
Persist 记录数阈值
|
||||
</label>
|
||||
<input
|
||||
id="bme-setting-persist-native-delta-threshold-records"
|
||||
class="bme-config-input"
|
||||
type="number"
|
||||
min="0"
|
||||
max="200000"
|
||||
/>
|
||||
</div>
|
||||
<div class="bme-config-row">
|
||||
<label for="bme-setting-persist-native-delta-threshold-structural-delta">
|
||||
Persist 结构变化阈值
|
||||
</label>
|
||||
<input
|
||||
id="bme-setting-persist-native-delta-threshold-structural-delta"
|
||||
class="bme-config-input"
|
||||
type="number"
|
||||
min="0"
|
||||
max="200000"
|
||||
/>
|
||||
</div>
|
||||
<div class="bme-config-row">
|
||||
<label for="bme-setting-persist-native-delta-threshold-serialized-chars">
|
||||
Persist 序列化体积阈值
|
||||
</label>
|
||||
<input
|
||||
id="bme-setting-persist-native-delta-threshold-serialized-chars"
|
||||
class="bme-config-input"
|
||||
type="number"
|
||||
min="0"
|
||||
max="50000000"
|
||||
step="1000"
|
||||
/>
|
||||
</div>
|
||||
<div class="bme-config-row">
|
||||
<label for="bme-setting-load-native-hydrate-threshold-records">
|
||||
Hydrate 记录数阈值
|
||||
</label>
|
||||
<input
|
||||
id="bme-setting-load-native-hydrate-threshold-records"
|
||||
class="bme-config-input"
|
||||
type="number"
|
||||
min="0"
|
||||
max="200000"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div class="bme-config-card">
|
||||
<div class="bme-config-card-head">
|
||||
<div>
|
||||
|
||||
391
ui/panel.js
391
ui/panel.js
@@ -1250,6 +1250,7 @@ export function refreshLiveState() {
|
||||
if (!overlayEl?.classList.contains("active")) return;
|
||||
_applyGraphRuntimeConfig(_getSettings?.() || {});
|
||||
_refreshRuntimeStatus();
|
||||
_refreshNativeRolloutStatusUi(_getSettings?.() || {});
|
||||
|
||||
switch (currentTabId) {
|
||||
case "dashboard":
|
||||
@@ -1468,6 +1469,132 @@ function _readPersistenceDiagnosticObject(snapshot = null) {
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
function _formatNativeHydrateGateReasonText(reasons = []) {
|
||||
const labels = {
|
||||
"below-min-snapshot-records": "记录数不足",
|
||||
};
|
||||
const normalized = Array.isArray(reasons)
|
||||
? reasons.map((item) => String(item || "").trim()).filter(Boolean)
|
||||
: [];
|
||||
if (!normalized.length) return "—";
|
||||
return normalized.map((item) => labels[item] || item).join(" · ");
|
||||
}
|
||||
|
||||
function _formatNativeHydrateGateText(diagnostics = null) {
|
||||
if (!diagnostics || typeof diagnostics !== "object") return "—";
|
||||
if (diagnostics.hydrateNativeRequested !== true) return "未请求 native";
|
||||
if (diagnostics.hydrateNativeForceDisabled === true) return "已强制关闭";
|
||||
if (diagnostics.hydrateNativeGateAllowed === true) return "通过";
|
||||
return `已拦截 · ${_formatNativeHydrateGateReasonText(diagnostics.hydrateNativeGateReasons)}`;
|
||||
}
|
||||
|
||||
function _formatNativeHydrateResultText(diagnostics = null) {
|
||||
if (!diagnostics || typeof diagnostics !== "object") return "暂无";
|
||||
if (diagnostics.hydrateNativeRequested !== true) return "未请求 native";
|
||||
if (diagnostics.hydrateNativeForceDisabled === true) return "已强制关闭";
|
||||
if (diagnostics.hydrateNativeGateAllowed !== true) return "已拦截";
|
||||
if (diagnostics.hydrateNativeUsed === true) {
|
||||
const status = String(diagnostics.hydrateNativeStatus || "").trim();
|
||||
return status ? `已命中 · ${status}` : "已命中";
|
||||
}
|
||||
const fallbackReason =
|
||||
String(diagnostics.hydrateNativeStatus || "").trim() ||
|
||||
String(diagnostics.hydrateNativePreloadStatus || "").trim() ||
|
||||
"js";
|
||||
return `已回退 · ${fallbackReason}`;
|
||||
}
|
||||
|
||||
function _formatNativeHydrateModuleText(diagnostics = null) {
|
||||
if (!diagnostics || typeof diagnostics !== "object") return "—";
|
||||
const parts = [];
|
||||
const preload = String(diagnostics.hydrateNativePreloadStatus || "").trim();
|
||||
const source = String(diagnostics.hydrateNativeModuleSource || "").trim();
|
||||
if (preload) parts.push(`preload ${preload}`);
|
||||
if (diagnostics.hydrateNativeModuleLoaded === true) parts.push("loaded");
|
||||
if (source) parts.push(source);
|
||||
return parts.join(" · ") || "—";
|
||||
}
|
||||
|
||||
function _formatNativeLayoutStatusSummary(layout = null, settings = _getSettings?.() || {}) {
|
||||
if (settings.graphNativeForceDisable === true) return "已强制关闭";
|
||||
if (settings.graphUseNativeLayout !== true) return "已关闭";
|
||||
if (!layout || typeof layout !== "object") return "暂无最近布局诊断";
|
||||
const parts = [String(layout.mode || layout.solver || "unknown").trim() || "unknown"];
|
||||
const totalText = _formatDurationMs(layout.totalMs);
|
||||
const moduleSource = String(layout.moduleSource || "").trim();
|
||||
const reason = String(layout.reason || "").trim();
|
||||
if (totalText !== "—") parts.push(totalText);
|
||||
if (moduleSource) parts.push(moduleSource);
|
||||
if (reason && reason !== parts[0]) parts.push(reason);
|
||||
return parts.join(" · ");
|
||||
}
|
||||
|
||||
function _formatNativePersistStatusSummary(diagnostics = null, settings = _getSettings?.() || {}) {
|
||||
if (settings.graphNativeForceDisable === true) return "已强制关闭";
|
||||
if (settings.persistUseNativeDelta !== true) return "已关闭";
|
||||
const snapshot = _readPersistenceDiagnosticObject(diagnostics);
|
||||
if (!snapshot) return "暂无最近写回诊断";
|
||||
const parts = [String(snapshot.path || "pending")];
|
||||
const gateText = String(_formatPersistDeltaGateText(snapshot) || "").trim();
|
||||
const fallbackReason = String(snapshot.fallbackReason || "").trim();
|
||||
if (gateText && gateText !== "—") parts.push(gateText);
|
||||
if (fallbackReason) parts.push(`回退 ${fallbackReason}`);
|
||||
return parts.join(" · ");
|
||||
}
|
||||
|
||||
function _formatNativeHydrateStatusSummary(diagnostics = null, settings = _getSettings?.() || {}) {
|
||||
if (settings.graphNativeForceDisable === true) return "已强制关闭";
|
||||
if (settings.loadUseNativeHydrate !== true) return "已关闭";
|
||||
const snapshot = _readPersistenceDiagnosticObject(diagnostics);
|
||||
if (!snapshot) return "暂无最近加载诊断";
|
||||
const parts = [_formatNativeHydrateResultText(snapshot)];
|
||||
const gateText = String(_formatNativeHydrateGateText(snapshot) || "").trim();
|
||||
const preload = String(snapshot.hydrateNativePreloadStatus || "").trim();
|
||||
if (gateText && gateText !== "—" && gateText !== "通过") parts.push(gateText);
|
||||
if (preload && preload !== "loaded" && preload !== "not-requested") {
|
||||
parts.push(`preload ${preload}`);
|
||||
}
|
||||
return Array.from(new Set(parts.filter(Boolean))).join(" · ");
|
||||
}
|
||||
|
||||
function _refreshNativeRolloutStatusUi(
|
||||
settings = _getSettings?.() || {},
|
||||
loadInfo = _getGraphPersistenceSnapshot(),
|
||||
) {
|
||||
const summaryEl = document.getElementById("bme-native-rollout-status");
|
||||
const layoutEl = document.getElementById("bme-native-layout-status");
|
||||
const persistEl = document.getElementById("bme-native-persist-status");
|
||||
const hydrateEl = document.getElementById("bme-native-hydrate-status");
|
||||
if (!summaryEl && !layoutEl && !persistEl && !hydrateEl) return;
|
||||
|
||||
const panelDebug = _getRuntimeDebugSnapshot?.() || {};
|
||||
const runtimeDebug = panelDebug.runtimeDebug || {};
|
||||
const layout = runtimeDebug?.graphLayout || null;
|
||||
const persistDelta = _readPersistenceDiagnosticObject(
|
||||
loadInfo?.persistDelta || runtimeDebug?.graphPersistence?.persistDelta,
|
||||
);
|
||||
const loadDiagnostics = _readPersistenceDiagnosticObject(
|
||||
loadInfo?.loadDiagnostics || runtimeDebug?.graphPersistence?.loadDiagnostics,
|
||||
);
|
||||
const rolloutVersion = Math.max(
|
||||
0,
|
||||
Math.floor(Number(settings?.nativeRolloutVersion || 0)),
|
||||
);
|
||||
const summaryText = settings.graphNativeForceDisable === true
|
||||
? `rollout v${rolloutVersion} · 全局强制关闭 · ${settings.nativeEngineFailOpen !== false ? "fail-open 已启用" : "严格模式"}`
|
||||
: `rollout v${rolloutVersion} · 按阈值自动尝试 native · ${settings.nativeEngineFailOpen !== false ? "fail-open 已启用" : "严格模式"}`;
|
||||
if (summaryEl) summaryEl.textContent = summaryText;
|
||||
if (layoutEl) {
|
||||
layoutEl.textContent = `Layout:${_formatNativeLayoutStatusSummary(layout, settings)}`;
|
||||
}
|
||||
if (persistEl) {
|
||||
persistEl.textContent = `Persist:${_formatNativePersistStatusSummary(persistDelta, settings)}`;
|
||||
}
|
||||
if (hydrateEl) {
|
||||
hydrateEl.textContent = `Hydrate:${_formatNativeHydrateStatusSummary(loadDiagnostics, settings)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function _formatLoadDiagnosticsStageLabel(stage = "") {
|
||||
const normalized = String(stage || "").trim();
|
||||
if (!normalized) return "—";
|
||||
@@ -1522,6 +1649,9 @@ function _formatPersistenceLoadSummary(loadDiagnostics = null) {
|
||||
const parts = [statusText];
|
||||
if (stageLabel !== "—") parts.push(stageLabel);
|
||||
if (totalText !== "—") parts.push(`total ${totalText}`);
|
||||
if (diagnostics.hydrateNativeRequested === true) {
|
||||
parts.push(`native ${_formatNativeHydrateResultText(diagnostics)}`);
|
||||
}
|
||||
if (reasonText) parts.push(reasonText);
|
||||
return parts.join(" · ");
|
||||
}
|
||||
@@ -1679,6 +1809,12 @@ function _buildLoadDiagnosticRows(loadDiagnostics = null) {
|
||||
const updatedAtText = diagnostics.updatedAt
|
||||
? _formatTaskProfileTime(diagnostics.updatedAt)
|
||||
: "—";
|
||||
const nativeErrorText = String(
|
||||
diagnostics.hydrateNativeModuleError ||
|
||||
diagnostics.hydrateNativePreloadError ||
|
||||
diagnostics.hydrateNativeError ||
|
||||
"",
|
||||
).trim();
|
||||
|
||||
return [
|
||||
["Load 阶段", _formatLoadDiagnosticsStageLabel(diagnostics.stage)],
|
||||
@@ -1691,6 +1827,11 @@ function _buildLoadDiagnosticRows(loadDiagnostics = null) {
|
||||
["前置(除导出)", _formatDurationMs(diagnostics.preApplyOtherMs)],
|
||||
["Hydrate", _formatDurationMs(diagnostics.hydrateMs)],
|
||||
["Hydrate 细分", _formatLoadHydrateBreakdownText(diagnostics)],
|
||||
["Hydrate Native Gate", _formatNativeHydrateGateText(diagnostics)],
|
||||
["Hydrate Native 结果", _formatNativeHydrateResultText(diagnostics)],
|
||||
["Hydrate Native Module", _formatNativeHydrateModuleText(diagnostics)],
|
||||
["Hydrate Native Records", _formatDurationMs(diagnostics.hydrateNativeRecordsMs)],
|
||||
["Hydrate Native 错误", nativeErrorText || "—"],
|
||||
["Apply 调用", _formatDurationMs(diagnostics.applyInvokeMs)],
|
||||
["Apply 运行", _formatDurationMs(diagnostics.applyRuntimeMs)],
|
||||
["Load 未归因", _formatDurationMs(diagnostics.untrackedMs)],
|
||||
@@ -6507,6 +6648,26 @@ function _refreshConfigTab() {
|
||||
"bme-setting-ai-monitor-enabled",
|
||||
settings.enableAiMonitor ?? true,
|
||||
);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-graph-native-force-disable",
|
||||
settings.graphNativeForceDisable === true,
|
||||
);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-native-engine-fail-open",
|
||||
settings.nativeEngineFailOpen !== false,
|
||||
);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-graph-use-native-layout",
|
||||
settings.graphUseNativeLayout === true,
|
||||
);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-persist-use-native-delta",
|
||||
settings.persistUseNativeDelta === true,
|
||||
);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-load-use-native-hydrate",
|
||||
settings.loadUseNativeHydrate === true,
|
||||
);
|
||||
_setCheckboxValue(
|
||||
"bme-setting-hide-old-messages-enabled",
|
||||
settings.hideOldMessagesEnabled ?? false,
|
||||
@@ -6841,6 +7002,34 @@ function _refreshConfigTab() {
|
||||
settings.probRecallChance ?? 0.15,
|
||||
);
|
||||
_setInputValue("bme-setting-reflect-every", settings.reflectEveryN ?? 10);
|
||||
_setInputValue(
|
||||
"bme-setting-graph-native-layout-threshold-nodes",
|
||||
settings.graphNativeLayoutThresholdNodes ?? 280,
|
||||
);
|
||||
_setInputValue(
|
||||
"bme-setting-graph-native-layout-threshold-edges",
|
||||
settings.graphNativeLayoutThresholdEdges ?? 1600,
|
||||
);
|
||||
_setInputValue(
|
||||
"bme-setting-graph-native-layout-worker-timeout-ms",
|
||||
settings.graphNativeLayoutWorkerTimeoutMs ?? 260,
|
||||
);
|
||||
_setInputValue(
|
||||
"bme-setting-persist-native-delta-threshold-records",
|
||||
settings.persistNativeDeltaThresholdRecords ?? 20000,
|
||||
);
|
||||
_setInputValue(
|
||||
"bme-setting-persist-native-delta-threshold-structural-delta",
|
||||
settings.persistNativeDeltaThresholdStructuralDelta ?? 600,
|
||||
);
|
||||
_setInputValue(
|
||||
"bme-setting-persist-native-delta-threshold-serialized-chars",
|
||||
settings.persistNativeDeltaThresholdSerializedChars ?? 4000000,
|
||||
);
|
||||
_setInputValue(
|
||||
"bme-setting-load-native-hydrate-threshold-records",
|
||||
settings.loadNativeHydrateThresholdRecords ?? 12000,
|
||||
);
|
||||
|
||||
_setInputValue("bme-setting-llm-url", settings.llmApiUrl || "");
|
||||
_setInputValue("bme-setting-llm-key", settings.llmApiKey || "");
|
||||
@@ -6910,6 +7099,7 @@ function _refreshConfigTab() {
|
||||
_refreshPromptCardStates(settings);
|
||||
_refreshTaskProfileWorkspace(settings);
|
||||
_refreshMessageTraceWorkspace(settings);
|
||||
_refreshNativeRolloutStatusUi(settings);
|
||||
_highlightThemeChoice(settings.panelTheme || "crimson");
|
||||
_syncConfigSectionState();
|
||||
}
|
||||
@@ -6936,6 +7126,21 @@ function _bindConfigControls() {
|
||||
_patchSettings({ enableAiMonitor: checked });
|
||||
_refreshDashboard();
|
||||
});
|
||||
bindCheckbox("bme-setting-graph-native-force-disable", (checked) => {
|
||||
_patchSettings({ graphNativeForceDisable: checked });
|
||||
});
|
||||
bindCheckbox("bme-setting-native-engine-fail-open", (checked) => {
|
||||
_patchSettings({ nativeEngineFailOpen: checked });
|
||||
});
|
||||
bindCheckbox("bme-setting-graph-use-native-layout", (checked) => {
|
||||
_patchSettings({ graphUseNativeLayout: checked });
|
||||
});
|
||||
bindCheckbox("bme-setting-persist-use-native-delta", (checked) => {
|
||||
_patchSettings({ persistUseNativeDelta: checked });
|
||||
});
|
||||
bindCheckbox("bme-setting-load-use-native-hydrate", (checked) => {
|
||||
_patchSettings({ loadUseNativeHydrate: checked });
|
||||
});
|
||||
bindCheckbox("bme-setting-hide-old-messages-enabled", (checked) => {
|
||||
_patchSettings({ hideOldMessagesEnabled: checked });
|
||||
});
|
||||
@@ -7353,6 +7558,55 @@ function _bindConfigControls() {
|
||||
bindNumber("bme-setting-reflect-every", 10, 1, 200, (value) =>
|
||||
_patchSettings({ reflectEveryN: value }),
|
||||
);
|
||||
bindNumber(
|
||||
"bme-setting-graph-native-layout-threshold-nodes",
|
||||
280,
|
||||
1,
|
||||
20000,
|
||||
(value) => _patchSettings({ graphNativeLayoutThresholdNodes: value }),
|
||||
);
|
||||
bindNumber(
|
||||
"bme-setting-graph-native-layout-threshold-edges",
|
||||
1600,
|
||||
1,
|
||||
50000,
|
||||
(value) => _patchSettings({ graphNativeLayoutThresholdEdges: value }),
|
||||
);
|
||||
bindNumber(
|
||||
"bme-setting-graph-native-layout-worker-timeout-ms",
|
||||
260,
|
||||
40,
|
||||
15000,
|
||||
(value) => _patchSettings({ graphNativeLayoutWorkerTimeoutMs: value }),
|
||||
);
|
||||
bindNumber(
|
||||
"bme-setting-persist-native-delta-threshold-records",
|
||||
20000,
|
||||
0,
|
||||
200000,
|
||||
(value) => _patchSettings({ persistNativeDeltaThresholdRecords: value }),
|
||||
);
|
||||
bindNumber(
|
||||
"bme-setting-persist-native-delta-threshold-structural-delta",
|
||||
600,
|
||||
0,
|
||||
200000,
|
||||
(value) => _patchSettings({ persistNativeDeltaThresholdStructuralDelta: value }),
|
||||
);
|
||||
bindNumber(
|
||||
"bme-setting-persist-native-delta-threshold-serialized-chars",
|
||||
4000000,
|
||||
0,
|
||||
50000000,
|
||||
(value) => _patchSettings({ persistNativeDeltaThresholdSerializedChars: value }),
|
||||
);
|
||||
bindNumber(
|
||||
"bme-setting-load-native-hydrate-threshold-records",
|
||||
12000,
|
||||
0,
|
||||
200000,
|
||||
(value) => _patchSettings({ loadNativeHydrateThresholdRecords: value }),
|
||||
);
|
||||
|
||||
const llmPresetSelect = document.getElementById("bme-llm-preset-select");
|
||||
if (llmPresetSelect && llmPresetSelect.dataset.bmeBound !== "true") {
|
||||
@@ -8282,6 +8536,7 @@ function _getMessageTraceWorkspaceState(settings = _getSettings?.() || {}) {
|
||||
runtimeDebug: null,
|
||||
};
|
||||
const runtimeDebug = panelDebug.runtimeDebug || {};
|
||||
const graphPersistence = _getGraphPersistenceSnapshot();
|
||||
|
||||
return {
|
||||
settings,
|
||||
@@ -8289,7 +8544,12 @@ function _getMessageTraceWorkspaceState(settings = _getSettings?.() || {}) {
|
||||
runtimeDebug,
|
||||
recallInjection: runtimeDebug?.injections?.recall || null,
|
||||
graphLayout: runtimeDebug?.graphLayout || null,
|
||||
persistDelta: runtimeDebug?.graphPersistence?.persistDelta || null,
|
||||
persistDelta:
|
||||
graphPersistence?.persistDelta || runtimeDebug?.graphPersistence?.persistDelta || null,
|
||||
loadDiagnostics:
|
||||
graphPersistence?.loadDiagnostics ||
|
||||
runtimeDebug?.graphPersistence?.loadDiagnostics ||
|
||||
null,
|
||||
messageTrace: runtimeDebug?.messageTrace || null,
|
||||
recallLlmRequest: runtimeDebug?.taskLlmRequests?.recall || null,
|
||||
recallPromptBuild: runtimeDebug?.taskPromptBuilds?.recall || null,
|
||||
@@ -8315,6 +8575,7 @@ function _renderMessageTraceWorkspace(state) {
|
||||
state.recallInjection?.updatedAt,
|
||||
state.graphLayout?.updatedAt,
|
||||
state.persistDelta?.updatedAt,
|
||||
state.loadDiagnostics?.updatedAt,
|
||||
state.recallLlmRequest?.updatedAt,
|
||||
state.extractLlmRequest?.updatedAt,
|
||||
state.extractPromptBuild?.updatedAt,
|
||||
@@ -8353,6 +8614,9 @@ function _renderMessageTraceWorkspace(state) {
|
||||
<div class="bme-config-card">
|
||||
${_renderPersistDeltaTraceCard(state)}
|
||||
</div>
|
||||
<div class="bme-config-card">
|
||||
${_renderHydrateNativeTraceCard(state)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -9060,6 +9324,97 @@ function _renderPersistDeltaTraceCard(state) {
|
||||
`;
|
||||
}
|
||||
|
||||
function _renderHydrateNativeTraceCard(state) {
|
||||
const diagnostics = _readPersistenceDiagnosticObject(state.loadDiagnostics);
|
||||
if (!diagnostics) {
|
||||
return `
|
||||
<div class="bme-config-card-title">Hydrate / Native 诊断</div>
|
||||
<div class="bme-config-help">
|
||||
还没有 hydrate 诊断快照。等图谱完成一次真实加载后,这里会显示 load hydrate 是否命中 native、是否被 gate 拦截,以及 preload / module / fallback 状态。
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
const errorText = String(
|
||||
diagnostics.hydrateNativeModuleError ||
|
||||
diagnostics.hydrateNativePreloadError ||
|
||||
diagnostics.hydrateNativeError ||
|
||||
diagnostics.error ||
|
||||
"",
|
||||
).trim();
|
||||
|
||||
return `
|
||||
<div class="bme-config-card-head">
|
||||
<div>
|
||||
<div class="bme-config-card-title">Hydrate / Native 诊断</div>
|
||||
<div class="bme-config-card-subtitle">
|
||||
记录最近一次图谱加载的 hydrate 是否尝试 native、是否命中、以及 preload / module / fallback 明细。
|
||||
</div>
|
||||
</div>
|
||||
<span class="bme-task-pill">${_escHtml(_formatTaskProfileTime(diagnostics.updatedAt))}</span>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv">
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Load 阶段</span>
|
||||
<strong>${_escHtml(_formatLoadDiagnosticsStageLabel(diagnostics.stage))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Load 来源</span>
|
||||
<strong>${_escHtml(String(diagnostics.source || diagnostics.statusLabel || "—"))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Load 状态</span>
|
||||
<strong>${_escHtml(
|
||||
diagnostics.success === true
|
||||
? "成功"
|
||||
: diagnostics.success === false
|
||||
? "失败"
|
||||
: "未知",
|
||||
)}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Hydrate Native Gate</span>
|
||||
<strong>${_escHtml(_formatNativeHydrateGateText(diagnostics))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Hydrate Native 结果</span>
|
||||
<strong>${_escHtml(_formatNativeHydrateResultText(diagnostics))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Preload</span>
|
||||
<strong>${_escHtml(String(diagnostics.hydrateNativePreloadStatus || "—"))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Module</span>
|
||||
<strong>${_escHtml(_formatNativeHydrateModuleText(diagnostics))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Load / Hydrate</span>
|
||||
<strong>${_escHtml(
|
||||
`${_formatDurationMs(diagnostics.totalMs)} / ${_formatDurationMs(diagnostics.hydrateMs)}`,
|
||||
)}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Hydrate 细分</span>
|
||||
<strong>${_escHtml(_formatLoadHydrateBreakdownText(diagnostics))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>Native Records</span>
|
||||
<strong>${_escHtml(_formatDurationMs(diagnostics.hydrateNativeRecordsMs))}</strong>
|
||||
</div>
|
||||
<div class="bme-ai-monitor-kv__row">
|
||||
<span>未归因</span>
|
||||
<strong>${_escHtml(_formatDurationMs(diagnostics.untrackedMs))}</strong>
|
||||
</div>
|
||||
</div>
|
||||
${_renderMessageTraceTextBlock(
|
||||
"Hydrate / native error",
|
||||
errorText,
|
||||
"当前没有 hydrate / native error。",
|
||||
)}
|
||||
`;
|
||||
}
|
||||
|
||||
function _renderMessageTraceTextBlock(title, text, emptyText = "暂无内容") {
|
||||
const normalized = String(text || "").trim();
|
||||
return `
|
||||
@@ -10269,6 +10624,15 @@ function _renderTaskDebugGraphPersistenceCard(graphPersistence) {
|
||||
}
|
||||
|
||||
const persistDelta = graphPersistence.persistDelta || null;
|
||||
const loadDiagnostics = _readPersistenceDiagnosticObject(
|
||||
graphPersistence.loadDiagnostics,
|
||||
);
|
||||
const hydrateNativeError = String(
|
||||
loadDiagnostics?.hydrateNativeModuleError ||
|
||||
loadDiagnostics?.hydrateNativePreloadError ||
|
||||
loadDiagnostics?.hydrateNativeError ||
|
||||
"",
|
||||
).trim();
|
||||
|
||||
return `
|
||||
<div class="bme-config-card-head">
|
||||
@@ -10375,6 +10739,30 @@ function _renderTaskDebugGraphPersistenceCard(graphPersistence) {
|
||||
: "—",
|
||||
)}</span>
|
||||
</div>
|
||||
<div class="bme-debug-kv-item">
|
||||
<span class="bme-debug-kv-key">Hydrate Native Gate</span>
|
||||
<span class="bme-debug-kv-value">${_escHtml(
|
||||
_formatNativeHydrateGateText(loadDiagnostics),
|
||||
)}</span>
|
||||
</div>
|
||||
<div class="bme-debug-kv-item">
|
||||
<span class="bme-debug-kv-key">Hydrate Native 结果</span>
|
||||
<span class="bme-debug-kv-value">${_escHtml(
|
||||
_formatNativeHydrateResultText(loadDiagnostics),
|
||||
)}</span>
|
||||
</div>
|
||||
<div class="bme-debug-kv-item">
|
||||
<span class="bme-debug-kv-key">Hydrate Native Module</span>
|
||||
<span class="bme-debug-kv-value">${_escHtml(
|
||||
_formatNativeHydrateModuleText(loadDiagnostics),
|
||||
)}</span>
|
||||
</div>
|
||||
<div class="bme-debug-kv-item">
|
||||
<span class="bme-debug-kv-key">Hydrate Native 错误</span>
|
||||
<span class="bme-debug-kv-value">${_escHtml(
|
||||
hydrateNativeError || "—",
|
||||
)}</span>
|
||||
</div>
|
||||
<div class="bme-debug-kv-item">
|
||||
<span class="bme-debug-kv-key">Persist Delta 路径</span>
|
||||
<span class="bme-debug-kv-value">${_escHtml(String(persistDelta?.path || "—"))}</span>
|
||||
@@ -12723,6 +13111,7 @@ function _patchSettings(patch = {}, options = {}) {
|
||||
if (options.refreshTheme)
|
||||
_highlightThemeChoice(settings.panelTheme || "crimson");
|
||||
_refreshCloudStorageModeUi(settings);
|
||||
_refreshNativeRolloutStatusUi(settings);
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user