feat(chat): adopt order=latest for transcript initial load and paging (issue #859) (#870)

Backend now supports order=latest on GET /api/sessions/{id}/messages
(offset measured back from the newest message, page returned
chronologically). The mobile initial load previously computed its anchor
from a possibly-stale session-list message_count, which landed the first
page at the wrong position (dropped history or a duplicated tail).

- HermesApiService.getSessionMessages: add @Query("order")
- Initial load requests the newest page directly (order=latest, offset=0)
  and drops the fetchServerMessageCount offset math; legacy backends
  (no pagination echo) fall back to the count-based anchor
- Backward paging advances the from-end offset by a full page; a short
  page marks the oldest boundary and stops pagination
- ChatMessage stable keys under latest paging use the server's
  AUTOINCREMENT row id (from-end positions shift as the transcript
  grows and would collide across hydrations)
- syncCurrentSession refetches the newest page and merges by row id
  with a logical-content fallback for re-keyed rows

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-08-10 14:40:20 +03:00
1 parent ea8fead087
commit 4a034684bb
4 files changed
+392 -32

No files matched your search

@@ -187,6 +187,10 @@ interface HermesApiService {
@Path("id", encoded = true) sessionId: String,
@Query("limit") limit: Int? = null,
@Query("offset") offset: Int = 0,
// Issue #859: order=latest pages back from the newest message (offset
// measured from the end, page returned chronologically). Omitted on
// legacy backends that don't know the param — they ignore it.
@Query("order") order: String? = null,
@Query("include_compacted") includeCompacted: Boolean? = true,
): Response<SessionMessagesResponse>