diff --git a/api/config.py b/api/config.py
index 189cafb..f9db9ca 100644
--- a/api/config.py
+++ b/api/config.py
@@ -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."""
diff --git a/static/boot.js b/static/boot.js
index e6d6a5e..6ee4cf2 100644
--- a/static/boot.js
+++ b/static/boot.js
@@ -322,7 +322,7 @@ function applyBotName(){
(async()=>{
// Load send key preference
let _bootSettings={};
- try{const s=await api('/api/settings');_bootSettings=s;window._sendKey=s.send_key||'enter';window._showTokenUsage=!!s.show_token_usage;window._showCliSessions=!!s.show_cli_sessions;window._botName=s.bot_name||'Hermes';const _theme=s.theme||'dark';document.documentElement.dataset.theme=_theme;localStorage.setItem('hermes-theme',_theme);applyBotName();}catch(e){window._sendKey='enter';window._showTokenUsage=false;window._showCliSessions=false;window._botName='Hermes';_bootSettings={check_for_updates:false};}
+ try{const s=await api('/api/settings');_bootSettings=s;window._sendKey=s.send_key||'enter';window._showTokenUsage=!!s.show_token_usage;window._showCliSessions=!!s.show_cli_sessions;window._soundEnabled=!!s.sound_enabled;window._notificationsEnabled=!!s.notifications_enabled;window._botName=s.bot_name||'Hermes';const _theme=s.theme||'dark';document.documentElement.dataset.theme=_theme;localStorage.setItem('hermes-theme',_theme);applyBotName();}catch(e){window._sendKey='enter';window._showTokenUsage=false;window._showCliSessions=false;window._soundEnabled=false;window._notificationsEnabled=false;window._botName='Hermes';_bootSettings={check_for_updates:false};}
// Non-blocking update check (fire-and-forget, once per tab session)
// ?test_updates=1 in URL forces banner display for testing (bypasses sessionStorage guards)
const _testUpdates=new URLSearchParams(location.search).get('test_updates')==='1';
diff --git a/static/index.html b/static/index.html
index 67ad9f1..9b1079d 100644
--- a/static/index.html
+++ b/static/index.html
@@ -345,6 +345,20 @@
+
+
+
Play a sound when the assistant finishes a response.
+
+
+
+
Show a system notification when a response completes while the tab is in the background.
+