11from flask import Flask , render_template , request , redirect , url_for , abort , current_app as app
22from utils .text import time_ago , format_text , clean_text , alphanumeric_text , clean_text , sanitize_text , date_text
33from routes .asn import asn_blueprint , asn_api_v1_blueprint
4- from utils .socket import sock , broadcaster
4+ from routes .ai import ai_blueprint , ai_api_v1_blueprint
5+ from utils .socket import sock , subscriber , chat
6+ from utils .database import get_db , close_db
7+ from utils .mcp import list_tools , run_tool
58from utils .cache import cache , caching
69from utils .limiter import limiter
710from flask_compress import Compress
811from flask_talisman import Talisman
912from utils .seo import get_sitemap
1013from datetime import timedelta
1114from logging import StreamHandler
15+ from sqlalchemy import text
1216from config import Config
1317import logging
18+ import gevent
1419import atexit
15- import sass # type: ignore
20+ import json
21+ import sass
1622import sys
1723import re
18- import gevent
24+
1925from gevent import monkey
20- monkey .patch_all ()
26+ monkey .patch_all (ssl = False )
2127
2228def compile_scss ():
2329 scss_file = 'static/styles/main.scss'
@@ -162,23 +168,26 @@ def sitemap_index_xml():
162168
163169
164170 """
165- Subscriptions
171+ WebSocket
166172 """
167173
168174 # Initialize socket
169- broadcaster .init_app (app )
175+ subscriber .init_app (app )
176+ chat .init_app (app )
170177
171178 # Register socket shutdown
172- atexit .register (lambda : broadcaster .shutdown (wait = False ))
179+ atexit .register (lambda : subscriber .shutdown (wait = False ))
180+ atexit .register (lambda : chat .shutdown (wait = False ))
173181
174182 # Start socket
175- broadcaster .start ()
183+ subscriber .start ()
184+ chat .start ()
176185
177186 @sock .route ('/ws/v1/subscribe/<resource>' )
178187 def ws_v1_subscribe (ws , resource ):
179188 try :
180189 app .logger .info (f"WebSocket connected for { resource } " )
181- broadcaster .register (ws , resource = resource )
190+ subscriber .register (ws , resource = resource )
182191
183192 while True :
184193 try :
@@ -197,14 +206,41 @@ def ws_v1_subscribe(ws, resource):
197206 app .logger .error (f"WebSocket connection error for { resource } : { str (e )} " , exc_info = True )
198207 finally :
199208 app .logger .info (f"WebSocket disconnected for { resource } " )
200- broadcaster .unregister (ws , resource )
209+ subscriber .unregister (ws , resource )
210+
211+ @sock .route ('/ws/v1/chat' )
212+ def ws_v1_chat (ws ):
213+ try :
214+ app .logger .info (f"WebSocket connected for chat" )
215+ chat .register (ws )
216+
217+ while True :
218+ # Receive message from client
219+ message = ws .receive ()
220+ if not message :
221+ break
222+
223+ try :
224+ data = json .loads (message )
225+ chat .handle (ws , data )
226+
227+ except json .JSONDecodeError :
228+ ws .send (json .dumps ({'type' : 'error' , 'message' : 'Invalid JSON format' }))
229+ except Exception as e :
230+ app .logger .error ("WebSocket chat error: %s" , str (e ), exc_info = True )
231+ ws .send (json .dumps ({'type' : 'error' , 'message' : str (e )}))
232+
233+ except Exception as e :
234+ app .logger .error ("WebSocket connection error: %s" , str (e ), exc_info = True )
235+ finally :
236+ app .logger .info (f"WebSocket disconnected for chat" )
237+ chat .unregister (ws )
201238
202239
203240 """
204- Basic
241+ Base
205242 """
206243
207-
208244 @app .route ('/' )
209245 @caching (timeout = 86400 ) # 24 hours
210246 def index ():
@@ -221,6 +257,8 @@ def index():
221257 # Register Blueprints
222258 app .register_blueprint (asn_blueprint , url_prefix = '/as' )
223259 app .register_blueprint (asn_api_v1_blueprint , url_prefix = '/api/v1/as' )
260+ app .register_blueprint (ai_blueprint , url_prefix = '/ai' )
261+ app .register_blueprint (ai_api_v1_blueprint , url_prefix = '/api/v1/ai' )
224262
225263 return app
226264
0 commit comments