import Anthropic from '@anthropic-ai/sdk';
import { memoryDB } from '../db/memory-db.js';
import { decryptString } from '../crypto/envelope.js';
import { anthropicCircuitBreaker, executeWithCircuitBreaker } from '../utils/circuit-breaker.js';
export class AnthropicProvider {
    name = 'Anthropic';
    type = 'anthropic';
    client;
    apiKey;
    async isConfigured() {
        try {
            const credential = await memoryDB.findActiveToolCredential('anthropic');
            if (!credential) {
                return false;
            }
            const kekBase64 = process.env['KEK_BASE64'];
            if (!kekBase64) {
                console.warn('[Anthropic] KEK_BASE64 not configured');
                return false;
            }
            const kek = Buffer.from(kekBase64, 'base64');
            this.apiKey = decryptString(credential.encryptedCredential, kek);
            this.client = new Anthropic({
                apiKey: this.apiKey
            });
            return true;
        }
        catch (error) {
            console.error('[Anthropic] Configuration error:', error);
            return false;
        }
    }
    async getAvailableModels() {
        return [
            'claude-3-5-sonnet-20241022',
            'claude-3-opus-20240229',
            'claude-3-sonnet-20240229',
            'claude-3-haiku-20240307',
            'claude-2.1',
            'claude-2.0',
            'claude-instant-1.2'
        ];
    }
    async complete(params) {
        if (!await this.isConfigured()) {
            throw new Error('Anthropic not configured - no active credential found');
        }
        if (!this.client) {
            throw new Error('Anthropic client not initialized');
        }
        try {
            const systemMessage = params.messages.find(m => m.role === 'system');
            const messages = params.messages.filter(m => m.role !== 'system');
            const response = await executeWithCircuitBreaker(anthropicCircuitBreaker, async () => this.client.messages.create({
                model: params.model,
                ...(systemMessage && { system: systemMessage.content }),
                messages: messages.map(m => ({
                    role: m.role,
                    content: m.content
                })),
                temperature: params.temperature ?? 0.7,
                max_tokens: params.maxTokens ?? 1000,
                ...(params.topP !== undefined && { top_p: params.topP }),
                ...(params.stopSequences && { stop_sequences: params.stopSequences })
            }));
            const content = response.content?.[0];
            if (!content) {
                throw new Error('No content returned from Anthropic');
            }
            return {
                content: content.type === 'text' ? content.text : '',
                model: response.model,
                usage: {
                    promptTokens: response.usage.input_tokens,
                    completionTokens: response.usage.output_tokens,
                    totalTokens: response.usage.input_tokens + response.usage.output_tokens
                },
                finishReason: this.mapStopReason(response.stop_reason),
                raw: response
            };
        }
        catch (error) {
            if (error.status === 401) {
                throw new Error('Anthropic authentication failed - check API key');
            }
            if (error.status === 429) {
                throw new Error('Anthropic rate limit exceeded');
            }
            if (error.status === 400) {
                throw new Error(`Anthropic request error: ${error.message}`);
            }
            throw new Error(`Anthropic request failed: ${error.message}`);
        }
    }
    async estimateCost(params) {
        const estimatedPromptTokens = JSON.stringify(params.messages).length / 4;
        const estimatedCompletionTokens = params.maxTokens || 1000;
        const pricing = {
            'claude-3-5-sonnet-20241022': { input: 3.0, output: 15.0 },
            'claude-3-opus-20240229': { input: 15.0, output: 75.0 },
            'claude-3-sonnet-20240229': { input: 3.0, output: 15.0 },
            'claude-3-haiku-20240307': { input: 0.25, output: 1.25 },
            'claude-2.1': { input: 8.0, output: 24.0 },
            'claude-2.0': { input: 8.0, output: 24.0 },
            'claude-instant-1.2': { input: 0.8, output: 2.4 }
        };
        const modelPricing = pricing[params.model] || pricing['claude-3-haiku-20240307'];
        const inputCost = (estimatedPromptTokens / 1_000_000) * modelPricing.input;
        const outputCost = (estimatedCompletionTokens / 1_000_000) * modelPricing.output;
        return inputCost + outputCost;
    }
    async testConnection() {
        try {
            const response = await this.complete({
                model: 'claude-3-haiku-20240307',
                messages: [{ role: 'user', content: 'Hello' }],
                maxTokens: 5
            });
            return response.content.length > 0;
        }
        catch (error) {
            console.error('[Anthropic] Connection test failed:', error);
            return false;
        }
    }
    mapStopReason(reason) {
        switch (reason) {
            case 'end_turn':
                return 'stop';
            case 'max_tokens':
                return 'length';
            case 'tool_use':
                return 'tool_use';
            default:
                return 'error';
        }
    }
}
//# sourceMappingURL=anthropic-provider.js.map