добавь функцию чата и добавь поддержку видеокарты import os
import json
import logging
from typing import Dict, List
import requests
from bs4 import BeautifulSoup
import speech_recognition as sr
import pyttsx3
from datetime import datetime
from local_gemma import LocalGemma2ForCausalLM
from transformers import AutoTokenizer

class AdvancedVoiceAssistant:
    def __init__(self):
        # Настройка логирования
        logging.basicConfig(level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s',
                            filename='assistant_log.txt')
        self.logger = logging.getLogger(__name__)

        # Инициализация распознавания речи и микрофона
        self.recognizer = sr.Recognizer()
        self.microphone = sr.Microphone()

        # Используйте ваш токен аутентификации для Hugging Face
        self.huggingface_token = os.getenv('HUGGINGFACE_HUB_TOKEN', '<TRUFFLEHOG_REDACTED_HUGGINGFACE>')

        # Инициализация модели для генерации текста
        try:
            self.model = LocalGemma2ForCausalLM.from_pretrained(
                "google/gemma-2-9b",
                token=self.huggingface_token,
                preset="memory"
            )
            self.tokenizer = AutoTokenizer.from_pretrained(
                "google/gemma-2-9b",
                token=self.huggingface_token
            )
        except Exception as e:
            self.logger.error(f"Ошибка при загрузке модели: {e}")
            print("Ошибка при загрузке модели. Проверьте ваш токен и интернет-соединение.")
            raise

        # Инициализация движка синтеза речи
        self.tts_engine = pyttsx3.init()
        voices = self.tts_engine.getProperty('voices')
        selected_voice = None
        for voice in voices:
            if 'ru' in voice.languages or 'russian' in voice.name.lower():
                self.tts_engine.setProperty('voice', voice.id)
                selected_voice = voice.name
                break
        if selected_voice:
            self.logger.info(f"Используется голос: {selected_voice}")
        else:
            self.logger.warning("Русскоязычный голос не найден. Используется голос по умолчанию.")

        # Параметры обучения
        self.memory_file = 'assistant_memory.json'
        self.knowledge_base = self._load_knowledge_base()

        # Определение внутренних команд и их обработчиков
        self.internal_commands = {
            '#reset_memory': self.reset_memory,
            '#show_history': self.show_history,
            '#clear_logs': self.clear_logs,
        }

    def listen(self):
        """Функция для прослушивания и распознавания речи с использованием микрофона."""
        with self.microphone as source:
            self.recognizer.adjust_for_ambient_noise(source)
            print("Listening...")
            audio = self.recognizer.listen(source)
        try:
            query = self.recognizer.recognize_google(audio, language="ru-RU")
            print(f"You said: {query}")
            self.logger.info(f"Распознанный запрос: {query}")
            return query
        except sr.UnknownValueError:
            self.respond("Извините, я не смогла понять вашу речь.")
            self.logger.warning("Не удалось распознать речь.")
            return ""
        except sr.RequestError as e:
            self.respond("Ошибка запроса к сервису распознавания.")
            self.logger.error(f"Ошибка запроса к сервису распознавания: {e}")
            return ""

    def respond(self, response_text):
        """Функция для синтеза и воспроизведения речи."""
        print(response_text)
        self.tts_engine.say(response_text)
        self.tts_engine.runAndWait()
        self.logger.info(f"Произнесённый ответ: {response_text}")

    def run(self):
        """Основной цикл работы ассистента"""
        print("Запуск продвинутого голосового ассистента...")
        self.logger.info("Ассистент запущен.")
        while True:
            try:
                query = self.listen()
                if not query:
                    continue

                if self.is_internal_command(query):
                    continue

                if self._requires_internet_search(query):
                    search_results = self.internet_search(query)
                    if not search_results:
                        response = "Извините, я не смог выполнить поиск в интернете."
                    else:
                        response = self._formulate_response_with_search(query, search_results)
                else:
                    response = self.generate_response(query)
                self.respond(response)
            except KeyboardInterrupt:
                print("Завершение работы...")
                self.logger.info("Ассистент завершил работу по запросу пользователя.")
                break
            except Exception as e:
                print(f"Непредвиденная ошибка: {e}")
                self.logger.error(f"Непредвиденная ошибка: {e}")

    def is_internal_command(self, query: str) -> bool:
        if not query.startswith('#'):
            return False
        command = query.strip()
        handler = self.internal_commands.get(command)
        if handler:
            handler()
            self.logger.info(f"Выполнена внутренняя команда: {command}")
        else:
            self.logger.warning(f"Неизвестная внутренняя команда: {command}")
            self.respond(f"Неизвестная внутренняя команда: {command}")
        return True

    def reset_memory(self):
        self.knowledge_base = {
            'search_history': [],
            'learned_information': {}
        }
        self._save_knowledge_base()
        self.logger.info("Память ассистента была сброшена.")
        self.respond("Память ассистента была успешно сброшена.")

    def show_history(self):
        history = self.knowledge_base.get('search_history', [])
        if not history:
            self.logger.info("История поиска пуста.")
            self.respond("История поиска пуста.")
            return
        history_text = "История поиска:\n"
        for entry in history:
            history_text += f"Запрос: {entry['query']} - Время: {entry['timestamp']}\n"
        self.respond(history_text)
        self.logger.info("Показана история поиска.")

    def clear_logs(self):
        try:
            open('assistant_log.txt', 'w').close()
            self.logger.info("Логи были успешно очищены.")
            self.respond("Логи были успешно очищены.")
        except Exception as e:
            self.logger.error(f"Ошибка при очистке логов: {e}")
            self.respond("Произошла ошибка при очистке логов.")

    def _load_knowledge_base(self):
        try:
            with open(self.memory_file, 'r', encoding='utf-8') as f:
                knowledge_base = json.load(f)
                self.logger.info("База знаний успешно загружена.")
                return knowledge_base
        except FileNotFoundError:
            self.logger.warning("Файл базы знаний не найден. Создаётся новая база знаний.")
            return {
                'search_history': [],
                'learned_information': {}
            }
        except json.JSONDecodeError as e:
            self.logger.error(f"Ошибка декодирования JSON: {e}")
            return {
                'search_history': [],
                'learned_information': {}
            }

    def generate_response(self, query: str) -> str:
        learned_response = self.knowledge_base['learned_information'].get(query.lower())
        if learned_response:
            self.logger.info(f"Используется сохранённый ответ для запроса '{query}'.")
            return learned_response

        try:
            model_inputs = self.tokenizer(query, return_tensors="pt")
            generated_ids = self.model.generate(**model_inputs.to(self.model.device), max_new_tokens=100)
            response_text = self.tokenizer.decode(generated_ids[0], skip_special_tokens=True)

            self.knowledge_base['learned_information'][query.lower()] = response_text
            self._save_knowledge_base()

            self.logger.info(f"Сохранен новый ответ для запроса '{query}'.")
            return response_text
        except Exception as e:
            self.logger.error(f"Ошибка при генерации ответа: {e}")
            return "Извините, произошла ошибка при генерации ответа."

    def _save_knowledge_base(self):
        try:
            with open(self.memory_file, 'w', encoding='utf-8') as f:
                json.dump(self.knowledge_base, f, ensure_ascii=False, indent=4)
            self.logger.info("База знаний успешно сохранена.")
        except Exception as e:
            self.logger.error(f"Ошибка при сохранении базы знаний: {e}")

    def _requires_internet_search(self, query: str) -> bool:
        keywords = [
            'сколько времени', 'погода', 'новости', 'цена',
            'курс валют', 'расписание', 'курс доллара', 'доллара',
            'текущее время', 'посмотреть время', 'сейчас время',
            'текущий курс', 'курс сегодня', 'курсы валют'
        ]
        query_lower = query.lower()
        requires_search = any(keyword in query_lower for keyword in keywords)
        self.logger.info(f"Запрос требует интернет-поиска: {requires_search}")
        return requires_search

    def internet_search(self, query):
        search_url = "https://www.google.com/search"
        params = {'q': query}
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
        }
        try:
            response = requests.get(search_url, params=params, headers=headers)
            response.raise_for_status()

            soup = BeautifulSoup(response.text, 'html.parser')
            results = []
            for g in soup.find_all('div', class_='g'):
                title = g.find('h3')
                link = g.find('a', href=True)
                snippet = g.find('span', class_='aCOpRe')
                if title and link and snippet:
                    results.append({
                        'title': title.text,
                        'link': link['href'],
                        'snippet': snippet.text
                    })
            self.logger.info(f"Поиск для запроса '{query}' вернул {len(results)} результатов.")
            return results
        except requests.RequestException as e:
            self.logger.error(f"Ошибка интернет-поиска: {e}")
            return []

    def _formulate_response_with_search(self, query: str, search_results: List[Dict[str, str]]) -> str:
        if search_results:
            first_result = search_results[0]
            response = f"{first_result['snippet']} Подробнее: {first_result['link']}"
            self.logger.info(f"Ответ на основе поиска: {response}")
            return response
        else:
            self.logger.warning("Нет результатов для формирования ответа.")
            return "Извините, я не смог найти ответ на ваш вопрос."

if __name__ == "__main__":
    assistant = AdvancedVoiceAssistant()
    assistant.run()