oc-codex-multi-auth 6.8.1 → 6.9.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 +53 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts/rotation.d.ts +5 -3
- package/dist/lib/accounts/rotation.d.ts.map +1 -1
- package/dist/lib/accounts/rotation.js +32 -5
- package/dist/lib/accounts/rotation.js.map +1 -1
- package/dist/lib/accounts.d.ts +1 -1
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +4 -4
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +123 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/request/fetch-helpers.js +20 -1
- package/dist/lib/request/fetch-helpers.js.map +1 -1
- package/dist/lib/request/helpers/user-agent.d.ts +9 -0
- package/dist/lib/request/helpers/user-agent.d.ts.map +1 -0
- package/dist/lib/request/helpers/user-agent.js +40 -0
- package/dist/lib/request/helpers/user-agent.js.map +1 -0
- package/dist/lib/runtime.d.ts +4 -0
- package/dist/lib/runtime.d.ts.map +1 -1
- package/dist/lib/runtime.js.map +1 -1
- package/dist/lib/schemas.d.ts +1 -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-help.d.ts.map +1 -1
- package/dist/lib/tools/codex-help.js +12 -1
- package/dist/lib/tools/codex-help.js.map +1 -1
- package/dist/lib/tools/codex-pool.d.ts +5 -0
- package/dist/lib/tools/codex-pool.d.ts.map +1 -0
- package/dist/lib/tools/codex-pool.js +176 -0
- package/dist/lib/tools/codex-pool.js.map +1 -0
- package/dist/lib/tools/index.d.ts +1 -1
- package/dist/lib/tools/index.d.ts.map +1 -1
- package/dist/lib/tools/index.js +2 -0
- package/dist/lib/tools/index.js.map +1 -1
- package/package.json +155 -153
package/README.md
CHANGED
|
@@ -180,6 +180,7 @@ If browser launch is blocked, use the alternate login paths in [docs/getting-sta
|
|
|
180
180
|
| `codex-limits` | What quota or rate-limit state is visible now? |
|
|
181
181
|
| `codex-reset` | Do I have a banked rate-limit reset credit, and how do I redeem it? |
|
|
182
182
|
| `codex-dashboard` | Can I manage accounts from one interactive surface? |
|
|
183
|
+
| `codex-pool` | Which accounts are preferred for each model, and how do I change them? |
|
|
183
184
|
|
|
184
185
|
Most of these also run as a **direct CLI** with no agent/model involvement (no token cost) — e.g. `oc-codex-multi-auth warm`, `oc-codex-multi-auth status`, or `npx -y oc-codex-multi-auth@latest warm`. Use `oc-codex-multi-auth warm` to open every enabled account's usage window at the start of a session and stagger the rolling quota cooldowns. Add `--json` for scriptable output.
|
|
185
186
|
|
|
@@ -244,6 +245,58 @@ Primary config files:
|
|
|
244
245
|
- `~/.config/opencode/tui.json`
|
|
245
246
|
- `~/.opencode/openai-codex-auth-config.json`
|
|
246
247
|
|
|
248
|
+
### Route models to preferred accounts
|
|
249
|
+
|
|
250
|
+
Use `modelAccountPools` to assign one or more preferred ChatGPT accounts to a
|
|
251
|
+
model. Account references use stable account IDs, so adding, removing, or
|
|
252
|
+
reordering accounts does not silently change a model's routing.
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{
|
|
256
|
+
"modelAccountPools": {
|
|
257
|
+
"gpt-5.6-sol": [
|
|
258
|
+
"org-example-account-id",
|
|
259
|
+
"00000000-0000-0000-0000-000000000000"
|
|
260
|
+
],
|
|
261
|
+
"gpt-5.6-terra": [
|
|
262
|
+
"org-another-account-id"
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Save this configuration in `~/.opencode/openai-codex-auth-config.json`, then
|
|
269
|
+
restart OpenCode. Model matching is case-insensitive and uses the effective
|
|
270
|
+
model after request model normalization.
|
|
271
|
+
|
|
272
|
+
Use `codex-pool` to manage these mappings with ordinary 1-based account
|
|
273
|
+
numbers. The tool resolves those numbers and writes stable IDs to disk:
|
|
274
|
+
|
|
275
|
+
```text
|
|
276
|
+
codex-pool
|
|
277
|
+
codex-pool action="set" model="gpt-5.6-sol" accounts=[7,8]
|
|
278
|
+
codex-pool action="add" model="gpt-5.6-sol" accounts=[9]
|
|
279
|
+
codex-pool action="remove" model="gpt-5.6-sol" accounts=[7]
|
|
280
|
+
codex-pool action="clear" model="gpt-5.6-sol"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Add `dryRun=true` to preview a mutation. Use `format="json"` for structured
|
|
284
|
+
output; stable IDs remain redacted unless `includeSensitive=true` is also set.
|
|
285
|
+
Restart OpenCode after an applied mutation. The plugin configuration is global
|
|
286
|
+
while account storage is per-project by default, so a reference unresolved in
|
|
287
|
+
the current project is reported but never automatically deleted.
|
|
288
|
+
|
|
289
|
+
Routing behavior:
|
|
290
|
+
|
|
291
|
+
- A mapped model uses only healthy, selectable accounts in its preferred pool.
|
|
292
|
+
- Existing rotation strategy, quota, cooldown, and token-health rules still apply within the preferred pool.
|
|
293
|
+
- If every preferred account is unavailable, disabled, unknown, cooling down, or rate-limited, routing automatically falls back to the healthy general account pool.
|
|
294
|
+
- An unmapped model or an empty account list uses the general account pool directly.
|
|
295
|
+
- `codex-status`, `codex-dashboard`, and routing diagnostics report the account-pool mode as `preferred`, `general`, or `general-fallback`.
|
|
296
|
+
|
|
297
|
+
Account IDs are local account metadata but should still be treated as private
|
|
298
|
+
configuration. Do not publish a populated configuration file.
|
|
299
|
+
|
|
247
300
|
Selected runtime/environment overrides:
|
|
248
301
|
|
|
249
302
|
| Variable | Effect |
|
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;AA6M/D;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAgvH/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, getPerProjectAccounts, getEmptyResponseMaxRetries, getEmptyResponseRetryDelayMs, getPidOffsetEnabled, getRotationStrategy, 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, getPerProjectAccounts, getEmptyResponseMaxRetries, getEmptyResponseRetryDelayMs, getPidOffsetEnabled, getRotationStrategy, getModelAccountPool, 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";
|
|
@@ -132,6 +132,8 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
132
132
|
fallbackFrom: snapshot?.fallbackFrom ?? null,
|
|
133
133
|
fallbackTo: snapshot?.fallbackTo ?? null,
|
|
134
134
|
fallbackReason: snapshot?.fallbackReason ?? null,
|
|
135
|
+
accountPoolMode: snapshot?.accountPoolMode ?? null,
|
|
136
|
+
configuredAccountPoolSize: snapshot?.configuredAccountPoolSize ?? 0,
|
|
135
137
|
selectionExplainability: serializeSelectionExplainability(options.selectionExplainability ?? snapshot?.explainability ?? []),
|
|
136
138
|
};
|
|
137
139
|
};
|
|
@@ -160,6 +162,8 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
160
162
|
lines.push(` Fallback from: ${formatRoutingValue(routing.fallbackFrom)}`);
|
|
161
163
|
lines.push(` Fallback to: ${formatRoutingValue(routing.fallbackTo)}`);
|
|
162
164
|
lines.push(` Fallback reason: ${formatRoutingValue(routing.fallbackReason)}`);
|
|
165
|
+
lines.push(` Account pool: ${formatRoutingValue(routing.accountPoolMode)}`);
|
|
166
|
+
lines.push(` Configured pool size: ${routing.configuredAccountPoolSize}`);
|
|
163
167
|
if (options.includeExplainability) {
|
|
164
168
|
lines.push(" Selection explainability:");
|
|
165
169
|
if (routing.selectionExplainability.length === 0) {
|
|
@@ -186,6 +190,8 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
186
190
|
lines.push(formatUiKeyValue(ui, "Fallback from", formatRoutingValue(routing.fallbackFrom), "muted"));
|
|
187
191
|
lines.push(formatUiKeyValue(ui, "Fallback to", formatRoutingValue(routing.fallbackTo), "muted"));
|
|
188
192
|
lines.push(formatUiKeyValue(ui, "Fallback reason", formatRoutingValue(routing.fallbackReason), routing.fallbackReason ? "warning" : "muted"));
|
|
193
|
+
lines.push(formatUiKeyValue(ui, "Account pool", formatRoutingValue(routing.accountPoolMode), routing.accountPoolMode === "general-fallback" ? "warning" : "muted"));
|
|
194
|
+
lines.push(formatUiKeyValue(ui, "Configured pool size", String(routing.configuredAccountPoolSize), "muted"));
|
|
189
195
|
if (options.includeExplainability) {
|
|
190
196
|
lines.push("");
|
|
191
197
|
lines.push(...formatUiSection(ui, "Selection explainability"));
|
|
@@ -1355,6 +1361,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1355
1361
|
const attempted = new Set();
|
|
1356
1362
|
let restartAccountTraversalWithFallback = false;
|
|
1357
1363
|
let restartAccountTraversalAfterWorkspaceDeactivation = false;
|
|
1364
|
+
const preferredAccountIds = getModelAccountPool(pluginConfig, model);
|
|
1358
1365
|
while (attempted.size < Math.max(1, accountCount)) {
|
|
1359
1366
|
const selectionExplainability = accountManager.getSelectionExplainability(modelFamily, model, Date.now());
|
|
1360
1367
|
runtimeMetrics.lastSelectionSnapshot = {
|
|
@@ -1370,8 +1377,9 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1370
1377
|
fallbackFrom,
|
|
1371
1378
|
fallbackTo,
|
|
1372
1379
|
fallbackReason,
|
|
1380
|
+
configuredAccountPoolSize: preferredAccountIds.length,
|
|
1373
1381
|
};
|
|
1374
|
-
const account = accountManager.getAccountForStrategy(rotationStrategy, modelFamily, model, { pidOffsetEnabled });
|
|
1382
|
+
const account = accountManager.getAccountForStrategy(rotationStrategy, modelFamily, model, { pidOffsetEnabled }, preferredAccountIds);
|
|
1375
1383
|
if (!account || attempted.has(account.index)) {
|
|
1376
1384
|
break;
|
|
1377
1385
|
}
|
|
@@ -1389,6 +1397,13 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1389
1397
|
fallbackFrom,
|
|
1390
1398
|
fallbackTo,
|
|
1391
1399
|
fallbackReason,
|
|
1400
|
+
accountPoolMode: preferredAccountIds.length === 0
|
|
1401
|
+
? "general"
|
|
1402
|
+
: account.accountId !== undefined &&
|
|
1403
|
+
preferredAccountIds.includes(account.accountId)
|
|
1404
|
+
? "preferred"
|
|
1405
|
+
: "general-fallback",
|
|
1406
|
+
configuredAccountPoolSize: preferredAccountIds.length,
|
|
1392
1407
|
};
|
|
1393
1408
|
}
|
|
1394
1409
|
// Log account selection for debugging rotation
|