SHOW:
|
|
- or go back to the newest paste.
| 1 | import { Configuration, OpenAIApi } from "openai-edge";
| |
| 2 | import { Message, OpenAIStream, StreamingTextResponse } from "ai";
| |
| 3 | import { getContext } from "@/lib/context";
| |
| 4 | import { db } from "@/lib/db";
| |
| 5 | import { chats, messages as _messages } from "@/lib/db/schema";
| |
| 6 | import { eq } from "drizzle-orm";
| |
| 7 | import { NextResponse } from "next/server";
| |
| 8 | ||
| 9 | export const runtime = "edge"; | |
| 10 | ||
| 11 | const config = new Configuration({
| |
| 12 | apiKey: process.env.OPENAI_API_KEY, | |
| 13 | }); | |
| 14 | const openai = new OpenAIApi(config); | |
| 15 | ||
| 16 | export async function POST(req: Request) {
| |
| 17 | try {
| |
| 18 | const { messages, chatId } = await req.json();
| |
| 19 | const _chats = await db.select().from(chats).where(eq(chats.id, chatId)); | |
| 20 | if (_chats.length != 1) {
| |
| 21 | return NextResponse.json({ error: "chat not found" }, { status: 404 });
| |
| 22 | } | |
| 23 | const fileKey = _chats[0].fileKey; | |
| 24 | const lastMessage = messages[messages.length - 1]; | |
| 25 | const context = await getContext(lastMessage.content, fileKey); | |
| 26 | ||
| 27 | const prompt = {
| |
| 28 | role: "system", | |
| 29 | content: `AI assistant is a brand new, powerful, human-like artificial intelligence. | |
| 30 | The traits of AI include expert knowledge, helpfulness, cleverness, and articulateness. | |
| 31 | AI is a well-behaved and well-mannered individual. | |
| 32 | AI is always friendly, kind, and inspiring, and he is eager to provide vivid and thoughtful responses to the user. | |
| 33 | AI has the sum of all knowledge in their brain, and is able to accurately answer nearly any question about any topic in conversation. | |
| 34 | AI assistant is a big fan of Pinecone and Vercel. | |
| 35 | START CONTEXT BLOCK | |
| 36 | ${context}
| |
| 37 | END OF CONTEXT BLOCK | |
| 38 | AI assistant will take into account any CONTEXT BLOCK that is provided in a conversation. | |
| 39 | If the context does not provide the answer to question, the AI assistant will say, "I'm sorry, but I don't know the answer to that question". | |
| 40 | AI assistant will not apologize for previous responses, but instead will indicated new information was gained. | |
| 41 | AI assistant will not invent anything that is not drawn directly from the context. | |
| 42 | `, | |
| 43 | }; | |
| 44 | ||
| 45 | const response = await openai.createChatCompletion({
| |
| 46 | model: "gpt-3.5-turbo", | |
| 47 | messages: [ | |
| 48 | prompt, | |
| 49 | ...messages.filter((message: Message) => message.role === "user"), | |
| 50 | ], | |
| 51 | stream: true, | |
| 52 | }); | |
| 53 | const stream = OpenAIStream(response, {
| |
| 54 | onStart: async () => {
| |
| 55 | // save user message into db | |
| 56 | await db.insert(_messages).values({
| |
| 57 | chatId, | |
| 58 | content: lastMessage.content, | |
| 59 | role: "user", | |
| 60 | }); | |
| 61 | }, | |
| 62 | onCompletion: async (completion) => {
| |
| 63 | // save ai message into db | |
| 64 | await db.insert(_messages).values({
| |
| 65 | chatId, | |
| 66 | content: completion, | |
| 67 | role: "system", | |
| 68 | }); | |
| 69 | }, | |
| 70 | }); | |
| 71 | return new StreamingTextResponse(stream); | |
| 72 | } catch (error) {}
| |
| 73 | } | |
| 74 |