fix: reduce workbench session list load

This commit is contained in:
lyon
2026-06-19 21:52:42 +08:00
parent 95797da17f
commit 7544b52c27
2 changed files with 22 additions and 3 deletions
+6 -1
View File
@@ -17,6 +17,7 @@ import { createWorkbenchReadModel } from "./workbench-read-model.ts";
import { createWorkbenchTurnProjection, RUNNING_STATUSES, TERMINAL_STATUSES } from "./workbench-turn-projection.ts";
const DEFAULT_PAGE_LIMIT = 50;
const DEFAULT_SESSION_LIST_LIMIT = 8;
const MAX_PAGE_LIMIT = 100;
const DEFAULT_WORKBENCH_SSE_HEARTBEAT_MS = 15000;
export async function handleWorkbenchReadModelHttp(request, response, url, options = {}) {
@@ -307,7 +308,7 @@ async function authenticateWorkbenchRead(request, response, options) {
async function handleWorkbenchSessionList(response, url, options, actor) {
if (url.searchParams.has("projectId") || url.searchParams.has("workspaceId")) return sendJson(response, 400, workbenchError("workbench_authority_removed", "Workbench session list is keyed by sessionId only."));
const limit = boundedLimit(url.searchParams.get("limit"));
const limit = boundedSessionListLimit(url.searchParams.get("limit"));
const offset = cursorOffset(url.searchParams.get("cursor") ?? url.searchParams.get("after"));
const includeSessionId = safeSessionId(url.searchParams.get("includeSessionId"));
const includeRouteId = includeSessionId ?? safeConversationId(url.searchParams.get("includeSessionId"));
@@ -924,6 +925,10 @@ function boundedLimit(value) {
return Math.min(MAX_PAGE_LIMIT, parsePositiveInteger(value, DEFAULT_PAGE_LIMIT));
}
function boundedSessionListLimit(value) {
return Math.min(MAX_PAGE_LIMIT, parsePositiveInteger(value, DEFAULT_SESSION_LIST_LIMIT));
}
function cursorOffset(value) {
const text = textValue(value);
if (!text) return 0;
+16 -2
View File
@@ -21,7 +21,7 @@ const TRACE_HYDRATION_MAX_ATTEMPTS = 3;
const TRACE_HYDRATION_RETRY_DELAY_MS = 700;
const ACTIVE_TURN_GAP_DELAY_MS = 1_000;
const ACTIVE_TURN_GAP_MAX_ATTEMPTS = 12;
const SESSION_LIST_PAGE_LIMIT = 20;
const SESSION_LIST_PAGE_LIMIT = 8;
interface HydrateOptions {
sessionId?: string | null;
@@ -68,6 +68,7 @@ export const useWorkbenchStore = defineStore("workbench", () => {
let realtimeKey = "";
let realtimeGapTimer: number | null = null;
let activeTurnGapTimer: number | null = null;
const sessionListRefreshInFlight = new Map<string, Promise<void>>();
const activeSession = computed(() => selectActiveSession(serverState.value, explicitSessionId.value));
const activeSessionSelectionSource = computed(() => activeSelectionSource.value);
@@ -233,7 +234,20 @@ export const useWorkbenchStore = defineStore("workbench", () => {
}
async function refreshSessions(includeSessionId: string | null = activeSessionId.value): Promise<void> {
const response = await api.workbench.sessions({ includeSessionId, limit: currentSessionListLimit() });
const requestIncludeSessionId = firstNonEmptyString(includeSessionId);
const requestLimit = currentSessionListLimit();
const requestKey = `${requestIncludeSessionId ?? ""}|${requestLimit}`;
const existing = sessionListRefreshInFlight.get(requestKey);
if (existing) return existing;
const refresh = refreshSessionsNow(requestIncludeSessionId, requestLimit).finally(() => {
if (sessionListRefreshInFlight.get(requestKey) === refresh) sessionListRefreshInFlight.delete(requestKey);
});
sessionListRefreshInFlight.set(requestKey, refresh);
return refresh;
}
async function refreshSessionsNow(includeSessionId: string | null, limit: number): Promise<void> {
const response = await api.workbench.sessions({ includeSessionId, limit });
if (response.ok) {
const listed = workbenchSessionsFromPayload(response.data);
const activeSeed = activeSessionListSeed();