/** * TypeScript types matching the FastAPI backend. * See d2l-space/app.py for source-of-truth. */ // ─── Health & Ops ────────────────────────────────────────────────── export type HealthResponse = { status: "ok"; model_loaded: boolean; doc_count: number; gpu_memory_gb: number; }; export type PingResponse = { status: "alive"; ts: number; }; export type ReindexResponse = { status: "ok" | "no_change"; mode?: "incremental" | "full_rebuild"; added: number; removed: number; indexed_count: number; store_count: number; anchors_rebuilt: boolean; anchors_k: number; elapsed_seconds: number; }; // ─── Documents ───────────────────────────────────────────────────── export type DocumentMeta = { doc_id: string; name: string; length_chars: number; created_at: number; }; export type DocumentsListResponse = { documents: DocumentMeta[]; count: number; }; export type CreateDocumentRequest = { text: string; name?: string; }; // ─── Inference ───────────────────────────────────────────────────── export type GroundingStatus = | "answered" | "answered_partial" | "ungrounded" | "rejected_low_similarity" | "model_refused"; export type SourceDoc = { doc_id: string; name: string; similarity: number; dense_similarity?: number; rerank_score?: number; }; export type AskSmartRequest = { question: string; top_k?: number; max_new_tokens?: number; similarity_threshold?: number; rerank_threshold?: number; anchor_threshold?: number; use_grounding?: boolean; repetition_penalty?: number; no_repeat_ngram_size?: number; scaler?: number; bias_scaler?: number; history?: { question: string; answer: string }[]; stream?: boolean; }; export type AskSmartResponse = { answer: string; source_docs: SourceDoc[]; _grounding_status: GroundingStatus; _grounding_score?: number | null; _top_similarity: number; _top_rerank_score?: number | null; _anchor_score?: number; _corpus_relevance?: number; _threshold: number; _reject_reason?: string; retrieve_seconds: number; inference_seconds: number; total_seconds: number; }; export type AskRequest = { doc_id: string; question: string; scaler?: number; bias_scaler?: number; max_new_tokens?: number; }; export type AskResponse = { answer: string; doc_id: string; elapsed_seconds: number; }; export type DocumentContentResponse = { doc_id: string; name: string; length_chars: number; created_at?: number; text: string; }; /** * SSE events emitted by /ask_smart when stream=true. */ export type AskSmartStreamEvent = | { event: "status"; data: { phase: string; retrieve_seconds?: number } } | { event: "sources"; data: Partial & { source_docs: SourceDoc[] } } | { event: "rejected"; data: AskSmartResponse } | { event: "token"; data: { text: string } } | { event: "done"; data: AskSmartResponse } | { event: "error"; data: { status: number; message: string } };