/** Định nghĩa tool (OpenAI-compatible function schema) cho LLM tool-calling */ interface ToolDefinition { type: 'function'; function: { name: string; description: string; /** JSON Schema cho tham số */ parameters: Record; }; } /** Tool call hoàn chỉnh sau khi aggregate các delta */ interface AggregatedToolCall { id: string; name: string; /** JSON string arguments từ model */ arguments: string; } /** Kết quả thực thi tool do caller cung cấp */ interface ToolExecutionResult { toolCallId: string; name: string; /** Kết quả serialize thành JSON string khi gửi lại model */ result: unknown; isError?: boolean; } /** Executor: nhận (name, parsedArgs) → kết quả. Throw = lỗi tool (báo lại model) */ type ToolExecutor = (name: string, args: Record) => Promise; /** Cấu hình vòng lặp tool-calling */ interface ToolLoopConfig { tools: ToolDefinition[]; executor: ToolExecutor; /** Số vòng tool-call tối đa (chống vòng lặp vô hạn). Mặc định 4 */ maxRounds?: number; /** Báo mỗi lần bắt đầu thực thi tool (để UI hiển thị) */ onToolStart?: (name: string, args: Record) => void; /** Báo kết quả tool */ onToolResult?: (result: ToolExecutionResult) => void; /** Báo lỗi tool (không dừng workflow — tool error được đưa lại cho model tự xử lý) */ onToolError?: (name: string, error: string) => void; } interface ChatMessage { role: 'user' | 'assistant' | 'system' | 'model'; content: string; } interface StreamRunnerOptions { openrouterKey?: string; deepseekKey?: string; alibabaKey?: string; geminiKey?: string; nvidiaKey?: string; openaiKey?: string; anthropicKey?: string; model?: string; systemPersona?: string; maxTokens?: number; temperature?: number; reasoningEffort?: 'off' | 'low' | 'medium' | 'high' | 'max'; /** Thời gian tối đa cho phép không nhận thêm token mới trước khi abort (mặc định 90_000ms = 90s; env ARTIFACT_STREAM_IDLE_TIMEOUT_MS override) */ idleTimeoutMs?: number; /** Thời gian hard cap tối đa cho toàn bộ lượt stream trước khi abort (mặc định 420_000ms = 7 phút) */ timeoutMs?: number; /** * Host-provided inference override (Vercel AI SDK gateway, test stubs, …). * When set, ALL built-in provider routes (raw-fetch NVIDIA/OpenRouter/ * DeepSeek/DashScope/Gemini + designated fallback chain) are bypassed and * every inference call goes through this function instead. It receives the * fully-formed system instruction (persona + project context + guidelines) * and the user prompt, plus the same onChunk contract as the built-in * routes: stream text deltas via ('content'|'thought'), and report token * spend via onChunk(JSON.stringify({ promptTokens, completionTokens, * totalTokens, reasoningTokens }), 'usage'). Return the full completion text. */ customInference?: (request: { systemInstruction: string; userPrompt: string; messages: ChatMessage[]; temperature: number; maxTokens: number; onChunk: (token: string, type: ChunkType) => void; }) => Promise; /** * Host-provided TOOL-CALLING inference override (unified-tracing mandate, * gap #8 audit 2026-09-14). When present, `streamCurriculumAIInferenceWithTools` * routes every turn through this gateway instead of its built-in raw-fetch * provider routes, so tool-loop calls emit the host's OpenTelemetry spans * (unified Langfuse trace). The request carries the FULL conversation * (including prior assistant tool_calls and tool results) and the OpenAI- * compatible tool definitions; the implementation returns the turn result. * Stream text deltas via ('content'|'thought') chunks and report token spend * via onChunk(JSON.stringify({ promptTokens, completionTokens, totalTokens, * reasoningTokens }), 'usage') — same contract as customInference. */ customToolInference?: (request: { messages: Array<{ role: string; content: string | null; tool_calls?: Array<{ id: string; type: 'function'; function: { name: string; arguments: string; }; }>; tool_call_id?: string; }>; tools: ToolDefinition[]; temperature: number; maxTokens: number; onChunk: (token: string, type: ChunkType) => void; }) => Promise<{ content: string; toolCalls: AggregatedToolCall[]; }>; } declare function resolveApiKey(keyName: string, explicitKey?: string): string; /** * Checks if a specific AI provider is enabled via environment variables. * Supported env controls: * 1. ENABLE_=true|false (e.g. ENABLE_ALIBABA=false, ENABLE_OPENROUTER=true) * 2. ALLOWED_AI_PROVIDERS=openrouter,nvidia * 3. DISABLED_AI_PROVIDERS=alibaba,deepseek,gemini */ declare function isProviderEnabled(provider: string): boolean; /** * Checks if a model is permitted by ALLOWED_AI_MODELS filter (supports wildcards e.g. nvidia/*, *:free) */ declare function isModelAllowed(model: string): boolean; interface FallbackTarget { provider: string; model: string; } /** * Resolves the designated last-resort fallback chain from environment variables. * Comma-separated lists are parsed in left-to-right priority order: * - FALLBACK_AI_PROVIDER=nvidia,openrouter (Must be enabled / in ALLOWED_AI_PROVIDERS) * - FALLBACK_AI_MODEL=nvidia/nemotron-3-ultra-550b-a55b:free,@preset/coding-free,deepseek/deepseek-chat:free */ declare function getDesignatedFallbackChain(): FallbackTarget[]; declare function getDesignatedFallbackConfig(): FallbackTarget; type ChunkType = 'content' | 'thought' | 'tool_call' | 'usage'; /** * Separate thinking process from main content safely */ declare function extractThoughtAndContent(rawText: string): { thought: string; content: string; }; declare const DEFAULT_ARTIFACT_STREAM_IDLE_MS = 90000; declare const DEFAULT_ARTIFACT_STREAM_TOTAL_MS = 480000; interface StreamAbortController { signal: AbortSignal; /** Reset the idle window (call on every received chunk). */ kick: () => void; /** Clear all pending timers once the request lifecycle is over. */ dispose: () => void; } /** * Budget-aware stream abort controller. Combines an idle window (kicked on * every received chunk — covers slow TTFT and hung connections) with a generous * total hard cap (defaults to 420s / 7 minutes). * * Configurable via options or process.env: * - ARTIFACT_STREAM_IDLE_TIMEOUT_MS / STREAM_IDLE_TIMEOUT_MS * - ARTIFACT_STREAM_TOTAL_TIMEOUT_MS / STREAM_TOTAL_TIMEOUT_MS */ declare function createStreamAbortController(options?: { idleMs?: number; totalMs?: number; }): StreamAbortController; /** Backward-compatible alias */ declare function createIdleAbortController(idleMs?: number, totalMs?: number): StreamAbortController; type IdleAbort = StreamAbortController; /** * Real-time Streaming Multi-Provider Inference Runner with Thinking & Tool Streaming */ declare function streamCurriculumAIInference(messages: ChatMessage[], projectContext: string, options?: StreamRunnerOptions, onChunk?: (token: string, type: ChunkType) => void): Promise; /** * Synchronous Multi-Model Inference Wrapper with strict error propagation */ declare function runCurriculumAIInference(messages: ChatMessage[], projectContext: string, options?: StreamRunnerOptions, onChunk?: (token: string, type: ChunkType) => void): Promise; export { type AggregatedToolCall as A, type ChunkType 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, type ChatMessage as a, isModelAllowed as b, getDesignatedFallbackConfig 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 };