added: grade, subject and chapter in new chat, fixed that shitty card bug
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import express from "express";
|
||||
import { streamChatResponse } from "../services/ai.js";
|
||||
import { createSession, addMessage, getMessages, getSession, listSessions } from "../stores/sessionStore.js";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* POST /api/chat — Send a message and stream back an AI response.
|
||||
*
|
||||
* Request body:
|
||||
* {
|
||||
* text: "What is photosynthesis?",
|
||||
* chatId: "optional_existing_session_id",
|
||||
* grade: "Grade 10",
|
||||
* subject: "Biology",
|
||||
* chapter: "Nutrition in Plants"
|
||||
* }
|
||||
*/
|
||||
router.post("/", async (req, res) => {
|
||||
const { text, chatId, grade, subject, chapter } = req.body;
|
||||
|
||||
// Validate input
|
||||
if (!text || !text.trim()) {
|
||||
return res.status(400).json({ error: "Message text is required" });
|
||||
}
|
||||
|
||||
// Resolve or create session
|
||||
let session;
|
||||
if (chatId) {
|
||||
session = getSession(chatId);
|
||||
if (!session) {
|
||||
return res.status(404).json({ error: "Session not found" });
|
||||
}
|
||||
} else {
|
||||
session = createSession(grade, subject, chapter);
|
||||
}
|
||||
|
||||
const currentChatId = session.id;
|
||||
|
||||
// Get conversation history
|
||||
const chatMessages = getMessages(currentChatId);
|
||||
|
||||
// Add user message to history
|
||||
const userMsg = {
|
||||
id: `user_${Date.now()}`,
|
||||
role: "user",
|
||||
text: text.trim(),
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
addMessage(currentChatId, userMsg);
|
||||
|
||||
// Set SSE headers
|
||||
res.setHeader("Content-Type", "text/event-stream");
|
||||
res.setHeader("Cache-Control", "no-cache");
|
||||
res.setHeader("Connection", "keep-alive");
|
||||
res.setHeader("X-Accel-Buffering", "no");
|
||||
|
||||
let assistantText = "";
|
||||
let errorOccurred = false;
|
||||
|
||||
// Stream the AI response
|
||||
try {
|
||||
await streamChatResponse(
|
||||
chatMessages,
|
||||
grade || session.grade,
|
||||
subject || session.subject,
|
||||
chapter || session.chapter,
|
||||
(chunk) => {
|
||||
assistantText += chunk;
|
||||
// Send chunk as SSE event
|
||||
res.write(`data: ${JSON.stringify({ type: "chunk", content: chunk })}\n\n`);
|
||||
},
|
||||
(err) => {
|
||||
errorOccurred = true;
|
||||
res.write(`data: ${JSON.stringify({ type: "error", message: err })}\n\n`);
|
||||
res.end();
|
||||
}
|
||||
);
|
||||
|
||||
// Send end event
|
||||
res.write(`data: ${JSON.stringify({ type: "done" })}\n\n`);
|
||||
|
||||
// Save assistant message to history
|
||||
const assistantMsg = {
|
||||
id: `assistant_${Date.now()}`,
|
||||
role: "assistant",
|
||||
text: assistantText,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
addMessage(currentChatId, assistantMsg);
|
||||
} catch (err) {
|
||||
res.write(`data: ${JSON.stringify({ type: "error", message: err.message })}\n\n`);
|
||||
} finally {
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/chat/:chatId — Get conversation messages for a session
|
||||
*/
|
||||
router.get("/:chatId", (req, res) => {
|
||||
const { chatId } = req.params;
|
||||
const session = getSession(chatId);
|
||||
|
||||
if (!session) {
|
||||
return res.status(404).json({ error: "Session not found" });
|
||||
}
|
||||
|
||||
const msgHistory = getMessages(chatId);
|
||||
|
||||
res.json({
|
||||
session: {
|
||||
id: session.id,
|
||||
grade: session.grade,
|
||||
subject: session.subject,
|
||||
chapter: session.chapter,
|
||||
createdAt: session.createdAt,
|
||||
updatedAt: session.updatedAt,
|
||||
},
|
||||
messages: msgHistory,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* GET /api/chat/sessions — List all chat sessions
|
||||
*/
|
||||
router.get("/sessions", (_req, res) => {
|
||||
const sessions = listSessions();
|
||||
res.json(sessions);
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user