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

175 lines (174 loc) 6.14 kB
/** * Utility functions for AI provider management * Consolidated from providerUtils-fixed.ts */ import { AIProviderFactory } from "../core/factory.js"; import { logger } from "./logger.js"; /** * Get the best available provider based on real-time availability checks * Enhanced version consolidated from providerUtils-fixed.ts * @param requestedProvider - Optional preferred provider name * @returns The best provider name to use */ export async function getBestProvider(requestedProvider) { // 🔧 FIX: Check for explicit default provider in env if (process.env.DEFAULT_PROVIDER && (await isProviderAvailable(process.env.DEFAULT_PROVIDER))) { return process.env.DEFAULT_PROVIDER; } // 🔧 FIX: Special case for Ollama - prioritize local when available if (process.env.OLLAMA_BASE_URL && process.env.OLLAMA_MODEL) { try { if (await isProviderAvailable("ollama")) { logger.debug(`[getBestProvider] Prioritizing working local Ollama`); return "ollama"; // Prioritize working local AI } } catch { // Fall through to cloud providers } } const providers = [ "google-ai", "anthropic", "openai", "mistral", "vertex", "azure", "huggingface", "bedrock", "ollama", // Keep as fallback ]; if (requestedProvider && requestedProvider !== "auto") { if (await isProviderAvailable(requestedProvider)) { logger.debug(`[getBestProvider] Using requested provider: ${requestedProvider}`); return requestedProvider; } else { logger.warn(`[getBestProvider] Requested provider '${requestedProvider}' is not available. Falling back to auto-selection.`); } } for (const provider of providers) { if (await isProviderAvailable(provider)) { logger.debug(`[getBestProvider] Selected provider: ${provider}`); return provider; } } throw new Error("No available AI providers. Please check your configurations."); } /** * Check if a provider is truly available by performing a quick authentication test. * Enhanced function consolidated from providerUtils-fixed.ts * @param providerName - The name of the provider to check. * @returns True if the provider is available and authenticated. */ async function isProviderAvailable(providerName) { if (!hasProviderEnvVars(providerName) && providerName !== "ollama") { return false; } if (providerName === "ollama") { try { const response = await fetch("http://localhost:11434/api/tags", { method: "GET", signal: AbortSignal.timeout(2000), }); if (response.ok) { const { models } = await response.json(); const defaultOllamaModel = "llama3.2:latest"; return models.some((m) => m.name === defaultOllamaModel); } return false; } catch (error) { return false; } } try { const provider = await AIProviderFactory.createProvider(providerName); await provider.generate({ prompt: "test", maxTokens: 1 }); return true; } catch (error) { return false; } } /** * Check if a provider has the minimum required environment variables * NOTE: This only checks if variables exist, not if they're valid * @param provider - Provider name to check * @returns True if the provider has required environment variables */ export function hasProviderEnvVars(provider) { switch (provider.toLowerCase()) { case "bedrock": case "amazon": case "aws": return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY); case "vertex": case "googlevertex": case "google": case "gemini": return !!((process.env.GOOGLE_CLOUD_PROJECT_ID || process.env.VERTEX_PROJECT_ID || process.env.GOOGLE_VERTEX_PROJECT || process.env.GOOGLE_CLOUD_PROJECT) && (process.env.GOOGLE_APPLICATION_CREDENTIALS || process.env.GOOGLE_SERVICE_ACCOUNT_KEY || (process.env.GOOGLE_AUTH_CLIENT_EMAIL && process.env.GOOGLE_AUTH_PRIVATE_KEY))); case "openai": case "gpt": return !!process.env.OPENAI_API_KEY; case "anthropic": case "claude": return !!process.env.ANTHROPIC_API_KEY; case "azure": case "azureOpenai": return !!process.env.AZURE_OPENAI_API_KEY; case "google-ai": case "google-studio": return !!(process.env.GOOGLE_AI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY); case "huggingface": case "hugging-face": case "hf": return !!(process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN); case "ollama": case "local": case "local-ollama": // For Ollama, we check if the service is potentially available // This is a basic check - actual connectivity will be verified during usage return true; // Ollama doesn't require environment variables, just local service case "mistral": case "mistral-ai": case "mistralai": return !!process.env.MISTRAL_API_KEY; default: return false; } } /** * Get available provider names * @returns Array of available provider names */ export function getAvailableProviders() { return [ "bedrock", "vertex", "openai", "anthropic", "azure", "google-ai", "huggingface", "ollama", "mistral", ]; } /** * Validate provider name * @param provider - Provider name to validate * @returns True if provider name is valid */ export function isValidProvider(provider) { return getAvailableProviders().includes(provider.toLowerCase()); }