@@ -193,6 +193,10 @@ import {
193193 clampActiveIndices ,
194194 isFlaggableFailure ,
195195} from "./lib/runtime/account-check-helpers.js" ;
196+ import {
197+ invalidateAccountManagerCacheState ,
198+ reloadAccountManagerFromDiskState ,
199+ } from "./lib/runtime/account-manager-cache.js" ;
196200import {
197201 type TokenSuccessWithAccount as AccountPoolTokenSuccessWithAccount ,
198202 persistAccountPoolResults ,
@@ -204,7 +208,12 @@ import {
204208 resolveActiveIndex ,
205209} from "./lib/runtime/account-status.js" ;
206210import { runBrowserOAuthFlow } from "./lib/runtime/browser-oauth-flow.js" ;
211+ import { handleRuntimeEvent } from "./lib/runtime/event-handler.js" ;
207212import { buildManualOAuthFlow } from "./lib/runtime/manual-oauth-flow.js" ;
213+ import {
214+ applyPreemptiveQuotaSettingsFromConfig ,
215+ resolveUiRuntimeFromConfig ,
216+ } from "./lib/runtime/quota-settings.js" ;
208217import {
209218 ensureLiveAccountSyncState ,
210219 ensureRefreshGuardianState ,
@@ -500,31 +509,33 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
500509 } ;
501510
502511 const resolveUiRuntime = ( ) : UiRuntimeOptions => {
503- return applyUiRuntimeFromConfig ( loadPluginConfig ( ) , setUiRuntimeOptions ) ;
512+ return resolveUiRuntimeFromConfig ( loadPluginConfig , ( pluginConfig ) =>
513+ applyUiRuntimeFromConfig ( pluginConfig , setUiRuntimeOptions ) ,
514+ ) ;
504515 } ;
505516
506517 const invalidateAccountManagerCache = ( ) : void => {
507- cachedAccountManager = null ;
508- accountManagerPromise = null ;
518+ const next = invalidateAccountManagerCacheState ( ) ;
519+ cachedAccountManager = next . cachedAccountManager ;
520+ accountManagerPromise = next . accountManagerPromise ;
509521 } ;
510522
511523 const reloadAccountManagerFromDisk = async (
512524 authFallback ?: OAuthAuthDetails ,
513525 ) : Promise < AccountManager > => {
514- if ( accountReloadInFlight ) {
515- return accountReloadInFlight ;
516- }
517- accountReloadInFlight = ( async ( ) => {
518- const reloaded = await AccountManager . loadFromDisk ( authFallback ) ;
519- cachedAccountManager = reloaded ;
520- accountManagerPromise = Promise . resolve ( reloaded ) ;
521- return reloaded ;
522- } ) ( ) ;
523- try {
524- return await accountReloadInFlight ;
525- } finally {
526- accountReloadInFlight = null ;
527- }
526+ accountReloadInFlight = reloadAccountManagerFromDiskState ( {
527+ currentReloadInFlight : accountReloadInFlight ,
528+ loadFromDisk : ( fallback ) => AccountManager . loadFromDisk ( fallback ) ,
529+ authFallback,
530+ onLoaded : ( reloaded ) => {
531+ cachedAccountManager = reloaded ;
532+ accountManagerPromise = Promise . resolve ( reloaded ) ;
533+ } ,
534+ onSettled : ( ) => {
535+ accountReloadInFlight = null ;
536+ } ,
537+ } ) ;
538+ return accountReloadInFlight ;
528539 } ;
529540
530541 const applyAccountStorageScope = (
@@ -611,85 +622,38 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
611622
612623 const applyPreemptiveQuotaSettings = (
613624 pluginConfig : ReturnType < typeof loadPluginConfig > ,
614- ) : void => {
615- preemptiveQuotaScheduler . configure ( {
616- enabled : getPreemptiveQuotaEnabled ( pluginConfig ) ,
617- remainingPercentThresholdPrimary :
618- getPreemptiveQuotaRemainingPercent5h ( pluginConfig ) ,
619- remainingPercentThresholdSecondary :
620- getPreemptiveQuotaRemainingPercent7d ( pluginConfig ) ,
621- maxDeferralMs : getPreemptiveQuotaMaxDeferralMs ( pluginConfig ) ,
625+ ) : void =>
626+ applyPreemptiveQuotaSettingsFromConfig ( pluginConfig , {
627+ configure : ( options ) => preemptiveQuotaScheduler . configure ( options ) ,
628+ getPreemptiveQuotaEnabled,
629+ getPreemptiveQuotaRemainingPercent5h,
630+ getPreemptiveQuotaRemainingPercent7d,
631+ getPreemptiveQuotaMaxDeferralMs,
622632 } ) ;
623- } ;
624633
625634 // Event handler for session recovery and account selection
626635 const eventHandler = async ( input : {
627636 event : { type : string ; properties ?: unknown } ;
628- } ) => {
629- try {
630- const { event } = input ;
631- // Handle TUI account selection events
632- // Accepts generic selection events with an index property
633- if (
634- event . type === "account.select" ||
635- event . type === "openai.account.select"
636- ) {
637- const props = event . properties as {
638- index ?: number ;
639- accountIndex ?: number ;
640- provider ?: string ;
641- } ;
642- // Filter by provider if specified
643- if (
644- props . provider &&
645- props . provider !== "openai" &&
646- props . provider !== PROVIDER_ID
647- ) {
648- return ;
649- }
650-
651- const index = props . index ?? props . accountIndex ;
652- if ( typeof index === "number" ) {
653- const storage = await loadAccounts ( ) ;
654- if ( ! storage || index < 0 || index >= storage . accounts . length ) {
655- return ;
656- }
657-
658- const now = Date . now ( ) ;
659- const account = storage . accounts [ index ] ;
660- if ( account ) {
661- account . lastUsed = now ;
662- account . lastSwitchReason = "rotation" ;
663- }
664- storage . activeIndex = index ;
665- storage . activeIndexByFamily = storage . activeIndexByFamily ?? { } ;
666- for ( const family of MODEL_FAMILIES ) {
667- storage . activeIndexByFamily [ family ] = index ;
668- }
669-
670- await saveAccounts ( storage ) ;
671- if ( cachedAccountManager ) {
672- await cachedAccountManager . syncCodexCliActiveSelectionForIndex (
673- index ,
674- ) ;
675- }
676- lastCodexCliActiveSyncIndex = index ;
677-
678- // Reload manager from disk so we don't overwrite newer rotated
679- // refresh tokens with stale in-memory state.
680- if ( cachedAccountManager ) {
681- await reloadAccountManagerFromDisk ( ) ;
682- }
683-
684- await showToast ( `Switched to account ${ index + 1 } ` , "info" ) ;
685- }
686- }
687- } catch ( error ) {
688- logDebug (
689- `[${ PLUGIN_NAME } ] Event handler error: ${ error instanceof Error ? error . message : String ( error ) } ` ,
690- ) ;
691- }
692- } ;
637+ } ) =>
638+ handleRuntimeEvent ( {
639+ input,
640+ providerId : PROVIDER_ID ,
641+ modelFamilies : MODEL_FAMILIES ,
642+ loadAccounts,
643+ saveAccounts,
644+ hasCachedAccountManager : ( ) => ! ! cachedAccountManager ,
645+ syncCodexCliActiveSelectionForIndex : async ( index ) => {
646+ if ( ! cachedAccountManager ) return ;
647+ await cachedAccountManager . syncCodexCliActiveSelectionForIndex ( index ) ;
648+ } ,
649+ setLastCodexCliActiveSyncIndex : ( index ) => {
650+ lastCodexCliActiveSyncIndex = index ;
651+ } ,
652+ reloadAccountManagerFromDisk : ( ) => reloadAccountManagerFromDisk ( ) ,
653+ showToast : ( message , variant ) => showToast ( message , variant ) ,
654+ logDebug,
655+ pluginName : PLUGIN_NAME ,
656+ } ) ;
693657
694658 // Initialize runtime UI settings once on plugin load; auth/tools refresh this dynamically.
695659 resolveUiRuntime ( ) ;
0 commit comments