Add explicit auto compression toggle

This commit is contained in:
Youzini-afk
2026-04-04 16:14:26 +08:00
parent f367b8989c
commit 5d11a736ee
5 changed files with 78 additions and 15 deletions

View File

@@ -473,6 +473,7 @@ const defaultSettings = {
enableReflection: true, // 启用反思 enableReflection: true, // 启用反思
reflectEveryN: 10, // 每 N 次提取后反思 reflectEveryN: 10, // 每 N 次提取后反思
consolidationAutoMinNewNodes: 2, consolidationAutoMinNewNodes: 2,
enableAutoCompression: true,
compressionEveryN: 10, compressionEveryN: 10,
// UI 面板 // UI 面板
@@ -2705,6 +2706,18 @@ function migrateLegacyAutoMaintenanceSettings(loaded = {}) {
50, 50,
); );
} }
if (!Object.prototype.hasOwnProperty.call(migrated, "enableAutoCompression")) {
const parsedEveryN = Math.floor(Number(migrated.compressionEveryN));
migrated.enableAutoCompression = !(
Number.isFinite(parsedEveryN) && parsedEveryN <= 0
);
}
if (
Object.prototype.hasOwnProperty.call(migrated, "compressionEveryN") &&
Math.floor(Number(migrated.compressionEveryN)) <= 0
) {
migrated.compressionEveryN = defaultSettings.compressionEveryN;
}
delete migrated.maintenanceAutoMinNewNodes; delete migrated.maintenanceAutoMinNewNodes;
return migrated; return migrated;
} }
@@ -5046,15 +5059,21 @@ function evaluateAutoCompressionSchedule(
currentExtractionCount, currentExtractionCount,
settings = {}, settings = {},
) { ) {
const everyN = clampInt(settings.compressionEveryN, 10, 0, 500); const enabled = settings.enableAutoCompression !== false;
const everyN = clampInt(
settings.compressionEveryN,
defaultSettings.compressionEveryN,
1,
500,
);
const safeExtractionCount = Math.max(0, Number(currentExtractionCount) || 0); const safeExtractionCount = Math.max(0, Number(currentExtractionCount) || 0);
if (everyN <= 0) { if (!enabled) {
return { return {
scheduled: false, scheduled: false,
everyN, everyN,
nextExtractionCount: null, nextExtractionCount: null,
reason: "自动压缩已关闭", reason: "自动压缩开关已关闭",
}; };
} }
@@ -7266,20 +7285,19 @@ async function handleExtractionSuccess(
typeof evaluateAutoCompressionSchedule === "function" typeof evaluateAutoCompressionSchedule === "function"
? evaluateAutoCompressionSchedule ? evaluateAutoCompressionSchedule
: (currentCount, localSettings = {}) => { : (currentCount, localSettings = {}) => {
const parsedEveryN = Math.floor( const enabled = localSettings?.enableAutoCompression !== false;
Number(localSettings?.compressionEveryN), const parsedEveryN = Math.floor(Number(localSettings?.compressionEveryN));
);
const everyN = const everyN =
Number.isFinite(parsedEveryN) && parsedEveryN >= 0 Number.isFinite(parsedEveryN) && parsedEveryN >= 1
? Math.min(500, parsedEveryN) ? Math.min(500, parsedEveryN)
: 10; : 10;
const safeCount = Math.max(0, Number(currentCount) || 0); const safeCount = Math.max(0, Number(currentCount) || 0);
if (everyN <= 0) { if (!enabled) {
return { return {
scheduled: false, scheduled: false,
everyN, everyN,
nextExtractionCount: null, nextExtractionCount: null,
reason: "自动压缩已关闭", reason: "自动压缩开关已关闭",
}; };
} }
const remainder = safeCount % everyN; const remainder = safeCount % everyN;

View File

@@ -939,6 +939,21 @@
type="checkbox" type="checkbox"
/> />
</label> </label>
<label
class="bme-toggle-item"
for="bme-setting-auto-compression-enabled"
>
<span class="bme-toggle-copy">
<span class="bme-toggle-title">启用自动压缩</span>
<span class="bme-toggle-desc"
>按提取周期做层级压缩,减少同类记忆越积越散。</span
>
</span>
<input
id="bme-setting-auto-compression-enabled"
type="checkbox"
/>
</label>
<label <label
class="bme-toggle-item" class="bme-toggle-item"
for="bme-setting-prob-recall-enabled" for="bme-setting-prob-recall-enabled"
@@ -1936,14 +1951,20 @@
</div> </div>
</div> </div>
<div class="bme-config-card"> <div
class="bme-config-card bme-guarded-card"
data-guard-settings="enableAutoCompression"
>
<div class="bme-config-card-head"> <div class="bme-config-card-head">
<div> <div>
<div class="bme-config-card-title">自动压缩周期</div> <div class="bme-config-card-title">自动压缩周期</div>
<div class="bme-config-card-subtitle"> <div class="bme-config-card-subtitle">
按提取次数计数;到周期点时才尝试自动压缩。填 0 表示关闭。 按提取次数计数;只有到周期点时才尝试自动压缩。
</div> </div>
</div> </div>
<div class="bme-config-guard-note">
在“功能开关”中启用后生效。
</div>
</div> </div>
<div class="bme-config-row"> <div class="bme-config-row">
<label for="bme-setting-compression-every" <label for="bme-setting-compression-every"
@@ -1953,7 +1974,7 @@
id="bme-setting-compression-every" id="bme-setting-compression-every"
class="bme-config-input" class="bme-config-input"
type="number" type="number"
min="0" min="1"
max="500" max="500"
/> />
</div> </div>

View File

@@ -1620,6 +1620,10 @@ function _refreshConfigTab() {
"bme-setting-sleep-cycle-enabled", "bme-setting-sleep-cycle-enabled",
settings.enableSleepCycle ?? false, settings.enableSleepCycle ?? false,
); );
_setCheckboxValue(
"bme-setting-auto-compression-enabled",
settings.enableAutoCompression ?? true,
);
_setCheckboxValue( _setCheckboxValue(
"bme-setting-prob-recall-enabled", "bme-setting-prob-recall-enabled",
settings.enableProbRecall ?? false, settings.enableProbRecall ?? false,
@@ -1944,6 +1948,10 @@ function _bindConfigControls() {
_patchSettings({ enableSleepCycle: checked }); _patchSettings({ enableSleepCycle: checked });
_refreshGuardedConfigStates(); _refreshGuardedConfigStates();
}); });
bindCheckbox("bme-setting-auto-compression-enabled", (checked) => {
_patchSettings({ enableAutoCompression: checked });
_refreshGuardedConfigStates();
});
bindCheckbox("bme-setting-prob-recall-enabled", (checked) => { bindCheckbox("bme-setting-prob-recall-enabled", (checked) => {
_patchSettings({ enableProbRecall: checked }); _patchSettings({ enableProbRecall: checked });
_refreshGuardedConfigStates(); _refreshGuardedConfigStates();

View File

@@ -126,6 +126,7 @@ assert.equal(defaultSettings.injectDepth, 9999);
assert.equal(defaultSettings.enabled, true); assert.equal(defaultSettings.enabled, true);
assert.equal(defaultSettings.enableReflection, true); assert.equal(defaultSettings.enableReflection, true);
assert.equal(defaultSettings.consolidationAutoMinNewNodes, 2); assert.equal(defaultSettings.consolidationAutoMinNewNodes, 2);
assert.equal(defaultSettings.enableAutoCompression, true);
assert.equal(defaultSettings.compressionEveryN, 10); assert.equal(defaultSettings.compressionEveryN, 10);
assert.equal("maintenanceAutoMinNewNodes" in defaultSettings, false); assert.equal("maintenanceAutoMinNewNodes" in defaultSettings, false);
assert.equal(defaultSettings.embeddingTransportMode, "direct"); assert.equal(defaultSettings.embeddingTransportMode, "direct");
@@ -138,7 +139,17 @@ const migratedSettings = mergePersistedSettings({
maintenanceAutoMinNewNodes: 7, maintenanceAutoMinNewNodes: 7,
}); });
assert.equal(migratedSettings.consolidationAutoMinNewNodes, 7); assert.equal(migratedSettings.consolidationAutoMinNewNodes, 7);
assert.equal(migratedSettings.enableAutoCompression, true);
assert.equal(migratedSettings.compressionEveryN, 10); assert.equal(migratedSettings.compressionEveryN, 10);
assert.equal("maintenanceAutoMinNewNodes" in migratedSettings, false); assert.equal("maintenanceAutoMinNewNodes" in migratedSettings, false);
const migratedLegacyCompressionDisabled = mergePersistedSettings({
compressionEveryN: 0,
});
assert.equal(migratedLegacyCompressionDisabled.enableAutoCompression, false);
assert.equal(
migratedLegacyCompressionDisabled.compressionEveryN,
defaultSettings.compressionEveryN,
);
console.log("default-settings tests passed"); console.log("default-settings tests passed");

View File

@@ -2679,7 +2679,8 @@ async function testAutoConsolidationRunsOnHighDuplicateRiskSingleNode() {
enableConsolidation: true, enableConsolidation: true,
consolidationAutoMinNewNodes: 2, consolidationAutoMinNewNodes: 2,
consolidationThreshold: 0.85, consolidationThreshold: 0.85,
compressionEveryN: 0, enableAutoCompression: false,
compressionEveryN: 10,
enableSynopsis: false, enableSynopsis: false,
enableReflection: false, enableReflection: false,
enableSleepCycle: false, enableSleepCycle: false,
@@ -2706,7 +2707,7 @@ async function testAutoConsolidationRunsOnHighDuplicateRiskSingleNode() {
assert.equal(effects.batchStatus.autoCompressionScheduled, false); assert.equal(effects.batchStatus.autoCompressionScheduled, false);
assert.match( assert.match(
effects.batchStatus.autoCompressionSkippedReason, effects.batchStatus.autoCompressionSkippedReason,
/自动压缩已关闭/, /自动压缩.*已关闭/,
); );
} }
@@ -2756,7 +2757,8 @@ async function testAutoConsolidationSkipsLowRiskSingleNode() {
enableConsolidation: true, enableConsolidation: true,
consolidationAutoMinNewNodes: 2, consolidationAutoMinNewNodes: 2,
consolidationThreshold: 0.85, consolidationThreshold: 0.85,
compressionEveryN: 0, enableAutoCompression: false,
compressionEveryN: 10,
enableSynopsis: false, enableSynopsis: false,
enableReflection: false, enableReflection: false,
enableSleepCycle: false, enableSleepCycle: false,
@@ -2822,6 +2824,7 @@ async function testAutoCompressionRunsOnlyOnConfiguredInterval() {
8, 8,
{ {
enableConsolidation: false, enableConsolidation: false,
enableAutoCompression: true,
compressionEveryN: 10, compressionEveryN: 10,
enableSynopsis: false, enableSynopsis: false,
enableReflection: false, enableReflection: false,
@@ -2873,6 +2876,7 @@ async function testAutoCompressionSkipsWhenNotScheduledOrNoCandidates() {
9, 9,
{ {
enableConsolidation: false, enableConsolidation: false,
enableAutoCompression: true,
compressionEveryN: 10, compressionEveryN: 10,
enableSynopsis: false, enableSynopsis: false,
enableReflection: false, enableReflection: false,
@@ -2930,6 +2934,7 @@ async function testAutoCompressionSkipsWhenNotScheduledOrNoCandidates() {
10, 10,
{ {
enableConsolidation: false, enableConsolidation: false,
enableAutoCompression: true,
compressionEveryN: 10, compressionEveryN: 10,
enableSynopsis: false, enableSynopsis: false,
enableReflection: false, enableReflection: false,