diff --git a/main/xiaozhi-server/app.py b/main/xiaozhi-server/app.py index bdefe42d..9fb3a9ea 100644 --- a/main/xiaozhi-server/app.py +++ b/main/xiaozhi-server/app.py @@ -45,7 +45,7 @@ async def monitor_stdin(): async def main(): check_ffmpeg_installed() - config = load_config() + config = await load_config() # auth_key优先级:配置文件server.auth_key > manager-api.secret > 自动生成 # auth_key用于jwt认证,比如视觉分析接口的jwt认证、ota接口的token生成与websocket认证 diff --git a/main/xiaozhi-server/config/config_loader.py b/main/xiaozhi-server/config/config_loader.py index 33a57e72..9e7e1c11 100644 --- a/main/xiaozhi-server/config/config_loader.py +++ b/main/xiaozhi-server/config/config_loader.py @@ -7,7 +7,6 @@ from config.manage_api_client import ( get_server_config, get_agent_models, get_correct_words, - lookup_address_book, DeviceNotFoundException, DeviceBindException, ) @@ -24,7 +23,7 @@ def read_config(config_path): return config -def load_config(): +async def load_config(): """加载配置文件""" from core.utils.cache.manager import cache_manager, CacheType @@ -41,16 +40,7 @@ def load_config(): custom_config = read_config(custom_config_path) if custom_config.get("manager-api", {}).get("url"): - import asyncio - try: - loop = asyncio.get_running_loop() - # 如果已经在事件循环中,使用异步版本 - config = asyncio.run_coroutine_threadsafe( - get_config_from_api_async(custom_config), loop - ).result() - except RuntimeError: - # 如果不在事件循环中(启动时),创建新的事件循环 - config = asyncio.run(get_config_from_api_async(custom_config)) + config = await get_config_from_api_async(custom_config) else: # 合并配置 config = merge_configs(default_config, custom_config) @@ -139,7 +129,7 @@ def ensure_directories(config): selected_provider = selected_modules.get(module_type) if not selected_provider: continue - if config.get(module) is None: + if config.get(module_type) is None: continue if config.get(selected_provider) is None: continue diff --git a/main/xiaozhi-server/config/logger.py b/main/xiaozhi-server/config/logger.py index ee1b4c36..34737247 100644 --- a/main/xiaozhi-server/config/logger.py +++ b/main/xiaozhi-server/config/logger.py @@ -1,9 +1,10 @@ import os import sys +import asyncio from loguru import logger from config.config_loader import load_config from config.settings import check_config_file -from datetime import datetime +from core.utils.cache.manager import cache_manager, CacheType SERVER_VERSION = "0.9.5" _logger_initialized = False @@ -45,10 +46,15 @@ def formatter(record): return record["message"] -def setup_logging(): - check_config_file() +def setup_logging(config=None): """从配置文件中读取日志配置,并设置日志输出格式和级别""" - config = load_config() + if config is None: + check_config_file() + # 先查缓存,避免在 async 上下文中重复 await load_config + config = cache_manager.get(CacheType.CONFIG, "main_config") + if config is None: + # 缓存也没有(理论上不该发生),才走 asyncio.run + config = asyncio.run(load_config()) log_config = config["log"] global _logger_initialized diff --git a/main/xiaozhi-server/config/settings.py b/main/xiaozhi-server/config/settings.py index fb8868b4..cfca89b6 100644 --- a/main/xiaozhi-server/config/settings.py +++ b/main/xiaozhi-server/config/settings.py @@ -1,4 +1,5 @@ import os +import asyncio from config.config_loader import read_config, get_project_dir, load_config @@ -20,7 +21,7 @@ def check_config_file(): ) # 检查是否从API读取配置 - config = load_config() + config = asyncio.run(load_config()) if config.get("read_config_from_api", False): print("从API读取配置") old_config_origin = read_config(custom_config_file) diff --git a/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py b/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py index cbf410ae..2dc93358 100644 --- a/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py +++ b/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py @@ -1,4 +1,5 @@ import json +import asyncio import traceback from ..base import MemoryProviderBase, logger @@ -59,7 +60,9 @@ class MemoryProvider(MemoryProviderBase): messages.append({"role": message.role, "content": content}) - result = self.client.add(messages, user_id=self.role_id) + result = await asyncio.to_thread( + self.client.add, messages, user_id=self.role_id + ) logger.bind(tag=TAG).debug(f"Save memory result: {result}") except Exception as e: logger.bind(tag=TAG).error(f"保存记忆失败: {str(e)}") @@ -84,7 +87,9 @@ class MemoryProvider(MemoryProviderBase): except (json.JSONDecodeError, KeyError): pass - results = self.client.search(search_query, filters=filters) + results = await asyncio.to_thread( + self.client.search, search_query, filters=filters + ) if not results or "results" not in results: return "" diff --git a/main/xiaozhi-server/core/providers/memory/powermem/powermem.py b/main/xiaozhi-server/core/providers/memory/powermem/powermem.py index 3e96fdfd..72d6526f 100644 --- a/main/xiaozhi-server/core/providers/memory/powermem/powermem.py +++ b/main/xiaozhi-server/core/providers/memory/powermem/powermem.py @@ -186,13 +186,19 @@ class MemoryProvider(MemoryProviderBase): messages.append({"role": message.role, "content": content}) # Add memory using PowerMem SDK - result = self.memory_client.add( - messages=messages, - user_id=self.role_id - ) - # Handle both sync and async returns - if asyncio.iscoroutine(result): - result = await result + if self.enable_user_profile: + # UserMemory uses sync add + result = await asyncio.to_thread( + self.memory_client.add, + messages=messages, + user_id=self.role_id + ) + else: + # AsyncMemory uses async add + result = await self.memory_client.add( + messages=messages, + user_id=self.role_id + ) logger.bind(tag=TAG).debug(f"Save memory result: {result}") diff --git a/main/xiaozhi-server/core/websocket_server.py b/main/xiaozhi-server/core/websocket_server.py index 077f7f4d..2ef7cda7 100644 --- a/main/xiaozhi-server/core/websocket_server.py +++ b/main/xiaozhi-server/core/websocket_server.py @@ -42,7 +42,7 @@ TAG = __name__ class WebSocketServer: def __init__(self, config: dict): self.config = config - self.logger = setup_logging() + self.logger = setup_logging(config) self.config_lock = asyncio.Lock() modules = initialize_modules( self.logger,