Files
MoviePilot/tests/test_llm_provider_runcrate.py
Nirupam Bhowmick 363b8d9e5d feat(llm): 新增 Runcrate provider
新增 Runcrate OpenAI-compatible 预设(https://api.runcrate.ai/v1),沿用共享
openai_compatible 通道,模型目录通过 /v1/models 发现;附带模型发现的边界回归测试。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 08:02:17 +00:00

61 lines
2.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Runcrate 预设通过共享 OpenAI 兼容通道发现模型的边界回归。"""
from unittest.mock import AsyncMock
import httpx
import pytest
from app.agent.llm.provider import LLMProviderManager
from app.foundation.singleton import Singleton
@pytest.fixture
def manager(monkeypatch):
"""隔离管理器单例及目录缓存,防止测试影响其他 provider。"""
key = (LLMProviderManager, (), frozenset())
monkeypatch.setattr(Singleton, "_instances", {k: v for k, v in Singleton._instances.items() if k != key})
instance = LLMProviderManager()
monkeypatch.setattr(instance, "get_models_dev_data", AsyncMock(return_value={}))
return instance
@pytest.mark.asyncio
@pytest.mark.parametrize(
"base_url, expected_url",
[
(None, "https://api.runcrate.ai/v1/models"),
("https://relay.example/v1", "https://relay.example/v1/models"),
],
)
async def test_runcrate_discovers_authenticated_models(manager, monkeypatch, base_url, expected_url):
"""预设及覆盖地址都传递密钥,保留带厂商前缀的完整模型 ID,不推断缺失的上下文元数据。"""
requests = []
def respond(request):
requests.append(request)
return httpx.Response(
200,
json={
"object": "list",
"data": [
{"id": "deepseek-ai/DeepSeek-V4.1-Flash", "object": "model", "created": 0},
{"id": "zai-org/GLM-5.3-Flash", "object": "model", "created": 0},
],
},
)
monkeypatch.setattr(
manager,
"_build_sdk_http_client",
lambda use_proxy: httpx.AsyncClient(transport=httpx.MockTransport(respond)),
)
models = await manager.list_models("runcrate", api_key="test-runcrate-key", base_url=base_url)
assert len(requests) == 1
assert requests[0].method == "GET"
assert str(requests[0].url) == expected_url
assert requests[0].headers["Authorization"] == "Bearer test-runcrate-key"
assert [model["id"] for model in models] == ["deepseek-ai/DeepSeek-V4.1-Flash", "zai-org/GLM-5.3-Flash"]
assert all(model["source"] == "provider" and model["context_tokens"] is None for model in models)