@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
127 lines (126 loc) • 5.58 kB
JavaScript
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { streamText } from "ai";
import { GoogleAIModels } from "../core/types.js";
import { BaseProvider } from "../core/baseProvider.js";
import { logger } from "../utils/logger.js";
import { createTimeoutController, TimeoutError, } from "../utils/timeout.js";
import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
import { buildMessagesArray } from "../utils/messageBuilder.js";
// Environment variable setup
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY &&
process.env.GOOGLE_AI_API_KEY) {
process.env.GOOGLE_GENERATIVE_AI_API_KEY = process.env.GOOGLE_AI_API_KEY;
}
/**
* Google AI Studio provider implementation using BaseProvider
* Migrated from original GoogleAIStudio class to new factory pattern
*/
export class GoogleAIStudioProvider extends BaseProvider {
constructor(modelName, sdk) {
super(modelName, "google-ai", sdk);
logger.debug("GoogleAIStudioProvider initialized", {
model: this.modelName,
provider: this.providerName,
sdkProvided: !!sdk,
});
}
// ===================
// ABSTRACT METHOD IMPLEMENTATIONS
// ===================
getProviderName() {
return "google-ai";
}
getDefaultModel() {
return process.env.GOOGLE_AI_MODEL || GoogleAIModels.GEMINI_2_5_FLASH;
}
/**
* 🔧 PHASE 2: Return AI SDK model instance for tool calling
*/
getAISDKModel() {
const apiKey = this.getApiKey();
const google = createGoogleGenerativeAI({ apiKey });
return google(this.modelName);
}
handleProviderError(error) {
if (error instanceof TimeoutError) {
throw new NetworkError(error.message, this.providerName);
}
const errorRecord = error;
const message = typeof errorRecord?.message === "string"
? errorRecord.message
: "Unknown error";
if (message.includes("API_KEY_INVALID")) {
throw new AuthenticationError("Invalid Google AI API key. Please check your GOOGLE_AI_API_KEY environment variable.", this.providerName);
}
if (message.includes("RATE_LIMIT_EXCEEDED")) {
throw new RateLimitError("Google AI rate limit exceeded. Please try again later.", this.providerName);
}
throw new ProviderError(`Google AI error: ${message}`, this.providerName);
}
// executeGenerate removed - BaseProvider handles all generation with tools
async executeStream(options, analysisSchema) {
this.validateStreamOptions(options);
const startTime = Date.now();
const apiKey = this.getApiKey();
// Ensure environment variable is set for @ai-sdk/google
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY) {
process.env.GOOGLE_GENERATIVE_AI_API_KEY = apiKey;
}
const google = createGoogleGenerativeAI({ apiKey });
const model = google(this.modelName);
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() : {};
// Build message array from options
const messages = buildMessagesArray(options);
const result = await streamText({
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: `google-ai-stream-${Date.now()}`,
streamingMode: true,
});
return {
stream: transformedStream,
provider: this.providerName,
model: this.modelName,
analytics: analyticsPromise,
metadata: {
startTime,
streamId: `google-ai-${Date.now()}`,
},
};
}
catch (error) {
timeoutController?.cleanup();
throw this.handleProviderError(error);
}
}
// ===================
// HELPER METHODS
// ===================
getApiKey() {
const apiKey = process.env.GOOGLE_AI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY;
if (!apiKey) {
throw new AuthenticationError("GOOGLE_AI_API_KEY or GOOGLE_GENERATIVE_AI_API_KEY environment variable is not set", this.providerName);
}
return apiKey;
}
}
export default GoogleAIStudioProvider;