maxpool 1.22.0 → 1.22.2
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 +12 -13
- package/src/index.js +12 -1
- package/src/tui.js +17 -9
package/package.json
CHANGED
package/src/account-manager.js
CHANGED
|
@@ -1445,10 +1445,11 @@ export class AccountManager {
|
|
|
1445
1445
|
*
|
|
1446
1446
|
* The ceiling is switchThreshold and never 1.0, deliberately: the owner asked for a
|
|
1447
1447
|
* cap that "always preserves some meaningful room for usage of those accounts outside
|
|
1448
|
-
* of MaxPool".
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1448
|
+
* of MaxPool". NOTE the invariant is the WEAKER one: never LESS available than the
|
|
1449
|
+
* FIXED CAP it replaces (pinned by T3c) — NOT "identical to an uncapped account".
|
|
1450
|
+
* Above the ceiling the cap still hard-benches ('capped', ahead of the upstreamAllows
|
|
1451
|
+
* carve-out) where the uncapped twin would read 'reserve' and stay routable. That is
|
|
1452
|
+
* the reservation doing its job at the margin, not a parity bug.
|
|
1452
1453
|
*
|
|
1453
1454
|
* Fails CLOSED in every uncertain case (no stamp, unusable duration): an unknown
|
|
1454
1455
|
* window position returns the floor, never an opened-up cap.
|
|
@@ -1946,7 +1947,13 @@ export class AccountManager {
|
|
|
1946
1947
|
}
|
|
1947
1948
|
|
|
1948
1949
|
if (q.unified5h != null && q.unified5h >= bench) {
|
|
1949
|
-
|
|
1950
|
+
// DYNAMIC CAP twin of the weekly arm's _capUnbenchAt: a rising session cap
|
|
1951
|
+
// unbenches at its own ramp crossing, often hours before the 5h reset. Without
|
|
1952
|
+
// this, util 0.55 over a floor 0.50 that has just rolled tells the client to wait
|
|
1953
|
+
// ~5h when the cap releases it at ~2.8h (architect finding 2026-09-24).
|
|
1954
|
+
const crossing = this._capUnbenchAt(account, q.unified5h, 'ses', now);
|
|
1955
|
+
const retryAt = crossing ?? (q.unified5hReset || null);
|
|
1956
|
+
return { cause: 'session_limit', retryAt, queueable: Boolean(retryAt) };
|
|
1950
1957
|
}
|
|
1951
1958
|
|
|
1952
1959
|
if (q.tokensLimit != null && q.tokensRemaining != null && q.tokensLimit > 0) {
|
|
@@ -4202,10 +4209,6 @@ export class AccountManager {
|
|
|
4202
4209
|
// the restart AND the next `cc all` header re-send (the upsert guard).
|
|
4203
4210
|
capUtilization: a.capUtilization ?? null,
|
|
4204
4211
|
capMode: a.capMode ?? null,
|
|
4205
|
-
capEffective: a.capUtilization == null ? null : {
|
|
4206
|
-
ses: this._effectiveCap(a, 'ses'),
|
|
4207
|
-
wk: this._effectiveCap(a, 'wk'),
|
|
4208
|
-
},
|
|
4209
4212
|
}));
|
|
4210
4213
|
}
|
|
4211
4214
|
|
|
@@ -4420,10 +4423,6 @@ export class AccountManager {
|
|
|
4420
4423
|
priority: a.priority,
|
|
4421
4424
|
capUtilization: a.capUtilization ?? null,
|
|
4422
4425
|
capMode: a.capMode ?? null,
|
|
4423
|
-
capEffective: a.capUtilization == null ? null : {
|
|
4424
|
-
ses: this._effectiveCap(a, 'ses'),
|
|
4425
|
-
wk: this._effectiveCap(a, 'wk'),
|
|
4426
|
-
},
|
|
4427
4426
|
runtime: a.runtime,
|
|
4428
4427
|
status: a.status,
|
|
4429
4428
|
refreshDead: Boolean(a.refreshDead),
|
package/src/index.js
CHANGED
|
@@ -2113,14 +2113,25 @@ async function syncAccountsFromDisk(diskConfig, memConfig, accountManager) {
|
|
|
2113
2113
|
// this a config-edit cap is stale until the next full reload).
|
|
2114
2114
|
const diskCap = Number.isFinite(diskAcct.capUtilization) && diskAcct.capUtilization > 0 && diskAcct.capUtilization < 1
|
|
2115
2115
|
? diskAcct.capUtilization : null;
|
|
2116
|
-
// The MODE
|
|
2116
|
+
// The MODE and the two per-account OVERRIDES ride along with the cap: a hand
|
|
2117
|
+
// edit to any of them must not sit stale until a restart (the staleness class
|
|
2118
|
+
// this whole block exists to fix). a hand-edited config that adds/changes a cap
|
|
2117
2119
|
// without naming a mode gets the dynamic default, exactly as a fresh load would —
|
|
2118
2120
|
// otherwise a hot edit would silently produce a capped account with no mode, whose
|
|
2119
2121
|
// effective cap is the floor forever (a fixed cap wearing the new feature's name).
|
|
2122
|
+
// Same validation as boot (_capMode): a typo'd capMode must not fail open in
|
|
2123
|
+
// silence on the hot path either — the boot path logs, so this does too.
|
|
2124
|
+
if (diskCap != null && diskAcct.capMode != null && diskAcct.capMode !== 'fixed' && diskAcct.capMode !== 'dynamic') {
|
|
2125
|
+
console.log(`[Maxpool] Ignoring unknown capMode ${JSON.stringify(diskAcct.capMode)} for "${mgr.name}" on hot sync — expected "fixed" or "dynamic"; using dynamic`);
|
|
2126
|
+
}
|
|
2120
2127
|
const diskMode = diskCap == null ? null : (diskAcct.capMode === 'fixed' ? 'fixed' : 'dynamic');
|
|
2121
2128
|
if (mgr.capUtilization !== diskCap || mgr.capMode !== diskMode) {
|
|
2122
2129
|
mgr.capUtilization = diskCap;
|
|
2123
2130
|
mgr.capMode = diskMode;
|
|
2131
|
+
const dCeil = Number.isFinite(diskAcct.capCeiling) && diskAcct.capCeiling > 0 && diskAcct.capCeiling < 1 ? diskAcct.capCeiling : null;
|
|
2132
|
+
const dRamp = Number.isFinite(diskAcct.capRampStart) && diskAcct.capRampStart >= 0 && diskAcct.capRampStart < 1 ? diskAcct.capRampStart : null;
|
|
2133
|
+
mgr.capCeiling = dCeil;
|
|
2134
|
+
mgr.capRampStart = dRamp;
|
|
2124
2135
|
console.log(`[Maxpool] Usage cap for "${mgr.name}" ${diskCap ? `set to ${Math.round(diskCap * 100)}% (${diskMode})` : 'removed'} from config`);
|
|
2125
2136
|
}
|
|
2126
2137
|
memConfig.accounts[memIdx] = { ...memConfig.accounts[memIdx], ...diskAcct };
|
package/src/tui.js
CHANGED
|
@@ -211,23 +211,31 @@ function capText(a, benched, am) {
|
|
|
211
211
|
// scheduler is not using. `cap 50%>67%` reads as "reserved 50%, currently allowing
|
|
212
212
|
// 67%"; the two collapse to one number while the cap sits at its floor, so an
|
|
213
213
|
// early-window dynamic account looks exactly like the fixed one it replaced.
|
|
214
|
+
// The WINDOW is named, not just the number. `cap 50%>75%` alone is ambiguous in the
|
|
215
|
+
// way that matters for the decision the row exists to support ("is it safe for me to
|
|
216
|
+
// use this account myself right now?"): a lift driven by the 5h window means reduced
|
|
217
|
+
// protection for minutes, the same number off the weekly means DAYS of it. Council
|
|
218
|
+
// finding 2026-09-24.
|
|
214
219
|
const eff = capEffectivePct(am, a);
|
|
215
|
-
const t = (eff != null && eff !== floorPct)
|
|
216
|
-
? `cap ${floorPct}%>${eff}
|
|
220
|
+
const t = (eff != null && eff.pct !== floorPct)
|
|
221
|
+
? `cap ${floorPct}%>${eff.pct}% ${eff.window}`
|
|
217
222
|
: `cap ${floorPct}%`;
|
|
218
223
|
return benched ? yellow(t) : dim(t);
|
|
219
224
|
}
|
|
220
225
|
|
|
221
|
-
/**
|
|
222
|
-
*
|
|
223
|
-
*
|
|
226
|
+
/** What routing is ACTUALLY enforcing on this account right now: the worse (lower) of
|
|
227
|
+
* its two windows' effective caps — the one that benches first — AND WHICH window that
|
|
228
|
+
* is. Returns {pct, window:'5h'|'wk'} or null for a fixed cap / when the manager cannot
|
|
229
|
+
* compute one. The window label is load-bearing: the same percentage means "protection
|
|
230
|
+
* is thin for the next few minutes" off the 5h window and "thin for days" off the weekly. */
|
|
224
231
|
function capEffectivePct(am, a) {
|
|
225
232
|
if (!am?._effectiveCap || a?.capMode !== 'dynamic') return null;
|
|
226
|
-
const vals = ['ses', 'wk']
|
|
227
|
-
.map(w => am._effectiveCap(a, w))
|
|
228
|
-
.filter(
|
|
233
|
+
const vals = [['ses', '5h'], ['wk', 'wk']]
|
|
234
|
+
.map(([w, label]) => ({ v: am._effectiveCap(a, w), window: label }))
|
|
235
|
+
.filter(e => typeof e.v === 'number' && Number.isFinite(e.v));
|
|
229
236
|
if (!vals.length) return null;
|
|
230
|
-
|
|
237
|
+
const worst = vals.reduce((lo, e) => (e.v < lo.v ? e : lo));
|
|
238
|
+
return { pct: Math.round(worst.v * 100), window: worst.window };
|
|
231
239
|
}
|
|
232
240
|
|
|
233
241
|
/** PER-ACCOUNT SETTINGS the user set by hand — the last column's whole job
|