mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-09 08:21:50 +00:00
fix(doctor): allow vendor slugs for named custom providers
This commit is contained in:
parent
421226e404
commit
732ababa1a
4 changed files with 65 additions and 3 deletions
|
|
@ -740,6 +740,7 @@ def run_doctor(args):
|
|||
|
||||
# Warn if model is set to a provider-prefixed name on a provider that doesn't use them
|
||||
provider_for_policy = runtime_provider or catalog_provider
|
||||
provider_policy_id = str(provider_for_policy or "").strip().lower()
|
||||
providers_accepting_vendor_slugs = {
|
||||
"openrouter",
|
||||
"custom",
|
||||
|
|
@ -753,8 +754,9 @@ def run_doctor(args):
|
|||
if (
|
||||
default_model
|
||||
and "/" in default_model
|
||||
and provider_for_policy
|
||||
and provider_for_policy not in providers_accepting_vendor_slugs
|
||||
and provider_policy_id
|
||||
and provider_policy_id not in providers_accepting_vendor_slugs
|
||||
and not provider_policy_id.startswith("custom:")
|
||||
):
|
||||
check_warn(
|
||||
f"model.default '{default_model}' uses a vendor/model slug but provider is '{provider_raw}'",
|
||||
|
|
|
|||
|
|
@ -492,7 +492,10 @@ def get_label(provider_id: str) -> str:
|
|||
|
||||
def is_aggregator(provider: str) -> bool:
|
||||
"""Return True when the provider is a multi-model aggregator."""
|
||||
pdef = get_provider(provider)
|
||||
provider_norm = normalize_provider(provider or "")
|
||||
if provider_norm.startswith("custom:"):
|
||||
return True
|
||||
pdef = get_provider(provider_norm)
|
||||
return pdef.is_aggregator if pdef else False
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -540,6 +540,54 @@ def test_run_doctor_accepts_hermes_provider_ids_that_catalog_aliases(
|
|||
)
|
||||
|
||||
|
||||
def test_run_doctor_accepts_vendor_slugs_for_named_custom_provider(monkeypatch, tmp_path):
|
||||
home = tmp_path / ".hermes"
|
||||
home.mkdir(parents=True, exist_ok=True)
|
||||
(home / "config.yaml").write_text(
|
||||
"model:\n"
|
||||
" provider: custom:hpc-ai\n"
|
||||
" default: deepseek/deepseek-v4-flash\n"
|
||||
"custom_providers:\n"
|
||||
" - name: hpc-ai\n"
|
||||
" base_url: https://hpc-ai.example/v1\n"
|
||||
" api_key: test-key\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
monkeypatch.setattr(doctor_mod, "HERMES_HOME", home)
|
||||
monkeypatch.setattr(doctor_mod, "PROJECT_ROOT", tmp_path / "project")
|
||||
monkeypatch.setattr(doctor_mod, "_DHH", str(home))
|
||||
(tmp_path / "project").mkdir(exist_ok=True)
|
||||
|
||||
fake_model_tools = types.SimpleNamespace(
|
||||
check_tool_availability=lambda *a, **kw: ([], []),
|
||||
TOOLSET_REQUIREMENTS={},
|
||||
)
|
||||
monkeypatch.setitem(sys.modules, "model_tools", fake_model_tools)
|
||||
|
||||
try:
|
||||
from hermes_cli import auth as _auth_mod
|
||||
monkeypatch.setattr(_auth_mod, "get_nous_auth_status", lambda: {})
|
||||
monkeypatch.setattr(_auth_mod, "get_codex_auth_status", lambda: {})
|
||||
monkeypatch.setattr(_auth_mod, "get_xai_oauth_auth_status", lambda: {})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
buf = io.StringIO()
|
||||
with contextlib.redirect_stdout(buf):
|
||||
doctor_mod.run_doctor(Namespace(fix=False))
|
||||
|
||||
out = buf.getvalue()
|
||||
assert "model.provider 'custom:hpc-ai' is not a recognised provider" not in out
|
||||
assert "model.provider 'custom:hpc-ai' is unknown" not in out
|
||||
assert (
|
||||
"model.default 'deepseek/deepseek-v4-flash' uses a vendor/model slug but provider is "
|
||||
"'custom:hpc-ai'"
|
||||
not in out
|
||||
)
|
||||
assert "Either set model.provider to 'openrouter', or drop the vendor prefix." not in out
|
||||
|
||||
|
||||
|
||||
|
||||
def test_run_doctor_accepts_kimi_coding_cn_provider(monkeypatch, tmp_path):
|
||||
|
|
|
|||
|
|
@ -65,6 +65,15 @@ def test_resolve_provider_full_finds_named_custom_provider():
|
|||
assert resolved.source == "user-config"
|
||||
|
||||
|
||||
def test_is_aggregator_recognizes_named_custom_provider():
|
||||
assert providers_mod.is_aggregator("custom:hpc-ai") is True
|
||||
assert providers_mod.is_aggregator("custom:litellm") is True
|
||||
|
||||
|
||||
def test_is_aggregator_leaves_unknown_provider_non_aggregator():
|
||||
assert providers_mod.is_aggregator("not-a-provider") is False
|
||||
|
||||
|
||||
def test_switch_model_accepts_explicit_named_custom_provider(monkeypatch):
|
||||
"""Shared /model switch pipeline should accept --provider for custom_providers."""
|
||||
monkeypatch.setattr(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue