@thanh01.pmt/curriculum-kit 1.0.15 → 1.0.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/ai/index.cjs CHANGED
@@ -255,29 +255,46 @@ function extractThoughtAndContent(rawText) {
255
255
  content: content.trim()
256
256
  };
257
257
  }
258
- function createIdleAbortController(idleMs) {
258
+ var DEFAULT_ARTIFACT_STREAM_IDLE_MS = 45e3;
259
+ var DEFAULT_ARTIFACT_STREAM_TOTAL_MS = 42e4;
260
+ function createStreamAbortController(options) {
261
+ const envIdle = Number(process.env.ARTIFACT_STREAM_IDLE_TIMEOUT_MS || process.env.STREAM_IDLE_TIMEOUT_MS);
262
+ const envTotal = Number(process.env.ARTIFACT_STREAM_TOTAL_TIMEOUT_MS || process.env.STREAM_TOTAL_TIMEOUT_MS);
263
+ const idleMs = Number.isFinite(options?.idleMs) && options.idleMs > 0 ? options.idleMs : Number.isFinite(envIdle) && envIdle > 0 ? envIdle : DEFAULT_ARTIFACT_STREAM_IDLE_MS;
264
+ const totalMs = Number.isFinite(options?.totalMs) && options.totalMs > 0 ? options.totalMs : Number.isFinite(envTotal) && envTotal > 0 ? envTotal : DEFAULT_ARTIFACT_STREAM_TOTAL_MS;
259
265
  const controller = new AbortController();
260
- let timer = null;
261
- const arm = () => {
262
- if (timer) clearTimeout(timer);
263
- timer = setTimeout(
266
+ let idleTimer = null;
267
+ let totalTimer = null;
268
+ const armIdle = () => {
269
+ if (idleTimer) clearTimeout(idleTimer);
270
+ idleTimer = setTimeout(
264
271
  () => controller.abort(new Error(`Idle timeout: no data for ${Math.round(idleMs / 1e3)}s`)),
265
272
  idleMs
266
273
  );
267
- timer?.unref?.();
274
+ idleTimer?.unref?.();
268
275
  };
269
- arm();
276
+ armIdle();
277
+ if (totalMs > 0) {
278
+ totalTimer = setTimeout(
279
+ () => controller.abort(new Error(`Total stream timeout after ${Math.round(totalMs / 1e3)}s`)),
280
+ totalMs
281
+ );
282
+ totalTimer?.unref?.();
283
+ }
270
284
  return {
271
285
  signal: controller.signal,
272
- /** Reset the idle window (call on every received chunk). */
273
- kick: arm,
274
- /** Clear the pending timer once the request lifecycle is over. */
286
+ kick: armIdle,
275
287
  dispose: () => {
276
- if (timer) clearTimeout(timer);
277
- timer = null;
288
+ if (idleTimer) clearTimeout(idleTimer);
289
+ if (totalTimer) clearTimeout(totalTimer);
290
+ idleTimer = null;
291
+ totalTimer = null;
278
292
  }
279
293
  };
280
294
  }
295
+ function createIdleAbortController(idleMs, totalMs) {
296
+ return createStreamAbortController({ idleMs, totalMs });
297
+ }
281
298
  async function processOpenAISSEStream(response, onChunk, idle, toolCallCollector) {
282
299
  if (!response.body) return "";
283
300
  const reader = response.body.getReader();
@@ -461,7 +478,7 @@ Guidelines:
461
478
  if (isNvidiaPreferred || uniqueNvidiaModels.length > 0) {
462
479
  for (const model of uniqueNvidiaModels) {
463
480
  try {
464
- const idle = createIdleAbortController(18e4);
481
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
465
482
  const res = await fetch("https://integrate.api.nvidia.com/v1/chat/completions", {
466
483
  method: "POST",
467
484
  headers: {
@@ -505,7 +522,7 @@ Guidelines:
505
522
  const uniqueOrModels = Array.from(new Set(openrouterModels));
506
523
  for (const model of uniqueOrModels) {
507
524
  try {
508
- const idle = createIdleAbortController(18e4);
525
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
509
526
  const res = await fetch("https://openrouter.ai/api/v1/chat/completions", {
510
527
  method: "POST",
511
528
  headers: {
@@ -544,7 +561,7 @@ Guidelines:
544
561
  const dsModel = options.model?.includes("deepseek-reasoner") ? "deepseek-reasoner" : "deepseek-chat";
545
562
  if (isModelAllowed(dsModel)) {
546
563
  try {
547
- const idle = createIdleAbortController(18e4);
564
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
548
565
  const res = await fetch("https://api.deepseek.com/chat/completions", {
549
566
  method: "POST",
550
567
  headers: {
@@ -579,7 +596,7 @@ Guidelines:
579
596
  const baseUrl = alibabaKey.startsWith("sk-sp-") ? "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions" : "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions";
580
597
  for (const qwenModel of qwenModels) {
581
598
  try {
582
- const idle = createIdleAbortController(18e4);
599
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
583
600
  const payload = {
584
601
  model: qwenModel,
585
602
  messages: formattedMessages,
@@ -622,7 +639,7 @@ Guidelines:
622
639
  ];
623
640
  for (const gModel of geminiModels) {
624
641
  try {
625
- const idle = createIdleAbortController(18e4);
642
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
626
643
  const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${gModel}:streamGenerateContent?alt=sse&key=${geminiKey}`, {
627
644
  method: "POST",
628
645
  headers: { "Content-Type": "application/json" },
@@ -658,7 +675,7 @@ Guidelines:
658
675
  const { provider, model } = target;
659
676
  if (provider === "nvidia" && nvidiaKey && isProviderEnabled("nvidia")) {
660
677
  try {
661
- const idle = createIdleAbortController(18e4);
678
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
662
679
  const res = await fetch("https://integrate.api.nvidia.com/v1/chat/completions", {
663
680
  method: "POST",
664
681
  headers: {
@@ -690,7 +707,7 @@ Guidelines:
690
707
  }
691
708
  } else if (provider === "openrouter" && openrouterKey && isProviderEnabled("openrouter")) {
692
709
  try {
693
- const idle = createIdleAbortController(18e4);
710
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
694
711
  const res = await fetch("https://openrouter.ai/api/v1/chat/completions", {
695
712
  method: "POST",
696
713
  headers: {
@@ -725,7 +742,7 @@ Guidelines:
725
742
  } else if ((provider === "alibaba" || provider === "dashscope") && alibabaKey && isProviderEnabled("alibaba")) {
726
743
  const baseUrl = alibabaKey.startsWith("sk-sp-") ? "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions" : "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions";
727
744
  try {
728
- const idle = createIdleAbortController(18e4);
745
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
729
746
  const res = await fetch(baseUrl, {
730
747
  method: "POST",
731
748
  headers: {
@@ -757,7 +774,7 @@ Guidelines:
757
774
  }
758
775
  } else if ((provider === "google" || provider === "gemini") && geminiKey && (isProviderEnabled("gemini") || isProviderEnabled("google"))) {
759
776
  try {
760
- const idle = createIdleAbortController(18e4);
777
+ const idle = createStreamAbortController({ idleMs: options.idleTimeoutMs, totalMs: options.timeoutMs });
761
778
  const res = await fetch(
762
779
  `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse&key=${geminiKey}`,
763
780
  {
@@ -4952,6 +4969,8 @@ Guidelines:
4952
4969
  return finalContent;
4953
4970
  }
4954
4971
 
4972
+ exports.DEFAULT_ARTIFACT_STREAM_IDLE_MS = DEFAULT_ARTIFACT_STREAM_IDLE_MS;
4973
+ exports.DEFAULT_ARTIFACT_STREAM_TOTAL_MS = DEFAULT_ARTIFACT_STREAM_TOTAL_MS;
4955
4974
  exports.DEFAULT_ENABLED_PROVIDERS = DEFAULT_ENABLED_PROVIDERS;
4956
4975
  exports.LLMJudgeEngine = LLMJudgeEngine;
4957
4976
  exports.ModelPolicyResolver = ModelPolicyResolver;
@@ -4973,6 +4992,8 @@ exports.buildSlidesPrompt = buildSlidesPrompt;
4973
4992
  exports.buildTeacherGuidePrompt = buildTeacherGuidePrompt;
4974
4993
  exports.buildWorksheetPrompt = buildWorksheetPrompt;
4975
4994
  exports.contentTools = contentTools;
4995
+ exports.createIdleAbortController = createIdleAbortController;
4996
+ exports.createStreamAbortController = createStreamAbortController;
4976
4997
  exports.designerTools = designerTools;
4977
4998
  exports.extractThoughtAndContent = extractThoughtAndContent;
4978
4999
  exports.generateActivityFlow = generateActivityFlow;