From 0b8bb728e2170d96306a8ee258a39dc618223afd Mon Sep 17 00:00:00 2001 From: Sakura-RanChen <1908198662@qq.com> Date: Wed, 8 Jul 2026 11:47:04 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=8C=85=E8=A3=85=E9=81=BF=E5=85=8D=E9=98=BB?= =?UTF-8?q?=E5=A1=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/providers/memory/mem0ai/mem0ai.py | 5 ++++- .../providers/memory/powermem/powermem.py | 20 ++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py b/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py index cbf410ae..0e7d3b72 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 @@ -84,7 +85,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}") From a32500a6a447bc41b5aa82471cd18aaebe93dd3a Mon Sep 17 00:00:00 2001 From: Sakura-RanChen <1908198662@qq.com> Date: Thu, 9 Jul 2026 10:29:41 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E6=B6=88=E9=99=A4=E6=AD=BB=E9=94=81?= =?UTF-8?q?=E9=9A=90=E6=82=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/app.py | 2 +- main/xiaozhi-server/config/config_loader.py | 16 +++------------- main/xiaozhi-server/config/logger.py | 14 ++++++++++---- main/xiaozhi-server/config/settings.py | 3 ++- .../core/providers/memory/mem0ai/mem0ai.py | 4 +++- main/xiaozhi-server/core/websocket_server.py | 2 +- 6 files changed, 20 insertions(+), 21 deletions(-) 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 0e7d3b72..2dc93358 100644 --- a/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py +++ b/main/xiaozhi-server/core/providers/memory/mem0ai/mem0ai.py @@ -60,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)}") 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,