@thanh01.pmt/curriculum-kit 1.4.9 → 1.4.11
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/ai/index.cjs +5 -0
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.mjs +5 -0
- package/dist/ai/index.mjs.map +1 -1
- package/dist/index.cjs +59 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.mjs +59 -12
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +23 -22
- package/LICENSE +0 -21
package/dist/index.cjs
CHANGED
|
@@ -5459,6 +5459,11 @@ Every slide MUST include notes with:
|
|
|
5459
5459
|
- Cold-Call: 1 check question
|
|
5460
5460
|
- Scaffolding Tip: 1 analogy or hint
|
|
5461
5461
|
|
|
5462
|
+
### \u26A0\uFE0F STRICT SLIDE FORMATTING INVARIANTS:
|
|
5463
|
+
1. Every slide MUST store its content fields inside "slots": { ... }. NEVER put "title", "content", or points at the top level of a slide!
|
|
5464
|
+
2. All code slots MUST contain real, executable, high-fidelity code. Never use placeholders like "<CODE>" or "...".
|
|
5465
|
+
3. All point and card slots MUST contain concrete, rich pedagogical explanations. Never use placeholder dots or empty cards.
|
|
5466
|
+
|
|
5462
5467
|
### Output JSON Format:
|
|
5463
5468
|
\`\`\`json
|
|
5464
5469
|
{
|
|
@@ -25326,10 +25331,15 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
25326
25331
|
const isHtmlEngine = options.slidesEngine === "html";
|
|
25327
25332
|
if (isHtmlEngine) {
|
|
25328
25333
|
let presentationKitAi = null;
|
|
25334
|
+
let presentationKitCore = null;
|
|
25329
25335
|
try {
|
|
25330
25336
|
presentationKitAi = await import('@thanh01.pmt/presentation-kit/ai');
|
|
25331
25337
|
} catch {
|
|
25332
25338
|
}
|
|
25339
|
+
try {
|
|
25340
|
+
presentationKitCore = await import('@thanh01.pmt/presentation-kit');
|
|
25341
|
+
} catch {
|
|
25342
|
+
}
|
|
25333
25343
|
const slidePrompt = buildHtmlDeckSlidePrompt({
|
|
25334
25344
|
lessonCode,
|
|
25335
25345
|
lessonTitle,
|
|
@@ -25364,12 +25374,21 @@ ${glossaryContext}` : void 0,
|
|
|
25364
25374
|
const candidate = fenceMatch ? fenceMatch[1] : str;
|
|
25365
25375
|
return candidate.trim();
|
|
25366
25376
|
};
|
|
25377
|
+
const normalizeDeckSlides = (deck) => {
|
|
25378
|
+
const normalizer = presentationKitCore?.normalizeSlideSlots || presentationKitAi?.normalizeSlideSlots;
|
|
25379
|
+
if (deck && Array.isArray(deck.slides) && normalizer) {
|
|
25380
|
+
deck.slides = deck.slides.map((s) => normalizer(s));
|
|
25381
|
+
}
|
|
25382
|
+
return deck;
|
|
25383
|
+
};
|
|
25367
25384
|
try {
|
|
25368
25385
|
deckJson = JSON.parse(extractCleanJson(rawSlide));
|
|
25386
|
+
deckJson = normalizeDeckSlides(deckJson);
|
|
25369
25387
|
} catch {
|
|
25370
25388
|
try {
|
|
25371
25389
|
const { jsonrepair: jsonrepair2 } = await import('jsonrepair');
|
|
25372
25390
|
deckJson = JSON.parse(jsonrepair2(extractCleanJson(rawSlide)));
|
|
25391
|
+
deckJson = normalizeDeckSlides(deckJson);
|
|
25373
25392
|
} catch {
|
|
25374
25393
|
}
|
|
25375
25394
|
}
|
|
@@ -25391,11 +25410,13 @@ Fix ALL issues and output the complete corrected JSON object strictly matching t
|
|
|
25391
25410
|
);
|
|
25392
25411
|
try {
|
|
25393
25412
|
deckJson = JSON.parse(extractCleanJson(repairedRaw));
|
|
25413
|
+
deckJson = normalizeDeckSlides(deckJson);
|
|
25394
25414
|
validation = presentationKitAi.validateHtmlSlideDeck(deckJson, true);
|
|
25395
25415
|
} catch {
|
|
25396
25416
|
try {
|
|
25397
25417
|
const { jsonrepair: jsonrepair2 } = await import('jsonrepair');
|
|
25398
25418
|
deckJson = JSON.parse(jsonrepair2(extractCleanJson(repairedRaw)));
|
|
25419
|
+
deckJson = normalizeDeckSlides(deckJson);
|
|
25399
25420
|
validation = presentationKitAi.validateHtmlSlideDeck(deckJson, true);
|
|
25400
25421
|
} catch {
|
|
25401
25422
|
}
|
|
@@ -25423,9 +25444,10 @@ ${JSON.stringify(deckJson || {}, null, 2)}
|
|
|
25423
25444
|
const deckJsonStr = JSON.stringify(deckJson, null, 2);
|
|
25424
25445
|
await storage.saveArtifact(projectId, `_content/${unitCode}/SLIDE_${lessonCode}.deck.json`, deckJsonStr);
|
|
25425
25446
|
producedArtifacts.push(`SLIDE_${lessonCode}.deck.json`);
|
|
25426
|
-
|
|
25447
|
+
const compiler = presentationKitCore?.compileHtmlDeck || presentationKitAi?.compileHtmlDeck;
|
|
25448
|
+
if (compiler) {
|
|
25427
25449
|
try {
|
|
25428
|
-
const compiled =
|
|
25450
|
+
const compiled = compiler(deckJson);
|
|
25429
25451
|
if (compiled?.html) {
|
|
25430
25452
|
await storage.saveArtifact(projectId, `_content/${unitCode}/SLIDE_${lessonCode}.html`, compiled.html);
|
|
25431
25453
|
producedArtifacts.push(`SLIDE_${lessonCode}.html`);
|
|
@@ -27302,13 +27324,13 @@ var DeterministicPipelineRunner = class {
|
|
|
27302
27324
|
|
|
27303
27325
|
// src/services/prefillService.ts
|
|
27304
27326
|
init_streamRunner();
|
|
27305
|
-
var DEFAULT_STREAM_IDLE_MS =
|
|
27327
|
+
var DEFAULT_STREAM_IDLE_MS = 18e4;
|
|
27306
27328
|
var DEFAULT_STREAM_TOTAL_MS = 48e4;
|
|
27307
27329
|
var LAYER_IDLE_BUDGET_MS = {
|
|
27308
|
-
1:
|
|
27309
|
-
2:
|
|
27330
|
+
1: 18e4,
|
|
27331
|
+
2: 18e4,
|
|
27310
27332
|
3: 18e4
|
|
27311
|
-
//
|
|
27333
|
+
// 3 minutes idle protection across all layers for free-tier reasoning models
|
|
27312
27334
|
};
|
|
27313
27335
|
var LAYER_TOTAL_BUDGET_MS = {
|
|
27314
27336
|
1: 48e4,
|
|
@@ -27369,10 +27391,20 @@ function extractStreamChunk(part) {
|
|
|
27369
27391
|
}
|
|
27370
27392
|
return {};
|
|
27371
27393
|
}
|
|
27372
|
-
function createStreamAbortSignal(budget) {
|
|
27394
|
+
function createStreamAbortSignal(budget, parentSignal) {
|
|
27373
27395
|
const controller = new AbortController();
|
|
27374
27396
|
let idleTimer = null;
|
|
27375
27397
|
let totalTimer = null;
|
|
27398
|
+
const onParentAbort = () => {
|
|
27399
|
+
controller.abort(parentSignal?.reason || new Error("Aborted by parent signal"));
|
|
27400
|
+
};
|
|
27401
|
+
if (parentSignal) {
|
|
27402
|
+
if (parentSignal.aborted) {
|
|
27403
|
+
controller.abort(parentSignal.reason || new Error("Parent signal already aborted"));
|
|
27404
|
+
} else {
|
|
27405
|
+
parentSignal.addEventListener("abort", onParentAbort, { once: true });
|
|
27406
|
+
}
|
|
27407
|
+
}
|
|
27376
27408
|
const armIdle = () => {
|
|
27377
27409
|
if (idleTimer) clearTimeout(idleTimer);
|
|
27378
27410
|
if (budget.idleMs > 0) {
|
|
@@ -27399,6 +27431,9 @@ function createStreamAbortSignal(budget) {
|
|
|
27399
27431
|
dispose: () => {
|
|
27400
27432
|
if (idleTimer) clearTimeout(idleTimer);
|
|
27401
27433
|
if (totalTimer) clearTimeout(totalTimer);
|
|
27434
|
+
if (parentSignal) {
|
|
27435
|
+
parentSignal.removeEventListener("abort", onParentAbort);
|
|
27436
|
+
}
|
|
27402
27437
|
idleTimer = null;
|
|
27403
27438
|
totalTimer = null;
|
|
27404
27439
|
}
|
|
@@ -27510,7 +27545,7 @@ function safeParseJson(rawText) {
|
|
|
27510
27545
|
}
|
|
27511
27546
|
return null;
|
|
27512
27547
|
}
|
|
27513
|
-
async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onChunk, preferredModel, preferredProvider, budget) {
|
|
27548
|
+
async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onChunk, preferredModel, preferredProvider, budget, signal) {
|
|
27514
27549
|
const alibabaKey = apiKeys.alibaba || apiKeys.dashscope || process.env.ALIBABA_API_KEY || process.env.DASHSCOPE_API_KEY;
|
|
27515
27550
|
const nvidiaKey = apiKeys.nvidia || process.env.NVIDIA_API_KEY;
|
|
27516
27551
|
const deepseekKey = apiKeys.deepseek || process.env.DEEPSEEK_API_KEY;
|
|
@@ -27542,7 +27577,6 @@ async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onC
|
|
|
27542
27577
|
const nemotronModels = [
|
|
27543
27578
|
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
27544
27579
|
"nvidia/nemotron-3.5-lightning-30b-a3b",
|
|
27545
|
-
"nvidia/nemotron-3-super-120b-a12b",
|
|
27546
27580
|
"nvidia/llama-3.1-nemotron-70b-instruct"
|
|
27547
27581
|
].filter((m) => isModelAllowed(m));
|
|
27548
27582
|
for (const m of nemotronModels) {
|
|
@@ -27593,8 +27627,12 @@ THINKING DIRECTIVE: Do ALL your reasoning internally BEFORE emitting output. Do
|
|
|
27593
27627
|
totalMs: budget?.totalMs ?? DEFAULT_STREAM_TOTAL_MS
|
|
27594
27628
|
};
|
|
27595
27629
|
for (const candidate of candidates) {
|
|
27630
|
+
if (signal?.aborted) {
|
|
27631
|
+
console.log(`[curriculum-kit:VercelAI] AbortSignal already aborted, cancelling candidate loop.`);
|
|
27632
|
+
break;
|
|
27633
|
+
}
|
|
27596
27634
|
const t0 = Date.now();
|
|
27597
|
-
const abort = createStreamAbortSignal(resolvedBudget);
|
|
27635
|
+
const abort = createStreamAbortSignal(resolvedBudget, signal);
|
|
27598
27636
|
try {
|
|
27599
27637
|
const modelInstance = getAIModel({
|
|
27600
27638
|
provider: candidate.provider,
|
|
@@ -27626,6 +27664,13 @@ THINKING DIRECTIVE: Do ALL your reasoning internally BEFORE emitting output. Do
|
|
|
27626
27664
|
}
|
|
27627
27665
|
} catch (e) {
|
|
27628
27666
|
console.warn(`[curriculum-kit:VercelAI] Candidate ${candidate.provider} (${candidate.model}) failed in ${Date.now() - t0}ms:`, e?.message || e);
|
|
27667
|
+
const isClientAborted = Boolean(
|
|
27668
|
+
signal?.aborted || e?.name === "AbortError" && signal?.aborted || e?.message && (e.message.includes("Controller is already closed") || e.message.includes("The operation was aborted") || e.message.includes("Aborted by parent signal"))
|
|
27669
|
+
);
|
|
27670
|
+
if (isClientAborted) {
|
|
27671
|
+
console.log(`[curriculum-kit:VercelAI] Client aborted or stream closed, halting candidate fallback loop.`);
|
|
27672
|
+
break;
|
|
27673
|
+
}
|
|
27629
27674
|
} finally {
|
|
27630
27675
|
abort.dispose();
|
|
27631
27676
|
}
|
|
@@ -27677,7 +27722,8 @@ Return concise JSON matching:
|
|
|
27677
27722
|
totalMs: options.timeoutMs,
|
|
27678
27723
|
model: options.model,
|
|
27679
27724
|
provider: options.provider
|
|
27680
|
-
})
|
|
27725
|
+
}),
|
|
27726
|
+
options.signal
|
|
27681
27727
|
);
|
|
27682
27728
|
let parsedResearch = {
|
|
27683
27729
|
groundTruthSummary: `Verified ecosystem standards for ${projectName}`,
|
|
@@ -27887,7 +27933,8 @@ REQUIREMENT: Synthesize ALL parameters above \u2014 every single line in FULL AC
|
|
|
27887
27933
|
totalMs: options.timeoutMs,
|
|
27888
27934
|
model: options.model,
|
|
27889
27935
|
provider: options.provider
|
|
27890
|
-
})
|
|
27936
|
+
}),
|
|
27937
|
+
options.signal
|
|
27891
27938
|
);
|
|
27892
27939
|
const parsed = safeParseJson(rawContent);
|
|
27893
27940
|
return {
|