1
0
Fork 0
This commit is contained in:
Arthur K. 2026-04-21 00:01:56 +03:00
parent ecb5f68e32
commit 5349befcf4
Signed by: wzray
GPG key ID: B97F30FDC4636357
2 changed files with 33 additions and 1 deletions

View file

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
import json import json
import logging
import httpx import httpx
@ -10,6 +11,8 @@ from gibby.settings import Settings
MODELS_URL = "https://chatgpt.com/backend-api/codex/models" MODELS_URL = "https://chatgpt.com/backend-api/codex/models"
logger = logging.getLogger(__name__)
class OpenAIAPIError(RuntimeError): class OpenAIAPIError(RuntimeError):
def __init__( def __init__(
@ -104,7 +107,17 @@ class OpenAIClient:
return parse_usage_payload(await self.fetch_usage_payload(access_token)) return parse_usage_payload(await self.fetch_usage_payload(access_token))
async def validate_token(self, access_token: str) -> bool: async def validate_token(self, access_token: str) -> bool:
response = await self.http_client.get(MODELS_URL, headers=self._headers(access_token)) response = await self.http_client.get(
MODELS_URL,
headers=self._headers(access_token),
params={"client_version": "2.3.9"},
)
if response.status_code != 200:
logger.warning(
"token validation failed: status=%s body=%s",
response.status_code,
_extract_error_text(response),
)
return response.status_code == 200 return response.status_code == 200
@staticmethod @staticmethod

View file

@ -29,10 +29,29 @@ class AccountManager:
while True: while True:
state = self.store.load() state = self.store.load()
if not state.accounts: if not state.accounts:
logger.error("no usable account available: no accounts in state file")
raise NoUsableAccountError("No usable account available") raise NoUsableAccountError("No usable account available")
account = await self._select_account(state) account = await self._select_account(state)
if account is None: if account is None:
logger.error(
"no usable account available: active_account=%s accounts=%s",
state.active_account,
[
{
"email": item.email,
"disabled": item.disabled,
"usage_checked_at": item.usage_checked_at,
"primary": item.usage.primary_window.used_percent
if item.usage and item.usage.primary_window
else None,
"secondary": item.usage.secondary_window.used_percent
if item.usage and item.usage.secondary_window
else None,
}
for item in state.accounts
],
)
raise NoUsableAccountError("No usable account available") raise NoUsableAccountError("No usable account available")
state = self.store.load() state = self.store.load()