Spaces:
Sleeping
Sleeping
| /** | |
| * RAG Chat Route | |
| * | |
| * POST /api/rag/chat | |
| * Answer questions using RAG (Retrieval-Augmented Generation) | |
| * | |
| * Emits Socket.io `stage_update` events as the pipeline progresses: | |
| * Stage 1 β Retrieving documents | |
| * Stage 2 β Generating answer | |
| * Stage 3 β Done / Stage -1 β Error | |
| */ | |
| import { NextRequest, NextResponse } from "next/server"; | |
| import { getCurrentUser } from "@/lib/auth"; | |
| import { ragChat } from "@/lib/ai-client"; | |
| import { emitStageUpdate } from "@/lib/socket"; | |
| import { v4 as uuidv4 } from "uuid"; | |
| export async function POST(request: NextRequest) { | |
| // Each request gets a sessionId so the frontend can join the right room. | |
| // If the client passes one we reuse it, otherwise we generate one. | |
| const body = await request.json(); | |
| const sessionId: string = body.session_id || uuidv4(); | |
| try { | |
| const user = await getCurrentUser(request); | |
| if (!user) { | |
| return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); | |
| } | |
| const { question, repo_name, top_k } = body; | |
| if (!question) { | |
| return NextResponse.json({ error: "question is required" }, { status: 400 }); | |
| } | |
| // ββ Stage 1: Retrieval ββββββββββββββββββββββββββββββββββββββ | |
| emitStageUpdate(sessionId, { | |
| stage: 1, | |
| label: "Retrieving relevant documentsβ¦", | |
| progress: 30, | |
| }); | |
| const result = await ragChat(question, repo_name, top_k || 5); | |
| if (!result.success) { | |
| // ββ Stage -1: Error βββββββββββββββββββββββββββββββββββββ | |
| emitStageUpdate(sessionId, { | |
| stage: -1, | |
| label: "AI service unavailable", | |
| meta: { error: result.error }, | |
| }); | |
| console.error("RAG service unavailable:", result.error); | |
| return NextResponse.json({ | |
| session_id: sessionId, | |
| answer: "I'm sorry, but the AI service is temporarily unavailable. Please try again in a few moments. If this persists, the service might be waking up from sleep mode.", | |
| sources: [], | |
| related_issues: [], | |
| error: result.error, | |
| service_unavailable: true | |
| }, { status: 200 }); | |
| } | |
| // ββ Stage 2: Generation complete ββββββββββββββββββββββββββββ | |
| emitStageUpdate(sessionId, { | |
| stage: 2, | |
| label: "Answer generated", | |
| progress: 90, | |
| }); | |
| // ββ Stage 3: Done βββββββββββββββββββββββββββββββββββββββββββ | |
| emitStageUpdate(sessionId, { | |
| stage: 3, | |
| label: "Complete", | |
| progress: 100, | |
| }); | |
| return NextResponse.json({ session_id: sessionId, ...result.data as object }); | |
| } catch (error) { | |
| emitStageUpdate(sessionId, { | |
| stage: -1, | |
| label: "Internal error", | |
| meta: { error: String(error) }, | |
| }); | |
| console.error("RAG chat error:", error); | |
| return NextResponse.json({ | |
| session_id: sessionId, | |
| answer: "I encountered an error processing your request. Please try again.", | |
| sources: [], | |
| related_issues: [], | |
| error: "Internal server error", | |
| service_unavailable: true | |
| }, { status: 200 }); | |
| } | |
| } | |