@thanh01.pmt/curriculum-kit 1.0.6 → 1.0.7

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
@@ -4,7 +4,7 @@ import { z } from 'zod';
4
4
  import { createGoogleGenerativeAI } from '@ai-sdk/google';
5
5
  import { createOpenAI } from '@ai-sdk/openai';
6
6
  import { createDeepSeek } from '@ai-sdk/deepseek';
7
- import { generateObject, streamObject } from 'ai';
7
+ import { generateObject, streamObject, streamText } from 'ai';
8
8
  import pLimit from 'p-limit';
9
9
  import fsPromises from 'fs/promises';
10
10
  import crypto, { createHash } from 'crypto';
@@ -12,8 +12,7 @@ import { createClient } from '@supabase/supabase-js';
12
12
  import { fileURLToPath } from 'url';
13
13
  import { jsonrepair } from 'jsonrepair';
14
14
  import { Octokit } from '@octokit/rest';
15
- import * as workflowPkg from 'workflow';
16
- import { getStepMetadata, RetryableError, sleep } from 'workflow';
15
+ import { defineHook, getStepMetadata, RetryableError, sleep } from 'workflow';
17
16
 
18
17
  var __defProp = Object.defineProperty;
19
18
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -9547,14 +9546,14 @@ init_errors();
9547
9546
 
9548
9547
  // src/workflow/gateSettings.ts
9549
9548
  var DEFAULT_GATE_SETTINGS = Object.freeze({
9550
- LEARNER_PROFILE: "HITL",
9551
- PROJECT_BRIEF: "HITL",
9552
- REFERENCE_PACK: "HITL",
9553
- CURRICULUM_FRAMEWORK: "HITL",
9554
- KNOWLEDGE_EXPOSITION: "LLM_JUDGE",
9555
- STYLE_GUIDE: "HITL",
9556
- ART_DIRECTION: "HITL",
9557
- LESSON: "LLM_JUDGE",
9549
+ LEARNER_PROFILE: "OFF",
9550
+ PROJECT_BRIEF: "OFF",
9551
+ REFERENCE_PACK: "OFF",
9552
+ CURRICULUM_FRAMEWORK: "OFF",
9553
+ KNOWLEDGE_EXPOSITION: "OFF",
9554
+ STYLE_GUIDE: "OFF",
9555
+ ART_DIRECTION: "OFF",
9556
+ LESSON: "OFF",
9558
9557
  ACT: "OFF",
9559
9558
  QUIZ: "OFF",
9560
9559
  SLIDE: "OFF",
@@ -9562,7 +9561,7 @@ var DEFAULT_GATE_SETTINGS = Object.freeze({
9562
9561
  WKS: "OFF",
9563
9562
  HANDOUT: "OFF",
9564
9563
  EXT: "OFF",
9565
- CODE: "LLM_JUDGE",
9564
+ CODE: "OFF",
9566
9565
  MEDIA_SCRIPT: "OFF",
9567
9566
  EXIT_TICKET: "OFF"
9568
9567
  });
@@ -11451,9 +11450,10 @@ Fix ALL issues above and output the complete corrected document.` }],
11451
11450
  const taskState = pipelineState.tasks[lessonCode] || {};
11452
11451
  const currentLessonInfo = taskState.LESSON;
11453
11452
  const lessonGate = gateModeFor(gates, "LESSON");
11454
- let isLessonApproved = lessonGate !== "HITL" || // OFF/LLM_JUDGE: không cần duyệt người
11455
- currentLessonInfo?.state === "approved" || currentLessonInfo?.review?.decision === "APPROVED" || approvedArtifacts.includes("LESSON") || approvedArtifacts.includes(lessonCode);
11456
- if (lessonGate === "LLM_JUDGE" && !isLessonApproved && lessonContent) {
11453
+ const humanApproved = currentLessonInfo?.state === "approved" || currentLessonInfo?.review?.decision === "APPROVED" || approvedArtifacts.includes("LESSON") || approvedArtifacts.includes(lessonCode);
11454
+ const needsJudge = lessonGate === "LLM_JUDGE" && !humanApproved;
11455
+ let isLessonApproved = lessonGate === "OFF" || humanApproved;
11456
+ if (needsJudge && lessonContent) {
11457
11457
  onProgress?.("@reviewer", `\u{1F916} Executing LLM-as-Judge academic evaluation on LESSON_${lessonCode}.md...`);
11458
11458
  try {
11459
11459
  let injectYamlReviewMetadata2 = function(content, meta) {
@@ -12492,6 +12492,8 @@ async function generateSingleArtifact(req) {
12492
12492
  extraContext,
12493
12493
  config,
12494
12494
  contextSot = {},
12495
+ mediaPolicy,
12496
+ researchContext,
12495
12497
  options = {},
12496
12498
  onChunk
12497
12499
  } = req;
@@ -12529,7 +12531,10 @@ ${langRule}
12529
12531
  3. PEDAGOGICAL GROUNDING: Strictly align with the ${pedagogy.toUpperCase()} model, Bloom's Revised Taxonomy, and IEEE/ACM CS2023 guidelines.
12530
12532
  4. SCAFFOLDING LEVEL: "${scaffoldingLevel.toUpperCase()}".${scaffoldingRule}
12531
12533
  5. TARGET AUDIENCE: ${gradeLevel ? `Grade ${gradeLevel}, ` : ""}${targetAge} on ${hwStr}.${deviceRule}${classDynamicsRule}${extraContextRule}
12532
- 6. OUTPUT INTEGRITY: Output clean Markdown starting directly with YAML frontmatter. Do not wrap entire response in triple backticks.${artifactSpecializedPrompt}`;
12534
+ 6. OUTPUT INTEGRITY: Output clean Markdown starting directly with YAML frontmatter. Do not wrap entire response in triple backticks.${artifactSpecializedPrompt}${mediaPolicy ? `
12535
+
12536
+ 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).
12537
+ 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.` : ""}`;
12533
12538
  const userPrompt = `### CONTEXT GROUND TRUTH:
12534
12539
  - Topic / Concept Domain: "${topic}"
12535
12540
  - Lesson ID: "${lessonId || "ON_DEMAND"}"
@@ -12544,6 +12549,9 @@ ${selectedDevices ? `- Device Mode: "${selectedDevices}"
12544
12549
  ` : ""}${extraContext ? `- User Specific Guidance & Requirements: "${extraContext}"
12545
12550
  ` : ""}${config ? `- Full Task Config: ${JSON.stringify(config)}
12546
12551
  ` : ""}
12552
+ ${researchContext ? `### RESEARCH GROUND TRUTH (fact-checked context \u2014 \u01B0u ti\xEAn d\xF9ng, KH\xD4NG b\u1ECBa s\u1ED1 li\u1EC7u):
12553
+ ${researchContext.slice(0, 4e3)}
12554
+ ` : ""}
12547
12555
  ${contextSot.framework ? `### SOT CURRICULUM FRAMEWORK:
12548
12556
  ${contextSot.framework.slice(0, 1500)}
12549
12557
  ` : ""}
@@ -12584,13 +12592,171 @@ Generate the complete, thorough, publication-grade "${artifactType.toUpperCase()
12584
12592
  }
12585
12593
  );
12586
12594
  const { thought, content } = extractThoughtAndContent(rawResult);
12587
- return {
12588
- artifactType,
12589
- filename: meta.filename,
12590
- content: content || accumulatedContent,
12591
- persona: meta.persona,
12592
- thought: thought || accumulatedThought
12595
+ const finalContent = content || accumulatedContent;
12596
+ const finalThought = thought || accumulatedThought;
12597
+ const gates = resolveGateSettings(req.gateSettings);
12598
+ const kitGateType = {
12599
+ lesson: "LESSON",
12600
+ slide: "SLIDE",
12601
+ act: "ACT",
12602
+ quiz: "QUIZ",
12603
+ guide: "GUIDE",
12604
+ handout: "HANDOUT",
12605
+ worksheet: "WKS",
12606
+ ext: "EXT",
12607
+ codelab: "CODE",
12608
+ exit_ticket: "EXIT_TICKET"
12609
+ }[artifactType];
12610
+ const gateMode = kitGateType ? gateModeFor(gates, kitGateType) : "OFF";
12611
+ if (gateMode === "OFF") {
12612
+ return { artifactType, filename: meta.filename, content: finalContent, persona: meta.persona, thought: finalThought };
12613
+ }
12614
+ const injectReviewMeta = (doc, metaMap) => {
12615
+ const fm = doc.match(/^---\s*\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
12616
+ if (!fm) {
12617
+ return `---
12618
+ ${Object.entries(metaMap).map(([k, v]) => `${k}: "${v}"`).join("\n")}
12619
+ ---
12620
+
12621
+ ${doc}`;
12622
+ }
12623
+ let yaml = fm[1] ?? "";
12624
+ for (const [k, v] of Object.entries(metaMap)) {
12625
+ const re = new RegExp(`^${k}:.*$`, "m");
12626
+ if (re.test(yaml)) yaml = yaml.replace(re, `${k}: "${v}"`);
12627
+ else yaml += `
12628
+ ${k}: "${v}"`;
12629
+ }
12630
+ return doc.replace(fm[0], `---
12631
+ ${yaml.trim()}
12632
+ ---
12633
+ `);
12593
12634
  };
12635
+ if (gateMode === "HITL") {
12636
+ return {
12637
+ artifactType,
12638
+ filename: meta.filename,
12639
+ content: injectReviewMeta(finalContent, { review_status: "PENDING_REVIEW", review_decision: "PENDING" }),
12640
+ persona: meta.persona,
12641
+ thought: finalThought,
12642
+ pausedForReview: true,
12643
+ gateStatus: "awaiting_approval"
12644
+ };
12645
+ }
12646
+ const judgeObjectives = [{ code: "A1", description: `Artifact fulfills its pedagogical contract for topic "${topic}" with complete required sections`, bloomLevel: "Analyze" }];
12647
+ try {
12648
+ const verdict = await LLMJudgeEngine.evaluateArtifactWithLLM({
12649
+ targetArtifactType: artifactType.toUpperCase(),
12650
+ lessonId: lessonId || "ON_DEMAND",
12651
+ expectedLanguage: language.toLowerCase().includes("viet") ? "vietnamese" : "english",
12652
+ targetObjectives: judgeObjectives,
12653
+ generatedContentJson: JSON.stringify({ content: finalContent, artifactType, lessonId: lessonId || "ON_DEMAND", title: displayTitle })
12654
+ });
12655
+ const passed = Boolean(verdict.passed) && verdict.score >= 85;
12656
+ if (passed) {
12657
+ return {
12658
+ artifactType,
12659
+ filename: meta.filename,
12660
+ content: injectReviewMeta(finalContent, {
12661
+ review_status: "APPROVED",
12662
+ reviewed_by: "@reviewer (LLM-as-Judge)",
12663
+ review_decision: "APPROVED"
12664
+ }),
12665
+ persona: meta.persona,
12666
+ thought: finalThought,
12667
+ judgeScore: verdict.score,
12668
+ judgeCritique: verdict.critique
12669
+ };
12670
+ }
12671
+ const repairFeedback = [verdict.autoRepairInstructions, ...verdict.weaknesses || []].filter(Boolean).join("\n");
12672
+ const repairedRaw = await streamCurriculumAIInference(
12673
+ [
12674
+ { role: "user", content: `You previously authored \`${meta.filename}\` and the academic Judge REJECTED it with the critique below.
12675
+ Rewrite the COMPLETE corrected document: fix every listed issue, keep the mandatory structure, frontmatter and all approved sections. Output 100% clean Markdown only.
12676
+
12677
+ JUDGE CRITIQUE:
12678
+ ${repairFeedback}
12679
+
12680
+ CURRENT DOCUMENT:
12681
+ ${finalContent}` }
12682
+ ],
12683
+ userPrompt,
12684
+ { ...options, systemPersona: systemPrompt },
12685
+ (chunk, type) => {
12686
+ if (onChunk) onChunk(chunk, type === "thought" ? "thought" : "content");
12687
+ }
12688
+ );
12689
+ const repairedExtract = extractThoughtAndContent(repairedRaw);
12690
+ const repaired = repairedExtract.content || repairedRaw;
12691
+ if (repaired && repaired.trim().length > 100) {
12692
+ const reVerdict = await LLMJudgeEngine.evaluateArtifactWithLLM({
12693
+ targetArtifactType: artifactType.toUpperCase(),
12694
+ lessonId: lessonId || "ON_DEMAND",
12695
+ expectedLanguage: language.toLowerCase().includes("viet") ? "vietnamese" : "english",
12696
+ targetObjectives: judgeObjectives,
12697
+ generatedContentJson: JSON.stringify({ content: repaired, artifactType, lessonId: lessonId || "ON_DEMAND", title: displayTitle })
12698
+ });
12699
+ if (reVerdict.passed && reVerdict.score >= 85) {
12700
+ return {
12701
+ artifactType,
12702
+ filename: meta.filename,
12703
+ content: injectReviewMeta(repaired, {
12704
+ review_status: "APPROVED",
12705
+ reviewed_by: "@reviewer (LLM-as-Judge)",
12706
+ review_decision: "APPROVED"
12707
+ }),
12708
+ persona: meta.persona,
12709
+ thought: repairedExtract.thought || "",
12710
+ judgeScore: reVerdict.score,
12711
+ judgeCritique: reVerdict.critique
12712
+ };
12713
+ }
12714
+ return {
12715
+ artifactType,
12716
+ filename: meta.filename,
12717
+ content: injectReviewMeta(repaired, {
12718
+ review_status: "NEEDS_REVISION",
12719
+ reviewed_by: "@reviewer (LLM-as-Judge)",
12720
+ review_decision: "NEEDS_REVISION"
12721
+ }),
12722
+ persona: meta.persona,
12723
+ thought: repairedExtract.thought || "",
12724
+ pausedForReview: true,
12725
+ gateStatus: "judge_needs_revision",
12726
+ judgeScore: reVerdict.score,
12727
+ judgeCritique: reVerdict.critique
12728
+ };
12729
+ }
12730
+ return {
12731
+ artifactType,
12732
+ filename: meta.filename,
12733
+ content: injectReviewMeta(finalContent, {
12734
+ review_status: "NEEDS_REVISION",
12735
+ reviewed_by: "@reviewer (LLM-as-Judge)",
12736
+ review_decision: "NEEDS_REVISION"
12737
+ }),
12738
+ persona: meta.persona,
12739
+ thought: finalThought,
12740
+ pausedForReview: true,
12741
+ gateStatus: "judge_needs_revision",
12742
+ judgeScore: verdict.score,
12743
+ judgeCritique: verdict.critique
12744
+ };
12745
+ } catch (judgeErr) {
12746
+ return {
12747
+ artifactType,
12748
+ filename: meta.filename,
12749
+ content: injectReviewMeta(finalContent, {
12750
+ review_status: "NEEDS_REVISION",
12751
+ review_decision: "NEEDS_REVISION",
12752
+ critique: `Judge unavailable (fail-closed): ${String(judgeErr?.message || judgeErr).slice(0, 300)}`
12753
+ }),
12754
+ persona: meta.persona,
12755
+ thought: finalThought,
12756
+ pausedForReview: true,
12757
+ gateStatus: "judge_error"
12758
+ };
12759
+ }
12594
12760
  } catch (error) {
12595
12761
  throw createAiInferenceError({
12596
12762
  errorCode: "ERR_AI_ALL_PROVIDERS_FAILED",
@@ -13346,43 +13512,15 @@ function safeParseJson(rawText) {
13346
13512
  return null;
13347
13513
  }
13348
13514
  }
13349
- async function readSseStream(reader, decoder, onData) {
13350
- let buffer = "";
13351
- while (true) {
13352
- const { done, value } = await reader.read();
13353
- if (done) break;
13354
- buffer += decoder.decode(value, { stream: true });
13355
- const lines = buffer.split("\n");
13356
- buffer = lines.pop() || "";
13357
- for (const line of lines) {
13358
- const trimmed = line.trim();
13359
- if (!trimmed || trimmed.startsWith(":")) continue;
13360
- if (trimmed === "data: [DONE]") return;
13361
- if (trimmed.startsWith("data: ")) {
13362
- const dataStr = trimmed.slice(6).trim();
13363
- if (dataStr) onData(dataStr);
13364
- }
13365
- }
13366
- }
13367
- }
13368
13515
  async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onChunk) {
13369
- apiKeys.alibaba || apiKeys.dashscope || process.env.ALIBABA_API_KEY || process.env.DASHSCOPE_API_KEY;
13516
+ const alibabaKey = apiKeys.alibaba || apiKeys.dashscope || process.env.ALIBABA_API_KEY || process.env.DASHSCOPE_API_KEY;
13370
13517
  const nvidiaKey = apiKeys.nvidia || process.env.NVIDIA_API_KEY;
13371
- apiKeys.deepseek || process.env.DEEPSEEK_API_KEY;
13518
+ const deepseekKey = apiKeys.deepseek || process.env.DEEPSEEK_API_KEY;
13372
13519
  const openrouterKey = apiKeys.openrouter || process.env.OPENROUTER_API_KEY;
13373
- apiKeys.gemini || process.env.GEMINI_API_KEY;
13520
+ const geminiKey = apiKeys.gemini || process.env.GEMINI_API_KEY;
13374
13521
  const openrouterPreset = process.env.OPENROUTER_FREE_PRESET || "@preset/coding-free";
13375
- const messages = [
13376
- {
13377
- role: "system",
13378
- content: `${systemPrompt}
13379
-
13380
- THINKING DIRECTIVE: Keep reasoning concise, structured, and focused strictly on the core pedagogical trade-offs in 4-6 concise bullet points (under 120 words). Then output the JSON immediately.`
13381
- },
13382
- { role: "user", content: userPrompt }
13383
- ];
13522
+ const candidates = [];
13384
13523
  if (openrouterKey && isProviderEnabled("openrouter")) {
13385
- const t0 = Date.now();
13386
13524
  const orModels = [
13387
13525
  openrouterPreset,
13388
13526
  "openrouter/free",
@@ -13392,174 +13530,82 @@ THINKING DIRECTIVE: Keep reasoning concise, structured, and focused strictly on
13392
13530
  "minimax/minimax-m3:free",
13393
13531
  "cohere/north-mini-code:free"
13394
13532
  ].filter((m) => isModelAllowed(m));
13395
- const uniqueOrModels = Array.from(new Set(orModels));
13396
- for (const model of uniqueOrModels) {
13397
- try {
13398
- const controller = new AbortController();
13399
- const timeout = setTimeout(() => controller.abort(), 25e3);
13400
- const res = await fetch("https://openrouter.ai/api/v1/chat/completions", {
13401
- method: "POST",
13402
- headers: {
13403
- "Content-Type": "application/json",
13404
- "Authorization": `Bearer ${openrouterKey}`
13405
- },
13406
- body: JSON.stringify({
13407
- model,
13408
- messages,
13409
- stream: true,
13410
- temperature: 0.3
13411
- }),
13412
- signal: controller.signal
13413
- });
13414
- clearTimeout(timeout);
13415
- if (res.ok && res.body) {
13416
- const reader = res.body.getReader();
13417
- const decoder = new TextDecoder();
13418
- let fullContent = "";
13419
- await readSseStream(reader, decoder, (dataStr) => {
13420
- try {
13421
- const parsed = JSON.parse(dataStr);
13422
- const delta = parsed.choices?.[0]?.delta;
13423
- if (delta?.content) {
13424
- fullContent += delta.content;
13425
- onChunk?.(delta.content, "content");
13426
- }
13427
- } catch {
13428
- }
13429
- });
13430
- if (fullContent.trim()) {
13431
- console.log(`[curriculum-kit:LayerPrefill] \u2705 Tier 1 OpenRouter (${model}) streamed in ${Date.now() - t0}ms`);
13432
- return fullContent.trim();
13433
- }
13434
- }
13435
- } catch (e) {
13436
- console.warn(`[curriculum-kit:LayerPrefill] Tier 1 OpenRouter stream failed for ${model} in ${Date.now() - t0}ms:`, e?.message || e);
13437
- }
13533
+ for (const m of Array.from(new Set(orModels))) {
13534
+ candidates.push({ provider: "openrouter", model: m, apiKey: openrouterKey });
13438
13535
  }
13439
13536
  }
13440
13537
  if (nvidiaKey && isProviderEnabled("nvidia")) {
13441
- const t0 = Date.now();
13442
13538
  const nemotronModels = [
13443
13539
  "nvidia/nemotron-3-ultra-550b-a55b",
13444
13540
  "nvidia/nemotron-3.5-lightning-30b-a3b",
13445
13541
  "nvidia/nemotron-3-super-120b-a12b",
13446
13542
  "nvidia/llama-3.1-nemotron-70b-instruct"
13447
13543
  ].filter((m) => isModelAllowed(m));
13448
- for (const model of nemotronModels) {
13449
- try {
13450
- const controller = new AbortController();
13451
- const timeout = setTimeout(() => controller.abort(), 25e3);
13452
- const res = await fetch("https://integrate.api.nvidia.com/v1/chat/completions", {
13453
- method: "POST",
13454
- headers: {
13455
- "Content-Type": "application/json",
13456
- "Authorization": `Bearer ${nvidiaKey}`
13457
- },
13458
- body: JSON.stringify({
13459
- model,
13460
- messages,
13461
- stream: true,
13462
- temperature: 0.2
13463
- }),
13464
- signal: controller.signal
13465
- });
13466
- clearTimeout(timeout);
13467
- if (res.ok && res.body) {
13468
- const reader = res.body.getReader();
13469
- const decoder = new TextDecoder();
13470
- let fullContent = "";
13471
- await readSseStream(reader, decoder, (dataStr) => {
13472
- try {
13473
- const parsed = JSON.parse(dataStr);
13474
- const delta = parsed.choices?.[0]?.delta;
13475
- if (delta?.content) {
13476
- fullContent += delta.content;
13477
- onChunk?.(delta.content, "content");
13478
- }
13479
- } catch {
13480
- }
13481
- });
13482
- if (fullContent.trim()) {
13483
- console.log(`[curriculum-kit:LayerPrefill] \u2705 Tier 2 NVIDIA NIM (${model}) streamed in ${Date.now() - t0}ms`);
13484
- return fullContent.trim();
13485
- }
13486
- }
13487
- } catch (e) {
13488
- console.warn(`[curriculum-kit:LayerPrefill] Tier 2 NVIDIA NIM stream failed for ${model} in ${Date.now() - t0}ms:`, e?.message || e);
13489
- }
13544
+ for (const m of nemotronModels) {
13545
+ candidates.push({ provider: "nvidia", model: m, apiKey: nvidiaKey });
13546
+ }
13547
+ }
13548
+ if (alibabaKey && isProviderEnabled("alibaba")) {
13549
+ const aliModels = ["qwen-plus", "qwen-turbo", "qwen3.7-plus"].filter((m) => isModelAllowed(m));
13550
+ for (const m of aliModels) {
13551
+ candidates.push({ provider: "alibaba", model: m, apiKey: alibabaKey });
13552
+ }
13553
+ }
13554
+ if (deepseekKey && isProviderEnabled("deepseek")) {
13555
+ const dsModels = ["deepseek-chat", "deepseek-coder"].filter((m) => isModelAllowed(m));
13556
+ for (const m of dsModels) {
13557
+ candidates.push({ provider: "deepseek", model: m, apiKey: deepseekKey });
13558
+ }
13559
+ }
13560
+ if (geminiKey && (isProviderEnabled("gemini") || isProviderEnabled("google"))) {
13561
+ const gModels = ["gemini-1.5-flash", "gemini-2.0-flash", "gemini-1.5-pro"].filter((m) => isModelAllowed(m));
13562
+ for (const m of gModels) {
13563
+ candidates.push({ provider: "google", model: m, apiKey: geminiKey });
13490
13564
  }
13491
13565
  }
13492
13566
  const fallbackChain = getDesignatedFallbackChain();
13493
13567
  for (const target of fallbackChain) {
13494
- const { provider, model } = target;
13495
- if (provider === "nvidia" && nvidiaKey && isProviderEnabled("nvidia")) {
13496
- try {
13497
- const res = await fetch("https://integrate.api.nvidia.com/v1/chat/completions", {
13498
- method: "POST",
13499
- headers: {
13500
- "Content-Type": "application/json",
13501
- "Authorization": `Bearer ${nvidiaKey}`
13502
- },
13503
- body: JSON.stringify({
13504
- model,
13505
- messages,
13506
- stream: true,
13507
- temperature: 0.2
13508
- })
13509
- });
13510
- if (res.ok && res.body) {
13511
- const reader = res.body.getReader();
13512
- const decoder = new TextDecoder();
13513
- let fullContent = "";
13514
- await readSseStream(reader, decoder, (dataStr) => {
13515
- try {
13516
- const parsed = JSON.parse(dataStr);
13517
- const delta = parsed.choices?.[0]?.delta;
13518
- if (delta?.content) {
13519
- fullContent += delta.content;
13520
- onChunk?.(delta.content, "content");
13521
- }
13522
- } catch {
13523
- }
13524
- });
13525
- if (fullContent.trim()) return fullContent.trim();
13568
+ if (!candidates.some((c) => c.provider === target.provider && c.model === target.model)) {
13569
+ candidates.push({
13570
+ provider: target.provider,
13571
+ model: target.model,
13572
+ apiKey: apiKeys[target.provider]
13573
+ });
13574
+ }
13575
+ }
13576
+ const systemInstructions = `${systemPrompt}
13577
+
13578
+ THINKING DIRECTIVE: Keep reasoning concise, structured, and focused strictly on the core pedagogical trade-offs in 4-6 concise bullet points (under 120 words). Then output the JSON immediately.`;
13579
+ for (const candidate of candidates) {
13580
+ const t0 = Date.now();
13581
+ try {
13582
+ const modelInstance = getAIModel({
13583
+ provider: candidate.provider,
13584
+ modelName: candidate.model,
13585
+ apiKey: candidate.apiKey
13586
+ });
13587
+ const streamResult = streamText({
13588
+ model: modelInstance,
13589
+ system: systemInstructions,
13590
+ prompt: userPrompt,
13591
+ temperature: 0.2,
13592
+ abortSignal: AbortSignal.timeout(25e3)
13593
+ });
13594
+ let fullContent = "";
13595
+ for await (const part of streamResult.fullStream) {
13596
+ if (part.type === "reasoning-delta") {
13597
+ onChunk?.(part.text, "thought");
13598
+ } else if (part.type === "text-delta") {
13599
+ fullContent += part.text;
13600
+ onChunk?.(part.text, "content");
13526
13601
  }
13527
- } catch {
13528
13602
  }
13529
- } else if (provider === "openrouter" && openrouterKey && isProviderEnabled("openrouter")) {
13530
- try {
13531
- const res = await fetch("https://openrouter.ai/api/v1/chat/completions", {
13532
- method: "POST",
13533
- headers: {
13534
- "Content-Type": "application/json",
13535
- "Authorization": `Bearer ${openrouterKey}`
13536
- },
13537
- body: JSON.stringify({
13538
- model,
13539
- messages,
13540
- stream: true,
13541
- temperature: 0.2
13542
- })
13543
- });
13544
- if (res.ok && res.body) {
13545
- const reader = res.body.getReader();
13546
- const decoder = new TextDecoder();
13547
- let fullContent = "";
13548
- await readSseStream(reader, decoder, (dataStr) => {
13549
- try {
13550
- const parsed = JSON.parse(dataStr);
13551
- const delta = parsed.choices?.[0]?.delta;
13552
- if (delta?.content) {
13553
- fullContent += delta.content;
13554
- onChunk?.(delta.content, "content");
13555
- }
13556
- } catch {
13557
- }
13558
- });
13559
- if (fullContent.trim()) return fullContent.trim();
13560
- }
13561
- } catch {
13603
+ if (fullContent.trim()) {
13604
+ console.log(`[curriculum-kit:VercelAI] \u2705 ${candidate.provider} (${candidate.model}) streamed in ${Date.now() - t0}ms`);
13605
+ return fullContent.trim();
13562
13606
  }
13607
+ } catch (e) {
13608
+ console.warn(`[curriculum-kit:VercelAI] Candidate ${candidate.provider} (${candidate.model}) failed in ${Date.now() - t0}ms:`, e?.message || e);
13563
13609
  }
13564
13610
  }
13565
13611
  return null;
@@ -14727,10 +14773,10 @@ var approvalPayloadSchema = z.object({
14727
14773
  feedback: z.string().optional().describe("Actionable feedback or required changes if rejected"),
14728
14774
  timestamp: z.string().optional().describe("ISO timestamp of the approval action")
14729
14775
  });
14730
- var hookFactory = workflowPkg.defineHook || workflowPkg.createHook || ((opts) => opts);
14731
- var lessonApprovalHook = hookFactory({
14732
- schema: approvalPayloadSchema
14733
- });
14776
+ var lessonApprovalHook = defineHook();
14777
+ function approvalHookToken(projectId, lessonId, artifactType) {
14778
+ return `approval:${projectId}:${lessonId}:${artifactType}`;
14779
+ }
14734
14780
 
14735
14781
  // src/standards/standardsCoverageGate.ts
14736
14782
  function resolveStatementRef(ref, packs) {
@@ -15080,9 +15126,9 @@ async function generateMilestoneWorkflow(input) {
15080
15126
  } else if (lessonGate === "HITL") {
15081
15127
  const hookToken = "gate:lesson:" + milestoneId;
15082
15128
  console.log(" \u23F8 [Gate] LESSON awaiting HUMAN review (HITL) \u2014 hook " + hookToken);
15083
- const workflowPkg2 = await import('workflow');
15084
- const createHook2 = workflowPkg2.createHook;
15085
- const hook = createHook2({ token: hookToken });
15129
+ const workflowPkg = await import('workflow');
15130
+ const createHook = workflowPkg.createHook;
15131
+ const hook = createHook({ token: hookToken });
15086
15132
  const review = await hook;
15087
15133
  console.log(" \u2705 [Gate] Human verdict: " + (review.approved ? "APPROVED" : "REJECTED") + (review.feedback ? " \u2014 " + review.feedback : ""));
15088
15134
  if (!review.approved) {
@@ -15102,7 +15148,7 @@ async function generateMilestoneWorkflow(input) {
15102
15148
  standardsContext: standardsContext || void 0,
15103
15149
  modelOptions: input.modelOptions
15104
15150
  });
15105
- const hook2 = createHook2({ token: hookToken + ":v2" });
15151
+ const hook2 = createHook({ token: hookToken + ":v2" });
15106
15152
  const review2 = await hook2;
15107
15153
  console.log(" \u2705 [Gate] Human verdict (v2): " + (review2.approved ? "APPROVED" : "REJECTED"));
15108
15154
  if (!review2.approved) {
@@ -16712,6 +16758,36 @@ var MediaLedger = class {
16712
16758
  doneCount() {
16713
16759
  return this.listByStatus("done").length;
16714
16760
  }
16761
+ /**
16762
+ * Scan artifact content và seed pending entries cho mọi placeholder [IMAGE: slug].
16763
+ * Được gọi sau khi agent sinh artifact (trước khi Curator duyệt) — đây là cầu nối
16764
+ * duy nhất giữa "agent chèn placeholder" và "sổ cái có entry để Curator/Fulfiller xử".
16765
+ * Idempotent: slug đã có entry active (pending/approved/done) → giữ nguyên;
16766
+ * chỉ re-describe khi entry trước bị rejected/failed.
16767
+ */
16768
+ seedFromArtifact(artifactId, content) {
16769
+ const seeded = [];
16770
+ const re = /\[IMAGE\s*:\s*([a-z0-9][a-z0-9-]*)\s*\]/gi;
16771
+ const seen = /* @__PURE__ */ new Set();
16772
+ let m;
16773
+ while ((m = re.exec(content)) !== null) {
16774
+ const slug = m[1].toLowerCase();
16775
+ if (seen.has(slug)) continue;
16776
+ seen.add(slug);
16777
+ const existing = this.entries.get(slug);
16778
+ const isActive = existing && (existing.status === "pending" || existing.status === "approved" || existing.status === "done");
16779
+ if (isActive) continue;
16780
+ seeded.push(this.upsert({
16781
+ slug,
16782
+ artifactId,
16783
+ name: slug.replace(/^(img-|image-)/, "").replace(/-/g, " "),
16784
+ description: `Placeholder ch\xE8n b\u1EDFi agent trong artifact ${artifactId} \u2014 ch\u1EDD Curator enrich (m\xF4 t\u1EA3 g\u1ED1c ch\u01B0a c\xF3).`,
16785
+ mode: "generate",
16786
+ status: "pending"
16787
+ }));
16788
+ }
16789
+ return seeded;
16790
+ }
16715
16791
  };
16716
16792
 
16717
16793
  // src/media/curator.ts
@@ -16942,6 +17018,6 @@ function renderMediaPlaceholder(entry) {
16942
17018
  return `> \u{1F5BC}\uFE0F [\u1EA2nh \u0111ang ch\u1EDD: ${entry.name} \u2014 s\u1EBD \u0111\u01B0\u1EE3c t\u1EA1o sau khi duy\u1EC7t media]`;
16943
17019
  }
16944
17020
 
16945
- 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_ENABLED_PROVIDERS, DEFAULT_GATE_SETTINGS, 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, 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, approvalPayloadSchema, assertAcyclic, assessorTools, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildExpositionContext, buildExtensionPrompt, buildHandoutPrompt, buildImagePrompt, buildJudgePrompt, buildLessonMasterPrompt, buildProjectInstructionPrompt, buildSelfLabPrompt, buildSessionSliceContext, buildSlidesPrompt, buildStandardStackMarkdown, buildStandardsContext, buildStandardsContextBlock, buildTeacherGuidePrompt, buildWorksheetPrompt, computeContentHash, computePackingSpec, conductPreliminaryResearch, contentTools, convertRoadmapToFoundationSot, createAiInferenceError, createCurriculumStorage, curateMediaLedger, designerTools, detectProjectPedagogy, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateStandardsCoverage, executeCurriculumCommand, executeSingleArtifactStep, exportAllProjectQuizzes, expositionCacheKey, extractScopeSequenceRows, extractSessionSlice, extractThoughtAndContent, formatQuizzesToCsv, fulfillMediaLedger, gateModeFor, generateActivityFlow, generateActivityStep, generateCodeLabFlow, generateCodeLabStep, generateDiagnosticQuizFlow, generateDiagnosticQuizStep, generateEducationalImage, generateExtensionFlow, generateExtensionStep, generateHandoutFlow, generateHandoutStep, generateLessonMasterFlow, generateMasterLessonStep, generateMilestoneCurriculumBundle, generateMilestoneWorkflow, generatePhase1SotArtifacts, generatePhase2SotArtifacts, generateProjectInstruction, generateProjectInstructionFlow, generateRoadmapCurriculum, generateRoadmapWorkflow, generateSelfLabFlow, generateSelfLabStep, generateSelfPacedBundle, generateSingleArtifact, generateSingleArtifactWorkflow, generateSlidesFlow, generateSlidesStep, generateTeacherGuideFlow, generateTeacherGuideStep, generateWorksheetFlow, generateWorksheetStep, getAIModel, getArtifactMetadata, getDesignatedFallbackChain, getDesignatedFallbackConfig, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, illustratorTools, importRoadmapToProject, ingestProjectGraphIntoProject, initializeProjectInStorage, injectMediaIntoMarkdown, isExpositionFresh, isModelAllowed, isProviderEnabled, isTranslationDue, judgeMasterLessonStep, judgeSatelliteStep, lessonApprovalHook, lintAndSanitizeArtifact, lintCurriculumFramework, lintFrameworkPack, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, packagerTools, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToGitStep, publishToSupabase, publishToSupabaseStep, rankGenCandidates, renderFrameworkFromPlan, renderMediaPlaceholder, repairMasterLessonStep, researcherTools, resolveGateSettings, resolveStandardsPacks, resolveTranslationTargets, reviewerTools, runCurriculumAIInference, safeParseJson, saveMilestoneToWorkspaceStep, searchEducationalImages, searchEducationalVideos, selectStatementsForLesson, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, slugifyProjectName, streamCurriculumAIInference, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLLMWithFallback, streamLayerPrefillWithFallback, streamLessonMasterFlow, streamSelfLabFlow, techSmeTools, topoSort, uploadAssetToBucket, validateCurriculumPlan, validateFrameworkPack, validateMarkdownTables, validateMermaidSyntax, withAutoRepair, withRateLimitBackoff };
17021
+ 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_ENABLED_PROVIDERS, DEFAULT_GATE_SETTINGS, 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, 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, approvalHookToken, approvalPayloadSchema, assertAcyclic, assessorTools, auditCurriculumQualityFlow, auditQualityReport, buildActivityPrompt, buildCodeLabPrompt, buildCurriculumContext, buildCurriculumPlan, buildDeliveryPackages, buildDiagnosticQuizPrompt, buildExpositionContext, buildExtensionPrompt, buildHandoutPrompt, buildImagePrompt, buildJudgePrompt, buildLessonMasterPrompt, buildProjectInstructionPrompt, buildSelfLabPrompt, buildSessionSliceContext, buildSlidesPrompt, buildStandardStackMarkdown, buildStandardsContext, buildStandardsContextBlock, buildTeacherGuidePrompt, buildWorksheetPrompt, computeContentHash, computePackingSpec, conductPreliminaryResearch, contentTools, convertRoadmapToFoundationSot, createAiInferenceError, createCurriculumStorage, curateMediaLedger, designerTools, detectProjectPedagogy, ensureExpositionForLesson, ensureKnowledgeExposition, evaluateStandardsCoverage, executeCurriculumCommand, executeSingleArtifactStep, exportAllProjectQuizzes, expositionCacheKey, extractScopeSequenceRows, extractSessionSlice, extractThoughtAndContent, formatQuizzesToCsv, fulfillMediaLedger, gateModeFor, generateActivityFlow, generateActivityStep, generateCodeLabFlow, generateCodeLabStep, generateDiagnosticQuizFlow, generateDiagnosticQuizStep, generateEducationalImage, generateExtensionFlow, generateExtensionStep, generateHandoutFlow, generateHandoutStep, generateLessonMasterFlow, generateMasterLessonStep, generateMilestoneCurriculumBundle, generateMilestoneWorkflow, generatePhase1SotArtifacts, generatePhase2SotArtifacts, generateProjectInstruction, generateProjectInstructionFlow, generateRoadmapCurriculum, generateRoadmapWorkflow, generateSelfLabFlow, generateSelfLabStep, generateSelfPacedBundle, generateSingleArtifact, generateSingleArtifactWorkflow, generateSlidesFlow, generateSlidesStep, generateTeacherGuideFlow, generateTeacherGuideStep, generateWorksheetFlow, generateWorksheetStep, getAIModel, getArtifactMetadata, getDesignatedFallbackChain, getDesignatedFallbackConfig, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, illustratorTools, importRoadmapToProject, ingestProjectGraphIntoProject, initializeProjectInStorage, injectMediaIntoMarkdown, isExpositionFresh, isModelAllowed, isProviderEnabled, isTranslationDue, judgeMasterLessonStep, judgeSatelliteStep, lessonApprovalHook, lintAndSanitizeArtifact, lintCurriculumFramework, lintFrameworkPack, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, packagerTools, parseGateSettings, parseQuizMarkdown, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, publishToGitHub, publishToGitStep, publishToSupabase, publishToSupabaseStep, rankGenCandidates, renderFrameworkFromPlan, renderMediaPlaceholder, repairMasterLessonStep, researcherTools, resolveGateSettings, resolveStandardsPacks, resolveTranslationTargets, reviewerTools, runCurriculumAIInference, safeParseJson, saveMilestoneToWorkspaceStep, searchEducationalImages, searchEducationalVideos, selectStatementsForLesson, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, slugifyProjectName, streamCurriculumAIInference, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLLMWithFallback, streamLayerPrefillWithFallback, streamLessonMasterFlow, streamSelfLabFlow, techSmeTools, topoSort, uploadAssetToBucket, validateCurriculumPlan, validateFrameworkPack, validateMarkdownTables, validateMermaidSyntax, withAutoRepair, withRateLimitBackoff };
16946
17022
  //# sourceMappingURL=index.mjs.map
16947
17023
  //# sourceMappingURL=index.mjs.map