maxpool 1.15.0 → 1.16.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/package.json +1 -1
- package/src/tui.js +91 -28
package/package.json
CHANGED
package/src/tui.js
CHANGED
|
@@ -162,22 +162,54 @@ function countdown(ts) {
|
|
|
162
162
|
return `${Math.ceil(ms / 86_400_000)}d`;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
/** ACTIVITY cell — "is this account working, and is it healthy?" in as few glyphs
|
|
166
|
+
* as that question needs. Rewritten 2026-08-27 on owner feedback: the old form
|
|
167
|
+
* ("Now 0 15m 0r 1h 0r") printed three numbers on EVERY row, and on a resting
|
|
168
|
+
* account all three were zero — a column of noise whose vocabulary ("now", then
|
|
169
|
+
* some minutes, then hours) nobody could read. An idle account now renders
|
|
170
|
+
* NOTHING, and a working one renders live · rate · latency.
|
|
171
|
+
*
|
|
172
|
+
* ▶2 · 17/h · 8.5s 2 in flight, 17 requests in the last hour, 8.5s average
|
|
173
|
+
* 17/h · 8.5s idle this second, but working
|
|
174
|
+
* 17/h · 8.5s 2f …with 2 failures in the last 15m
|
|
175
|
+
* (blank) resting — nothing to say
|
|
176
|
+
*/
|
|
165
177
|
function loadText(load) {
|
|
166
|
-
const
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
178
|
+
const inflight = load?.current?.inFlight || 0;
|
|
179
|
+
const hourReq = load?.last1h?.requests || 0;
|
|
180
|
+
const failed = load?.last15m?.failed || 0;
|
|
181
|
+
if (!inflight && !hourReq && !failed) return '';
|
|
182
|
+
const parts = [];
|
|
183
|
+
if (inflight) parts.push(`▶${inflight}`);
|
|
184
|
+
if (hourReq) parts.push(`${hourReq}/h`);
|
|
185
|
+
const avg = load?.last15m?.avgMs ?? load?.last1h?.avgMs;
|
|
186
|
+
if (avg != null && hourReq) parts.push(formatMs(avg));
|
|
187
|
+
let s = parts.join(' · ');
|
|
188
|
+
if (failed) s += ` ${red(`${failed}f`)}`;
|
|
189
|
+
return s;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** The usage CAP is an account PROPERTY, not a state — so it renders whenever one
|
|
193
|
+
* is set, on every account type, whatever the account is doing. It previously
|
|
194
|
+
* lived inline in the provider branch only, so the OAuth account the feature was
|
|
195
|
+
* built for (max@gomokka.com) showed no cap anywhere: reported 2026-08-27, "I need
|
|
196
|
+
* to be able to see whether an account has a cap or not." Yellow while the cap is
|
|
197
|
+
* actively holding traffic back, dim otherwise. */
|
|
198
|
+
function capText(a, benched) {
|
|
199
|
+
if (a?.capUtilization == null) return '';
|
|
200
|
+
const t = `cap ${Math.round(a.capUtilization * 100)}%`;
|
|
201
|
+
return benched ? yellow(t) : dim(t);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** True when the reservation is what is currently keeping traffic off this account
|
|
205
|
+
* — either window at or past the cap. Reads the manager's own predicate so the
|
|
206
|
+
* label can never disagree with routing. */
|
|
207
|
+
function capBenched(am, a) {
|
|
208
|
+
if (a?.capUtilization == null) return false;
|
|
209
|
+
const q = a.quota || {};
|
|
210
|
+
const ses = a.type === 'provider' ? q.providerSes : q.unified5h;
|
|
211
|
+
const wk = a.type === 'provider' ? q.providerWk : q.unified7d;
|
|
212
|
+
return !!(am?._capped?.(a, ses) || am?._capped?.(a, wk));
|
|
181
213
|
}
|
|
182
214
|
|
|
183
215
|
export function weeklyPolicyText(am, account) {
|
|
@@ -190,6 +222,14 @@ export function weeklyPolicyText(am, account) {
|
|
|
190
222
|
return yellow(`Cap ${Math.round((account.capUtilization || 0) * 100)}%`);
|
|
191
223
|
}
|
|
192
224
|
if (!state || state === 'unknown' || state === 'normal') return '';
|
|
225
|
+
// SAY IT ONCE (2026-08-27). An account Anthropic is rejecting outright already
|
|
226
|
+
// says so twice on this row: the Wk bar reads 100%, and the Status column reads
|
|
227
|
+
// "exhausted". A third "Wk exhausted 100%" tag was pure repetition, and it pushed
|
|
228
|
+
// the genuinely-informative tags (Cap, a per-model sub-limit) off to the right.
|
|
229
|
+
// Dropped ONLY when the Status column carries the same fact — a soft/reserve/
|
|
230
|
+
// critical row, or an exhausted-by-threshold row the status column shows as
|
|
231
|
+
// "active", still needs the tag.
|
|
232
|
+
if (am._isAccountWideRejected?.(account)) return '';
|
|
193
233
|
const rawState = am._weeklyRawState?.(account) || state;
|
|
194
234
|
const used = Number(account.quota?.unified7d);
|
|
195
235
|
const pct = Number.isFinite(used)
|
|
@@ -1738,7 +1778,7 @@ export class TUI {
|
|
|
1738
1778
|
// Glossary FOOTER (expands the abbreviations the header + inline labels can't
|
|
1739
1779
|
// spell out). Below the rows so it never breaks the header↔column alignment.
|
|
1740
1780
|
if (W >= 88) {
|
|
1741
|
-
lines.push(' ' + dim('Legend Ses = 5h · Wk = 7d ·
|
|
1781
|
+
lines.push(' ' + dim('Legend Ses = 5h · Wk = 7d · ▶ = in-flight · /h = requests last hour · avg latency · f = fails'));
|
|
1742
1782
|
}
|
|
1743
1783
|
}
|
|
1744
1784
|
|
|
@@ -1859,13 +1899,16 @@ export class TUI {
|
|
|
1859
1899
|
if (a.enabled !== false && upstreamBlocking && a.status === 'active') {
|
|
1860
1900
|
effectiveStatus = a.inFlight > 0 ? 'probing' : 'waiting';
|
|
1861
1901
|
}
|
|
1862
|
-
//
|
|
1863
|
-
//
|
|
1864
|
-
//
|
|
1865
|
-
//
|
|
1866
|
-
//
|
|
1902
|
+
// Anthropic is rejecting the WHOLE account (a 'rejected' unified status
|
|
1903
|
+
// corroborated by an exhausted unified bucket). A per-model cap (Fable) is NOT
|
|
1904
|
+
// account-wide — it shows as the separate "… maxed" tag, leaving the status
|
|
1905
|
+
// column truthful. Keys on a.status (not effectiveStatus) so a genuine block
|
|
1906
|
+
// wins even inside an upstream-throttle window.
|
|
1907
|
+
// Named "exhausted", not "blocked" (2026-08-27): the row's own quota bar and
|
|
1908
|
+
// every other surface call this state exhausted, and two words for one state
|
|
1909
|
+
// read as two different problems.
|
|
1867
1910
|
if (a.enabled !== false && a.status === 'active' && this.am._isAccountWideRejected?.(a)) {
|
|
1868
|
-
effectiveStatus = '
|
|
1911
|
+
effectiveStatus = 'exhausted';
|
|
1869
1912
|
}
|
|
1870
1913
|
// A dead refresh token surfaces as "reauth" (re-login needed) rather than a
|
|
1871
1914
|
// generic "error", so the user knows the fix. Display-only — account.status
|
|
@@ -1879,7 +1922,7 @@ export class TUI {
|
|
|
1879
1922
|
switch (effectiveStatus) {
|
|
1880
1923
|
case 'active': status = isCur ? green('active') : 'active'; break;
|
|
1881
1924
|
case 'reauth': status = yellow('reauth'); break;
|
|
1882
|
-
case 'blocked': status = red('
|
|
1925
|
+
case 'blocked': status = red('exhausted'); break;
|
|
1883
1926
|
case 'probing': status = green('probing'); break;
|
|
1884
1927
|
case 'waiting': status = yellow('waiting'); break;
|
|
1885
1928
|
case 'paused': status = yellow('paused'); break;
|
|
@@ -1936,6 +1979,14 @@ export class TUI {
|
|
|
1936
1979
|
}
|
|
1937
1980
|
const weekly = weeklyPolicyText(this.am, a);
|
|
1938
1981
|
if (weekly) line += ` ${weekly}`;
|
|
1982
|
+
// The reservation, whatever the account is doing. weeklyPolicyText renders
|
|
1983
|
+
// "Cap 50%" only while the cap is the ACTIVE weekly state; this is the standing
|
|
1984
|
+
// property, so a capped account that is exhausted, throttled or idle still says
|
|
1985
|
+
// so. Suppressed when the weekly tag is already the Cap label (no double tag).
|
|
1986
|
+
if (weekly.includes('Cap ') === false) {
|
|
1987
|
+
const capTag = capText(a, capBenched(this.am, a));
|
|
1988
|
+
if (capTag) line += ` ${capTag}`;
|
|
1989
|
+
}
|
|
1939
1990
|
// Per-model weekly caps (e.g. Fable, while the unified weekly still has
|
|
1940
1991
|
// headroom). Show the ACTUAL utilization — "Fable 90%" (yellow) while high but
|
|
1941
1992
|
// still usable, "Fable maxed" (red) ONLY at genuine exhaustion. This is the
|
|
@@ -1958,7 +2009,8 @@ export class TUI {
|
|
|
1958
2009
|
// cause (e.g. rate-limited) when a probe failure is on record — rather than imply
|
|
1959
2010
|
// the last-known value is current.
|
|
1960
2011
|
line += this._probeHealthNote(a);
|
|
1961
|
-
|
|
2012
|
+
const act = loadText(this._accountLoad(a));
|
|
2013
|
+
if (act) line += ` ${dim(act)}`;
|
|
1962
2014
|
return line;
|
|
1963
2015
|
}
|
|
1964
2016
|
|
|
@@ -2031,7 +2083,6 @@ export class TUI {
|
|
|
2031
2083
|
const m = this.am._fastRefillMultiplier(a);
|
|
2032
2084
|
if (m < 1) note += ` ${cyan(`fast·refill ×${m.toFixed(2)}`)}`;
|
|
2033
2085
|
}
|
|
2034
|
-
if (a.capUtilization != null) note += ` ${yellow(`cap ${Math.round(a.capUtilization * 100)}%`)}`;
|
|
2035
2086
|
} else if (q.providerQuotaSource === 'console-only') {
|
|
2036
2087
|
sesCell = emptyBar('n/a', bw);
|
|
2037
2088
|
wkCell = emptyBar('n/a', bw);
|
|
@@ -2040,15 +2091,27 @@ export class TUI {
|
|
|
2040
2091
|
sesCell = emptyBar('probing', bw);
|
|
2041
2092
|
wkCell = emptyBar('probing', bw);
|
|
2042
2093
|
}
|
|
2094
|
+
// The cap rides OUTSIDE the quota-readable branch: an account with an
|
|
2095
|
+
// unreadable or not-yet-probed quota still HAS its reservation, and hiding the
|
|
2096
|
+
// setting whenever the probe is quiet is how a shipped feature reads as absent.
|
|
2097
|
+
const capTag = capText(a, capBenched(this.am, a));
|
|
2098
|
+
if (capTag) note += ` ${capTag}`;
|
|
2043
2099
|
|
|
2044
2100
|
let line = ` ${sel}${cur} ${name} ${type} ${status} Ses ${sesCell}`;
|
|
2045
2101
|
if (showBoth) line += ` Wk ${wkCell}`;
|
|
2046
2102
|
line += note;
|
|
2047
2103
|
// Same recent-load columns as OAuth (providers track inFlight + load events),
|
|
2048
2104
|
// plus a compact Last <status> <ms> — the one signal that matters for a
|
|
2049
|
-
// rarely-hit fallback
|
|
2050
|
-
|
|
2051
|
-
if (
|
|
2105
|
+
// rarely-hit fallback. loadText renders empty when fully idle.
|
|
2106
|
+
const act = loadText(this._accountLoad(a));
|
|
2107
|
+
if (act) line += ` ${dim(act)}`;
|
|
2108
|
+
// "Last 200 6.4s" next to a live "17/h · 6.4s" said the same thing twice. Keep it
|
|
2109
|
+
// for the two cases where it is the ONLY thing that speaks: a non-2xx last result
|
|
2110
|
+
// (always worth seeing), or an idle row whose activity cell is blank.
|
|
2111
|
+
const lastOk = a.lastStatus >= 200 && a.lastStatus < 300;
|
|
2112
|
+
if (a.lastStatus && (!lastOk || !act)) {
|
|
2113
|
+
line += ` ${dim('Last')} ${statusColor(a.lastStatus)} ${dim(formatMs(a.lastResponseMs))}`;
|
|
2114
|
+
}
|
|
2052
2115
|
// Header-derived generic rate-limit (distinct from the monitor-endpoint quota),
|
|
2053
2116
|
// if the provider upstream returns x-ratelimit-* headers — only when present.
|
|
2054
2117
|
if (q.genericLimit != null && q.genericRemaining != null) {
|