copilot-api-plus 1.2.50 → 1.2.51

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/dist/main.js CHANGED
@@ -2266,6 +2266,7 @@ async function handleMultiAccountHttpError(error, account, retryContext) {
2266
2266
  default:
2267
2267
  if (error.response.status >= 500) {
2268
2268
  accountManager.markAccountStatus(account.id, "error", `HTTP ${error.response.status}`);
2269
+ recordBreakerFailure(`HTTP ${error.response.status}`);
2269
2270
  return null;
2270
2271
  }
2271
2272
  if (error.response.status === 400) {
@@ -2280,7 +2281,42 @@ async function handleMultiAccountHttpError(error, account, retryContext) {
2280
2281
  return null;
2281
2282
  }
2282
2283
  }
2284
+ const CB_THRESHOLD = 3;
2285
+ const CB_OPEN_MS = 3e4;
2286
+ const breaker = {
2287
+ failures: 0,
2288
+ openedAt: 0
2289
+ };
2290
+ function breakerOpenRemainingMs() {
2291
+ if (breaker.openedAt === 0) return 0;
2292
+ const elapsed = Date.now() - breaker.openedAt;
2293
+ return elapsed >= CB_OPEN_MS ? 0 : CB_OPEN_MS - elapsed;
2294
+ }
2295
+ function recordBreakerSuccess() {
2296
+ if (breaker.failures !== 0 || breaker.openedAt !== 0) consola.info("Circuit breaker: closing (request succeeded)");
2297
+ breaker.failures = 0;
2298
+ breaker.openedAt = 0;
2299
+ }
2300
+ function recordBreakerFailure(reason) {
2301
+ breaker.failures += 1;
2302
+ if (breaker.failures >= CB_THRESHOLD && breaker.openedAt === 0) {
2303
+ breaker.openedAt = Date.now();
2304
+ consola.warn(`Circuit breaker OPEN for ${CB_OPEN_MS / 1e3}s after ${breaker.failures} consecutive failures (last: ${reason})`);
2305
+ }
2306
+ }
2283
2307
  async function createWithMultiAccount(payload) {
2308
+ const remaining = breakerOpenRemainingMs();
2309
+ if (remaining > 0) throw new HTTPError("Upstream temporarily unavailable", new Response(JSON.stringify({ error: {
2310
+ type: "service_unavailable",
2311
+ message: `Upstream (or proxy) is failing repeatedly. Circuit breaker open; will retry probe in ${Math.ceil(remaining / 1e3)}s.`
2312
+ } }), {
2313
+ status: 503,
2314
+ statusText: "Service Unavailable",
2315
+ headers: {
2316
+ "content-type": "application/json",
2317
+ "retry-after": String(Math.ceil(remaining / 1e3))
2318
+ }
2319
+ }));
2284
2320
  const triedAccountIds = /* @__PURE__ */ new Set();
2285
2321
  let lastError;
2286
2322
  let networkRetried = false;
@@ -2321,6 +2357,7 @@ async function createWithMultiAccount(payload) {
2321
2357
  const result = await doFetch(payload, tokenSource, account.id);
2322
2358
  account.lastRequestAt = Date.now();
2323
2359
  accountManager.markAccountSuccess(account.id);
2360
+ recordBreakerSuccess();
2324
2361
  if (Symbol.asyncIterator in result) result.__accountInfo = {
2325
2362
  accountId: account.id,
2326
2363
  accountProxy: account.proxy,
@@ -2346,6 +2383,7 @@ async function createWithMultiAccount(payload) {
2346
2383
  continue;
2347
2384
  }
2348
2385
  consola.warn(`Account ${account.label}: network error after retry (giving up): ${errMsg}`);
2386
+ recordBreakerFailure(`network: ${errMsg.slice(0, 80)}`);
2349
2387
  throw error;
2350
2388
  }
2351
2389
  consola.warn(`Account ${account.label} failed (attempt ${attempt + 1}), trying next...`);