mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-07 08:26:53 +08:00
fix(agent): log tool selector results
This commit is contained in:
@@ -321,7 +321,7 @@ class ToolSelectorMiddleware(LLMToolSelectorMiddleware):
|
|||||||
处理工具筛选响应,并保留空结果回退所有工具的 MoviePilot 策略。
|
处理工具筛选响应,并保留空结果回退所有工具的 MoviePilot 策略。
|
||||||
"""
|
"""
|
||||||
if response.get("tools") == []:
|
if response.get("tools") == []:
|
||||||
logger.warning("工具筛选结果为空,将恢复使用所有工具。")
|
logger.info("工具筛选结果为空,将恢复使用所有工具。")
|
||||||
|
|
||||||
always_included_tools: list[BaseTool] = [
|
always_included_tools: list[BaseTool] = [
|
||||||
tool
|
tool
|
||||||
@@ -343,12 +343,15 @@ class ToolSelectorMiddleware(LLMToolSelectorMiddleware):
|
|||||||
valid_tool_names=valid_tool_names,
|
valid_tool_names=valid_tool_names,
|
||||||
available_tools=available_tools,
|
available_tools=available_tools,
|
||||||
)
|
)
|
||||||
return super()._process_selection_response(
|
modified_request = super()._process_selection_response(
|
||||||
response,
|
response,
|
||||||
available_tools,
|
available_tools,
|
||||||
valid_tool_names,
|
valid_tool_names,
|
||||||
request,
|
request,
|
||||||
)
|
)
|
||||||
|
selected_tool_names = self._extract_selected_tool_names(modified_request)
|
||||||
|
logger.info(f"工具筛选结果: {', '.join(selected_tool_names) or '无有效工具'}")
|
||||||
|
return modified_request
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_json_object(text: str) -> dict[str, Any]:
|
def _parse_json_object(text: str) -> dict[str, Any]:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
|
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
|
||||||
|
|
||||||
@@ -291,6 +292,64 @@ def test_tool_selection_failure_falls_back_to_all_tools():
|
|||||||
assert state_update == {"selected_tool_names": ["search", "calendar"]}
|
assert state_update == {"selected_tool_names": ["search", "calendar"]}
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_tool_selection_logs_info_not_warning():
|
||||||
|
"""工具筛选返回空数组时应按信息日志记录降级。"""
|
||||||
|
tools = [
|
||||||
|
SimpleNamespace(name="search", description="Search for information"),
|
||||||
|
SimpleNamespace(name="calendar", description="Manage events"),
|
||||||
|
]
|
||||||
|
middleware = tool_selector_module.ToolSelectorMiddleware(
|
||||||
|
max_tools=2,
|
||||||
|
selection_tools=tools,
|
||||||
|
)
|
||||||
|
request = _FakeRequest(
|
||||||
|
tools=tools,
|
||||||
|
messages=[HumanMessage(content="帮我安排明天的行程并查天气")],
|
||||||
|
model=_FakeModel(),
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch.object(tool_selector_module.logger, "info") as logger_info, \
|
||||||
|
patch.object(tool_selector_module.logger, "warning") as logger_warning:
|
||||||
|
result = middleware._process_selection_response(
|
||||||
|
{"tools": []},
|
||||||
|
available_tools=tools,
|
||||||
|
valid_tool_names=[tool.name for tool in tools],
|
||||||
|
request=request,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert [tool.name for tool in result.tools] == ["search", "calendar"]
|
||||||
|
logger_info.assert_called_once_with("工具筛选结果为空,将恢复使用所有工具。")
|
||||||
|
logger_warning.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_process_selection_response_logs_selected_tools():
|
||||||
|
"""工具筛选返回有效工具时应记录最终生效的工具名。"""
|
||||||
|
tools = [
|
||||||
|
SimpleNamespace(name="search", description="Search for information"),
|
||||||
|
SimpleNamespace(name="calendar", description="Manage events"),
|
||||||
|
]
|
||||||
|
middleware = tool_selector_module.ToolSelectorMiddleware(
|
||||||
|
max_tools=2,
|
||||||
|
selection_tools=tools,
|
||||||
|
)
|
||||||
|
request = _FakeRequest(
|
||||||
|
tools=tools,
|
||||||
|
messages=[HumanMessage(content="帮我安排明天的行程并查天气")],
|
||||||
|
model=_FakeModel(),
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch.object(tool_selector_module.logger, "info") as logger_info:
|
||||||
|
result = middleware._process_selection_response(
|
||||||
|
{"tools": ["calendar"]},
|
||||||
|
available_tools=tools,
|
||||||
|
valid_tool_names=[tool.name for tool in tools],
|
||||||
|
request=request,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert [tool.name for tool in result.tools] == ["calendar"]
|
||||||
|
logger_info.assert_called_once_with("工具筛选结果: calendar")
|
||||||
|
|
||||||
|
|
||||||
def test_normalize_selection_response_accepts_code_fence_json():
|
def test_normalize_selection_response_accepts_code_fence_json():
|
||||||
"""工具筛选响应应兼容 Markdown 代码围栏包裹的 JSON。"""
|
"""工具筛选响应应兼容 Markdown 代码围栏包裹的 JSON。"""
|
||||||
middleware = tool_selector_module.ToolSelectorMiddleware()
|
middleware = tool_selector_module.ToolSelectorMiddleware()
|
||||||
|
|||||||
Reference in New Issue
Block a user