maxpool 1.5.69 → 1.5.70

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.5.69",
3
+ "version": "1.5.70",
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",
@@ -1165,6 +1165,10 @@ export class AccountManager {
1165
1165
  if (used >= this.switchThreshold) return true;
1166
1166
  }
1167
1167
 
1168
+ // Provider (z.ai/Kimi) session quota — the 5h token window. Without this a
1169
+ // provider at 95% of its 5h cap reads as fully available.
1170
+ if (q.providerSes != null && q.providerSes >= this.switchThreshold) return true;
1171
+
1168
1172
  return false;
1169
1173
  }
1170
1174
 
@@ -2110,6 +2114,15 @@ export class AccountManager {
2110
2114
  if (q.requestsLimit != null && q.requestsRemaining != null && q.requestsLimit > 0) {
2111
2115
  scarcity = Math.max(scarcity, 1 - q.requestsRemaining / q.requestsLimit);
2112
2116
  }
2117
+ // Provider (z.ai/Kimi) quota — same scoring axis as Anthropic's windows. Without
2118
+ // this, a GLM account at 80% of its 5h session scored the same as one at 5%,
2119
+ // so the scheduler dogpiled the near-cap account until z.ai 429'd it.
2120
+ if (q.providerSes != null) {
2121
+ scarcity = Math.max(scarcity, this._windowScarcity(q.providerSes, q.providerSesReset, FIVE_HOUR_MS, now));
2122
+ }
2123
+ if (q.providerWk != null) {
2124
+ scarcity = Math.max(scarcity, this._windowScarcity(q.providerWk, q.providerWkReset, WEEK_MS, now));
2125
+ }
2113
2126
  return scarcity;
2114
2127
  }
2115
2128
 
@@ -2190,6 +2203,22 @@ export class AccountManager {
2190
2203
  const q = account.quota;
2191
2204
  this._clearExpiredQuotas(account);
2192
2205
  if (this._isAccountWideRejected(account)) return 'exhausted';
2206
+
2207
+ // Provider accounts (GLM/Kimi) carry their quota in providerSes/providerWk, NOT
2208
+ // unified7d — those fields are Anthropic-only. Without this, a provider at 83%
2209
+ // weekly (Kimi measured 2026-08-08) reads as 'unknown' = healthy, so the scheduler
2210
+ // keeps piling onto it instead of spreading load. The same thresholds apply.
2211
+ if (account.type === 'provider') {
2212
+ const sesUsed = q.providerSes != null ? clamp01(q.providerSes) : null;
2213
+ const wkUsed = q.providerWk != null ? clamp01(q.providerWk) : null;
2214
+ const used = Math.max(sesUsed ?? 0, wkUsed ?? 0);
2215
+ if (used >= this.scheduler.weeklyExhaustedThreshold) return 'exhausted';
2216
+ if (used >= this.scheduler.weeklyCriticalThreshold) return 'critical';
2217
+ if (used >= this.scheduler.weeklyReserveThreshold) return 'reserve';
2218
+ if (used >= this.scheduler.weeklySoftThreshold) return 'soft';
2219
+ return 'normal';
2220
+ }
2221
+
2193
2222
  if (q.unified7d == null) return 'unknown';
2194
2223
 
2195
2224
  const used = clamp01(q.unified7d);
@@ -2212,6 +2241,8 @@ export class AccountManager {
2212
2241
  }
2213
2242
 
2214
2243
  _weeklyPaceState(account) {
2244
+ // Provider quota lives in separate fields — see _weeklyRawState.
2245
+ if (account.type === 'provider') return this._weeklyRawState(account);
2215
2246
  if (account.quota.unified7d == null) return 'unknown';
2216
2247
  const effective = this._effectiveWeeklyUsage(account);
2217
2248
  if (effective >= this.scheduler.weeklyExhaustedThreshold) return 'exhausted';