feat(chat-api): handle messages as separate entities

This commit is contained in:
ItzCrazyKns
2025-08-29 12:44:40 +05:30
parent 266c333b29
commit 34fa52ad12
2 changed files with 23 additions and 17 deletions

View File

@@ -52,11 +52,10 @@ const handleEmitterEvents = async (
stream: EventEmitter, stream: EventEmitter,
writer: WritableStreamDefaultWriter, writer: WritableStreamDefaultWriter,
encoder: TextEncoder, encoder: TextEncoder,
aiMessageId: string,
chatId: string, chatId: string,
) => { ) => {
let recievedMessage = ''; let recievedMessage = '';
let sources: any[] = []; const aiMessageId = crypto.randomBytes(7).toString('hex');
stream.on('data', (data) => { stream.on('data', (data) => {
const parsedData = JSON.parse(data); const parsedData = JSON.parse(data);
@@ -83,7 +82,17 @@ const handleEmitterEvents = async (
), ),
); );
sources = parsedData.data; const sourceMessageId = crypto.randomBytes(7).toString('hex');
db.insert(messagesSchema)
.values({
chatId: chatId,
messageId: sourceMessageId,
role: 'source',
sources: parsedData.data,
createdAt: new Date().toString(),
})
.execute();
} }
}); });
stream.on('end', () => { stream.on('end', () => {
@@ -91,7 +100,6 @@ const handleEmitterEvents = async (
encoder.encode( encoder.encode(
JSON.stringify({ JSON.stringify({
type: 'messageEnd', type: 'messageEnd',
messageId: aiMessageId,
}) + '\n', }) + '\n',
), ),
); );
@@ -103,10 +111,7 @@ const handleEmitterEvents = async (
chatId: chatId, chatId: chatId,
messageId: aiMessageId, messageId: aiMessageId,
role: 'assistant', role: 'assistant',
metadata: JSON.stringify({ createdAt: new Date().toString(),
createdAt: new Date(),
...(sources && sources.length > 0 && { sources }),
}),
}) })
.execute(); .execute();
}); });
@@ -167,9 +172,7 @@ const handleHistorySave = async (
chatId: message.chatId, chatId: message.chatId,
messageId: humanMessageId, messageId: humanMessageId,
role: 'user', role: 'user',
metadata: JSON.stringify({ createdAt: new Date().toString(),
createdAt: new Date(),
}),
}) })
.execute(); .execute();
} else { } else {
@@ -251,7 +254,6 @@ export const POST = async (req: Request) => {
const humanMessageId = const humanMessageId =
message.messageId ?? crypto.randomBytes(7).toString('hex'); message.messageId ?? crypto.randomBytes(7).toString('hex');
const aiMessageId = crypto.randomBytes(7).toString('hex');
const history: BaseMessage[] = body.history.map((msg) => { const history: BaseMessage[] = body.history.map((msg) => {
if (msg[0] === 'human') { if (msg[0] === 'human') {
@@ -290,7 +292,7 @@ export const POST = async (req: Request) => {
const writer = responseStream.writable.getWriter(); const writer = responseStream.writable.getWriter();
const encoder = new TextEncoder(); const encoder = new TextEncoder();
handleEmitterEvents(stream, writer, encoder, aiMessageId, message.chatId); handleEmitterEvents(stream, writer, encoder, message.chatId);
handleHistorySave(message, humanMessageId, body.focusMode, body.files); handleHistorySave(message, humanMessageId, body.focusMode, body.files);
return new Response(responseStream.readable, { return new Response(responseStream.readable, {

View File

@@ -1,15 +1,19 @@
import { sql } from 'drizzle-orm'; import { sql } from 'drizzle-orm';
import { text, integer, sqliteTable } from 'drizzle-orm/sqlite-core'; import { text, integer, sqliteTable } from 'drizzle-orm/sqlite-core';
import { Document } from 'langchain/document';
export const messages = sqliteTable('messages', { export const messages = sqliteTable('messages', {
id: integer('id').primaryKey(), id: integer('id').primaryKey(),
content: text('content').notNull(), role: text('type', { enum: ['assistant', 'user', 'source'] }).notNull(),
chatId: text('chatId').notNull(), chatId: text('chatId').notNull(),
createdAt: text('createdAt').notNull(),
messageId: text('messageId').notNull(), messageId: text('messageId').notNull(),
role: text('type', { enum: ['assistant', 'user'] }),
metadata: text('metadata', { content: text('content'),
sources: text('sources', {
mode: 'json', mode: 'json',
}), }).$type<Document[]>(),
}); });
interface File { interface File {