@thanh01.pmt/curriculum-kit 1.4.34 → 1.4.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/ai/index.cjs +57 -1
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +2 -2
- package/dist/ai/index.d.ts +2 -2
- package/dist/ai/index.mjs +57 -1
- package/dist/ai/index.mjs.map +1 -1
- package/dist/{gateSettings-DabOqP6_.d.cts → gateSettings-oo5tCUS_.d.cts} +18 -0
- package/dist/{gateSettings-DabOqP6_.d.ts → gateSettings-oo5tCUS_.d.ts} +18 -0
- package/dist/index.cjs +764 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +234 -74
- package/dist/index.d.ts +234 -74
- package/dist/index.mjs +748 -71
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +57 -1
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +57 -1
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/schemas/index.cjs +63 -1
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +436 -33
- package/dist/schemas/index.d.ts +436 -33
- package/dist/schemas/index.mjs +58 -2
- package/dist/schemas/index.mjs.map +1 -1
- package/dist/standards/index.d.cts +2 -2
- package/dist/standards/index.d.ts +2 -2
- package/dist/workflow/index.cjs +84 -2
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.d.cts +3 -3
- package/dist/workflow/index.d.ts +3 -3
- package/dist/workflow/index.mjs +84 -2
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +22 -23
- package/dist/{standardsCoverageGate-DR5YTtlt.d.cts → standardsCoverageGate-49pJq5t8.d.cts} +6 -6
- package/dist/{standardsCoverageGate-DR5YTtlt.d.ts → standardsCoverageGate-49pJq5t8.d.ts} +6 -6
package/dist/index.mjs
CHANGED
|
@@ -3562,6 +3562,50 @@ var ScaffoldDecisionEntrySchema = z.object({
|
|
|
3562
3562
|
minutes_saved: z.number().int().nonnegative().default(0),
|
|
3563
3563
|
reason: z.string().min(3)
|
|
3564
3564
|
});
|
|
3565
|
+
var ZpdVerdictSchema = z.enum(["OK", "TOO_MANY_NEW", "NO_ZPD_BRIDGE"]);
|
|
3566
|
+
var SessionZpdStatusSchema = z.object({
|
|
3567
|
+
verdict: ZpdVerdictSchema,
|
|
3568
|
+
new_concept_count: z.number().int().nonnegative().default(0),
|
|
3569
|
+
known_concept_count: z.number().int().nonnegative().default(0),
|
|
3570
|
+
issues: z.array(z.string()).default([])
|
|
3571
|
+
});
|
|
3572
|
+
var ConceptSpiralEncounterSchema = z.object({
|
|
3573
|
+
concept_code: z.string(),
|
|
3574
|
+
session_id: LessonCodeSchema,
|
|
3575
|
+
encounter_index: z.number().int().positive(),
|
|
3576
|
+
bloom_cap: BloomLevelSchema,
|
|
3577
|
+
depth: DepthLevelSchema
|
|
3578
|
+
});
|
|
3579
|
+
var WalkingSkeletonSchema = z.object({
|
|
3580
|
+
epitome_unit_id: z.string().default("U01"),
|
|
3581
|
+
epitome_deliverables: z.array(z.string()).default([]),
|
|
3582
|
+
elaborations: z.array(z.object({
|
|
3583
|
+
unit_id: z.string(),
|
|
3584
|
+
focus_area: z.string(),
|
|
3585
|
+
elaborates_on: z.array(z.string()).default([])
|
|
3586
|
+
})).default([])
|
|
3587
|
+
});
|
|
3588
|
+
var MasteryGateSchema = z.object({
|
|
3589
|
+
phase_or_unit_id: z.string(),
|
|
3590
|
+
gate_name: z.string(),
|
|
3591
|
+
exit_criteria: z.array(z.string()).min(1),
|
|
3592
|
+
next_unit_id: z.string(),
|
|
3593
|
+
remediation: z.object({
|
|
3594
|
+
trigger: z.literal("FAIL_GATE_CRITERIA"),
|
|
3595
|
+
focus_minutes: z.number().int().default(15),
|
|
3596
|
+
action: z.string()
|
|
3597
|
+
})
|
|
3598
|
+
});
|
|
3599
|
+
var ConceptPrerequisiteEdgeSchema = z.object({
|
|
3600
|
+
concept_code: z.string(),
|
|
3601
|
+
requires: z.string(),
|
|
3602
|
+
source: z.enum(["MASTER_TREE", "INFERRED", "CONCEPT_LEVEL_PREREQ"]).default("CONCEPT_LEVEL_PREREQ"),
|
|
3603
|
+
confidence: z.number().min(0).max(1).default(0.8),
|
|
3604
|
+
rationale: z.string().default(""),
|
|
3605
|
+
structure_supported: z.boolean().default(true),
|
|
3606
|
+
needs_review: z.boolean().default(false),
|
|
3607
|
+
hub: z.boolean().default(false)
|
|
3608
|
+
});
|
|
3565
3609
|
var SessionPlanSchema = z.object({
|
|
3566
3610
|
id: LessonCodeSchema,
|
|
3567
3611
|
unit_id: z.string().regex(/^U\d{2}$/),
|
|
@@ -3582,7 +3626,14 @@ var SessionPlanSchema = z.object({
|
|
|
3582
3626
|
scaffold_decisions: z.array(ScaffoldDecisionEntrySchema).default([]),
|
|
3583
3627
|
// What the student can demonstrate after this session — feeds exit tickets.
|
|
3584
3628
|
exit_evidence: z.array(z.string()).min(1),
|
|
3585
|
-
differentiation: z.object({ bronze: z.string(), silver: z.string(), gold: z.string() })
|
|
3629
|
+
differentiation: z.object({ bronze: z.string(), silver: z.string(), gold: z.string() }),
|
|
3630
|
+
// P50: ZPD cognitive load status for this session
|
|
3631
|
+
zpd_status: SessionZpdStatusSchema.default({
|
|
3632
|
+
verdict: "OK",
|
|
3633
|
+
new_concept_count: 0,
|
|
3634
|
+
known_concept_count: 0,
|
|
3635
|
+
issues: []
|
|
3636
|
+
})
|
|
3586
3637
|
});
|
|
3587
3638
|
var TranslationPolicySchema = z.object({
|
|
3588
3639
|
policy: z.enum(["after_artifact", "end_of_unit", "at_publish", "native"]).default("native"),
|
|
@@ -3637,6 +3688,11 @@ var CurriculumPlanSchema = z.object({
|
|
|
3637
3688
|
// [2]
|
|
3638
3689
|
sessions: z.array(SessionPlanSchema).min(1),
|
|
3639
3690
|
// [3][4][5][6]
|
|
3691
|
+
// P50: Macro-pedagogical course structures
|
|
3692
|
+
walking_skeleton: WalkingSkeletonSchema.optional(),
|
|
3693
|
+
mastery_gates: z.array(MasteryGateSchema).default([]),
|
|
3694
|
+
concept_spiral_progression: z.array(ConceptSpiralEncounterSchema).default([]),
|
|
3695
|
+
concept_prerequisites: z.array(ConceptPrerequisiteEdgeSchema).default([]),
|
|
3640
3696
|
glossary_scope: z.array(z.object({
|
|
3641
3697
|
session_id: LessonCodeSchema,
|
|
3642
3698
|
terms: z.array(z.string())
|
|
@@ -11267,7 +11323,8 @@ function parseAllSessions(plan, frameworkMarkdown) {
|
|
|
11267
11323
|
prose_objective: s.prose_objective || s.objective || "",
|
|
11268
11324
|
new_keywords: Array.isArray(s.new_keywords) ? s.new_keywords : Array.isArray(s.keywords) ? s.keywords : [],
|
|
11269
11325
|
prerequisite_keywords: Array.isArray(s.prerequisite_keywords) ? s.prerequisite_keywords : [],
|
|
11270
|
-
depth_assignments: Array.isArray(s.depth_assignments) ? s.depth_assignments : []
|
|
11326
|
+
depth_assignments: Array.isArray(s.depth_assignments) ? s.depth_assignments : [],
|
|
11327
|
+
zpd_status: s.zpd_status
|
|
11271
11328
|
}));
|
|
11272
11329
|
}
|
|
11273
11330
|
}
|
|
@@ -11415,12 +11472,16 @@ async function extractCurriculumHorizon(opts) {
|
|
|
11415
11472
|
title: s.title,
|
|
11416
11473
|
keywords: s.new_keywords || []
|
|
11417
11474
|
}));
|
|
11475
|
+
const rawSpirals = Array.isArray(plan?.concept_spiral_progression) ? plan.concept_spiral_progression : [];
|
|
11476
|
+
const sessionSpirals = rawSpirals.filter((e) => e.session_id === targetLessonId);
|
|
11418
11477
|
return {
|
|
11419
11478
|
targetLessonId,
|
|
11420
11479
|
targetLessonIndex: targetIndex + 1,
|
|
11421
11480
|
totalLessons: sessions.length,
|
|
11422
11481
|
targetTitle: currentSession.title,
|
|
11423
11482
|
targetKeywords: currentSession.new_keywords || [],
|
|
11483
|
+
zpdStatus: currentSession.zpd_status,
|
|
11484
|
+
spiralProgression: sessionSpirals,
|
|
11424
11485
|
compactMasterySet: {
|
|
11425
11486
|
masteredKeywords,
|
|
11426
11487
|
masteredConcepts
|
|
@@ -11436,6 +11497,8 @@ function renderHorizonPromptBlock(horizon) {
|
|
|
11436
11497
|
totalLessons,
|
|
11437
11498
|
targetTitle,
|
|
11438
11499
|
targetKeywords,
|
|
11500
|
+
zpdStatus,
|
|
11501
|
+
spiralProgression,
|
|
11439
11502
|
compactMasterySet,
|
|
11440
11503
|
detailedBridge,
|
|
11441
11504
|
boundaryPeek
|
|
@@ -11443,6 +11506,19 @@ function renderHorizonPromptBlock(horizon) {
|
|
|
11443
11506
|
const lines = [
|
|
11444
11507
|
`# \u{1F9ED} CURRICULUM HORIZON & SCAFFOLDING MATRIX (Lesson ${targetLessonIndex}/${totalLessons}: "${targetTitle}" [${targetLessonId}])`
|
|
11445
11508
|
];
|
|
11509
|
+
if (zpdStatus && zpdStatus.verdict !== "OK") {
|
|
11510
|
+
lines.push(
|
|
11511
|
+
`
|
|
11512
|
+
> \u26A0\uFE0F **ZPD COGNITIVE LOAD ALERT (${zpdStatus.verdict}):** ${zpdStatus.issues?.join("; ") || "Scaffolding bridge mandated"}. Introduce minimal new syntax and anchor into known concepts.`
|
|
11513
|
+
);
|
|
11514
|
+
}
|
|
11515
|
+
if (spiralProgression && spiralProgression.length > 0) {
|
|
11516
|
+
const spiralNotes = spiralProgression.map(
|
|
11517
|
+
(sp) => `\`${sp.concept_code}\` (Encounter #${sp.encounter_index}): Bloom Cap [${sp.bloom_cap}], Depth [${sp.depth.toUpperCase()}]`
|
|
11518
|
+
);
|
|
11519
|
+
lines.push(`
|
|
11520
|
+
- **\u{1F300} Bruner Spiral Curricula Guidance:** ${spiralNotes.join(" | ")}`);
|
|
11521
|
+
}
|
|
11446
11522
|
if (compactMasterySet.masteredKeywords.length > 0 || compactMasterySet.masteredConcepts.length > 0) {
|
|
11447
11523
|
const rawKeywords = compactMasterySet.masteredKeywords;
|
|
11448
11524
|
const displayedKeywords = rawKeywords.length > 20 ? rawKeywords.slice(-20) : rawKeywords;
|
|
@@ -11613,9 +11689,9 @@ function buildSectionAwareExcerpt(markdown, opts = {}) {
|
|
|
11613
11689
|
if (s.canonicalKey && !byCanonical.has(s.canonicalKey)) {
|
|
11614
11690
|
byCanonical.set(s.canonicalKey, s);
|
|
11615
11691
|
}
|
|
11616
|
-
const
|
|
11617
|
-
if (!byCleanTitle.has(
|
|
11618
|
-
byCleanTitle.set(
|
|
11692
|
+
const norm2 = normalizeHeading(s.cleanTitle);
|
|
11693
|
+
if (!byCleanTitle.has(norm2)) {
|
|
11694
|
+
byCleanTitle.set(norm2, s);
|
|
11619
11695
|
}
|
|
11620
11696
|
if (!s.canonicalKey) {
|
|
11621
11697
|
unmatched.push(s);
|
|
@@ -11753,8 +11829,8 @@ function parseMarkdownSections(markdown, slcMap, artifactType) {
|
|
|
11753
11829
|
const flush = () => {
|
|
11754
11830
|
if (!currentHeading) return;
|
|
11755
11831
|
const cleanTitle = currentHeading.replace(/^#{1,4}\s+/, "").trim();
|
|
11756
|
-
const
|
|
11757
|
-
const canonicalKey = reverseMap.get(
|
|
11832
|
+
const norm2 = normalizeHeading(cleanTitle);
|
|
11833
|
+
const canonicalKey = reverseMap.get(norm2) || findCanonicalFuzzy(norm2);
|
|
11758
11834
|
sections.push({
|
|
11759
11835
|
rawHeading: currentHeading,
|
|
11760
11836
|
cleanTitle,
|
|
@@ -11780,49 +11856,55 @@ function parseMarkdownSections(markdown, slcMap, artifactType) {
|
|
|
11780
11856
|
function normalizeHeading(str) {
|
|
11781
11857
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
11782
11858
|
}
|
|
11783
|
-
function findCanonicalFuzzy(
|
|
11784
|
-
if (
|
|
11859
|
+
function findCanonicalFuzzy(norm2) {
|
|
11860
|
+
if (norm2.includes("toolchain") || norm2.includes("moi truong phat trien") || norm2.includes("cong cu") || norm2.includes("version") || norm2.includes("phan mem") || norm2.includes("development environment") || norm2.includes("technical overview") || norm2.includes("kien truc")) {
|
|
11785
11861
|
return "Technical Overview & Architecture Blueprint";
|
|
11786
11862
|
}
|
|
11787
|
-
if (
|
|
11863
|
+
if (norm2.includes("pinout") || norm2.includes("phan cung") || norm2.includes("hardware") || norm2.includes("wiring") || norm2.includes("ket noi")) {
|
|
11788
11864
|
return "Hardware Pinout & Wiring Configuration Matrix";
|
|
11789
11865
|
}
|
|
11790
|
-
if (
|
|
11866
|
+
if (norm2.includes("pedagog") || norm2.includes("phuong phap") || norm2.includes("day hoc") || norm2.includes("su pham")) {
|
|
11791
11867
|
return "Core Pedagogical Concept Anchor & Real-World Domain Bridge";
|
|
11792
11868
|
}
|
|
11793
|
-
if (
|
|
11869
|
+
if (norm2.includes("standard") || norm2.includes("tieu chuan") || norm2.includes("csta") || norm2.includes("cs2023") || norm2.includes("chuan academic")) {
|
|
11794
11870
|
return "Standards Alignment";
|
|
11795
11871
|
}
|
|
11796
|
-
if (
|
|
11872
|
+
if (norm2.includes("roadmap") || norm2.includes("lo trinh") || norm2.includes("milestone") || norm2.includes("giai doan")) {
|
|
11797
11873
|
return void 0;
|
|
11798
11874
|
}
|
|
11799
|
-
if (
|
|
11875
|
+
if (norm2.includes("symbol") || norm2.includes("identifier ledger") || norm2.includes("dinh danh")) {
|
|
11800
11876
|
return "Symbol & Identifier Ledger";
|
|
11801
11877
|
}
|
|
11802
|
-
if (
|
|
11878
|
+
if (norm2.includes("artifact contract") || norm2.includes("hop dong hoc lieu")) {
|
|
11803
11879
|
return "Artifact Contract";
|
|
11804
11880
|
}
|
|
11805
|
-
if (
|
|
11881
|
+
if (norm2.includes("lesson design plan") || norm2.includes("ke hoach thiet ke")) {
|
|
11806
11882
|
return "A. Lesson Design Plan";
|
|
11807
11883
|
}
|
|
11808
|
-
if (
|
|
11884
|
+
if (norm2.includes("lesson flow") || norm2.includes("tien trinh giang day")) {
|
|
11809
11885
|
return "B. Lesson Flow";
|
|
11810
11886
|
}
|
|
11811
|
-
if (
|
|
11887
|
+
if (norm2.includes("learning objective") || norm2.includes("muc tieu bai hoc")) {
|
|
11812
11888
|
return "Learning Objectives & Evidence";
|
|
11813
11889
|
}
|
|
11814
|
-
if (
|
|
11890
|
+
if (norm2.includes("activity sequence") || norm2.includes("chuoi hoat dong")) {
|
|
11815
11891
|
return "Activity Sequence";
|
|
11816
11892
|
}
|
|
11817
|
-
if (
|
|
11893
|
+
if (norm2.includes("key term") || norm2.includes("thuat ngu")) {
|
|
11818
11894
|
return "Key Terms";
|
|
11819
11895
|
}
|
|
11820
|
-
if (
|
|
11896
|
+
if (norm2.includes("concept narrative") || norm2.includes("dien giai khai niem")) {
|
|
11821
11897
|
return "Concept Narratives";
|
|
11822
11898
|
}
|
|
11823
|
-
if (
|
|
11899
|
+
if (norm2.includes("worked example") || norm2.includes("vi du")) {
|
|
11824
11900
|
return "Worked Micro-Examples";
|
|
11825
11901
|
}
|
|
11902
|
+
if (norm2.includes("common mistake") || norm2.includes("loi thuong gap") || norm2.includes("sai lam") || norm2.includes("pitfall")) {
|
|
11903
|
+
return "Common Mistakes";
|
|
11904
|
+
}
|
|
11905
|
+
if (norm2.includes("self check") || norm2.includes("self-check") || norm2.includes("tu kiem tra")) {
|
|
11906
|
+
return "Self-Check Questions";
|
|
11907
|
+
}
|
|
11826
11908
|
return void 0;
|
|
11827
11909
|
}
|
|
11828
11910
|
function truncateByBudget(source, budget) {
|
|
@@ -12757,7 +12839,7 @@ function decideScaffolds(session, nodeById, warnings) {
|
|
|
12757
12839
|
return decisions;
|
|
12758
12840
|
}
|
|
12759
12841
|
var DEPTH_NEXT = { ulo: "cio", cio: "sio", sio: "sio" };
|
|
12760
|
-
function assignDepths(nodeIds, nodeById) {
|
|
12842
|
+
function assignDepths(nodeIds, nodeById, conceptEncounterMap) {
|
|
12761
12843
|
const assignments = [];
|
|
12762
12844
|
let lastDepth = null;
|
|
12763
12845
|
for (const id of nodeIds) {
|
|
@@ -12765,8 +12847,14 @@ function assignDepths(nodeIds, nodeById) {
|
|
|
12765
12847
|
let depth;
|
|
12766
12848
|
let source;
|
|
12767
12849
|
if (node.kind === "concept") {
|
|
12850
|
+
const primaryCode = node.concept_codes[0];
|
|
12851
|
+
const encounters = primaryCode && conceptEncounterMap ? conceptEncounterMap.get(primaryCode) ?? 1 : 1;
|
|
12768
12852
|
const advanced = node.phase_id !== "" && /__ADV\d{2}$/.test(node.id);
|
|
12769
|
-
|
|
12853
|
+
if (encounters >= 2 || advanced) {
|
|
12854
|
+
depth = "sio";
|
|
12855
|
+
} else {
|
|
12856
|
+
depth = "cio";
|
|
12857
|
+
}
|
|
12770
12858
|
source = "planner";
|
|
12771
12859
|
} else {
|
|
12772
12860
|
depth = node.depth_hint ?? "cio";
|
|
@@ -12781,6 +12869,201 @@ function assignDepths(nodeIds, nodeById) {
|
|
|
12781
12869
|
}
|
|
12782
12870
|
return assignments;
|
|
12783
12871
|
}
|
|
12872
|
+
function computeConceptSpiralProgression(sessions, nodeById) {
|
|
12873
|
+
const encounters = [];
|
|
12874
|
+
const conceptCounts = /* @__PURE__ */ new Map();
|
|
12875
|
+
for (const s of sessions) {
|
|
12876
|
+
const sessionConcepts = [...new Set(s.node_ids.flatMap((id) => nodeById.get(id)?.concept_codes || []))];
|
|
12877
|
+
for (const cCode of sessionConcepts) {
|
|
12878
|
+
const count = (conceptCounts.get(cCode) || 0) + 1;
|
|
12879
|
+
conceptCounts.set(cCode, count);
|
|
12880
|
+
let bloomCap;
|
|
12881
|
+
let depth;
|
|
12882
|
+
if (count === 1) {
|
|
12883
|
+
bloomCap = "Understand";
|
|
12884
|
+
depth = "cio";
|
|
12885
|
+
} else if (count === 2) {
|
|
12886
|
+
bloomCap = "Apply";
|
|
12887
|
+
depth = "sio";
|
|
12888
|
+
} else {
|
|
12889
|
+
bloomCap = "Analyze";
|
|
12890
|
+
depth = "sio";
|
|
12891
|
+
}
|
|
12892
|
+
encounters.push({
|
|
12893
|
+
concept_code: cCode,
|
|
12894
|
+
session_id: s.id,
|
|
12895
|
+
encounter_index: count,
|
|
12896
|
+
bloom_cap: bloomCap,
|
|
12897
|
+
depth
|
|
12898
|
+
});
|
|
12899
|
+
}
|
|
12900
|
+
}
|
|
12901
|
+
return encounters;
|
|
12902
|
+
}
|
|
12903
|
+
function checkSessionZpd(sessionIndex, nodeIds, nodeById, allSeenConcepts, allSeenKeywords, entryKw, warnings) {
|
|
12904
|
+
const concepts = [...new Set(nodeIds.flatMap((id) => nodeById.get(id)?.concept_codes || []))];
|
|
12905
|
+
const newConcepts = concepts.filter((c) => !allSeenConcepts.has(c));
|
|
12906
|
+
const knownConcepts = concepts.filter((c) => allSeenConcepts.has(c));
|
|
12907
|
+
const allKeywords = [...new Set(nodeIds.flatMap((id) => nodeById.get(id)?.keywords || []))];
|
|
12908
|
+
const newKeywords = allKeywords.filter((k) => !allSeenKeywords.has(k.toLowerCase()) && !entryKw.has(k.toLowerCase()));
|
|
12909
|
+
const knownKeywords = allKeywords.filter((k) => allSeenKeywords.has(k.toLowerCase()) || entryKw.has(k.toLowerCase()));
|
|
12910
|
+
const issues = [];
|
|
12911
|
+
let verdict = "OK";
|
|
12912
|
+
if (concepts.length > 0 && newConcepts.length > 2) {
|
|
12913
|
+
verdict = "TOO_MANY_NEW";
|
|
12914
|
+
issues.push(`${newConcepts.length} new concepts exceed ZPD limit (max 2)`);
|
|
12915
|
+
} else if (concepts.length === 0 && newKeywords.length > 4) {
|
|
12916
|
+
verdict = "TOO_MANY_NEW";
|
|
12917
|
+
issues.push(`${newKeywords.length} new keywords exceed ZPD limit (max 4)`);
|
|
12918
|
+
}
|
|
12919
|
+
if (sessionIndex > 0) {
|
|
12920
|
+
if (concepts.length > 1 && knownConcepts.length === 0) {
|
|
12921
|
+
verdict = "NO_ZPD_BRIDGE";
|
|
12922
|
+
issues.push("No known concepts from previous sessions to bridge new learning");
|
|
12923
|
+
} else if (concepts.length === 0 && allKeywords.length > 2 && knownKeywords.length === 0) {
|
|
12924
|
+
verdict = "NO_ZPD_BRIDGE";
|
|
12925
|
+
issues.push("No known keywords from previous sessions to bridge new learning");
|
|
12926
|
+
}
|
|
12927
|
+
}
|
|
12928
|
+
let bridgeRepair;
|
|
12929
|
+
if (verdict === "NO_ZPD_BRIDGE" && (allSeenConcepts.size > 0 || allSeenKeywords.size > 0)) {
|
|
12930
|
+
const bridgeAnchor = [...allSeenConcepts].pop() || [...allSeenKeywords].pop() || "prior knowledge";
|
|
12931
|
+
bridgeRepair = {
|
|
12932
|
+
node_id: nodeIds[0],
|
|
12933
|
+
decision: "recap_in_lesson",
|
|
12934
|
+
reason: `ZPD self-healing: recap anchor (${bridgeAnchor}) to bridge into new material`
|
|
12935
|
+
};
|
|
12936
|
+
warnings.push(`ZPD bridge self-healing: session ${sessionIndex + 1} injected recap anchor (${bridgeAnchor})`);
|
|
12937
|
+
}
|
|
12938
|
+
for (const c of concepts) allSeenConcepts.add(c);
|
|
12939
|
+
for (const k of allKeywords) allSeenKeywords.add(k.toLowerCase());
|
|
12940
|
+
return {
|
|
12941
|
+
status: {
|
|
12942
|
+
verdict,
|
|
12943
|
+
new_concept_count: concepts.length > 0 ? newConcepts.length : newKeywords.length,
|
|
12944
|
+
known_concept_count: concepts.length > 0 ? knownConcepts.length : knownKeywords.length,
|
|
12945
|
+
issues
|
|
12946
|
+
},
|
|
12947
|
+
bridgeRepair
|
|
12948
|
+
};
|
|
12949
|
+
}
|
|
12950
|
+
function buildWalkingSkeleton(units, sessions) {
|
|
12951
|
+
const epitomeUnit = units[0];
|
|
12952
|
+
const epitomeId = epitomeUnit?.id || "U01";
|
|
12953
|
+
const epitomeDeliverables = sessions.filter((s) => s.unit_id === epitomeId).flatMap((s) => s.exit_evidence || []).slice(0, 8);
|
|
12954
|
+
const elaborations = units.slice(1).map((u) => ({
|
|
12955
|
+
unit_id: u.id,
|
|
12956
|
+
focus_area: u.name,
|
|
12957
|
+
elaborates_on: epitomeDeliverables.slice(0, 3)
|
|
12958
|
+
}));
|
|
12959
|
+
return {
|
|
12960
|
+
epitome_unit_id: epitomeId,
|
|
12961
|
+
epitome_deliverables: epitomeDeliverables,
|
|
12962
|
+
elaborations
|
|
12963
|
+
};
|
|
12964
|
+
}
|
|
12965
|
+
function buildMasteryGates(units, sessions) {
|
|
12966
|
+
const gates = [];
|
|
12967
|
+
for (let i = 0; i < units.length - 1; i++) {
|
|
12968
|
+
const cur = units[i];
|
|
12969
|
+
const next = units[i + 1];
|
|
12970
|
+
const unitEvidence = sessions.filter((s) => s.unit_id === cur.id).flatMap((s) => s.exit_evidence || []).slice(0, 6);
|
|
12971
|
+
gates.push({
|
|
12972
|
+
phase_or_unit_id: cur.id,
|
|
12973
|
+
gate_name: `${cur.name} Mastery Gate`,
|
|
12974
|
+
exit_criteria: unitEvidence.length > 0 ? unitEvidence : [`Master all deliverables for ${cur.name}`],
|
|
12975
|
+
next_unit_id: next.id,
|
|
12976
|
+
remediation: {
|
|
12977
|
+
trigger: "FAIL_GATE_CRITERIA",
|
|
12978
|
+
focus_minutes: 15,
|
|
12979
|
+
action: `Review and complete failing practical criteria for ${cur.name} before starting ${next.name}`
|
|
12980
|
+
}
|
|
12981
|
+
});
|
|
12982
|
+
}
|
|
12983
|
+
return gates;
|
|
12984
|
+
}
|
|
12985
|
+
function dropCyclicConceptEdges(edges) {
|
|
12986
|
+
const pairSet = new Set(edges.map((e) => `${e.concept_code}|${e.requires}`));
|
|
12987
|
+
const nonSymmetric = edges.filter((e) => !pairSet.has(`${e.requires}|${e.concept_code}`));
|
|
12988
|
+
const deps = /* @__PURE__ */ new Map();
|
|
12989
|
+
const createsCycle = (a, b) => {
|
|
12990
|
+
const stack = [b];
|
|
12991
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12992
|
+
while (stack.length > 0) {
|
|
12993
|
+
const n = stack.pop();
|
|
12994
|
+
if (n === a) return true;
|
|
12995
|
+
if (seen.has(n)) continue;
|
|
12996
|
+
seen.add(n);
|
|
12997
|
+
const targets = deps.get(n);
|
|
12998
|
+
if (targets) {
|
|
12999
|
+
for (const t of targets) stack.push(t);
|
|
13000
|
+
}
|
|
13001
|
+
}
|
|
13002
|
+
return false;
|
|
13003
|
+
};
|
|
13004
|
+
const out = [];
|
|
13005
|
+
for (const e of nonSymmetric) {
|
|
13006
|
+
if (createsCycle(e.concept_code, e.requires)) continue;
|
|
13007
|
+
if (!deps.has(e.concept_code)) deps.set(e.concept_code, /* @__PURE__ */ new Set());
|
|
13008
|
+
deps.get(e.concept_code).add(e.requires);
|
|
13009
|
+
out.push(e);
|
|
13010
|
+
}
|
|
13011
|
+
return out;
|
|
13012
|
+
}
|
|
13013
|
+
function buildConceptPrerequisites(sessions, nodeById, edges) {
|
|
13014
|
+
const firstSeen = /* @__PURE__ */ new Map();
|
|
13015
|
+
for (let i = 0; i < sessions.length; i++) {
|
|
13016
|
+
const s = sessions[i];
|
|
13017
|
+
for (const nid of s.node_ids) {
|
|
13018
|
+
const codes = nodeById.get(nid)?.concept_codes || [];
|
|
13019
|
+
for (const c of codes) {
|
|
13020
|
+
if (!firstSeen.has(c)) firstSeen.set(c, i);
|
|
13021
|
+
}
|
|
13022
|
+
}
|
|
13023
|
+
}
|
|
13024
|
+
const rawEdges = [];
|
|
13025
|
+
const seenPair = /* @__PURE__ */ new Set();
|
|
13026
|
+
for (const e of edges) {
|
|
13027
|
+
const fromNode = nodeById.get(e.from);
|
|
13028
|
+
const toNode = nodeById.get(e.to);
|
|
13029
|
+
if (!fromNode || !toNode) continue;
|
|
13030
|
+
const fromCodes = fromNode.concept_codes || [];
|
|
13031
|
+
const toCodes = toNode.concept_codes || [];
|
|
13032
|
+
for (const tc of toCodes) {
|
|
13033
|
+
for (const fc of fromCodes) {
|
|
13034
|
+
if (tc === fc) continue;
|
|
13035
|
+
const key = `${tc}|${fc}`;
|
|
13036
|
+
if (seenPair.has(key)) continue;
|
|
13037
|
+
seenPair.add(key);
|
|
13038
|
+
const firstSeenTc = firstSeen.get(tc) ?? 999;
|
|
13039
|
+
const firstSeenFc = firstSeen.get(fc) ?? 999;
|
|
13040
|
+
const supported = firstSeenFc <= firstSeenTc;
|
|
13041
|
+
rawEdges.push({
|
|
13042
|
+
concept_code: tc,
|
|
13043
|
+
requires: fc,
|
|
13044
|
+
source: "CONCEPT_LEVEL_PREREQ",
|
|
13045
|
+
confidence: supported ? 0.8 : 0.6,
|
|
13046
|
+
rationale: e.reason || `Derived from planning node dependency: ${fromNode.name} -> ${toNode.name}`,
|
|
13047
|
+
structure_supported: supported,
|
|
13048
|
+
needs_review: !supported,
|
|
13049
|
+
hub: false
|
|
13050
|
+
});
|
|
13051
|
+
}
|
|
13052
|
+
}
|
|
13053
|
+
}
|
|
13054
|
+
const fanOut = /* @__PURE__ */ new Map();
|
|
13055
|
+
for (const re of rawEdges) {
|
|
13056
|
+
fanOut.set(re.concept_code, (fanOut.get(re.concept_code) || 0) + 1);
|
|
13057
|
+
}
|
|
13058
|
+
for (const re of rawEdges) {
|
|
13059
|
+
if ((fanOut.get(re.concept_code) || 0) >= 6) {
|
|
13060
|
+
re.hub = true;
|
|
13061
|
+
re.confidence = Math.min(re.confidence, 0.5);
|
|
13062
|
+
re.needs_review = true;
|
|
13063
|
+
}
|
|
13064
|
+
}
|
|
13065
|
+
return dropCyclicConceptEdges(rawEdges);
|
|
13066
|
+
}
|
|
12784
13067
|
async function buildCurriculumPlan(rawGraph, options) {
|
|
12785
13068
|
const { constraints } = options;
|
|
12786
13069
|
const warnings = [];
|
|
@@ -12876,6 +13159,9 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12876
13159
|
const seenNodes = /* @__PURE__ */ new Set();
|
|
12877
13160
|
const multiPartNodes = new Set(packed.flatMap((s) => s.entries.filter((e) => e.totalParts > 1).map((e) => e.id)));
|
|
12878
13161
|
const sessions = [];
|
|
13162
|
+
const allSeenConcepts = /* @__PURE__ */ new Set();
|
|
13163
|
+
const allSeenKeywords = /* @__PURE__ */ new Set();
|
|
13164
|
+
const conceptEncounterMap = /* @__PURE__ */ new Map();
|
|
12879
13165
|
for (let i = 0; i < packed.length; i++) {
|
|
12880
13166
|
const s = packed[i];
|
|
12881
13167
|
for (const id of s.nodeIds) {
|
|
@@ -12920,6 +13206,16 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12920
13206
|
knowledge: s.knowledgeMinutes || 0,
|
|
12921
13207
|
practice: s.practiceMinutes + (s.practiceMinutes === 0 && s.knowledgeMinutes > 0 ? Math.min(spareMinutes, 10) : 0)
|
|
12922
13208
|
};
|
|
13209
|
+
const sessionConcepts = [...new Set(s.nodeIds.flatMap((id) => nodeById.get(id)?.concept_codes || []))];
|
|
13210
|
+
for (const cCode of sessionConcepts) {
|
|
13211
|
+
const curCount = (conceptEncounterMap.get(cCode) || 0) + 1;
|
|
13212
|
+
conceptEncounterMap.set(cCode, curCount);
|
|
13213
|
+
}
|
|
13214
|
+
const zpdResult = checkSessionZpd(i, s.nodeIds, nodeById, allSeenConcepts, allSeenKeywords, entryKw, warnings);
|
|
13215
|
+
const prereqDecisions = decidePrerequisites(ctx, nodeById, graph.edges, sessionIndexByNode, sessionOrderByIndex, constraints);
|
|
13216
|
+
if (zpdResult.bridgeRepair) {
|
|
13217
|
+
prereqDecisions.unshift(zpdResult.bridgeRepair);
|
|
13218
|
+
}
|
|
12923
13219
|
sessions.push({
|
|
12924
13220
|
id: lessonCode,
|
|
12925
13221
|
unit_id: unit.id,
|
|
@@ -12940,8 +13236,8 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12940
13236
|
// Spiral pedagogy = apply at greater depth, not re-lecture.
|
|
12941
13237
|
practice_minutes: sessionMinutes.practice,
|
|
12942
13238
|
overhead_minutes: spec.overheadMinutes,
|
|
12943
|
-
depth_assignments: assignDepths(s.nodeIds, nodeById),
|
|
12944
|
-
prerequisite_decisions:
|
|
13239
|
+
depth_assignments: assignDepths(s.nodeIds, nodeById, conceptEncounterMap),
|
|
13240
|
+
prerequisite_decisions: prereqDecisions,
|
|
12945
13241
|
scaffold_decisions: decideScaffolds(ctx, nodeById, warnings),
|
|
12946
13242
|
// Deliverable phrasing follows the node role: concept → evidence is the
|
|
12947
13243
|
// explanation, product_step/skill → the artifact or activity itself.
|
|
@@ -12956,16 +13252,58 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12956
13252
|
bronze: "Complete the core deliverable for " + nodeNames[0] + " with provided scaffolding.",
|
|
12957
13253
|
silver: "Complete all session deliverables independently.",
|
|
12958
13254
|
gold: "Extend the deliverable: combine " + nodeNames.join(", ") + " in a self-chosen variant."
|
|
12959
|
-
}
|
|
13255
|
+
},
|
|
13256
|
+
// P50: ZPD cognitive load status for this session
|
|
13257
|
+
zpd_status: zpdResult.status
|
|
12960
13258
|
});
|
|
12961
13259
|
}
|
|
12962
13260
|
const unassigned = graph.nodes.map((n) => n.id).filter((id) => !seenNodes.has(id));
|
|
12963
13261
|
if (unassigned.length > 0) throw new Error("Coverage violation: unassigned nodes " + unassigned.join(", "));
|
|
13262
|
+
if (options.llmFn && sessions.length > 0) {
|
|
13263
|
+
try {
|
|
13264
|
+
const sessionSummaries = sessions.map((s) => `${s.id}|${s.title}|objective: ${s.prose_objective.slice(0, 120)}|keywords: ${s.new_keywords.join("/")}`).join("\n");
|
|
13265
|
+
const dSys = 'You differentiate learning tasks. Output ONLY a JSON object mapping session-id to {"bronze":string,"silver":string,"gold":string}. Each tier ONE sentence: bronze = foundational task with provided scaffolding; silver = independent application; gold = creative extension combining session concepts. Same language as the objectives.';
|
|
13266
|
+
const dUsr = `Age band: ${constraints.age_band[0]}-${constraints.age_band[1]}. Entry level: ${constraints.entry_level}.
|
|
13267
|
+
Sessions:
|
|
13268
|
+
${sessionSummaries}`;
|
|
13269
|
+
const raw = (await options.llmFn(dSys, dUsr)).trim();
|
|
13270
|
+
const match = raw.match(/\{[\s\S]*\}/);
|
|
13271
|
+
if (match) {
|
|
13272
|
+
const parsed = JSON.parse(match[0]);
|
|
13273
|
+
let upgraded = 0;
|
|
13274
|
+
for (const s of sessions) {
|
|
13275
|
+
const d = parsed[s.id];
|
|
13276
|
+
if (d && typeof d.bronze === "string" && d.bronze.length >= 10 && typeof d.silver === "string" && d.silver.length >= 10 && typeof d.gold === "string" && d.gold.length >= 10) {
|
|
13277
|
+
s.differentiation = { bronze: d.bronze, silver: d.silver, gold: d.gold };
|
|
13278
|
+
upgraded++;
|
|
13279
|
+
}
|
|
13280
|
+
}
|
|
13281
|
+
if (upgraded < sessions.length) warnings.push(`differentiation_llm_partial:${upgraded}/${sessions.length}`);
|
|
13282
|
+
} else {
|
|
13283
|
+
warnings.push("differentiation_llm_unparseable");
|
|
13284
|
+
}
|
|
13285
|
+
} catch (e) {
|
|
13286
|
+
warnings.push("differentiation_llm_failed:" + (e instanceof Error ? e.message.slice(0, 80) : String(e).slice(0, 80)));
|
|
13287
|
+
}
|
|
13288
|
+
}
|
|
12964
13289
|
const glossaryScope = sessions.map((s) => ({
|
|
12965
13290
|
session_id: s.id,
|
|
12966
13291
|
terms: [...new Set(s.node_ids.flatMap((id) => nodeById.get(id).keywords))]
|
|
12967
13292
|
}));
|
|
12968
|
-
const
|
|
13293
|
+
const conceptSpiralProgression = computeConceptSpiralProgression(sessions, nodeById);
|
|
13294
|
+
const walkingSkeleton = buildWalkingSkeleton(units, sessions);
|
|
13295
|
+
const masteryGates = buildMasteryGates(units, sessions);
|
|
13296
|
+
const conceptPrerequisites = buildConceptPrerequisites(sessions, nodeById, graph.edges);
|
|
13297
|
+
const planPayload = {
|
|
13298
|
+
units,
|
|
13299
|
+
sessions,
|
|
13300
|
+
course: { objectives: courseObjectives },
|
|
13301
|
+
constraints,
|
|
13302
|
+
walking_skeleton: walkingSkeleton,
|
|
13303
|
+
mastery_gates: masteryGates,
|
|
13304
|
+
concept_spiral_progression: conceptSpiralProgression,
|
|
13305
|
+
concept_prerequisites: conceptPrerequisites
|
|
13306
|
+
};
|
|
12969
13307
|
const planHash = createHash("sha256").update(JSON.stringify(planPayload)).digest("hex").slice(0, 16);
|
|
12970
13308
|
const plan = CurriculumPlanSchema.parse({
|
|
12971
13309
|
schema_version: 1,
|
|
@@ -12977,6 +13315,10 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
12977
13315
|
course: { objectives: courseObjectives, capstone_ref: constraints.capstone },
|
|
12978
13316
|
units,
|
|
12979
13317
|
sessions,
|
|
13318
|
+
walking_skeleton: walkingSkeleton,
|
|
13319
|
+
mastery_gates: masteryGates,
|
|
13320
|
+
concept_spiral_progression: conceptSpiralProgression,
|
|
13321
|
+
concept_prerequisites: conceptPrerequisites,
|
|
12980
13322
|
glossary_scope: glossaryScope,
|
|
12981
13323
|
translation: options.translation ?? { policy: "at_publish", target_language: null },
|
|
12982
13324
|
coverage_report: { assigned_node_ids: [...seenNodes], unassigned_node_ids: [], warnings },
|
|
@@ -13008,6 +13350,13 @@ function buildSessionSliceContext(plan, lessonCode) {
|
|
|
13008
13350
|
lines.push("- Prerequisite keywords: " + (s.prerequisite_keywords.join(", ") || "(none)"));
|
|
13009
13351
|
lines.push("- Time split: knowledge " + s.knowledge_minutes + "m / practice " + s.practice_minutes + "m / overhead " + s.overhead_minutes + "m");
|
|
13010
13352
|
lines.push("- Depth assignments: " + s.depth_assignments.map((d) => d.node_id + "=" + d.depth.toUpperCase() + "(" + d.source + ")").join("; "));
|
|
13353
|
+
if (s.zpd_status && s.zpd_status.verdict !== "OK") {
|
|
13354
|
+
lines.push("- ZPD alert: " + s.zpd_status.verdict + " (" + s.zpd_status.issues.join("; ") + ")");
|
|
13355
|
+
}
|
|
13356
|
+
const sessionSpirals = (plan.concept_spiral_progression || []).filter((e) => e.session_id === lessonCode);
|
|
13357
|
+
if (sessionSpirals.length > 0) {
|
|
13358
|
+
lines.push("- Spiral encounters: " + sessionSpirals.map((e) => `${e.concept_code}#${e.encounter_index}=${e.bloom_cap}(${e.depth.toUpperCase()})`).join("; "));
|
|
13359
|
+
}
|
|
13011
13360
|
if (s.prerequisite_decisions.length > 0) {
|
|
13012
13361
|
lines.push("- Prerequisite decisions [" + s.prerequisite_decisions.length + "]:");
|
|
13013
13362
|
for (const d of s.prerequisite_decisions) lines.push(" * " + d.node_id + ": " + d.decision + " \u2014 " + d.reason);
|
|
@@ -13329,14 +13678,14 @@ function lintFrameworkPack(pack) {
|
|
|
13329
13678
|
const primaryLang = pack.manifest.languages[0];
|
|
13330
13679
|
const text = s.texts[primaryLang];
|
|
13331
13680
|
if (!text) continue;
|
|
13332
|
-
const
|
|
13333
|
-
if (!
|
|
13334
|
-
const prev = seen.get(
|
|
13681
|
+
const norm2 = text.toLowerCase().replace(/[^\p{L}\p{N}\s]/gu, " ").split(/\s+/).filter((w) => w.length > 2).sort().join(" ");
|
|
13682
|
+
if (!norm2) continue;
|
|
13683
|
+
const prev = seen.get(norm2);
|
|
13335
13684
|
if (prev !== void 0) {
|
|
13336
13685
|
issues.push({ severity: "WARNING", code: "DUP_TEXT_EXACT", message: `Text is token-identical to statement "${prev}"`, ref: s.id });
|
|
13337
13686
|
} else {
|
|
13338
13687
|
for (const [otherNorm, otherId] of seen.entries()) {
|
|
13339
|
-
const a = new Set(
|
|
13688
|
+
const a = new Set(norm2.split(" "));
|
|
13340
13689
|
const b = new Set(otherNorm.split(" "));
|
|
13341
13690
|
let inter = 0;
|
|
13342
13691
|
for (const w of a) if (b.has(w)) inter++;
|
|
@@ -13346,7 +13695,7 @@ function lintFrameworkPack(pack) {
|
|
|
13346
13695
|
break;
|
|
13347
13696
|
}
|
|
13348
13697
|
}
|
|
13349
|
-
seen.set(
|
|
13698
|
+
seen.set(norm2, s.id);
|
|
13350
13699
|
}
|
|
13351
13700
|
}
|
|
13352
13701
|
for (const m of pack.mappings ?? []) {
|
|
@@ -26087,6 +26436,229 @@ function extractStandardRefs(text) {
|
|
|
26087
26436
|
return Array.from(new Set(matches));
|
|
26088
26437
|
}
|
|
26089
26438
|
|
|
26439
|
+
// src/services/contextSlots.ts
|
|
26440
|
+
var LESSON_SLOT_BUDGETS = {
|
|
26441
|
+
ACT: { budget: 8e3 },
|
|
26442
|
+
GUIDE: { budget: 6e3 },
|
|
26443
|
+
QUIZ: { budget: 3500, priorities: ["A. Lesson Design Plan"] },
|
|
26444
|
+
SLIDE: { budget: 4500, priorities: ["B. Lesson Flow", "A. Lesson Design Plan"] },
|
|
26445
|
+
WKS: { budget: 4500, priorities: ["A. Lesson Design Plan", "B. Lesson Flow"] },
|
|
26446
|
+
EXIT_TICKET: { budget: 3e3, priorities: ["A. Lesson Design Plan", "B. Lesson Flow"] }
|
|
26447
|
+
};
|
|
26448
|
+
var KX_ONLY_TYPES = /* @__PURE__ */ new Set(["CODE", "HANDOUT", "EXT"]);
|
|
26449
|
+
var KX_SLOT_PRIORITIES = {
|
|
26450
|
+
QUIZ: ["Common Mistakes", "Self-Check Questions", "Key Terms", "Concept Narratives"],
|
|
26451
|
+
EXIT_TICKET: ["Self-Check Questions", "Key Terms"],
|
|
26452
|
+
WKS: ["Self-Check Questions", "Worked Micro-Examples", "Key Terms"],
|
|
26453
|
+
CODE: ["Worked Micro-Examples", "Key Terms", "Common Mistakes"],
|
|
26454
|
+
GUIDE: ["Common Mistakes", "Key Terms", "Concept Narratives"],
|
|
26455
|
+
HANDOUT: ["Key Terms", "Concept Narratives", "Common Mistakes"],
|
|
26456
|
+
SLIDE: ["Key Terms", "Worked Micro-Examples"],
|
|
26457
|
+
ACT: ["Worked Micro-Examples", "Common Mistakes"],
|
|
26458
|
+
EXT: ["Worked Micro-Examples", "Common Mistakes"]
|
|
26459
|
+
};
|
|
26460
|
+
var norm = (s) => s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "");
|
|
26461
|
+
function extractActivityContractRows(lessonContent, artifactType, maxChars = 1500) {
|
|
26462
|
+
if (!lessonContent) return "";
|
|
26463
|
+
const wanted = norm(artifactType).replace(/_/g, "");
|
|
26464
|
+
const lines = lessonContent.split("\n");
|
|
26465
|
+
let inSeq = false;
|
|
26466
|
+
const headerRows = [];
|
|
26467
|
+
const matchedRows = [];
|
|
26468
|
+
const allRows = [];
|
|
26469
|
+
for (let i = 0; i < lines.length; i++) {
|
|
26470
|
+
const line = lines[i];
|
|
26471
|
+
const h = line.match(/^#{2,4}\s+(.*)$/);
|
|
26472
|
+
if (h) {
|
|
26473
|
+
const t2 = h[1];
|
|
26474
|
+
if (/activity\s*sequence/i.test(t2)) inSeq = true;
|
|
26475
|
+
else if (inSeq) break;
|
|
26476
|
+
continue;
|
|
26477
|
+
}
|
|
26478
|
+
if (!inSeq) continue;
|
|
26479
|
+
const t = line.trim();
|
|
26480
|
+
if (!t.startsWith("|")) continue;
|
|
26481
|
+
if (/^\|\s*[-: |]+\|\s*$/.test(t)) continue;
|
|
26482
|
+
const cells = t.split("|").slice(1, -1).map((c) => c.trim());
|
|
26483
|
+
if (cells.length >= 4) {
|
|
26484
|
+
if (headerRows.length === 0) {
|
|
26485
|
+
headerRows.push(t);
|
|
26486
|
+
continue;
|
|
26487
|
+
}
|
|
26488
|
+
allRows.push(t);
|
|
26489
|
+
const contract = cells[cells.length - 1] ?? "";
|
|
26490
|
+
const candidates = contract.split(/[,;/]/).map((c) => norm(c));
|
|
26491
|
+
if (candidates.some((c) => c === wanted || c.length > 3 && (c.includes(wanted) || wanted.includes(c)))) {
|
|
26492
|
+
matchedRows.push(t);
|
|
26493
|
+
}
|
|
26494
|
+
}
|
|
26495
|
+
}
|
|
26496
|
+
const rows = matchedRows.length > 0 ? matchedRows : allRows.slice(0, 3);
|
|
26497
|
+
if (rows.length === 0) return "";
|
|
26498
|
+
let out = headerRows[0] ?? "";
|
|
26499
|
+
for (const r of rows) {
|
|
26500
|
+
if (out.length + r.length + 1 > maxChars) break;
|
|
26501
|
+
out += "\n" + r;
|
|
26502
|
+
}
|
|
26503
|
+
return out;
|
|
26504
|
+
}
|
|
26505
|
+
function extractTieredScaffoldingBlock(lessonContent, maxChars = 900) {
|
|
26506
|
+
if (!lessonContent) return "";
|
|
26507
|
+
const lines = lessonContent.split("\n");
|
|
26508
|
+
let capture = null;
|
|
26509
|
+
for (const line of lines) {
|
|
26510
|
+
const h = line.match(/^#{2,4}\s+(.*)$/);
|
|
26511
|
+
if (h) {
|
|
26512
|
+
const isTierHeading = /elaborate|tiered|scaffold/i.test(h[1] ?? "");
|
|
26513
|
+
if (capture && !isTierHeading) break;
|
|
26514
|
+
if (isTierHeading) capture = [];
|
|
26515
|
+
continue;
|
|
26516
|
+
}
|
|
26517
|
+
if (capture) {
|
|
26518
|
+
capture.push(line);
|
|
26519
|
+
if (capture.join("").length >= maxChars) break;
|
|
26520
|
+
}
|
|
26521
|
+
}
|
|
26522
|
+
const body = (capture ?? []).join("\n").trim();
|
|
26523
|
+
return body ? body.slice(0, maxChars) : "";
|
|
26524
|
+
}
|
|
26525
|
+
function extractAssessmentMap(lessonContent, maxChars = 1200) {
|
|
26526
|
+
if (!lessonContent) return "";
|
|
26527
|
+
const lines = lessonContent.split("\n");
|
|
26528
|
+
let capture = null;
|
|
26529
|
+
for (const line of lines) {
|
|
26530
|
+
const h = line.match(/^#{2,4}\s+(.*)$/);
|
|
26531
|
+
if (h) {
|
|
26532
|
+
const isTarget = /assessment\s*map/i.test(h[1] ?? "");
|
|
26533
|
+
if (capture && !isTarget) break;
|
|
26534
|
+
if (isTarget) capture = [];
|
|
26535
|
+
continue;
|
|
26536
|
+
}
|
|
26537
|
+
if (capture) {
|
|
26538
|
+
capture.push(line);
|
|
26539
|
+
if (capture.join("").length >= maxChars) break;
|
|
26540
|
+
}
|
|
26541
|
+
}
|
|
26542
|
+
const body = (capture ?? []).join("\n").trim();
|
|
26543
|
+
return body ? body.slice(0, maxChars) : "";
|
|
26544
|
+
}
|
|
26545
|
+
function blockMeta(slot, source, text, verified, issues = []) {
|
|
26546
|
+
return { slot, source, chars: text.length, verified, issues };
|
|
26547
|
+
}
|
|
26548
|
+
function buildSatelliteContext(input) {
|
|
26549
|
+
const {
|
|
26550
|
+
artifactType,
|
|
26551
|
+
commonContext,
|
|
26552
|
+
lessonContent,
|
|
26553
|
+
lessonExcerpt,
|
|
26554
|
+
expositionContent,
|
|
26555
|
+
slcMarkdown,
|
|
26556
|
+
symbolLedgerBlock,
|
|
26557
|
+
pedagogyLabel,
|
|
26558
|
+
mode = "legacy"
|
|
26559
|
+
} = input;
|
|
26560
|
+
const type = (artifactType || "").toUpperCase().trim();
|
|
26561
|
+
if (mode === "legacy" || type === "LESSON") {
|
|
26562
|
+
const context2 = `${commonContext}
|
|
26563
|
+
|
|
26564
|
+
[CANONICAL LESSON PLAN (${pedagogyLabel ?? "LESSON"})]:
|
|
26565
|
+
${lessonExcerpt.excerpt}${symbolLedgerBlock}`;
|
|
26566
|
+
return {
|
|
26567
|
+
context: context2,
|
|
26568
|
+
blocks: [
|
|
26569
|
+
blockMeta("commonContext", "COMPOSITE", commonContext, true),
|
|
26570
|
+
blockMeta("lessonExcerpt", "LESSON", lessonExcerpt.excerpt, lessonExcerpt.verified, lessonExcerpt.issues)
|
|
26571
|
+
],
|
|
26572
|
+
verified: lessonExcerpt.verified,
|
|
26573
|
+
sectionAware: lessonExcerpt.sectionAware,
|
|
26574
|
+
issues: lessonExcerpt.issues,
|
|
26575
|
+
tokenEstimate: Math.round(context2.length / 4)
|
|
26576
|
+
};
|
|
26577
|
+
}
|
|
26578
|
+
const blocks = [];
|
|
26579
|
+
const issues = [];
|
|
26580
|
+
const parts = [commonContext];
|
|
26581
|
+
blocks.push(blockMeta("commonContext", "COMPOSITE", commonContext, true));
|
|
26582
|
+
const compositeHasKx = /###\s+KNOWLEDGE_EXPOSITION/.test(commonContext);
|
|
26583
|
+
if (expositionContent.trim() && !compositeHasKx) {
|
|
26584
|
+
const kxExcerpt = buildSectionAwareExcerpt(expositionContent, {
|
|
26585
|
+
priorities: KX_SLOT_PRIORITIES[type] ?? ["Key Terms", "Concept Narratives", "Worked Micro-Examples"],
|
|
26586
|
+
budget: 4500,
|
|
26587
|
+
sectionLanguageContract: slcMarkdown,
|
|
26588
|
+
artifactType: "KNOWLEDGE_EXPOSITION"
|
|
26589
|
+
});
|
|
26590
|
+
parts.push(`
|
|
26591
|
+
|
|
26592
|
+
[KNOWLEDGE_EXPOSITION (canonical knowledge \u2014 teach from this, do not contradict; scoped for ${type})]:
|
|
26593
|
+
${kxExcerpt.excerpt}`);
|
|
26594
|
+
blocks.push(blockMeta("kxExcerpt:" + type, "KNOWLEDGE_EXPOSITION", kxExcerpt.excerpt, kxExcerpt.verified, kxExcerpt.issues));
|
|
26595
|
+
if (!kxExcerpt.verified) issues.push(...kxExcerpt.issues.map((i) => `kx:${i}`));
|
|
26596
|
+
}
|
|
26597
|
+
if (!KX_ONLY_TYPES.has(type)) {
|
|
26598
|
+
const spec = LESSON_SLOT_BUDGETS[type] ?? { budget: 12e3 };
|
|
26599
|
+
const excerpt = buildSectionAwareExcerpt(lessonContent, {
|
|
26600
|
+
priorities: spec.priorities ?? ["Artifact Contract", "A. Lesson Design Plan", "B. Lesson Flow", "Learning Objectives & Evidence", "Activity Sequence"],
|
|
26601
|
+
budget: spec.budget,
|
|
26602
|
+
sectionLanguageContract: slcMarkdown,
|
|
26603
|
+
artifactType: "LESSON"
|
|
26604
|
+
});
|
|
26605
|
+
parts.push(`
|
|
26606
|
+
|
|
26607
|
+
[CANONICAL LESSON PLAN (scoped for ${type})]:
|
|
26608
|
+
${excerpt.excerpt}`);
|
|
26609
|
+
blocks.push(blockMeta("lessonExcerpt:" + type, "LESSON", excerpt.excerpt, excerpt.verified, excerpt.issues));
|
|
26610
|
+
if (!excerpt.verified) issues.push(...excerpt.issues.map((i) => `lesson:${i}`));
|
|
26611
|
+
if (type === "QUIZ" || type === "WKS") {
|
|
26612
|
+
const am = extractAssessmentMap(lessonContent, 1200);
|
|
26613
|
+
if (am) {
|
|
26614
|
+
parts.push(`
|
|
26615
|
+
|
|
26616
|
+
[ASSESSMENT MAP (criteria anchor \u2014 assess exactly these)]:
|
|
26617
|
+
${am}`);
|
|
26618
|
+
blocks.push(blockMeta("assessmentMap:" + type, "LESSON", am, true));
|
|
26619
|
+
} else {
|
|
26620
|
+
issues.push(`assessment-map:unresolved:${type}`);
|
|
26621
|
+
}
|
|
26622
|
+
}
|
|
26623
|
+
if (symbolLedgerBlock) {
|
|
26624
|
+
parts.push(symbolLedgerBlock);
|
|
26625
|
+
blocks.push(blockMeta("symbolLedger", "LESSON", symbolLedgerBlock, true));
|
|
26626
|
+
}
|
|
26627
|
+
} else {
|
|
26628
|
+
const contractRows = extractActivityContractRows(lessonContent, type === "CODE" ? "CODE_LAB" : type, 1500);
|
|
26629
|
+
const tierBlock = type === "CODE" || type === "EXT" ? extractTieredScaffoldingBlock(lessonContent, 900) : "";
|
|
26630
|
+
const mini = [
|
|
26631
|
+
contractRows ? `### Activity Sequence rows assigned to ${type} (canonical \u2014 do not invent a different task):
|
|
26632
|
+
${contractRows}` : "",
|
|
26633
|
+
tierBlock ? `### Tiered task ladder (from LESSON Elaborate phase):
|
|
26634
|
+
${tierBlock}` : ""
|
|
26635
|
+
].filter(Boolean).join("\n\n");
|
|
26636
|
+
if (mini) {
|
|
26637
|
+
parts.push(`
|
|
26638
|
+
|
|
26639
|
+
[LESSON ACTIVITY CONTRACT (mini-slot)]:
|
|
26640
|
+
${mini}`);
|
|
26641
|
+
blocks.push(blockMeta("activityContract:" + type, "LESSON", mini, true));
|
|
26642
|
+
} else {
|
|
26643
|
+
issues.push(`activity-contract:unresolved:${type}`);
|
|
26644
|
+
blocks.push(blockMeta("activityContract:" + type, "LESSON", "", false, ["no-matching-rows"]));
|
|
26645
|
+
}
|
|
26646
|
+
if (type === "CODE" && symbolLedgerBlock) {
|
|
26647
|
+
parts.push(symbolLedgerBlock);
|
|
26648
|
+
blocks.push(blockMeta("symbolLedger", "LESSON", symbolLedgerBlock, true));
|
|
26649
|
+
}
|
|
26650
|
+
}
|
|
26651
|
+
const context = parts.join("");
|
|
26652
|
+
return {
|
|
26653
|
+
context,
|
|
26654
|
+
blocks,
|
|
26655
|
+
verified: blocks.filter((b) => b.slot !== "commonContext").every((b) => b.verified),
|
|
26656
|
+
sectionAware: blocks.some((b) => b.slot.startsWith("lessonExcerpt") || b.slot.startsWith("kxExcerpt")),
|
|
26657
|
+
issues,
|
|
26658
|
+
tokenEstimate: Math.round(context.length / 4)
|
|
26659
|
+
};
|
|
26660
|
+
}
|
|
26661
|
+
|
|
26090
26662
|
// src/services/lessonProductionService.ts
|
|
26091
26663
|
var __filename2 = typeof import.meta?.url === "string" && typeof fileURLToPath === "function" ? fileURLToPath(import.meta.url) : "";
|
|
26092
26664
|
var _resolvedDir = __filename2 ? path3.dirname(__filename2) : typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
@@ -26659,9 +27231,9 @@ ${renderHorizonPromptBlock(horizon)}`;
|
|
|
26659
27231
|
console.warn(`[produceSingleLesson] Notice: Curriculum Horizon extraction:`, hErr?.message || hErr);
|
|
26660
27232
|
}
|
|
26661
27233
|
let productSpecBlock = "";
|
|
26662
|
-
const buildGroundTruthBlock = () => {
|
|
27234
|
+
const buildGroundTruthBlock = (includeKx = true) => {
|
|
26663
27235
|
const parts = [];
|
|
26664
|
-
if (expositionContext) {
|
|
27236
|
+
if (includeKx && expositionContext) {
|
|
26665
27237
|
parts.push(`### KNOWLEDGE_EXPOSITION (CANONICAL KNOWLEDGE \u2014 teach from this, do not contradict)
|
|
26666
27238
|
${expositionContext}`);
|
|
26667
27239
|
}
|
|
@@ -26695,10 +27267,10 @@ ${sessionSliceContext}` : "";
|
|
|
26695
27267
|
const guardrailBlock = `
|
|
26696
27268
|
|
|
26697
27269
|
${platformGuardrail}`;
|
|
26698
|
-
const assembleCommonContext = (sg) => `${baseContextPrefix}
|
|
27270
|
+
const assembleCommonContext = (sg, includeKx = true) => `${baseContextPrefix}
|
|
26699
27271
|
|
|
26700
27272
|
[CONTENT STYLE GUIDE EXCERPT]:
|
|
26701
|
-
${sg}${standardsBlock}${glossaryBlock}${buildGroundTruthBlock()}${sessionSliceBlock}${horizonBlock}${guardrailBlock}`;
|
|
27273
|
+
${sg}${standardsBlock}${glossaryBlock}${buildGroundTruthBlock(includeKx)}${sessionSliceBlock}${horizonBlock}${guardrailBlock}`;
|
|
26702
27274
|
let commonContext = assembleCommonContext(effectiveStyleGuide);
|
|
26703
27275
|
const MAX_COMPOSITE_PROMPT_CHARS = 3e4;
|
|
26704
27276
|
const runnerOptions = options.customInference ? { customInference: options.customInference } : {};
|
|
@@ -27107,10 +27679,32 @@ ${currentContent}` }],
|
|
|
27107
27679
|
- Entry Source File: \`${symbolLedger.entryFileName || symbolLedger.primarySymbol}\`
|
|
27108
27680
|
- Key Identifiers to inherit verbatim: ${symbolLedger.keySymbols.map((s) => `\`${s}\``).join(", ")}
|
|
27109
27681
|
- INVARIANT: You MUST use these exact identifier names in all code examples, exercises, and test assertions. Do NOT invent new struct/class names!` : "";
|
|
27110
|
-
const
|
|
27111
|
-
|
|
27112
|
-
|
|
27113
|
-
|
|
27682
|
+
const routingMode = options.contextRoutingMode ?? "legacy";
|
|
27683
|
+
const kxFreeCommonContext = routingMode === "hybrid" ? assembleCommonContext(effectiveStyleGuide, false) : "";
|
|
27684
|
+
const satelliteContexts = {};
|
|
27685
|
+
const satelliteContextFor = (artifactType) => {
|
|
27686
|
+
const key = artifactType.toUpperCase();
|
|
27687
|
+
if (!satelliteContexts[key]) {
|
|
27688
|
+
const built = buildSatelliteContext({
|
|
27689
|
+
artifactType: key,
|
|
27690
|
+
commonContext: routingMode === "hybrid" ? kxFreeCommonContext : commonContext,
|
|
27691
|
+
lessonContent,
|
|
27692
|
+
lessonExcerpt: lessonExcerptResult,
|
|
27693
|
+
expositionContent: expositionContext,
|
|
27694
|
+
slcMarkdown,
|
|
27695
|
+
symbolLedgerBlock,
|
|
27696
|
+
pedagogyLabel,
|
|
27697
|
+
mode: routingMode
|
|
27698
|
+
});
|
|
27699
|
+
satelliteContexts[key] = built.context;
|
|
27700
|
+
onProgress?.(
|
|
27701
|
+
"@content",
|
|
27702
|
+
`[CONTEXT] ${key} satellite context: ${built.context.length} chars (${built.blocks.map((b) => `${b.slot}:${b.chars}`).join(", ")})`,
|
|
27703
|
+
{ type: "progress", promptChars: built.context.length, artifactType: key }
|
|
27704
|
+
);
|
|
27705
|
+
}
|
|
27706
|
+
return satelliteContexts[key];
|
|
27707
|
+
};
|
|
27114
27708
|
const judgeSat = (sat, content) => {
|
|
27115
27709
|
if (gateModeFor(gates, sat) !== "LLM_JUDGE") return Promise.resolve();
|
|
27116
27710
|
const det = validateArtifactDeterministic({ content, refPack });
|
|
@@ -27191,7 +27785,7 @@ ${languageDirective}
|
|
|
27191
27785
|
${buildHeadingDirective("ACT", slcMarkdown, targetLang)}`;
|
|
27192
27786
|
const rawAct = await runCurriculumAIInference(
|
|
27193
27787
|
[{ role: "user", content: actPrompt }],
|
|
27194
|
-
|
|
27788
|
+
satelliteContextFor("ACT"),
|
|
27195
27789
|
runnerOptions,
|
|
27196
27790
|
(chunk, type) => {
|
|
27197
27791
|
options.onProgress?.("@activity", chunk, { type: type || "content", artifactType: "ACT" });
|
|
@@ -27261,7 +27855,7 @@ ${languageDirective}
|
|
|
27261
27855
|
${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
27262
27856
|
const rawQuiz = await runCurriculumAIInference(
|
|
27263
27857
|
[{ role: "user", content: quizPrompt }],
|
|
27264
|
-
|
|
27858
|
+
satelliteContextFor("QUIZ"),
|
|
27265
27859
|
runnerOptions,
|
|
27266
27860
|
(chunk, type) => {
|
|
27267
27861
|
options.onProgress?.("@assessor", chunk, { type: type || "content", artifactType: "QUIZ" });
|
|
@@ -27314,7 +27908,7 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
27314
27908
|
headingDirective: buildHeadingDirective("SLIDE", slcMarkdown, targetLang),
|
|
27315
27909
|
groundContext: slideGroundContext,
|
|
27316
27910
|
productSpecBlock: productSpecBlock || void 0,
|
|
27317
|
-
satelliteContext,
|
|
27911
|
+
satelliteContext: satelliteContextFor("SLIDE"),
|
|
27318
27912
|
runnerOptions,
|
|
27319
27913
|
onProgress: (agent, msg, meta) => {
|
|
27320
27914
|
options.onProgress?.(agent, msg, meta || { type: "content", artifactType: "SLIDE" });
|
|
@@ -27398,7 +27992,7 @@ footer: "Curriculum OS \u2022 ${lessonCode} (${pedagogyLabel})"
|
|
|
27398
27992
|
});
|
|
27399
27993
|
const rawSlide = await runCurriculumAIInference(
|
|
27400
27994
|
[{ role: "user", content: slidePrompt }],
|
|
27401
|
-
|
|
27995
|
+
satelliteContextFor("SLIDE"),
|
|
27402
27996
|
runnerOptions,
|
|
27403
27997
|
(chunk, type) => {
|
|
27404
27998
|
options.onProgress?.("@illustrator", chunk, { type: type || "content", artifactType: "SLIDE" });
|
|
@@ -27459,7 +28053,7 @@ ${languageDirective}
|
|
|
27459
28053
|
${buildHeadingDirective("GUIDE", slcMarkdown, targetLang)}`;
|
|
27460
28054
|
const rawGuide = await runCurriculumAIInference(
|
|
27461
28055
|
[{ role: "user", content: guidePrompt }],
|
|
27462
|
-
|
|
28056
|
+
satelliteContextFor("GUIDE"),
|
|
27463
28057
|
runnerOptions,
|
|
27464
28058
|
(chunk, type) => {
|
|
27465
28059
|
options.onProgress?.("@content", chunk, { type: type || "chunk", artifactType: "GUIDE" });
|
|
@@ -27511,7 +28105,7 @@ ${languageDirective}
|
|
|
27511
28105
|
${buildHeadingDirective("HANDOUT", slcMarkdown, targetLang)}`;
|
|
27512
28106
|
const rawHandout = await runCurriculumAIInference(
|
|
27513
28107
|
[{ role: "user", content: handoutPrompt }],
|
|
27514
|
-
|
|
28108
|
+
satelliteContextFor("HANDOUT"),
|
|
27515
28109
|
runnerOptions,
|
|
27516
28110
|
(chunk, type) => {
|
|
27517
28111
|
options.onProgress?.("@content", chunk, { type: type || "chunk", artifactType: "HANDOUT" });
|
|
@@ -27567,7 +28161,7 @@ ${languageDirective}
|
|
|
27567
28161
|
${buildHeadingDirective("WKS", slcMarkdown, targetLang)}`;
|
|
27568
28162
|
const rawWks = await runCurriculumAIInference(
|
|
27569
28163
|
[{ role: "user", content: wksPrompt }],
|
|
27570
|
-
|
|
28164
|
+
satelliteContextFor("WKS"),
|
|
27571
28165
|
runnerOptions,
|
|
27572
28166
|
(chunk, type) => {
|
|
27573
28167
|
options.onProgress?.("@content", chunk, { type: type || "chunk", artifactType: "WKS" });
|
|
@@ -27627,7 +28221,7 @@ ${languageDirective}
|
|
|
27627
28221
|
${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
|
|
27628
28222
|
const rawCode = await runCurriculumAIInference(
|
|
27629
28223
|
[{ role: "user", content: codePrompt }],
|
|
27630
|
-
|
|
28224
|
+
satelliteContextFor("CODE"),
|
|
27631
28225
|
runnerOptions,
|
|
27632
28226
|
(chunk, type) => {
|
|
27633
28227
|
options.onProgress?.("@activity", chunk, { type: type || "chunk", artifactType: "CODE" });
|
|
@@ -27714,7 +28308,7 @@ ${languageDirective}
|
|
|
27714
28308
|
${buildHeadingDirective("EXT", slcMarkdown, targetLang)}`;
|
|
27715
28309
|
const rawExt = await runCurriculumAIInference(
|
|
27716
28310
|
[{ role: "user", content: extPrompt }],
|
|
27717
|
-
|
|
28311
|
+
satelliteContextFor("EXT"),
|
|
27718
28312
|
runnerOptions,
|
|
27719
28313
|
(chunk, type) => {
|
|
27720
28314
|
options.onProgress?.("@activity", chunk, { type: type || "chunk", artifactType: "EXT" });
|
|
@@ -29691,26 +30285,40 @@ Return concise JSON matching:
|
|
|
29691
30285
|
"technicalGotchas": ["Important safety or compatibility note 1", "Note 2"]
|
|
29692
30286
|
}`;
|
|
29693
30287
|
let rawContent = "";
|
|
29694
|
-
|
|
29695
|
-
|
|
29696
|
-
|
|
29697
|
-
|
|
29698
|
-
|
|
29699
|
-
|
|
29700
|
-
|
|
29701
|
-
|
|
29702
|
-
|
|
29703
|
-
|
|
29704
|
-
|
|
29705
|
-
|
|
29706
|
-
|
|
29707
|
-
|
|
29708
|
-
|
|
29709
|
-
|
|
29710
|
-
|
|
29711
|
-
|
|
29712
|
-
|
|
29713
|
-
|
|
30288
|
+
if (options.customInference) {
|
|
30289
|
+
rawContent = await options.customInference({
|
|
30290
|
+
systemInstruction: "You are an authoritative STEM & CS curriculum researcher. Output valid JSON only.",
|
|
30291
|
+
userPrompt: researchPrompt,
|
|
30292
|
+
messages: [{ role: "user", content: researchPrompt }],
|
|
30293
|
+
temperature: 0.2,
|
|
30294
|
+
maxTokens: 32768,
|
|
30295
|
+
onChunk: (token, type) => {
|
|
30296
|
+
if (type === "content") rawContent += token;
|
|
30297
|
+
if (type === "content" || type === "thought") onChunk?.(token, type);
|
|
30298
|
+
}
|
|
30299
|
+
}) || "";
|
|
30300
|
+
} else {
|
|
30301
|
+
await streamLLMWithFallback(
|
|
30302
|
+
"You are an authoritative STEM & CS curriculum researcher. Output valid JSON only.",
|
|
30303
|
+
researchPrompt,
|
|
30304
|
+
apiKeys,
|
|
30305
|
+
(chunk, type) => {
|
|
30306
|
+
if (type === "content") rawContent += chunk;
|
|
30307
|
+
onChunk?.(chunk, type);
|
|
30308
|
+
},
|
|
30309
|
+
options.model,
|
|
30310
|
+
options.provider,
|
|
30311
|
+
// Research may run live web grounding — generous budget, still idle-guarded.
|
|
30312
|
+
resolveStreamBudget(void 0, {
|
|
30313
|
+
idleMs: options.idleTimeoutMs,
|
|
30314
|
+
totalMs: options.timeoutMs,
|
|
30315
|
+
model: options.model,
|
|
30316
|
+
provider: options.provider
|
|
30317
|
+
}),
|
|
30318
|
+
options.signal,
|
|
30319
|
+
options.onProviderEvent
|
|
30320
|
+
);
|
|
30321
|
+
}
|
|
29714
30322
|
let parsedResearch = {
|
|
29715
30323
|
groundTruthSummary: `Verified ecosystem standards for ${projectName}`,
|
|
29716
30324
|
hardwareVersion: "Standard Environment",
|
|
@@ -30800,6 +31408,75 @@ var DeterministicStructuralLinter = class {
|
|
|
30800
31408
|
strengths
|
|
30801
31409
|
};
|
|
30802
31410
|
}
|
|
31411
|
+
/**
|
|
31412
|
+
* P50: Validates macro-pedagogical invariants across a CurriculumPlan.
|
|
31413
|
+
* Checks:
|
|
31414
|
+
* 1. ZPD violations without self-healing recap (NO_ZPD_BRIDGE)
|
|
31415
|
+
* 2. Walking Skeleton existence (Unit 1 delivers working software)
|
|
31416
|
+
* 3. Inter-unit Mastery Gate presence
|
|
31417
|
+
*/
|
|
31418
|
+
static lintPlan(plan) {
|
|
31419
|
+
const findings = [];
|
|
31420
|
+
const strengths = [];
|
|
31421
|
+
let score = 100;
|
|
31422
|
+
for (const s of plan.sessions) {
|
|
31423
|
+
if (s.zpd_status?.verdict === "TOO_MANY_NEW") {
|
|
31424
|
+
score -= 10;
|
|
31425
|
+
findings.push({
|
|
31426
|
+
id: `PLAN_TOO_MANY_NEW_${s.id}`,
|
|
31427
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
31428
|
+
severity: "MINOR",
|
|
31429
|
+
title: `Cognitive Overload in Session ${s.id}`,
|
|
31430
|
+
description: s.zpd_status.issues.join("; ") || `Session introduces too many new concepts/keywords, exceeding ZPD capacity.`,
|
|
31431
|
+
remediationAdvice: `Distribute new concepts across multiple sessions or introduce via scaffolding.`,
|
|
31432
|
+
affectedElement: s.id
|
|
31433
|
+
});
|
|
31434
|
+
} else if (s.zpd_status?.verdict === "NO_ZPD_BRIDGE") {
|
|
31435
|
+
const hasRecap = s.prerequisite_decisions.some((d) => d.decision === "recap_in_lesson");
|
|
31436
|
+
if (!hasRecap) {
|
|
31437
|
+
score -= 15;
|
|
31438
|
+
findings.push({
|
|
31439
|
+
id: `PLAN_NO_ZPD_BRIDGE_${s.id}`,
|
|
31440
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
31441
|
+
severity: "MAJOR",
|
|
31442
|
+
title: `Unhealed ZPD Bridge in Session ${s.id}`,
|
|
31443
|
+
description: `Session introduces new concepts with 0 known concept bridges, and lacks recap scaffolding.`,
|
|
31444
|
+
remediationAdvice: `Add a recap_in_lesson prerequisite decision to anchor new learning in prior concepts.`,
|
|
31445
|
+
affectedElement: s.id
|
|
31446
|
+
});
|
|
31447
|
+
}
|
|
31448
|
+
}
|
|
31449
|
+
}
|
|
31450
|
+
if (!plan.walking_skeleton || plan.walking_skeleton.epitome_deliverables.length === 0) {
|
|
31451
|
+
score -= 10;
|
|
31452
|
+
findings.push({
|
|
31453
|
+
id: "PLAN_MISSING_WALKING_SKELETON",
|
|
31454
|
+
dimension: "CONSTRUCTIVE_ALIGNMENT",
|
|
31455
|
+
severity: "MINOR",
|
|
31456
|
+
title: "Missing Walking Skeleton Definition",
|
|
31457
|
+
description: "Plan does not declare an Epitome (walking skeleton) in Unit 1.",
|
|
31458
|
+
remediationAdvice: "Ensure Unit 1 defines minimal end-to-end deliverables."
|
|
31459
|
+
});
|
|
31460
|
+
} else {
|
|
31461
|
+
strengths.push(`Unit ${plan.walking_skeleton.epitome_unit_id} establishes an end-to-end Walking Skeleton (Epitome).`);
|
|
31462
|
+
}
|
|
31463
|
+
if (plan.units.length > 1 && (!plan.mastery_gates || plan.mastery_gates.length === 0)) {
|
|
31464
|
+
score -= 10;
|
|
31465
|
+
findings.push({
|
|
31466
|
+
id: "PLAN_MISSING_MASTERY_GATES",
|
|
31467
|
+
dimension: "5E_INSTRUCTIONAL_FIDELITY",
|
|
31468
|
+
severity: "MINOR",
|
|
31469
|
+
title: "Missing Inter-Unit Mastery Gates",
|
|
31470
|
+
description: "Multi-unit course lacks formal transition gates between units.",
|
|
31471
|
+
remediationAdvice: "Define exit criteria and remediation sprints for each inter-unit boundary."
|
|
31472
|
+
});
|
|
31473
|
+
} else if (plan.mastery_gates && plan.mastery_gates.length > 0) {
|
|
31474
|
+
strengths.push(`${plan.mastery_gates.length} inter-unit Mastery Gates defined with remediation protocols.`);
|
|
31475
|
+
}
|
|
31476
|
+
score = Math.max(0, Math.min(100, score));
|
|
31477
|
+
const passed = score >= 80 && !findings.some((f) => f.severity === "CRITICAL");
|
|
31478
|
+
return { passed, score, findings, strengths };
|
|
31479
|
+
}
|
|
30803
31480
|
};
|
|
30804
31481
|
|
|
30805
31482
|
// src/evaluators/academicAuditor.ts
|
|
@@ -32434,6 +33111,6 @@ function renderMediaPlaceholder(entry) {
|
|
|
32434
33111
|
return `> \u{1F5BC}\uFE0F [\u1EA2nh \u0111ang ch\u1EDD: ${entry.name} \u2014 s\u1EBD \u0111\u01B0\u1EE3c t\u1EA1o sau khi duy\u1EC7t media]`;
|
|
32435
33112
|
}
|
|
32436
33113
|
|
|
32437
|
-
export { ACT_TEMPLATE, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, AcademicAuditor, ActiveLearningWorkflowSchema, ActivityLabSchema, ActivitySeqRowSchema, ActivityStepSchema, ArtifactContractRowSchema, AssessmentMapRowSchema, AssessmentObjectiveSchema, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BUNDLED_STANDARDS_PACK_IDS, BellRingerDaySchema, BellRingerSchema, BloomHintSchema, BloomLevelSchema, BloomTaxonomyEvaluator, BronzeTierSchema, CERConclusionSchema, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, CardTierEnum, ChoiceBoardRubricRowSchema, ChoiceBoardSchema, ChoiceRuleSchema, ChoiceSquareSchema, ClassificationSchema, CodeHardwareFeasibilityEvaluator, CodeLabSchema, CodeSnippetSchema, CompetencyRubricRowSchema, ComputationalThinkingSchema, ConstructiveAlignmentEvaluator, CoreConceptSchema, CourseObjectiveSchema, CoverageReportSchema, CrossArtifactDriftEvaluator, CurriculumArtifactSchema, CurriculumError, CurriculumPlanSchema, CurriculumQualityReportSchema, DEFAULT_ARTIFACT_STREAM_IDLE_MS, DEFAULT_ARTIFACT_STREAM_TOTAL_MS, DEFAULT_ENABLED_PROVIDERS, DEFAULT_GATE_SETTINGS, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdgeSchema, DepthAssignmentSchema, DepthLevelSchema, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuestionSchema, DiagnosticQuizSchema, EDPPhaseEnum, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, EntryLevelSchema, ExitTicketBugHuntSchema, ExitTicketMetacognitionSchema, ExitTicketQuickItemSchema, ExitTicketRecallPromptSchema, ExitTicketSchema, ExperimentalDesignSchema, ExpositionApprovalError, ExtensionChallengeSchema, ExtensionSchema, FileSystemCurriculumAdapter, FiveEFlowPhaseSchema, FiveEInstructionalEvaluator, FiveEPhaseEnum, FrameworkMappingSchema, FrameworkPackManifestSchema, FrameworkPackSchema, FrameworkStatementSchema, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, GeneratedSlideArraySchema, GeneratedSlideSchema, GlossaryQuickRefRowSchema, GlossarySchema, GlossaryTermSchema, GoldTierSchema, GradeBandSchema, GraphicOrganizerItemSchema, GraphicOrganizerSchema, HANDOUT_TEMPLATE, HandoutSchema, HandoutSectionSchema, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, InstructionSectionSchema, InstructionStepSchema, JudgeCriterionSchema, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, LLMJudgeEngine, LabTierTaskSchema, LearningObjectiveInputSchema, LearningObjectiveRowSchema, LessonFlowPhaseSchema, LessonPlan5ESchema, LessonPlanEDPSchema, LessonPlanSchema, LessonSectionSchema, LocalWorkspaceManager, MappingKindSchema, MarpSlideSchema, MediaError, MediaLedger, MentorCheatsheetSchema, MilestoneInputSchema, MisconceptionEvaluator, MisconceptionSchema, ModelPolicyResolver, NVIDIA_MODELS, NodeKindSchema, OrganizerTypeEnum, PROJECT_INSTRUCTION_TEMPLATE, PhaseInputSchema, PlanConstraintsSchema, PlannerInputSchema, PlanningGraphSchema, PlanningNodeSchema, PrerequisiteDecisionEntrySchema, PrerequisiteDecisionSchema, ProductGoalSchema, ProgressiveHintsSchema, ProjectGraphSchema, ProjectInstructionSchema, ProjectProfileSchema, QUIZ_TEMPLATE, QualityAuditVerdictSchema, QuizOptionSchema, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, RecordProvenanceSchema, ResourceMapRowSchema, ReviewGameExportRowSchema, ReviewGameQuestionSchema, ReviewGameSchema, RoadmapInputSchema, RotationStationSchema, RubricCriteriaSchema, RubricSchema, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_CANONICAL_METHODOLOGY, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STANDARD_REF_REGEX, STANDARD_SOT_FILES, STATION_ROTATION_TEMPLATE, ScaffoldDecisionEntrySchema, ScaffoldDecisionSchema, ScienceLabSchema, ScoringRubricRowSchema, SelfLabSchema, SelfPacedBundleSchema, SelfPacedChallengeSchema, SessionPlanSchema, SilverTierSchema, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeckSchema, StandardizedTermRowSchema, StandardsRegistryAdapter, StationRecordRowSchema, StationRotationSchema, StationTypeEnum, SupabaseCurriculumAdapter, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TaskCardSchema, TaskCardsSchema, TeacherGuideSchema, TeachingScriptPhaseSchema, TierLevelEnum, TierObjectiveSchema, TieredPracticeSchema, TranslationPolicySchema, TroubleshootingEntrySchema, TroubleshootingRowSchema, UnitPlanSchema, UserJourneySchema, WORKSHEET_TEMPLATE, WorksheetItemSchema, WorksheetItemTypeEnum, WorksheetPartSchema, WorksheetSchema, activityTools, analystTools, analyzeProjectCreationIntent, assertAcyclic, assessorTools, atomicWriteFileSync, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildExtensionPrompt, buildHandoutPrompt, buildHeadingDirective, buildHtmlDeckSlidePrompt, buildImagePrompt, buildJudgePrompt, buildLanguageDirective, buildLessonExcerpt, buildLessonMasterPrompt, buildMarpMarkdownSlidePrompt, buildProjectInstructionPrompt, buildSectionAwareExcerpt, buildSelfLabPrompt, buildSessionSliceContext, buildSlidesPrompt, buildStandardStackMarkdown, buildStandardsContext, buildStandardsContextBlock, buildTeacherGuidePrompt, buildWorksheetPrompt, closeTruncatedJson, computeContentHash, computePackingSpec, conductPreliminaryResearch, contentTools, convertRoadmapToFoundationSot, createAiInferenceError, createContextMissingError, createCurriculumStorage, createIdleAbortController, createStreamAbortController, createStreamAbortSignal, createStreamChunkExtractor, curateMediaLedger, designerTools, detectProjectPedagogy, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateStandardsCoverage, executeCurriculumCommand, executeSlideProductionWorkflow, exportAllProjectQuizzes, expositionCacheKey, extractCurriculumHorizon, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStandardRefs, extractStreamChunk, extractSymbolLedger, extractThoughtAndContent, findStandardStatement, formatQuizzesToCsv, fulfillMediaLedger, gateModeFor, generateActivityFlow, generateCodeLabFlow, generateDiagnosticQuizFlow, generateEducationalImage, generateExtensionFlow, generateHandoutFlow, generateLessonMasterFlow, generateMilestoneCurriculumBundle, generatePhase1SotArtifacts, generatePhase2SotArtifacts, generateProjectInstruction, generateProjectInstructionFlow, generateRoadmapCurriculum, generateSelfLabFlow, generateSelfPacedBundle, generateSingleArtifact, generateSlidesFlow, generateTeacherGuideFlow, generateWorksheetFlow, getAIModel, getArtifactMetadata, getDesignatedFallbackChain, getDesignatedFallbackConfig, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, illustratorTools, importRoadmapToProject, ingestProjectGraphIntoProject, initializeProjectInStorage, injectMediaIntoMarkdown, isExpositionFresh, isModelAllowed, isProviderEnabled, isTranslationDue, lintAndSanitizeArtifact, lintCurriculumFramework, lintFrameworkPack, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, packagerTools, parseAllSessions, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToSupabase, rankGenCandidates, renderFrameworkFromPlan, renderHorizonPromptBlock, renderMediaPlaceholder, researcherTools, resolveApiKey, resolveGateSettings, resolveStandardsPacks, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, reviewerTools, runCurriculumAIInference, safeParseJson, searchEducationalImages, searchEducationalVideos, selectStatementsForLesson, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, slugifyProjectName, streamCurriculumAIInference, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLLMWithFallback, streamLayerPrefillWithFallback, streamLessonMasterFlow, streamSelfLabFlow, stripLlmJsonWrappers, targetLanguageDisplayName, techSmeTools, topoSort, uploadAssetToBucket, validateArtifactDependencies, validateCurriculumPlan, validateFrameworkPack, validateHorizonCompliance, validateHybridDeckSlides, validateMarkdownTables, validateMermaidSyntax, withAutoRepair };
|
|
33114
|
+
export { ACT_TEMPLATE, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, AcademicAuditor, ActiveLearningWorkflowSchema, ActivityLabSchema, ActivitySeqRowSchema, ActivityStepSchema, ArtifactContractRowSchema, AssessmentMapRowSchema, AssessmentObjectiveSchema, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BUNDLED_STANDARDS_PACK_IDS, BellRingerDaySchema, BellRingerSchema, BloomHintSchema, BloomLevelSchema, BloomTaxonomyEvaluator, BronzeTierSchema, CERConclusionSchema, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, CardTierEnum, ChoiceBoardRubricRowSchema, ChoiceBoardSchema, ChoiceRuleSchema, ChoiceSquareSchema, ClassificationSchema, CodeHardwareFeasibilityEvaluator, CodeLabSchema, CodeSnippetSchema, CompetencyRubricRowSchema, ComputationalThinkingSchema, ConceptPrerequisiteEdgeSchema, ConceptSpiralEncounterSchema, ConstructiveAlignmentEvaluator, CoreConceptSchema, CourseObjectiveSchema, CoverageReportSchema, CrossArtifactDriftEvaluator, CurriculumArtifactSchema, CurriculumError, CurriculumPlanSchema, CurriculumQualityReportSchema, DEFAULT_ARTIFACT_STREAM_IDLE_MS, DEFAULT_ARTIFACT_STREAM_TOTAL_MS, DEFAULT_ENABLED_PROVIDERS, DEFAULT_GATE_SETTINGS, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdgeSchema, DepthAssignmentSchema, DepthLevelSchema, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuestionSchema, DiagnosticQuizSchema, EDPPhaseEnum, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, EntryLevelSchema, ExitTicketBugHuntSchema, ExitTicketMetacognitionSchema, ExitTicketQuickItemSchema, ExitTicketRecallPromptSchema, ExitTicketSchema, ExperimentalDesignSchema, ExpositionApprovalError, ExtensionChallengeSchema, ExtensionSchema, FileSystemCurriculumAdapter, FiveEFlowPhaseSchema, FiveEInstructionalEvaluator, FiveEPhaseEnum, FrameworkMappingSchema, FrameworkPackManifestSchema, FrameworkPackSchema, FrameworkStatementSchema, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, GeneratedSlideArraySchema, GeneratedSlideSchema, GlossaryQuickRefRowSchema, GlossarySchema, GlossaryTermSchema, GoldTierSchema, GradeBandSchema, GraphicOrganizerItemSchema, GraphicOrganizerSchema, HANDOUT_TEMPLATE, HandoutSchema, HandoutSectionSchema, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, InstructionSectionSchema, InstructionStepSchema, JudgeCriterionSchema, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, LLMJudgeEngine, LabTierTaskSchema, LearningObjectiveInputSchema, LearningObjectiveRowSchema, LessonFlowPhaseSchema, LessonPlan5ESchema, LessonPlanEDPSchema, LessonPlanSchema, LessonSectionSchema, LocalWorkspaceManager, MappingKindSchema, MarpSlideSchema, MasteryGateSchema, MediaError, MediaLedger, MentorCheatsheetSchema, MilestoneInputSchema, MisconceptionEvaluator, MisconceptionSchema, ModelPolicyResolver, NVIDIA_MODELS, NodeKindSchema, OrganizerTypeEnum, PROJECT_INSTRUCTION_TEMPLATE, PhaseInputSchema, PlanConstraintsSchema, PlannerInputSchema, PlanningGraphSchema, PlanningNodeSchema, PrerequisiteDecisionEntrySchema, PrerequisiteDecisionSchema, ProductGoalSchema, ProgressiveHintsSchema, ProjectGraphSchema, ProjectInstructionSchema, ProjectProfileSchema, QUIZ_TEMPLATE, QualityAuditVerdictSchema, QuizOptionSchema, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, RecordProvenanceSchema, ResourceMapRowSchema, ReviewGameExportRowSchema, ReviewGameQuestionSchema, ReviewGameSchema, RoadmapInputSchema, RotationStationSchema, RubricCriteriaSchema, RubricSchema, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_CANONICAL_METHODOLOGY, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STANDARD_REF_REGEX, STANDARD_SOT_FILES, STATION_ROTATION_TEMPLATE, ScaffoldDecisionEntrySchema, ScaffoldDecisionSchema, ScienceLabSchema, ScoringRubricRowSchema, SelfLabSchema, SelfPacedBundleSchema, SelfPacedChallengeSchema, SessionPlanSchema, SessionZpdStatusSchema, SilverTierSchema, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeckSchema, StandardizedTermRowSchema, StandardsRegistryAdapter, StationRecordRowSchema, StationRotationSchema, StationTypeEnum, SupabaseCurriculumAdapter, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TaskCardSchema, TaskCardsSchema, TeacherGuideSchema, TeachingScriptPhaseSchema, TierLevelEnum, TierObjectiveSchema, TieredPracticeSchema, TranslationPolicySchema, TroubleshootingEntrySchema, TroubleshootingRowSchema, UnitPlanSchema, UserJourneySchema, WORKSHEET_TEMPLATE, WalkingSkeletonSchema, WorksheetItemSchema, WorksheetItemTypeEnum, WorksheetPartSchema, WorksheetSchema, ZpdVerdictSchema, activityTools, analystTools, analyzeProjectCreationIntent, assertAcyclic, assessorTools, assignDepths, atomicWriteFileSync, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildConceptPrerequisites, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildExtensionPrompt, buildHandoutPrompt, buildHeadingDirective, buildHtmlDeckSlidePrompt, buildImagePrompt, buildJudgePrompt, buildLanguageDirective, buildLessonExcerpt, buildLessonMasterPrompt, buildMarpMarkdownSlidePrompt, buildMasteryGates, buildProjectInstructionPrompt, buildSatelliteContext, buildSectionAwareExcerpt, buildSelfLabPrompt, buildSessionSliceContext, buildSlidesPrompt, buildStandardStackMarkdown, buildStandardsContext, buildStandardsContextBlock, buildTeacherGuidePrompt, buildWalkingSkeleton, buildWorksheetPrompt, checkSessionZpd, closeTruncatedJson, computeConceptSpiralProgression, computeContentHash, computePackingSpec, conductPreliminaryResearch, contentTools, convertRoadmapToFoundationSot, createAiInferenceError, createContextMissingError, createCurriculumStorage, createIdleAbortController, createStreamAbortController, createStreamAbortSignal, createStreamChunkExtractor, curateMediaLedger, designerTools, detectProjectPedagogy, dropCyclicConceptEdges, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateStandardsCoverage, executeCurriculumCommand, executeSlideProductionWorkflow, exportAllProjectQuizzes, expositionCacheKey, extractActivityContractRows, extractAssessmentMap, extractCurriculumHorizon, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStandardRefs, extractStreamChunk, extractSymbolLedger, extractThoughtAndContent, extractTieredScaffoldingBlock, findStandardStatement, formatQuizzesToCsv, fulfillMediaLedger, gateModeFor, generateActivityFlow, generateCodeLabFlow, generateDiagnosticQuizFlow, generateEducationalImage, generateExtensionFlow, generateHandoutFlow, generateLessonMasterFlow, generateMilestoneCurriculumBundle, generatePhase1SotArtifacts, generatePhase2SotArtifacts, generateProjectInstruction, generateProjectInstructionFlow, generateRoadmapCurriculum, generateSelfLabFlow, generateSelfPacedBundle, generateSingleArtifact, generateSlidesFlow, generateTeacherGuideFlow, generateWorksheetFlow, getAIModel, getArtifactMetadata, getDesignatedFallbackChain, getDesignatedFallbackConfig, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, illustratorTools, importRoadmapToProject, ingestProjectGraphIntoProject, initializeProjectInStorage, injectMediaIntoMarkdown, isExpositionFresh, isModelAllowed, isProviderEnabled, isTranslationDue, lintAndSanitizeArtifact, lintCurriculumFramework, lintFrameworkPack, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, packagerTools, parseAllSessions, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToSupabase, rankGenCandidates, renderFrameworkFromPlan, renderHorizonPromptBlock, renderMediaPlaceholder, researcherTools, resolveApiKey, resolveGateSettings, resolveStandardsPacks, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, reviewerTools, runCurriculumAIInference, safeParseJson, searchEducationalImages, searchEducationalVideos, selectStatementsForLesson, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, slugifyProjectName, streamCurriculumAIInference, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLLMWithFallback, streamLayerPrefillWithFallback, streamLessonMasterFlow, streamSelfLabFlow, stripLlmJsonWrappers, targetLanguageDisplayName, techSmeTools, topoSort, uploadAssetToBucket, validateArtifactDependencies, validateCurriculumPlan, validateFrameworkPack, validateHorizonCompliance, validateHybridDeckSlides, validateMarkdownTables, validateMermaidSyntax, withAutoRepair };
|
|
32438
33115
|
//# sourceMappingURL=index.mjs.map
|
|
32439
33116
|
//# sourceMappingURL=index.mjs.map
|