"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AIService = void 0;
const vscode = __importStar(require("vscode"));
class AIService {
    apiKeys = new Map();
    constructor() {
        this.loadApiKeys();
    }
    loadApiKeys() {
        const config = vscode.workspace.getConfiguration('axion-ai');
        const keyMap = {
            'anthropic': 'anthropicApiKey',
            'openai': 'openaiApiKey',
            'google': 'googleApiKey',
            'xai': 'xaiApiKey',
            'deepseek': 'deepseekApiKey',
            'mistral': 'mistralApiKey',
            'groq': 'groqApiKey',
            'huggingface': 'huggingfaceApiKey',
            'together': 'togetherApiKey',
            'perplexity': 'perplexityApiKey'
        };
        for (const [provider, configKey] of Object.entries(keyMap)) {
            const key = config.get(configKey);
            if (key) {
                this.apiKeys.set(provider, key);
            }
        }
    }
    setApiKey(provider, key) {
        this.apiKeys.set(provider, key);
    }
    getApiKey(provider) {
        return this.apiKeys.get(provider);
    }
    hasApiKey(provider) {
        // Free providers still need API keys (free tier available)
        // They work but users need to get free keys from the providers
        return this.apiKeys.has(provider) && this.apiKeys.get(provider) !== '';
    }
    async chat(model, messages, mode, context, onStream) {
        const apiKey = this.apiKeys.get(model.provider);
        if (!apiKey) {
            const freeProviders = ['groq', 'huggingface', 'together', 'perplexity'];
            if (freeProviders.includes(model.provider)) {
                throw new Error(`No API key configured for ${model.provider}. Get a free API key from the provider's website and add it in settings.`);
            }
            throw new Error(`No API key configured for ${model.provider}. Please set your API key in settings.`);
        }
        const systemPrompt = this.getSystemPrompt(mode, context);
        const messagesWithSystem = [
            { role: 'system', content: systemPrompt },
            ...messages
        ];
        switch (model.provider) {
            case 'anthropic':
                return this.callAnthropic(model, messagesWithSystem, apiKey, onStream);
            case 'openai':
                return this.callOpenAI(model, messagesWithSystem, apiKey, onStream);
            case 'google':
                return this.callGoogle(model, messagesWithSystem, apiKey, onStream);
            case 'xai':
                return this.callXAI(model, messagesWithSystem, apiKey, onStream);
            case 'deepseek':
                return this.callDeepSeek(model, messagesWithSystem, apiKey, onStream);
            case 'mistral':
                return this.callMistral(model, messagesWithSystem, apiKey, onStream);
            case 'groq':
                return this.callGroq(model, messagesWithSystem, apiKey, onStream);
            case 'huggingface':
                return this.callHuggingFace(model, messagesWithSystem, apiKey, onStream);
            case 'together':
                return this.callTogether(model, messagesWithSystem, apiKey, onStream);
            case 'perplexity':
                return this.callPerplexity(model, messagesWithSystem, apiKey, onStream);
            default:
                throw new Error(`Unsupported provider: ${model.provider}`);
        }
    }
    getSystemPrompt(mode, context) {
        const basePrompt = `You are Axion AI, an advanced coding assistant with deep understanding of software engineering principles, design patterns, and best practices. You help developers write, understand, and improve their code with intelligence and precision.

Your capabilities include:
- Deep code analysis and understanding
- Intelligent code generation following best practices
- Proactive bug detection and fixing
- Performance optimization
- Security vulnerability detection
- Code refactoring and improvement
- Architecture and design pattern suggestions
- Documentation generation
- Test creation and validation

Always prioritize:
1. Code quality and maintainability
2. Performance and efficiency
3. Security and best practices
4. Readability and documentation
5. Testability and reliability`;
        let modePrompt = '';
        switch (mode) {
            case 'agent':
                modePrompt = `
You are operating in AGENT mode - the most powerful coding mode. In this mode:

CAPABILITIES:
- Full read/write access to the codebase
- Can analyze entire projects and understand architecture
- Can suggest and implement code changes
- Can create, modify, and delete files
- Can refactor code across multiple files
- Can detect and fix bugs proactively
- Can optimize code for performance
- Can suggest architectural improvements

CODE MODIFICATION FORMAT:
When suggesting file changes, use this exact format:

\`\`\`file:path/to/file.ext
// Complete file content or changes
// Use clear comments to explain modifications
\`\`\`

BEST PRACTICES:
- Always explain WHY you're making changes
- Provide clear, concise explanations
- Follow the existing code style and patterns
- Maintain consistency with the codebase
- Consider edge cases and error handling
- Add appropriate comments and documentation
- Ensure backward compatibility when possible
- Test your suggestions mentally before proposing

WORKFLOW:
1. Analyze the request and context thoroughly
2. Understand the existing codebase structure
3. Identify potential issues or improvements
4. Propose clear, actionable changes
5. Explain the benefits and trade-offs
6. Be ready to iterate based on feedback`;
                break;
            case 'ask':
                modePrompt = `
You are operating in ASK mode - a read-only analysis mode. In this mode:

CAPABILITIES:
- Full read access to analyze codebase
- Deep code understanding and explanation
- Answer questions about code functionality
- Provide insights and recommendations
- Explain complex concepts clearly
- Identify patterns and relationships

RESTRICTIONS:
- You CANNOT modify any files
- You CANNOT suggest file changes in executable format
- Focus on explanation and guidance only

BEST PRACTICES:
- Provide clear, detailed explanations
- Use examples and analogies when helpful
- Break down complex concepts into understandable parts
- Reference specific code sections when explaining
- Suggest improvements but explain them conceptually
- Help users learn and understand their codebase deeply`;
                break;
            case 'library':
                modePrompt = `
You are operating in LIBRARY CODER mode - specialized for library development. In this mode:

EXPERTISE:
- Library architecture and design patterns
- API design principles (RESTful, GraphQL, RPC, etc.)
- Package management and distribution
- Versioning strategies (semantic versioning)
- Documentation standards (JSDoc, TypeDoc, Sphinx, etc.)
- Testing strategies for libraries
- Backwards compatibility management

CAPABILITIES:
- Design clean, intuitive APIs
- Create well-structured library code
- Generate comprehensive documentation
- Create usage examples and tutorials
- Design for extensibility and maintainability
- Implement proper error handling
- Create type definitions and interfaces
- Design for multiple programming languages

BEST PRACTICES:
- Follow language-specific library conventions
- Ensure proper encapsulation and abstraction
- Design for testability
- Consider performance implications
- Plan for future extensibility
- Maintain backwards compatibility
- Provide clear migration guides
- Document all public APIs thoroughly`;
                break;
            case 'swarm':
                modePrompt = `
You are operating in SWARM INTELLIGENCE mode. In this mode:
- You are part of a collective AI intelligence analyzing code
- Provide your unique perspective and analysis
- Consider multiple approaches and solutions
- Rate your confidence in your suggestions
- Be aware that other AI models are also analyzing the same code
- Your response will be synthesized with others to create a consensus
- Think critically and provide well-reasoned analysis`;
                break;
            case 'evolution':
                modePrompt = `
You are operating in CODE EVOLUTION mode. In this mode:
- You evolve code through generations like biological evolution
- Each generation should improve upon the previous one
- Apply mutations, natural selection, and genetic algorithms concepts
- Track fitness scores and improvements
- Explain mutations and adaptations made
- Show the evolutionary path of the code
- Optimize for performance, readability, and maintainability`;
                break;
            case 'quantum':
                modePrompt = `
You are operating in QUANTUM CODE OPTIMIZATION mode. In this mode:
- Think in quantum superposition - consider all possible solutions simultaneously
- Find the most optimal solution across multiple dimensions
- Consider parallel execution paths and quantum algorithms
- Optimize for quantum computing principles where applicable
- Provide the most efficient solution possible
- Think outside classical computing constraints`;
                break;
            case 'neural':
                modePrompt = `
You are operating in NEURAL ARCHITECTURE SEARCH mode. In this mode:
- Design optimal code architectures using neural network principles
- Suggest layer-like code structures
- Optimize for information flow and data processing
- Consider activation functions, weights, and biases in code design
- Create self-organizing, adaptive code structures
- Apply deep learning concepts to code architecture`;
                break;
            case 'timetravel':
                modePrompt = `
You are operating in TIME TRAVEL DEBUGGING mode. In this mode:
- Analyze code history and git commits
- Identify when bugs were introduced
- Suggest fixes based on historical context
- Predict future issues based on patterns
- Understand code evolution over time
- Provide temporal analysis of code changes`;
                break;
            case 'predictive':
                modePrompt = `
You are operating in PREDICTIVE CODING mode. In this mode:
- Predict what the developer will code next
- Analyze coding patterns and style
- Suggest next steps based on context
- Provide confidence levels for predictions
- Consider multiple possible futures
- Help developers code faster by anticipating needs`;
                break;
            case 'mindmeld':
                modePrompt = `
You are operating in MIND MELD mode. In this mode:
- Deeply understand the developer's coding style and preferences
- Match their exact patterns, naming conventions, and structure
- Think like the developer would think
- Maintain consistency with their existing codebase
- Adapt to their unique approach
- Become one with their coding philosophy`;
                break;
            case 'parallel':
                modePrompt = `
You are operating in PARALLEL UNIVERSE TESTING mode. In this mode:
- Test code in multiple hypothetical scenarios simultaneously
- Consider edge cases and alternative realities
- Test different execution paths
- Validate code across multiple dimensions
- Find issues that might occur in parallel universes
- Ensure code works in all possible scenarios`;
                break;
            case 'dna':
                modePrompt = `
You are operating in CODE DNA ANALYSIS mode. In this mode:
- Analyze code at the genetic level
- Identify code patterns, mutations, and evolution
- Map code relationships and inheritance
- Detect code anomalies and genetic defects
- Suggest genetic improvements
- Understand code lineage and ancestry`;
                break;
            case 'collaborative':
                modePrompt = `
You are operating in MULTI-AI COLLABORATION mode. In this mode:
- You are working with other AI models on the same task
- Coordinate your response with other AIs
- Build upon suggestions from other models
- Provide complementary perspectives
- Create a unified, comprehensive solution
- Think as part of a team`;
                break;
        }
        const contextPrompt = context ? `\n\nCurrent project context:\n${context}` : '';
        const qualityGuidelines = `
CODE QUALITY GUIDELINES:
- Write clean, readable, and maintainable code
- Follow SOLID principles and design patterns
- Use meaningful variable and function names
- Add appropriate comments and documentation
- Handle errors gracefully
- Consider edge cases and boundary conditions
- Optimize for performance when appropriate
- Ensure code is testable
- Follow language-specific best practices
- Maintain consistency with existing codebase style

RESPONSE FORMAT:
- Always format code blocks with the appropriate language identifier
- Use markdown for better readability
- Structure responses clearly with headers and sections
- Provide explanations before code changes
- Include examples when helpful
- Be concise but thorough
- Use bullet points for lists
- Highlight important information`;
        return `${basePrompt}${modePrompt}${contextPrompt}${qualityGuidelines}`;
    }
    async callAnthropic(model, messages, apiKey, onStream) {
        const systemMessage = messages.find(m => m.role === 'system')?.content || '';
        const chatMessages = messages.filter(m => m.role !== 'system');
        if (onStream) {
            // Streaming response
            const response = await fetch('https://api.anthropic.com/v1/messages', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'x-api-key': apiKey,
                    'anthropic-version': '2023-06-01'
                },
                body: JSON.stringify({
                    model: model.apiModelId,
                    max_tokens: model.maxTokens,
                    system: systemMessage,
                    stream: true,
                    messages: chatMessages.map(m => ({
                        role: m.role,
                        content: m.content
                    }))
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`Anthropic API error: ${error}`);
            }
            const reader = response.body?.getReader();
            const decoder = new TextDecoder();
            let fullContent = '';
            let thinking = '';
            let usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
            if (reader) {
                while (true) {
                    const { done, value } = await reader.read();
                    if (done)
                        break;
                    const chunk = decoder.decode(value);
                    const lines = chunk.split('\n');
                    for (const line of lines) {
                        if (line.startsWith('data: ')) {
                            const data = line.slice(6);
                            if (data === '[DONE]')
                                continue;
                            try {
                                const parsed = JSON.parse(data);
                                if (parsed.type === 'content_block_delta') {
                                    const text = parsed.delta?.text || '';
                                    fullContent += text;
                                    onStream(text, 'content');
                                }
                                else if (parsed.type === 'message_delta' && parsed.usage) {
                                    usage.completionTokens = parsed.usage.output_tokens || 0;
                                }
                                else if (parsed.type === 'message_start' && parsed.message?.usage) {
                                    usage.promptTokens = parsed.message.usage.input_tokens || 0;
                                }
                            }
                            catch { }
                        }
                    }
                }
            }
            usage.totalTokens = usage.promptTokens + usage.completionTokens;
            return { content: fullContent, thinking, usage };
        }
        else {
            const response = await fetch('https://api.anthropic.com/v1/messages', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'x-api-key': apiKey,
                    'anthropic-version': '2023-06-01'
                },
                body: JSON.stringify({
                    model: model.apiModelId,
                    max_tokens: model.maxTokens,
                    system: systemMessage,
                    messages: chatMessages.map(m => ({
                        role: m.role,
                        content: m.content
                    }))
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`Anthropic API error: ${error}`);
            }
            const data = await response.json();
            return {
                content: data.content[0].text,
                usage: {
                    promptTokens: data.usage?.input_tokens || 0,
                    completionTokens: data.usage?.output_tokens || 0,
                    totalTokens: (data.usage?.input_tokens || 0) + (data.usage?.output_tokens || 0)
                }
            };
        }
    }
    async callOpenAI(model, messages, apiKey, onStream) {
        if (onStream) {
            const response = await fetch('https://api.openai.com/v1/chat/completions', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${apiKey}`
                },
                body: JSON.stringify({
                    model: model.apiModelId,
                    max_tokens: model.maxTokens,
                    stream: true,
                    messages: messages.map(m => ({
                        role: m.role,
                        content: m.content
                    }))
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`OpenAI API error: ${error}`);
            }
            const reader = response.body?.getReader();
            const decoder = new TextDecoder();
            let fullContent = '';
            if (reader) {
                while (true) {
                    const { done, value } = await reader.read();
                    if (done)
                        break;
                    const chunk = decoder.decode(value);
                    const lines = chunk.split('\n');
                    for (const line of lines) {
                        if (line.startsWith('data: ')) {
                            const data = line.slice(6);
                            if (data === '[DONE]')
                                continue;
                            try {
                                const parsed = JSON.parse(data);
                                const text = parsed.choices?.[0]?.delta?.content || '';
                                if (text) {
                                    fullContent += text;
                                    onStream(text, 'content');
                                }
                            }
                            catch { }
                        }
                    }
                }
            }
            return { content: fullContent };
        }
        else {
            const response = await fetch('https://api.openai.com/v1/chat/completions', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${apiKey}`
                },
                body: JSON.stringify({
                    model: model.apiModelId,
                    max_tokens: model.maxTokens,
                    messages: messages.map(m => ({
                        role: m.role,
                        content: m.content
                    }))
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`OpenAI API error: ${error}`);
            }
            const data = await response.json();
            return {
                content: data.choices[0].message.content,
                usage: {
                    promptTokens: data.usage?.prompt_tokens || 0,
                    completionTokens: data.usage?.completion_tokens || 0,
                    totalTokens: data.usage?.total_tokens || 0
                }
            };
        }
    }
    async callGoogle(model, messages, apiKey, onStream) {
        const contents = messages
            .filter(m => m.role !== 'system')
            .map(m => ({
            role: m.role === 'assistant' ? 'model' : 'user',
            parts: [{ text: m.content }]
        }));
        const systemInstruction = messages.find(m => m.role === 'system')?.content;
        if (onStream) {
            const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model.apiModelId}:streamGenerateContent?key=${apiKey}&alt=sse`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    contents,
                    systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : undefined,
                    generationConfig: { maxOutputTokens: model.maxTokens }
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`Google API error: ${error}`);
            }
            const reader = response.body?.getReader();
            const decoder = new TextDecoder();
            let fullContent = '';
            if (reader) {
                while (true) {
                    const { done, value } = await reader.read();
                    if (done)
                        break;
                    const chunk = decoder.decode(value);
                    const lines = chunk.split('\n');
                    for (const line of lines) {
                        if (line.startsWith('data: ')) {
                            try {
                                const parsed = JSON.parse(line.slice(6));
                                const text = parsed.candidates?.[0]?.content?.parts?.[0]?.text || '';
                                if (text) {
                                    fullContent += text;
                                    onStream(text, 'content');
                                }
                            }
                            catch { }
                        }
                    }
                }
            }
            return { content: fullContent };
        }
        else {
            const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model.apiModelId}:generateContent?key=${apiKey}`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    contents,
                    systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : undefined,
                    generationConfig: { maxOutputTokens: model.maxTokens }
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`Google API error: ${error}`);
            }
            const data = await response.json();
            const text = data.candidates?.[0]?.content?.parts?.[0]?.text || '';
            return {
                content: text,
                usage: {
                    promptTokens: data.usageMetadata?.promptTokenCount || 0,
                    completionTokens: data.usageMetadata?.candidatesTokenCount || 0,
                    totalTokens: data.usageMetadata?.totalTokenCount || 0
                }
            };
        }
    }
    async callXAI(model, messages, apiKey, onStream) {
        return this.callOpenAICompatible(model, messages, apiKey, 'https://api.x.ai/v1', onStream);
    }
    async callDeepSeek(model, messages, apiKey, onStream) {
        return this.callOpenAICompatible(model, messages, apiKey, 'https://api.deepseek.com/v1', onStream);
    }
    async callMistral(model, messages, apiKey, onStream) {
        return this.callOpenAICompatible(model, messages, apiKey, 'https://api.mistral.ai/v1', onStream);
    }
    async callGroq(model, messages, apiKey, onStream) {
        // Groq uses OpenAI-compatible API (free tier available at console.groq.com)
        if (!apiKey) {
            throw new Error('Groq requires an API key. Get a free key at https://console.groq.com');
        }
        return this.callOpenAICompatible(model, messages, apiKey, 'https://api.groq.com/openai/v1', onStream);
    }
    async callTogether(model, messages, apiKey, onStream) {
        // Together AI uses OpenAI-compatible API (free tier available at together.ai)
        if (!apiKey) {
            throw new Error('Together AI requires an API key. Get a free key at https://together.ai');
        }
        return this.callOpenAICompatible(model, messages, apiKey, 'https://api.together.xyz/v1', onStream);
    }
    async callHuggingFace(model, messages, apiKey, onStream) {
        // Hugging Face Inference API (free token available at huggingface.co/settings/tokens)
        if (!apiKey) {
            throw new Error('Hugging Face requires an API token. Get a free token at https://huggingface.co/settings/tokens');
        }
        const systemMessage = messages.find(m => m.role === 'system')?.content || '';
        const chatMessages = messages.filter(m => m.role !== 'system');
        // Convert to Hugging Face format
        const prompt = chatMessages.map(m => {
            if (m.role === 'user')
                return `<|user|>\n${m.content}<|end|>\n`;
            if (m.role === 'assistant')
                return `<|assistant|>\n${m.content}<|end|>\n`;
            return '';
        }).join('') + '<|assistant|>\n';
        const response = await fetch(`https://api-inference.huggingface.co/models/${model.apiModelId}`, {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${apiKey}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                inputs: systemMessage + prompt,
                parameters: {
                    max_new_tokens: Math.min(model.maxTokens, 1024),
                    temperature: 0.7,
                    return_full_text: false
                }
            })
        });
        if (!response.ok) {
            throw new Error(`Hugging Face API error: ${response.statusText}`);
        }
        const data = await response.json();
        const content = Array.isArray(data) ? data[0]?.generated_text || '' : data.generated_text || '';
        return {
            content: content.trim(),
            usage: {
                promptTokens: 0,
                completionTokens: 0,
                totalTokens: 0
            }
        };
    }
    async callPerplexity(model, messages, apiKey, onStream) {
        // Perplexity API (free tier available at perplexity.ai)
        if (!apiKey) {
            throw new Error('Perplexity requires an API key. Get a free key at https://perplexity.ai');
        }
        const systemMessage = messages.find(m => m.role === 'system')?.content || '';
        const chatMessages = messages.filter(m => m.role !== 'system');
        const response = await fetch('https://api.perplexity.ai/chat/completions', {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${apiKey}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                model: model.apiModelId,
                messages: [
                    { role: 'system', content: systemMessage },
                    ...chatMessages
                ],
                max_tokens: model.maxTokens,
                temperature: 0.7
            })
        });
        if (!response.ok) {
            throw new Error(`Perplexity API error: ${response.statusText}`);
        }
        const data = await response.json();
        const content = data.choices[0]?.message?.content || '';
        return {
            content,
            usage: {
                promptTokens: data.usage?.prompt_tokens || 0,
                completionTokens: data.usage?.completion_tokens || 0,
                totalTokens: data.usage?.total_tokens || 0
            }
        };
    }
    async callOpenAICompatible(model, messages, apiKey, baseUrl, onStream) {
        if (onStream) {
            const response = await fetch(`${baseUrl}/chat/completions`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${apiKey}`
                },
                body: JSON.stringify({
                    model: model.apiModelId,
                    max_tokens: model.maxTokens,
                    stream: true,
                    messages: messages.map(m => ({
                        role: m.role,
                        content: m.content
                    }))
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`API error: ${error}`);
            }
            const reader = response.body?.getReader();
            const decoder = new TextDecoder();
            let fullContent = '';
            if (reader) {
                while (true) {
                    const { done, value } = await reader.read();
                    if (done)
                        break;
                    const chunk = decoder.decode(value);
                    const lines = chunk.split('\n');
                    for (const line of lines) {
                        if (line.startsWith('data: ')) {
                            const data = line.slice(6);
                            if (data === '[DONE]')
                                continue;
                            try {
                                const parsed = JSON.parse(data);
                                const text = parsed.choices?.[0]?.delta?.content || '';
                                if (text) {
                                    fullContent += text;
                                    onStream(text, 'content');
                                }
                            }
                            catch { }
                        }
                    }
                }
            }
            return { content: fullContent };
        }
        else {
            const response = await fetch(`${baseUrl}/chat/completions`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${apiKey}`
                },
                body: JSON.stringify({
                    model: model.apiModelId,
                    max_tokens: model.maxTokens,
                    messages: messages.map(m => ({
                        role: m.role,
                        content: m.content
                    }))
                })
            });
            if (!response.ok) {
                const error = await response.text();
                throw new Error(`API error: ${error}`);
            }
            const data = await response.json();
            return {
                content: data.choices[0].message.content,
                usage: {
                    promptTokens: data.usage?.prompt_tokens || 0,
                    completionTokens: data.usage?.completion_tokens || 0,
                    totalTokens: data.usage?.total_tokens || 0
                }
            };
        }
    }
    parseFileChanges(content) {
        const changes = [];
        const regex = /```file:([^\n]+)\n([\s\S]*?)```/g;
        let match;
        while ((match = regex.exec(content)) !== null) {
            changes.push({
                path: match[1].trim(),
                content: match[2].trim()
            });
        }
        return changes;
    }
}
exports.AIService = AIService;
//# sourceMappingURL=AIService.js.map