@thanh01.pmt/curriculum-kit 1.4.25 → 1.4.27

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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai/index.cjs +68 -5
  3. package/dist/ai/index.cjs.map +1 -1
  4. package/dist/ai/index.d.cts +4 -4
  5. package/dist/ai/index.d.ts +4 -4
  6. package/dist/ai/index.mjs +68 -6
  7. package/dist/ai/index.mjs.map +1 -1
  8. package/dist/index.cjs +71 -6
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +5 -5
  11. package/dist/index.d.ts +5 -5
  12. package/dist/index.mjs +71 -7
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/media/index.cjs +52 -4
  15. package/dist/media/index.cjs.map +1 -1
  16. package/dist/media/index.d.cts +1 -1
  17. package/dist/media/index.d.ts +1 -1
  18. package/dist/media/index.mjs +52 -4
  19. package/dist/media/index.mjs.map +1 -1
  20. package/dist/{milestoneBundleGenerator-CzSOeAzU.d.cts → milestoneBundleGenerator-CN6F1zPs.d.cts} +1 -1
  21. package/dist/{milestoneBundleGenerator-Bkba8OPG.d.ts → milestoneBundleGenerator-DTiJ5gIh.d.ts} +1 -1
  22. package/dist/pipeline/index.cjs +23 -4
  23. package/dist/pipeline/index.cjs.map +1 -1
  24. package/dist/pipeline/index.d.cts +3 -3
  25. package/dist/pipeline/index.d.ts +3 -3
  26. package/dist/pipeline/index.mjs +23 -4
  27. package/dist/pipeline/index.mjs.map +1 -1
  28. package/dist/{provider-factory-DxzOVEmh.d.cts → provider-factory-Bv-eIkhg.d.cts} +1 -1
  29. package/dist/{provider-factory-DxzOVEmh.d.ts → provider-factory-Bv-eIkhg.d.ts} +1 -1
  30. package/dist/storage/index.d.cts +2 -2
  31. package/dist/storage/index.d.ts +2 -2
  32. package/dist/{streamRunner-CYESG6IE.d.cts → streamRunner-kpS4MZP1.d.cts} +2 -1
  33. package/dist/{streamRunner-CYESG6IE.d.ts → streamRunner-kpS4MZP1.d.ts} +2 -1
  34. package/dist/workflow/index.cjs +67 -5
  35. package/dist/workflow/index.cjs.map +1 -1
  36. package/dist/workflow/index.d.cts +1 -1
  37. package/dist/workflow/index.d.ts +1 -1
  38. package/dist/workflow/index.mjs +67 -5
  39. package/dist/workflow/index.mjs.map +1 -1
  40. package/package.json +22 -23
@@ -1,6 +1,6 @@
1
1
  import { LanguageModel } from 'ai';
2
2
 
3
- type AIProviderName = 'google' | 'openai' | 'deepseek' | 'alibaba' | 'dashscope' | 'ollama' | 'nvidia' | 'openrouter';
3
+ type AIProviderName = '9router' | 'ninerouter' | 'google' | 'openai' | 'deepseek' | 'alibaba' | 'dashscope' | 'ollama' | 'nvidia' | 'openrouter';
4
4
  interface ModelResolutionOptions {
5
5
  provider?: AIProviderName;
6
6
  modelName?: string;
@@ -1,6 +1,6 @@
1
1
  import { LanguageModel } from 'ai';
2
2
 
3
- type AIProviderName = 'google' | 'openai' | 'deepseek' | 'alibaba' | 'dashscope' | 'ollama' | 'nvidia' | 'openrouter';
3
+ type AIProviderName = '9router' | 'ninerouter' | 'google' | 'openai' | 'deepseek' | 'alibaba' | 'dashscope' | 'ollama' | 'nvidia' | 'openrouter';
4
4
  interface ModelResolutionOptions {
5
5
  provider?: AIProviderName;
6
6
  modelName?: string;
@@ -1,10 +1,10 @@
1
1
  import { I as ICurriculumStorage, a as SotDocument, L as LessonArtifactSummary, P as ProjectStatusReport, c as PipelineState, b as ArtifactLifecycleInfo } from '../types-BUJGYiep.cjs';
2
2
  export { A as ArtifactLifecycleState, Q as QualityAuditReport, R as ReviewRecord, S as SmartResumeContext, T as TaskLifecycleState } from '../types-BUJGYiep.cjs';
3
3
  import { SupabaseClient } from '@supabase/supabase-js';
4
- import { M as MilestoneCurriculumBundle } from '../milestoneBundleGenerator-CzSOeAzU.cjs';
4
+ import { M as MilestoneCurriculumBundle } from '../milestoneBundleGenerator-CN6F1zPs.cjs';
5
5
  import '../schemas/index.cjs';
6
6
  import 'zod';
7
- import '../provider-factory-DxzOVEmh.cjs';
7
+ import '../provider-factory-Bv-eIkhg.cjs';
8
8
  import 'ai';
9
9
 
10
10
  declare function computeContentHash(content: string): string;
@@ -1,10 +1,10 @@
1
1
  import { I as ICurriculumStorage, a as SotDocument, L as LessonArtifactSummary, P as ProjectStatusReport, c as PipelineState, b as ArtifactLifecycleInfo } from '../types-BUJGYiep.js';
2
2
  export { A as ArtifactLifecycleState, Q as QualityAuditReport, R as ReviewRecord, S as SmartResumeContext, T as TaskLifecycleState } from '../types-BUJGYiep.js';
3
3
  import { SupabaseClient } from '@supabase/supabase-js';
4
- import { M as MilestoneCurriculumBundle } from '../milestoneBundleGenerator-Bkba8OPG.js';
4
+ import { M as MilestoneCurriculumBundle } from '../milestoneBundleGenerator-DTiJ5gIh.js';
5
5
  import '../schemas/index.js';
6
6
  import 'zod';
7
- import '../provider-factory-DxzOVEmh.js';
7
+ import '../provider-factory-Bv-eIkhg.js';
8
8
  import 'ai';
9
9
 
10
10
  declare function computeContentHash(content: string): string;
@@ -39,6 +39,7 @@ interface StreamRunnerOptions {
39
39
  onChunk: (token: string, type: ChunkType) => void;
40
40
  }) => Promise<string>;
41
41
  }
42
+ declare function resolveApiKey(keyName: string, explicitKey?: string): string;
42
43
  /**
43
44
  * Checks if a specific AI provider is enabled via environment variables.
44
45
  * Supported env controls:
@@ -105,4 +106,4 @@ declare function streamCurriculumAIInference(messages: ChatMessage[], projectCon
105
106
  */
106
107
  declare function runCurriculumAIInference(messages: ChatMessage[], projectContext: string, options?: StreamRunnerOptions, onChunk?: (token: string, type: ChunkType) => void): Promise<string>;
107
108
 
108
- export { type ChatMessage as C, DEFAULT_ARTIFACT_STREAM_IDLE_MS as D, type FallbackTarget as F, type IdleAbort as I, type StreamRunnerOptions as S, isModelAllowed as a, getDesignatedFallbackConfig as b, type ChunkType as c, DEFAULT_ARTIFACT_STREAM_TOTAL_MS as d, extractThoughtAndContent as e, type StreamAbortController as f, getDesignatedFallbackChain as g, createStreamAbortController as h, isProviderEnabled as i, createIdleAbortController as j, runCurriculumAIInference as r, streamCurriculumAIInference as s };
109
+ export { type ChatMessage as C, DEFAULT_ARTIFACT_STREAM_IDLE_MS as D, type FallbackTarget as F, type IdleAbort as I, type StreamRunnerOptions as S, isModelAllowed as a, getDesignatedFallbackConfig as b, type ChunkType as c, DEFAULT_ARTIFACT_STREAM_TOTAL_MS as d, extractThoughtAndContent as e, type StreamAbortController as f, getDesignatedFallbackChain as g, createStreamAbortController as h, isProviderEnabled as i, createIdleAbortController as j, runCurriculumAIInference as k, resolveApiKey as r, streamCurriculumAIInference as s };
@@ -39,6 +39,7 @@ interface StreamRunnerOptions {
39
39
  onChunk: (token: string, type: ChunkType) => void;
40
40
  }) => Promise<string>;
41
41
  }
42
+ declare function resolveApiKey(keyName: string, explicitKey?: string): string;
42
43
  /**
43
44
  * Checks if a specific AI provider is enabled via environment variables.
44
45
  * Supported env controls:
@@ -105,4 +106,4 @@ declare function streamCurriculumAIInference(messages: ChatMessage[], projectCon
105
106
  */
106
107
  declare function runCurriculumAIInference(messages: ChatMessage[], projectContext: string, options?: StreamRunnerOptions, onChunk?: (token: string, type: ChunkType) => void): Promise<string>;
107
108
 
108
- export { type ChatMessage as C, DEFAULT_ARTIFACT_STREAM_IDLE_MS as D, type FallbackTarget as F, type IdleAbort as I, type StreamRunnerOptions as S, isModelAllowed as a, getDesignatedFallbackConfig as b, type ChunkType as c, DEFAULT_ARTIFACT_STREAM_TOTAL_MS as d, extractThoughtAndContent as e, type StreamAbortController as f, getDesignatedFallbackChain as g, createStreamAbortController as h, isProviderEnabled as i, createIdleAbortController as j, runCurriculumAIInference as r, streamCurriculumAIInference as s };
109
+ export { type ChatMessage as C, DEFAULT_ARTIFACT_STREAM_IDLE_MS as D, type FallbackTarget as F, type IdleAbort as I, type StreamRunnerOptions as S, isModelAllowed as a, getDesignatedFallbackConfig as b, type ChunkType as c, DEFAULT_ARTIFACT_STREAM_TOTAL_MS as d, extractThoughtAndContent as e, type StreamAbortController as f, getDesignatedFallbackChain as g, createStreamAbortController as h, isProviderEnabled as i, createIdleAbortController as j, runCurriculumAIInference as k, resolveApiKey as r, streamCurriculumAIInference as s };
@@ -204,14 +204,19 @@ function isModelAllowed(model) {
204
204
  });
205
205
  }
206
206
  function getDesignatedFallbackChain() {
207
- const rawProviders = resolveApiKey("FALLBACK_AI_PROVIDER") || resolveApiKey("FALLBACK_AI_PROVIDERS") || resolveApiKey("DEFAULT_AI_PROVIDER") || "nvidia,openrouter";
208
- const rawModels = resolveApiKey("FALLBACK_AI_MODEL") || resolveApiKey("FALLBACK_AI_MODELS") || resolveApiKey("DEFAULT_AI_MODEL") || "nvidia/nemotron-3-ultra-550b-a55b:free,@preset/coding-free,deepseek/deepseek-chat:free";
207
+ const rawProviders = resolveApiKey("FALLBACK_AI_PROVIDER") || resolveApiKey("FALLBACK_AI_PROVIDERS") || resolveApiKey("DEFAULT_AI_PROVIDER") || "9router,nvidia,openrouter";
208
+ const rawModels = resolveApiKey("FALLBACK_AI_MODEL") || resolveApiKey("FALLBACK_AI_MODELS") || resolveApiKey("DEFAULT_AI_MODEL") || "fast-reasoning,deep-reasoning,mid-range,free-tier";
209
209
  const providerList = rawProviders.split(",").map((p) => p.trim().toLowerCase()).filter((p) => p.length > 0 && isProviderEnabled(p));
210
210
  const modelList = rawModels.split(",").map((m) => m.trim()).filter((m) => m.length > 0 && isModelAllowed(m));
211
211
  const chain = [];
212
212
  for (const provider of providerList) {
213
213
  let providerModels = [];
214
- if (provider === "nvidia") {
214
+ if (provider === "9router" || provider === "ninerouter") {
215
+ providerModels = modelList.filter((m) => ["fast-reasoning", "deep-reasoning", "mid-range", "free-tier"].includes(m));
216
+ if (providerModels.length === 0) {
217
+ providerModels = ["fast-reasoning", "mid-range", "free-tier"];
218
+ }
219
+ } else if (provider === "nvidia") {
215
220
  providerModels = modelList.filter((m) => m.startsWith("nvidia/") || m.startsWith("meta/") || m.startsWith("mistralai/"));
216
221
  if (providerModels.length === 0) {
217
222
  providerModels = ["nvidia/nemotron-3-ultra-550b-a55b:free", "nvidia/nemotron-3.5-lightning-30b-a3b"];
@@ -250,7 +255,7 @@ function getDesignatedFallbackChain() {
250
255
  function getDesignatedFallbackConfig() {
251
256
  const chain = getDesignatedFallbackChain();
252
257
  if (chain.length > 0) return chain[0];
253
- return { provider: "nvidia", model: "nvidia/nemotron-3-ultra-550b-a55b:free" };
258
+ return { provider: "9router", model: "fast-reasoning" };
254
259
  }
255
260
  function extractThoughtAndContent(rawText) {
256
261
  let text = rawText || "";
@@ -489,8 +494,51 @@ Guidelines:
489
494
  }))
490
495
  ];
491
496
  const providerErrors = {};
492
- const requestedModel = options.model || "@preset/coding-free";
497
+ const requestedModel = options.model || "fast-reasoning";
493
498
  const isNvidiaPreferred = requestedModel.startsWith("nvidia/") || Boolean(nvidiaKey && !openrouterKey) && isProviderEnabled("nvidia");
499
+ const ninerouterKey = resolveApiKey("NINEROUTER_API_KEY") || resolveApiKey("NINE_ROUTER_API_KEY");
500
+ if (ninerouterKey && isProviderEnabled("9router")) {
501
+ const rawUrl = resolveApiKey("NINEROUTER_BASE_URL") || resolveApiKey("NINE_ROUTER_BASE_URL") || "https://ai-router.orchable.app/v1";
502
+ const ninerouterBaseUrl = rawUrl.replace(/^["']|["']$/g, "").replace(/\/$/, "");
503
+ const candidateModels = [
504
+ options.model || "fast-reasoning",
505
+ "fast-reasoning",
506
+ "mid-range",
507
+ "free-tier"
508
+ ].filter((m) => isModelAllowed(m));
509
+ const unique9RouterModels = Array.from(new Set(candidateModels));
510
+ for (const model of unique9RouterModels) {
511
+ try {
512
+ const idle = createStreamAbortController({ idleMs: 45e3, totalMs: 3e5 });
513
+ const res = await fetch(`${ninerouterBaseUrl}/chat/completions`, {
514
+ method: "POST",
515
+ headers: {
516
+ "Authorization": `Bearer ${ninerouterKey}`,
517
+ "Content-Type": "application/json"
518
+ },
519
+ body: JSON.stringify({
520
+ model,
521
+ messages: formattedMessages,
522
+ max_tokens: maxTokens,
523
+ temperature,
524
+ stream: true,
525
+ stream_options: { include_usage: true }
526
+ }),
527
+ signal: idle.signal
528
+ });
529
+ if (res.ok) {
530
+ const text = await processOpenAISSEStream(res, onChunk, idle);
531
+ if (text && text.trim()) return text;
532
+ } else {
533
+ const errText = await res.text().catch(() => "");
534
+ providerErrors[`9router_${model}`] = `HTTP ${res.status}: ${errText.slice(0, 120)}`;
535
+ }
536
+ } catch (e) {
537
+ providerErrors[`9router_${model}`] = e?.message || "Network error";
538
+ console.warn(`[9Router Stream] Failover for ${model}:`, e?.message || e);
539
+ }
540
+ }
541
+ }
494
542
  if (nvidiaKey && isProviderEnabled("nvidia")) {
495
543
  const candidateNemotronModels = [
496
544
  requestedModel.startsWith("nvidia/") ? requestedModel : "nvidia/nemotron-3-ultra-550b-a55b:free",
@@ -872,6 +920,15 @@ function getAIModel(options = {}) {
872
920
  console.warn(`[provider-factory] Model "${resolvedModelName}" is not permitted by ALLOWED_AI_MODELS. Using designated model "${designated.model}".`);
873
921
  resolvedModelName = designated.model;
874
922
  }
923
+ if (provider === "9router" || provider === "ninerouter") {
924
+ const apiKey = options.apiKey || resolveApiKey("NINEROUTER_API_KEY") || resolveApiKey("NINE_ROUTER_API_KEY") || "";
925
+ const rawUrl = options.baseURL || resolveApiKey("NINEROUTER_BASE_URL") || resolveApiKey("NINE_ROUTER_BASE_URL") || "https://ai-router.orchable.app/v1";
926
+ const ninerouter = openai.createOpenAI({
927
+ apiKey,
928
+ baseURL: rawUrl.replace(/^["']|["']$/g, "").trim()
929
+ });
930
+ return ninerouter.chat(resolvedModelName || "fast-reasoning");
931
+ }
875
932
  if (provider === "nvidia") {
876
933
  const apiKey = options.apiKey || process.env.NVIDIA_API_KEY || "";
877
934
  const nvidia = openai.createOpenAI({
@@ -940,6 +997,9 @@ function getAIModel(options = {}) {
940
997
  return fallback.chat(resolvedModelName);
941
998
  }
942
999
  function detectDefaultProvider() {
1000
+ if ((process.env.NINEROUTER_API_KEY || resolveApiKey("NINEROUTER_API_KEY") || resolveApiKey("NINE_ROUTER_API_KEY")) && isProviderEnabled("9router")) {
1001
+ return "9router";
1002
+ }
943
1003
  if (process.env.NVIDIA_API_KEY && isProviderEnabled("nvidia")) {
944
1004
  return "nvidia";
945
1005
  }
@@ -965,6 +1025,8 @@ var init_provider_factory = __esm({
965
1025
  "src/ai/provider-factory.ts"() {
966
1026
  init_streamRunner();
967
1027
  DEFAULT_MODELS = {
1028
+ "9router": "fast-reasoning",
1029
+ ninerouter: "fast-reasoning",
968
1030
  nvidia: "nvidia/nemotron-3-ultra-550b-a55b:free",
969
1031
  openrouter: "@preset/coding-free",
970
1032
  alibaba: "qwen3.7-plus",