fix: sync generated title to state.db so hermes sessions list shows WebUI titles

Background title generation (`_run_background_title_update` and
`_run_background_title_refresh`) writes the title to the WebUI sidecar
JSON but never syncs it back to hermes-agent's `state.db`. This causes
`hermes sessions list` to show blank titles for all WebUI-originated
sessions.

The existing `sync_session_usage` path is gated by the `sync_to_insights`
setting (default: off) and executes before the background title thread
completes, so it cannot cover this case.

Fix: add `sync_session_title()` to `state_sync.py` — an unconditional
(not gated by `sync_to_insights`) title-only sync — and call it from both
title generation paths immediately after persisting the title to the
sidecar.
This commit is contained in:
liuguangyong93 committed 2026-08-12 14:48:10 +08:00
1 parent e9f1e2a459
commit ae8311915b
2 files changed
+38

No files matched your search

+26
View File
@@ -195,3 +195,29 @@ def sync_session_usage(session_id: str, input_tokens: int=0, output_tokens: int=
db.close()
except Exception:
logger.debug("Failed to close state.db")
def sync_session_title(session_id: str, title: str, profile: Optional[str] = None) -> None:
"""Sync a generated title to state.db unconditionally (not gated by sync_to_insights).
Background title generation writes the title to the WebUI sidecar JSON but
not to hermes-agent's state.db, so ``hermes sessions list`` shows blank
titles for WebUI sessions. This function bridges that gap and is called
from the background title update/refresh paths after a title is persisted.
"""
if not title:
return
db = _get_state_db(profile=profile)
if not db:
return
try:
# Ensure the session row exists (idempotent) so the UPDATE has a target.
db.ensure_session(session_id=session_id, source='webui')
db.set_session_title(session_id, title)
except Exception:
logger.debug("Failed to sync session title to state.db for %s", session_id)
finally:
try:
db.close()
except Exception:
logger.debug("Failed to close state.db")