From b4813f091a1f0c73b882f357d8726f0f72984513 Mon Sep 17 00:00:00 2001 From: Nicolas Varrot Date: Thu, 12 Feb 2026 23:17:27 +0000 Subject: [PATCH] feat: add message metadata viewer on hover Small info button appears on hover of each message bubble. Click to expand a panel showing raw message metadata (id, role, timestamp, channel, sender info, etc.) from the gateway. Useful for debugging and understanding message routing. Collapsed by default, doesn't clutter the UI. Closes feedback item #39 --- FEEDBACK.md | 11 +++++++++++ src/components/ChatMessage.tsx | 35 ++++++++++++++++++++++++++++++++-- src/hooks/useGateway.ts | 7 +++++++ src/lib/i18n.ts | 2 ++ src/types/index.ts | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/FEEDBACK.md b/FEEDBACK.md index 7f87b39..a64b6dc 100644 --- a/FEEDBACK.md +++ b/FEEDBACK.md @@ -479,3 +479,14 @@ - Could use a lighter background (slightly brighter than assistant messages) or a colored left border - Keep it subtle but clearly distinguishable - Test against the zinc dark theme to make sure it's readable for keratoconus (no harsh contrast) + +## Item #45 +- **Date:** 2026-02-12 +- **Priority:** high +- **Status:** pending +- **Description:** Display the agent's avatar when set in OpenClaw config + - OpenClaw gateway can provide an avatar URL for the agent (configured in openclaw.json) + - PinchChat should display this avatar next to assistant messages instead of the default Bot icon + - Check the gateway WebSocket session/handshake data for avatar info + - Fallback to the current default icon if no avatar is configured + - Should also appear in the header next to the agent name diff --git a/src/components/ChatMessage.tsx b/src/components/ChatMessage.tsx index 5832458..551c927 100644 --- a/src/components/ChatMessage.tsx +++ b/src/components/ChatMessage.tsx @@ -10,7 +10,7 @@ import { CodeBlock } from './CodeBlock'; import { ToolCall } from './ToolCall'; import { ImageBlock } from './ImageBlock'; import { buildImageSrc } from '../lib/image'; -import { Bot, User, Wrench, Copy, Check, RefreshCw, Zap } from 'lucide-react'; +import { Bot, User, Wrench, Copy, Check, RefreshCw, Zap, Info } from 'lucide-react'; import { t, getLocale } from '../lib/i18n'; import { useLocale } from '../hooks/useLocale'; // ChevronDown, ChevronRight, Wrench still used by InternalOnlyMessage @@ -240,6 +240,34 @@ function CopyButton({ text }: { text: string }) { ); } +function MetadataViewer({ metadata }: { metadata?: Record }) { + const [open, setOpen] = useState(false); + if (!metadata || Object.keys(metadata).length === 0) return null; + + return ( +
+ + {open && ( +
+ {Object.entries(metadata).map(([k, v]) => ( +
+ {k}: + {typeof v === 'object' ? JSON.stringify(v) : String(v)} +
+ ))} +
+ )} +
+ ); +} + /** Extract plain text from message blocks for clipboard copy */ function getPlainText(message: ChatMessageType): string { if (message.blocks.length > 0) { @@ -305,10 +333,13 @@ export function ChatMessageComponent({ message, onRetry }: { message: ChatMessag ? 'bg-gradient-to-b from-cyan-800/40 to-cyan-900/25 text-zinc-100 border border-cyan-400/30' : 'bg-zinc-800/40 text-zinc-300 border border-white/8 shadow-[0_0_0_1px_rgba(255,255,255,0.03)]' }`}> - {/* Copy button (assistant messages only) */} + {/* Action buttons */} {!isUser && !message.isStreaming && getPlainText(message).trim() && ( )} +
+ +
{/* Retry button (user messages only) */} {isUser && onRetry && (