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

119 lines (118 loc) 4.65 kB
import { anthropic } from "@ai-sdk/anthropic"; import { streamText, Output } from "ai"; import { BaseProvider } from "../core/baseProvider.js"; import { logger } from "../utils/logger.js"; import { createTimeoutController, TimeoutError, getDefaultTimeout, } from "../utils/timeout.js"; import { DEFAULT_MAX_TOKENS } from "../core/constants.js"; import { validateApiKey, createAnthropicConfig, getProviderModel, } from "../utils/providerConfig.js"; // Configuration helpers - now using consolidated utility const getAnthropicApiKey = () => { return validateApiKey(createAnthropicConfig()); }; const getDefaultAnthropicModel = () => { return getProviderModel("ANTHROPIC_MODEL", "claude-3-5-sonnet-20241022"); }; /** * Anthropic Provider v2 - BaseProvider Implementation * Fixed syntax and enhanced with proper error handling */ export class AnthropicProvider extends BaseProvider { model; constructor(modelName, sdk) { super(modelName, "anthropic", sdk); // Initialize Anthropic model with API key validation const apiKey = getAnthropicApiKey(); // Set Anthropic API key as environment variable (required by @ai-sdk/anthropic) process.env.ANTHROPIC_API_KEY = apiKey; // Initialize Anthropic with proper configuration this.model = anthropic(this.modelName || getDefaultAnthropicModel()); logger.debug("Anthropic Provider v2 initialized", { modelName: this.modelName, provider: this.providerName, }); } getProviderName() { return "anthropic"; } getDefaultModel() { return getDefaultAnthropicModel(); } /** * Returns the Vercel AI SDK model instance for Anthropic */ getAISDKModel() { return this.model; } handleProviderError(error) { if (error instanceof TimeoutError) { return new Error(`Anthropic request timed out: ${error.message}`); } const errorRecord = error; if ((typeof errorRecord?.message === "string" && errorRecord.message.includes("API_KEY_INVALID")) || (typeof errorRecord?.message === "string" && errorRecord.message.includes("Invalid API key"))) { return new Error("Invalid Anthropic API key. Please check your ANTHROPIC_API_KEY environment variable."); } if (typeof errorRecord?.message === "string" && errorRecord.message.includes("rate limit")) { return new Error("Anthropic rate limit exceeded. Please try again later."); } const message = typeof errorRecord?.message === "string" ? errorRecord.message : "Unknown error"; return new Error(`Anthropic error: ${message}`); } // executeGenerate removed - BaseProvider handles all generation with tools async executeStream(options, analysisSchema) { // Convert StreamOptions to TextGenerationOptions for validation const validationOptions = { prompt: options.input.text, systemPrompt: options.systemPrompt, temperature: options.temperature, maxTokens: options.maxTokens, }; this.validateOptions(validationOptions); const timeout = this.getTimeout(options); const timeoutController = createTimeoutController(timeout, this.providerName, "stream"); try { const result = await streamText({ model: this.model, prompt: options.input.text, system: options.systemPrompt || undefined, temperature: options.temperature, maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS, abortSignal: timeoutController?.controller.signal, }); timeoutController?.cleanup(); // Transform string stream to content object stream const transformedStream = async function* () { for await (const chunk of result.textStream) { yield { content: chunk }; } }; return { stream: transformedStream(), provider: this.providerName, model: this.modelName, }; } catch (error) { timeoutController?.cleanup(); throw this.handleProviderError(error); } } async isAvailable() { try { getAnthropicApiKey(); return true; } catch { return false; } } getModel() { return this.model; } } export default AnthropicProvider;