import OpenAI from 'openai';
import { memoryDB } from '../db/memory-db.js';
import { decryptString } from '../crypto/envelope.js';
import { openAICircuitBreaker, executeWithCircuitBreaker } from '../utils/circuit-breaker.js';
export class OpenAIProvider {
    name = 'OpenAI';
    type = 'openai';
    client;
    apiKey;
    async isConfigured() {
        try {
            const credential = await memoryDB.findActiveToolCredential('openai');
            if (!credential) {
                return false;
            }
            const kekBase64 = process.env['KEK_BASE64'];
            if (!kekBase64) {
                console.warn('[OpenAI] KEK_BASE64 not configured');
                return false;
            }
            const kek = Buffer.from(kekBase64, 'base64');
            this.apiKey = decryptString(credential.encryptedCredential, kek);
            this.client = new OpenAI({
                apiKey: this.apiKey
            });
            return true;
        }
        catch (error) {
            console.error('[OpenAI] Configuration error:', error);
            return false;
        }
    }
    async getAvailableModels() {
        if (!await this.isConfigured()) {
            throw new Error('OpenAI not configured');
        }
        return [
            'gpt-4-turbo-preview',
            'gpt-4',
            'gpt-4-32k',
            'gpt-3.5-turbo',
            'gpt-3.5-turbo-16k'
        ];
    }
    async complete(params) {
        if (!await this.isConfigured()) {
            throw new Error('OpenAI not configured - no active credential found');
        }
        if (!this.client) {
            throw new Error('OpenAI client not initialized');
        }
        try {
            const response = await executeWithCircuitBreaker(openAICircuitBreaker, async () => this.client.chat.completions.create({
                model: params.model,
                messages: params.messages,
                temperature: params.temperature ?? 0.7,
                max_tokens: params.maxTokens ?? 1000,
                ...(params.topP !== undefined && { top_p: params.topP }),
                ...(params.frequencyPenalty !== undefined && { frequency_penalty: params.frequencyPenalty }),
                ...(params.presencePenalty !== undefined && { presence_penalty: params.presencePenalty }),
                ...(params.stopSequences && { stop: params.stopSequences })
            }));
            const choice = response.choices[0];
            if (!choice) {
                throw new Error('No response choices returned from OpenAI');
            }
            return {
                content: choice.message.content || '',
                model: response.model,
                usage: {
                    promptTokens: response.usage?.prompt_tokens || 0,
                    completionTokens: response.usage?.completion_tokens || 0,
                    totalTokens: response.usage?.total_tokens || 0
                },
                finishReason: this.mapFinishReason(choice.finish_reason),
                raw: response
            };
        }
        catch (error) {
            if (error.status === 401) {
                throw new Error('OpenAI authentication failed - check API key');
            }
            if (error.status === 429) {
                throw new Error('OpenAI rate limit exceeded');
            }
            if (error.status === 400) {
                throw new Error(`OpenAI request error: ${error.message}`);
            }
            throw new Error(`OpenAI request failed: ${error.message}`);
        }
    }
    async estimateCost(params) {
        const estimatedPromptTokens = JSON.stringify(params.messages).length / 4;
        const estimatedCompletionTokens = params.maxTokens || 1000;
        const totalTokens = estimatedPromptTokens + estimatedCompletionTokens;
        const pricing = {
            'gpt-4-turbo-preview': { input: 0.01, output: 0.03 },
            'gpt-4': { input: 0.03, output: 0.06 },
            'gpt-4-32k': { input: 0.06, output: 0.12 },
            'gpt-3.5-turbo': { input: 0.0005, output: 0.0015 },
            'gpt-3.5-turbo-16k': { input: 0.001, output: 0.002 }
        };
        const modelPricing = pricing[params.model] || pricing['gpt-3.5-turbo'];
        const inputCost = (estimatedPromptTokens / 1000) * modelPricing.input;
        const outputCost = (estimatedCompletionTokens / 1000) * modelPricing.output;
        return inputCost + outputCost;
    }
    async testConnection() {
        try {
            const response = await this.complete({
                model: 'gpt-3.5-turbo',
                messages: [{ role: 'user', content: 'Hello' }],
                maxTokens: 5
            });
            return response.content.length > 0;
        }
        catch (error) {
            console.error('[OpenAI] Connection test failed:', error);
            return false;
        }
    }
    mapFinishReason(reason) {
        switch (reason) {
            case 'stop':
                return 'stop';
            case 'length':
                return 'length';
            case 'tool_calls':
            case 'function_call':
                return 'tool_use';
            default:
                return 'error';
        }
    }
}
//# sourceMappingURL=openai-provider.js.map