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

208 lines (207 loc) • 9.41 kB
import { createVertex, } from "@ai-sdk/google-vertex"; import { streamText } from "ai"; import { BaseProvider } from "../core/baseProvider.js"; import { logger } from "../utils/logger.js"; import { TimeoutError, } from "../utils/timeout.js"; import { DEFAULT_MAX_TOKENS } from "../core/constants.js"; import { validateApiKey, createVertexProjectConfig, createGoogleAuthConfig, } from "../utils/providerConfig.js"; // Cache for anthropic module to avoid repeated imports let _createVertexAnthropic = null; let _anthropicImportAttempted = false; // Function to dynamically import anthropic support async function getCreateVertexAnthropic() { if (_anthropicImportAttempted) { return _createVertexAnthropic; } _anthropicImportAttempted = true; try { // Try to import the anthropic module - available in @ai-sdk/google-vertex ^2.2.0+ // Use proper dynamic import without eval() for security const anthropicModule = (await import("@ai-sdk/google-vertex/anthropic")); _createVertexAnthropic = anthropicModule.createVertexAnthropic; logger.debug("[GoogleVertexAI] Anthropic module successfully loaded"); return _createVertexAnthropic; } catch (error) { // Anthropic module not available logger.warn("[GoogleVertexAI] Anthropic module not available. Install @ai-sdk/google-vertex ^2.2.0 for Anthropic model support."); return null; } } // Configuration helpers // Configuration helpers - now using consolidated utility const getVertexProjectId = () => { return validateApiKey(createVertexProjectConfig()); }; const getVertexLocation = () => { return (process.env.GOOGLE_CLOUD_LOCATION || process.env.VERTEX_LOCATION || process.env.GOOGLE_VERTEX_LOCATION || "us-central1"); }; const getDefaultVertexModel = () => { return process.env.VERTEX_MODEL || "gemini-1.5-pro"; }; const hasGoogleCredentials = () => { return !!(process.env.GOOGLE_APPLICATION_CREDENTIALS || process.env.GOOGLE_SERVICE_ACCOUNT_KEY || (process.env.GOOGLE_AUTH_CLIENT_EMAIL && process.env.GOOGLE_AUTH_PRIVATE_KEY)); }; /** * Google Vertex AI Provider v2 - BaseProvider Implementation * * PHASE 3.5: Simple BaseProvider wrap around existing @ai-sdk/google-vertex implementation * * Features: * - Extends BaseProvider for shared functionality * - Preserves existing Google Cloud authentication * - Maintains Anthropic model support via dynamic imports * - Uses pre-initialized Vertex instance for efficiency * - Enhanced error handling with setup guidance */ export class GoogleVertexProvider extends BaseProvider { vertex; model; projectId; location; cachedAnthropicModel = null; constructor(modelName, sdk) { super(modelName, "vertex", sdk); // Validate Google Cloud credentials - now using consolidated utility if (!hasGoogleCredentials()) { validateApiKey(createGoogleAuthConfig()); } // Initialize Google Cloud configuration this.projectId = getVertexProjectId(); this.location = getVertexLocation(); const vertexConfig = { project: this.projectId, location: this.location, }; // Create Vertex provider instance this.vertex = createVertex(vertexConfig); // Pre-initialize model for efficiency this.model = this.vertex(this.modelName || getDefaultVertexModel()); logger.debug("Google Vertex AI BaseProvider v2 initialized", { modelName: this.modelName, projectId: this.projectId, location: this.location, provider: this.providerName, }); } getProviderName() { return "vertex"; } getDefaultModel() { return getDefaultVertexModel(); } /** * Returns the Vercel AI SDK model instance for Google Vertex * Handles both Google and Anthropic models */ async getAISDKModel() { // Check if this is an Anthropic model if (this.modelName && this.modelName.includes("claude")) { // Return cached Anthropic model if available if (this.cachedAnthropicModel) { return this.cachedAnthropicModel; } // Create and cache new Anthropic model const anthropicModel = await this.createAnthropicModel(this.modelName); if (anthropicModel) { this.cachedAnthropicModel = anthropicModel; return anthropicModel; } // Fall back to regular model if Anthropic not available logger.warn(`Anthropic model ${this.modelName} requested but not available, falling back to Google model`); } return this.model; } // executeGenerate removed - BaseProvider handles all generation with tools async executeStream(options, analysisSchema) { try { this.validateStreamOptions(options); const result = await streamText({ model: this.model, prompt: options.input.text, system: options.systemPrompt, maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS, temperature: options.temperature, }); return { stream: (async function* () { for await (const chunk of result.textStream) { yield { content: chunk }; } })(), provider: this.providerName, model: this.modelName, }; } catch (error) { throw this.handleProviderError(error); } } handleProviderError(error) { const errorRecord = error; if (typeof errorRecord?.name === "string" && errorRecord.name === "TimeoutError") { return new TimeoutError(`Google Vertex AI request timed out. Consider increasing timeout or using a lighter model.`, this.defaultTimeout); } const message = typeof errorRecord?.message === "string" ? errorRecord.message : "Unknown error occurred"; if (message.includes("PERMISSION_DENIED")) { return new Error(`āŒ Google Vertex AI Permission Denied\n\nYour Google Cloud credentials don't have permission to access Vertex AI.\n\nšŸ”§ Required Steps:\n1. Ensure your service account has Vertex AI User role\n2. Check if Vertex AI API is enabled in your project\n3. Verify your project ID is correct\n4. Confirm your location/region has Vertex AI available`); } if (message.includes("NOT_FOUND")) { return new Error(`āŒ Google Vertex AI Model Not Found\n\n${message}\n\nšŸ”§ Check:\n1. Model name is correct (e.g., 'gemini-1.5-pro')\n2. Model is available in your region (${this.location})\n3. Your project has access to the model\n4. Model supports your request parameters`); } if (message.includes("QUOTA_EXCEEDED")) { return new Error(`āŒ Google Vertex AI Quota Exceeded\n\n${message}\n\nšŸ”§ Solutions:\n1. Check your Vertex AI quotas in Google Cloud Console\n2. Request quota increase if needed\n3. Try a different model or reduce request frequency\n4. Consider using a different region`); } if (message.includes("INVALID_ARGUMENT")) { return new Error(`āŒ Google Vertex AI Invalid Request\n\n${message}\n\nšŸ”§ Check:\n1. Request parameters are within model limits\n2. Input text is properly formatted\n3. Temperature and other settings are valid\n4. Model supports your request type`); } return new Error(`āŒ Google Vertex AI Provider Error\n\n${message}\n\nšŸ”§ Troubleshooting:\n1. Check Google Cloud credentials and permissions\n2. Verify project ID and location settings\n3. Ensure Vertex AI API is enabled\n4. Check network connectivity`); } validateStreamOptions(options) { if (!options.input?.text?.trim()) { throw new Error("Prompt is required for streaming"); } if (options.maxTokens && (options.maxTokens < 1 || options.maxTokens > 8192)) { throw new Error("maxTokens must be between 1 and 8192 for Google Vertex AI"); } if (options.temperature && (options.temperature < 0 || options.temperature > 2)) { throw new Error("temperature must be between 0 and 2"); } } /** * Check if Anthropic models are available * @returns Promise<boolean> indicating if Anthropic support is available */ async hasAnthropicSupport() { const createVertexAnthropic = await getCreateVertexAnthropic(); return createVertexAnthropic !== null; } /** * Create an Anthropic model instance if available * @param modelName Anthropic model name (e.g., 'claude-3-sonnet@20240229') * @returns LanguageModelV1 instance or null if not available */ async createAnthropicModel(modelName) { const createVertexAnthropic = await getCreateVertexAnthropic(); if (!createVertexAnthropic) { return null; } const vertexAnthropic = createVertexAnthropic({ project: this.projectId, location: this.location, }); return vertexAnthropic(modelName); } } export default GoogleVertexProvider;