Skip to content

Commit cadc3f1

Browse files
diegosouzapwDiego Rodrigues de Sa e Souzardselfmegamen32KooshaPari
authored
Release v3.8.35 (#4743)
* chore(release): open v3.8.35 development cycle * fix db vacuum scheduler settings (#4726) Scheduled VACUUM now follows Storage page settings (scheduledVacuum/vacuumHour) as single source of truth; env-flag control path removed. 11/11 vacuum-scheduler tests pass against release/v3.8.35 tip; no orphaned env refs. Integrated into release/v3.8.35. * fix(tier): noAuth providers count as free; free filter returns empty … (#4753) noAuth providers now classified free (union of legacy list + NOAUTH_PROVIDERS chat-tier derivation), -free arena_elo alias, and auto/<cat>:free returns an empty pool when no free candidate matches (opt-in legacy fallback via OMNIROUTE_AUTO_FREE_FALLBACK_TO_FULL_POOL). New env var documented in .env.example + ENVIRONMENT.md; CHANGELOG bullet added (maintainer co-author). 46/46 node + 56/56 vitest tests pass on release tip; env-doc-sync, docs-sync, typecheck:core, lint, file-size all green. Integrated into release/v3.8.35. * refactor(chatCore): extrai 11 helpers de nível superior para 6 leaves puros (#3501) (#4571) chatCore god-file decomposition (#3501): extract 6 pure leaves (cacheUsageMeta, executorClientHeaders, nonStreamingResponseBody, skillsFormat, streamErrorResult, streamFinalize) from chatCore.ts. Rebased onto release/v3.8.35 tip (resolved single chatCore.ts conflict — removed now-extracted inline buildExecutorClientHeaders). 265/265 chatcore tests, 26/26 new leaf tests, typecheck:core, cycles, file-size all green. Integrated into release/v3.8.35. * refactor(chatCore): extrai resolveExecutorWithProxy + getExecutionCredentials para leaves (#3501) (#4646) chatCore #3501: extract resolveExecutorWithProxy + getExecutionCredentials to leaves (executorProxy.ts, executionCredentials.ts). Clean cherry-pick onto release tip post-#4571. 12/12 new leaf tests, typecheck:core, cycles, file-size green. Integrated into release/v3.8.35. * refactor(chatCore): extrai transforms de mensagens Claude p/ leaf (#3501) (#4708) chatCore #3501: extract Claude upstream-message transforms to leaf (claudeUpstreamMessages.ts + claudeMessageTypes.ts). Clean cherry-pick post-#4646. 8/8 new leaf tests, typecheck/cycles/file-size green. Integrated into release/v3.8.35. * refactor(chatCore): extrai persistAttemptLogs para leaf (#3501) (#4717) chatCore #3501: extract persistAttemptLogs to leaf (attemptLogging.ts). Rebased onto release tip post-#4708 (resolved imports conflict: kept tip's resolveCompressionHeader from compression Phase 3, dropped now-unused logTruncation import moved into the leaf). 288/288 chatcore tests, typecheck/cycles/file-size green. Integrated into release/v3.8.35. * refactor(chatCore): extrai stageTrace + compressionUsageReceipt para leaves (#3501) (#4721) chatCore #3501: extract stageTrace + compressionUsageReceipt to leaves. Clean cherry-pick post-#4717. 6/6 new leaf tests, typecheck/cycles/file-size green. Integrated into release/v3.8.35. * refactor(chatCore): extrai prepareUpstreamBody (1ª sub-fatia do executeProviderRequest, #3501) (#4730) chatCore #3501: extract prepareUpstreamBody (first sub-slice of executeProviderRequest) to leaf (upstreamBody.ts). Clean cherry-pick post-#4721. 7/7 new leaf tests, full 301/301 chatcore suite, typecheck/cycles/file-size green. Completes the 6-PR chatCore decomposition stack into release/v3.8.35. * fix(db): make db-backup import size cap configurable (#4719) (#4757) Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> * chore(quality): expand check:release-green to the FULL release-PR gate set (#4758) The release-green pre-flight (Solution C) previously covered only a subset of the gates that run exclusively on the release PR (PR→main), so reds still accrued silently on release/** and surfaced in ~40-min layers at release time (v3.8.34: 3 CI rounds — CodeQL sanitization, then the fail-fast Quality Ratchet revealing openapi then cyclomatic-complexity one push at a time, plus zizmor/integration). Now check:release-green reproduces the COMPLETE release-PR gate set and reports EVERY red in one pass (collected, not fail-fast): - New DRIFT ratchets (report-only, rebaselined at release, never block): cyclomatic complexity, dead-code, type-coverage, compression-budget, openapi-coverage, workflow-lint (zizmor), codeql-ratchet. - New HARD gates (real defects): docs-all (fabricated-docs strict + i18n mirror sync) and the integration test suite (gated behind !--quick). The only release-PR gates it still cannot reproduce locally are GitHub-side CodeQL semantic analysis and SonarQube/SonarCloud (external services). The nightly-release-green workflow and /green-prs inherit the expanded coverage automatically (they invoke this script), so cycle drift is now surfaced continuously and the release PR is green on its first CI run. Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> * fix(dashboard): add missing onboarding.tiers step title (#4698) (#4755) Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> * feat(compression): Output Styles registry + D0 telemetry (Phase 4A) (#4694) Phase 4A: Output Styles registry + D0 telemetry. Integrated into release/v3.8.35. * feat(compression): SLM tier for ultra (Phase 4B) [stacked on #4694] (#4707) Phase 4B: SLM tier for ultra. Integrated into release/v3.8.35. * feat(compression): context-budget adaptive compression (Phase 4C) [stacked on #4707] (#4716) Phase 4C: adaptive context-budget compression. Integrated into release/v3.8.35. * feat(compression): offline evaluation harness (Phase 4 D1) [stacked on #4716] (#4720) Phase 4 D1: offline evaluation harness. Integrated into release/v3.8.35. * fix(sse): deepseek-web folds role:tool results into prompt transcript (#4712) (#4756) Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> * fix(dashboard): remove dead unconditional useLiveRequests call in HomePageClient (#4759, #4745, #4596) (#4761) Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> * fix(dashboard): dedupe provider nodes by id on compatible-provider add (#4746) (#4768) Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> * chore(db): re-export compressionRunTelemetry from localDb to satisfy db-rules (#4775) Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> * docs(security): add canonical STRIDE-based threat model (#4783) Canonical STRIDE threat model. Integrated into release/v3.8.35. * test(dashboard): add smoke test for home client dashboard (#4793) Smoke test guarding the dashboard home client render (regression #4745/#4759). Code fix already landed via #4761; this PR's jsdom smoke test is the net-new regression guard. Integrated into release/v3.8.35. * fix(combos): auto-promote zeroLatencyOptimizationsEnabled so legacy configs (pre-3.8.33 fallbackCompressionMode="lite") round-trip on the first GUI edit (#4774) Auto-promote zeroLatencyOptimizationsEnabled + strip v3.8.31-era removed keys so legacy combo configs round-trip through PUT /api/combos/{id} on first GUI edit (closes #4382 followup). Pre-merge: rewrote the now-stale reject test to assert auto-promotion + added passthrough/round-trip regression guards; reconciled combos/page.tsx file-size baseline. Integrated into release/v3.8.35. * refactor(chatCore): extrai parse + usage-stats não-streaming do executeProviderRequest (#3501) (#4762) chatCore #3501: extract parseNonStreamingResponseBody + recordNonStreamingUsageStats. Integrated into release/v3.8.35. * refactor(chatCore): extrai recordContextEditingTelemetryHook (#3501) (#4779) chatCore #3501: extract recordContextEditingTelemetryHook. Integrated into release/v3.8.35. * refactor(chatCore): extrai recordCompressionCacheStats (#3501) (#4792) chatCore #3501: extract recordCompressionCacheStats. Integrated into release/v3.8.35. * refactor(chatCore): extrai writeCavemanOutputAnalytics (#3501) (#4794) chatCore #3501: extract writeCavemanOutputAnalytics. Integrated into release/v3.8.35. * refactor(chatCore): extrai scheduleQuotaShareConsumption (POST-hook não-streaming, #3501) (#4780) chatCore #3501: extract scheduleQuotaShareConsumption (non-streaming POST-hook). Integrated into release/v3.8.35. * refactor(chatCore): extrai emitRequestGamificationEvent (helper compartilhado DRY, #3501) (#4776) chatCore #3501: extract emitRequestGamificationEvent (DRY streaming/non-streaming). Integrated into release/v3.8.35. * refactor(chatCore): extrai runPluginOnResponseHook (#3501) (#4782) chatCore #3501: extract runPluginOnResponseHook. Integrated into release/v3.8.35. * refactor(chatCore): extrai scheduleStreamingQuotaShareConsumption (POST-hook streaming, #3501) (#4784) chatCore #3501: extract scheduleStreamingQuotaShareConsumption (streaming POST-hook). Integrated into release/v3.8.35. * refactor(chatCore): extrai recordStreamingUsageStats (analytics de usage streaming, #3501) (#4791) chatCore #3501: extract recordStreamingUsageStats. Integrated into release/v3.8.35. * refactor(chatCore): extrai recordStreamingCost (custo por-request streaming, #3501) (#4790) chatCore #3501: extract recordStreamingCost (per-request streaming cost). Integrated into release/v3.8.35. * docs(readme): credit ponytail + OmniCompress; restore env-doc-sync release-green (#4799) README compression credits (ponytail/OmniCompress) + env-doc-sync ignore for eval-only OMNIROUTE_EVAL_CREDENTIALS (restores release-green after #4720). Integrated into release/v3.8.35. * chore(quality): trim combo-config.test.ts comments under file-size cap (#4774 follow-up) (#4800) Restore file-size release-green. Integrated into release/v3.8.35. * feat(api-docs): Redoc-rendered /api/docs + consolidate OpenAPI spec to docs/openapi.yaml (#4781) Redoc /api/docs + OpenAPI spec consolidated to docs/openapi.yaml (canonical 201-path complete spec; old path → legacy fallback). All refs/gates/tests/CI updated. Integrated into release/v3.8.35. * docs(compression): declare Phase 4 layers — Output Styles, adaptive dial, per-request control (#4801) The README compression section listed the 9 input engines but not the Phase 4 layers now in production: - Output Styles (output-axis steering: terse-prose / less-code / terse-cjk, lite/full/ultra) - adaptive context-budget dial (reserve-output|percentage|absolute · floor|replace-autotrigger|off) - per-request x-omniroute-compression precedence + the offline eval harness Also bumped the highlights range to v3.8.35, expanded the compression feature bullet, and marked the GUIDE's Phase 4 row Shipped (was 'Planned' — it's merged on v3.8.35). Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(release): finalize v3.8.35 CHANGELOG + docs reconciliation - CHANGELOG: complete 3.8.35 section (all 35 commits since v3.8.34, contributor attribution: @rdself @megamen32 @KooshaPari @JxnLexn) - docs(security): align THREAT_MODEL.md refs with real code (routeGuard.ts, tokenLimits.ts, /api/monitoring/health) — fabricated-docs gate - check:fabricated-docs: skip docs/superpowers/specs (dated research reports) - i18n: sync 3.8.35 section into 41 CHANGELOG mirrors (docs-sync size gate) - ratchet rebaseline: cyclomatic 1916->1920, eslintWarnings 3907->3912 (inherited cycle drift; release-finalize diff is docs-only) * fix(release): resolve inherited base-reds surfaced by v3.8.35 release CI Cycle base-reds that only run on PR→main (not the PR→release fast-path): - test(autoCombo): suffixComposition-4517 used node:test in a vitest-only dir (#4753) → vitest found no suite. Switch to the vitest API. (Vitest job) - test(agentSkills): openapiParser fixture wrote docs/reference/openapi.yaml; parser reads docs/openapi.yaml since #4781 → point fixture at the new path. (Unit/Coverage/Node24/Node26 shard 4) - test(integration): proxy-pipeline source-scan expected inline streaming-cost code that #4790/#3501 extracted to the recordStreamingCost leaf → assert the delegation instead. (Integration 1/2) - fix(chatCore): derive the log trace id from crypto, not Math.random (CodeQL js/insecure-randomness — log-correlation id, not a secret). - test(resilience): circuit-breaker invalid-cooldown fallback asserted t>29000, flaking on slow CI where ~1.6s elapsed gave t=28401 → tolerate wall-clock drift (t>25000). (Unit 6/8) * fix(usage): derive pending-request id from crypto, not Math.random CodeQL js/insecure-randomness (#669): the pending-request id generated in trackPendingRequest (usageHistory.ts) flows into attempt logging and was flagged as insecure randomness in a security context. It's a log-correlation id, not a secret — switch to crypto RNG to clear the alert. Pairs with the chatCore traceId fix in 37c4978 (same sink). --------- Co-authored-by: Diego Rodrigues de Sa e Souza <souzamiriamrodrigues790@gmail.com> Co-authored-by: Randi <55005611+rdself@users.noreply.github.com> Co-authored-by: Demiurge The Single <megamen932@gmail.com> Co-authored-by: KooshaPari <42529354+KooshaPari@users.noreply.github.com> Co-authored-by: Jan Leon <Jan.gaschler@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 19d91d8 commit cadc3f1

300 files changed

Lines changed: 18126 additions & 1483 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,14 @@ QUOTA_STORE_DRIVER=sqlite # sqlite | redis
16401640
# QUOTA_CONSUMPTION_RETENTION_DAYS=14 # GC de buckets quota_consumption.updated_at antigos
16411641
# QUOTA_PREFLIGHT_CUTOFF_ENABLED=false # opt-in (default OFF): hard quota cutoff drops low-quota candidates before auto-routing scoring
16421642

1643+
# ─── Auto-Combo tier filter (#4517) ───────────────────────────────────────
1644+
# When an `auto/<category>:free` (or any `:<tier>`) request matches NO connected
1645+
# candidates, OmniRoute returns an EMPTY pool by default — so `:free` really means
1646+
# "free tier only" and a paid model is never picked just because no free provider is
1647+
# connected. Set this to `true`/`1` to restore the legacy behavior of falling back to
1648+
# the full (unfiltered) pool with a warning. Source: open-sse/services/autoCombo/virtualFactory.ts
1649+
# OMNIROUTE_AUTO_FREE_FALLBACK_TO_FULL_POOL=false
1650+
16431651
# ─── OpenCode config regeneration (scripts/ad-hoc/regen-opencode-config.ts) ───
16441652
# Base URL of the OmniRoute instance to query for /v1/models when regenerating
16451653
# an opencode.json with accurate limit.context values. Used by:
@@ -1729,21 +1737,3 @@ QUOTA_STORE_DRIVER=sqlite # sqlite | redis
17291737
# BIFROST_API_KEY=
17301738
# BIFROST_STREAMING_ENABLED=true
17311739
# BIFROST_TIMEOUT_MS=30000
1732-
1733-
# ── Scheduled VACUUM (Issue #4437) ────────────────────────────────────────
1734-
# Master switch for the scheduled SQLite VACUUM job.
1735-
# - OMNIROUTE_VACUUM_ENABLED=1 (default) → start a setInterval timer at boot
1736-
# that runs VACUUM once every OMNIROUTE_VACUUM_INTERVAL_HOURS.
1737-
# - 0 → disable the scheduler entirely (manual "Vacuum Now" still works).
1738-
# Source: src/lib/db/vacuumScheduler.ts
1739-
# OMNIROUTE_VACUUM_ENABLED=1
1740-
1741-
# How often to run VACUUM. Default: 24 hours. Minimum: 1. Must be an integer.
1742-
# The actual interval is computed lazily from OMNIROUTE_VACUUM_INTERVAL_HOURS
1743-
# at boot time, so changes here require a restart (or `omniroute vacuum restart`).
1744-
# OMNIROUTE_VACUUM_INTERVAL_HOURS=24
1745-
1746-
# Window in which the first VACUUM is allowed to run (cron-like start window).
1747-
# Default: 02:00-04:00 (local server time). Outside the window the scheduler
1748-
# waits until the window opens. Format: HH:MM-HH:MM (24-hour).
1749-
# OMNIROUTE_VACUUM_WINDOW=02:00-04:00

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ jobs:
227227
runs-on: ubuntu-latest
228228
steps:
229229
# fetch-depth: 0 — the OpenAPI breaking-change gate (oasdiff) reads the base
230-
# spec via `git show <base_ref>:docs/reference/openapi.yaml`; a shallow clone
230+
# spec via `git show <base_ref>:docs/openapi.yaml`; a shallow clone
231231
# would lack the base ref and the gate would self-skip (base-unresolved).
232232
- uses: actions/checkout@v7
233233
with:
@@ -318,7 +318,7 @@ jobs:
318318
- name: Workflow lint (actionlint+zizmor, ratchet, blocking)
319319
run: npm run check:workflows -- --ratchet
320320
# OpenAPI breaking-change detection (oasdiff). Diffs the PR's public API
321-
# contract (docs/reference/openapi.yaml) against the base branch's spec.
321+
# contract (docs/openapi.yaml) against the base branch's spec.
322322
# BLOCKING ratchet (Fase 9 Onda 0): reads metrics.openapiBreaking.value and
323323
# exits 1 ONLY on a measured regression (count > baseline). It SKIPs (exit 0)
324324
# when oasdiff is absent or the base spec can't be resolved — a missing

.github/workflows/dast-smoke.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
- run: pip install schemathesis
4343
- name: Schemathesis smoke (high-risk endpoints, blocking)
4444
run: |
45-
schemathesis run docs/reference/openapi.yaml --url http://localhost:20128 \
45+
schemathesis run docs/openapi.yaml --url http://localhost:20128 \
4646
--include-path-regex '^/v1/(chat/completions|models)$|^/api/(auth|keys)' \
4747
--max-examples 8 --workers 4 --checks all --max-response-time 30 \
4848
--request-timeout 20 --suppress-health-check all --no-color

.github/workflows/nightly-schemathesis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
# PROVE the contract is fuzzable and surface regressions, not to gate the build.
4646
continue-on-error: true
4747
run: |
48-
schemathesis run docs/reference/openapi.yaml \
48+
schemathesis run docs/openapi.yaml \
4949
--url http://localhost:20128 \
5050
--max-examples 20 \
5151
--workers 4 \

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ For any non-trivial change, read the matching deep-dive first:
554554
| Agent protocols (A2A / ACP / Cloud) | [`docs/frameworks/AGENT_PROTOCOLS_GUIDE.md`](docs/frameworks/AGENT_PROTOCOLS_GUIDE.md) |
555555
| MCP server | [`docs/frameworks/MCP-SERVER.md`](docs/frameworks/MCP-SERVER.md) |
556556
| A2A server | [`docs/frameworks/A2A-SERVER.md`](docs/frameworks/A2A-SERVER.md) |
557-
| API reference | [`docs/reference/API_REFERENCE.md`](docs/reference/API_REFERENCE.md) + [`docs/reference/openapi.yaml`](docs/reference/openapi.yaml) |
557+
| API reference | [`docs/reference/API_REFERENCE.md`](docs/reference/API_REFERENCE.md) + [`docs/openapi.yaml`](docs/openapi.yaml) |
558558
| Provider catalog (auto-generated) | [`docs/reference/PROVIDER_REFERENCE.md`](docs/reference/PROVIDER_REFERENCE.md) |
559559
| Tunnels | [`docs/ops/TUNNELS_GUIDE.md`](docs/ops/TUNNELS_GUIDE.md) |
560560
| Electron desktop | [`docs/guides/ELECTRON_GUIDE.md`](docs/guides/ELECTRON_GUIDE.md) |

CHANGELOG.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,36 @@
44

55
---
66

7+
## [3.8.35] — 2026-06-23
8+
9+
### ✨ New Features
10+
11+
- **Adaptive context compression (Phase 4)**: a four-layer compression upgrade landed across stacked PRs — an **Output Styles** registry (`terse-prose` / `less-code` / `terse-cjk`) ([#4694](https://github.com/diegosouzapw/OmniRoute/pull/4694) — thanks @diegosouzapw), an opt-in **SLM `ultra` tier** (two-tier LLMLingua with heuristic fallback) ([#4707](https://github.com/diegosouzapw/OmniRoute/pull/4707) — thanks @diegosouzapw), a **context-budget adaptive dial** (reserve-output ladder + floor) ([#4716](https://github.com/diegosouzapw/OmniRoute/pull/4716) — thanks @diegosouzapw), and an **offline evaluation harness** (PII-gated corpus, self-test judge, gold-grader, real-pipeline runner behind a `ModelClient` seam) ([#4720](https://github.com/diegosouzapw/OmniRoute/pull/4720) — thanks @diegosouzapw). All four layers share a single `CompressionRunTelemetry` contract.
12+
- **Redoc-rendered API docs**: a consolidated OpenAPI spec now lives at `docs/openapi.yaml` and is served as interactive Redoc documentation at `/api/docs`. ([#4781](https://github.com/diegosouzapw/OmniRoute/pull/4781) — thanks @KooshaPari / @diegosouzapw)
13+
14+
### 🔧 Bug Fixes
15+
16+
- **db-backups**: make the database-import size cap configurable via `OMNIROUTE_DB_IMPORT_MAX_MB` (default 100 MB, 4 GB ceiling) so backups larger than 100 MB can be restored; error message now points to the env var and to VACUUM ([#4757](https://github.com/diegosouzapw/OmniRoute/pull/4757) — closes #4719, thanks @diegosouzapw).
17+
- **Onboarding**: add the missing `onboarding.tiers` step-title translation so the setup wizard no longer crashes with `MISSING_MESSAGE: onboarding.tiers` ([#4755](https://github.com/diegosouzapw/OmniRoute/pull/4755) — closes #4698, thanks @diegosouzapw).
18+
- **deepseek-web**: fold `role:"tool"` results into the single-prompt transcript (`messagesToPrompt`) so tool outputs reach the model instead of being silently dropped when a follow-up turn omits the `tools[]` array ([#4756](https://github.com/diegosouzapw/OmniRoute/pull/4756) — closes #4712, thanks @diegosouzapw).
19+
- **Dashboard**: remove the dead, unconditional `useLiveRequests()` call from `HomePageClient.tsx` — it crashed the `/home` page in production builds with `ReferenceError: useLiveRequests is not defined` (#4759, #4745) and opened the live-dashboard WebSocket even when Provider Topology was hidden (#4596). The live feed remains owned by the settings-gated `HomeProviderTopologySection` ([#4761](https://github.com/diegosouzapw/OmniRoute/pull/4761) — thanks @diegosouzapw).
20+
- **Providers dashboard**: dedupe provider nodes by id when adding a compatible provider (`upsertProviderNodeById`) so the same provider can no longer appear twice and no-op adds don't invalidate the compatible-provider memo ([#4768](https://github.com/diegosouzapw/OmniRoute/pull/4768) — closes #4746, thanks @diegosouzapw).
21+
- **Storage VACUUM**: the scheduled VACUUM job now follows the Storage page settings (`scheduledVacuum` / `vacuumHour`) as the single source of truth; the legacy env-flag control path was removed ([#4726](https://github.com/diegosouzapw/OmniRoute/pull/4726) — thanks @rdself).
22+
- **Tiers**: no-auth providers are now counted as free, and the free-tier filter returns an empty set instead of falling through to every provider ([#4753](https://github.com/diegosouzapw/OmniRoute/pull/4753) — thanks @megamen32 / @diegosouzapw).
23+
- **Combos**: auto-promote `zeroLatencyOptimizationsEnabled` so legacy configs (pre-3.8.33 `fallbackCompressionMode="lite"`) round-trip cleanly on the first GUI edit ([#4774](https://github.com/diegosouzapw/OmniRoute/pull/4774) — thanks @KooshaPari / @diegosouzapw).
24+
25+
### 📝 Maintenance
26+
27+
- **chatCore (#3501)**: continued the incremental decomposition of `executeProviderRequest` and the streaming/non-streaming hooks into pure leaf modules — top-level helpers + 6 pure leaves ([#4571](https://github.com/diegosouzapw/OmniRoute/pull/4571)), `resolveExecutorWithProxy` + `getExecutionCredentials` ([#4646](https://github.com/diegosouzapw/OmniRoute/pull/4646)), Claude message transforms ([#4708](https://github.com/diegosouzapw/OmniRoute/pull/4708)), `persistAttemptLogs` ([#4717](https://github.com/diegosouzapw/OmniRoute/pull/4717)), `stageTrace` + `compressionUsageReceipt` ([#4721](https://github.com/diegosouzapw/OmniRoute/pull/4721)), `prepareUpstreamBody` ([#4730](https://github.com/diegosouzapw/OmniRoute/pull/4730)), parse + non-streaming usage-stats ([#4762](https://github.com/diegosouzapw/OmniRoute/pull/4762)), `recordContextEditingTelemetryHook` ([#4779](https://github.com/diegosouzapw/OmniRoute/pull/4779)), `scheduleQuotaShareConsumption` ([#4780](https://github.com/diegosouzapw/OmniRoute/pull/4780)), `emitRequestGamificationEvent` ([#4776](https://github.com/diegosouzapw/OmniRoute/pull/4776)), `runPluginOnResponseHook` ([#4782](https://github.com/diegosouzapw/OmniRoute/pull/4782)), `scheduleStreamingQuotaShareConsumption` ([#4784](https://github.com/diegosouzapw/OmniRoute/pull/4784)), `recordCompressionCacheStats` ([#4792](https://github.com/diegosouzapw/OmniRoute/pull/4792)), `writeCavemanOutputAnalytics` ([#4794](https://github.com/diegosouzapw/OmniRoute/pull/4794)), `recordStreamingUsageStats` ([#4791](https://github.com/diegosouzapw/OmniRoute/pull/4791)), and `recordStreamingCost` ([#4790](https://github.com/diegosouzapw/OmniRoute/pull/4790)). (thanks @diegosouzapw)
28+
- **Quality**: expand `check:release-green` to reproduce the full release-PR gate set locally ([#4758](https://github.com/diegosouzapw/OmniRoute/pull/4758) — thanks @diegosouzapw).
29+
- **db**: re-export `compressionRunTelemetry` from `localDb` to satisfy the db-rules gate ([#4775](https://github.com/diegosouzapw/OmniRoute/pull/4775) — thanks @diegosouzapw).
30+
- **Security docs**: add a canonical STRIDE-based threat model ([#4783](https://github.com/diegosouzapw/OmniRoute/pull/4783) — thanks @KooshaPari).
31+
- **Tests**: add a smoke test for the home-client dashboard ([#4793](https://github.com/diegosouzapw/OmniRoute/pull/4793) — thanks @JxnLexn).
32+
- **Docs**: credit **ponytail** and **OmniCompress** in the README inspiring-projects list and restore the `check:env-doc-sync` release-green by exempting the harness-only `OMNIROUTE_EVAL_CREDENTIALS` var ([#4799](https://github.com/diegosouzapw/OmniRoute/pull/4799) — thanks @diegosouzapw); declare the Phase 4 compression layers in the README + GUIDE ([#4801](https://github.com/diegosouzapw/OmniRoute/pull/4801) — thanks @diegosouzapw).
33+
- **Quality**: trim `combo-config.test.ts` comments back under the file-size cap (follow-up to #4774) ([#4800](https://github.com/diegosouzapw/OmniRoute/pull/4800) — thanks @diegosouzapw).
34+
35+
---
36+
737
## [3.8.34] — 2026-06-23
838

939
### ✨ New Features
@@ -18,6 +48,8 @@
1848

1949
### 🐛 Fixed
2050

51+
- **fix(tier): noAuth providers count as free; `auto/<cat>:free` returns an empty pool when no free candidate matches** — `freeProviders` is now the union of the legacy explicit list and every chat-tier `noAuth` provider derived from `NOAUTH_PROVIDERS` (so opencode / mimocode / duckduckgo-web are correctly classified free), the task-fitness lookup inherits a base model's `arena_elo` for its `-free` variant, and the `auto/<category>:<tier>` filter no longer silently falls back to the full pool — a `:free` request that matches no connected free model returns empty instead of billing a paid model (opt back into the legacy fallback with `OMNIROUTE_AUTO_FREE_FALLBACK_TO_FULL_POOL=true`). Corrupted/invalid `tier_config` rows now log a structured warning and fall back to defaults instead of throwing. ([#4753](https://github.com/diegosouzapw/OmniRoute/pull/4753), [#4517](https://github.com/diegosouzapw/OmniRoute/issues/4517) — thanks @megamen32)
52+
- **fix(db): scheduled VACUUM follows Storage settings** — the SQLite VACUUM scheduler now uses the existing Storage page `scheduledVacuum` / `vacuumHour` configuration as its single source of truth, refreshes immediately when those settings are saved, and no longer exposes a separate environment-variable control path.
2153
- **fix(db): scheduled cleanup actually runs + queries target the real tables (DB-bloat / OOM)** — `runAutoCleanup` was never scheduled, so retention cleanup never executed and tables (`compression_analytics`, `usage_history`, …) grew unbounded into multi-GB SQLite files driving high RSS. Worse, several cleanup queries referenced wrong table/column names (`call_logs.created_at`→`timestamp`, `compression_analytics.created_at`→`timestamp`, `mcp_audit_log`→`mcp_tool_audit`, `a2a_events`→`a2a_task_events`, `memory_entries`→`memories`), so even a manual run silently no-op'd or errored. Fixed the five queries to match the real schema, added `cleanupProxyLogs`, and wired a `startCleanupScheduler` (startup + every 6h, VACUUM after deletes) into `server-init` alongside the existing budget-reset and reasoning-cache jobs. ([#4691](https://github.com/diegosouzapw/OmniRoute/pull/4691), extracted from [#4428](https://github.com/diegosouzapw/OmniRoute/pull/4428) — thanks @oyi77 / @diegosouzapw)
2254
- **fix(routing): include all noAuth models in auto-combos + add reka-flash + best-free template** — noAuth provider models are no longer skipped when building auto-combos, `reka-flash` is registered, and a `best-free` combo template is added. ([#4621](https://github.com/diegosouzapw/OmniRoute/pull/4621) — thanks @oyi77)
2355
- **fix: noAuth provider validation + Kimi executor routing** — corrects noAuth provider membership checks and removes a mis-routed Kimi alias. (closes #4620) ([#4699](https://github.com/diegosouzapw/OmniRoute/pull/4699) — thanks @oyi77)
@@ -115,7 +147,7 @@
115147
- **fix(dashboard): migrate ManualConfigModal copy to the shared `useCopyToClipboard` hook** ([#4502](https://github.com/diegosouzapw/OmniRoute/pull/4502) — thanks @diegosouzapw)
116148
- **fix(sse): skip disabled providers in combo fallback** ([#4500](https://github.com/diegosouzapw/OmniRoute/pull/4500) — thanks @diegosouzapw)
117149
- **fix(usage): parse numeric-string quota reset timestamps as Unix sec/ms** ([#4493](https://github.com/diegosouzapw/OmniRoute/pull/4493) — thanks @diegosouzapw)
118-
- **fix(db): scheduled VACUUM + persist `lastVacuumAt`** — a new `vacuumScheduler.ts` persists the last run timestamp and last error to the `key_value` table (migration 102) and feeds the database settings panel; wired into the Next.js lifecycle (default 24h, window 02:00–04:00 local). New env flags: `OMNIROUTE_VACUUM_ENABLED`, `OMNIROUTE_VACUUM_INTERVAL_HOURS`, `OMNIROUTE_VACUUM_WINDOW`. ([#4480](https://github.com/diegosouzapw/OmniRoute/pull/4480) — thanks @KooshaPari / @oyi77)
150+
- **fix(db): scheduled VACUUM + persist `lastVacuumAt`** — a new `vacuumScheduler.ts` persists the last run timestamp and last error to the `key_value` table (migration 102) and feeds the database settings panel; wired into the Next.js lifecycle (default 24h, window 02:00–04:00 local). The initial env-flag control path from this entry is superseded in v3.8.34 by the Storage page settings. ([#4480](https://github.com/diegosouzapw/OmniRoute/pull/4480) — thanks @KooshaPari / @oyi77)
119151
- **perf(quota): stop writing redundant `quota_snapshots` rows from idle connections** — the 60s background refresh persisted a snapshot for every window of every connection regardless of change, generating 400K+ rows/day from idle accounts. `setQuotaCache` now skips the write when a window's `remaining_percentage`/`is_exhausted` is unchanged from the last cached observation; the first observation and every real change still persist. ([#4565](https://github.com/diegosouzapw/OmniRoute/pull/4565), [#4438](https://github.com/diegosouzapw/OmniRoute/issues/4438) — thanks @oyi77)
120152

121153
### 🔒 Security
@@ -1609,7 +1641,7 @@ And thank you to the OmniRoute community for the bug reports, reproductions, and
16091641
`tests/e2e/traffic-inspector.spec.ts`, `tests/e2e/agent-bridge-traffic-cross.spec.ts`
16101642
(skip-gated on CI by `RUN_AGENT_BRIDGE_E2E` / `RUN_TRAFFIC_INSPECTOR_E2E` / `RUN_CROSS_E2E`).
16111643
- **Documentation** — `docs/frameworks/AGENTBRIDGE.md` and `docs/frameworks/TRAFFIC_INSPECTOR.md`;
1612-
`docs/architecture/REPOSITORY_MAP.md` updated; `docs/reference/openapi.yaml` updated with
1644+
`docs/architecture/REPOSITORY_MAP.md` updated; `docs/openapi.yaml` updated with
16131645
~28 new routes and 20+ new schemas.
16141646
- **i18n:** translate Ukrainian (uk-UA) menu and UI strings, plus complete uk-UA UI coverage (#2981 / #2988 — thanks @Lion-killer)
16151647
- **providers:** add SiliconFlow endpoint selector (#2975 — thanks @xz-dev)

0 commit comments

Comments
 (0)