Ignore WS heartbeats and reject empty chat messages (#32)
## Summary - Closes #31 - Ignore WebSocket `type: ping` heartbeats so keepalives no longer create conversations or hit title/LLM pipelines - Reject empty/whitespace user messages in both chat consumers, `PromptSerializer`, and REST conversation prompt POST ## Test plan - [x] `UserPromptGuardTestCase`, `PromptSerializerTestCase` blank/whitespace cases - [x] `WebSocketReceiveGuardTestCase` ping ignore + empty message rejection (both WS routes) - [ ] Deploy to beta; leave idle tab open and confirm no new rogue conversations - [ ] Confirm normal chat send still works Related FE: https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/51Reviewed-on: #32
This commit was merged in pull request #32.
This commit is contained in:
1 parent
5d5b448868
commit
ee3d47c8c3
8 files changed
+170
-4
No files matched your search
@@ -22,6 +22,7 @@ from .services.title_generator import title_generator
|
||||
from .services.moderation_classifier import moderation_classifier, ModerationLabel
|
||||
from .services.prompt_classifier.prompt_classifier import PromptClassifier, PromptType
|
||||
from .services.data_analysis_service import AsyncDataAnalysisService
|
||||
from .utils import has_usable_user_prompt, is_heartbeat_payload, normalize_user_message
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -288,13 +289,29 @@ class ChatConsumerGraph(AsyncWebsocketConsumer):
|
||||
print("Text Data: ", text_data)
|
||||
if text_data:
|
||||
data = json.loads(text_data)
|
||||
# Keepalive frames must not create conversations or hit the LLM.
|
||||
if is_heartbeat_payload(data):
|
||||
return
|
||||
|
||||
model = data.get("modelName", "Turbo")
|
||||
message = data.get("message", None)
|
||||
message = normalize_user_message(data.get("message", None))
|
||||
conversation_id = data.get("conversation_id", None)
|
||||
email = data.get("email", None)
|
||||
file = data.get("file", None)
|
||||
file_type = data.get("fileType", "")
|
||||
|
||||
|
||||
if not has_usable_user_prompt(message, file):
|
||||
logger.info("Ignoring websocket payload with empty message")
|
||||
await self.send_json_message(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "error",
|
||||
"content": "Message text cannot be empty.",
|
||||
}
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
if not conversation_id:
|
||||
title = await title_generator.generate_async(message)
|
||||
conversation_id = await create_conversation(message, email, title)
|
||||
|
||||
Reference in new issue
Block a user