@thanh01.pmt/curriculum-kit 1.0.8 → 1.0.9

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.
@@ -15,6 +15,25 @@ interface StreamRunnerOptions {
15
15
  maxTokens?: number;
16
16
  temperature?: number;
17
17
  reasoningEffort?: 'off' | 'low' | 'medium' | 'high' | 'max';
18
+ /**
19
+ * Host-provided inference override (Vercel AI SDK gateway, test stubs, …).
20
+ * When set, ALL built-in provider routes (raw-fetch NVIDIA/OpenRouter/
21
+ * DeepSeek/DashScope/Gemini + designated fallback chain) are bypassed and
22
+ * every inference call goes through this function instead. It receives the
23
+ * fully-formed system instruction (persona + project context + guidelines)
24
+ * and the user prompt, plus the same onChunk contract as the built-in
25
+ * routes: stream text deltas via ('content'|'thought'), and report token
26
+ * spend via onChunk(JSON.stringify({ promptTokens, completionTokens,
27
+ * totalTokens, reasoningTokens }), 'usage'). Return the full completion text.
28
+ */
29
+ customInference?: (request: {
30
+ systemInstruction: string;
31
+ userPrompt: string;
32
+ messages: ChatMessage[];
33
+ temperature: number;
34
+ maxTokens: number;
35
+ onChunk: (token: string, type: ChunkType) => void;
36
+ }) => Promise<string>;
18
37
  }
19
38
  /**
20
39
  * Checks if a specific AI provider is enabled via environment variables.
@@ -15,6 +15,25 @@ interface StreamRunnerOptions {
15
15
  maxTokens?: number;
16
16
  temperature?: number;
17
17
  reasoningEffort?: 'off' | 'low' | 'medium' | 'high' | 'max';
18
+ /**
19
+ * Host-provided inference override (Vercel AI SDK gateway, test stubs, …).
20
+ * When set, ALL built-in provider routes (raw-fetch NVIDIA/OpenRouter/
21
+ * DeepSeek/DashScope/Gemini + designated fallback chain) are bypassed and
22
+ * every inference call goes through this function instead. It receives the
23
+ * fully-formed system instruction (persona + project context + guidelines)
24
+ * and the user prompt, plus the same onChunk contract as the built-in
25
+ * routes: stream text deltas via ('content'|'thought'), and report token
26
+ * spend via onChunk(JSON.stringify({ promptTokens, completionTokens,
27
+ * totalTokens, reasoningTokens }), 'usage'). Return the full completion text.
28
+ */
29
+ customInference?: (request: {
30
+ systemInstruction: string;
31
+ userPrompt: string;
32
+ messages: ChatMessage[];
33
+ temperature: number;
34
+ maxTokens: number;
35
+ onChunk: (token: string, type: ChunkType) => void;
36
+ }) => Promise<string>;
18
37
  }
19
38
  /**
20
39
  * Checks if a specific AI provider is enabled via environment variables.
@@ -429,6 +429,32 @@ Guidelines:
429
429
  3. Keep technical terminology and official API symbols intact.
430
430
  4. Format output using clean Markdown, clear sections, bullet points, and code blocks where required.
431
431
  5. Do NOT use emojis in headings, tab titles, or UI navigation labels.`;
432
+ if (options.customInference) {
433
+ try {
434
+ const text = await options.customInference({
435
+ systemInstruction,
436
+ userPrompt: messages.map((m) => m.content).join("\n\n"),
437
+ messages,
438
+ temperature,
439
+ maxTokens,
440
+ onChunk: onChunk ?? (() => {
441
+ })
442
+ });
443
+ if (text && text.trim()) return text;
444
+ throw createAiInferenceError({
445
+ errorCode: "ERR_AI_ALL_PROVIDERS_FAILED",
446
+ message: "customInference returned empty output",
447
+ rawError: { customInference: "empty response" }
448
+ });
449
+ } catch (e) {
450
+ if (e?.errorCode || e?.name === "AiInferenceError") throw e;
451
+ throw createAiInferenceError({
452
+ errorCode: "ERR_AI_ALL_PROVIDERS_FAILED",
453
+ message: `customInference failed: ${e?.message || e}`,
454
+ rawError: { customInference: String(e?.message || e) }
455
+ });
456
+ }
457
+ }
432
458
  const formattedMessages = [
433
459
  { role: "system", content: systemInstruction },
434
460
  ...messages.map((m) => ({