From 59f7a7c5209d803b7f58bb83650aa72693b741ee Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Thu, 22 Jan 2026 22:11:39 +0300 Subject: [PATCH] feat: add OpenRouter AI service integration --- .../ai_services/openrouter_service.py | 51 +++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/myproject/integrations/services/ai_services/openrouter_service.py b/myproject/integrations/services/ai_services/openrouter_service.py index 5d76a1d..6ee23c2 100644 --- a/myproject/integrations/services/ai_services/openrouter_service.py +++ b/myproject/integrations/services/ai_services/openrouter_service.py @@ -3,28 +3,45 @@ from ..base import BaseIntegrationService from .config import get_openrouter_config import logging import sys -import locale +import traceback # Патч для исправления проблемы с кодировкой в httpx на Windows # Устанавливаем кодировку по умолчанию для Python if sys.platform == 'win32': try: import httpx._models - original_normalize_header_value = httpx._models._normalize_header_value + + # Сохраняем оригинальную функцию, если она есть + _original_normalize_header_value = getattr(httpx._models, '_normalize_header_value', None) def patched_normalize_header_value(value, encoding): """Патч для использования UTF-8 вместо ASCII для заголовков""" - # Если значение уже bytes, возвращаем его как есть - if isinstance(value, bytes): - return value - # Всегда используем UTF-8 вместо ASCII - encoding = encoding or 'utf-8' - if encoding.lower() == 'ascii': - encoding = 'utf-8' - return value.encode(encoding) + try: + # Если значение уже bytes, возвращаем его как есть + if isinstance(value, bytes): + return value + + # Если значение не строка и не байты, приводим к строке + if not isinstance(value, str): + value = str(value) + + # Всегда используем UTF-8 вместо ASCII + encoding = encoding or 'utf-8' + if encoding.lower() == 'ascii': + encoding = 'utf-8' + + return value.encode(encoding) + except Exception as e: + # В случае ошибки логируем и пробуем максимально безопасный вариант + logging.getLogger(__name__).error(f"Error in patched_normalize_header_value: {e}. Value: {repr(value)}") + if isinstance(value, str): + return value.encode('utf-8', errors='ignore') + return b'' httpx._models._normalize_header_value = patched_normalize_header_value - logging.getLogger(__name__).info("Applied patch for httpx header encoding on Windows") + logging.getLogger(__name__).info("Applied robust patch for httpx header encoding on Windows") + except ImportError: + logging.getLogger(__name__).warning("httpx module not found, patch skipped") except Exception as e: logging.getLogger(__name__).warning(f"Failed to apply httpx patch: {e}") @@ -148,8 +165,10 @@ class OpenRouterIntegrationService(BaseIntegrationService): } except Exception as e: - logger.error(f"Ошибка генерации текста с помощью OpenRouter: {str(e)}") - return False, f"Ошибка генерации: {str(e)}", None + error_msg = str(e) + logger.error(f"Ошибка генерации текста с помощью OpenRouter: {error_msg}") + logger.error(traceback.format_exc()) + return False, f"Ошибка генерации: {error_msg}", None def generate_code(self, prompt: str, @@ -196,5 +215,7 @@ class OpenRouterIntegrationService(BaseIntegrationService): } except Exception as e: - logger.error(f"Ошибка генерации кода с помощью OpenRouter: {str(e)}") - return False, f"Ошибка генерации кода: {str(e)}", None + error_msg = str(e) + logger.error(f"Ошибка генерации кода с помощью OpenRouter: {error_msg}") + logger.error(traceback.format_exc()) + return False, f"Ошибка генерации кода: {error_msg}", None