fix(setup): default browser/TTS picker to free local backend, not paid Nous (#37800)

The Browser Automation and Text-to-Speech provider pickers listed the paid
"Nous Subscription" gateway row first, so on a fresh install the menu cursor
defaulted to index 0 (Nous). Pressing Enter selected it and ran the inline
Nous Portal device-code login — walking users into a paid offering they
never chose.

Reorder both provider lists so the free, no-key local backend is index 0
(Local Browser / Microsoft Edge TTS). Users who already configured Nous are
unaffected: _detect_active_provider_index still resolves their active row
first, so the cursor lands on Nous (now index 1) for them.

Reported by Javier via Kujila.
This commit is contained in:
Teknium
2026-06-02 19:49:10 -07:00
committed by GitHub
parent 918aef267b
commit b28dd3417d
2 changed files with 56 additions and 19 deletions
+36 -2
View File
@@ -609,7 +609,12 @@ def test_visible_providers_include_nous_subscription_when_logged_in(monkeypatch)
providers = _visible_providers(TOOL_CATEGORIES["browser"], config)
assert providers[0]["name"].startswith("Nous Subscription")
# The managed Nous row is listed (not necessarily first — "Local Browser"
# sorts first so a fresh-install Enter lands on the free local backend).
assert any(p["name"].startswith("Nous Subscription") for p in providers)
# "Local Browser" must be the index-0 default so pressing Enter never
# walks a user into a paid Nous Portal login.
assert providers[0]["name"] == "Local Browser"
def test_visible_providers_show_nous_subscription_when_logged_out(monkeypatch):
@@ -685,7 +690,9 @@ def test_visible_providers_force_fresh_shows_nous_subscription_after_upgrade(mon
force_fresh=True,
)
assert providers[0]["name"].startswith("Nous Subscription")
# The managed Nous row reappears after the entitlement upgrade. It is no
# longer asserted to be first — "Local Browser" sorts first by design.
assert any(p["name"].startswith("Nous Subscription") for p in providers)
assert ("features", True) in calls
@@ -702,6 +709,33 @@ def test_local_browser_provider_is_saved_explicitly(monkeypatch):
assert config["browser"]["cloud_provider"] == "local"
def test_fresh_install_browser_default_is_free_local_not_paid_nous():
"""On a fresh install the browser picker must default to the free local
backend, never the paid Nous Subscription gateway.
Regression: the Nous row used to sort first, so the menu cursor defaulted
to index 0 (Nous) and pressing Enter walked users straight into a Nous
Portal login for a paid offering (Javier's bug, June 2026).
"""
from hermes_cli.tools_config import _detect_active_provider_index
providers = TOOL_CATEGORIES["browser"]["providers"]
assert providers[0]["name"] == "Local Browser"
assert providers[0]["browser_provider"] == "local"
# Nothing active/configured → cursor defaults to index 0 (the free local row).
assert _detect_active_provider_index(providers, {}) == 0
def test_fresh_install_tts_default_is_free_edge_not_paid_nous():
"""TTS picker defaults to the free Edge backend on a fresh install."""
from hermes_cli.tools_config import _detect_active_provider_index
providers = TOOL_CATEGORIES["tts"]["providers"]
assert providers[0]["name"] == "Microsoft Edge TTS"
assert providers[0]["tts_provider"] == "edge"
assert _detect_active_provider_index(providers, {}) == 0
def test_reconfigure_lists_enabled_web_without_existing_provider_config(monkeypatch):
config = {"platform_toolsets": {"cli": ["web"]}}
seen = {}