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
+9 -4
View File
@@ -5,7 +5,7 @@ import type { Session, Message, Part } from "@opencode-ai/sdk/v2";
import type { PermissionRequest, PermissionResponse } from "@/types/permission";
import type { QuestionRequest } from "@/types/question";
import type { SessionStore, AttachedFile, EditPermissionMode, SyntheticContextPart } from "./types/sessionTypes";
import { getActiveSessionWindow, getMemoryLimits } from "./types/sessionTypes";
import { getMessageLimit, getBackgroundTrimLimit } from "./types/sessionTypes";
import { useSessionStore as useSessionManagementStore } from "./sessionStore";
import { useMessageStore } from "./messageStore";
@@ -292,7 +292,7 @@ export const useSessionStore = create<SessionStore>()(
get().updateViewportAnchor(previousSessionId, previousMessages.length - 1);
}
get().trimToViewportWindow(previousSessionId, getMemoryLimits().VIEWPORT_MESSAGES);
get().trimToViewportWindow(previousSessionId, getBackgroundTrimLimit());
}
}
@@ -301,12 +301,17 @@ export const useSessionStore = create<SessionStore>()(
if (id) {
const existingMessages = get().messages.get(id);
if (!existingMessages) {
const memoryState = get().sessionMemoryState.get(id);
const needsHistoryBootstrap =
!memoryState ||
memoryState.historyComplete === undefined;
if (!existingMessages || needsHistoryBootstrap) {
await get().loadMessages(id);
}
get().trimToViewportWindow(id, getActiveSessionWindow());
get().trimToViewportWindow(id, getMessageLimit());
// Analyze session messages to extract agent/model/variant choices
// This ensures context is available even when ModelControls isn't mounted