| 13 | import { memo } from "react"; |
| 14 | |
| 15 | export function PurePreviewMessage({ message }: { message: Message }) { |
| 16 | return ( |
| 17 | <AnimatePresence> |
| 18 | <motion.div |
| 19 | className="group/message mx-auto w-full max-w-3xl px-0.5" |
| 20 | initial={{ y: 5, opacity: 0 }} |
| 21 | animate={{ y: 0, opacity: 1 }} |
| 22 | data-role={message.role} |
| 23 | > |
| 24 | <div className="flex w-full gap-4 group-data-[role=user]/message:ml-auto group-data-[role=user]/message:w-fit group-data-[role=user]/message:max-w-2xl"> |
| 25 | {message.role === "assistant" && ( |
| 26 | <div className="flex size-8 shrink-0 items-center justify-center rounded-full bg-background ring-1 ring-border"> |
| 27 | <div className="translate-y-px"> |
| 28 | <Icons.sparkles size={14} /> |
| 29 | </div> |
| 30 | </div> |
| 31 | )} |
| 32 | <div |
| 33 | className={cn("flex flex-col gap-4", { |
| 34 | "rounded-xl bg-primary px-3 py-2 text-primary-foreground": |
| 35 | message.role === "user", |
| 36 | })} |
| 37 | > |
| 38 | {message.content.length > 0 ? ( |
| 39 | <Markdown>{message.content as string}</Markdown> |
| 40 | ) : ( |
| 41 | <span className="font-light italic"> |
| 42 | {"calling tool: " + message?.toolInvocations?.[0].toolName} |
| 43 | </span> |
| 44 | )} |
| 45 | </div> |
| 46 | </div> |
| 47 | </motion.div> |
| 48 | </AnimatePresence> |
| 49 | ); |
| 50 | } |
| 51 | |
| 52 | export const PreviewMessage = memo( |
| 53 | PurePreviewMessage, |