|
@@ -0,0 +1,142 @@
|
|
|
+import os
|
|
|
+import sys
|
|
|
+import copy
|
|
|
+import json
|
|
|
+import uuid
|
|
|
+import time
|
|
|
+import queue
|
|
|
+import asyncio
|
|
|
+import threading
|
|
|
+import traceback
|
|
|
+import subprocess
|
|
|
+import websockets
|
|
|
+from config.logger import setup_logging
|
|
|
+from core.auth import AuthMiddleware, AuthenticationError
|
|
|
+from concurrent.futures import ThreadPoolExecutor
|
|
|
+from core.utils.voiceprint_provider import VoiceprintProvider
|
|
|
+from collections import deque
|
|
|
+from core.utils.dialogue import Dialogue
|
|
|
+from core.utils.prompt_manager import PromptManager
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+TAG = __name__
|
|
|
+
|
|
|
+auto_import_modules("plugins_func.functions")
|
|
|
+
|
|
|
+class TTSSException(RuntimeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class ConnnectionHandler:
|
|
|
+ def __init_(
|
|
|
+ self,
|
|
|
+ config: Dict[str, Any],
|
|
|
+ _vad,
|
|
|
+ _asr,
|
|
|
+ _llm,
|
|
|
+ _memory,
|
|
|
+ _intent.
|
|
|
+ server=None,
|
|
|
+ ):
|
|
|
+ self.common_config = config
|
|
|
+ self.config = copy.deepcopy(config)
|
|
|
+ self.session_id = str(uuid.uuid4())
|
|
|
+ self.logger = setup_logging()
|
|
|
+ self.server = server # 保存server实例的引用
|
|
|
+
|
|
|
+ self.auth = AuthMiddleware(config)
|
|
|
+ self.need_bind = False
|
|
|
+ self.bind_code = None
|
|
|
+ self.read_config_from_api = self.config.get("read_config_from_api",False)
|
|
|
+
|
|
|
+ self.websocket = None
|
|
|
+ self.headers = None
|
|
|
+ self.device_id = None
|
|
|
+ self.client_ip = None
|
|
|
+ self.prompt = None
|
|
|
+ self.welcome_msg = None
|
|
|
+ self.max_output_size = 0
|
|
|
+ self.chat_history_conf = 0
|
|
|
+ self.audio_format = "opus"
|
|
|
+
|
|
|
+ # 客户端状态相关
|
|
|
+ self.client_abort = False
|
|
|
+ self.client_is_speaking = False
|
|
|
+ self.client_listen_mode = "auto"
|
|
|
+
|
|
|
+ # 线程任务相关
|
|
|
+ self.loop = asyncio.get_event_loop()
|
|
|
+ self.stop_event = threading.Event()
|
|
|
+ self.executor = ThreadPoolExecutor(max_workers=5)
|
|
|
+
|
|
|
+ # 添加上报线程池
|
|
|
+ self.report_queue = queue.Queue()
|
|
|
+ self.report_thread = None
|
|
|
+ # 未来可以通过修改此处,调节asr的上报和tts的上报,目前默认都开启
|
|
|
+ self.report_asr_enable = self.read_config_from_api
|
|
|
+ self.report_tts_enable = self.read_config_from_api
|
|
|
+
|
|
|
+ # 依赖的组件
|
|
|
+ self.vad = None
|
|
|
+ self.asr = None
|
|
|
+ self.tts = None
|
|
|
+ self._asr = _asr
|
|
|
+ self._vad = _vad
|
|
|
+ self.llm = _llm
|
|
|
+ self.memory = _memory
|
|
|
+ self.intent = _intent
|
|
|
+
|
|
|
+ # 为每个连接单独管理声纹识别
|
|
|
+ self.voiceprint_provider = None
|
|
|
+
|
|
|
+ # vad相关变量
|
|
|
+ self.client_audio_buffer = bytearray()
|
|
|
+ self.client_have_voice = False
|
|
|
+ self.last_activity_time = 0.0 # 统一的活动时间戳(毫秒)
|
|
|
+ self.client_voice_stop = False
|
|
|
+ self.client_voice_window = deque(maxlen=5)
|
|
|
+ self.last_is_voice = False
|
|
|
+
|
|
|
+ # asr相关变量
|
|
|
+ # 因为实际部署时可能会用到公共的本地ASR,不能把变量暴露给公共ASR
|
|
|
+ # 所以涉及到ASR的变量,需要在这里定义,属于connection的私有变量
|
|
|
+ self.asr_audio = []
|
|
|
+ self.asr_audio_queue = queue.Queue()
|
|
|
+
|
|
|
+ # llm相关变量
|
|
|
+ self.llm_finish_task = True
|
|
|
+ self.dialogue = Dialogue()
|
|
|
+
|
|
|
+ # tts相关变量
|
|
|
+ self.sentence_id = None
|
|
|
+ self.tts_MessageText = ""
|
|
|
+
|
|
|
+ # iot相关变量
|
|
|
+ self.iot_descriptors = {}
|
|
|
+ self.func_handler = None
|
|
|
+
|
|
|
+ self.cmd_exit = self.config["exit_commands"]
|
|
|
+ self.max_cmd_length = 0
|
|
|
+ for cmd in self.cmd_exit:
|
|
|
+ if len(cmd) > self.max_cmd_length:
|
|
|
+ self.max_cmd_length = len(cmd)
|
|
|
+
|
|
|
+ # 是否在聊天结束后关闭连接
|
|
|
+ self.close_after_chat = False
|
|
|
+ self.load_function_plugins = False
|
|
|
+ self.intent_type = "nointent"
|
|
|
+
|
|
|
+ self.timeout_seconds = (
|
|
|
+ int(self.config.get("close_connection_no_voice_time", 120)) + 60
|
|
|
+ ) # 在第一道语音结束后的60秒后,如果用户没有说话,则关闭连接
|
|
|
+ self.timeout_task = None
|
|
|
+
|
|
|
+ # {"mcp": true} 表示启用MCP功能
|
|
|
+ self.features = None
|
|
|
+
|
|
|
+ # 初始化提示词管理器
|
|
|
+ self.prompt_manager = PromptManager(config, self.logger)
|
|
|
+
|
|
|
+
|
|
|
+
|