chatbot-ui starter

This commit is contained in:
Mckay Wrigley
2023-03-13 19:21:14 -06:00
parent 4c9730e4cd
commit a6503fb498
25 changed files with 7259 additions and 71 deletions
+13
View File
@@ -0,0 +1,13 @@
import "@/styles/globals.css";
import type { AppProps } from "next/app";
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] });
export default function App({ Component, pageProps }: AppProps<{}>) {
return (
<main className={inter.className}>
<Component {...pageProps} />
</main>
);
}
+13
View File
@@ -0,0 +1,13 @@
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
+36
View File
@@ -0,0 +1,36 @@
import { Message } from "@/types";
import { OpenAIStream } from "@/utils";
export const config = {
runtime: "edge"
};
const handler = async (req: Request): Promise<Response> => {
try {
const { messages } = (await req.json()) as {
messages: Message[];
};
const charLimit = 12000;
let charCount = 0;
let messagesToSend = [];
for (let i = 0; i < messages.length; i++) {
const message = messages[i];
if (charCount + message.content.length > charLimit) {
break;
}
charCount += message.content.length;
messagesToSend.push(message);
}
const stream = await OpenAIStream(messagesToSend);
return new Response(stream);
} catch (error) {
console.error(error);
return new Response("Error", { status: 500 });
}
};
export default handler;
+127
View File
@@ -0,0 +1,127 @@
import { Chat } from "@/components/Chat/Chat";
import { Footer } from "@/components/Layout/Footer";
import { Navbar } from "@/components/Layout/Navbar";
import { Message } from "@/types";
import Head from "next/head";
import { useEffect, useRef, useState } from "react";
export default function Home() {
const [messages, setMessages] = useState<Message[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const messagesEndRef = useRef<HTMLDivElement>(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
};
const handleSend = async (message: Message) => {
const updatedMessages = [...messages, message];
setMessages(updatedMessages);
setLoading(true);
const response = await fetch("/api/chat", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
messages: updatedMessages
})
});
if (!response.ok) {
setLoading(false);
throw new Error(response.statusText);
}
const data = response.body;
if (!data) {
return;
}
setLoading(false);
const reader = data.getReader();
const decoder = new TextDecoder();
let done = false;
let isFirst = true;
while (!done) {
const { value, done: doneReading } = await reader.read();
done = doneReading;
const chunkValue = decoder.decode(value);
if (isFirst) {
isFirst = false;
setMessages((messages) => [
...messages,
{
role: "assistant",
content: chunkValue
}
]);
} else {
setMessages((messages) => {
const lastMessage = messages[messages.length - 1];
const updatedMessage = {
...lastMessage,
content: lastMessage.content + chunkValue
};
return [...messages.slice(0, -1), updatedMessage];
});
}
}
};
useEffect(() => {
scrollToBottom();
}, [messages]);
useEffect(() => {
setMessages([
{
role: "assistant",
content: `Hi there! I'm Chatbot UI, an AI assistant. I can help you with things like answering questions, providing information, and helping with tasks. How can I help you?`
}
]);
}, []);
return (
<>
<Head>
<title>Chatbot UI</title>
<meta
name="description"
content="A simple chatbot starter kit for OpenAI's chat model using Next.js, TypeScript, and Tailwind CSS."
/>
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<link
rel="icon"
href="/favicon.ico"
/>
</Head>
<div className="flex flex-col h-screen">
<Navbar />
<div className="flex-1 overflow-auto sm:px-10 pb-4 sm:pb-10">
<div className="max-w-[800px] mx-auto mt-4 sm:mt-12">
<Chat
messages={messages}
loading={loading}
onSend={handleSend}
/>
<div ref={messagesEndRef} />
</div>
</div>
<Footer />
</div>
</>
);
}