From 1011c950bef934d32eca90095b7f3b5867ec9851 Mon Sep 17 00:00:00 2001 From: ekko <152005280+EKKOLearnAI@users.noreply.github.com> Date: Wed, 6 May 2026 14:07:13 +0800 Subject: [PATCH] fix: improve chat message display and compression logic (#476) Frontend: - Filter out assistant messages with empty content in mapHermesMessages() - Prevents displaying 194/585 empty messages in long sessions - Reduces visual clutter and improves UX Backend: - Add message count limit (<= 200) to compression threshold checks - Prevents compressing sessions with too many messages - Improves compression performance and reliability Co-authored-by: Claude Sonnet 4.6 --- packages/client/src/stores/hermes/chat.ts | 12 ++++++++++-- .../server/src/services/hermes/chat-run-socket.ts | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/client/src/stores/hermes/chat.ts b/packages/client/src/stores/hermes/chat.ts index 89d9ee6..3b8005e 100644 --- a/packages/client/src/stores/hermes/chat.ts +++ b/packages/client/src/stores/hermes/chat.ts @@ -119,10 +119,18 @@ async function buildContentBlocks( } function mapHermesMessages(msgs: HermesMessage[]): Message[] { + // Filter out assistant messages with empty content + const filteredMsgs = msgs.filter(m => { + if (m.role === 'assistant') { + return m.content && m.content.trim() !== '' + } + return true + }) + // Build lookups from assistant messages with tool_calls const toolNameMap = new Map() const toolArgsMap = new Map() - for (const msg of msgs) { + for (const msg of filteredMsgs) { if (msg.role === 'assistant' && msg.tool_calls) { for (const tc of msg.tool_calls) { if (tc.id) { @@ -134,7 +142,7 @@ function mapHermesMessages(msgs: HermesMessage[]): Message[] { } const result: Message[] = [] - for (const msg of msgs) { + for (const msg of filteredMsgs) { // Skip assistant messages that only contain tool_calls (no meaningful content) if (msg.role === 'assistant' && msg.tool_calls?.length && !msg.content?.trim()) { // Emit a tool.started message for each tool call diff --git a/packages/server/src/services/hermes/chat-run-socket.ts b/packages/server/src/services/hermes/chat-run-socket.ts index c160160..a8e8d25 100644 --- a/packages/server/src/services/hermes/chat-run-socket.ts +++ b/packages/server/src/services/hermes/chat-run-socket.ts @@ -578,7 +578,7 @@ export class ChatRunSocket { logger.info('[context-compress] session=%s: snapshot at %d, %d new messages, assembled ~%d tokens (threshold %d)', session_id, snapshot.lastMessageIndex, newMessages.length, totalTokens, triggerTokens) // triggerTokens - if (totalTokens <= triggerTokens) { + if (totalTokens <= triggerTokens && newMessages.length <= 200) { // Under threshold — use assembled context directly, no LLM call needed history = [ { role: 'user', content: SUMMARY_PREFIX + '\n\n' + snapshot.summary }, @@ -684,7 +684,7 @@ export class ChatRunSocket { } else if (history.length > 4) { // No snapshot — check if raw history exceeds threshold - if (totalTokens <= triggerTokens) { + if (totalTokens <= triggerTokens && history.length <= 200) { // Under threshold — use raw history as-is logger.info('[context-compress] session=%s: %d messages, ~%d tokens — under threshold, skip', session_id, history.length, totalTokens) } else {