Spaces:
Sleeping
Sleeping
File size: 3,773 Bytes
b336134 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | """
WebSocket endpoint β receives natural-language commands, returns results.
Protocol:
Client β Server: {"command": "salary ko 10% badhao"}
Server β Client: {"status": "success|error|unresolved", "message": "...", "diff": {...}, "suggestions": [...]}
"""
from __future__ import annotations
import asyncio
from fastapi import WebSocket, WebSocketDisconnect
from core.parser.fallback import parse_intent_hybrid
from core.validator import validate_intent
from core.execution.mvcc_executor import execute_mvcc_command
from core.column_registry import column_registry
from services import session_manager, audit_service
async def websocket_handler(ws: WebSocket, session_id: str) -> None:
await ws.accept()
# Verify session exists
meta = session_manager.get(session_id)
if meta is None:
await ws.send_json({
"status": "error",
"message": "Session nahi mila. Pehle file upload karo.",
})
await ws.close()
return
try:
while True:
# ββ Receive command βββββββββββββββββββββββββββββββββββββ
data = await ws.receive_json()
command: str = data.get("command", "").strip()
if not command:
await ws.send_json({
"status": "error",
"message": "Empty command",
})
continue
# ββ Parse intent ββββββββββββββββββββββββββββββββββββββββ
intent = parse_intent_hybrid(session_id, command)
if intent is None:
# Unresolved β suggest available columns
cols = column_registry.get_columns(session_id)
await ws.send_json({
"status": "unresolved",
"message": "Command samajh nahi aaya. Column ka naam check karo.",
"suggestions": cols,
})
continue
# ββ Validate ββββββββββββββββββββββββββββββββββββββββββββ
error = validate_intent(session_id, intent)
if error:
await ws.send_json({
"status": "error",
"message": error,
})
continue
# ββ Execute (offload to thread for large files) βββββββββ
try:
result = await asyncio.to_thread(execute_mvcc_command, session_id, intent)
except Exception as exc:
await ws.send_json({
"status": "error",
"message": f"Execution error: {exc}",
})
continue
# ββ Audit log βββββββββββββββββββββββββββββββββββββββββββ
await audit_service.log_command(
session_id=session_id,
command=command,
intent=intent,
diff=result.get("diff"),
)
# Touch session
session_manager.touch(session_id)
# ββ Send result βββββββββββββββββββββββββββββββββββββββββ
await ws.send_json({
"status": "success",
"message": result["message"],
"diff": result.get("diff", {}),
})
except WebSocketDisconnect:
pass # Client disconnected, clean exit |