oc-codex-multi-auth 6.3.3 → 6.4.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.
Files changed (64) hide show
  1. package/README.md +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +21 -6
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/accounts/rotation.d.ts +17 -0
  6. package/dist/lib/accounts/rotation.d.ts.map +1 -1
  7. package/dist/lib/accounts/rotation.js +51 -0
  8. package/dist/lib/accounts/rotation.js.map +1 -1
  9. package/dist/lib/accounts/stale-state.d.ts +139 -0
  10. package/dist/lib/accounts/stale-state.d.ts.map +1 -0
  11. package/dist/lib/accounts/stale-state.js +192 -0
  12. package/dist/lib/accounts/stale-state.js.map +1 -0
  13. package/dist/lib/accounts/warm-request.d.ts +41 -0
  14. package/dist/lib/accounts/warm-request.d.ts.map +1 -0
  15. package/dist/lib/accounts/warm-request.js +97 -0
  16. package/dist/lib/accounts/warm-request.js.map +1 -0
  17. package/dist/lib/accounts/warm.d.ts +71 -0
  18. package/dist/lib/accounts/warm.d.ts.map +1 -0
  19. package/dist/lib/accounts/warm.js +86 -0
  20. package/dist/lib/accounts/warm.js.map +1 -0
  21. package/dist/lib/accounts.d.ts +9 -0
  22. package/dist/lib/accounts.d.ts.map +1 -1
  23. package/dist/lib/accounts.js +19 -0
  24. package/dist/lib/accounts.js.map +1 -1
  25. package/dist/lib/auth/login-runner.d.ts.map +1 -1
  26. package/dist/lib/auth/login-runner.js +5 -1
  27. package/dist/lib/auth/login-runner.js.map +1 -1
  28. package/dist/lib/config.d.ts +17 -0
  29. package/dist/lib/config.d.ts.map +1 -1
  30. package/dist/lib/config.js +30 -0
  31. package/dist/lib/config.js.map +1 -1
  32. package/dist/lib/constants.d.ts +11 -0
  33. package/dist/lib/constants.d.ts.map +1 -1
  34. package/dist/lib/constants.js +11 -0
  35. package/dist/lib/constants.js.map +1 -1
  36. package/dist/lib/request/fetch-helpers.d.ts +11 -0
  37. package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
  38. package/dist/lib/request/fetch-helpers.js +25 -0
  39. package/dist/lib/request/fetch-helpers.js.map +1 -1
  40. package/dist/lib/schemas.d.ts +5 -0
  41. package/dist/lib/schemas.d.ts.map +1 -1
  42. package/dist/lib/schemas.js +1 -0
  43. package/dist/lib/schemas.js.map +1 -1
  44. package/dist/lib/storage/identity.d.ts +1 -0
  45. package/dist/lib/storage/identity.d.ts.map +1 -1
  46. package/dist/lib/storage/identity.js +45 -2
  47. package/dist/lib/storage/identity.js.map +1 -1
  48. package/dist/lib/tools/codex-doctor.d.ts.map +1 -1
  49. package/dist/lib/tools/codex-doctor.js +110 -2
  50. package/dist/lib/tools/codex-doctor.js.map +1 -1
  51. package/dist/lib/tools/codex-health.d.ts.map +1 -1
  52. package/dist/lib/tools/codex-health.js +21 -0
  53. package/dist/lib/tools/codex-health.js.map +1 -1
  54. package/dist/lib/tools/codex-help.d.ts.map +1 -1
  55. package/dist/lib/tools/codex-help.js +1 -0
  56. package/dist/lib/tools/codex-help.js.map +1 -1
  57. package/dist/lib/tools/codex-warm.d.ts +33 -0
  58. package/dist/lib/tools/codex-warm.d.ts.map +1 -0
  59. package/dist/lib/tools/codex-warm.js +113 -0
  60. package/dist/lib/tools/codex-warm.js.map +1 -0
  61. package/dist/lib/tools/index.d.ts.map +1 -1
  62. package/dist/lib/tools/index.js +2 -0
  63. package/dist/lib/tools/index.js.map +1 -1
  64. package/package.json +7 -4
@@ -1 +1 @@
1
- {"version":3,"file":"rotation.js","sourceRoot":"","sources":["../../../lib/accounts/rotation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rotation.js","sourceRoot":"","sources":["../../../lib/accounts/rotation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Account stale-state repair helpers used by `codex-doctor --fix`.
3
+ *
4
+ * Background (issue #171): after a successful token refresh, an account can
5
+ * still be skipped by rotation because it carries stale account-health state
6
+ * that nothing in the normal request path clears:
7
+ *
8
+ * - an `auth-failure` / `network-error` cooldown left over from a transient
9
+ * failure that has since recovered, and/or
10
+ * - `rateLimitResetTimes` entries that point at a future reset that no longer
11
+ * reflects real quota (the user's own `--pure` requests succeed, proving the
12
+ * account is usable).
13
+ *
14
+ * A successful token refresh is strong, explicit evidence that the credential
15
+ * is alive, so when the user runs the explicit `--fix` repair we clear that
16
+ * stale state for the refreshed account. The next genuine 401/429 re-establishes
17
+ * accurate state, so the blast radius of clearing is a single real retry.
18
+ *
19
+ * These helpers are intentionally pure (operate on a mutable record, return what
20
+ * changed) so they can be unit-tested without the AccountManager or the plugin
21
+ * runtime.
22
+ */
23
+ /**
24
+ * Subset of a stored account record this module mutates. Kept permissive so the
25
+ * doctor can pass `AccountMetadataV3` records without coupling to the full
26
+ * schema shape.
27
+ */
28
+ export interface StaleStateAccount {
29
+ coolingDownUntil?: number;
30
+ cooldownReason?: string;
31
+ rateLimitResetTimes?: Record<string, number | undefined>;
32
+ }
33
+ export interface ClearedStaleState {
34
+ /** True when an active cooldown window was cleared. */
35
+ clearedCooldown: boolean;
36
+ /** Number of rate-limit reset entries removed. */
37
+ clearedRateLimitKeys: number;
38
+ }
39
+ /**
40
+ * Clear stale health state from an account that has just been proven healthy
41
+ * (its token refresh succeeded this run).
42
+ *
43
+ * - Removes any cooldown (`coolingDownUntil` / `cooldownReason`). A successful
44
+ * refresh contradicts both `auth-failure` (auth just worked) and
45
+ * `network-error` (the network call just worked) cooldowns.
46
+ * - Removes all `rateLimitResetTimes` entries. On an explicit repair, a stale
47
+ * future-dated reset is exactly the dark-state bug from #171; the next real
48
+ * 429 re-sets it accurately.
49
+ *
50
+ * @returns what was cleared, so the caller can report it.
51
+ */
52
+ export declare function clearRefreshedAccountStaleState(account: StaleStateAccount): ClearedStaleState;
53
+ export interface StaleStateRepairSummary {
54
+ /** Accounts that had an active cooldown cleared. */
55
+ cooldownsCleared: number;
56
+ /** Total rate-limit reset entries removed across all accounts. */
57
+ rateLimitKeysCleared: number;
58
+ }
59
+ /**
60
+ * Apply {@link clearRefreshedAccountStaleState} across the given accounts and
61
+ * return an aggregate summary. Only call this for accounts whose refresh
62
+ * succeeded.
63
+ */
64
+ export declare function clearRefreshedAccountsStaleState(accounts: StaleStateAccount[]): StaleStateRepairSummary;
65
+ /**
66
+ * Subset of a stored account used for duplicate detection. Permissive on
67
+ * purpose so callers can pass full `AccountMetadataV3` records.
68
+ */
69
+ export interface DuplicateScanAccount {
70
+ organizationId?: string;
71
+ accountIdSource?: string;
72
+ email?: string;
73
+ enabled?: boolean;
74
+ }
75
+ /**
76
+ * Detect disabled `token`-source duplicates that shadow an enabled,
77
+ * org-backed real account sharing the same email (issue #171).
78
+ *
79
+ * A fresh host re-login can mint a `accountIdSource: "token"` entry from the
80
+ * raw auth token instead of updating the matching `org`-source account. When
81
+ * that token entry is left `enabled: false`, it is harmless for rotation but
82
+ * pollutes diagnostics (account count, TUI quota cache index) and confuses
83
+ * recovery. We only *flag* these — never auto-remove — because a `token`-source
84
+ * and an `org`-source record are linked solely by email, and email-only merges
85
+ * are exactly what multi-org handling (#64) must not collapse blindly. Removal
86
+ * stays a user decision (`codex-remove`).
87
+ *
88
+ * @returns the 0-based indexes of disabled token-source duplicates.
89
+ */
90
+ export declare function findDisabledTokenSourceDuplicates(accounts: DuplicateScanAccount[]): number[];
91
+ /**
92
+ * Subset of a stored account used for the read-only stale-state diagnostic.
93
+ */
94
+ export interface StaleStateScanAccount {
95
+ enabled?: boolean;
96
+ coolingDownUntil?: number;
97
+ cooldownReason?: string;
98
+ rateLimitResetTimes?: Record<string, number | undefined>;
99
+ }
100
+ /**
101
+ * Identify enabled accounts that are currently blocked ONLY by a future-dated
102
+ * cooldown and/or future-dated rate-limit reset — i.e. the exact dark state from
103
+ * issue #171 that `codex-doctor --fix` can recover (a successful token refresh
104
+ * proves the credential is alive, so the block is stale).
105
+ *
106
+ * This is read-only (it mutates nothing) so both `codex-health` and the
107
+ * non-`--fix` `codex-doctor` path can surface the finding and point the user at
108
+ * the repair. Expired cooldowns / rate-limits are ignored because the normal
109
+ * request path already clears those.
110
+ *
111
+ * @returns the 0-based indexes of accounts blocked by recoverable stale state.
112
+ */
113
+ export declare function findStaleRecoverableAccounts(accounts: StaleStateScanAccount[], now?: number): number[];
114
+ /**
115
+ * Subset of a stored account used for the absorbed-credential diagnostic.
116
+ */
117
+ export interface FreshCredentialScanAccount {
118
+ enabled?: boolean;
119
+ expiresAt?: number;
120
+ accessToken?: string;
121
+ }
122
+ /**
123
+ * Identify accounts that are DISABLED yet carry a fresh (unexpired) access
124
+ * token — the fingerprint of a user-disabled account that absorbed a newer
125
+ * enabled re-login during dedup (issue #171).
126
+ *
127
+ * The merge is intentionally fail-closed: a user-disabled record stays disabled
128
+ * even after it absorbs a fresh credential. That is correct, but it is silent —
129
+ * the absorbing record is org-source AND disabled, so it is skipped by every
130
+ * other #171 diagnostic and the user gets no hint that a fresh login they just
131
+ * performed landed on a deliberately-disabled slot. This read-only detector
132
+ * surfaces that case so tooling can suggest re-enabling the account if intended.
133
+ *
134
+ * Read-only: mutates nothing, and never re-enables (that stays a user decision).
135
+ *
136
+ * @returns the 0-based indexes of disabled accounts holding a fresh credential.
137
+ */
138
+ export declare function findDisabledAccountsWithFreshCredential(accounts: FreshCredentialScanAccount[], now?: number): number[];
139
+ //# sourceMappingURL=stale-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-state.d.ts","sourceRoot":"","sources":["../../../lib/accounts/stale-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,iBAAiB;IACjC,uDAAuD;IACvD,eAAe,EAAE,OAAO,CAAC;IACzB,kDAAkD;IAClD,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAC9C,OAAO,EAAE,iBAAiB,GACxB,iBAAiB,CAsBnB;AAED,MAAM,WAAW,uBAAuB;IACvC,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC/C,QAAQ,EAAE,iBAAiB,EAAE,GAC3B,uBAAuB,CASzB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iCAAiC,CAChD,QAAQ,EAAE,oBAAoB,EAAE,GAC9B,MAAM,EAAE,CAgCV;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,qBAAqB,EAAE,EACjC,GAAG,GAAE,MAAgB,GACnB,MAAM,EAAE,CAyBV;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uCAAuC,CACtD,QAAQ,EAAE,0BAA0B,EAAE,EACtC,GAAG,GAAE,MAAgB,GACnB,MAAM,EAAE,CAeV"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Account stale-state repair helpers used by `codex-doctor --fix`.
3
+ *
4
+ * Background (issue #171): after a successful token refresh, an account can
5
+ * still be skipped by rotation because it carries stale account-health state
6
+ * that nothing in the normal request path clears:
7
+ *
8
+ * - an `auth-failure` / `network-error` cooldown left over from a transient
9
+ * failure that has since recovered, and/or
10
+ * - `rateLimitResetTimes` entries that point at a future reset that no longer
11
+ * reflects real quota (the user's own `--pure` requests succeed, proving the
12
+ * account is usable).
13
+ *
14
+ * A successful token refresh is strong, explicit evidence that the credential
15
+ * is alive, so when the user runs the explicit `--fix` repair we clear that
16
+ * stale state for the refreshed account. The next genuine 401/429 re-establishes
17
+ * accurate state, so the blast radius of clearing is a single real retry.
18
+ *
19
+ * These helpers are intentionally pure (operate on a mutable record, return what
20
+ * changed) so they can be unit-tested without the AccountManager or the plugin
21
+ * runtime.
22
+ */
23
+ import { nowMs } from "../utils.js";
24
+ /**
25
+ * Clear stale health state from an account that has just been proven healthy
26
+ * (its token refresh succeeded this run).
27
+ *
28
+ * - Removes any cooldown (`coolingDownUntil` / `cooldownReason`). A successful
29
+ * refresh contradicts both `auth-failure` (auth just worked) and
30
+ * `network-error` (the network call just worked) cooldowns.
31
+ * - Removes all `rateLimitResetTimes` entries. On an explicit repair, a stale
32
+ * future-dated reset is exactly the dark-state bug from #171; the next real
33
+ * 429 re-sets it accurately.
34
+ *
35
+ * @returns what was cleared, so the caller can report it.
36
+ */
37
+ export function clearRefreshedAccountStaleState(account) {
38
+ const now = nowMs();
39
+ const hadActiveCooldown = typeof account.coolingDownUntil === "number" && account.coolingDownUntil > now;
40
+ if (account.coolingDownUntil !== undefined || account.cooldownReason !== undefined) {
41
+ delete account.coolingDownUntil;
42
+ delete account.cooldownReason;
43
+ }
44
+ let clearedRateLimitKeys = 0;
45
+ if (account.rateLimitResetTimes) {
46
+ clearedRateLimitKeys = Object.keys(account.rateLimitResetTimes).length;
47
+ if (clearedRateLimitKeys > 0) {
48
+ account.rateLimitResetTimes = {};
49
+ }
50
+ }
51
+ return {
52
+ clearedCooldown: hadActiveCooldown,
53
+ clearedRateLimitKeys,
54
+ };
55
+ }
56
+ /**
57
+ * Apply {@link clearRefreshedAccountStaleState} across the given accounts and
58
+ * return an aggregate summary. Only call this for accounts whose refresh
59
+ * succeeded.
60
+ */
61
+ export function clearRefreshedAccountsStaleState(accounts) {
62
+ let cooldownsCleared = 0;
63
+ let rateLimitKeysCleared = 0;
64
+ for (const account of accounts) {
65
+ const cleared = clearRefreshedAccountStaleState(account);
66
+ if (cleared.clearedCooldown)
67
+ cooldownsCleared += 1;
68
+ rateLimitKeysCleared += cleared.clearedRateLimitKeys;
69
+ }
70
+ return { cooldownsCleared, rateLimitKeysCleared };
71
+ }
72
+ /**
73
+ * Detect disabled `token`-source duplicates that shadow an enabled,
74
+ * org-backed real account sharing the same email (issue #171).
75
+ *
76
+ * A fresh host re-login can mint a `accountIdSource: "token"` entry from the
77
+ * raw auth token instead of updating the matching `org`-source account. When
78
+ * that token entry is left `enabled: false`, it is harmless for rotation but
79
+ * pollutes diagnostics (account count, TUI quota cache index) and confuses
80
+ * recovery. We only *flag* these — never auto-remove — because a `token`-source
81
+ * and an `org`-source record are linked solely by email, and email-only merges
82
+ * are exactly what multi-org handling (#64) must not collapse blindly. Removal
83
+ * stays a user decision (`codex-remove`).
84
+ *
85
+ * @returns the 0-based indexes of disabled token-source duplicates.
86
+ */
87
+ export function findDisabledTokenSourceDuplicates(accounts) {
88
+ const enabledOrgEmails = new Set();
89
+ for (const account of accounts) {
90
+ const email = account.email?.trim().toLowerCase();
91
+ if (!email)
92
+ continue;
93
+ const isEnabled = account.enabled !== false;
94
+ const isOrgBacked = account.accountIdSource === "org" ||
95
+ (typeof account.organizationId === "string" && account.organizationId.trim().length > 0);
96
+ if (isEnabled && isOrgBacked) {
97
+ enabledOrgEmails.add(email);
98
+ }
99
+ }
100
+ if (enabledOrgEmails.size === 0)
101
+ return [];
102
+ const duplicates = [];
103
+ for (let i = 0; i < accounts.length; i += 1) {
104
+ const account = accounts[i];
105
+ if (!account)
106
+ continue;
107
+ if (account.enabled !== false)
108
+ continue;
109
+ if (account.accountIdSource !== "token")
110
+ continue;
111
+ const hasOrg = typeof account.organizationId === "string" && account.organizationId.trim().length > 0;
112
+ if (hasOrg)
113
+ continue;
114
+ const email = account.email?.trim().toLowerCase();
115
+ if (!email)
116
+ continue;
117
+ if (enabledOrgEmails.has(email)) {
118
+ duplicates.push(i);
119
+ }
120
+ }
121
+ return duplicates;
122
+ }
123
+ /**
124
+ * Identify enabled accounts that are currently blocked ONLY by a future-dated
125
+ * cooldown and/or future-dated rate-limit reset — i.e. the exact dark state from
126
+ * issue #171 that `codex-doctor --fix` can recover (a successful token refresh
127
+ * proves the credential is alive, so the block is stale).
128
+ *
129
+ * This is read-only (it mutates nothing) so both `codex-health` and the
130
+ * non-`--fix` `codex-doctor` path can surface the finding and point the user at
131
+ * the repair. Expired cooldowns / rate-limits are ignored because the normal
132
+ * request path already clears those.
133
+ *
134
+ * @returns the 0-based indexes of accounts blocked by recoverable stale state.
135
+ */
136
+ export function findStaleRecoverableAccounts(accounts, now = nowMs()) {
137
+ const blocked = [];
138
+ for (let i = 0; i < accounts.length; i += 1) {
139
+ const account = accounts[i];
140
+ if (!account)
141
+ continue;
142
+ if (account.enabled === false)
143
+ continue;
144
+ const hasFutureCooldown = typeof account.coolingDownUntil === "number" && account.coolingDownUntil > now;
145
+ let hasFutureRateLimit = false;
146
+ if (account.rateLimitResetTimes) {
147
+ for (const reset of Object.values(account.rateLimitResetTimes)) {
148
+ if (typeof reset === "number" && reset > now) {
149
+ hasFutureRateLimit = true;
150
+ break;
151
+ }
152
+ }
153
+ }
154
+ if (hasFutureCooldown || hasFutureRateLimit) {
155
+ blocked.push(i);
156
+ }
157
+ }
158
+ return blocked;
159
+ }
160
+ /**
161
+ * Identify accounts that are DISABLED yet carry a fresh (unexpired) access
162
+ * token — the fingerprint of a user-disabled account that absorbed a newer
163
+ * enabled re-login during dedup (issue #171).
164
+ *
165
+ * The merge is intentionally fail-closed: a user-disabled record stays disabled
166
+ * even after it absorbs a fresh credential. That is correct, but it is silent —
167
+ * the absorbing record is org-source AND disabled, so it is skipped by every
168
+ * other #171 diagnostic and the user gets no hint that a fresh login they just
169
+ * performed landed on a deliberately-disabled slot. This read-only detector
170
+ * surfaces that case so tooling can suggest re-enabling the account if intended.
171
+ *
172
+ * Read-only: mutates nothing, and never re-enables (that stays a user decision).
173
+ *
174
+ * @returns the 0-based indexes of disabled accounts holding a fresh credential.
175
+ */
176
+ export function findDisabledAccountsWithFreshCredential(accounts, now = nowMs()) {
177
+ const flagged = [];
178
+ for (let i = 0; i < accounts.length; i += 1) {
179
+ const account = accounts[i];
180
+ if (!account)
181
+ continue;
182
+ if (account.enabled !== false)
183
+ continue;
184
+ const hasToken = typeof account.accessToken === "string" && account.accessToken.length > 0;
185
+ const fresh = typeof account.expiresAt === "number" && account.expiresAt > now;
186
+ if (hasToken && fresh) {
187
+ flagged.push(i);
188
+ }
189
+ }
190
+ return flagged;
191
+ }
192
+ //# sourceMappingURL=stale-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-state.js","sourceRoot":"","sources":["../../../lib/accounts/stale-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Real upstream "warm" request for issue #182.
3
+ *
4
+ * Sends a single minimal billable request to `POST /codex/responses` — the
5
+ * same endpoint and request shape the live request path uses for its quota
6
+ * probe — so the account's rolling usage window actually starts. A read-only
7
+ * `GET /wham/usage` does NOT open the window (it only reports server-side
8
+ * windows that already exist), so warming must send a genuine inference
9
+ * request. The body is deliberately tiny (reasoning effort "none", verbosity
10
+ * "low", no stored conversation) to keep the quota cost negligible, and mirrors
11
+ * the proven quota-probe request shape used by the live request path.
12
+ *
13
+ * This module owns the network side-effect; the pure iteration/summary logic
14
+ * lives in `warm.ts` and is injected this function via `codex-warm.ts`.
15
+ */
16
+ import type { RequestBody } from "../types.js";
17
+ export interface WarmRequestParams {
18
+ accountId: string;
19
+ accessToken: string;
20
+ organizationId: string | undefined;
21
+ /** Override the timeout (tests). */
22
+ timeoutMs?: number;
23
+ /** Injectable fetch for tests; defaults to global fetch. */
24
+ fetchImpl?: typeof fetch;
25
+ }
26
+ /**
27
+ * Build the minimal warm-ping request body. Exported for tests so the exact
28
+ * shape (stream/store/reasoning) stays pinned.
29
+ */
30
+ export declare function buildWarmRequestBody(model?: string): Promise<RequestBody>;
31
+ /**
32
+ * Send one warm request to open the account's usage window.
33
+ *
34
+ * Resolves `true` when the upstream accepted the request enough to start the
35
+ * window. A 2xx clearly opens it; a 429 (rate-limited) means the window is
36
+ * already open/active, which still satisfies the user intent ("the window is
37
+ * ticking"). Any other non-2xx, or a network/timeout error, throws so the
38
+ * caller records the account as failed.
39
+ */
40
+ export declare function warmAccountWindow(params: WarmRequestParams): Promise<boolean>;
41
+ //# sourceMappingURL=warm-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warm-request.d.ts","sourceRoot":"","sources":["../../../lib/accounts/warm-request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW/C,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,SAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBnF;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CA4CnF"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Real upstream "warm" request for issue #182.
3
+ *
4
+ * Sends a single minimal billable request to `POST /codex/responses` — the
5
+ * same endpoint and request shape the live request path uses for its quota
6
+ * probe — so the account's rolling usage window actually starts. A read-only
7
+ * `GET /wham/usage` does NOT open the window (it only reports server-side
8
+ * windows that already exist), so warming must send a genuine inference
9
+ * request. The body is deliberately tiny (reasoning effort "none", verbosity
10
+ * "low", no stored conversation) to keep the quota cost negligible, and mirrors
11
+ * the proven quota-probe request shape used by the live request path.
12
+ *
13
+ * This module owns the network side-effect; the pure iteration/summary logic
14
+ * lives in `warm.ts` and is injected this function via `codex-warm.ts`.
15
+ */
16
+ import { CODEX_BASE_URL } from "../constants.js";
17
+ import { createCodexHeaders } from "../request/fetch-helpers.js";
18
+ import { getCodexInstructions } from "../prompts/codex.js";
19
+ import { createLogger } from "../logger.js";
20
+ const log = createLogger("warm-request");
21
+ /** Model used for the warm ping. Mirrors the live quota-probe default. */
22
+ const WARM_MODEL = "gpt-5.4";
23
+ /** Hard ceiling on a warm request so a hung upstream cannot wedge the batch. */
24
+ const WARM_TIMEOUT_MS = 15_000;
25
+ /**
26
+ * Build the minimal warm-ping request body. Exported for tests so the exact
27
+ * shape (stream/store/reasoning) stays pinned.
28
+ */
29
+ export async function buildWarmRequestBody(model = WARM_MODEL) {
30
+ const instructions = await getCodexInstructions(model);
31
+ return {
32
+ model,
33
+ stream: true,
34
+ store: false,
35
+ include: ["reasoning.encrypted_content"],
36
+ instructions,
37
+ input: [
38
+ {
39
+ type: "message",
40
+ role: "user",
41
+ content: [{ type: "input_text", text: "warm ping" }],
42
+ },
43
+ ],
44
+ reasoning: { effort: "none", summary: "auto" },
45
+ text: { verbosity: "low" },
46
+ };
47
+ }
48
+ /**
49
+ * Send one warm request to open the account's usage window.
50
+ *
51
+ * Resolves `true` when the upstream accepted the request enough to start the
52
+ * window. A 2xx clearly opens it; a 429 (rate-limited) means the window is
53
+ * already open/active, which still satisfies the user intent ("the window is
54
+ * ticking"). Any other non-2xx, or a network/timeout error, throws so the
55
+ * caller records the account as failed.
56
+ */
57
+ export async function warmAccountWindow(params) {
58
+ const doFetch = params.fetchImpl ?? fetch;
59
+ const body = await buildWarmRequestBody();
60
+ const headers = createCodexHeaders(undefined, params.accountId, params.accessToken, {
61
+ model: WARM_MODEL,
62
+ organizationId: params.organizationId,
63
+ });
64
+ const controller = new AbortController();
65
+ const timeout = setTimeout(() => controller.abort(), params.timeoutMs ?? WARM_TIMEOUT_MS);
66
+ try {
67
+ const response = await doFetch(`${CODEX_BASE_URL}/codex/responses`, {
68
+ method: "POST",
69
+ headers,
70
+ body: JSON.stringify(body),
71
+ signal: controller.signal,
72
+ });
73
+ // Drain/cancel the SSE stream immediately — we only needed to start the
74
+ // window, not consume the response.
75
+ try {
76
+ await response.body?.cancel();
77
+ }
78
+ catch {
79
+ // Ignore cancellation failures.
80
+ }
81
+ if (response.ok)
82
+ return true;
83
+ // 429 = window already open and currently rate-limited. The user's goal
84
+ // (window is ticking) is satisfied, so treat it as a successful warm.
85
+ if (response.status === 429) {
86
+ log.debug("Warm ping hit 429 — window already active", {
87
+ accountId: params.accountId,
88
+ });
89
+ return true;
90
+ }
91
+ throw new Error(`Warm request failed: HTTP ${response.status}`);
92
+ }
93
+ finally {
94
+ clearTimeout(timeout);
95
+ }
96
+ }
97
+ //# sourceMappingURL=warm-request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warm-request.js","sourceRoot":"","sources":["../../../lib/accounts/warm-request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;AAEzC,0EAA0E;AAC1E,MAAM,UAAU,GAAG,SAAS,CAAC;AAE7B,gFAAgF;AAChF,MAAM,eAAe,GAAG,MAAM,CAAC;AAY/B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAK,GAAG,UAAU;IAC5D,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACvD,OAAO;QACN,KAAK;QACL,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,CAAC,6BAA6B,CAAC;QACxC,YAAY;QACZ,KAAK,EAAE;YACN;gBACC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;aACpD;SACD;QACD,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;QAC9C,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;KAC1B,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAyB;IAChE,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,oBAAoB,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,EAAE;QACnF,KAAK,EAAE,UAAU;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc;KACrC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CACzB,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EACxB,MAAM,CAAC,SAAS,IAAI,eAAe,CACnC,CAAC;IACF,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,cAAc,kBAAkB,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;SACzB,CAAC,CAAC;QAEH,wEAAwE;QACxE,oCAAoC;QACpC,IAAI,CAAC;YACJ,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACR,gCAAgC;QACjC,CAAC;QAED,IAAI,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAE7B,wEAAwE;QACxE,sEAAsE;QACtE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC7B,GAAG,CAAC,KAAK,CAAC,2CAA2C,EAAE;gBACtD,SAAS,EAAE,MAAM,CAAC,SAAS;aAC3B,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;YAAS,CAAC;QACV,YAAY,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;AACF,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Account "warm-up" orchestrator (issue #182).
3
+ *
4
+ * Sends one minimal request to each enabled account so its rolling usage
5
+ * window (the ~5h ChatGPT/Codex quota window) starts ticking immediately,
6
+ * rather than only when the rotation eventually lands on that account. This
7
+ * lets users prime every account at the start of a session ("send a hi to each
8
+ * account") instead of waiting for the current account to run dry.
9
+ *
10
+ * This module is intentionally pure: it contains the iteration, outcome
11
+ * classification, and summary logic, but performs no network or auth I/O
12
+ * itself. The real upstream call is injected as `warmOne`, which keeps this
13
+ * logic fully deterministic and unit-testable, and keeps the network-touching
14
+ * adapter isolated in the `codex-warm` tool. The split mirrors how
15
+ * `lib/rotation.ts` (pure selection) is separated from `lib/accounts/rotation.ts`
16
+ * (the manager-facing wrapper).
17
+ */
18
+ /**
19
+ * Per-account result of a warm attempt.
20
+ *
21
+ * - `warmed`: the upstream request succeeded; the window is now open.
22
+ * - `failed`: the upstream request was attempted but errored (auth invalid,
23
+ * network error, upstream 5xx, etc.). `detail` carries a short reason.
24
+ * - `skipped`: the account was not attempted (e.g. disabled). `detail` says why.
25
+ */
26
+ export type WarmStatus = "warmed" | "failed" | "skipped";
27
+ export interface WarmOutcome {
28
+ status: WarmStatus;
29
+ /** Short human-readable reason, primarily for `failed` / `skipped`. */
30
+ detail?: string;
31
+ }
32
+ /** A warm result paired with the account it belongs to. */
33
+ export interface WarmAccountResult<A> {
34
+ account: A;
35
+ /** Zero-based position in the input list (stable for display ordering). */
36
+ index: number;
37
+ status: WarmStatus;
38
+ detail?: string;
39
+ }
40
+ export interface WarmSummary<A> {
41
+ results: WarmAccountResult<A>[];
42
+ warmedCount: number;
43
+ failedCount: number;
44
+ skippedCount: number;
45
+ /** Total accounts considered (= results.length). */
46
+ total: number;
47
+ }
48
+ export interface WarmAccountsOptions {
49
+ /**
50
+ * Run warm attempts concurrently (default) or strictly one at a time.
51
+ * Sequential mode is useful when the caller wants to avoid bursting the
52
+ * upstream with parallel requests. Defaults to `true` (concurrent).
53
+ */
54
+ concurrent?: boolean;
55
+ }
56
+ /**
57
+ * Warm every account in `accounts` by invoking `warmOne` on each one that is
58
+ * eligible, then summarize the outcomes.
59
+ *
60
+ * `warmOne` must resolve (never reject) — but to be defensive against an
61
+ * injected function that throws or rejects, any thrown error is captured and
62
+ * recorded as a `failed` outcome so a single bad account can never abort the
63
+ * whole batch.
64
+ *
65
+ * The returned `results` array preserves the input order regardless of
66
+ * concurrency, so display output is deterministic.
67
+ */
68
+ export declare function warmAccounts<A extends {
69
+ enabled?: boolean;
70
+ }>(accounts: readonly A[], warmOne: (account: A, index: number) => Promise<WarmOutcome>, options?: WarmAccountsOptions): Promise<WarmSummary<A>>;
71
+ //# sourceMappingURL=warm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warm.d.ts","sourceRoot":"","sources":["../../../lib/accounts/warm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB,CAAC,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC;IACX,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC7B,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAUD;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EACjE,QAAQ,EAAE,SAAS,CAAC,EAAE,EACtB,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,EAC5D,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAgDzB"}