From 8137ce4f23b5304bf4424c7378b51fb83c30412d Mon Sep 17 00:00:00 2001 From: weishu Date: Mon, 26 Jan 2026 10:29:14 +0800 Subject: [PATCH] feat: add microcompact_boundary event handling in web UI Adds support for Claude Code's microcompact_boundary system message type to display context microcompaction events with token savings information in the chat UI. Shows a package icon with formatted token count (e.g., "Context compacted (saved 32K tokens)"). close #108 --- web/src/chat/normalizeAgent.ts | 17 +++++++++++++++++ web/src/chat/presentation.ts | 5 +++++ web/src/chat/types.ts | 1 + 3 files changed, 23 insertions(+) diff --git a/web/src/chat/normalizeAgent.ts b/web/src/chat/normalizeAgent.ts index 5fe7a8fc..a16f4678 100644 --- a/web/src/chat/normalizeAgent.ts +++ b/web/src/chat/normalizeAgent.ts @@ -246,6 +246,23 @@ export function normalizeAgentRecord( meta } } + if (data.type === 'system' && data.subtype === 'microcompact_boundary') { + const metadata = isObject(data.microcompactMetadata) ? data.microcompactMetadata : null + return { + id: messageId, + localId, + createdAt, + role: 'event', + content: { + type: 'microcompact', + trigger: asString(metadata?.trigger) ?? 'auto', + preTokens: asNumber(metadata?.preTokens) ?? 0, + tokensSaved: asNumber(metadata?.tokensSaved) ?? 0 + }, + isSidechain: false, + meta + } + } return null } diff --git a/web/src/chat/presentation.ts b/web/src/chat/presentation.ts index 49491859..67a0f6ad 100644 --- a/web/src/chat/presentation.ts +++ b/web/src/chat/presentation.ts @@ -58,6 +58,11 @@ export function getEventPresentation(event: AgentEvent): EventPresentation { const ms = typeof event.durationMs === 'number' ? event.durationMs : 0 return { icon: '⏱️', text: `Turn: ${formatDuration(ms)}` } } + if (event.type === 'microcompact') { + const saved = typeof event.tokensSaved === 'number' ? event.tokensSaved : 0 + const formatted = saved >= 1000 ? `${Math.round(saved / 1000)}K` : String(saved) + return { icon: '📦', text: `Context compacted (saved ${formatted} tokens)` } + } try { return { icon: null, text: JSON.stringify(event) } } catch { diff --git a/web/src/chat/types.ts b/web/src/chat/types.ts index fd17d2c7..a171e670 100644 --- a/web/src/chat/types.ts +++ b/web/src/chat/types.ts @@ -16,6 +16,7 @@ export type AgentEvent = | { type: 'ready' } | { type: 'api-error'; retryAttempt: number; maxRetries: number; error: unknown } | { type: 'turn-duration'; durationMs: number } + | { type: 'microcompact'; trigger: string; preTokens: number; tokensSaved: number } | ({ type: string } & Record) export type ToolResultPermission = {