maxpool 1.12.0 → 1.13.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 +72 -16
- package/src/capacity-ledger.js +60 -2
- package/src/tui.js +63 -51
package/package.json
CHANGED
package/src/account-manager.js
CHANGED
|
@@ -1134,7 +1134,10 @@ export class AccountManager {
|
|
|
1134
1134
|
// disappears (without this, OAuth cycles essentially never close: red-team 2026-08-22).
|
|
1135
1135
|
if (q.unified5h != null && q.unified5hReset && now >= q.unified5hReset) {
|
|
1136
1136
|
console.log(`[Maxpool] Account "${account.name}" session quota reset`);
|
|
1137
|
-
|
|
1137
|
+
// TANK: q.unified5h is still the CLOSING window's fullness here — the nulls below
|
|
1138
|
+
// come after. Snapshot into the cycle before the rollover wipes it.
|
|
1139
|
+
this.capacity?.closeCycle?.(account.name, 'ses', q.unified5hReset,
|
|
1140
|
+
{ resetAt: q.unified5hReset, finalUtilization: q.unified5h });
|
|
1138
1141
|
q.unified5h = null;
|
|
1139
1142
|
q.unified5hReset = null;
|
|
1140
1143
|
changed = true;
|
|
@@ -1142,7 +1145,8 @@ export class AccountManager {
|
|
|
1142
1145
|
}
|
|
1143
1146
|
if (q.unified7d != null && q.unified7dReset && now >= q.unified7dReset) {
|
|
1144
1147
|
console.log(`[Maxpool] Account "${account.name}" weekly quota reset`);
|
|
1145
|
-
this.capacity?.closeCycle?.(account.name, 'wk', q.unified7dReset,
|
|
1148
|
+
this.capacity?.closeCycle?.(account.name, 'wk', q.unified7dReset,
|
|
1149
|
+
{ resetAt: q.unified7dReset, finalUtilization: q.unified7d });
|
|
1146
1150
|
q.unified7d = null;
|
|
1147
1151
|
q.unified7dReset = null;
|
|
1148
1152
|
q.unifiedStatus = null;
|
|
@@ -2667,7 +2671,7 @@ export class AccountManager {
|
|
|
2667
2671
|
* in-window) and criticalPeakUnlock is enabled. Default off.
|
|
2668
2672
|
* Precedence prereset > pressure > peak: the cheaper drain wins.
|
|
2669
2673
|
*/
|
|
2670
|
-
_criticalUnlock(account, requestInfo = {}, excludedIndexes = new Set(),
|
|
2674
|
+
_criticalUnlock(account, requestInfo = {}, excludedIndexes = new Set(), _pressureCache = null, now = Date.now()) {
|
|
2671
2675
|
const state = this._weeklyRawState(account);
|
|
2672
2676
|
if (state !== 'critical') return null;
|
|
2673
2677
|
|
|
@@ -2736,7 +2740,7 @@ export class AccountManager {
|
|
|
2736
2740
|
* - pressure/peak: a flat cost ABOVE reserve's attainable max, so critical is
|
|
2737
2741
|
* relief for a LOADED last route and never preempts an idle reserve.
|
|
2738
2742
|
*/
|
|
2739
|
-
_criticalCost(account,
|
|
2743
|
+
_criticalCost(account, _now = Date.now(), unlock = null, weeklyState = this._weeklyRawState(account)) {
|
|
2740
2744
|
if (weeklyState !== 'critical') return 0;
|
|
2741
2745
|
if (!unlock) return 0;
|
|
2742
2746
|
if (unlock.reason === 'prereset') {
|
|
@@ -2915,10 +2919,14 @@ export class AccountManager {
|
|
|
2915
2919
|
const account = this.accounts[accountIndex];
|
|
2916
2920
|
if (!account || !usage) return;
|
|
2917
2921
|
const q = account.quota;
|
|
2918
|
-
// CAPACITY LEDGER: prev stamps, so a probe observing the
|
|
2919
|
-
// the old cycle
|
|
2922
|
+
// CAPACITY LEDGER: prev stamps AND prev utilizations, so a probe observing the
|
|
2923
|
+
// window ADVANCE closes the old cycle with the OLD window's tank reading —
|
|
2924
|
+
// snapshot BEFORE the writes below clobber the fields with the new window's
|
|
2925
|
+
// values (the OAuth twin of the applyProviderUsage hook).
|
|
2920
2926
|
const prevSesReset = q.unified5hReset;
|
|
2921
2927
|
const prevWkReset = q.unified7dReset;
|
|
2928
|
+
const prevSesUtil = q.unified5h;
|
|
2929
|
+
const prevWkUtil = q.unified7d;
|
|
2922
2930
|
|
|
2923
2931
|
if (usage.fiveHour) {
|
|
2924
2932
|
if (usage.fiveHour.utilization != null) q.unified5h = clamp01(usage.fiveHour.utilization);
|
|
@@ -2928,8 +2936,8 @@ export class AccountManager {
|
|
|
2928
2936
|
if (usage.sevenDay.utilization != null) q.unified7d = clamp01(usage.sevenDay.utilization);
|
|
2929
2937
|
if (usage.sevenDay.resetAt != null) q.unified7dReset = usage.sevenDay.resetAt;
|
|
2930
2938
|
}
|
|
2931
|
-
this.noteCapacityWindowAdvance(account.name, 'ses', prevSesReset, usage.fiveHour?.resetAt);
|
|
2932
|
-
this.noteCapacityWindowAdvance(account.name, 'wk', prevWkReset, usage.sevenDay?.resetAt);
|
|
2939
|
+
this.noteCapacityWindowAdvance(account.name, 'ses', prevSesReset, usage.fiveHour?.resetAt, prevSesUtil);
|
|
2940
|
+
this.noteCapacityWindowAdvance(account.name, 'wk', prevWkReset, usage.sevenDay?.resetAt, prevWkUtil);
|
|
2933
2941
|
// Utilization readings feed the capacity ESTIMATE. The probe path passes per-window
|
|
2934
2942
|
// marks so the DELTA method can difference consecutive readings.
|
|
2935
2943
|
this.capacity.noteUtilizationObserved(Date.now(), [
|
|
@@ -3046,11 +3054,14 @@ export class AccountManager {
|
|
|
3046
3054
|
const account = this.accounts[accountIndex];
|
|
3047
3055
|
if (!account || !usage) return;
|
|
3048
3056
|
const q = account.quota;
|
|
3049
|
-
// CAPACITY LEDGER: snapshot the previous reset stamps so a probe
|
|
3050
|
-
// window ADVANCE (new stamp) closes the capacity cycle at the old
|
|
3051
|
-
//
|
|
3057
|
+
// CAPACITY LEDGER: snapshot the previous reset stamps AND utilizations so a probe
|
|
3058
|
+
// observing the window ADVANCE (new stamp) closes the capacity cycle at the old
|
|
3059
|
+
// boundary WITH the old window's tank reading — covers windows whose old stamp
|
|
3060
|
+
// was never learned (clock-close can't fire). Snapshot before the writes below.
|
|
3052
3061
|
const prevSesReset = q.providerSesReset;
|
|
3053
3062
|
const prevWkReset = q.providerWkReset;
|
|
3063
|
+
const prevSesUtil = q.providerSes;
|
|
3064
|
+
const prevWkUtil = q.providerWk;
|
|
3054
3065
|
if (usage.error) {
|
|
3055
3066
|
// Distinguish "no pollable quota" (Kimi) from a transient probe failure.
|
|
3056
3067
|
// Never clear existing values on a transient error — let them age into the
|
|
@@ -3078,8 +3089,8 @@ export class AccountManager {
|
|
|
3078
3089
|
q.weeklyAbsent = true;
|
|
3079
3090
|
}
|
|
3080
3091
|
q.lastProbeOkAt = Date.now();
|
|
3081
|
-
this.noteCapacityWindowAdvance(account.name, 'ses', prevSesReset, usage.ses?.resetAt);
|
|
3082
|
-
this.noteCapacityWindowAdvance(account.name, 'wk', prevWkReset, usage.wk?.resetAt);
|
|
3092
|
+
this.noteCapacityWindowAdvance(account.name, 'ses', prevSesReset, usage.ses?.resetAt, prevSesUtil);
|
|
3093
|
+
this.noteCapacityWindowAdvance(account.name, 'wk', prevWkReset, usage.wk?.resetAt, prevWkUtil);
|
|
3083
3094
|
this.capacity.noteUtilizationObserved(Date.now(), [
|
|
3084
3095
|
{ name: account.name, window: 'ses', utilization: usage.ses?.utilization },
|
|
3085
3096
|
{ name: account.name, window: 'wk', utilization: usage.wk?.utilization },
|
|
@@ -3277,6 +3288,24 @@ export class AccountManager {
|
|
|
3277
3288
|
return this.capacity.estimateFromUtilization(a.name, window, util) || null;
|
|
3278
3289
|
}
|
|
3279
3290
|
|
|
3291
|
+
/** Measured TANK for an account+window: capacity, not delivery. Prefers completed
|
|
3292
|
+
* cycles (tokens ÷ closing utilization, averaged); falls back to the live open
|
|
3293
|
+
* window's estimate so a row is useful from minute one instead of reading
|
|
3294
|
+
* "no completed cycle yet" while the vendor is plainly reporting a percentage. */
|
|
3295
|
+
capacityTank(accountIndex, window) {
|
|
3296
|
+
const a = this.accounts[accountIndex];
|
|
3297
|
+
if (!a) return null;
|
|
3298
|
+
const measured = this.capacity.tankStats(a.name, window);
|
|
3299
|
+
if (measured) return { ...measured, source: 'cycles' };
|
|
3300
|
+
const est = this.capacityEstimate(accountIndex, window);
|
|
3301
|
+
if (!est) return null;
|
|
3302
|
+
return {
|
|
3303
|
+
avg: est.tokens, last: est.tokens, n: 0, exact: est.lowerBound ? 0 : 1,
|
|
3304
|
+
bounded: est.lowerBound ? 1 : 0, lowerBound: Boolean(est.lowerBound),
|
|
3305
|
+
source: 'live', utilization: est.utilization, method: est.method, fresh: est.fresh,
|
|
3306
|
+
};
|
|
3307
|
+
}
|
|
3308
|
+
|
|
3280
3309
|
accrueCapacity(accountIndex, { input = 0, output = 0 } = {}) {
|
|
3281
3310
|
const account = this.accounts[accountIndex];
|
|
3282
3311
|
if (!account) return;
|
|
@@ -3289,6 +3318,18 @@ export class AccountManager {
|
|
|
3289
3318
|
this.capacity.accrue(account.name, { input, output }, undefined, windows);
|
|
3290
3319
|
}
|
|
3291
3320
|
|
|
3321
|
+
/** The vendor's CURRENT fullness reading for a window — the tank numerator's
|
|
3322
|
+
* denominator. Returns null when unreadable (a null reading divides nothing and
|
|
3323
|
+
* must never coerce to 0, which would make tank = Infinity). */
|
|
3324
|
+
_windowUtilization(account, window) {
|
|
3325
|
+
const q = account?.quota;
|
|
3326
|
+
if (!q) return null;
|
|
3327
|
+
const v = account.type === 'provider'
|
|
3328
|
+
? (window === 'wk' ? q.providerWk : q.providerSes)
|
|
3329
|
+
: (window === 'wk' ? q.unified7d : q.unified5h);
|
|
3330
|
+
return Number.isFinite(v) && v >= 0 ? v : null;
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3292
3333
|
/** Close any window cycle whose reset time has passed — CLOCK-AUTHORITATIVE, so a
|
|
3293
3334
|
* stale or dead probe can never leave a cycle open and mis-attribute the next
|
|
3294
3335
|
* window's tokens to it (pre-mortem M5; worst case is the no-weekly account whose
|
|
@@ -3332,7 +3373,14 @@ export class AccountManager {
|
|
|
3332
3373
|
// here as well (round-2) made a prober-first notice silently swallow all of
|
|
3333
3374
|
// those whenever the sweep won the race (red-team round 3, RT3-1).
|
|
3334
3375
|
if (resetAt && now >= resetAt) {
|
|
3335
|
-
this.capacity.closeCycle(a.name, win, resetAt, {
|
|
3376
|
+
this.capacity.closeCycle(a.name, win, resetAt, {
|
|
3377
|
+
resetAt,
|
|
3378
|
+
// TANK: the vendor's own fullness for the window we are closing. Read it
|
|
3379
|
+
// BEFORE _clearExpiredQuotas nulls it — this sweep runs first by design
|
|
3380
|
+
// (see the close-only note above), which is exactly why the reading is
|
|
3381
|
+
// still the CLOSING window's and not the new one's.
|
|
3382
|
+
finalUtilization: this._windowUtilization(a, win),
|
|
3383
|
+
});
|
|
3336
3384
|
}
|
|
3337
3385
|
}
|
|
3338
3386
|
}
|
|
@@ -3340,7 +3388,7 @@ export class AccountManager {
|
|
|
3340
3388
|
|
|
3341
3389
|
/** Close a cycle because a probe observed the window ADVANCE (a new reset stamp) —
|
|
3342
3390
|
* covers the case where the old stamp was never learned. */
|
|
3343
|
-
noteCapacityWindowAdvance(accountName, window, prevResetAt, nextResetAt) {
|
|
3391
|
+
noteCapacityWindowAdvance(accountName, window, prevResetAt, nextResetAt, prevUtilization = null) {
|
|
3344
3392
|
if (!prevResetAt || !nextResetAt) return;
|
|
3345
3393
|
// TWO guards, both learned from live data (2026-08-23):
|
|
3346
3394
|
// 1. PAST stamp = a probe that answered late (its window rolled mid-request) or
|
|
@@ -3361,7 +3409,15 @@ export class AccountManager {
|
|
|
3361
3409
|
// expired) — endedAt is always within [start, now].
|
|
3362
3410
|
const boundary = Math.min(nextResetAt, nowMs);
|
|
3363
3411
|
if (boundary - prevResetAt < WINDOW_ADVANCE_EPSILON_MS) return;
|
|
3364
|
-
|
|
3412
|
+
// TANK: the CLOSING window's own fullness, passed in by the caller. It must be the
|
|
3413
|
+
// caller's SNAPSHOT, never a re-read here: both probe paths write the new window's
|
|
3414
|
+
// utilization into the quota fields before calling us, so re-reading would divide
|
|
3415
|
+
// the old window's tokens by the NEW window's percentage — a silently wrong tank
|
|
3416
|
+
// on exactly the rollover this path exists to catch.
|
|
3417
|
+
this.capacity.closeCycle(accountName, window, boundary, {
|
|
3418
|
+
resetAt: prevResetAt,
|
|
3419
|
+
finalUtilization: Number.isFinite(prevUtilization) && prevUtilization >= 0 ? prevUtilization : null,
|
|
3420
|
+
});
|
|
3365
3421
|
}
|
|
3366
3422
|
|
|
3367
3423
|
/**
|
package/src/capacity-ledger.js
CHANGED
|
@@ -199,8 +199,15 @@ export class CapacityLedger {
|
|
|
199
199
|
|
|
200
200
|
/** Close the open cycle for a window (M5: clock-authoritative — the close is keyed
|
|
201
201
|
* on `endedAt`, which the caller derives from the reset stamp or the clock, and the
|
|
202
|
-
* cycle keeps its own book regardless of probe health). No-op if none open.
|
|
203
|
-
|
|
202
|
+
* cycle keeps its own book regardless of probe health). No-op if none open.
|
|
203
|
+
*
|
|
204
|
+
* TANK (2026-08-25, owner-directed): the closed row records `finalUtilization` —
|
|
205
|
+
* the vendor's own fullness reading for the window at close. tank = tokens ÷ util
|
|
206
|
+
* is the CAPACITY of the plan, as distinct from the tokens we happened to deliver.
|
|
207
|
+
* Delivery measures demand; tank measures the plan. Both are recorded; the UI
|
|
208
|
+
* decides which to show. Recording happens on a best-effort basis here (the ledger
|
|
209
|
+
* keeps its own book — the caller passes the reading in, it does not poll). */
|
|
210
|
+
closeCycle(name, window, endedAt = this._now(), { resetAt = null, finalUtilization = null } = {}) {
|
|
204
211
|
const rec = this._accounts.get(name);
|
|
205
212
|
if (!rec || !rec[window]?.open) return null;
|
|
206
213
|
const open = rec[window].open;
|
|
@@ -221,7 +228,10 @@ export class CapacityLedger {
|
|
|
221
228
|
// Fold ONLY a complete tail: folding a partial/disabled tail would flip the
|
|
222
229
|
// flags on the prior legitimate observation and ERASE it from the averages
|
|
223
230
|
// (round 3, RT3-2) — strictly worse than leaving a tiny excluded cycle.
|
|
231
|
+
// The fold ALSO takes the tail's tank reading if the prior row lacks one —
|
|
232
|
+
// same boundary, same window, so the later reading is simply fresher.
|
|
224
233
|
prev.tokens += open.tokensSoFar;
|
|
234
|
+
if (prev.finalUtilization == null && finalUtilization != null) prev.finalUtilization = finalUtilization;
|
|
225
235
|
rec[window].open = null;
|
|
226
236
|
return prev;
|
|
227
237
|
}
|
|
@@ -232,6 +242,12 @@ export class CapacityLedger {
|
|
|
232
242
|
complete: open.complete,
|
|
233
243
|
disabledDuring: open.disabledDuring,
|
|
234
244
|
...(open.partialReason ? { partialReason: open.partialReason } : {}),
|
|
245
|
+
...(finalUtilization != null ? { finalUtilization } : {}),
|
|
246
|
+
// Carried onto the closed row because tankStats needs it: a cycle observed from
|
|
247
|
+
// its window START yields an EXACT tank; one we joined late yields a lower bound
|
|
248
|
+
// (we only counted the tokens that flowed through maxpool, while the vendor's
|
|
249
|
+
// percentage counts everything). Dropping it here made every tank read "bounded".
|
|
250
|
+
...(open.windowStartedAt != null ? { windowStartedAt: open.windowStartedAt } : {}),
|
|
235
251
|
resetAt,
|
|
236
252
|
});
|
|
237
253
|
if (rec[window].closed.length > MAX_CYCLES_PER_WINDOW) rec[window].closed.shift();
|
|
@@ -366,6 +382,48 @@ export class CapacityLedger {
|
|
|
366
382
|
* ABSENCE (present in dayKeys, absent from days) — and with MAX_DAY_BUCKETS=10 an
|
|
367
383
|
* idle day no longer even evicts; only real activity ages out. `partial` is true
|
|
368
384
|
* when any bucket in the window is flagged partial — the figure is ≤ observed. */
|
|
385
|
+
/** TANK STATS — the CAPACITY of the plan, from the owner's own formula:
|
|
386
|
+
* tank = tokens delivered ÷ utilization at close, per cycle, averaged across
|
|
387
|
+
* cycles (2026-08-25, owner-directed). This measures the plan, not the demand:
|
|
388
|
+
* a cycle that delivered 812k at 96% and one that delivered 51k at 6% both say
|
|
389
|
+
* "~846k tank". Delivered-only averages (windowStats) measure demand and stay
|
|
390
|
+
* available separately.
|
|
391
|
+
*
|
|
392
|
+
* Guards, because the raw formula lies in two ways:
|
|
393
|
+
* - We only count tokens that flowed THROUGH maxpool; a cycle whose vendor util
|
|
394
|
+
* includes spend we never saw (joined mid-window, or usage outside the proxy)
|
|
395
|
+
* yields a tank ≥ the truth but not equal to it. Only a cycle observed from its
|
|
396
|
+
* window start is exact; later ones are marked `lowerBound`.
|
|
397
|
+
* - Vendors report whole percents. At 3% full, 1pp of rounding = 33% error, so a
|
|
398
|
+
* reading below MIN_UTIL is excluded (rounding-dominated) rather than folded
|
|
399
|
+
* into the average as fake precision.
|
|
400
|
+
* Returns { avg, exact, n, bounded, last } or null when no usable readings. */
|
|
401
|
+
tankStats(name, window) {
|
|
402
|
+
const rec = this._accounts.get(name);
|
|
403
|
+
const floor = (this._readFloorOverride ?? READ_FLOOR_MS)[window] ?? 0;
|
|
404
|
+
const usable = (rec?.[window]?.closed || []).filter(c =>
|
|
405
|
+
c.complete && !c.disabledDuring
|
|
406
|
+
&& Number.isFinite(c.finalUtilization)
|
|
407
|
+
&& c.finalUtilization >= 0.05
|
|
408
|
+
&& (c.endedAt - c.startedAt) >= floor - 1_000);
|
|
409
|
+
if (!usable.length) return null;
|
|
410
|
+
let sum = 0, exact = 0, bounded = 0;
|
|
411
|
+
for (const c of usable) {
|
|
412
|
+
const observedFromStart = c.startedAt != null && c.windowStartedAt != null
|
|
413
|
+
&& c.startedAt <= c.windowStartedAt + 60_000;
|
|
414
|
+
sum += c.tokens / c.finalUtilization;
|
|
415
|
+
if (observedFromStart) exact++; else bounded++;
|
|
416
|
+
}
|
|
417
|
+
const last = usable[usable.length - 1];
|
|
418
|
+
return {
|
|
419
|
+
avg: Math.round(sum / usable.length),
|
|
420
|
+
exact, bounded,
|
|
421
|
+
n: usable.length,
|
|
422
|
+
last: Math.round(last.tokens / last.finalUtilization),
|
|
423
|
+
lowerBound: bounded > 0 && exact === 0,
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
369
427
|
rollingThroughput(name, days = 7) {
|
|
370
428
|
const rec = this._accounts.get(name);
|
|
371
429
|
if (!rec) return { tokens: 0, partial: false };
|
package/src/tui.js
CHANGED
|
@@ -2031,7 +2031,7 @@ export class TUI {
|
|
|
2031
2031
|
const ledger = this.am.capacity;
|
|
2032
2032
|
const title = win === 'wk' ? 'Weekly (7d) capacity' : 'Session (5h) capacity';
|
|
2033
2033
|
out.push('');
|
|
2034
|
-
out.push(` ${bold(title)} ${dim('— tokens
|
|
2034
|
+
out.push(` ${bold(title)} ${dim('— how many tokens each account can deliver per window')}`);
|
|
2035
2035
|
out.push('');
|
|
2036
2036
|
|
|
2037
2037
|
if (!ledger) { out.push(yellow(' Capacity ledger unavailable on this worker.')); return out; }
|
|
@@ -2039,15 +2039,19 @@ export class TUI {
|
|
|
2039
2039
|
// Narrow terminals: drop trailing columns rather than let fitLine chop a number
|
|
2040
2040
|
// mid-digit (at W=80 the full 6-column row is 82+ chars — every row silently lost
|
|
2041
2041
|
// its last two cells). The dropped ones are the aggregates, not the observations.
|
|
2042
|
-
|
|
2043
|
-
|
|
2042
|
+
// CAPACITY (tank) is the headline: tokens ÷ the vendor's own fullness at close,
|
|
2043
|
+
// per cycle. That measures the PLAN. The delivered-token columns measure DEMAND —
|
|
2044
|
+
// useful, but they were the headline before 2026-08-25 and read as capacity, which
|
|
2045
|
+
// is why an account that simply went unused looked small.
|
|
2046
|
+
const ALL_COLS = ['Capacity', 'Used now', 'Last cyc', 'Avg cyc'];
|
|
2047
|
+
const CW = 10;
|
|
2044
2048
|
const nameW = 12;
|
|
2045
2049
|
let COLS = ALL_COLS;
|
|
2046
|
-
while (COLS.length > 1 && (nameW + PROVIDER_W + 2 + COLS.length * CW +
|
|
2050
|
+
while (COLS.length > 1 && (nameW + PROVIDER_W + 2 + COLS.length * CW + 16) > W) {
|
|
2047
2051
|
COLS = COLS.slice(0, -1);
|
|
2048
2052
|
}
|
|
2049
2053
|
const header = ' ' + 'Account'.padEnd(nameW) + ' ' + 'Provider'.padEnd(PROVIDER_W) + ' '
|
|
2050
|
-
+ COLS.map(c => c.padStart(CW)).join('') + '
|
|
2054
|
+
+ COLS.map(c => c.padStart(CW)).join('') + ' Basis';
|
|
2051
2055
|
out.push(dimUnderline(fitLine(header, W)));
|
|
2052
2056
|
|
|
2053
2057
|
let anyData = false;
|
|
@@ -2065,14 +2069,16 @@ export class TUI {
|
|
|
2065
2069
|
// capacity). 33.6 five-hour windows fit in 7 days — the user's own
|
|
2066
2070
|
// approximation ("from the session limits"), shipped as a ceiling, never a cap.
|
|
2067
2071
|
const t = ledger.rollingThroughput(a.name, 7);
|
|
2068
|
-
const ses = ledger.windowStats(a.name, 'ses');
|
|
2069
2072
|
const windowsPerWk = (7 * 24) / 5;
|
|
2070
2073
|
anyData = anyData || t.tokens > 0;
|
|
2071
2074
|
const vol = t.tokens > 0 ? formatTokens(t.tokens) : '--';
|
|
2072
|
-
// The ceiling needs a measured session capacity
|
|
2073
|
-
//
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2075
|
+
// The ceiling needs a measured session TANK (capacity, not avg delivery) —
|
|
2076
|
+
// multiplying an old avg-delivery number understates a demand-limited account.
|
|
2077
|
+
const sesTank = this.am.capacityTank?.(i, 'ses');
|
|
2078
|
+
const ceiling = sesTank
|
|
2079
|
+
? ` · ≈${formatTokens(Math.round(windowsPerWk * sesTank.avg))}/wk ceiling`
|
|
2080
|
+
+ dim(` (${windowsPerWk.toFixed(0)} × ${formatTokens(sesTank.avg)} per 5h)`)
|
|
2081
|
+
: '';
|
|
2076
2082
|
// Always disclose the window's age boundary: today is unfinished, so the 7d
|
|
2077
2083
|
// figure grows through the day; a genuinely partial day adds the ≤-observed floor.
|
|
2078
2084
|
const note = t.partial
|
|
@@ -2083,54 +2089,60 @@ export class TUI {
|
|
|
2083
2089
|
continue;
|
|
2084
2090
|
}
|
|
2085
2091
|
const st = ledger.windowStats(a.name, win);
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
const op = est.lowerBound ? '≥' : '~';
|
|
2105
|
-
const via = est.method === 'delta'
|
|
2106
|
-
? `Δ ${(est.utilization * 100).toFixed(0)}% full` : `${(est.utilization * 100).toFixed(0)}% full`;
|
|
2107
|
-
out.push(' ' + name + ' ' + prov + ' ' + cyan(op + formatTokens(est.tokens).padStart(CW - 1))
|
|
2108
|
-
+ dim(` est from ${via}${caveat} — measured after this window completes`) + nowTag);
|
|
2109
|
-
} else {
|
|
2110
|
-
out.push(' ' + name + ' ' + prov + ' ' + dim('no completed cycle yet') + nowTag);
|
|
2111
|
-
}
|
|
2092
|
+
let tank = this.am.capacityTank?.(i, win);
|
|
2093
|
+
const nowOpen = ledger.openCycle(a.name, win);
|
|
2094
|
+
const util = this.am._windowUtilization?.(a, win);
|
|
2095
|
+
// A reading we cannot prove is from THIS window must not badge the capacity
|
|
2096
|
+
// number as "live" — it may describe the previous window entirely (the estimate
|
|
2097
|
+
// still renders; the basis line just stops claiming freshness it can't prove).
|
|
2098
|
+
if (tank?.source === 'live' && tank.fresh === false) tank = null;
|
|
2099
|
+
|
|
2100
|
+
// A row with NEITHER a tank nor any delivery has genuinely nothing to say. Say
|
|
2101
|
+
// WHY in the account's own terms — "no completed cycle yet" was true and useless
|
|
2102
|
+
// (reported 2026-08-25: an account sitting at 99% weekly rendered that line).
|
|
2103
|
+
if (!tank && !st && !(nowOpen?.tokensSoFar > 0)) {
|
|
2104
|
+
const why = util == null
|
|
2105
|
+
? 'no quota reading from this provider'
|
|
2106
|
+
: util > 0
|
|
2107
|
+
? `${(util * 100).toFixed(0)}% used, but no traffic through maxpool to measure with`
|
|
2108
|
+
: 'window empty — nothing used yet';
|
|
2109
|
+
out.push(' ' + name + ' ' + prov + ' ' + dim(why));
|
|
2112
2110
|
continue;
|
|
2113
2111
|
}
|
|
2114
2112
|
anyData = true;
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2113
|
+
|
|
2114
|
+
// Capacity: measured tank, or the live in-window estimate. `~` = estimate from an
|
|
2115
|
+
// open window; `≥` = we joined the window late, so the vendor's percentage counts
|
|
2116
|
+
// spend maxpool never saw and the true tank is at least this.
|
|
2117
|
+
const capCell = tank
|
|
2118
|
+
? (tank.lowerBound ? '≥' : tank.source === 'live' ? '~' : ' ') + formatTokens(tank.avg)
|
|
2119
|
+
: '--';
|
|
2120
|
+
const usedNow = nowOpen?.tokensSoFar > 0 ? formatTokens(nowOpen.tokensSoFar) : '--';
|
|
2121
|
+
const cellsByName = {
|
|
2122
|
+
Capacity: capCell,
|
|
2123
|
+
'Used now': usedNow,
|
|
2124
|
+
'Last cyc': st ? formatTokens(st.last) : '--',
|
|
2125
|
+
'Avg cyc': st ? formatTokens(st.avg10) : '--',
|
|
2126
|
+
};
|
|
2127
|
+
const cells = COLS.map(c => cellsByName[c].padStart(CW)).join('');
|
|
2128
|
+
|
|
2129
|
+
// Basis: how the capacity number was arrived at, in one short phrase. Never a
|
|
2130
|
+
// bare count — "3" told the reader nothing about what it was counting.
|
|
2131
|
+
const basis = !tank ? dim('no capacity reading yet')
|
|
2132
|
+
: tank.source === 'cycles'
|
|
2133
|
+
? dim(`${tank.n} full ${tank.n === 1 ? 'window' : 'windows'}`)
|
|
2134
|
+
: dim(`live · ${((tank.utilization ?? 0) * 100).toFixed(0)}% used`);
|
|
2135
|
+
const pct = util != null && tank?.source !== 'live' ? dim(` (${(util * 100).toFixed(0)}% full now)`) : '';
|
|
2136
|
+
out.push(' ' + name + ' ' + prov + ' ' + cyan(cells) + ' ' + basis + pct);
|
|
2121
2137
|
}
|
|
2122
2138
|
|
|
2123
2139
|
out.push('');
|
|
2124
2140
|
if (!anyData) {
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
: ' A session figure appears after an account\'s 5h window resets once.'));
|
|
2131
|
-
}
|
|
2132
|
-
out.push(' ' + dim('A cycle counts only if maxpool ran for all of it and the account stayed enabled.'));
|
|
2133
|
-
out.push(' ' + dim('~ = estimated; ≥ = at least; Δ = exact-by-difference; ≈/wk = session-rate ceiling; ▸ = live this window.'));
|
|
2141
|
+
out.push(' ' + yellow('Nothing to measure yet.')
|
|
2142
|
+
+ dim(' Capacity needs traffic through maxpool plus a quota reading from the provider.'));
|
|
2143
|
+
}
|
|
2144
|
+
out.push(' ' + dim('Capacity = tokens delivered ÷ how full the provider said the window was.'));
|
|
2145
|
+
out.push(' ' + dim('~ = from the window still running · ≥ = at least this (maxpool joined the window late).'));
|
|
2134
2146
|
return out;
|
|
2135
2147
|
}
|
|
2136
2148
|
|