maxpool 1.11.0 → 1.12.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/account-manager.js +83 -2
- package/src/tui.js +20 -4
package/package.json
CHANGED
package/src/account-manager.js
CHANGED
|
@@ -161,6 +161,27 @@ const DEFAULT_SCHEDULER = {
|
|
|
161
161
|
reserveConcurrencyTarget: 2, // tighter in-flight cap for reserve (capPenalty bites at inflight>2 ⇒ load fans out
|
|
162
162
|
// across the fleet before any single reserve account is dogpiled toward a 429)
|
|
163
163
|
spreadShareWeight: 3, // multiplies an account's share of recent fleet load (0..1)
|
|
164
|
+
// FAST-REFILL DISCOUNT (2026-08-25). The two LOAD-BALANCING terms — utilizationCost
|
|
165
|
+
// and paceCost — price a window by how FULL it is, never by how much absolute
|
|
166
|
+
// headroom it holds or how soon it refills. So "17% of a 5h window that refills 33.6x
|
|
167
|
+
// a week" is priced identically to "17% of a weekly window that refills once", and an
|
|
168
|
+
// account whose only cap is a fast-refilling session never pulls ahead of one guarding
|
|
169
|
+
// a scarce weekly budget. That is the whole reason the fleet's largest-capacity
|
|
170
|
+
// account sat at ~17% of fleet traffic (measured 2026-08-25) while four Claude
|
|
171
|
+
// accounts ran at weekly 1.0.
|
|
172
|
+
//
|
|
173
|
+
// The discount is a MULTIPLIER on those two terms only — never a flat bonus. A flat
|
|
174
|
+
// bonus would drive an idle account's total NEGATIVE (idle floor is concurrency×2 = 2),
|
|
175
|
+
// below the entire band structure that reserveFloorCost:5 / criticalPressureCost:21
|
|
176
|
+
// assume is non-negative. A multiplier in [0,1] cannot: it only ever REMOVES cost that
|
|
177
|
+
// is already there, so the total stays ≥ the concurrency floor and every safety term
|
|
178
|
+
// (concurrency, capPenalty, reserve, critical, ramp, failures) is untouched.
|
|
179
|
+
//
|
|
180
|
+
// It also DECAYS: at session util 0 the discount is full, and it is gone by
|
|
181
|
+
// fastRefillFadeUtil — so as the fast window fills, the account converges back to
|
|
182
|
+
// normal pricing and the fleet re-balances smoothly instead of flapping at a cliff.
|
|
183
|
+
fastRefillDiscount: 0.6, // 0 = off (full cost), 0.6 = discount up to 60% of the two balancing terms
|
|
184
|
+
fastRefillFadeUtil: 0.65, // discount reaches 0 at this session utilization (weeklySoftThreshold)
|
|
164
185
|
recoveryRampWeight: 4, // decaying penalty applied to a just-recovered account
|
|
165
186
|
recoveryRampMs: 5 * 60_000, // how long the post-recovery ramp lasts
|
|
166
187
|
spreadWindowMs: 15 * 60_000, // rolling window used to measure recent per-account load
|
|
@@ -250,6 +271,13 @@ const FIVE_HOUR_MS = 5 * 60 * 60 * 1000;
|
|
|
250
271
|
const PERSISTED_QUOTA_FIELDS = [
|
|
251
272
|
'unified5h', 'unified7d', 'unified5hReset', 'unified7dReset', 'unifiedStatus', 'scopedWeekly',
|
|
252
273
|
'tokensLimit', 'tokensRemaining', 'requestsLimit', 'requestsRemaining', 'resetsAt',
|
|
274
|
+
// Plan identity, not a utilization: a successful probe's "no weekly window" is
|
|
275
|
+
// positive knowledge (2026-08-06). Without persisting it, every restart clears the
|
|
276
|
+
// flag and the fast-refill discount (plus the TUI "Wk none" rendering) silently
|
|
277
|
+
// drops until the next probe sweep re-learns it. The probe still rewrites it on
|
|
278
|
+
// every successful sweep, so a plan change heals on the same cadence.
|
|
279
|
+
'weeklyAbsent', 'providerSes', 'providerSesReset', 'providerWk', 'providerWkReset',
|
|
280
|
+
'providerQuotaSource', 'lastProbeOkAt',
|
|
253
281
|
];
|
|
254
282
|
|
|
255
283
|
function clampRetryAfterSeconds(value) {
|
|
@@ -2487,7 +2515,11 @@ export class AccountManager {
|
|
|
2487
2515
|
|
|
2488
2516
|
// Burn-pace COST only (demoted from the old dominant scarcity×6 term): a
|
|
2489
2517
|
// soft de-preference of accounts burning ahead of an even pace. Never a bench.
|
|
2490
|
-
|
|
2518
|
+
// FAST-REFILL DISCOUNT: applied to the pace and utilization terms (and only
|
|
2519
|
+
// those) for an account whose only cap is a fast-refilling session window —
|
|
2520
|
+
// see the DEFAULT_SCHEDULER block for the full rationale.
|
|
2521
|
+
const refillMult = this._fastRefillMultiplier(account);
|
|
2522
|
+
const paceCost = this._accountScarcity(account, now) * this.scheduler.paceCostWeight * refillMult;
|
|
2491
2523
|
|
|
2492
2524
|
// RAW utilization cost — direct, not pace-adjusted. The pace cost above discounts
|
|
2493
2525
|
// by how far into the window you are, so an account at 80% with 2h left is only
|
|
@@ -2495,7 +2527,7 @@ export class AccountManager {
|
|
|
2495
2527
|
// benching, but wrong for load balancing: an account at 80% should be clearly less
|
|
2496
2528
|
// attractive than one at 10% even if both are "on pace". Measured 2026-08-10: cc at
|
|
2497
2529
|
// 80% scored 52.30 vs glm at 10% at 52.15 — a 0.15 gap drowned by round-robin.
|
|
2498
|
-
const utilizationCost = this._rawUtilization(account) * this.scheduler.utilizationWeight;
|
|
2530
|
+
const utilizationCost = this._rawUtilization(account) * this.scheduler.utilizationWeight * refillMult;
|
|
2499
2531
|
|
|
2500
2532
|
// Per-model weekly de-preference: an account whose scoped weekly for THIS
|
|
2501
2533
|
// request's model (e.g. Fable) is high-but-not-exhausted is a poor pick for
|
|
@@ -2722,6 +2754,39 @@ export class AccountManager {
|
|
|
2722
2754
|
return this._criticalUnlock(account, { profile: 'claude' }, new Set(), null, now);
|
|
2723
2755
|
}
|
|
2724
2756
|
|
|
2757
|
+
/**
|
|
2758
|
+
* FAST-REFILL MULTIPLIER — 1.0 (no change) or a discount in (0,1) for an account
|
|
2759
|
+
* whose ONLY cap is a fast-refilling session window. The predicate is exactly the
|
|
2760
|
+
* one the TUI already renders ("Wk none"): a provider whose quota poll succeeded
|
|
2761
|
+
* and carried NO weekly window (positive knowledge the plan has none — measured
|
|
2762
|
+
* 2026-08-06, z.ai `max` returns one TOKENS_LIMIT unit 3 = 5h and no unit-6 weekly).
|
|
2763
|
+
*
|
|
2764
|
+
* The discount is LINEARLY FADED to 0 by session utilization: full at 0%, gone at
|
|
2765
|
+
* fastRefillFadeUtil. So the preference this grants decays as the window fills and
|
|
2766
|
+
* the account converges back to normal pricing — no cliff, no flap. At util ≥ fade
|
|
2767
|
+
* point the multiplier is exactly 1, making the term byte-identical to pre-2026-08-25
|
|
2768
|
+
* behaviour by construction.
|
|
2769
|
+
*
|
|
2770
|
+
* Rationale (why a weeklyAbsent account at all): its window refills 33.6× per week
|
|
2771
|
+
* vs a weekly window's 1×, so equal FULLNESS does not mean equal VALUE — capacity
|
|
2772
|
+
* that expires unused every 5h is worth spending faster than capacity that guards a
|
|
2773
|
+
* whole week. This is the use-it-or-lose-it principle _windowScarcity already applies
|
|
2774
|
+
* WITHIN a window, extended across window KINDS. It is a discount on balancing terms
|
|
2775
|
+
* only — never a flat bonus (a flat bonus drives the total negative, under the
|
|
2776
|
+
* non-negative band structure reserveFloorCost/criticalPressureCost were calibrated
|
|
2777
|
+
* against), and never on safety terms (concurrency, capPenalty, reserve, critical).
|
|
2778
|
+
*/
|
|
2779
|
+
_fastRefillMultiplier(account) {
|
|
2780
|
+
const disc = this.scheduler.fastRefillDiscount;
|
|
2781
|
+
if (!(disc > 0)) return 1; // feature off → multiplier 1
|
|
2782
|
+
if (!(account?.type === 'provider' && account.quota?.weeklyAbsent)) return 1;
|
|
2783
|
+
const fade = this.scheduler.fastRefillFadeUtil;
|
|
2784
|
+
const ses = clamp01(account.quota.providerSes ?? 0);
|
|
2785
|
+
if (ses >= fade) return 1;
|
|
2786
|
+
// 1 at ses=0 → 1-disc at ses=0; linear to 1 at ses=fade
|
|
2787
|
+
return 1 - disc * (1 - ses / Math.max(1e-6, fade));
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2725
2790
|
_reserveCost(account, now = Date.now(), weeklyState = this._weeklyRawState(account)) {
|
|
2726
2791
|
if (weeklyState !== 'reserve') return 0;
|
|
2727
2792
|
const q = account.quota;
|
|
@@ -3974,6 +4039,22 @@ export class AccountManager {
|
|
|
3974
4039
|
safetyMaxActivePerAccount: this.scheduler.safetyMaxActivePerAccount,
|
|
3975
4040
|
safetyMaxGlobalActive: this.scheduler.safetyMaxGlobalActive,
|
|
3976
4041
|
peak: this.peakSummary(),
|
|
4042
|
+
// FAST-REFILL visibility (2026-08-25): monitors must be able to assert the
|
|
4043
|
+
// discount is ARMED (config > 0) and, per eligible account, the multiplier
|
|
4044
|
+
// actually being applied — a flag that can never show "inert" is not a
|
|
4045
|
+
// monitorable feature. Mirrors the peak block's shape.
|
|
4046
|
+
fastRefill: {
|
|
4047
|
+
enabled: this.scheduler.fastRefillDiscount > 0,
|
|
4048
|
+
discount: this.scheduler.fastRefillDiscount,
|
|
4049
|
+
fadeUtil: this.scheduler.fastRefillFadeUtil,
|
|
4050
|
+
accounts: this.accounts
|
|
4051
|
+
.filter(a => a.type === 'provider' && a.quota?.weeklyAbsent)
|
|
4052
|
+
.map(a => ({
|
|
4053
|
+
name: a.name,
|
|
4054
|
+
sesUtilization: clamp01(a.quota.providerSes ?? 0),
|
|
4055
|
+
multiplier: Number(this._fastRefillMultiplier(a).toFixed(3)),
|
|
4056
|
+
})),
|
|
4057
|
+
},
|
|
3977
4058
|
},
|
|
3978
4059
|
upstreamThrottle: {
|
|
3979
4060
|
active: this._isUpstreamThrottleBlocking(),
|
package/src/tui.js
CHANGED
|
@@ -1961,6 +1961,13 @@ export class TUI {
|
|
|
1961
1961
|
if (tier === 2) note += ` ${yellow(`peak·capped ${Math.round((wu ?? 0) * 100)}%`)}`;
|
|
1962
1962
|
else if (tier === 1) note += wu == null ? ` ${dim('peak·cap n/a')}` : ` ${yellow('peak')}`;
|
|
1963
1963
|
}
|
|
1964
|
+
// FAST-REFILL tag (2026-08-25): mirrors the router's own _fastRefillMultiplier —
|
|
1965
|
+
// the label cannot disagree with routing because it reads the same predicate.
|
|
1966
|
+
// Only shown when a discount is actually applied (< 1).
|
|
1967
|
+
if (a.quota?.weeklyAbsent && this.am._fastRefillMultiplier) {
|
|
1968
|
+
const m = this.am._fastRefillMultiplier(a);
|
|
1969
|
+
if (m < 1) note += ` ${cyan(`fast·refill ×${m.toFixed(2)}`)}`;
|
|
1970
|
+
}
|
|
1964
1971
|
} else if (q.providerQuotaSource === 'console-only') {
|
|
1965
1972
|
sesCell = emptyBar('n/a', bw);
|
|
1966
1973
|
wkCell = emptyBar('n/a', bw);
|
|
@@ -2082,6 +2089,12 @@ export class TUI {
|
|
|
2082
2089
|
// being an estimate. `~` marks it; a measured column replaces it after the first
|
|
2083
2090
|
// full window. A stale-util caveat only when we cannot prove same-window.
|
|
2084
2091
|
const est = this.am.capacityEstimate?.(i, win);
|
|
2092
|
+
// LIVE now-column: the open cycle is the only number that moves between window
|
|
2093
|
+
// closes, and without it the page read as frozen (reported 2026-08-25: "they
|
|
2094
|
+
// don't seem to be updating at all"). Rendered on every row that has one.
|
|
2095
|
+
const nowOpen = ledger.openCycle(a.name, win);
|
|
2096
|
+
const nowTag = nowOpen && nowOpen.tokensSoFar > 0
|
|
2097
|
+
? ' ' + yellow(`▸ ${formatTokens(nowOpen.tokensSoFar)} this window`) : '';
|
|
2085
2098
|
if (est) {
|
|
2086
2099
|
anyData = true;
|
|
2087
2100
|
const caveat = est.fresh ? '' : ' (utilization reading may be from the previous window)';
|
|
@@ -2092,16 +2105,19 @@ export class TUI {
|
|
|
2092
2105
|
const via = est.method === 'delta'
|
|
2093
2106
|
? `Δ ${(est.utilization * 100).toFixed(0)}% full` : `${(est.utilization * 100).toFixed(0)}% full`;
|
|
2094
2107
|
out.push(' ' + name + ' ' + prov + ' ' + cyan(op + formatTokens(est.tokens).padStart(CW - 1))
|
|
2095
|
-
+ dim(` est from ${via}${caveat} — measured after this window completes`));
|
|
2108
|
+
+ dim(` est from ${via}${caveat} — measured after this window completes`) + nowTag);
|
|
2096
2109
|
} else {
|
|
2097
|
-
out.push(' ' + name + ' ' + prov + ' ' + dim('no completed cycle yet'));
|
|
2110
|
+
out.push(' ' + name + ' ' + prov + ' ' + dim('no completed cycle yet') + nowTag);
|
|
2098
2111
|
}
|
|
2099
2112
|
continue;
|
|
2100
2113
|
}
|
|
2101
2114
|
anyData = true;
|
|
2102
2115
|
const all = { Last: st.last, Prev: st.prev, 'Prev-1': st.prev1, 'Avg 3': st.avg3, 'Avg 10': st.avg10, 'All time': st.allTime };
|
|
2103
2116
|
const cells = COLS.map(c => formatTokens(all[c]).padStart(CW)).join('');
|
|
2104
|
-
|
|
2117
|
+
const nowOpen = ledger.openCycle(a.name, win);
|
|
2118
|
+
const nowTag = nowOpen && nowOpen.tokensSoFar > 0
|
|
2119
|
+
? ' ' + yellow(`▸ ${formatTokens(nowOpen.tokensSoFar)}`) : '';
|
|
2120
|
+
out.push(' ' + name + ' ' + prov + ' ' + cells + ' ' + dim(String(st.cycles)) + nowTag);
|
|
2105
2121
|
}
|
|
2106
2122
|
|
|
2107
2123
|
out.push('');
|
|
@@ -2114,7 +2130,7 @@ export class TUI {
|
|
|
2114
2130
|
: ' A session figure appears after an account\'s 5h window resets once.'));
|
|
2115
2131
|
}
|
|
2116
2132
|
out.push(' ' + dim('A cycle counts only if maxpool ran for all of it and the account stayed enabled.'));
|
|
2117
|
-
out.push(' ' + dim('~ = estimated
|
|
2133
|
+
out.push(' ' + dim('~ = estimated; ≥ = at least; Δ = exact-by-difference; ≈/wk = session-rate ceiling; ▸ = live this window.'));
|
|
2118
2134
|
return out;
|
|
2119
2135
|
}
|
|
2120
2136
|
|