You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.2 KiB
83 lines
2.2 KiB
import { Router, Response } from "express"; |
|
import prisma from "../lib/prisma"; |
|
import { getDeepSeekClient } from "../lib/deepseek"; |
|
import type { AuthRequest } from "../middleware/auth"; |
|
|
|
const router = Router(); |
|
|
|
router.get("/history", async (req: AuthRequest, res: Response) => { |
|
const studentId = req.studentId!; |
|
const messages = await prisma.chatMessage.findMany({ |
|
where: { studentId }, |
|
orderBy: { createdAt: "asc" }, |
|
take: 100, |
|
}); |
|
res.json(messages); |
|
}); |
|
|
|
router.post("/", async (req: AuthRequest, res: Response) => { |
|
const { message } = req.body; |
|
const studentId = req.studentId!; |
|
|
|
if (!message || typeof message !== "string") { |
|
res.status(400).json({ error: "Message is required" }); |
|
return; |
|
} |
|
|
|
await prisma.chatMessage.create({ |
|
data: { role: "user", content: message, studentId }, |
|
}); |
|
|
|
const history = await prisma.chatMessage.findMany({ |
|
where: { studentId }, |
|
orderBy: { createdAt: "asc" }, |
|
take: 50, |
|
}); |
|
|
|
const client = await getDeepSeekClient(); |
|
|
|
const messages = history.map((m: { role: string; content: string }) => ({ |
|
role: m.role as "user" | "assistant", |
|
content: m.content, |
|
})); |
|
|
|
res.setHeader("Content-Type", "text/event-stream"); |
|
res.setHeader("Cache-Control", "no-cache"); |
|
res.setHeader("Connection", "keep-alive"); |
|
|
|
try { |
|
const stream = await client.chat.completions.create({ |
|
model: "deepseek-chat", |
|
messages, |
|
stream: true, |
|
}); |
|
|
|
let fullResponse = ""; |
|
|
|
for await (const chunk of stream) { |
|
const content = chunk.choices[0]?.delta?.content || ""; |
|
if (content) { |
|
fullResponse += content; |
|
res.write(`data: ${JSON.stringify({ content })}\n\n`); |
|
} |
|
} |
|
|
|
await prisma.chatMessage.create({ |
|
data: { role: "assistant", content: fullResponse, studentId }, |
|
}); |
|
|
|
res.write(`data: [DONE]\n\n`); |
|
res.end(); |
|
} catch (err: any) { |
|
res.write(`data: ${JSON.stringify({ error: err.message })}\n\n`); |
|
res.end(); |
|
} |
|
}); |
|
|
|
router.delete("/history", async (req: AuthRequest, res: Response) => { |
|
const studentId = req.studentId!; |
|
await prisma.chatMessage.deleteMany({ where: { studentId } }); |
|
res.json({ success: true }); |
|
}); |
|
|
|
export default router;
|
|
|