Skip to content

Commit 9130fbf

Browse files
committed
refactor: extract account select event handler
1 parent bd0f091 commit 9130fbf

2 files changed

Lines changed: 89 additions & 56 deletions

File tree

index.ts

Lines changed: 16 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ import { withStreamingFailover } from "./lib/request/stream-failover.js";
162162
import { addJitter } from "./lib/rotation.js";
163163
import { persistAccountPool } from "./lib/runtime/account-pool.js";
164164
import { applyAccountStorageScope } from "./lib/runtime/account-scope.js";
165+
import { handleAccountSelectEvent } from "./lib/runtime/account-select-event.js";
165166
import {
166167
resolveAccountSelection,
167168
type TokenSuccessWithAccount,
@@ -538,63 +539,22 @@ export const OpenAIOAuthPlugin: Plugin = async ({ client }: PluginInput) => {
538539
event: { type: string; properties?: unknown };
539540
}) => {
540541
try {
541-
const { event } = input;
542-
// Handle TUI account selection events
543-
// Accepts generic selection events with an index property
544-
if (
545-
event.type === "account.select" ||
546-
event.type === "openai.account.select"
547-
) {
548-
const props = event.properties as {
549-
index?: number;
550-
accountIndex?: number;
551-
provider?: string;
552-
};
553-
// Filter by provider if specified
554-
if (
555-
props.provider &&
556-
props.provider !== "openai" &&
557-
props.provider !== PROVIDER_ID
558-
) {
559-
return;
560-
}
561-
562-
const index = props.index ?? props.accountIndex;
563-
if (typeof index === "number") {
564-
const storage = await loadAccounts();
565-
if (!storage || index < 0 || index >= storage.accounts.length) {
566-
return;
567-
}
568-
569-
const now = Date.now();
570-
const account = storage.accounts[index];
571-
if (account) {
572-
account.lastUsed = now;
573-
account.lastSwitchReason = "rotation";
574-
}
575-
storage.activeIndex = index;
576-
storage.activeIndexByFamily = storage.activeIndexByFamily ?? {};
577-
for (const family of MODEL_FAMILIES) {
578-
storage.activeIndexByFamily[family] = index;
579-
}
580-
581-
await saveAccounts(storage);
582-
if (cachedAccountManager) {
583-
await cachedAccountManager.syncCodexCliActiveSelectionForIndex(
584-
index,
585-
);
586-
}
542+
const handled = await handleAccountSelectEvent({
543+
event: input.event,
544+
providerId: PROVIDER_ID,
545+
loadAccounts,
546+
saveAccounts,
547+
modelFamilies: MODEL_FAMILIES,
548+
cachedAccountManager,
549+
reloadAccountManagerFromDisk: async () => {
550+
await reloadAccountManagerFromDisk();
551+
},
552+
setLastCodexCliActiveSyncIndex: (index) => {
587553
lastCodexCliActiveSyncIndex = index;
588-
589-
// Reload manager from disk so we don't overwrite newer rotated
590-
// refresh tokens with stale in-memory state.
591-
if (cachedAccountManager) {
592-
await reloadAccountManagerFromDisk();
593-
}
594-
595-
await showToast(`Switched to account ${index + 1}`, "info");
596-
}
597-
}
554+
},
555+
showToast,
556+
});
557+
if (handled) return;
598558
} catch (error) {
599559
logDebug(
600560
`[${PLUGIN_NAME}] Event handler error: ${error instanceof Error ? error.message : String(error)}`,
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type { ModelFamily } from "../prompts/codex.js";
2+
import type { AccountStorageV3 } from "../storage.js";
3+
4+
export async function handleAccountSelectEvent(input: {
5+
event: { type: string; properties?: unknown };
6+
providerId: string;
7+
loadAccounts: () => Promise<AccountStorageV3 | null>;
8+
saveAccounts: (storage: AccountStorageV3) => Promise<void>;
9+
modelFamilies: readonly ModelFamily[];
10+
cachedAccountManager: {
11+
syncCodexCliActiveSelectionForIndex(index: number): Promise<void>;
12+
} | null;
13+
reloadAccountManagerFromDisk: () => Promise<unknown>;
14+
setLastCodexCliActiveSyncIndex: (index: number) => void;
15+
showToast: (
16+
message: string,
17+
variant?: "info" | "success" | "warning" | "error",
18+
) => Promise<void>;
19+
}): Promise<boolean> {
20+
const { event } = input;
21+
if (
22+
event.type !== "account.select" &&
23+
event.type !== "openai.account.select"
24+
) {
25+
return false;
26+
}
27+
28+
const props = event.properties as {
29+
index?: number;
30+
accountIndex?: number;
31+
provider?: string;
32+
};
33+
if (
34+
props.provider &&
35+
props.provider !== "openai" &&
36+
props.provider !== input.providerId
37+
) {
38+
return true;
39+
}
40+
41+
const index = props.index ?? props.accountIndex;
42+
if (typeof index !== "number") return true;
43+
44+
const storage = await input.loadAccounts();
45+
if (!storage || index < 0 || index >= storage.accounts.length) {
46+
return true;
47+
}
48+
49+
const now = Date.now();
50+
const account = storage.accounts[index];
51+
if (account) {
52+
account.lastUsed = now;
53+
account.lastSwitchReason = "rotation";
54+
}
55+
storage.activeIndex = index;
56+
storage.activeIndexByFamily = storage.activeIndexByFamily ?? {};
57+
for (const family of input.modelFamilies) {
58+
storage.activeIndexByFamily[family] = index;
59+
}
60+
61+
await input.saveAccounts(storage);
62+
if (input.cachedAccountManager) {
63+
await input.cachedAccountManager.syncCodexCliActiveSelectionForIndex(index);
64+
}
65+
input.setLastCodexCliActiveSyncIndex(index);
66+
67+
if (input.cachedAccountManager) {
68+
await input.reloadAccountManagerFromDisk();
69+
}
70+
71+
await input.showToast(`Switched to account ${index + 1}`, "info");
72+
return true;
73+
}

0 commit comments

Comments
 (0)