mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-25 08:33:53 +08:00
Merge branch 'main' into py-audio-aec
This commit is contained in:
@@ -43,9 +43,13 @@ class ASRProvider(ASRProviderBase):
|
||||
|
||||
# 内存检测,要求大于2G
|
||||
min_mem_bytes = 2 * 1024 * 1024 * 1024
|
||||
total_mem = psutil.virtual_memory().total
|
||||
if total_mem < min_mem_bytes:
|
||||
logger.bind(tag=TAG).error(f"可用内存不足2G,当前仅有 {total_mem / (1024*1024):.2f} MB,可能无法启动FunASR")
|
||||
try:
|
||||
total_mem = psutil.virtual_memory().total
|
||||
except RuntimeError as e:
|
||||
logger.bind(tag=TAG).warning(f"获取系统内存信息失败,跳过FunASR内存检测: {e}")
|
||||
else:
|
||||
if total_mem < min_mem_bytes:
|
||||
logger.bind(tag=TAG).error(f"可用内存不足2G,当前仅有 {total_mem / (1024*1024):.2f} MB,可能无法启动FunASR")
|
||||
|
||||
self.interface_type = InterfaceType.LOCAL
|
||||
self.model_dir = config.get("model_dir")
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
@@ -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}")
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""服务端插件工具执行器"""
|
||||
|
||||
import asyncio
|
||||
from typing import Dict, Any, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -41,6 +42,10 @@ class ServerPluginExecutor(ToolExecutor):
|
||||
# 默认不传conn参数
|
||||
result = func_item.func(**arguments)
|
||||
|
||||
# 兼容 async def 工具函数
|
||||
if asyncio.iscoroutine(result):
|
||||
result = await result
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
"""
|
||||
|
||||
import os
|
||||
import asyncio
|
||||
import threading
|
||||
from typing import Dict, Any, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -169,12 +171,33 @@ class PromptManager:
|
||||
if cached_weather is not None:
|
||||
return cached_weather
|
||||
|
||||
# 缓存未命中,调用get_weather函数获取
|
||||
# 缓存未命中,调用 async get_weather 函数
|
||||
# Windows ProactorEventLoop 不支持 run_coroutine_threadsafe().result()
|
||||
# 因此用 call_soon_threadsafe 提交任务 + threading.Event 等待结果
|
||||
# 注意:Event.wait() 只阻塞当前线程池线程,不阻塞主事件循环
|
||||
from plugins_func.functions.get_weather import get_weather
|
||||
from plugins_func.register import ActionResponse
|
||||
|
||||
# 调用get_weather函数
|
||||
result = get_weather(conn, location=location, lang="zh_CN")
|
||||
result_holder = []
|
||||
exception_holder = []
|
||||
|
||||
async def _call():
|
||||
try:
|
||||
result_holder.append(
|
||||
await get_weather(conn, location=location, lang="zh_CN")
|
||||
)
|
||||
except Exception as e:
|
||||
exception_holder.append(e)
|
||||
finally:
|
||||
event.set()
|
||||
|
||||
event = threading.Event()
|
||||
conn.loop.call_soon_threadsafe(lambda: asyncio.ensure_future(_call()))
|
||||
if not event.wait(timeout=10):
|
||||
raise TimeoutError("获取天气信息超时")
|
||||
if exception_holder:
|
||||
raise exception_holder[0]
|
||||
result = result_holder[0]
|
||||
if isinstance(result, ActionResponse):
|
||||
weather_report = result.result
|
||||
self.cache_manager.set(self.CacheType.WEATHER, location, weather_report)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user