mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-28 10:03:54 +08:00
feat: 为多个模块添加类型注解以增强代码可读性
为 ConnectionHandler 相关的函数参数添加类型注解,使用 TYPE_CHECKING 避免循环导入。主要修改包括: - 在 abortHandle、textHandle 等处理模块中为 conn 参数添加 ConnectionHandler 类型注解 - 在 websocket_server、connection 等核心模块中为方法参数添加类型注解 - 在 plugins_func 下的多个功能模块中为函数参数添加类型注解 - 在 providers 相关模块中为工具执行器和方法添加类型注解 - 统一代码格式,如将单引号字符串改为双引号 Fixes #2034
This commit is contained in:
@@ -13,6 +13,10 @@ from datetime import datetime
|
||||
from config.logger import setup_logging
|
||||
from core.providers.asr.base import ASRProviderBase
|
||||
from core.providers.asr.dto.dto import InterfaceType
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -125,7 +129,7 @@ class ASRProvider(ASRProviderBase):
|
||||
async def open_audio_channels(self, conn):
|
||||
await super().open_audio_channels(conn)
|
||||
|
||||
async def receive_audio(self, conn, audio, audio_have_voice):
|
||||
async def receive_audio(self, conn: "ConnectionHandler", audio, audio_have_voice):
|
||||
# 初始化音频缓存
|
||||
if not hasattr(conn, 'asr_audio_for_voiceprint'):
|
||||
conn.asr_audio_for_voiceprint = []
|
||||
@@ -154,7 +158,7 @@ class ASRProvider(ASRProviderBase):
|
||||
logger.bind(tag=TAG).warning(f"发送音频失败: {str(e)}")
|
||||
await self._cleanup(conn)
|
||||
|
||||
async def _start_recognition(self, conn):
|
||||
async def _start_recognition(self, conn: "ConnectionHandler"):
|
||||
"""开始识别会话"""
|
||||
if self._is_token_expired():
|
||||
self._refresh_token()
|
||||
@@ -200,7 +204,7 @@ class ASRProvider(ASRProviderBase):
|
||||
await self.asr_ws.send(json.dumps(start_request, ensure_ascii=False))
|
||||
logger.bind(tag=TAG).debug("已发送开始请求,等待服务器准备...")
|
||||
|
||||
async def _forward_results(self, conn):
|
||||
async def _forward_results(self, conn: "ConnectionHandler"):
|
||||
"""转发识别结果"""
|
||||
try:
|
||||
while not conn.stop_event.is_set():
|
||||
|
||||
@@ -3,7 +3,11 @@ import uuid
|
||||
import asyncio
|
||||
import websockets
|
||||
import opuslib_next
|
||||
from typing import List
|
||||
from typing import List, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
|
||||
from config.logger import setup_logging
|
||||
from core.providers.asr.base import ASRProviderBase
|
||||
from core.providers.asr.dto.dto import InterfaceType
|
||||
@@ -51,7 +55,7 @@ class ASRProvider(ASRProviderBase):
|
||||
async def open_audio_channels(self, conn):
|
||||
await super().open_audio_channels(conn)
|
||||
|
||||
async def receive_audio(self, conn, audio, audio_have_voice):
|
||||
async def receive_audio(self, conn: "ConnectionHandler", audio, audio_have_voice):
|
||||
# 初始化音频缓存
|
||||
if not hasattr(conn, 'asr_audio_for_voiceprint'):
|
||||
conn.asr_audio_for_voiceprint = []
|
||||
@@ -82,7 +86,7 @@ class ASRProvider(ASRProviderBase):
|
||||
logger.bind(tag=TAG).warning(f"发送音频失败: {str(e)}")
|
||||
await self._cleanup()
|
||||
|
||||
async def _start_recognition(self, conn):
|
||||
async def _start_recognition(self, conn: "ConnectionHandler"):
|
||||
"""开始识别会话"""
|
||||
try:
|
||||
# 如果为手动模式,设置超时时长为最大值
|
||||
@@ -162,7 +166,7 @@ class ASRProvider(ASRProviderBase):
|
||||
|
||||
return message
|
||||
|
||||
async def _forward_results(self, conn):
|
||||
async def _forward_results(self, conn: "ConnectionHandler"):
|
||||
"""转发识别结果"""
|
||||
try:
|
||||
while not conn.stop_event.is_set():
|
||||
|
||||
@@ -11,7 +11,10 @@ import threading
|
||||
import opuslib_next
|
||||
from abc import ABC, abstractmethod
|
||||
from config.logger import setup_logging
|
||||
from typing import Optional, Tuple, List
|
||||
from typing import Optional, Tuple, List, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
from core.handle.receiveAudioHandle import startToChat
|
||||
from core.handle.reportHandle import enqueue_asr_report
|
||||
from core.utils.util import remove_punctuation_and_length
|
||||
@@ -26,14 +29,14 @@ class ASRProviderBase(ABC):
|
||||
pass
|
||||
|
||||
# 打开音频通道
|
||||
async def open_audio_channels(self, conn):
|
||||
async def open_audio_channels(self, conn: "ConnectionHandler"):
|
||||
conn.asr_priority_thread = threading.Thread(
|
||||
target=self.asr_text_priority_thread, args=(conn,), daemon=True
|
||||
)
|
||||
conn.asr_priority_thread.start()
|
||||
|
||||
# 有序处理ASR音频
|
||||
def asr_text_priority_thread(self, conn):
|
||||
def asr_text_priority_thread(self, conn: "ConnectionHandler"):
|
||||
while not conn.stop_event.is_set():
|
||||
try:
|
||||
message = conn.asr_audio_queue.get(timeout=1)
|
||||
@@ -51,7 +54,7 @@ class ASRProviderBase(ABC):
|
||||
continue
|
||||
|
||||
# 接收音频
|
||||
async def receive_audio(self, conn, audio, audio_have_voice):
|
||||
async def receive_audio(self, conn: "ConnectionHandler", audio, audio_have_voice):
|
||||
if conn.client_listen_mode == "manual":
|
||||
# 手动模式:缓存音频用于ASR识别
|
||||
conn.asr_audio.append(audio)
|
||||
@@ -74,7 +77,7 @@ class ASRProviderBase(ABC):
|
||||
await self.handle_voice_stop(conn, asr_audio_task)
|
||||
|
||||
# 处理语音停止
|
||||
async def handle_voice_stop(self, conn, asr_audio_task: List[bytes]):
|
||||
async def handle_voice_stop(self, conn: "ConnectionHandler", asr_audio_task: List[bytes]):
|
||||
"""并行处理ASR和声纹识别"""
|
||||
try:
|
||||
total_start_time = time.monotonic()
|
||||
|
||||
@@ -7,6 +7,10 @@ import opuslib_next
|
||||
from core.providers.asr.base import ASRProviderBase
|
||||
from config.logger import setup_logging
|
||||
from core.providers.asr.dto.dto import InterfaceType
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -34,7 +38,9 @@ class ASRProvider(ASRProviderBase):
|
||||
|
||||
# 火山引擎ASR配置
|
||||
enable_multilingual = config.get("enable_multilingual", False)
|
||||
self.enable_multilingual = False if str(enable_multilingual).lower() == 'false' else True
|
||||
self.enable_multilingual = (
|
||||
False if str(enable_multilingual).lower() == "false" else True
|
||||
)
|
||||
if self.enable_multilingual:
|
||||
self.ws_url = "wss://openspeech.bytedance.com/api/v3/sauc/bigmodel_nostream"
|
||||
else:
|
||||
@@ -59,16 +65,20 @@ class ASRProvider(ASRProviderBase):
|
||||
async def open_audio_channels(self, conn):
|
||||
await super().open_audio_channels(conn)
|
||||
|
||||
async def receive_audio(self, conn, audio, audio_have_voice):
|
||||
async def receive_audio(self, conn: "ConnectionHandler", audio, audio_have_voice):
|
||||
conn.asr_audio.append(audio)
|
||||
conn.asr_audio = conn.asr_audio[-10:]
|
||||
# 存储音频数据
|
||||
if not hasattr(conn, 'asr_audio_for_voiceprint'):
|
||||
if not hasattr(conn, "asr_audio_for_voiceprint"):
|
||||
conn.asr_audio_for_voiceprint = []
|
||||
conn.asr_audio_for_voiceprint.append(audio)
|
||||
|
||||
# 当没有音频数据时处理完整语音片段
|
||||
if conn.client_listen_mode != "manual" and not audio and len(conn.asr_audio_for_voiceprint) > 0:
|
||||
if (
|
||||
conn.client_listen_mode != "manual"
|
||||
and not audio
|
||||
and len(conn.asr_audio_for_voiceprint) > 0
|
||||
):
|
||||
await self.handle_voice_stop(conn, conn.asr_audio_for_voiceprint)
|
||||
conn.asr_audio_for_voiceprint = []
|
||||
|
||||
@@ -160,11 +170,11 @@ class ASRProvider(ASRProviderBase):
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).info(f"发送音频数据时发生错误: {e}")
|
||||
|
||||
async def _forward_asr_results(self, conn):
|
||||
async def _forward_asr_results(self, conn: "ConnectionHandler"):
|
||||
try:
|
||||
while self.asr_ws and not conn.stop_event.is_set():
|
||||
# 获取当前连接的音频数据
|
||||
audio_data = getattr(conn, 'asr_audio_for_voiceprint', [])
|
||||
audio_data = getattr(conn, "asr_audio_for_voiceprint", [])
|
||||
try:
|
||||
response = await self.asr_ws.recv()
|
||||
result = self.parse_response(response)
|
||||
@@ -181,8 +191,9 @@ class ASRProvider(ASRProviderBase):
|
||||
utterances = payload["result"].get("utterances", [])
|
||||
# 检查duration和空文本的情况
|
||||
if (
|
||||
not self.enable_multilingual # 注意:多语种模式不返回中间结果,需要等待最终结果
|
||||
and payload.get("audio_info", {}).get("duration", 0) > 2000
|
||||
not self.enable_multilingual # 注意:多语种模式不返回中间结果,需要等待最终结果
|
||||
and payload.get("audio_info", {}).get("duration", 0)
|
||||
> 2000
|
||||
and not utterances
|
||||
and not payload["result"].get("text")
|
||||
and conn.client_listen_mode != "manual"
|
||||
@@ -200,8 +211,14 @@ class ASRProvider(ASRProviderBase):
|
||||
if self.enable_multilingual:
|
||||
continue
|
||||
|
||||
if conn.client_listen_mode == "manual" and conn.client_voice_stop and len(audio_data) > 0:
|
||||
logger.bind(tag=TAG).debug("消息结束收到停止信号,触发处理")
|
||||
if (
|
||||
conn.client_listen_mode == "manual"
|
||||
and conn.client_voice_stop
|
||||
and len(audio_data) > 0
|
||||
):
|
||||
logger.bind(tag=TAG).debug(
|
||||
"消息结束收到停止信号,触发处理"
|
||||
)
|
||||
await self.handle_voice_stop(conn, audio_data)
|
||||
# 清理音频缓存
|
||||
conn.asr_audio.clear()
|
||||
@@ -223,9 +240,16 @@ class ASRProvider(ASRProviderBase):
|
||||
self.text = current_text
|
||||
|
||||
# 在接收消息中途时收到停止信号
|
||||
if conn.client_voice_stop and len(audio_data) > 0:
|
||||
logger.bind(tag=TAG).debug("消息中途收到停止信号,触发处理")
|
||||
await self.handle_voice_stop(conn, audio_data)
|
||||
if (
|
||||
conn.client_voice_stop
|
||||
and len(audio_data) > 0
|
||||
):
|
||||
logger.bind(tag=TAG).debug(
|
||||
"消息中途收到停止信号,触发处理"
|
||||
)
|
||||
await self.handle_voice_stop(
|
||||
conn, audio_data
|
||||
)
|
||||
# 清理音频缓存
|
||||
conn.asr_audio.clear()
|
||||
conn.reset_vad_states()
|
||||
@@ -235,7 +259,9 @@ class ASRProvider(ASRProviderBase):
|
||||
self.text = current_text
|
||||
conn.reset_vad_states()
|
||||
if len(audio_data) > 15: # 确保有足够音频数据
|
||||
await self.handle_voice_stop(conn, audio_data)
|
||||
await self.handle_voice_stop(
|
||||
conn, audio_data
|
||||
)
|
||||
break
|
||||
elif "error" in payload:
|
||||
error_msg = payload.get("error", "未知错误")
|
||||
@@ -263,9 +289,9 @@ class ASRProvider(ASRProviderBase):
|
||||
self.asr_ws = None
|
||||
self.is_processing = False
|
||||
if conn:
|
||||
if hasattr(conn, 'asr_audio_for_voiceprint'):
|
||||
if hasattr(conn, "asr_audio_for_voiceprint"):
|
||||
conn.asr_audio_for_voiceprint = []
|
||||
if hasattr(conn, 'asr_audio'):
|
||||
if hasattr(conn, "asr_audio"):
|
||||
conn.asr_audio = []
|
||||
|
||||
def stop_ws_connection(self):
|
||||
@@ -280,7 +306,9 @@ class ASRProvider(ASRProviderBase):
|
||||
try:
|
||||
# 发送结束标记的音频帧(gzip压缩的空数据)
|
||||
empty_payload = gzip.compress(b"")
|
||||
last_audio_request = bytearray(self.generate_last_audio_default_header())
|
||||
last_audio_request = bytearray(
|
||||
self.generate_last_audio_default_header()
|
||||
)
|
||||
last_audio_request.extend(len(empty_payload).to_bytes(4, "big"))
|
||||
last_audio_request.extend(empty_payload)
|
||||
await self.asr_ws.send(last_audio_request)
|
||||
@@ -426,9 +454,9 @@ class ASRProvider(ASRProviderBase):
|
||||
pass
|
||||
self.forward_task = None
|
||||
self.is_processing = False
|
||||
|
||||
|
||||
# 显式释放decoder资源
|
||||
if hasattr(self, 'decoder') and self.decoder is not None:
|
||||
if hasattr(self, "decoder") and self.decoder is not None:
|
||||
try:
|
||||
del self.decoder
|
||||
self.decoder = None
|
||||
@@ -437,9 +465,9 @@ class ASRProvider(ASRProviderBase):
|
||||
logger.bind(tag=TAG).debug(f"释放Doubao decoder资源时出错: {e}")
|
||||
|
||||
# 清理所有连接的音频缓冲区
|
||||
if hasattr(self, '_connections'):
|
||||
if hasattr(self, "_connections"):
|
||||
for conn in self._connections.values():
|
||||
if hasattr(conn, 'asr_audio_for_voiceprint'):
|
||||
if hasattr(conn, "asr_audio_for_voiceprint"):
|
||||
conn.asr_audio_for_voiceprint = []
|
||||
if hasattr(conn, 'asr_audio'):
|
||||
if hasattr(conn, "asr_audio"):
|
||||
conn.asr_audio = []
|
||||
|
||||
@@ -9,7 +9,10 @@ import gc
|
||||
from time import mktime
|
||||
from datetime import datetime
|
||||
from urllib.parse import urlencode
|
||||
from typing import List
|
||||
from typing import List, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
from config.logger import setup_logging
|
||||
from wsgiref.handlers import format_date_time
|
||||
from core.providers.asr.base import ASRProviderBase
|
||||
@@ -94,10 +97,10 @@ class ASRProvider(ASRProviderBase):
|
||||
url = url + "?" + urlencode(v)
|
||||
return url
|
||||
|
||||
async def open_audio_channels(self, conn):
|
||||
async def open_audio_channels(self, conn: "ConnectionHandler"):
|
||||
await super().open_audio_channels(conn)
|
||||
|
||||
async def receive_audio(self, conn, audio, audio_have_voice):
|
||||
async def receive_audio(self, conn: "ConnectionHandler", audio, audio_have_voice):
|
||||
# 先调用父类方法处理基础逻辑
|
||||
await super().receive_audio(conn, audio, audio_have_voice)
|
||||
|
||||
@@ -124,7 +127,7 @@ class ASRProvider(ASRProviderBase):
|
||||
logger.bind(tag=TAG).warning(f"发送音频数据时发生错误: {e}")
|
||||
await self._cleanup()
|
||||
|
||||
async def _start_recognition(self, conn):
|
||||
async def _start_recognition(self, conn: "ConnectionHandler"):
|
||||
"""开始识别会话"""
|
||||
try:
|
||||
self.is_processing = True
|
||||
@@ -194,7 +197,7 @@ class ASRProvider(ASRProviderBase):
|
||||
|
||||
await self.asr_ws.send(json.dumps(frame_data, ensure_ascii=False))
|
||||
|
||||
async def _forward_results(self, conn):
|
||||
async def _forward_results(self, conn: "ConnectionHandler"):
|
||||
"""转发识别结果"""
|
||||
try:
|
||||
while not conn.stop_event.is_set():
|
||||
@@ -232,7 +235,7 @@ class ASRProvider(ASRProviderBase):
|
||||
|
||||
if status == 2:
|
||||
if conn.client_listen_mode == "manual":
|
||||
audio_data = getattr(conn, 'asr_audio_for_voiceprint', [])
|
||||
audio_data = getattr(conn, "asr_audio_for_voiceprint", [])
|
||||
if len(audio_data) > 0:
|
||||
logger.bind(tag=TAG).debug("收到最终识别结果,触发处理")
|
||||
await self.handle_voice_stop(conn, audio_data)
|
||||
@@ -270,7 +273,9 @@ class ASRProvider(ASRProviderBase):
|
||||
if hasattr(conn, "asr_audio"):
|
||||
conn.asr_audio = []
|
||||
|
||||
async def handle_voice_stop(self, conn, asr_audio_task: List[bytes]):
|
||||
async def handle_voice_stop(
|
||||
self, conn: "ConnectionHandler", asr_audio_task: List[bytes]
|
||||
):
|
||||
"""处理语音停止,发送最后一帧并处理识别结果"""
|
||||
try:
|
||||
# 先发送最后一帧表示音频结束
|
||||
@@ -355,7 +360,7 @@ class ASRProvider(ASRProviderBase):
|
||||
self.is_processing = False
|
||||
|
||||
# 显式释放decoder资源
|
||||
if hasattr(self, 'decoder') and self.decoder is not None:
|
||||
if hasattr(self, "decoder") and self.decoder is not None:
|
||||
try:
|
||||
del self.decoder
|
||||
self.decoder = None
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
from typing import List, Dict
|
||||
from typing import List, Dict, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
from ..base import IntentProviderBase
|
||||
from plugins_func.functions.play_music import initialize_music_handler
|
||||
from config.logger import setup_logging
|
||||
@@ -122,7 +125,9 @@ class IntentProvider(IntentProviderBase):
|
||||
)
|
||||
return llm_result
|
||||
|
||||
async def detect_intent(self, conn, dialogue_history: List[Dict], text: str) -> str:
|
||||
async def detect_intent(
|
||||
self, conn: "ConnectionHandler", dialogue_history: List[Dict], text: str
|
||||
) -> str:
|
||||
if not self.llm:
|
||||
raise ValueError("LLM provider not set")
|
||||
if conn.func_handler is None:
|
||||
|
||||
@@ -3,12 +3,16 @@
|
||||
import asyncio
|
||||
from config.logger import setup_logging
|
||||
from .iot_descriptor import IotDescriptor
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
|
||||
async def handleIotDescriptors(conn, descriptors):
|
||||
async def handleIotDescriptors(conn: "ConnectionHandler", descriptors):
|
||||
"""处理物联网描述"""
|
||||
wait_max_time = 5
|
||||
while (
|
||||
@@ -61,7 +65,7 @@ async def handleIotDescriptors(conn, descriptors):
|
||||
conn.func_handler.current_support_functions()
|
||||
|
||||
|
||||
async def handleIotStatus(conn, states):
|
||||
async def handleIotStatus(conn: "ConnectionHandler", states):
|
||||
"""处理物联网状态"""
|
||||
for state in states:
|
||||
for key, value in conn.iot_descriptors.items():
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""设备端MCP工具执行器"""
|
||||
|
||||
from typing import Dict, Any
|
||||
from typing import Dict, Any, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
from ..base import ToolType, ToolDefinition, ToolExecutor
|
||||
from plugins_func.register import Action, ActionResponse
|
||||
from .mcp_handler import call_mcp_tool
|
||||
@@ -13,7 +16,7 @@ class DeviceMCPExecutor(ToolExecutor):
|
||||
self.conn = conn
|
||||
|
||||
async def execute(
|
||||
self, conn, tool_name: str, arguments: Dict[str, Any]
|
||||
self, conn: "ConnectionHandler", tool_name: str, arguments: Dict[str, Any]
|
||||
) -> ActionResponse:
|
||||
"""执行设备端MCP工具"""
|
||||
if not hasattr(conn, "mcp_client") or not conn.mcp_client:
|
||||
|
||||
@@ -7,6 +7,10 @@ from concurrent.futures import Future
|
||||
from core.utils.util import get_vision_url, sanitize_tool_name
|
||||
from core.utils.auth import AuthToken
|
||||
from config.logger import setup_logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -96,7 +100,7 @@ class MCPClient:
|
||||
self.call_results.pop(id)
|
||||
|
||||
|
||||
async def send_mcp_message(conn, payload: dict):
|
||||
async def send_mcp_message(conn: "ConnectionHandler", payload: dict):
|
||||
"""Helper to send MCP messages, encapsulating common logic."""
|
||||
if not conn.features.get("mcp"):
|
||||
logger.bind(tag=TAG).warning("客户端不支持MCP,无法发送MCP消息")
|
||||
@@ -111,7 +115,9 @@ async def send_mcp_message(conn, payload: dict):
|
||||
logger.bind(tag=TAG).error(f"发送MCP消息失败: {e}")
|
||||
|
||||
|
||||
async def handle_mcp_message(conn, mcp_client: MCPClient, payload: dict):
|
||||
async def handle_mcp_message(
|
||||
conn: "ConnectionHandler", mcp_client: MCPClient, payload: dict
|
||||
):
|
||||
"""处理MCP消息,包括初始化、工具列表和工具调用响应等"""
|
||||
logger.bind(tag=TAG).debug(f"处理MCP消息: {str(payload)[:100]}")
|
||||
|
||||
@@ -229,7 +235,7 @@ async def handle_mcp_message(conn, mcp_client: MCPClient, payload: dict):
|
||||
)
|
||||
|
||||
|
||||
async def send_mcp_initialize_message(conn):
|
||||
async def send_mcp_initialize_message(conn: "ConnectionHandler"):
|
||||
"""发送MCP初始化消息"""
|
||||
|
||||
vision_url = get_vision_url(conn.config)
|
||||
@@ -264,7 +270,7 @@ async def send_mcp_initialize_message(conn):
|
||||
await send_mcp_message(conn, payload)
|
||||
|
||||
|
||||
async def send_mcp_tools_list_request(conn):
|
||||
async def send_mcp_tools_list_request(conn: "ConnectionHandler"):
|
||||
"""发送MCP工具列表请求"""
|
||||
payload = {
|
||||
"jsonrpc": "2.0",
|
||||
@@ -275,7 +281,7 @@ async def send_mcp_tools_list_request(conn):
|
||||
await send_mcp_message(conn, payload)
|
||||
|
||||
|
||||
async def send_mcp_tools_list_continue_request(conn, cursor: str):
|
||||
async def send_mcp_tools_list_continue_request(conn: "ConnectionHandler", cursor: str):
|
||||
"""发送带有cursor的MCP工具列表请求"""
|
||||
payload = {
|
||||
"jsonrpc": "2.0",
|
||||
@@ -288,7 +294,11 @@ async def send_mcp_tools_list_continue_request(conn, cursor: str):
|
||||
|
||||
|
||||
async def call_mcp_tool(
|
||||
conn, mcp_client: MCPClient, tool_name: str, args: str = "{}", timeout: int = 30
|
||||
conn: "ConnectionHandler",
|
||||
mcp_client: MCPClient,
|
||||
tool_name: str,
|
||||
args: str = "{}",
|
||||
timeout: int = 30,
|
||||
):
|
||||
"""
|
||||
调用指定的工具,并等待响应
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
"""服务端插件工具执行器"""
|
||||
|
||||
from typing import Dict, Any
|
||||
from typing import Dict, Any, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
from ..base import ToolType, ToolDefinition, ToolExecutor
|
||||
from plugins_func.register import all_function_registry, Action, ActionResponse
|
||||
|
||||
@@ -8,12 +11,12 @@ from plugins_func.register import all_function_registry, Action, ActionResponse
|
||||
class ServerPluginExecutor(ToolExecutor):
|
||||
"""服务端插件工具执行器"""
|
||||
|
||||
def __init__(self, conn):
|
||||
def __init__(self, conn: "ConnectionHandler"):
|
||||
self.conn = conn
|
||||
self.config = conn.config
|
||||
|
||||
async def execute(
|
||||
self, conn, tool_name: str, arguments: Dict[str, Any]
|
||||
self, conn: "ConnectionHandler", tool_name: str, arguments: Dict[str, Any]
|
||||
) -> ActionResponse:
|
||||
"""执行服务端插件工具"""
|
||||
func_item = all_function_registry.get(tool_name)
|
||||
|
||||
Reference in New Issue
Block a user