将发送消息工具设为必选工具

This commit is contained in:
jxxghp
2026-05-27 08:48:56 +08:00
parent 990a28b51b
commit 5b6b4c9744
3 changed files with 8 additions and 40 deletions

View File

@@ -798,12 +798,6 @@ class MoviePilotAgent:
always_include_tools = (
MoviePilotToolFactory.get_tool_selector_always_include_names(tools)
)
if self.is_heartbeat_session:
available_tool_names = {
tool.name for tool in tools if getattr(tool, "name", None)
}
if "send_message" in available_tool_names:
always_include_tools.append("send_message")
# 中间件
middlewares = [

View File

@@ -91,7 +91,7 @@ class MoviePilotToolFactory:
"""
# 这些通用工具需要始终保留,避免大工具集裁剪后让 Agent 丢失基础的
# 文件系统、命令执行或交互确认能力。AskUserChoiceTool 仅在支持按钮
# 文件系统、命令执行、主动消息发送或交互确认能力。AskUserChoiceTool 仅在支持按钮
# 的渠道中才会实际注入,因此后续会再按已加载工具做一次求交集。
TOOL_SELECTOR_ALWAYS_INCLUDE_NAMES = (
"list_directory",
@@ -99,6 +99,7 @@ class MoviePilotToolFactory:
"read_file",
"edit_file",
"execute_command",
"send_message",
"ask_user_choice",
)

View File

@@ -12,6 +12,7 @@ from app.agent import (
UNSUPPORTED_IMAGE_INPUT_MESSAGE,
)
from app.agent.memory import memory_manager
from app.agent.tools.factory import MoviePilotToolFactory
from app.core.config import settings
from app.utils.identity import SYSTEM_INTERNAL_USER_ID
@@ -320,42 +321,14 @@ class AgentBackgroundOutputTest(unittest.IsolatedAsyncioTestCase):
created["middleware"],
)
async def test_heartbeat_session_always_keeps_send_message_tool(self):
agent = MoviePilotAgent(
session_id=f"{HEARTBEAT_SESSION_PREFIX}test__",
user_id="system",
)
def test_send_message_tool_is_always_included_by_tool_selector(self):
send_message_tool = SimpleNamespace(name="send_message")
agent._initialize_tools = lambda: [send_message_tool]
captured = {}
always_include = MoviePilotToolFactory.get_tool_selector_always_include_names(
[send_message_tool]
)
def fake_tool_selector(*args, **kwargs):
captured["always_include"] = kwargs["always_include"]
return "selector"
with (
patch.object(settings, "LLM_MAX_TOOLS", 1),
patch.object(agent, "_initialize_llm", new=AsyncMock(return_value=object())),
patch("app.agent.prompt_manager.get_agent_prompt", return_value="PROMPT"),
patch(
"app.agent.MoviePilotToolFactory.get_tool_selector_always_include_names",
return_value=[],
),
patch("app.agent.SkillsMiddleware", side_effect=lambda *args, **kwargs: "skills"),
patch("app.agent.JobsMiddleware", side_effect=lambda *args, **kwargs: "jobs"),
patch("app.agent.RuntimeConfigMiddleware", side_effect=lambda *args, **kwargs: "runtime"),
patch("app.agent.MemoryMiddleware", side_effect=lambda *args, **kwargs: "memory"),
patch("app.agent.SummarizationMiddleware", side_effect=lambda *args, **kwargs: "summary"),
patch("app.agent.PatchToolCallsMiddleware", side_effect=lambda *args, **kwargs: "patch"),
patch("app.agent.UsageMiddleware", side_effect=lambda *args, **kwargs: "usage"),
patch("app.agent.ToolSelectorMiddleware", side_effect=fake_tool_selector),
patch("app.agent.InMemorySaver", return_value="checkpointer"),
patch("app.agent.create_agent", side_effect=lambda **kwargs: kwargs),
):
await agent._create_agent(streaming=False)
self.assertIn("send_message", captured["always_include"])
self.assertIn("send_message", always_include)
async def test_create_agent_keeps_activity_log_for_normal_session(self):
agent = MoviePilotAgent(session_id="normal-session", user_id="system")