Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions hermes_cli/doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,17 @@ def run_doctor(args):
known_providers.add("custom:" + name.lower().replace(" ", "-"))

canonical_provider = provider
if provider and _resolve_provider_full is not None and provider != "auto":
provider_is_known = bool(provider and provider in known_providers)
if provider and _resolve_provider_full is not None and provider not in {"auto", "custom"}:
provider_def = _resolve_provider_full(provider, user_providers, custom_providers)
canonical_provider = provider_def.id if provider_def is not None else None
if provider_def is not None:
canonical_provider = provider_def.id
provider_is_known = True
else:
canonical_provider = None

if provider and provider != "auto":
if canonical_provider is None or (known_providers and canonical_provider not in known_providers):
if not provider_is_known and (canonical_provider is None or (known_providers and canonical_provider not in known_providers)):
known_list = ", ".join(sorted(known_providers)) if known_providers else "(unavailable)"
check_fail(
f"model.provider '{provider_raw}' is not a recognised provider",
Expand Down
54 changes: 54 additions & 0 deletions tests/hermes_cli/test_doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,60 @@ def test_run_doctor_accepts_named_provider_from_providers_section(monkeypatch, t
assert "model.provider 'volcengine-plan' is not a recognised provider" not in out


@pytest.mark.parametrize(
("provider_name", "model_config"),
[
(
"custom",
{
"provider": "custom",
"default": "gpt-5.4",
"base_url": "https://api.openai.com/v1",
},
),
(
"ai-gateway",
{
"provider": "ai-gateway",
"default": "gpt-5.4",
},
),
],
)
def test_run_doctor_accepts_builtin_and_alias_providers(monkeypatch, tmp_path, provider_name, model_config):
home = tmp_path / ".hermes"
home.mkdir(parents=True, exist_ok=True)

import yaml

(home / "config.yaml").write_text(yaml.dump({"model": model_config}))

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: {})
except Exception:
pass

buf = io.StringIO()
with contextlib.redirect_stdout(buf):
doctor_mod.run_doctor(Namespace(fix=False))

out = buf.getvalue()
assert f"model.provider '{provider_name}' is not a recognised provider" not in out


def test_run_doctor_termux_does_not_mark_browser_available_without_agent_browser(monkeypatch, tmp_path):
home = tmp_path / ".hermes"
home.mkdir(parents=True, exist_ok=True)
Expand Down