nico-martin's picture
nico-martin HF Staff
small improvements
b2847f1
raw
history blame
3.04 kB
import { Modal } from "@theme";
import cn from "@utils/classnames.ts";
import { formatDuration } from "@utils/format.ts";
import { SquareCode, StopCircle } from "lucide-react";
import { useState } from "react";
import type { ChatMessageAssistant } from "../textGeneration/types.ts";
import MessageContent from "./MessageContent.tsx";
import MessageToolCall from "./MessageToolCall.tsx";
export default function Message({
message,
className = "",
}: {
message: ChatMessageAssistant;
className?: string;
}) {
const [templateOpen, setTemplateOpen] = useState<boolean>(false);
return (
<div className={cn(className, "group relative flex flex-col gap-1")}>
{message.metadata && (
<Modal
title="Full Template"
isOpen={templateOpen}
onClose={() => setTemplateOpen(false)}
size="xl"
>
<pre className="max-h-[70vh] overflow-auto rounded-lg border border-gray-300 bg-gray-50 p-4 text-sm leading-relaxed text-gray-900 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-100">
{message.metadata.template}
</pre>
</Modal>
)}
{message.content.map((part) =>
part.type === "tool" ? (
<MessageToolCall tool={part} />
) : (
<MessageContent content={part.content} />
)
)}
{message.interrupted && (
<div className="mt-2 flex items-center gap-2 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-800 dark:border-amber-700 dark:bg-amber-950 dark:text-amber-200">
<StopCircle className="size-4 shrink-0" />
<span>Response interrupted by the user</span>
</div>
)}
{message.metadata && (
<div className="mt-1 inline-flex flex-wrap items-center gap-1.5 self-end rounded-lg bg-gray-200 px-2.5 py-1 text-xs font-medium text-gray-700 opacity-0 transition-opacity group-hover:opacity-100 dark:bg-gray-700 dark:text-gray-300">
<span className="font-semibold">{message.metadata.model}</span>
<span className="text-gray-400 dark:text-gray-500"></span>
<span>
Output: {Math.round(message.metadata.outputTps)} tok/s (
{message.metadata.outputTokens} tokens in{" "}
{formatDuration(message.metadata.outputDurationMs)})
</span>
<span className="text-gray-400 dark:text-gray-500"></span>
<span title="Input processing time">
Prefill: {formatDuration(message.metadata.inputDurationMs)}
</span>
<span className="text-gray-400 dark:text-gray-500"></span>
<button
className="flex items-center gap-1 rounded-md px-1.5 py-0.5 transition-colors hover:bg-gray-300 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-gray-100"
onClick={() => setTemplateOpen(true)}
>
<SquareCode className="size-3 -translate-y-1/20" />
<span>Template</span>
</button>
</div>
)}
</div>
);
}