Skip to content

Commit

Permalink
fix: for chat api
Browse files Browse the repository at this point in the history
  • Loading branch information
Bensigo committed Oct 12, 2023
1 parent befb6d7 commit c6fdc2e
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 153 deletions.
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"build": "next build",
"dev": "next dev",
"postinstall": "prisma db push && prisma generate",
"postinstall": "prisma generate --no-engine",
"lint": "next lint",
"start": "next start"
},
Expand All @@ -16,7 +16,8 @@
"@emotion/styled": "^11.11.0",
"@hookform/resolvers": "^3.1.1",
"@next-auth/prisma-adapter": "^1.0.5",
"@prisma/client": "^4.14.0",
"@prisma/client": "^5.2.0",
"@prisma/extension-accelerate": "^0.6.2",
"@reduxjs/toolkit": "^1.9.5",
"@sendgrid/mail": "^7.7.0",
"@t3-oss/env-nextjs": "^0.3.1",
Expand All @@ -41,6 +42,7 @@
"next-redux-wrapper": "^8.1.0",
"nodemailer": "^6.9.3",
"openai": "^3.3.0",
"openai-edge": "^1.2.2",
"react": "18.2.0",
"react-chartjs-2": "^5.2.0",
"react-datepicker": "^4.16.0",
Expand All @@ -52,6 +54,7 @@
"react-redux": "^8.1.0",
"react-type-animation": "^3.1.0",
"superjson": "1.12.2",
"yarn": "^1.22.19",
"yup": "^1.2.0",
"zod": "^3.21.4"
},
Expand All @@ -68,7 +71,7 @@
"env-cmd": "^10.1.0",
"eslint": "^8.40.0",
"eslint-config-next": "^13.4.2",
"prisma": "^4.14.0",
"prisma": "^5.2.0",
"typescript": "^5.0.4"
},
"ct3aMetadata": {
Expand Down
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ generator client {
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
// directUrl = env("DIRECT_DATABASE_URL")
}

model Example {
Expand Down
2 changes: 2 additions & 0 deletions src/env.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const env = createEnv({
*/
server: {
DATABASE_URL: z.string().url(),
// DIRECT_DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(["development", "test", "production"]),
NEXTAUTH_SECRET:
process.env.NODE_ENV === "production"
Expand Down Expand Up @@ -45,6 +46,7 @@ export const env = createEnv({
*/
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
DIRECT_DATABASE_URL: process.env.DIRECT_DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
Expand Down
125 changes: 55 additions & 70 deletions src/pages/api/v2/chat.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { type DailyTherapySession, PrismaClient } from "@prisma/client";
import { type NextApiResponse, type NextApiRequest } from "next";
import { Configuration, OpenAIApi } from "openai";
import { type DailyTherapySession, PrismaClient } from "@prisma/client/edge";
import { withAccelerate } from '@prisma/extension-accelerate';
import { OpenAIStream, StreamingTextResponse } from 'ai'
import { Configuration, OpenAIApi } from 'openai-edge'
import { env } from "@/env.mjs";
import { authOptions, getServerAuthSession } from "@/server/auth";
import { type IncomingMessage } from "http";
import { auth } from "../auth/[...nextauth]";

export const maxDuration = 100;


export const runtime = 'edge';

const config = new Configuration({
apiKey: env.OPEN_AI,
});
const openai = new OpenAIApi(config)
})

let content = ''
const openai = new OpenAIApi(config)

export default async function POST(req: NextApiRequest, res: NextApiResponse) {
export default async function POST(req: Request) {

// handle auth
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const session = await getServerAuthSession({ req, res, authOptions });
if(!session){
return res.status(401).send("Unauthorized")
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const session = req.headers.getSetCookie()

console.log({ session })
if (!session){
return new Response('Unauthorized', {
status: 401
})
}


const prisma = new PrismaClient();
const prisma = new PrismaClient().$extends(withAccelerate());
const json = await req.json() as { messages: any[], sessionId: string }

const { sessionId, messages } = JSON.parse(req.body as string) as { messages: any[], sessionId: string };
const { sessionId, messages } = json;



const dailySession = await prisma.dailyTherapySession.findFirst({
where: {
Expand All @@ -41,73 +48,51 @@ export default async function POST(req: NextApiRequest, res: NextApiResponse) {
});

if (!dailySession) {
return res.status(400).send("Invalid Therapy Session")
return Response.json("Invalid Therapy Session")

}



const isValidChatSession = isValidSession(dailySession)
if (!isValidChatSession){
res.status(400).send("Expired session")
return;
}
// const isValidChatSession = isValidSession(dailySession)
// if (!isValidChatSession){
// res.status(400).send("Expired session")
// return;
// }

const response = await openai.createChatCompletion({
stream: true,
model: "gpt-3.5-turbo",
messages,
temperature: 0.6,
}, { responseType: 'stream'});

temperature: 0.4,
});

const stream = response.data as unknown as IncomingMessage;

stream.on('data', (chunk: Buffer) => processChunk(chunk, res));

stream.on('error', (err: Error) => {
console.log(err);
res.status(500).send("Internal Server Error");
const stream = OpenAIStream(response, {
async onCompletion(content){
await prisma.message.createMany({
data: [
{
sender: "user",
sessionId,
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
content: messages[messages.length - 1].content,
},
{
sender: "assistant",
sessionId,
content,
},
],
});

stream.on('end', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const msg = messages[messages.length - 1].content
const saveMessagesToDatabase = async () => await prisma.message.createMany({
data: [
{
sender: "user",
sessionId,
content: msg,
},
{
sender: "assistant",
sessionId,
content,
},
],
});
void saveMessagesToDatabase();
return;
}
})

return res.status(200);
}

function processChunk(chunk: Buffer, res: NextApiResponse) {
const payloads = chunk.toString().split("\n\n");
for (const payload of payloads) {
if (payload.includes('[DONE]')) return;
if (payload.startsWith("data:")) {
const data = JSON.parse(payload.replace("data: ", ""));
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const chunkContent: string | undefined = data.choices[0].delta?.content;
if (chunkContent) {
content += chunkContent;
res.write(chunkContent);
}
}
}
return new StreamingTextResponse(stream)
}



function isValidSession(dailySession: DailyTherapySession) {
const startTime = new Date(dailySession.start);
const currentTime = new Date();
Expand Down
2 changes: 1 addition & 1 deletion src/shared-ui/ZenQuestCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function ZenQuestCard(props: ZenQuestCardProps) {
mutate({ id: props.id }, {
onSuccess: () => {
const ctx = api.useContext()
const invalidateListQuest = async() => await ctx.quest.list.refetch({
const invalidateListQuest = async() => await ctx.quest.list.reset({
filter: props.selectedFilter,
take: 20
})
Expand Down
21 changes: 7 additions & 14 deletions src/ui/quest/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import { ChatScrollAnchor } from "./chatScrollArchor";
const ChatUI = ({ msgs }: { msgs: Message[] }) => {
const router = useRouter();
const context = api.useContext();
const [isSendBtnDisabled, setSendDisabled] = useState(false);
const [input, setInput] = useState("");
const [timeRemaining, setTimeRemaining] = useState(1800); // 30 minutes in seconds


Expand All @@ -37,7 +35,7 @@ const ChatUI = ({ msgs }: { msgs: Message[] }) => {

const { mutate } = api.activity.completeQuestActivity.useMutation();

const { messages, append } = useChat({
const { messages, append, isLoading, input, setInput } = useChat({
api: `/api/v2/chat`,
body: {
sessionId: msgs[0]?.sessionId,
Expand All @@ -49,7 +47,7 @@ const ChatUI = ({ msgs }: { msgs: Message[] }) => {
createdAt: msg.createdAt,
})),
onResponse(res) {
setSendDisabled(false)

if (res.status === 401) {
toast({
description: res.statusText,
Expand All @@ -67,20 +65,16 @@ const ChatUI = ({ msgs }: { msgs: Message[] }) => {
status: "error",
});
},
onFinish: () => {
console.log("got here");
setSendDisabled(false);
},

});

const goBack = () => {
router.back();
};

const handleSendMessage = async () => {
const msg = input.trim()
setSendDisabled(true);
setInput("");
const msg = input.trim()
setInput("")
await append({
id: msgs[0]?.sessionId,
content: msg,
Expand Down Expand Up @@ -127,7 +121,6 @@ const ChatUI = ({ msgs }: { msgs: Message[] }) => {
}, 1000);

if (timeRemaining <= 0) {
setSendDisabled(true);
clearInterval(timer);
}

Expand Down Expand Up @@ -215,7 +208,7 @@ const ChatUI = ({ msgs }: { msgs: Message[] }) => {
<Text> {message.content}</Text>
</Box>
))}
<ChatScrollAnchor trackVisibility={!isSendBtnDisabled} />
<ChatScrollAnchor trackVisibility={!isLoading} />
</VStack>

</Box>
Expand Down Expand Up @@ -251,7 +244,7 @@ const ChatUI = ({ msgs }: { msgs: Message[] }) => {
colorScheme="sage"
aria-label="Send"
onClick={() => void handleSendMessage()}
isDisabled={isSendBtnDisabled}
isDisabled={isLoading}
borderRadius="md"
/>
</Flex>
Expand Down
Loading

0 comments on commit c6fdc2e

Please sign in to comment.