Files
wehub-resource-sync e4dcfc49aa
Tests / Import Check (Python 3.13) (push) Has been cancelled
Tests / Import Check (Python 3.14) (push) Has been cancelled
Tests / Python Tests (Python 3.11) (push) Has been cancelled
Tests / Python Tests (Python 3.12) (push) Has been cancelled
Tests / Python Tests (Python 3.14) (push) Has been cancelled
Tests / Test Summary (push) Has been cancelled
Tests / Lint and Format (push) Has been cancelled
Tests / Web Node Tests (push) Has been cancelled
Tests / Import Check (Python 3.11) (push) Has been cancelled
Tests / Import Check (Python 3.12) (push) Has been cancelled
Tests / Python Tests (Python 3.13) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:00:43 +08:00

413 lines
13 KiB
Python

"""Tests for TutorBot-style runtime config adapter."""
from __future__ import annotations
from deeptutor.services.config.provider_runtime import (
resolve_llm_runtime_config,
resolve_search_runtime_config,
)
def _build_catalog(
*,
llm_profile: dict | None = None,
llm_model: dict | None = None,
search_profile: dict | None = None,
) -> dict:
llm_profile = llm_profile or {
"id": "llm-p",
"name": "LLM",
"binding": "openai",
"base_url": "",
"api_key": "",
"api_version": "",
"extra_headers": {},
"models": [{"id": "llm-m", "name": "m", "model": "gpt-4o-mini"}],
}
llm_model = llm_model or llm_profile["models"][0]
search_profile = search_profile or {
"id": "search-p",
"name": "Search",
"provider": "brave",
"base_url": "",
"api_key": "",
"proxy": "",
"models": [],
}
return {
"version": 1,
"services": {
"llm": {
"active_profile_id": llm_profile["id"],
"active_model_id": llm_model["id"],
"profiles": [llm_profile],
},
"embedding": {
"active_profile_id": None,
"active_model_id": None,
"profiles": [],
},
"search": {
"active_profile_id": search_profile["id"],
"profiles": [search_profile],
},
},
}
def test_llm_explicit_binding_and_headers() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "dashscope",
"base_url": "",
"api_key": "dash-key",
"api_version": "",
"extra_headers": {"APP-Code": "abc"},
"models": [{"id": "llm-m", "name": "q", "model": "qwen-max"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "dashscope"
assert resolved.provider_mode == "standard"
assert resolved.effective_url == "https://dashscope.aliyuncs.com/compatible-mode/v1"
assert resolved.extra_headers == {"APP-Code": "abc"}
def test_llm_api_key_prefix_gateway() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "",
"base_url": "",
"api_key": "sk-or-test-key",
"api_version": "",
"extra_headers": {},
"models": [{"id": "llm-m", "name": "m", "model": "gemini-2.5-pro"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "openrouter"
assert resolved.provider_mode == "gateway"
assert resolved.effective_url == "https://openrouter.ai/api/v1"
def test_llm_api_base_keyword_gateway() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "",
"base_url": "https://api.aihubmix.com/v1",
"api_key": "k",
"api_version": "",
"extra_headers": {"APP-Code": "x"},
"models": [{"id": "llm-m", "name": "m", "model": "claude-3-7-sonnet"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "aihubmix"
assert resolved.provider_mode == "gateway"
assert resolved.effective_url == "https://api.aihubmix.com/v1"
assert resolved.extra_headers == {"APP-Code": "x"}
def test_llm_local_fallback() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "",
"base_url": "http://localhost:11434/v1",
"api_key": "",
"api_version": "",
"extra_headers": {},
"models": [{"id": "llm-m", "name": "m", "model": "llama3.2"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "ollama"
assert resolved.provider_mode == "local"
assert resolved.api_key == "sk-no-key-required"
def test_llm_minimax_binding_uses_minimaxi_endpoint() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "minimax",
"base_url": "",
"api_key": "minimax-key",
"api_version": "",
"extra_headers": {},
"models": [{"id": "llm-m", "name": "m", "model": "MiniMax-M3"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "minimax"
assert resolved.provider_mode == "standard"
assert resolved.effective_url == "https://api.minimaxi.com/v1"
def test_llm_minimax_anthropic_binding_uses_anthropic_endpoint() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "minimax_anthropic",
"base_url": "",
"api_key": "minimax-key",
"api_version": "",
"extra_headers": {},
"models": [{"id": "llm-m", "name": "c", "model": "claude-sonnet-4-20250514"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "minimax_anthropic"
assert resolved.provider_mode == "standard"
assert resolved.effective_url == "https://api.minimaxi.com/anthropic"
def test_llm_custom_anthropic_binding_stays_direct() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "custom_anthropic",
"base_url": "https://claude-proxy.example/v1/messages",
"api_key": "anthropic-key",
"api_version": "",
"extra_headers": {"x-tenant": "lab"},
"models": [{"id": "llm-m", "name": "c", "model": "claude-sonnet-4-20250514"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "custom_anthropic"
assert resolved.provider_mode == "direct"
assert resolved.binding == "custom_anthropic"
assert resolved.effective_url == "https://claude-proxy.example/v1/messages"
assert resolved.extra_headers == {"x-tenant": "lab"}
def test_llm_lm_studio_alias_resolves_to_local_provider() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "lm-studio",
"base_url": "",
"api_key": "",
"api_version": "",
"extra_headers": {},
"models": [{"id": "llm-m", "name": "m", "model": "llama-3.2"}],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.provider_name == "lm_studio"
assert resolved.provider_mode == "local"
assert resolved.effective_url == "http://localhost:1234/v1"
assert resolved.api_key == "sk-no-key-required"
def test_llm_context_window_passes_through_from_catalog() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": "sk-test",
"api_version": "",
"extra_headers": {},
"models": [
{
"id": "llm-m",
"name": "GPT 4o mini",
"model": "gpt-4o-mini",
"context_window": 128000,
}
],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.context_window == 128000
def test_llm_selection_overrides_active_model_without_mutating_catalog() -> None:
profile_a = {
"id": "p-a",
"name": "OpenRouter",
"binding": "openrouter",
"base_url": "https://openrouter.ai/api/v1",
"api_key": "sk-or-test",
"api_version": "",
"extra_headers": {},
"models": [
{
"id": "m-a",
"name": "Gemini",
"model": "google/gemini-3-flash-preview",
}
],
}
profile_b = {
"id": "p-b",
"name": "Local",
"binding": "ollama",
"base_url": "http://localhost:11434/v1",
"api_key": "",
"api_version": "",
"extra_headers": {},
"models": [{"id": "m-b", "name": "Llama", "model": "llama3.2"}],
}
catalog = _build_catalog(llm_profile=profile_a, llm_model=profile_a["models"][0])
catalog["services"]["llm"]["profiles"].append(profile_b)
resolved = resolve_llm_runtime_config(
catalog=catalog,
llm_selection={"profile_id": "p-b", "model_id": "m-b"},
)
assert resolved.model == "llama3.2"
assert resolved.provider_name == "ollama"
assert resolved.provider_mode == "local"
assert catalog["services"]["llm"]["active_profile_id"] == "p-a"
assert catalog["services"]["llm"]["active_model_id"] == "m-a"
def test_llm_reasoning_effort_resolves_from_catalog() -> None:
catalog = _build_catalog(
llm_profile={
"id": "llm-p",
"name": "LLM",
"binding": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": "sk-test",
"api_version": "",
"extra_headers": {},
"models": [
{
"id": "llm-m",
"name": "GPT 4o mini",
"model": "gpt-4o-mini",
"reasoning_effort": "high",
}
],
}
)
resolved = resolve_llm_runtime_config(catalog=catalog)
assert resolved.reasoning_effort == "high"
def test_search_fallback_to_duckduckgo_without_key() -> None:
catalog = _build_catalog(
search_profile={
"id": "search-p",
"name": "Search",
"provider": "brave",
"base_url": "",
"api_key": "",
"proxy": "http://127.0.0.1:7890",
"models": [],
}
)
resolved = resolve_search_runtime_config(catalog=catalog)
assert resolved.provider == "duckduckgo"
assert resolved.requested_provider == "brave"
assert resolved.fallback_reason is not None
assert resolved.proxy == "http://127.0.0.1:7890"
def test_search_none_disables_runtime_provider() -> None:
catalog = _build_catalog(
search_profile={
"id": "search-p",
"name": "Search",
"provider": "none",
"base_url": "",
"api_key": "",
"proxy": "",
"models": [],
}
)
resolved = resolve_search_runtime_config(catalog=catalog)
assert resolved.provider == "none"
assert resolved.requested_provider == "none"
assert resolved.status == "ok"
def test_search_marks_deprecated_provider() -> None:
catalog = _build_catalog(
search_profile={
"id": "search-p",
"name": "Search",
"provider": "exa",
"base_url": "",
"api_key": "k",
"proxy": "",
"models": [],
}
)
resolved = resolve_search_runtime_config(catalog=catalog)
assert resolved.unsupported_provider is True
assert resolved.deprecated_provider is True
assert resolved.provider == "exa"
def test_search_perplexity_missing_credentials() -> None:
catalog = _build_catalog(
search_profile={
"id": "search-p",
"name": "Search",
"provider": "perplexity",
"base_url": "",
"api_key": "",
"proxy": "",
"models": [],
}
)
resolved = resolve_search_runtime_config(catalog=catalog)
assert resolved.provider == "perplexity"
assert resolved.unsupported_provider is False
assert resolved.deprecated_provider is False
assert resolved.missing_credentials is True
def test_search_serper_missing_credentials() -> None:
catalog = _build_catalog(
search_profile={
"id": "search-p",
"name": "Search",
"provider": "serper",
"base_url": "",
"api_key": "",
"proxy": "",
"models": [],
}
)
resolved = resolve_search_runtime_config(catalog=catalog)
assert resolved.provider == "serper"
assert resolved.unsupported_provider is False
assert resolved.deprecated_provider is False
assert resolved.missing_credentials is True
def test_search_searxng_without_url_fallback() -> None:
catalog = _build_catalog(
search_profile={
"id": "search-p",
"name": "Search",
"provider": "searxng",
"base_url": "",
"api_key": "",
"proxy": "",
"models": [],
}
)
resolved = resolve_search_runtime_config(catalog=catalog)
assert resolved.provider == "duckduckgo"
assert resolved.fallback_reason is not None