fix the code output only code i get qan error 500 on send:
# main.py
import os
import subprocess
import sys
import logging
from flask import Flask, request, jsonify, render_template_string
from llm import client, get_embedding, get_available_models

# ============================
# Configuration
# ============================

app = Flask(__name__)
app.config['CHAT_MODEL'] = "gpt-4o-mini"  # Use the specified model
app.config['DEBUG'] = False  # Set to False in production
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'your-default-secret-key')  # For Flask sessions

# ============================
# Setup Logging for Flask
# ============================

logging.basicConfig(level=logging.DEBUG if app.config['DEBUG'] else logging.INFO,
                    format='%(asctime)s %(levelname)s: %(message)s',
                    handlers=[
                        logging.StreamHandler(sys.stdout),
                        logging.FileHandler("app.log")
                    ])
logger = logging.getLogger(__name__)

# ============================
# Helper Functions
# ============================

def run_python_code(code):
    """Executes Python code safely and returns stdout and stderr."""
    logger.debug(f"Running Python code: {code}")
    try:
        process = subprocess.Popen(
            [sys.executable, '-c', code],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        stdout, stderr = process.communicate(timeout=10)  # Timeout after 10 seconds
        logger.debug(f"Code execution stdout: {stdout}")
        logger.debug(f"Code execution stderr: {stderr}")
        return stdout, stderr
    except subprocess.TimeoutExpired:
        logger.error("Code execution timed out.")
        process.kill()
        return "", "Error: Code execution timed out."
    except Exception as e:
        logger.exception("Error during code execution.")
        return "", f"Error: {str(e)}"

def extract_code_blocks(text):
    """Extracts code blocks enclosed in triple backticks from the given text."""
    logger.debug(f"Extracting code blocks from text: {text}")
    codes = []
    parts = text.split('```')
    for i in range(1, len(parts), 2):
        codes.append(parts[i].strip())
    logger.debug(f"Extracted code blocks: {codes}")
    return codes

def escape_html(text):
    """Escapes HTML special characters in text."""
    import html
    return html.escape(text)

# ============================
# HTML with Inline CSS and JS
# ============================

INDEX_HTML = """
<!DOCTYPE html>
<html>
<head>
    <title>LLM Code Runner</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            display: flex;
            flex-direction: row;
            height: 100vh;
            margin: 0;
            padding: 0;
            background: linear-gradient(135deg, #1e1e2f, #27293d);
            color: #ffffff;
        }
        .panel {
            padding: 20px;
            box-sizing: border-box;
            overflow-y: auto;
        }
        #left-panel {
            width: 25%;
            border-right: 1px solid #444;
            background-color: #2e2e42;
        }
        #main-panel {
            width: 50%;
            border-right: 1px solid #444;
            display: flex;
            flex-direction: column;
            background-color: #1e1e2f;
        }
        #chat-panel {
            width: 25%;
            display: flex;
            flex-direction: column;
            padding: 20px;
            box-sizing: border-box;
            background-color: #2e2e42;
            border-left: 1px solid #444;
        }
        h2, h3 {
            margin-top: 0;
            color: #f0f0f0;
        }
        .button-group button {
            width: 30px;
            height: 30px;
            margin-left: 5px;
            border: none;
            background-color: #007BFF;
            color: #fff;
            border-radius: 3px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
        }
        .button-group button:hover {
            background-color: #0056b3;
        }
        #tabs {
            flex-grow: 1;
            overflow-y: auto;
            padding: 10px;
            border: 1px solid #444;
            border-radius: 5px;
            background-color: #2e2e42;
            margin-bottom: 20px;
        }
        .tab {
            border: 1px solid #555;
            padding: 10px;
            margin-bottom: 10px;
            border-radius: 5px;
            background-color: #3a3a58;
            position: relative;
        }
        .tab h3 {
            margin-bottom: 10px;
            font-size: 16px;
            color: #f0f0f0;
        }
        .tab pre {
            background-color: #44445a;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
            color: #e0e0e0;
            white-space: pre-wrap;
            word-wrap: break-word;
        }
        #terminal-output {
            height: 200px;
            overflow-y: scroll;
            background-color: #000;
            color: #0f0;
            padding: 10px;
            border-radius: 5px;
            margin-top: 10px;
            white-space: pre-wrap;
            font-family: 'Courier New', Courier, monospace;
        }
        #log-panel {
            height: 200px;
            overflow-y: scroll;
            background-color: #3a3a58;
            padding: 10px;
            border-radius: 5px;
            border: 1px solid #555;
            margin-top: 10px;
            white-space: pre-wrap;
            color: #e0e0e0;
        }
        .input-container {
            position: fixed;
            bottom: 20px;
            left: 25%;
            width: 50%;
            display: flex;
            align-items: center;
        }
        @media (max-width: 1200px) {
            .input-container {
                left: 0;
                width: 100%;
            }
        }
        .input-container input {
            width: 100%;
            padding: 10px 40px 10px 10px; /* Make space for send icon */
            border: 1px solid #555;
            border-radius: 5px;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            font-size: 14px;
            background-color: #2e2e42;
            color: #f0f0f0;
        }
        .input-container img {
            position: absolute;
            right: 10px;
            width: 24px;
            height: 24px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <!-- Left Panel -->
    <div id="left-panel" class="panel">
        <h2>Settings</h2>
        <label for="model-select">Model:</label>
        <select id="model-select" class="select">
            {% for model in model_options %}
                <option value="{{ model }}">{{ model }}</option>
            {% endfor %}
        </select>
        <br><br>
        <label for="max-tokens">Max Tokens:</label>
        <div class="token-container">
            <input type="number" id="max-tokens" value="1000" min="0" class="input">
            <div class="button-group">
                <button id="decrease-tokens">-</button>
                <button id="increase-tokens">+</button>
            </div>
        </div>
        <br>
        <h3>Log Panel</h3>
        <div id="log-panel" class="log-panel"></div>
    </div>

    <!-- Main Panel -->
    <div id="main-panel" class="panel">
        <div class="header">
            <h2>Code and Files</h2>
            <button id="run-code" class="run-button">▶ Run Code</button>
        </div>
        <div id="tabs" class="tabs"></div>
        <h3>Terminal Output</h3>
        <div id="terminal-output" class="terminal-output"></div>
    </div>

    <!-- Chat Panel -->
    <div id="chat-panel" class="panel">
        <h2>Chat Interface</h2>
        <div id="chat-output" class="chat-output"></div>
        <div class="input-container">
            <input type="text" id="chat-input" placeholder="Type your message here..." class="input">
            <img src="https://img.icons8.com/ios-glyphs/30/ffffff/filled-sent.png" alt="Send" id="send-icon" title="Send">
        </div>
        <input type="file" id="file-input" accept=".txt,.py,.md" class="file-input">
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const logPanel = document.getElementById('log-panel');
            const modelSelect = document.getElementById('model-select');
            const maxTokensInput = document.getElementById('max-tokens');
            const increaseButton = document.getElementById('increase-tokens');
            const decreaseButton = document.getElementById('decrease-tokens');
            const chatInput = document.getElementById('chat-input');
            const chatOutput = document.getElementById('chat-output');
            const fileInput = document.getElementById('file-input');
            const tabsDiv = document.getElementById('tabs');
            const runCodeButton = document.getElementById('run-code');
            const terminalOutput = document.getElementById('terminal-output');
            const sendIcon = document.getElementById('send-icon');

            // Increase Max Tokens
            increaseButton.addEventListener('click', function() {
                let value = parseInt(maxTokensInput.value);
                if (!isNaN(value)) {
                    maxTokensInput.value = value + 100;
                    log(`Max tokens increased to ${maxTokensInput.value}`, 'success');
                } else {
                    log('Max Tokens must be an integer.', 'error');
                }
            });

            // Decrease Max Tokens
            decreaseButton.addEventListener('click', function() {
                let value = parseInt(maxTokensInput.value);
                if (!isNaN(value)) {
                    let newValue = value - 100;
                    if (newValue < 0) newValue = 0;
                    maxTokensInput.value = newValue;
                    log(`Max tokens decreased to ${maxTokensInput.value}`, 'success');
                } else {
                    log('Max Tokens must be an integer.', 'error');
                }
            });

            // Send Message via Send Icon Click
            sendIcon.addEventListener('click', function() {
                sendMessage();
            });

            // Send Message via Enter Key
            chatInput.addEventListener('keypress', function(event) {
                if (event.key === 'Enter') {
                    event.preventDefault();
                    sendMessage();
                }
            });

            // Send Message Function with Debugging Logs
            function sendMessage() {
                let message = chatInput.value.trim();
                if (message === '') return;

                appendChat('User', message);
                chatInput.value = '';

                fetch('/send_message', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        model: modelSelect.value,
                        max_tokens: parseInt(maxTokensInput.value),
                        messages: getAllSystemMessages(),
                        user_message: message
                    })
                })
                .then(response => {
                    logger.debug(`Response status: ${response.status}`);
                    if (!response.ok) {
                        return response.json().then(errorData => {
                            logger.error(`Error data: ${JSON.stringify(errorData)}`);
                            throw new Error(errorData.error || 'Unknown error occurred.');
                        });
                    }
                    return response.json();
                })
                .then(data => {
                    logger.debug(`Response data: ${JSON.stringify(data)}`);
                    if (data.reply) {
                        appendChat('Assistant', data.reply);
                        // Extract code blocks and add as tabs without using regex
                        let codeBlocks = extractCodeBlocks(data.reply);
                        codeBlocks.forEach((code, index) => {
                            addTab(`Assistant Code ${index+1}`, code);
                            log(`Added code from assistant: Assistant Code ${index+1}`, 'success');
                        });
                    } else if (data.error) {
                        log(data.error, 'error');
                    }
                })
                .catch(error => {
                    logger.error(`Send message failed: ${error.toString()}`);
                    log(`Error: ${error.toString()}`, 'error');
                });
            }

            // File Upload
            fileInput.addEventListener('change', function() {
                let file = fileInput.files[0];
                if (!file) return;

                let reader = new FileReader();
                reader.onload = function(e) {
                    let content = e.target.result;
                    addTab(file.name, content);
                    log(`Loaded file: ${file.name}`, 'success');
                    // Optionally, you can send this for embedding
                };
                reader.onerror = function(e) {
                    log('Error loading file.', 'error');
                };
                reader.readAsText(file);
                fileInput.value = '';
            });

            // Run Code
            runCodeButton.addEventListener('click', function() {
                let activeTab = getActiveTab();
                if (!activeTab) {
                    terminalOutput.innerHTML += `<p class="error">No code to run.</p>`;
                    log('No code to run.', 'error');
                    return;
                }

                let code = activeTab.content;
                fetch('/run_code', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ code: code })
                })
                .then(response => response.json())
                .then(data => {
                    logger.debug(`Run code response data: ${JSON.stringify(data)}`);
                    if (data.error) {
                        terminalOutput.innerHTML += `<pre class="error">${escapeHtml(data.error)}</pre>`;
                        log(`Error: ${data.error}`, 'error');
                    } else {
                        if (data.stdout) {
                            terminalOutput.innerHTML += `<pre>${escapeHtml(data.stdout)}</pre>`;
                            log('Code executed successfully.', 'success');
                        }
                        if (data.stderr) {
                            terminalOutput.innerHTML += `<pre class="error">${escapeHtml(data.stderr)}</pre>`;
                            log(`Error: ${data.stderr}`, 'error');
                        }
                    }
                })
                .catch(error => {
                    terminalOutput.innerHTML += `<pre class="error">${escapeHtml(error.toString())}</pre>`;
                    logger.error(`Run code failed: ${error.toString()}`);
                    log(`Error: ${error.toString()}`, 'error');
                });
            });

            // Helper Functions
            function log(message, type) {
                let p = document.createElement('p');
                if (type === 'error') {
                    p.classList.add('error');
                } else if (type === 'success') {
                    p.classList.add('success');
                }
                p.textContent = message;
                logPanel.appendChild(p);
                logPanel.scrollTop = logPanel.scrollHeight;
                console.log(`[${type.toUpperCase()}] ${message}`);
            }

            function appendChat(role, message) {
                let div = document.createElement('div');
                div.innerHTML = `<strong>${role}:</strong> ${escapeHtml(message)}`;
                chatOutput.appendChild(div);
                chatOutput.scrollTop = chatOutput.scrollHeight;
                console.log(`[${role.toUpperCase()}] ${message}`);
            }

            function addTab(title, content) {
                let tabDiv = document.createElement('div');
                tabDiv.classList.add('tab');
                tabDiv.innerHTML = `<h3>${escapeHtml(title)}</h3><pre>${escapeHtml(content)}</pre>`;
                tabDiv.content = content;
                tabsDiv.appendChild(tabDiv);
                logger.info(`Added tab: ${title}`);
            }

            function getActiveTab() {
                let tabs = document.querySelectorAll('.tab');
                if (tabs.length === 0) return null;
                return tabs[tabs.length - 1]; // Return the latest tab as active
            }

            function getAllSystemMessages() {
                // Retrieve system messages for context
                return [{"role": "system", "content": "You are a helpful assistant."}];
            }

            function extractCodeBlocks(text) {
                let codes = [];
                let parts = text.split('```');
                for (let i = 1; i < parts.length; i += 2) {
                    codes.push(parts[i].trim());
                }
                return codes;
            }

            function escapeHtml(text) {
                const map = {
                    '&': '&amp;',
                    '<': '&lt;',
                    '>': '&gt;',
                    '"': '&quot;',
                    "'": '&#039;'
                };
                return text.replace(/[&<>"']/g, function(m) { return map[m]; });
            }
        </script>
    </body>
    </html>
    """

# ============================
# Routes
# ============================

@app.route('/')
def index():
    model_options = get_available_models()
    return render_template_string(INDEX_HTML, model_options=model_options)

@app.route('/send_message', methods=['POST'])
def send_message_route():
    if not request.is_json:
        logger.warning("Request content type is not application/json.")
        return jsonify({'error': 'Request must be in JSON format.'}), 400

    try:
        data = request.get_json()
        logger.debug(f"Received data: {data}")
    except Exception as e:
        logger.error(f"JSON parsing error: {e}")
        return jsonify({'error': 'Invalid JSON.'}), 400

    model = data.get('model', app.config['CHAT_MODEL'])
    max_tokens = data.get('max_tokens', 1000)
    user_message = data.get('user_message', '')
    system_messages = data.get('messages', [{"role": "system", "content": "You are a helpful assistant."}])

    if not user_message:
        logger.warning("Received empty user message.")
        return jsonify({'error': 'User message is empty.'}), 400

    messages = system_messages + [{"role": "user", "content": user_message}]

    try:
        logger.debug("Sending request to OpenAI ChatCompletion API.")
        response = client.chat_completions.create(
            model=model,
            messages=messages,
            max_tokens=max_tokens
        )
        logger.debug(f"Received response from OpenAI: {response}")
        assistant_reply = response['choices'][0]['message']['content'].strip()
        logger.info("Successfully obtained assistant reply.")
        return jsonify({'reply': assistant_reply})
    except openai.error.InvalidRequestError as e:
        logger.error(f"InvalidRequestError: {e}")
        return jsonify({'error': str(e)}), 400
    except openai.error.AuthenticationError as e:
        logger.error(f"AuthenticationError: {e}")
        return jsonify({'error': 'Invalid OpenAI API key.'}), 401
    except openai.error.OpenAIError as e:
        logger.error(f"OpenAIError: {e}")
        return jsonify({'error': 'An error occurred with the OpenAI API.'}), 500
    except Exception as e:
        logger.exception("Unexpected error during /send_message.")
        return jsonify({'error': 'An unexpected error occurred.'}), 500

@app.route('/run_code', methods=['POST'])
def run_code_route():
    data = request.get_json()
    code = data.get('code', '')

    if not code:
        logger.warning("No code provided for execution.")
        return jsonify({'error': 'No code provided.'}), 400

    stdout, stderr = run_python_code(code)
    logger.info("Code execution completed.")

    return jsonify({'stdout': stdout, 'stderr': stderr})

@app.route('/embed', methods=['POST'])
def embed_route():
    data = request.get_json()
    texts = data.get('texts', [])

    if not texts:
        logger.warning("No texts provided for embedding.")
        return jsonify({'error': 'No texts provided for embedding.'}), 400

    embeddings = []
    for text in texts:
        embedding = get_embedding(text, model='text-embedding-3-small')
        if embedding is None:
            logger.error(f"Failed to generate embedding for text: {text}")
            return jsonify({'error': f"Failed to generate embedding for text: {text}"}), 500
        embeddings.append(embedding)

    try:
        df = pd.DataFrame({
            'text': texts,
            'ada_embedding': embeddings
        })
        df.to_csv(app.config['EMBEDDING_OUTPUT_FILE'], index=False)
        logger.info(f"Embeddings saved to {app.config['EMBEDDING_OUTPUT_FILE']}.")
        return jsonify({
            'embeddings': embeddings,
            'message': f'Embeddings saved to {app.config["EMBEDDING_OUTPUT_FILE"]}.'
        })
    except Exception as e:
        logger.exception("Error saving embeddings to CSV.")
        return jsonify({'error': str(e)}), 500

# ============================
# Error Handlers
# ============================

@app.errorhandler(404)
def not_found_error(error):
    logger.warning(f"404 Error: {error}")
    return jsonify({'error': 'Not found.'}), 404

@app.errorhandler(500)
def internal_error(error):
    logger.error(f"500 Error: {error}")
    return jsonify({'error': 'Internal server error.'}), 500

# ============================
# Run the App
# ============================

if __name__ == '__main__':
    # It's recommended to set DEBUG=False in production
    app.run(host='0.0.0.0', port=5010, debug=app.config['DEBUG'])