diff --git a/web/frontend/src/components/chat/assistant-message.tsx b/web/frontend/src/components/chat/assistant-message.tsx index 1c52f2921..150f2f87d 100644 --- a/web/frontend/src/components/chat/assistant-message.tsx +++ b/web/frontend/src/components/chat/assistant-message.tsx @@ -16,6 +16,8 @@ export function AssistantMessage({ timestamp = "", }: AssistantMessageProps) { const [isCopied, setIsCopied] = useState(false) + const formattedTimestamp = + timestamp !== "" ? formatMessageTime(timestamp) : "" const handleCopy = () => { navigator.clipboard.writeText(content).then(() => { @@ -29,10 +31,10 @@ export function AssistantMessage({
PicoClaw - {timestamp && ( + {formattedTimestamp && ( <> - {formatMessageTime(timestamp)} + {formattedTimestamp} )}
diff --git a/web/frontend/src/hooks/use-pico-chat.ts b/web/frontend/src/hooks/use-pico-chat.ts index fbc3261c2..950f10a1e 100644 --- a/web/frontend/src/hooks/use-pico-chat.ts +++ b/web/frontend/src/hooks/use-pico-chat.ts @@ -11,7 +11,7 @@ interface PicoMessage { type: string id?: string session_id?: string - timestamp?: number + timestamp?: number | string payload?: Record } @@ -28,9 +28,37 @@ function generateSessionId(): string { return crypto.randomUUID() } +const UNIX_MS_THRESHOLD = 1e12 + +function normalizeUnixTimestamp(timestamp: number): number { + return timestamp < UNIX_MS_THRESHOLD ? timestamp * 1000 : timestamp +} + +function parseTimestamp(dateRaw: number | string | Date) { + if (typeof dateRaw === "number") { + return dayjs(normalizeUnixTimestamp(dateRaw)) + } + + if (typeof dateRaw === "string") { + const trimmed = dateRaw.trim() + if (/^-?\d+(\.\d+)?$/.test(trimmed)) { + const numeric = Number(trimmed) + if (Number.isFinite(numeric)) { + return dayjs(normalizeUnixTimestamp(numeric)) + } + } + return dayjs(trimmed) + } + + return dayjs(dateRaw) +} + // Helper to format message timestamps export function formatMessageTime(dateRaw: number | string | Date): string { - const date = dayjs(dateRaw) + const date = parseTimestamp(dateRaw) + if (!date.isValid()) { + return "" + } const now = dayjs() const isToday = date.isSame(now, "day") @@ -75,7 +103,10 @@ export function usePicoChat() { const content = (payload.content as string) || "" const messageId = (payload.message_id as string) || `pico-${Date.now()}` // Use provided timestamp or current time - const timestampRaw = msg.timestamp ? msg.timestamp * 1000 : Date.now() + const timestampRaw = + msg.timestamp !== undefined && Number.isFinite(Number(msg.timestamp)) + ? normalizeUnixTimestamp(Number(msg.timestamp)) + : Date.now() setMessages((prev) => [ ...prev,