"use client"; import styles from './page.module.css'; import { useEffect, useState } from 'react'; import { useChat } from 'ai/react'; import { FunctionCallHandler, Message, nanoid } from 'ai'; import ReactMarkdown from "react-markdown"; import { Bot, User } from "lucide-react"; import { toast } from 'sonner'; import { FunctionIcon } from './icons'; import { updateBackground } from './util'; const Page: React.FC = () => { useEffect(() => { updateBackground(); const interval = setInterval(updateBackground, 6000); return () => clearInterval(interval); }, []); const functionCallHandler: FunctionCallHandler = async ( chatMessages, functionCall, ) => { let result; const { name, arguments: args } = functionCall; const response = await fetch("/api/functions", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ args: args, name: name }) } as any); if (!response.ok) { const errorText = await response.text(); toast.error(`Something went wrong: ${errorText}`); return; } result = await response.text(); return { messages: [ ...chatMessages, { id: nanoid(), name: functionCall.name, role: "function" as const, content: result, }, ], }; }; const { messages, input, setInput, handleSubmit, isLoading } = useChat({ experimental_onFunctionCall: functionCallHandler, onError: (error: any) => { console.log(error); }, }); const [isExpanded, setIsExpanded] = useState(false); const toggleExpand = () => { setIsExpanded(!isExpanded); }; const roleUIConfig: { [key: string]: { avatar: JSX.Element; bgColor: string; avatarColor: string; // eslint-disable-next-line no-unused-vars dialogComponent: (message: Message) => JSX.Element; }; } = { user: { avatar: , bgColor: "bg-white", avatarColor: "bg-black", dialogComponent: (message: Message) => ( ( ), }} > {message.content} ), }, assistant: { avatar: , bgColor: "bg-gray-100", avatarColor: "bg-green-500", dialogComponent: (message: Message) => ( ( ), }} > {message.content} ), }, function: { avatar:
, bgColor: "bg-gray-200", avatarColor: "bg-blue-500", dialogComponent: (message: Message) => { return (
{isExpanded && (
{message.content}
)}
); }, } }; return (
{messages.length > 0 ? ( messages.map((message, i) => { const messageClass = `${styles.message} ${message.role === 'user' ? styles['message-user'] : ''}`; return (
{roleUIConfig[message.role].avatar}
{message.content === "" && message.function_call != undefined ? ( typeof message.function_call === "object" ? (
Using{" "} {message.function_call.name} {" "} ...
{message.function_call.arguments}
) : (
{message.function_call}
) ) : ( roleUIConfig[message.role].dialogComponent(message) )}
); }) ) : null}
setInput(e.target.value)} placeholder="Chat with Internet" className={styles.input} />
); } export default Page;