@@ -177,6 +177,7 @@ import {
177177import { applyFastSessionDefaults } from "./lib/request/request-transformer.js" ;
178178import { applyResponseCompaction } from "./lib/request/response-compaction.js" ;
179179import { isEmptyResponse } from "./lib/request/response-handler.js" ;
180+ import { CodexAuthError } from "./lib/errors.js" ;
180181import {
181182 parseRetryAfterHintMs ,
182183 sanitizeResponseHeadersForLog ,
@@ -997,9 +998,10 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
997998 accountAuth ,
998999 client ,
9991000 ) ) as OAuthAuthDetails ;
1000- accountManager . updateFromAuth ( account , accountAuth ) ;
1001- accountManager . clearAuthFailures ( account ) ;
1002- accountManager . saveToDiskDebounced ( ) ;
1001+ await accountManager . commitRefreshedAuth (
1002+ account ,
1003+ accountAuth ,
1004+ ) ;
10031005 }
10041006 } catch ( err ) {
10051007 logDebug (
@@ -1010,18 +1012,48 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
10101012 runtimeMetrics . accountRotations ++ ;
10111013 runtimeMetrics . lastError =
10121014 ( err as Error ) ?. message ?? String ( err ) ;
1013- const failures =
1014- accountManager . incrementAuthFailures ( account ) ;
1015+ const isRetryableRefreshError =
1016+ err instanceof CodexAuthError && err . retryable ;
10151017 const accountLabel = formatAccountLabel (
10161018 account ,
10171019 account . index ,
10181020 ) ;
10191021
1022+ sessionAffinityStore ?. forgetSession ( sessionAffinityKey ) ;
1023+
1024+ if ( isRetryableRefreshError ) {
1025+ runtimeMetrics . networkErrors ++ ;
1026+ const retryableRefreshPolicy = evaluateFailurePolicy (
1027+ { kind : "network" , failoverMode } ,
1028+ { networkCooldownMs : networkErrorCooldownMs } ,
1029+ ) ;
1030+ if ( retryableRefreshPolicy . recordFailure ) {
1031+ accountManager . recordFailure (
1032+ account ,
1033+ modelFamily ,
1034+ model ,
1035+ ) ;
1036+ }
1037+ if (
1038+ typeof retryableRefreshPolicy . cooldownMs === "number" &&
1039+ retryableRefreshPolicy . cooldownReason
1040+ ) {
1041+ accountManager . markAccountCoolingDown (
1042+ account ,
1043+ retryableRefreshPolicy . cooldownMs ,
1044+ retryableRefreshPolicy . cooldownReason ,
1045+ ) ;
1046+ accountManager . saveToDiskDebounced ( ) ;
1047+ }
1048+ continue ;
1049+ }
1050+
1051+ const failures =
1052+ accountManager . incrementAuthFailures ( account ) ;
10201053 const authFailurePolicy = evaluateFailurePolicy ( {
10211054 kind : "auth-refresh" ,
10221055 consecutiveAuthFailures : failures ,
10231056 } ) ;
1024- sessionAffinityStore ?. forgetSession ( sessionAffinityKey ) ;
10251057
10261058 if ( authFailurePolicy . removeAccount ) {
10271059 const removedIndex = account . index ;
@@ -1945,14 +1977,10 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
19451977 fallbackAuth ,
19461978 client ,
19471979 ) ) as OAuthAuthDetails ;
1948- accountManager . updateFromAuth (
1980+ await accountManager . commitRefreshedAuth (
19491981 fallbackAccount ,
19501982 fallbackAuth ,
19511983 ) ;
1952- accountManager . clearAuthFailures (
1953- fallbackAccount ,
1954- ) ;
1955- accountManager . saveToDiskDebounced ( ) ;
19561984 }
19571985 } catch ( refreshError ) {
19581986 logWarn (
0 commit comments