fix(tui): avoid network lookup during startup

This commit is contained in:
Brooklyn Nicholson
2026-04-25 13:47:18 -05:00
parent 4db58d45d4
commit 2dfcc8087a
2 changed files with 63 additions and 4 deletions

View File

@@ -112,6 +112,9 @@ def test_startup_runtime_does_not_treat_inference_provider_as_explicit(monkeypat
monkeypatch.setenv("HERMES_MODEL", "nous/hermes-test")
monkeypatch.delenv("HERMES_TUI_PROVIDER", raising=False)
monkeypatch.setenv("HERMES_INFERENCE_PROVIDER", "nous")
monkeypatch.setattr(
server, "_detect_static_provider_for_model", lambda model, provider: None
)
assert server._resolve_startup_runtime() == ("nous/hermes-test", None)
@@ -127,7 +130,7 @@ def test_startup_runtime_detects_provider_for_model_env(monkeypatch):
assert current_provider == "auto"
return "anthropic", "anthropic/claude-sonnet-4.6"
monkeypatch.setattr("hermes_cli.models.detect_provider_for_model", fake_detect)
monkeypatch.setattr(server, "_detect_static_provider_for_model", fake_detect)
assert server._resolve_startup_runtime() == (
"anthropic/claude-sonnet-4.6",
@@ -135,6 +138,22 @@ def test_startup_runtime_detects_provider_for_model_env(monkeypatch):
)
def test_startup_runtime_does_not_call_network_detector(monkeypatch):
monkeypatch.setenv("HERMES_MODEL", "sonnet")
monkeypatch.delenv("HERMES_TUI_PROVIDER", raising=False)
monkeypatch.delenv("HERMES_INFERENCE_PROVIDER", raising=False)
monkeypatch.setattr(server, "_load_cfg", lambda: {"model": {"provider": "auto"}})
monkeypatch.setattr(
"hermes_cli.models.detect_provider_for_model",
lambda *_args, **_kwargs: (_ for _ in ()).throw(AssertionError("network detector called")),
)
model, provider = server._resolve_startup_runtime()
assert model
assert provider in {None, "anthropic"}
def _session(agent=None, **extra):
return {
"agent": agent if agent is not None else types.SimpleNamespace(),

View File

@@ -574,6 +574,48 @@ def _resolve_model() -> str:
return "anthropic/claude-sonnet-4"
def _detect_static_provider_for_model(model_name: str, current_provider: str) -> tuple[str, str] | None:
"""Startup-safe provider detection: static catalogs only, no network fetches."""
name = (model_name or "").strip()
if not name:
return None
try:
from hermes_cli.models import (
_PROVIDER_ALIASES,
_PROVIDER_LABELS,
_PROVIDER_MODELS,
normalize_provider,
)
except Exception:
return None
name_lower = name.lower()
normalized_current = normalize_provider(current_provider)
resolved_provider = _PROVIDER_ALIASES.get(name_lower, name_lower)
if resolved_provider not in {"custom", "openrouter"}:
default_models = _PROVIDER_MODELS.get(resolved_provider, [])
if (
resolved_provider in _PROVIDER_LABELS
and default_models
and resolved_provider != normalized_current
):
return resolved_provider, default_models[0]
aggregators = {"nous", "openrouter", "ai-gateway", "copilot", "kilocode"}
current_models = _PROVIDER_MODELS.get(normalized_current, [])
if any(name_lower == m.lower() for m in current_models):
return None
for provider, models in _PROVIDER_MODELS.items():
if provider == normalized_current or provider in aggregators:
continue
if any(name_lower == m.lower() for m in models):
return provider, name
return None
def _resolve_startup_runtime() -> tuple[str, str | None]:
model = _resolve_model()
explicit_provider = os.environ.get("HERMES_TUI_PROVIDER", "").strip()
@@ -588,15 +630,13 @@ def _resolve_startup_runtime() -> tuple[str, str | None]:
return model, None
try:
from hermes_cli.models import detect_provider_for_model
cfg = _load_cfg().get("model") or {}
current_provider = (
str(cfg.get("provider") or "").strip().lower()
if isinstance(cfg, dict)
else ""
) or os.environ.get("HERMES_INFERENCE_PROVIDER", "").strip().lower() or "auto"
detected = detect_provider_for_model(explicit_model, current_provider)
detected = _detect_static_provider_for_model(explicit_model, current_provider)
if detected:
provider, detected_model = detected
return detected_model, provider