| import * as React from "react"; |
| import Link from "next/link"; |
| import { ChatBubbleIcon, ReaderIcon } from "@radix-ui/react-icons"; |
|
|
| interface ChatMessage { |
| role: string; |
| content: { context: { source: string }[]; answer: string } | string; |
| } |
|
|
| interface ResponseType { |
| context: { source: string }[]; |
| answer: string; |
| } |
|
|
| export function AgentMessage({ message }: { message: ChatMessage }) { |
| const [parsedSources, setParsedSources] = React.useState<string[]>([]); |
| const [parsedAnswer, setParsedAnswer] = React.useState(""); |
|
|
| const parseResponse = (response: ResponseType | string) => { |
| const { content } = message; |
| let sources: string[] = []; |
| let answer: string = ""; |
| if (typeof response === "object" && content.context && content.answer) { |
| sources = content.context.map((item) => item.source); |
| answer = content.answer; |
| } else if (typeof content === "string") { |
| const sourcesMatch = content.match(/<sources>(.*?)<\/sources>/s); |
| if (sourcesMatch && sourcesMatch[1]) { |
| sources = sourcesMatch[1].trim().split("\n"); |
| } |
| answer = content.split("</sources>").pop() || ""; |
| } |
| return { sources, answer }; |
| }; |
|
|
| React.useEffect(() => { |
| const parsedResponse = parseResponse(message); |
| setParsedSources(parsedResponse.sources); |
| setParsedAnswer(parsedResponse.answer); |
| }, [message]); |
|
|
| return ( |
| <div className="space-y-4"> |
| <h3 className="text-xl flex justify-start items-center"> |
| <ReaderIcon /> |
| Sources |
| </h3> |
| <ol className="space-y-2"> |
| {parsedSources.map((source, idx) => source && ( |
| <li key={idx} className="text-gray-600 underline underline-offset-2"> |
| <Link href={JSON.parse(source).url}>{JSON.parse(source).url}</Link> |
| </li> |
| ))} |
| </ol> |
| <h3 className="text-xl flex justify-start items-center"> |
| <ChatBubbleIcon /> |
| Answer |
| </h3> |
| <p className="text-gray-600">{parsedAnswer}</p> |
| </div> |
| ); |
| } |
|
|