From 0a9641a110aaad4c6a6d193e7f2977d98e954779 Mon Sep 17 00:00:00 2001 From: ItzCrazyKns <95534749+ItzCrazyKns@users.noreply.github.com> Date: Wed, 24 Dec 2025 15:24:06 +0530 Subject: [PATCH] feat(providers): add anthropic --- .../providers/anthropic/anthropicLLM.ts | 5 + src/lib/models/providers/anthropic/index.ts | 115 ++++++++++++++++++ src/lib/models/providers/index.ts | 4 +- src/lib/models/providers/lemonade/index.ts | 3 - 4 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 src/lib/models/providers/anthropic/anthropicLLM.ts create mode 100644 src/lib/models/providers/anthropic/index.ts diff --git a/src/lib/models/providers/anthropic/anthropicLLM.ts b/src/lib/models/providers/anthropic/anthropicLLM.ts new file mode 100644 index 0000000..9d660d6 --- /dev/null +++ b/src/lib/models/providers/anthropic/anthropicLLM.ts @@ -0,0 +1,5 @@ +import OpenAILLM from "../openai/openaiLLM"; + +class AnthropicLLM extends OpenAILLM {} + +export default AnthropicLLM; \ No newline at end of file diff --git a/src/lib/models/providers/anthropic/index.ts b/src/lib/models/providers/anthropic/index.ts new file mode 100644 index 0000000..2278ca2 --- /dev/null +++ b/src/lib/models/providers/anthropic/index.ts @@ -0,0 +1,115 @@ +import { UIConfigField } from '@/lib/config/types'; +import { getConfiguredModelProviderById } from '@/lib/config/serverRegistry'; +import { Model, ModelList, ProviderMetadata } from '../../types'; +import BaseEmbedding from '../../base/embedding'; +import BaseModelProvider from '../../base/provider'; +import BaseLLM from '../../base/llm'; +import AnthropicLLM from './anthropicLLM'; + +interface AnthropicConfig { + apiKey: string; +} + +const providerConfigFields: UIConfigField[] = [ + { + type: 'password', + name: 'API Key', + key: 'apiKey', + description: 'Your Anthropic API key', + required: true, + placeholder: 'Anthropic API Key', + env: 'ANTHROPIC_API_KEY', + scope: 'server', + }, +]; + +class AnthropicProvider extends BaseModelProvider { + constructor(id: string, name: string, config: AnthropicConfig) { + super(id, name, config); + } + + async getDefaultModels(): Promise { + const res = await fetch('https://api.anthropic.com/v1/models?limit=999', { + method: 'GET', + headers: { + 'x-api-key': this.config.apiKey, + 'anthropic-version': '2023-06-01', + 'Content-type': 'application/json', + }, + }); + + if (!res.ok) { + throw new Error(`Failed to fetch Anthropic models: ${res.statusText}`); + } + + const data = (await res.json()).data; + + const models: Model[] = data.map((m: any) => { + return { + key: m.id, + name: m.display_name, + }; + }); + + return { + embedding: [], + chat: models, + }; + } + + async getModelList(): Promise { + const defaultModels = await this.getDefaultModels(); + const configProvider = getConfiguredModelProviderById(this.id)!; + + return { + embedding: [], + chat: [...defaultModels.chat, ...configProvider.chatModels], + }; + } + + async loadChatModel(key: string): Promise> { + const modelList = await this.getModelList(); + + const exists = modelList.chat.find((m) => m.key === key); + + if (!exists) { + throw new Error( + 'Error Loading Anthropic Chat Model. Invalid Model Selected', + ); + } + + return new AnthropicLLM({ + apiKey: this.config.apiKey, + model: key, + baseURL: 'https://api.anthropic.com/v1' + }); + } + + async loadEmbeddingModel(key: string): Promise> { + throw new Error('Anthropic provider does not support embedding models.'); + } + + static parseAndValidate(raw: any): AnthropicConfig { + if (!raw || typeof raw !== 'object') + throw new Error('Invalid config provided. Expected object'); + if (!raw.apiKey) + throw new Error('Invalid config provided. API key must be provided'); + + return { + apiKey: String(raw.apiKey), + }; + } + + static getProviderConfigFields(): UIConfigField[] { + return providerConfigFields; + } + + static getProviderMetadata(): ProviderMetadata { + return { + key: 'anthropic', + name: 'Anthropic', + }; + } +} + +export default AnthropicProvider; \ No newline at end of file diff --git a/src/lib/models/providers/index.ts b/src/lib/models/providers/index.ts index b3dc550..c53cb71 100644 --- a/src/lib/models/providers/index.ts +++ b/src/lib/models/providers/index.ts @@ -6,6 +6,7 @@ import GeminiProvider from './gemini'; import TransformersProvider from './transformers'; import GroqProvider from './groq'; import LemonadeProvider from './lemonade'; +import AnthropicProvider from './anthropic'; export const providers: Record> = { openai: OpenAIProvider, @@ -13,7 +14,8 @@ export const providers: Record> = { gemini: GeminiProvider, transformers: TransformersProvider, groq: GroqProvider, - lemonade: LemonadeProvider + lemonade: LemonadeProvider, + anthropic: AnthropicProvider }; export const getModelProvidersUIConfigSection = diff --git a/src/lib/models/providers/lemonade/index.ts b/src/lib/models/providers/lemonade/index.ts index 582363a..12f5391 100644 --- a/src/lib/models/providers/lemonade/index.ts +++ b/src/lib/models/providers/lemonade/index.ts @@ -1,6 +1,3 @@ -import { BaseChatModel } from '@langchain/core/language_models/chat_models'; -import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai'; -import { Embeddings } from '@langchain/core/embeddings'; import { UIConfigField } from '@/lib/config/types'; import { getConfiguredModelProviderById } from '@/lib/config/serverRegistry'; import BaseModelProvider from '../../base/provider';