@@ -593,6 +593,28 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
593593 : newWs ;
594594 } )
595595 : existing . workspaces ;
596+ const nextCurrentWorkspaceIndex =
597+ mergedWorkspaces && mergedWorkspaces . length > 0
598+ ? ( ( ) => {
599+ const currentIndex =
600+ typeof existing . currentWorkspaceIndex === "number"
601+ ? existing . currentWorkspaceIndex
602+ : 0 ;
603+ if ( currentIndex >= 0 && currentIndex < mergedWorkspaces . length ) {
604+ return currentIndex ;
605+ }
606+ const defaultWorkspaceIndex = mergedWorkspaces . findIndex (
607+ ( workspace ) => workspace . isDefault === true ,
608+ ) ;
609+ if ( defaultWorkspaceIndex >= 0 ) {
610+ return defaultWorkspaceIndex ;
611+ }
612+ const firstEnabledWorkspaceIndex = mergedWorkspaces . findIndex (
613+ ( workspace ) => workspace . enabled !== false ,
614+ ) ;
615+ return firstEnabledWorkspaceIndex >= 0 ? firstEnabledWorkspaceIndex : 0 ;
616+ } ) ( )
617+ : existing . currentWorkspaceIndex ;
596618 accounts [ existingIndex ] = {
597619 ...existing ,
598620 accountId : nextAccountId ,
@@ -604,6 +626,7 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
604626 expiresAt : result . expires ,
605627 lastUsed : now ,
606628 workspaces : mergedWorkspaces ,
629+ currentWorkspaceIndex : nextCurrentWorkspaceIndex ,
607630 } ;
608631 }
609632
@@ -1940,56 +1963,63 @@ accountAttemptLoop: while (attempted.size < Math.max(1, accountCount)) {
19401963 runtimeMetrics . failedRequests ++ ;
19411964 runtimeMetrics . lastError = `Workspace disabled for account ${ account . index + 1 } ` ;
19421965
1943- const currentWorkspace = accountManager . getCurrentWorkspace ( account ) ;
1944- const workspaceName = currentWorkspace ?. name ?? currentWorkspace ?. id ?? "unknown" ;
1966+ if ( ! account . workspaces || account . workspaces . length === 0 ) {
1967+ logWarn (
1968+ `Workspace disabled/expired for account ${ account . index + 1 } without tracked workspaces. Leaving account enabled.` ,
1969+ { errorCode : workspaceErrorCode } ,
1970+ ) ;
1971+ } else {
1972+ const currentWorkspace = accountManager . getCurrentWorkspace ( account ) ;
1973+ const workspaceName = currentWorkspace ?. name ?? currentWorkspace ?. id ?? "unknown" ;
19451974
1946- logWarn (
1947- `Workspace disabled/expired for account ${ account . index + 1 } - workspace: ${ workspaceName } . Rotating to next workspace.` ,
1948- { errorCode : workspaceErrorCode } ,
1949- ) ;
1975+ logWarn (
1976+ `Workspace disabled/expired for account ${ account . index + 1 } - workspace: ${ workspaceName } . Rotating to next workspace.` ,
1977+ { errorCode : workspaceErrorCode } ,
1978+ ) ;
19501979
1951- const disabledWorkspace = currentWorkspace
1952- ? accountManager . disableCurrentWorkspace ( account , currentWorkspace . id )
1953- : false ;
1954- let nextWorkspace = disabledWorkspace
1955- ? accountManager . rotateToNextWorkspace ( account )
1956- : accountManager . getCurrentWorkspace ( account ) ;
1957- if ( ! disabledWorkspace && ( ! nextWorkspace || nextWorkspace . enabled === false ) ) {
1958- nextWorkspace = accountManager . rotateToNextWorkspace ( account ) ;
1959- }
1980+ const disabledWorkspace = currentWorkspace
1981+ ? accountManager . disableCurrentWorkspace ( account , currentWorkspace . id )
1982+ : false ;
1983+ let nextWorkspace = disabledWorkspace
1984+ ? accountManager . rotateToNextWorkspace ( account )
1985+ : accountManager . getCurrentWorkspace ( account ) ;
1986+ if ( ! disabledWorkspace && ( ! nextWorkspace || nextWorkspace . enabled === false ) ) {
1987+ nextWorkspace = accountManager . rotateToNextWorkspace ( account ) ;
1988+ }
19601989
1961- if ( nextWorkspace ) {
1990+ if ( nextWorkspace ) {
1991+ accountManager . saveToDiskDebounced ( ) ;
1992+
1993+ const newWorkspaceName = nextWorkspace . name ?? nextWorkspace . id ;
1994+ await showToast (
1995+ `Workspace ${ workspaceName } disabled. Switched to ${ newWorkspaceName } .` ,
1996+ "warning" ,
1997+ { duration : toastDurationMs } ,
1998+ ) ;
1999+
2000+ logInfo ( `Rotated to workspace ${ newWorkspaceName } for account ${ account . index + 1 } ` ) ;
2001+
2002+ // Allow the same account to be selected again with fresh request state.
2003+ attempted . delete ( account . index ) ;
2004+ continue accountAttemptLoop;
2005+ }
2006+
2007+ logWarn ( `All workspaces disabled for account ${ account . index + 1 } . Disabling account.` ) ;
2008+
2009+ accountManager . setAccountEnabled ( account . index , false ) ;
19622010 accountManager . saveToDiskDebounced ( ) ;
19632011
1964- const newWorkspaceName = nextWorkspace . name ?? nextWorkspace . id ;
19652012 await showToast (
1966- `Workspace ${ workspaceName } disabled. Switched to ${ newWorkspaceName } .` ,
2013+ `All workspaces disabled for account ${ account . index + 1 } . Switching to another account .` ,
19672014 "warning" ,
19682015 { duration : toastDurationMs } ,
19692016 ) ;
19702017
1971- logInfo ( `Rotated to workspace ${ newWorkspaceName } for account ${ account . index + 1 } ` ) ;
1972-
1973- // Allow the same account to be selected again with fresh request state.
1974- attempted . delete ( account . index ) ;
2018+ // Forget session affinity and continue the outer loop so another
2019+ // enabled account can service the request.
2020+ sessionAffinityStore ?. forgetSession ( sessionAffinityKey ) ;
19752021 continue accountAttemptLoop;
19762022 }
1977-
1978- logWarn ( `All workspaces disabled for account ${ account . index + 1 } . Disabling account.` ) ;
1979-
1980- accountManager . setAccountEnabled ( account . index , false ) ;
1981- accountManager . saveToDiskDebounced ( ) ;
1982-
1983- await showToast (
1984- `All workspaces disabled for account ${ account . index + 1 } . Switching to another account.` ,
1985- "warning" ,
1986- { duration : toastDurationMs } ,
1987- ) ;
1988-
1989- // Forget session affinity and continue the outer loop so another
1990- // enabled account can service the request.
1991- sessionAffinityStore ?. forgetSession ( sessionAffinityKey ) ;
1992- continue accountAttemptLoop;
19932023 }
19942024
19952025 if ( errorResponse . status === 403 && ! unsupportedModelInfo . isUnsupported && ! isDisabledWorkspaceError ) {
0 commit comments