diff --git a/tests/hermes_cli/test_config.py b/tests/hermes_cli/test_config.py index 397027d3a..9f77bb4c8 100644 --- a/tests/hermes_cli/test_config.py +++ b/tests/hermes_cli/test_config.py @@ -564,6 +564,30 @@ class TestCustomProviderCompatibility: # Legacy entry wins (read first) assert compatible[0]["api_key"] == "legacy-key" + def test_dedup_preserves_entries_with_different_models(self, tmp_path): + """Entries with same name+URL but different models must not be collapsed.""" + config_path = tmp_path / "config.yaml" + config_path.write_text( + yaml.safe_dump( + { + "_config_version": 17, + "custom_providers": [ + {"name": "Ollama Cloud", "base_url": "https://ollama.com/v1", "model": "qwen3-coder"}, + {"name": "Ollama Cloud", "base_url": "https://ollama.com/v1", "model": "glm-5.1"}, + {"name": "Ollama Cloud", "base_url": "https://ollama.com/v1", "model": "kimi-k2.5"}, + ], + } + ), + encoding="utf-8", + ) + + with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}): + compatible = get_compatible_custom_providers() + + assert len(compatible) == 3 + models = [e.get("model") for e in compatible] + assert models == ["qwen3-coder", "glm-5.1", "kimi-k2.5"] + class TestInterimAssistantMessageConfig: """Test the explicit gateway interim-message config gate.""" diff --git a/tests/hermes_cli/test_model_switch_custom_providers.py b/tests/hermes_cli/test_model_switch_custom_providers.py index 9b81e5641..8c39eef18 100644 --- a/tests/hermes_cli/test_model_switch_custom_providers.py +++ b/tests/hermes_cli/test_model_switch_custom_providers.py @@ -102,3 +102,57 @@ def test_switch_model_accepts_explicit_named_custom_provider(monkeypatch): assert result.new_model == "rotator-openrouter-coding" assert result.base_url == "http://127.0.0.1:4141/v1" assert result.api_key == "no-key-required" + + +def test_list_groups_same_name_custom_providers_into_one_row(monkeypatch): + """Multiple custom_providers entries sharing a name should produce one row + with all models collected, not N duplicate rows.""" + monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {}) + monkeypatch.setattr(providers_mod, "HERMES_OVERLAYS", {}) + + providers = list_authenticated_providers( + current_provider="openrouter", + user_providers={}, + custom_providers=[ + {"name": "Ollama Cloud", "base_url": "https://ollama.com/v1", "model": "qwen3-coder:480b-cloud"}, + {"name": "Ollama Cloud", "base_url": "https://ollama.com/v1", "model": "glm-5.1:cloud"}, + {"name": "Ollama Cloud", "base_url": "https://ollama.com/v1", "model": "kimi-k2.5"}, + {"name": "Ollama Cloud", "base_url": "https://ollama.com/v1", "model": "minimax-m2.7:cloud"}, + {"name": "Moonshot", "base_url": "https://api.moonshot.ai/v1", "model": "kimi-k2-thinking"}, + ], + max_models=50, + ) + + ollama_rows = [p for p in providers if p["name"] == "Ollama Cloud"] + assert len(ollama_rows) == 1, f"Expected 1 Ollama Cloud row, got {len(ollama_rows)}" + assert ollama_rows[0]["models"] == [ + "qwen3-coder:480b-cloud", "glm-5.1:cloud", "kimi-k2.5", "minimax-m2.7:cloud" + ] + assert ollama_rows[0]["total_models"] == 4 + + moonshot_rows = [p for p in providers if p["name"] == "Moonshot"] + assert len(moonshot_rows) == 1 + assert moonshot_rows[0]["models"] == ["kimi-k2-thinking"] + + +def test_list_deduplicates_same_model_in_group(monkeypatch): + """Duplicate model entries under the same provider name should not produce + duplicate entries in the models list.""" + monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {}) + monkeypatch.setattr(providers_mod, "HERMES_OVERLAYS", {}) + + providers = list_authenticated_providers( + current_provider="openrouter", + user_providers={}, + custom_providers=[ + {"name": "MyProvider", "base_url": "http://localhost:11434/v1", "model": "llama3"}, + {"name": "MyProvider", "base_url": "http://localhost:11434/v1", "model": "llama3"}, + {"name": "MyProvider", "base_url": "http://localhost:11434/v1", "model": "mistral"}, + ], + max_models=50, + ) + + my_rows = [p for p in providers if p["name"] == "MyProvider"] + assert len(my_rows) == 1 + assert my_rows[0]["models"] == ["llama3", "mistral"] + assert my_rows[0]["total_models"] == 2