codex-multi-auth 2.8.1 → 2.8.3
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 +3 -1
- package/dist/lib/accounts.d.ts +15 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +126 -21
- package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-pool-write.js +4 -0
- package/dist/lib/codex-manager/backend-settings-schema.js +1 -1
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/status.js +5 -1
- package/dist/lib/codex-manager/commands/uninstall.d.ts +1 -0
- package/dist/lib/codex-manager/commands/uninstall.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/uninstall.js +12 -1
- package/dist/lib/codex-manager/commands/why-selected.d.ts +1 -1
- package/dist/lib/codex-manager/commands/why-selected.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/why-selected.js +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.js +32 -2
- package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
- package/dist/lib/codex-manager/health-check.js +19 -3
- package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-oauth.js +13 -7
- package/dist/lib/codex-manager.d.ts +4 -0
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +50 -16
- package/dist/lib/config.d.ts +3 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +3 -1
- package/dist/lib/forecast.d.ts.map +1 -1
- package/dist/lib/forecast.js +7 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/lib/parallel-probe.d.ts.map +1 -1
- package/dist/lib/parallel-probe.js +3 -1
- package/dist/lib/policy/runtime-policy.d.ts +1 -0
- package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
- package/dist/lib/policy/runtime-policy.js +7 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
- package/dist/lib/preemptive-quota-scheduler.js +35 -15
- package/dist/lib/rotation.d.ts +4 -0
- package/dist/lib/rotation.d.ts.map +1 -1
- package/dist/lib/rotation.js +13 -6
- package/dist/lib/runtime/app-bind.d.ts +40 -0
- package/dist/lib/runtime/app-bind.d.ts.map +1 -1
- package/dist/lib/runtime/app-bind.js +550 -20
- package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-account-selection.js +2 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts +2 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-token-refresh.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-token-refresh.js +3 -0
- package/dist/lib/runtime-constants.d.ts +2 -0
- package/dist/lib/runtime-constants.d.ts.map +1 -1
- package/dist/lib/runtime-constants.js +2 -0
- package/dist/lib/runtime-rotation-proxy.d.ts +8 -0
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +59 -5
- package/dist/lib/schemas.d.ts +15 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +3 -0
- package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
- package/dist/lib/storage/flagged-storage.js +15 -0
- package/dist/lib/storage/path-state.d.ts +1 -0
- package/dist/lib/storage/path-state.d.ts.map +1 -1
- package/dist/lib/storage/path-state.js +30 -3
- package/dist/lib/storage/public-types.d.ts +6 -0
- package/dist/lib/storage/public-types.d.ts.map +1 -1
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +17 -4
- package/package.json +198 -198
- package/scripts/codex-app-router.js +47 -3
- package/scripts/codex.js +165 -21
- package/scripts/install-codex-auth-utils.js +9 -2
- package/scripts/postinstall.js +2 -0
- package/scripts/preuninstall.js +11 -0
|
@@ -43,7 +43,8 @@ export function styleQuotaSummary(summary) {
|
|
|
43
43
|
export function formatQuotaSnapshotForDashboard(snapshot, settings, now = Date.now()) {
|
|
44
44
|
if (!settings.showQuotaDetails)
|
|
45
45
|
return "live session OK";
|
|
46
|
-
|
|
46
|
+
const summary = formatCompactQuotaSnapshot(snapshot, now, { showReset: true });
|
|
47
|
+
return summary ? `live session OK (${summary})` : "live session OK";
|
|
47
48
|
}
|
|
48
49
|
export function quotaCacheEntryToSnapshot(entry) {
|
|
49
50
|
return {
|
|
@@ -72,17 +73,38 @@ function formatCompactQuotaWindowLabel(windowMinutes) {
|
|
|
72
73
|
return `${windowMinutes / 60}h`;
|
|
73
74
|
return `${windowMinutes}m`;
|
|
74
75
|
}
|
|
76
|
+
function isUninformativeFullQuotaWindow(windowMinutes, usedPercent, resetAtMs, now) {
|
|
77
|
+
if (formatCompactQuotaWindowLabel(windowMinutes) !== "quota")
|
|
78
|
+
return false;
|
|
79
|
+
if (typeof usedPercent !== "number" || !Number.isFinite(usedPercent)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
const left = quotaLeftPercentFromUsed(usedPercent);
|
|
83
|
+
return (!formatQuotaResetAt(resetAtMs, now) &&
|
|
84
|
+
(left === undefined || left >= 100));
|
|
85
|
+
}
|
|
75
86
|
function formatCompactQuotaPart(windowMinutes, usedPercent, resetAtMs, options, now) {
|
|
76
87
|
const label = formatCompactQuotaWindowLabel(windowMinutes);
|
|
77
88
|
if (typeof usedPercent !== "number" || !Number.isFinite(usedPercent)) {
|
|
78
89
|
return null;
|
|
79
90
|
}
|
|
80
91
|
const left = quotaLeftPercentFromUsed(usedPercent);
|
|
92
|
+
// The reset validity is computed regardless of showReset: it also feeds the
|
|
93
|
+
// uninformative-window check below, so hiding stays consistent across the
|
|
94
|
+
// compact (no-reset) and check (with-reset) surfaces.
|
|
95
|
+
const reset = formatQuotaResetAt(resetAtMs, now);
|
|
96
|
+
// An unlabeled window ("quota" — upstream reported no duration) that sits at
|
|
97
|
+
// 100% left with no reset timestamp carries no actionable signal; since the
|
|
98
|
+
// 2026-07/08 upstream limit changes it renders as a permanent "quota 100%"
|
|
99
|
+
// on every account. Hide exactly that shape: the segment reappears as soon
|
|
100
|
+
// as the window reports a duration, any depletion, or a reset time.
|
|
101
|
+
if (!reset && label === "quota" && (left === undefined || left >= 100)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
81
104
|
const part = `${label} ${left}%`;
|
|
82
105
|
if (!options.showReset)
|
|
83
106
|
return part;
|
|
84
107
|
// A missing or malformed reset timestamp must never drop the percentage.
|
|
85
|
-
const reset = formatQuotaResetAt(resetAtMs, now);
|
|
86
108
|
return reset ? `${part}, resets ${reset}` : part;
|
|
87
109
|
}
|
|
88
110
|
export function formatCompactQuotaSnapshot(snapshot, now = Date.now(), options = {}) {
|
|
@@ -99,6 +121,10 @@ export function formatCompactQuotaSnapshot(snapshot, now = Date.now(), options =
|
|
|
99
121
|
if (parts.length > 0) {
|
|
100
122
|
return parts.join(" | ");
|
|
101
123
|
}
|
|
124
|
+
if (isUninformativeFullQuotaWindow(snapshot.primary.windowMinutes, snapshot.primary.usedPercent, snapshot.primary.resetAtMs, now) ||
|
|
125
|
+
isUninformativeFullQuotaWindow(snapshot.secondary.windowMinutes, snapshot.secondary.usedPercent, snapshot.secondary.resetAtMs, now)) {
|
|
126
|
+
return "";
|
|
127
|
+
}
|
|
102
128
|
return formatQuotaSnapshotLine(snapshot);
|
|
103
129
|
}
|
|
104
130
|
export function formatAccountQuotaSummary(entry, now = Date.now(), options = {}) {
|
|
@@ -115,5 +141,9 @@ export function formatAccountQuotaSummary(entry, now = Date.now(), options = {})
|
|
|
115
141
|
if (parts.length > 0) {
|
|
116
142
|
return parts.join(" | ");
|
|
117
143
|
}
|
|
144
|
+
if (isUninformativeFullQuotaWindow(entry.primary.windowMinutes, entry.primary.usedPercent, entry.primary.resetAtMs, now) ||
|
|
145
|
+
isUninformativeFullQuotaWindow(entry.secondary.windowMinutes, entry.secondary.usedPercent, entry.secondary.resetAtMs, now)) {
|
|
146
|
+
return "";
|
|
147
|
+
}
|
|
118
148
|
return formatQuotaSnapshotLine(quotaCacheEntryToSnapshot(entry));
|
|
119
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/health-check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/health-check.ts"],"names":[],"mappings":"AAQA,OAAO,EACN,KAAK,wBAAwB,EAE7B,MAAM,0BAA0B,CAAC;AA2ClC;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAED,wBAAsB,cAAc,CACnC,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA4Uf"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extractAccountEmail, extractAccountId, formatAccountLabel, sanitizeEmail, } from "../accounts.js";
|
|
1
|
+
import { AUTH_INVALIDATION_MARKER, extractAccountEmail, extractAccountId, formatAccountLabel, sanitizeEmail, } from "../accounts.js";
|
|
2
2
|
import { setCodexCliActiveSelection } from "../codex-cli/writer.js";
|
|
3
3
|
import { DEFAULT_DASHBOARD_DISPLAY_SETTINGS, } from "../dashboard-settings.js";
|
|
4
4
|
import { isCodexUnavailableError } from "../errors.js";
|
|
@@ -12,6 +12,12 @@ import { applyTokenAccountIdentity, hasLikelyInvalidRefreshToken, hasUsableAcces
|
|
|
12
12
|
import { saveAccountsWithRetry } from "./forecast-report-shared.js";
|
|
13
13
|
import { formatModelInspection, formatQuotaSnapshotForDashboard, formatResultSummary, inspectRequestedModel, normalizeFailureDetail, styleAccountDetailText, stylePromptText, } from "./formatters/index.js";
|
|
14
14
|
import { cloneQuotaCacheData, DEFAULT_LIVE_PROBE_MODEL, pruneUnsafeQuotaEmailCacheEntry, updateQuotaCacheForAccount, } from "./quota-cache-helpers.js";
|
|
15
|
+
function appendAuthInvalidationMarker(account, detail) {
|
|
16
|
+
return typeof account.authInvalidatedAt === "number" &&
|
|
17
|
+
Number.isFinite(account.authInvalidatedAt)
|
|
18
|
+
? `${detail} [${AUTH_INVALIDATION_MARKER}]`
|
|
19
|
+
: detail;
|
|
20
|
+
}
|
|
15
21
|
export async function runHealthCheck(options = {}) {
|
|
16
22
|
const forceRefresh = options.forceRefresh === true;
|
|
17
23
|
const liveProbe = options.liveProbe === true;
|
|
@@ -106,6 +112,7 @@ export async function runHealthCheck(options = {}) {
|
|
|
106
112
|
if (hasLikelyInvalidRefreshToken(account.refreshToken)) {
|
|
107
113
|
healthDetail += " (re-login suggested soon)";
|
|
108
114
|
}
|
|
115
|
+
healthDetail = appendAuthInvalidationMarker(account, healthDetail);
|
|
109
116
|
ok += 1;
|
|
110
117
|
if (display.showPerAccountRows) {
|
|
111
118
|
const healthMarker = healthTone === "success" ? "✓" : "!";
|
|
@@ -144,6 +151,12 @@ export async function runHealthCheck(options = {}) {
|
|
|
144
151
|
account.enabled = true;
|
|
145
152
|
changed = true;
|
|
146
153
|
}
|
|
154
|
+
if (typeof account.authInvalidatedAt === "number" ||
|
|
155
|
+
account.authInvalidationErrorCode !== undefined) {
|
|
156
|
+
delete account.authInvalidatedAt;
|
|
157
|
+
delete account.authInvalidationErrorCode;
|
|
158
|
+
changed = true;
|
|
159
|
+
}
|
|
147
160
|
if (accountIdentityChanged && liveProbe && workingQuotaCache) {
|
|
148
161
|
quotaEmailFallbackState = buildQuotaEmailFallbackState(storage.accounts);
|
|
149
162
|
quotaCacheChanged =
|
|
@@ -195,6 +208,7 @@ export async function runHealthCheck(options = {}) {
|
|
|
195
208
|
}
|
|
196
209
|
}
|
|
197
210
|
if (display.showPerAccountRows) {
|
|
211
|
+
healthyMessage = appendAuthInvalidationMarker(account, healthyMessage);
|
|
198
212
|
const healthyMarker = healthyTone === "success" ? "✓" : "!";
|
|
199
213
|
console.log(` ${stylePromptText(healthyMarker, healthyTone)} ${labelText} ${stylePromptText("|", "muted")} ${styleAccountDetailText(healthyMessage, healthyTone)}`);
|
|
200
214
|
}
|
|
@@ -207,13 +221,15 @@ export async function runHealthCheck(options = {}) {
|
|
|
207
221
|
signedInOnly += 1;
|
|
208
222
|
}
|
|
209
223
|
if (display.showPerAccountRows) {
|
|
210
|
-
|
|
224
|
+
const detailWithMarker = appendAuthInvalidationMarker(account, `refresh failed (${detail}) but this account still works right now`);
|
|
225
|
+
console.log(` ${stylePromptText("!", "warning")} ${labelText} ${stylePromptText("|", "muted")} ${stylePromptText(detailWithMarker, "warning")}`);
|
|
211
226
|
}
|
|
212
227
|
}
|
|
213
228
|
else {
|
|
214
229
|
failed += 1;
|
|
215
230
|
if (display.showPerAccountRows) {
|
|
216
|
-
|
|
231
|
+
const detailWithMarker = appendAuthInvalidationMarker(account, detail);
|
|
232
|
+
console.log(` ${stylePromptText("✗", "danger")} ${labelText} ${stylePromptText("|", "muted")} ${stylePromptText(detailWithMarker, "danger")}`);
|
|
217
233
|
}
|
|
218
234
|
}
|
|
219
235
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-oauth.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/login-oauth.ts"],"names":[],"mappings":"AAEA,OAAO,EAON,KAAK,SAAS,EACd,MAAM,gBAAgB,CAAC;AAsBxB,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EACN,KAAK,uBAAuB,EAG5B,MAAM,yBAAyB,CAAC;AAOjC;;;;;GAKG;AAEH,gBAAgB;AAChB,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACrE,gBAAgB;AAChB,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAIF,gBAAgB;AAChB,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GAC/C,OAAO,CAGT;AAED,gBAAgB;AAChB,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIpD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,YAAY,EACpB,WAAW,CAAC,EAAE,MAAM,GAClB,uBAAuB,CA+DzB;AA0FD,gBAAgB;AAChB,MAAM,MAAM,eAAe,GACxB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,gBAAgB,GAChB,QAAQ,CAAC;AACZ,gBAAgB;AAChB,MAAM,MAAM,iBAAiB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,gBAAgB;AAChB,wBAAsB,YAAY,CACjC,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,CAAC,GACxD,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"login-oauth.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/login-oauth.ts"],"names":[],"mappings":"AAEA,OAAO,EAON,KAAK,SAAS,EACd,MAAM,gBAAgB,CAAC;AAsBxB,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EACN,KAAK,uBAAuB,EAG5B,MAAM,yBAAyB,CAAC;AAOjC;;;;;GAKG;AAEH,gBAAgB;AAChB,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACrE,gBAAgB;AAChB,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAIF,gBAAgB;AAChB,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GAC/C,OAAO,CAGT;AAED,gBAAgB;AAChB,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIpD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,YAAY,EACpB,WAAW,CAAC,EAAE,MAAM,GAClB,uBAAuB,CA+DzB;AA0FD,gBAAgB;AAChB,MAAM,MAAM,eAAe,GACxB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,gBAAgB,GAChB,QAAQ,CAAC;AACZ,gBAAgB;AAChB,MAAM,MAAM,iBAAiB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,gBAAgB;AAChB,wBAAsB,YAAY,CACjC,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,CAAC,GACxD,OAAO,CAAC,WAAW,CAAC,CA6ItB;AAED,gBAAgB;AAChB,wBAAsB,aAAa,CAClC,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC,EACrE,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,WAAW,CAAC,CAetB;AAED,gBAAgB;AAChB,MAAM,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEhE,gBAAgB;AAChB,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,uBAAuB,EAAE,EAClC,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAuD3C;AAED,gBAAgB;AAChB,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
|
@@ -174,6 +174,7 @@ function isReadlineClosedError(error) {
|
|
|
174
174
|
/** @internal */
|
|
175
175
|
export async function runOAuthFlow(forceNewLogin, signInMode) {
|
|
176
176
|
const { pkce, state, url } = await createAuthorizationFlow({ forceNewLogin });
|
|
177
|
+
const displayUrl = redactOAuthUrlForLog(url);
|
|
177
178
|
let code = null;
|
|
178
179
|
let oauthServer = null;
|
|
179
180
|
try {
|
|
@@ -196,12 +197,6 @@ export async function runOAuthFlow(forceNewLogin, signInMode) {
|
|
|
196
197
|
oauthServer = null;
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
|
-
// Display the OAuth URL with sensitive query parameters (state,
|
|
200
|
-
// code, code_challenge, code_verifier) redacted so they do not leak
|
|
201
|
-
// into shell history, screen captures, CI transcripts, or clipboard
|
|
202
|
-
// managers. The full URL is still handed to the browser opener and
|
|
203
|
-
// the clipboard so sign-in continues to work end-to-end.
|
|
204
|
-
const displayUrl = redactOAuthUrlForLog(url);
|
|
205
200
|
if (signInMode === "browser") {
|
|
206
201
|
const opened = openBrowserUrl(url);
|
|
207
202
|
if (opened) {
|
|
@@ -212,10 +207,21 @@ export async function runOAuthFlow(forceNewLogin, signInMode) {
|
|
|
212
207
|
console.log(`${stylePromptText(UI_COPY.oauth.goTo, "accent")} ${displayUrl}`);
|
|
213
208
|
const copied = copyTextToClipboard(url);
|
|
214
209
|
console.log(stylePromptText(copied ? UI_COPY.oauth.copyOk : UI_COPY.oauth.copyFail, copied ? "success" : "warning"));
|
|
210
|
+
if (!copied) {
|
|
211
|
+
// The redacted line is safe for normal logs, but it cannot complete
|
|
212
|
+
// an incognito/manual handoff. If clipboard access also failed,
|
|
213
|
+
// provide the exact URL as the final recovery path.
|
|
214
|
+
console.log(`${stylePromptText(UI_COPY.oauth.goTo, "accent")} ${url}`);
|
|
215
|
+
}
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
218
|
else {
|
|
218
|
-
|
|
219
|
+
// Manual/incognito sign-in depends on the exact authorization URL. In
|
|
220
|
+
// particular, replacing `state` with a redaction marker causes the
|
|
221
|
+
// provider to return that marker and the callback's CSRF validation must
|
|
222
|
+
// (correctly) reject it. State validation remains strict below; this
|
|
223
|
+
// output simply preserves the value minted for this login attempt.
|
|
224
|
+
console.log(`${stylePromptText(UI_COPY.oauth.goTo, "accent")} ${url}`);
|
|
219
225
|
const copied = copyTextToClipboard(url);
|
|
220
226
|
console.log(stylePromptText(copied ? UI_COPY.oauth.copyOk : UI_COPY.oauth.copyFail, copied ? "success" : "warning"));
|
|
221
227
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { selectHybridAccountTraced } from "./rotation.js";
|
|
1
2
|
import { formatBackupSavedAt, styleAccountDetailText } from "./codex-manager/formatters/index.js";
|
|
3
|
+
import { type AccountStorageV3 } from "./storage.js";
|
|
2
4
|
export { formatBackupSavedAt, styleAccountDetailText };
|
|
3
5
|
export declare function autoSyncActiveAccountToCodex(): Promise<boolean>;
|
|
6
|
+
/** @internal Exposed for diagnostics regression tests; not part of the CLI API. */
|
|
7
|
+
export declare function buildSelectAccountTraced(): (storage: AccountStorageV3) => Promise<ReturnType<typeof selectHybridAccountTraced>>;
|
|
4
8
|
export declare function runCodexMultiAuthCli(rawArgs: string[]): Promise<number>;
|
|
5
9
|
//# sourceMappingURL=codex-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-manager.d.ts","sourceRoot":"","sources":["../../lib/codex-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"codex-manager.d.ts","sourceRoot":"","sources":["../../lib/codex-manager.ts"],"names":[],"mappings":"AA2DA,OAAO,EAIN,yBAAyB,EACzB,MAAM,eAAe,CAAC;AA4BvB,OAAO,EAEN,mBAAmB,EAMnB,sBAAsB,EAGtB,MAAM,qCAAqC,CAAC;AA+B7C,OAAO,EAEN,KAAK,gBAAgB,EAWrB,MAAM,cAAc,CAAC;AAKtB,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,CAAC;AA4IvD,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,OAAO,CAAC,CAuGrE;AACD,mFAAmF;AACnF,wBAAgB,wBAAwB,IAAI,CAC3C,OAAO,EAAE,gBAAgB,KACrB,OAAO,CAAC,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC,CAwEzD;AAmPD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4C7E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extractAccountEmail, extractAccountId, formatAccountLabel, formatWaitTime, sanitizeEmail, } from "./accounts.js";
|
|
1
|
+
import { AUTH_INVALIDATION_MARKER, AccountManager, extractAccountEmail, extractAccountId, formatAccountLabel, formatWaitTime, sanitizeEmail, } from "./accounts.js";
|
|
2
2
|
import { loadCodexCliState } from "./codex-cli/state.js";
|
|
3
3
|
import { setCodexCliActiveSelection } from "./codex-cli/writer.js";
|
|
4
4
|
import { parseBestArgs, printBestUsage, runBestCommand, } from "./codex-manager/commands/best.js";
|
|
@@ -22,6 +22,8 @@ import { parseWhySelectedArgs, printWhySelectedUsage, runWhySelectedCommand, } f
|
|
|
22
22
|
import { parseVerifyArgs, printVerifyUsage, runVerifyCommand, } from "./codex-manager/commands/verify.js";
|
|
23
23
|
import { findProjectRoot, getProjectConfigDir, getProjectGlobalConfigDir, getProjectStorageKey, resolveProjectStorageIdentityRoot, resolvePath as resolveStoragePath, } from "./storage/paths.js";
|
|
24
24
|
import { getHealthTracker, getTokenTracker, selectHybridAccountTraced, } from "./rotation.js";
|
|
25
|
+
import { evaluateRuntimePolicy, loadRuntimePolicyState, } from "./policy/runtime-policy.js";
|
|
26
|
+
import { CURRENT_CODEX_MODEL } from "./request/helpers/model-map.js";
|
|
25
27
|
import { runDoctor as runRepairDoctor, runFix as runRepairFix, runVerifyFlagged as runRepairVerifyFlagged, } from "./codex-manager/repair-commands.js";
|
|
26
28
|
import { runUninstallCommand } from "./codex-manager/commands/uninstall.js";
|
|
27
29
|
import { runForecastCommand } from "./codex-manager/commands/forecast.js";
|
|
@@ -277,35 +279,67 @@ export async function autoSyncActiveAccountToCodex() {
|
|
|
277
279
|
...(syncIdToken ? { idToken: syncIdToken } : {}),
|
|
278
280
|
});
|
|
279
281
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
+
/** @internal Exposed for diagnostics regression tests; not part of the CLI API. */
|
|
283
|
+
export function buildSelectAccountTraced() {
|
|
284
|
+
return async (storage) => {
|
|
282
285
|
const now = Date.now();
|
|
283
286
|
const healthTracker = getHealthTracker();
|
|
284
287
|
const tokenTracker = getTokenTracker();
|
|
288
|
+
const runtimeAccountManager = new AccountManager(undefined, storage);
|
|
289
|
+
const runtimeAccountsByIndex = new Map(runtimeAccountManager
|
|
290
|
+
.getAccountsSnapshot()
|
|
291
|
+
.map((account) => [account.index, account]));
|
|
285
292
|
const accountsWithMetrics = storage.accounts.map((account, index) => {
|
|
286
|
-
const
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
if (typeof value === "number" && value > now) {
|
|
291
|
-
rateLimited = true;
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
const coolingDown = typeof account?.coolingDownUntil === "number" &&
|
|
296
|
-
account.coolingDownUntil > now;
|
|
297
|
-
const isAvailable = enabled && !rateLimited && !coolingDown;
|
|
293
|
+
const runtimeAccount = runtimeAccountsByIndex.get(index);
|
|
294
|
+
const runtimeSkipReason = runtimeAccount
|
|
295
|
+
? runtimeAccountManager.getManagedAccountRuntimeSkipReason(runtimeAccount, "codex", CURRENT_CODEX_MODEL)
|
|
296
|
+
: "missing";
|
|
298
297
|
return {
|
|
299
298
|
index,
|
|
300
299
|
trackerKey: account?.accountId ?? index,
|
|
301
|
-
isAvailable,
|
|
300
|
+
isAvailable: runtimeSkipReason === null,
|
|
301
|
+
unavailableReason: runtimeSkipReason ?? undefined,
|
|
302
302
|
lastUsed: account?.lastUsed ?? 0,
|
|
303
303
|
};
|
|
304
304
|
});
|
|
305
|
+
const policyState = await loadRuntimePolicyState();
|
|
306
|
+
const policy = await evaluateRuntimePolicy({
|
|
307
|
+
state: policyState,
|
|
308
|
+
accounts: storage.accounts.map((account, index) => ({
|
|
309
|
+
index,
|
|
310
|
+
accountId: account.accountId,
|
|
311
|
+
email: account.email,
|
|
312
|
+
})),
|
|
313
|
+
model: CURRENT_CODEX_MODEL,
|
|
314
|
+
now,
|
|
315
|
+
});
|
|
316
|
+
const blockedAccountIndexes = new Set(policy.blockedAccountIndexes);
|
|
317
|
+
const blockedReasonByAccount = {
|
|
318
|
+
...(policy.blockedAccountReasons ?? {}),
|
|
319
|
+
};
|
|
320
|
+
if (!policy.allowed) {
|
|
321
|
+
for (const { index } of accountsWithMetrics) {
|
|
322
|
+
blockedAccountIndexes.add(index);
|
|
323
|
+
blockedReasonByAccount[index] =
|
|
324
|
+
policy.errorCode ?? "policy-blocked";
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
for (const [index, account] of storage.accounts.entries()) {
|
|
328
|
+
if (typeof account.authInvalidatedAt === "number" &&
|
|
329
|
+
Number.isFinite(account.authInvalidatedAt)) {
|
|
330
|
+
blockedAccountIndexes.add(index);
|
|
331
|
+
blockedReasonByAccount[index] = AUTH_INVALIDATION_MARKER;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
305
334
|
return selectHybridAccountTraced({
|
|
306
335
|
accounts: accountsWithMetrics,
|
|
307
336
|
healthTracker,
|
|
308
337
|
tokenTracker,
|
|
338
|
+
options: {
|
|
339
|
+
blockedAccountIndexes,
|
|
340
|
+
blockedReasonByAccount,
|
|
341
|
+
scoreBoostByAccount: policy.scoreBoostByAccount,
|
|
342
|
+
},
|
|
309
343
|
});
|
|
310
344
|
};
|
|
311
345
|
}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -308,7 +308,9 @@ export declare function getPreemptiveQuotaRemainingPercent5h(pluginConfig: Plugi
|
|
|
308
308
|
*/
|
|
309
309
|
export declare function getPreemptiveQuotaRemainingPercent7d(pluginConfig: PluginConfig): number;
|
|
310
310
|
/**
|
|
311
|
-
* Get the configured
|
|
311
|
+
* Get the configured fallback deferral time (in milliseconds) for preemptive quota checks.
|
|
312
|
+
* Trusted future quota resets may extend a deferral beyond this fallback, up to the
|
|
313
|
+
* scheduler's seven-day safety ceiling.
|
|
312
314
|
*
|
|
313
315
|
* Reads an environment override or the plugin configuration and enforces a minimum of 1000 ms.
|
|
314
316
|
*
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.js
CHANGED
|
@@ -1279,7 +1279,9 @@ export function getPreemptiveQuotaRemainingPercent7d(pluginConfig) {
|
|
|
1279
1279
|
return resolveNumberSetting("CODEX_AUTH_PREEMPTIVE_QUOTA_7D_REMAINING_PCT", pluginConfig.preemptiveQuotaRemainingPercent7d, 5, { min: 0, max: 100 });
|
|
1280
1280
|
}
|
|
1281
1281
|
/**
|
|
1282
|
-
* Get the configured
|
|
1282
|
+
* Get the configured fallback deferral time (in milliseconds) for preemptive quota checks.
|
|
1283
|
+
* Trusted future quota resets may extend a deferral beyond this fallback, up to the
|
|
1284
|
+
* scheduler's seven-day safety ceiling.
|
|
1283
1285
|
*
|
|
1284
1286
|
* Reads an environment override or the plugin configuration and enforces a minimum of 1000 ms.
|
|
1285
1287
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../lib/forecast.ts"],"names":[],"mappings":"
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { formatAccountLabel, formatWaitTime } from "./accounts.js";
|
|
1
|
+
import { AUTH_INVALIDATION_MARKER, formatAccountLabel, formatWaitTime, } from "./accounts.js";
|
|
2
2
|
import { findQuotaCacheEntryForAccount, isQuotaCacheEntryExhausted, quotaUsedPercentIsExhausted, } from "./quota-readiness.js";
|
|
3
3
|
import { getRateLimitResetTimeForFamily } from "./runtime/account-status.js";
|
|
4
4
|
function clampRisk(score) {
|
|
@@ -103,6 +103,12 @@ export function evaluateForecastAccount(input) {
|
|
|
103
103
|
riskScore += 95;
|
|
104
104
|
reasons.push("account is disabled");
|
|
105
105
|
}
|
|
106
|
+
if (typeof account.authInvalidatedAt === "number" &&
|
|
107
|
+
Number.isFinite(account.authInvalidatedAt)) {
|
|
108
|
+
availability = "unavailable";
|
|
109
|
+
riskScore += 95;
|
|
110
|
+
reasons.push(AUTH_INVALIDATION_MARKER);
|
|
111
|
+
}
|
|
106
112
|
if (input.refreshFailure) {
|
|
107
113
|
const hard = isHardRefreshFailure(input.refreshFailure);
|
|
108
114
|
hardFailure = hard;
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export * from "./request/failure-policy.js";
|
|
|
23
23
|
export * from "./entitlement-cache.js";
|
|
24
24
|
export * from "./preemptive-quota-scheduler.js";
|
|
25
25
|
export * from "./runtime-rotation-proxy.js";
|
|
26
|
+
export * from "./runtime/app-bind.js";
|
|
26
27
|
export * from "./unified-settings.js";
|
|
27
28
|
export * from "./capability-policy.js";
|
|
28
29
|
export * from "./request/stream-failover.js";
|
package/dist/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EACN,wBAAwB,EACxB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,EAC7B,iCAAiC,IAAI,2CAA2C,EAChF,qBAAqB,EACrB,2BAA2B,GAC3B,MAAM,iCAAiC,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EACN,wBAAwB,EACxB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,EAC7B,iCAAiC,IAAI,2CAA2C,EAChF,qBAAqB,EACrB,2BAA2B,GAC3B,MAAM,iCAAiC,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gBAAgB,CAAC"}
|
package/dist/lib/index.js
CHANGED
|
@@ -23,6 +23,7 @@ export * from "./request/failure-policy.js";
|
|
|
23
23
|
export * from "./entitlement-cache.js";
|
|
24
24
|
export * from "./preemptive-quota-scheduler.js";
|
|
25
25
|
export * from "./runtime-rotation-proxy.js";
|
|
26
|
+
export * from "./runtime/app-bind.js";
|
|
26
27
|
export * from "./unified-settings.js";
|
|
27
28
|
export * from "./capability-policy.js";
|
|
28
29
|
export * from "./request/stream-failover.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parallel-probe.d.ts","sourceRoot":"","sources":["../../lib/parallel-probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAWtD,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC7B,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,CAAC;IACb,KAAK,CAAC,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACtC,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACtB;AA8BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,sBAAsB,GAC5B,cAAc,EAAE,CAAC;AACpB,wBAAgB,gBAAgB,CAC/B,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,aAAa,EAAE,MAAM,GACnB,cAAc,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"parallel-probe.d.ts","sourceRoot":"","sources":["../../lib/parallel-probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAWtD,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC7B,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,CAAC;IACb,KAAK,CAAC,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACtC,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACtB;AA8BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,sBAAsB,GAC5B,cAAc,EAAE,CAAC;AACpB,wBAAgB,gBAAgB,CAC/B,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,aAAa,EAAE,MAAM,GACnB,cAAc,EAAE,CAAC;AAiGpB;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,CAAC,EAC9C,UAAU,EAAE,cAAc,EAAE,EAC5B,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACrE,QAAQ,GAAE,OAAO,CAAC,oBAAoB,CAAM,GAC1C,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CA8ChC;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAKlF"}
|
|
@@ -74,7 +74,9 @@ export function getTopCandidates(accountManagerOrParams, modelFamily, model, max
|
|
|
74
74
|
clearExpiredRateLimits(account);
|
|
75
75
|
const isRateLimited = isRateLimitedForFamily(account, normalizedModelFamily, resolvedModel);
|
|
76
76
|
const isCoolingDown = account.coolingDownUntil !== undefined && account.coolingDownUntil > Date.now();
|
|
77
|
-
const
|
|
77
|
+
const isAuthInvalidated = typeof account.authInvalidatedAt === "number" &&
|
|
78
|
+
Number.isFinite(account.authInvalidatedAt);
|
|
79
|
+
const isAvailable = !isRateLimited && !isCoolingDown && !isAuthInvalidated;
|
|
78
80
|
accountsWithMetrics.push({
|
|
79
81
|
index: account.index,
|
|
80
82
|
trackerKey: getRuntimeTrackerKey(account),
|
|
@@ -15,6 +15,7 @@ export interface RuntimePolicyDecision {
|
|
|
15
15
|
reasons: string[];
|
|
16
16
|
projectKey: string | null;
|
|
17
17
|
blockedAccountIndexes: Set<number>;
|
|
18
|
+
blockedAccountReasons?: Record<number, string>;
|
|
18
19
|
scoreBoostByAccount: Record<number, number>;
|
|
19
20
|
budgetEvaluations: BudgetGuardEvaluation[];
|
|
20
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-policy.d.ts","sourceRoot":"","sources":["../../../lib/policy/runtime-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,OAAO,EAGN,KAAK,kBAAkB,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAKN,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEN,KAAK,4BAA4B,EACjC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,oBAAoB,EAGpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,iBAAiB,EAAE,qBAAqB,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IAClC,eAAe,EAAE,kBAAkB,CAAC;IACpC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,4BAA4B,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,WAAW,EAAE,MAAM,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACvC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,sBAAsB,CAC3C,QAAQ,SAAgB,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAO7B;AA6DD,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IAClD,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"runtime-policy.d.ts","sourceRoot":"","sources":["../../../lib/policy/runtime-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -70,6 +70,7 @@ export async function evaluateRuntimePolicy(input) {
|
|
|
70
70
|
const now = input.now ?? Date.now();
|
|
71
71
|
const reasons = [];
|
|
72
72
|
const blockedAccountIndexes = new Set();
|
|
73
|
+
const blockedAccountReasons = {};
|
|
73
74
|
const scoreBoostByAccount = {};
|
|
74
75
|
const profile = input.state.project.profile;
|
|
75
76
|
if (profile?.modelDenylist.length && matchesModel(profile.modelDenylist, input.model)) {
|
|
@@ -102,9 +103,13 @@ export async function evaluateRuntimePolicy(input) {
|
|
|
102
103
|
let boost = 0;
|
|
103
104
|
if (accountPolicy?.paused) {
|
|
104
105
|
blockedAccountIndexes.add(account.index);
|
|
106
|
+
blockedAccountReasons[account.index] = "policy: paused";
|
|
105
107
|
}
|
|
106
108
|
if (accountPolicy?.drained) {
|
|
107
109
|
blockedAccountIndexes.add(account.index);
|
|
110
|
+
blockedAccountReasons[account.index] = accountPolicy.paused
|
|
111
|
+
? "policy: paused, drained"
|
|
112
|
+
: "policy: drained";
|
|
108
113
|
}
|
|
109
114
|
if (accountPolicy) {
|
|
110
115
|
boost += (accountPolicy.weight - 1) * 2;
|
|
@@ -134,6 +139,7 @@ export async function evaluateRuntimePolicy(input) {
|
|
|
134
139
|
const capabilitySnapshot = input.capabilityPolicy?.getSnapshot(capabilityKey, input.model ?? "unknown");
|
|
135
140
|
if (capabilitySnapshot && capabilitySnapshot.unsupported > 0) {
|
|
136
141
|
blockedAccountIndexes.add(account.index);
|
|
142
|
+
blockedAccountReasons[account.index] = "policy: unsupported model";
|
|
137
143
|
}
|
|
138
144
|
scoreBoostByAccount[account.index] = boost;
|
|
139
145
|
}
|
|
@@ -146,6 +152,7 @@ export async function evaluateRuntimePolicy(input) {
|
|
|
146
152
|
reasons,
|
|
147
153
|
projectKey: input.state.project.projectKey,
|
|
148
154
|
blockedAccountIndexes,
|
|
155
|
+
blockedAccountReasons,
|
|
149
156
|
scoreBoostByAccount,
|
|
150
157
|
budgetEvaluations,
|
|
151
158
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preemptive-quota-scheduler.d.ts","sourceRoot":"","sources":["../../lib/preemptive-quota-scheduler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preemptive-quota-scheduler.d.ts","sourceRoot":"","sources":["../../lib/preemptive-quota-scheduler.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,oBAAoB,CAAC;IAC9B,SAAS,EAAE,oBAAoB,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,GAAG,uBAAuB,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,kCAAkC,CAAC,EAAE,MAAM,CAAC;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AA6GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,sBAAsB,GAAG,IAAI,CAqB5H;AAED,qBAAa,wBAAwB;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6C;IACvE,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,gCAAgC,CAAS;IACjD,OAAO,CAAC,kCAAkC,CAAS;IACnD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAK;gBAEZ,OAAO,GAAE,qBAA0B;IAQ/C,SAAS,CAAC,OAAO,GAAE,qBAA0B,GAAG,IAAI;IA2CpD,OAAO,CAAC,UAAU;IAMlB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAM3D,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IA8B1E,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,qBAAqB;IAkEjE,KAAK,CAAC,GAAG,SAAa,GAAG,MAAM;CAW/B"}
|
|
@@ -1,6 +1,31 @@
|
|
|
1
|
+
import { MAX_RATE_LIMIT_DELAY_MS } from "./constants.js";
|
|
1
2
|
import { quotaLeftPercentFromUsed } from "./quota-readiness.js";
|
|
2
3
|
const DEFAULT_REMAINING_PERCENT_THRESHOLD = 5;
|
|
3
4
|
const DEFAULT_MAX_DEFERRAL_MS = 2 * 60 * 60_000;
|
|
5
|
+
const MAX_TRUSTED_RESET_AGE_MS = MAX_RATE_LIMIT_DELAY_MS;
|
|
6
|
+
/**
|
|
7
|
+
* Return a reset wait only when the timestamp came from a recent, coherent snapshot.
|
|
8
|
+
* A future timestamp from an old or clock-invalid snapshot must not extend a
|
|
9
|
+
* preemptive cooldown beyond the configured fallback cap.
|
|
10
|
+
*/
|
|
11
|
+
function trustedResetWaitMs(window, snapshot, now) {
|
|
12
|
+
const resetAtMs = window.resetAtMs;
|
|
13
|
+
const updatedAt = snapshot.updatedAt;
|
|
14
|
+
if (typeof resetAtMs !== "number" ||
|
|
15
|
+
!Number.isFinite(resetAtMs) ||
|
|
16
|
+
typeof updatedAt !== "number" ||
|
|
17
|
+
!Number.isFinite(updatedAt) ||
|
|
18
|
+
updatedAt > now ||
|
|
19
|
+
now - updatedAt > MAX_TRUSTED_RESET_AGE_MS) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// An explicit reset that has already passed is healthy again. Do not turn
|
|
23
|
+
// an expired primary window into another fallback deferral merely because a
|
|
24
|
+
// secondary window keeps the aggregate snapshot alive.
|
|
25
|
+
if (resetAtMs <= now)
|
|
26
|
+
return 0;
|
|
27
|
+
return Math.min(resetAtMs - now, MAX_RATE_LIMIT_DELAY_MS);
|
|
28
|
+
}
|
|
4
29
|
/**
|
|
5
30
|
* Clamp a number to the inclusive integer range [min, max] after flooring.
|
|
6
31
|
*
|
|
@@ -194,16 +219,6 @@ export class PreemptiveQuotaScheduler {
|
|
|
194
219
|
const snapshot = this.snapshots.get(key);
|
|
195
220
|
if (!snapshot)
|
|
196
221
|
return { defer: false, waitMs: 0 };
|
|
197
|
-
const primaryWait = typeof snapshot.primary.resetAtMs === "number" &&
|
|
198
|
-
Number.isFinite(snapshot.primary.resetAtMs) &&
|
|
199
|
-
snapshot.primary.resetAtMs > now
|
|
200
|
-
? snapshot.primary.resetAtMs - now
|
|
201
|
-
: 0;
|
|
202
|
-
const secondaryWait = typeof snapshot.secondary.resetAtMs === "number" &&
|
|
203
|
-
Number.isFinite(snapshot.secondary.resetAtMs) &&
|
|
204
|
-
snapshot.secondary.resetAtMs > now
|
|
205
|
-
? snapshot.secondary.resetAtMs - now
|
|
206
|
-
: 0;
|
|
207
222
|
// For a 429 deferral, only count a window whose reset is genuinely a
|
|
208
223
|
// rate-limit / exhaustion window. A window carrying a healthy usedPercent
|
|
209
224
|
// (e.g. a weekly secondary at 30% from a prior 200 snapshot) is NOT the
|
|
@@ -235,12 +250,17 @@ export class PreemptiveQuotaScheduler {
|
|
|
235
250
|
const secondaryNearExhausted = typeof snapshot.secondary.usedPercent === "number" &&
|
|
236
251
|
Number.isFinite(snapshot.secondary.usedPercent) &&
|
|
237
252
|
snapshot.secondary.usedPercent >= 100 - this.secondaryRemainingPercentThreshold;
|
|
238
|
-
const
|
|
253
|
+
const getNearExhaustedWait = (window) => {
|
|
254
|
+
const trustedWait = trustedResetWaitMs(window, snapshot, now);
|
|
255
|
+
return trustedWait === null ? this.maxDeferralMs : trustedWait;
|
|
256
|
+
};
|
|
257
|
+
const nearExhaustedWait = Math.max(primaryNearExhausted && snapshot.status !== 429
|
|
258
|
+
? getNearExhaustedWait(snapshot.primary)
|
|
259
|
+
: 0, secondaryNearExhausted && snapshot.status !== 429
|
|
260
|
+
? getNearExhaustedWait(snapshot.secondary)
|
|
261
|
+
: 0);
|
|
239
262
|
if (nearExhaustedWait > 0) {
|
|
240
|
-
|
|
241
|
-
if (bounded > 0) {
|
|
242
|
-
return { defer: true, waitMs: bounded, reason: "quota-near-exhaustion" };
|
|
243
|
-
}
|
|
263
|
+
return { defer: true, waitMs: nearExhaustedWait, reason: "quota-near-exhaustion" };
|
|
244
264
|
}
|
|
245
265
|
return { defer: false, waitMs: 0 };
|
|
246
266
|
}
|
package/dist/lib/rotation.d.ts
CHANGED
|
@@ -92,6 +92,8 @@ export interface AccountWithMetrics {
|
|
|
92
92
|
index: number;
|
|
93
93
|
trackerKey?: TrackerKey;
|
|
94
94
|
isAvailable: boolean;
|
|
95
|
+
/** Runtime gate that made an unavailable account ineligible, for diagnostics. */
|
|
96
|
+
unavailableReason?: string;
|
|
95
97
|
lastUsed: number;
|
|
96
98
|
}
|
|
97
99
|
export interface HybridSelectionConfig {
|
|
@@ -115,6 +117,8 @@ export interface HybridSelectionConfig {
|
|
|
115
117
|
export interface HybridSelectionOptions {
|
|
116
118
|
pidOffsetEnabled?: boolean;
|
|
117
119
|
scoreBoostByAccount?: Record<number, number>;
|
|
120
|
+
blockedAccountIndexes?: ReadonlySet<number>;
|
|
121
|
+
blockedReasonByAccount?: Record<number, string>;
|
|
118
122
|
}
|
|
119
123
|
/**
|
|
120
124
|
* Named-parameter alternative for selectHybridAccount to avoid brittle positional arguments.
|