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.
- package/README.md +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts/rotation.d.ts +17 -0
- package/dist/lib/accounts/rotation.d.ts.map +1 -1
- package/dist/lib/accounts/rotation.js +51 -0
- package/dist/lib/accounts/rotation.js.map +1 -1
- package/dist/lib/accounts/stale-state.d.ts +139 -0
- package/dist/lib/accounts/stale-state.d.ts.map +1 -0
- package/dist/lib/accounts/stale-state.js +192 -0
- package/dist/lib/accounts/stale-state.js.map +1 -0
- package/dist/lib/accounts/warm-request.d.ts +41 -0
- package/dist/lib/accounts/warm-request.d.ts.map +1 -0
- package/dist/lib/accounts/warm-request.js +97 -0
- package/dist/lib/accounts/warm-request.js.map +1 -0
- package/dist/lib/accounts/warm.d.ts +71 -0
- package/dist/lib/accounts/warm.d.ts.map +1 -0
- package/dist/lib/accounts/warm.js +86 -0
- package/dist/lib/accounts/warm.js.map +1 -0
- package/dist/lib/accounts.d.ts +9 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +19 -0
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/auth/login-runner.d.ts.map +1 -1
- package/dist/lib/auth/login-runner.js +5 -1
- package/dist/lib/auth/login-runner.js.map +1 -1
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +30 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +11 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +11 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/request/fetch-helpers.d.ts +11 -0
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/request/fetch-helpers.js +25 -0
- package/dist/lib/request/fetch-helpers.js.map +1 -1
- package/dist/lib/schemas.d.ts +5 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +1 -0
- package/dist/lib/schemas.js.map +1 -1
- package/dist/lib/storage/identity.d.ts +1 -0
- package/dist/lib/storage/identity.d.ts.map +1 -1
- package/dist/lib/storage/identity.js +45 -2
- package/dist/lib/storage/identity.js.map +1 -1
- package/dist/lib/tools/codex-doctor.d.ts.map +1 -1
- package/dist/lib/tools/codex-doctor.js +110 -2
- package/dist/lib/tools/codex-doctor.js.map +1 -1
- package/dist/lib/tools/codex-health.d.ts.map +1 -1
- package/dist/lib/tools/codex-health.js +21 -0
- package/dist/lib/tools/codex-health.js.map +1 -1
- package/dist/lib/tools/codex-help.d.ts.map +1 -1
- package/dist/lib/tools/codex-help.js +1 -0
- package/dist/lib/tools/codex-help.js.map +1 -1
- package/dist/lib/tools/codex-warm.d.ts +33 -0
- package/dist/lib/tools/codex-warm.d.ts.map +1 -0
- package/dist/lib/tools/codex-warm.js +113 -0
- package/dist/lib/tools/codex-warm.js.map +1 -0
- package/dist/lib/tools/index.d.ts.map +1 -1
- package/dist/lib/tools/index.js +2 -0
- package/dist/lib/tools/index.js.map +1 -1
- package/package.json +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"}
|