DocDoeAI / src /lib /api /learn-lesson.ts
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
2.22 kB
import { apiPost } from "@/lib/api/client";
/**
* Learn Anything playable lesson. The backend generates this once per unique
* lesson (LLM teaching script -> Deepgram/AI4Bharat audio) and caches it by
* content hash, so repeat opens are free and instant. The browser "plays" it
* — audio + synced board — instead of streaming a rendered MP4.
*/
export interface LessonBeat {
kind: string;
narration: string;
board_heading: string;
board_lines: string[];
visual_hint: string;
audio_src: string;
start_second: number;
duration_seconds: number;
}
export interface LessonManifest {
schema: string;
lessonHash: string;
topic: string;
lessonTitle: string;
level: string;
medium: string;
voice: string;
/** Audio when available; reading is an explicit, fully navigable fallback. */
deliveryMode?: "audio" | "reading";
/** Honest explanation when the class opens without generated voice. */
deliveryNotice?: string;
isFallback?: boolean;
totalSeconds: number;
totalMinutes: number;
/** One-line description of the class (added v1.1; older cached lessons omit it). */
summary?: string;
/** "By the end you can…" outcomes (added v1.1; older cached lessons omit it). */
objectives?: string[];
beats: LessonBeat[];
notes: string[];
flashcards: { front: string; back: string }[];
}
export interface LearnLessonRequestBody {
topic: string;
lesson_title: string;
level?: string;
medium?: string;
source_ids?: string[];
}
/**
* Build (first time) or fetch (cached) a playable lesson. First call for a new
* lesson takes a while — the server is writing the script and voicing it — so
* callers should show a "preparing your class" state.
*/
export function fetchLearnLesson(body: LearnLessonRequestBody): Promise<LessonManifest> {
// The backend returns a voiced lesson when explicitly enabled, otherwise
// it returns the existing labelled reading manifest within its SLA. Keep a
// browser-side ceiling as the final protection against a stale deployment
// or a provider that ignores cancellation.
return apiPost<LessonManifest, LearnLessonRequestBody>(
"/generate/learn-lesson",
body,
{ timeoutMs: 45_000 },
);
}