fix(api): add pagination to GET /api/sessions/{id}/messages

The session messages endpoint returned ALL messages in a single
response with no limit/offset. Sessions with 500+ messages produced
1.2-1.6 MB JSON payloads, causing GIL starvation and WebSocket
timeouts on the Desktop client (#60155).

Add optional limit/offset query params to both the API endpoint and
SessionDB.get_messages(). Limit clamped to 500 max per page. Response
now includes a pagination object with limit/offset/returned count.

Backward compatible: callers that omit limit get the old behavior
(all messages).

Closes #60155
This commit is contained in:
mahdiwafy 2026-07-07 23:01:58 +07:00
parent 009b42d008
commit d58396b154
2 changed files with 36 additions and 9 deletions

View file

@ -8121,15 +8121,30 @@ async def get_session_latest_descendant(session_id: str):
}
@app.get("/api/sessions/{session_id}/messages")
async def get_session_messages(session_id: str, profile: Optional[str] = None):
async def get_session_messages(
session_id: str,
profile: Optional[str] = None,
limit: Optional[int] = None,
offset: int = 0,
):
db = _open_session_db_for_profile(profile)
try:
sid = db.resolve_session_id(session_id)
if not sid:
raise HTTPException(status_code=404, detail="Session not found")
sid = db.resolve_resume_session_id(sid)
messages = db.get_messages(sid)
return {"session_id": sid, "messages": messages}
# Clamp limit to prevent abuse (max 500 per page)
_limit = min(limit, 500) if limit is not None else None
messages = db.get_messages(sid, limit=_limit, offset=offset)
return {
"session_id": sid,
"messages": messages,
"pagination": {
"limit": _limit,
"offset": offset,
"returned": len(messages),
},
}
finally:
db.close()