"use strict";
/**
 * Provider Plugin Adapter for BFUI
 *
 * This module provides adapters for provider plugins to work with BFUI components.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProviderAdapter = exports.ProviderAdapterError = void 0;
exports.getProviderAdapter = getProviderAdapter;
const plugin_system_js_1 = require("./plugin-system.js");
/**
 * Error class for provider adapter errors
 */
class ProviderAdapterError extends Error {
    constructor(message, code, details) {
        super(message);
        this.name = 'ProviderAdapterError';
        this.code = code;
        this.details = details;
    }
}
exports.ProviderAdapterError = ProviderAdapterError;
/**
 * Convert BFUI chat request to native-ai plugin request format
 */
function convertToChatRequest(chatRequest) {
    return {
        provider: chatRequest.provider,
        model: chatRequest.model,
        messages: chatRequest.messages.map(msg => ({
            role: msg.role,
            content: msg.content,
            name: msg.name
        })),
        parameters: {
            temperature: chatRequest.temperature || 0.7,
            max_tokens: chatRequest.maxTokens || 1000,
            stream: chatRequest.stream || false,
            system_prompt: chatRequest.systemPrompt
        },
        tools: chatRequest.functions ? chatRequest.functions.map(fn => ({
            name: fn.name,
            description: fn.description || '',
            parameters: fn.parameters
        })) : undefined
    };
}
/**
 * Convert native-ai plugin response to BFUI response format
 */
function convertToChatResponse(response) {
    return {
        id: response.id || `chat-${Date.now()}`,
        model: response.model,
        created: Date.now(),
        choices: [
            {
                index: 0,
                message: {
                    role: 'assistant',
                    content: response.content
                },
                finish_reason: response.finish_reason || 'stop'
            }
        ],
        usage: response.usage || {
            prompt_tokens: response.prompt_tokens || 0,
            completion_tokens: response.completion_tokens || 0,
            total_tokens: (response.prompt_tokens || 0) + (response.completion_tokens || 0)
        }
    };
}
/**
 * Convert native-ai plugin error to BFUI error format
 */
function convertError(error) {
    if (error instanceof ProviderAdapterError) {
        return {
            code: error.code,
            message: error.message,
            details: error.details
        };
    }
    return {
        code: error.code || 'unknown_error',
        message: error.message || 'An unknown error occurred',
        details: error.details || error
    };
}
/**
 * Provider adapter for BFUI components
 */
class ProviderAdapter {
    /**
     * Create a new provider adapter
     */
    constructor(providerOrId) {
        if (typeof providerOrId === 'string') {
            const provider = plugin_system_js_1.pluginManager.getProviderPlugin(providerOrId);
            if (!provider) {
                throw new ProviderAdapterError(`Provider not found: ${providerOrId}`, 'provider_not_found', { providerId: providerOrId });
            }
            this.provider = provider;
        }
        else {
            this.provider = providerOrId;
        }
    }
    /**
     * Execute a chat completion request
     */
    async chat(chatRequest, options) {
        try {
            if (!this.provider.isInitialized()) {
                throw new ProviderAdapterError('Provider not initialized', 'provider_not_initialized', { providerId: this.provider.id });
            }
            const request = convertToChatRequest(chatRequest);
            // Execute with or without streaming
            if (chatRequest.stream && options?.onStream) {
                // Create a streaming callback
                const streamingHandler = {
                    onChunk: (chunk) => {
                        if (options.onStream) {
                            options.onStream({
                                choices: [{
                                        index: 0,
                                        delta: {
                                            content: chunk.content,
                                            role: 'assistant'
                                        },
                                        finish_reason: chunk.done ? 'stop' : undefined
                                    }]
                            });
                        }
                    },
                    onComplete: () => { },
                    onError: () => { }
                };
                // Execute streaming request
                await this.provider.executeStreaming(request, streamingHandler);
                // Return a dummy response for streaming (final response will come through callback)
                return {
                    id: `stream-${Date.now()}`,
                    model: chatRequest.model || '',
                    created: Date.now(),
                    choices: [{
                            index: 0,
                            message: {
                                role: 'assistant',
                                content: ''
                            },
                            finish_reason: 'stop'
                        }],
                    usage: {
                        prompt_tokens: 0,
                        completion_tokens: 0,
                        total_tokens: 0
                    }
                };
            }
            else {
                // Execute normal request
                const response = await this.provider.execute(request, {
                    abortSignal: options?.abortSignal
                });
                return convertToChatResponse(response);
            }
        }
        catch (error) {
            throw convertError(error);
        }
    }
    /**
     * Generate embeddings for text
     */
    async embeddings(texts, model) {
        try {
            if (!this.provider.isInitialized()) {
                throw new ProviderAdapterError('Provider not initialized', 'provider_not_initialized', { providerId: this.provider.id });
            }
            // Check if provider supports embeddings
            const capabilities = this.provider.getCapabilities();
            if (!capabilities.embeddings) {
                throw new ProviderAdapterError(`Provider does not support embeddings: ${this.provider.id}`, 'embeddings_not_supported', { providerId: this.provider.id });
            }
            // Create embedding request
            const request = {
                texts,
                model: model || 'text-embedding-ada-002'
            };
            // Execute request
            const response = await this.provider.execute(request, {
                endpoint: 'embeddings'
            });
            return response.embeddings || [];
        }
        catch (error) {
            throw convertError(error);
        }
    }
    /**
     * Get provider capabilities
     */
    getCapabilities() {
        return this.provider.getCapabilities();
    }
    /**
     * Get available models from the provider
     */
    getModels() {
        return this.provider.getModels();
    }
    /**
     * Get provider ID
     */
    getId() {
        return this.provider.id;
    }
    /**
     * Get provider name
     */
    getName() {
        return this.provider.name;
    }
}
exports.ProviderAdapter = ProviderAdapter;
/**
 * Factory function to get a provider adapter
 */
function getProviderAdapter(providerId) {
    // Use specified provider or default provider
    const provider = providerId
        ? plugin_system_js_1.pluginManager.getProviderPlugin(providerId)
        : plugin_system_js_1.pluginManager.getDefaultProvider();
    if (!provider) {
        throw new ProviderAdapterError(`Provider not found: ${providerId || 'default'}`, 'provider_not_found', { providerId });
    }
    return new ProviderAdapter(provider);
}
//# sourceMappingURL=provider-adapter.js.map