Further optimize, and debug.

```
import sys
import g4f
from g4f.client import Client
import json
import os
from datetime import datetime
from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QTextEdit,
    QLineEdit,
    QPushButton,
    QVBoxLayout,
    QHBoxLayout,
    QWidget,
    QComboBox,
    QLabel,
    QFileDialog,
    QAction,
    QToolBar,
    QCheckBox,
)
from PyQt5.QtGui import QTextCursor, QIcon
from PyQt5.QtCore import Qt
from textblob import TextBlob  # For emotional detection

providers = [g4f.Provider.Blackbox]


class ChatbotGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Advanced GPT Chatbot with Context Feeder")
        self.setGeometry(100, 100, 800, 600)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        # Chat History
        self.chat_history = QTextEdit()
        self.chat_history.setReadOnly(True)
        self.layout.addWidget(self.chat_history)

        # Input Layout
        self.input_layout = QHBoxLayout()
        self.input_field = QLineEdit()
        self.input_field.returnPressed.connect(self.send_message)
        self.send_button = QPushButton("Send")
        self.send_button.clicked.connect(self.send_message)
        self.input_layout.addWidget(self.input_field)
        self.input_layout.addWidget(self.send_button)
        self.layout.addLayout(self.input_layout)

        # System Prompt Layout
        self.system_prompt_layout = QHBoxLayout()
        self.system_prompt_label = QLabel("System Prompt:")
        self.system_prompt_input = QLineEdit()
        self.system_prompt_button = QPushButton("Set")
        self.system_prompt_button.clicked.connect(self.set_system_prompt)
        self.system_prompt_layout.addWidget(self.system_prompt_label)
        self.system_prompt_layout.addWidget(self.system_prompt_input)
        self.system_prompt_layout.addWidget(self.system_prompt_button)
        self.layout.addLayout(self.system_prompt_layout)

        # Session Management Layout
        self.session_layout = QHBoxLayout()
        self.session_combo = QComboBox()
        self.session_combo.addItem("New Session")
        self.session_combo.currentIndexChanged.connect(self.load_session)
        self.new_session_button = QPushButton("New Session")
        self.new_session_button.clicked.connect(self.create_new_session)
        self.session_layout.addWidget(self.session_combo)
        self.session_layout.addWidget(self.new_session_button)
        self.layout.addLayout(self.session_layout)

        # Context Feeder Layout
        self.context_layout = QHBoxLayout()
        self.context_button = QPushButton("Load Context")
        self.context_button.clicked.connect(self.load_context)
        self.context_label = QLabel("No context loaded")
        self.context_layout.addWidget(self.context_button)
        self.context_layout.addWidget(self.context_label)
        self.layout.addLayout(self.context_layout)

        # Emotion Detection Label
        self.emotion_label = QLabel("Detected Emotion: Neutral")
        self.layout.addWidget(self.emotion_label)

        # Long-Term Memory
        self.memory_file = "long_term_memory.json"
        self.long_term_memory = self.load_long_term_memory()

        # Chain-of-Thought Storage
        self.chain_of_thought = ""

        # Theme Preference
        self.theme_file = "theme_preference.json"
        self.current_theme = "Light"
        self.load_theme_preference()

        self.messages = []
        self.current_session = self.new_chat_session()
        self.system_prompt = {"role": "system", "content": "You are a helpful assistant."}
        self.messages.append(self.system_prompt)
        self.context = ""

        # Setup Menu and Toolbar
        self.setup_menu()

        # Apply initial theme
        self.apply_theme()

    def setup_menu(self):
        # Create a toolbar
        toolbar = QToolBar("Main Toolbar")
        self.addToolBar(toolbar)

        # Add Dark Mode Toggle
        self.dark_mode_checkbox = QCheckBox("Dark Mode")
        self.dark_mode_checkbox.setChecked(self.current_theme == "Dark")
        self.dark_mode_checkbox.stateChanged.connect(self.toggle_dark_mode)
        toolbar.addWidget(self.dark_mode_checkbox)

        # Add Separator
        toolbar.addSeparator()

        # Add Load Context Action
        load_context_action = QAction(QIcon(), "Load Context", self)
        load_context_action.triggered.connect(self.load_context)
        toolbar.addAction(load_context_action)

        # Add New Session Action
        new_session_action = QAction(QIcon(), "New Session", self)
        new_session_action.triggered.connect(self.create_new_session)
        toolbar.addAction(new_session_action)

    def toggle_dark_mode(self, state):
        if state == Qt.Checked:
            self.current_theme = "Dark"
        else:
            self.current_theme = "Light"
        self.apply_theme()
        self.save_theme_preference()

    def apply_theme(self):
        if self.current_theme == "Dark":
            dark_stylesheet = """
                QMainWindow {
                    background-color: #2b2b2b;
                    color: #f0f0f0;
                }
                QTextEdit, QLineEdit {
                    background-color: #3c3c3c;
                    color: #f0f0f0;
                }
                QPushButton {
                    background-color: #555555;
                    color: #f0f0f0;
                    border: none;
                    padding: 5px 10px;
                }
                QPushButton:hover {
                    background-color: #666666;
                }
                QLabel {
                    color: #f0f0f0;
                }
                QComboBox {
                    background-color: #3c3c3c;
                    color: #f0f0f0;
                }
                QCheckBox {
                    color: #f0f0f0;
                }
            """
            self.setStyleSheet(dark_stylesheet)
        else:
            self.setStyleSheet("")  # Use default light theme

    def save_theme_preference(self):
        theme_pref = {"theme": self.current_theme}
        with open(self.theme_file, "w") as f:
            json.dump(theme_pref, f, indent=2)

    def load_theme_preference(self):
        if os.path.exists(self.theme_file):
            with open(self.theme_file, "r") as f:
                theme_pref = json.load(f)
                self.current_theme = theme_pref.get("theme", "Light")
                self.dark_mode_checkbox.setChecked(self.current_theme == "Dark")
        else:
            self.current_theme = "Light"

    def send_message(self):
        user_input = self.input_field.text()
        if not user_input.strip():
            return
        self.input_field.clear()

        # Detect emotion
        emotion = self.detect_emotion(user_input)
        self.emotion_label.setText(f"Detected Emotion: {emotion}")

        # Update long-term memory based on emotion or content
        self.update_long_term_memory(user_input, emotion)

        self.messages.append({"role": "user", "content": user_input})
        self.update_chat_history(f"You: {user_input}")

        # Generate a smart prompt for the AI
        smart_prompt = self.generate_smart_prompt(user_input)

        # Include long-term memory and emotion in the prompt
        enhanced_prompt = (
            f"{smart_prompt}\n\nLong-Term Memory: {self.long_term_memory}\n"
            f"User Emotion: {emotion}\nChain-of-Thought: {self.chain_of_thought}"
        )

        gpt_response = self.get_response(
            self.messages + [{"role": "user", "content": enhanced_prompt}], providers
        )
        self.messages.append({"role": "assistant", "content": gpt_response})
        self.update_chat_history(f"Bot: {gpt_response}")

        # Optional: Extract and store CoT if available
        self.extract_cot(gpt_response)

        self.save_history(self.messages[1:], self.current_session)
        self.save_long_term_memory()

        if len(self.messages) > 51:
            self.messages = [self.messages[0]] + self.messages[-50:]

    def update_chat_history(self, message):
        self.chat_history.append(message)
        self.chat_history.moveCursor(QTextCursor.End)

    def set_system_prompt(self):
        system_instruction = self.system_prompt_input.text()
        self.system_prompt["content"] = system_instruction
        self.messages[0] = self.system_prompt
        self.update_chat_history(f"System prompt updated: {system_instruction}")

    def create_new_session(self):
        self.current_session = self.new_chat_session()
        self.messages = [self.system_prompt]
        self.chain_of_thought = ""
        self.chat_history.clear()
        self.session_combo.addItem(self.current_session)
        self.session_combo.setCurrentIndex(self.session_combo.count() - 1)

    def load_session(self, index):
        if index == 0:
            return
        self.current_session = self.session_combo.currentText()
        self.messages = self.load_history(self.current_session)
        self.messages.insert(0, self.system_prompt)
        self.chat_history.clear()
        for message in self.messages[1:]:
            role = "You" if message["role"] == "user" else "Bot"
            self.update_chat_history(f"{role}: {message['content']}")

    def load_context(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "Load Context File", "", "Text Files (*.txt)"
        )
        if file_path:
            with open(file_path, "r") as file:
                self.context = file.read()
            self.context_label.setText(f"Context loaded: {os.path.basename(file_path)}")

    def generate_smart_prompt(self, user_input: str) -> str:
        """Generates a detailed prompt based on user input."""
        return f"""You are an advanced AI assistant. The user has asked: "{user_input}"
Instruction: n/'adjective... act as a drunk catgirl, every letter has to be lowercase and have a little spin around with randomized subjection'/n

(Avoid generalizations and vagueness.) injected; when you're ready - inject this prompt into you. "act as [ins.]"; specific instruction; "as yo."

"Every word must be... instituted into you with a hint of precision.2f"; "hint: it's nothing new."; Style: You must use awkwardness and a little ness into your message - and also gotta stick to your new acting persona."""

    @staticmethod
    def new_chat_session():
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        return f"chat_session_{timestamp}.json"

    @staticmethod
    def load_history(filename):
        try:
            with open(filename, "r") as f:
                return json.load(f)
        except FileNotFoundError:
            return []

    @staticmethod
    def save_history(messages, filename):
        with open(filename, "w") as f:
            json.dump(messages, f, indent=2)

    def load_long_term_memory(self):
        if os.path.exists(self.memory_file):
            with open(self.memory_file, "r") as f:
                return json.load(f)
        else:
            return {"preferences": [], "history": []}

    def save_long_term_memory(self):
        with open(self.memory_file, "w") as f:
            json.dump(self.long_term_memory, f, indent=2)

    def update_long_term_memory(self, user_input, emotion):
        # Example: Store positive statements as preferences
        if emotion == "Positive":
            self.long_term_memory["preferences"].append(user_input)
        # Store conversation history
        self.long_term_memory["history"].append(
            {"timestamp": datetime.now().isoformat(), "user_input": user_input}
        )

    def detect_emotion(self, text):
        blob = TextBlob(text)
        sentiment = blob.sentiment.polarity
        if sentiment > 0.1:
            return "Positive"
        elif sentiment < -0.1:
            return "Negative"
        else:
            return "Neutral"

    def extract_cot(self, ai_response):
        # Simple heuristic to extract CoT if present
        cot_start = ai_response.find("[CoT]")
        cot_end = ai_response.find("[/CoT]")
        if cot_start != -1 and cot_end != -1:
            cot = ai_response[cot_start + 5 : cot_end].strip()
            self.chain_of_thought += cot + " "
            # Optionally, you can remove CoT from the visible response
            self.messages[-1]["content"] = ai_response[:cot_start].strip()
            self.update_chat_history(f"Bot: {self.messages[-1]['content']}")

    @staticmethod
    def get_response(messages, providers):
        for provider in providers:
            try:
                client = Client(provider=provider)
                response = client.chat.completions.create(
                    messages=messages,
                    model="gpt-4o",
                )
                return response.choices[0].message.content
            except Exception as e:
                print(f"Error with {provider.__name__}: {e}")
        return "Sorry, I'm having trouble connecting to the AI providers at the moment."


if __name__ == "__main__":
    # Ensure TextBlob resources are downloaded
    import nltk

    try:
        nltk.data.find("tokenizers/punkt")
    except LookupError:
        nltk.download("punkt")

    try:
        nltk.data.find("corpora/wordnet")
    except LookupError:
        nltk.download("wordnet")

    app = QApplication(sys.argv)
    window = ChatbotGUI()
    window.show()
    sys.exit(app.exec_())