@thanh01.pmt/curriculum-kit 1.4.16 → 1.4.17

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
@@ -11457,6 +11457,17 @@ function packUnitSessions(group, nodeById, spec, warnings) {
11457
11457
  const node = nodeById.get(id);
11458
11458
  const isKnowledge = node.kind === "concept";
11459
11459
  if (node.estimated_minutes > spec.contentBudget) {
11460
+ if (node.estimated_minutes <= spec.sessionDurationMinutes || node.estimated_minutes <= spec.contentBudget * 1.25) {
11461
+ if (current.entries.length > 0) flush();
11462
+ const entry = { id, minutes: spec.contentBudget, part: 1, totalParts: 1 };
11463
+ if (isKnowledge) current.knowledgeMinutes += entry.minutes;
11464
+ else current.practiceMinutes += entry.minutes;
11465
+ current.entries.push(entry);
11466
+ current.nodeIds.push(id);
11467
+ current.oversized = false;
11468
+ flush();
11469
+ continue;
11470
+ }
11460
11471
  const parts = [];
11461
11472
  let remaining = node.estimated_minutes;
11462
11473
  while (remaining > 0) {
@@ -11625,6 +11636,35 @@ async function buildCurriculumPlan(rawGraph, options) {
11625
11636
  const unitIndexByGroup = new Map(groups.map((g, i) => [g.key, i]));
11626
11637
  const packed = [];
11627
11638
  for (const g of groups) packed.push(...packUnitSessions(g, nodeById, spec, warnings));
11639
+ if (constraints.total_sessions && packed.length > constraints.total_sessions) {
11640
+ warnings.push(`Initial packing produced ${packed.length} sessions, coalescing to satisfy total_sessions constraint (${constraints.total_sessions})`);
11641
+ for (let i = 0; i < packed.length - 1 && packed.length > constraints.total_sessions; i++) {
11642
+ const curr = packed[i];
11643
+ const next = packed[i + 1];
11644
+ if (curr.groupId === next.groupId) {
11645
+ const currMins = curr.knowledgeMinutes + curr.practiceMinutes;
11646
+ const nextMins = next.knowledgeMinutes + next.practiceMinutes;
11647
+ const totalContent = currMins + nextMins;
11648
+ if (currMins <= 45 || nextMins <= 45 || totalContent <= spec.contentBudget * 1.5) {
11649
+ const scale = totalContent > spec.contentBudget ? spec.contentBudget / totalContent : 1;
11650
+ curr.nodeIds.push(...next.nodeIds);
11651
+ for (const e of next.entries) {
11652
+ e.minutes = Math.max(5, Math.round(e.minutes * scale));
11653
+ curr.entries.push(e);
11654
+ }
11655
+ for (const e of curr.entries) {
11656
+ e.minutes = Math.max(5, Math.round(e.minutes * scale));
11657
+ }
11658
+ const scaledKnowledge = Math.round((curr.knowledgeMinutes + next.knowledgeMinutes) * scale);
11659
+ curr.knowledgeMinutes = scaledKnowledge;
11660
+ curr.practiceMinutes = Math.max(0, spec.contentBudget - scaledKnowledge);
11661
+ curr.oversized = false;
11662
+ packed.splice(i + 1, 1);
11663
+ i--;
11664
+ }
11665
+ }
11666
+ }
11667
+ }
11628
11668
  packed.map(
11629
11669
  (_, i) => "U" + pad2(Math.min(units.length, 99)).replace("U", "U")
11630
11670
  /* placeholder replaced below */