From f74953e082b59f715c3f5007dbfadf17f923560e Mon Sep 17 00:00:00 2001 From: gitadmin Date: Wed, 2 Sep 2026 22:19:58 +0300 Subject: [PATCH] =?UTF-8?q?[ZILANT]=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=D0=B0=20=D0=90=D0=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db_update_shortname.py | 119 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 6 deletions(-) diff --git a/db_update_shortname.py b/db_update_shortname.py index 0d273c1..781fdf1 100644 --- a/db_update_shortname.py +++ b/db_update_shortname.py @@ -30,6 +30,79 @@ ROUTERAI_CONFIG = { # Настройки журналирования LOG_FILE = os.getenv('LOG_FILE', 'ai_namer.log') # Путь к лог-файлу LOG_PREFIX = "AI_namer" # Уникальный префикс для идентификации скрипта +LOG_AI_RESPONSE_MAX = int(os.getenv('LOG_AI_RESPONSE_MAX', '8000')) # обрезка длинных полей в логе + + +def _truncate_for_log(value, max_len=None): + """Обрезает длинные значения для журнала, не теряя информацию о размере.""" + if value is None: + return None + if not isinstance(value, str): + value = json.dumps(value, ensure_ascii=False, default=str) + limit = max_len if max_len is not None else LOG_AI_RESPONSE_MAX + if len(value) <= limit: + return value + return f"{value[:limit]}... [обрезано, всего {len(value)} символов]" + + +def _message_fields_for_log(message): + """Все значимые поля message из ответа chat/completions.""" + if not message: + return {} + logged = {} + for key in ( + 'role', 'content', 'reasoning_content', 'reasoning', + 'refusal', 'tool_calls', 'function_call', 'audio', + ): + if key not in message: + continue + value = message.get(key) + if value in (None, '', [], {}): + logged[key] = value + elif isinstance(value, str): + logged[key] = _truncate_for_log(value) + else: + logged[key] = _truncate_for_log(json.dumps(value, ensure_ascii=False, default=str)) + return logged + + +def _log_routerai_request(text, prompt): + """Журнал параметров исходящего запроса (без API-ключа).""" + log_message( + "Запрос RouterAI: " + f"model={ROUTERAI_CONFIG['model']}, " + f"text_len={len(text)}, prompt_len={len(prompt)}, " + f"text_preview={_truncate_for_log(text.strip(), 300)}" + ) + + +def _log_routerai_response(response, result=None, error_body=None): + """Подробный журнал HTTP-ответа RouterAI.""" + payload = { + "http_status": getattr(response, 'status_code', None), + "model": ROUTERAI_CONFIG.get('model'), + } + if result is not None: + payload["response_id"] = result.get("id") + payload["object"] = result.get("object") + payload["created"] = result.get("created") + payload["usage"] = result.get("usage") + payload["system_fingerprint"] = result.get("system_fingerprint") + choices = result.get("choices") or [] + payload["choices_count"] = len(choices) + payload["choices"] = [] + for i, choice in enumerate(choices): + payload["choices"].append({ + "index": choice.get("index", i), + "finish_reason": choice.get("finish_reason"), + "message": _message_fields_for_log(choice.get("message") or {}), + "logprobs": choice.get("logprobs"), + }) + if result.get("error"): + payload["api_error"] = result.get("error") + if error_body is not None: + payload["error_body"] = _truncate_for_log(error_body) + log_message(f"Ответ RouterAI: {json.dumps(payload, ensure_ascii=False, default=str)}") def log_message(message, max_retries=5, retry_delay=0.1): """ @@ -89,6 +162,8 @@ def _generate_shortname_by_api(text): "max_tokens": 5000, "temperature": 0.3, } + + _log_routerai_request(text, prompt) try: response = requests.post(url, headers=headers, json=data, timeout=180) @@ -106,21 +181,37 @@ def _generate_shortname_by_api(text): error_info["body"] = response.json() except Exception: pass - + + _log_routerai_response(response, error_body=error_info.get("body")) log_message(f"Ошибка 429: Превышен лимит запросов. Ответ API: {json.dumps(error_info, ensure_ascii=False)}") print("Ошибка 429: Превышен лимит запросов. Подробности в логе.") # Не sys.exit — эта функция вызывается и из веб-API Flask raise RuntimeError("RouterAI 429: превышен лимит запросов") - - response.raise_for_status() + + if not response.ok: + _log_routerai_response(response, error_body=response.text) + response.raise_for_status() + result = response.json() + _log_routerai_response(response, result=result) # Извлекаем только текст ответа (у thinking-моделей ответ в content, # рассуждения — в reasoning_content / reasoning) - message = result['choices'][0]['message'] + choices = result.get('choices') or [] + if not choices: + log_message("RouterAI вернул пустой choices — название не извлечь") + return None + + message = choices[0].get('message') or {} shortname = (message.get('content') or '').strip() if not shortname: - log_message(f"Пустой content в ответе RouterAI: {json.dumps(result, ensure_ascii=False)[:1000]}") + reasoning = (message.get('reasoning_content') or message.get('reasoning') or '').strip() + log_message( + "Пустой content в ответе RouterAI; " + f"finish_reason={choices[0].get('finish_reason')!r}, " + f"message_keys={list(message.keys())}, " + f"reasoning_len={len(reasoning)}" + ) return None # Удаляем возможные кавычки и лишние символы @@ -148,15 +239,31 @@ def _generate_shortname_by_api(text): error_info["body"] = e.response.json() except Exception: pass - + + _log_routerai_response(e.response, error_body=error_info.get("body")) log_message(f"Ошибка 429: Превышен лимит запросов. Ответ API: {json.dumps(error_info, ensure_ascii=False)}") print("Ошибка 429: Превышен лимит запросов. Подробности в логе.") raise RuntimeError("RouterAI 429: превышен лимит запросов") else: + if e.response is not None: + try: + _log_routerai_response(e.response, error_body=e.response.text) + except Exception: + pass error_msg = f"HTTP ошибка при генерации названия: {e}" log_message(error_msg) print(error_msg) return None + except requests.exceptions.Timeout as e: + error_msg = f"Таймаут запроса RouterAI ({e})" + log_message(error_msg) + print(error_msg) + return None + except requests.exceptions.RequestException as e: + error_msg = f"Сетевая ошибка RouterAI: {e}" + log_message(error_msg) + print(error_msg) + return None except RuntimeError: raise except Exception as e: