Add virtualized chat pagination (#1080)
This commit is contained in:
@@ -452,7 +452,7 @@ export function updateSessionStats(id: string): void {
|
||||
export function getSessionDetailPaginated(
|
||||
id: string,
|
||||
offset = 0,
|
||||
limit = 500,
|
||||
limit = 300,
|
||||
): PaginatedSessionDetailResult | null {
|
||||
if (!isSqliteAvailable()) {
|
||||
return null
|
||||
|
||||
@@ -182,10 +182,13 @@ groupChatRoutes.get('/api/hermes/group-chat/rooms/:roomId', async (ctx) => {
|
||||
return
|
||||
}
|
||||
|
||||
const messages = chatServer.getStorage().getMessages(ctx.params.roomId)
|
||||
const offset = ctx.query.offset ? Math.max(0, parseInt(ctx.query.offset as string, 10) || 0) : 0
|
||||
const limit = ctx.query.limit ? Math.max(1, parseInt(ctx.query.limit as string, 10) || 300) : 300
|
||||
const messages = chatServer.getStorage().getMessages(ctx.params.roomId, limit, offset)
|
||||
const total = chatServer.getStorage().getMessageCount(ctx.params.roomId)
|
||||
const agents = chatServer.getStorage().getRoomAgents(ctx.params.roomId)
|
||||
const members = chatServer.getStorage().getRoomMembers(ctx.params.roomId)
|
||||
ctx.body = { room, messages, agents, members }
|
||||
ctx.body = { room, messages, agents, members, total, offset, limit, hasMore: offset + messages.length < total }
|
||||
})
|
||||
|
||||
// List rooms
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user