Add virtualized chat pagination (#1080)

This commit is contained in:
ekko
2026-05-28 09:34:30 +08:00
committed by GitHub
parent 21bb8385f2
commit a6b3bec29b
16 changed files with 692 additions and 161 deletions
@@ -390,16 +390,23 @@ class ChatStorage {
// ─── Messages ─────────────────────────────────────────────
getMessages(roomId: string, limit = 500): ChatMessage[] {
getMessages(roomId: string, limit = 300, offset = 0): ChatMessage[] {
const rows = (this.db()?.prepare(
'SELECT id, roomId, senderId, senderName, content, timestamp, role, tool_call_id, tool_calls, tool_name, finish_reason, reasoning, reasoning_details, reasoning_content FROM gc_messages WHERE roomId = ? ORDER BY timestamp DESC LIMIT ?'
).all(roomId, limit) || []) as any[]
'SELECT id, roomId, senderId, senderName, content, timestamp, role, tool_call_id, tool_calls, tool_name, finish_reason, reasoning, reasoning_details, reasoning_content FROM gc_messages WHERE roomId = ? ORDER BY timestamp DESC LIMIT ? OFFSET ?'
).all(roomId, limit, offset) || []) as any[]
return sortGroupMessages(rows.map(row => ({
...row,
tool_calls: parseJsonArray(row.tool_calls),
})))
}
getMessageCount(roomId: string): number {
const row = this.db()?.prepare(
'SELECT COUNT(*) as total FROM gc_messages WHERE roomId = ?'
).get(roomId) as { total: number } | undefined
return row?.total || 0
}
getMessage(messageId: string): ChatMessage | null {
const row = this.db()?.prepare(
'SELECT id, roomId, senderId, senderName, content, timestamp, role, tool_call_id, tool_calls, tool_name, finish_reason, reasoning, reasoning_details, reasoning_content FROM gc_messages WHERE id = ?'
@@ -68,6 +68,10 @@ export async function loadSessionStateFromDb(sid: string, _sessionMap: Map<strin
logger.info('[chat-run-socket] loaded session %s from DB (%d messages)', sid, messages.length)
return {
messages,
messageTotal: actualDetail?.total || messages.length,
messageLoadedCount: actualDetail?.messages.length || messages.length,
messagePageLimit: actualDetail?.limit,
hasMoreBefore: actualDetail?.hasMore || false,
isWorking: false,
events: [],
inputTokens,
@@ -334,6 +334,10 @@ export class ChatRunSocket {
socket.emit('resumed', {
session_id: sid,
messages: state.messages,
messageTotal: state.messageTotal,
messageLoadedCount: state.messageLoadedCount,
messagePageLimit: state.messagePageLimit,
hasMoreBefore: state.hasMoreBefore,
isWorking: state.isWorking,
isAborting: state.isAborting || false,
events: state.isWorking ? state.events : [],
@@ -43,6 +43,10 @@ export interface QueuedRun {
export interface SessionState {
messages: SessionMessage[]
messageTotal?: number
messageLoadedCount?: number
messagePageLimit?: number
hasMoreBefore?: boolean
isWorking: boolean
events: Array<{ event: string; data: any }>
abortController?: AbortController