import { Message, EmailActionOptions } from "@/types/chat";
import SourceCard from "./SourceCard";
import RichResponseRenderer from "./rich/RichResponseRenderer";
import HexAvatar from "./HexAvatar";
interface MessageBubbleProps {
message: Message;
onEmailAction?: (content: string, options: EmailActionOptions) => void;
}
// Escape HTML before applying markdown — the result feeds
// dangerouslySetInnerHTML, and LLM output must never inject markup.
function escapeHtml(text: string): string {
return text
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function formatContent(text: string): string {
return escapeHtml(text)
.replace(/\*\*(.*?)\*\*/g, "$1")
.replace(/\*(.*?)\*/g, "$1")
.replace(/`([^`]+)`/g, "$1")
.replace(/\n/g, "
");
}
export default function MessageBubble({ message, onEmailAction }: MessageBubbleProps) {
const isUser = message.role === "user";
const time = message.timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
if (isUser) {
return (
{time}