91 lines
4.3 KiB
Python
91 lines
4.3 KiB
Python
import unittest.mock
|
|
from unittest.mock import patch, MagicMock
|
|
import pytest
|
|
from src import ai_client
|
|
|
|
def test_minimax_model_selection() -> None:
|
|
ai_client.set_provider("minimax", "MiniMax-M2.5")
|
|
assert ai_client._provider == "minimax"
|
|
assert ai_client._model == "MiniMax-M2.5"
|
|
|
|
def test_minimax_default_model() -> None:
|
|
ai_client.set_provider("minimax", "invalid-model")
|
|
assert ai_client._model == "MiniMax-M2.5"
|
|
|
|
def test_minimax_list_models() -> None:
|
|
models = ai_client.list_models("minimax")
|
|
assert "MiniMax-M2.7" in models
|
|
assert "MiniMax-M2.5" in models
|
|
assert "MiniMax-M2.1" in models
|
|
assert "MiniMax-M2" in models
|
|
|
|
def test_minimax_in_providers_list() -> None:
|
|
from src.models import PROVIDERS
|
|
assert "minimax" in PROVIDERS
|
|
|
|
def test_minimax_in_app_controller_providers() -> None:
|
|
from src.models import PROVIDERS
|
|
assert "minimax" in PROVIDERS
|
|
|
|
def test_minimax_credentials_template() -> None:
|
|
try:
|
|
ai_client._load_credentials()
|
|
except FileNotFoundError as e:
|
|
error_msg = str(e)
|
|
assert "minimax" in error_msg
|
|
|
|
def test_minimax_reasoning_extractor_used_when_caps_reasoning_true() -> None:
|
|
"""caps.reasoning=True (M2.5/M2.7) should pass the reasoning_extractor to run_with_tool_loop."""
|
|
from src import openai_compatible as oc
|
|
captured_kwargs: list[dict] = []
|
|
def _fake_send(client, request, *, capabilities):
|
|
captured_kwargs.append({"model": request.model})
|
|
return MagicMock(text="ok", tool_calls=[], usage_input_tokens=0, usage_output_tokens=0, usage_cache_read_tokens=0, usage_cache_creation_tokens=0, raw_response=None)
|
|
from src.vendor_capabilities import register, VendorCapabilities
|
|
register(VendorCapabilities(vendor='minimax', model='MiniMax-M2.5', reasoning=True))
|
|
with patch.object(oc, "send_openai_compatible", side_effect=_fake_send), \
|
|
patch("src.ai_client._ensure_minimax_client", return_value=MagicMock()), \
|
|
patch("src.ai_client._get_deepseek_tools", return_value=[]):
|
|
ai_client._send_minimax("system", "user", ".", None, "", False, None, None, None)
|
|
assert len(captured_kwargs) >= 1
|
|
|
|
def test_minimax_reasoning_extractor_omitted_when_caps_reasoning_false() -> None:
|
|
"""caps.reasoning=False (M2/M2.1) should NOT pass the reasoning_extractor (avoid useless getattr)."""
|
|
from src import openai_compatible as oc
|
|
from src.vendor_capabilities import register, VendorCapabilities
|
|
register(VendorCapabilities(vendor='minimax', model='MiniMax-M2', reasoning=False))
|
|
captured_kwargs: list[dict] = []
|
|
def _fake_send(client, request, *, capabilities):
|
|
captured_kwargs.append({"model": request.model})
|
|
return MagicMock(text="ok", tool_calls=[], usage_input_tokens=0, usage_output_tokens=0, usage_cache_read_tokens=0, usage_cache_creation_tokens=0, raw_response=None)
|
|
with patch.object(oc, "send_openai_compatible", side_effect=_fake_send), \
|
|
patch("src.ai_client._ensure_minimax_client", return_value=MagicMock()), \
|
|
patch("src.ai_client._get_deepseek_tools", return_value=[]):
|
|
ai_client._send_minimax("system", "user", ".", None, "", False, None, None, None)
|
|
assert len(captured_kwargs) >= 1
|
|
|
|
def test_minimax_ensure_client_instantiation() -> None:
|
|
"""Verify that _ensure_minimax_client instantiates the OpenAI client with correct credentials and base URL."""
|
|
mock_openai = MagicMock()
|
|
mock_openai_module = MagicMock()
|
|
mock_openai_module.OpenAI = mock_openai
|
|
|
|
with patch("src.ai_client._require_warmed", return_value=mock_openai_module), \
|
|
patch("src.ai_client._load_credentials", return_value={"minimax": {"api_key": "test-key-123", "base_url": "https://api.minimax.io/v1"}}):
|
|
# Reset client state to force instantiation
|
|
ai_client._minimax_client = None
|
|
ai_client._ensure_minimax_client()
|
|
|
|
# Assert correct arguments passed to OpenAI
|
|
mock_openai.assert_called_once_with(api_key="test-key-123", base_url="https://api.minimax.io/v1")
|
|
assert ai_client._minimax_client == mock_openai.return_value
|
|
|
|
def test_minimax_ensure_client_missing_key_raises_value_error() -> None:
|
|
"""Verify that _ensure_minimax_client raises ValueError if API key is missing."""
|
|
mock_openai_module = MagicMock()
|
|
with patch("src.ai_client._require_warmed", return_value=mock_openai_module), \
|
|
patch("src.ai_client._load_credentials", return_value={}):
|
|
ai_client._minimax_client = None
|
|
with pytest.raises(ValueError, match="MiniMax API key not found in credentials.toml"):
|
|
ai_client._ensure_minimax_client()
|