diff --git a/eval/tenant_panel/money.py b/eval/tenant_panel/money.py index b8f2e35d..7e8cb8f6 100644 --- a/eval/tenant_panel/money.py +++ b/eval/tenant_panel/money.py @@ -18,6 +18,7 @@ from __future__ import annotations import json import os import subprocess +import time import sys from functools import lru_cache from pathlib import Path @@ -134,15 +135,33 @@ def _refuse_unfrozen() -> None: raise SystemExit("⛔ вызывающий файл не определён") +# Транзиентные отказы провода, которые лечатся ожиданием, а не диагнозом. Поймано исполнением +# 08.08: `gemini-3.1-pro-preview` отдал HTTP 503 «This model is currently experiencing high +# demand» на ЧЕТЫРЁХ вызовах подряд ($0, клетки потеряны), а через минуту тот же слаг ответил с +# первой попытки; страница статуса Google при этом инцидентов не показывала. Без отступа +# обязательный кандидат Ф3 выпал бы из замера по причине, которая замером не является. +_TRANSIENT = ("503", "502", "504", "overloaded", "high demand", "timeout", "Timeout", + "RemoteProtocolError", "APIConnectionError") + + def purchase(led: Guarded, tag: str, model: str, client, kw: dict, **extra) -> dict: - """Один платный вызов. Кэш → фриз-гейт → проекционный гард → покупка.""" + """Один платный вызов. Кэш → фриз-гейт → проекционный гард → покупка (+ отступ на 5xx).""" f = OUT / f"{tag}.json" if f.exists(): return json.loads(f.read_text(encoding="utf-8")) if not any(tag.startswith(p.split("*")[0]) for p in TAGS[led.phase]): raise SystemExit(f"⛔ тег {tag!r} не покрыт глобом кассы {led.phase} — впиши в TAGS") _refuse_unfrozen() - return BUY.purchase(led, tag, model, client, kw, **extra) + rec = {} + for k in range(4): + rec = BUY.purchase(led, tag, model, client, kw, **extra) + err = rec.get("error", "") if rec.get("finish") == "error" else "" + if not err or not any(t in err for t in _TRANSIENT): + return rec + wait = 15 * (k + 1) + print(f" транзиентный отказ ({err[:60]}) — отступ {wait} с") + time.sleep(wait) + return rec def report() -> None: diff --git a/eval/tenant_panel/panel.py b/eval/tenant_panel/panel.py index 24e037d6..643abf73 100644 --- a/eval/tenant_panel/panel.py +++ b/eval/tenant_panel/panel.py @@ -55,7 +55,8 @@ OUT = MONEY.OUT ANCHOR = "deepseek-v4-flash" # боевой черновик — якорь панели EDITOR = "deepseek-v4-pro" # боевой редактор, конфиг `A_law` (full-regen + закон-блок) -MAX_TENANTS = 5 # потолок промта: до 5 жильцов + якорь +MAX_TENANTS = 5 # промт: «до 5 жильцов черновика + `deepseek-v4-flash` +# (якорь)» ⇒ пять СВЕРХ якоря, панель ≤6 клеток RETRIES = 3