-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
perf(webchat): enhance message handling with proactive saving and streaming completion #6698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,6 @@ | ||
| import asyncio | ||
| import os | ||
| import time | ||
| import uuid | ||
| from collections.abc import Callable, Coroutine | ||
| from pathlib import Path | ||
| from typing import Any | ||
|
|
@@ -92,32 +91,37 @@ async def send_by_session( | |
| active_request_ids = self._webchat_queue_mgr.list_back_request_ids( | ||
| conversation_id | ||
| ) | ||
| subscription_request_ids = [ | ||
| req_id for req_id in active_request_ids if req_id.startswith("ws_sub_") | ||
| stream_request_ids = [ | ||
| req_id for req_id in active_request_ids if not req_id.startswith("ws_sub_") | ||
| ] | ||
| target_request_ids = subscription_request_ids or active_request_ids | ||
|
|
||
| if target_request_ids: | ||
| for request_id in target_request_ids: | ||
| await WebChatMessageEvent._send( | ||
| request_id, | ||
| message_chain, | ||
| session.session_id, | ||
| target_request_ids = stream_request_ids or active_request_ids | ||
|
|
||
| if not target_request_ids: | ||
| # No active streams to consume this proactive message. | ||
| # Persist directly and return to avoid creating an unused queue. | ||
| try: | ||
| await self._save_proactive_message(conversation_id, message_chain) | ||
| except Exception as e: | ||
| logger.error( | ||
| f"[WebChatAdapter] Failed to save proactive message: {e}", | ||
| exc_info=True, | ||
| ) | ||
| else: | ||
| message_id = f"active_{uuid.uuid4()!s}" | ||
| await super().send_by_session(session, message_chain) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the scenario where there are no active streams to consume a proactive message, the message is first saved via |
||
| return | ||
|
|
||
| for request_id in target_request_ids: | ||
| await WebChatMessageEvent._send( | ||
| message_id, | ||
| request_id, | ||
| message_chain, | ||
| session.session_id, | ||
| streaming=True, | ||
| emit_complete=True, | ||
| ) | ||
|
|
||
| should_persist = ( | ||
| bool(subscription_request_ids) | ||
| or not active_request_ids | ||
| or all(req_id.startswith("active_") for req_id in active_request_ids) | ||
| ) | ||
| if should_persist: | ||
| # If only passive subscription queues exist for this conversation, | ||
| # keep a proactive save as a fallback since they are not tied to | ||
| # the normal streaming persistence path. | ||
| if not stream_request_ids: | ||
| try: | ||
| await self._save_proactive_message(conversation_id, message_chain) | ||
| except Exception as e: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,6 +34,7 @@ async def _send( | |
| message: MessageChain | None, | ||
| session_id: str, | ||
| streaming: bool = False, | ||
| emit_complete: bool = False, | ||
| ) -> str | None: | ||
| request_id = str(message_id) | ||
| conversation_id = _extract_conversation_id(session_id) | ||
|
|
@@ -127,6 +128,17 @@ async def _send( | |
| else: | ||
| logger.debug(f"webchat 忽略: {comp.type}") | ||
|
|
||
| if emit_complete: | ||
| await web_chat_back_queue.put( | ||
| { | ||
| "type": "complete", | ||
| "data": data, | ||
| "streaming": streaming, | ||
| "chain_type": message.type, | ||
| "message_id": message_id, | ||
| }, | ||
| ) | ||
|
Comment on lines
+131
to
+140
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
|
||
| return data | ||
|
|
||
| async def send(self, message: MessageChain | None) -> None: | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.