UNPKG

@juspay/neurolink

Version:

Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and

143 lines (142 loc) 5.63 kB
import { createMistral } from "@ai-sdk/mistral"; import { streamText } from "ai"; import { BaseProvider } from "../core/baseProvider.js"; import { logger } from "../utils/logger.js"; import { createTimeoutController, TimeoutError, } from "../utils/timeout.js"; import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js"; import { validateApiKey, createMistralConfig, getProviderModel, } from "../utils/providerConfig.js"; import { streamAnalyticsCollector } from "../core/streamAnalytics.js"; import { buildMessagesArray } from "../utils/messageBuilder.js"; import { createProxyFetch } from "../proxy/proxyFetch.js"; // Configuration helpers - now using consolidated utility const getMistralApiKey = () => { return validateApiKey(createMistralConfig()); }; const getDefaultMistralModel = () => { return getProviderModel("MISTRAL_MODEL", "mistral-large-latest"); }; /** * Mistral AI Provider v2 - BaseProvider Implementation * Supports official AI-SDK integration with all Mistral models */ export class MistralProvider extends BaseProvider { model; constructor(modelName, sdk) { // Type guard for NeuroLink parameter validation const validatedNeurolink = sdk && typeof sdk === "object" && "getInMemoryServers" in sdk ? sdk : undefined; super(modelName, "mistral", validatedNeurolink); // Initialize Mistral model with API key validation and proxy support const apiKey = getMistralApiKey(); const mistral = createMistral({ apiKey: apiKey, fetch: createProxyFetch(), }); this.model = mistral(this.modelName); logger.debug("Mistral Provider v2 initialized", { modelName: this.modelName, providerName: this.providerName, }); } // generate() method is inherited from BaseProvider; this provider uses the base implementation for generation with tools async executeStream(options, analysisSchema) { this.validateStreamOptions(options); const startTime = Date.now(); const timeout = this.getTimeout(options); const timeoutController = createTimeoutController(timeout, this.providerName, "stream"); try { // Get tools consistently with generate method const shouldUseTools = !options.disableTools && this.supportsTools(); const tools = shouldUseTools ? await this.getAllTools() : {}; const messages = buildMessagesArray(options); const result = await streamText({ model: this.model, messages: messages, temperature: options.temperature, maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS, tools, maxSteps: options.maxSteps || DEFAULT_MAX_STEPS, toolChoice: shouldUseTools ? "auto" : "none", abortSignal: timeoutController?.controller.signal, }); timeoutController?.cleanup(); // Transform string stream to content object stream using BaseProvider method const transformedStream = this.createTextStream(result); // Create analytics promise that resolves after stream completion const analyticsPromise = streamAnalyticsCollector.createAnalytics(this.providerName, this.modelName, result, Date.now() - startTime, { requestId: `mistral-stream-${Date.now()}`, streamingMode: true, }); return { stream: transformedStream, provider: this.providerName, model: this.modelName, analytics: analyticsPromise, metadata: { startTime, streamId: `mistral-${Date.now()}`, }, }; } catch (error) { timeoutController?.cleanup(); throw this.handleProviderError(error); } } // =================== // ABSTRACT METHOD IMPLEMENTATIONS // =================== getProviderName() { return this.providerName; } getDefaultModel() { return getDefaultMistralModel(); } /** * Returns the Vercel AI SDK model instance for Mistral */ getAISDKModel() { return this.model; } handleProviderError(error) { if (error instanceof TimeoutError) { return new Error(`Mistral request timed out: ${error.message}`); } const errorRecord = error; const message = typeof errorRecord?.message === "string" ? errorRecord.message : "Unknown error"; if (message.includes("API_KEY_INVALID") || message.includes("Invalid API key")) { return new Error("Invalid Mistral API key. Please check your MISTRAL_API_KEY environment variable."); } if (message.includes("rate limit")) { return new Error("Mistral rate limit exceeded. Please try again later."); } return new Error(`Mistral error: ${message}`); } /** * Validate provider configuration */ async validateConfiguration() { try { getMistralApiKey(); return true; } catch { return false; } } /** * Get provider-specific configuration */ getConfiguration() { return { provider: this.providerName, model: this.modelName, defaultModel: getDefaultMistralModel(), }; } } export default MistralProvider;