/**
* Anthropic provider adapter
*/
import Anthropic from '@anthropic-ai/sdk';
import { BaseAIProvider } from './base.js';
import { AIProviderConfig, AIResponse, Message } from '../types.js';
export class AnthropicProvider extends BaseAIProvider {
private client: Anthropic | null = null;
private getClient(apiKey?: string): Anthropic {
if (!this.client) {
this.client = new Anthropic({
apiKey: apiKey || process.env.ANTHROPIC_API_KEY
});
}
return this.client;
}
async call(messages: Message[], config: AIProviderConfig): Promise<AIResponse> {
const client = this.getClient(config.apiKey);
// Anthropic requires system message to be separate
const systemMessage = messages.find(m => m.role === 'system');
const userMessages = messages.filter(m => m.role !== 'system');
const response = await client.messages.create({
model: config.model,
max_tokens: config.maxTokens ?? 2000,
temperature: config.temperature ?? 0.7,
system: systemMessage?.content || config.systemPrompt,
messages: userMessages.map(msg => ({
role: msg.role as 'user' | 'assistant',
content: msg.content
}))
});
const textContent = response.content.find(c => c.type === 'text');
if (!textContent || textContent.type !== 'text') {
throw new Error('No text response from Anthropic');
}
return {
content: textContent.text,
model: response.model,
usage: {
promptTokens: response.usage.input_tokens,
completionTokens: response.usage.output_tokens,
totalTokens: response.usage.input_tokens + response.usage.output_tokens
},
metadata: {
stopReason: response.stop_reason,
id: response.id
}
};
}
}