增加设备私有配置,每台设备可以配置不同的模型和提示词

增加后台管理功能,可以通过后台调整设备私有配置信息
This commit is contained in:
玄凤科技
2025-02-15 19:48:46 +08:00
parent 38546ad20f
commit bef55e852c
40 changed files with 3756 additions and 4 deletions
+27 -1
View File
@@ -16,7 +16,7 @@ from core.utils.util import get_string_no_punctuation_or_emoji
from concurrent.futures import ThreadPoolExecutor, TimeoutError
from core.handle.audioHandle import handleAudioMessage, sendAudioMessage
from .auth import AuthMiddleware, AuthenticationError
from config.private_config import PrivateConfig # Updated import path
class ConnectionHandler:
def __init__(self, config: Dict[str, Any], _vad, _asr, _llm, _tts):
@@ -73,6 +73,8 @@ class ConnectionHandler:
for cmd in self.cmd_exit:
if len(cmd) > self.max_cmd_length:
self.max_cmd_length = len(cmd)
self.private_config = None
async def handle_connection(self, ws):
try:
@@ -83,6 +85,28 @@ class ConnectionHandler:
# 进行认证
await self.auth.authenticate(self.headers)
device_id = self.headers.get("device-id", None)
# Load private configuration if device_id is provided
bUsePrivateConfig = self.config.get("use_private_config", False)
logging.info(f"bUsePrivateConfig: {bUsePrivateConfig}, device_id: {device_id}")
if bUsePrivateConfig and device_id:
self.private_config = PrivateConfig(device_id, self.config)
await self.private_config.load_or_create()
# Create private instances using private config
vad, asr, llm, tts = self.private_config.create_private_instances()
if vad is not None and asr is not None and llm is not None and tts is not None:
self.vad = vad
self.asr = asr
self.llm = llm
self.tts = tts
self.logger.info(f"Loaded private config and instances for device {device_id}")
self.private_config.update_last_chat_time()
else:
self.logger.error(f"Failed to load private config for device {device_id}")
self.private_config = None
# 认证通过,继续处理
self.websocket = ws
self.session_id = str(uuid.uuid4())
@@ -121,6 +145,8 @@ class ConnectionHandler:
def _initialize_components(self):
self.prompt = self.config["prompt"]
if self.private_config:
self.prompt = self.private_config.private_config.get("prompt", self.prompt)
# 赋予LLM时间观念
if "{date_time}" in self.prompt:
date_time = time.strftime("%Y-%m-%d %H:%M", time.localtime())
+1 -1
View File
@@ -16,7 +16,7 @@ def create_instance(class_name, *args, **kwargs):
lib_name = f'core.providers.llm.{class_name}.{class_name}'
if lib_name not in sys.modules:
sys.modules[lib_name] = importlib.import_module(f'{lib_name}')
return sys.modules[lib_name].LLMProvider(*args, **kwargs)
return sys.modules[lib_name].LLMProvider(*args, **kwargs)
raise ValueError(f"不支持的LLM类型: {class_name},请检查该配置的type是否设置正确")
+1 -1
View File
@@ -14,7 +14,7 @@ def create_instance(class_name, *args, **kwargs):
lib_name = f'core.providers.tts.{class_name}'
if lib_name not in sys.modules:
sys.modules[lib_name] = importlib.import_module(f'{lib_name}')
return sys.modules[lib_name].TTSProvider(*args, **kwargs)
return sys.modules[lib_name].TTSProvider(*args, **kwargs)
raise ValueError(f"不支持的TTS类型: {class_name},请检查该配置的type是否设置正确")
+86
View File
@@ -0,0 +1,86 @@
import os
import sys
import logging
from aiohttp import web
from aiohttp_cors import setup as cors_setup, ResourceOptions
# 添加项目根目录到Python路径
current_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = os.path.dirname(current_dir)
sys.path.append(root_dir)
from manager.api.login import LoginHandler
from manager.api.register import RegisterHandler
from manager.user_manager import UserManager
from manager.api.config import ConfigHandler
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class WebUI:
def __init__(self):
self.app = web.Application()
self.user_manager = UserManager()
# 添加静态文件路径
self.static_path = os.path.join(root_dir, 'manager', 'static', 'webui')
# 创建配置字典
self.config = {
'users': self.user_manager.get_users(),
'hash_password': self.user_manager.hash_password,
'save_user_data': self.user_manager.save_user_data,
'get_user': self.user_manager.get_user,
'update_user': self.user_manager.update_user
}
self.setup_routes()
self.setup_cors()
def setup_cors(self):
"""设置CORS"""
cors = cors_setup(self.app, defaults={
"*": ResourceOptions(
allow_credentials=True,
expose_headers="*",
allow_headers="*",
allow_methods="*"
)
})
for route in list(self.app.router.routes()):
cors.add(route)
def setup_routes(self):
"""设置路由"""
login_handler = LoginHandler(self.config)
register_handler = RegisterHandler(self.config)
config_handler = ConfigHandler()
# API 路由
self.app.router.add_post('/api/login', login_handler.handle_login)
self.app.router.add_post('/api/register', register_handler.handle_register)
self.app.router.add_get('/api/config/devices', config_handler.get_private_configs)
self.app.router.add_post('/api/config/device', config_handler.save_device_config)
self.app.router.add_get('/api/config/module-options', config_handler.get_module_options)
self.app.router.add_post('/api/config/save_device_config', config_handler.save_device_config)
self.app.router.add_post('/api/config/delete_device', config_handler.delete_device_config)
# 添加静态文件服务
self.app.router.add_static('/assets/', path=os.path.join(self.static_path, 'assets'))
self.app.router.add_get('/{tail:.*}', self.handle_static_files)
async def handle_static_files(self, request):
"""处理静态文件请求,支持SPA前端路由"""
index_file = os.path.join(self.static_path, 'index.html')
if os.path.exists(index_file):
return web.FileResponse(index_file)
return web.Response(status=404, text='Not found')
def run(self, host='0.0.0.0', port=8002):
"""运行服务器"""
web.run_app(self.app, host=host, port=port)
if __name__ == '__main__':
webui = WebUI()
webui.run()