diff --git a/api/state_sync.py b/api/state_sync.py index 5a240031..caf03da0 100644 --- a/api/state_sync.py +++ b/api/state_sync.py @@ -198,12 +198,18 @@ def sync_session_usage(session_id: str, input_tokens: int=0, output_tokens: int= 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). + """Sync an auto-generated title to state.db (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. + + Uses ``set_auto_title_if_empty`` so it will only populate a NULL title and + never overwrite a manual rename made via CLI/Gateway/TUI. This means + title refreshes (where state.db already holds the initial auto-title) are + effectively no-ops at the state.db layer -- acceptable because the primary + goal is ensuring ``hermes sessions list`` is not blank. """ if not title: return @@ -213,7 +219,7 @@ def sync_session_title(session_id: str, title: str, profile: Optional[str] = Non 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) + db.set_auto_title_if_empty(session_id, title) except Exception: logger.debug("Failed to sync session title to state.db for %s", session_id) finally: diff --git a/api/streaming.py b/api/streaming.py index 1943f857..ff72cc4b 100644 --- a/api/streaming.py +++ b/api/streaming.py @@ -4469,7 +4469,7 @@ def _run_background_title_update(session_id: str, user_text: str, assistant_text # Sync the generated title to state.db so `hermes sessions list` shows it. try: from api.state_sync import sync_session_title - sync_session_title(session_id, effective_title, profile=getattr(s, 'profile', None)) + sync_session_title(session_id, effective_title, profile=getattr(s, 'profile', None) or 'default') except Exception: logger.debug("Failed to sync title to state.db after generation for %s", session_id) else: @@ -4547,7 +4547,7 @@ def _run_background_title_refresh(session_id: str, user_text: str, assistant_tex # Sync the refreshed title to state.db so `hermes sessions list` stays current. try: from api.state_sync import sync_session_title - sync_session_title(session_id, effective_title, profile=getattr(s, 'profile', None)) + sync_session_title(session_id, effective_title, profile=getattr(s, 'profile', None) or 'default') except Exception: logger.debug("Failed to sync refreshed title to state.db for %s", session_id) logger.info("Adaptive title refresh: session=%s new_title=%r", session_id, effective_title)