From 5e9fc614d77669f3ffb2bb0b2e8b111b3dd97157 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 30 Mar 2026 18:08:20 +0300 Subject: [PATCH] feat(llm): display message time --- apps/client/src/services/utils.ts | 1 + .../src/widgets/sidebar/SidebarChat.css | 4 +- .../type_widgets/llm_chat/ChatMessage.tsx | 60 +++++++++++-------- .../widgets/type_widgets/llm_chat/LlmChat.css | 19 ++++-- 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/apps/client/src/services/utils.ts b/apps/client/src/services/utils.ts index bc35a0bd3f..30b5e4eaf7 100644 --- a/apps/client/src/services/utils.ts +++ b/apps/client/src/services/utils.ts @@ -922,6 +922,7 @@ export default { parseDate, formatDateISO, formatDateTime, + formatTime, formatTimeInterval, formatSize, localNowDateTime, diff --git a/apps/client/src/widgets/sidebar/SidebarChat.css b/apps/client/src/widgets/sidebar/SidebarChat.css index f852b219ea..1f332bb5a3 100644 --- a/apps/client/src/widgets/sidebar/SidebarChat.css +++ b/apps/client/src/widgets/sidebar/SidebarChat.css @@ -36,8 +36,8 @@ font-size: 0.9rem; } -/* Usage footer: pull it closer to the message above by collapsing the flex gap */ -.sidebar-chat-messages .llm-chat-usage { +/* Footer: pull it closer to the message above by collapsing the flex gap */ +.sidebar-chat-messages .llm-chat-footer { margin-top: -0.35rem; margin-bottom: 0; } diff --git a/apps/client/src/widgets/type_widgets/llm_chat/ChatMessage.tsx b/apps/client/src/widgets/type_widgets/llm_chat/ChatMessage.tsx index 1bfd71a1e7..0702bd5953 100644 --- a/apps/client/src/widgets/type_widgets/llm_chat/ChatMessage.tsx +++ b/apps/client/src/widgets/type_widgets/llm_chat/ChatMessage.tsx @@ -5,6 +5,7 @@ import { marked } from "marked"; import { useMemo } from "preact/hooks"; import { t } from "../../../services/i18n.js"; +import utils from "../../../services/utils.js"; import type { ContentBlock, StoredMessage, ToolCall } from "./llm_chat_types.js"; import { getMessageText, getMessageToolCalls } from "./llm_chat_types.js"; @@ -205,30 +206,41 @@ export default function ChatMessage({ message, isStreaming }: Props) { )} - {message.usage && typeof message.usage.promptTokens === "number" && ( -
- {message.usage.model && ( - {message.usage.model} - )} - · - - {" "} - {t("llm_chat.total_tokens", { total: shortenNumber(message.usage.totalTokens) })} - - {message.usage.cost != null && ( - <> - · - ~${message.usage.cost.toFixed(4)} - - )} -
- )} +
+ + {utils.formatTime(new Date(message.createdAt))} + + {message.usage && typeof message.usage.promptTokens === "number" && ( + <> + {message.usage.model && ( + <> + · + {message.usage.model} + + )} + · + + {" "} + {t("llm_chat.total_tokens", { total: shortenNumber(message.usage.totalTokens) })} + + {message.usage.cost != null && ( + <> + · + ~${message.usage.cost.toFixed(4)} + + )} + + )} +
); } diff --git a/apps/client/src/widgets/type_widgets/llm_chat/LlmChat.css b/apps/client/src/widgets/type_widgets/llm_chat/LlmChat.css index 15dee696bc..bbd4fe8b4d 100644 --- a/apps/client/src/widgets/type_widgets/llm_chat/LlmChat.css +++ b/apps/client/src/widgets/type_widgets/llm_chat/LlmChat.css @@ -24,8 +24,8 @@ margin-top: 0; } -/* Collapse gap between the usage footer and the next message */ -.llm-chat-usage + .llm-chat-message { +/* Collapse gap between the footer and the next message */ +.llm-chat-footer + .llm-chat-message { margin-top: 0.5rem; } @@ -618,8 +618,8 @@ color: var(--danger-color, #dc3545); } -/* Token usage display (sits below the message bubble) */ -.llm-chat-usage { +/* Message footer (timestamp + token usage, sits below the bubble) */ +.llm-chat-footer { display: flex; align-items: center; gap: 0.375rem; @@ -630,10 +630,18 @@ cursor: default; } -.llm-chat-usage .bx { +.llm-chat-footer-user { + justify-content: flex-end; +} + +.llm-chat-footer .bx { font-size: 0.875rem; } +.llm-chat-footer-time { + cursor: help; +} + .llm-chat-usage-model { font-weight: 500; } @@ -643,6 +651,7 @@ } .llm-chat-usage-tokens { + cursor: help; font-family: var(--monospace-font-family, monospace); }