refactor: message list optimizations and single messageLimit setting (#409)

* feat: message list refactoring and optimizations

* refactor: collapse 3 memory-limit settings into single messageLimit

- Replace memoryLimitHistorical/Viewport/ActiveSession with one `messageLimit` (default 200)
- Background trim derived automatically (limit * 0.6), not user-facing
- Fix stale historyLimit overriding current messageLimit on session reload
- Remove streaming cap that reduced fetch to VIEWPORT_MESSAGES during active streams
- Deduplicate detectTurns() call in TurnGroupingContext (reuse staticValue.turns)
- Zustand v3 migration: collapse old fields, preserve user-customized values
- Server: sanitize single messageLimit field (10-500)
This commit is contained in:
Bohdan Triapitsyn
2026-02-12 20:36:02 +02:00
committed by GitHub
parent 3bf0843ebb
commit 252d4bd5ab
13 changed files with 627 additions and 330 deletions
+8 -16
View File
@@ -217,14 +217,12 @@ const applyDesktopUiPreferences = (settings: DesktopSettings) => {
}
}
if (typeof settings.memoryLimitHistorical === 'number' && Number.isFinite(settings.memoryLimitHistorical)) {
store.setMemoryLimitHistorical(settings.memoryLimitHistorical);
}
if (typeof settings.memoryLimitViewport === 'number' && Number.isFinite(settings.memoryLimitViewport)) {
store.setMemoryLimitViewport(settings.memoryLimitViewport);
}
if (typeof settings.memoryLimitActiveSession === 'number' && Number.isFinite(settings.memoryLimitActiveSession)) {
store.setMemoryLimitActiveSession(settings.memoryLimitActiveSession);
// Apply server-persisted message limit. Ignore stale legacy values.
const STALE_LIMITS = new Set([90, 120, 180, 220]);
if (typeof settings.messageLimit === 'number' && Number.isFinite(settings.messageLimit)) {
if (!STALE_LIMITS.has(settings.messageLimit)) {
store.setMessageLimit(settings.messageLimit);
}
}
if (typeof settings.queueModeEnabled === 'boolean' && settings.queueModeEnabled !== queueStore.queueModeEnabled) {
@@ -644,14 +642,8 @@ const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
result.openInAppId = candidate.openInAppId;
}
if (typeof candidate.memoryLimitHistorical === 'number' && Number.isFinite(candidate.memoryLimitHistorical)) {
result.memoryLimitHistorical = candidate.memoryLimitHistorical;
}
if (typeof candidate.memoryLimitViewport === 'number' && Number.isFinite(candidate.memoryLimitViewport)) {
result.memoryLimitViewport = candidate.memoryLimitViewport;
}
if (typeof candidate.memoryLimitActiveSession === 'number' && Number.isFinite(candidate.memoryLimitActiveSession)) {
result.memoryLimitActiveSession = candidate.memoryLimitActiveSession;
if (typeof candidate.messageLimit === 'number' && Number.isFinite(candidate.messageLimit)) {
result.messageLimit = candidate.messageLimit;
}
const skillCatalogs = sanitizeSkillCatalogs(candidate.skillCatalogs);