@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
JavaScript
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;