maxpool 1.8.2 → 1.8.3

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.8.2",
3
+ "version": "1.8.3",
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",
@@ -32,13 +32,24 @@ export class CapacityLedger {
32
32
  this._now = now;
33
33
  // accountName → { ses: {open?, closed: []}, wk: {open?, closed: []}, days: {utcDay: {tokens, partial}} }
34
34
  this._accounts = new Map();
35
+ // True only for a ledger restored with no usable history — see fromSerialized.
36
+ // Cleared per account+window once that window's first boundary is behind us.
37
+ this._joinedMidWindow = false;
35
38
  }
36
39
 
37
40
  /** Restore from a serialized payload (state.json). Tolerant: unknown schemaVersion →
38
41
  * start empty and KEEP the file (the caller preserves it); a corrupt shape → empty. */
39
42
  static fromSerialized(payload, { now = () => Date.now() } = {}) {
40
43
  const l = new CapacityLedger({ now });
41
- if (!payload || payload.schemaVersion !== SCHEMA_VERSION) return l;
44
+ if (!payload || payload.schemaVersion !== SCHEMA_VERSION) {
45
+ // No history to continue: whatever window each account is in RIGHT NOW is
46
+ // already in progress, so the next cycle we close saw only its tail. Flag it so
47
+ // it is shown but never averaged (live 2026-08-23: the first GLM cycle after the
48
+ // v1.8.1 migration read 21,192 tokens for a 5h window it had watched 14.6 min —
49
+ // and with one cycle recorded, that sliver WAS every column).
50
+ l._joinedMidWindow = true;
51
+ return l;
52
+ }
42
53
  try {
43
54
  for (const [name, rec] of Object.entries(payload.accounts || {})) {
44
55
  const a = { ses: { open: null, closed: [] }, wk: { open: null, closed: [] }, days: {} };
@@ -91,7 +102,12 @@ export class CapacityLedger {
91
102
  // reset stamp was never learned). startedAt is the accrual time then — the cycle
92
103
  // will be flagged partial by the caller if the boot gap warrants it (B1/B2).
93
104
  if (!rec[w].open) {
94
- rec[w].open = { startedAt: at, tokensSoFar: 0, lastAccrualAt: at, complete: true, disabledDuring: false };
105
+ const joined = this._joinedMidWindow && rec[w].closed.length === 0;
106
+ rec[w].open = {
107
+ startedAt: at, tokensSoFar: 0, lastAccrualAt: at,
108
+ complete: !joined, disabledDuring: false,
109
+ ...(joined ? { partialReason: 'joined-mid-window' } : {}),
110
+ };
95
111
  }
96
112
  rec[w].open.tokensSoFar += input + output;
97
113
  rec[w].open.lastAccrualAt = at;
@@ -162,6 +178,7 @@ export class CapacityLedger {
162
178
  tokens: open.tokensSoFar,
163
179
  complete: open.complete,
164
180
  disabledDuring: open.disabledDuring,
181
+ ...(open.partialReason ? { partialReason: open.partialReason } : {}),
165
182
  resetAt,
166
183
  });
167
184
  if (rec[window].closed.length > MAX_CYCLES_PER_WINDOW) rec[window].closed.shift();