"use client"; import type React from "react"; import { useRef, useEffect } from "react"; import Image from "next/image"; import { ScrollArea } from "@/components/ui/scroll-area"; import ExamplePanel from "./chat-example-panel"; import { Message } from "ai"; import { convertToLegalXml, replaceNodes } from "@/lib/utils"; interface ChatMessageDisplayProps { chartXML: string; messages: Message[]; error?: Error | null; setInput: (input: string) => void; setFiles: (files: FileList | undefined) => void; onDisplayChart: (xml: string) => void; } export function ChatMessageDisplay({ chartXML, messages, error, setInput, setFiles, onDisplayChart, }: ChatMessageDisplayProps) { const messagesEndRef = useRef(null); const previousXML = useRef(""); useEffect(() => { if (messagesEndRef.current) { messagesEndRef.current.scrollIntoView({ behavior: "smooth" }); } }, [messages]); const renderToolInvocation = (toolInvocation: any) => { const callId = toolInvocation.toolCallId; switch (toolInvocation.toolName) { case "display_diagram": { switch (toolInvocation.state) { case "partial-call": { const currentXml = toolInvocation.args?.xml || ""; // Increment the step counter // Determine whether to show details based on a simple threshold const convertedXml = convertToLegalXml(currentXml); if (convertedXml !== previousXML.current) { previousXML.current = convertedXml; // if "/root" in convertedXml const replacedXML = replaceNodes( chartXML, convertedXml ); console.log("currentXml", currentXml); console.log("converted xml", convertedXml); console.log("replaced xml", replacedXML); onDisplayChart(replacedXML); // if convertedXml changed } // if "/root" in convertedXml // if convertedXml changed } return (
Generating diagram...
Tool: display_diagram
onDisplayChart
); case "call": return (
Displaying diagram...
Tool: display_diagram
Args:{" "} {JSON.stringify( toolInvocation.args, null, 2 )}
); case "result": return null; } break; } default: return null; } }; return ( {messages.length === 0 ? ( ) : ( messages.map((message) => (
{message.parts ? message.parts.map((part, index) => { switch (part.type) { case "text": return (
{part.text}
); case "tool-invocation": return renderToolInvocation( part.toolInvocation ); default: return null; } }) : message.content}
{message?.experimental_attachments ?.filter((attachment) => attachment?.contentType?.startsWith("image/") ) .map((attachment, index) => (
{
))} {(message as any).function_call && (
Using tool:{" "} {(message as any).function_call.name} ...
)}
)) )} {error && (
Error: {error.message}
)}
); }