@thanh01.pmt/curriculum-kit 1.1.0 → 1.2.0

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/dist/index.mjs CHANGED
@@ -74,6 +74,8 @@ function getSuggestedActionForCode(code) {
74
74
  return "N\u1ED9i dung sinh ra thi\u1EBFu c\xE1c ph\u1EA7n b\u1EAFt bu\u1ED9c [REQUIRED]. H\xE3y k\xEDch ho\u1EA1t ki\u1EC3m th\u1EED ho\u1EB7c b\u1EA5m Rerun.";
75
75
  case "ERR_STORAGE_IO_FAILED":
76
76
  return "L\u1ED7i \u0111\u1ECDc/ghi t\u1EC7p tin tr\xEAn h\u1EC7 th\u1ED1ng l\u01B0u tr\u1EEF. Ki\u1EC3m tra quy\u1EC1n ghi th\u01B0 m\u1EE5c output/projects.";
77
+ case "ERR_CONTEXT_MISSING":
78
+ return "Thi\u1EBFu ngu\u1ED3n tri th\u1EE9c b\u1EAFt bu\u1ED9c (KNOWLEDGE_EXPOSITION ho\u1EB7c CANONICAL LESSON) theo Dependency Routing Matrix. Vui l\xF2ng t\u1EA1o ho\u1EB7c \u0111\u1ED3ng b\u1ED9 t\xE0i li\u1EC7u ngu\u1ED3n tr\u01B0\u1EDBc.";
77
79
  default:
78
80
  return "B\u1EA5m Rerun \u0111\u1EC3 th\u1EED l\u1EA1i ho\u1EB7c ki\u1EC3m tra nh\u1EADt k\xFD h\u1EC7 th\u1ED1ng.";
79
81
  }
@@ -91,11 +93,23 @@ function isCodeRetryable(code) {
91
93
  case "ERR_TASK_GATE_BLOCKED":
92
94
  case "ERR_METERED_LIMIT_EXCEEDED":
93
95
  case "ERR_SCHEMA_CONTRACT_VIOLATION":
96
+ case "ERR_CONTEXT_MISSING":
94
97
  return false;
95
98
  default:
96
99
  return true;
97
100
  }
98
101
  }
102
+ function createContextMissingError(params) {
103
+ return new CurriculumError({
104
+ errorCode: "ERR_CONTEXT_MISSING",
105
+ artifactType: params.artifactType,
106
+ lessonId: params.lessonId,
107
+ agent: params.agent,
108
+ message: `Required context source "${params.missingSource}" is missing for artifact "${params.artifactType}"`,
109
+ suggestedAction: `Generate or provide the authoritative "${params.missingSource}" source before producing "${params.artifactType}".`,
110
+ retryable: false
111
+ });
112
+ }
99
113
  var CurriculumError;
100
114
  var init_errors = __esm({
101
115
  "src/errors/index.ts"() {
@@ -5368,6 +5382,45 @@ Return a single valid JSON object matching SlideDeckSchema with these exact keys
5368
5382
  }
5369
5383
  `.trim();
5370
5384
  }
5385
+ var SLIDE_CANONICAL_METHODOLOGY = `
5386
+ MANDATORY 12-14 SLIDE MICRO-CYCLE STRUCTURE (Delimited by '---'):
5387
+ 1. **Slide 1 [Title & Mission]:** Real-world inquiry hook and overarching build mission
5388
+ 2. **Slide 2 [Agenda & Roadmap]:** Timing and milestone breakdown table
5389
+ 3. **Slide 3 [Warm-Up / Prior Knowledge]:** 2-column recall + 60-second diagnostic challenge card
5390
+ 4. **Slide 4 [High-Stakes Hook Scenario]:** Authentic engineering/domain crisis card + dilemma constraint
5391
+ 5. **Slide 5 [Core Concept 1: Mental Model]:** Definition, intuitive everyday analogy, and golden rule card
5392
+ 6. **Slide 6 [Architecture & Visual Flow]:** Clean Mermaid diagram (flowchart or sequenceDiagram) + 3 flow steps
5393
+ 7. **Slide 7 [Core Concept 2: Syntax / Mechanism Anatomy]:** Side-by-side runnable code + anatomy breakdown & syntax trap card
5394
+ 8. **Slide 8 [Guided Practice: Try It Now]:** 3-minute active desk task card with starter hint and success criteria
5395
+ 9. **Slide 9 [Integrated Hands-On Lab]:** 3-tier differentiated challenge cards (Bronze / Silver / Gold) + gotcha alert card
5396
+ 10. **Slide 10 [Traffic Light Checkpoint & Pitfalls]:** Formative self-check cards (\u{1F7E2}/\u{1F7E1}/\u{1F534}) & diagnostic test question
5397
+ 11. **Slide 11 [Exit Ticket & Metacognition]:** 2 scenario-based check questions + 1 metacognitive reflection prompt
5398
+ 12. **Slide 12 [Summary & Next Steps]:** 3 core golden rules + preview card of next upcoming milestone
5399
+
5400
+ Mandatory Canvas & Presentation Invariants:
5401
+ - A slide is an INTERACTIVE PROJECTION CANVAS, NOT a textbook! Absolutely NO dense paragraphs or walls of text.
5402
+ - Follow the 6x6 rule: Maximum 4-6 bullet points per slide, maximum 8-12 words per bullet.
5403
+ - Structure slides using \`<div class="columns"><div>...</div><div>...</div></div>\` and \`<div class="card">\`, \`<div class="card highlight">\`, \`<div class="card warning">\`, \`<div class="card success">\`.
5404
+ - MANDATORY PRESENTER NOTES ON EVERY SLIDE: Every slide MUST end with \`<!-- Presenter Notes: ... -->\` containing:
5405
+ * SCRIPT: 60-90s teacher talk track with intuitive analogies.
5406
+ * COLD CALL / CHECK: Specific diagnostic question to ask students.
5407
+ * SCAFFOLDING / GOTCHA: Guidance for students who get stuck.
5408
+ * PACING: Recommended minutes for the slide.
5409
+ - Output 100% valid Marp Markdown.
5410
+ `.trim();
5411
+ function buildMarpMarkdownSlidePrompt(input) {
5412
+ return `You are @illustrator & @content (Pedagogical Slide Deck Presentation Specialists).
5413
+ Based on Master Lesson Plan \`LESSON_${input.lessonCode}.md\`, lesson context, and the MARP SLIDE TEMPLATE below, author the complete, highly engaging Marp presentation deck: \`SLIDE_${input.lessonCode}.md\`.
5414
+
5415
+ [MARP SLIDE TEMPLATE SCAFFOLD]:
5416
+ ${input.templateScaffold}
5417
+
5418
+ ${SLIDE_CANONICAL_METHODOLOGY}
5419
+
5420
+ ${input.languageDirective}
5421
+
5422
+ ${input.headingDirective}`.trim();
5423
+ }
5371
5424
 
5372
5425
  // src/ai/prompts/teacherGuidePrompt.ts
5373
5426
  function buildTeacherGuidePrompt(input) {
@@ -9700,6 +9753,224 @@ function resolveGateSettings(raw) {
9700
9753
  function gateModeFor(resolved, type) {
9701
9754
  return resolved[type] ?? "OFF";
9702
9755
  }
9756
+
9757
+ // src/services/contextBuilder.ts
9758
+ var DEFAULT_LESSON_PRIORITIES = [
9759
+ "A. Lesson Design Plan",
9760
+ "B. Lesson Flow",
9761
+ "Learning Objectives & Evidence",
9762
+ "Activity Sequence"
9763
+ ];
9764
+ var DEFAULT_KX_PRIORITIES = [
9765
+ "Key Terms",
9766
+ "Concept Narratives",
9767
+ "Worked Micro-Examples"
9768
+ ];
9769
+ function buildSectionAwareExcerpt(markdown, opts = {}) {
9770
+ const budget = opts.budget ?? 12e3;
9771
+ const minContentChars = opts.minContentChars ?? 400;
9772
+ const issues = [];
9773
+ const source = (markdown || "").trim();
9774
+ if (!source) {
9775
+ return {
9776
+ excerpt: "",
9777
+ verified: false,
9778
+ sectionAware: false,
9779
+ includedSections: [],
9780
+ issues: ["empty-source"],
9781
+ tokenEstimate: 0
9782
+ };
9783
+ }
9784
+ const slcMap = normalizeSlcContract(opts.sectionLanguageContract);
9785
+ const sections = parseMarkdownSections(source, slcMap, opts.artifactType);
9786
+ if (sections.length === 0) {
9787
+ issues.push("parse:no-sections");
9788
+ const excerpt2 = truncateByBudget(source, budget);
9789
+ const verified2 = excerpt2.length >= minContentChars;
9790
+ if (excerpt2.length < minContentChars) issues.push("content:insufficient");
9791
+ return {
9792
+ excerpt: excerpt2,
9793
+ verified: verified2,
9794
+ sectionAware: false,
9795
+ includedSections: [],
9796
+ issues,
9797
+ tokenEstimate: Math.round(excerpt2.length / 4)
9798
+ };
9799
+ }
9800
+ const byCanonical = /* @__PURE__ */ new Map();
9801
+ const unmatched = [];
9802
+ for (const s of sections) {
9803
+ if (s.canonicalKey && !byCanonical.has(s.canonicalKey)) {
9804
+ byCanonical.set(s.canonicalKey, s);
9805
+ } else {
9806
+ unmatched.push(s);
9807
+ }
9808
+ }
9809
+ const priorities = opts.priorities ?? DEFAULT_LESSON_PRIORITIES;
9810
+ const includedSections = [];
9811
+ const blocks = [];
9812
+ let used = 0;
9813
+ const tryAdd = (heading, body, key) => {
9814
+ const trimmedBody = body.trim();
9815
+ if (!trimmedBody) return false;
9816
+ const block = `## ${heading}
9817
+
9818
+ ${trimmedBody}`;
9819
+ if (used + block.length > budget && blocks.length > 0) return false;
9820
+ blocks.push(block);
9821
+ used += block.length;
9822
+ includedSections.push(key);
9823
+ return true;
9824
+ };
9825
+ let sectionAware = false;
9826
+ for (const key of priorities) {
9827
+ const sec = byCanonical.get(key);
9828
+ if (!sec) continue;
9829
+ sectionAware = true;
9830
+ if (!tryAdd(sec.cleanTitle, sec.body, key)) break;
9831
+ }
9832
+ for (const [key, sec] of byCanonical) {
9833
+ if (includedSections.includes(key)) continue;
9834
+ if (used >= budget) break;
9835
+ if (!tryAdd(sec.cleanTitle, sec.body, key)) break;
9836
+ }
9837
+ for (const sec of unmatched) {
9838
+ if (used >= budget) break;
9839
+ if (!tryAdd(sec.cleanTitle, sec.body, sec.cleanTitle)) break;
9840
+ }
9841
+ if (priorities.length > 0 && !priorities.some((k) => includedSections.includes(k))) {
9842
+ issues.push("parse:no-priority-resolution");
9843
+ }
9844
+ let excerpt = blocks.join("\n\n");
9845
+ if (excerpt.length > budget) {
9846
+ excerpt = truncateByBudget(excerpt, budget);
9847
+ }
9848
+ const effectiveMinChars = Math.min(minContentChars, source.length);
9849
+ if (excerpt.length < effectiveMinChars) {
9850
+ issues.push("content:insufficient");
9851
+ }
9852
+ const verified = !issues.includes("parse:no-priority-resolution") && excerpt.length >= effectiveMinChars;
9853
+ return {
9854
+ excerpt,
9855
+ verified,
9856
+ sectionAware: sectionAware || priorities.length === 0 && sections.length > 0,
9857
+ includedSections,
9858
+ issues,
9859
+ tokenEstimate: Math.round(excerpt.length / 4)
9860
+ };
9861
+ }
9862
+ function buildExpositionExcerpt(markdown, opts = {}) {
9863
+ return buildSectionAwareExcerpt(markdown, {
9864
+ ...opts,
9865
+ priorities: DEFAULT_KX_PRIORITIES
9866
+ });
9867
+ }
9868
+ function buildLessonExcerpt(markdown, opts = {}) {
9869
+ return buildSectionAwareExcerpt(markdown, {
9870
+ ...opts,
9871
+ priorities: DEFAULT_LESSON_PRIORITIES
9872
+ });
9873
+ }
9874
+ function normalizeSlcContract(slc) {
9875
+ if (!slc) return void 0;
9876
+ if (typeof slc !== "string") return slc;
9877
+ const out = {};
9878
+ const blocks = slc.split(/\n(?=#{2,3}\s+[A-Z0-9_]+)/g);
9879
+ for (const block of blocks) {
9880
+ const header = block.match(/^#{2,3}\s+([A-Z0-9_]+)/);
9881
+ if (!header?.[1]) continue;
9882
+ const mapping = {};
9883
+ for (const line of block.split("\n")) {
9884
+ const t = line.trim();
9885
+ if (!t.startsWith("|") || t.includes("---")) continue;
9886
+ const cells = t.split("|").map((c) => c.trim()).filter((_, i, a) => i > 0 && i < a.length - 1);
9887
+ const [c0, c1] = cells;
9888
+ if (c0 && c1 && !c0.toLowerCase().includes("canonical") && !c1.toLowerCase().includes("localized")) {
9889
+ mapping[c0] = c1;
9890
+ }
9891
+ }
9892
+ if (Object.keys(mapping).length > 0) out[header[1]] = mapping;
9893
+ }
9894
+ return Object.keys(out).length > 0 ? out : void 0;
9895
+ }
9896
+ function parseMarkdownSections(markdown, slcMap, artifactType) {
9897
+ const sections = [];
9898
+ const lines = markdown.split("\n");
9899
+ let currentHeading = "";
9900
+ let currentBody = [];
9901
+ const reverseMap = /* @__PURE__ */ new Map();
9902
+ if (slcMap) {
9903
+ const maps = artifactType && slcMap[artifactType] ? [slcMap[artifactType]] : Object.values(slcMap);
9904
+ for (const m of maps) {
9905
+ for (const [canonical, localized] of Object.entries(m)) {
9906
+ reverseMap.set(normalizeHeading(localized), canonical);
9907
+ reverseMap.set(normalizeHeading(canonical), canonical);
9908
+ }
9909
+ }
9910
+ }
9911
+ const flush = () => {
9912
+ if (!currentHeading && currentBody.length === 0) return;
9913
+ const cleanTitle = currentHeading.replace(/^#{1,4}\s+/, "").trim();
9914
+ const norm = normalizeHeading(cleanTitle);
9915
+ const canonicalKey = reverseMap.get(norm) || findCanonicalFuzzy(norm);
9916
+ sections.push({
9917
+ rawHeading: currentHeading,
9918
+ cleanTitle,
9919
+ canonicalKey,
9920
+ body: currentBody.join("\n")
9921
+ });
9922
+ currentBody = [];
9923
+ };
9924
+ const hasH2 = lines.some((l) => /^##\s+/.test(l));
9925
+ const headingRegex = hasH2 ? /^##\s+(.*)$/ : /^#{2,3}\s+(.*)$/;
9926
+ for (const line of lines) {
9927
+ const headingMatch = line.match(headingRegex);
9928
+ if (headingMatch) {
9929
+ flush();
9930
+ currentHeading = line.trim();
9931
+ } else {
9932
+ currentBody.push(line);
9933
+ }
9934
+ }
9935
+ flush();
9936
+ return sections;
9937
+ }
9938
+ function normalizeHeading(str) {
9939
+ return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
9940
+ }
9941
+ function findCanonicalFuzzy(norm) {
9942
+ if (norm.includes("lesson design plan") || norm.includes("ke hoach thiet ke")) {
9943
+ return "A. Lesson Design Plan";
9944
+ }
9945
+ if (norm.includes("lesson flow") || norm.includes("tien trinh giang day")) {
9946
+ return "B. Lesson Flow";
9947
+ }
9948
+ if (norm.includes("learning objective") || norm.includes("muc tieu bai hoc")) {
9949
+ return "Learning Objectives & Evidence";
9950
+ }
9951
+ if (norm.includes("activity sequence") || norm.includes("chuoi hoat dong")) {
9952
+ return "Activity Sequence";
9953
+ }
9954
+ if (norm.includes("key term") || norm.includes("thuat ngu")) {
9955
+ return "Key Terms";
9956
+ }
9957
+ if (norm.includes("concept narrative") || norm.includes("dien giai khai niem")) {
9958
+ return "Concept Narratives";
9959
+ }
9960
+ if (norm.includes("worked example") || norm.includes("vi du")) {
9961
+ return "Worked Micro-Examples";
9962
+ }
9963
+ return void 0;
9964
+ }
9965
+ function truncateByBudget(source, budget) {
9966
+ if (source.length <= budget) return source;
9967
+ let cut = source.slice(0, budget);
9968
+ const fenceCount = (cut.match(/^```/gm) || []).length;
9969
+ if (fenceCount % 2 === 1) cut += "\n```";
9970
+ return cut;
9971
+ }
9972
+
9973
+ // src/services/knowledgeExpositionService.ts
9703
9974
  var EXPOSITION_REL = (lessonCode) => "_sot/expositions/" + lessonCode + ".md";
9704
9975
  var ExpositionApprovalError = class extends Error {
9705
9976
  constructor(message) {
@@ -9806,15 +10077,8 @@ async function ensureKnowledgeExposition(options) {
9806
10077
  return { relPath: EXPOSITION_REL(lessonCode), content: stamped, reused: false, gateMode: gateModeFor(options.gates ?? {}, "KNOWLEDGE_EXPOSITION") };
9807
10078
  }
9808
10079
  function buildExpositionContext(expositionContent, maxChars = 6e3) {
9809
- const trimmed = expositionContent.trim();
9810
- if (trimmed.length <= maxChars) return trimmed;
9811
- const sections = trimmed.split(/\n(?=## )/);
9812
- let out = sections[0];
9813
- for (let i = 1; i < sections.length && out.length < maxChars; i++) {
9814
- const s = sections[i];
9815
- out += "\n" + s.slice(0, Math.max(400, maxChars - out.length));
9816
- }
9817
- return out.slice(0, maxChars);
10080
+ if (!expositionContent || !expositionContent.trim()) return "";
10081
+ return buildExpositionExcerpt(expositionContent, { budget: maxChars }).excerpt;
9818
10082
  }
9819
10083
  function expositionCacheKey(planHash, lessonCode) {
9820
10084
  return createHash("sha256").update(planHash + "|" + lessonCode).digest("hex").slice(0, 16);
@@ -11102,9 +11366,19 @@ function buildLanguageDirective(targetLanguage) {
11102
11366
  - DO NOT mix in paragraphs, tables, or titles written in any other language. Strict adherence is required.${exampleLine ? `
11103
11367
  ${exampleLine}` : ""}`;
11104
11368
  }
11105
- function extractSectionHeadingsFromSLC(slcMarkdown, artifactType) {
11106
- if (!slcMarkdown) return {};
11369
+ function extractSectionHeadingsFromSLC(slcInput, artifactType) {
11370
+ if (!slcInput) return {};
11107
11371
  const upperType = artifactType.trim().toUpperCase();
11372
+ if (typeof slcInput === "object") {
11373
+ if (slcInput[upperType]) return slcInput[upperType];
11374
+ for (const [key, mapping] of Object.entries(slcInput)) {
11375
+ if (key.toUpperCase() === upperType || upperType.startsWith("LESSON") && key.toUpperCase().startsWith("LESSON")) {
11376
+ return mapping;
11377
+ }
11378
+ }
11379
+ return {};
11380
+ }
11381
+ const slcMarkdown = slcInput;
11108
11382
  const blocks = slcMarkdown.split(/\n(?=#{2,3}\s+[A-Z0-9_]+)/g);
11109
11383
  for (const block of blocks) {
11110
11384
  const headerMatch = block.match(/^#{2,3}\s+([A-Z0-9_]+)/);
@@ -11587,6 +11861,18 @@ async function produceSingleLesson(storage, projectId, lessonId, options = {}) {
11587
11861
  }
11588
11862
  const pedagogy = detectProjectPedagogy(framework, styleGuide, options.pedagogy);
11589
11863
  const pedagogyLabel = pedagogy.toUpperCase();
11864
+ const styleGuideExcerpt = styleGuide ? buildSectionAwareExcerpt(styleGuide, {
11865
+ priorities: ["Voice & Tone", "Standard Terminology (Glossary)", "Lesson Content Standards"],
11866
+ budget: 2e3
11867
+ }).excerpt : "";
11868
+ const refPackExcerpt = refPack ? buildSectionAwareExcerpt(refPack, {
11869
+ priorities: [
11870
+ "Technical Overview & Architecture Blueprint",
11871
+ "Hardware Pinout & Wiring Configuration Matrix",
11872
+ "Core Pedagogical Concept Anchor & Real-World Domain Bridge"
11873
+ ],
11874
+ budget: 2500
11875
+ }).excerpt : "";
11590
11876
  const commonContext = `PROJECT & ACADEMIC CONTEXT:
11591
11877
  - Project ID: ${projectId}
11592
11878
  - Pedagogical Model: ${pedagogyLabel}
@@ -11600,10 +11886,10 @@ async function produceSingleLesson(storage, projectId, lessonId, options = {}) {
11600
11886
  ${buildFrameworkExcerptForLesson(framework, lessonId)}
11601
11887
 
11602
11888
  [CONTENT STYLE GUIDE EXCERPT]:
11603
- ${styleGuide.slice(0, 1500)}
11889
+ ${styleGuideExcerpt}
11604
11890
 
11605
11891
  [REFERENCE PACK GROUND TRUTH]:
11606
- ${refPack.slice(0, 1e3)}${standardsContext ? "\n\n" + standardsContext : ""}${expositionContext ? "\n\n[KNOWLEDGE_EXPOSITION (CANONICAL KNOWLEDGE \u2014 teach from this, do not contradict)]:\n" + expositionContext : ""}${sessionSliceContext ? "\n\n" + sessionSliceContext : ""}`;
11892
+ ${refPackExcerpt}${standardsContext ? "\n\n" + standardsContext : ""}${expositionContext ? "\n\n[KNOWLEDGE_EXPOSITION (CANONICAL KNOWLEDGE \u2014 teach from this, do not contradict)]:\n" + expositionContext : ""}${sessionSliceContext ? "\n\n" + sessionSliceContext : ""}`;
11607
11893
  const producedArtifacts = [];
11608
11894
  const lessonRelPath = `_content/${unitCode}/LESSON_${lessonCode}.md`;
11609
11895
  const existingLessonContent = await storage.readArtifact(projectId, lessonRelPath);
@@ -11723,14 +12009,15 @@ ${yamlBlock.trim()}
11723
12009
  const judgeResult = await LLMJudgeEngine.evaluateArtifactWithLLM({
11724
12010
  targetArtifactType: "LESSON",
11725
12011
  lessonId: lessonCode,
11726
- expectedLanguage: "en",
12012
+ expectedLanguage: targetLang || "en",
11727
12013
  targetObjectives: judgeObjectives,
11728
12014
  generatedContentJson: JSON.stringify({
11729
12015
  lessonContent,
11730
12016
  lessonId: lessonCode,
11731
12017
  title: lessonTitle,
11732
- frameworkExcerpt: framework ? framework.slice(0, 2500) : void 0,
11733
- styleGuideExcerpt: styleGuide ? styleGuide.slice(0, 1500) : void 0
12018
+ frameworkExcerpt: framework ? buildFrameworkExcerptForLesson(framework, lessonId) : void 0,
12019
+ styleGuideExcerpt: styleGuideExcerpt || void 0,
12020
+ canonicalExposition: expositionContext ? expositionContext.slice(0, 3e3) : void 0
11734
12021
  }),
11735
12022
  standardStatements: Object.keys(standardStatements).length > 0 ? standardStatements : void 0
11736
12023
  });
@@ -11795,14 +12082,15 @@ ${currentContent}` }],
11795
12082
  const reJudge = await LLMJudgeEngine.evaluateArtifactWithLLM({
11796
12083
  targetArtifactType: "LESSON",
11797
12084
  lessonId: lessonCode,
11798
- expectedLanguage: "en",
12085
+ expectedLanguage: targetLang || "en",
11799
12086
  targetObjectives: parseLessonObjectives(currentContent, concept, bloomLevel),
11800
12087
  generatedContentJson: JSON.stringify({
11801
12088
  lessonContent: currentContent,
11802
12089
  lessonId: lessonCode,
11803
12090
  title: lessonTitle,
11804
- frameworkExcerpt: framework ? framework.slice(0, 2500) : void 0,
11805
- styleGuideExcerpt: styleGuide ? styleGuide.slice(0, 1500) : void 0
12091
+ frameworkExcerpt: framework ? buildFrameworkExcerptForLesson(framework, lessonId) : void 0,
12092
+ styleGuideExcerpt: styleGuideExcerpt || void 0,
12093
+ canonicalExposition: expositionContext ? expositionContext.slice(0, 3e3) : void 0
11806
12094
  }),
11807
12095
  standardStatements: Object.keys(standardStatements).length > 0 ? standardStatements : void 0
11808
12096
  });
@@ -11923,10 +12211,34 @@ ${currentContent}` }],
11923
12211
  contentHash
11924
12212
  });
11925
12213
  }
12214
+ const lessonExcerptResult = buildSectionAwareExcerpt(lessonContent, {
12215
+ priorities: DEFAULT_LESSON_PRIORITIES,
12216
+ budget: 12e3,
12217
+ sectionLanguageContract: slcMarkdown,
12218
+ artifactType: "LESSON"
12219
+ });
12220
+ const lessonExcerpt = lessonExcerptResult.excerpt;
11926
12221
  const satelliteContext = `${commonContext}
11927
12222
 
11928
12223
  [CANONICAL LESSON PLAN (${pedagogyLabel})]:
11929
- ${lessonContent.slice(0, 4e3)}`;
12224
+ ${lessonExcerpt}`;
12225
+ const judgeSat = (sat, content) => {
12226
+ if (gateModeFor(gates, sat) !== "LLM_JUDGE") return Promise.resolve();
12227
+ return judgeSatelliteArtifact({
12228
+ storage,
12229
+ projectId,
12230
+ lessonCode,
12231
+ sat,
12232
+ content,
12233
+ concept,
12234
+ bloomLevel,
12235
+ standardStatements,
12236
+ onProgress,
12237
+ targetLang,
12238
+ canonicalLessonContent: lessonContent,
12239
+ canonicalLessonExcerpt: lessonExcerpt
12240
+ });
12241
+ };
11930
12242
  const actRelPath = `_content/${unitCode}/ACT_${lessonCode}.md`;
11931
12243
  if (artifactScope.includes("ACT") && (!await storage.readArtifact(projectId, actRelPath) || force)) {
11932
12244
  onProgress?.("@activity", `[2/4] Authoring Hands-on Lab: \`ACT_${lessonCode}.md\`...`);
@@ -11995,19 +12307,7 @@ ${buildHeadingDirective("ACT", slcMarkdown, targetLang)}`;
11995
12307
  contentHash: computeContentHash(rawAct)
11996
12308
  });
11997
12309
  producedArtifacts.push(`ACT_${lessonCode}.md`);
11998
- if (gateModeFor(gates, "ACT") === "LLM_JUDGE") {
11999
- await judgeSatelliteArtifact({
12000
- storage,
12001
- projectId,
12002
- lessonCode,
12003
- sat: "ACT",
12004
- content: rawAct,
12005
- concept,
12006
- bloomLevel,
12007
- standardStatements,
12008
- onProgress
12009
- });
12010
- }
12310
+ await judgeSat("ACT", rawAct);
12011
12311
  }
12012
12312
  const quizRelPath = `_content/${unitCode}/QUIZ_${lessonCode}.md`;
12013
12313
  if (artifactScope.includes("QUIZ") && (!await storage.readArtifact(projectId, quizRelPath) || force)) {
@@ -12071,64 +12371,25 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
12071
12371
  contentHash: computeContentHash(rawQuiz)
12072
12372
  });
12073
12373
  producedArtifacts.push(`QUIZ_${lessonCode}.md`);
12074
- if (gateModeFor(gates, "QUIZ") === "LLM_JUDGE") {
12075
- await judgeSatelliteArtifact({
12076
- storage,
12077
- projectId,
12078
- lessonCode,
12079
- sat: "QUIZ",
12080
- content: rawQuiz,
12081
- concept,
12082
- bloomLevel,
12083
- standardStatements,
12084
- onProgress
12085
- });
12086
- }
12374
+ await judgeSat("QUIZ", rawQuiz);
12087
12375
  }
12088
12376
  const slideRelPath = `_content/${unitCode}/SLIDE_${lessonCode}.md`;
12089
12377
  if (artifactScope.includes("SLIDE") && (!await storage.readArtifact(projectId, slideRelPath) || force)) {
12090
12378
  onProgress?.("@illustrator", `[4/4] Authoring Presentation Slide Deck: \`SLIDE_${lessonCode}.md\`...`);
12091
12379
  const canonicalSlideTemplate = loadCurriculumTemplate("SLIDE_template.md");
12092
- const slidePrompt = `You are @illustrator & @content (Pedagogical Slide Deck Presentation Specialists).
12093
- Based on Master Lesson Plan \`LESSON_${lessonCode}.md\`, lesson context, and the MARP SLIDE TEMPLATE below, author the complete, highly engaging Marp presentation deck: \`SLIDE_${lessonCode}.md\`.
12094
-
12095
- [MARP SLIDE TEMPLATE SCAFFOLD]:
12096
- ${canonicalSlideTemplate || `---
12380
+ const templateScaffold = canonicalSlideTemplate || `---
12097
12381
  marp: true
12098
12382
  theme: default
12099
12383
  paginate: true
12100
12384
  header: "${titleHeader(lessonTitle)}"
12101
12385
  footer: "Curriculum OS \u2022 ${lessonCode} (${pedagogyLabel})"
12102
- ---`}
12103
-
12104
- MANDATORY 12-14 SLIDE MICRO-CYCLE STRUCTURE (Delimited by '---'):
12105
- 1. **Slide 1 [Title & Mission]:** ${lessonCode}: ${lessonTitle} + Real-world inquiry hook
12106
- 2. **Slide 2 [Agenda & Roadmap]:** Timing and milestone breakdown table (${pedagogyLabel})
12107
- 3. **Slide 3 [Warm-Up / Prior Knowledge]:** 2-column recall + 60-second diagnostic challenge card
12108
- 4. **Slide 4 [High-Stakes Hook Scenario]:** Authentic engineering/domain crisis card + dilemma constraint
12109
- 5. **Slide 5 [Core Concept 1: Mental Model]:** Definition, intuitive everyday analogy, and golden rule card
12110
- 6. **Slide 6 [Architecture & Visual Flow]:** Clean Mermaid diagram (flowchart or sequenceDiagram) + 3 flow steps
12111
- 7. **Slide 7 [Core Concept 2: Syntax / Mechanism Anatomy]:** Side-by-side 6-10 lines runnable code + anatomy breakdown & syntax trap card
12112
- 8. **Slide 8 [Guided Practice: Try It Now]:** 3-minute active desk task card with starter hint and success criteria
12113
- 9. **Slide 9 [Integrated Hands-On Lab]:** 3-tier differentiated challenge cards (Bronze / Silver / Gold) + gotcha alert card
12114
- 10. **Slide 10 [Traffic Light Checkpoint & Pitfalls]:** Formative self-check cards (\u{1F7E2}/\u{1F7E1}/\u{1F534}) & diagnostic test question
12115
- 11. **Slide 11 [Exit Ticket & Metacognition]:** 2 scenario-based check questions + 1 metacognitive reflection prompt
12116
- 12. **Slide 12 [Summary & Next Steps]:** 3 core golden rules + preview card of next upcoming milestone
12117
-
12118
- Mandatory Canvas & Presentation Invariants:
12119
- - A slide is an INTERACTIVE PROJECTION CANVAS, NOT a textbook! Absolutely NO dense paragraphs or walls of text.
12120
- - Follow the 6x6 rule: Maximum 4-6 bullet points per slide, maximum 8-12 words per bullet.
12121
- - Structure slides using \`<div class="columns"><div>...</div><div>...</div></div>\` and \`<div class="card">\`, \`<div class="card highlight">\`, \`<div class="card warning">\`, \`<div class="card success">\`.
12122
- - MANDATORY PRESENTER NOTES ON EVERY SLIDE: Every slide MUST end with \`<!-- Presenter Notes: ... -->\` containing:
12123
- * SCRIPT: 60-90s teacher talk track with intuitive analogies.
12124
- * COLD CALL / CHECK: Specific diagnostic question to ask students.
12125
- * SCAFFOLDING / GOTCHA: Guidance for students who get stuck.
12126
- * PACING: Recommended minutes for the slide.
12127
- - Output 100% valid Marp Markdown.
12128
-
12129
- ${languageDirective}
12130
-
12131
- ${buildHeadingDirective("SLIDE", slcMarkdown, targetLang)}`;
12386
+ ---`;
12387
+ const slidePrompt = buildMarpMarkdownSlidePrompt({
12388
+ lessonCode,
12389
+ templateScaffold,
12390
+ languageDirective,
12391
+ headingDirective: buildHeadingDirective("SLIDE", slcMarkdown, targetLang)
12392
+ });
12132
12393
  const rawSlide = await runCurriculumAIInference(
12133
12394
  [{ role: "user", content: slidePrompt }],
12134
12395
  satelliteContext,
@@ -12154,19 +12415,7 @@ ${buildHeadingDirective("SLIDE", slcMarkdown, targetLang)}`;
12154
12415
  contentHash: computeContentHash(rawSlide)
12155
12416
  });
12156
12417
  producedArtifacts.push(`SLIDE_${lessonCode}.md`);
12157
- if (gateModeFor(gates, "SLIDE") === "LLM_JUDGE") {
12158
- await judgeSatelliteArtifact({
12159
- storage,
12160
- projectId,
12161
- lessonCode,
12162
- sat: "SLIDE",
12163
- content: rawSlide,
12164
- concept,
12165
- bloomLevel,
12166
- standardStatements,
12167
- onProgress
12168
- });
12169
- }
12418
+ await judgeSat("SLIDE", rawSlide);
12170
12419
  }
12171
12420
  const guideRelPath = `_content/${unitCode}/GUIDE_${lessonCode}.md`;
12172
12421
  if (artifactScope.includes("GUIDE") && (!await storage.readArtifact(projectId, guideRelPath) || force)) {
@@ -12216,19 +12465,7 @@ ${buildHeadingDirective("GUIDE", slcMarkdown, targetLang)}`;
12216
12465
  contentHash: computeContentHash(rawGuide)
12217
12466
  });
12218
12467
  producedArtifacts.push(`GUIDE_${lessonCode}.md`);
12219
- if (gateModeFor(gates, "GUIDE") === "LLM_JUDGE") {
12220
- await judgeSatelliteArtifact({
12221
- storage,
12222
- projectId,
12223
- lessonCode,
12224
- sat: "GUIDE",
12225
- content: rawGuide,
12226
- concept,
12227
- bloomLevel,
12228
- standardStatements,
12229
- onProgress
12230
- });
12231
- }
12468
+ await judgeSat("GUIDE", rawGuide);
12232
12469
  }
12233
12470
  }
12234
12471
  const handoutRelPath = `_content/${unitCode}/HANDOUT_${lessonCode}.md`;
@@ -12279,19 +12516,7 @@ ${buildHeadingDirective("HANDOUT", slcMarkdown, targetLang)}`;
12279
12516
  contentHash: computeContentHash(rawHandout)
12280
12517
  });
12281
12518
  producedArtifacts.push(`HANDOUT_${lessonCode}.md`);
12282
- if (gateModeFor(gates, "HANDOUT") === "LLM_JUDGE") {
12283
- await judgeSatelliteArtifact({
12284
- storage,
12285
- projectId,
12286
- lessonCode,
12287
- sat: "HANDOUT",
12288
- content: rawHandout,
12289
- concept,
12290
- bloomLevel,
12291
- standardStatements,
12292
- onProgress
12293
- });
12294
- }
12519
+ await judgeSat("HANDOUT", rawHandout);
12295
12520
  }
12296
12521
  }
12297
12522
  const wksRelPath = `_content/${unitCode}/WKS_${lessonCode}.md`;
@@ -12346,19 +12571,7 @@ ${buildHeadingDirective("WKS", slcMarkdown, targetLang)}`;
12346
12571
  contentHash: computeContentHash(rawWks)
12347
12572
  });
12348
12573
  producedArtifacts.push(`WKS_${lessonCode}.md`);
12349
- if (gateModeFor(gates, "WKS") === "LLM_JUDGE") {
12350
- await judgeSatelliteArtifact({
12351
- storage,
12352
- projectId,
12353
- lessonCode,
12354
- sat: "WKS",
12355
- content: rawWks,
12356
- concept,
12357
- bloomLevel,
12358
- standardStatements,
12359
- onProgress
12360
- });
12361
- }
12574
+ await judgeSat("WKS", rawWks);
12362
12575
  }
12363
12576
  }
12364
12577
  const codeRelPath = `_content/${unitCode}/CODE_${lessonCode}.md`;
@@ -12422,19 +12635,7 @@ ${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
12422
12635
  contentHash: computeContentHash(rawCode)
12423
12636
  });
12424
12637
  producedArtifacts.push(`CODE_${lessonCode}.md`);
12425
- if (gateModeFor(gates, "CODE") === "LLM_JUDGE") {
12426
- await judgeSatelliteArtifact({
12427
- storage,
12428
- projectId,
12429
- lessonCode,
12430
- sat: "CODE",
12431
- content: rawCode,
12432
- concept,
12433
- bloomLevel,
12434
- standardStatements,
12435
- onProgress
12436
- });
12437
- }
12638
+ await judgeSat("CODE", rawCode);
12438
12639
  }
12439
12640
  }
12440
12641
  const extRelPath = `_content/${unitCode}/EXT_${lessonCode}.md`;
@@ -12487,19 +12688,7 @@ ${buildHeadingDirective("EXT", slcMarkdown, targetLang)}`;
12487
12688
  contentHash: computeContentHash(rawExt)
12488
12689
  });
12489
12690
  producedArtifacts.push(`EXT_${lessonCode}.md`);
12490
- if (gateModeFor(gates, "EXT") === "LLM_JUDGE") {
12491
- await judgeSatelliteArtifact({
12492
- storage,
12493
- projectId,
12494
- lessonCode,
12495
- sat: "EXT",
12496
- content: rawExt,
12497
- concept,
12498
- bloomLevel,
12499
- standardStatements,
12500
- onProgress
12501
- });
12502
- }
12691
+ await judgeSat("EXT", rawExt);
12503
12692
  }
12504
12693
  }
12505
12694
  onProgress?.("@reviewer", `\u2705 Successfully authored all requested artifacts for \`${lessonCode}\` (${pedagogyLabel})!`);
@@ -12565,12 +12754,22 @@ async function judgeSatelliteArtifact(ctx) {
12565
12754
  const { storage, projectId, lessonCode, sat, content } = ctx;
12566
12755
  try {
12567
12756
  ctx.onProgress?.("@reviewer", `\u{1F916} Judging ${sat}_${lessonCode}...`);
12757
+ const targetObjectives = parseLessonObjectives(
12758
+ ctx.canonicalLessonContent || content,
12759
+ ctx.concept,
12760
+ ctx.bloomLevel
12761
+ );
12568
12762
  const result = await LLMJudgeEngine.evaluateArtifactWithLLM({
12569
12763
  targetArtifactType: sat,
12570
12764
  lessonId: lessonCode,
12571
- expectedLanguage: "en",
12572
- targetObjectives: parseLessonObjectives(content, ctx.concept, ctx.bloomLevel),
12573
- generatedContentJson: JSON.stringify({ content, artifactType: sat, lessonId: lessonCode }),
12765
+ expectedLanguage: ctx.targetLang || "en",
12766
+ targetObjectives,
12767
+ generatedContentJson: JSON.stringify({
12768
+ content,
12769
+ artifactType: sat,
12770
+ lessonId: lessonCode,
12771
+ canonicalLessonExcerpt: ctx.canonicalLessonExcerpt
12772
+ }),
12574
12773
  standardStatements: Object.keys(ctx.standardStatements).length > 0 ? ctx.standardStatements : void 0
12575
12774
  });
12576
12775
  const passed = result.passed && result.score >= 85;
@@ -12693,6 +12892,87 @@ async function produceBatchLessons(storage, projectId, lessonIds, options = {})
12693
12892
  // src/services/singleArtifactService.ts
12694
12893
  init_streamRunner();
12695
12894
  init_errors();
12895
+
12896
+ // src/services/contextRouting.ts
12897
+ init_errors();
12898
+ var ARTIFACT_DEPENDENCY_ROUTING = {
12899
+ LESSON: {
12900
+ required: ["KNOWLEDGE_EXPOSITION", "SESSION_SLICE", "FRAMEWORK_EXCERPT"],
12901
+ optional: ["STYLE_GUIDE", "REFERENCE_PACK"],
12902
+ rationale: "D\u1EA1y theo ki\u1EBFn th\u1EE9c chu\u1EA9n c\u1EE7a plan, ph\xE2n b\u1ED5 m\u1EE5c ti\xEAu v\xE0 khung ch\u01B0\u01A1ng tr\xECnh"
12903
+ },
12904
+ HANDOUT: {
12905
+ required: ["KNOWLEDGE_EXPOSITION"],
12906
+ optional: ["SESSION_SLICE"],
12907
+ rationale: "T\xE0i li\u1EC7u t\u1EF1 h\u1ECDc \u2014 b\xE1m kh\xE1i ni\u1EC7m chu\u1EA9n, kh\xF4ng c\u1EA7n activity timeline"
12908
+ },
12909
+ EXT: {
12910
+ required: ["KNOWLEDGE_EXPOSITION"],
12911
+ optional: ["SESSION_SLICE"],
12912
+ rationale: "Th\u1EED th\xE1ch m\u1EDF r\u1ED9ng chuy\xEAn s\xE2u b\xE1m kh\xE1i ni\u1EC7m"
12913
+ },
12914
+ CODE: {
12915
+ required: ["KNOWLEDGE_EXPOSITION"],
12916
+ optional: ["LESSON_OBJECTIVES"],
12917
+ rationale: "Code lab th\u1EF1c h\xE0nh b\xE1m kh\xE1i ni\u1EC7m k\u1EF9 thu\u1EADt v\xE0 v\xED d\u1EE5 worked examples"
12918
+ },
12919
+ ACT: {
12920
+ required: ["CANONICAL_LESSON"],
12921
+ optional: ["KNOWLEDGE_EXPOSITION", "SESSION_SLICE"],
12922
+ rationale: "STEM Activity Lab b\u1EAFt bu\u1ED9c ph\u1EA3i kh\u1EDBp 100% Activity Sequence v\xE0 Lesson Flow c\u1EE7a LESSON"
12923
+ },
12924
+ WKS: {
12925
+ required: ["CANONICAL_LESSON"],
12926
+ optional: ["KNOWLEDGE_EXPOSITION"],
12927
+ rationale: "Phi\u1EBFu h\u1ECDc t\u1EADp (Worksheet) luy\u1EC7n t\u1EADp theo c\xE1c ch\u1EB7ng ho\u1EA1t \u0111\u1ED9ng c\u1EE7a gi\xE1o \xE1n"
12928
+ },
12929
+ GUIDE: {
12930
+ required: ["CANONICAL_LESSON"],
12931
+ optional: ["SESSION_SLICE"],
12932
+ rationale: "K\u1ECBch b\u1EA3n s\u01B0 ph\u1EA1m gi\xE1o vi\xEAn (Teacher Guide) b\xE1m s\xE1t timeline t\u1EEBng ph\xFAt c\u1EE7a LESSON"
12933
+ },
12934
+ SLIDE: {
12935
+ required: ["CANONICAL_LESSON"],
12936
+ optional: ["KNOWLEDGE_EXPOSITION"],
12937
+ rationale: "Slide b\xE0i gi\u1EA3ng tr\xECnh chi\u1EBFu theo c\u1EA5u tr\xFAc ph\xE2n ph\u1ED1i n\u1ED9i dung c\u1EE7a gi\xE1o \xE1n"
12938
+ },
12939
+ QUIZ: {
12940
+ required: ["KNOWLEDGE_EXPOSITION", "CANONICAL_LESSON"],
12941
+ optional: ["SESSION_SLICE"],
12942
+ rationale: "Ng\xE2n h\xE0ng c\xE2u h\u1ECFi \u0111\xE1nh gi\xE1 c\u1EA3 ki\u1EBFn th\u1EE9c chu\u1EA9n m\u1EF1c (KX) l\u1EABn m\u1EE5c ti\xEAu b\xE0i d\u1EA1y (LESSON)"
12943
+ }
12944
+ };
12945
+ function validateArtifactDependencies(artifactType, availableSources, opts = {}) {
12946
+ const normType = (artifactType || "").toUpperCase().trim();
12947
+ const rule = ARTIFACT_DEPENDENCY_ROUTING[normType];
12948
+ const failClosed = opts.failClosed ?? true;
12949
+ if (!rule) {
12950
+ return { valid: true, missing: [] };
12951
+ }
12952
+ const missing = [];
12953
+ for (const req of rule.required) {
12954
+ const val = availableSources[req];
12955
+ const isPresent = val !== void 0 && val !== null && (typeof val === "string" ? val.trim().length > 0 : true);
12956
+ if (!isPresent) {
12957
+ missing.push(req);
12958
+ }
12959
+ }
12960
+ if (missing.length > 0) {
12961
+ const err = createContextMissingError({
12962
+ artifactType: normType,
12963
+ missingSource: missing[0],
12964
+ lessonId: opts.lessonId,
12965
+ agent: opts.agent
12966
+ });
12967
+ if (failClosed) {
12968
+ throw err;
12969
+ }
12970
+ return { valid: false, missing, error: err };
12971
+ }
12972
+ return { valid: true, missing: [] };
12973
+ }
12974
+
12975
+ // src/services/singleArtifactService.ts
12696
12976
  function getArtifactMetadata(type, lessonId, pedagogy) {
12697
12977
  const id = lessonId || "ON_DEMAND";
12698
12978
  switch (type) {
@@ -12772,9 +13052,24 @@ async function generateSingleArtifact(req) {
12772
13052
  const templateContent = loadedTemplate || getDefaultFallbackTemplate(artifactType, displayTitle, lessonId || "ON_DEMAND");
12773
13053
  const hwStr = hardwarePlatform.join(", ");
12774
13054
  const selectedDevices = (config?.devices || (hardwarePlatform[0]?.toLowerCase().includes("paper") ? "paper-only" : "laptop")).toLowerCase();
12775
- const isBilingual = language.toLowerCase().includes("bilingual") || language.toLowerCase().includes("song");
12776
- const isVietnamese = !isBilingual && language.toLowerCase().includes("viet");
12777
- const langRule = isBilingual ? `1. AUTHORING LANGUAGE: Bilingual (Vietnamese - English). Headings and core conceptual definitions should be presented in Vietnamese with English technical terms in parentheses. Explanations and instructional text are in Vietnamese. Key code terms, comments, and challenge summaries are presented bilingually.` : isVietnamese ? `1. AUTHORING LANGUAGE: Vietnamese for all instructional text, explanations, questions, rubrics, and presenter notes. Programming code, syntax keywords, and standard API identifiers remain in standard English (with Vietnamese explanation comments/notes).` : `1. AUTHORING LANGUAGE: 100% English (Plan C Canonical Specification).`;
13055
+ language.toLowerCase().includes("bilingual") || language.toLowerCase().includes("song");
13056
+ const targetLang = resolveTargetLanguageCode(language);
13057
+ const langDirective = buildLanguageDirective(language);
13058
+ const headingDirective = buildHeadingDirective(
13059
+ artifactType.toUpperCase(),
13060
+ req.sectionLanguageContract,
13061
+ targetLang
13062
+ );
13063
+ const availableSources = {
13064
+ KNOWLEDGE_EXPOSITION: contextSot.exposition || researchContext,
13065
+ CANONICAL_LESSON: contextSot.lessonPlan,
13066
+ FRAMEWORK_EXCERPT: contextSot.framework
13067
+ };
13068
+ validateArtifactDependencies(artifactType.toUpperCase(), availableSources, {
13069
+ lessonId,
13070
+ agent: meta.persona,
13071
+ failClosed: req.failClosedContext ?? false
13072
+ });
12778
13073
  const isPaperOnly = selectedDevices === "paper-only" || hwStr.toLowerCase().includes("paper") || hwStr.toLowerCase().includes("print-ready");
12779
13074
  const deviceRule = isPaperOnly ? `
12780
13075
  - \u{1F4C4} PAPER-ONLY / NO-DEVICE ENVIRONMENT: The learning space has NO computers or screens. All exercises, worksheets, task cards, exit tickets, and code analyses MUST be 100% printable. Provide write-in blank boxes, printed code snippets with line numbers, tracing tables, and physical manipulative instructions.` : selectedDevices === "tablet" || selectedDevices === "smartphone" ? `
@@ -12795,7 +13090,8 @@ async function generateSingleArtifact(req) {
12795
13090
  Your task is to author a canonical, publication-grade learning artifact of type "${artifactType.toUpperCase()}".
12796
13091
 
12797
13092
  ### CORE OPERATIONAL INVARIANTS:
12798
- ${langRule}
13093
+ ${langDirective}
13094
+ ${headingDirective}
12799
13095
  2. NON-MOCK CODE INVARIANT: Any code snippet provided MUST be 100% syntactically valid, idiomatic, and executable without placeholders or fake functions.
12800
13096
  3. PEDAGOGICAL GROUNDING: Strictly align with the ${pedagogy.toUpperCase()} model, Bloom's Revised Taxonomy, and IEEE/ACM CS2023 guidelines.
12801
13097
  4. SCAFFOLDING LEVEL: "${scaffoldingLevel.toUpperCase()}".${scaffoldingRule}
@@ -12804,6 +13100,11 @@ ${langRule}
12804
13100
 
12805
13101
  IMAGE PLANNING (media ledger) \u2014 QUOTA GEN: t\u1ED1i \u0111a ${mediaPolicy.maxGenImagesPerArtifact} \u1EA3nh AI cho artifact n\xE0y (\u1EA3nh search kho kh\xF4ng gi\u1EDBi h\u1EA1n).
12806
13102
  Khi n\u1ED9i dung c\u1EA7n minh h\u1ECDa (diagram quy tr\xECnh, s\u01A1 \u0111\u1ED3 kh\xE1i ni\u1EC7m, step-by-step visual), ch\xE8n placeholder \u0111\xFAng format [IMAGE: slug] (slug ch\u1EEF th\u01B0\u1EDDng-g\u1EA1ch ngang, unique trong b\xE0i, vd img-for-loop-diagram) T\u1EA0I \u0110\xDANG CH\u1ED6 c\u1EA7n \u1EA3nh, tr\xEAn d\xF2ng ri\xEAng. KH\xD4NG t\u1EF1 sinh \u1EA3nh, KH\xD4NG d\xF9ng markdown image \u2014 placeholder s\u1EBD \u0111\u01B0\u1EE3c thay b\u1EB1ng \u1EA3nh th\u1EADt sau khi Media Curator duy\u1EC7t. Ch\u1EC9 \u0111\u1EB7t cho \u1EA3nh TH\u1EF0C S\u1EF0 c\u1EA7n thi\u1EBFt.` : ""}`;
13103
+ const slcContract = req.sectionLanguageContract;
13104
+ const frameworkExcerpt = contextSot.framework ? buildSectionAwareExcerpt(contextSot.framework, { budget: 2500, sectionLanguageContract: slcContract }).excerpt : "";
13105
+ const lessonPlanExcerpt = contextSot.lessonPlan ? buildLessonExcerpt(contextSot.lessonPlan, { budget: 8e3, sectionLanguageContract: slcContract, artifactType: "LESSON" }).excerpt : "";
13106
+ const handoutExcerpt = contextSot.handout ? buildSectionAwareExcerpt(contextSot.handout, { budget: 2e3, sectionLanguageContract: slcContract }).excerpt : "";
13107
+ const expositionExcerpt = contextSot.exposition ? buildExpositionExcerpt(contextSot.exposition, { budget: 6e3, sectionLanguageContract: slcContract }).excerpt : "";
12807
13108
  const userPrompt = `### CONTEXT GROUND TRUTH:
12808
13109
  - Topic / Concept Domain: "${topic}"
12809
13110
  - Lesson ID: "${lessonId || "ON_DEMAND"}"
@@ -12821,14 +13122,17 @@ ${selectedDevices ? `- Device Mode: "${selectedDevices}"
12821
13122
  ${researchContext ? `### RESEARCH GROUND TRUTH (fact-checked context \u2014 \u01B0u ti\xEAn d\xF9ng, KH\xD4NG b\u1ECBa s\u1ED1 li\u1EC7u):
12822
13123
  ${researchContext.slice(0, 4e3)}
12823
13124
  ` : ""}
12824
- ${contextSot.framework ? `### SOT CURRICULUM FRAMEWORK:
12825
- ${contextSot.framework.slice(0, 1500)}
13125
+ ${expositionExcerpt ? `### SOT KNOWLEDGE EXPOSITION (CANONICAL KNOWLEDGE \u2014 teach from this, do not contradict):
13126
+ ${expositionExcerpt}
13127
+ ` : ""}
13128
+ ${frameworkExcerpt ? `### SOT CURRICULUM FRAMEWORK:
13129
+ ${frameworkExcerpt}
12826
13130
  ` : ""}
12827
- ${contextSot.lessonPlan ? `### SOT CANONICAL LESSON PLAN:
12828
- ${contextSot.lessonPlan.slice(0, 1500)}
13131
+ ${lessonPlanExcerpt ? `### SOT CANONICAL LESSON PLAN:
13132
+ ${lessonPlanExcerpt}
12829
13133
  ` : ""}
12830
- ${contextSot.handout ? `### SOT STUDENT HANDOUT:
12831
- ${contextSot.handout.slice(0, 1e3)}
13134
+ ${handoutExcerpt ? `### SOT STUDENT HANDOUT:
13135
+ ${handoutExcerpt}
12832
13136
  ` : ""}
12833
13137
 
12834
13138
  ### MANDATORY CANONICAL TEMPLATE CONTRACT:
@@ -12917,9 +13221,16 @@ ${yaml.trim()}
12917
13221
  const verdict = await LLMJudgeEngine.evaluateArtifactWithLLM({
12918
13222
  targetArtifactType: artifactType.toUpperCase(),
12919
13223
  lessonId: lessonId || "ON_DEMAND",
12920
- expectedLanguage: language.toLowerCase().includes("viet") ? "vietnamese" : "english",
13224
+ expectedLanguage: targetLang || "en",
12921
13225
  targetObjectives: judgeObjectives,
12922
- generatedContentJson: JSON.stringify({ content: finalContent, artifactType, lessonId: lessonId || "ON_DEMAND", title: displayTitle })
13226
+ generatedContentJson: JSON.stringify({
13227
+ content: finalContent,
13228
+ artifactType,
13229
+ lessonId: lessonId || "ON_DEMAND",
13230
+ title: displayTitle,
13231
+ canonicalLessonExcerpt: lessonPlanExcerpt || void 0,
13232
+ canonicalExposition: expositionExcerpt || void 0
13233
+ })
12923
13234
  });
12924
13235
  const passed = Boolean(verdict.passed) && verdict.score >= 85;
12925
13236
  if (passed) {
@@ -12961,9 +13272,16 @@ ${finalContent}` }
12961
13272
  const reVerdict = await LLMJudgeEngine.evaluateArtifactWithLLM({
12962
13273
  targetArtifactType: artifactType.toUpperCase(),
12963
13274
  lessonId: lessonId || "ON_DEMAND",
12964
- expectedLanguage: language.toLowerCase().includes("viet") ? "vietnamese" : "english",
13275
+ expectedLanguage: targetLang || "en",
12965
13276
  targetObjectives: judgeObjectives,
12966
- generatedContentJson: JSON.stringify({ content: repaired, artifactType, lessonId: lessonId || "ON_DEMAND", title: displayTitle })
13277
+ generatedContentJson: JSON.stringify({
13278
+ content: repaired,
13279
+ artifactType,
13280
+ lessonId: lessonId || "ON_DEMAND",
13281
+ title: displayTitle,
13282
+ canonicalLessonExcerpt: lessonPlanExcerpt || void 0,
13283
+ canonicalExposition: expositionExcerpt || void 0
13284
+ })
12967
13285
  });
12968
13286
  if (reVerdict.passed && reVerdict.score >= 85) {
12969
13287
  return {
@@ -16914,6 +17232,6 @@ function renderMediaPlaceholder(entry) {
16914
17232
  return `> \u{1F5BC}\uFE0F [\u1EA2nh \u0111ang ch\u1EDD: ${entry.name} \u2014 s\u1EBD \u0111\u01B0\u1EE3c t\u1EA1o sau khi duy\u1EC7t media]`;
16915
17233
  }
16916
17234
 
16917
- export { ACT_TEMPLATE, 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_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, 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, GlossaryQuickRefRowSchema, GlossarySchema, GlossaryTermSchema, GoldTierSchema, GradeBandSchema, GraphicOrganizerItemSchema, GraphicOrganizerSchema, HANDOUT_TEMPLATE, HandoutSchema, HandoutSectionSchema, InstructionSectionSchema, InstructionStepSchema, JudgeCriterionSchema, 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, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STANDARD_SOT_FILES, STATION_ROTATION_TEMPLATE, ScaffoldDecisionEntrySchema, ScaffoldDecisionSchema, ScienceLabSchema, ScoringRubricRowSchema, SelfLabSchema, SelfPacedBundleSchema, SelfPacedChallengeSchema, SessionPlanSchema, SilverTierSchema, 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, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildExpositionContext, buildExtensionPrompt, buildHandoutPrompt, buildHeadingDirective, buildImagePrompt, buildJudgePrompt, buildLanguageDirective, buildLessonMasterPrompt, buildProjectInstructionPrompt, buildSelfLabPrompt, buildSessionSliceContext, buildSlidesPrompt, buildStandardStackMarkdown, buildStandardsContext, buildStandardsContextBlock, buildTeacherGuidePrompt, buildWorksheetPrompt, closeTruncatedJson, computeContentHash, computePackingSpec, conductPreliminaryResearch, contentTools, convertRoadmapToFoundationSot, createAiInferenceError, createCurriculumStorage, createIdleAbortController, createStreamAbortController, createStreamAbortSignal, createStreamChunkExtractor, curateMediaLedger, designerTools, detectProjectPedagogy, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateStandardsCoverage, executeCurriculumCommand, exportAllProjectQuizzes, expositionCacheKey, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStreamChunk, extractThoughtAndContent, 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, packagerTools, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToSupabase, rankGenCandidates, renderFrameworkFromPlan, renderMediaPlaceholder, researcherTools, 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, validateCurriculumPlan, validateFrameworkPack, validateMarkdownTables, validateMermaidSyntax, withAutoRepair };
17235
+ 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, 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, GlossaryQuickRefRowSchema, GlossarySchema, GlossaryTermSchema, GoldTierSchema, GradeBandSchema, GraphicOrganizerItemSchema, GraphicOrganizerSchema, HANDOUT_TEMPLATE, HandoutSchema, HandoutSectionSchema, InstructionSectionSchema, InstructionStepSchema, JudgeCriterionSchema, 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, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_CANONICAL_METHODOLOGY, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STANDARD_SOT_FILES, STATION_ROTATION_TEMPLATE, ScaffoldDecisionEntrySchema, ScaffoldDecisionSchema, ScienceLabSchema, ScoringRubricRowSchema, SelfLabSchema, SelfPacedBundleSchema, SelfPacedChallengeSchema, SessionPlanSchema, SilverTierSchema, 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, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildExpositionContext, buildExpositionExcerpt, buildExtensionPrompt, buildHandoutPrompt, buildHeadingDirective, 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, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateStandardsCoverage, executeCurriculumCommand, exportAllProjectQuizzes, expositionCacheKey, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStreamChunk, extractThoughtAndContent, 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, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToSupabase, rankGenCandidates, renderFrameworkFromPlan, renderMediaPlaceholder, researcherTools, 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, validateMarkdownTables, validateMermaidSyntax, withAutoRepair };
16918
17236
  //# sourceMappingURL=index.mjs.map
16919
17237
  //# sourceMappingURL=index.mjs.map