feat: notification sound and browser notifications on task completion

Add two new settings (both default off):
- sound_enabled: plays a short tone via Web Audio API when assistant
  finishes a response or requests approval
- notifications_enabled: shows a browser notification when a response
  completes while the tab is in the background

Uses Web Audio API (oscillator) instead of bundled MP3 file — zero
additional assets. Follows the standard 4-file settings pattern.

Also skip test_valid_skill_accepted when hermes-agent not installed
(skills endpoint returns 500 without the agent module).

Inspired by #176 (DavidSchuchert)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nathan Esquenazi
2026-04-08 09:02:02 -07:00
parent 907bb224d9
commit 5e899ee8fe
6 changed files with 64 additions and 2 deletions

View File

@@ -778,6 +778,8 @@ _SETTINGS_DEFAULTS = {
'check_for_updates': True, # check if webui/agent repos are behind upstream
'theme': 'dark', # active UI theme name (no enum gate -- allows custom themes)
'bot_name': os.getenv('HERMES_WEBUI_BOT_NAME', 'Hermes'), # display name for the assistant
'sound_enabled': False, # play notification sound when assistant finishes
'notifications_enabled': False, # browser notification when tab is in background
'password_hash': None, # PBKDF2-HMAC-SHA256 hash; None = auth disabled
}
@@ -797,7 +799,7 @@ _SETTINGS_ALLOWED_KEYS = set(_SETTINGS_DEFAULTS.keys()) - {'password_hash'}
_SETTINGS_ENUM_VALUES = {
'send_key': {'enter', 'ctrl+enter'},
}
_SETTINGS_BOOL_KEYS = {'show_token_usage', 'show_cli_sessions', 'sync_to_insights', 'check_for_updates'}
_SETTINGS_BOOL_KEYS = {'show_token_usage', 'show_cli_sessions', 'sync_to_insights', 'check_for_updates', 'sound_enabled', 'notifications_enabled'}
def save_settings(settings: dict) -> dict:
"""Save settings to disk. Returns the merged settings. Ignores unknown keys."""