mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix: tighten hermes doctor issue summary
This commit is contained in:
parent
5dda4cab41
commit
20853c23e2
2 changed files with 104 additions and 23 deletions
|
|
@ -454,11 +454,7 @@ def run_doctor(args):
|
|||
print(color("◆ Auth Providers", Colors.CYAN, Colors.BOLD))
|
||||
|
||||
try:
|
||||
from hermes_cli.auth import (
|
||||
get_nous_auth_status,
|
||||
get_codex_auth_status,
|
||||
get_gemini_oauth_auth_status,
|
||||
)
|
||||
from hermes_cli.auth import get_nous_auth_status, get_codex_auth_status
|
||||
|
||||
nous_status = get_nous_auth_status()
|
||||
if nous_status.get("logged_in"):
|
||||
|
|
@ -473,20 +469,6 @@ def run_doctor(args):
|
|||
check_warn("OpenAI Codex auth", "(not logged in)")
|
||||
if codex_status.get("error"):
|
||||
check_info(codex_status["error"])
|
||||
|
||||
gemini_status = get_gemini_oauth_auth_status()
|
||||
if gemini_status.get("logged_in"):
|
||||
email = gemini_status.get("email") or ""
|
||||
project = gemini_status.get("project_id") or ""
|
||||
pieces = []
|
||||
if email:
|
||||
pieces.append(email)
|
||||
if project:
|
||||
pieces.append(f"project={project}")
|
||||
suffix = f" ({', '.join(pieces)})" if pieces else ""
|
||||
check_ok("Google Gemini OAuth", f"(logged in{suffix})")
|
||||
else:
|
||||
check_warn("Google Gemini OAuth", "(not logged in)")
|
||||
except Exception as e:
|
||||
check_warn("Auth provider status", f"(could not check: {e})")
|
||||
|
||||
|
|
@ -1048,10 +1030,24 @@ def run_doctor(args):
|
|||
else:
|
||||
check_warn(item["name"], "(system dependency not met)")
|
||||
|
||||
# Count disabled tools with API key requirements
|
||||
api_disabled = [u for u in unavailable if (u.get("missing_vars") or u.get("env_vars"))]
|
||||
# Only summarize missing API keys for toolsets actually enabled in the CLI.
|
||||
# Otherwise default-off / disabled toolsets (for example rl) create noisy
|
||||
# false positives in the final "Found N issue(s)" summary.
|
||||
try:
|
||||
from hermes_cli.config import load_config
|
||||
from hermes_cli.tools_config import _get_platform_tools
|
||||
|
||||
enabled_cli_toolsets = set(_get_platform_tools(load_config(), "cli", include_default_mcp_servers=False))
|
||||
except Exception:
|
||||
enabled_cli_toolsets = set()
|
||||
|
||||
api_disabled = [
|
||||
u for u in unavailable
|
||||
if (u.get("missing_vars") or u.get("env_vars"))
|
||||
and (not enabled_cli_toolsets or u.get("name") in enabled_cli_toolsets)
|
||||
]
|
||||
if api_disabled:
|
||||
issues.append("Run 'hermes setup' to configure missing API keys for full tool access")
|
||||
issues.append("Run 'hermes setup' to configure missing API keys for enabled toolsets")
|
||||
except Exception as e:
|
||||
check_warn("Could not check tool availability", f"({e})")
|
||||
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ def test_run_doctor_kimi_cn_env_is_detected_and_probe_is_null_safe(monkeypatch,
|
|||
home = tmp_path / ".hermes"
|
||||
home.mkdir(parents=True, exist_ok=True)
|
||||
(home / "config.yaml").write_text("memory: {}\n", encoding="utf-8")
|
||||
(home / ".env").write_text("KIMI_CN_API_KEY=sk-test\n", encoding="utf-8")
|
||||
(home / ".env").write_text("KIMI_CN_API_KEY=***", encoding="utf-8")
|
||||
project = tmp_path / "project"
|
||||
project.mkdir(exist_ok=True)
|
||||
|
||||
|
|
@ -345,6 +345,91 @@ def test_run_doctor_kimi_cn_env_is_detected_and_probe_is_null_safe(monkeypatch,
|
|||
assert any(url == "https://api.moonshot.cn/v1/models" for url, _, _ in calls)
|
||||
|
||||
|
||||
def test_run_doctor_ignores_missing_api_keys_for_disabled_toolsets(monkeypatch, tmp_path):
|
||||
home = tmp_path / ".hermes"
|
||||
home.mkdir(parents=True, exist_ok=True)
|
||||
(home / "config.yaml").write_text("memory: {}\n", encoding="utf-8")
|
||||
project = tmp_path / "project"
|
||||
project.mkdir(exist_ok=True)
|
||||
|
||||
monkeypatch.setattr(doctor_mod, "HERMES_HOME", home)
|
||||
monkeypatch.setattr(doctor_mod, "PROJECT_ROOT", project)
|
||||
monkeypatch.setattr(doctor_mod, "_DHH", str(home))
|
||||
|
||||
fake_model_tools = types.SimpleNamespace(
|
||||
check_tool_availability=lambda *a, **kw: (
|
||||
["web"],
|
||||
[{"name": "rl", "missing_vars": ["TINKER_API_KEY", "WANDB_API_KEY"]}],
|
||||
),
|
||||
TOOLSET_REQUIREMENTS={"web": {"name": "web"}},
|
||||
)
|
||||
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: {})
|
||||
import httpx
|
||||
monkeypatch.setattr(httpx, "get", lambda *a, **kw: types.SimpleNamespace(status_code=200))
|
||||
from hermes_cli import config as _config_mod
|
||||
from hermes_cli import tools_config as _tools_mod
|
||||
monkeypatch.setattr(_config_mod, "load_config", lambda: {"platform_toolsets": {"cli": ["web"]}})
|
||||
monkeypatch.setattr(_tools_mod, "_get_platform_tools", lambda *a, **kw: {"web"})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
import io, contextlib
|
||||
buf = io.StringIO()
|
||||
with contextlib.redirect_stdout(buf):
|
||||
doctor_mod.run_doctor(Namespace(fix=False))
|
||||
out = buf.getvalue()
|
||||
|
||||
assert "⚠ rl" in out or "rl" in out
|
||||
assert "Run 'hermes setup' to configure missing API keys for enabled toolsets" not in out
|
||||
|
||||
|
||||
def test_run_doctor_reports_missing_api_keys_for_enabled_toolsets(monkeypatch, tmp_path):
|
||||
home = tmp_path / ".hermes"
|
||||
home.mkdir(parents=True, exist_ok=True)
|
||||
(home / "config.yaml").write_text("memory: {}\n", encoding="utf-8")
|
||||
project = tmp_path / "project"
|
||||
project.mkdir(exist_ok=True)
|
||||
|
||||
monkeypatch.setattr(doctor_mod, "HERMES_HOME", home)
|
||||
monkeypatch.setattr(doctor_mod, "PROJECT_ROOT", project)
|
||||
monkeypatch.setattr(doctor_mod, "_DHH", str(home))
|
||||
|
||||
fake_model_tools = types.SimpleNamespace(
|
||||
check_tool_availability=lambda *a, **kw: (
|
||||
[],
|
||||
[{"name": "web", "missing_vars": ["OPENROUTER_API_KEY"]}],
|
||||
),
|
||||
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: {})
|
||||
import httpx
|
||||
monkeypatch.setattr(httpx, "get", lambda *a, **kw: types.SimpleNamespace(status_code=200))
|
||||
from hermes_cli import config as _config_mod
|
||||
from hermes_cli import tools_config as _tools_mod
|
||||
monkeypatch.setattr(_config_mod, "load_config", lambda: {"platform_toolsets": {"cli": ["web"]}})
|
||||
monkeypatch.setattr(_tools_mod, "_get_platform_tools", lambda *a, **kw: {"web"})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
import io, contextlib
|
||||
buf = io.StringIO()
|
||||
with contextlib.redirect_stdout(buf):
|
||||
doctor_mod.run_doctor(Namespace(fix=False))
|
||||
out = buf.getvalue()
|
||||
|
||||
assert "Run 'hermes setup' to configure missing API keys for enabled toolsets" in out
|
||||
|
||||
|
||||
@pytest.mark.parametrize("base_url", [None, "https://opencode.ai/zen/go/v1"])
|
||||
def test_run_doctor_opencode_go_skips_invalid_models_probe(monkeypatch, tmp_path, base_url):
|
||||
home = tmp_path / ".hermes"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue