Files
hermes-webui/api
nesquena-hermes 0e9bd651a4 fix: TTS toggle CSS specificity collision (#1409) + Ollama env var bleed (#1410)
Two unrelated UX/Settings bugs, both small surgical fixes with regression
tests.

Issue #1409 — TTS toggle has no effect
=======================================
Reported via Discord: ticking Settings → Voice → "Text-to-Speech for
responses" did nothing. The speaker icon never appeared on assistant
messages despite the checkbox saving to localStorage correctly.

Root cause (CSS specificity collision):
  static/panels.js _applyTtsEnabled() set
    btn.style.display = enabled ? '' : 'none'
  on every .msg-tts-btn. The '' branch removes the inline override, after
  which the .msg-tts-btn { display:none; } rule from style.css re-hides the
  button. Both branches left the icon hidden, so the toggle has been
  silently broken since #499 first shipped the TTS feature.

Fix (body-class toggle, Option B from the issue):
  - panels.js: _applyTtsEnabled now toggles body.classList('tts-enabled')
  - style.css: new compound selector
      body.tts-enabled .msg-tts-btn { display:inline-flex; align-items:center; }
  - default-hidden rule (.msg-tts-btn{display:none;}) preserved so the icon
    stays hidden by default (CSS-only state)
  - boot.js paths that already call _applyTtsEnabled(localStorage…) work
    unchanged — the new function applies state at the body level instead of
    inline-styling individual buttons, so the rule survives renderMd()
    re-renders without re-querying every button

Verified end-to-end against live server: getComputedStyle on a probe
.msg-tts-btn returns display:flex when body has tts-enabled, display:none
when it doesn't. Two regression tests in TestIssue1409TtsToggleBodyClass
explicitly check for the body-class shape and forbid the broken inline-style
pattern.

Issue #1410 — Ollama (local) shows "API key configured" when only
              Ollama Cloud key is set
=================================================================
Reported via Discord: configuring Ollama Cloud lit up the local Ollama card
too. Both providers were mapped to OLLAMA_API_KEY in api/providers.py
_PROVIDER_ENV_VAR.

Root cause:
  api/providers.py:47-48
    "ollama":       "OLLAMA_API_KEY",
    "ollama-cloud": "OLLAMA_API_KEY",
  _provider_has_key("ollama") found the value the user set for Ollama Cloud
  and returned True. But the runtime code path in
  hermes_cli/runtime_provider.py only consumes OLLAMA_API_KEY when the base
  URL hostname is ollama.com (Ollama Cloud) — local Ollama is keyless by
  default and reaches a custom base URL with no auth. The WebUI was
  reporting "configured" for a key local Ollama doesn't even read.

Fix (Option A from the issue body, preferred):
  - Drop bare "ollama" from _PROVIDER_ENV_VAR with an inline comment
    explaining why
  - _provider_has_key("ollama") falls through to the config.yaml branch,
    which already supports providers.ollama.api_key for local users who
    genuinely need to set a token
  - ollama-cloud retains its OLLAMA_API_KEY mapping unchanged

Verified end-to-end against live server with OLLAMA_API_KEY=sk-cloud-key-test
in env: GET /api/providers reports has_key=True only for ollama-cloud, and
has_key=False for bare ollama. Two regression tests in
TestIssue1410OllamaEnvVarBleed cover the bleed-prevention case AND the
"local user with config.yaml api_key still reports configured" case to
guard against over-correction.

Tests
-----
3572 passed, 2 skipped, 3 xpassed (was 3567 — added 5 new regression tests).

Closes #1409
Closes #1410

Reported by @AvidFuturist (Discord, May 1 2026)
2026-05-01 17:14:51 +00:00
..
2026-04-29 19:54:07 -07:00