codex-multi-auth 2.8.5 → 2.8.7
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/.codex-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/dist/lib/accounts.d.ts +7 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +10 -0
- package/dist/lib/codex-manager/commands/best.d.ts +3 -0
- package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/best.js +10 -1
- package/dist/lib/codex-manager/commands/forecast.d.ts +3 -0
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +18 -1
- package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/report.js +14 -0
- package/dist/lib/forecast.d.ts +13 -0
- package/dist/lib/forecast.d.ts.map +1 -1
- package/dist/lib/forecast.js +18 -3
- package/dist/lib/request/rate-limit-decision.d.ts +46 -1
- package/dist/lib/request/rate-limit-decision.d.ts.map +1 -1
- package/dist/lib/request/rate-limit-decision.js +150 -3
- package/dist/lib/runtime/account-status.d.ts +67 -0
- package/dist/lib/runtime/account-status.d.ts.map +1 -1
- package/dist/lib/runtime/account-status.js +73 -0
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +90 -2
- package/package.json +1 -1
- package/scripts/codex.js +300 -82
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-multi-auth",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.7",
|
|
4
4
|
"description": "Install and operate codex-multi-auth for the official @openai/codex CLI with multi-account OAuth rotation, switching, health checks, and recovery tools.",
|
|
5
5
|
"interface": {
|
|
6
6
|
"composerIcon": "./assets/codex-multi-auth-icon.svg"
|
package/README.md
CHANGED
|
@@ -392,7 +392,7 @@ codex-multi-auth doctor --json
|
|
|
392
392
|
|
|
393
393
|
## Release Notes
|
|
394
394
|
|
|
395
|
-
- Current stable: [docs/releases/v2.8.
|
|
395
|
+
- Current stable: [docs/releases/v2.8.7.md](docs/releases/v2.8.7.md) — install via `npm i -g codex-multi-auth`
|
|
396
396
|
- Previous stable: [docs/releases/v2.8.3.md](docs/releases/v2.8.3.md)
|
|
397
397
|
- Previous stable: [docs/releases/v2.8.2.md](docs/releases/v2.8.2.md)
|
|
398
398
|
- Previous stable: [docs/releases/v2.7.1.md](docs/releases/v2.7.1.md)
|
package/dist/lib/accounts.d.ts
CHANGED
|
@@ -193,6 +193,13 @@ export declare class AccountManager {
|
|
|
193
193
|
isAccountCoolingDown(account: ManagedAccount): boolean;
|
|
194
194
|
clearAccountCooldown(account: ManagedAccount): void;
|
|
195
195
|
private isCircuitAvailable;
|
|
196
|
+
/**
|
|
197
|
+
* When the account's circuit breaker will admit an attempt again, as an
|
|
198
|
+
* epoch-ms deadline — null when it already would. Lets the pinned-503
|
|
199
|
+
* recovery metadata cover circuit-open skips, whose deadline lives in the
|
|
200
|
+
* breaker rather than the persisted account record.
|
|
201
|
+
*/
|
|
202
|
+
getCircuitRecoveryTime(account: ManagedAccount, now?: number): number | null;
|
|
196
203
|
incrementAuthFailures(account: ManagedAccount): number;
|
|
197
204
|
clearAuthFailures(account: ManagedAccount): void;
|
|
198
205
|
markAuthInvalidated(account: ManagedAccount, errorCode?: string, invalidatedAt?: number): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../lib/accounts.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../lib/accounts.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/accounts.js
CHANGED
|
@@ -926,6 +926,16 @@ export class AccountManager {
|
|
|
926
926
|
isCircuitAvailable(account) {
|
|
927
927
|
return getCircuitBreaker(getAccountCircuitKey(account)).isAvailable();
|
|
928
928
|
}
|
|
929
|
+
/**
|
|
930
|
+
* When the account's circuit breaker will admit an attempt again, as an
|
|
931
|
+
* epoch-ms deadline — null when it already would. Lets the pinned-503
|
|
932
|
+
* recovery metadata cover circuit-open skips, whose deadline lives in the
|
|
933
|
+
* breaker rather than the persisted account record.
|
|
934
|
+
*/
|
|
935
|
+
getCircuitRecoveryTime(account, now = Date.now()) {
|
|
936
|
+
const waitMs = getCircuitBreaker(getAccountCircuitKey(account)).getTimeUntilAvailable(now);
|
|
937
|
+
return waitMs > 0 ? now + waitMs : null;
|
|
938
|
+
}
|
|
929
939
|
incrementAuthFailures(account) {
|
|
930
940
|
account.consecutiveAuthFailures =
|
|
931
941
|
(account.consecutiveAuthFailures ?? 0) + 1;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ForecastAccountResult } from "../../forecast.js";
|
|
2
2
|
import { type CodexQuotaSnapshot } from "../../quota-probe.js";
|
|
3
|
+
import { type ModelFamily } from "../../request/helpers/model-map.js";
|
|
3
4
|
import type { AccountStorageV3 } from "../../storage.js";
|
|
4
5
|
import type { TokenFailure, TokenResult } from "../../types.js";
|
|
5
6
|
export interface BestCliOptions {
|
|
@@ -56,6 +57,8 @@ export interface BestCommandDeps {
|
|
|
56
57
|
now: number;
|
|
57
58
|
refreshFailure?: TokenFailure;
|
|
58
59
|
liveQuota?: CodexQuotaSnapshot;
|
|
60
|
+
family?: ModelFamily;
|
|
61
|
+
model?: string | null;
|
|
59
62
|
}>) => ForecastAccountResult[];
|
|
60
63
|
recommendForecastAccount: (results: ForecastAccountResult[]) => {
|
|
61
64
|
recommendedIndex: number | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"best.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/best.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,KAAK,kBAAkB,EAA6B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"best.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/best.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describeCodexProbeFailure } from "../../quota-probe.js";
|
|
2
|
-
import { resolveNormalizedModel } from "../../request/helpers/model-map.js";
|
|
2
|
+
import { getModelProfile, resolveNormalizedModel, } from "../../request/helpers/model-map.js";
|
|
3
3
|
import { DEFAULT_LIVE_PROBE_MODEL } from "../quota-cache-helpers.js";
|
|
4
4
|
/**
|
|
5
5
|
* Usage text and argument parsing for `best`. Previously module-private in
|
|
@@ -173,6 +173,13 @@ export async function runBestCommand(args, deps) {
|
|
|
173
173
|
probeErrors.push(`${deps.formatAccountLabel(account, i)}: ${message}`);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
+
// Only an explicit --model moves the recommendation off the codex family;
|
|
177
|
+
// see the note in the forecast command. `best` exists to pick the account
|
|
178
|
+
// for wrapper traffic, which is codex-family.
|
|
179
|
+
const forecastFamily = options.modelProvided
|
|
180
|
+
? getModelProfile(probeModel).promptFamily
|
|
181
|
+
: undefined;
|
|
182
|
+
const forecastModel = options.modelProvided ? probeModel : undefined;
|
|
176
183
|
const forecastInputs = storage.accounts.map((account, index) => ({
|
|
177
184
|
index,
|
|
178
185
|
account,
|
|
@@ -180,6 +187,8 @@ export async function runBestCommand(args, deps) {
|
|
|
180
187
|
now,
|
|
181
188
|
refreshFailure: refreshFailures.get(index),
|
|
182
189
|
liveQuota: liveQuotaByIndex.get(index),
|
|
190
|
+
family: forecastFamily,
|
|
191
|
+
model: forecastModel,
|
|
183
192
|
}));
|
|
184
193
|
const forecastResults = deps.evaluateForecastAccounts(forecastInputs);
|
|
185
194
|
const recommendation = deps.recommendForecastAccount(forecastResults);
|
|
@@ -2,6 +2,7 @@ import type { DashboardDisplaySettings } from "../../dashboard-settings.js";
|
|
|
2
2
|
import { type ForecastAccountResult, type RuntimeForecastOverlay } from "../../forecast.js";
|
|
3
3
|
import type { QuotaCacheData } from "../../quota-cache.js";
|
|
4
4
|
import { type CodexQuotaSnapshot } from "../../quota-probe.js";
|
|
5
|
+
import { type ModelFamily } from "../../request/helpers/model-map.js";
|
|
5
6
|
import { type AccountMetadataV3, type AccountStorageV3 } from "../../storage.js";
|
|
6
7
|
import type { TokenFailure, TokenResult } from "../../types.js";
|
|
7
8
|
type PromptTone = "accent" | "success" | "warning" | "danger" | "muted";
|
|
@@ -40,6 +41,8 @@ export interface ForecastCommandDeps {
|
|
|
40
41
|
quotaCache?: QuotaCacheData | null;
|
|
41
42
|
allAccounts?: readonly AccountMetadataV3[];
|
|
42
43
|
runtimeOverlay?: RuntimeForecastOverlay | null;
|
|
44
|
+
family?: ModelFamily;
|
|
45
|
+
model?: string | null;
|
|
43
46
|
}>) => ForecastAccountResult[];
|
|
44
47
|
summarizeForecast: (results: ForecastAccountResult[]) => {
|
|
45
48
|
total: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/forecast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAE5E,OAAO,EAEN,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,kBAAkB,EAA6B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/forecast.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { extractAccountEmail, sanitizeEmail } from "../../accounts.js";
|
|
|
2
2
|
import { buildForecastExplanation, } from "../../forecast.js";
|
|
3
3
|
import { applyRefreshedAccountPatch, persistRefreshedAccountPatch, serializeForecastResults, } from "../forecast-report-shared.js";
|
|
4
4
|
import { describeCodexProbeFailure } from "../../quota-probe.js";
|
|
5
|
-
import { DEFAULT_PROBE_MODEL, resolveNormalizedModel } from "../../request/helpers/model-map.js";
|
|
5
|
+
import { DEFAULT_PROBE_MODEL, getModelProfile, resolveNormalizedModel, } from "../../request/helpers/model-map.js";
|
|
6
6
|
function joinStyledSegments(parts, styleText) {
|
|
7
7
|
if (parts.length === 0)
|
|
8
8
|
return "";
|
|
@@ -27,6 +27,7 @@ function parseForecastArgs(args) {
|
|
|
27
27
|
json: false,
|
|
28
28
|
explain: false,
|
|
29
29
|
model: DEFAULT_PROBE_MODEL,
|
|
30
|
+
modelProvided: false,
|
|
30
31
|
runtimeOverlay: true,
|
|
31
32
|
};
|
|
32
33
|
for (let i = 0; i < args.length; i += 1) {
|
|
@@ -55,6 +56,7 @@ function parseForecastArgs(args) {
|
|
|
55
56
|
return { ok: false, message: "Missing value for --model" };
|
|
56
57
|
}
|
|
57
58
|
options.model = value;
|
|
59
|
+
options.modelProvided = true;
|
|
58
60
|
i += 1;
|
|
59
61
|
continue;
|
|
60
62
|
}
|
|
@@ -64,6 +66,7 @@ function parseForecastArgs(args) {
|
|
|
64
66
|
return { ok: false, message: "Missing value for --model" };
|
|
65
67
|
}
|
|
66
68
|
options.model = value;
|
|
69
|
+
options.modelProvided = true;
|
|
67
70
|
continue;
|
|
68
71
|
}
|
|
69
72
|
return { ok: false, message: `Unknown option: ${arg}` };
|
|
@@ -195,6 +198,18 @@ export async function runForecastCommand(args, deps) {
|
|
|
195
198
|
probeErrors.push(`${deps.formatAccountLabel(account, i)}: ${message}`);
|
|
196
199
|
}
|
|
197
200
|
}
|
|
201
|
+
// Only an explicit --model moves the forecast off the codex family. The
|
|
202
|
+
// default probe model is gpt-5.6-sol, whose family is gpt-5.2, so keying a
|
|
203
|
+
// bare `forecast` on it would evaluate every account against a family no
|
|
204
|
+
// wrapper request uses - /codex/responses buckets into codex.
|
|
205
|
+
//
|
|
206
|
+
// probeModel, not requestedModel: rate-limit records are keyed by the
|
|
207
|
+
// normalized model the proxy routes on. Resolved once rather than per
|
|
208
|
+
// account: getModelProfile re-parses the model string on every call.
|
|
209
|
+
const forecastFamily = options.modelProvided
|
|
210
|
+
? getModelProfile(requestedModel).promptFamily
|
|
211
|
+
: undefined;
|
|
212
|
+
const forecastModel = options.modelProvided ? probeModel : undefined;
|
|
198
213
|
const forecastInputs = storage.accounts.map((account, index) => ({
|
|
199
214
|
index,
|
|
200
215
|
account,
|
|
@@ -205,6 +220,8 @@ export async function runForecastCommand(args, deps) {
|
|
|
205
220
|
quotaCache,
|
|
206
221
|
allAccounts: storage.accounts,
|
|
207
222
|
runtimeOverlay,
|
|
223
|
+
family: forecastFamily,
|
|
224
|
+
model: forecastModel,
|
|
208
225
|
}));
|
|
209
226
|
const forecastResults = deps.evaluateForecastAccounts(forecastInputs);
|
|
210
227
|
const summary = deps.summarizeForecast(forecastResults);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/report.ts"],"names":[],"mappings":"AAoBA,OAAO,EACN,KAAK,kBAAkB,EAGvB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/report.ts"],"names":[],"mappings":"AAoBA,OAAO,EACN,KAAK,kBAAkB,EAGvB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA6ChE,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IAC5E,oBAAoB,EAAE,CACrB,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,WAAW,CAAC,EAC7D,GAAG,EAAE,MAAM,KACP,OAAO,CAAC;IACb,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,uBAAuB,EAAE,CAAC,KAAK,EAAE;QAChC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;KACd,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAClC,oBAAoB,EAAE,CACrB,OAAO,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,KACX,MAAM,GAAG,IAAI,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3D,sBAAsB,EAAE,CACvB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,KACtB,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IACtF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACtD;AAuLD,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,iBAAiB,GACrB,OAAO,CAAC,MAAM,CAAC,CA8VjB"}
|
|
@@ -44,6 +44,7 @@ function parseReportArgs(args) {
|
|
|
44
44
|
json: false,
|
|
45
45
|
explain: false,
|
|
46
46
|
model: DEFAULT_PROBE_MODEL,
|
|
47
|
+
modelProvided: false,
|
|
47
48
|
cachedOnly: false,
|
|
48
49
|
};
|
|
49
50
|
for (let i = 0; i < args.length; i += 1) {
|
|
@@ -72,6 +73,7 @@ function parseReportArgs(args) {
|
|
|
72
73
|
return { ok: false, message: "Missing value for --model" };
|
|
73
74
|
}
|
|
74
75
|
options.model = value;
|
|
76
|
+
options.modelProvided = true;
|
|
75
77
|
i += 1;
|
|
76
78
|
continue;
|
|
77
79
|
}
|
|
@@ -81,6 +83,7 @@ function parseReportArgs(args) {
|
|
|
81
83
|
return { ok: false, message: "Missing value for --model" };
|
|
82
84
|
}
|
|
83
85
|
options.model = value;
|
|
86
|
+
options.modelProvided = true;
|
|
84
87
|
continue;
|
|
85
88
|
}
|
|
86
89
|
if (arg === "--max-accounts") {
|
|
@@ -328,6 +331,15 @@ export async function runReportCommand(args, deps) {
|
|
|
328
331
|
}
|
|
329
332
|
}
|
|
330
333
|
}
|
|
334
|
+
// Only an explicit --model moves the report off the codex family; see the
|
|
335
|
+
// note in the forecast command. promptFamily is reused from the inspection
|
|
336
|
+
// rather than re-resolved per account.
|
|
337
|
+
const forecastFamily = options.modelProvided
|
|
338
|
+
? modelInspection.promptFamily
|
|
339
|
+
: undefined;
|
|
340
|
+
const forecastModel = options.modelProvided
|
|
341
|
+
? modelInspection.normalized
|
|
342
|
+
: undefined;
|
|
331
343
|
const forecastResults = storage
|
|
332
344
|
? evaluateForecastAccounts(storage.accounts.map((account, index) => ({
|
|
333
345
|
index,
|
|
@@ -339,6 +351,8 @@ export async function runReportCommand(args, deps) {
|
|
|
339
351
|
quotaCache,
|
|
340
352
|
allAccounts: storage.accounts,
|
|
341
353
|
runtimeOverlay: runtimeSnapshot,
|
|
354
|
+
family: forecastFamily,
|
|
355
|
+
model: forecastModel,
|
|
342
356
|
})))
|
|
343
357
|
: [];
|
|
344
358
|
const forecastSummary = summarizeForecast(forecastResults);
|
package/dist/lib/forecast.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CodexQuotaSnapshot } from "./quota-probe.js";
|
|
2
2
|
import type { QuotaCacheData } from "./quota-cache.js";
|
|
3
|
+
import type { ModelFamily } from "./request/helpers/model-map.js";
|
|
3
4
|
import type { AccountMetadataV3 } from "./storage.js";
|
|
4
5
|
import type { TokenFailure } from "./types.js";
|
|
5
6
|
type ForecastAvailability = "ready" | "delayed" | "unavailable";
|
|
@@ -14,6 +15,18 @@ export interface ForecastAccountInput {
|
|
|
14
15
|
quotaCache?: QuotaCacheData | null;
|
|
15
16
|
allAccounts?: readonly AccountMetadataV3[];
|
|
16
17
|
runtimeOverlay?: RuntimeForecastOverlay | null;
|
|
18
|
+
/**
|
|
19
|
+
* Prompt family whose per-family rate-limit records gate this forecast.
|
|
20
|
+
* Callers with a model in hand resolve it via getModelProfile; the codex
|
|
21
|
+
* default preserves the historical behavior for model-less surfaces.
|
|
22
|
+
*/
|
|
23
|
+
family?: ModelFamily;
|
|
24
|
+
/**
|
|
25
|
+
* Normalized model the forecast is about, when the caller has one. Selection
|
|
26
|
+
* keys token/concurrency limits under `family:<model>`, so without it a
|
|
27
|
+
* sibling model's record would be read as gating this one.
|
|
28
|
+
*/
|
|
29
|
+
model?: string | null;
|
|
17
30
|
}
|
|
18
31
|
export interface RuntimeForecastOverlay {
|
|
19
32
|
accountSkipReasons?: Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../lib/forecast.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../lib/forecast.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/forecast.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AUTH_INVALIDATION_MARKER, formatAccountLabel, formatWaitTime, } from "./accounts.js";
|
|
2
2
|
import { findQuotaCacheEntryForAccount, isQuotaCacheEntryExhausted, quotaUsedPercentIsExhausted, } from "./quota-readiness.js";
|
|
3
|
-
import { getRateLimitResetTimeForFamily } from "./runtime/account-status.js";
|
|
3
|
+
import { getRateLimitResetTimeForFamily, getRateLimitResetTimeForModel, } from "./runtime/account-status.js";
|
|
4
4
|
function clampRisk(score) {
|
|
5
5
|
if (!Number.isFinite(score))
|
|
6
6
|
return 100;
|
|
@@ -132,7 +132,18 @@ export function evaluateForecastAccount(input) {
|
|
|
132
132
|
riskScore += 45;
|
|
133
133
|
appendWaitReason(reasons, "cooldown remaining", remaining);
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
// With a model in hand, gate on exactly the keys selection consults for that
|
|
136
|
+
// family/model pair, and on the LATEST of them: a sibling model's record does
|
|
137
|
+
// not gate this request, and while both the family-wide and model-scoped keys
|
|
138
|
+
// are active the account stays skipped until the later one expires.
|
|
139
|
+
//
|
|
140
|
+
// Without one (status, fix) no model key can be singled out, so keep the
|
|
141
|
+
// family-wide union - the conservative answer, and the behavior those
|
|
142
|
+
// surfaces have always had.
|
|
143
|
+
const forecastFamily = input.family ?? "codex";
|
|
144
|
+
const rateLimitResetAt = input.model
|
|
145
|
+
? getRateLimitResetTimeForModel(account, now, forecastFamily, input.model)
|
|
146
|
+
: getRateLimitResetTimeForFamily(account, now, forecastFamily);
|
|
136
147
|
if (typeof rateLimitResetAt === "number") {
|
|
137
148
|
const remaining = Math.max(0, rateLimitResetAt - now);
|
|
138
149
|
waitMs = Math.max(waitMs, remaining);
|
|
@@ -176,7 +187,11 @@ export function evaluateForecastAccount(input) {
|
|
|
176
187
|
// drop the overlay reason when the condition it describes is no longer
|
|
177
188
|
// active. Each reason validates only against its own backing disk state
|
|
178
189
|
// ("rate-limited" -> rateLimitResetTimes, "cooling-down" -> coolingDownUntil)
|
|
179
|
-
// so we never substitute a misleading reason string.
|
|
190
|
+
// so we never substitute a misleading reason string. The rate-limited
|
|
191
|
+
// cross-check inherits rateLimitResetAt's scope above: a record under one of
|
|
192
|
+
// the keys that actually gates this family/model request keeps the reason,
|
|
193
|
+
// while a record for another family - or another model in the same family -
|
|
194
|
+
// neither sustains it nor gates this request. Non-time-bounded
|
|
180
195
|
// reasons ("circuit-open", "token-exhausted", "policy-blocked") have no disk
|
|
181
196
|
// expiry to check and are always applied.
|
|
182
197
|
const coolingDownActive = typeof account.coolingDownUntil === "number" &&
|
|
@@ -22,7 +22,52 @@ export interface PinnedUnavailableErrorBody {
|
|
|
22
22
|
code: "codex_pinned_account_unavailable";
|
|
23
23
|
pinnedAccountIndex: number | null;
|
|
24
24
|
reason: string | null;
|
|
25
|
+
/** How the pin was set; forced pins are not cleared by `unpin`. */
|
|
26
|
+
pin_source: "forced" | "manual" | null;
|
|
27
|
+
/** When the blocking record ends, when the skip reason is time-bounded. */
|
|
28
|
+
reset_at: string | null;
|
|
29
|
+
retry_after_ms: number | null;
|
|
25
30
|
account_skip_reasons: Record<string, string>;
|
|
26
31
|
}
|
|
27
|
-
export
|
|
32
|
+
export interface PinnedUnavailableContext {
|
|
33
|
+
/**
|
|
34
|
+
* "forced" when the pin came from the wrapper's forced-account mode
|
|
35
|
+
* (`--account` / CODEX_MULTI_AUTH_FORCE_ACCOUNT, which the wrapper resolves
|
|
36
|
+
* into the internal CODEX_MULTI_AUTH_FORCE_ACCOUNT_INDEX), "manual" when it
|
|
37
|
+
* came from `switch`. `unpin` clears only the manual kind, so the remedy
|
|
38
|
+
* line must not suggest it for a forced pin.
|
|
39
|
+
*/
|
|
40
|
+
pinSource?: "forced" | "manual" | null;
|
|
41
|
+
/** Epoch ms when the blocking record ends (rate limit or cooldown). */
|
|
42
|
+
resetAtMs?: number | null;
|
|
43
|
+
/**
|
|
44
|
+
* Which class of record supplies `resetAtMs`. That deadline is the max
|
|
45
|
+
* across every gating record, so a `rate-limited` skip reason can carry a
|
|
46
|
+
* deadline supplied by a breaker or cooldown that ends later, and the
|
|
47
|
+
* quota phrasing is only true when the rate limit itself is that bound.
|
|
48
|
+
*
|
|
49
|
+
* - `"rate-limit"` — the rate-limit records bound it; word it as a reset.
|
|
50
|
+
* - `"other"` — a cooldown or breaker ends later and bounds it instead.
|
|
51
|
+
* - `"unknown"` (the default) — the caller did not measure; trust the
|
|
52
|
+
* skip reason.
|
|
53
|
+
*
|
|
54
|
+
* Deliberately a value rather than the presence of a second deadline
|
|
55
|
+
* field. The previous shape branched on `"rateLimitResetAtMs" in context`,
|
|
56
|
+
* so a caller that spread the key with an `undefined` value got the
|
|
57
|
+
* opposite wording from one that omitted it — a contract no type could
|
|
58
|
+
* express and no compiler could check.
|
|
59
|
+
*/
|
|
60
|
+
recoveryBound?: "rate-limit" | "other" | "unknown";
|
|
61
|
+
/**
|
|
62
|
+
* The pin's CURRENT runtime skip reason, re-read from account state at the
|
|
63
|
+
* moment the 503 is built. `accountSkipReasons` holds the SELECTION
|
|
64
|
+
* verdict, and on the dominant path the retry loop has already overwritten
|
|
65
|
+
* it with its own bookkeeping token ("already-attempted") — wording the
|
|
66
|
+
* sentence from that is what issue #675 reported. Omitted when the caller
|
|
67
|
+
* did not re-read runtime state.
|
|
68
|
+
*/
|
|
69
|
+
currentSkipReason?: string | null;
|
|
70
|
+
now?: number;
|
|
71
|
+
}
|
|
72
|
+
export declare function buildPinnedUnavailableErrorBody(pinnedIndex: number | null | undefined, accountSkipReasons: ReadonlyMap<number, string>, context?: PinnedUnavailableContext): PinnedUnavailableErrorBody;
|
|
28
73
|
//# sourceMappingURL=rate-limit-decision.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit-decision.d.ts","sourceRoot":"","sources":["../../../lib/request/rate-limit-decision.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"rate-limit-decision.d.ts","sourceRoot":"","sources":["../../../lib/request/rate-limit-decision.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAe/C,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,GAAG,OAAO,CAWjG;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAapF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBlF;AAYD,wBAAgB,0BAA0B,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAuB3E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBxE;AA0BD,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,MAAM,GACT,MAAM,CAcR;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAE1E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,kCAAkC,CAAC;IACzC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,mEAAmE;IACnE,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAQD,MAAM,WAAW,wBAAwB;IACxC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IACvC,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,EAAE,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC;IACnD;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAwID,wBAAgB,+BAA+B,CAC9C,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/C,OAAO,CAAC,EAAE,wBAAwB,GAChC,0BAA0B,CA8E5B"}
|
|
@@ -172,22 +172,169 @@ export function getQuotaNearExhaustionWaitMs(headers, remainingThreshold, now) {
|
|
|
172
172
|
export function normalizeExhaustionStatus(reason) {
|
|
173
173
|
return reason === "rate-limit" ? HTTP_STATUS.TOO_MANY_REQUESTS : 503;
|
|
174
174
|
}
|
|
175
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Largest epoch-ms value `new Date(...).toISOString()` accepts; anything beyond
|
|
177
|
+
* throws RangeError (ECMAScript time-value limit, ±100,000,000 days).
|
|
178
|
+
*/
|
|
179
|
+
const MAX_ECMASCRIPT_TIME_VALUE = 8_640_000_000_000_000;
|
|
180
|
+
const DEADLINE_SENTENCES = {
|
|
181
|
+
"available-again": (resetAt) => `the account is expected to be available again at ${resetAt}`,
|
|
182
|
+
"next-attempt": (resetAt) => `the next attempt is allowed at ${resetAt}`,
|
|
183
|
+
"cooldown-ends": (resetAt) => `the cooldown ends at ${resetAt}`,
|
|
184
|
+
"rate-limit-reset": (resetAt) => `the rate limit resets at ${resetAt}`,
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Every cooldown variant is bounded by the same `coolingDownUntil` field, so
|
|
188
|
+
* they all word their deadline the same way. Two of them used to say "the next
|
|
189
|
+
* attempt is allowed at" while the rest said "the cooldown ends at", which
|
|
190
|
+
* reads as two different mechanisms to an operator comparing two 503s.
|
|
191
|
+
*
|
|
192
|
+
* `satisfies` is what keeps this honest: a new CooldownReason becomes a
|
|
193
|
+
* compile error here rather than falling through to the verbatim arm below,
|
|
194
|
+
* which would print the raw `cooling-down:<reason>` token in the sentence —
|
|
195
|
+
* the internal-token leak issue #675 was filed about.
|
|
196
|
+
*/
|
|
197
|
+
const COOLDOWN_DESCRIPTIONS = {
|
|
198
|
+
"auth-failure": {
|
|
199
|
+
parenthetical: "cooling down after authentication failures",
|
|
200
|
+
deadlineNoun: "cooldown-ends",
|
|
201
|
+
},
|
|
202
|
+
"network-error": {
|
|
203
|
+
parenthetical: "cooling down after network errors",
|
|
204
|
+
deadlineNoun: "cooldown-ends",
|
|
205
|
+
},
|
|
206
|
+
"server-error": {
|
|
207
|
+
parenthetical: "cooling down after upstream server errors",
|
|
208
|
+
deadlineNoun: "cooldown-ends",
|
|
209
|
+
},
|
|
210
|
+
"rate-limit": {
|
|
211
|
+
parenthetical: "cooling down after a rate limit",
|
|
212
|
+
deadlineNoun: "cooldown-ends",
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
const BLOCKER_DESCRIPTIONS = new Map([
|
|
216
|
+
[
|
|
217
|
+
"rate-limited",
|
|
218
|
+
// Upgraded to "rate-limit-reset" below when the caller confirms the
|
|
219
|
+
// rate limit is what bounds the advertised deadline.
|
|
220
|
+
{ parenthetical: "rate-limited", deadlineNoun: "available-again" },
|
|
221
|
+
],
|
|
222
|
+
[
|
|
223
|
+
"circuit-open",
|
|
224
|
+
{
|
|
225
|
+
parenthetical: "paused after repeated upstream errors",
|
|
226
|
+
deadlineNoun: "next-attempt",
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
["cooling-down", { parenthetical: "cooling down", deadlineNoun: "cooldown-ends" }],
|
|
230
|
+
...Object.entries(COOLDOWN_DESCRIPTIONS).map(([reason, description]) => [
|
|
231
|
+
`cooling-down:${reason}`,
|
|
232
|
+
description,
|
|
233
|
+
]),
|
|
234
|
+
]);
|
|
235
|
+
/** Whether the sentence has real wording for this token, or must echo it raw. */
|
|
236
|
+
function isDescribedBlocker(skipReason) {
|
|
237
|
+
return BLOCKER_DESCRIPTIONS.has(skipReason);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* The human sentence derives its parenthetical and its deadline noun from the
|
|
241
|
+
* blocker class. The deadline is max(rate-limit reset, cooldown end, breaker
|
|
242
|
+
* next-attempt), so calling it a "limit" is only true for the rate-limit
|
|
243
|
+
* class: during a provider outage a tripped breaker or a server-error
|
|
244
|
+
* cooldown printed "the recorded limit resets at …", and operators read a
|
|
245
|
+
* backend incident as a blown subscription quota. Only the message changes —
|
|
246
|
+
* the machine-readable `reason` keeps the raw skip token.
|
|
247
|
+
*/
|
|
248
|
+
function describePinnedBlocker(skipReason, rateLimitBoundsRecovery) {
|
|
249
|
+
if (skipReason === null) {
|
|
250
|
+
return {
|
|
251
|
+
parenthetical: null,
|
|
252
|
+
deadline: DEADLINE_SENTENCES["available-again"],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
const described = BLOCKER_DESCRIPTIONS.get(skipReason);
|
|
256
|
+
if (described === undefined) {
|
|
257
|
+
// Permanent blockers never reach the deadline clause (the call site
|
|
258
|
+
// suppresses their reset time), and future or internal tokens stay
|
|
259
|
+
// legible verbatim.
|
|
260
|
+
return {
|
|
261
|
+
parenthetical: skipReason,
|
|
262
|
+
deadline: DEADLINE_SENTENCES["available-again"],
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// A breaker or cooldown can outlive the rate limit; the deadline is the max
|
|
266
|
+
// of every gating record, so it is only worded as the limit's own reset
|
|
267
|
+
// when the rate limit actually supplies it.
|
|
268
|
+
const deadlineNoun = skipReason === "rate-limited" && rateLimitBoundsRecovery
|
|
269
|
+
? "rate-limit-reset"
|
|
270
|
+
: described.deadlineNoun;
|
|
271
|
+
return {
|
|
272
|
+
parenthetical: described.parenthetical,
|
|
273
|
+
deadline: DEADLINE_SENTENCES[deadlineNoun],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
export function buildPinnedUnavailableErrorBody(pinnedIndex, accountSkipReasons, context) {
|
|
176
277
|
const normalizedPinnedIndex = typeof pinnedIndex === "number" ? pinnedIndex : null;
|
|
177
278
|
const skipReason = normalizedPinnedIndex !== null
|
|
178
279
|
? accountSkipReasons.get(normalizedPinnedIndex) ?? null
|
|
179
280
|
: null;
|
|
180
|
-
const reasonSuffix = skipReason ? ` (${skipReason})` : "";
|
|
181
281
|
// On the desync path the pin index is unknown (null); claiming "account 1"
|
|
182
282
|
// there would contradict the machine-readable pinnedAccountIndex: null.
|
|
183
283
|
const accountPhrase = normalizedPinnedIndex === null
|
|
184
284
|
? "The pinned account"
|
|
185
285
|
: `Pinned account ${normalizedPinnedIndex + 1}`;
|
|
286
|
+
const pinSource = context?.pinSource ?? null;
|
|
287
|
+
// Upper bound as well as lower: resetAtMs comes from persisted account state
|
|
288
|
+
// (rateLimitResetTimes, coolingDownUntil), and markAccountCoolingDown clamps
|
|
289
|
+
// only the low side while nothing re-validates either on load. A finite but
|
|
290
|
+
// absurd deadline past the ECMAScript time limit would make toISOString below
|
|
291
|
+
// throw a RangeError inside handleRequestInner, collapsing this diagnostic 503
|
|
292
|
+
// into a generic 500 that carries no pinnedAccountIndex, reason, or skip map —
|
|
293
|
+
// the exact payload this branch exists to deliver. Such a value bounds nothing
|
|
294
|
+
// usable anyway, so treat it as "no known recovery" instead.
|
|
295
|
+
const resetAtMs = typeof context?.resetAtMs === "number" &&
|
|
296
|
+
Number.isFinite(context.resetAtMs) &&
|
|
297
|
+
context.resetAtMs > 0 &&
|
|
298
|
+
context.resetAtMs <= MAX_ECMASCRIPT_TIME_VALUE
|
|
299
|
+
? context.resetAtMs
|
|
300
|
+
: null;
|
|
301
|
+
const now = context?.now ?? Date.now();
|
|
302
|
+
const retryAfterMs = resetAtMs !== null ? Math.max(0, resetAtMs - now) : null;
|
|
303
|
+
const resetAt = resetAtMs !== null ? new Date(resetAtMs).toISOString() : null;
|
|
304
|
+
// "unknown" (the default) means the caller did not measure which record
|
|
305
|
+
// bounds the deadline — older callers and unit seams — so trust the skip
|
|
306
|
+
// reason. Only a measured "other" demotes to the neutral phrasing, which
|
|
307
|
+
// stays true for a live rate limit either way.
|
|
308
|
+
const rateLimitBoundsRecovery = (context?.recoveryBound ?? "unknown") !== "other";
|
|
309
|
+
// The machine-readable `reason` below stays the recorded SELECTION verdict;
|
|
310
|
+
// only the human sentence follows the blocker actually gating the pin. A
|
|
311
|
+
// recorded verdict that names a real blocker class wins, because the
|
|
312
|
+
// selection-only classes ("missing", "policy-blocked") have no
|
|
313
|
+
// runtime-state equivalent and would be lost. Otherwise the re-read runtime
|
|
314
|
+
// state is the truth and the recorded token is the retry loop's own
|
|
315
|
+
// bookkeeping — the dominant path in issue #675, where a 503/429 on the pin
|
|
316
|
+
// re-enters selection and records "already-attempted" over the real class.
|
|
317
|
+
const describedSkipReason = skipReason !== null && isDescribedBlocker(skipReason)
|
|
318
|
+
? skipReason
|
|
319
|
+
: context?.currentSkipReason ?? skipReason;
|
|
320
|
+
const blocker = describePinnedBlocker(describedSkipReason, rateLimitBoundsRecovery);
|
|
321
|
+
const reasonSuffix = blocker.parenthetical
|
|
322
|
+
? ` (${blocker.parenthetical})`
|
|
323
|
+
: "";
|
|
324
|
+
const waitSuffix = resetAt !== null ? `; ${blocker.deadline(resetAt)}` : "";
|
|
325
|
+
// A forced pin belongs to the launching process, not to the persisted pin
|
|
326
|
+
// state, so `unpin` would clear nothing — say what actually helps.
|
|
327
|
+
const remedy = pinSource === "forced"
|
|
328
|
+
? "the pin was set by this session's launcher, so relaunch to select a different account"
|
|
329
|
+
: "run `codex-multi-auth status` for details, or `codex-multi-auth unpin` to allow rotation";
|
|
186
330
|
return {
|
|
187
|
-
message: `${accountPhrase} is currently unavailable${reasonSuffix};
|
|
331
|
+
message: `${accountPhrase} is currently unavailable${reasonSuffix}${waitSuffix}; ${remedy}.`,
|
|
188
332
|
code: "codex_pinned_account_unavailable",
|
|
189
333
|
pinnedAccountIndex: normalizedPinnedIndex,
|
|
190
334
|
reason: skipReason,
|
|
335
|
+
pin_source: pinSource,
|
|
336
|
+
reset_at: resetAt,
|
|
337
|
+
retry_after_ms: retryAfterMs,
|
|
191
338
|
account_skip_reasons: Object.fromEntries([...accountSkipReasons.entries()].map(([index, reason]) => [
|
|
192
339
|
String(index),
|
|
193
340
|
reason,
|