@thanh01.pmt/curriculum-kit 1.4.33 → 1.4.35

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.d.cts CHANGED
@@ -3,8 +3,8 @@ export { ActiveLearningWorkflow, ActiveLearningWorkflowSchema, ActivityLabSchema
3
3
  import { A as AIProviderName, M as ModelResolutionOptions } from './provider-factory-Bv-eIkhg.cjs';
4
4
  export { N as NVIDIA_MODELS, g as getAIModel } from './provider-factory-Bv-eIkhg.cjs';
5
5
  export { ActivityPromptInput, AsyncLLMJudgeInput, AuditCurriculumQualityInput, CodeLabPromptInput, DEFAULT_ENABLED_PROVIDERS, DiagnosticQuizPromptInput, ExtensionPromptInput, GenerateActivityInput, GenerateCodeLabInput, GenerateDiagnosticQuizInput, GenerateExtensionInput, GenerateHandoutInput, GenerateLessonMasterInput, GenerateProjectInstructionInput, GenerateSelfLabInput, GenerateSlidesInput, GenerateTeacherGuideInput, GenerateWorksheetInput, HandoutPromptInput, HtmlDeckSlidePromptInput, JudgeEvaluationResult, JudgePromptInput, LLMJudgeEngine, LessonPromptInput, MarpMarkdownSlidePromptInput, ModelPolicyResolution, ModelPolicyResolver, ModelProviderKey, MultiProviderPolicyResolution, ProjectInstructionPromptInput, SLIDE_CANONICAL_METHODOLOGY, SelfLabPromptInput, SlidesPromptInput, StreamDiagnosticQuizInput, StreamLessonMasterInput, StreamSelfLabInput, TeacherGuidePromptInput, WorksheetPromptInput, activityTools, analystTools, assessorTools, auditCurriculumQualityFlow, buildActivityPrompt, buildCodeLabPrompt, buildDiagnosticQuizPrompt, buildExtensionPrompt, buildHandoutPrompt, buildHtmlDeckSlidePrompt, buildJudgePrompt, buildLessonMasterPrompt, buildMarpMarkdownSlidePrompt, buildProjectInstructionPrompt, buildSelfLabPrompt, buildSlidesPrompt, buildTeacherGuidePrompt, buildWorksheetPrompt, contentTools, designerTools, generateActivityFlow, generateCodeLabFlow, generateDiagnosticQuizFlow, generateExtensionFlow, generateHandoutFlow, generateLessonMasterFlow, generateProjectInstructionFlow, generateSelfLabFlow, generateSlidesFlow, generateTeacherGuideFlow, generateWorksheetFlow, illustratorTools, packagerTools, researcherTools, reviewerTools, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLessonMasterFlow, streamSelfLabFlow, techSmeTools } from './ai/index.cjs';
6
- import { S as StreamRunnerOptions } from './streamRunner-B0Z1nAG5.cjs';
7
- export { A as AggregatedToolCall, C as ChatMessage, c as ChunkType, D as DEFAULT_ARTIFACT_STREAM_IDLE_MS, d as DEFAULT_ARTIFACT_STREAM_TOTAL_MS, F as FallbackTarget, I as IdleAbort, f as StreamAbortController, T as ToolDefinition, l as ToolExecutionResult, m as ToolExecutor, n as ToolLoopConfig, j as createIdleAbortController, h as createStreamAbortController, e as extractThoughtAndContent, g as getDesignatedFallbackChain, b as getDesignatedFallbackConfig, a as isModelAllowed, i as isProviderEnabled, r as resolveApiKey, k as runCurriculumAIInference, s as streamCurriculumAIInference } from './streamRunner-B0Z1nAG5.cjs';
6
+ import { S as StreamRunnerOptions, C as ChunkType } from './streamRunner-BzlJrAGZ.cjs';
7
+ export { A as AggregatedToolCall, a as ChatMessage, D as DEFAULT_ARTIFACT_STREAM_IDLE_MS, d as DEFAULT_ARTIFACT_STREAM_TOTAL_MS, F as FallbackTarget, I as IdleAbort, f as StreamAbortController, T as ToolDefinition, l as ToolExecutionResult, m as ToolExecutor, n as ToolLoopConfig, j as createIdleAbortController, h as createStreamAbortController, e as extractThoughtAndContent, g as getDesignatedFallbackChain, c as getDesignatedFallbackConfig, b as isModelAllowed, i as isProviderEnabled, r as resolveApiKey, k as runCurriculumAIInference, s as streamCurriculumAIInference } from './streamRunner-BzlJrAGZ.cjs';
8
8
  export { ArtifactLintReport, ConvertedSotBundle, GenerateProjectInstructionOptions, GenerateRoadmapCurriculumOptions, GenerateSelfPacedBundleInput, LintIssue, ProjectInstructionResult, RoadmapCurriculumOutput, SelfPacedBundleOutput, convertRoadmapToFoundationSot, generateProjectInstruction, generateRoadmapCurriculum, generateSelfPacedBundle, importRoadmapToProject, lintAndSanitizeArtifact, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, validateMarkdownTables, validateMermaidSyntax } from './pipeline/index.cjs';
9
9
  export { A as AutoRepairOptions, a as AutoRepairResult, B as BundleTier, G as GenerateMilestoneBundleOptions, M as MilestoneCurriculumBundle, g as generateMilestoneCurriculumBundle, w as withAutoRepair } from './milestoneBundleGenerator-CN6F1zPs.cjs';
10
10
  import { I as ICurriculumStorage, P as ProjectStatusReport, S as SmartResumeContext, Q as QualityAuditReport } from './types-Bgk-C4K2.cjs';
@@ -431,6 +431,17 @@ declare class DeterministicPipelineRunner {
431
431
  };
432
432
  }
433
433
 
434
+ /** Lifecycle event for one cascade candidate — hosts forward it to the UI so a
435
+ * silent model switch (idle-timeout failover) is never invisible again. */
436
+ interface PrefillProviderEvent {
437
+ type: 'candidate-start' | 'candidate-failed' | 'candidate-success';
438
+ provider: string;
439
+ model: string;
440
+ attempt: number;
441
+ total: number;
442
+ elapsedMs: number;
443
+ error?: string;
444
+ }
434
445
  interface LayerPrefillOptions {
435
446
  action?: 'prefill' | 'research';
436
447
  targetLayer?: number;
@@ -448,6 +459,27 @@ interface LayerPrefillOptions {
448
459
  idleTimeoutMs?: number;
449
460
  /** Optional parent abort signal (e.g. from HTTP request) to stop immediately on client disconnect. */
450
461
  signal?: AbortSignal;
462
+ /**
463
+ * Host-provided inference override (Vercel AI SDK tiered gateway, test stubs).
464
+ * Same contract as StreamRunnerOptions['customInference']. When set it is the
465
+ * SOLE inference path: the built-in cascade (streamLLMWithFallback) never runs,
466
+ * so host apps that mandate one auditable gateway (Langfuse tracing, raw-wire
467
+ * idle kicks, reasoning_content extraction) get exactly that engine here too.
468
+ * Mirrors the unified-tracing mandate already enforced in lesson/chat/slide paths.
469
+ */
470
+ customInference?: (request: {
471
+ systemInstruction: string;
472
+ userPrompt: string;
473
+ messages: Array<{
474
+ role: 'user' | 'assistant' | 'system' | 'model';
475
+ content: string;
476
+ }>;
477
+ temperature: number;
478
+ maxTokens: number;
479
+ onChunk: (token: string, type: ChunkType) => void;
480
+ }) => Promise<string>;
481
+ /** Observe cascade candidate transitions (start/fail/success) for UI status. */
482
+ onProviderEvent?: (event: PrefillProviderEvent) => void;
451
483
  }
452
484
  interface PreliminaryResearchResult {
453
485
  groundTruthSummary: string;
@@ -568,7 +600,7 @@ declare function safeParseJson<T = any>(rawText: string | null): T | null;
568
600
  /**
569
601
  * Multi-tiered resilient streaming inference helper using 100% Vercel AI SDK.
570
602
  */
571
- declare function streamLLMWithFallback(systemPrompt: string, userPrompt: string, apiKeys?: Record<string, string>, onChunk?: LayerChunkCallback, preferredModel?: string, preferredProvider?: AIProviderName, budget?: StreamBudget, signal?: AbortSignal): Promise<string | null>;
603
+ declare function streamLLMWithFallback(systemPrompt: string, userPrompt: string, apiKeys?: Record<string, string>, onChunk?: LayerChunkCallback, preferredModel?: string, preferredProvider?: AIProviderName, budget?: StreamBudget, signal?: AbortSignal, onEvent?: (event: PrefillProviderEvent) => void): Promise<string | null>;
572
604
  /**
573
605
  * Conducts preliminary ecosystem research for a course project.
574
606
  */
@@ -1437,4 +1469,4 @@ declare function getSlideLayoutPresetById(id: string): SlideLayoutPreset | undef
1437
1469
  */
1438
1470
  declare function getSlideLayoutPresetsByCategory(category: SlideLayoutCategory): SlideLayoutPreset[];
1439
1471
 
1440
- export { ACT_TEMPLATE, AIProviderName, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, type AcademicAuditFinding, AcademicAuditor, type AcademicDimension, ActivityLab, type ArtifactDependencyRule, type ArtifactProductionSpec, type AuditBundleInput, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BloomTaxonomyEvaluator, type BuildContextOptions, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, CodeHardwareFeasibilityEvaluator, CodeLab, type ComprehensiveAcademicReport, ConstructiveAlignmentEvaluator, type ContextInjectionMeta, type ContextSourceKey, CoverageGateReport, CrossArtifactDriftEvaluator, CurriculumError, type CurriculumErrorCode, type CurriculumErrorDetail, CurriculumPlan, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdge, type DependencyValidationResult, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuiz, DiagnosticQuizInput, type DimensionScore, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, type ExcerptOptions, type ExcerptResult, type ExecuteCommandResult, ExpositionApprovalError, type ExpositionLlmFn, type ExpositionResult, type ExpositionStorage, type ExtractedJson, type ExtractedStreamChunk, type FindingSeverity, FiveEInstructionalEvaluator, type FrameworkLintFinding, type FrameworkLintReport, FrameworkPack, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, type GenerateExpositionOptions, GeneratedSlideArraySchema, GeneratedSlideSchema, HANDOUT_TEMPLATE, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, ICurriculumStorage, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, type LayerChunkCallback, type LayerPrefillOptions, type LayerPrefillResult, type LayoutBoxConfig, LessonPlan, MisconceptionEvaluator, ModelResolutionOptions, PROJECT_INSTRUCTION_TEMPLATE, type PackingSpec, type PedagogicalModel, type PipelineExecutionProgress, PlanConstraints, type PlanOptions, type PlanResult, type PlannerLlmFn, PlanningGraph, PlanningNode, type PreliminaryResearchResult, type ProduceLessonOptions, type ProduceLessonResult, type ProjectBriefingData, type ProjectClarification, type ProjectCreationPayload, type ProjectIntentAnalysisResult, ProjectStatusReport, type ProjectionMeta, QUIZ_TEMPLATE, QualityAuditReport, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, ResolvedGateSettings, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STATION_ROTATION_TEMPLATE, type SlashCommandDefinition, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeck, type SlideEngine, type SlideLayoutCategory, type SlideLayoutData, type SlideLayoutPreset, type SlideProductionWorkflowOptions, type SlideProductionWorkflowResult, SmartResumeContext, type StreamAbortHandle, type StreamBudget, type StreamChunkExtractor, StreamRunnerOptions, type SymbolLedgerResult, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TranslationPolicy, type TranslationTarget, type TranslationTrigger, type ValidationOptions, WORKSHEET_TEMPLATE, analyzeProjectCreationIntent, assertAcyclic, auditQualityReport, buildCurriculumContext, buildCurriculumPlan, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildHeadingDirective, buildLanguageDirective, buildLessonExcerpt, buildSectionAwareExcerpt, buildSessionSliceContext, closeTruncatedJson, computePackingSpec, conductPreliminaryResearch, createAiInferenceError, createContextMissingError, createStreamAbortSignal, createStreamChunkExtractor, detectProjectPedagogy, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, executeCurriculumCommand, executeSlideProductionWorkflow, expositionCacheKey, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStreamChunk, extractSymbolLedger, generatePhase1SotArtifacts, generatePhase2SotArtifacts, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, ingestProjectGraphIntoProject, initializeProjectInStorage, isExpositionFresh, isTranslationDue, lintCurriculumFramework, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, renderFrameworkFromPlan, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, safeParseJson, slugifyProjectName, streamLLMWithFallback, streamLayerPrefillWithFallback, stripLlmJsonWrappers, targetLanguageDisplayName, topoSort, validateArtifactDependencies, validateHybridDeckSlides };
1472
+ export { ACT_TEMPLATE, AIProviderName, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, type AcademicAuditFinding, AcademicAuditor, type AcademicDimension, ActivityLab, type ArtifactDependencyRule, type ArtifactProductionSpec, type AuditBundleInput, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BloomTaxonomyEvaluator, type BuildContextOptions, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, ChunkType, CodeHardwareFeasibilityEvaluator, CodeLab, type ComprehensiveAcademicReport, ConstructiveAlignmentEvaluator, type ContextInjectionMeta, type ContextSourceKey, CoverageGateReport, CrossArtifactDriftEvaluator, CurriculumError, type CurriculumErrorCode, type CurriculumErrorDetail, CurriculumPlan, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdge, type DependencyValidationResult, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuiz, DiagnosticQuizInput, type DimensionScore, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, type ExcerptOptions, type ExcerptResult, type ExecuteCommandResult, ExpositionApprovalError, type ExpositionLlmFn, type ExpositionResult, type ExpositionStorage, type ExtractedJson, type ExtractedStreamChunk, type FindingSeverity, FiveEInstructionalEvaluator, type FrameworkLintFinding, type FrameworkLintReport, FrameworkPack, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, type GenerateExpositionOptions, GeneratedSlideArraySchema, GeneratedSlideSchema, HANDOUT_TEMPLATE, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, ICurriculumStorage, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, type LayerChunkCallback, type LayerPrefillOptions, type LayerPrefillResult, type LayoutBoxConfig, LessonPlan, MisconceptionEvaluator, ModelResolutionOptions, PROJECT_INSTRUCTION_TEMPLATE, type PackingSpec, type PedagogicalModel, type PipelineExecutionProgress, PlanConstraints, type PlanOptions, type PlanResult, type PlannerLlmFn, PlanningGraph, PlanningNode, type PrefillProviderEvent, type PreliminaryResearchResult, type ProduceLessonOptions, type ProduceLessonResult, type ProjectBriefingData, type ProjectClarification, type ProjectCreationPayload, type ProjectIntentAnalysisResult, ProjectStatusReport, type ProjectionMeta, QUIZ_TEMPLATE, QualityAuditReport, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, ResolvedGateSettings, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STATION_ROTATION_TEMPLATE, type SlashCommandDefinition, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeck, type SlideEngine, type SlideLayoutCategory, type SlideLayoutData, type SlideLayoutPreset, type SlideProductionWorkflowOptions, type SlideProductionWorkflowResult, SmartResumeContext, type StreamAbortHandle, type StreamBudget, type StreamChunkExtractor, StreamRunnerOptions, type SymbolLedgerResult, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TranslationPolicy, type TranslationTarget, type TranslationTrigger, type ValidationOptions, WORKSHEET_TEMPLATE, analyzeProjectCreationIntent, assertAcyclic, auditQualityReport, buildCurriculumContext, buildCurriculumPlan, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildHeadingDirective, buildLanguageDirective, buildLessonExcerpt, buildSectionAwareExcerpt, buildSessionSliceContext, closeTruncatedJson, computePackingSpec, conductPreliminaryResearch, createAiInferenceError, createContextMissingError, createStreamAbortSignal, createStreamChunkExtractor, detectProjectPedagogy, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, executeCurriculumCommand, executeSlideProductionWorkflow, expositionCacheKey, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStreamChunk, extractSymbolLedger, generatePhase1SotArtifacts, generatePhase2SotArtifacts, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, ingestProjectGraphIntoProject, initializeProjectInStorage, isExpositionFresh, isTranslationDue, lintCurriculumFramework, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, renderFrameworkFromPlan, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, safeParseJson, slugifyProjectName, streamLLMWithFallback, streamLayerPrefillWithFallback, stripLlmJsonWrappers, targetLanguageDisplayName, topoSort, validateArtifactDependencies, validateHybridDeckSlides };
package/dist/index.d.ts CHANGED
@@ -3,8 +3,8 @@ export { ActiveLearningWorkflow, ActiveLearningWorkflowSchema, ActivityLabSchema
3
3
  import { A as AIProviderName, M as ModelResolutionOptions } from './provider-factory-Bv-eIkhg.js';
4
4
  export { N as NVIDIA_MODELS, g as getAIModel } from './provider-factory-Bv-eIkhg.js';
5
5
  export { ActivityPromptInput, AsyncLLMJudgeInput, AuditCurriculumQualityInput, CodeLabPromptInput, DEFAULT_ENABLED_PROVIDERS, DiagnosticQuizPromptInput, ExtensionPromptInput, GenerateActivityInput, GenerateCodeLabInput, GenerateDiagnosticQuizInput, GenerateExtensionInput, GenerateHandoutInput, GenerateLessonMasterInput, GenerateProjectInstructionInput, GenerateSelfLabInput, GenerateSlidesInput, GenerateTeacherGuideInput, GenerateWorksheetInput, HandoutPromptInput, HtmlDeckSlidePromptInput, JudgeEvaluationResult, JudgePromptInput, LLMJudgeEngine, LessonPromptInput, MarpMarkdownSlidePromptInput, ModelPolicyResolution, ModelPolicyResolver, ModelProviderKey, MultiProviderPolicyResolution, ProjectInstructionPromptInput, SLIDE_CANONICAL_METHODOLOGY, SelfLabPromptInput, SlidesPromptInput, StreamDiagnosticQuizInput, StreamLessonMasterInput, StreamSelfLabInput, TeacherGuidePromptInput, WorksheetPromptInput, activityTools, analystTools, assessorTools, auditCurriculumQualityFlow, buildActivityPrompt, buildCodeLabPrompt, buildDiagnosticQuizPrompt, buildExtensionPrompt, buildHandoutPrompt, buildHtmlDeckSlidePrompt, buildJudgePrompt, buildLessonMasterPrompt, buildMarpMarkdownSlidePrompt, buildProjectInstructionPrompt, buildSelfLabPrompt, buildSlidesPrompt, buildTeacherGuidePrompt, buildWorksheetPrompt, contentTools, designerTools, generateActivityFlow, generateCodeLabFlow, generateDiagnosticQuizFlow, generateExtensionFlow, generateHandoutFlow, generateLessonMasterFlow, generateProjectInstructionFlow, generateSelfLabFlow, generateSlidesFlow, generateTeacherGuideFlow, generateWorksheetFlow, illustratorTools, packagerTools, researcherTools, reviewerTools, streamCurriculumAIInferenceWithTools, streamDiagnosticQuizFlow, streamLessonMasterFlow, streamSelfLabFlow, techSmeTools } from './ai/index.js';
6
- import { S as StreamRunnerOptions } from './streamRunner-B0Z1nAG5.js';
7
- export { A as AggregatedToolCall, C as ChatMessage, c as ChunkType, D as DEFAULT_ARTIFACT_STREAM_IDLE_MS, d as DEFAULT_ARTIFACT_STREAM_TOTAL_MS, F as FallbackTarget, I as IdleAbort, f as StreamAbortController, T as ToolDefinition, l as ToolExecutionResult, m as ToolExecutor, n as ToolLoopConfig, j as createIdleAbortController, h as createStreamAbortController, e as extractThoughtAndContent, g as getDesignatedFallbackChain, b as getDesignatedFallbackConfig, a as isModelAllowed, i as isProviderEnabled, r as resolveApiKey, k as runCurriculumAIInference, s as streamCurriculumAIInference } from './streamRunner-B0Z1nAG5.js';
6
+ import { S as StreamRunnerOptions, C as ChunkType } from './streamRunner-BzlJrAGZ.js';
7
+ export { A as AggregatedToolCall, a as ChatMessage, D as DEFAULT_ARTIFACT_STREAM_IDLE_MS, d as DEFAULT_ARTIFACT_STREAM_TOTAL_MS, F as FallbackTarget, I as IdleAbort, f as StreamAbortController, T as ToolDefinition, l as ToolExecutionResult, m as ToolExecutor, n as ToolLoopConfig, j as createIdleAbortController, h as createStreamAbortController, e as extractThoughtAndContent, g as getDesignatedFallbackChain, c as getDesignatedFallbackConfig, b as isModelAllowed, i as isProviderEnabled, r as resolveApiKey, k as runCurriculumAIInference, s as streamCurriculumAIInference } from './streamRunner-BzlJrAGZ.js';
8
8
  export { ArtifactLintReport, ConvertedSotBundle, GenerateProjectInstructionOptions, GenerateRoadmapCurriculumOptions, GenerateSelfPacedBundleInput, LintIssue, ProjectInstructionResult, RoadmapCurriculumOutput, SelfPacedBundleOutput, convertRoadmapToFoundationSot, generateProjectInstruction, generateRoadmapCurriculum, generateSelfPacedBundle, importRoadmapToProject, lintAndSanitizeArtifact, serializeActivityToMarkdown, serializeCodeLabToMarkdown, serializeDiagnosticQuizToMarkdown, serializeHandoutToMarkdown, serializeLessonToMarkdown, serializeProjectInstructionToMarkdown, serializeSelfLabToMarkdown, validateMarkdownTables, validateMermaidSyntax } from './pipeline/index.js';
9
9
  export { A as AutoRepairOptions, a as AutoRepairResult, B as BundleTier, G as GenerateMilestoneBundleOptions, M as MilestoneCurriculumBundle, g as generateMilestoneCurriculumBundle, w as withAutoRepair } from './milestoneBundleGenerator-DTiJ5gIh.js';
10
10
  import { I as ICurriculumStorage, P as ProjectStatusReport, S as SmartResumeContext, Q as QualityAuditReport } from './types-Bgk-C4K2.js';
@@ -431,6 +431,17 @@ declare class DeterministicPipelineRunner {
431
431
  };
432
432
  }
433
433
 
434
+ /** Lifecycle event for one cascade candidate — hosts forward it to the UI so a
435
+ * silent model switch (idle-timeout failover) is never invisible again. */
436
+ interface PrefillProviderEvent {
437
+ type: 'candidate-start' | 'candidate-failed' | 'candidate-success';
438
+ provider: string;
439
+ model: string;
440
+ attempt: number;
441
+ total: number;
442
+ elapsedMs: number;
443
+ error?: string;
444
+ }
434
445
  interface LayerPrefillOptions {
435
446
  action?: 'prefill' | 'research';
436
447
  targetLayer?: number;
@@ -448,6 +459,27 @@ interface LayerPrefillOptions {
448
459
  idleTimeoutMs?: number;
449
460
  /** Optional parent abort signal (e.g. from HTTP request) to stop immediately on client disconnect. */
450
461
  signal?: AbortSignal;
462
+ /**
463
+ * Host-provided inference override (Vercel AI SDK tiered gateway, test stubs).
464
+ * Same contract as StreamRunnerOptions['customInference']. When set it is the
465
+ * SOLE inference path: the built-in cascade (streamLLMWithFallback) never runs,
466
+ * so host apps that mandate one auditable gateway (Langfuse tracing, raw-wire
467
+ * idle kicks, reasoning_content extraction) get exactly that engine here too.
468
+ * Mirrors the unified-tracing mandate already enforced in lesson/chat/slide paths.
469
+ */
470
+ customInference?: (request: {
471
+ systemInstruction: string;
472
+ userPrompt: string;
473
+ messages: Array<{
474
+ role: 'user' | 'assistant' | 'system' | 'model';
475
+ content: string;
476
+ }>;
477
+ temperature: number;
478
+ maxTokens: number;
479
+ onChunk: (token: string, type: ChunkType) => void;
480
+ }) => Promise<string>;
481
+ /** Observe cascade candidate transitions (start/fail/success) for UI status. */
482
+ onProviderEvent?: (event: PrefillProviderEvent) => void;
451
483
  }
452
484
  interface PreliminaryResearchResult {
453
485
  groundTruthSummary: string;
@@ -568,7 +600,7 @@ declare function safeParseJson<T = any>(rawText: string | null): T | null;
568
600
  /**
569
601
  * Multi-tiered resilient streaming inference helper using 100% Vercel AI SDK.
570
602
  */
571
- declare function streamLLMWithFallback(systemPrompt: string, userPrompt: string, apiKeys?: Record<string, string>, onChunk?: LayerChunkCallback, preferredModel?: string, preferredProvider?: AIProviderName, budget?: StreamBudget, signal?: AbortSignal): Promise<string | null>;
603
+ declare function streamLLMWithFallback(systemPrompt: string, userPrompt: string, apiKeys?: Record<string, string>, onChunk?: LayerChunkCallback, preferredModel?: string, preferredProvider?: AIProviderName, budget?: StreamBudget, signal?: AbortSignal, onEvent?: (event: PrefillProviderEvent) => void): Promise<string | null>;
572
604
  /**
573
605
  * Conducts preliminary ecosystem research for a course project.
574
606
  */
@@ -1437,4 +1469,4 @@ declare function getSlideLayoutPresetById(id: string): SlideLayoutPreset | undef
1437
1469
  */
1438
1470
  declare function getSlideLayoutPresetsByCategory(category: SlideLayoutCategory): SlideLayoutPreset[];
1439
1471
 
1440
- export { ACT_TEMPLATE, AIProviderName, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, type AcademicAuditFinding, AcademicAuditor, type AcademicDimension, ActivityLab, type ArtifactDependencyRule, type ArtifactProductionSpec, type AuditBundleInput, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BloomTaxonomyEvaluator, type BuildContextOptions, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, CodeHardwareFeasibilityEvaluator, CodeLab, type ComprehensiveAcademicReport, ConstructiveAlignmentEvaluator, type ContextInjectionMeta, type ContextSourceKey, CoverageGateReport, CrossArtifactDriftEvaluator, CurriculumError, type CurriculumErrorCode, type CurriculumErrorDetail, CurriculumPlan, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdge, type DependencyValidationResult, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuiz, DiagnosticQuizInput, type DimensionScore, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, type ExcerptOptions, type ExcerptResult, type ExecuteCommandResult, ExpositionApprovalError, type ExpositionLlmFn, type ExpositionResult, type ExpositionStorage, type ExtractedJson, type ExtractedStreamChunk, type FindingSeverity, FiveEInstructionalEvaluator, type FrameworkLintFinding, type FrameworkLintReport, FrameworkPack, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, type GenerateExpositionOptions, GeneratedSlideArraySchema, GeneratedSlideSchema, HANDOUT_TEMPLATE, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, ICurriculumStorage, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, type LayerChunkCallback, type LayerPrefillOptions, type LayerPrefillResult, type LayoutBoxConfig, LessonPlan, MisconceptionEvaluator, ModelResolutionOptions, PROJECT_INSTRUCTION_TEMPLATE, type PackingSpec, type PedagogicalModel, type PipelineExecutionProgress, PlanConstraints, type PlanOptions, type PlanResult, type PlannerLlmFn, PlanningGraph, PlanningNode, type PreliminaryResearchResult, type ProduceLessonOptions, type ProduceLessonResult, type ProjectBriefingData, type ProjectClarification, type ProjectCreationPayload, type ProjectIntentAnalysisResult, ProjectStatusReport, type ProjectionMeta, QUIZ_TEMPLATE, QualityAuditReport, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, ResolvedGateSettings, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STATION_ROTATION_TEMPLATE, type SlashCommandDefinition, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeck, type SlideEngine, type SlideLayoutCategory, type SlideLayoutData, type SlideLayoutPreset, type SlideProductionWorkflowOptions, type SlideProductionWorkflowResult, SmartResumeContext, type StreamAbortHandle, type StreamBudget, type StreamChunkExtractor, StreamRunnerOptions, type SymbolLedgerResult, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TranslationPolicy, type TranslationTarget, type TranslationTrigger, type ValidationOptions, WORKSHEET_TEMPLATE, analyzeProjectCreationIntent, assertAcyclic, auditQualityReport, buildCurriculumContext, buildCurriculumPlan, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildHeadingDirective, buildLanguageDirective, buildLessonExcerpt, buildSectionAwareExcerpt, buildSessionSliceContext, closeTruncatedJson, computePackingSpec, conductPreliminaryResearch, createAiInferenceError, createContextMissingError, createStreamAbortSignal, createStreamChunkExtractor, detectProjectPedagogy, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, executeCurriculumCommand, executeSlideProductionWorkflow, expositionCacheKey, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStreamChunk, extractSymbolLedger, generatePhase1SotArtifacts, generatePhase2SotArtifacts, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, ingestProjectGraphIntoProject, initializeProjectInStorage, isExpositionFresh, isTranslationDue, lintCurriculumFramework, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, renderFrameworkFromPlan, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, safeParseJson, slugifyProjectName, streamLLMWithFallback, streamLayerPrefillWithFallback, stripLlmJsonWrappers, targetLanguageDisplayName, topoSort, validateArtifactDependencies, validateHybridDeckSlides };
1472
+ export { ACT_TEMPLATE, AIProviderName, ARTIFACT_DEPENDENCY_ROUTING, ARTIFACT_EXECUTION_ORDER, type AcademicAuditFinding, AcademicAuditor, type AcademicDimension, ActivityLab, type ArtifactDependencyRule, type ArtifactProductionSpec, type AuditBundleInput, BELL_RINGER_TEMPLATE, BLOOM_ACTION_VERBS, BOM_TEMPLATE, BloomTaxonomyEvaluator, type BuildContextOptions, CHOICE_BOARD_TEMPLATE, CODE_LAB_TEMPLATE, CURRICULUM_SLASH_COMMANDS, ChunkType, CodeHardwareFeasibilityEvaluator, CodeLab, type ComprehensiveAcademicReport, ConstructiveAlignmentEvaluator, type ContextInjectionMeta, type ContextSourceKey, CoverageGateReport, CrossArtifactDriftEvaluator, CurriculumError, type CurriculumErrorCode, type CurriculumErrorDetail, CurriculumPlan, DEFAULT_KX_PRIORITIES, DEFAULT_LESSON_PRIORITIES, DEFAULT_STREAM_IDLE_MS, DEFAULT_STREAM_TOTAL_MS, DEFAULT_VIETNAMESE_SECTION_HEADINGS, DependencyEdge, type DependencyValidationResult, DeterministicPipelineRunner, DeterministicStructuralLinter, DiagnosticQuiz, DiagnosticQuizInput, type DimensionScore, EXIT_TICKET_TEMPLATE, EXPOSITION_REL, EXT_TEMPLATE, type ExcerptOptions, type ExcerptResult, type ExecuteCommandResult, ExpositionApprovalError, type ExpositionLlmFn, type ExpositionResult, type ExpositionStorage, type ExtractedJson, type ExtractedStreamChunk, type FindingSeverity, FiveEInstructionalEvaluator, type FrameworkLintFinding, type FrameworkLintReport, FrameworkPack, GLOSSARY_TEMPLATE, GRAPHIC_ORGANIZER_TEMPLATE, type GenerateExpositionOptions, GeneratedSlideArraySchema, GeneratedSlideSchema, HANDOUT_TEMPLATE, HybridBlueprintArraySchema, HybridBlueprintItemSchema, HybridDeckSlideArraySchema, HybridDeckSlideSchema, HybridPipelineError, ICurriculumStorage, LAYER_IDLE_BUDGET_MS, LAYER_TOTAL_BUDGET_MS, LESSON_PLAN_TEMPLATE, type LayerChunkCallback, type LayerPrefillOptions, type LayerPrefillResult, type LayoutBoxConfig, LessonPlan, MisconceptionEvaluator, ModelResolutionOptions, PROJECT_INSTRUCTION_TEMPLATE, type PackingSpec, type PedagogicalModel, type PipelineExecutionProgress, PlanConstraints, type PlanOptions, type PlanResult, type PlannerLlmFn, PlanningGraph, PlanningNode, type PrefillProviderEvent, type PreliminaryResearchResult, type ProduceLessonOptions, type ProduceLessonResult, type ProjectBriefingData, type ProjectClarification, type ProjectCreationPayload, type ProjectIntentAnalysisResult, ProjectStatusReport, type ProjectionMeta, QUIZ_TEMPLATE, QualityAuditReport, REVIEW_GAME_TEMPLATE, RUBRIC_TEMPLATE, ResolvedGateSettings, SATELLITE_LESSON_PRIORITIES, SCIENCE_LAB_TEMPLATE, SELF_LAB_TEMPLATE, SLIDE_LAYOUT_PRESETS, SLIDE_TEMPLATE, STATION_ROTATION_TEMPLATE, type SlashCommandDefinition, SlideBlueprintArraySchema, SlideBlueprintItemSchema, SlideDeck, type SlideEngine, type SlideLayoutCategory, type SlideLayoutData, type SlideLayoutPreset, type SlideProductionWorkflowOptions, type SlideProductionWorkflowResult, SmartResumeContext, type StreamAbortHandle, type StreamBudget, type StreamChunkExtractor, StreamRunnerOptions, type SymbolLedgerResult, TASK_CARDS_TEMPLATE, TEACHER_GUIDE_TEMPLATE, TIERED_PRACTICE_TEMPLATE, TranslationPolicy, type TranslationTarget, type TranslationTrigger, type ValidationOptions, WORKSHEET_TEMPLATE, analyzeProjectCreationIntent, assertAcyclic, auditQualityReport, buildCurriculumContext, buildCurriculumPlan, buildDomainLexiconGuardrail, buildExpositionContext, buildExpositionExcerpt, buildHeadingDirective, buildLanguageDirective, buildLessonExcerpt, buildSectionAwareExcerpt, buildSessionSliceContext, closeTruncatedJson, computePackingSpec, conductPreliminaryResearch, createAiInferenceError, createContextMissingError, createStreamAbortSignal, createStreamChunkExtractor, detectProjectPedagogy, emitUsage, ensureExpositionForLesson, ensureKnowledgeExposition, executeCurriculumCommand, executeSlideProductionWorkflow, expositionCacheKey, extractJsonArray, extractScopeSequenceRows, extractSectionHeadingsFromSLC, extractSessionSlice, extractStreamChunk, extractSymbolLedger, generatePhase1SotArtifacts, generatePhase2SotArtifacts, getLessonMetadata, getProjectArtifactScope, getProjectStatusReport, getSlideLayoutPresetById, getSlideLayoutPresetsByCategory, getSmartResumeContext, glossaryTermsForSession, ingestProjectGraphIntoProject, initializeProjectInStorage, isExpositionFresh, isTranslationDue, lintCurriculumFramework, loadCurriculumTemplate, loadSotTemplate, normalizePlanningGraph, normalizeSlcContract, parseRoadmapJsonToProjectPayload, produceBatchLessons, produceSingleLesson, renderFrameworkFromPlan, resolveStreamBudget, resolveTargetLanguageCode, resolveTranslationTargets, safeParseJson, slugifyProjectName, streamLLMWithFallback, streamLayerPrefillWithFallback, stripLlmJsonWrappers, targetLanguageDisplayName, topoSort, validateArtifactDependencies, validateHybridDeckSlides };
package/dist/index.mjs CHANGED
@@ -29507,7 +29507,7 @@ function safeParseJson(rawText) {
29507
29507
  }
29508
29508
  return null;
29509
29509
  }
29510
- async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onChunk, preferredModel, preferredProvider, budget, signal) {
29510
+ async function streamLLMWithFallback(systemPrompt, userPrompt, apiKeys = {}, onChunk, preferredModel, preferredProvider, budget, signal, onEvent) {
29511
29511
  const alibabaKey = apiKeys.alibaba || apiKeys.dashscope || process.env.ALIBABA_API_KEY || process.env.DASHSCOPE_API_KEY;
29512
29512
  const nvidiaKey = apiKeys.nvidia || process.env.NVIDIA_API_KEY;
29513
29513
  const deepseekKey = apiKeys.deepseek || process.env.DEEPSEEK_API_KEY;
@@ -29588,12 +29588,14 @@ THINKING DIRECTIVE: Do ALL your reasoning internally BEFORE emitting output. Do
29588
29588
  idleMs: budget?.idleMs ?? DEFAULT_STREAM_IDLE_MS,
29589
29589
  totalMs: budget?.totalMs ?? DEFAULT_STREAM_TOTAL_MS
29590
29590
  };
29591
- for (const candidate of candidates) {
29591
+ for (const [candidateIdx, candidate] of candidates.entries()) {
29592
29592
  if (signal?.aborted) {
29593
29593
  console.log(`[curriculum-kit:VercelAI] AbortSignal already aborted, cancelling candidate loop.`);
29594
29594
  break;
29595
29595
  }
29596
29596
  const t0 = Date.now();
29597
+ const attempt = candidateIdx + 1;
29598
+ onEvent?.({ type: "candidate-start", provider: candidate.provider, model: candidate.model, attempt, total: candidates.length, elapsedMs: 0 });
29597
29599
  const abort = createStreamAbortSignal(resolvedBudget, signal);
29598
29600
  try {
29599
29601
  const modelInstance = getAIModel({
@@ -29601,18 +29603,35 @@ THINKING DIRECTIVE: Do ALL your reasoning internally BEFORE emitting output. Do
29601
29603
  modelName: candidate.model,
29602
29604
  apiKey: candidate.apiKey
29603
29605
  });
29606
+ const wireFetch = (input, init) => fetch(input, init).then((res) => {
29607
+ if (!res.body) return res;
29608
+ const kicked = res.body.pipeThrough(
29609
+ new TransformStream({
29610
+ transform(chunk, ctrl) {
29611
+ abort.kick();
29612
+ ctrl.enqueue(chunk);
29613
+ }
29614
+ })
29615
+ );
29616
+ return new Response(kicked, res);
29617
+ });
29604
29618
  const streamResult = streamText({
29605
29619
  model: modelInstance,
29606
29620
  system: systemInstructions,
29607
29621
  prompt: userPrompt,
29608
29622
  temperature: 0.2,
29609
29623
  includeRawChunks: true,
29610
- abortSignal: abort.signal
29624
+ abortSignal: abort.signal,
29625
+ fetch: wireFetch
29611
29626
  });
29612
29627
  let fullContent = "";
29613
29628
  const extract = createStreamChunkExtractor();
29614
29629
  for await (const part of streamResult.fullStream) {
29615
29630
  abort.kick();
29631
+ if (part?.type === "error") {
29632
+ const errText = part.errorText ?? String(part.error ?? "unknown stream error");
29633
+ throw new Error(`[${candidate.provider}] stream error part: ${errText}`);
29634
+ }
29616
29635
  const extracted = extract(part);
29617
29636
  if (extracted.thought) onChunk?.(extracted.thought, "thought");
29618
29637
  if (extracted.content) {
@@ -29622,10 +29641,14 @@ THINKING DIRECTIVE: Do ALL your reasoning internally BEFORE emitting output. Do
29622
29641
  }
29623
29642
  if (fullContent.trim()) {
29624
29643
  console.log(`[curriculum-kit:VercelAI] \u2705 ${candidate.provider} (${candidate.model}) streamed in ${Date.now() - t0}ms`);
29644
+ onEvent?.({ type: "candidate-success", provider: candidate.provider, model: candidate.model, attempt, total: candidates.length, elapsedMs: Date.now() - t0 });
29625
29645
  return fullContent.trim();
29626
29646
  }
29647
+ console.warn(`[curriculum-kit:VercelAI] Candidate ${candidate.provider} (${candidate.model}) returned EMPTY content in ${Date.now() - t0}ms \u2192 trying next candidate.`);
29648
+ onEvent?.({ type: "candidate-failed", provider: candidate.provider, model: candidate.model, attempt, total: candidates.length, elapsedMs: Date.now() - t0, error: "empty content" });
29627
29649
  } catch (e) {
29628
29650
  console.warn(`[curriculum-kit:VercelAI] Candidate ${candidate.provider} (${candidate.model}) failed in ${Date.now() - t0}ms:`, e?.message || e);
29651
+ onEvent?.({ type: "candidate-failed", provider: candidate.provider, model: candidate.model, attempt, total: candidates.length, elapsedMs: Date.now() - t0, error: e?.message || String(e) });
29629
29652
  const isClientAborted = Boolean(
29630
29653
  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"))
29631
29654
  );
@@ -29668,25 +29691,40 @@ Return concise JSON matching:
29668
29691
  "technicalGotchas": ["Important safety or compatibility note 1", "Note 2"]
29669
29692
  }`;
29670
29693
  let rawContent = "";
29671
- await streamLLMWithFallback(
29672
- "You are an authoritative STEM & CS curriculum researcher. Output valid JSON only.",
29673
- researchPrompt,
29674
- apiKeys,
29675
- (chunk, type) => {
29676
- if (type === "content") rawContent += chunk;
29677
- onChunk?.(chunk, type);
29678
- },
29679
- options.model,
29680
- options.provider,
29681
- // Research may run live web grounding — generous budget, still idle-guarded.
29682
- resolveStreamBudget(void 0, {
29683
- idleMs: options.idleTimeoutMs,
29684
- totalMs: options.timeoutMs,
29685
- model: options.model,
29686
- provider: options.provider
29687
- }),
29688
- options.signal
29689
- );
29694
+ if (options.customInference) {
29695
+ rawContent = await options.customInference({
29696
+ systemInstruction: "You are an authoritative STEM & CS curriculum researcher. Output valid JSON only.",
29697
+ userPrompt: researchPrompt,
29698
+ messages: [{ role: "user", content: researchPrompt }],
29699
+ temperature: 0.2,
29700
+ maxTokens: 32768,
29701
+ onChunk: (token, type) => {
29702
+ if (type === "content") rawContent += token;
29703
+ if (type === "content" || type === "thought") onChunk?.(token, type);
29704
+ }
29705
+ }) || "";
29706
+ } else {
29707
+ await streamLLMWithFallback(
29708
+ "You are an authoritative STEM & CS curriculum researcher. Output valid JSON only.",
29709
+ researchPrompt,
29710
+ apiKeys,
29711
+ (chunk, type) => {
29712
+ if (type === "content") rawContent += chunk;
29713
+ onChunk?.(chunk, type);
29714
+ },
29715
+ options.model,
29716
+ options.provider,
29717
+ // Research may run live web grounding — generous budget, still idle-guarded.
29718
+ resolveStreamBudget(void 0, {
29719
+ idleMs: options.idleTimeoutMs,
29720
+ totalMs: options.timeoutMs,
29721
+ model: options.model,
29722
+ provider: options.provider
29723
+ }),
29724
+ options.signal,
29725
+ options.onProviderEvent
29726
+ );
29727
+ }
29690
29728
  let parsedResearch = {
29691
29729
  groundTruthSummary: `Verified ecosystem standards for ${projectName}`,
29692
29730
  hardwareVersion: "Standard Environment",
@@ -29767,6 +29805,23 @@ async function streamLayerPrefillWithFallback(options, onChunk) {
29767
29805
  const research = await conductPreliminaryResearch(options, onChunk);
29768
29806
  return { success: true, research };
29769
29807
  }
29808
+ const runWithCustomInference = async (systemInstruction, userPrompt2) => {
29809
+ if (!options.customInference) return "";
29810
+ return options.customInference({
29811
+ systemInstruction,
29812
+ userPrompt: userPrompt2,
29813
+ messages: [{ role: "user", content: userPrompt2 }],
29814
+ temperature: 0.2,
29815
+ // Layer 3 synthesizes full context — give reasoning models the same
29816
+ // generous ceiling the artifact paths use (32k) so JSON is never truncated.
29817
+ maxTokens: 32768,
29818
+ onChunk: (token, type) => {
29819
+ if (type === "content") rawContent += token;
29820
+ if (type === "content" || type === "thought") onChunk?.(token, type);
29821
+ }
29822
+ });
29823
+ };
29824
+ let rawContent = "";
29770
29825
  const {
29771
29826
  projectName = "Curriculum Course",
29772
29827
  projectCode = "curriculum-course",
@@ -29878,27 +29933,31 @@ FULL ACCUMULATED CONTEXT (ALL CONFIRMED PARAMETERS FROM EVERY PREVIOUS STEP \u20
29878
29933
  ${buildRemainingContextBlock(accumulatedData) || "(no additional context)"}
29879
29934
 
29880
29935
  REQUIREMENT: Synthesize ALL parameters above \u2014 every single line in FULL ACCUMULATED CONTEXT is a confirmed user decision or system constraint and MUST influence the generated configuration. Produce the high-fidelity pre-fill configuration for LAYER ${targetLayer}.`;
29881
- let rawContent = "";
29882
- await streamLLMWithFallback(
29883
- systemPrompt,
29884
- userPrompt,
29885
- apiKeys,
29886
- (chunk, type) => {
29887
- if (type === "content") rawContent += chunk;
29888
- onChunk?.(chunk, type);
29889
- },
29890
- options.model,
29891
- options.provider,
29892
- // RC-W1: layer-aware budget — Layer 3 synthesizes full context and free-tier
29893
- // models (especially NVIDIA NIM) may think/stream for minutes. Idle window still catches hangs.
29894
- resolveStreamBudget(targetLayer, {
29895
- idleMs: options.idleTimeoutMs,
29896
- totalMs: options.timeoutMs,
29897
- model: options.model,
29898
- provider: options.provider
29899
- }),
29900
- options.signal
29901
- );
29936
+ if (options.customInference) {
29937
+ rawContent = await runWithCustomInference(systemPrompt, userPrompt) || "";
29938
+ } else {
29939
+ await streamLLMWithFallback(
29940
+ systemPrompt,
29941
+ userPrompt,
29942
+ apiKeys,
29943
+ (chunk, type) => {
29944
+ if (type === "content") rawContent += chunk;
29945
+ onChunk?.(chunk, type);
29946
+ },
29947
+ options.model,
29948
+ options.provider,
29949
+ // RC-W1: layer-aware budget — Layer 3 synthesizes full context and free-tier
29950
+ // models (especially NVIDIA NIM) may think/stream for minutes. Idle window still catches hangs.
29951
+ resolveStreamBudget(targetLayer, {
29952
+ idleMs: options.idleTimeoutMs,
29953
+ totalMs: options.timeoutMs,
29954
+ model: options.model,
29955
+ provider: options.provider
29956
+ }),
29957
+ options.signal,
29958
+ options.onProviderEvent
29959
+ );
29960
+ }
29902
29961
  const parsed = safeParseJson(rawContent);
29903
29962
  return {
29904
29963
  success: !!parsed,