Files
MoviePilot/tests/test_agent_llm_runtime_config.py
2026-08-05 19:19:26 +08:00

106 lines
4.3 KiB
Python

import asyncio
from types import SimpleNamespace
from unittest.mock import AsyncMock, patch
from app.agent import MoviePilotAgent
from app.core.config import settings
from app.schemas import AgentLLMProviderEventData
from app.schemas.types import ChainEventType
def test_resolve_llm_runtime_config_uses_system_thinking_level(monkeypatch) -> None:
"""插件未提供有效思考强度时应使用系统配置。"""
monkeypatch.setattr(settings, "LLM_THINKING_LEVEL", "xhigh")
agent = MoviePilotAgent(session_id="thinking-level-default", user_id="user-1")
async def return_empty_config(event_type, event_data):
"""模拟插件未返回有效运行时配置。"""
assert event_type == ChainEventType.AgentLLMProvider
assert event_data.thinking_level == "xhigh"
return SimpleNamespace(event_data=AgentLLMProviderEventData())
with patch(
"app.agent.eventmanager.async_send_event",
new=AsyncMock(side_effect=return_empty_config),
):
runtime_config = asyncio.run(agent._resolve_llm_runtime_config())
assert runtime_config["thinking_level"] == "xhigh"
def test_resolve_llm_runtime_config_prefers_plugin_thinking_level(monkeypatch) -> None:
"""插件显式覆盖思考强度时应优先使用插件值。"""
monkeypatch.setattr(settings, "LLM_THINKING_LEVEL", "xhigh")
agent = MoviePilotAgent(session_id="thinking-level-plugin", user_id="user-1")
async def override_thinking_level(_event_type, event_data):
"""模拟插件覆盖思考强度。"""
event_data.thinking_level = "high"
return SimpleNamespace(event_data=event_data)
with patch(
"app.agent.eventmanager.async_send_event",
new=AsyncMock(side_effect=override_thinking_level),
):
runtime_config = asyncio.run(agent._resolve_llm_runtime_config())
assert runtime_config["thinking_level"] == "high"
def test_resolve_llm_runtime_config_uses_system_api_protocol(monkeypatch) -> None:
"""插件未提供 API 协议时应使用系统配置。"""
monkeypatch.setattr(settings, "LLM_API_PROTOCOL", "responses")
agent = MoviePilotAgent(session_id="api-protocol-default", user_id="user-1")
async def return_empty_config(event_type, event_data):
"""模拟插件未返回有效运行时配置。"""
assert event_type == ChainEventType.AgentLLMProvider
assert event_data.api_protocol == "responses"
return SimpleNamespace(event_data=AgentLLMProviderEventData())
with patch(
"app.agent.eventmanager.async_send_event",
new=AsyncMock(side_effect=return_empty_config),
):
runtime_config = asyncio.run(agent._resolve_llm_runtime_config())
assert runtime_config["api_protocol"] == "responses"
def test_resolve_llm_runtime_config_prefers_plugin_api_protocol(monkeypatch) -> None:
"""插件显式覆盖 API 协议时应优先使用插件值。"""
monkeypatch.setattr(settings, "LLM_API_PROTOCOL", "responses")
agent = MoviePilotAgent(session_id="api-protocol-plugin", user_id="user-1")
async def override_api_protocol(_event_type, event_data):
"""模拟插件覆盖 API 协议。"""
event_data.api_protocol = "chat_completions"
return SimpleNamespace(event_data=event_data)
with patch(
"app.agent.eventmanager.async_send_event",
new=AsyncMock(side_effect=override_api_protocol),
):
runtime_config = asyncio.run(agent._resolve_llm_runtime_config())
assert runtime_config["api_protocol"] == "chat_completions"
def test_resolve_llm_runtime_config_prefers_plugin_web_search_mode(monkeypatch) -> None:
"""插件显式覆盖联网搜索模式时应优先使用插件值。"""
monkeypatch.setattr(settings, "LLM_WEB_SEARCH_MODE", "local")
agent = MoviePilotAgent(session_id="web-search-plugin", user_id="user-1")
async def override_web_search_mode(_event_type, event_data):
"""模拟插件覆盖联网搜索模式。"""
event_data.web_search_mode = "builtin"
return SimpleNamespace(event_data=event_data)
with patch(
"app.agent.eventmanager.async_send_event",
new=AsyncMock(side_effect=override_web_search_mode),
):
runtime_config = asyncio.run(agent._resolve_llm_runtime_config())
assert runtime_config["web_search_mode"] == "builtin"