import os from .llm_providers import get_provider, get_available_providers from .prompts import get_analysis_prompt class NPAAnalyzer: def __init__(self, provider_name="openrouter", model=None): self.base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) self.methodology_path = os.path.join(self.base_dir, 'data', 'methodology.txt') # Ініціалізація провайдера try: self.provider = get_provider(provider_name, model=model) print(f"Використовується провайдер: {self.provider.name}, модель: {model or 'за замовчуванням'}") except ValueError as e: print(f"Помилка при ініціалізації провайдера: {str(e)}") print("Спроба ініціалізації OpenRouter...") try: # Спроба OpenRouter self.provider = get_provider("openrouter") print(f"Успішно ініціалізовано OpenRouter") except ValueError as e: print(f"Помилка при ініціалізації OpenRouter: {str(e)}") print("Спроба ініціалізації Anthropic...") # Спроба Anthropic self.provider = get_provider("anthropic") print(f"Успішно ініціалізовано Anthropic") self.methodology = self._load_methodology() print(f"Методологія завантажена, розмір: {len(self.methodology)} символів") def _load_methodology(self): print(f"Спроба читання методології з: {self.methodology_path}") try: with open(self.methodology_path, 'r', encoding='utf-8') as file: content = file.read() content = content.strip() if not content: raise ValueError("Файл методології порожній") return content except FileNotFoundError: raise FileNotFoundError(f"Файл методології не знайдено за шляхом: {self.methodology_path}") except Exception as e: raise Exception(f"Помилка при читанні файлу методології: {str(e)}") def analyze_npa(self, npa_text: str, enable_thinking=False, thinking_budget=2000) -> dict: """ Аналізує нормативно-правовий акт і повертає словник з текстом відповіді та роздумами. Args: npa_text (str): Текст НПА для аналізу enable_thinking (bool): Чи включати режим "thinking" (за замовчуванням False) thinking_budget (int): Бюджет токенів для режиму "thinking" (за замовчуванням 2000) Returns: dict: Словник з ключами 'response' (основна відповідь) та 'thinking' (хід роздумів, якщо доступно) """ if not npa_text: return {"response": "Будь ласка, введіть текст НПА для аналізу.", "thinking": None} try: # Підготовка промпту analysis_prompt = get_analysis_prompt(self.methodology, npa_text) # Вивід інформації в консоль про загальний розмір промпту try: from .prompts import count_tokens total_tokens = count_tokens(analysis_prompt) print(f"\nЗАГАЛЬНИЙ РОЗМІР ПРОМПТУ: {total_tokens} токенів") print(f"Розмір НПА: {len(npa_text)} символів ({count_tokens(npa_text)} токенів)") print(f"Розмір методології: {len(self.methodology)} символів ({count_tokens(self.methodology)} токенів)") print(f"Провайдер: {self.provider.name}, Модель: {self.provider._model}") print(f"Режим роздумів: {'Увімкнено' if enable_thinking else 'Вимкнено'}, Бюджет: {thinking_budget} токенів\n") except Exception as e: print(f"Помилка при підрахунку токенів: {str(e)}") # Використовуємо відповідний провайдер для аналізу # Якщо провайдер не підтримує thinking, але enable_thinking=True, то це буде проігноровано result = self.provider.analyze( prompt=analysis_prompt, enable_thinking=enable_thinking and self.provider.supports_thinking, thinking_budget=thinking_budget ) return result except Exception as e: error_message = str(e) print(f"Помилка при аналізі: {error_message}") return {"response": f"Помилка при аналізі: {error_message}", "thinking": None} def get_available_models(self): """Повертає список доступних моделей для поточного провайдера""" return self.provider.available_models def get_provider_name(self): """Повертає назву поточного провайдера""" return self.provider.name def supports_thinking(self): """Повертає True, якщо поточний провайдер підтримує режим роздумів""" return self.provider.supports_thinking @staticmethod def get_available_providers(): """Повертає список доступних провайдерів""" return get_available_providers() def change_provider(self, provider_name, model=None): """Змінює поточного провайдера""" try: self.provider = get_provider(provider_name, model=model) print(f"Провайдера змінено на: {self.provider.name}, модель: {model or 'за замовчуванням'}") return True except Exception as e: print(f"Помилка при зміні провайдера: {str(e)}") return False def change_model(self, model): """Змінює модель для поточного провайдера""" try: current_provider_name = self.provider.name self.provider = get_provider(current_provider_name, model=model) print(f"Модель змінено на: {model}") return True except Exception as e: print(f"Помилка при зміні моделі: {str(e)}") return False