import { AppError } from "@/server/errors"; import { RAG_REQUEST_TIMEOUT_MS, RAG_SERVICE_SECRET, RAG_SERVICE_URL, } from "@/lib/constants"; type RagHistoryTurn = { question: string; answer: string; }; type RagAnswerResponse = { answer: string; sources: Array<{ file_id: string; file_name: string; page_number: number | null; score: number | null; snippet: string; }>; }; async function callRagService( path: string, body: Record, ): Promise { const response = await fetch(`${RAG_SERVICE_URL}${path}`, { method: "POST", headers: { "Content-Type": "application/json", "x-rag-service-secret": RAG_SERVICE_SECRET, }, body: JSON.stringify(body), signal: AbortSignal.timeout(RAG_REQUEST_TIMEOUT_MS), }); const payload = (await response.json().catch(() => null)) as | { detail?: string; message?: string } | T | null; if (!response.ok) { throw new AppError( (payload as { detail?: string; message?: string } | null)?.detail || (payload as { detail?: string; message?: string } | null)?.message || "تعذر التواصل مع خدمة الذكاء الاصطناعي.", 502, ); } return payload as T; } export async function ingestCaseFileIntoRag(params: { ownerId: string; caseId: string; fileId: string; bucket: string; objectKey: string; fileName: string; }) { return callRagService<{ indexed_chunks: number }>("/ingest", { owner_id: params.ownerId, case_id: params.caseId, file_id: params.fileId, bucket: params.bucket, object_key: params.objectKey, file_name: params.fileName, }); } export async function askCaseRagQuestion(params: { ownerId: string; caseId: string; question: string; history: RagHistoryTurn[]; }) { return callRagService("/answer", { owner_id: params.ownerId, case_id: params.caseId, question: params.question, history: params.history, }); }