Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

## [Unreleased]

### Added

- Add a Settings preference to ignore Hermes Agent update notices while keeping WebUI update checks, banners, and update actions enabled for the WebUI itself.

## [v0.51.124] — 2026-05-24 — Release CV (stage-batch6 — 3-PR Windows-only stack — agent paths / docs / port hardening)

### Added
Expand Down
2 changes: 2 additions & 0 deletions api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4365,6 +4365,7 @@ def _get_session_agent_lock(session_id: str) -> threading.Lock:
"show_previous_messaging_sessions": False, # show older Telegram/Discord/etc. reset segments
"sync_to_insights": False, # mirror WebUI token usage to state.db for /insights
"check_for_updates": True, # check if webui/agent repos are behind upstream
"ignore_agent_updates": False, # keep WebUI update notices but suppress Agent update checks
"whats_new_summary_enabled": False, # show an LLM-written What's New summary before diff links
"theme": "dark", # light | dark | system
"skin": "default", # accent color skin: default | ares | mono | slate | poseidon | sisyphus | charizard | sienna | catppuccin | nous
Expand Down Expand Up @@ -4524,6 +4525,7 @@ def load_settings() -> dict:
"show_previous_messaging_sessions",
"sync_to_insights",
"check_for_updates",
"ignore_agent_updates",
"whats_new_summary_enabled",
"sound_enabled",
"rtl",
Expand Down
6 changes: 4 additions & 2 deletions api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4260,6 +4260,7 @@ def handle_get(handler, parsed) -> bool:
settings = load_settings()
if not settings.get("check_for_updates", True):
return j(handler, {"disabled": True})
include_agent_updates = not bool(settings.get("ignore_agent_updates"))
qs = parse_qs(parsed.query)
force = qs.get("force", ["0"])[0] == "1"
# ?simulate=1 returns fake behind counts for UI testing (localhost only)
Expand All @@ -4281,7 +4282,8 @@ def handle_get(handler, parsed) -> bool:
},
"agent": {
"name": "agent",
"behind": 1,
"behind": 1 if include_agent_updates else 0,
"ignored": not include_agent_updates,
"current_sha": "aaa0001",
"latest_sha": "bbb0002",
"branch": "master",
Expand All @@ -4293,7 +4295,7 @@ def handle_get(handler, parsed) -> bool:
)
from api.updates import check_for_updates

return j(handler, check_for_updates(force=force))
return j(handler, check_for_updates(force=force, include_agent=include_agent_updates))

if parsed.path == "/api/chat/stream/status":
stream_id = parse_qs(parsed.query).get("stream_id", [""])[0]
Expand Down
19 changes: 15 additions & 4 deletions api/updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
except ImportError:
_AGENT_DIR = None

_update_cache = {'webui': None, 'agent': None, 'checked_at': 0}
_update_cache = {'webui': None, 'agent': None, 'checked_at': 0, 'include_agent': True}
_SUMMARY_CACHE_MAX = 16
_summary_cache: OrderedDict = OrderedDict()
_cache_lock = threading.Lock()
Expand Down Expand Up @@ -521,11 +521,21 @@ def _check_repo(path, name):
return _check_repo_branch(path, name, fetch=False)


def check_for_updates(force=False):
def _ignored_agent_update_info() -> dict:
"""Return a stable update-check payload for intentionally ignored Agent updates."""
return {'name': 'agent', 'behind': 0, 'ignored': True}


def check_for_updates(force=False, *, include_agent=True):
"""Return cached update status for webui and agent repos."""
global _check_in_progress
include_agent = bool(include_agent)
with _cache_lock:
if not force and time.time() - _update_cache['checked_at'] < CACHE_TTL:
if (
not force
and _update_cache.get('include_agent') == include_agent
and time.time() - _update_cache['checked_at'] < CACHE_TTL
):
return dict(_update_cache)
if _check_in_progress:
return dict(_update_cache) # another thread is already checking
Expand All @@ -534,12 +544,13 @@ def check_for_updates(force=False):
try:
# Run checks outside the lock (network I/O)
webui_info = _check_repo(REPO_ROOT, 'webui')
agent_info = _check_repo(_AGENT_DIR, 'agent')
agent_info = _check_repo(_AGENT_DIR, 'agent') if include_agent else _ignored_agent_update_info()

with _cache_lock:
_update_cache['webui'] = webui_info
_update_cache['agent'] = agent_info
_update_cache['checked_at'] = time.time()
_update_cache['include_agent'] = include_agent
return dict(_update_cache)
finally:
_check_in_progress = False
Expand Down
Loading
Loading