fix(setup): warn loudly when the wizard finishes without a working provider

Cancelling the API-key prompt mid-wizard (Enter → 'Cancelled.') let the
wizard continue through Terminal/Gateway/Tools and finish 'successfully'
with no model configured — the user exits believing they're set up, then
hits a broken chat.

_print_setup_summary() (called by every setup path: full, quick,
blank-slate, portal) now probes resolve_provider() and, when nothing is
configured, prints an unmissable warning with the two one-line fixes
(hermes model / hermes setup --portal).

Consumer-onboarding audit finding #7 (sev 4), Aug 2026.
This commit is contained in:
Teknium
2026-08-01 14:53:38 -07:00
parent eec6d3efde
commit 38453baeee
2 changed files with 68 additions and 0 deletions
+19
View File
@@ -395,6 +395,25 @@ def _prompt_api_key(var: dict):
def _print_setup_summary(config: dict, hermes_home):
"""Print the setup completion summary."""
# Provider readiness — the one thing setup absolutely must produce.
# Previously a user could cancel the API-key prompt mid-wizard (Enter →
# "Cancelled."), watch the wizard continue through Terminal/Gateway/Tools,
# and exit "successfully" with NO working model — believing they were set
# up. Say so loudly instead (consumer-onboarding audit finding #7).
try:
from hermes_cli.auth import resolve_provider
resolve_provider()
_provider_ready = True
except Exception:
_provider_ready = False
if not _provider_ready:
print()
print_warning("No inference provider is configured — Hermes cannot chat yet.")
print_info(" Finish this one step with either of:")
print_info(" hermes model (pick any provider/model)")
print_info(" hermes setup --portal (Nous Portal OAuth, no API key)")
# Tool availability summary
print()
print_header("Tool Availability Summary")
@@ -0,0 +1,49 @@
"""Setup summary must warn loudly when no provider got configured.
Regression test for the "wizard silently succeeds with no model" dead end:
cancelling the API-key prompt mid-wizard printed "Cancelled." but the wizard
continued through the remaining sections and finished "successfully" with no
working model configured (consumer-onboarding audit finding #7, Aug 2026).
"""
from unittest.mock import patch
from hermes_cli.auth import AuthError
def _summary_output(capsys, provider_ready: bool):
from hermes_cli import setup as setup_mod
if provider_ready:
resolver = lambda *a, **k: "openrouter" # noqa: E731
else:
def resolver(*a, **k):
raise AuthError(
"No inference provider configured.",
code="no_provider_configured",
)
# Keep the summary fast/hermetic: stub the heavier feature probes.
with patch("hermes_cli.auth.resolve_provider", resolver), \
patch.object(setup_mod, "get_nous_subscription_features") as feats:
feats.side_effect = Exception("stubbed")
try:
setup_mod._print_setup_summary({}, "/tmp/nowhere")
except Exception:
# Downstream summary sections may fail from the stubbed
# features — the provider warning prints first and is what
# this test asserts on.
pass
return capsys.readouterr().out
def test_summary_warns_when_no_provider(capsys):
out = _summary_output(capsys, provider_ready=False)
assert "No inference provider is configured" in out
assert "hermes model" in out
assert "hermes setup --portal" in out
def test_summary_quiet_when_provider_ready(capsys):
out = _summary_output(capsys, provider_ready=True)
assert "No inference provider is configured" not in out