mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-11 18:50:59 +08:00
feat: add LLM proxy toggle
This commit is contained in:
@@ -107,6 +107,7 @@ class AgentTokensEventsTest(unittest.IsolatedAsyncioTestCase):
|
||||
base_url="https://tokens.example.com/v1",
|
||||
base_url_preset=None,
|
||||
user_agent="AgentTokens-UA/1.0",
|
||||
use_proxy=True,
|
||||
thinking_level=None,
|
||||
)
|
||||
self.assertEqual("provider-1", agent._llm_provider_selection["selected_provider_id"])
|
||||
|
||||
@@ -135,6 +135,7 @@ _stub_module(
|
||||
LLM_THINKING_LEVEL=None,
|
||||
LLM_TEMPERATURE=0.1,
|
||||
LLM_MAX_CONTEXT_TOKENS=64,
|
||||
LLM_USE_PROXY=True,
|
||||
PROXY_HOST=None,
|
||||
),
|
||||
)
|
||||
@@ -188,6 +189,7 @@ class LlmHelperTestCallTest(unittest.TestCase):
|
||||
base_url="https://api.deepseek.com",
|
||||
base_url_preset="deepseek-default",
|
||||
user_agent=None,
|
||||
use_proxy=None,
|
||||
)
|
||||
self.assertEqual(result["provider"], "deepseek")
|
||||
self.assertEqual(result["model"], "deepseek-chat")
|
||||
@@ -489,6 +491,7 @@ class LlmHelperTestCallTest(unittest.TestCase):
|
||||
"base_url": "https://updated.example.com/v1",
|
||||
"base_url_preset_id": "updated-preset",
|
||||
"user_agent": None,
|
||||
"use_proxy": None,
|
||||
},
|
||||
)
|
||||
self.assertEqual(len(llm_calls), 1)
|
||||
@@ -500,6 +503,46 @@ class LlmHelperTestCallTest(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(llm_calls[0].get("default_headers"), {"X-Test": "1"})
|
||||
|
||||
def test_get_llm_applies_proxy_only_when_enabled(self):
|
||||
"""LLM 构造时应按独立开关决定是否传入系统代理。"""
|
||||
calls = []
|
||||
|
||||
class _FakeChatOpenAI:
|
||||
def __init__(self, **kwargs):
|
||||
calls.append(kwargs)
|
||||
self.model = kwargs["model"]
|
||||
self.profile = None
|
||||
|
||||
with patch.object(llm_module.settings, "PROXY_HOST", "http://proxy.example.com:7890"), patch.dict(
|
||||
sys.modules,
|
||||
{"langchain_openai": SimpleNamespace(ChatOpenAI=_FakeChatOpenAI)},
|
||||
):
|
||||
asyncio.run(
|
||||
llm_module.LLMHelper.get_llm(
|
||||
provider="openai",
|
||||
model="gpt-5-mini",
|
||||
api_key="sk-test",
|
||||
base_url="https://api.example.com/v1",
|
||||
use_proxy=True,
|
||||
)
|
||||
)
|
||||
asyncio.run(
|
||||
llm_module.LLMHelper.get_llm(
|
||||
provider="openai",
|
||||
model="gpt-5-mini",
|
||||
api_key="sk-test",
|
||||
base_url="https://api.example.com/v1",
|
||||
use_proxy=False,
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(calls[0].get("openai_proxy"), "http://proxy.example.com:7890")
|
||||
self.assertNotIn("http_client", calls[0])
|
||||
self.assertNotIn("http_async_client", calls[0])
|
||||
self.assertIsNone(calls[1].get("openai_proxy"))
|
||||
self.assertIn("http_client", calls[1])
|
||||
self.assertIn("http_async_client", calls[1])
|
||||
|
||||
def test_get_llm_passes_user_agent_as_openai_default_header(self):
|
||||
calls = []
|
||||
|
||||
|
||||
@@ -182,11 +182,15 @@ class LlmProviderRegistryTest(unittest.TestCase):
|
||||
with patch.object(
|
||||
manager,
|
||||
"get_models_dev_data",
|
||||
AsyncMock(side_effect=lambda force_refresh=False: manager.__dict__.update({"_models_dev_data": payload}) or payload),
|
||||
AsyncMock(
|
||||
side_effect=lambda force_refresh=False, use_proxy=None: manager.__dict__.update(
|
||||
{"_models_dev_data": payload}
|
||||
) or payload
|
||||
),
|
||||
) as fetch_mock:
|
||||
providers = asyncio.run(manager.list_providers_async())
|
||||
|
||||
fetch_mock.assert_awaited_once_with(force_refresh=False)
|
||||
fetch_mock.assert_awaited_once_with(force_refresh=False, use_proxy=None)
|
||||
self.assertIn("frogbot", {item["id"] for item in providers})
|
||||
|
||||
def test_list_models_uses_dynamic_provider_after_refresh(self):
|
||||
@@ -207,7 +211,7 @@ class LlmProviderRegistryTest(unittest.TestCase):
|
||||
}
|
||||
}
|
||||
|
||||
async def _load_models_dev(force_refresh: bool = False):
|
||||
async def _load_models_dev(force_refresh: bool = False, use_proxy=None):
|
||||
manager._models_dev_data = payload
|
||||
return payload
|
||||
|
||||
|
||||
@@ -147,6 +147,8 @@ class LlmTestEndpointTest(unittest.TestCase):
|
||||
system_endpoint.settings, "LLM_BASE_URL_PRESET", "deepseek-default"
|
||||
), patch.object(
|
||||
system_endpoint.settings, "LLM_USER_AGENT", "MoviePilot-Test/1.0"
|
||||
), patch.object(
|
||||
system_endpoint.settings, "LLM_USE_PROXY", True
|
||||
), patch.object(
|
||||
system_endpoint.LLMHelper,
|
||||
"test_current_settings",
|
||||
@@ -163,6 +165,7 @@ class LlmTestEndpointTest(unittest.TestCase):
|
||||
base_url="https://api.deepseek.com",
|
||||
base_url_preset="deepseek-default",
|
||||
user_agent="MoviePilot-Test/1.0",
|
||||
use_proxy=True,
|
||||
)
|
||||
self.assertTrue(resp.success)
|
||||
self.assertEqual(resp.data["provider"], "deepseek")
|
||||
@@ -188,6 +191,7 @@ class LlmTestEndpointTest(unittest.TestCase):
|
||||
base_url="https://example.com/v1",
|
||||
base_url_preset="openai-default",
|
||||
user_agent="MoviePilot-Custom/1.0",
|
||||
use_proxy=False,
|
||||
)
|
||||
|
||||
with patch.object(system_endpoint.settings, "AI_AGENT_ENABLE", False), patch.object(
|
||||
@@ -212,6 +216,7 @@ class LlmTestEndpointTest(unittest.TestCase):
|
||||
base_url="https://example.com/v1",
|
||||
base_url_preset="openai-default",
|
||||
user_agent="MoviePilot-Custom/1.0",
|
||||
use_proxy=False,
|
||||
)
|
||||
self.assertTrue(resp.success)
|
||||
self.assertEqual(resp.data["provider"], "openai")
|
||||
@@ -234,6 +239,7 @@ class LlmTestEndpointTest(unittest.TestCase):
|
||||
base_url="https://api.deepseek.com",
|
||||
base_url_preset="deepseek-default",
|
||||
user_agent=None,
|
||||
use_proxy=None,
|
||||
)
|
||||
|
||||
with patch.object(system_endpoint.settings, "AI_AGENT_ENABLE", False), patch.object(
|
||||
@@ -252,6 +258,7 @@ class LlmTestEndpointTest(unittest.TestCase):
|
||||
base_url="https://api.deepseek.com",
|
||||
base_url_preset="deepseek-default",
|
||||
user_agent=None,
|
||||
use_proxy=None,
|
||||
)
|
||||
self.assertTrue(resp.success)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user