@thanh01.pmt/curriculum-kit 1.4.16 → 1.4.18
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/index.cjs +181 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.mjs +180 -13
- package/dist/index.mjs.map +1 -1
- package/dist/workflow/index.cjs +87 -1
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.mjs +87 -1
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +22 -23
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Tony Pham
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -10690,6 +10690,8 @@ ${lines.join("\n")}
|
|
|
10690
10690
|
|
|
10691
10691
|
// src/services/contextBuilder.ts
|
|
10692
10692
|
var DEFAULT_LESSON_PRIORITIES = [
|
|
10693
|
+
"Symbol & Identifier Ledger",
|
|
10694
|
+
"Artifact Contract",
|
|
10693
10695
|
"A. Lesson Design Plan",
|
|
10694
10696
|
"B. Lesson Flow",
|
|
10695
10697
|
"Learning Objectives & Evidence",
|
|
@@ -10908,6 +10910,12 @@ function normalizeHeading(str) {
|
|
|
10908
10910
|
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
10909
10911
|
}
|
|
10910
10912
|
function findCanonicalFuzzy(norm) {
|
|
10913
|
+
if (norm.includes("symbol") || norm.includes("identifier ledger") || norm.includes("dinh danh")) {
|
|
10914
|
+
return "Symbol & Identifier Ledger";
|
|
10915
|
+
}
|
|
10916
|
+
if (norm.includes("artifact contract") || norm.includes("hop dong hoc lieu")) {
|
|
10917
|
+
return "Artifact Contract";
|
|
10918
|
+
}
|
|
10911
10919
|
if (norm.includes("lesson design plan") || norm.includes("ke hoach thiet ke")) {
|
|
10912
10920
|
return "A. Lesson Design Plan";
|
|
10913
10921
|
}
|
|
@@ -10958,6 +10966,39 @@ function deriveArtifactTypeFromFileName(fileName) {
|
|
|
10958
10966
|
const token = base.match(/^([A-Z][A-Z0-9_]*?)(?=_|$)/);
|
|
10959
10967
|
return token ? token[1] : void 0;
|
|
10960
10968
|
}
|
|
10969
|
+
function extractSymbolLedger(lessonMarkdown) {
|
|
10970
|
+
const result = {
|
|
10971
|
+
keySymbols: [],
|
|
10972
|
+
rawBlock: ""
|
|
10973
|
+
};
|
|
10974
|
+
if (!lessonMarkdown) return result;
|
|
10975
|
+
const ledgerMatch = lessonMarkdown.match(/###?\s*(?:Symbol & Identifier Ledger|Bảng Định Danh|Artifact Contract)[\s\S]*?(?=\n##|\n---|$)/i);
|
|
10976
|
+
if (ledgerMatch) {
|
|
10977
|
+
result.rawBlock = ledgerMatch[0].trim();
|
|
10978
|
+
}
|
|
10979
|
+
const structMatch = lessonMarkdown.match(/(?:Primary Struct|Primary Class|Primary Function|Main Component|Primary Module|Struct chính|Class chính|Hàm chính)[:\s*`]+([A-Za-z0-9_]+)/i);
|
|
10980
|
+
if (structMatch) {
|
|
10981
|
+
result.primarySymbol = structMatch[1];
|
|
10982
|
+
result.keySymbols.push(structMatch[1]);
|
|
10983
|
+
} else {
|
|
10984
|
+
const codeStructMatch = lessonMarkdown.match(/(?:struct|class|interface|type|def|function)\s+([A-Za-z0-9_]+)/);
|
|
10985
|
+
if (codeStructMatch) {
|
|
10986
|
+
const sym = codeStructMatch[1];
|
|
10987
|
+
result.primarySymbol = sym;
|
|
10988
|
+
result.keySymbols.push(sym);
|
|
10989
|
+
}
|
|
10990
|
+
}
|
|
10991
|
+
const fileMatch = lessonMarkdown.match(/(?:Entry File|Source File|Target File|Tên file mã nguồn)[:\s*`]+([A-Za-z0-9_\-\.]+\.[a-z0-9_]+)/i);
|
|
10992
|
+
if (fileMatch) {
|
|
10993
|
+
result.entryFileName = fileMatch[1];
|
|
10994
|
+
} else {
|
|
10995
|
+
const codeFileComment = lessonMarkdown.match(/(?:\/\/\s*|#\s*|\/\*\s*)([A-Za-z0-9_\-]+\.[a-zA-Z0-9]+)/);
|
|
10996
|
+
if (codeFileComment) {
|
|
10997
|
+
result.entryFileName = codeFileComment[1];
|
|
10998
|
+
}
|
|
10999
|
+
}
|
|
11000
|
+
return result;
|
|
11001
|
+
}
|
|
10961
11002
|
|
|
10962
11003
|
// src/services/knowledgeExpositionService.ts
|
|
10963
11004
|
var EXPOSITION_REL = (lessonCode) => "_sot/expositions/" + lessonCode + ".md";
|
|
@@ -10977,8 +11018,22 @@ var DEPTH_RULES = {
|
|
|
10977
11018
|
cio: "Write WHAT + WHY + HOW: include the mechanism, step by step, still technology-independent.",
|
|
10978
11019
|
sio: "Write WHAT + WHY + HOW + SPECIFIC: include concrete implementations and how the real project keywords are used."
|
|
10979
11020
|
};
|
|
10980
|
-
function
|
|
11021
|
+
function buildDomainLexiconGuardrail(techStack, hardwarePlatform) {
|
|
11022
|
+
const targetTech = (techStack || "").trim();
|
|
11023
|
+
const targetHw = (hardwarePlatform || "").trim();
|
|
11024
|
+
const platformAnchor = [targetTech, targetHw].filter(Boolean).join(" | ");
|
|
11025
|
+
if (!platformAnchor) {
|
|
11026
|
+
return `- \u{1F512} TECHNICAL DOMAIN ANCHOR: Strictly adhere to the declared curriculum domain. Use ONLY native, standard, idiomatic syntax and mechanisms. Strictly FORBIDDEN from using foreign paradigms, cross-domain jargon, or hallucinated APIs.`;
|
|
11027
|
+
}
|
|
11028
|
+
return `- \u{1F512} STRICT DOMAIN & TECHNICAL PLATFORM ANCHOR:
|
|
11029
|
+
\u2022 Declared Platform: "${platformAnchor}"
|
|
11030
|
+
\u2022 NATIVE PARADIGM ONLY: You MUST strictly use standard, idiomatic syntax, conventions, naming patterns, and mental models of "${platformAnchor}".
|
|
11031
|
+
\u2022 ANTI-CONTAMINATION INVARIANT: Strictly FORBIDDEN from importing or using syntax, units, keywords, tags, or concepts from unrelated/foreign ecosystems (e.g., do NOT leak Web/HTML/CSS tags or units into native mobile/embedded stacks, do NOT leak dynamic scripting into statically typed systems, do NOT use hardware/circuit terminology in pure-software courses).
|
|
11032
|
+
\u2022 REAL APIS ONLY: Every method, modifier, property, and API referenced must exist in the standard SDK of "${platformAnchor}".`;
|
|
11033
|
+
}
|
|
11034
|
+
function buildSystemPrompt(targetLanguage = "vi", techStack, hardwarePlatform) {
|
|
10981
11035
|
const langDirective = buildLanguageDirective(targetLanguage);
|
|
11036
|
+
const domainGuardrails = buildDomainLexiconGuardrail(techStack, hardwarePlatform);
|
|
10982
11037
|
return [
|
|
10983
11038
|
"You write KNOWLEDGE_EXPOSITION: self-study reading material for a student in a teacherless program.",
|
|
10984
11039
|
"Rules:",
|
|
@@ -10987,6 +11042,7 @@ function buildSystemPrompt(targetLanguage = "vi") {
|
|
|
10987
11042
|
"3. Respect each concept depth target (ULO/CIO/SIO) \u2014 do not overshoot.",
|
|
10988
11043
|
"4. Student-facing only: no teacher instructions, no classroom management text.",
|
|
10989
11044
|
"5. Output the full markdown document following the provided section skeleton exactly (headers and placeholders preserved).",
|
|
11045
|
+
domainGuardrails,
|
|
10990
11046
|
langDirective
|
|
10991
11047
|
].join("\n");
|
|
10992
11048
|
}
|
|
@@ -11023,7 +11079,7 @@ function buildUserPrompt(session, plan, glossary, targetLanguage = "vi", slcMark
|
|
|
11023
11079
|
].filter(Boolean).join("\n");
|
|
11024
11080
|
}
|
|
11025
11081
|
async function ensureKnowledgeExposition(options) {
|
|
11026
|
-
const { projectId, lessonCode, plan, glossary, llmFn, storage } = options;
|
|
11082
|
+
const { projectId, lessonCode, plan, glossary, llmFn, storage, techStack, hardwarePlatform } = options;
|
|
11027
11083
|
const session = plan.sessions.find((s) => s.id === lessonCode);
|
|
11028
11084
|
if (!session) throw new Error("Session " + lessonCode + " not found in plan " + plan.plan_id);
|
|
11029
11085
|
const existing = await storage.readArtifact(projectId, EXPOSITION_REL(lessonCode));
|
|
@@ -11038,7 +11094,7 @@ async function ensureKnowledgeExposition(options) {
|
|
|
11038
11094
|
}
|
|
11039
11095
|
const targetLanguage = options.targetLanguage || plan.translation?.target_language || "vi";
|
|
11040
11096
|
const content = (await llmFn(
|
|
11041
|
-
buildSystemPrompt(targetLanguage),
|
|
11097
|
+
buildSystemPrompt(targetLanguage, techStack, hardwarePlatform),
|
|
11042
11098
|
buildUserPrompt(session, plan, glossary, targetLanguage, options.slcMarkdown)
|
|
11043
11099
|
)).trim();
|
|
11044
11100
|
if (content.length < 200) {
|
|
@@ -11108,6 +11164,18 @@ async function ensureExpositionForLesson(storage, projectId, lessonCode, options
|
|
|
11108
11164
|
}
|
|
11109
11165
|
const scopedTerms = new Set(plan.glossary_scope.find((g) => g.session_id === lessonCode)?.terms ?? []);
|
|
11110
11166
|
glossary = glossary.filter((g) => scopedTerms.has(g.term));
|
|
11167
|
+
let hw = options.hardwarePlatform;
|
|
11168
|
+
let tech = options.techStack;
|
|
11169
|
+
if (!hw || !tech) {
|
|
11170
|
+
try {
|
|
11171
|
+
const lpRaw = await storage.readSotDocument(projectId, "LEARNER_PROFILE.md");
|
|
11172
|
+
if (lpRaw) {
|
|
11173
|
+
const hwMatch = lpRaw.match(/(?:Student Equipment|Hardware|Platform|Thiết bị)[:\s*`]+([^\n\r]+)/i);
|
|
11174
|
+
if (hwMatch && !hw) hw = hwMatch[1].trim();
|
|
11175
|
+
}
|
|
11176
|
+
} catch {
|
|
11177
|
+
}
|
|
11178
|
+
}
|
|
11111
11179
|
const { runCurriculumAIInference: runCurriculumAIInference2 } = await Promise.resolve().then(() => (init_streamRunner(), streamRunner_exports));
|
|
11112
11180
|
const targetLang = options.targetLanguage || plan.translation?.target_language || "vi";
|
|
11113
11181
|
const result = await ensureKnowledgeExposition({
|
|
@@ -11117,6 +11185,8 @@ async function ensureExpositionForLesson(storage, projectId, lessonCode, options
|
|
|
11117
11185
|
glossary,
|
|
11118
11186
|
targetLanguage: targetLang,
|
|
11119
11187
|
slcMarkdown: options.slcMarkdown,
|
|
11188
|
+
techStack: tech,
|
|
11189
|
+
hardwarePlatform: hw,
|
|
11120
11190
|
llmFn: async (systemPrompt, userPrompt) => {
|
|
11121
11191
|
const runnerOpts = options.customInference ? { customInference: options.customInference } : {};
|
|
11122
11192
|
const out = await runCurriculumAIInference2(
|
|
@@ -11469,6 +11539,17 @@ function packUnitSessions(group, nodeById, spec, warnings) {
|
|
|
11469
11539
|
const node = nodeById.get(id);
|
|
11470
11540
|
const isKnowledge = node.kind === "concept";
|
|
11471
11541
|
if (node.estimated_minutes > spec.contentBudget) {
|
|
11542
|
+
if (node.estimated_minutes <= spec.sessionDurationMinutes || node.estimated_minutes <= spec.contentBudget * 1.25) {
|
|
11543
|
+
if (current.entries.length > 0) flush();
|
|
11544
|
+
const entry = { id, minutes: spec.contentBudget, part: 1, totalParts: 1 };
|
|
11545
|
+
if (isKnowledge) current.knowledgeMinutes += entry.minutes;
|
|
11546
|
+
else current.practiceMinutes += entry.minutes;
|
|
11547
|
+
current.entries.push(entry);
|
|
11548
|
+
current.nodeIds.push(id);
|
|
11549
|
+
current.oversized = false;
|
|
11550
|
+
flush();
|
|
11551
|
+
continue;
|
|
11552
|
+
}
|
|
11472
11553
|
const parts = [];
|
|
11473
11554
|
let remaining = node.estimated_minutes;
|
|
11474
11555
|
while (remaining > 0) {
|
|
@@ -11637,6 +11718,35 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
11637
11718
|
const unitIndexByGroup = new Map(groups.map((g, i) => [g.key, i]));
|
|
11638
11719
|
const packed = [];
|
|
11639
11720
|
for (const g of groups) packed.push(...packUnitSessions(g, nodeById, spec, warnings));
|
|
11721
|
+
if (constraints.total_sessions && packed.length > constraints.total_sessions) {
|
|
11722
|
+
warnings.push(`Initial packing produced ${packed.length} sessions, coalescing to satisfy total_sessions constraint (${constraints.total_sessions})`);
|
|
11723
|
+
for (let i = 0; i < packed.length - 1 && packed.length > constraints.total_sessions; i++) {
|
|
11724
|
+
const curr = packed[i];
|
|
11725
|
+
const next = packed[i + 1];
|
|
11726
|
+
if (curr.groupId === next.groupId) {
|
|
11727
|
+
const currMins = curr.knowledgeMinutes + curr.practiceMinutes;
|
|
11728
|
+
const nextMins = next.knowledgeMinutes + next.practiceMinutes;
|
|
11729
|
+
const totalContent = currMins + nextMins;
|
|
11730
|
+
if (currMins <= 45 || nextMins <= 45 || totalContent <= spec.contentBudget * 1.5) {
|
|
11731
|
+
const scale = totalContent > spec.contentBudget ? spec.contentBudget / totalContent : 1;
|
|
11732
|
+
curr.nodeIds.push(...next.nodeIds);
|
|
11733
|
+
for (const e of next.entries) {
|
|
11734
|
+
e.minutes = Math.max(5, Math.round(e.minutes * scale));
|
|
11735
|
+
curr.entries.push(e);
|
|
11736
|
+
}
|
|
11737
|
+
for (const e of curr.entries) {
|
|
11738
|
+
e.minutes = Math.max(5, Math.round(e.minutes * scale));
|
|
11739
|
+
}
|
|
11740
|
+
const scaledKnowledge = Math.round((curr.knowledgeMinutes + next.knowledgeMinutes) * scale);
|
|
11741
|
+
curr.knowledgeMinutes = scaledKnowledge;
|
|
11742
|
+
curr.practiceMinutes = Math.max(0, spec.contentBudget - scaledKnowledge);
|
|
11743
|
+
curr.oversized = false;
|
|
11744
|
+
packed.splice(i + 1, 1);
|
|
11745
|
+
i--;
|
|
11746
|
+
}
|
|
11747
|
+
}
|
|
11748
|
+
}
|
|
11749
|
+
}
|
|
11640
11750
|
packed.map(
|
|
11641
11751
|
(_, i) => "U" + pad2(Math.min(units.length, 99)).replace("U", "U")
|
|
11642
11752
|
/* placeholder replaced below */
|
|
@@ -25103,7 +25213,11 @@ type: "LESSON_EDP"
|
|
|
25103
25213
|
|
|
25104
25214
|
### 3. Resource Map (Slide, Handout, Starter Code, Lab Tools)
|
|
25105
25215
|
### 4. Assessment Map (Rubric criteria, formative checkpoints, remediation paths)
|
|
25106
|
-
### 5. Artifact Contract
|
|
25216
|
+
### 5. Artifact Contract & Code Symbol Ledger
|
|
25217
|
+
- **Primary Struct / Class / Component:** [Explicit canonical identifier e.g. ProfileCardView]
|
|
25218
|
+
- **Entry Source File:** [Explicit file name e.g. ProfileCardView.swift]
|
|
25219
|
+
- **Key Functions & State Variables:** [Canonical identifiers used across all student activities]
|
|
25220
|
+
- **Artifact Specifications:** [Deliverable requirements for ACT, SLIDE, QUIZ, GUIDE, WKS, CODE, EXT]
|
|
25107
25221
|
|
|
25108
25222
|
---
|
|
25109
25223
|
|
|
@@ -25153,7 +25267,11 @@ type: "LESSON_GENERAL"
|
|
|
25153
25267
|
|
|
25154
25268
|
### 3. Resource Map
|
|
25155
25269
|
### 4. Assessment Map
|
|
25156
|
-
### 5. Artifact Contract
|
|
25270
|
+
### 5. Artifact Contract & Code Symbol Ledger
|
|
25271
|
+
- **Primary Struct / Class / Component:** [Explicit canonical identifier e.g. MainComponent]
|
|
25272
|
+
- **Entry Source File:** [Explicit file name e.g. MainComponent.ext]
|
|
25273
|
+
- **Key Functions & State Variables:** [Canonical identifiers used across all student activities]
|
|
25274
|
+
- **Artifact Specifications:** [Deliverable requirements for ACT, SLIDE, QUIZ, GUIDE, WKS, CODE, EXT]
|
|
25157
25275
|
|
|
25158
25276
|
---
|
|
25159
25277
|
|
|
@@ -25201,7 +25319,11 @@ type: "LESSON_5E"
|
|
|
25201
25319
|
|
|
25202
25320
|
### 3. Resource Map
|
|
25203
25321
|
### 4. Assessment Map
|
|
25204
|
-
### 5. Artifact Contract
|
|
25322
|
+
### 5. Artifact Contract & Code Symbol Ledger
|
|
25323
|
+
- **Primary Struct / Class / Component:** [Explicit canonical identifier e.g. MainComponent]
|
|
25324
|
+
- **Entry Source File:** [Explicit file name e.g. MainComponent.ext]
|
|
25325
|
+
- **Key Functions & State Variables:** [Canonical identifiers used across all student activities]
|
|
25326
|
+
- **Artifact Specifications:** [Deliverable requirements for ACT, SLIDE, QUIZ, GUIDE, WKS, CODE, EXT]
|
|
25205
25327
|
|
|
25206
25328
|
---
|
|
25207
25329
|
|
|
@@ -25776,17 +25898,23 @@ ${currentContent}` }],
|
|
|
25776
25898
|
artifactType: "LESSON"
|
|
25777
25899
|
});
|
|
25778
25900
|
const lessonExcerpt = lessonExcerptResult.excerpt;
|
|
25779
|
-
|
|
25780
|
-
source: "LESSON",
|
|
25901
|
+
({
|
|
25781
25902
|
verified: lessonExcerptResult.verified,
|
|
25782
25903
|
sectionAware: lessonExcerptResult.sectionAware,
|
|
25783
25904
|
issues: lessonExcerptResult.issues
|
|
25784
|
-
};
|
|
25785
|
-
|
|
25905
|
+
});
|
|
25906
|
+
const symbolLedger = extractSymbolLedger(lessonContent);
|
|
25907
|
+
const symbolLedgerBlock = symbolLedger.primarySymbol ? `
|
|
25908
|
+
|
|
25909
|
+
[MANDATORY CODE SYMBOL REGISTRY (Inherited from LESSON Plan)]:
|
|
25910
|
+
- Primary Struct / Class / Component: \`${symbolLedger.primarySymbol}\`
|
|
25911
|
+
- Entry Source File: \`${symbolLedger.entryFileName || symbolLedger.primarySymbol}\`
|
|
25912
|
+
- Key Identifiers to inherit verbatim: ${symbolLedger.keySymbols.map((s) => `\`${s}\``).join(", ")}
|
|
25913
|
+
- INVARIANT: You MUST use these exact identifier names in all code examples, exercises, and test assertions. Do NOT invent new struct/class names!` : "";
|
|
25786
25914
|
const satelliteContext = `${commonContext}
|
|
25787
25915
|
|
|
25788
25916
|
[CANONICAL LESSON PLAN (${pedagogyLabel})]:
|
|
25789
|
-
${lessonExcerpt}`;
|
|
25917
|
+
${lessonExcerpt}${symbolLedgerBlock}`;
|
|
25790
25918
|
const judgeSat = (sat, content) => {
|
|
25791
25919
|
if (gateModeFor(gates, sat) !== "LLM_JUDGE") return Promise.resolve();
|
|
25792
25920
|
return judgeSatelliteArtifact({
|
|
@@ -26289,6 +26417,14 @@ ${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
|
|
|
26289
26417
|
c3: "### Challenge 3: [Name] (Difficulty: \u2B50\u2B50\u2B50\u2B50\u2B50) \u2014 Extension Milestones (Level 1: Ninja \u2192 Level 2: Guru \u2192 Level 3: Master)",
|
|
26290
26418
|
meta: "## [REQUIRED] Metacognitive Deep Dive & Engineering Trade-offs"
|
|
26291
26419
|
};
|
|
26420
|
+
const lessonIdxMatch = lessonCode.match(/L0*(\d+)/i);
|
|
26421
|
+
const lessonIdx = lessonIdxMatch ? parseInt(lessonIdxMatch[1], 10) : 1;
|
|
26422
|
+
const isEarlyLesson = lessonIdx <= 4;
|
|
26423
|
+
const zpdCeilingPrompt = isEarlyLesson ? `
|
|
26424
|
+
4. CRITICAL ZPD SCOPE LOCK (LESSON #${lessonIdx} - FOUNDATIONAL):
|
|
26425
|
+
- This is an early foundational lesson. The extension challenge MUST focus on creative design variations, parameterization, or edge cases of the current lesson concepts ONLY.
|
|
26426
|
+
- STRICTLY FORBIDDEN: NEVER introduce advanced mechanisms from future lessons (No complex event buses, No remote network/API calls, No persistent databases, No async concurrency, No out-of-scope hardware/sensors).` : `
|
|
26427
|
+
4. ZPD SCOPE: Focus on architectural edge cases, algorithmic optimization, and synthesis of learned concepts up to Lesson #${lessonIdx}.`;
|
|
26292
26428
|
const extPrompt = `You are @activity (Lead STEM Specialist & Differentiated Extension Designer).
|
|
26293
26429
|
Based on Master Lesson Plan \`LESSON_${lessonCode}.md\`, author the advanced extension challenge: \`EXT_${lessonCode}.md\`.
|
|
26294
26430
|
|
|
@@ -26320,6 +26456,7 @@ ${extHeadings.sub}
|
|
|
26320
26456
|
- ${extHeadings.c3}
|
|
26321
26457
|
- ${extHeadings.meta}
|
|
26322
26458
|
3. Output 100% clean Markdown directly \u2014 NO code fences around the document.
|
|
26459
|
+
${zpdCeilingPrompt}
|
|
26323
26460
|
|
|
26324
26461
|
${languageDirective}
|
|
26325
26462
|
|
|
@@ -26850,6 +26987,15 @@ async function generateSingleArtifact(req) {
|
|
|
26850
26987
|
const artifactSpecializedPrompt = getArtifactSpecializedInvariants(artifactType, {
|
|
26851
26988
|
...req,
|
|
26852
26989
|
studentCount});
|
|
26990
|
+
const techStack = req.config?.techStack || req.hardwarePlatform?.[0] || "Declared Technical Domain";
|
|
26991
|
+
const domainGuardrail = buildDomainLexiconGuardrail(techStack, hwStr);
|
|
26992
|
+
const symbolLedger = contextSot.lessonPlan ? extractSymbolLedger(contextSot.lessonPlan) : null;
|
|
26993
|
+
const symbolLedgerPrompt = symbolLedger?.primarySymbol ? `
|
|
26994
|
+
7. MANDATORY CODE SYMBOL REGISTRY (Inherited from Canonical LESSON):
|
|
26995
|
+
- Primary Struct / Class: \`${symbolLedger.primarySymbol}\`
|
|
26996
|
+
- Entry Source File: \`${symbolLedger.entryFileName || symbolLedger.primarySymbol + ".swift"}\`
|
|
26997
|
+
- Key Identifiers to inherit: ${symbolLedger.keySymbols.map((s) => `\`${s}\``).join(", ")}
|
|
26998
|
+
- INVARIANT: You MUST use these exact identifier names in all code examples, exercises, and starter templates. Do NOT invent conflicting struct or class names.` : "";
|
|
26853
26999
|
const systemPrompt = `You are ${meta.persona}, an expert Curriculum & Pedagogical Specialist in the Curriculum OS Multi-Agent Team.
|
|
26854
27000
|
Your task is to author a canonical, publication-grade learning artifact of type "${artifactType.toUpperCase()}".
|
|
26855
27001
|
|
|
@@ -26860,7 +27006,10 @@ ${headingDirective}
|
|
|
26860
27006
|
3. PEDAGOGICAL GROUNDING: Strictly align with the ${pedagogy.toUpperCase()} model, Bloom's Revised Taxonomy, and IEEE/ACM CS2023 guidelines.
|
|
26861
27007
|
4. SCAFFOLDING LEVEL: "${scaffoldingLevel.toUpperCase()}".${scaffoldingRule}
|
|
26862
27008
|
5. TARGET AUDIENCE: ${gradeLevel ? `Grade ${gradeLevel}, ` : ""}${targetAge} on ${hwStr}.${deviceRule}${classDynamicsRule}${extraContextRule}
|
|
26863
|
-
6.
|
|
27009
|
+
6. DOMAIN & TECH STACK GUARDRAILS:
|
|
27010
|
+
${domainGuardrail}
|
|
27011
|
+
${symbolLedgerPrompt}
|
|
27012
|
+
8. OUTPUT INTEGRITY: Output clean Markdown starting directly with YAML frontmatter. Do not wrap entire response in triple backticks.${artifactSpecializedPrompt}${mediaPolicy ? `
|
|
26864
27013
|
|
|
26865
27014
|
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).
|
|
26866
27015
|
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.` : ""}`;
|
|
@@ -27340,6 +27489,24 @@ ${includeUnitTests ? "- Unit Testing: Provide automated assertions or test runne
|
|
|
27340
27489
|
1. **CLASS-SCALED INVENTORY FOR ${studentCount} STUDENTS**:
|
|
27341
27490
|
- Exact quantities calculated for ${studentCount} students.
|
|
27342
27491
|
- Component specifications, estimated unit cost, and affordable alternatives.`;
|
|
27492
|
+
case "ext": {
|
|
27493
|
+
const lessonIdxMatch = (req.lessonId || "").match(/L0*(\d+)/i);
|
|
27494
|
+
const lessonIdx = lessonIdxMatch ? parseInt(lessonIdxMatch[1], 10) : 1;
|
|
27495
|
+
const isEarlyLesson = lessonIdx <= 4;
|
|
27496
|
+
const zpdCeilingRule = isEarlyLesson ? `- \u{1F6D1} ZPD COMPLEXITY CEILING (FOUNDATIONAL LESSON #${lessonIdx}):
|
|
27497
|
+
\u2022 SCOPE LOCK: This is an early foundational lesson. The extension challenge MUST focus on creative design variations, parameterization, or edge cases of the current lesson concepts ONLY.
|
|
27498
|
+
\u2022 STRICTLY FORBIDDEN: NEVER introduce advanced mechanisms from future lessons (No complex event buses, No remote network/API calls, No persistent databases, No async concurrency, No out-of-scope hardware/sensors).` : `- \u{1F680} ZPD ADVANCED CHALLENGE (LESSON #${lessonIdx}):
|
|
27499
|
+
\u2022 Focus on architectural edge cases, algorithmic optimization, and synthesis of learned concepts up to Lesson #${lessonIdx}.`;
|
|
27500
|
+
return `
|
|
27501
|
+
### \u{1F680} EXTENSION CHALLENGE ARCHITECTURE INVARIANTS:
|
|
27502
|
+
${zpdCeilingRule}
|
|
27503
|
+
1. **STRUCTURED 3-TIER CHALLENGES**:
|
|
27504
|
+
- Challenge 1 (Mission Briefing): High-stakes real-world scenario applying today's concepts.
|
|
27505
|
+
- Challenge 2 (Architectural Constraints & Edge Cases): Deeper technical rules without violating prerequisite boundaries.
|
|
27506
|
+
- Challenge 3 (Extension Milestones): Progressive milestones (Level 1: Novice \u2192 Level 2: Advanced \u2192 Level 3: Master).
|
|
27507
|
+
2. **METACOGNITIVE & ENGINEERING TRADE-OFFS**:
|
|
27508
|
+
- Explicit reflection prompts evaluating architectural choices, code maintainability, and design patterns.`;
|
|
27509
|
+
}
|
|
27343
27510
|
case "lesson": {
|
|
27344
27511
|
const lessonDuration = cfg.lessonDuration || 90;
|
|
27345
27512
|
const pedagogicalModel = cfg.pedagogicalModel || req.pedagogy || "5e";
|
|
@@ -31163,6 +31330,7 @@ exports.buildCurriculumContext = buildCurriculumContext;
|
|
|
31163
31330
|
exports.buildCurriculumPlan = buildCurriculumPlan;
|
|
31164
31331
|
exports.buildDeliveryPackages = buildDeliveryPackages;
|
|
31165
31332
|
exports.buildDiagnosticQuizPrompt = buildDiagnosticQuizPrompt;
|
|
31333
|
+
exports.buildDomainLexiconGuardrail = buildDomainLexiconGuardrail;
|
|
31166
31334
|
exports.buildExpositionContext = buildExpositionContext;
|
|
31167
31335
|
exports.buildExpositionExcerpt = buildExpositionExcerpt;
|
|
31168
31336
|
exports.buildExtensionPrompt = buildExtensionPrompt;
|
|
@@ -31213,6 +31381,7 @@ exports.extractSectionHeadingsFromSLC = extractSectionHeadingsFromSLC;
|
|
|
31213
31381
|
exports.extractSessionSlice = extractSessionSlice;
|
|
31214
31382
|
exports.extractStandardRefs = extractStandardRefs;
|
|
31215
31383
|
exports.extractStreamChunk = extractStreamChunk;
|
|
31384
|
+
exports.extractSymbolLedger = extractSymbolLedger;
|
|
31216
31385
|
exports.extractThoughtAndContent = extractThoughtAndContent;
|
|
31217
31386
|
exports.findStandardStatement = findStandardStatement;
|
|
31218
31387
|
exports.formatQuizzesToCsv = formatQuizzesToCsv;
|