From 3a5359210746c555d342cf4295c12ae9bbbedde5 Mon Sep 17 00:00:00 2001 From: junjunjunbong <153147718+junjunjunbong@users.noreply.github.com> Date: Fri, 15 May 2026 15:17:40 +0900 Subject: [PATCH 1/2] Add previous messaging session controls --- api/config.py | 2 + api/routes.py | 16 ++++++- static/boot.js | 1 + static/i18n.js | 10 +++++ static/index.html | 7 ++++ static/panels.js | 7 ++++ static/sessions.js | 17 ++++++++ tests/test_1003_preferences_autosave.py | 9 ++-- tests/test_gateway_sync.py | 55 +++++++++++++++++++++++++ 9 files changed, 118 insertions(+), 6 deletions(-) diff --git a/api/config.py b/api/config.py index faa3ac13076..73aa89c0855 100644 --- a/api/config.py +++ b/api/config.py @@ -4128,6 +4128,7 @@ def _get_session_agent_lock(session_id: str) -> threading.Lock: "show_tps": False, # show tokens-per-second chip in assistant message headers "fade_text_effect": False, # animate newly streamed words with a lightweight fade-in effect "show_cli_sessions": False, # merge CLI sessions from state.db into the sidebar + "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 "whats_new_summary_enabled": False, # show an LLM-written What's New summary before diff links @@ -4263,6 +4264,7 @@ def load_settings() -> dict: "show_tps", "fade_text_effect", "show_cli_sessions", + "show_previous_messaging_sessions", "sync_to_insights", "check_for_updates", "whats_new_summary_enabled", diff --git a/api/routes.py b/api/routes.py index 3cf867ef4ea..10f2207053a 100644 --- a/api/routes.py +++ b/api/routes.py @@ -2158,8 +2158,15 @@ def _messaging_source_key(session: dict) -> str | None: return _messaging_session_identity(session, raw) -def _keep_latest_messaging_session_per_source(sessions: list[dict]) -> list[dict]: +def _keep_latest_messaging_session_per_source( + sessions: list[dict], + *, + show_previous_messaging_sessions: bool = False, +) -> list[dict]: """Keep only the newest sidebar row per messaging session identity.""" + if show_previous_messaging_sessions: + return sorted(sessions, key=_session_sort_timestamp, reverse=True) + gateway_metadata = _load_gateway_session_identity_map() active_gateway_session_ids = {str(sid) for sid in gateway_metadata.keys() if sid} active_gateway_sources = { @@ -3943,7 +3950,12 @@ def handle_get(handler, parsed) -> bool: if _profiles_match(s.get("profile"), active_profile)] other_profile_count = len(merged) - len(scoped) diag.stage("messaging_dedupe") - scoped = _keep_latest_messaging_session_per_source(scoped) + scoped = _keep_latest_messaging_session_per_source( + scoped, + show_previous_messaging_sessions=bool( + settings.get("show_previous_messaging_sessions") + ), + ) if show_cli_sessions: diag.stage("cli_cap") scoped = _cap_recent_cli_sessions(scoped, cli_cap=CLI_VISIBLE_SESSION_CAP) diff --git a/static/boot.js b/static/boot.js index 9464f1670d3..1db3bc6a83a 100644 --- a/static/boot.js +++ b/static/boot.js @@ -1412,6 +1412,7 @@ function applyBotName(){ window._showTps=!!s.show_tps; window._fadeTextEffect=!!s.fade_text_effect; window._showCliSessions=!!s.show_cli_sessions; + window._showPreviousMessagingSessions=!!s.show_previous_messaging_sessions; window._soundEnabled=!!s.sound_enabled; window._notificationsEnabled=!!s.notifications_enabled; // Persist default workspace so the blank new-chat page can show it diff --git a/static/i18n.js b/static/i18n.js index e1ad98e3170..315753a7c01 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -430,12 +430,15 @@ const LOCALES = { session_move_project_desc_has: 'Change the project for this conversation', session_move_project_desc_none: 'Assign a project to this conversation', session_archive: 'Archive conversation', + session_hide_external: 'Hide from list', session_restore: 'Restore conversation', session_archive_desc: 'Hide this conversation until archived is shown', session_archive_worktree_desc: 'Hide this conversation; keep its worktree on disk', + session_hide_external_desc: 'Hide this imported session from WebUI without deleting the source history.', session_restore_desc: 'Bring this conversation back into the main list', session_archived: 'Session archived', session_archived_worktree: 'Session archived. Worktree remains on disk.', + session_hidden: 'Session hidden from list', session_restored: 'Session restored', session_archive_failed: 'Archive failed: ', session_duplicate: 'Duplicate conversation', @@ -546,6 +549,7 @@ const LOCALES = { settings_label_sidebar_density: 'Sidebar density', cmd_reasoning: 'Toggle thinking visibility (show/hide), set effort level, or check current status', settings_label_external_sessions: 'Show non-WebUI sessions', + settings_label_previous_messaging_sessions: 'Show previous messaging sessions', settings_label_sync_insights: 'Sync to insights', settings_label_check_updates: 'Check for updates', settings_label_whats_new_summary: "Summarize What's New with AI", @@ -784,6 +788,7 @@ const LOCALES = { settings_auto_title_refresh_20: 'Every 20 exchanges', settings_desc_auto_title_refresh: 'Automatically re-generates the session title based on the latest exchange, keeping it relevant as the conversation evolves. Requires an LLM title generation model to be configured.', settings_desc_external_sessions: 'Show conversations from CLI, Telegram, Discord, Slack, and other channels in the session list. Click to import and continue.', + settings_desc_previous_messaging_sessions: 'Show older Discord, Telegram, Slack, and Weixin sessions that were replaced by reset or compression.', settings_desc_sync_insights: 'Mirrors WebUI token usage to state.db so hermes /insights includes browser session data. Off by default.', settings_desc_check_updates: 'Show a banner when newer versions of the WebUI or Agent are available. Runs a background git fetch periodically.', settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.", @@ -10858,12 +10863,15 @@ const LOCALES = { session_move_project_desc_has: 'Change the project for this conversation', session_move_project_desc_none: 'Assign a project to this conversation', session_archive: 'Archive conversation', + session_hide_external: '목록에서 숨기기', session_restore: 'Restore conversation', session_archive_desc: 'Hide this conversation until archived is shown', session_archive_worktree_desc: '이 대화를 숨기고 worktree는 디스크에 유지합니다', + session_hide_external_desc: '원본 기록은 삭제하지 않고 WebUI 목록에서만 숨깁니다.', session_restore_desc: 'Bring this conversation back into the main list', session_archived: 'Session archived', session_archived_worktree: '세션이 보관되었습니다. Worktree는 디스크에 남아 있습니다.', + session_hidden: '목록에서 숨겼습니다', session_restored: 'Session restored', session_archive_failed: 'Archive failed: ', session_duplicate: 'Duplicate conversation', @@ -10974,6 +10982,7 @@ const LOCALES = { settings_label_sidebar_density: '사이드바 밀도', cmd_reasoning: 'Toggle thinking visibility (show/hide), set effort level, or check current status', settings_label_external_sessions: '외부 세션 표시', + settings_label_previous_messaging_sessions: '이전 메시징 세션 표시', settings_label_sync_insights: 'Insights에 동기화', settings_label_check_updates: '업데이트 확인', settings_label_whats_new_summary: "Summarize What's New with AI", @@ -11161,6 +11170,7 @@ const LOCALES = { settings_auto_title_refresh_20: 'Every 20 exchanges', settings_desc_auto_title_refresh: '최신 대화를 바탕으로 세션 제목을 자동으로 다시 생성해 대화가 진행되어도 제목을 관련 있게 유지합니다. LLM 제목 생성 모델 설정이 필요합니다.', settings_desc_external_sessions: 'CLI, Telegram, Discord, Slack 및 기타 채널의 대화를 세션 목록에 표시합니다. 클릭하여 가져오고 계속하세요.', + settings_desc_previous_messaging_sessions: 'reset 또는 compression으로 교체된 이전 Discord, Telegram, Slack, Weixin 세션을 표시합니다.', settings_desc_sync_insights: 'WebUI 토큰 사용량을 state.db에 반영하여 hermes /insights에 브라우저 세션 데이터가 포함되도록 합니다. 기본값은 꺼짐입니다.', settings_desc_check_updates: 'WebUI 또는 Agent의 새 버전이 있으면 배너를 표시합니다. 백그라운드에서 주기적으로 git fetch를 실행합니다.', settings_desc_whats_new_summary: "Changes the What's New action from opening the raw diff first to generating a short, human-readable summary. The regular diff comparison stays available after the summary.", diff --git a/static/index.html b/static/index.html index d507395c1d8..9682788c946 100644 --- a/static/index.html +++ b/static/index.html @@ -1129,6 +1129,13 @@

What can I help with?

Show conversations from CLI, Telegram, Discord, Slack, and other channels in the session list. Click to import and continue.
+
+ +
Show older Discord, Telegram, Slack, and Weixin sessions that were replaced by reset or compression.
+