{"repo":"NousResearch/hermes-agent","public_id":"4082","display_label":"MiniMax model config and pricing corrections","summary":"These issues and fixes address incorrect MiniMax model catalog entries, context lengths, auxiliary model selection, and a cost concern with the default highspeed auxiliary model being priced higher than expected. Changes update configuration details including base_url and thinking guard settings.","subsystem":"agent","counts":{"members":4,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":2},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":6082,"merged_at":"2026-04-08T09:20:46+00:00"},"resolution":{"state":"unresolved","by":null},"freshness":{"state":"stale","last_verified_at":"2026-04-08T09:20:46+00:00","is_stale":true},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.5},"fix_edges":[{"issue_number":4082,"pr_number":6082,"tier":"verified","basis":"superseded_ref","confidence":0.9,"recoverable_from_timeline":false,"pr_merged_at":"2026-04-08T09:20:46+00:00"},{"issue_number":5777,"pr_number":6082,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-04-08T09:20:46+00:00"},{"issue_number":6039,"pr_number":6082,"tier":"verified","basis":"superseded_ref","confidence":0.9,"recoverable_from_timeline":false,"pr_merged_at":"2026-04-08T09:20:46+00:00"}],"members":[{"kind":"issue","number":4082,"title":"[Bug]: Minimax Default Auxiallry Model MiniMax-M2.7-highspeed is twice the price at API rates","url":null,"state":"closed"},{"kind":"pr","number":4115,"title":"fix(agent): use standard MiniMax-M2.7 for auxiliary model instead of highspeed","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#6082","number":6082}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false},{"kind":"pr","number":6046,"title":"fix(minimax): correct context lengths, model catalog, thinking guard, aux model, and config base_url","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#6082","number":6082}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":6082,"title":"fix(minimax): correct context lengths, model catalog, thinking guard, aux model, and config base_url","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["agent/anthropic_adapter.py","agent/auxiliary_client.py","agent/model_metadata.py","hermes_cli/models.py","hermes_cli/runtime_provider.py","hermes_cli/setup.py","tests/agent/test_minimax_provider.py","tests/hermes_cli/test_runtime_provider_resolution.py","tests/hermes_cli/test_setup_model_selection.py"],"fix_hunks":[{"file":"agent/anthropic_adapter.py","hunks":["@@ -1224,9 +1224,9 @@ def build_anthropic_kwargs(\n     # Map reasoning_config to Anthropic's thinking parameter.\n     # Claude 4.6 models use adaptive thinking + output_config.effort.\n     # Older models use manual thinking with budget_tokens.\n-    # Haiku models do NOT support extended thinking at all — skip entirely.\n+    # Haiku and MiniMax models do NOT support extended thinking — skip entirely.\n     if reasoning_config and isinstance(reasoning_config, dict):\n-        if reasoning_config.get(\"enabled\") is not False and \"haiku\" not in model.lower():\n+        if reasoning_config.get(\"enabled\") is not False and \"haiku\" not in model.lower() and \"minimax\" not in model.lower():\n             effort = str(reasoning_config.get(\"effort\", \"medium\")).lower()\n             budget = THINKING_BUDGET.get(effort, 8000)\n             if _supports_adaptive_thinking(model):"]},{"file":"agent/auxiliary_client.py","hunks":["@@ -99,8 +99,8 @@ def _normalize_aux_provider(provider: Optional[str], *, for_vision: bool = False\n     \"gemini\": \"gemini-3-flash-preview\",\n     \"zai\": \"glm-4.5-flash\",\n     \"kimi-coding\": \"kimi-k2-turbo-preview\",\n-    \"minimax\": \"MiniMax-M2.7-highspeed\",\n-    \"minimax-cn\": \"MiniMax-M2.7-highspeed\",\n+    \"minimax\": \"MiniMax-M2.7\",\n+    \"minimax-cn\": \"MiniMax-M2.7\",\n     \"anthropic\": \"claude-haiku-4-5-20251001\",\n     \"ai-gateway\": \"google/gemini-3-flash\",\n     \"opencode-zen\": \"gemini-3-flash\","]},{"file":"agent/model_metadata.py","hunks":["@@ -113,8 +113,15 @@ def _strip_provider_prefix(model: str) -> str:\n     \"llama\": 131072,\n     # Qwen\n     \"qwen\": 131072,\n-    # MiniMax\n-    \"minimax\": 204800,\n+    # MiniMax (lowercase — lookup lowercases model names at line 973)\n+    \"minimax-m1-256k\": 1000000,\n+    \"minimax-m1-128k\": 1000000,\n+    \"minimax-m1-80k\": 1000000,\n+    \"minimax-m1-40k\": 1000000,\n+    \"minimax-m1\": 1000000,\n+    \"minimax-m2.5\": 1048576,\n+    \"minimax-m2.7\": 1048576,\n+    \"minimax\": 1048576,\n     # GLM\n     \"glm\": 202752,\n     # Kimi","@@ -127,7 +134,7 @@ def _strip_provider_prefix(model: str) -> str:\n     \"deepseek-ai/DeepSeek-V3.2\": 65536,\n     \"moonshotai/Kimi-K2.5\": 262144,\n     \"moonshotai/Kimi-K2-Thinking\": 262144,\n-    \"MiniMaxAI/MiniMax-M2.5\": 204800,\n+    \"minimaxai/minimax-m2.5\": 1048576,\n     \"XiaomiMiMo/MiMo-V2-Flash\": 32768,\n     \"mimo-v2-pro\": 1048576,\n     \"mimo-v2-omni\": 1048576,"]},{"file":"hermes_cli/models.py","hunks":["@@ -144,18 +144,22 @@\n         \"kimi-k2-0905-preview\",\n     ],\n     \"minimax\": [\n-        \"MiniMax-M2.7\",\n-        \"MiniMax-M2.7-highspeed\",\n+        \"MiniMax-M1\",\n+        \"MiniMax-M1-40k\",\n+        \"MiniMax-M1-80k\",\n+        \"MiniMax-M1-128k\",\n+        \"MiniMax-M1-256k\",\n         \"MiniMax-M2.5\",\n-        \"MiniMax-M2.5-highspeed\",\n-        \"MiniMax-M2.1\",\n+        \"MiniMax-M2.7\",\n     ],\n     \"minimax-cn\": [\n-        \"MiniMax-M2.7\",\n-        \"MiniMax-M2.7-highspeed\",\n+        \"MiniMax-M1\",\n+        \"MiniMax-M1-40k\",\n+        \"MiniMax-M1-80k\",\n+        \"MiniMax-M1-128k\",\n+        \"MiniMax-M1-256k\",\n         \"MiniMax-M2.5\",\n-        \"MiniMax-M2.5-highspeed\",\n-        \"MiniMax-M2.1\",\n+        \"MiniMax-M2.7\",\n     ],\n     \"anthropic\": [\n         \"claude-opus-4-6\","]},{"file":"hermes_cli/runtime_provider.py","hunks":["@@ -163,6 +163,16 @@ def _resolve_runtime_from_pool_entry(\n         api_mode = _copilot_runtime_api_mode(model_cfg, getattr(entry, \"runtime_api_key\", \"\"))\n     else:\n         configured_provider = str(model_cfg.get(\"provider\") or \"\").strip().lower()\n+        # Honour model.base_url from config.yaml when the configured provider\n+        # matches this provider — same pattern as the Anthropic branch above.\n+        # Only override when the pool entry has no explicit base_url (i.e. it\n+        # fell back to the hardcoded default).  Env var overrides win (#6039).\n+        pconfig = PROVIDER_REGISTRY.get(provider)\n+        pool_url_is_default = pconfig and base_url.rstrip(\"/\") == pconfig.inference_base_url.rstrip(\"/\")\n+        if configured_provider == provider and pool_url_is_default:\n+            cfg_base_url = str(model_cfg.get(\"base_url\") or \"\").strip().rstrip(\"/\")\n+            if cfg_base_url:\n+                base_url = cfg_base_url\n         configured_mode = _parse_api_mode(model_cfg.get(\"api_mode\"))\n         if configured_mode and _provider_supports_explicit_api_mode(provider, configured_provider):\n             api_mode = configured_mode","@@ -724,7 +734,15 @@ def resolve_runtime_provider(\n     pconfig = PROVIDER_REGISTRY.get(provider)\n     if pconfig and pconfig.auth_type == \"api_key\":\n         creds = resolve_api_key_provider_credentials(provider)\n-        base_url = creds.get(\"base_url\", \"\").rstrip(\"/\")\n+        # Honour model.base_url from config.yaml when the configured provider\n+        # matches this provider — mirrors the Anthropic path above.  Without\n+        # this, users who set model.base_url to e.g. api.minimaxi.com/anthropic\n+        # (China endpoint) still get the hardcoded api.minimax.io default (#6039).\n+        cfg_provider = str(model_cfg.get(\"provider\") or \"\").strip().lower()\n+        cfg_base_url = \"\"\n+        if cfg_provider == provider:\n+            cfg_base_url = (model_cfg.get(\"base_url\") or \"\").strip().rstrip(\"/\")\n+        base_url = cfg_base_url or creds.get(\"base_url\", \"\").rstrip(\"/\")\n         api_mode = \"chat_completions\"\n         if provider == \"copilot\":\n             api_mode = _copilot_runtime_api_mode(model_cfg, creds.get(\"api_key\", \"\"))"]},{"file":"hermes_cli/setup.py","hunks":["@@ -105,8 +105,8 @@ def _supports_same_provider_pool_setup(provider: str) -> bool:\n     ],\n     \"zai\": [\"glm-5\", \"glm-4.7\", \"glm-4.5\", \"glm-4.5-flash\"],\n     \"kimi-coding\": [\"kimi-k2.5\", \"kimi-k2-thinking\", \"kimi-k2-turbo-preview\"],\n-    \"minimax\": [\"MiniMax-M2.7\", \"MiniMax-M2.7-highspeed\", \"MiniMax-M2.5\", \"MiniMax-M2.5-highspeed\", \"MiniMax-M2.1\"],\n-    \"minimax-cn\": [\"MiniMax-M2.7\", \"MiniMax-M2.7-highspeed\", \"MiniMax-M2.5\", \"MiniMax-M2.5-highspeed\", \"MiniMax-M2.1\"],\n+    \"minimax\": [\"MiniMax-M1\", \"MiniMax-M1-40k\", \"MiniMax-M1-80k\", \"MiniMax-M1-128k\", \"MiniMax-M1-256k\", \"MiniMax-M2.5\", \"MiniMax-M2.7\"],\n+    \"minimax-cn\": [\"MiniMax-M1\", \"MiniMax-M1-40k\", \"MiniMax-M1-80k\", \"MiniMax-M1-128k\", \"MiniMax-M1-256k\", \"MiniMax-M2.5\", \"MiniMax-M2.7\"],\n     \"ai-gateway\": [\"anthropic/claude-opus-4.6\", \"anthropic/claude-sonnet-4.6\", \"openai/gpt-5\", \"google/gemini-3-flash\"],\n     \"kilocode\": [\"anthropic/claude-opus-4.6\", \"anthropic/claude-sonnet-4.6\", \"openai/gpt-5.4\", \"google/gemini-3-pro-preview\", \"google/gemini-3-flash-preview\"],\n     \"opencode-zen\": [\"gpt-5.4\", \"gpt-5.3-codex\", \"claude-sonnet-4-6\", \"gemini-3-flash\", \"glm-5\", \"kimi-k2.5\", \"minimax-m2.7\"],"]},{"file":"tests/agent/test_minimax_provider.py","hunks":["@@ -0,0 +1,105 @@\n+\"\"\"Tests for MiniMax provider hardening — context lengths, thinking guard, catalog.\"\"\"\n+\n+\n+class TestMinimaxContextLengths:\n+    \"\"\"Verify per-model context length entries for MiniMax models.\"\"\"\n+\n+    def test_m1_variants_have_1m_context(self):\n+        from agent.model_metadata import DEFAULT_CONTEXT_LENGTHS\n+        # Keys are lowercase because the lookup lowercases model names\n+        for model in (\"minimax-m1\", \"minimax-m1-40k\", \"minimax-m1-80k\",\n+                       \"minimax-m1-128k\", \"minimax-m1-256k\"):\n+            assert model in DEFAULT_CONTEXT_LENGTHS, f\"{model} missing from context lengths\"\n+            assert DEFAULT_CONTEXT_LENGTHS[model] == 1_000_000, f\"{model} expected 1M\"\n+\n+    def test_m2_variants_have_1m_context(self):\n+        from agent.model_metadata import DEFAULT_CONTEXT_LENGTHS\n+        # Keys are lowercase because the lookup lowercases model names\n+        for model in (\"minimax-m2.5\", \"minimax-m2.7\"):\n+            assert model in DEFAULT_CONTEXT_LENGTHS, f\"{model} missing from context lengths\"\n+            assert DEFAULT_CONTEXT_LENGTHS[model] == 1_048_576, f\"{model} expected 1048576\"\n+\n+    def test_minimax_prefix_fallback(self):\n+        from agent.model_metadata import DEFAULT_CONTEXT_LENGTHS\n+        # The generic \"minimax\" prefix entry should be 1M for unknown models\n+        assert DEFAULT_CONTEXT_LENGTHS[\"minimax\"] == 1_048_576\n+\n+\n+\n+class TestMinimaxThinkingGuard:\n+    \"\"\"Verify that build_anthropic_kwargs does NOT add thinking params for MiniMax models.\"\"\"\n+\n+    def test_no_thinking_for_minimax_m27(self):\n+        from agent.anthropic_adapter import build_anthropic_kwargs\n+        kwargs = build_anthropic_kwargs(\n+            model=\"MiniMax-M2.7\",\n+            messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n+            tools=None,\n+            max_tokens=4096,\n+            reasoning_config={\"enabled\": True, \"effort\": \"medium\"},\n+        )\n+        assert \"thinking\" not in kwargs\n+        assert \"output_config\" not in kwargs\n+\n+    def test_no_thinking_for_minimax_m1(self):\n+        from agent.anthropic_adapter import build_anthropic_kwargs\n+        kwargs = build_anthropic_kwargs(\n+            model=\"MiniMax-M1-128k\",\n+            messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n+            tools=None,\n+            max_tokens=4096,\n+            reasoning_config={\"enabled\": True, \"effort\": \"high\"},\n+        )\n+        assert \"thinking\" not in kwargs\n+\n+    def test_thinking_still_works_for_claude(self):\n+        from agent.anthropic_adapter import build_anthropic_kwargs\n+        kwargs = build_anthropic_kwargs(\n+            model=\"claude-sonnet-4-20250514\",\n+            messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n+            tools=None,\n+            max_tokens=4096,\n+            reasoning_config={\"enabled\": True, \"effort\": \"medium\"},\n+        )\n+        assert \"thinking\" in kwargs\n+\n+\n+class TestMinimaxAuxModel:\n+    \"\"\"Verify auxiliary model is standard (not highspeed).\"\"\"\n+\n+    def test_minimax_aux_is_standard(self):\n+        from agent.auxiliary_client import _API_KEY_PROVIDER_AUX_MODELS\n+        assert _API_KEY_PROVIDER_AUX_MODELS[\"minimax\"] == \"MiniMax-M2.7\"\n+        assert _API_KEY_PROVIDER_AUX_MODELS[\"minimax-cn\"] == \"MiniMax-M2.7\"\n+\n+    def test_minimax_aux_not_highspeed(self):\n+        from agent.auxiliary_client import _API_KEY_PROVIDER_AUX_MODELS\n+        assert \"highspeed\" not in _API_KEY_PROVIDER_AUX_MODELS[\"minimax\"]\n+        assert \"highspeed\" not in _API_KEY_PROVIDER_AUX_MODELS[\"minimax-cn\"]\n+\n+\n+class TestMinimaxModelCatalog:\n+    \"\"\"Verify the model catalog includes M1 family and excludes deprecated models.\"\"\"\n+\n+    def test_catalog_includes_m1_family(self):\n+        from hermes_cli.models import _PROVIDER_MODELS\n+        for provider in (\"minimax\", \"minimax-cn\"):\n+            models = _PROVIDER_MODELS[provider]\n+            assert \"MiniMax-M1\" in models\n+            assert \"MiniMax-M1-40k\" in models\n+            assert \"MiniMax-M1-80k\" in models\n+            assert \"MiniMax-M1-128k\" in models\n+            assert \"MiniMax-M1-256k\" in models\n+\n+    def test_catalog_excludes_deprecated(self):\n+        from hermes_cli.models import _PROVIDER_MODELS\n+        for provider in (\"minimax\", \"minimax-cn\"):\n+            models = _PROVIDER_MODELS[provider]\n+            assert \"MiniMax-M2.1\" not in models\n+\n+    def test_catalog_excludes_highspeed(self):\n+        from hermes_cli.models import _PROVIDER_MODELS\n+        for provider in (\"minimax\", \"minimax-cn\"):\n+            models = _PROVIDER_MODELS[provider]\n+            assert \"MiniMax-M2.7-highspeed\" not in models\n+            assert \"MiniMax-M2.5-highspeed\" not in models"]},{"file":"tests/hermes_cli/test_runtime_provider_resolution.py","hunks":["@@ -808,6 +808,55 @@ def test_minimax_explicit_api_mode_respected(monkeypatch):\n     assert resolved[\"api_mode\"] == \"chat_completions\"\n \n \n+def test_minimax_config_base_url_overrides_hardcoded_default(monkeypatch):\n+    \"\"\"model.base_url in config.yaml should override the hardcoded default (#6039).\"\"\"\n+    monkeypatch.setattr(rp, \"resolve_provider\", lambda *a, **k: \"minimax\")\n+    monkeypatch.setattr(rp, \"_get_model_config\", lambda: {\n+        \"provider\": \"minimax\",\n+        \"base_url\": \"https://api.minimaxi.com/anthropic\",\n+    })\n+    monkeypatch.setenv(\"MINIMAX_API_KEY\", \"test-minimax-key\")\n+    monkeypatch.delenv(\"MINIMAX_BASE_URL\", raising=False)\n+\n+    resolved = rp.resolve_runtime_provider(requested=\"minimax\")\n+\n+    assert resolved[\"provider\"] == \"minimax\"\n+    assert resolved[\"base_url\"] == \"https://api.minimaxi.com/anthropic\"\n+    assert resolved[\"api_mode\"] == \"anthropic_messages\"\n+\n+\n+def test_minimax_env_base_url_still_wins_over_config(monkeypatch):\n+    \"\"\"MINIMAX_BASE_URL env var should take priority over config.yaml model.base_url.\"\"\"\n+    monkeypatch.setattr(rp, \"resolve_provider\", lambda *a, **k: \"minimax\")\n+    monkeypatch.setattr(rp, \"_get_model_config\", lambda: {\n+        \"provider\": \"minimax\",\n+        \"base_url\": \"https://api.minimaxi.com/anthropic\",\n+    })\n+    monkeypatch.setenv(\"MINIMAX_API_KEY\", \"test-minimax-key\")\n+    monkeypatch.setenv(\"MINIMAX_BASE_URL\", \"https://custom.example.com/v1\")\n+\n+    resolved = rp.resolve_runtime_provider(requested=\"minimax\")\n+\n+    # Env var wins because resolve_api_key_provider_credentials prefers it\n+    assert resolved[\"base_url\"] == \"https://custom.example.com/v1\"\n+\n+\n+def test_minimax_config_base_url_ignored_for_different_provider(monkeypatch):\n+    \"\"\"model.base_url should NOT be used when model.provider doesn't match.\"\"\"\n+    monkeypatch.setattr(rp, \"resolve_provider\", lambda *a, **k: \"minimax\")\n+    monkeypatch.setattr(rp, \"_get_model_config\", lambda: {\n+        \"provider\": \"openrouter\",\n+        \"base_url\": \"https://some-other-endpoint.com/v1\",\n+    })\n+    monkeypatch.setenv(\"MINIMAX_API_KEY\", \"test-minimax-key\")\n+    monkeypatch.delenv(\"MINIMAX_BASE_URL\", raising=False)\n+\n+    resolved = rp.resolve_runtime_provider(requested=\"minimax\")\n+\n+    # Should use the default, NOT the config base_url from a different provider\n+    assert resolved[\"base_url\"] == \"https://api.minimax.io/anthropic\"\n+\n+\n def test_alibaba_default_coding_intl_endpoint_uses_chat_completions(monkeypatch):\n     \"\"\"Alibaba default coding-intl /v1 URL should use chat_completions mode.\"\"\"\n     monkeypatch.setattr(rp, \"resolve_provider\", lambda *a, **k: \"alibaba\")"]},{"file":"tests/hermes_cli/test_setup_model_selection.py","hunks":["@@ -34,8 +34,8 @@ class TestSetupProviderModelSelection:\n     @pytest.mark.parametrize(\"provider_id,expected_defaults\", [\n         (\"zai\", [\"glm-5\", \"glm-4.7\", \"glm-4.5\", \"glm-4.5-flash\"]),\n         (\"kimi-coding\", [\"kimi-k2.5\", \"kimi-k2-thinking\", \"kimi-k2-turbo-preview\"]),\n-        (\"minimax\", [\"MiniMax-M2.7\", \"MiniMax-M2.7-highspeed\", \"MiniMax-M2.5\", \"MiniMax-M2.5-highspeed\", \"MiniMax-M2.1\"]),\n-        (\"minimax-cn\", [\"MiniMax-M2.7\", \"MiniMax-M2.7-highspeed\", \"MiniMax-M2.5\", \"MiniMax-M2.5-highspeed\", \"MiniMax-M2.1\"]),\n+        (\"minimax\", [\"MiniMax-M1\", \"MiniMax-M1-40k\", \"MiniMax-M1-80k\", \"MiniMax-M1-128k\", \"MiniMax-M1-256k\", \"MiniMax-M2.5\", \"MiniMax-M2.7\"]),\n+        (\"minimax-cn\", [\"MiniMax-M1\", \"MiniMax-M1-40k\", \"MiniMax-M1-80k\", \"MiniMax-M1-128k\", \"MiniMax-M1-256k\", \"MiniMax-M2.5\", \"MiniMax-M2.7\"]),\n         (\"opencode-zen\", [\"gpt-5.4\", \"gpt-5.3-codex\", \"claude-sonnet-4-6\", \"gemini-3-flash\"]),\n         (\"opencode-go\", [\"glm-5\", \"kimi-k2.5\", \"minimax-m2.5\", \"minimax-m2.7\"]),\n     ])\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}