- Add emailPrivacyStore (Zustand + persist) for global toggle state
- Add EmailPrivacyToggle component with eye open/closed icons
- Add pickDisplayValue() visibility-aware masking function
- Integrate toggle into provider detail, usage limits & playground pages
- Per-modal showEmail now uses global store (synced across all pages)
- Default: emails hidden; toggle persists across page reloads
- Add showEmails/hideEmails i18n keys
- Update CHANGELOG.md and openapi.yaml to v3.6.2
* fix(minimax): switch auth from x-api-key to Authorization Bearer (#1076)
Integrated into release/v3.5.6 — MiniMax auth fix with authHeader consistency normalization
* feat(CI,i18n): autogenerate language files + Add missing strings (#1071)
Integrated into release/v3.5.6 — i18n translations for memory, skills, and missing keys across 31 languages
* fix(ci): restore i18n continue-on-error, remove auto-commit race condition
* fix(husky): load nvm in hooks for VS Code compatibility
* fix(husky): gracefully skip hooks when npm is not in PATH
* fix: convert OpenAI function tool_choice to Claude tool format (#1072)
* fix: prevent EPIPE feedback loop filling logs at GB/s (#1006)
* fix: fallback to native fetch when undici dispatcher fails (#1054)
* fix: improve Qoder PAT validation with actionable error messages (#966)
- Add QODER_PERSONAL_ACCESS_TOKEN env var fallback for both validation and execution
- Pre-flight ping check to diagnose connectivity issues (Docker/proxy)
- Detect encrypted auth blobs from ~/.qoder/.auth/user and guide to website PAT
- Clear error messages for auth failures with link to integrations page
- Treat non-auth 4xx as auth-pass (request format issue, not token issue)
- Update tests to cover new validation paths (23 tests, all passing)
* feat: Improve the Chinese translation (#1079)
Integrated into release/v3.5.6
* chore(release): v3.5.6 — i18n updates and credential security fixes
* fix(ci): resolve e2e and docs-sync pipeline failures
* fix(security): bump next to 16.2.3 to resolve SNYK-JS-NEXT-15954202
* fix: guard Memory/Cache UI against null toLocaleString crash (#1083)
* fix: translate OpenAI tool_choice type 'function' to Claude 'tool' format (#1072)
* fix: pass custom baseUrl in provider API key validation (#1078)
* docs: update CHANGELOG with v3.5.6 bug fixes and security patches
* docs: rewrite implement-features workflow with 5-phase harvest-research-report-plan-execute pipeline
* docs: organize _ideia/ into viable/defer/notfit + add Phase 2.5 auto-response workflow
* docs: implementation plans for #1025, #750, #960, #1046 + close already-implemented #833, #973, #982
* feat: mask email addresses in dashboard for privacy (#1025)
* feat: add OpenRouter and GitHub to embedding/image provider registries (#960)
* feat: add model visibility toggle and search filter to provider page (#750)
* docs: move implemented features to notfit, update task plans status
* chore: untrack _ideia/ and _tasks/ from git — private/internal only
* chore(release): bump to v3.5.6 — changelog, docs, version sync & any-budget fix
* fix: remove explicit .ts extension in qoderCli import that caused 500 error in production build
---------
Co-authored-by: Jean Brito <jeanfbrito@gmail.com>
Co-authored-by: zenobit <zenobit@disroot.org>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: Ethan Hunt <136065060+only4copilot@users.noreply.github.com>
When running OmniRoute with Node.js >=24, the better-sqlite3 native module
fails to load, causing a confusing 'not a valid Win32 application' or
'Module did not self-register' error at the login screen.
This change adds proactive Node.js version detection:
- API: /api/settings/require-login now returns nodeVersion and nodeCompatible
fields, computed before any SQLite access so they work even when the DB fails
- UI: A prominent red warning banner appears on the login page when an
incompatible Node.js version is detected, showing the current version and
instructions to install Node 22 LTS via nvm
- i18n: Added 4 new translation keys for the warning banner
Closes#1060, Closes#1040
- Fix SSRF (CodeQL #73): sync-models route uses localhost allowlist instead of
user-provided request.url to construct internal fetch target
- Fix insecure randomness (CodeQL #33,#34): already fixed in geminiHelper.ts
using crypto.randomBytes, stale alerts will close on rescan
- Fix incomplete URL sanitization (CodeQL #109,#110): already fixed with
startsWith in previous commit, stale alerts will close on rescan
- Fix incomplete hostname regexp (CodeQL #103-108): already fixed with escaped
dots in previous commit, stale alerts will close on rescan
- Fix Dependabot #50-55: override hono@4.12.12 and @hono/node-server@1.19.13
to patch cookie bypass, IP restriction, path traversal, and serveStatic
middleware bypass vulnerabilities
- Fix CI: update context-manager test expectation from 1000000 to 1048576 to
match registry defaultContextLength for gemini
- Fix CI: sync-models route now correctly resolves localhost origin from
incoming request for test compatibility
- CRITICAL: Fetch old settings BEFORE update in PATCH handler to correctly
compare wasEnabled vs isEnabled for sync lifecycle management
- CRITICAL: Handle modelsDevSyncInterval changes (restart periodic sync with
new interval when it changes)
- MEDIUM: Add error logging and user feedback to useEffect catch
- MEDIUM: Add revert logic to updateInterval on API failure
Fixes all 3 review comments from Gemini Code Assist on PR #983
- Add models.dev sync engine (src/lib/modelsDevSync.ts) for pricing, capabilities, and model specs
- Fetch from https://models.dev/api.json (109 providers, 4,146+ models, MIT licensed)
- 4-layer pricing resolution: User Override > models.dev > LiteLLM > Hardcoded Default
- New model_capabilities DB table for synced capability data
- UI toggle in Settings > AI tab: enable/disable sync, configure interval (1h-7d), manual sync trigger
- Live stats dashboard showing provider/model/capability counts
- New API route /api/settings/models-dev for sync status and manual triggers
- Fix 39 missing i18n keys across all 30 languages (Memory & Skills tab fully translated)
- 25 unit + integration tests, 1,439 existing tests pass, lint clean, typecheck clean
Closes#979
The hardcoded BUFFER_TOKENS = 2000 constant inflates prompt_tokens and
input_tokens in every API response, which is helpful for CLI tools that
rely on reported usage to manage context windows but misleading for SDK
users, cost dashboards, and any integration comparing token counts
across providers.
This change makes the buffer configurable via three layered sources
(in priority order):
1. Environment variable: USAGE_TOKEN_BUFFER=0
2. Settings API / Dashboard: PATCH /api/settings { usageTokenBuffer: 0 }
3. Default: 2000 (preserves existing behavior)
Setting the value to 0 disables the buffer entirely, causing OmniRoute
to return raw provider token counts. The setting is cached in-process
with a 30-second TTL and invalidated immediately when updated through
the settings API.
Changes:
- open-sse/utils/usageTracking.ts: replace hardcoded constant with
getBufferTokens() that reads env / DB settings with TTL cache
- src/shared/validation/settingsSchemas.ts: add usageTokenBuffer field
(int, 0–50000) to the Zod update schema
- src/app/api/settings/route.ts: invalidate buffer cache on update
- Add proxy support to all OAuth flows (authorization, token exchange, import)
- Add proxy support to token refresh operations for all providers
- Add proxy support to model synchronization
- Initialize global fetch proxy patch at server startup
- Use Proxy Registry with priority: Provider Proxy → Global Proxy → Direct
- Fix Global Proxy display in settings UI to show proxy from Proxy Registry
Changes:
- open-sse/services/tokenRefresh.ts: Add proxyConfig parameter to all refresh functions
- src/sse/services/tokenRefresh.ts: Resolve proxy before calling refresh functions
- src/app/api/oauth/*/route.ts: Use resolveProxyForProvider for OAuth flows
- src/app/api/providers/[id]/models/route.ts: Add proxy support for model sync
- src/instrumentation-node.ts: Initialize proxy patch at startup
- src/app/api/settings/proxy/route.ts: Read Global Proxy from Proxy Registry
- src/lib/db/proxies.ts: Export resolveProxyForProvider
- src/lib/localDb.ts: Re-export resolveProxyForProvider
- src/models/index.ts: Re-export resolveProxyForProvider
15 files changed, 405 insertions(+), 240 deletions(-)
Co-authored-by: growab <growab@users.noreply.github.com>
Stability fixes for the Gemini provider — no new features:
- Map SAFETY/RECITATION/BLOCKLIST finish reasons (gemini-to-openai → content_filter)
- Add 15s per-page timeout on models sync pagination to prevent indefinite hangs
- Fix mime_type → mimeType in inlineData to match Gemini v1beta API (camelCase)
- Fix include_thoughts → includeThoughts to match Gemini API (camelCase)
- Add inlineData/mime_type fallback in gemini-to-openai request translator
Google AI Studio defaults to 50 models per page. Set pageSize=1000
to maximize per-page results and follow nextPageToken to fetch all
available models across pages. Also fixes query param separator when
base URL already contains query string.
- Show import progress dialog when adding Gemini API key with model
list, completion status, and Close button
- Remove hardcoded Gemini model registry — models come exclusively
from Google API sync per API key
- Hide "Import from /models" button for Gemini (sync handles it)
- Remove server-side fire-and-forget auto-sync (client handles it)
- Categorize synced Gemini models by endpoint type in catalog:
embedding, image, and audio (transcription + speech)
- Add modelsImported and close i18n keys to all 33 languages
Removed hardcoded registry fallback for Gemini in dashboard, catalog,
and v1beta endpoints. Without synced models (no API keys), Gemini shows
nothing. Hardcoded entries are always removed from v1beta regardless
of sync result.
Store synced models keyed by providerId:connectionId so each API key's
models are tracked separately. On read, union across all connections.
On connection delete, remove only that key's models. Models with no
remaining connections are automatically excluded.