maxpool 1.10.2 → 1.10.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maxpool",
3
- "version": "1.10.2",
3
+ "version": "1.10.4",
4
4
  "description": "Multi-account Claude Code proxy with adaptive, rate-aware load balancing across Claude accounts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -3010,7 +3010,11 @@ export class AccountManager {
3010
3010
  * cycle is no longer a truthful capacity observation — flag it partial (B2/SC6).
3011
3011
  * It still displays; it is excluded from averages. */
3012
3012
  restoreCapacityState(payload, now = Date.now(), downtimeMs = null) {
3013
+ // Preserve the test seam across the ledger swap (fromSerialized returns a fresh
3014
+ // instance; without this the zero-floor harness override dies on any restore).
3015
+ const floorOverride = this.capacity?._readFloorOverride ?? null;
3013
3016
  this.capacity = CapacityLedger.fromSerialized(payload);
3017
+ this.capacity._readFloorOverride = floorOverride;
3014
3018
  // Partial is keyed on MAXPOOL'S OWN downtime, NEVER on the account's last request:
3015
3019
  // an account parked >10min mid-cycle is normal fleet rotation, and keying on its
3016
3020
  // last request discarded valid observations on every reload (red-team F3). The
@@ -3051,7 +3055,13 @@ export class AccountManager {
3051
3055
  accrueCapacity(accountIndex, { input = 0, output = 0 } = {}) {
3052
3056
  const account = this.accounts[accountIndex];
3053
3057
  if (!account) return;
3054
- this.capacity.accrue(account.name, { input, output });
3058
+ // A no-weekly plan (z.ai legacy TOKENS_LIMIT, weeklyAbsent) has no weekly window to
3059
+ // measure, so opening a wk cycle only creates a cycle that can NEVER close — dead
3060
+ // weight that grows until the stuck-open invariant false-alarms (~12d). Session
3061
+ // window + day buckets (the 7d volume) are the real signals for such accounts.
3062
+ const windows = account.type === 'provider' && account.quota?.weeklyAbsent
3063
+ ? ['ses'] : ['ses', 'wk'];
3064
+ this.capacity.accrue(account.name, { input, output }, undefined, windows);
3055
3065
  }
3056
3066
 
3057
3067
  /** Close any window cycle whose reset time has passed — CLOCK-AUTHORITATIVE, so a
@@ -3064,6 +3074,18 @@ export class AccountManager {
3064
3074
  const pairs = a.type === 'provider'
3065
3075
  ? [['ses', 'providerSesReset'], ['wk', 'providerWkReset']]
3066
3076
  : [['ses', 'unified5hReset'], ['wk', 'unified7dReset']];
3077
+ // A no-weekly plan's wk cycle can never close (no stamp will ever arrive).
3078
+ // Retire it as an explicitly-labelled partial so it stops occupying the open slot
3079
+ // and never trips the stuck-open invariant. Reachable for cycles opened before
3080
+ // the plan was confirmed no-weekly.
3081
+ if (a.type === 'provider' && q.weeklyAbsent) {
3082
+ const wkOpen = this.capacity.openCycle(a.name, 'wk');
3083
+ if (wkOpen) {
3084
+ wkOpen.complete = false;
3085
+ wkOpen.partialReason = 'no-weekly-plan';
3086
+ this.capacity.closeCycle(a.name, 'wk', now, {});
3087
+ }
3088
+ }
3067
3089
  // Keep the open cycle's windowStartedAt fresh: a NEW reset stamp whose window
3068
3090
  // start precedes the cycle's open means we joined mid-window (the absolute
3069
3091
  // estimate is then only a lower bound — see the delta method).
@@ -31,6 +31,10 @@ const SCHEMA_VERSION = 3;
31
31
  // Two closes this far apart are the SAME boundary observed twice (a clock-close and a
32
32
  // stamp-advance racing across the boundary second), not two windows.
33
33
  const SAME_BOUNDARY_MS = 5_000;
34
+
35
+ // The minimum span of a COMPLETE cycle per window (80% of nominal): a real one is
36
+ // flagged partial by the writer, so a complete cycle below this is corrupt history.
37
+ const READ_FLOOR_MS = { ses: 4 * 3600_000, wk: 5 * 86400_000 };
34
38
  const MAX_CYCLES_PER_WINDOW = 50;
35
39
  const MAX_DAY_BUCKETS = 10;
36
40
 
@@ -54,6 +58,9 @@ export class CapacityLedger {
54
58
  // Cleared per account+window once that window's first boundary is behind us.
55
59
  this._joinedMidWindow = false;
56
60
  this._utilObservedAt = 0; // last utilization-reading arrival (see estimateFromUtilization)
61
+ // Test seam ONLY: real-window fixtures are laborious for every close-cycle test,
62
+ // so tests may zero the read floor. Production never touches this.
63
+ this._readFloorOverride = null;
57
64
  }
58
65
 
59
66
  /** Restore from a serialized payload (state.json). Tolerant: unknown schemaVersion →
@@ -140,10 +147,10 @@ export class CapacityLedger {
140
147
  * M3 in the pre-mortem — Anthropic interim deltas are CUMULATIVE, so the SSE seam
141
148
  * passes the running max, and this adds it exactly once per request).
142
149
  * count_tokens requests are the CALLER's job to skip (M4) — they never reach here. */
143
- accrue(name, { input, output }, at = this._now()) {
150
+ accrue(name, { input, output }, at = this._now(), windows = ['ses', 'wk']) {
144
151
  if (!(input > 0) && !(output > 0)) return;
145
152
  const rec = this._rec(name);
146
- for (const w of ['ses', 'wk']) {
153
+ for (const w of windows) {
147
154
  // Open the window lazily if nothing is open (a mid-cycle boot or a window whose
148
155
  // reset stamp was never learned). startedAt is the accrual time then — the cycle
149
156
  // will be flagged partial by the caller if the boot gap warrants it (B1/B2).
@@ -324,7 +331,20 @@ export class CapacityLedger {
324
331
  * are observations, not capacity). */
325
332
  windowStats(name, window) {
326
333
  const rec = this._accounts.get(name);
327
- const closed = (rec?.[window]?.closed || []).filter(c => c.complete && !c.disabledDuring);
334
+ // READ-TIME FLOOR. A cycle marked complete + never-disabled but spanning far less
335
+ // than its window is junk from a writer bug — the live ledger held a 0.5-second /
336
+ // 588-token "cycle" (clock-close and stamp-advance racing at one boundary, the fold
337
+ // refused on an endedAt mismatch) and it dragged this account's Avg3 down ~188k.
338
+ // Unlike the WRITE-time floor I tried first (reverted: it punished accounts that
339
+ // were merely idle early in their window), at read time a genuinely short cycle is
340
+ // already flagged complete:false by the writer — so a complete sub-floor cycle is
341
+ // definitionally corrupt, never a real observation.
342
+ const floor = (this._readFloorOverride ?? READ_FLOOR_MS)[window] ?? 0;
343
+ // >= floor, with a 1s tolerance for the accrue-vs-close clock race (an accrue can
344
+ // stamp Date.now() a tick AFTER the close computed its boundary, making a 0-span
345
+ // cycle read as -1ms — found by debugging a D2 failure that only reproduced in-file).
346
+ const closed = (rec?.[window]?.closed || []).filter(c =>
347
+ c.complete && !c.disabledDuring && (c.endedAt - c.startedAt) >= floor - 1_000);
328
348
  if (!closed.length) return null;
329
349
  const avg = (arr) => arr.length ? Math.round(arr.reduce((a, b) => a + b, 0) / arr.length) : null;
330
350
  const tokens = closed.map(c => c.tokens);
package/src/tui.js CHANGED
@@ -2040,18 +2040,27 @@ export class TUI {
2040
2040
  const name = truncate(a.name, nameW).padEnd(nameW);
2041
2041
  const prov = gray(providerLabel(a).padEnd(PROVIDER_W));
2042
2042
  if (noWeekly) {
2043
- // No weekly limit — the favourite legacy plan. There is no cycle to complete,
2044
- // so a capacity number would be a fiction. Show what it actually DID move.
2043
+ // No weekly limit — the favourite legacy plan. There is no weekly CAP, so a
2044
+ // measured weekly capacity is a fiction; but there IS a real ceiling: the 5h
2045
+ // session limit gates throughput, capping the week at (windows/wk × session
2046
+ // capacity). 33.6 five-hour windows fit in 7 days — the user's own
2047
+ // approximation ("from the session limits"), shipped as a ceiling, never a cap.
2045
2048
  const t = ledger.rollingThroughput(a.name, 7);
2049
+ const ses = ledger.windowStats(a.name, 'ses');
2050
+ const windowsPerWk = (7 * 24) / 5;
2046
2051
  anyData = anyData || t.tokens > 0;
2047
2052
  const vol = t.tokens > 0 ? formatTokens(t.tokens) : '--';
2053
+ // The ceiling needs a measured session capacity; without one it would multiply
2054
+ // a guess — show the volume alone rather than fabricate the headline.
2055
+ const ceiling = ses ? ` · ≈${formatTokens(Math.round(windowsPerWk * ses.avg10))}/wk ceiling`
2056
+ + dim(` (${windowsPerWk.toFixed(0)} sessions × ${formatTokens(ses.avg10)})`) : '';
2048
2057
  // Always disclose the window's age boundary: today is unfinished, so the 7d
2049
2058
  // figure grows through the day; a genuinely partial day adds the ≤-observed floor.
2050
2059
  const note = t.partial
2051
2060
  ? ' (≤ observed — maxpool was down part of the window; includes today, in progress)'
2052
2061
  : ' (includes today, in progress)';
2053
2062
  out.push(' ' + name + ' ' + prov + ' '
2054
- + cyan(`no weekly limit · 7d volume ${vol}`) + dim(note));
2063
+ + cyan(`no weekly limit · 7d volume ${vol}`) + yellow(ceiling) + dim(note));
2055
2064
  continue;
2056
2065
  }
2057
2066
  const st = ledger.windowStats(a.name, win);
@@ -2093,7 +2102,7 @@ export class TUI {
2093
2102
  : ' A session figure appears after an account\'s 5h window resets once.'));
2094
2103
  }
2095
2104
  out.push(' ' + dim('A cycle counts only if maxpool ran for all of it and the account stayed enabled.'));
2096
- out.push(' ' + dim('~ = estimated from utilization; ≥ = at least this (window joined late); Δ = exact-by-difference; measured replaces both.'));
2105
+ out.push(' ' + dim('~ = estimated from utilization; ≥ = at least this (window joined late); Δ = exact-by-difference; ≈/wk ceiling = session rate, not a cap.'));
2097
2106
  return out;
2098
2107
  }
2099
2108