/** * Polling client for the evaluation endpoint. * * Polls GET /api/v1/query/{queryId}/evaluation every 3 seconds. * Stops on: scores received, 404, or 90s timeout. * The backend returns "pending" while the TruLens background thread is still * running, and "complete" once the row has been persisted to evaluation_results. */ import api from "./client"; import type { EvalPollResponse } from "../types"; const POLL_INTERVAL_MS = 3000; const POLL_TIMEOUT_MS = 90000; export function pollEvaluation( queryId: string, onResult: (response: EvalPollResponse) => void, onError: (err: string) => void, ): () => void { const startTime = Date.now(); let intervalId: ReturnType | null = null; function stop() { if (intervalId !== null) { clearInterval(intervalId); intervalId = null; } } intervalId = setInterval(async () => { if (Date.now() - startTime > POLL_TIMEOUT_MS) { stop(); onError("Evaluation timed out"); return; } try { const { data } = await api.get( `/query/${queryId}/evaluation`, ); if (data.status === "complete") { stop(); onResult(data); } // "pending" → keep polling } catch (err: unknown) { const status = (err as { response?: { status?: number } })?.response?.status; // 404 means the provider is "none" or evaluation was skipped — stop silently if (status === 404) { stop(); } else { stop(); onError("Failed to fetch evaluation scores"); } } }, POLL_INTERVAL_MS); return stop; }