Download src/lib/teaching/physicsSourcePacks.ts from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 9.48 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/lib/teaching/physicsSourcePacks.ts
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/lib/teaching/physicsSourcePacks.ts
-
curl -L -o physicsSourcePacks.ts https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/lib/teaching/physicsSourcePacks.ts
9.48 kB
| import { | |
| getChapters, | |
| getDefinitions, | |
| getFormulas, | |
| getNumericalPatterns, | |
| getQuestions, | |
| getVisualLessonFrames, | |
| type ChapterSummary, | |
| } from "@/lib/knowledge-base/sslc-physics"; | |
| import type { LessonSeedSourceRef } from "./physicsLessonSeeds"; | |
| import { getMagneticEffectEvidencePack } from "./source-overrides/magneticEffectEvidence"; | |
| export type PhysicsChapterSourcePack = { | |
| subject: "Physics"; | |
| chapterId: string; | |
| chapterTitle: string; | |
| sourceBook: string; | |
| pageRange?: string; | |
| sourceRefs: LessonSeedSourceRef[]; | |
| extractedSignals: { | |
| formulas: string[]; | |
| definitions: string[]; | |
| possibleQuestions: string[]; | |
| keyTerms: string[]; | |
| diagrams: string[]; | |
| numericalPatterns: string[]; | |
| }; | |
| coverageConfidence: "high" | "medium" | "low"; | |
| warnings: string[]; | |
| /** True when the extracted signals were repaired from a manual source-evidence override (Phase 6I). */ | |
| sourceRepaired?: boolean; | |
| }; | |
| /** | |
| * Manual source-evidence overrides (Phase 6I). These do NOT create lesson seeds | |
| * and do NOT make a chapter teachable — they only repair thin auto-extraction so | |
| * the source pack reflects the real (source-referenced) chapter scope. | |
| */ | |
| type SourceEvidenceOverride = { | |
| definitions: string[]; | |
| keyTerms: string[]; | |
| diagrams: string[]; | |
| possibleQuestions: string[]; | |
| }; | |
| function magneticEffectOverride(): SourceEvidenceOverride { | |
| const pack = getMagneticEffectEvidencePack(); | |
| return { | |
| definitions: pack.definitions.map((d) => `${d.term}: ${d.definition}`), | |
| keyTerms: pack.keyTerms, | |
| diagrams: pack.diagrams.map((d) => `${d.title}: ${d.visualDescription}`), | |
| possibleQuestions: pack.questions.map((q) => q.question), | |
| }; | |
| } | |
| function evidenceOverrideFor(chapterId: string): SourceEvidenceOverride | null { | |
| if (chapterId === "phy-p1-c4") return magneticEffectOverride(); | |
| return null; | |
| } | |
| const SOURCE_BOOK = "Kerala SCERT Physics, Standard X (2025)"; | |
| const MAX_SIGNAL_LENGTH = 180; | |
| const MAX_SIGNALS_PER_KIND = 20; | |
| function asRecord(value: unknown): Record<string, unknown> { | |
| return value && typeof value === "object" ? (value as Record<string, unknown>) : {}; | |
| } | |
| function readString(value: unknown): string { | |
| return typeof value === "string" ? value.trim() : ""; | |
| } | |
| function getChapterTitle(chapter: ChapterSummary): string { | |
| const maybeTitle = chapter as ChapterSummary & { title?: string }; | |
| return chapter.chapter_title?.trim() || maybeTitle.title?.trim() || chapter.chapter_id; | |
| } | |
| function compactText(value: string): string { | |
| return value.replace(/\s+/g, " ").trim().slice(0, MAX_SIGNAL_LENGTH); | |
| } | |
| function unique(values: string[]): string[] { | |
| return Array.from(new Set(values.map(compactText).filter(Boolean))).slice(0, MAX_SIGNALS_PER_KIND); | |
| } | |
| function firstText(record: Record<string, unknown>, keys: string[]): string { | |
| for (const key of keys) { | |
| const value = readString(record[key]); | |
| if (value) return value; | |
| } | |
| return ""; | |
| } | |
| function sourcePageRange(chapter: ChapterSummary): string | undefined { | |
| const printedStart = Number(chapter.printed_start_page); | |
| const printedEnd = Number(chapter.printed_end_page); | |
| if (Number.isFinite(printedStart) && printedStart > 0) { | |
| return Number.isFinite(printedEnd) && printedEnd >= printedStart | |
| ? `${printedStart}-${printedEnd}` | |
| : String(printedStart); | |
| } | |
| const pdfStart = Number(chapter.pdf_start_page); | |
| const pdfEnd = Number(chapter.pdf_end_page); | |
| if (Number.isFinite(pdfStart) && pdfStart > 0) { | |
| return Number.isFinite(pdfEnd) && pdfEnd >= pdfStart ? `${pdfStart}-${pdfEnd}` : String(pdfStart); | |
| } | |
| return undefined; | |
| } | |
| function buildSourceRef(chapter: ChapterSummary): LessonSeedSourceRef { | |
| const pageRange = sourcePageRange(chapter); | |
| const chapterTitle = getChapterTitle(chapter); | |
| return { | |
| label: pageRange | |
| ? `Kerala SSLC Physics - ${chapterTitle} (pp. ${pageRange})` | |
| : `Kerala SSLC Physics - ${chapterTitle}`, | |
| sourceBook: SOURCE_BOOK, | |
| chapterTitle, | |
| pageRange, | |
| url: null, | |
| confidence: chapter.needs_review ? "needs_review" : "source_backed", | |
| }; | |
| } | |
| function formulaSignals(chapterId: string): string[] { | |
| return unique( | |
| (getFormulas(chapterId) ?? []).map((item) => { | |
| const record = asRecord(item); | |
| const formula = firstText(record, ["formula", "formula_used", "equation", "expression"]); | |
| const name = firstText(record, ["name", "title", "formula_name", "pattern_name"]); | |
| return formula && name ? `${name}: ${formula}` : formula || name; | |
| }), | |
| ); | |
| } | |
| function definitionSignals(chapterId: string): string[] { | |
| return unique( | |
| getDefinitions(chapterId).map((item) => { | |
| const term = item.term?.trim() ?? ""; | |
| const definition = item.definition?.trim() ?? ""; | |
| return definition ? `${term}: ${definition}` : term; | |
| }), | |
| ); | |
| } | |
| function questionSignals(chapterId: string): string[] { | |
| return unique(getQuestions(chapterId).map((item) => item.question)); | |
| } | |
| function termSignals(chapterId: string): string[] { | |
| const fromDefinitions = getDefinitions(chapterId).map((item) => item.term); | |
| const fromQuestions = getQuestions(chapterId).flatMap((item) => item.keywords ?? []); | |
| const fromFormulas = (getFormulas(chapterId) ?? []).map((item) => firstText(asRecord(item), ["name", "title"])); | |
| return unique([...fromDefinitions, ...fromQuestions, ...fromFormulas]); | |
| } | |
| function numericalSignals(chapterId: string): string[] { | |
| return unique( | |
| (getNumericalPatterns(chapterId) ?? []).map((item) => { | |
| const record = asRecord(item); | |
| const pattern = firstText(record, ["pattern_name", "title", "name"]); | |
| const formula = firstText(record, ["formula_used", "formula", "equation"]); | |
| return pattern && formula ? `${pattern}: ${formula}` : pattern || formula; | |
| }), | |
| ); | |
| } | |
| function diagramSignals(chapterId: string): string[] { | |
| return unique( | |
| (getVisualLessonFrames(chapterId) ?? []).flatMap((item) => { | |
| const record = asRecord(item); | |
| const title = firstText(record, ["title", "frame_title", "name"]); | |
| const idea = firstText(record, ["diagramDescription", "description", "teacherAction", "visual_idea"]); | |
| return [title, idea]; | |
| }), | |
| ); | |
| } | |
| function buildWarnings(signals: PhysicsChapterSourcePack["extractedSignals"], sourceRefs: LessonSeedSourceRef[]): string[] { | |
| const warnings: string[] = []; | |
| if (sourceRefs.length === 0) warnings.push("Missing chapter source reference."); | |
| if (signals.definitions.length === 0) warnings.push("No extracted definitions; concept missions need human curation."); | |
| if (signals.formulas.length === 0) warnings.push("No extracted formulas; formula/numerical missions need review."); | |
| if (signals.possibleQuestions.length < 10) warnings.push("Thin possible-question coverage."); | |
| if (signals.diagrams.length === 0) warnings.push("No extracted visual-board/diagram signal."); | |
| if (signals.numericalPatterns.length === 0) warnings.push("No extracted numerical pattern."); | |
| return warnings; | |
| } | |
| function confidenceFor(signals: PhysicsChapterSourcePack["extractedSignals"], sourceRefs: LessonSeedSourceRef[]): "high" | "medium" | "low" { | |
| if (sourceRefs.length === 0) return "low"; | |
| if (signals.definitions.length === 0 && signals.formulas.length === 0) return "low"; | |
| const signalScore = [ | |
| signals.definitions.length > 0, | |
| signals.formulas.length > 0, | |
| signals.possibleQuestions.length >= 10, | |
| signals.diagrams.length > 0, | |
| signals.numericalPatterns.length > 0, | |
| ].filter(Boolean).length; | |
| if (signalScore >= 4) return "high"; | |
| if (signalScore >= 2) return "medium"; | |
| return "low"; | |
| } | |
| function buildPack(chapter: ChapterSummary): PhysicsChapterSourcePack { | |
| const sourceRefs = [buildSourceRef(chapter)]; | |
| const extractedSignals: PhysicsChapterSourcePack["extractedSignals"] = { | |
| formulas: formulaSignals(chapter.chapter_id), | |
| definitions: definitionSignals(chapter.chapter_id), | |
| possibleQuestions: questionSignals(chapter.chapter_id), | |
| keyTerms: termSignals(chapter.chapter_id), | |
| diagrams: diagramSignals(chapter.chapter_id), | |
| numericalPatterns: numericalSignals(chapter.chapter_id), | |
| }; | |
| const override = evidenceOverrideFor(chapter.chapter_id); | |
| if (override) { | |
| extractedSignals.definitions = unique([...extractedSignals.definitions, ...override.definitions]); | |
| extractedSignals.keyTerms = unique([...extractedSignals.keyTerms, ...override.keyTerms]); | |
| extractedSignals.diagrams = unique([...extractedSignals.diagrams, ...override.diagrams]); | |
| extractedSignals.possibleQuestions = unique([...extractedSignals.possibleQuestions, ...override.possibleQuestions]); | |
| } | |
| const warnings = buildWarnings(extractedSignals, sourceRefs); | |
| if (override) { | |
| warnings.push( | |
| "Source manually repaired from the extracted textbook question bank and figure references (Phase 6I evidence override).", | |
| ); | |
| } | |
| return { | |
| subject: "Physics", | |
| chapterId: chapter.chapter_id, | |
| chapterTitle: getChapterTitle(chapter), | |
| sourceBook: SOURCE_BOOK, | |
| pageRange: sourceRefs[0]?.pageRange, | |
| sourceRefs, | |
| extractedSignals, | |
| coverageConfidence: confidenceFor(extractedSignals, sourceRefs), | |
| warnings, | |
| sourceRepaired: Boolean(override), | |
| }; | |
| } | |
| export function getPhysicsSourcePacks(): PhysicsChapterSourcePack[] { | |
| return getChapters().map(buildPack); | |
| } | |
| export function getPhysicsSourcePack(chapterId: string): PhysicsChapterSourcePack | null { | |
| return getPhysicsSourcePacks().find((pack) => pack.chapterId === chapterId) ?? null; | |
| } | |