fix the issue causing it not to work properly import sys
import os
import asyncio
import json
import ast
import re
import logging
from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog,
    QTextEdit, QProgressBar, QMessageBox, QLabel, QTabWidget, QHBoxLayout, QLineEdit
)
from PyQt6.QtCore import Qt, QThread, QThreadPool, QObject, pyqtSignal, QRunnable
from PyQt6.QtGui import QTextCursor
from functools import lru_cache
from concurrent.futures import ProcessPoolExecutor
from dotenv import load_dotenv
import torch
from transformers import GPTNeoForCausalLM, GPT2Tokenizer
import nltk
import spacy
from accelerate import Accelerator
import aiohttp
from aiolimiter import AsyncLimiter
from groq import AsyncGroq
from bs4 import BeautifulSoup

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# Load environment variables
load_dotenv()

# Environment variables
GROQ_API_KEY = os.getenv('GROQ_API_KEY')
GROQ_MODEL = os.getenv('GROQ_MODEL', 'mixtral-8x7b-32768')
MODEL_PATH = os.getenv('MODEL_PATH', './local_gpt_neo_model')
KNOWLEDGE_PATH = os.getenv('KNOWLEDGE_PATH', 'solana_knowledge_base.json')
MEMORY_PATH = os.getenv('MEMORY_PATH', 'memory.json')
ANALYZED_SCRIPTS_PATH = os.getenv('ANALYZED_SCRIPTS_PATH', 'analyzed_scripts.json')

# Constants
MAX_MEMORY_ENTRIES = 500
MAX_ANALYZED_SCRIPTS = 500
MAX_GROQ_TOKENS = 2000
MAX_LOCAL_INFERENCE_LENGTH = 300
TEMPERATURE = 0.8
TOP_K = 40
TOP_P = 0.9
REPETITION_PENALTY = 1.2
NUM_BEAMS = 4

# Initialize Accelerator
accelerator = Accelerator()
device = accelerator.device
logger.info(f"Using device: {device}")

# Define a function to load the model. Use a cache to ensure it is loaded once
@lru_cache(maxsize=1)
def load_model():
    logger.info(f"Loading model from {MODEL_PATH}...")
    tokenizer = GPT2Tokenizer.from_pretrained(MODEL_PATH)
    model = GPTNeoForCausalLM.from_pretrained(MODEL_PATH).to(device)
    model.eval()
    logger.info("Model loaded successfully.")
    return tokenizer, model

# Initialize clients
groq_client = AsyncGroq(api_key=GROQ_API_KEY)

# Rate limiters
token_limiter = AsyncLimiter(10000, 60)
call_limiter = AsyncLimiter(50, 60)

# Download necessary NLTK data files
nltk.download('punkt', quiet=True)
nltk.download('stopwords', quiet=True)
nltk.download('wordnet', quiet=True)

# Load Spacy language model
nlp = spacy.load('en_core_web_sm')

# Utility functions for JSON operations
def load_json_file(file_path, default):
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except (FileNotFoundError, json.JSONDecodeError) as e:
        logger.warning(f"Failed to load {file_path}: {e}")
        return default

def save_json_file(data, file_path):
    try:
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=2)
    except Exception as e:
        logger.error(f"Error saving to {file_path}: {e}")

# Load persistent data
memory = load_json_file(MEMORY_PATH, [])
analyzed_scripts = load_json_file(ANALYZED_SCRIPTS_PATH, [])
knowledge_base = load_json_file(KNOWLEDGE_PATH, {})

# Function to analyze a file
def analyze_file(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()
        analysis = {
            'file_name': os.path.basename(file_path),
            'content_length': len(content),
            'imports': [],
            'functions': [],
            'structs': [],
        }
        if file_path.endswith('.py'):
            try:
                tree = ast.parse(content)
                for node in ast.walk(tree):
                    if isinstance(node, ast.Import):
                        analysis['imports'].extend(n.name for n in node.names)
                    elif isinstance(node, ast.ImportFrom):
                        analysis['imports'].extend(f"{node.module}.{n.name}" for n in node.names)
                    elif isinstance(node, ast.FunctionDef):
                        analysis['functions'].append(node.name)
                    elif isinstance(node, ast.ClassDef):
                        analysis['structs'].append(node.name)
            except SyntaxError as e:
                logger.error(f"Syntax error in {file_path}: {e}")
        elif file_path.endswith('.rs'):
            for line in content.split('\n'):
                if line.strip().startswith('use '):
                    analysis['imports'].append(line.strip())
                elif match := re.match(r'fn\s+(\w+)', line.strip()):
                    analysis['functions'].append(match.group(1))
                elif match := re.match(r'struct\s+(\w+)', line.strip()):
                    analysis['structs'].append(match.group(1))
        return analysis
    except Exception as e:
        logger.error(f"Error analyzing file {file_path}: {e}")
        return None

# Optimized local model inference
@torch.no_grad()
def local_model_inference(prompt, max_length=MAX_LOCAL_INFERENCE_LENGTH):
    tokenizer, model = load_model()  # Ensure models are loaded
    inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512).to(device)
    output = model.generate(
        **inputs,
        max_length=max_length,
        num_return_sequences=1,
        temperature=TEMPERATURE,
        top_k=TOP_K,
        top_p=TOP_P,
        repetition_penalty=REPETITION_PENALTY,
        num_beams=NUM_BEAMS,
        do_sample=True
    )
    generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
    return generated_text[len(prompt):].strip()

async def fetch_url(session, url):
    try:
        async with session.get(url, timeout=30) as response:
            html = await response.text()
            soup = BeautifulSoup(html, 'html.parser')
            return soup.get_text()
    except Exception as e:
        logger.error(f"Error fetching {url}: {e}")
        return ""

async def efficient_web_crawl(urls):
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_url(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
    return " ".join(results)

async def groq_web_crawl(query, urls):
    crawled_text = await efficient_web_crawl(urls)
    async with call_limiter:
        async with token_limiter:
            chat_completion = await groq_client.chat.completions.create(
                messages=[
                    {"role": "system", "content": "Find and extract high-quality Solana code snippets and documentation from the following content:"},
                    {"role": "user", "content": f"{crawled_text}\n\nQuery: {query}"}
                ],
                model=GROQ_MODEL,
                max_tokens=MAX_GROQ_TOKENS
            )
    return chat_completion.choices[0].message.content.strip()

async def process_chat_message(message):
    context = f"""
    Memory: {json.dumps(memory[-5:])}
    Analyzed Scripts: {json.dumps(analyzed_scripts[-5:])}
    Knowledge Base: {json.dumps(list(knowledge_base.items())[:5])}
    User Message: {message}
    """
    
    local_response = local_model_inference(context)
    
    if "need more information" in local_response.lower():
        urls = knowledge_base.get(message, [])
        if urls:
            groq_response = await groq_web_crawl(message, urls)
            knowledge_base[message] = groq_response
            save_json_file(knowledge_base, KNOWLEDGE_PATH)
            final_response = local_model_inference(context + "\nAdditional Info: " + groq_response[:500])
        else:
            final_response = "I don't have enough information to answer that question. Can you provide more context or specific URLs to search?"
    else:
        final_response = local_response

    append_to_memory({"user": message, "ai": final_response})
    return final_response

def append_to_memory(entry):
    memory.append(entry)
    if len(memory) > MAX_MEMORY_ENTRIES:
        memory.pop(0)
    save_json_file(memory, MEMORY_PATH)

class WorkerSignals(QObject):
    finished = pyqtSignal()
    error = pyqtSignal(tuple)
    result = pyqtSignal(object)
    progress = pyqtSignal(int)

class Worker(QRunnable):
    def __init__(self, fn, *args, **kwargs):
        super().__init__()
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        self.signals = WorkerSignals()

    def run(self):
        try:
            result = self.fn(*self.args, **self.kwargs)
        except Exception as e:
            traceback.print_exc()
            exctype, value = sys.exc_info()[:2]
            self.signals.error.emit((exctype, value, traceback.format_exc()))
        else:
            self.signals.result.emit(result)
        finally:
            self.signals.finished.emit()

class AsyncHelper(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.loop = asyncio.new_event_loop()
        self.thread = QThread()
        self.thread.started.connect(self._start_loop)

    def _start_loop(self):
        asyncio.set_event_loop(self.loop)
        self.loop.run_forever()

    def start(self):
        self.thread.start()

    def stop(self):
        self.loop.call_soon_threadsafe(self.loop.stop)
        self.thread.quit()
        self.thread.wait()

    def run_coroutine(self, coro):
        future = asyncio.run_coroutine_threadsafe(coro, self.loop)
        try:
            return future.result()
        except Exception as e:
            logger.error(f"Error running coroutine: {e}")
            return None

class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'Solana Sniper Bot Analyzer and Enhancer'
        self.threadpool = QThreadPool()
        self.async_helper = AsyncHelper(self)
        self.async_helper.start()
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(100, 100, 900, 700)

        layout = QVBoxLayout()
        self.tabs = QTabWidget()
        layout.addWidget(self.tabs)

        self.tab1 = QWidget()
        self.tabs.addTab(self.tab1, "Code Analyzer")
        self.tab1UI()

        self.tab2 = QWidget()
        self.tabs.addTab(self.tab2, "AI Chat")
        self.tab2UI()

        self.setLayout(layout)

    def tab1UI(self):
        layout = QVBoxLayout()

        title = QLabel("Solana Sniper Bot Code Analyzer and Enhancer")
        title.setStyleSheet("font-size: 18px; font-weight: bold;")
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)

        self.select_script_directory_btn = QPushButton('Select Directory for Scripts')
        self.select_script_directory_btn.clicked.connect(self.select_and_read_scripts)
        layout.addWidget(self.select_script_directory_btn)

        self.selected_folder_label = QLabel('No folder selected.')
        layout.addWidget(self.selected_folder_label)

        self.start_btn = QPushButton('Start Analysis')
        self.start_btn.clicked.connect(self.start_analysis)
        self.start_btn.setEnabled(False)
        layout.addWidget(self.start_btn)

        self.progress_bar = QProgressBar()
        layout.addWidget(self.progress_bar)

        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        layout.addWidget(self.log_text)

        self.tab1.setLayout(layout)

    def tab2UI(self):
        layout = QVBoxLayout()

        self.chat_display = QTextEdit()
        self.chat_display.setReadOnly(True)
        layout.addWidget(self.chat_display)

        h_layout = QHBoxLayout()
        self.chat_input = QLineEdit()
        self.chat_input.setPlaceholderText("Type your message here...")
        self.chat_input.returnPressed.connect(self.send_chat)
        send_btn = QPushButton("Send")
        send_btn.clicked.connect(self.send_chat)
        h_layout.addWidget(self.chat_input)
        h_layout.addWidget(send_btn)

        layout.addLayout(h_layout)
        self.tab2.setLayout(layout)

    def select_and_read_scripts(self):
        directory = QFileDialog.getExistingDirectory(self, 'Select Directory for Scripts')
        if directory:
            self.selected_folder = directory
            self.selected_folder_label.setText(f'Selected Directory: {directory}')
            self.start_btn.setEnabled(True)

    def start_analysis(self):
        self.start_btn.setEnabled(False)
        worker = Worker(self.analyze_scripts)
        worker.signals.result.connect(self.analysis_finished)
        worker.signals.error.connect(self.analysis_error)
        self.threadpool.start(worker)
        self.log_text.append("Analysis started...")

    def analyze_scripts(self):
        try:
            files = [f for f in os.listdir(self.selected_folder) if f.endswith(('.py', '.rs'))]
            total_files = len(files)
            
            with ProcessPoolExecutor() as executor:
                futures = [executor.submit(analyze_file, os.path.join(self.selected_folder, file)) for file in files]
                for i, future in enumerate(futures):
                    analysis = future.result()
                    if analysis:
                        self.log_text.append(f"Analyzed {analysis['file_name']}: {analysis['content_length']} chars")
                        if not any(a['file_name'] == analysis['file_name'] for a in analyzed_scripts):
                            analyzed_scripts.append(analysis)
                            if len(analyzed_scripts) > MAX_ANALYZED_SCRIPTS:
                                analyzed_scripts.pop(0)
                        self.progress_bar.setValue(int((i + 1) / total_files * 100))
            
            save_json_file(analyzed_scripts, ANALYZED_SCRIPTS_PATH)
            return "Analysis completed successfully."
        except Exception as e:
            logger.error(f"Error during analysis: {e}")
            return "Error occurred during analysis."

    def analysis_finished(self, result):
        self.log_text.append(result)
        self.start_btn.setEnabled(True)
        QMessageBox.information(self, "Completed", "Analysis and enhancement completed.")

    def analysis_error(self, error_info):
        self.log_text.append(f"Error during analysis: {error_info[1]}")
        self.start_btn.setEnabled(True)

    def send_chat(self):
        message = self.chat_input.text().strip()
        if message:
            self.chat_display.append(f"User: {message}")
            self.chat_input.clear()
            QApplication.processEvents()

            # Use the async helper to run the coroutine
            worker = Worker(self.async_helper.run_coroutine, self.process_chat(message))
            worker.signals.result.connect(self.handle_chat_response)
            self.threadpool.start(worker)

    async def process_chat(self, message):
        return await process_chat_message(message)

    def handle_chat_response(self, response):
        self.chat_display.append(f"AI: {response}")
        self.chat_display.moveCursor(QTextCursor.MoveOperation.End)

    def closeEvent(self, event):
        self.async_helper.stop()
        super().closeEvent(event)

def main():
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec())

if __name__ == '__main__':
    main()
 write the entire script please