Web UI: show Compaction divider in chat history (#11341)

This commit is contained in:
Tak Hoffman
2026-02-07 12:37:22 -06:00
committed by GitHub
parent f0722498a4
commit 82419eaad6
5 changed files with 117 additions and 0 deletions

View File

@@ -54,6 +54,33 @@
opacity: 0.7;
}
/* Chat divider (e.g., compaction marker) */
.chat-divider {
display: flex;
align-items: center;
gap: 10px;
margin: 18px 8px;
color: var(--muted);
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
user-select: none;
}
.chat-divider__line {
flex: 1 1 0;
height: 1px;
background: var(--border);
opacity: 0.9;
}
.chat-divider__label {
padding: 2px 10px;
border: 1px solid var(--border);
border-radius: 999px;
background: rgba(255, 255, 255, 0.02);
}
/* Avatar Styles */
.chat-avatar {
width: 40px;

View File

@@ -5,6 +5,7 @@
/** Union type for items in the chat thread */
export type ChatItem =
| { kind: "message"; key: string; message: unknown }
| { kind: "divider"; key: string; label: string; timestamp: number }
| { kind: "stream"; key: string; text: string; startedAt: number }
| { kind: "reading-indicator"; key: string };

View File

@@ -224,6 +224,16 @@ export function renderChat(props: ChatProps) {
buildChatItems(props),
(item) => item.key,
(item) => {
if (item.kind === "divider") {
return html`
<div class="chat-divider" role="separator" data-ts=${String(item.timestamp)}>
<span class="chat-divider__line"></span>
<span class="chat-divider__label">${item.label}</span>
<span class="chat-divider__line"></span>
</div>
`;
}
if (item.kind === "reading-indicator") {
return renderReadingIndicatorGroup(assistantIdentity);
}
@@ -477,6 +487,20 @@ function buildChatItems(props: ChatProps): Array<ChatItem | MessageGroup> {
for (let i = historyStart; i < history.length; i++) {
const msg = history[i];
const normalized = normalizeMessage(msg);
const raw = msg as Record<string, unknown>;
const marker = raw.__openclaw as Record<string, unknown> | undefined;
if (marker && marker.kind === "compaction") {
items.push({
kind: "divider",
key:
typeof marker.id === "string"
? `divider:compaction:${marker.id}`
: `divider:compaction:${normalized.timestamp}:${i}`,
label: "Compaction",
timestamp: normalized.timestamp ?? Date.now(),
});
continue;
}
if (!props.showThinking && normalized.role.toLowerCase() === "toolresult") {
continue;