28
28
import json
29
29
import re
30
30
import time
31
+ from typing import Optional
32
+
31
33
import cachetools .func
32
34
33
35
from threading import Event , Timer
@@ -303,7 +305,7 @@ def get_neon_service(self, wait_timeout: int = 10) -> None:
303
305
LOG .info ("Joining sync consumer" )
304
306
sync_consumer .join ()
305
307
if not self .neon_service_event .is_set ():
306
- LOG .warning (f"Failed to get neon_service in { wait_timeout } seconds" )
308
+ LOG .warning (f"Failed to get neon response in { wait_timeout } seconds" )
307
309
self .__neon_service_id = ""
308
310
309
311
def register_sio_handlers (self ):
@@ -326,6 +328,8 @@ def register_sio_handlers(self):
326
328
handler = self .request_revoke_submind_ban_from_conversation ,
327
329
)
328
330
self ._sio .on ("auth_expired" , handler = self ._handle_auth_expired )
331
+ self ._sio .on ("configured_personas_changed" ,
332
+ handler = self ._handle_personas_changed )
329
333
330
334
def connect_sio (self ):
331
335
"""
@@ -396,6 +400,7 @@ def get_neon_request_structure(msg_data: dict):
396
400
if requested_skill == "tts" :
397
401
utterance = msg_data .pop ("utterance" , "" ) or msg_data .pop ("text" , "" )
398
402
request_dict = {
403
+ "msg_type" : "neon.get_tts" ,
399
404
"data" : {
400
405
"utterance" : utterance ,
401
406
"text" : utterance ,
@@ -404,12 +409,14 @@ def get_neon_request_structure(msg_data: dict):
404
409
}
405
410
elif requested_skill == "stt" :
406
411
request_dict = {
412
+ "msg_type" : "neon.get_stt" ,
407
413
"data" : {
408
414
"audio_data" : msg_data .pop ("audio_data" , msg_data ["message_body" ]),
409
415
}
410
416
}
411
417
else :
412
418
request_dict = {
419
+ "msg_type" : "recognizer_loop:utterance" ,
413
420
"data" : {
414
421
"utterances" : [msg_data ["message_body" ]],
415
422
},
@@ -419,13 +426,17 @@ def get_neon_request_structure(msg_data: dict):
419
426
return request_dict
420
427
421
428
def __handle_neon_recipient (self , recipient_data : dict , msg_data : dict ):
429
+ """
430
+ Handle a chat message intended for Neon.
431
+ """
422
432
msg_data .setdefault ("message_body" , msg_data .pop ("messageText" , "" ))
423
433
msg_data .setdefault ("message_id" , msg_data .pop ("messageID" , "" ))
424
434
recipient_data .setdefault ("context" , {})
425
435
pattern = re .compile ("Neon" , re .IGNORECASE )
426
436
msg_data ["message_body" ] = (
427
- pattern .sub ("" , msg_data ["message_body" ], 1 ).strip ("<>@,.:|- " ). capitalize ( )
437
+ pattern .sub ("" , msg_data ["message_body" ], 1 ).strip ("<>@,.:|- \n " )
428
438
)
439
+ # This is really referencing an MQ endpoint (i.e. stt, tts), not a skill
429
440
msg_data .setdefault (
430
441
"requested_skill" , recipient_data ["context" ].pop ("service" , "recognizer" )
431
442
)
@@ -774,6 +785,7 @@ def on_subminds_state(self, body: dict):
774
785
775
786
@create_mq_callback ()
776
787
def on_get_configured_personas (self , body : dict ):
788
+ # Handles request to get all defined personas
777
789
response_data = self ._fetch_persona_api (user_id = body .get ("user_id" ))
778
790
response_data ["items" ] = [
779
791
item
@@ -791,7 +803,7 @@ def on_get_configured_personas(self, body: dict):
791
803
)
792
804
793
805
@cachetools .func .ttl_cache (ttl = 15 )
794
- def _fetch_persona_api (self , user_id : str ) -> dict :
806
+ def _fetch_persona_api (self , user_id : Optional [ str ] ) -> dict :
795
807
query_string = self ._build_persona_api_query (user_id = user_id )
796
808
url = f"{ self .server_url } /personas/list?{ query_string } "
797
809
try :
@@ -803,12 +815,25 @@ def _fetch_persona_api(self, user_id: str) -> dict:
803
815
data = {"items" : []}
804
816
return data
805
817
818
+ def _handle_personas_changed (self , data : dict ):
819
+ """
820
+ SIO handler called when configured personas are modified. This emits an
821
+ MQ message to allow any connected listeners to maintain a set of known
822
+ personas.
823
+ """
824
+ self .send_message (
825
+ request_data = data ,
826
+ vhost = self .get_vhost ("llm" ),
827
+ queue = "configured_personas_changed" ,
828
+ expiration = 5000 ,
829
+ )
830
+
806
831
def _refresh_default_persona_llms (self , data ):
807
832
for item in data ["items" ]:
808
833
if default_llm := item .get ("default_llm" ):
809
834
self .default_persona_llms [item ["id" ]] = item ["id" ] + "_" + default_llm
810
835
811
- def _build_persona_api_query (self , user_id : str ) -> str :
836
+ def _build_persona_api_query (self , user_id : Optional [ str ] ) -> str :
812
837
url_query_params = f"only_enabled=true"
813
838
if user_id :
814
839
url_query_params += f"&user_id={ user_id } "
0 commit comments