From 3f88553765563aaca6646f0543e050a3382fb55e Mon Sep 17 00:00:00 2001 From: Zhicheng Han <43314240+hanzckernel@users.noreply.github.com> Date: Wed, 22 Apr 2026 02:09:58 +0200 Subject: [PATCH] feat(web-ui): add pinned sessions and live monitor in Chat (#118) * feat: add single-page live session monitor and chat pinning * fix: restore full test green after main merge * fix: use Array.from instead of Set spread for ts-node compatibility [...new Set()] requires downlevelIteration which isn't enabled in ts-node dev mode, causing sonic-boom crash on startup. Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: ekko Co-authored-by: Claude Opus 4.6 --- .../client/src/api/hermes/conversations.ts | 58 +++ .../src/components/hermes/chat/ChatPanel.vue | 292 ++++++------ .../hermes/chat/ConversationMonitorPane.vue | 299 ++++++++++++ .../hermes/chat/SessionListItem.vue | 63 +++ .../hermes/settings/SessionSettings.vue | 10 +- packages/client/src/i18n/locales/de.ts | 15 + packages/client/src/i18n/locales/en.ts | 15 + packages/client/src/i18n/locales/es.ts | 17 +- packages/client/src/i18n/locales/fr.ts | 17 +- packages/client/src/i18n/locales/ja.ts | 15 + packages/client/src/i18n/locales/ko.ts | 15 + packages/client/src/i18n/locales/pt.ts | 17 +- packages/client/src/i18n/locales/zh.ts | 15 + packages/client/src/shared/session-display.ts | 38 ++ packages/client/src/stores/hermes/chat.ts | 4 + packages/client/src/stores/hermes/profiles.ts | 2 + .../stores/hermes/session-browser-prefs.ts | 116 +++++ .../server/src/controllers/hermes/sessions.ts | 32 ++ .../server/src/routes/hermes/proxy-handler.ts | 7 +- packages/server/src/routes/hermes/sessions.ts | 2 + .../src/services/hermes/conversations.ts | 435 ++++++++++++++++++ .../server/src/services/hermes/hermes-cli.ts | 124 ++--- tests/client/chat-panel-features.test.ts | 236 ++++++++++ tests/client/chat-panel.test.ts | 26 +- tests/client/chat-store.test.ts | 27 +- .../client/conversation-monitor-pane.test.ts | 175 +++++++ tests/client/conversations-api.test.ts | 39 ++ tests/client/profiles-store.test.ts | 9 + tests/client/session-browser-prefs.test.ts | 67 +++ tests/client/session-settings.test.ts | 74 +++ tests/server/auth.test.ts | 176 ++++--- tests/server/conversations-service.test.ts | 263 +++++++++++ tests/server/proxy-handler.test.ts | 16 +- tests/server/sessions-routes.test.ts | 59 +++ 34 files changed, 2497 insertions(+), 278 deletions(-) create mode 100644 packages/client/src/api/hermes/conversations.ts create mode 100644 packages/client/src/components/hermes/chat/ConversationMonitorPane.vue create mode 100644 packages/client/src/components/hermes/chat/SessionListItem.vue create mode 100644 packages/client/src/shared/session-display.ts create mode 100644 packages/client/src/stores/hermes/session-browser-prefs.ts create mode 100644 packages/server/src/services/hermes/conversations.ts create mode 100644 tests/client/chat-panel-features.test.ts create mode 100644 tests/client/conversation-monitor-pane.test.ts create mode 100644 tests/client/conversations-api.test.ts create mode 100644 tests/client/session-browser-prefs.test.ts create mode 100644 tests/client/session-settings.test.ts create mode 100644 tests/server/conversations-service.test.ts diff --git a/packages/client/src/api/hermes/conversations.ts b/packages/client/src/api/hermes/conversations.ts new file mode 100644 index 0000000..d4d2707 --- /dev/null +++ b/packages/client/src/api/hermes/conversations.ts @@ -0,0 +1,58 @@ +import { request } from '../client' + +export interface ConversationSummary { + id: string + source: string + model: string + title: string | null + started_at: number + ended_at: number | null + last_active: number + message_count: number + tool_call_count: number + input_tokens: number + output_tokens: number + cache_read_tokens: number + cache_write_tokens: number + reasoning_tokens: number + billing_provider: string | null + estimated_cost_usd: number + actual_cost_usd: number | null + cost_status: string + preview: string + is_active: boolean + thread_session_count: number +} + +export interface ConversationMessage { + id: number | string + session_id: string + role: 'user' | 'assistant' + content: string + timestamp: number +} + +export interface ConversationDetail { + session_id: string + messages: ConversationMessage[] + visible_count: number + thread_session_count: number +} + +export async function fetchConversationSummaries(params: { humanOnly?: boolean; source?: string; limit?: number } = {}): Promise { + const query = new URLSearchParams() + if (params.humanOnly === false) query.set('humanOnly', 'false') + if (params.source) query.set('source', params.source) + if (params.limit != null) query.set('limit', String(params.limit)) + const suffix = query.toString() ? `?${query.toString()}` : '' + const res = await request<{ sessions: ConversationSummary[] }>(`/api/hermes/sessions/conversations${suffix}`) + return res.sessions +} + +export async function fetchConversationDetail(sessionId: string, params: { humanOnly?: boolean; source?: string } = {}): Promise { + const query = new URLSearchParams() + if (params.humanOnly === false) query.set('humanOnly', 'false') + if (params.source) query.set('source', params.source) + const suffix = query.toString() ? `?${query.toString()}` : '' + return request(`/api/hermes/sessions/conversations/${encodeURIComponent(sessionId)}/messages${suffix}`) +} diff --git a/packages/client/src/components/hermes/chat/ChatPanel.vue b/packages/client/src/components/hermes/chat/ChatPanel.vue index 26b69de..5e0a58a 100644 --- a/packages/client/src/components/hermes/chat/ChatPanel.vue +++ b/packages/client/src/components/hermes/chat/ChatPanel.vue @@ -1,16 +1,23 @@ + + + + diff --git a/packages/client/src/components/hermes/chat/SessionListItem.vue b/packages/client/src/components/hermes/chat/SessionListItem.vue new file mode 100644 index 0000000..dcbf575 --- /dev/null +++ b/packages/client/src/components/hermes/chat/SessionListItem.vue @@ -0,0 +1,63 @@ + + + diff --git a/packages/client/src/components/hermes/settings/SessionSettings.vue b/packages/client/src/components/hermes/settings/SessionSettings.vue index df5b532..8cca4d3 100644 --- a/packages/client/src/components/hermes/settings/SessionSettings.vue +++ b/packages/client/src/components/hermes/settings/SessionSettings.vue @@ -1,10 +1,12 @@