From de60011bd6939b40cdfdae9ee6775e9c4d991073 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 23 Apr 2026 20:41:49 +0000 Subject: [PATCH] feat(ui): playground/ChatMessageBubble to shadcn - @ant-design RobotOutlined/UserOutlined \u2192 lucide Bot/User. Inline hex palette (#f0f8ff/#ffffff/#e6f0fa/#f0f0f0/#f5f5f5/#2563eb/ #4b5563/#e5e7eb/#f5f5f5) \u2192 blue-50/background/blue-100/border/ muted + blue-600/muted-foreground tokens. User bubble keeps categorical blue accent; file added to .eslintrc overrides. Gates: TS \u2713 | Build \u2713. Co-authored-by: yuneng-jiang --- ui/litellm-dashboard/.eslintrc.json | 1 + .../playground/chat_ui/ChatMessageBubble.tsx | 47 ++++++++++--------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/ui/litellm-dashboard/.eslintrc.json b/ui/litellm-dashboard/.eslintrc.json index 843164aaf82..99acb96b8f0 100644 --- a/ui/litellm-dashboard/.eslintrc.json +++ b/ui/litellm-dashboard/.eslintrc.json @@ -90,6 +90,7 @@ "src/components/mcp_tools/OAuthFormFields.tsx", "src/components/transform_request.tsx", "src/components/Navbar/UserDropdown/UserDropdown.tsx", + "src/components/playground/chat_ui/ChatMessageBubble.tsx", "src/components/permissions/VectorStorePermissions.tsx", "src/components/permissions/AgentPermissions.tsx", "src/components/permissions/MCPServerPermissions.tsx", diff --git a/ui/litellm-dashboard/src/components/playground/chat_ui/ChatMessageBubble.tsx b/ui/litellm-dashboard/src/components/playground/chat_ui/ChatMessageBubble.tsx index 15978c17f7e..56136530550 100644 --- a/ui/litellm-dashboard/src/components/playground/chat_ui/ChatMessageBubble.tsx +++ b/ui/litellm-dashboard/src/components/playground/chat_ui/ChatMessageBubble.tsx @@ -1,4 +1,5 @@ -import { RobotOutlined, UserOutlined } from "@ant-design/icons"; +import { Bot, User } from "lucide-react"; +import { cn } from "@/lib/utils"; import React from "react"; import ReactMarkdown from "react-markdown"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; @@ -41,32 +42,34 @@ function ChatMessageBubble({ const isUser = message.role === "user"; return ( -
+
{/* Header: role icon + name + model badge */}
{isUser ? ( - + ) : ( - + )}
{message.role} {message.role === "assistant" && message.model && ( - + {message.model} )} @@ -114,10 +117,11 @@ function ChatMessageBubble({ }} > {message.isImage ? ( + // eslint-disable-next-line @next/next/no-img-element Generated image ) : message.isAudio ? ( @@ -143,6 +147,7 @@ function ChatMessageBubble({ const match = /language-(\w+)/.exec(className || ""); return !inline && match ? ( ) : ( {children} ); }, - pre: ({ node, ...props }) => ( -
+                  pre: ({ ...props }) => (
+                    
                   ),
                 }}
               >
@@ -174,10 +178,11 @@ function ChatMessageBubble({
               {/* Generated image from chat completions */}
               {message.image && (
                 
+ {/* eslint-disable-next-line @next/next/no-img-element */} Generated image