better-ccflare 3.5.53 → 3.5.54
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/README.md +1 -1
- package/dist/better-ccflare +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -798,7 +798,7 @@ Inspired by [snipeship/ccflare](https://github.com/snipeship/ccflare) - thanks f
|
|
|
798
798
|
- [@wonkooklee](https://github.com/wonkooklee) - Fixed ZlibError on startup caused by Bun auto-decompressing upstream 404 responses while leaving stale `content-encoding: gzip` headers intact — applied `withSanitizedProxyHeaders` to the model-not-found early-return path, matching every other forward path (PR #243)
|
|
799
799
|
- [@Cotch22](https://github.com/Cotch22) - Fixed garbled non-ASCII text in request details modal by decoding base64 bodies as UTF-8 via `TextDecoder` instead of raw `atob()` (PR #246)
|
|
800
800
|
- [@zenprocess](https://github.com/zenprocess) - LeastUsed load-balancing strategy selecting accounts by lowest utilization to prevent burst pool-exhaustion (PR #193); fix keepalive 429s incorrectly cooling accounts by skipping cooldown application on synthetic keepalive replays, and shorten the no-reset fallback cooldown from 1 hour to 60 seconds (overridable via env) to prevent mass account lockout on burst contention (PR #196); optional `X-Anthropic-Agent-Id` header for explicit per-agent attribution ([#260](https://github.com/tombii/better-ccflare/pull/260)); detect and record premature SSE termination for all Anthropic-Messages-shaped streams — generalized the terminal-recovery wrapper to cover every anthropic-compatible provider (not just native Anthropic), added a `stream_terminal_state` column distinguishing complete/recovered/error/truncated/client-cancelled outcomes, and fixed success-rate metrics silently recording truncated mid-stream responses as successful ([#344](https://github.com/tombii/better-ccflare/pull/344)); fixed usage-exhausted accounts staying in the selection pool and getting cycled through every model instead of being skipped, by filtering accounts whose representative usage window is fully exhausted out of `getOrderedAccounts()` before the load-balancing strategy ever sees them, with `isAccountAvailable` gaining an optional usage-snapshot parameter so the same exhaustion check backs both the forced-account and combo-slot selection paths ([#345](https://github.com/tombii/better-ccflare/pull/345)); fixed dashboard double-submit creating duplicate accounts and the by-name delete cascade that could wipe every account sharing a name — added a DB-level `UNIQUE(name, provider, custom_endpoint)` guard across all add paths (dashboard, CLI, OAuth), switched account deletion to be genuinely id-scoped everywhere, and added a non-destructive migration that merges existing duplicate rows (credentials, counters, flags, cooldown state) into a single survivor before enforcing uniqueness on both the SQLite and PostgreSQL paths ([#343](https://github.com/tombii/better-ccflare/pull/343)); added MiniMax Token Plan usage polling mirroring the zai/xai fetcher pattern, deriving each window's interval length from its own `end_time - start_time`, inverting the API's remaining-percent into utilization, and using only the `general` model-class row (never falling back to an unrelated quota pool like `video`) so a healthy account can't be misreported as exhausted ([#346](https://github.com/tombii/better-ccflare/pull/346)); fixed the dashboard's `no_account` bucket always reporting 0% success and being un-clickable — `COALESCE(account_used, ...)` in the success-rate query and an `IS NULL OR = ...` drill-down filter so NULL-encoded and legacy `'no_account'`-literal rows both collapse into the same bucket, plus a self-reported PostgreSQL production incident (GROUP BY functional-dependency violation from the placeholder renumberer) diagnosed and fixed same-day with a verified `GROUP BY 1` rewrite, BIGINT-as-string coercions across several repositories, and a new `DATABASE_URL`-gated live PostgreSQL query harness ([#352](https://github.com/tombii/better-ccflare/pull/352)); added a startup-time multi-instance guard warning the operator (or optionally refusing to start, via `BETTER_CCFLARE_MULTI_INSTANCE=refuse`) when another live ccflare process shares the same database — a `instance_heartbeats` table (ported to both SQLite and PostgreSQL) is written and refreshed on a 5s tick per instance, with rows older than 30s treated as a dead predecessor so a crash never blocks a legitimate restart, naming the seven categories of in-process coordination state (session affinity, usage caches, refresh mutex, circuit breaker, etc.) that silently diverge across instances sharing one database ([#376](https://github.com/tombii/better-ccflare/pull/376)); hardened MiniMax Token Plan status-code handling — replaced the `!== 0` failure check with a positive success allowlist distinguishing known failures (auth/quota) from unrecognized codes so a future MiniMax success code other than `0` can't silently read as a permanent failure, and fixed `registerMinimaxUsagePolling` silently skipping accounts with a missing/empty API key with no log signal, which previously surfaced as a misleading "no Minimax accounts found" diagnosis when accounts existed but lacked credentials ([#350](https://github.com/tombii/better-ccflare/pull/350)); gated agent workspace auto-discovery in `interceptAndModifyRequest` behind an opt-in `BETTER_CCFLARE_AGENT_WORKSPACE_AUTODISCOVER` flag (off by default), mirroring the existing `BETTER_CCFLARE_DISCOVER_PLUGIN_AGENTS` precedent — stops every request in containerized/server deploys from regex-hunting filesystem paths out of client system prompts and burning a hot-path `existsSync` + `registerWorkspace()` cache refresh that could never succeed against the local allowlist anyway, while already-persisted workspaces continue to load normally ([#361](https://github.com/tombii/better-ccflare/pull/361)); fixed Bun's native off-heap body retention (issue #273) on abandoned proxy `Response`s — benchmarked and disproved the prior `body.cancel()` mitigation as a no-op on every released Bun (indistinguishable RSS growth with or without it, confirmed upstream at oven-sh/bun#35093), then replaced it with a chunked drain (`drainBody`) that actually releases the native backing store, wired across all 12 failover/retry discard sites plus the previously-unreleased `extractUsageInfo` response clone in `updateAccountMetadata`; also caught and disclosed a flaw in the PR's own real-network leak harness after merge (bad auth token producing 144-byte responses, plus shared-process RSS measurement masking the signal), replacing it with an isolated-process rig and cautioning that its own median result is inconclusive at n=6 ([#353](https://github.com/tombii/better-ccflare/pull/353)); made the pool-exhausted 503 usage-aware after a production incident where every account was usage-capped (not rate-limited) for 116 minutes — `/health` kept reporting `routable: 3` and every 503 carried a flat `Retry-After: 60`, which combined with `CLAUDE_CODE_MAX_RETRIES=5` to kill client retries in ~300s; added a `usage_exhausted` reason to the pool-exhausted response ladder, derived `next_available_at`/`Retry-After` from the earliest of cooldown expiry and known usage reset with a 600s (UsageCache TTL) floor when no reset is known, and made `/health`'s `routable` count usage-aware to match what the proxy will actually route ([#365](https://github.com/tombii/better-ccflare/pull/365)); added a per-account/per-provider circuit breaker (closed/open/half-open) around the proxy's failure handling, tripping on sustained upstream failures independently of rate-limit/usage state and exposing a distinct `circuit_open` pool-exhaustion reason with its own 30s Retry-After cooldown floor — composed against the concurrently-landed usage-aware pool-exhaustion work (#365) so `circuit_open` still reports the longer, more honest wait when a breaker-tripped account also has a known usage or rate-limit recovery time, rather than undercutting it with the bare 30s floor ([#349](https://github.com/tombii/better-ccflare/pull/349)); surfaced full anomaly-detector totals and truncation state in the Insights dashboard — a new per-detector `AnomalyDetectorSummary` (`totalCount`/`truncated`) exposes the untrimmed detected count alongside the existing top-N sample so an operator can tell "50 of 50" (healthy) from "50 of 3,247" (a real spike) instead of a silently saturated cap, with a new `AnomaliesView` panel surfacing severity ordering, a truncation badge, and threshold text derived live from response `meta` rather than hard-coded; also fixed a self-caught regression where sanitizing the `project` field for display before anomaly detection collapsed distinct same-63-char-prefix projects into one runaway-loop group — moved the sanitizer to the output boundary so detection always sees the raw, already-length-capped DB value ([#369](https://github.com/tombii/better-ccflare/pull/369)); added an optional build-time `CCFLARE_BUILD_SUFFIX` env var so patched/forked builds report `<version>+<suffix>` instead of an indistinguishable stock version string, surfaced through the CLI `--version` flag, the server startup banner, and the dashboard bundle, with a strict no-op (byte-identical output) when unset ([#371](https://github.com/tombii/better-ccflare/pull/371)); fixed MiniMax Token Plan and Alibaba Coding Plan accounts collapsing to a single most-restrictive usage bar instead of separate 5-hour/7-day rows — added the missing providers to the dashboard's weekly-usage allow-list and a shape-based probe in `RateLimitProgress` disambiguating MiniMax's canonical camelCase `resetAt` windows from the Anthropic-style snake_case `resets_at` shape, so each window now renders its own utilization instead of the top-level `Math.max`-across-windows fallback hiding real headroom ([#372](https://github.com/tombii/better-ccflare/pull/372)); fixed `runaway_loop` anomaly detector firing CRITICAL alerts on healthy fleet parallelism (issue #367) — refined the detector's group key from `(account, model, project)` to `(account, model, project, agentUsed)` so independently-routed workers sharing one account+model+project no longer collapse into a single bucket and trip each other, threaded `agentUsed` through the row interface and detection path, added `x-claude-code-session-id` as a last-resort attribution fallback in the agent interceptor (after explicit-header and system-prompt detection) with a distinct `session_header` attribution source so claude-cli traffic gains per-session identity with no client change, and made the `loopMinRequests` threshold configurable with project preserved in the cooldown/alert dedup ID so distinct projects on the same account/model can't suppress each other's alerts ([#370](https://github.com/tombii/better-ccflare/pull/370)); deployment guide section documenting the single-instance-per-database operator rule — names the seven categories of in-process coordination state (session affinity, usage caches, refresh mutex, circuit breaker, etc.) that silently diverge when two instances share a database, explains why the divergence produces no error, and gives concrete alternatives (cold-handoff rolling restarts instead of true blue/green, and account-partitioned horizontal scaling with one database per instance); also flagged the pre-existing Kubernetes example's contradiction with the new rule for maintainer resolution rather than editing it unilaterally ([#377](https://github.com/tombii/better-ccflare/pull/377)); added build-time provenance (`version`, `git_sha`, `git_ref`, `build_date`) to the `/health` response so operators can verify the running image matches the deploy branch HEAD, with each field falling back to `"unknown"` when unset so the shape stays stable ([#380](https://github.com/tombii/better-ccflare/pull/380)); diagnosed the PostgreSQL `instance_heartbeats` integer-out-of-range crash loop (issue #383) with a production-tested repro, root cause, and workaround, then hardened the multi-instance guard's refuse-path cleanup against transient DELETE failures (SQLITE_BUSY, brief PG connection blips) that could otherwise leave an orphaned heartbeat row and cause a fast restart to falsely refuse startup again — added `clearHeartbeatWithRetry` with bounded exponential backoff (3 attempts, 25/50/100ms), used only on the refuse path since the shutdown-path stopper has no benefit from retrying a dying process ([#387](https://github.com/tombii/better-ccflare/pull/387)); replaced deployment-specific hostnames, an operator filesystem path, and internal issue-tracker identifiers with generic wording across comments and test descriptions in 12 files, preserving engineering meaning with zero behavior change ([#385](https://github.com/tombii/better-ccflare/pull/385)); fixed three real defects masking each other in `bun test`'s full-suite run — cross-file `mock.module()` pollution in `oauth.test.ts`/`qwen-account-reauth.test.ts` silently nuking other tests' `@better-ccflare/proxy`/provider exports for the rest of the process (fixed by capturing and restoring the real module around each mock), an unhandled `PRAGMA wal_checkpoint` rejection surfacing as "Unhandled error between tests" when a test's scratch DB was already unlinked before `close()` ran (made best-effort), and a CLI TLS test missing `--ssl-cert`; then routed 19 hardcoded `/tmp/test-*.db` paths through `TMPDIR` so the suite passes under sandboxed CI, and cleaned up per-test CLI database + WAL/SHM siblings to stop them accumulating across runs (issue #107, [PR #386](https://github.com/tombii/better-ccflare/pull/386)); closed the remaining gap flagged by greptile-apps on merged PR #196 — the mid-stream SSE rate-limit path in `response-handler.ts` was missing the cache-keepalive cooldown exemption already applied at the other 3 sites in `proxy-operations.ts` and `response-processor.ts`, so a keepalive replay's 200 OK response later emitting a mid-stream `event: error` frame could still cool an account that should have been exempt; applied the same `isInternalProbe(headers, ctx, 'keepalive')` idiom with the anti-forgery secret gate preserved, with regression tests pinning both exempt error types and the forged-header case ([PR #388](https://github.com/tombii/better-ccflare/pull/388))
|
|
801
|
-
- [@robsonek](https://github.com/robsonek) - Stopped accounts being benched for a request-scoped Anthropic 429 that reports `x-should-retry: true` with no rate-limit metadata — added a fail-closed, header-only `isRetryable429` predicate (scanning all header names by `anthropic-ratelimit-`/`x-ratelimit-` prefix so a future window shape is automatically declined) that classifies such responses as `windowless_429`, failing over per-request with no account cooldown and no consecutive-429 increment instead of draining the pool account-by-account until force-reset was required (PR #375)
|
|
801
|
+
- [@robsonek](https://github.com/robsonek) - Stopped accounts being benched for a request-scoped Anthropic 429 that reports `x-should-retry: true` with no rate-limit metadata — added a fail-closed, header-only `isRetryable429` predicate (scanning all header names by `anthropic-ratelimit-`/`x-ratelimit-` prefix so a future window shape is automatically declined) that classifies such responses as `windowless_429`, failing over per-request with no account cooldown and no consecutive-429 increment instead of draining the pool account-by-account until force-reset was required (PR #375); fixed refresh-token rotation races that could permanently flag healthy OAuth accounts as requiring re-auth — a production incident flagged 7 of 8 accounts this way, 4 holding valid tokens at the time. Three-layer defense in depth: the token-manager funnel joins in-flight refreshes before the backoff check and adopts fresher DB credentials by monotonic ordering before ever refreshing, so a stale-snapshot refresh can't replay an already-rotated token; rotated-token persistence and `requires_reauth` flagging both move to compare-and-set writes keyed on the exact token the provider rejected, so a superseded token can never condemn a healthy account; and a new pending-rotation registry retains a provider-committed rotation in memory (serving it and suppressing `requires_reauth`) when DB persistence itself fails, re-persisting at every later touchpoint. Proactive scheduler paths (qwen/xai/codex) get the same CAS treatment. 30+ new tests, three rounds of review including Greptile P1 fixes for a superseded-result edge case and a registry eviction safety valve, and production validation showing zero false flags through a post-restart thundering herd ([#407](https://github.com/tombii/better-ccflare/pull/407))
|
|
802
802
|
- [@issmirnov](https://github.com/issmirnov) - Persisted analytics view controls (view mode, time range, metric, model breakdown, filters) in the URL query string and localStorage so selections survive reloads and are shareable via link, with defensive decoding and cumulative-view coupling enforced centrally (PR #252); round the Success Rate Trend chart's Y-axis tick labels and tooltip to zero decimals via `formatPercentage(..., 0)` so values like `99.1666...%` no longer overflow their container, and add a human-readable "Success Rate" line name (PR #280)
|
|
803
803
|
- [@CorentinLumineau](https://github.com/CorentinLumineau) - Plugin agent discovery scanning Claude Code plugin directories for agent definitions alongside the built-in agents path, with manifest parsing, name validation, and dashboard display (PR #197)
|
|
804
804
|
- [@d4rken](https://github.com/d4rken) - fixed dashboard "Active" badge showing the most-recently-used account instead of the one the load balancer would actually pick next — introduced a side-effect-free `peek()` to `LoadBalancingStrategy` (shared `peek-availability.ts` mirrors auto-unpause logic without DB writes), dashboard accounts endpoint stamps `isPrimary: true` on the predicted pick, badge renamed from "Active" to "Primary"; also inlined the account-row controls previously hidden behind a `MoreHorizontal` dropdown into flat action buttons (PR #218); Dashboard account row reorganization into wrap-friendly multi-row layout with overflow kebab menu, restored tooltip context for moved actions, and deduped re-auth condition (PR #204); surfaced API key mutation errors inline in create/delete/toggle dialogs, prevented first-key lockout by disabling admin checkbox during loading with fail-safe isFirstKey guard, and added dismissible error banner for role/toggle failures (PR #205); fixed OAuth account creation silently discarding the priority value by adding a priority column to oauth_sessions and threading it through init → session → callback → account creation, plus replaced the constraint-dropping `CREATE TABLE … AS SELECT` tier-drop rebuild with an explicit schema-preserving migration (PR #206); surfaced update-check failure reason in dashboard tile by including the underlying error message in the backend 500 response body, switching to structured Logger, and displaying the error message under "Check Failed" in the frontend sidebar tile (PR #207); exempted /api/version/check from authentication so the dashboard update tile works correctly when API keys are configured (PR #208); replaced bare error-code list with grouped error UI featuring per-(errorCode, account) dismissal, time-window selector (1h/24h/7d/all) persisted in localStorage, clickable rows opening a details modal with human-readable descriptions and recovery info, and a CTE+window-function backend query joining account rate-limit state (PR #209); added combined-quota "5h Pool" and "7d Pool" metric tiles to the Overview dashboard aggregating per-account utilization across all eligible accounts, with worst-account subline, popover breakdown by contributing/exhausted/excluded/fallback accounts, at-risk projection, and next-reset time (PR #210); fixed SIGTERM race where interval-manager's synchronous process.exit(0) short-circuited async shutdown, dropping in-flight requests and pending DB writes — removed the early exit, added HTTP drain via serverInstance.stop(), reordered shutdown sequence (schedulers → HTTP drain → usage worker → DB flush), and added a 30s watchdog to bound total shutdown time (PR #214); fixed API key copy button silently failing on plain-HTTP hosts by adding a `copyText` helper that prefers the async Clipboard API and falls back to an off-screen textarea + `execCommand` for non-secure contexts, and routed `CopyButton` and the inline copy buttons in `ApiKeysTab` through it so the checkmark animation works in both cases (PR #215); fixed post-processor worker timing out on large databases (multi-GB) by passing `fastMode=true` to skip the redundant PRAGMA integrity_check — the main thread already ran it, and re-running it in the worker blew past the 10s startup deadline causing silent request loss (PR #220); replaced the bare recent-errors string list with a grouped error card featuring per-(errorCode, account) dismissal, time-window selector (1h/24h/7d/all), clickable rows opening a details modal with human-readable descriptions, recovery info, and provider-aware copy for model_fallback_429 that escalates to error only when no other accounts are available (PR #212); redesigned request history row layout into a two-row card that never wraps the top-line summary, switched the list view to the summary-only endpoint to eliminate the ~12MB per-page-load body fetch, and fixed the API key and account filter dropdowns to source options from dedicated endpoints so deleted-but-historical entries remain selectable (PR #221); replaced fs.copyFileSync migration backup with VACUUM INTO + atomic rename via a .partial temp file, producing a defragmented consistent snapshot and ensuring the named backup only appears complete (PR #222); added bounded backup retention — after each migration backup, prunes `.backup.<ts>` files to keep the newest N (default 3, configurable via `BETTER_CCFLARE_MIGRATION_BACKUP_KEEP`, 0 to disable), sorting by name-embedded timestamp to survive rsync/clock-drift, skipping operator-renamed files with non-integer suffixes (PR #223); bumped the post-processor worker startup timeout from 10s to 60s and made it overridable via `CF_WORKER_STARTUP_TIMEOUT_MS`, preventing silent analytics loss on large (multi-GB) databases where the per-handle PRAGMA work blew past the old deadline (PR #224); narrowed the migration backup gate from a 41-condition OR to only the three genuinely irreversible operations (refresh_token NOT NULL rebuild, account_tier drop, oauth_sessions.tier drop), eliminating multi-GB backup copies on every restart when only additive ALTER TABLE ADD COLUMN migrations are pending (PR #225); resolved all 42 error-level Biome diagnostics across dashboard components, hooks, and openai-formats tests — replaced `noNonNullAssertedOptionalChain` patterns in tests with explicit non-null assertions after `toBeDefined()`, converted `forEach` callbacks to `for…of` to fix `useIterableCallbackReturn`, added scoped `biome-ignore` comments with explanations for `noArrayIndexKey` cases where stable ids aren't available, and fixed two a11y errors in ErrorBoundary (SVG role/aria-label/title, button type attribute) (PR #226); replaced the blocking startup `PRAGMA integrity_check` (which froze the event loop for 94s on a 7.6 GiB DB) with a dual-timer background scheduler running `quick_check` every 6h and a full `integrity_check` + `foreign_key_check` every 24h in a dedicated `bun:sqlite` worker, added a sticky-corrupt rule so a quick `ok` cannot mask a full corruption finding, exposed the status via an expanded `/api/storage` response and a new `POST /api/storage/integrity/check` on-demand endpoint, and surfaced it in the Overview dashboard via a `StorageIntegrityCard` and sticky `StorageIntegrityBanner` on corruption — also adds `foreign_key_check` to the full probe since `integrity_check` per SQLite docs does not verify foreign keys (PR #227); fixed Logger.{error,warn,info,debug} silently emitting `{}` for Error instances by normalizing Errors to plain objects with name/message/stack/cause before serialization — affects 159 call sites including the "Failed to intercept/modify request" line in agent-interceptor — and demoted all per-request INFO logs in agent-interceptor and extractSystemPrompt to DEBUG, plus skipped the spurious `~/.claude/.claude/agents` path construction for global CLAUDE.md entries since global agents are already loaded unconditionally by AgentRegistry (PR #228); fixed `LOG_LEVEL=DEBUG` being silently ignored — `LogLevel.DEBUG === 0` is falsy so `getLogLevelFromEnv() || level` fell back to the constructor default (INFO), suppressing all debug output even when explicitly configured; switched to `??` so the env override applies for DEBUG too, and added regression tests covering DEBUG/WARN/ERROR/unset/unknown values plus the `silentConsole` side-effect (PR #229); eliminated the blocking full VACUUM trap — hourly retention cleanup and "Compact now" called `incrementalVacuum` which silently fell back to a live full VACUUM on existing DBs (auto_vacuum≠INCREMENTAL), freezing the proxy for minutes every hour — replaced with: `configureSqlite` and `ensureSchema` set `PRAGMA auto_vacuum = INCREMENTAL` on fresh DBs, new `bootstrapAutoVacuum()` migrates existing mode-0 DBs once at startup before HTTP binds (one-time VACUUM cost, never blocks live traffic), `incrementalVacuum()` now dispatches `PRAGMA incremental_vacuum(N)` to a worker thread on mode-2 DBs or logs and returns otherwise (no destructive fallback), drops hourly N from 200000 to 8000 (~32 MiB) to keep writer-slot hold sub-100ms, adds consecutive-skip escalation after 3 missed ticks, and gates the auto_vacuum PRAGMA on mode=0 only to preserve operator-set FULL mode; also removed the dashboard "Compact now" button/endpoint (same hang trap from a different surface) while retaining `bun run cli --compact` with a writer-lock probe that refuses if a running service holds it; and dropped the stale `fastMode` constructor arg from DatabaseOperations after PR #227's integrity-scheduler rework made it redundant (PR #230); fixed `mmapSize=0` being silently ignored in `configureSqlite` — the `> 0` guard meant the default `mmapSize: 0` fell through to bun:sqlite's built-in mmap default (~15 GiB observed on a 15 GiB DB), causing the OOM-killing VACUUM scenario from #230 to recur; also applied memory-bounded PRAGMAs (`mmap_size=0`, `cache_size=-2000`, `temp_store=FILE`) to the full-VACUUM worker thread opened by `compact()` / `--compact`, which had the same gap (PR #231); bounded AsyncDbWriter retention to stop a post-processor worker memory leak — split the single job queue into separate metadata (count-capped at 2000) and payload (count-capped at 1000, byte-capped at 100 MB) queues, added a MAX_JOBS_PER_TICK=50 / MAX_DRAIN_MS_PER_TICK=250ms dual budget so processQueue yields to the event loop instead of monopolizing it, added round-robin scheduling to prevent starvation between queue types, added canAcceptPayload() preflight to skip serialization under backpressure, and surfaced per-queue lengths, byte budget, oldest-job age, and per-kind drop counters in getHealth() (PR #234); enabled the refresh-usage button for Codex OAuth accounts — sends one minimal `/responses` request (bounded to `max_output_tokens: 1`, `reasoning.effort: "minimal"`) to capture `x-codex-*` rate-limit headers, cancels the response body after the header snapshot, deduplicates concurrent clicks per-account with a shared in-flight promise, and wires the result into the existing usageCache + accounts.rate_limit_reset flow; polling intentionally excluded to avoid burning quota at 90s cadence (PR #219); added "Avg / day" and "Avg / week" burn-rate sub-rows to the Plan Value metric card on the Overview dashboard — computed server-side from fixed 7-day and 30-day windows (filter-independent) with a clamped divisor via `effectiveBurnRateDays` so thin history doesn't inflate averages, plus a generic `subRows` prop on `MetricCard` for the UI (PR #235); routed Anthropic 529 overloaded_error responses through the existing rate-limit failover machinery so configured fallback providers take over during an overload instead of forwarding the 529 directly to the client — `parseRateLimit` treats 529 as rate-limited, parsing Retry-After (delta-seconds and HTTP-date) and x-ratelimit-reset with a `clampResetTime` helper that caps reset times to 24h to prevent hostile headers from permanently disabling an account; mid-stream `SseRateLimitSniffer` fires on `overloaded_error` frames for Anthropic-shape providers (anthropic/claude-oauth) only with a line-anchored regex to prevent false positives; two new `RateLimitReason` values (`upstream_529_overloaded_with_reset` / `upstream_529_overloaded_no_reset`) surface accurate audit attribution in the dashboard; `returnRateLimitedResponseOnExhaustion` forwards the original 529 upstream response to the client when the full account pool is exhausted so callers see the real error instead of a generic 503 (PR #236); fixed auto-refresh scheduler probing manually-paused accounts in an endless loop — the eligibility SQL excluded paused accounts only when `auto_pause_on_overage_enabled=0`, ignoring `pause_reason`, while the auto-resume guard in `sendDummyMessage` only un-pauses accounts where `pause_reason IN (NULL,'overage')`; aligned the SQL eligibility query to a positive allowlist (`paused=0 OR (overage_enabled=1 AND pause_reason IN (NULL,'overage'))`) and tightened `isOveragePaused` in `account-selector.ts` to require the same condition, so manual, failure-threshold, and peak_hours pauses are left completely alone; adds a regression test that re-executes the live scheduler SQL against a seeded in-memory SQLite DB covering all seven pause-reason scenarios (PR #237); replaced flat per-account 429 cooldown with adaptive exponential backoff — `consecutive_rate_limits` counter increments atomically in SQL on each 429 and drives `min(upstream_reset, BASE × 2^(n−1))` cooldown (capped at MAX, default 30s base / 5min max), counter resets after 5min of clean operation or on successful token refresh, all four 429 paths (response-processor, model_fallback_429, all_models_exhausted_429, mid-stream SSE sniffer) route through a single `applyRateLimitCooldown` helper, tunables overridable via `CCFLARE_RATE_LIMIT_BACKOFF_BASE_MS` / `CCFLARE_RATE_LIMIT_BACKOFF_MAX_MS` / `CCFLARE_RATE_LIMIT_RESET_STABILITY_MS` (PR #213)
|
package/dist/better-ccflare
CHANGED
|
Binary file
|
package/package.json
CHANGED