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

139 lines (138 loc) 5.09 kB
import { logger } from "../utils/logger.js"; /** * True Factory Pattern implementation for AI Providers * Uses registration-based approach to eliminate switch statements * and enable dynamic provider registration */ export class ProviderFactory { static providers = new Map(); static initialized = false; /** * Register a provider with the factory */ static registerProvider(name, constructor, defaultModel, // Optional - provider can read from env aliases = []) { const registration = { constructor, defaultModel, aliases, }; // Register main name this.providers.set(name.toLowerCase(), registration); // Register aliases aliases.forEach((alias) => { this.providers.set(alias.toLowerCase(), registration); }); logger.debug(`Registered provider: ${name} with model ${defaultModel || "from-env"}`); } /** * Create a provider instance */ static async createProvider(providerName, modelName, sdk) { // Note: Providers are registered explicitly by ProviderRegistry to avoid circular dependencies const normalizedName = providerName.toLowerCase(); const registration = this.providers.get(normalizedName); if (!registration) { throw new Error(`Unknown provider: ${providerName}. Available providers: ${this.getAvailableProviders().join(", ")}`); } // Respect environment variables before falling back to registry default let model = modelName; if (!model) { // Check for provider-specific environment variables if (providerName.toLowerCase().includes("vertex")) { model = process.env.VERTEX_MODEL; } // Fallback to registry default if no env var model = model || registration.defaultModel; } try { let result; try { // Try as async factory function first (most providers are async functions) result = await registration.constructor(model, providerName, sdk); } catch (functionError) { // Fallback to constructor - ensure parameters are maintained result = new registration.constructor(model, providerName, sdk); } // Return result (no need to await again if already awaited in try block) return result; } catch (error) { logger.error(`Failed to create provider ${providerName}:`, error); throw new Error(`Failed to create provider ${providerName}: ${error}`); } } /** * Check if a provider is registered */ static hasProvider(providerName) { return this.providers.has(providerName.toLowerCase()); } /** * Get list of available providers */ static getAvailableProviders() { return Array.from(this.providers.keys()).filter((name, index, arr) => arr.indexOf(name) === index); } /** * Get provider registration info */ static getProviderInfo(providerName) { return this.providers.get(providerName.toLowerCase()); } /** * Normalize provider names using aliases (PHASE 1: Factory Pattern) */ static normalizeProviderName(providerName) { const normalized = providerName.toLowerCase(); // Check direct registration if (this.providers.has(normalized)) { return normalized; } // Check aliases from all registrations for (const [name, registration] of this.providers.entries()) { if (registration.aliases?.includes(normalized)) { return name; } } return null; } /** * Clear all registrations (mainly for testing) */ static clearRegistrations() { this.providers.clear(); this.initialized = false; } /** * Ensure providers are initialized */ static ensureInitialized() { if (!this.initialized) { this.initializeDefaultProviders(); this.initialized = true; } } /** * Initialize default providers * NOTE: Providers are now registered by ProviderRegistry to avoid circular dependencies */ static initializeDefaultProviders() { logger.debug("BaseProvider factory pattern ready - providers registered by ProviderRegistry"); // No hardcoded registrations - all done dynamically by ProviderRegistry } /** * Create the best available provider for the given name * Used by NeuroLink SDK for streaming and generation */ static async createBestProvider(providerName, modelName, enableMCP, sdk) { return await this.createProvider(providerName, modelName, sdk); } } /** * Helper function to create providers with backward compatibility */ export async function createAIProvider(providerName, modelName) { return await ProviderFactory.createProvider(providerName, modelName); }