fix(sessions): honor load-time maintenance config

This commit is contained in:
Peter Steinberger
2026-04-25 03:52:19 +01:00
parent 26f06afb90
commit 355c92d69b
3 changed files with 52 additions and 2 deletions

View File

@@ -67,6 +67,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Sessions: honor configured `session.maintenance` settings during load-time maintenance instead of falling back to default entry caps. Fixes #71356. Thanks @comolago.
- Browser/sandbox: pass the resolved `browser.ssrfPolicy` into sandbox browser bridges and refresh cached bridges when the effective policy changes, so sandboxed browser navigation honors private-network opt-ins. Fixes #45153 and #57055. Thanks @jzakirov, @zuoanCo, and @kybrcore.
- Browser/proxy: keep Gateway/provider proxy environment variables from proxying the OpenClaw-managed browser, so `HTTP_PROXY` and `HTTPS_PROXY` no longer block ordinary browser navigation. Fixes #71358. Thanks @Sanjays2402.
- Dashboard/Windows: open Control UI and OAuth URLs through the system URL handler without `cmd.exe` parsing or PATH-based `rundll32` lookup, and reject non-HTTP browser-open inputs. Fixes #71098. Thanks @Sanjays2402.

View File

@@ -8,10 +8,10 @@ import {
setSerializedSessionStore,
writeSessionStoreCache,
} from "./store-cache.js";
import { resolveMaintenanceConfig } from "./store-maintenance-runtime.js";
import {
capEntryCount,
pruneStaleEntries,
resolveMaintenanceConfigFromInput,
type ResolvedSessionMaintenanceConfig,
} from "./store-maintenance.js";
import { applySessionStoreMigrations } from "./store-migrations.js";
@@ -128,7 +128,7 @@ export function loadSessionStore(
applySessionStoreMigrations(store);
normalizeSessionStore(store);
const maintenance = opts.maintenanceConfig ?? resolveMaintenanceConfigFromInput();
const maintenance = opts.maintenanceConfig ?? resolveMaintenanceConfig();
if (maintenance.mode === "enforce" && Object.keys(store).length > maintenance.maxEntries) {
const beforeCount = Object.keys(store).length;
const pruned = pruneStaleEntries(store, maintenance.pruneAfterMs, { log: false });

View File

@@ -287,6 +287,55 @@ describe("Integration: saveSessionStore with pruning", () => {
expect(loaded.newest).toBeDefined();
});
it("loadSessionStore honors configured maxEntries without an explicit override", async () => {
mockLoadConfig.mockReturnValue({
session: {
maintenance: {
mode: "enforce",
pruneAfter: "365d",
maxEntries: 1000,
rotateBytes: 10_485_760,
},
},
});
const now = Date.now();
const store = Object.fromEntries(
Array.from({ length: 501 }, (_, index) => [`session-${index}`, makeEntry(now - index)]),
);
await fs.writeFile(storePath, JSON.stringify(store), "utf-8");
const loaded = loadSessionStore(storePath, { skipCache: true });
expect(Object.keys(loaded)).toHaveLength(501);
});
it("loadSessionStore honors configured warn mode without an explicit override", async () => {
mockLoadConfig.mockReturnValue({
session: {
maintenance: {
mode: "warn",
pruneAfter: "365d",
maxEntries: 1,
rotateBytes: 10_485_760,
},
},
});
const now = Date.now();
const store: Record<string, SessionEntry> = {
oldest: makeEntry(now - DAY_MS),
newest: makeEntry(now),
};
await fs.writeFile(storePath, JSON.stringify(store), "utf-8");
const loaded = loadSessionStore(storePath, { skipCache: true });
expect(Object.keys(loaded)).toHaveLength(2);
expect(loaded.oldest).toBeDefined();
expect(loaded.newest).toBeDefined();
});
it("archives transcript files for entries evicted by maxEntries capping", async () => {
applyCappedMaintenanceConfig(mockLoadConfig);