Made a basic AI chat streaming content, but there is still no auth yet,

should be added soon. And add the test file test.vue to be ignored. This
file is just a poc (it is AI generated based on my API file)
This commit is contained in:
吳元皓 2025-05-23 22:51:19 +08:00
parent 13c9b7ecc8
commit d21957a8f9
2 changed files with 61 additions and 25 deletions

3
.gitignore vendored
View File

@ -33,3 +33,6 @@ __pycache__
*.sql *.sql
!database/*.sql !database/*.sql
_dt_*.py _dt_*.py
# Testing files
test.vue

View File

@ -4,30 +4,39 @@ import sql from "~/server/components/postgres";
const groq = new Groq(); const groq = new Groq();
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
const host = await getRequestHost(event);
const protocol = await getRequestProtocol(event);
const hears = await getRequestHeaders(event);
const slug = getRouterParam(event, "slug"); const slug = getRouterParam(event, "slug");
const body = await readBody(event);
if (!slug) { if (!slug) {
throw createError({ throw createError({
statusCode: 400, statusCode: 400,
message: "A UUID is required for this action.", message: "A UUID is required for this action.",
}); });
} }
const getChatHistory = await sql` const getChatHistory = await sql`
select * from chatHistory select * from chat_history
where uuid = ${slug} where uuid = ${slug}
order by created_ata asc order by created_at asc
`; `;
if (getChatHistory.length === 0) {
} const buildURL = protocol + "://" + host + "/api/news/get/lt/" + "LX30VwG";
const body = await readBody(event); const data = await fetch(buildURL);
const fetchNewsArticle = await sql` const fetchNewsArticle = await data.json();
select * from newArticle
where newsid = ${body.newsid} // Set headers for Server-Sent Events
`; setHeader(event, "Content-Type", "text/plain; charset=utf-8");
setHeader(event, "Cache-Control", "no-cache");
setHeader(event, "Connection", "keep-alive");
setHeader(event, "Access-Control-Allow-Origin", "*");
const chatCompletion = await groq.chat.completions.create({ const chatCompletion = await groq.chat.completions.create({
messages: [ messages: [
{ {
role: "system", role: "system",
content: `You are a news chat, the following content will be used to chat with the user title: ${fetchNewsArticle.title}\n content: ${fetchNewsArticle.content}`, content: `You are a news chat, the following content will be used to chat with the user title: ${fetchNewsArticle.title} article: ${fetchNewsArticle.paragraph} origin: ${fetchNewsArticle.origin} author: ${fetchNewsArticle.author}`,
}, },
...getChatHistory.map((chat) => ({ ...getChatHistory.map((chat) => ({
role: chat.role, role: chat.role,
@ -35,7 +44,7 @@ export default defineEventHandler(async (event) => {
})), })),
{ {
role: "user", role: "user",
content: `${body}`, content: body.message,
}, },
], ],
model: "llama-3.1-8b-instant", model: "llama-3.1-8b-instant",
@ -45,20 +54,44 @@ export default defineEventHandler(async (event) => {
stream: true, stream: true,
stop: null, stop: null,
}); });
/*
// Save user message
await sql` await sql`
INSERT INTO chat_history (uuid, role, content) INSERT INTO chat_history (uuid, role, content)
VALUES (${slug}, 'user', ${body}) VALUES (${slug}, 'user', ${body.message})
`; `; */
let assistantResponse = ""; let assistantResponse = "";
for await (const chunk of chatCompletion) {
const content = chunk.choices[0]?.delta?.content || ""; // Create a readable stream
assistantResponse += content; const stream = new ReadableStream({
process.stdout.write(content); async start(controller) {
} try {
if (assistantResponse) { for await (const chunk of chatCompletion) {
await sql` const content = chunk.choices[0]?.delta?.content || "";
INSERT INTO chat_history (uuid, role, content) if (content) {
VALUES (${slug}, 'assistant', ${assistantResponse}) assistantResponse += content;
`; // Send chunk to client
} controller.enqueue(new TextEncoder().encode(content));
}
}
/*
// Save complete assistant response
if (assistantResponse) {
await sql`
INSERT INTO chat_history (uuid, role, content)
VALUES (${slug}, 'assistant', ${assistantResponse})
`;
} */
controller.close();
} catch (error) {
controller.error(error);
}
},
});
return sendStream(event, stream);
}); });