maxpool 1.5.61 → 1.5.63

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.61",
3
+ "version": "1.5.63",
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",
@@ -176,6 +176,10 @@ const LOAD_EVENT_MAX_AGE_MS = 60 * 60 * 1000;
176
176
  // fall back to per-account handling. Bounds any future "poisoned probe" from becoming
177
177
  // an indefinite fleet-wide outage (2026-07-25 incident).
178
178
  const MAX_FAILED_PROBES = 4;
179
+ // Consecutive quota-probe failures before we say so. High enough that a network blip or a
180
+ // single 429 never trips it; low enough that a permanently dead endpoint surfaces the same
181
+ // day rather than never.
182
+ const PROBE_FAILURE_ALERT_AT = 20;
179
183
  const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
180
184
  const FIVE_HOUR_MS = 5 * 60 * 60 * 1000;
181
185
 
@@ -2150,7 +2154,18 @@ export class AccountManager {
2150
2154
  if (q.unified7d == null) return 'unknown';
2151
2155
 
2152
2156
  const used = clamp01(q.unified7d);
2153
- if (used >= this.scheduler.weeklyExhaustedThreshold) return 'exhausted';
2157
+ // NEVER bench on utilization alone while the upstream explicitly says the account is
2158
+ // ALLOWED. Anthropic reports both a percentage and a verdict; the verdict is the
2159
+ // authority, and it keeps saying "allowed"/"allowed_warning" at 100% used. This mirrors
2160
+ // _isAccountWideRejected above, which already treats an explicit 'rejected' as decisive
2161
+ // for the negative case — the positive case was simply missing.
2162
+ // Measured 2026-08-06: max@gomokka.com sat benched at unified7d=1.00 with
2163
+ // unifiedStatus='allowed_warning' and returned 200 to a live request. Capacity the user
2164
+ // was waiting on, withheld because a threshold outranked the upstream's own answer.
2165
+ // 'exhausted' is the only state that removes an account from routing, so the override
2166
+ // is scoped to it — critical/reserve still apply their soft costs unchanged.
2167
+ const upstreamAllows = typeof q.unifiedStatus === 'string' && q.unifiedStatus.startsWith('allowed');
2168
+ if (used >= this.scheduler.weeklyExhaustedThreshold && !upstreamAllows) return 'exhausted';
2154
2169
  if (used >= this.scheduler.weeklyCriticalThreshold) return 'critical';
2155
2170
  if (used >= this.scheduler.weeklyReserveThreshold) return 'reserve';
2156
2171
  if (used >= this.scheduler.weeklySoftThreshold) return 'soft';
@@ -2183,6 +2198,8 @@ export class AccountManager {
2183
2198
  * Same effect as learning quota from a live response, but for idle accounts.
2184
2199
  */
2185
2200
  applyUsageData(accountIndex, usage) {
2201
+ // A successful probe ends any escalation streak.
2202
+ if (this.accounts[accountIndex]?.quota) this.accounts[accountIndex].quota.consecutiveProbeFailures = 0;
2186
2203
  const account = this.accounts[accountIndex];
2187
2204
  if (!account || !usage) return;
2188
2205
  const q = account.quota;
@@ -2257,6 +2274,24 @@ export class AccountManager {
2257
2274
  q.lastProbeError = message ? String(message).slice(0, 160) : 'probe failed';
2258
2275
  q.lastProbeErrorAt = Date.now();
2259
2276
  q.lastProbeErrorStatus = Number.isFinite(status) ? status : null;
2277
+ // ESCALATE A SYSTEMIC PROBE FAILURE. These fields were written and never read by
2278
+ // anything, so a probe failing on every call would do so in total silence.
2279
+ // (Correction: an earlier version of this comment claimed the Anthropic quota probe was
2280
+ // dead because /v1/usages and /v1/usage 404. Those are the KIMI PROVIDER endpoints
2281
+ // (src/oauth.js fetchProviderUsage). Anthropic's OAuth quota endpoint is
2282
+ // /api/oauth/usage and it is healthy — every account carries a recent lastProbeOkAt and
2283
+ // zero consecutive failures, and this escalation has never fired. The guard is still
2284
+ // worth having; the diagnosis that motivated it was wrong.)
2285
+ q.consecutiveProbeFailures = (q.consecutiveProbeFailures || 0) + 1;
2286
+ const n = q.consecutiveProbeFailures;
2287
+ // Once, at a threshold that cannot be a blip, then every 100th so it stays visible
2288
+ // without walling the log.
2289
+ if (n === PROBE_FAILURE_ALERT_AT || (n > PROBE_FAILURE_ALERT_AT && n % 100 === 0)) {
2290
+ console.error(`[Maxpool] Quota probe has failed ${n}x in a row for "${account.name}"`
2291
+ + `${status ? ` (HTTP ${status})` : ''}: ${q.lastProbeError}. `
2292
+ + 'Weekly quota can only be learned from upstream 429 headers until this recovers, '
2293
+ + 'so an account that has not hit a 429 will show a blank weekly.');
2294
+ }
2260
2295
  }
2261
2296
 
2262
2297
  /**