d2l-ui / lib /types.ts
Berkkirik's picture
feat: streaming + multi-turn + view source + doc-scoped + UX fixes
df790cc
/**
* 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<AskSmartResponse> & { source_docs: SourceDoc[] } }
| { event: "rejected"; data: AskSmartResponse }
| { event: "token"; data: { text: string } }
| { event: "done"; data: AskSmartResponse }
| { event: "error"; data: { status: number; message: string } };