• Stefy Lanza (nextime / spora )'s avatar
    Treat a refreshable codex credential as authenticated · f446a561
    Stefy Lanza (nextime / spora ) authored
    get_provider_handler() gates every provider on the synchronous
    validate_credentials(), which for codex OAuth2 asks is_authenticated() ->
    get_valid_token().  That returns None as soon as the cached access token is
    within five minutes of expiry, and deliberately does not refresh.  The request
    paths do refresh - get_valid_token_with_refresh() at codex.py:311 and :1188,
    writing the new tokens back - but they are never reached, because handler
    construction has already raised "credentials not valid or not configured".
    
    So an access token going stale takes the provider out of every rotation, and
    nothing puts it back: a provider that cannot be built cannot refresh the token
    that would let it be built.  Only a human re-login clears it.  On aisbf.cloud
    all six codex providers were in that state - the main one since its token
    expired on 2026-09-10 - with working refresh tokens sitting in the credential
    files beside them, so rotation/lisa quietly served every request from its
    kilo fallback instead of codex.
    
    is_authenticated() now answers the question validate_credentials() is really
    asking - can these credentials still produce a token - by accepting a stale
    access token when a refresh token is present.  If that refresh later fails the
    request fails and the rotation fails over, which is the behaviour it already
    has for any other provider error.
    
    kilo is left alone: its get_valid_token_with_refresh() only reloads the file
    and cannot refresh, so for kilo an expired token really is terminal.  Qwen has
    the same shape as codex, but its OAuth2 path is documented as discontinued.
    Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
    f446a561
Name
Last commit
Last update
aisbf Loading commit data...
config Loading commit data...
docs Loading commit data...
static Loading commit data...
templates Loading commit data...
tests Loading commit data...
.gitignore Loading commit data...
AI.PROMPT Loading commit data...
API_EXAMPLES.md Loading commit data...
BUILD_DEPLOY.md Loading commit data...
CHANGELOG.md Loading commit data...
DEBUG_GUIDE.md Loading commit data...
DOCUMENTATION.md Loading commit data...
ENDPOINTS.md Loading commit data...
KILO_OAUTH2.md Loading commit data...
LICENSE.txt Loading commit data...
MANIFEST.in Loading commit data...
MISSING_ENDPOINTS.md Loading commit data...
PYPI.md Loading commit data...
QUICK_START_PAYMENT.md Loading commit data...
README.md Loading commit data...
RUNPOD_IMPLEMENTATION_PLAN.md Loading commit data...
SUBSCRIPTION_PRICING_FEATURE.md Loading commit data...
TODO.md Loading commit data...
TORRC_SETUP.md Loading commit data...
aisbf.sh Loading commit data...
build.sh Loading commit data...
chatgpt-api-implementation-guide.md Loading commit data...
clean.sh Loading commit data...
cli.py Loading commit data...
codex-oauth-implementation-guide.md Loading commit data...
main.py Loading commit data...
main.py.bak Loading commit data...
minio-archive-plan.md Loading commit data...
pyproject.toml Loading commit data...
requirements.txt Loading commit data...
screenshot.png Loading commit data...
setup.py Loading commit data...
start_proxy.sh Loading commit data...
verify_release.sh Loading commit data...