oc-codex-multi-auth 6.11.4 → 6.12.0
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/README.md +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -9
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts/rotation.d.ts +4 -4
- package/dist/lib/accounts/rotation.d.ts.map +1 -1
- package/dist/lib/accounts/rotation.js +29 -11
- package/dist/lib/accounts/rotation.js.map +1 -1
- package/dist/lib/accounts.d.ts +2 -2
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +6 -6
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/config.d.ts +6 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +48 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/runtime.d.ts +2 -2
- package/dist/lib/runtime.d.ts.map +1 -1
- package/dist/lib/runtime.js.map +1 -1
- package/dist/lib/schemas.d.ts +4 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +1 -0
- package/dist/lib/schemas.js.map +1 -1
- package/dist/lib/tools/codex-pool.d.ts.map +1 -1
- package/dist/lib/tools/codex-pool.js +35 -10
- package/dist/lib/tools/codex-pool.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -307,6 +307,10 @@ reordering accounts does not silently change a model's routing.
|
|
|
307
307
|
"gpt-5.6-terra": [
|
|
308
308
|
"org-another-account-id"
|
|
309
309
|
]
|
|
310
|
+
},
|
|
311
|
+
"modelAccountPoolModes": {
|
|
312
|
+
"gpt-5.6-sol": "strict",
|
|
313
|
+
"gpt-5.6-terra": "preferred"
|
|
310
314
|
}
|
|
311
315
|
}
|
|
312
316
|
```
|
|
@@ -323,6 +327,7 @@ codex-pool
|
|
|
323
327
|
codex-pool action="set" model="gpt-5.6-sol" accounts=[7,8]
|
|
324
328
|
codex-pool action="add" model="gpt-5.6-sol" accounts=[9]
|
|
325
329
|
codex-pool action="remove" model="gpt-5.6-sol" accounts=[7]
|
|
330
|
+
codex-pool action="set-mode" model="gpt-5.6-sol" poolMode="strict"
|
|
326
331
|
codex-pool action="clear" model="gpt-5.6-sol"
|
|
327
332
|
```
|
|
328
333
|
|
|
@@ -334,11 +339,12 @@ the current project is reported but never automatically deleted.
|
|
|
334
339
|
|
|
335
340
|
Routing behavior:
|
|
336
341
|
|
|
337
|
-
- A mapped model uses
|
|
342
|
+
- A mapped model defaults to `preferred` mode and uses healthy, selectable accounts in its pool.
|
|
338
343
|
- Existing rotation strategy, quota, cooldown, and token-health rules still apply within the preferred pool.
|
|
339
|
-
-
|
|
344
|
+
- In `preferred` mode, an unavailable pool falls back to the healthy general account pool.
|
|
345
|
+
- In `strict` mode, routing never leaves the configured pool and immediately returns `strict_pool_unavailable` when no pooled account is selectable.
|
|
340
346
|
- An unmapped model or an empty account list uses the general account pool directly.
|
|
341
|
-
- `codex-status`, `codex-dashboard`, and routing diagnostics report
|
|
347
|
+
- `codex-status`, `codex-dashboard`, and routing diagnostics also report `strict` and `strict-unavailable` modes.
|
|
342
348
|
|
|
343
349
|
Account IDs are local account metadata but should still be treated as private
|
|
344
350
|
configuration. Do not publish a populated configuration file.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAwN/D;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MA8oH/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAoB,CAAC;AAElD,eAAe,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ import { queuedRefresh } from "./lib/refresh-queue.js";
|
|
|
32
32
|
import { openBrowserUrl } from "./lib/auth/browser.js";
|
|
33
33
|
import { startLocalOAuthServer } from "./lib/auth/server.js";
|
|
34
34
|
import { promptAddAnotherAccount, promptLoginMode } from "./lib/cli.js";
|
|
35
|
-
import { getCodexMode, getRequestTransformMode, getFastSession, getFastSessionStrategy, getFastSessionMaxInputItems, getRetryProfile, getRetryBudgetOverrides, getRateLimitToastDebounceMs, getRetryAllAccountsMaxRetries, getRetryAllAccountsMaxWaitMs, getRetryAllAccountsRateLimited, getFallbackToGpt52OnUnsupportedGpt53, getUnsupportedCodexPolicy, getUnsupportedCodexFallbackChain, getTokenRefreshSkewMs, getSessionRecovery, getAutoResume, getAutoUpdate, getToastDurationMs, getAccountToastsEnabled, getPerProjectAccounts, getEmptyResponseMaxRetries, getEmptyResponseRetryDelayMs, getPidOffsetEnabled, getRotationStrategy, getModelAccountPool, getFetchTimeoutMs, getStreamStallTimeoutMs, getCodexTuiV2, getCodexTuiColorProfile, getCodexTuiGlyphMode, getBeginnerSafeMode, getCodexTuiMaskEmail, loadPluginConfig, } from "./lib/config.js";
|
|
35
|
+
import { getCodexMode, getRequestTransformMode, getFastSession, getFastSessionStrategy, getFastSessionMaxInputItems, getRetryProfile, getRetryBudgetOverrides, getRateLimitToastDebounceMs, getRetryAllAccountsMaxRetries, getRetryAllAccountsMaxWaitMs, getRetryAllAccountsRateLimited, getFallbackToGpt52OnUnsupportedGpt53, getUnsupportedCodexPolicy, getUnsupportedCodexFallbackChain, getTokenRefreshSkewMs, getSessionRecovery, getAutoResume, getAutoUpdate, getToastDurationMs, getAccountToastsEnabled, getPerProjectAccounts, getEmptyResponseMaxRetries, getEmptyResponseRetryDelayMs, getPidOffsetEnabled, getRotationStrategy, getModelAccountPool, getModelAccountPoolMode, getFetchTimeoutMs, getStreamStallTimeoutMs, getCodexTuiV2, getCodexTuiColorProfile, getCodexTuiGlyphMode, getBeginnerSafeMode, getCodexTuiMaskEmail, loadPluginConfig, } from "./lib/config.js";
|
|
36
36
|
import { AUTH_LABELS, CODEX_BASE_URL, DUMMY_API_KEY, LOG_STAGES, PLUGIN_NAME, PROVIDER_ID, ACCOUNT_LIMITS, } from "./lib/constants.js";
|
|
37
37
|
import { initLogger, logRequest, logDebug, logInfo, logWarn, logError, setCorrelationId, clearCorrelationId, } from "./lib/logger.js";
|
|
38
38
|
import { checkAndNotify } from "./lib/auto-update-checker.js";
|
|
@@ -191,7 +191,10 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
191
191
|
lines.push(formatUiKeyValue(ui, "Fallback from", formatRoutingValue(routing.fallbackFrom), "muted"));
|
|
192
192
|
lines.push(formatUiKeyValue(ui, "Fallback to", formatRoutingValue(routing.fallbackTo), "muted"));
|
|
193
193
|
lines.push(formatUiKeyValue(ui, "Fallback reason", formatRoutingValue(routing.fallbackReason), routing.fallbackReason ? "warning" : "muted"));
|
|
194
|
-
lines.push(formatUiKeyValue(ui, "Account pool", formatRoutingValue(routing.accountPoolMode), routing.accountPoolMode === "general-fallback"
|
|
194
|
+
lines.push(formatUiKeyValue(ui, "Account pool", formatRoutingValue(routing.accountPoolMode), routing.accountPoolMode === "general-fallback" ||
|
|
195
|
+
routing.accountPoolMode === "strict-unavailable"
|
|
196
|
+
? "warning"
|
|
197
|
+
: "muted"));
|
|
195
198
|
lines.push(formatUiKeyValue(ui, "Configured pool size", String(routing.configuredAccountPoolSize), "muted"));
|
|
196
199
|
if (options.includeExplainability) {
|
|
197
200
|
lines.push("");
|
|
@@ -1434,6 +1437,8 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1434
1437
|
let restartAccountTraversalWithFallback = false;
|
|
1435
1438
|
let restartAccountTraversalAfterWorkspaceDeactivation = false;
|
|
1436
1439
|
const preferredAccountIds = getModelAccountPool(pluginConfig, model);
|
|
1440
|
+
const accountPoolMode = getModelAccountPoolMode(pluginConfig, model);
|
|
1441
|
+
const strictAccountPool = preferredAccountIds.length > 0 && accountPoolMode === "strict";
|
|
1437
1442
|
while (attempted.size < Math.max(1, accountCount)) {
|
|
1438
1443
|
const selectionExplainability = accountManager.getSelectionExplainability(modelFamily, model, Date.now());
|
|
1439
1444
|
runtimeMetrics.lastSelectionSnapshot = {
|
|
@@ -1450,8 +1455,9 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1450
1455
|
fallbackTo,
|
|
1451
1456
|
fallbackReason,
|
|
1452
1457
|
configuredAccountPoolSize: preferredAccountIds.length,
|
|
1458
|
+
accountPoolMode: strictAccountPool ? "strict" : undefined,
|
|
1453
1459
|
};
|
|
1454
|
-
const account = accountManager.getAccountForStrategy(rotationStrategy, modelFamily, model, { pidOffsetEnabled }, preferredAccountIds);
|
|
1460
|
+
const account = accountManager.getAccountForStrategy(rotationStrategy, modelFamily, model, { pidOffsetEnabled }, preferredAccountIds, accountPoolMode, attempted);
|
|
1455
1461
|
if (!account || attempted.has(account.index)) {
|
|
1456
1462
|
break;
|
|
1457
1463
|
}
|
|
@@ -1469,12 +1475,14 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1469
1475
|
fallbackFrom,
|
|
1470
1476
|
fallbackTo,
|
|
1471
1477
|
fallbackReason,
|
|
1472
|
-
accountPoolMode:
|
|
1473
|
-
? "
|
|
1474
|
-
:
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
+
accountPoolMode: strictAccountPool
|
|
1479
|
+
? "strict"
|
|
1480
|
+
: preferredAccountIds.length === 0
|
|
1481
|
+
? "general"
|
|
1482
|
+
: account.accountId !== undefined &&
|
|
1483
|
+
preferredAccountIds.includes(account.accountId)
|
|
1484
|
+
? "preferred"
|
|
1485
|
+
: "general-fallback",
|
|
1478
1486
|
configuredAccountPoolSize: preferredAccountIds.length,
|
|
1479
1487
|
};
|
|
1480
1488
|
}
|
|
@@ -2132,6 +2140,36 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2132
2140
|
if (restartAccountTraversalAfterWorkspaceDeactivation) {
|
|
2133
2141
|
continue;
|
|
2134
2142
|
}
|
|
2143
|
+
if (strictAccountPool) {
|
|
2144
|
+
const poolWaitMs = accountManager.getMinWaitTimeForFamily(modelFamily, model, preferredAccountIds);
|
|
2145
|
+
const effectiveModel = model ?? requestedModel ?? "requested model";
|
|
2146
|
+
const waitDetail = poolWaitMs > 0
|
|
2147
|
+
? ` Try again in ${formatWaitTime(poolWaitMs)}.`
|
|
2148
|
+
: " Check the pooled accounts with `codex-health`.";
|
|
2149
|
+
const message = `Strict account pool unavailable for ${effectiveModel}. ` +
|
|
2150
|
+
`None of its ${preferredAccountIds.length} configured account(s) is selectable.` +
|
|
2151
|
+
waitDetail;
|
|
2152
|
+
if (runtimeMetrics.lastSelectionSnapshot) {
|
|
2153
|
+
runtimeMetrics.lastSelectionSnapshot = {
|
|
2154
|
+
...runtimeMetrics.lastSelectionSnapshot,
|
|
2155
|
+
accountPoolMode: "strict-unavailable",
|
|
2156
|
+
};
|
|
2157
|
+
}
|
|
2158
|
+
runtimeMetrics.failedRequests++;
|
|
2159
|
+
runtimeMetrics.lastError = message;
|
|
2160
|
+
runtimeMetrics.lastErrorCategory = "strict-pool-unavailable";
|
|
2161
|
+
return new Response(JSON.stringify({
|
|
2162
|
+
error: {
|
|
2163
|
+
code: "strict_pool_unavailable",
|
|
2164
|
+
message,
|
|
2165
|
+
},
|
|
2166
|
+
}), {
|
|
2167
|
+
status: poolWaitMs > 0 ? 429 : 503,
|
|
2168
|
+
headers: {
|
|
2169
|
+
"content-type": "application/json; charset=utf-8",
|
|
2170
|
+
},
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2135
2173
|
const waitMs = accountManager.getMinWaitTimeForFamily(modelFamily, model);
|
|
2136
2174
|
const count = accountManager.getAccountCount();
|
|
2137
2175
|
if (retryAllAccountsRateLimited &&
|