From f45abff45a6eef701d8971d98fd0bfc391f7c668 Mon Sep 17 00:00:00 2001 From: Xiangzhe Date: Fri, 14 Aug 2026 21:29:20 -0300 Subject: [PATCH] docs: correct drifted counts, reconcile the v3.8.50 changelog and gate the free-forever number Audit of every numeric claim in the README, AGENTS.md and the README SVGs against live code, plus a changelog/credit reconciliation over the full v3.8.50 cycle. Corrected numbers (all measured, not estimated): - Provider circuit breaker thresholds were scaled up in code for 500+ connection deployments (`providerFailureThreshold`: OAuth 3 -> 10, API key 5 -> 15) but the docs still published the pre-scale values. Fixed in AGENTS.md (now a table that also separates the provider-level threshold from the per-connection one and lists the provider cooldowns), in the README alt text and inside resilience-layers.svg (visible label and aria-label). - "40+ free forever" was unsourced. Measured from the free-tier catalog as every provider whose free access renews or needs no key (recurring-monthly, -daily, -uncapped, -credit, keyless; one-time signup credits and discontinued pools excluded): 56. Updated in the README and promise-pillars.svg. - Cycle-evolution table: v3.8.49 shipped 290 providers, not 291, and the model row compared the v3.8.49 free-tier catalog (516) against today's full catalog. Both columns now use the same metric - distinct documented models, 1185 -> 1202. - Tech-stack row: 95 domain modules -> 117. The free-forever count is now enforced by check:docs-counts so it cannot drift again; it is derived from freeType in the live catalog, like every other gated number. Changelog reconciliation (`scripts/release/list-uncovered-commits.mjs`): uncovered cycle commits drop from 149 to 62. 75 user-facing commits gained a bullet with author attribution, the 45 ref-less direct pushes and 29 chore/ci/test/docs commits were consolidated into rollup bullets, and the contributors table grew from 147 to 161 rows - 14 contributors who had landed work with no credit at all (including @amartinawi, @pacocartones and @excessivechaos) are now credited. The remaining 62 carry no PR/issue ref, which is the ceiling of ref-based coverage. --- AGENTS.md | 17 +- CHANGELOG.md | 772 +++++++++++++---------- README.md | 12 +- docs/diagrams/promise-pillars.svg | 4 +- docs/diagrams/resilience-layers.svg | 4 +- scripts/check/check-docs-counts-sync.mjs | 11 +- 6 files changed, 467 insertions(+), 353 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 59be68c2c8..03889aac0a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -118,11 +118,18 @@ upstream/service level, so one unhealthy provider does not slow down every reque - `HALF_OPEN`: reset timeout has elapsed; allow a probe request. Success closes the breaker, failure opens it again. -**Defaults** (`open-sse/config/constants.ts`): +**Defaults** (`open-sse/config/constants.ts` → `PROVIDER_PROFILES`). Two thresholds live side by +side — do not confuse them: -- OAuth providers: threshold `3`, reset timeout `60s`. -- API-key providers: threshold `5`, reset timeout `30s`. -- Local providers: threshold `2`, reset timeout `15s`. +| Profile | `providerFailureThreshold` (whole provider) | `providerCooldownMs` | `circuitBreakerThreshold` (one connection) | `circuitBreakerReset` | +| ------- | ------------------------------------------: | -------------------: | -----------------------------------------: | --------------------: | +| OAuth | `10` | `5min` | `8` | `60s` | +| API key | `15` | `10min` | `12` | `30s` | +| Local | `2` | `1min` | `2` | `15s` | + +The provider-level thresholds were scaled up for deployments with 500+ connections (OAuth was +`3`, API key was `5`); every default is overridable through the `OMNIROUTE_PROVIDER_BREAKER_*` +and `OMNIROUTE_CIRCUIT_BREAKER_*` env vars. Only provider-level failure statuses should trip the provider breaker: @@ -679,7 +686,7 @@ the stale-enforcement added in Fase 6A.3. causa-raiz de DOIS wipes (2026-08-08 e 2026-08-10: `git reset --hard` materializou o symlink rastreado por cima do diretório real e o git apagou todo o conteúdo ignorado sem aviso); (c) após qualquer escrita relevante, `git -C _tasks add -A && git -C _tasks commit - && git -C _tasks push` — o push frequente é o backup real; (d) repetir esta proibição +&& git -C _tasks push` — o push frequente é o backup real; (d) repetir esta proibição VERBATIM no prompt de todo subagente que toque git; (e) se `_tasks` aparecer como symlink quebrado, NÃO commitar nada — restaurar do remote e avisar o operador. O gate `check:tracked-artifacts` (pre-commit + CI) bloqueia `_tasks` rastreado em qualquer forma. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6198c78746..f1769e3e35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `ed2db6cb19` → tip). Bullets carry the merged PR and its author; direct pushes listed separately._ ### ✨ New Features + - **feat(core):** add Layer A capability filter at router (#5696) - **feat(providers):** add DeepAI as paid API-key image provider ([#6671](https://github.com/diegosouzapw/OmniRoute/issues/6671)) - **feat(providers):** add Naga.ac and ChatAnywhere aggregator gateway providers (#6674 — thanks @chirag127) @@ -31,7 +32,7 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `e - **Providers**: expands the Novita AI catalog from a single Llama 3.1 8B entry to 19 curated serving models (DeepSeek V4, Kimi K3, GLM 5.2, MiniMax M3, Qwen3.7 Max, Qwen3 Coder 480B, MiMo V2.5 Pro, gpt-oss-120b, Gemma 4 31B and more), each carrying its real context window, output cap and reasoning flag from the live `/openai/v1/models` listing, and each vision flag confirmed by an actual image request rather than the listing's self-reported modalities ([#8913](https://github.com/diegosouzapw/OmniRoute/pull/8913)) — thanks @jax-novita - **feat(providers):** native xAI Agent Tools passthrough on `/v1/responses` for `xai` / `xai-oauth` (`xao`) — forward `web_search` + `x_search` to `api.x.ai` instead of rewriting or rejecting them ([#8964](https://github.com/diegosouzapw/OmniRoute/issues/8964)) - **feat(providers): add UnoRouter provider** — UnoRouter is an OpenAI-compatible routing gateway supporting hundreds of models. It is now registered as an API-key provider. ([#8978](https://github.com/diegosouzapw/OmniRoute/issues/8978)) -- **feat(sse):** deprecated the legacy `gemini-cli` **upstream provider**. It was not routable (no registry entry, no executor), yet the scheduler kept refreshing its token against Google — maintaining a credential that could never serve a request. A stored connection now becomes terminal with a legible reason and a working migration path: re-add the account under `gemini`, which uses the same Google OAuth client. The `gemini-cli` **client identity** (requests arriving *from* the Gemini CLI, issue #7034) is untouched ([#8980](https://github.com/diegosouzapw/OmniRoute/pull/8980)) +- **feat(sse):** deprecated the legacy `gemini-cli` **upstream provider**. It was not routable (no registry entry, no executor), yet the scheduler kept refreshing its token against Google — maintaining a credential that could never serve a request. A stored connection now becomes terminal with a legible reason and a working migration path: re-add the account under `gemini`, which uses the same Google OAuth client. The `gemini-cli` **client identity** (requests arriving _from_ the Gemini CLI, issue #7034) is untouched ([#8980](https://github.com/diegosouzapw/OmniRoute/pull/8980)) - Add a default-off connection setting for Codex, OpenAI, and OpenAI-compatible Responses API providers that preserves client-supplied `reasoning.encrypted_content` items for replay, including per-target combo routing. - Omit opaque encrypted reasoning values from persisted call logs while retaining compact diagnostic markers. (#9000) - **feat(providers):** add Regolo AI OpenAI-compatible provider ([#9031](https://github.com/diegosouzapw/OmniRoute/issues/9031)) @@ -44,6 +45,7 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `e - feat(images): execute full combo strategy + fallback in /v1/images/generations (#9239) Adds open-sse/services/imageCombo.ts that expands combo targets, filters to images-capable, executes the priority strategy with handleImageGeneration per target, and returns the first success or last failure. Route patches detect combo names before model resolution and divert to the new execution path. + - feat: make forwarded upstream response-header budget configurable via env var (#9243) - **feat(providers):** filter provider detail connections server-side while preserving full-page search and pagination. (thanks @RobertsXML) ([#9247](https://github.com/diegosouzapw/OmniRoute/pull/9247)) - **feat(providers):** make video_url passthrough configurable per provider/model via compat override ([#9248](https://github.com/diegosouzapw/OmniRoute/issues/9248)) — thanks @HellFiveOsborn @@ -61,6 +63,7 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `e - feat(opencode-plugin): warm catalog startup from disk snapshot + parallel refresh (#9490) The config-shim hook now reads the last disk snapshot before fetching, so the provider registers immediately with the last-known-good catalog (~1-2s vs ~30s on a warm gateway). All six fetchers run concurrently via Promise.allSettled instead of sequentially. A failed refresh keeps the snapshot (no overwrite). An in-flight guard prevents concurrent refreshes for the same cache key. The features.diskCache: false opt-out disables the warm read entirely. + - **feat(models):** Test All's "Auto-hide failed models" no longer hides quota errors — daily-quota-exhausted and credits-exhausted responses are now classified via the routing path's existing quota detectors, so an evening Test All on a free-tier provider no longer silently wipes the catalog. Quota results stay visible with a distinct amber badge ([#9511](https://github.com/diegosouzapw/OmniRoute/issues/9511)) - Add an advisory forgotten-sibling-tests report to pull-request quality checks. The report traces changed modules through their static consumers to candidate sibling tests, while keeping barrel and dynamic-import cases non-blocking and requiring reviewed, referenced exceptions. (#9530) - feat(providers): add Muse Code CLI provider preset (#9544) @@ -76,6 +79,7 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `e `model`, `provider`, `errorCode`. Non-breaking — existing `onResponse` hooks with `{ streamed: true }` remain unchanged. + - **feat(audio):** Soniox STT + TTS provider (`sx`) — async speech-to-text (`stt-async-v5`, `stt-async-v4`) and real-time text-to-speech (`tts-rt-v1`) ([#9579](https://github.com/diegosouzapw/OmniRoute/pull/9579)) - Show cache-read and cache-write token counts in request log rows and details when providers report them. (#9620) @@ -148,6 +152,22 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `e - **feat(admission) — direct pushes:** adaptive overload/pressure controls with shared admission wired across the LLM routes, plus mutation-test registration for the capability-filter suite - **feat(agentrouter) — direct pushes:** support Claude and Codex protocols — infer the protocol from the client endpoint and honor the alternate protocol through the chat pipeline - **feat(providers) — direct pushes:** ChatGPT Web session credential guide with a Cookie Editor fast-path (canonical chromewebstore install link) and web-session fast-path test coverage +- **feat(sse):** honor provider-rule lock scope for agentrouter (connection vs model) ([#10419](https://github.com/diegosouzapw/OmniRoute/pull/10419)) +- **feat(ocr):** Vertex AI DeepSeek-OCR provider ([#10398](https://github.com/diegosouzapw/OmniRoute/pull/10398)) +- **feat(providers):** derive imageToText from the OCR registry + chutes dots.ocr seed ([#10400](https://github.com/diegosouzapw/OmniRoute/pull/10400)) +- **feat(ocr):** multi-provider /v1/ocr with transformation layer (Azure Document Intelligence) ([#10283](https://github.com/diegosouzapw/OmniRoute/pull/10283)) +- **feat(providers):** declare imageToText serviceKind on major vision providers ([#10275](https://github.com/diegosouzapw/OmniRoute/pull/10275)) +- **feat(bridge):** native-vision skip guard + configurable describe output cap ([#10289](https://github.com/diegosouzapw/OmniRoute/pull/10289)) +- **feat(bridge):** normalize images to 2048px long edge before vision describe self-call ([#10287](https://github.com/diegosouzapw/OmniRoute/pull/10287)) +- **feat(sse):** restate agentrouter quota 403/400 as retryable 429 with provider-scoped error rules ([#10335](https://github.com/diegosouzapw/OmniRoute/pull/10335)) +- **feat(sse):** add i-have-adhd output style to compression catalog ([#10271](https://github.com/diegosouzapw/OmniRoute/pull/10271)) +- **feat(codex):** add OAuth fingerprint convergence modes ([#10243](https://github.com/diegosouzapw/OmniRoute/pull/10243)) — thanks @xz-dev +- **feat(i18n):** complete Portuguese (PT-PT) translation ([#10250](https://github.com/diegosouzapw/OmniRoute/pull/10250)) — thanks @DarkEsteves +- **feat(providers):** publish Poolside's probed Laguna Preview catalog ([#10216](https://github.com/diegosouzapw/OmniRoute/pull/10216)) — thanks @pacocartones +- **feat(crof):** advertise reasoning effort tiers incl. max from live discovery and registry ([#10062](https://github.com/diegosouzapw/OmniRoute/pull/10062)) — thanks @excessivechaos +- **feat(open-sse):** expose provider-level circuit breaker thresholds via env vars (#10040) ([#10046](https://github.com/diegosouzapw/OmniRoute/pull/10046)) — thanks @tiangao88 +- **feat(dashboard):** Kimi 15% first-top-up campaign — dedicated tracked link + discount-first banner copy ([#10240](https://github.com/diegosouzapw/OmniRoute/pull/10240)) +- **feat(providers):** integrate audited free-tier gateways ([#9210](https://github.com/diegosouzapw/OmniRoute/pull/9210)) ### 🐛 Bug Fixes @@ -553,6 +573,63 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `e - **fix(i18n) — direct pushes:** restore/unescape HTML entities in UI strings, translate capability-filter messages, complete web-session guide translations and Vietnamese parity - **fix(providers) — direct pushes:** repair the DeepAI registry import + executor - **fix(deps) — direct pushes:** CVE-driven bumps (nanoid, dompurify, mermaid, js-yaml + transitive deps for 26 Dependabot alerts) and retained isolated-build runtime dependencies in the pack +- **fix(ci):** pin Build (advisory) to a hosted runner with memory provisioning ([#10408](https://github.com/diegosouzapw/OmniRoute/pull/10408)) +- **fix(providers):** refresh the translate-path golden for the bailian Token Plan endpoint ([#10410](https://github.com/diegosouzapw/OmniRoute/pull/10410)) +- **fix(sse):** surface Qwen/Alibaba personal Token Plan quota in dashboard and preflight ([#10290](https://github.com/diegosouzapw/OmniRoute/pull/10290)) +- **fix(deps):** pin next to an exact version so a fresh upstream release cannot break installs ([#10340](https://github.com/diegosouzapw/OmniRoute/pull/10340)) +- **fix(types):** restore custom model output limit contract ([#10339](https://github.com/diegosouzapw/OmniRoute/pull/10339)) — thanks @backryun +- **fix(sse):** stop the executor-contract guard from hot-looping the router ([#10373](https://github.com/diegosouzapw/OmniRoute/pull/10373)) +- **fix(types):** validate nonstreaming JSON contracts ([#10258](https://github.com/diegosouzapw/OmniRoute/pull/10258)) — thanks @backryun +- **fix(types):** narrow refresh token rotation inputs ([#10257](https://github.com/diegosouzapw/OmniRoute/pull/10257)) — thanks @backryun +- **fix(types):** normalize executor result contracts ([#10256](https://github.com/diegosouzapw/OmniRoute/pull/10256)) — thanks @backryun +- **fix(types):** align Responses stream options ([#10255](https://github.com/diegosouzapw/OmniRoute/pull/10255)) — thanks @backryun +- **fix(types):** narrow combo credential preflight ([#10254](https://github.com/diegosouzapw/OmniRoute/pull/10254)) — thanks @backryun +- **fix(compression):** cap countTextTokens at 50k chars and strip base64 data URIs ([#10118](https://github.com/diegosouzapw/OmniRoute/pull/10118)) — thanks @adevwithpurpose +- **fix(ci):** clear base-reds on release/v3.8.50 (round 4) ([#10260](https://github.com/diegosouzapw/OmniRoute/pull/10260)) +- **fix(sse):** extract perplexity-web answers from workflow_block ([#10259](https://github.com/diegosouzapw/OmniRoute/pull/10259)) — thanks @jeyhunfaslanov +- **fix(mcp):** persist and re-attach Gemini thoughtSignature on the direct Claude<->Gemini path ([#9448](https://github.com/diegosouzapw/OmniRoute/pull/9448)) — thanks @Sam280903 +- **fix(opencode-plugin):** respect log level for lifecycle output (#8982) ([#9316](https://github.com/diegosouzapw/OmniRoute/pull/9316)) — thanks @xiaoyaner0201 +- **fix(providers):** raise default provider probe timeout from 5s to 8s ([#9283](https://github.com/diegosouzapw/OmniRoute/pull/9283)) — thanks @Sam280903 +- **fix(opencode-plugin):** stop warning when an auto combo replaces its expected /v1/models twin (#8983) ([#9042](https://github.com/diegosouzapw/OmniRoute/pull/9042)) — thanks @xiaoyaner0201 +- **fix(opencode):** force CLI User-Agent when CLI identity synthesis is enabled ([#10222](https://github.com/diegosouzapw/OmniRoute/pull/10222)) — thanks @adevwithpurpose +- **fix(deepseek-web):** classify business auth rejection as 401 ([#10218](https://github.com/diegosouzapw/OmniRoute/pull/10218)) — thanks @Zartharas +- **fix(combo):** make failoverBeforeRetry actually skip the same-model retry ([#10217](https://github.com/diegosouzapw/OmniRoute/pull/10217)) — thanks @hartmark +- **fix(responses):** preserve case-insensitive combo names before Codex rewrite ([#10177](https://github.com/diegosouzapw/OmniRoute/pull/10177)) — thanks @ddarkr +- **fix(discovery):** parse reasoning tiers nested under metadata.reasoning.supported_efforts ([#10138](https://github.com/diegosouzapw/OmniRoute/pull/10138)) — thanks @excessivechaos +- **fix(combo):** isolate session stickiness by combo ([#10137](https://github.com/diegosouzapw/OmniRoute/pull/10137)) — thanks @hydraxman +- **fix(combo):** default chaos SSE to comment-only for OpenAI-compatible clients ([#10128](https://github.com/diegosouzapw/OmniRoute/pull/10128)) — thanks @herjarsa +- **fix(kimi):** normalize MFJS tool schemas ([#10079](https://github.com/diegosouzapw/OmniRoute/pull/10079)) — thanks @xz-dev +- **fix(mcp):** move pack validation out of unit suite ([#10065](https://github.com/diegosouzapw/OmniRoute/pull/10065)) — thanks @yansigit +- **fix(zed-hosted):** send the provider wire values cloud.zed.dev accepts ([#10051](https://github.com/diegosouzapw/OmniRoute/pull/10051)) — thanks @ARC345 +- **fix(ci):** repair and wire the two live-server E2E suites ([#10050](https://github.com/diegosouzapw/OmniRoute/pull/10050)) — thanks @ARC345 +- **fix(reasoning):** preserve and replay assistant turns ([#10045](https://github.com/diegosouzapw/OmniRoute/pull/10045)) — thanks @jackjinke +- **fix(types):** tighten chatCore helper contracts ([#10175](https://github.com/diegosouzapw/OmniRoute/pull/10175)) — thanks @backryun +- **fix(cli):** read the full provider catalog instead of the 6-entry fallback ([#10097](https://github.com/diegosouzapw/OmniRoute/pull/10097)) — thanks @amartinawi +- **fix(cli):** stop swallowing non-2xx responses into benign-looking results ([#10092](https://github.com/diegosouzapw/OmniRoute/pull/10092)) — thanks @amartinawi +- **fix(cli):** openapi endpoints/paths/validate accept the served catalog shape ([#10091](https://github.com/diegosouzapw/OmniRoute/pull/10091)) — thanks @amartinawi +- **fix(cli):** doctor detects prebuilt better-sqlite3 binaries ([#10090](https://github.com/diegosouzapw/OmniRoute/pull/10090)) — thanks @amartinawi +- **fix(providers):** kilo-gateway authType should be optional, not apikey ([#10086](https://github.com/diegosouzapw/OmniRoute/pull/10086)) — thanks @TengSivtean +- **fix(cli):** strip inline comments when parsing .env values ([#10101](https://github.com/diegosouzapw/OmniRoute/pull/10101)) — thanks @amartinawi +- **fix(logging):** document CHAT_LOG_MAX_BODY_KB, capture messageCount for Responses API bodies ([#10038](https://github.com/diegosouzapw/OmniRoute/pull/10038)) — thanks @hartmark +- **fix(dashboard):** expose OpenAI Responses store toggle for non-Codex connections ([#10121](https://github.com/diegosouzapw/OmniRoute/pull/10121)) — thanks @hartmark +- **fix(combo):** clear LKGP pin when its target fails, not only set it on success ([#10034](https://github.com/diegosouzapw/OmniRoute/pull/10034)) — thanks @hartmark +- **fix(sse):** provider-response summary format bugs (dashboard Provider Response panel) ([#10037](https://github.com/diegosouzapw/OmniRoute/pull/10037)) — thanks @hartmark +- **fix(responses-api):** tool call after reasoning collided on the same output_index ([#10025](https://github.com/diegosouzapw/OmniRoute/pull/10025)) — thanks @hartmark +- **fix(responses-api):** explicit function-tool declaration must win over apply_patch-is-custom fallback ([#10041](https://github.com/diegosouzapw/OmniRoute/pull/10041)) — thanks @hartmark +- **fix(kimi):** recupera limite temporario sem bloquear conta ([#10058](https://github.com/diegosouzapw/OmniRoute/pull/10058)) — thanks @bortolidiego +- **fix(translator):** preserve Responses custom tools for OpenAI-compatible providers ([#10114](https://github.com/diegosouzapw/OmniRoute/pull/10114)) — thanks @mtb-ninja +- **fix(providers):** xai-oauth chat→responses body + missing breaker import (#10165) ([#10170](https://github.com/diegosouzapw/OmniRoute/pull/10170)) — thanks @nordz0r +- **fix(ollama-cloud):** map xhigh reasoning effort to max ([#10160](https://github.com/diegosouzapw/OmniRoute/pull/10160)) — thanks @Chewji9875 +- **fix(translator):** strip Codex encrypted tool-schema key for Gemini/Antigravity ([#10053](https://github.com/diegosouzapw/OmniRoute/pull/10053)) — thanks @XDayonline +- **fix(combo):** preserve OpenCode Free oc/ prefix for connections ([#10180](https://github.com/diegosouzapw/OmniRoute/pull/10180)) — thanks @AStupidBear +- **fix(sse):** apply free-tier filter to auto/best-free on chat path ([#10199](https://github.com/diegosouzapw/OmniRoute/pull/10199)) — thanks @ggdayup +- **fix(providers):** default missing cache_control.ttl to 1h on the native Claude OAuth path ([#10221](https://github.com/diegosouzapw/OmniRoute/pull/10221)) — thanks @jeff-alves +- **fix(ci):** clear base-reds on release/v3.8.50 (round 3) ([#10213](https://github.com/diegosouzapw/OmniRoute/pull/10213)) +- **fix(security):** correct XML double-unescape and non-CSPRNG nonce from CodeQL sweep ([#10154](https://github.com/diegosouzapw/OmniRoute/pull/10154)) +- **fix(docker):** eliminate npm-bundled CVEs from the published image ([#10182](https://github.com/diegosouzapw/OmniRoute/pull/10182)) +- **fix(security):** resolve open CodeQL alerts ([#10188](https://github.com/diegosouzapw/OmniRoute/pull/10188)) +- **fix(dashboard):** retarget Kimi promo CTA to the API platform aff link ([#10200](https://github.com/diegosouzapw/OmniRoute/pull/10200)) +- **fix(build):** repair broken production build, red lint gate and SWR crash ([#10198](https://github.com/diegosouzapw/OmniRoute/pull/10198)) ### 📝 Maintenance @@ -698,160 +775,178 @@ _Living section — regenerated 2026-08-12 from all cycle commits (cycle open `e - **deps (rollup):** dependency bumps and lockfile maintenance across the cycle — Dependabot groups and manual CVE-driven bumps ([#9081](https://github.com/diegosouzapw/OmniRoute/pull/9081), [#9082](https://github.com/diegosouzapw/OmniRoute/pull/9082), [#9427](https://github.com/diegosouzapw/OmniRoute/pull/9427), [#9458](https://github.com/diegosouzapw/OmniRoute/pull/9458), [#9459](https://github.com/diegosouzapw/OmniRoute/pull/9459), [#9461](https://github.com/diegosouzapw/OmniRoute/pull/9461), [#9462](https://github.com/diegosouzapw/OmniRoute/pull/9462), [#9472](https://github.com/diegosouzapw/OmniRoute/pull/9472)) - **docs/chore (rollup):** documentation, refactoring and repository-hygiene upkeep across the cycle ([#8954](https://github.com/diegosouzapw/OmniRoute/pull/8954), [#8991](https://github.com/diegosouzapw/OmniRoute/pull/8991), [#9059](https://github.com/diegosouzapw/OmniRoute/pull/9059), [#9194](https://github.com/diegosouzapw/OmniRoute/pull/9194), [#9258](https://github.com/diegosouzapw/OmniRoute/pull/9258), [#9508](https://github.com/diegosouzapw/OmniRoute/pull/9508)) - **main-branch plumbing (rollup):** work that landed on `main` between cycles and was carried into this one — the Mergify merge-queue migration and tuning (#7168, #7179, #7216, #7220, #7225), npm-publish unblock via dynamic runner + CI build reuse (#8941), CodeQL-driven e2e mock hardening (#7559), hermetic self-ref guard (#6634, #7341), coverage-baseline tightening (#7347), Dependabot alert resolutions via npm overrides (#8067, #8070), README flag/doc-link polish (#8317), and the v3.8.49 release plumbing itself (#7076) +- **deps:** bump the development group across 1 directory with 22 updates ([#10043](https://github.com/diegosouzapw/OmniRoute/pull/10043)) — thanks @app/dependabot +- **deps:** bump electron from 43.2.0 to 43.3.0 in /electron ([#10042](https://github.com/diegosouzapw/OmniRoute/pull/10042)) — thanks @app/dependabot +- **maint(release):** 45 direct pushes to the release branch with no PR ref — base-red and quality-gate repairs, i18n string completion and stream/type fixes (quality ×6, i18n ×5, deps ×3, agentrouter ×3, providers ×2, release ×2, security ×2, logging ×2) +- **maint(repo):** 29 chore/ci/test/docs commits rolled up — quality baselines, mutation registration, CI re-triggers, doc restructure and repo hygiene (#10187, #10189, #10190, #10193, #10196, #10203, #10204, #10205, #10207, #10210, #10236, #10318) ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: -| Contributor | PRs / Issues | -| --- | --- | -| [@AbdullahFageeh](https://github.com/AbdullahFageeh) | #9087 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790 | -| [@adrianojiu](https://github.com/adrianojiu) | #8438 | -| [@agisota](https://github.com/agisota) | #9837 | -| [@AgnesRiber](https://github.com/AgnesRiber) | #9718, #9976 | -| [@ahmet-cetinkaya](https://github.com/ahmet-cetinkaya) | #8878 | -| [@AIB1TAL0S](https://github.com/AIB1TAL0S) | #9284 | -| [@AlanSyue](https://github.com/AlanSyue) | direct commit / report | -| [@alex-jordan547](https://github.com/alex-jordan547) | #9235, #9245, #9813 | -| [@AndrianBalanescu](https://github.com/AndrianBalanescu) | #8888, #8889, #8890, #8891, #8892, #8893, #8894, #8895 | -| [@AnhLead](https://github.com/AnhLead) | #9722 | -| [@aniketshukla1](https://github.com/aniketshukla1) | #9148 | -| [@Anjielon](https://github.com/Anjielon) | #8776 | -| [@apoapostolov](https://github.com/apoapostolov) | #8916 | -| [@ARC345](https://github.com/ARC345) | #9628 | -| [@artickc](https://github.com/artickc) | #8571, #8578, #8791, #8843, #8870, #8927, #8974, #9097, #9549 | -| [@Arul-](https://github.com/Arul-) | #9761 | -| [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10178 | -| [@Benson-mk](https://github.com/Benson-mk) | #8369 | -| [@benzntech](https://github.com/benzntech) | #9810, #9812, #9939 | -| [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | -| [@branben](https://github.com/branben) | #9940 | -| [@Chewji9875](https://github.com/Chewji9875) | #9257, #9420, #9821, #9994 | -| [@chirag127](https://github.com/chirag127) | #6674 | -| [@chloeassistant](https://github.com/chloeassistant) | #9675, #9746 | -| [@configurowebmax](https://github.com/configurowebmax) | #8877 | -| [@corefusiion](https://github.com/corefusiion) | #8285 | -| [@costaeder](https://github.com/costaeder) | #8626, #8629, #8630 | -| [@csoftware-arigpt](https://github.com/csoftware-arigpt) | #3440 | -| [@DaDecky](https://github.com/DaDecky) | direct commit / report | -| [@ddarkr](https://github.com/ddarkr) | #9035, #9036 | -| [@Dingding-leo](https://github.com/Dingding-leo) | #7987, #8640, #8678, #8704, #8774, #8790, #8808, #8817 | -| [@DinonowDev](https://github.com/DinonowDev) | #8804 | -| [@Dragost](https://github.com/Dragost) | #8339 | -| [@dsitmilis](https://github.com/dsitmilis) | direct commit / report | -| [@Egorich-print](https://github.com/Egorich-print) | #9001, #9020, #9058 | -| [@engmarcosjr](https://github.com/engmarcosjr) | #9993 | -| [@epsilonode](https://github.com/epsilonode) | #8871 | -| [@ervareza](https://github.com/ervareza) | direct commit / report | -| [@fajarhide](https://github.com/fajarhide) | #9191, #9198 | -| [@fenix007](https://github.com/fenix007) | #9618 | -| [@Gecky2102](https://github.com/Gecky2102) | #9280 | -| [@Gioxaa](https://github.com/Gioxaa) | #9162, #9171 | -| [@HaoNgo232](https://github.com/HaoNgo232) | direct commit / report | -| [@Hariprajwal](https://github.com/Hariprajwal) | #9922 | -| [@hartmark](https://github.com/hartmark) | #9635, #9704, #9711, #9712, #9727, #9734, #9735, #9738, #9741, #9744, #9745, #9822 | -| [@Hdiaktoros](https://github.com/Hdiaktoros) | #8930 | -| [@HectorBernstorff](https://github.com/HectorBernstorff) | direct commit / report | -| [@HellFiveOsborn](https://github.com/HellFiveOsborn) | #9248 | -| [@herjarsa](https://github.com/herjarsa) | #9714, #9816, #9937, #9946 | -| [@horacecar](https://github.com/horacecar) | #7679 | -| [@HouMinXi](https://github.com/HouMinXi) | #8886, #8904, #8905, #8976, #8984, #9079, #9106, #9207, #9242, #9328, #9340, #9342, #9351, #9365, #9380, #9381, #9392, #9449, #9482, #9483, #9509, #9510, #9572, #9631, #9634, #9695, #9929 | -| [@hppsc1215](https://github.com/hppsc1215) | #8970 | -| [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | -| [@infinit-X](https://github.com/infinit-X) | #9095 | -| [@isaaclb98](https://github.com/isaaclb98) | #9730 | -| [@jackjinke](https://github.com/jackjinke) | #9556, #9601, #10005 | -| [@jax-novita](https://github.com/jax-novita) | #8913 | -| [@jhordanjw123](https://github.com/jhordanjw123) | #8736 | -| [@jktan0504](https://github.com/jktan0504) | #9025 | -| [@joachimBrindeau](https://github.com/joachimBrindeau) | #9200 | -| [@JoshimOfficial](https://github.com/JoshimOfficial) | #9011 | -| [@jowimila](https://github.com/jowimila) | #9325 | -| [@JxnLexn](https://github.com/JxnLexn) | #8933, #8940, #8944, #8949 | -| [@Kaedo17](https://github.com/Kaedo17) | #8922 | -| [@khoazero123](https://github.com/khoazero123) | #9272 | -| [@KittisakT](https://github.com/KittisakT) | #9423 | -| [@KooshaPari](https://github.com/KooshaPari) | #7329 | -| [@larin-vas](https://github.com/larin-vas) | #9828 | -| [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | -| [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@Llliao1113](https://github.com/Llliao1113) | #8921 | -| [@lucasalx](https://github.com/lucasalx) | #9919 | -| [@lucasmellos](https://github.com/lucasmellos) | #8925 | -| [@lukiod](https://github.com/lukiod) | #8828 | -| [@luoyide](https://github.com/luoyide) | direct commit / report | -| [@mad-gooze](https://github.com/mad-gooze) | #9052 | -| [@maisdesign](https://github.com/maisdesign) | #8858 | -| [@marchlhw](https://github.com/marchlhw) | #9050 | -| [@matiasbaglieri](https://github.com/matiasbaglieri) | #9707 | -| [@maxmad64bis](https://github.com/maxmad64bis) | #9150, #9246, #9291, #9414 | -| [@McLuck](https://github.com/McLuck) | #8914 | -| [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | -| [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244 | -| [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | -| [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | -| [@Momen4444](https://github.com/Momen4444) | #9612 | -| [@MrShitFox](https://github.com/MrShitFox) | #9826 | -| [@MumuTW](https://github.com/MumuTW) | #8839 | -| [@mvanhorn](https://github.com/mvanhorn) | #9542 | -| [@Mynacol](https://github.com/Mynacol) | #9733 | -| [@nguyenha935](https://github.com/nguyenha935) | #9044, #9215 | -| [@nosolosoft](https://github.com/nosolosoft) | #8900 | -| [@oyi77](https://github.com/oyi77) | #8299, #8752, #9158, #9818 | -| [@PixmaNts](https://github.com/PixmaNts) | #9432 | -| [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | -| [@Poid-ZA](https://github.com/Poid-ZA) | #9467 | -| [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | -| [@qianze0628](https://github.com/qianze0628) | #9038 | -| [@raflyazf](https://github.com/raflyazf) | direct commit / report | -| [@Rahulsharma0810](https://github.com/Rahulsharma0810) | #8961 | -| [@rinseaid](https://github.com/rinseaid) | #8945, #9037, #9932, #9933, #9969, #9982 | -| [@rixzkiye](https://github.com/rixzkiye) | direct commit / report | -| [@RobertsXML](https://github.com/RobertsXML) | direct commit / report | -| [@royanrosyad85](https://github.com/royanrosyad85) | direct commit / report | -| [@rushsinging](https://github.com/rushsinging) | #8947 | -| [@ryan-brosas](https://github.com/ryan-brosas) | #9693 | -| [@ryanngit](https://github.com/ryanngit) | direct commit / report | -| [@sadSanta-07](https://github.com/sadSanta-07) | #9938 | -| [@SalyyS1](https://github.com/SalyyS1) | direct commit / report | -| [@Sam280903](https://github.com/Sam280903) | #9274, #9278, #9281 | -| [@seakleangnhak](https://github.com/seakleangnhak) | direct commit / report | -| [@seanford](https://github.com/seanford) | #8523 | -| [@SemonCat](https://github.com/SemonCat) | direct commit / report | -| [@shixi-li](https://github.com/shixi-li) | #9022, #9513, #10001 | -| [@soulhakr](https://github.com/soulhakr) | #8799 | -| [@stanleytejakusuma](https://github.com/stanleytejakusuma) | #9610 | -| [@Stazyu](https://github.com/Stazyu) | #9007, #9226, #9438 | -| [@SupremeNexas](https://github.com/SupremeNexas) | #9913 | -| [@swingtempo](https://github.com/swingtempo) | #9307 | -| [@szzhoujiarui](https://github.com/szzhoujiarui) | #9218 | -| [@tald26](https://github.com/tald26) | #9959 | -| [@taltas](https://github.com/taltas) | direct commit / report | -| [@TechNickAI](https://github.com/TechNickAI) | #9251 | -| [@TengSivtean](https://github.com/TengSivtean) | #10000, #10002 | -| [@TheFrenchGhosty](https://github.com/TheFrenchGhosty) | #9326 | -| [@tuxmonteiro](https://github.com/tuxmonteiro) | #9065 | -| [@vinogradovnet](https://github.com/vinogradovnet) | #9581 | -| [@VXNCXNX](https://github.com/VXNCXNX) | #9111, #9783 | -| [@wgordon17](https://github.com/wgordon17) | #8909, #9233, #9441, #9619 | -| [@Witroch4](https://github.com/Witroch4) | #8713 | -| [@witt3rd](https://github.com/witt3rd) | #9962, #9963 | -| [@xiaoyaner0201](https://github.com/xiaoyaner0201) | #8757, #8869, #8876, #8883, #8906, #8931, #9021, #9027, #9452 | -| [@xz-dev](https://github.com/xz-dev) | #8908, #9199, #9205, #9262, #9290, #9313, #9555, #9569, #9629, #9788, #9983 | -| [@yansigit](https://github.com/yansigit) | #9834, #9911, #9917, #9921 | -| [@yidecode](https://github.com/yidecode) | direct commit / report | -| [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@yutuknown](https://github.com/yutuknown) | #8999 | -| [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | -| [@Zartharas](https://github.com/Zartharas) | #9161, #9164, #9181, #9182, #9184, #9185, #9186, #9189, #9294, #9825, #9833, #9936, #9965, #9992 | -| [@Zenlyte](https://github.com/Zenlyte) | #9005 | -| [@zhiru](https://github.com/zhiru) | #9099, #9101 | -| [@ziuus](https://github.com/ziuus) | #8912 | -| [@zuckdorsey](https://github.com/zuckdorsey) | #9723 | -| [@diegosouzapw](https://github.com/diegosouzapw) | maintainer | +| Contributor | PRs / Issues | +| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [@AbdullahFageeh](https://github.com/AbdullahFageeh) | #9087 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222 | +| [@adrianojiu](https://github.com/adrianojiu) | #8438 | +| [@agisota](https://github.com/agisota) | #9837 | +| [@AgnesRiber](https://github.com/AgnesRiber) | #9718, #9976 | +| [@ahmet-cetinkaya](https://github.com/ahmet-cetinkaya) | #8878 | +| [@AIB1TAL0S](https://github.com/AIB1TAL0S) | #9284 | +| [@AlanSyue](https://github.com/AlanSyue) | direct commit / report | +| [@alex-jordan547](https://github.com/alex-jordan547) | #9235, #9245, #9813 | +| [@amartinawi](https://github.com/amartinawi) | #10090, #10091, #10092, #10097, #10101 | +| [@AndrianBalanescu](https://github.com/AndrianBalanescu) | #8888, #8889, #8890, #8891, #8892, #8893, #8894, #8895 | +| [@AnhLead](https://github.com/AnhLead) | #9722 | +| [@aniketshukla1](https://github.com/aniketshukla1) | #9148 | +| [@Anjielon](https://github.com/Anjielon) | #8776 | +| [@apoapostolov](https://github.com/apoapostolov) | #8916 | +| [@ARC345](https://github.com/ARC345) | #9628, #10050, #10051 | +| [@artickc](https://github.com/artickc) | #8571, #8578, #8791, #8843, #8870, #8927, #8974, #9097, #9549 | +| [@Arul-](https://github.com/Arul-) | #9761 | +| [@AStupidBear](https://github.com/AStupidBear) | #10180 | +| [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10178, #10175, #10254, #10255, #10256, #10257, #10258, #10339 | +| [@Benson-mk](https://github.com/Benson-mk) | #8369 | +| [@benzntech](https://github.com/benzntech) | #9810, #9812, #9939 | +| [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | +| [@bortolidiego](https://github.com/bortolidiego) | #10058 | +| [@branben](https://github.com/branben) | #9940 | +| [@Chewji9875](https://github.com/Chewji9875) | #9257, #9420, #9821, #9994, #10160 | +| [@chirag127](https://github.com/chirag127) | #6674 | +| [@chloeassistant](https://github.com/chloeassistant) | #9675, #9746 | +| [@configurowebmax](https://github.com/configurowebmax) | #8877 | +| [@corefusiion](https://github.com/corefusiion) | #8285 | +| [@costaeder](https://github.com/costaeder) | #8626, #8629, #8630 | +| [@csoftware-arigpt](https://github.com/csoftware-arigpt) | #3440 | +| [@DaDecky](https://github.com/DaDecky) | direct commit / report | +| [@DarkEsteves](https://github.com/DarkEsteves) | #10250 | +| [@ddarkr](https://github.com/ddarkr) | #9035, #9036, #10177 | +| [@diegosouzapw](https://github.com/diegosouzapw) | maintainer | +| [@Dingding-leo](https://github.com/Dingding-leo) | #7987, #8640, #8678, #8704, #8774, #8790, #8808, #8817 | +| [@DinonowDev](https://github.com/DinonowDev) | #8804 | +| [@Dragost](https://github.com/Dragost) | #8339 | +| [@dsitmilis](https://github.com/dsitmilis) | direct commit / report | +| [@Egorich-print](https://github.com/Egorich-print) | #9001, #9020, #9058 | +| [@engmarcosjr](https://github.com/engmarcosjr) | #9993 | +| [@epsilonode](https://github.com/epsilonode) | #8871 | +| [@ervareza](https://github.com/ervareza) | direct commit / report | +| [@excessivechaos](https://github.com/excessivechaos) | #10062, #10138 | +| [@fajarhide](https://github.com/fajarhide) | #9191, #9198 | +| [@fenix007](https://github.com/fenix007) | #9618 | +| [@Gecky2102](https://github.com/Gecky2102) | #9280 | +| [@ggdayup](https://github.com/ggdayup) | #10199 | +| [@Gioxaa](https://github.com/Gioxaa) | #9162, #9171 | +| [@HaoNgo232](https://github.com/HaoNgo232) | direct commit / report | +| [@Hariprajwal](https://github.com/Hariprajwal) | #9922 | +| [@hartmark](https://github.com/hartmark) | #9635, #9704, #9711, #9712, #9727, #9734, #9735, #9738, #9741, #9744, #9745, #9822, #10025, #10034, #10037, #10038, #10041, #10121, #10217 | +| [@Hdiaktoros](https://github.com/Hdiaktoros) | #8930 | +| [@HectorBernstorff](https://github.com/HectorBernstorff) | direct commit / report | +| [@HellFiveOsborn](https://github.com/HellFiveOsborn) | #9248 | +| [@herjarsa](https://github.com/herjarsa) | #9714, #9816, #9937, #9946, #10128 | +| [@horacecar](https://github.com/horacecar) | #7679 | +| [@HouMinXi](https://github.com/HouMinXi) | #8886, #8904, #8905, #8976, #8984, #9079, #9106, #9207, #9242, #9328, #9340, #9342, #9351, #9365, #9380, #9381, #9392, #9449, #9482, #9483, #9509, #9510, #9572, #9631, #9634, #9695, #9929 | +| [@hppsc1215](https://github.com/hppsc1215) | #8970 | +| [@hydraxman](https://github.com/hydraxman) | #10137 | +| [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | +| [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | +| [@infinit-X](https://github.com/infinit-X) | #9095 | +| [@isaaclb98](https://github.com/isaaclb98) | #9730 | +| [@jackjinke](https://github.com/jackjinke) | #9556, #9601, #10005, #10045 | +| [@jax-novita](https://github.com/jax-novita) | #8913 | +| [@jeff-alves](https://github.com/jeff-alves) | #10221 | +| [@jeyhunfaslanov](https://github.com/jeyhunfaslanov) | #10259 | +| [@jhordanjw123](https://github.com/jhordanjw123) | #8736 | +| [@jktan0504](https://github.com/jktan0504) | #9025 | +| [@joachimBrindeau](https://github.com/joachimBrindeau) | #9200 | +| [@JoshimOfficial](https://github.com/JoshimOfficial) | #9011 | +| [@jowimila](https://github.com/jowimila) | #9325 | +| [@JxnLexn](https://github.com/JxnLexn) | #8933, #8940, #8944, #8949 | +| [@Kaedo17](https://github.com/Kaedo17) | #8922 | +| [@khoazero123](https://github.com/khoazero123) | #9272 | +| [@KittisakT](https://github.com/KittisakT) | #9423 | +| [@KooshaPari](https://github.com/KooshaPari) | #7329 | +| [@larin-vas](https://github.com/larin-vas) | #9828 | +| [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | +| [@LeonG606](https://github.com/LeonG606) | #9457 | +| [@Llliao1113](https://github.com/Llliao1113) | #8921 | +| [@lucasalx](https://github.com/lucasalx) | #9919 | +| [@lucasmellos](https://github.com/lucasmellos) | #8925 | +| [@lukiod](https://github.com/lukiod) | #8828 | +| [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@mad-gooze](https://github.com/mad-gooze) | #9052 | +| [@maisdesign](https://github.com/maisdesign) | #8858 | +| [@marchlhw](https://github.com/marchlhw) | #9050 | +| [@matiasbaglieri](https://github.com/matiasbaglieri) | #9707 | +| [@maxmad64bis](https://github.com/maxmad64bis) | #9150, #9246, #9291, #9414 | +| [@McLuck](https://github.com/McLuck) | #8914 | +| [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | +| [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244 | +| [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | +| [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | +| [@Momen4444](https://github.com/Momen4444) | #9612 | +| [@MrShitFox](https://github.com/MrShitFox) | #9826 | +| [@mtb-ninja](https://github.com/mtb-ninja) | #10114 | +| [@MumuTW](https://github.com/MumuTW) | #8839 | +| [@mvanhorn](https://github.com/mvanhorn) | #9542 | +| [@Mynacol](https://github.com/Mynacol) | #9733 | +| [@nguyenha935](https://github.com/nguyenha935) | #9044, #9215 | +| [@nordz0r](https://github.com/nordz0r) | #10170 | +| [@nosolosoft](https://github.com/nosolosoft) | #8900 | +| [@oyi77](https://github.com/oyi77) | #8299, #8752, #9158, #9818 | +| [@pacocartones](https://github.com/pacocartones) | #10216 | +| [@PixmaNts](https://github.com/PixmaNts) | #9432 | +| [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | +| [@Poid-ZA](https://github.com/Poid-ZA) | #9467 | +| [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | +| [@qianze0628](https://github.com/qianze0628) | #9038 | +| [@raflyazf](https://github.com/raflyazf) | direct commit / report | +| [@Rahulsharma0810](https://github.com/Rahulsharma0810) | #8961 | +| [@rinseaid](https://github.com/rinseaid) | #8945, #9037, #9932, #9933, #9969, #9982 | +| [@rixzkiye](https://github.com/rixzkiye) | direct commit / report | +| [@RobertsXML](https://github.com/RobertsXML) | direct commit / report | +| [@royanrosyad85](https://github.com/royanrosyad85) | direct commit / report | +| [@rushsinging](https://github.com/rushsinging) | #8947 | +| [@ryan-brosas](https://github.com/ryan-brosas) | #9693 | +| [@ryanngit](https://github.com/ryanngit) | direct commit / report | +| [@sadSanta-07](https://github.com/sadSanta-07) | #9938 | +| [@SalyyS1](https://github.com/SalyyS1) | direct commit / report | +| [@Sam280903](https://github.com/Sam280903) | #9274, #9278, #9281, #9283, #9448 | +| [@seakleangnhak](https://github.com/seakleangnhak) | direct commit / report | +| [@seanford](https://github.com/seanford) | #8523 | +| [@SemonCat](https://github.com/SemonCat) | direct commit / report | +| [@shixi-li](https://github.com/shixi-li) | #9022, #9513, #10001 | +| [@soulhakr](https://github.com/soulhakr) | #8799 | +| [@stanleytejakusuma](https://github.com/stanleytejakusuma) | #9610 | +| [@Stazyu](https://github.com/Stazyu) | #9007, #9226, #9438 | +| [@SupremeNexas](https://github.com/SupremeNexas) | #9913 | +| [@swingtempo](https://github.com/swingtempo) | #9307 | +| [@szzhoujiarui](https://github.com/szzhoujiarui) | #9218 | +| [@tald26](https://github.com/tald26) | #9959 | +| [@taltas](https://github.com/taltas) | direct commit / report | +| [@TechNickAI](https://github.com/TechNickAI) | #9251 | +| [@TengSivtean](https://github.com/TengSivtean) | #10000, #10002, #10086 | +| [@TheFrenchGhosty](https://github.com/TheFrenchGhosty) | #9326 | +| [@tiangao88](https://github.com/tiangao88) | #10046 | +| [@tuxmonteiro](https://github.com/tuxmonteiro) | #9065 | +| [@vinogradovnet](https://github.com/vinogradovnet) | #9581 | +| [@VXNCXNX](https://github.com/VXNCXNX) | #9111, #9783 | +| [@wgordon17](https://github.com/wgordon17) | #8909, #9233, #9441, #9619 | +| [@Witroch4](https://github.com/Witroch4) | #8713 | +| [@witt3rd](https://github.com/witt3rd) | #9962, #9963 | +| [@XDayonline](https://github.com/XDayonline) | #10053 | +| [@xiaoyaner0201](https://github.com/xiaoyaner0201) | #8757, #8869, #8876, #8883, #8906, #8931, #9021, #9027, #9452, #9042, #9316 | +| [@xz-dev](https://github.com/xz-dev) | #8908, #9199, #9205, #9262, #9290, #9313, #9555, #9569, #9629, #9788, #9983, #10079, #10243 | +| [@yansigit](https://github.com/yansigit) | #9834, #9911, #9917, #9921, #10065 | +| [@yidecode](https://github.com/yidecode) | direct commit / report | +| [@yulinlina](https://github.com/yulinlina) | #10013 | +| [@yutuknown](https://github.com/yutuknown) | #8999 | +| [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | +| [@Zartharas](https://github.com/Zartharas) | #9161, #9164, #9181, #9182, #9184, #9185, #9186, #9189, #9294, #9825, #9833, #9936, #9965, #9992, #10218 | +| [@Zenlyte](https://github.com/Zenlyte) | #9005 | +| [@zhiru](https://github.com/zhiru) | #9099, #9101 | +| [@ziuus](https://github.com/ziuus) | #8912 | +| [@zuckdorsey](https://github.com/zuckdorsey) | #9723 | --- @@ -1148,6 +1243,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **feat(quality):** temporary relax of complexity/file-size ratchets for v3.8.50-3.8.54 PREPARE phase ([#8767](https://github.com/diegosouzapw/OmniRoute/pull/8767)) - **feat(db):** let the migration runner scan extra namespaced directories ([#8770](https://github.com/diegosouzapw/OmniRoute/pull/8770)) - **feat(api):** prompt-cache health summary endpoint and analytics tab ([#8827](https://github.com/diegosouzapw/OmniRoute/pull/8827)) + ### ⚡ Performance - **perf(db):** project columns + composite index in getProviderConnections ([#6918](https://github.com/diegosouzapw/OmniRoute/pull/6918)) — thanks @oyi77 @@ -1163,6 +1259,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **perf:** lazy provider init, P2C quota cache, structuredClone elimination, getSettings→getCachedSettings (batch 2) ([#7893](https://github.com/diegosouzapw/OmniRoute/pull/7893)) — thanks @oyi77 - **perf(api):** singleflight version lookups ([#8301](https://github.com/diegosouzapw/OmniRoute/pull/8301)) — thanks @RaviTharuma - **perf(api):** skip the full catalog build for quota-exclusive keys ([#8771](https://github.com/diegosouzapw/OmniRoute/pull/8771)) + ### 🐛 Bug Fixes - **fix:** add re-entrancy guard to token health check sweep ([#6917](https://github.com/diegosouzapw/OmniRoute/pull/6917)) — thanks @oyi77 @@ -1562,7 +1659,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **fix(resilience):** a combo step "pinned" to one fingerprint account (mimocode/mcode/opencode multi-account providers) never actually resolved to that account, so it couldn't fail over when the pinned account was depleted ([#6696](https://github.com/diegosouzapw/OmniRoute/issues/6696), relates #6612) — the combo builder UI encodes an account pin as a composite connectionId (`${rowId}|fp|${fingerprint}`, `src/lib/combos/builderOptions.ts`), but `expandTargetsByFingerprints()` (`open-sse/services/combo/fingerprintExpansion.ts`) looked that composite string up directly in `connectionById` (keyed by real DB row ids), got `undefined`, and passed the target through unchanged, still carrying the bogus composite id — so downstream credential resolution could never match it either. `expandTargetsByFingerprints()` now splits the `|fp|` composite id back into the real connection row id + the pinned fingerprint (new `splitFingerprintPin()` helper) before any lookup, resolving the target to the real connectionId (with the pinned fingerprint carried on the new `pinnedFingerprint` field) instead of the inert composite string. Regression guard: `tests/unit/combo-fingerprint-pin-6696.test.ts`. ([#6732](https://github.com/diegosouzapw/OmniRoute/pull/6732)) - **fix(api):** Responses passthrough emitted event-only SSE frames (no `data:` line) for every dropped commentary event, breaking the OpenAI Python SDK's `sse.json()` parser ([#6561](https://github.com/diegosouzapw/OmniRoute/issues/6561)), follow-up to #6199/#6232 — the commentary-drop `continue;` branches in `open-sse/utils/stream.ts` skipped the `data:` line for a dropped commentary event but never cleared the already-buffered `event:` line for that same frame, so the next blank line flushed the stale `event:` line alone. Both drop sites now call `clearPendingPassthroughEvent()` before `continue`, discarding the buffered prefix along with the dropped payload; the commentary-drop decision itself was extracted into a new `open-sse/utils/responsesCommentaryDrop.ts` so the fix does not grow the frozen `stream.ts`. Regression guard: `tests/unit/responses-commentary-event-frame-6561.test.ts` (realistic `event:\ndata:\n\n` frames — the existing #6199 test only used bare `data:` lines and never exercised this path). ([#6735](https://github.com/diegosouzapw/OmniRoute/pull/6735)) - **fix(compression):** `/api/compression/preview`'s top-level `originalTokens`/`compressedTokens` diverged from `engineBreakdown[0]`'s counts for the same single-engine run (tiktoken outer counts vs the `JSON.stringify(...).length/4` estimate per engine), worst on small inputs. A new `reconcileSingleEngineTokens()` overwrites the single-engine breakdown entry with the outer, more accurate figures; multi-step pipeline breakdowns are left untouched ([#6488](https://github.com/diegosouzapw/OmniRoute/issues/6488)). Regression guard: `tests/unit/compression/preview-outer-engine-token-reconcile-6488.test.ts`. ([#6741](https://github.com/diegosouzapw/OmniRoute/pull/6741)) -- **fix(resilience):** account selection could pick an account already out of quota upstream on every credentialed route except `chat`/`codex` ([#6686](https://github.com/diegosouzapw/OmniRoute/issues/6686)) — `getProviderCredentials()` (`src/sse/services/auth.ts`) only skips a connection when a *local cache* already flags it exhausted (`isQuotaExhaustedForRequest`/`src/domain/quotaCache.ts`); it never itself calls the registered upstream `QuotaFetcher`. Only `getProviderCredentialsWithQuotaPreflight()` performs that live upstream check, and it was wired into exactly 2 call sites (`src/sse/handlers/chat.ts`, `src/app/api/internal/codex-responses-ws/route.ts`) — every other credentialed route (`rerank`, `images/generations`, `images/edits`, `audio/transcriptions|speech|translations`, `videos/generations`, `music/generations`, `ocr`, `providers/[provider]/embeddings`, `providers/[provider]/images/generations`, `web/fetch`, `moderations`, `search`) called the plain, cache-only selector, so an account whose cache entry was never populated (e.g. its first request landed on one of these routes) could be selected even at 0% quota remaining. Those 14 call sites now go through `getProviderCredentialsWithQuotaPreflight()` instead, matching chat/codex coverage. Regression guard: `tests/unit/issue-6686-quota-preflight-coverage.test.ts` (static check that none of the routes call the plain selector anymore + a behavioral check that the preflight-aware selector blocks a 100%-used account). ([#6742](https://github.com/diegosouzapw/OmniRoute/pull/6742)) +- **fix(resilience):** account selection could pick an account already out of quota upstream on every credentialed route except `chat`/`codex` ([#6686](https://github.com/diegosouzapw/OmniRoute/issues/6686)) — `getProviderCredentials()` (`src/sse/services/auth.ts`) only skips a connection when a _local cache_ already flags it exhausted (`isQuotaExhaustedForRequest`/`src/domain/quotaCache.ts`); it never itself calls the registered upstream `QuotaFetcher`. Only `getProviderCredentialsWithQuotaPreflight()` performs that live upstream check, and it was wired into exactly 2 call sites (`src/sse/handlers/chat.ts`, `src/app/api/internal/codex-responses-ws/route.ts`) — every other credentialed route (`rerank`, `images/generations`, `images/edits`, `audio/transcriptions|speech|translations`, `videos/generations`, `music/generations`, `ocr`, `providers/[provider]/embeddings`, `providers/[provider]/images/generations`, `web/fetch`, `moderations`, `search`) called the plain, cache-only selector, so an account whose cache entry was never populated (e.g. its first request landed on one of these routes) could be selected even at 0% quota remaining. Those 14 call sites now go through `getProviderCredentialsWithQuotaPreflight()` instead, matching chat/codex coverage. Regression guard: `tests/unit/issue-6686-quota-preflight-coverage.test.ts` (static check that none of the routes call the plain selector anymore + a behavioral check that the preflight-aware selector blocks a 100%-used account). ([#6742](https://github.com/diegosouzapw/OmniRoute/pull/6742)) - **fix(api):** `reasoning_content` (extended-thinking text) was silently dropped from `/v1/chat/completions` SSE on the `claude-web` and `v0-vercel-web` executors ([#6662](https://github.com/diegosouzapw/OmniRoute/issues/6662)) — every chunk builder in both adapters hardcoded `delta: { content: ... }` with no reasoning path, unlike the established pattern already used by `default.ts`/`deepseek-web.ts`/`bedrock.ts` and the real-Anthropic-API `claude-to-openai.ts` translator (`thinking_delta` → `reasoning_content`). `v0-vercel-web.ts` now forwards an upstream `delta.reasoning_content` field (streaming and non-streaming) the same way `deepseek-web.ts` does. `claude-web.ts`'s `buildClaudeStreamingResponse` now maps a `content_block_start`(`type: "thinking"`)/`content_block_delta`(`delta.thinking`) pair onto `delta.reasoning_content`, and `claude-web/payload.ts`'s `transformToClaude()` no longer hardcodes `thinking_mode: "off"` — a new `wantsExtendedThinking()` derives it from the request's `reasoning_effort`/`reasoning.effort`/`thinking.type` signal, so extended thinking can actually be requested. Regression guard: `tests/unit/issue-6662-repro.test.ts` (RED→GREEN for both adapters). ([#6743](https://github.com/diegosouzapw/OmniRoute/pull/6743)) - **fix(api):** the compression config PUT schema now accepts `enableRenderers` for the RTK engine instead of rejecting the documented option (#6703, #6757 — thanks @alltomatos, with an independent duplicate fix from @chirag127 via #6756). - **fix(api):** raised the provider `apiKey` length cap for cookie-based web providers, whose session-cookie credentials legitimately exceed the previous limit (#6715, #6759 — thanks @alltomatos). @@ -1682,7 +1779,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - fix(sse): stop stream readiness from treating a choices-less mid-stream error frame as a successful stream, so combo can fail over instead of returning zero `choices` (#7503) - Fixed the Codex connection **Test** button always reporting success for ChatGPT-account tokens: the probe used `gpt-5.3-codex`, a codex-only model ChatGPT accounts reject with a 400 — the same status the probe treats as "auth OK", so a bad token was indistinguishable from a good one. It now probes with `gpt-5.5`, a model ChatGPT-account sessions actually support (#7521). - The Codex account import (`POST /api/oauth/codex/import`) now validates each record's `refresh_token` against OpenAI's OAuth endpoint before persisting the connection: an already-invalidated session (`refresh_token_invalidated` / a dead `auth.json`) is rejected with a clear "run `codex login` again and re-import" message instead of importing as `active` and failing confusingly on first use. Valid tokens import as before, with any rotated tokens applied (#7522). -- The PKCE OAuth start (`/api/oauth/[provider]/start-callback-server`, used by Codex/Windsurf/Devin) now detects when OmniRoute is being driven from a remote host and returns a reverse-tunnel hint (`remoteHost`, `tunnelCommand`, `message`) instead of hanging silently: the callback server binds the *server's* localhost:PORT, so a browser on a different machine would redirect to its own localhost and never complete. Loopback access is unchanged (#7523). +- The PKCE OAuth start (`/api/oauth/[provider]/start-callback-server`, used by Codex/Windsurf/Devin) now detects when OmniRoute is being driven from a remote host and returns a reverse-tunnel hint (`remoteHost`, `tunnelCommand`, `message`) instead of hanging silently: the callback server binds the _server's_ localhost:PORT, so a browser on a different machine would redirect to its own localhost and never complete. Loopback access is unchanged (#7523). - fix(providers): search providers now expose a static model catalog derived from `searchTypes`, fixing "does not support models listing" 400 for serper-search, brave-search, perplexity-search, exa-search, tavily-search, google-pse-search, youcom-search, searxng-search, zai-search (#7529) - fix(sse): map `tool_search` to a Chat function tool instead of dropping it during Responses->Chat translation (#7532) - fix(sse): gate `verbosity`/`prompt_cache_key` on OpenAI destination during Responses->Chat translation, stopping the leak to non-OpenAI upstreams like NVIDIA (#7533) @@ -1992,6 +2089,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **fix(dashboard):** the /home quick-start cards no longer prefetch — #8292 opted the sidebar out of automatic route prefetch but left the landing page's own five links untouched, so first paint still fired 12 speculative RSC requests. The e2e guard shipped in that same PR could not catch it: it hung in the auth helper and never reached its assertion until this release's CI. - **fix(dashboard):** Request Logs detail no longer crashes on a structured error object — #7920 introduced `formatErrorForDisplay` for exactly this, but the combo-503 / cooldown checks added by #8213 read the raw field and called `.toLowerCase()` on it. Both paths now share the helper. - **fix(dashboard):** the logs detail modal stops reopening on first close again — #6830 fixed it by reading the deep-link id once, and the #8354 page rewrite regressed it by reading the live `searchParams` on every render, flipping the prop mid-session. + ### 📚 Docs - **docs(quality):** codify retry policy per runner + release-level drift rule (WS5.4/WS5.5) ([#7107](https://github.com/diegosouzapw/OmniRoute/pull/7107)) @@ -2034,6 +2132,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **docs(codex):** document session affinity and stream idle for long tasks ([#8709](https://github.com/diegosouzapw/OmniRoute/pull/8709)) — thanks @DinonowDev - **docs:** replace outdated Polish docs with translation from latest English ([#8823](https://github.com/diegosouzapw/OmniRoute/pull/8823)) — thanks @leszek3737 - **docs:** restore the Polish API_REFERENCE removed by #8823 ([#8831](https://github.com/diegosouzapw/OmniRoute/pull/8831)) + ### 🧪 Tests & Quality - **test(build):** derive pack-artifact closures for all npm-shipped entrypoints (#7065 class) ([#7081](https://github.com/diegosouzapw/OmniRoute/pull/7081)) @@ -2051,6 +2150,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **test(e2e):** contract test for the full provider journey ([#8444](https://github.com/diegosouzapw/OmniRoute/pull/8444)) — thanks @HoneyTyagii - **test(sse):** repair two base-red gates on release/v3.8.49 ([#8490](https://github.com/diegosouzapw/OmniRoute/pull/8490)) — thanks @backryun - **test(context):** isolate context-manager suite from local DATA_DIR ([#8596](https://github.com/diegosouzapw/OmniRoute/pull/8596)) — thanks @DinonowDev + ### 🔧 Chores / CI - **chore(release):** gate the sync-back push on release-green --quick (WS0.3) ([#7083](https://github.com/diegosouzapw/OmniRoute/pull/7083)) @@ -2141,6 +2241,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **refactor(sse):** use the shared ApiKeyMetadata in reasoningRouting instead of a local duck-type ([#8643](https://github.com/diegosouzapw/OmniRoute/pull/8643)) — thanks @backryun - **refactor(sse):** narrow three media-generation result unions ([#8645](https://github.com/diegosouzapw/OmniRoute/pull/8645)) — thanks @backryun - **refactor(sse):** declare the semantic-cache read path's parameters ([#8646](https://github.com/diegosouzapw/OmniRoute/pull/8646)) — thanks @backryun + ### 🔀 Other - [needs-vps] fix(electron): materialize Turbopack hashed-module symlinks during packaging (#6724, #6594) ([#6794](https://github.com/diegosouzapw/OmniRoute/pull/6794)) — thanks @huohua-dev @@ -2170,6 +2271,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **refactor(antigravity):** align official clients and callable catalog ([#8013](https://github.com/diegosouzapw/OmniRoute/pull/8013)) — thanks @backryun - **refactor(compression):** extract resolveHeadroomDetail to keep dispatchCompression under the complexity gate ([#8058](https://github.com/diegosouzapw/OmniRoute/pull/8058)) - **deps:** bump next from 16.2.10 to 16.2.11 ([#8235](https://github.com/diegosouzapw/OmniRoute/pull/8235)) — thanks @dependabot[bot] + ### 🩹 Direct release-branch fixes (no PR — authorized base-red sweep, 2026-07-18) - **fix(base-red):** full-suite realignment after the 102-PR merge campaign: two real production fixes (legacy `refresh_token` column healed before its index is created; `shouldSkipCloudSyncInitialization` no longer swaps its `(env, argv)` arguments) plus 13 test files, goldens, provider counts, and env docs realigned to the live-validated behavior of the merged PRs. @@ -2177,6 +2279,7 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **test(ui):** the `vitest:ui` suite was red across the whole cycle and nobody saw it — the job kept being cancelled by successive pushes, so a blocking gate never ran to completion. Root cause: #7935 instrumented ~180 shared/dashboard components with `next-intl` without updating the tests that mount them. Fixed at the shared setup (`tests/_setup/vitestUiPolyfills.ts`) with a translator backed by the real `en.json`, memoized per namespace so components whose `useCallback`/`useEffect` depend on `t` no longer loop; 15 test files realigned to the real strings. 194→198 files green. ### 📝 Maintenance + - **Merge-train script** (`scripts/release/merge-train.sh`): batch-validates N queued PRs as ONE merged result on the runner box — merges every queued PR into a throwaway worktree cut from the release tip, runs the fast-gates parity suite once, and prints the `--admin` evidence block per PR (merge-gates §7). Replaces O(N²) per-PR CI re-runs in merge-storms. Regression guard: `tests/unit/merge-train-plan.test.ts`. ([#6784](https://github.com/diegosouzapw/OmniRoute/pull/6784)) - **release:** `list-uncovered-commits.mjs` now unions the CHANGELOG scan window with `changelog.d/` fragment refs (filename `-` prefix + every `#N` in the body), so a commit covered only by a fragment is no longer reported as an uncovered reconciliation gap ([#6857](https://github.com/diegosouzapw/OmniRoute/issues/6857) via [#6878](https://github.com/diegosouzapw/OmniRoute/pull/6878)) - **chore(ci):** stop dependabot from proposing `typescript` majors — `typescript-eslint` pins a hard peer upper bound (`>=4.8.4 <6.1.0`), so a TS 7 bump violates the peer and takes the whole toolchain red at once. #7068 grouped it with 6 harmless dev bumps and blocked all of them. TS majors now migrate intentionally, in their own PR. @@ -2274,195 +2377,190 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62 - **CI**: promote `test:vitest:ui` to a blocking gate — the suite is 870/870 green again after the WS6.1 triage (#7127), so `continue-on-error` is removed from the vitest job - chore(tests): fix all 70 failing `test:vitest:ui` tests across 30 files (was advisory/parked) — root causes were 15 node:test-authored `.tsx` files never collected by vitest, a missing `window.matchMedia` jsdom polyfill, stale assertions against a redesigned BuildTab wizard / CompressionHub Phase-2 UI, and one obsolete test for a retired Plans screen; suite is now 158/158 files, 870/870 tests green (promotion to blocking is a follow-up) - - - - - ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.49: -| Contributor | PRs / Issues | -| --- | --- | -| [@0x2f0](https://github.com/0x2f0) | #8679 | -| [@0xheycat](https://github.com/0xheycat) | #8751 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #8123 | -| [@adrianaryaputra](https://github.com/adrianaryaputra) | #7928 | -| [@advane204f](https://github.com/advane204f) | direct commit / report | -| [@Ajeesh25353646](https://github.com/Ajeesh25353646) | #7528 | -| [@allanvb](https://github.com/allanvb) | #8471, #8759, #8814, #8862 | -| [@alltomatos](https://github.com/alltomatos) | #6703, #6715, #6756, #6757, #6759, #6813, #6819, #6821, #7041, #7042, #7164, #7277, #7490, #7492, #7644 | -| [@alvaretto](https://github.com/alvaretto) | #8077, #8161, #8170 | -| [@amitgolan60-coder](https://github.com/amitgolan60-coder) | #8727 | -| [@andrea-kingautomation](https://github.com/andrea-kingautomation) | #7678 | -| [@andrewmunsell](https://github.com/andrewmunsell) | #6774, #6779, #6795 | -| [@AndrianBalanescu](https://github.com/AndrianBalanescu) | #6828, #6829, #7794, #7804, #7810, #7813, #7816, #7891, #8050 | -| [@anhdiepmmk](https://github.com/anhdiepmmk) | direct commit / report | -| [@anndev-69](https://github.com/anndev-69) | direct commit / report | -| [@apoapostolov](https://github.com/apoapostolov) | #8127 | -| [@arpit-jaiswal-dev](https://github.com/arpit-jaiswal-dev) | #7881 | -| [@artickc](https://github.com/artickc) | #6763, #6955, #7204, #7696, #7768, #7896, #7900, #7911, #7930, #7994, #8006, #8159, #8470, #8496, #8511, #8863 | -| [@Arul-](https://github.com/Arul-) | #7878 | -| [@asynx6](https://github.com/asynx6) | direct commit / report | -| [@attid](https://github.com/attid) | #6984 | -| [@backryun](https://github.com/backryun) | #6280, #6675, #6862, #7296, #7314, #7358, #7531, #7687, #7772, #7812, #7866, #7874, #7882, #7914, #8013, #8225, #8226, #8227, #8230, #8266, #8275, #8298, #8464, #8473, #8483, #8485, #8489, #8490, #8498, #8499, #8520, #8525, #8528, #8531, #8533, #8557, #8638, #8639, #8641, #8643, #8644, #8645, #8646, #8647, #8661, #8663, #8665, #8732, #8810, #8811, #8812, #8815, #8816, #8819, #8820, #8824 | -| [@beingshafin](https://github.com/beingshafin) | direct commit / report | -| [@brick30llc-ctrl](https://github.com/brick30llc-ctrl) | #6944 | -| [@brunnolouzada](https://github.com/brunnolouzada) | #8581 | -| [@c4usal](https://github.com/c4usal) | #7627, #8129 | -| [@CahyokPutraDev99](https://github.com/CahyokPutraDev99) | direct commit / report | -| [@Capslockb](https://github.com/Capslockb) | #7892 | -| [@CarmeloCampos](https://github.com/CarmeloCampos) | direct commit / report | -| [@Chewji9875](https://github.com/Chewji9875) | #7545 | -| [@chirag127](https://github.com/chirag127) | #6022, #6593, #6643, #6644, #6646, #6650, #6769, #6771, #6804, #7079, #7520, #8143 | -| [@chitholian](https://github.com/chitholian) | direct commit / report | -| [@chy1211](https://github.com/chy1211) | direct commit / report | -| [@CitrusIce](https://github.com/CitrusIce) | #6937, #6938 | -| [@costaeder](https://github.com/costaeder) | #8628 | -| [@Dan-ex-hub](https://github.com/Dan-ex-hub) | #7743 | -| [@danscMax](https://github.com/danscMax) | #7359, #7511, #7517, #7648, #7656, #7672, #7689 | -| [@dependabot](https://github.com/dependabot) | #7897, #7898, #8235 | -| [@Dingding-leo](https://github.com/Dingding-leo) | #7988, #7989, #8162, #8165, #8167, #8283, #8286, #8287, #8633, #8636, #8642, #8651, #8652, #8667, #8691, #8715, #8730, #8731, #8762, #8763, #8764, #8795 | -| [@DinonowDev](https://github.com/DinonowDev) | #8552, #8559, #8583, #8596, #8615, #8709, #8710, #8716, #8798, #8800, #8802 | -| [@dionisius95](https://github.com/dionisius95) | direct commit / report | -| [@DKotsyuba](https://github.com/DKotsyuba) | #7500 | -| [@dongwook-chan](https://github.com/dongwook-chan) | #7574, #7582, #7704 | -| [@Dragost](https://github.com/Dragost) | #8289 | -| [@Duongkhanhtool](https://github.com/Duongkhanhtool) | direct commit / report | -| [@dvirarad](https://github.com/dvirarad) | #8410 | -| [@ekinnee](https://github.com/ekinnee) | #7601, #7613, #7614, #7662, #7779, #7927, #7932, #7980, #8735 | -| [@enjoyer-hub](https://github.com/enjoyer-hub) | #6647, #7863 | -| [@epsilonode](https://github.com/epsilonode) | #8724 | -| [@evinjohnn](https://github.com/evinjohnn) | direct commit / report | -| [@fajarbossit](https://github.com/fajarbossit) | direct commit / report | -| [@felipeleite](https://github.com/felipeleite) | direct commit / report | -| [@fenix007](https://github.com/fenix007) | #7171, #7399, #8306, #8561 | -| [@FenjuFu](https://github.com/FenjuFu) | #7942 | -| [@floze-the-genius](https://github.com/floze-the-genius) | #7707 | -| [@fontvu](https://github.com/fontvu) | direct commit / report | -| [@fuko2935](https://github.com/fuko2935) | #8726 | -| [@fzrilsh](https://github.com/fzrilsh) | direct commit / report | -| [@gitcommit90](https://github.com/gitcommit90) | #6986 | -| [@glazec](https://github.com/glazec) | #8632 | -| [@growab](https://github.com/growab) | #7062, #7300 | -| [@guanbear](https://github.com/guanbear) | #7028 | -| [@guhcostan](https://github.com/guhcostan) | #8433 | -| [@hartmark](https://github.com/hartmark) | #8208, #8209, #8210, #8211, #8212, #8213, #8337, #8341, #8354, #8462 | -| [@HassiyYT](https://github.com/HassiyYT) | #7864 | -| [@heishen6](https://github.com/heishen6) | direct commit / report | -| [@herjarsa](https://github.com/herjarsa) | #7612, #7625, #7633, #7869, #7871, #8476 | -| [@HoneyTyagii](https://github.com/HoneyTyagii) | #8444 | -| [@HouMinXi](https://github.com/HouMinXi) | #7035, #7129, #7290, #7398, #7408, #7973, #8290, #8312, #8842, #8845, #8860, #8865 | -| [@hppsc1215](https://github.com/hppsc1215) | #7546, #8835 | -| [@huohua-dev](https://github.com/huohua-dev) | #6794 | -| [@hydraxman](https://github.com/hydraxman) | #7909 | -| [@iamraydoan](https://github.com/iamraydoan) | #6798 | -| [@ianriizky](https://github.com/ianriizky) | #6072, #6538 | -| [@ikelvingo](https://github.com/ikelvingo) | #8355 | -| [@insoln](https://github.com/insoln) | #7906, #7908, #8041, #8054, #8062 | -| [@irvandikky](https://github.com/irvandikky) | #7695 | -| [@isiahw1](https://github.com/isiahw1) | #7555 | -| [@itiwant](https://github.com/itiwant) | direct commit / report | -| [@janeza2](https://github.com/janeza2) | #6308 | -| [@Jordannst](https://github.com/Jordannst) | direct commit / report | -| [@JoshimOfficial](https://github.com/JoshimOfficial) | #8526 | -| [@justdoGIT](https://github.com/justdoGIT) | #8695 | -| [@JxnLexn](https://github.com/JxnLexn) | #6776, #6993, #7154, #7177, #7269, #7273, #7280, #7281, #7282, #7323, #7360, #7377, #7378, #7379, #7380, #7381, #7419, #7607, #7894, #7905, #7912, #8008, #8009, #8010 | -| [@kamenkadmitry](https://github.com/kamenkadmitry) | #7350, #7425 | -| [@kaon0388v1](https://github.com/kaon0388v1) | #7049 | -| [@KaynXu](https://github.com/KaynXu) | #8284 | -| [@KooshaPari](https://github.com/KooshaPari) | #6611, #6632, #6856, #7008, #7087, #7093, #7128, #7130, #7136, #7315, #7318, #7334, #7336 | -| [@KunN-21](https://github.com/KunN-21) | direct commit / report | -| [@leninejunior](https://github.com/leninejunior) | #8049 | -| [@leszek3737](https://github.com/leszek3737) | #7782, #7807, #8343, #8543, #8823 | -| [@like3213934360-lab](https://github.com/like3213934360-lab) | direct commit / report | -| [@linhdmn](https://github.com/linhdmn) | #8439 | -| [@Long-Feeds](https://github.com/Long-Feeds) | #8011 | -| [@loulanyue](https://github.com/loulanyue) | #7540 | -| [@lucasjustinudin](https://github.com/lucasjustinudin) | direct commit / report | -| [@lunkerchen](https://github.com/lunkerchen) | #8024 | -| [@makcimbx](https://github.com/makcimbx) | #7692, #8171, #8432 | -| [@Mananz90](https://github.com/Mananz90) | #8723 | -| [@marceli1404](https://github.com/marceli1404) | #8570 | -| [@maxmad64bis](https://github.com/maxmad64bis) | #8660 | -| [@megamen32](https://github.com/megamen32) | #7313 | -| [@MichaelYcJo](https://github.com/MichaelYcJo) | #8224 | -| [@mikeiagents](https://github.com/mikeiagents) | #8598 | -| [@MikeTuev](https://github.com/MikeTuev) | #6586 | -| [@mikolaj92](https://github.com/mikolaj92) | #6973 | -| [@MisileLab](https://github.com/MisileLab) | #8566 | -| [@MonteNegroX](https://github.com/MonteNegroX) | #8217 | -| [@Moseyuh333](https://github.com/Moseyuh333) | #7781, #8264 | -| [@MrFadiAi](https://github.com/MrFadiAi) | #7073 | -| [@mrprohack](https://github.com/mrprohack) | direct commit / report | -| [@MumuTW](https://github.com/MumuTW) | #8423, #8425, #8426, #8427, #8428, #8524, #8534, #8544, #8545, #8546, #8547, #8548, #8554, #8582, #8585, #8589, #8592, #8604, #8605, #8612, #8619, #8657, #8690, #8741, #8749 | -| [@mustafa-phd](https://github.com/mustafa-phd) | #7686 | -| [@NBN-N3](https://github.com/NBN-N3) | #8794 | -| [@nguyenha935](https://github.com/nguyenha935) | #7493, #7547, #7552, #7553, #7629, #7935, #8031, #8098, #8233, #8565 | -| [@nguyenphi37](https://github.com/nguyenphi37) | direct commit / report | -| [@not-knope](https://github.com/not-knope) | #8206 | -| [@nramabad](https://github.com/nramabad) | #7926 | -| [@oyi77](https://github.com/oyi77) | #6917, #6918, #6919, #6920, #6921, #6923, #7032, #7045, #7046, #7066, #7070, #7178, #7719, #7744, #7787, #7893, #8219 | -| [@Pitchfork-and-Torch](https://github.com/Pitchfork-and-Torch) | #6747, #6791 | -| [@professional-ALFIE](https://github.com/professional-ALFIE) | #6877 | -| [@Prudhvivuda](https://github.com/Prudhvivuda) | #8032, #8220, #8250, #8309, #8441, #8467, #8488, #8493, #8494, #8495, #8586, #8587, #8606, #8607, #8608, #8611, #8805, #8806 | -| [@QRcode1337](https://github.com/QRcode1337) | #7034 | -| [@quanturbo](https://github.com/quanturbo) | #6780 | -| [@rafaeldrincon](https://github.com/rafaeldrincon) | #8866, #8867 | -| [@rafaumeu](https://github.com/rafaumeu) | #6813, #6979, #6982, #6983, #6987, #6988, #7001, #7808, #7815, #8071, #8113, #8179, #8184, #8185, #8190, #8195, #8196, #8203 | -| [@RaviTharuma](https://github.com/RaviTharuma) | #7852, #7853, #7855, #7862, #7885, #7972, #7978, #8021, #8022, #8023, #8025, #8027, #8030, #8101, #8102, #8124, #8252, #8292, #8296, #8301, #8302, #8303, #8304, #8308 | -| [@RCrushMe](https://github.com/RCrushMe) | #8151, #8378 | -| [@ricatix](https://github.com/ricatix) | direct commit / report | -| [@ridho9](https://github.com/ridho9) | #8310 | -| [@rinseaid](https://github.com/rinseaid) | #8721, #8729, #8821 | -| [@rixzkiye](https://github.com/rixzkiye) | direct commit / report | -| [@rqzbeh](https://github.com/rqzbeh) | #8514, #8515 | -| [@rushsinging](https://github.com/rushsinging) | #7256 | -| [@ryanngit](https://github.com/ryanngit) | direct commit / report | -| [@samir-abis](https://github.com/samir-abis) | direct commit / report | -| [@seanford](https://github.com/seanford) | #8194, #8218, #8232 | -| [@SeaXen](https://github.com/SeaXen) | #7063, #7264, #7294 | -| [@Securiteru](https://github.com/Securiteru) | #7683 | -| [@SemonCat](https://github.com/SemonCat) | direct commit / report | -| [@shixi-li](https://github.com/shixi-li) | #8569 | -| [@SingCJ](https://github.com/SingCJ) | direct commit / report | -| [@skutanjir](https://github.com/skutanjir) | #7865, #7939 | -| [@spacesky-cell](https://github.com/spacesky-cell) | direct commit / report | -| [@SteeleHu](https://github.com/SteeleHu) | #8747 | -| [@sumanxg](https://github.com/sumanxg) | #8837, #8856 | -| [@swingtempo](https://github.com/swingtempo) | #7790, #8349, #8766 | -| [@Tasogarre](https://github.com/Tasogarre) | #7861, #8207 | -| [@techsolutionmta](https://github.com/techsolutionmta) | direct commit / report | -| [@tenshiak](https://github.com/tenshiak) | #7274, #7643 | -| [@terrafirmbot-source](https://github.com/terrafirmbot-source) | #8685 | -| [@thepigdestroyer](https://github.com/thepigdestroyer) | #7497 | -| [@tianrking](https://github.com/tianrking) | #7353 | -| [@tientien17](https://github.com/tientien17) | #7841, #7844, #7925 | -| [@TitoTFP](https://github.com/TitoTFP) | #8838 | -| [@tjengbudi](https://github.com/tjengbudi) | #4009 | -| [@tmone](https://github.com/tmone) | #7806, #7933 | -| [@TrackCrewGalore](https://github.com/TrackCrewGalore) | #6271, #8128 | -| [@trfi](https://github.com/trfi) | direct commit / report | -| [@TuyulSpam](https://github.com/TuyulSpam) | direct commit / report | -| [@ViFigueiredo](https://github.com/ViFigueiredo) | #7301 | -| [@vzts](https://github.com/vzts) | #7390 | -| [@warelik](https://github.com/warelik) | direct commit / report | -| [@way-art](https://github.com/way-art) | direct commit / report | -| [@webmasterarbez](https://github.com/webmasterarbez) | #7504 | -| [@wgordon17](https://github.com/wgordon17) | #8852 | -| [@whale9820](https://github.com/whale9820) | direct commit / report | -| [@Wibias](https://github.com/Wibias) | #7125 | -| [@wilsonicdev](https://github.com/wilsonicdev) | direct commit / report | -| [@Witroch4](https://github.com/Witroch4) | #6753, #6762, #6790, #7901, #7902 | -| [@XCrag](https://github.com/XCrag) | direct commit / report | -| [@xiaoyaner0201](https://github.com/xiaoyaner0201) | #8122, #8261, #8262 | -| [@xier2012](https://github.com/xier2012) | #7036, #7050, #7052, #7053, #7056, #7059, #7060, #7061, #7166, #7299 | -| [@xxue-z](https://github.com/xxue-z) | #7098 | -| [@xz-dev](https://github.com/xz-dev) | #6323, #6330, #6714, #6727, #7004, #7012, #7027, #7673, #7700, #7747, #7776, #7843 | -| [@yidecode](https://github.com/yidecode) | direct commit / report | -| [@yinaoxiong](https://github.com/yinaoxiong) | #6805 | -| [@diegosouzapw](https://github.com/diegosouzapw) | maintainer | +| Contributor | PRs / Issues | +| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| [@0x2f0](https://github.com/0x2f0) | #8679 | +| [@0xheycat](https://github.com/0xheycat) | #8751 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #8123 | +| [@adrianaryaputra](https://github.com/adrianaryaputra) | #7928 | +| [@advane204f](https://github.com/advane204f) | direct commit / report | +| [@Ajeesh25353646](https://github.com/Ajeesh25353646) | #7528 | +| [@allanvb](https://github.com/allanvb) | #8471, #8759, #8814, #8862 | +| [@alltomatos](https://github.com/alltomatos) | #6703, #6715, #6756, #6757, #6759, #6813, #6819, #6821, #7041, #7042, #7164, #7277, #7490, #7492, #7644 | +| [@alvaretto](https://github.com/alvaretto) | #8077, #8161, #8170 | +| [@amitgolan60-coder](https://github.com/amitgolan60-coder) | #8727 | +| [@andrea-kingautomation](https://github.com/andrea-kingautomation) | #7678 | +| [@andrewmunsell](https://github.com/andrewmunsell) | #6774, #6779, #6795 | +| [@AndrianBalanescu](https://github.com/AndrianBalanescu) | #6828, #6829, #7794, #7804, #7810, #7813, #7816, #7891, #8050 | +| [@anhdiepmmk](https://github.com/anhdiepmmk) | direct commit / report | +| [@anndev-69](https://github.com/anndev-69) | direct commit / report | +| [@apoapostolov](https://github.com/apoapostolov) | #8127 | +| [@arpit-jaiswal-dev](https://github.com/arpit-jaiswal-dev) | #7881 | +| [@artickc](https://github.com/artickc) | #6763, #6955, #7204, #7696, #7768, #7896, #7900, #7911, #7930, #7994, #8006, #8159, #8470, #8496, #8511, #8863 | +| [@Arul-](https://github.com/Arul-) | #7878 | +| [@asynx6](https://github.com/asynx6) | direct commit / report | +| [@attid](https://github.com/attid) | #6984 | +| [@backryun](https://github.com/backryun) | #6280, #6675, #6862, #7296, #7314, #7358, #7531, #7687, #7772, #7812, #7866, #7874, #7882, #7914, #8013, #8225, #8226, #8227, #8230, #8266, #8275, #8298, #8464, #8473, #8483, #8485, #8489, #8490, #8498, #8499, #8520, #8525, #8528, #8531, #8533, #8557, #8638, #8639, #8641, #8643, #8644, #8645, #8646, #8647, #8661, #8663, #8665, #8732, #8810, #8811, #8812, #8815, #8816, #8819, #8820, #8824 | +| [@beingshafin](https://github.com/beingshafin) | direct commit / report | +| [@brick30llc-ctrl](https://github.com/brick30llc-ctrl) | #6944 | +| [@brunnolouzada](https://github.com/brunnolouzada) | #8581 | +| [@c4usal](https://github.com/c4usal) | #7627, #8129 | +| [@CahyokPutraDev99](https://github.com/CahyokPutraDev99) | direct commit / report | +| [@Capslockb](https://github.com/Capslockb) | #7892 | +| [@CarmeloCampos](https://github.com/CarmeloCampos) | direct commit / report | +| [@Chewji9875](https://github.com/Chewji9875) | #7545 | +| [@chirag127](https://github.com/chirag127) | #6022, #6593, #6643, #6644, #6646, #6650, #6769, #6771, #6804, #7079, #7520, #8143 | +| [@chitholian](https://github.com/chitholian) | direct commit / report | +| [@chy1211](https://github.com/chy1211) | direct commit / report | +| [@CitrusIce](https://github.com/CitrusIce) | #6937, #6938 | +| [@costaeder](https://github.com/costaeder) | #8628 | +| [@Dan-ex-hub](https://github.com/Dan-ex-hub) | #7743 | +| [@danscMax](https://github.com/danscMax) | #7359, #7511, #7517, #7648, #7656, #7672, #7689 | +| [@dependabot](https://github.com/dependabot) | #7897, #7898, #8235 | +| [@Dingding-leo](https://github.com/Dingding-leo) | #7988, #7989, #8162, #8165, #8167, #8283, #8286, #8287, #8633, #8636, #8642, #8651, #8652, #8667, #8691, #8715, #8730, #8731, #8762, #8763, #8764, #8795 | +| [@DinonowDev](https://github.com/DinonowDev) | #8552, #8559, #8583, #8596, #8615, #8709, #8710, #8716, #8798, #8800, #8802 | +| [@dionisius95](https://github.com/dionisius95) | direct commit / report | +| [@DKotsyuba](https://github.com/DKotsyuba) | #7500 | +| [@dongwook-chan](https://github.com/dongwook-chan) | #7574, #7582, #7704 | +| [@Dragost](https://github.com/Dragost) | #8289 | +| [@Duongkhanhtool](https://github.com/Duongkhanhtool) | direct commit / report | +| [@dvirarad](https://github.com/dvirarad) | #8410 | +| [@ekinnee](https://github.com/ekinnee) | #7601, #7613, #7614, #7662, #7779, #7927, #7932, #7980, #8735 | +| [@enjoyer-hub](https://github.com/enjoyer-hub) | #6647, #7863 | +| [@epsilonode](https://github.com/epsilonode) | #8724 | +| [@evinjohnn](https://github.com/evinjohnn) | direct commit / report | +| [@fajarbossit](https://github.com/fajarbossit) | direct commit / report | +| [@felipeleite](https://github.com/felipeleite) | direct commit / report | +| [@fenix007](https://github.com/fenix007) | #7171, #7399, #8306, #8561 | +| [@FenjuFu](https://github.com/FenjuFu) | #7942 | +| [@floze-the-genius](https://github.com/floze-the-genius) | #7707 | +| [@fontvu](https://github.com/fontvu) | direct commit / report | +| [@fuko2935](https://github.com/fuko2935) | #8726 | +| [@fzrilsh](https://github.com/fzrilsh) | direct commit / report | +| [@gitcommit90](https://github.com/gitcommit90) | #6986 | +| [@glazec](https://github.com/glazec) | #8632 | +| [@growab](https://github.com/growab) | #7062, #7300 | +| [@guanbear](https://github.com/guanbear) | #7028 | +| [@guhcostan](https://github.com/guhcostan) | #8433 | +| [@hartmark](https://github.com/hartmark) | #8208, #8209, #8210, #8211, #8212, #8213, #8337, #8341, #8354, #8462 | +| [@HassiyYT](https://github.com/HassiyYT) | #7864 | +| [@heishen6](https://github.com/heishen6) | direct commit / report | +| [@herjarsa](https://github.com/herjarsa) | #7612, #7625, #7633, #7869, #7871, #8476 | +| [@HoneyTyagii](https://github.com/HoneyTyagii) | #8444 | +| [@HouMinXi](https://github.com/HouMinXi) | #7035, #7129, #7290, #7398, #7408, #7973, #8290, #8312, #8842, #8845, #8860, #8865 | +| [@hppsc1215](https://github.com/hppsc1215) | #7546, #8835 | +| [@huohua-dev](https://github.com/huohua-dev) | #6794 | +| [@hydraxman](https://github.com/hydraxman) | #7909 | +| [@iamraydoan](https://github.com/iamraydoan) | #6798 | +| [@ianriizky](https://github.com/ianriizky) | #6072, #6538 | +| [@ikelvingo](https://github.com/ikelvingo) | #8355 | +| [@insoln](https://github.com/insoln) | #7906, #7908, #8041, #8054, #8062 | +| [@irvandikky](https://github.com/irvandikky) | #7695 | +| [@isiahw1](https://github.com/isiahw1) | #7555 | +| [@itiwant](https://github.com/itiwant) | direct commit / report | +| [@janeza2](https://github.com/janeza2) | #6308 | +| [@Jordannst](https://github.com/Jordannst) | direct commit / report | +| [@JoshimOfficial](https://github.com/JoshimOfficial) | #8526 | +| [@justdoGIT](https://github.com/justdoGIT) | #8695 | +| [@JxnLexn](https://github.com/JxnLexn) | #6776, #6993, #7154, #7177, #7269, #7273, #7280, #7281, #7282, #7323, #7360, #7377, #7378, #7379, #7380, #7381, #7419, #7607, #7894, #7905, #7912, #8008, #8009, #8010 | +| [@kamenkadmitry](https://github.com/kamenkadmitry) | #7350, #7425 | +| [@kaon0388v1](https://github.com/kaon0388v1) | #7049 | +| [@KaynXu](https://github.com/KaynXu) | #8284 | +| [@KooshaPari](https://github.com/KooshaPari) | #6611, #6632, #6856, #7008, #7087, #7093, #7128, #7130, #7136, #7315, #7318, #7334, #7336 | +| [@KunN-21](https://github.com/KunN-21) | direct commit / report | +| [@leninejunior](https://github.com/leninejunior) | #8049 | +| [@leszek3737](https://github.com/leszek3737) | #7782, #7807, #8343, #8543, #8823 | +| [@like3213934360-lab](https://github.com/like3213934360-lab) | direct commit / report | +| [@linhdmn](https://github.com/linhdmn) | #8439 | +| [@Long-Feeds](https://github.com/Long-Feeds) | #8011 | +| [@loulanyue](https://github.com/loulanyue) | #7540 | +| [@lucasjustinudin](https://github.com/lucasjustinudin) | direct commit / report | +| [@lunkerchen](https://github.com/lunkerchen) | #8024 | +| [@makcimbx](https://github.com/makcimbx) | #7692, #8171, #8432 | +| [@Mananz90](https://github.com/Mananz90) | #8723 | +| [@marceli1404](https://github.com/marceli1404) | #8570 | +| [@maxmad64bis](https://github.com/maxmad64bis) | #8660 | +| [@megamen32](https://github.com/megamen32) | #7313 | +| [@MichaelYcJo](https://github.com/MichaelYcJo) | #8224 | +| [@mikeiagents](https://github.com/mikeiagents) | #8598 | +| [@MikeTuev](https://github.com/MikeTuev) | #6586 | +| [@mikolaj92](https://github.com/mikolaj92) | #6973 | +| [@MisileLab](https://github.com/MisileLab) | #8566 | +| [@MonteNegroX](https://github.com/MonteNegroX) | #8217 | +| [@Moseyuh333](https://github.com/Moseyuh333) | #7781, #8264 | +| [@MrFadiAi](https://github.com/MrFadiAi) | #7073 | +| [@mrprohack](https://github.com/mrprohack) | direct commit / report | +| [@MumuTW](https://github.com/MumuTW) | #8423, #8425, #8426, #8427, #8428, #8524, #8534, #8544, #8545, #8546, #8547, #8548, #8554, #8582, #8585, #8589, #8592, #8604, #8605, #8612, #8619, #8657, #8690, #8741, #8749 | +| [@mustafa-phd](https://github.com/mustafa-phd) | #7686 | +| [@NBN-N3](https://github.com/NBN-N3) | #8794 | +| [@nguyenha935](https://github.com/nguyenha935) | #7493, #7547, #7552, #7553, #7629, #7935, #8031, #8098, #8233, #8565 | +| [@nguyenphi37](https://github.com/nguyenphi37) | direct commit / report | +| [@not-knope](https://github.com/not-knope) | #8206 | +| [@nramabad](https://github.com/nramabad) | #7926 | +| [@oyi77](https://github.com/oyi77) | #6917, #6918, #6919, #6920, #6921, #6923, #7032, #7045, #7046, #7066, #7070, #7178, #7719, #7744, #7787, #7893, #8219 | +| [@Pitchfork-and-Torch](https://github.com/Pitchfork-and-Torch) | #6747, #6791 | +| [@professional-ALFIE](https://github.com/professional-ALFIE) | #6877 | +| [@Prudhvivuda](https://github.com/Prudhvivuda) | #8032, #8220, #8250, #8309, #8441, #8467, #8488, #8493, #8494, #8495, #8586, #8587, #8606, #8607, #8608, #8611, #8805, #8806 | +| [@QRcode1337](https://github.com/QRcode1337) | #7034 | +| [@quanturbo](https://github.com/quanturbo) | #6780 | +| [@rafaeldrincon](https://github.com/rafaeldrincon) | #8866, #8867 | +| [@rafaumeu](https://github.com/rafaumeu) | #6813, #6979, #6982, #6983, #6987, #6988, #7001, #7808, #7815, #8071, #8113, #8179, #8184, #8185, #8190, #8195, #8196, #8203 | +| [@RaviTharuma](https://github.com/RaviTharuma) | #7852, #7853, #7855, #7862, #7885, #7972, #7978, #8021, #8022, #8023, #8025, #8027, #8030, #8101, #8102, #8124, #8252, #8292, #8296, #8301, #8302, #8303, #8304, #8308 | +| [@RCrushMe](https://github.com/RCrushMe) | #8151, #8378 | +| [@ricatix](https://github.com/ricatix) | direct commit / report | +| [@ridho9](https://github.com/ridho9) | #8310 | +| [@rinseaid](https://github.com/rinseaid) | #8721, #8729, #8821 | +| [@rixzkiye](https://github.com/rixzkiye) | direct commit / report | +| [@rqzbeh](https://github.com/rqzbeh) | #8514, #8515 | +| [@rushsinging](https://github.com/rushsinging) | #7256 | +| [@ryanngit](https://github.com/ryanngit) | direct commit / report | +| [@samir-abis](https://github.com/samir-abis) | direct commit / report | +| [@seanford](https://github.com/seanford) | #8194, #8218, #8232 | +| [@SeaXen](https://github.com/SeaXen) | #7063, #7264, #7294 | +| [@Securiteru](https://github.com/Securiteru) | #7683 | +| [@SemonCat](https://github.com/SemonCat) | direct commit / report | +| [@shixi-li](https://github.com/shixi-li) | #8569 | +| [@SingCJ](https://github.com/SingCJ) | direct commit / report | +| [@skutanjir](https://github.com/skutanjir) | #7865, #7939 | +| [@spacesky-cell](https://github.com/spacesky-cell) | direct commit / report | +| [@SteeleHu](https://github.com/SteeleHu) | #8747 | +| [@sumanxg](https://github.com/sumanxg) | #8837, #8856 | +| [@swingtempo](https://github.com/swingtempo) | #7790, #8349, #8766 | +| [@Tasogarre](https://github.com/Tasogarre) | #7861, #8207 | +| [@techsolutionmta](https://github.com/techsolutionmta) | direct commit / report | +| [@tenshiak](https://github.com/tenshiak) | #7274, #7643 | +| [@terrafirmbot-source](https://github.com/terrafirmbot-source) | #8685 | +| [@thepigdestroyer](https://github.com/thepigdestroyer) | #7497 | +| [@tianrking](https://github.com/tianrking) | #7353 | +| [@tientien17](https://github.com/tientien17) | #7841, #7844, #7925 | +| [@TitoTFP](https://github.com/TitoTFP) | #8838 | +| [@tjengbudi](https://github.com/tjengbudi) | #4009 | +| [@tmone](https://github.com/tmone) | #7806, #7933 | +| [@TrackCrewGalore](https://github.com/TrackCrewGalore) | #6271, #8128 | +| [@trfi](https://github.com/trfi) | direct commit / report | +| [@TuyulSpam](https://github.com/TuyulSpam) | direct commit / report | +| [@ViFigueiredo](https://github.com/ViFigueiredo) | #7301 | +| [@vzts](https://github.com/vzts) | #7390 | +| [@warelik](https://github.com/warelik) | direct commit / report | +| [@way-art](https://github.com/way-art) | direct commit / report | +| [@webmasterarbez](https://github.com/webmasterarbez) | #7504 | +| [@wgordon17](https://github.com/wgordon17) | #8852 | +| [@whale9820](https://github.com/whale9820) | direct commit / report | +| [@Wibias](https://github.com/Wibias) | #7125 | +| [@wilsonicdev](https://github.com/wilsonicdev) | direct commit / report | +| [@Witroch4](https://github.com/Witroch4) | #6753, #6762, #6790, #7901, #7902 | +| [@XCrag](https://github.com/XCrag) | direct commit / report | +| [@xiaoyaner0201](https://github.com/xiaoyaner0201) | #8122, #8261, #8262 | +| [@xier2012](https://github.com/xier2012) | #7036, #7050, #7052, #7053, #7056, #7059, #7060, #7061, #7166, #7299 | +| [@xxue-z](https://github.com/xxue-z) | #7098 | +| [@xz-dev](https://github.com/xz-dev) | #6323, #6330, #6714, #6727, #7004, #7012, #7027, #7673, #7700, #7747, #7776, #7843 | +| [@yidecode](https://github.com/yidecode) | direct commit / report | +| [@yinaoxiong](https://github.com/yinaoxiong) | #6805 | +| [@diegosouzapw](https://github.com/diegosouzapw) | maintainer | --- diff --git a/README.md b/README.md index e31e2710a6..b7c70a6342 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,8 @@ | | v3.8.49 | **v3.8.50** | `v3.8.51+` | | ------------------------- | :-----: | :---------: | :---------: | -| 🌐 Providers | 291 | **339** | more queued | -| 🧠 Documented models | 500+ | **1200+** | — | +| 🌐 Providers | 290 | **339** | more queued | +| 🧠 Documented models | 1185 | **1202** | — | | 🖼️ Modality Bridge | — | 🆕 vision | video | | 📡 Radar free catalog | — | — | 🔭 next | | ⚖️ Quota-aware scheduling | — | — | 🔭 next | @@ -210,7 +210,7 @@ curl http://localhost:20128/v1/chat/completions \ -The Promise — One endpoint. 339 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 339 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 15–95%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 40+ free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 105 tools, A2A, memory, guardrails, evals — 25,000+ tests). +The Promise — One endpoint. 339 providers. Never stop building — OmniRoute picks the cheapest one that works. Six pillars: Never hit limits (auto-fallback across 339 providers in milliseconds, zero downtime) · Save up to 95% tokens (RTK + Caveman stacked compression cuts 15–95%, ~89% avg on tool-heavy sessions) · $0 to start (90+ free tiers, 56 free forever — no card needed) · Every tool works (33 coding agents through one config) · One endpoint (OpenAI ↔ Claude ↔ Gemini ↔ Responses API at /v1) · Production-grade (circuit breakers, TLS stealth, MCP 105 tools, A2A, memory, guardrails, evals — 25,000+ tests).

@@ -449,7 +449,7 @@ All **19** strategies — mix & match per combo step: ### 🧱 Resilience is built in (3 independent layers) -OmniRoute resilience — 3 independent self-healing layers, the right layer for the right failure. Layer 1 provider circuit breaker (whole provider): trips only on 408/5xx, thresholds OAuth 3× / API-key 5× / local 2×, resets 60s/30s/15s into a HALF-OPEN probe, lazy recovery; while OPEN the combo reroutes to the next provider. Layer 2 connection cooldown (one key/account): base 5s OAuth / 3s API-key, exponential ×2 backoff with anti-thundering-herd guard, 429 honors Retry-After, success clears all error state; one cooling key is skipped while sibling keys keep serving. Layer 3 model lockout (one model): per-model 429, local 404 or mode denials lock just that model — never the whole connection. Terminal states (banned, expired, credits exhausted) are for the operator, not cooldowns. +OmniRoute resilience — 3 independent self-healing layers, the right layer for the right failure. Layer 1 provider circuit breaker (whole provider): trips only on 408/5xx, thresholds OAuth 10× / API-key 15× / local 2×, resets 60s/30s/15s into a HALF-OPEN probe, lazy recovery; while OPEN the combo reroutes to the next provider. Layer 2 connection cooldown (one key/account): base 5s OAuth / 3s API-key, exponential ×2 backoff with anti-thundering-herd guard, 429 honors Retry-After, success clears all error state; one cooling key is skipped while sibling keys keep serving. Layer 3 model lockout (one model): per-model 429, local 404 or mode denials lock just that model — never the whole connection. Terminal states (banned, expired, credits exhausted) are for the operator, not cooldowns. 📖 [Auto-Combo Engine](docs/routing/AUTO-COMBO.md) · [Resilience Guide](docs/architecture/RESILIENCE_GUIDE.md) @@ -603,7 +603,7 @@ Pix copia-e-cola: -> The most complete catalog of any open-source router: **339 providers**, **90+ with a free tier**, **40+ free forever**. +> The most complete catalog of any open-source router: **339 providers**, **90+ with a free tier**, **56 free forever**.
@@ -1061,7 +1061,7 @@ same process on one port, so there is no separate CLI-only package today. RuntimeNode.js 22.x / 24.x LTS — >=22.22.2 <23 || >=24.0.0 <27 LanguageTypeScript 6.0 — 100% TypeScript across src/ and open-sse/ (zero any in core since v2.0) FrameworkNext.js 16 + React 19 + Tailwind CSS 4 - Databasebetter-sqlite3 (SQLite, WAL journaling) + LowDB (JSON legacy) — 95 domain modules, 145 migrations + Databasebetter-sqlite3 (SQLite, WAL journaling) + LowDB (JSON legacy) — 117 domain modules, 145 migrations MemorySQLite FTS5 full-text + int8-quantized vector embeddings, typed decay SchemasZod 4 — MCP tool I/O validation + API contracts ProtocolsMCP (stdio / HTTP / SSE) + A2A v0.3 (JSON-RPC 2.0 + SSE) diff --git a/docs/diagrams/promise-pillars.svg b/docs/diagrams/promise-pillars.svg index 4f975d25fb..284bf765d8 100644 --- a/docs/diagrams/promise-pillars.svg +++ b/docs/diagrams/promise-pillars.svg @@ -1,4 +1,4 @@ - + Animated promise card: six pillar tiles fade in in reading order, then a soft colored border highlight sweeps from tile to tile in a continuous cycle. @@ -73,7 +73,7 @@ $0 to start - 90+ providers with a free tier, 40+ free + 90+ providers with a free tier, 56 free forever — Qoder, Pollinations, Cloudflare, SiliconFlow… No card needed. diff --git a/docs/diagrams/resilience-layers.svg b/docs/diagrams/resilience-layers.svg index b4d49b7f31..022e35f365 100644 --- a/docs/diagrams/resilience-layers.svg +++ b/docs/diagrams/resilience-layers.svg @@ -1,4 +1,4 @@ - + Animated resilience card: three stacked layer panels, each replaying its healing loop — breaker states cycling CLOSED, OPEN, HALF-OPEN; a cooling key with backoff while other keys serve; a locked model while sibling models keep serving. First frame is fully readable. @@ -17,6 +17,6 @@ The right layer for the right failure — never kill more than what actually broke. PROVIDERCONNECTION / KEYMODEL - LAYER 1 · SCOPE: WHOLE PROVIDERProvider circuit breakerisolate a provider failing upstream —reroute now, auto-probe to recovertrips only on 408 · 500 · 502 · 503 · 504threshold — oauth 3× · api-key 5× · local 2×reset — 60s · 30s · 15s → HALF-OPEN probelazy recovery — reads refresh expired staterouterprovider Afails ×5provider B ← nextCLOSEDOPENHALF-OPENLAYER 2 · SCOPE: ONE KEY / ACCOUNTConnection cooldownskip one rate-limited key while theother keys keep serving the providerbase cooldown — oauth 5s · api-key 3srepeat fails — backoff ×2 (anti-herd guard)429 honors Retry-After / reset headerssuccess → clearAccountError() resets allprovider · 3 keyskey-1429key-2key-3cooling ×2ⁿLAYER 3 · SCOPE: ONE MODELModel lockoutquarantine a single model — never killthe whole connection for one 429scope — provider + connection + modelper-model 429 · local 404 · mode denialslocked model ≠ dead keyother models keep serving instantlykey-1model-amodel-bmodel-c + LAYER 1 · SCOPE: WHOLE PROVIDERProvider circuit breakerisolate a provider failing upstream —reroute now, auto-probe to recovertrips only on 408 · 500 · 502 · 503 · 504threshold — oauth 3× · api-key 5× · local 2×reset — 60s · 30s · 15s → HALF-OPEN probelazy recovery — reads refresh expired staterouterprovider Afails ×15provider B ← nextCLOSEDOPENHALF-OPENLAYER 2 · SCOPE: ONE KEY / ACCOUNTConnection cooldownskip one rate-limited key while theother keys keep serving the providerbase cooldown — oauth 5s · api-key 3srepeat fails — backoff ×2 (anti-herd guard)429 honors Retry-After / reset headerssuccess → clearAccountError() resets allprovider · 3 keyskey-1429key-2key-3cooling ×2ⁿLAYER 3 · SCOPE: ONE MODELModel lockoutquarantine a single model — never killthe whole connection for one 429scope — provider + connection + modelper-model 429 · local 404 · mode denialslocked model ≠ dead keyother models keep serving instantlykey-1model-amodel-bmodel-c which failure trips what → 5xx / 408 : breaker · key 429 / 401 : cooldown · one-model 429 / 404 : lockout · banned / expired / credits : terminal (operator) \ No newline at end of file diff --git a/scripts/check/check-docs-counts-sync.mjs b/scripts/check/check-docs-counts-sync.mjs index 61077b8cf9..5c9bd64ffb 100644 --- a/scripts/check/check-docs-counts-sync.mjs +++ b/scripts/check/check-docs-counts-sync.mjs @@ -175,10 +175,15 @@ function readCodeFacts() { "for(const x of (t?.scopes||[]))sc.add(x);", "const t=computeFreeModelTotals();const cli=Object.values(CLI_TOOLS);", "const by=(c)=>cli.filter(x=>x.category===c).length;", + // "Free forever" = every provider whose free access renews or needs no key at all. + // one-time-initial (signup credits) and discontinued pools are excluded on purpose. + "const FOREVER=new Set(['recurring-monthly','recurring-daily','recurring-uncapped',", + "'recurring-credit','keyless']);", + "const ff=new Set();for(const m of t.perModel)if(FOREVER.has(m.freeType))ff.add(m.provider);", 'console.log("@@"+JSON.stringify({freeSteady:t.steadyRecurringTokens,', "freeFirst:t.firstMonthRealisticTokens,freePools:t.poolCount,engines:ENGINE_IDS.length,", "cliTotal:cli.length,cliCode:by('code'),cliAgent:by('agent'),", - "mcpTools:countUniqueMcpTools(cols),mcpScopes:sc.size,providers:pids.size}));", + "mcpTools:countUniqueMcpTools(cols),mcpScopes:sc.size,providers:pids.size,freeForever:ff.size}));", ].join(""); const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "docs-counts-")); try { @@ -460,6 +465,10 @@ export function buildChecks() { ), claim(f.mcpScopes, "MCP scopes", { pattern: /(\d+) scopes/gi }, ["README.md", "AGENTS.md"]), claim(f.cliTotal, "CLI tools", { pattern: /(\d+) tools(?=\s*\(\d+ CLI)/gi }, ["README.md"]), + claim(f.freeForever, "free-forever providers", { pattern: /(\d+) free forever/gi }, [ + "README.md", + "docs/diagrams/promise-pillars.svg", + ]), ]; })(), {