feat: 错误提示中文化、GPT Image 余额查询、Nano Banana 自动重试

- gemini_client: 更新 429/504 中文错误文案,与产品文案对齐
- gpt_image_client: 新增 query_balance_sync / format_balance_info 余额查询方法
- gpt_image: 每次执行后打印余额日志(finally 块保证触发)
- nano_banana_pro: 单张生成支持自动重试,遇 429/503/504 最多重试 4 次,指数退避 2-32s,终端显示显眼重试状态
- nano_banana_pro: 关闭调试日志(DEBUG_LOG_ENABLED = False)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
This commit is contained in:
o1key
2026-04-22 18:10:35 +08:00
co-authored by Claude Sonnet 4.5
parent 949f7bb180
commit fe3cc65b71
4 changed files with 127 additions and 66 deletions
+32
View File
@@ -417,3 +417,35 @@ class GptImageClient:
raise RuntimeError(
f"o1key GPT Image 请求超时(>{_REQUEST_TIMEOUT}s),请检查网络或稍后重试"
)
# ── 余额查询 ──────────────────────────────────────────────────────────────
async def _query_balance_async(self) -> dict:
url = f"{self.base_url}/api/usage/token"
connector = aiohttp.TCPConnector(ssl=False, force_close=True)
timeout = aiohttp.ClientTimeout(total=10)
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
async with session.get(url, headers=self._auth_headers()) as resp:
if resp.status != 200:
raise RuntimeError(f"余额查询失败 HTTP {resp.status}")
return await resp.json()
def query_balance_sync(self) -> dict:
def _run():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
return loop.run_until_complete(self._query_balance_async())
finally:
loop.close()
with ThreadPoolExecutor(max_workers=1) as executor:
return executor.submit(_run).result(timeout=15)
@staticmethod
def format_balance_info(balance_data: dict) -> str:
data = balance_data.get("data", {})
api_name = data.get("name", "未知")
total_available = data.get("total_available", 0)
balance_in_dollars = total_available / 500000
return f"当前余额:{balance_in_dollars:.2f} | API{api_name}"