can you fix the code so it will render html properly? i get all the time an error (dont send or retry sending to the llm a second time, fin dthe error in the first time and make it work, cancel resend automatically if json not ok, show me the json)
from flask import Flask, request, jsonify, render_template_string
import json
import re
import os
import requests
from openai import OpenAI
from LLM import request_llm_response

# Initialize OpenAI Client
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY', 'your_openai_api_key').strip()
OPENAI_MODEL = "gpt-4o-mini"

if not OPENAI_API_KEY:
    raise EnvironmentError("OpenAI API Key is not set.")

client = OpenAI(api_key=OPENAI_API_KEY)

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# HTML template
index_html = '''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic App Generator</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: #f5f5f5;
        }
        #input-container {
            display: flex;
            align-items: center;
            position: relative;
            width: 100%;
            max-width: 800px;
            margin-bottom: 10px;
        }
        #user-input {
            flex-grow: 1;
            padding: 12px 20px;
            font-size: 18px;
            border: 1px solid #d9d9d9;
            border-radius: 24px;
            outline: none;
            width: 100%;
            resize: none;
            box-sizing: border-box;
        }
        .control-button {
            background: transparent;
            color: #3498db;
            border: none;
            cursor: pointer;
            font-size: 24px;
            padding: 8px;
            margin-left: 8px;
        }
        #send-button, #upload-button {
            position: absolute;
            right: 10px;
        }
        #upload-button {
            right: 50px;
        }
        #file-input {
            display: none;
        }
        #app-container {
            width: 100%;
            max-width: 800px;
            max-height: 600px;
            margin-bottom: 20px;
            overflow: auto;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
            background-color: #f9f9f9;
            padding: 20px;
            box-sizing: border-box;
        }
        #code-display, #llm-response-display, #sent-prompt-display {
            width: 100%;
            max-width: 800px;
            padding: 20px;
            border-radius: 8px;
            overflow: auto;
            font-family: monospace;
            display: none;
        }
        .spinner {
            display: none;
            width: 50px;
            height: 50px;
            border: 8px solid #f3f3f3;
            border-top: 8px solid #3498db;
            border-radius: 50%;
            animation: spin 2s linear infinite;
            margin: auto;
        }
        @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
        #status-label {
            margin-top: 10px;
            font-weight: bold;
            color: #3498db;
        }
    </style>
</head>
<body>
    <div id="buttons-container">
        <button class="control-button" id="refresh-button" title="Refresh and Improve">🔄</button>
        <button class="control-button" id="clear-button" title="Clear GUI">🗑️</button>
        <button class="control-button" id="ai-vision-button" title="AI Vision">👁️</button>
    </div>
    <div id="input-container">
        <textarea id="user-input" placeholder="Enter your app request..." rows="2"></textarea>
        <button class="control-button" id="upload-button" title="Attach JSON">📎</button>
        <button class="control-button" id="send-button">➡️</button>
        <input type="file" id="file-input" accept=".json" />
    </div>
    <div id="sent-prompt-display"></div>
    <div id="status-label"></div>
    <div id="loading-indicator" class="spinner"></div>
    <div id="app-container"></div>
    <div id="code-display">
        <pre id="code-content"></pre>
    </div>
    <div id="llm-response-display">
        <pre id="llm-response-content"></pre>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const userInput = document.getElementById('user-input');
            const sendButton = document.getElementById('send-button');
            const uploadButton = document.getElementById('upload-button');
            const fileInput = document.getElementById('file-input');
            const refreshButton = document.getElementById('refresh-button');
            const clearButton = document.getElementById('clear-button');
            const appContainer = document.getElementById('app-container');
            const loadingIndicator = document.getElementById('loading-indicator');
            const llmResponseDisplay = document.getElementById('llm-response-display');
            const llmResponseContent = document.getElementById('llm-response-content');
            const statusLabel = document.getElementById('status-label');
            const sentPromptDisplay = document.getElementById('sent-prompt-display');
            let currentCode = null;

            function showLoading() {
                loadingIndicator.style.display = 'block';
            }

            function hideLoading() {
                loadingIndicator.style.display = 'none';
            }

            function displaySentPrompt(prompt) {
                sentPromptDisplay.textContent = 'Sent Prompt: ' + prompt;
                sentPromptDisplay.style.display = 'block';
            }

            function sendUserRequest() {
                const userRequest = userInput.value.trim();
                if (userRequest === '') {
                    alert('Please enter a request.');
                    return;
                }
                const promptToSend = JSON.stringify({ user_request: userRequest, current_code: currentCode }, null, 2);
                displaySentPrompt(promptToSend);
                showLoading();
                fetch('/generate_app', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: promptToSend
                })
                .then(response => response.json())
                .then(data => {
                    hideLoading();
                    llmResponseContent.textContent = data.llm_response || 'No LLM response';
                    llmResponseDisplay.style.display = 'block';
                    if (data.success) {
                        currentCode = data.gui_definition;
                        renderApp(currentCode);
                        statusLabel.textContent = '';
                    } else {
                        statusLabel.textContent = 'Error: ' + data.error;
                    }
                })
                .catch(error => {
                    hideLoading();
                    statusLabel.textContent = 'Error: ' + error;
                });
            }

            function renderApp(guiDefinition) {
                appContainer.innerHTML = '';
                try {
                    // Adjust the parsing logic based on your LLM structure
                    if (guiDefinition.gui_component) {
                        // Ensure to access the HTML content correctly
                        const html = guiDefinition.gui_component.html || "<p>Generated Content Placeholder</p>";
                        appContainer.innerHTML = html; // Set the HTML directly
                    } else {
                        appContainer.innerHTML = '<p>No valid GUI content available.</p>';
                        console.warn("Invalid structure in GUI definition:", guiDefinition);
                    }
                } catch (error) {
                    appContainer.innerHTML = '<p>Failed to parse GUI definition. Check console for errors.</p>';
                    console.error('Error in renderApp:', error);
                }
            }

            sendButton.addEventListener('click', sendUserRequest);

            userInput.addEventListener('keypress', function (e) {
                if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    sendUserRequest();
                }
            });

            uploadButton.addEventListener('click', function () {
                fileInput.click();
            });

            fileInput.addEventListener('change', function () {
                const file = fileInput.files[0];
                if (!file) {
                    return;
                }
                const reader = new FileReader();
                reader.onload = function (e) {
                    try {
                        const data = JSON.parse(e.target.result);
                        currentCode = data;
                        renderApp(currentCode);
                        statusLabel.textContent = '';
                    } catch (err) {
                        statusLabel.textContent = 'Invalid JSON file.';
                    }
                };
                reader.readAsText(file);
            });

            refreshButton.addEventListener('click', function () {
                if (!currentCode) {
                    alert('No code to refresh. Please generate an app first.');
                    return;
                }
                showLoading();
                fetch('/improve_app', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ current_code: currentCode })
                })
                .then(response => response.json())
                .then(data => {
                    hideLoading();
                    llmResponseContent.textContent = data.llm_response || '';
                    llmResponseDisplay.style.display = 'block';
                    if (data.success) {
                        currentCode = data.gui_definition;
                        renderApp(currentCode);
                        statusLabel.textContent = '';
                    } else {
                        statusLabel.textContent = 'Error: ' + data.error;
                    }
                })
                .catch(error => {
                    hideLoading();
                    statusLabel.textContent = 'Error: ' + error;
                });
            });

            clearButton.addEventListener('click', function () {
                currentCode = null;
                codeDisplay.style.display = 'none';
                llmResponseDisplay.style.display = 'none';
                sentPromptDisplay.style.display = 'none';
                codeContent.textContent = '';
                appContainer.innerHTML = '';
                userInput.value = '';
                statusLabel.textContent = '';
            });
        });
    </script>
</body>
</html>
<script>
    document.addEventListener('DOMContentLoaded', function () {
        const userInput = document.getElementById('user-input');
        const sendButton = document.getElementById('send-button');
        const uploadButton = document.getElementById('upload-button');
        const fileInput = document.getElementById('file-input');
        const refreshButton = document.getElementById('refresh-button');
        const clearButton = document.getElementById('clear-button');
        const appContainer = document.getElementById('app-container');
        const loadingIndicator = document.getElementById('loading-indicator');
        const llmResponseDisplay = document.getElementById('llm-response-display');
        const llmResponseContent = document.getElementById('llm-response-content');
        const statusLabel = document.getElementById('status-label');
        const sentPromptDisplay = document.getElementById('sent-prompt-display');
        let currentCode = null;

        function showLoading() {
            loadingIndicator.style.display = 'block';
        }

        function hideLoading() {
            loadingIndicator.style.display = 'none';
        }

        function displaySentPrompt(prompt) {
            sentPromptDisplay.textContent = 'Sent Prompt: ' + prompt;
            sentPromptDisplay.style.display = 'block';
        }

        function sendUserRequest() {
            const userRequest = userInput.value.trim();
            if (userRequest === '') {
                alert('Please enter a request.');
                return;
            }
            const promptToSend = JSON.stringify({ user_request: userRequest, current_code: currentCode }, null, 2);
            displaySentPrompt(promptToSend);
            showLoading();
            fetch('/generate_app', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: promptToSend
            })
            .then(response => response.json())
            .then(data => {
                hideLoading();
                llmResponseContent.textContent = data.llm_response || 'No LLM response';
                llmResponseDisplay.style.display = 'block';
                if (data.success) {
                    currentCode = data.gui_definition;
                    renderApp(currentCode);
                    statusLabel.textContent = '';
                } else {
                    statusLabel.textContent = 'Error: ' + data.error;
                }
            })
            .catch(error => {
                hideLoading();
                statusLabel.textContent = 'Error: ' + error;
            });
        }

        function renderApp(guiDefinition) {
            appContainer.innerHTML = '';
            try {
                if (guiDefinition.component && guiDefinition.component.htmlContent) {
                    appContainer.innerHTML = guiDefinition.component.htmlContent; // Access directly to `htmlContent`
                } else {
                    appContainer.innerHTML = '<p>No valid GUI content available.</p>';
                    console.warn("Missing 'htmlContent' in GUI definition:", guiDefinition);
                }
            } catch (error) {
                appContainer.innerHTML = '<p>Failed to render GUI definition. Check console for errors.</p>';
                console.error('Error in renderApp:', error);
            }
        }

        sendButton.addEventListener('click', sendUserRequest);

        userInput.addEventListener('keypress', function (e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendUserRequest();
            }
        });

        uploadButton.addEventListener('click', function () {
            fileInput.click();
        });

        fileInput.addEventListener('change', function () {
            const file = fileInput.files[0];
            if (!file) {
                return;
            }
            const reader = new FileReader();
            reader.onload = function (e) {
                try {
                    const data = JSON.parse(e.target.result);
                    currentCode = data;
                    renderApp(currentCode);
                    statusLabel.textContent = '';
                } catch (err) {
                    statusLabel.textContent = 'Invalid JSON file.';
                }
            };
            reader.readAsText(file);
        });

        refreshButton.addEventListener('click', function () {
            if (!currentCode) {
                alert('No code to refresh. Please generate an app first.');
                return;
            }
            showLoading();
            fetch('/improve_app', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ current_code: currentCode })
            })
            .then(response => response.json())
            .then(data => {
                hideLoading();
                llmResponseContent.textContent = data.llm_response || '';
                llmResponseDisplay.style.display = 'block';
                if (data.success) {
                    currentCode = data.gui_definition;
                    renderApp(currentCode);
                    statusLabel.textContent = '';
                } else {
                    statusLabel.textContent = 'Error: ' + data.error;
                }
            })
            .catch(error => {
                hideLoading();
                statusLabel.textContent = 'Error: ' + error;
            });
        });

        clearButton.addEventListener('click', function () {
            currentCode = null;
            codeDisplay.style.display = 'none';
            llmResponseDisplay.style.display = 'none';
            sentPromptDisplay.style.display = 'none';
            codeContent.textContent = '';
            appContainer.innerHTML = '';
            userInput.value = '';
            statusLabel.textContent = '';
        });
    });
</script>
'''

@app.route('/')
def index():
    return render_template_string(index_html)

@app.route('/generate_app', methods=['POST'])
def generate_app():
    data = request.get_json()
    user_request = data.get('user_request', '').strip()
    current_code = data.get('current_code', None)
    if not user_request:
        return jsonify({'success': False, 'error': 'No user request provided.'})

    result = request_llm_response(user_request, current_code)
    response_data = {
        'llm_response': result.get('llm_response', 'LLM response not provided'),
        'prompt': user_request  # Include the prompt for display
    }

    if result['success']:
        response_data.update({'success': True, 'gui_definition': result['gui_definition']})
    else:
        response_data.update({'success': False, 'error': result['error']})

    return jsonify(response_data)

@app.route('/improve_app', methods=['POST'])
def improve_app():
    data = request.get_json()
    current_code = data.get('current_code', None)
    if not current_code:
        return jsonify({'success': False, 'error': 'No current code available to improve.'})

    result = request_llm_response("", current_code)
    response_data = {
        'llm_response': result.get('llm_response', 'LLM response not provided')
    }

    if result['success']:
        response_data.update({'success': True, 'gui_definition': result['gui_definition']})
    else:
        response_data.update({'success': False, 'error': result['error']})

    return jsonify(response_data)

if __name__ == '__main__':
    app.run(debug=True)