| """Tests for MiniMax model validation via static catalog (issues #12611, #12460, #12399, #12547). |
| |
| MiniMax and MiniMax-CN providers don't expose /v1/models, so validate_requested_model() |
| must validate against the static catalog instead of probing the live API. |
| """ |
|
|
| from unittest.mock import patch |
|
|
| import pytest |
|
|
| from hermes_cli.models import validate_requested_model |
|
|
|
|
| class TestMiniMaxModelValidation: |
| """Test that validate_requested_model handles MiniMax providers correctly.""" |
|
|
| @pytest.fixture(autouse=True) |
| def _isolate_minimax(self): |
| """Ensure MiniMax catalog is used even if a live /v1/models endpoint exists.""" |
| |
| |
| probe_payload = { |
| "models": None, |
| "probed_url": "https://api.minimax.io/v1/models", |
| "resolved_base_url": "https://api.minimax.io/v1", |
| "suggested_base_url": None, |
| "used_fallback": False, |
| } |
| with patch("hermes_cli.models.fetch_api_models", return_value=None), \ |
| patch("hermes_cli.models.probe_api_models", return_value=probe_payload): |
| yield |
|
|
| |
| |
| |
| def test_valid_minimax_model_accepted(self): |
| result = validate_requested_model("MiniMax-M2.7", "minimax") |
| assert result["accepted"] is True |
| assert result["persist"] is True |
| assert result["recognized"] is True |
| assert result["message"] is None |
|
|
| |
| |
| |
| def test_valid_minimax_model_case_insensitive(self): |
| result = validate_requested_model("minimax-m2.7", "minimax") |
| assert result["accepted"] is True |
| assert result["persist"] is True |
| assert result["recognized"] is True |
| assert result["message"] is None |
|
|
| def test_valid_minimax_model_uppercase(self): |
| result = validate_requested_model("MINIMAX-M2.7", "minimax") |
| assert result["accepted"] is True |
| assert result["recognized"] is True |
|
|
| |
| |
| |
| def test_near_match_minimax_cn_suggests_similar(self): |
| |
| |
| |
| result = validate_requested_model("MiniMax-M2.7-highspeed", "minimax-cn") |
| assert result["accepted"] is True |
| assert result["persist"] is True |
| assert result["recognized"] is False |
| |
| assert "corrected_model" not in result |
| |
| assert "MiniMax-M2.7" in result["message"] |
|
|
| |
| |
| |
| def test_unknown_minimax_model_accepted_with_warning(self): |
| |
| |
| |
| result = validate_requested_model("NotARealModel", "minimax") |
| assert result["accepted"] is True |
| assert result["persist"] is True |
| assert result["recognized"] is False |
| assert "NotARealModel" in result["message"] |
| assert "not found in the MiniMax catalog" in result["message"] |
| assert "MiniMax does not expose a /models endpoint" in result["message"] |
|
|
| |
| |
| |
| def test_minimax_uses_catalog_not_api_probe(self): |
| """Ensure that when fetch_api_models returns None, the catalog is still checked.""" |
| |
| |
| result = validate_requested_model("MiniMax-M2.5", "minimax") |
| assert result["accepted"] is True |
| assert result["recognized"] is True |
| assert result["message"] is None |
|
|
|
|
| class TestMiniMaxCatalogPathRequired: |
| """Prove the catalog path is necessary: without it, MiniMax would fail. |
| |
| These tests demonstrate that when fetch_api_models returns None (simulating |
| the real 404 from MiniMax /v1/models), the openai-codex-style catalog path |
| is the only way to avoid a "Could not reach the API" failure. |
| """ |
|
|
| def test_minimax_without_fix_would_reach_api_probe(self): |
| """Without the catalog block, minimax falls through to fetch_api_models. |
| |
| This test documents the before-fix behavior: when the MiniMax block |
| is absent, the code falls through to `api_models = fetch_api_models(...)` |
| which returns None (404), leading to rejection. |
| """ |
| probe_payload = { |
| "models": None, |
| "probed_url": "https://api.minimax.io/v1/models", |
| "resolved_base_url": "https://api.minimax.io/v1", |
| "suggested_base_url": None, |
| "used_fallback": False, |
| } |
| with patch("hermes_cli.models.fetch_api_models", return_value=None), \ |
| patch("hermes_cli.models.probe_api_models", return_value=probe_payload): |
| |
| |
| result = validate_requested_model("MiniMax-M2.7", "minimax") |
| |
| assert result["accepted"] is True |
|
|