initial commit

This commit is contained in:
Zoe
2026-01-11 05:04:29 -06:00
commit 0877cc10bd
65 changed files with 5009 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
import { protectRoute } from '~~/server/utils/auth';
import { registerPendingGeneration } from '~~/server/utils/generation';
import type { GenerateRequestBody } from '~~/server/types/chat';
export default defineEventHandler(async (event) => {
await protectRoute(event);
const body = await readBody(event) as GenerateRequestBody;
const { topicId, messages } = body;
if (!topicId || !messages) {
throw createError({
statusCode: 400,
statusMessage: 'Missing required fields: topicId and messages'
});
}
if (messages.length === 0) {
throw createError({
statusCode: 400,
statusMessage: 'Messages array cannot be empty'
});
}
const generationId = `gen_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
registerPendingGeneration(event.context.user.id, generationId, topicId, messages);
return {
generationId,
status: 'pending'
};
});
+52
View File
@@ -0,0 +1,52 @@
import { protectRoute } from '~~/server/utils/auth';
import { getPendingGeneration, getActiveGeneration, isGenerationActive } from '~~/server/utils/generation';
import type { GenerationStatus } from '~~/server/types/chat';
export default defineEventHandler(async (event) => {
await protectRoute(event);
const generationId = getRouterParam(event, 'id');
if (!generationId) {
throw createError({
statusCode: 400,
statusMessage: 'Missing generation ID'
});
}
const pendingGeneration = getPendingGeneration(generationId);
const isActive = isGenerationActive(generationId);
const activeGeneration = getActiveGeneration(generationId);
if (!pendingGeneration && !activeGeneration) {
throw createError({
statusCode: 404,
statusMessage: 'Generation not found'
});
}
if (pendingGeneration) {
const status: GenerationStatus = {
generationId,
status: 'pending',
topicId: pendingGeneration.topicId
};
return status;
}
if (isActive && activeGeneration) {
const status: GenerationStatus = {
generationId,
status: 'active',
content: activeGeneration.content,
topicId: activeGeneration.topicId
};
return status;
}
const status: GenerationStatus = {
generationId,
status: 'completed'
};
return status;
});
+67
View File
@@ -0,0 +1,67 @@
import { protectRoute } from '~~/server/utils/auth';
import { getPendingGeneration, startGeneration, addClientToGeneration, removeClientFromGeneration, sendToClient } from '~~/server/utils/generation';
import { eventHandler, setHeader, setResponseStatus } from 'h3';
import { generations, messages } from '~~/db/schema';
import { eq } from 'drizzle-orm';
export default eventHandler(async (event) => {
await protectRoute(event);
const generationId = getRouterParam(event, 'id');
if (!generationId) {
throw createError({
statusCode: 400,
statusMessage: 'Missing generation ID'
});
}
const pendingGeneration = getPendingGeneration(generationId);
if (pendingGeneration && pendingGeneration.expired) {
throw createError({
statusCode: 410,
statusMessage: 'Generation expired - no client connected within 60 seconds'
});
}
setHeader(event, 'Content-Type', 'text/event-stream');
setHeader(event, 'Cache-Control', 'no-cache');
setHeader(event, 'Connection', 'keep-alive');
setHeader(event, 'X-Accel-Buffering', 'no');
setResponseStatus(event, 200);
const shouldStartGeneration = pendingGeneration;
try {
const stream = new ReadableStream({
async start(controller) {
addClientToGeneration(generationId, controller);
if (shouldStartGeneration) {
startGeneration(generationId, controller);
} else {
const generation = await useDrizzle().select().from(generations).where(eq(generations.id, getRouterParam(event, 'id')!))
if (!generation) throw createError({ statusCode: 404, statusMessage: 'Generation not found' });
const message = await useDrizzle().select().from(messages).where(eq(messages.id, generation[0].messageId!))
if (!message) throw createError({ statusCode: 404, statusMessage: 'Message not found' });
sendToClient(controller, {
type: 'complete',
data: message[0].content
});
controller.close();
}
event.node.req.on('close', () => {
removeClientFromGeneration(generationId, controller);
});
}
});
return sendStream(event, stream);
} catch (error) {
// assume it failed because the generation is complete so try to send the message
}
});