Download src/components/study-chat/study-workflow.ts from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 8.76 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/study-chat/study-workflow.ts
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/study-chat/study-workflow.ts
-
curl -L -o study-workflow.ts https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/study-chat/study-workflow.ts
8.76 kB
| import { | |
| askDocDoe, | |
| generateBrainDeepChapter, | |
| generateBrainExamAnswer, | |
| generateBrainFlashcards, | |
| generateBrainLastNightPlan, | |
| generateBrainNotes, | |
| generateBrainPyqAnalysis, | |
| generateBrainQuiz, | |
| generateBrainVisualLesson, | |
| generateStudyPath, | |
| } from "@/lib/api/brain"; | |
| import type { ApiDocument, BrainGeneratePayload } from "@/lib/api/types"; | |
| import { buildStructuredStudyResponse, shouldUseStructuredStudyResponse } from "@/lib/phase3-learning"; | |
| import type { StudyIntent } from "@/lib/study-intents"; | |
| import { askModeForIntent, type StudyBrainContext } from "./study-brain-context"; | |
| import type { StudyCard, StudyCardMeta } from "./types"; | |
| export type RunStudyGenerationInput = { | |
| intent: StudyIntent; | |
| prompt: string; | |
| topic?: string | null; | |
| sourceIds: string[]; | |
| selectedDocuments: ApiDocument[]; | |
| brainContext?: StudyBrainContext; | |
| /** | |
| * When true, source IDs are stripped before calling the API. | |
| * Use for "general_answer" mode where the user asked a topic | |
| * question without explicitly requesting their uploaded material. | |
| */ | |
| generalMode?: boolean; | |
| }; | |
| function revisionTimeLeftForPrompt(prompt: string) { | |
| const value = prompt.toLowerCase(); | |
| if (/\b(30\s*min|half\s*hour)\b/.test(value)) return "30_minutes"; | |
| if (/\b(1\s*hour|one\s*hour|60\s*min)\b/.test(value)) return "1_hour"; | |
| if (/\b(2\s*hours?|two\s*hours?)\b/.test(value)) return "2_hours"; | |
| if (/\b(3\s*hours?|three\s*hours?)\b/.test(value)) return "3_hours"; | |
| if (/\b(5\s*hours?|five\s*hours?|half\s*day)\b/.test(value)) return "5_hours"; | |
| if (/\b(tonight|one\s+night|overnight|cram|last\s+night)\b/.test(value)) return "tonight"; | |
| if (/\b(tomorrow|next\s+day|1\s*day|one\s*day)\b/.test(value)) return "tomorrow"; | |
| return "tonight"; | |
| } | |
| function generationPayload( | |
| generationTopic: string, | |
| sourceIds: string[], | |
| brainContext?: StudyBrainContext, | |
| extra: Partial<BrainGeneratePayload> = {}, | |
| ): BrainGeneratePayload { | |
| return { | |
| topic: generationTopic, | |
| source_id: sourceIds[0] ?? null, | |
| source_ids: sourceIds, | |
| subject: brainContext?.subject ?? null, | |
| study_profile_id: brainContext?.studyProfileId ?? null, | |
| level: brainContext?.level ?? null, | |
| language_preference: brainContext?.languagePreference ?? null, | |
| ...extra, | |
| }; | |
| } | |
| const GENERAL_EVIDENCE_LABEL = "No source attached - general answer"; | |
| export function metaFromResponse(response: { | |
| trust_note?: string | null; | |
| evidence_label?: string | null; | |
| is_fallback?: boolean; | |
| suggested_actions?: string[]; | |
| citations?: unknown[]; | |
| }, sourceIds: string[] = []): StudyCardMeta { | |
| const trustNote = response.trust_note ?? null; | |
| const evidenceLabel = response.evidence_label ?? null; | |
| const citations = Array.isArray(response.citations) ? response.citations : []; | |
| const looksSourceBacked = evidenceLabel ? /uploaded|source|material|paper/i.test(evidenceLabel) : false; | |
| const saysNoSource = trustNote ? /no source attached|not source-grounded|generic/i.test(trustNote) : false; | |
| const shouldUseGeneralLabel = sourceIds.length === 0 && citations.length === 0 && (saysNoSource || looksSourceBacked); | |
| return { | |
| trustNote, | |
| evidenceLabel: shouldUseGeneralLabel ? GENERAL_EVIDENCE_LABEL : evidenceLabel, | |
| isFallback: Boolean(response.is_fallback), | |
| suggestedActions: response.suggested_actions ?? [], | |
| }; | |
| } | |
| export async function runStudyGeneration({ | |
| intent, | |
| prompt, | |
| topic, | |
| sourceIds: rawSourceIds, | |
| selectedDocuments, | |
| brainContext, | |
| generalMode = false, | |
| }: RunStudyGenerationInput): Promise<StudyCard> { | |
| const sourceIds = generalMode ? [] : rawSourceIds; | |
| const generationTopic = topic?.trim() || prompt; | |
| if (sourceIds.length === 0 && shouldUseStructuredStudyResponse(prompt, intent)) { | |
| const data = buildStructuredStudyResponse(prompt); | |
| return { | |
| kind: "structured_study_response", | |
| data, | |
| topic: data.topic || generationTopic, | |
| meta: { | |
| trustNote: "Frontend fallback. Backend structured chapter contract is still a TODO.", | |
| evidenceLabel: "No source attached - Study Chat fallback", | |
| isFallback: true, | |
| }, | |
| }; | |
| } | |
| if (intent === "analyze_pyq" || intent === "predict_questions") { | |
| const response = await generateBrainPyqAnalysis( | |
| generationPayload(generationTopic, sourceIds, brainContext, { | |
| subject: selectedDocuments[0]?.subject ?? brainContext?.subject ?? null, | |
| options: { raw_text: prompt }, | |
| }), | |
| ); | |
| return { | |
| kind: "pyq_analysis", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "generate_notes" || intent === "show_formulas") { | |
| const response = await generateBrainNotes( | |
| generationPayload(generationTopic, sourceIds, brainContext, { | |
| options: { mode: intent === "show_formulas" ? "formulas" : "smart_notes" }, | |
| }), | |
| ); | |
| return { | |
| kind: "notes", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "generate_quiz") { | |
| const response = await generateBrainQuiz( | |
| generationPayload(generationTopic, sourceIds, brainContext, { | |
| options: { num_questions: 8 }, | |
| }), | |
| ); | |
| return { | |
| kind: "quiz", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "generate_flashcards") { | |
| const response = await generateBrainFlashcards( | |
| generationPayload(generationTopic, sourceIds, brainContext, { | |
| options: { card_count: 10 }, | |
| }), | |
| ); | |
| return { | |
| kind: "flashcards", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "generate_exam_answer") { | |
| const response = await generateBrainExamAnswer( | |
| generationPayload(generationTopic, sourceIds, brainContext), | |
| ); | |
| return { | |
| kind: "exam_answer", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "create_revision_plan") { | |
| const response = await generateBrainLastNightPlan( | |
| generationPayload(generationTopic, sourceIds, brainContext, { | |
| time_left: revisionTimeLeftForPrompt(prompt), | |
| }), | |
| ); | |
| return { | |
| kind: "revision_plan", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "continue_learning") { | |
| const response = await generateStudyPath({ | |
| raw_text: prompt, | |
| source_id: sourceIds[0] ?? null, | |
| source_ids: sourceIds, | |
| subject: brainContext?.subject ?? selectedDocuments[0]?.subject ?? null, | |
| topic: generationTopic, | |
| goal: "School exam tuition path", | |
| time_left: "next exam", | |
| use_my_profile: true, | |
| level: brainContext?.level ?? null, | |
| language_preference: brainContext?.languagePreference ?? null, | |
| }); | |
| return { | |
| kind: "study_path", | |
| data: response, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "create_video_plan" || intent === "render_video") { | |
| const response = await generateBrainVisualLesson( | |
| generationPayload(generationTopic, sourceIds, brainContext, { | |
| options: { raw_text: prompt, mode: "visual_lesson" }, | |
| }), | |
| ); | |
| return { | |
| kind: "visual_lesson", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| if (intent === "teach_topic" || intent === "ask_doubt" || intent === "explain_source" || intent === "summarize_source" || intent === "use_syllabus_chapter") { | |
| const response = await generateBrainDeepChapter( | |
| generationPayload(generationTopic, sourceIds, brainContext, { | |
| options: { raw_text: prompt }, | |
| }), | |
| ); | |
| return { | |
| kind: "deep_chapter", | |
| data: response.output, | |
| topic: response.topic || generationTopic, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |
| const response = await askDocDoe({ | |
| question: prompt, | |
| source_id: sourceIds[0] ?? null, | |
| source_ids: sourceIds, | |
| mode: askModeForIntent(intent, prompt), | |
| level: brainContext?.level ?? null, | |
| language_preference: brainContext?.languagePreference ?? null, | |
| study_profile_id: brainContext?.studyProfileId ?? null, | |
| }); | |
| return { | |
| kind: "explanation", | |
| data: response, | |
| topic: generationTopic, | |
| intent, | |
| meta: metaFromResponse(response, sourceIds), | |
| }; | |
| } | |