UNPKG

@nomyx/assistant

Version:

A powerful assistant library and cli for your AI projects. works with Vertex AI (Claude and Gemini)

120 lines (100 loc) 3.93 kB
import { ChatMessage, ChatOptions, ProviderResponse } from '../../../types/chat'; import { Tool, GenericToolSchema, StandardizedToolCall } from '../../../types/tool'; import { IAIProvider, AIProviderMiddleware, AIProviderPlugin, ProviderCapabilities } from '../../../types/provider'; import { AnthropicProviderConfig } from '../../../types/provider'; import { AnthropicCacheKey } from './types'; import { AnthropicCache } from './cache'; import { chat } from './chat'; import { streamChat } from './streaming'; import { AnthropicConfig } from './config'; import { handleAnthropicError } from './errors'; import { ILogger } from '../../../types/common'; import { convertToolSchema, convertToolCall } from './tools'; export class AnthropicProvider implements IAIProvider { private config: AnthropicConfig; private cache: AnthropicCache; private middleware: AIProviderMiddleware[] = []; constructor(config: AnthropicProviderConfig, logger: ILogger) { this.config = new AnthropicConfig(config, logger); this.cache = new AnthropicCache(); } async chat(messages: ChatMessage[], options: ChatOptions, tools?: Tool[]): Promise<ProviderResponse> { try { const cacheKey: AnthropicCacheKey = { messages, options, tools }; if (this.cache.has(cacheKey)) { return this.cache.get(cacheKey)!; } let processedMessages = messages; for (const mw of this.middleware) { processedMessages = await mw.preProcess(processedMessages); } let response: ProviderResponse = await chat(this.config, processedMessages, options, tools); for (const mw of this.middleware) { response = await mw.postProcess(response); } if (response.toolCalls && response.toolCalls.length > 0) { for (const mw of this.middleware) { if (mw.processToolCalls) { response.toolCalls = await mw.processToolCalls(response.toolCalls); } } } this.cache.set(cacheKey, response); return response; } catch (error) { throw handleAnthropicError(error); } } async *streamChat(messages: ChatMessage[], options: ChatOptions, tools?: Tool[]): AsyncIterableIterator<ProviderResponse> { try { let processedMessages = messages; for (const mw of this.middleware) { processedMessages = await mw.preProcess(processedMessages); } const stream = streamChat(this.config, processedMessages, options, tools); for await (const chunk of stream) { let processedChunk = chunk; for (const mw of this.middleware) { processedChunk = await mw.postProcess(processedChunk); } if (processedChunk.toolCalls && processedChunk.toolCalls.length > 0) { for (const mw of this.middleware) { if (mw.processToolCalls) { processedChunk.toolCalls = await mw.processToolCalls(processedChunk.toolCalls); } } } yield processedChunk; } } catch (error) { throw handleAnthropicError(error); } } getCapabilities(): ProviderCapabilities { return { maxTokens: 100000, // Adjust based on Anthropic's actual limits supportsFunctionCalling: true, supportsStreaming: true, supportedModels: [this.config.model], maxSimultaneousCalls: 1, // Adjust based on Anthropic's rate limits supportsSemanticCaching: false, }; } use(middleware: AIProviderMiddleware): void { this.middleware.push(middleware); } registerPlugin(plugin: AIProviderPlugin): void { plugin.initialize(this); } convertToolSchema(schema: GenericToolSchema): any { return convertToolSchema(schema); } convertToolCall(call: any): StandardizedToolCall { return convertToolCall(call); } clearCache(): void { this.cache.clear(); } } export * from './types'; export { AnthropicProviderError } from './errors';