codex-multi-auth 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -1
- package/README.md +16 -3
- package/assets/readme-hero.svg +31 -31
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -65
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +29 -10
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/codex-cli/sync.d.ts +9 -16
- package/dist/lib/codex-cli/sync.d.ts.map +1 -1
- package/dist/lib/codex-cli/sync.js +51 -284
- package/dist/lib/codex-cli/sync.js.map +1 -1
- package/dist/lib/codex-manager/settings-hub.d.ts +44 -2
- package/dist/lib/codex-manager/settings-hub.d.ts.map +1 -1
- package/dist/lib/codex-manager/settings-hub.js +746 -117
- package/dist/lib/codex-manager/settings-hub.js.map +1 -1
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +240 -216
- package/dist/lib/codex-manager.js.map +1 -1
- package/dist/lib/context-overflow.js +10 -10
- package/dist/lib/entitlement-cache.d.ts +8 -5
- package/dist/lib/entitlement-cache.d.ts.map +1 -1
- package/dist/lib/entitlement-cache.js +24 -9
- package/dist/lib/entitlement-cache.js.map +1 -1
- package/dist/lib/named-backup-export.d.ts +69 -0
- package/dist/lib/named-backup-export.d.ts.map +1 -0
- package/dist/lib/named-backup-export.js +207 -0
- package/dist/lib/named-backup-export.js.map +1 -0
- package/dist/lib/oc-chatgpt-import-adapter.d.ts +64 -0
- package/dist/lib/oc-chatgpt-import-adapter.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-import-adapter.js +522 -0
- package/dist/lib/oc-chatgpt-import-adapter.js.map +1 -0
- package/dist/lib/oc-chatgpt-orchestrator.d.ts +80 -0
- package/dist/lib/oc-chatgpt-orchestrator.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-orchestrator.js +130 -0
- package/dist/lib/oc-chatgpt-orchestrator.js.map +1 -0
- package/dist/lib/oc-chatgpt-target-detection.d.ts +59 -0
- package/dist/lib/oc-chatgpt-target-detection.d.ts.map +1 -0
- package/dist/lib/oc-chatgpt-target-detection.js +327 -0
- package/dist/lib/oc-chatgpt-target-detection.js.map +1 -0
- package/dist/lib/prompts/codex.js +2 -2
- package/dist/lib/runtime-paths.d.ts.map +1 -1
- package/dist/lib/runtime-paths.js +21 -1
- package/dist/lib/runtime-paths.js.map +1 -1
- package/dist/lib/storage.d.ts +67 -16
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +797 -169
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/ui/copy.d.ts +15 -1
- package/dist/lib/ui/copy.d.ts.map +1 -1
- package/dist/lib/ui/copy.js +15 -1
- package/dist/lib/ui/copy.js.map +1 -1
- package/package.json +130 -131
- package/scripts/bench-format/hashline-v2.mjs +642 -642
- package/scripts/bench-format/render.mjs +496 -496
- package/scripts/bench-format/stats.mjs +54 -54
- package/scripts/bench-format/tasks.mjs +151 -151
- package/scripts/benchmark-render-dashboard.mjs +49 -49
- package/scripts/install-codex-auth.js +9 -9
- package/scripts/test-all-models.sh +7 -7
- package/scripts/test-model-matrix.js +138 -46
- package/scripts/validate-model-map.sh +7 -7
package/LICENSE
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ndycode
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Codex CLI-first multi-account OAuth manager for the official `@openai/codex` CLI
|
|
|
17
17
|
- Multi-account OAuth pool with health-aware selection and automatic failover
|
|
18
18
|
- Project-scoped account storage under `~/.codex/multi-auth/projects/<project-key>/...`
|
|
19
19
|
- Interactive dashboard for account actions and settings
|
|
20
|
+
- Experimental settings tab for staged sync, backup, and refresh-guard controls
|
|
20
21
|
- Forecast, report, fix, and doctor commands for operational safety
|
|
21
22
|
- Flagged account verification and restore flow
|
|
22
23
|
- Session affinity and live account sync controls
|
|
@@ -199,6 +200,18 @@ codex auth forecast --live
|
|
|
199
200
|
|
|
200
201
|
---
|
|
201
202
|
|
|
203
|
+
## Experimental Settings Highlights
|
|
204
|
+
|
|
205
|
+
The Settings menu now includes an `Experimental` section for staged features:
|
|
206
|
+
|
|
207
|
+
- preview-first sync into `oc-chatgpt-multi-auth`
|
|
208
|
+
- named local pool backup export with filename prompt
|
|
209
|
+
- refresh guard toggle and interval controls moved out of Backend Controls
|
|
210
|
+
|
|
211
|
+
These flows are intentionally non-destructive by default: sync previews before apply, destination-only accounts are preserved, and backup filename collisions fail safely.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
202
215
|
## Troubleshooting
|
|
203
216
|
|
|
204
217
|
<details open>
|
|
@@ -265,9 +278,9 @@ codex auth doctor --json
|
|
|
265
278
|
|
|
266
279
|
## Release Notes
|
|
267
280
|
|
|
268
|
-
- Current stable: [docs/releases/v0.1.
|
|
269
|
-
- Previous stable: [docs/releases/v0.1.
|
|
270
|
-
- Earlier stable: [docs/releases/v0.1.
|
|
281
|
+
- Current stable: [docs/releases/v0.1.9.md](docs/releases/v0.1.9.md)
|
|
282
|
+
- Previous stable: [docs/releases/v0.1.8.md](docs/releases/v0.1.8.md)
|
|
283
|
+
- Earlier stable: [docs/releases/v0.1.7.md](docs/releases/v0.1.7.md)
|
|
271
284
|
- Archived prerelease: [docs/releases/v0.1.0-beta.0.md](docs/releases/v0.1.0-beta.0.md)
|
|
272
285
|
|
|
273
286
|
## License
|
package/assets/readme-hero.svg
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="300" viewBox="0 0 1200 300" role="img" aria-label="Codex Multi-Auth OAuth">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
-
<stop offset="0%" stop-color="#0f172a" />
|
|
5
|
-
<stop offset="100%" stop-color="#1f2937" />
|
|
6
|
-
</linearGradient>
|
|
7
|
-
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
|
|
8
|
-
<stop offset="0%" stop-color="#38bdf8" />
|
|
9
|
-
<stop offset="100%" stop-color="#22d3ee" />
|
|
10
|
-
</linearGradient>
|
|
11
|
-
</defs>
|
|
12
|
-
<rect width="1200" height="300" rx="28" fill="url(#bg)" />
|
|
13
|
-
<g opacity="0.12">
|
|
14
|
-
<circle cx="1020" cy="70" r="120" fill="#38bdf8" />
|
|
15
|
-
<circle cx="150" cy="260" r="140" fill="#22d3ee" />
|
|
16
|
-
</g>
|
|
17
|
-
<g fill="none" stroke="url(#accent)" stroke-width="8" stroke-linecap="round" stroke-linejoin="round">
|
|
18
|
-
<path d="M160 95 L100 150 L160 205" />
|
|
19
|
-
<path d="M280 95 L340 150 L280 205" />
|
|
20
|
-
<path d="M205 80 L235 220" />
|
|
21
|
-
</g>
|
|
22
|
-
<text x="420" y="120" fill="#e2e8f0" font-size="42" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif" font-weight="600">
|
|
23
|
-
Codex Multi-Auth OAuth
|
|
24
|
-
</text>
|
|
25
|
-
<text x="420" y="170" fill="#cbd5f5" font-size="24" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif">
|
|
26
|
-
ChatGPT Plus/Pro auth for GPT-5.2 and Codex models
|
|
27
|
-
</text>
|
|
28
|
-
<text x="420" y="220" fill="#7dd3fc" font-size="18" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif">
|
|
29
|
-
One-command install, modern variants, full tool support
|
|
30
|
-
</text>
|
|
31
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="300" viewBox="0 0 1200 300" role="img" aria-label="Codex Multi-Auth OAuth">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0%" stop-color="#0f172a" />
|
|
5
|
+
<stop offset="100%" stop-color="#1f2937" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
|
|
8
|
+
<stop offset="0%" stop-color="#38bdf8" />
|
|
9
|
+
<stop offset="100%" stop-color="#22d3ee" />
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
<rect width="1200" height="300" rx="28" fill="url(#bg)" />
|
|
13
|
+
<g opacity="0.12">
|
|
14
|
+
<circle cx="1020" cy="70" r="120" fill="#38bdf8" />
|
|
15
|
+
<circle cx="150" cy="260" r="140" fill="#22d3ee" />
|
|
16
|
+
</g>
|
|
17
|
+
<g fill="none" stroke="url(#accent)" stroke-width="8" stroke-linecap="round" stroke-linejoin="round">
|
|
18
|
+
<path d="M160 95 L100 150 L160 205" />
|
|
19
|
+
<path d="M280 95 L340 150 L280 205" />
|
|
20
|
+
<path d="M205 80 L235 220" />
|
|
21
|
+
</g>
|
|
22
|
+
<text x="420" y="120" fill="#e2e8f0" font-size="42" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif" font-weight="600">
|
|
23
|
+
Codex Multi-Auth OAuth
|
|
24
|
+
</text>
|
|
25
|
+
<text x="420" y="170" fill="#cbd5f5" font-size="24" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif">
|
|
26
|
+
ChatGPT Plus/Pro auth for GPT-5.2 and Codex models
|
|
27
|
+
</text>
|
|
28
|
+
<text x="420" y="220" fill="#7dd3fc" font-size="18" font-family="'IBM Plex Sans','Segoe UI',Arial,sans-serif">
|
|
29
|
+
One-command install, modern variants, full tool support
|
|
30
|
+
</text>
|
|
31
|
+
</svg>
|
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* For production applications, use the OpenAI Platform API: https://platform.openai.com/
|
|
19
19
|
*
|
|
20
20
|
* @license MIT with Usage Disclaimer (see LICENSE file)
|
|
21
|
-
* @author
|
|
21
|
+
* @author ndycode
|
|
22
22
|
* @repository https://github.com/ndycode/codex-multi-auth
|
|
23
23
|
|
|
24
24
|
*/
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,kBAAkB,CAAC;AAmL5D;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,kBAAkB,CAAC;AAmL5D;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MA60H/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,KAAoB,CAAC;AAElD,eAAe,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* For production applications, use the OpenAI Platform API: https://platform.openai.com/
|
|
19
19
|
*
|
|
20
20
|
* @license MIT with Usage Disclaimer (see LICENSE file)
|
|
21
|
-
* @author
|
|
21
|
+
* @author ndycode
|
|
22
22
|
* @repository https://github.com/ndycode/codex-multi-auth
|
|
23
23
|
|
|
24
24
|
*/
|
|
@@ -34,7 +34,7 @@ import { initLogger, logRequest, logDebug, logInfo, logWarn, logError, setCorrel
|
|
|
34
34
|
import { checkAndNotify } from "./lib/auto-update-checker.js";
|
|
35
35
|
import { handleContextOverflow } from "./lib/context-overflow.js";
|
|
36
36
|
import { AccountManager, getAccountIdCandidates, extractAccountEmail, extractAccountId, formatAccountLabel, formatCooldown, formatWaitTime, sanitizeEmail, selectBestAccountCandidate, shouldUpdateAccountIdFromToken, resolveRequestAccountId, parseRateLimitReason, lookupCodexCliTokensByEmail, isCodexCliSyncEnabled, } from "./lib/accounts.js";
|
|
37
|
-
import { getStoragePath, loadAccounts, saveAccounts, withAccountStorageTransaction, clearAccounts, setStoragePath, exportAccounts, importAccounts, loadFlaggedAccounts, saveFlaggedAccounts, clearFlaggedAccounts,
|
|
37
|
+
import { getStoragePath, loadAccounts, saveAccounts, withAccountStorageTransaction, clearAccounts, setStoragePath, exportAccounts, importAccounts, loadFlaggedAccounts, saveFlaggedAccounts, clearFlaggedAccounts, findMatchingAccountIndex, StorageError, formatStorageErrorHint, setStorageBackupEnabled, } from "./lib/storage.js";
|
|
38
38
|
import { createCodexHeaders, extractRequestUrl, handleErrorResponse, handleSuccessResponse, getUnsupportedCodexModelInfo, resolveUnsupportedCodexFallbackModel, refreshAndUpdateToken, rewriteUrlForCodex, shouldRefreshToken, transformRequestForCodex, } from "./lib/request/fetch-helpers.js";
|
|
39
39
|
import { applyFastSessionDefaults } from "./lib/request/request-transformer.js";
|
|
40
40
|
import { getRateLimitBackoff, RATE_LIMIT_SHORT_RETRY_THRESHOLD_MS, resetRateLimitBackoff, } from "./lib/request/rate-limit-backoff.js";
|
|
@@ -315,24 +315,6 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
315
315
|
const now = Date.now();
|
|
316
316
|
const stored = replaceAll ? null : loadedStorage;
|
|
317
317
|
const accounts = stored?.accounts ? [...stored.accounts] : [];
|
|
318
|
-
const indexByRefreshToken = new Map();
|
|
319
|
-
const indexByAccountId = new Map();
|
|
320
|
-
const indexByEmail = new Map();
|
|
321
|
-
for (let i = 0; i < accounts.length; i += 1) {
|
|
322
|
-
const account = accounts[i];
|
|
323
|
-
if (!account)
|
|
324
|
-
continue;
|
|
325
|
-
if (account.refreshToken) {
|
|
326
|
-
indexByRefreshToken.set(account.refreshToken, i);
|
|
327
|
-
}
|
|
328
|
-
if (account.accountId) {
|
|
329
|
-
indexByAccountId.set(account.accountId, i);
|
|
330
|
-
}
|
|
331
|
-
const emailKey = normalizeEmailKey(account.email);
|
|
332
|
-
if (emailKey) {
|
|
333
|
-
indexByEmail.set(emailKey, i);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
318
|
for (const result of results) {
|
|
337
319
|
const accountId = result.accountIdOverride ?? extractAccountId(result.access);
|
|
338
320
|
const accountIdSource = accountId
|
|
@@ -341,16 +323,14 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
341
323
|
: undefined;
|
|
342
324
|
const accountLabel = result.accountLabel;
|
|
343
325
|
const accountEmail = sanitizeEmail(extractAccountEmail(result.access, result.idToken));
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
:
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
:
|
|
350
|
-
|
|
351
|
-
const existingIndex = existingById ?? existingByEmail ?? existingByToken;
|
|
326
|
+
const existingIndex = findMatchingAccountIndex(accounts, {
|
|
327
|
+
accountId,
|
|
328
|
+
email: accountEmail,
|
|
329
|
+
refreshToken: result.refresh,
|
|
330
|
+
}, {
|
|
331
|
+
allowUniqueAccountIdFallbackWithoutEmail: true,
|
|
332
|
+
});
|
|
352
333
|
if (existingIndex === undefined) {
|
|
353
|
-
const newIndex = accounts.length;
|
|
354
334
|
accounts.push({
|
|
355
335
|
accountId,
|
|
356
336
|
accountIdSource,
|
|
@@ -362,20 +342,11 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
362
342
|
addedAt: now,
|
|
363
343
|
lastUsed: now,
|
|
364
344
|
});
|
|
365
|
-
indexByRefreshToken.set(result.refresh, newIndex);
|
|
366
|
-
if (accountId) {
|
|
367
|
-
indexByAccountId.set(accountId, newIndex);
|
|
368
|
-
}
|
|
369
|
-
if (accountEmail) {
|
|
370
|
-
indexByEmail.set(accountEmail, newIndex);
|
|
371
|
-
}
|
|
372
345
|
continue;
|
|
373
346
|
}
|
|
374
347
|
const existing = accounts[existingIndex];
|
|
375
348
|
if (!existing)
|
|
376
349
|
continue;
|
|
377
|
-
const oldToken = existing.refreshToken;
|
|
378
|
-
const oldEmail = existing.email;
|
|
379
350
|
const nextEmail = accountEmail ?? sanitizeEmail(existing.email);
|
|
380
351
|
const nextAccountId = accountId ?? existing.accountId;
|
|
381
352
|
const nextAccountIdSource = accountId ? accountIdSource ?? existing.accountIdSource : existing.accountIdSource;
|
|
@@ -391,21 +362,6 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
391
362
|
expiresAt: result.expires,
|
|
392
363
|
lastUsed: now,
|
|
393
364
|
};
|
|
394
|
-
if (oldToken !== result.refresh) {
|
|
395
|
-
indexByRefreshToken.delete(oldToken);
|
|
396
|
-
indexByRefreshToken.set(result.refresh, existingIndex);
|
|
397
|
-
}
|
|
398
|
-
if (accountId) {
|
|
399
|
-
indexByAccountId.set(accountId, existingIndex);
|
|
400
|
-
}
|
|
401
|
-
const oldEmailKey = normalizeEmailKey(oldEmail);
|
|
402
|
-
const nextEmailKey = normalizeEmailKey(nextEmail);
|
|
403
|
-
if (oldEmailKey && oldEmailKey !== nextEmailKey) {
|
|
404
|
-
indexByEmail.delete(oldEmailKey);
|
|
405
|
-
}
|
|
406
|
-
if (nextEmailKey) {
|
|
407
|
-
indexByEmail.set(nextEmailKey, existingIndex);
|
|
408
|
-
}
|
|
409
365
|
}
|
|
410
366
|
if (accounts.length === 0)
|
|
411
367
|
return;
|
|
@@ -1023,6 +979,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1023
979
|
const accountCount = accountManager.getAccountCount();
|
|
1024
980
|
const attempted = new Set();
|
|
1025
981
|
let restartAccountTraversalWithFallback = false;
|
|
982
|
+
let retryNextAccountBeforeFallback = false;
|
|
1026
983
|
let usedPreferredSessionAccount = false;
|
|
1027
984
|
const capabilityBoostByAccount = {};
|
|
1028
985
|
const accountSnapshotSource = accountManager;
|
|
@@ -1111,22 +1068,23 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1111
1068
|
const hadAccountId = !!account.accountId;
|
|
1112
1069
|
const tokenAccountId = extractAccountId(accountAuth.access);
|
|
1113
1070
|
const accountId = resolveRequestAccountId(account.accountId, account.accountIdSource, tokenAccountId);
|
|
1114
|
-
const entitlementAccountKey = resolveEntitlementAccountKey({
|
|
1115
|
-
accountId: hadAccountId ? account.accountId : undefined,
|
|
1116
|
-
email: account.email,
|
|
1117
|
-
index: account.index,
|
|
1118
|
-
});
|
|
1119
1071
|
if (!accountId) {
|
|
1120
1072
|
accountManager.markAccountCoolingDown(account, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
1121
1073
|
accountManager.saveToDiskDebounced();
|
|
1122
1074
|
continue;
|
|
1123
1075
|
}
|
|
1076
|
+
const resolvedEmail = extractAccountEmail(accountAuth.access) ?? account.email;
|
|
1077
|
+
const entitlementAccountKey = resolveEntitlementAccountKey({
|
|
1078
|
+
accountId: account.accountId ?? accountId,
|
|
1079
|
+
email: resolvedEmail,
|
|
1080
|
+
refreshToken: account.refreshToken,
|
|
1081
|
+
index: account.index,
|
|
1082
|
+
});
|
|
1124
1083
|
account.accountId = accountId;
|
|
1125
1084
|
if (!hadAccountId && tokenAccountId && accountId === tokenAccountId) {
|
|
1126
1085
|
account.accountIdSource = account.accountIdSource ?? "token";
|
|
1127
1086
|
}
|
|
1128
|
-
account.email =
|
|
1129
|
-
extractAccountEmail(accountAuth.access) ?? account.email;
|
|
1087
|
+
account.email = resolvedEmail;
|
|
1130
1088
|
const entitlementBlock = entitlementCache.isBlocked(entitlementAccountKey, model ?? modelFamily);
|
|
1131
1089
|
if (entitlementBlock.blocked) {
|
|
1132
1090
|
runtimeMetrics.accountRotations++;
|
|
@@ -1299,6 +1257,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1299
1257
|
fallbackApplied: false,
|
|
1300
1258
|
fallbackReason: "unsupported-model-entitlement",
|
|
1301
1259
|
});
|
|
1260
|
+
retryNextAccountBeforeFallback = true;
|
|
1302
1261
|
break;
|
|
1303
1262
|
}
|
|
1304
1263
|
const fallbackModel = resolveUnsupportedCodexFallbackModel({
|
|
@@ -1626,7 +1585,9 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1626
1585
|
if (successAccountForResponse.index !== account.index) {
|
|
1627
1586
|
accountManager.markSwitched(successAccountForResponse, "rotation", modelFamily);
|
|
1628
1587
|
}
|
|
1629
|
-
const successAccountKey =
|
|
1588
|
+
const successAccountKey = successAccountForResponse.index === account.index
|
|
1589
|
+
? entitlementAccountKey
|
|
1590
|
+
: resolveEntitlementAccountKey(successAccountForResponse);
|
|
1630
1591
|
accountManager.recordSuccess(successAccountForResponse, modelFamily, model);
|
|
1631
1592
|
capabilityPolicyStore.recordSuccess(successAccountKey, capabilityModelKey);
|
|
1632
1593
|
entitlementCache.clear(successAccountKey, capabilityModelKey);
|
|
@@ -1639,6 +1600,10 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1639
1600
|
}
|
|
1640
1601
|
return successResponse;
|
|
1641
1602
|
}
|
|
1603
|
+
if (retryNextAccountBeforeFallback) {
|
|
1604
|
+
retryNextAccountBeforeFallback = false;
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
1642
1607
|
if (restartAccountTraversalWithFallback) {
|
|
1643
1608
|
break;
|
|
1644
1609
|
}
|
|
@@ -2331,7 +2296,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2331
2296
|
await clearAccounts();
|
|
2332
2297
|
await clearFlaggedAccounts();
|
|
2333
2298
|
invalidateAccountManagerCache();
|
|
2334
|
-
console.log("\
|
|
2299
|
+
console.log("\nCleared saved accounts from active storage. Recovery snapshots remain available. Starting fresh.\n");
|
|
2335
2300
|
}
|
|
2336
2301
|
break;
|
|
2337
2302
|
}
|
|
@@ -2398,9 +2363,17 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2398
2363
|
const accountId = resolved.accountIdOverride ?? extractAccountId(resolved.access);
|
|
2399
2364
|
const label = resolved.accountLabel ?? email ?? accountId ?? "Unknown account";
|
|
2400
2365
|
logInfo(`Authenticated as: ${label}`);
|
|
2401
|
-
const isDuplicate = accounts.
|
|
2402
|
-
|
|
2403
|
-
|
|
2366
|
+
const isDuplicate = findMatchingAccountIndex(accounts.map((account) => ({
|
|
2367
|
+
accountId: account.accountIdOverride ?? extractAccountId(account.access),
|
|
2368
|
+
email: sanitizeEmail(extractAccountEmail(account.access, account.idToken)),
|
|
2369
|
+
refreshToken: account.refresh,
|
|
2370
|
+
})), {
|
|
2371
|
+
accountId,
|
|
2372
|
+
email: sanitizeEmail(email),
|
|
2373
|
+
refreshToken: resolved.refresh,
|
|
2374
|
+
}, {
|
|
2375
|
+
allowUniqueAccountIdFallbackWithoutEmail: true,
|
|
2376
|
+
}) !== undefined;
|
|
2404
2377
|
if (isDuplicate) {
|
|
2405
2378
|
logWarn(`WARNING: duplicate account login detected (${label}). Existing entry will be updated.`);
|
|
2406
2379
|
}
|