@thanh01.pmt/curriculum-kit 1.4.31 → 1.4.33
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 +126 -1
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +10 -46
- package/dist/ai/index.d.ts +10 -46
- package/dist/ai/index.mjs +126 -1
- package/dist/ai/index.mjs.map +1 -1
- package/dist/index.cjs +128 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +128 -1
- package/dist/index.mjs.map +1 -1
- package/dist/media/index.cjs.map +1 -1
- package/dist/media/index.d.cts +1 -1
- package/dist/media/index.d.ts +1 -1
- package/dist/media/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +48 -1
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +48 -1
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/{streamRunner-DYHFhNUr.d.cts → streamRunner-B0Z1nAG5.d.cts} +76 -1
- package/dist/{streamRunner-DYHFhNUr.d.ts → streamRunner-B0Z1nAG5.d.ts} +76 -1
- package/dist/workflow/index.cjs +48 -1
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.mjs +48 -1
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
/** Định nghĩa tool (OpenAI-compatible function schema) cho LLM tool-calling */
|
|
2
|
+
interface ToolDefinition {
|
|
3
|
+
type: 'function';
|
|
4
|
+
function: {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
/** JSON Schema cho tham số */
|
|
8
|
+
parameters: Record<string, unknown>;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Tool call hoàn chỉnh sau khi aggregate các delta */
|
|
12
|
+
interface AggregatedToolCall {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
/** JSON string arguments từ model */
|
|
16
|
+
arguments: string;
|
|
17
|
+
}
|
|
18
|
+
/** Kết quả thực thi tool do caller cung cấp */
|
|
19
|
+
interface ToolExecutionResult {
|
|
20
|
+
toolCallId: string;
|
|
21
|
+
name: string;
|
|
22
|
+
/** Kết quả serialize thành JSON string khi gửi lại model */
|
|
23
|
+
result: unknown;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Executor: nhận (name, parsedArgs) → kết quả. Throw = lỗi tool (báo lại model) */
|
|
27
|
+
type ToolExecutor = (name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
28
|
+
/** Cấu hình vòng lặp tool-calling */
|
|
29
|
+
interface ToolLoopConfig {
|
|
30
|
+
tools: ToolDefinition[];
|
|
31
|
+
executor: ToolExecutor;
|
|
32
|
+
/** Số vòng tool-call tối đa (chống vòng lặp vô hạn). Mặc định 4 */
|
|
33
|
+
maxRounds?: number;
|
|
34
|
+
/** Báo mỗi lần bắt đầu thực thi tool (để UI hiển thị) */
|
|
35
|
+
onToolStart?: (name: string, args: Record<string, unknown>) => void;
|
|
36
|
+
/** Báo kết quả tool */
|
|
37
|
+
onToolResult?: (result: ToolExecutionResult) => void;
|
|
38
|
+
/** Báo lỗi tool (không dừng workflow — tool error được đưa lại cho model tự xử lý) */
|
|
39
|
+
onToolError?: (name: string, error: string) => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
1
42
|
interface ChatMessage {
|
|
2
43
|
role: 'user' | 'assistant' | 'system' | 'model';
|
|
3
44
|
content: string;
|
|
@@ -38,6 +79,40 @@ interface StreamRunnerOptions {
|
|
|
38
79
|
maxTokens: number;
|
|
39
80
|
onChunk: (token: string, type: ChunkType) => void;
|
|
40
81
|
}) => Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Host-provided TOOL-CALLING inference override (unified-tracing mandate,
|
|
84
|
+
* gap #8 audit 2026-09-14). When present, `streamCurriculumAIInferenceWithTools`
|
|
85
|
+
* routes every turn through this gateway instead of its built-in raw-fetch
|
|
86
|
+
* provider routes, so tool-loop calls emit the host's OpenTelemetry spans
|
|
87
|
+
* (unified Langfuse trace). The request carries the FULL conversation
|
|
88
|
+
* (including prior assistant tool_calls and tool results) and the OpenAI-
|
|
89
|
+
* compatible tool definitions; the implementation returns the turn result.
|
|
90
|
+
* Stream text deltas via ('content'|'thought') chunks and report token spend
|
|
91
|
+
* via onChunk(JSON.stringify({ promptTokens, completionTokens, totalTokens,
|
|
92
|
+
* reasoningTokens }), 'usage') — same contract as customInference.
|
|
93
|
+
*/
|
|
94
|
+
customToolInference?: (request: {
|
|
95
|
+
messages: Array<{
|
|
96
|
+
role: string;
|
|
97
|
+
content: string | null;
|
|
98
|
+
tool_calls?: Array<{
|
|
99
|
+
id: string;
|
|
100
|
+
type: 'function';
|
|
101
|
+
function: {
|
|
102
|
+
name: string;
|
|
103
|
+
arguments: string;
|
|
104
|
+
};
|
|
105
|
+
}>;
|
|
106
|
+
tool_call_id?: string;
|
|
107
|
+
}>;
|
|
108
|
+
tools: ToolDefinition[];
|
|
109
|
+
temperature: number;
|
|
110
|
+
maxTokens: number;
|
|
111
|
+
onChunk: (token: string, type: ChunkType) => void;
|
|
112
|
+
}) => Promise<{
|
|
113
|
+
content: string;
|
|
114
|
+
toolCalls: AggregatedToolCall[];
|
|
115
|
+
}>;
|
|
41
116
|
}
|
|
42
117
|
declare function resolveApiKey(keyName: string, explicitKey?: string): string;
|
|
43
118
|
/**
|
|
@@ -106,4 +181,4 @@ declare function streamCurriculumAIInference(messages: ChatMessage[], projectCon
|
|
|
106
181
|
*/
|
|
107
182
|
declare function runCurriculumAIInference(messages: ChatMessage[], projectContext: string, options?: StreamRunnerOptions, onChunk?: (token: string, type: ChunkType) => void): Promise<string>;
|
|
108
183
|
|
|
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 };
|
|
184
|
+
export { type AggregatedToolCall as A, type ChatMessage as C, DEFAULT_ARTIFACT_STREAM_IDLE_MS as D, type FallbackTarget as F, type IdleAbort as I, type StreamRunnerOptions as S, type ToolDefinition as T, 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, type ToolExecutionResult as l, type ToolExecutor as m, type ToolLoopConfig as n, resolveApiKey as r, streamCurriculumAIInference as s };
|
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
/** Định nghĩa tool (OpenAI-compatible function schema) cho LLM tool-calling */
|
|
2
|
+
interface ToolDefinition {
|
|
3
|
+
type: 'function';
|
|
4
|
+
function: {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
/** JSON Schema cho tham số */
|
|
8
|
+
parameters: Record<string, unknown>;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Tool call hoàn chỉnh sau khi aggregate các delta */
|
|
12
|
+
interface AggregatedToolCall {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
/** JSON string arguments từ model */
|
|
16
|
+
arguments: string;
|
|
17
|
+
}
|
|
18
|
+
/** Kết quả thực thi tool do caller cung cấp */
|
|
19
|
+
interface ToolExecutionResult {
|
|
20
|
+
toolCallId: string;
|
|
21
|
+
name: string;
|
|
22
|
+
/** Kết quả serialize thành JSON string khi gửi lại model */
|
|
23
|
+
result: unknown;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Executor: nhận (name, parsedArgs) → kết quả. Throw = lỗi tool (báo lại model) */
|
|
27
|
+
type ToolExecutor = (name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
28
|
+
/** Cấu hình vòng lặp tool-calling */
|
|
29
|
+
interface ToolLoopConfig {
|
|
30
|
+
tools: ToolDefinition[];
|
|
31
|
+
executor: ToolExecutor;
|
|
32
|
+
/** Số vòng tool-call tối đa (chống vòng lặp vô hạn). Mặc định 4 */
|
|
33
|
+
maxRounds?: number;
|
|
34
|
+
/** Báo mỗi lần bắt đầu thực thi tool (để UI hiển thị) */
|
|
35
|
+
onToolStart?: (name: string, args: Record<string, unknown>) => void;
|
|
36
|
+
/** Báo kết quả tool */
|
|
37
|
+
onToolResult?: (result: ToolExecutionResult) => void;
|
|
38
|
+
/** Báo lỗi tool (không dừng workflow — tool error được đưa lại cho model tự xử lý) */
|
|
39
|
+
onToolError?: (name: string, error: string) => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
1
42
|
interface ChatMessage {
|
|
2
43
|
role: 'user' | 'assistant' | 'system' | 'model';
|
|
3
44
|
content: string;
|
|
@@ -38,6 +79,40 @@ interface StreamRunnerOptions {
|
|
|
38
79
|
maxTokens: number;
|
|
39
80
|
onChunk: (token: string, type: ChunkType) => void;
|
|
40
81
|
}) => Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Host-provided TOOL-CALLING inference override (unified-tracing mandate,
|
|
84
|
+
* gap #8 audit 2026-09-14). When present, `streamCurriculumAIInferenceWithTools`
|
|
85
|
+
* routes every turn through this gateway instead of its built-in raw-fetch
|
|
86
|
+
* provider routes, so tool-loop calls emit the host's OpenTelemetry spans
|
|
87
|
+
* (unified Langfuse trace). The request carries the FULL conversation
|
|
88
|
+
* (including prior assistant tool_calls and tool results) and the OpenAI-
|
|
89
|
+
* compatible tool definitions; the implementation returns the turn result.
|
|
90
|
+
* Stream text deltas via ('content'|'thought') chunks and report token spend
|
|
91
|
+
* via onChunk(JSON.stringify({ promptTokens, completionTokens, totalTokens,
|
|
92
|
+
* reasoningTokens }), 'usage') — same contract as customInference.
|
|
93
|
+
*/
|
|
94
|
+
customToolInference?: (request: {
|
|
95
|
+
messages: Array<{
|
|
96
|
+
role: string;
|
|
97
|
+
content: string | null;
|
|
98
|
+
tool_calls?: Array<{
|
|
99
|
+
id: string;
|
|
100
|
+
type: 'function';
|
|
101
|
+
function: {
|
|
102
|
+
name: string;
|
|
103
|
+
arguments: string;
|
|
104
|
+
};
|
|
105
|
+
}>;
|
|
106
|
+
tool_call_id?: string;
|
|
107
|
+
}>;
|
|
108
|
+
tools: ToolDefinition[];
|
|
109
|
+
temperature: number;
|
|
110
|
+
maxTokens: number;
|
|
111
|
+
onChunk: (token: string, type: ChunkType) => void;
|
|
112
|
+
}) => Promise<{
|
|
113
|
+
content: string;
|
|
114
|
+
toolCalls: AggregatedToolCall[];
|
|
115
|
+
}>;
|
|
41
116
|
}
|
|
42
117
|
declare function resolveApiKey(keyName: string, explicitKey?: string): string;
|
|
43
118
|
/**
|
|
@@ -106,4 +181,4 @@ declare function streamCurriculumAIInference(messages: ChatMessage[], projectCon
|
|
|
106
181
|
*/
|
|
107
182
|
declare function runCurriculumAIInference(messages: ChatMessage[], projectContext: string, options?: StreamRunnerOptions, onChunk?: (token: string, type: ChunkType) => void): Promise<string>;
|
|
108
183
|
|
|
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 };
|
|
184
|
+
export { type AggregatedToolCall as A, type ChatMessage as C, DEFAULT_ARTIFACT_STREAM_IDLE_MS as D, type FallbackTarget as F, type IdleAbort as I, type StreamRunnerOptions as S, type ToolDefinition as T, 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, type ToolExecutionResult as l, type ToolExecutor as m, type ToolLoopConfig as n, resolveApiKey as r, streamCurriculumAIInference as s };
|
package/dist/workflow/index.cjs
CHANGED
|
@@ -958,6 +958,52 @@ var init_streamRunner = __esm({
|
|
|
958
958
|
DEFAULT_ARTIFACT_STREAM_TOTAL_MS = 48e4;
|
|
959
959
|
}
|
|
960
960
|
});
|
|
961
|
+
function cleanNonStreamingFetch() {
|
|
962
|
+
return async (input, init) => {
|
|
963
|
+
const res = await fetch(input, init);
|
|
964
|
+
let wantsStream = false;
|
|
965
|
+
try {
|
|
966
|
+
const body = init?.body;
|
|
967
|
+
if (typeof body === "string") wantsStream = /"stream"\s*:\s*true/.test(body);
|
|
968
|
+
} catch {
|
|
969
|
+
}
|
|
970
|
+
if (wantsStream) return res;
|
|
971
|
+
const contentType = res.headers.get("content-type") || "";
|
|
972
|
+
if (!contentType.includes("text/event-stream") && !contentType.includes("application/json")) return res;
|
|
973
|
+
const text = await res.text();
|
|
974
|
+
const trimmed = text.trim();
|
|
975
|
+
if (trimmed.startsWith("data:")) {
|
|
976
|
+
let content = "";
|
|
977
|
+
let lastChunk = null;
|
|
978
|
+
for (const line of trimmed.split("\n")) {
|
|
979
|
+
const l = line.trim();
|
|
980
|
+
if (!l || !l.startsWith("data:")) continue;
|
|
981
|
+
const jsonStr = l.slice(5).trim();
|
|
982
|
+
if (jsonStr === "[DONE]") continue;
|
|
983
|
+
try {
|
|
984
|
+
const chunk = JSON.parse(jsonStr);
|
|
985
|
+
lastChunk = chunk;
|
|
986
|
+
content += chunk.choices?.[0]?.delta?.content || "";
|
|
987
|
+
} catch {
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
const assembled = {
|
|
991
|
+
id: lastChunk?.id || "chatcmpl-" + Date.now(),
|
|
992
|
+
object: "chat.completion",
|
|
993
|
+
created: lastChunk?.created || Math.floor(Date.now() / 1e3),
|
|
994
|
+
model: lastChunk?.model || "9router",
|
|
995
|
+
choices: [{ index: 0, message: { role: "assistant", content }, finish_reason: "stop" }],
|
|
996
|
+
usage: lastChunk?.usage || void 0
|
|
997
|
+
};
|
|
998
|
+
const headers = new Headers(res.headers);
|
|
999
|
+
headers.set("content-type", "application/json");
|
|
1000
|
+
return new Response(JSON.stringify(assembled), { status: res.status, statusText: res.statusText, headers });
|
|
1001
|
+
}
|
|
1002
|
+
const doneIndex = text.indexOf("data: [DONE]");
|
|
1003
|
+
if (doneIndex === -1) return res;
|
|
1004
|
+
return new Response(text.slice(0, doneIndex).trim(), { status: res.status, statusText: res.statusText, headers: res.headers });
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
961
1007
|
function getAIModel(options = {}) {
|
|
962
1008
|
const designated = getDesignatedFallbackConfig();
|
|
963
1009
|
const defaultProvider = process.env.DEFAULT_AI_PROVIDER || process.env.LLM_PROVIDER || detectDefaultProvider();
|
|
@@ -976,7 +1022,8 @@ function getAIModel(options = {}) {
|
|
|
976
1022
|
const rawUrl = options.baseURL || resolveApiKey("NINEROUTER_BASE_URL") || resolveApiKey("NINE_ROUTER_BASE_URL") || "https://ai-router.orchable.app/v1";
|
|
977
1023
|
const ninerouter = openai.createOpenAI({
|
|
978
1024
|
apiKey,
|
|
979
|
-
baseURL: rawUrl.replace(/^["']|["']$/g, "").trim()
|
|
1025
|
+
baseURL: rawUrl.replace(/^["']|["']$/g, "").trim(),
|
|
1026
|
+
fetch: cleanNonStreamingFetch()
|
|
980
1027
|
});
|
|
981
1028
|
return ninerouter.chat(resolvedModelName || "fast-reasoning");
|
|
982
1029
|
}
|