maxpool 1.24.23 → 1.24.24
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 +42 -17
package/package.json
CHANGED
package/src/tui.js
CHANGED
|
@@ -271,23 +271,31 @@ function settingsTags(am, a) {
|
|
|
271
271
|
return tags;
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
/**
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
|
|
278
|
-
*
|
|
279
|
-
*
|
|
274
|
+
/** The session (5h) window is what keeps traffic off this account: a pure mirror of
|
|
275
|
+
* the router's _isSessionQuotaUnavailable, without its expiry-clearing write.
|
|
276
|
+
* Which readings expire on their reset is the ROUTER's rule, copied here: it clears
|
|
277
|
+
* the Claude 5h reading and the API-key limits when their reset passes, but NEVER
|
|
278
|
+
* a provider's (GLM/Kimi) providerSes — that stays until the next usage probe, so a
|
|
279
|
+
* provider past its reset stamp is still refused and must not read "active". */
|
|
280
280
|
function sessionFull(am, a) {
|
|
281
281
|
const q = a?.quota || {};
|
|
282
282
|
const now = Date.now();
|
|
283
283
|
const bench = am?._sessionBenchThreshold?.(a, now);
|
|
284
284
|
if (!Number.isFinite(bench)) return false;
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
285
|
+
const expired = reset => reset != null && now >= reset;
|
|
286
|
+
if (q.unified5h != null && !expired(q.unified5hReset) && q.unified5h >= bench) return true;
|
|
287
|
+
const apiLive = !(q.resetsAt && now >= new Date(q.resetsAt).getTime());
|
|
288
|
+
if (apiLive && q.tokensLimit != null && q.tokensRemaining != null
|
|
289
|
+
&& 1 - q.tokensRemaining / q.tokensLimit >= bench) return true;
|
|
290
|
+
if (apiLive && q.requestsLimit != null && q.requestsRemaining != null
|
|
291
|
+
&& 1 - q.requestsRemaining / q.requestsLimit >= bench) return true;
|
|
292
|
+
if (q.providerSes != null && q.providerSes >= bench) return true;
|
|
293
|
+
return false;
|
|
289
294
|
}
|
|
290
295
|
|
|
296
|
+
/** True when the reservation is what is currently keeping traffic off this account
|
|
297
|
+
* — either window at or past the cap. Reads the manager's own predicate so the
|
|
298
|
+
* label can never disagree with routing. */
|
|
291
299
|
function capBenched(am, a) {
|
|
292
300
|
if (a?.capUtilization == null) return false;
|
|
293
301
|
const q = a.quota || {};
|
|
@@ -296,7 +304,13 @@ function capBenched(am, a) {
|
|
|
296
304
|
// Each reading is judged against ITS OWN window's cap — under the dynamic cap the
|
|
297
305
|
// two differ (a 5h window nearly over is lifted while the weekly is still at its
|
|
298
306
|
// floor), so passing the default window for both would mislabel one of them.
|
|
299
|
-
|
|
307
|
+
if (am?._capped?.(a, ses, 'ses') || am?._capped?.(a, wk, 'wk')) return true;
|
|
308
|
+
// Providers: the router's weekly gate judges max(5h, weekly) against the WEEKLY
|
|
309
|
+
// cap (_weeklyRawState), so a 5h reading over the weekly cap benches it too.
|
|
310
|
+
if (a.type === 'provider' && (ses != null || wk != null)) {
|
|
311
|
+
return !!am?._capped?.(a, Math.max(ses ?? 0, wk ?? 0), 'wk');
|
|
312
|
+
}
|
|
313
|
+
return false;
|
|
300
314
|
}
|
|
301
315
|
|
|
302
316
|
export function weeklyPolicyText(am, account) {
|
|
@@ -1014,7 +1028,9 @@ export class TUI {
|
|
|
1014
1028
|
|
|
1015
1029
|
|
|
1016
1030
|
_keyRouting(k) {
|
|
1017
|
-
if (k === 'a') {
|
|
1031
|
+
if (k === 'a' && this.am.routingMode !== 'preferred') {
|
|
1032
|
+
this._addLog('No account is pinned — routing is already automatic');
|
|
1033
|
+
} else if (k === 'a') {
|
|
1018
1034
|
this._confirm(
|
|
1019
1035
|
'Unpin and use automatic routing?',
|
|
1020
1036
|
'Removes the pinned account. New requests are spread across all healthy accounts again.',
|
|
@@ -2020,6 +2036,15 @@ export class TUI {
|
|
|
2020
2036
|
lines.push(` ${gray(this.log[i].t)} ${this.log[i].msg}`);
|
|
2021
2037
|
}
|
|
2022
2038
|
|
|
2039
|
+
// The footer is the screen's controls — it must never be pushed off. On a short
|
|
2040
|
+
// terminal cut the BODY from the bottom, and say so.
|
|
2041
|
+
if (lines.length > H - footerH) {
|
|
2042
|
+
const keep = Math.max(0, H - footerH - 1);
|
|
2043
|
+
const hidden = lines.length - keep;
|
|
2044
|
+
lines.length = keep;
|
|
2045
|
+
lines.push(` ${dim(`… ${hidden} more row${hidden === 1 ? '' : 's'} — make the window taller to see them`)}`);
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2023
2048
|
// Pad to fill
|
|
2024
2049
|
while (lines.length < H - footerH) lines.push('');
|
|
2025
2050
|
|
|
@@ -2116,10 +2141,10 @@ export class TUI {
|
|
|
2116
2141
|
// relabels an otherwise-active row; exhausted / throttled / auth states keep their
|
|
2117
2142
|
// own (more specific) word. "capped" = the owner's usage cap is holding it;
|
|
2118
2143
|
// "5h full" = its session window is used up until the reset shown on the row.
|
|
2119
|
-
//
|
|
2120
|
-
// _clearExpiredQuotas, which MUTATES the quota (nulls an expired window)
|
|
2121
|
-
//
|
|
2122
|
-
//
|
|
2144
|
+
// Pure predicates on purpose: _weeklyRawState/_isSessionQuotaUnavailable call
|
|
2145
|
+
// _clearExpiredQuotas, which MUTATES the quota (nulls an expired window), so calling
|
|
2146
|
+
// them here blanked this row's own bars mid-render. (_render already runs the
|
|
2147
|
+
// manager's expiry refresh once per frame, before any row is drawn.)
|
|
2123
2148
|
if (a.enabled !== false && effectiveStatus === 'active') {
|
|
2124
2149
|
if (capBenched(this.am, a)) effectiveStatus = 'capped';
|
|
2125
2150
|
else if (sessionFull(this.am, a)) effectiveStatus = '5h full';
|
|
@@ -2551,7 +2576,7 @@ export class TUI {
|
|
|
2551
2576
|
out.push(` ${dim('Usage cap for ONE account:')} ${bold('Esc')} ${dim('then')} ${bold('a')} ${dim('→')} ${bold('u')} ${dim('(Claude or GLM)')}`);
|
|
2552
2577
|
const capped = this.am.accounts.filter(a => a.capUtilization != null && a.enabled !== false);
|
|
2553
2578
|
if (capped.length) {
|
|
2554
|
-
out.push(` ${dim('
|
|
2579
|
+
out.push(` ${dim('Caps set:')} ${capped.map(a => `${a.name} ${Math.round(a.capUtilization * 100)}%`).join(', ')}`);
|
|
2555
2580
|
}
|
|
2556
2581
|
return out;
|
|
2557
2582
|
}
|