@thanh01.pmt/curriculum-kit 1.0.12 → 1.0.13
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.cjs +102 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -2
- package/dist/index.d.ts +59 -2
- package/dist/index.mjs +97 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -13525,6 +13525,78 @@ var DeterministicPipelineRunner = class {
|
|
|
13525
13525
|
|
|
13526
13526
|
// src/services/prefillService.ts
|
|
13527
13527
|
init_streamRunner();
|
|
13528
|
+
var DEFAULT_STREAM_IDLE_MS = 45e3;
|
|
13529
|
+
var DEFAULT_STREAM_TOTAL_MS = 3e5;
|
|
13530
|
+
var LAYER_TOTAL_BUDGET_MS = {
|
|
13531
|
+
1: 18e4,
|
|
13532
|
+
2: 36e4,
|
|
13533
|
+
3: 36e4
|
|
13534
|
+
};
|
|
13535
|
+
function resolveStreamBudget(layer, opts) {
|
|
13536
|
+
const envIdle = Number(process.env.WIZARD_PREFILL_IDLE_TIMEOUT_MS);
|
|
13537
|
+
const envTotal = Number(process.env.WIZARD_PREFILL_TOTAL_TIMEOUT_MS);
|
|
13538
|
+
const layerTotal = layer !== void 0 ? LAYER_TOTAL_BUDGET_MS[layer] : void 0;
|
|
13539
|
+
return {
|
|
13540
|
+
idleMs: opts?.idleMs ?? (Number.isFinite(envIdle) && envIdle > 0 ? envIdle : DEFAULT_STREAM_IDLE_MS),
|
|
13541
|
+
totalMs: opts?.totalMs ?? (Number.isFinite(envTotal) && envTotal > 0 ? envTotal : layerTotal ?? DEFAULT_STREAM_TOTAL_MS)
|
|
13542
|
+
};
|
|
13543
|
+
}
|
|
13544
|
+
function extractStreamChunk(part) {
|
|
13545
|
+
if (!part || typeof part !== "object") return {};
|
|
13546
|
+
if (part.type === "reasoning-delta" || part.type === "reasoning") {
|
|
13547
|
+
const thought = part.text ?? part.delta ?? part.reasoning ?? "";
|
|
13548
|
+
return thought ? { thought } : {};
|
|
13549
|
+
}
|
|
13550
|
+
if (part.type === "text-delta") {
|
|
13551
|
+
const content = part.text ?? part.delta ?? "";
|
|
13552
|
+
return content ? { content } : {};
|
|
13553
|
+
}
|
|
13554
|
+
if (part.type === "raw") {
|
|
13555
|
+
const raw = part.rawValue;
|
|
13556
|
+
const delta = raw?.choices?.[0]?.delta;
|
|
13557
|
+
const reasoning = delta?.reasoning_content ?? delta?.reasoning ?? raw?.delta?.reasoning_content ?? raw?.delta?.reasoning;
|
|
13558
|
+
if (typeof reasoning === "string" && reasoning) return { thought: reasoning };
|
|
13559
|
+
const text = delta?.content ?? raw?.delta?.content;
|
|
13560
|
+
if (typeof text === "string" && text) return { content: text };
|
|
13561
|
+
return {};
|
|
13562
|
+
}
|
|
13563
|
+
return {};
|
|
13564
|
+
}
|
|
13565
|
+
function createStreamAbortSignal(budget) {
|
|
13566
|
+
const controller = new AbortController();
|
|
13567
|
+
let idleTimer = null;
|
|
13568
|
+
let totalTimer = null;
|
|
13569
|
+
const armIdle = () => {
|
|
13570
|
+
if (idleTimer) clearTimeout(idleTimer);
|
|
13571
|
+
if (budget.idleMs > 0) {
|
|
13572
|
+
idleTimer = setTimeout(
|
|
13573
|
+
() => controller.abort(new Error(`Idle timeout: no data for ${Math.round(budget.idleMs / 1e3)}s`)),
|
|
13574
|
+
budget.idleMs
|
|
13575
|
+
);
|
|
13576
|
+
idleTimer?.unref?.();
|
|
13577
|
+
}
|
|
13578
|
+
};
|
|
13579
|
+
armIdle();
|
|
13580
|
+
if (budget.totalMs > 0) {
|
|
13581
|
+
totalTimer = setTimeout(
|
|
13582
|
+
() => controller.abort(new Error(`Total stream timeout after ${Math.round(budget.totalMs / 1e3)}s`)),
|
|
13583
|
+
budget.totalMs
|
|
13584
|
+
);
|
|
13585
|
+
totalTimer?.unref?.();
|
|
13586
|
+
}
|
|
13587
|
+
return {
|
|
13588
|
+
signal: controller.signal,
|
|
13589
|
+
/** Reset the idle window — call on EVERY received stream part. */
|
|
13590
|
+
kick: armIdle,
|
|
13591
|
+
/** Clear both timers once the stream lifecycle is over. */
|
|
13592
|
+
dispose: () => {
|
|
13593
|
+
if (idleTimer) clearTimeout(idleTimer);
|
|
13594
|
+
if (totalTimer) clearTimeout(totalTimer);
|
|
13595
|
+
idleTimer = null;
|
|
13596
|
+
totalTimer = null;
|
|
13597
|
+
}
|
|
13598
|
+
};
|
|
13599
|
+
}
|
|
13528
13600
|
function safeParseJson(rawText) {
|
|
13529
13601
|
if (!rawText) return null;
|
|
13530
13602
|
const cleaned = rawText.replace(/```json\s*/gi, "").replace(/```\s*/g, "").trim();
|
|
@@ -13549,7 +13621,7 @@ function safeParseJson(rawText) {
|
|
|
13549
13621
|
return null;
|
|
13550
13622
|
}
|
|
13551
13623
|
}
|
|
13552
|
-
async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onChunk, preferredModel, preferredProvider) {
|
|
13624
|
+
async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onChunk, preferredModel, preferredProvider, budget) {
|
|
13553
13625
|
const alibabaKey = apiKeys.alibaba || apiKeys.dashscope || process.env.ALIBABA_API_KEY || process.env.DASHSCOPE_API_KEY;
|
|
13554
13626
|
const nvidiaKey = apiKeys.nvidia || process.env.NVIDIA_API_KEY;
|
|
13555
13627
|
const deepseekKey = apiKeys.deepseek || process.env.DEEPSEEK_API_KEY;
|
|
@@ -13627,8 +13699,13 @@ async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onC
|
|
|
13627
13699
|
const systemInstructions = `${systemPrompt}
|
|
13628
13700
|
|
|
13629
13701
|
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.`;
|
|
13702
|
+
const resolvedBudget = {
|
|
13703
|
+
idleMs: budget?.idleMs ?? DEFAULT_STREAM_IDLE_MS,
|
|
13704
|
+
totalMs: budget?.totalMs ?? DEFAULT_STREAM_TOTAL_MS
|
|
13705
|
+
};
|
|
13630
13706
|
for (const candidate of candidates) {
|
|
13631
13707
|
const t0 = Date.now();
|
|
13708
|
+
const abort = createStreamAbortSignal(resolvedBudget);
|
|
13632
13709
|
try {
|
|
13633
13710
|
const modelInstance = getAIModel({
|
|
13634
13711
|
provider: candidate.provider,
|
|
@@ -13641,26 +13718,16 @@ THINKING DIRECTIVE: Keep reasoning concise, structured, and focused strictly on
|
|
|
13641
13718
|
prompt: userPrompt,
|
|
13642
13719
|
temperature: 0.2,
|
|
13643
13720
|
includeRawChunks: true,
|
|
13644
|
-
abortSignal:
|
|
13721
|
+
abortSignal: abort.signal
|
|
13645
13722
|
});
|
|
13646
13723
|
let fullContent = "";
|
|
13647
13724
|
for await (const part of streamResult.fullStream) {
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
const reasoning = delta?.reasoning_content || delta?.reasoning;
|
|
13655
|
-
if (reasoning) {
|
|
13656
|
-
onChunk?.(reasoning, "thought");
|
|
13657
|
-
}
|
|
13658
|
-
} else if (part.type === "text-delta") {
|
|
13659
|
-
const textDelta = part.text ?? part.delta ?? "";
|
|
13660
|
-
if (textDelta) {
|
|
13661
|
-
fullContent += textDelta;
|
|
13662
|
-
onChunk?.(textDelta, "content");
|
|
13663
|
-
}
|
|
13725
|
+
abort.kick();
|
|
13726
|
+
const extracted = extractStreamChunk(part);
|
|
13727
|
+
if (extracted.thought) onChunk?.(extracted.thought, "thought");
|
|
13728
|
+
if (extracted.content) {
|
|
13729
|
+
fullContent += extracted.content;
|
|
13730
|
+
onChunk?.(extracted.content, "content");
|
|
13664
13731
|
}
|
|
13665
13732
|
}
|
|
13666
13733
|
if (fullContent.trim()) {
|
|
@@ -13669,6 +13736,8 @@ THINKING DIRECTIVE: Keep reasoning concise, structured, and focused strictly on
|
|
|
13669
13736
|
}
|
|
13670
13737
|
} catch (e) {
|
|
13671
13738
|
console.warn(`[curriculum-kit:VercelAI] Candidate ${candidate.provider} (${candidate.model}) failed in ${Date.now() - t0}ms:`, e?.message || e);
|
|
13739
|
+
} finally {
|
|
13740
|
+
abort.dispose();
|
|
13672
13741
|
}
|
|
13673
13742
|
}
|
|
13674
13743
|
return null;
|
|
@@ -13709,7 +13778,11 @@ Return concise JSON matching:
|
|
|
13709
13778
|
(chunk, type) => {
|
|
13710
13779
|
if (type === "content") rawContent += chunk;
|
|
13711
13780
|
onChunk?.(chunk, type);
|
|
13712
|
-
}
|
|
13781
|
+
},
|
|
13782
|
+
options.model,
|
|
13783
|
+
options.provider,
|
|
13784
|
+
// Research may run live web grounding — generous budget, still idle-guarded.
|
|
13785
|
+
resolveStreamBudget(void 0, { idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs })
|
|
13713
13786
|
);
|
|
13714
13787
|
let parsedResearch = {
|
|
13715
13788
|
groundTruthSummary: `Verified ecosystem standards for ${projectName}`,
|
|
@@ -13911,7 +13984,10 @@ REQUIREMENT: Synthesize ALL parameters above \u2014 every single line in FULL AC
|
|
|
13911
13984
|
onChunk?.(chunk, type);
|
|
13912
13985
|
},
|
|
13913
13986
|
options.model,
|
|
13914
|
-
options.provider
|
|
13987
|
+
options.provider,
|
|
13988
|
+
// RC-W1: layer-aware budget — Layer 2 has the largest output and free-tier
|
|
13989
|
+
// models may think/stream for minutes. Idle window still catches hangs.
|
|
13990
|
+
resolveStreamBudget(targetLayer, { idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs })
|
|
13915
13991
|
);
|
|
13916
13992
|
const parsed = safeParseJson(rawContent);
|
|
13917
13993
|
return {
|
|
@@ -17190,6 +17266,8 @@ exports.CurriculumPlanSchema = CurriculumPlanSchema;
|
|
|
17190
17266
|
exports.CurriculumQualityReportSchema = CurriculumQualityReportSchema;
|
|
17191
17267
|
exports.DEFAULT_ENABLED_PROVIDERS = DEFAULT_ENABLED_PROVIDERS;
|
|
17192
17268
|
exports.DEFAULT_GATE_SETTINGS = DEFAULT_GATE_SETTINGS;
|
|
17269
|
+
exports.DEFAULT_STREAM_IDLE_MS = DEFAULT_STREAM_IDLE_MS;
|
|
17270
|
+
exports.DEFAULT_STREAM_TOTAL_MS = DEFAULT_STREAM_TOTAL_MS;
|
|
17193
17271
|
exports.DependencyEdgeSchema = DependencyEdgeSchema;
|
|
17194
17272
|
exports.DepthAssignmentSchema = DepthAssignmentSchema;
|
|
17195
17273
|
exports.DepthLevelSchema = DepthLevelSchema;
|
|
@@ -17234,6 +17312,7 @@ exports.HandoutSectionSchema = HandoutSectionSchema;
|
|
|
17234
17312
|
exports.InstructionSectionSchema = InstructionSectionSchema;
|
|
17235
17313
|
exports.InstructionStepSchema = InstructionStepSchema;
|
|
17236
17314
|
exports.JudgeCriterionSchema = JudgeCriterionSchema;
|
|
17315
|
+
exports.LAYER_TOTAL_BUDGET_MS = LAYER_TOTAL_BUDGET_MS;
|
|
17237
17316
|
exports.LESSON_PLAN_TEMPLATE = LESSON_PLAN_TEMPLATE;
|
|
17238
17317
|
exports.LLMJudgeEngine = LLMJudgeEngine;
|
|
17239
17318
|
exports.LabTierTaskSchema = LabTierTaskSchema;
|
|
@@ -17363,6 +17442,7 @@ exports.contentTools = contentTools;
|
|
|
17363
17442
|
exports.convertRoadmapToFoundationSot = convertRoadmapToFoundationSot;
|
|
17364
17443
|
exports.createAiInferenceError = createAiInferenceError;
|
|
17365
17444
|
exports.createCurriculumStorage = createCurriculumStorage;
|
|
17445
|
+
exports.createStreamAbortSignal = createStreamAbortSignal;
|
|
17366
17446
|
exports.curateMediaLedger = curateMediaLedger;
|
|
17367
17447
|
exports.designerTools = designerTools;
|
|
17368
17448
|
exports.detectProjectPedagogy = detectProjectPedagogy;
|
|
@@ -17375,6 +17455,7 @@ exports.exportAllProjectQuizzes = exportAllProjectQuizzes;
|
|
|
17375
17455
|
exports.expositionCacheKey = expositionCacheKey;
|
|
17376
17456
|
exports.extractScopeSequenceRows = extractScopeSequenceRows;
|
|
17377
17457
|
exports.extractSessionSlice = extractSessionSlice;
|
|
17458
|
+
exports.extractStreamChunk = extractStreamChunk;
|
|
17378
17459
|
exports.extractThoughtAndContent = extractThoughtAndContent;
|
|
17379
17460
|
exports.formatQuizzesToCsv = formatQuizzesToCsv;
|
|
17380
17461
|
exports.fulfillMediaLedger = fulfillMediaLedger;
|
|
@@ -17457,6 +17538,7 @@ exports.repairMasterLessonStep = repairMasterLessonStep;
|
|
|
17457
17538
|
exports.researcherTools = researcherTools;
|
|
17458
17539
|
exports.resolveGateSettings = resolveGateSettings;
|
|
17459
17540
|
exports.resolveStandardsPacks = resolveStandardsPacks;
|
|
17541
|
+
exports.resolveStreamBudget = resolveStreamBudget;
|
|
17460
17542
|
exports.resolveTranslationTargets = resolveTranslationTargets;
|
|
17461
17543
|
exports.reviewerTools = reviewerTools;
|
|
17462
17544
|
exports.runCurriculumAIInference = runCurriculumAIInference;
|