Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions astrbot/dashboard/routes/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@

from .route import Response, Route, RouteContext

# SSE heartbeat message to keep the connection alive during long-running operations
SSE_HEARTBEAT = ": heartbeat\n\n"


@asynccontextmanager
async def track_conversation(convs: dict, conv_id: str):
Expand All @@ -40,6 +43,9 @@ async def _poll_webchat_stream_result(back_queue, username: str):
try:
result = await asyncio.wait_for(back_queue.get(), timeout=1)
except asyncio.TimeoutError:
# Return a sentinel so the caller can send an SSE heartbeat to
# keep the connection alive during long-running operations (e.g.
# context compression with reasoning models). See #6938.
return None, False
except asyncio.CancelledError:
logger.debug(f"[WebChat] 用户 {username} 断开聊天长连接。")
Expand Down Expand Up @@ -364,6 +370,11 @@ async def stream():
client_disconnected = True
break
if not result:
# Send an SSE comment as keep-alive so the client
# doesn't time out during slow backend ops like
# context compression with reasoning models (#6938).
if not client_disconnected:
yield SSE_HEARTBEAT
continue

if (
Expand Down
Loading