fix: 修复 MCP 动态加载插件工具 (#6214)

This commit is contained in:
cyt-666
2026-07-31 22:31:46 +08:00
committed by GitHub
parent 2310a3a456
commit 6c89f1eb4b
6 changed files with 205 additions and 40 deletions
+47 -11
View File
@@ -1,9 +1,11 @@
import json
import threading
import uuid
from typing import Any, Dict, List, Optional
from app.agent.tools.base import ToolExecutionTimeoutError, format_tool_result_for_agent
from app.agent.tools.factory import MoviePilotToolFactory
from app.core.plugin import PluginManager
from app.log import logger
@@ -40,27 +42,59 @@ class MoviePilotToolsManager:
self.session_id = session_id
self.is_admin = is_admin
self.tools: List[Any] = []
self._tools_lock = threading.Lock()
self._plugin_agent_tools_revision = -1
self._load_tools()
def _load_tools(self):
def _load_tools(self) -> None:
"""
加载所有MoviePilot工具
"""
try:
# 创建工具实例
self.tools = MoviePilotToolFactory.create_tools(
session_id=self.session_id,
user_id=self.user_id,
channel=None,
source="api",
username="API Client",
stream_handler=None,
agent_context={"is_admin": self.is_admin},
)
plugin_manager = PluginManager()
while True:
plugin_tools_revision = (
plugin_manager.get_plugin_agent_tools_revision()
)
tools = MoviePilotToolFactory.create_tools(
session_id=self.session_id,
user_id=self.user_id,
channel=None,
source="api",
username="API Client",
stream_handler=None,
agent_context={"is_admin": self.is_admin},
)
if (
plugin_tools_revision
== plugin_manager.get_plugin_agent_tools_revision()
):
break
self.tools = tools
self._plugin_agent_tools_revision = plugin_tools_revision
logger.info(f"成功加载 {len(self.tools)} 个工具")
except Exception as e:
logger.error(f"加载工具失败: {e}", exc_info=True)
self.tools = []
self._plugin_agent_tools_revision = -1
def _ensure_tools_current(self) -> None:
"""
在插件工具注册表变化后惰性刷新工具实例。
"""
plugin_manager = PluginManager()
if (
self._plugin_agent_tools_revision
== plugin_manager.get_plugin_agent_tools_revision()
):
return
with self._tools_lock:
if (
self._plugin_agent_tools_revision
== plugin_manager.get_plugin_agent_tools_revision()
):
return
self._load_tools()
def list_tools(self) -> List[ToolDefinition]:
"""
@@ -69,6 +103,7 @@ class MoviePilotToolsManager:
Returns:
工具定义列表
"""
self._ensure_tools_current()
tools_list = []
for tool in self.tools:
if getattr(tool, "_require_admin", False) and not self.is_admin:
@@ -102,6 +137,7 @@ class MoviePilotToolsManager:
Returns:
工具实例,如果未找到返回None
"""
self._ensure_tools_current()
for tool in self.tools:
if tool.name == tool_name:
return tool