Releases: youssefvdel/qwen-gate
Releases · youssefvdel/qwen-gate
v0.5.1
What's Changed
Features
- Show unlock timestamp in throttle logs and API responses
Bug Fixes
- Auto-switch accounts on rate limit
- Non-streaming path now extracts local MCP tool calls
- Fix emittedToolCallCount index for concurrent tool call SSE events
- Remove prewarm pool + persist throttle across restarts
- Delete stale prewarmed sessions from Qwen servers
- Release session on stream timeout (chat leak)
- Remove top-level tools from Qwen payload to preserve full thinking
- Fix answer content lost with thinking_format=full
- Full thinking_format support with real-time reasoning_content streaming
- Remove timeout error message from client, silently terminate with [DONE]
- Dedup feature_config + switch thinking_format to full
- Delete Qwen session immediately after response (was 60s delay)
- Always write [DONE] on error paths, prevent SSE client hang
- Real error logging, thinking capture, upstream SSE error detection
Performance
- Skip filter pipeline when inside tool call block (depth > 0)
- Streaming parse optimization + sliding window fix
Refactor
- Remove dead toolResultContents field across pipeline
Tests
- Fix getAll test env var collision in CI
- Delete throttleAccount test that wrote test data to real accounts.json
CI
- Switch CI from setup-node/npm to oven-sh/setup-bun/bun
Chores
- Cleanup reports/docs, thinking format improvements
- Bump version to 0.5.1
v0.5.0
What's New in v0.5.0
Fixed
- Stream Idle Timeout Hang: Upstream silence no longer hangs the client indefinitely. Catches timeout gracefully, writes error SSE event +
[DONE], logs to dashboard. Default timeout 45s, configurable viaSTREAM_IDLE_TIMEOUT_MS. - Tool Call Content Leak: Streaming tool call XML fragments (
<function=,=filePath>,-edit) no longer leak into emitted content. UsestoolCallDepthstate counter + per-chunk detection. - Timing-Safe API Key: Config route now uses constant-time comparison (
safeCompare) for API key check. - Dashboard Script Injection: Fixed critical bug where
serveHtmlbroke all<script src="...">tags when injectingwindow.APP_VERSION.
Changed
- Data-Driven Stripping: All tag names centralized in
src/utils/tagNames.ts.TOOL_CALL_KEYWORDS,THINK_TAG_NAMES,TOOL_RESULT_KEYWORDSarrays drive regex construction in all stripping sites. No hardcoded regex patterns. - Deduplication: Think tag regex consolidated from 5 sites → 1 shared. Newline normalization unified everywhere. Removed 250+ lines of dead code (
json.ts,stripStreamingDelta,repairMalformedJson, unused re-exports). - Performance:
END_TAG_PATTERNShoisted to module-level.IDLE_TIMEOUT_MShoisted out of hot loop. Short-circuit guards added tocleanThinkTagsandparseXmlToolCalls. - Better Diagnostics: JSON parse errors log raw data. Stream errors captured in both console and dashboard log.
Full changelog: https://github.com/youssefvdel/qwen-gate/blob/v0.5.0/CHANGELOG.md
v0.4.0
Authentication & Account Management
- Refactored authentication to read tokens exclusively from Chromium browser profiles instead of cookie files (src/services/auth.ts, src/services/accountManager.ts)
- Removed cookie folder system -- no more qwen_profile/cookies/ directory fallback (src/services/accountManager.ts)
- Added browser profile authorization on account creation via openBrowserProfile before falling back to API login (src/services/accountManager.ts) (@studi929)
- Added loadCookiesFromProfile function to extract tokens from persistent Chromium profiles (src/services/auth.ts) (@studi929)
- Added parallel profile/cookie extraction at startup (batch 3 concurrent) with phased initialization (src/services/auth.ts)
- Added automatic cookie refresh from Chromium profile on every boot (src/services/browserProfiles.ts)
- Fixed refresh_token extraction and saving during profile-based auth (src/services/browserProfiles.ts, src/services/auth.ts)
- Fixed Token TTL showing 0 for session cookies from browser profiles (src/services/browserProfiles.ts)
- Added HOST config option for binding the server to a custom hostname (src/services/configService.ts)
- Added validation in ConfigService for PORT range and negative values for numeric config keys (src/services/configService.ts)
- Added warning on unknown config keys in config.json (src/services/configService.ts)
- Removed double inFlight increment in pickAccount() on the account manager side (src/services/accountManager.ts)
- Made pickAccount() async with mutex-guarded account selection and inFlight tracking (src/services/accountManager.ts)
- Made getTokenWithAccount() async to match async pickAccount() (src/services/accountManager.ts, src/services/playwright.ts)
- Fixed rate limiting on account add/delete endpoints (src/routes/accounts.ts) (@studi929)
- Replaced loginFresh call in account login route with openBrowserProfile + loadCookiesFromProfile (src/routes/accounts.ts) (@studi929)
- Updated manual login (autofill) flow to open non-headless browser and poll for auth completion (src/routes/accounts.ts) (@studi929)
- Added AES-256-GCM encryption for stored account passwords using API_KEY or machine-based key derivation (src/services/accountManager.ts)
- Added migrateFromOldPaths() to move accounts from qwen_profile/ to .qwen/ directory (src/services/accountManager.ts)
- Changed account watcher to watch .qwen/accounts.json instead of the old cookie directory (src/services/accountManager.ts)
- Added removeAccountContext and removeAccountContext to properly clean up Playwright contexts on account removal (src/services/playwright.ts, src/services/accountManager.ts)
- Added watcher retry logic with debounced timer for filesystem watch failures (src/services/accountManager.ts)
- Fixed getAccountByEmail to normalize email casing before lookup (src/services/accountManager.ts) (@studi929)
- Fixed silent autoFillLogin export removal -- removed unused function (src/services/browserProfiles.ts)
- Migrated all console.error/warn calls to logStore.log in auth-related services (src/services/loginHelpers.ts, src/services/tokenRefresh.ts, src/services/auth.ts, src/services/browserProfiles.ts, src/services/accountManager.ts) (@studi929)
- Fixed auth navigation to only clear specific auth cookies instead of ALL cookies (src/services/loginHelpers.ts) (@studi929)
- Added JSON response body token extraction in signin route interception (faster than set-cookie headers) (src/services/loginHelpers.ts) (@studi929)
- Replaced blind 2s sleep with polling loop (10 attempts, 500ms intervals) in temp context login (src/services/loginHelpers.ts) (@studi929)
- Reduced auth page timeouts from 30s to 20s and selector waits from 15s to 10s (src/services/loginHelpers.ts) (@studi929)
- Fixed loginFresh to try fetch-based login before browser-based login (src/services/auth.ts) (@studi929)
- Added autoLoginAllAccounts to run logins in parallel instead of sequential with delays (src/services/auth.ts)
- Removed loadSavedCookies function -- no longer reads from cookie files (src/services/auth.ts)
- Fixed saveCookies to write token persistence to .qwen/tokens/ directory instead of cookie files (src/services/auth.ts)
- Updated auth fallback in refreshAccountCookies to skip throttling when a valid token exists in memory (src/services/playwright.ts)
- Added JWT token injection as cookie in browser context during cookie refresh (src/services/playwright.ts)
- Changed cookie refresh interval from 30s to 120s with jitter (src/services/playwright.ts)
Dashboard & UI
- Removed API_KEY-based authentication from dashboard log, health, metrics, account stats, and config read endpoints (src/routes/dashboard/dashboardRoutes.ts)
- Added conditional bearer auth on admin-only endpoints (reload accounts, delete-all-chats) only when API_KEY is configured (src/routes/dashboard/dashboardRoutes.ts)
- Sanitized sensitive data in dashboard log entries -- mask emails, truncate large content, strip credentials (src/routes/dashboard/dashboardRoutes.ts)
- Exposed config without API_KEY value in the /api/config endpoint (src/routes/dashboard/dashboardRoutes.ts)
- Reformatted overview.css from single-line to multi-line with proper indentation (src/routes/dashboard/public/overview.css)
- Changed overview grid layout from 2fr 1fr to 3fr 2fr (src/routes/dashboard/public/overview.css)
- Added max-height: 100vh and max-height: 80vh constraints to panels and system logs container (src/routes/dashboard/public/overview.css, src/routes/dashboard/public/accounts.css)
- Added scrollable system logs container with overflow-y auto (src/routes/dashboard/public/overview.css)
- Fixed system logs to append new entries via insertAdjacentHTML instead of full innerHTML replacement (src/routes/dashboard/public/overview.js)
- Added notification dedup -- caps at 5 visible notifications at a time (src/routes/dashboard/public/overview.js)
- Added createPoller utility with exponential backoff on failures and pause-on-hidden (src/routes/dashboard/public/shared.js)
- Replaced all setInterval pollers with createPoller for adaptive polling across dashboard pages (src/routes/dashboard/public/overview.js, src/routes/dashboard/public/logs.js, src/routes/dashboard/public/accounts.js, src/routes/dashboard/public/network.js)
- Added toast limit to 5 on accounts page (src/routes/dashboard/public/accounts.js)
- Fixed login button state management -- removed stale setTimeout resets (src/routes/dashboard/public/accounts.js) (@studi929)
- Added active poll timer tracking to prevent duplicate pollAuth intervals (src/routes/dashboard/public/accounts.js)
- Removed API_KEY from logs page fetch headers and EventSource URL (src/routes/dashboard/public/logs.js)
- Added hidden entries buffer and Load More functionality for log entries (src/routes/dashboard/public/logs.js)
- Fixed network.js duration classification -- changed threshold from 3000ms to 500ms for slow (src/routes/dashboard/public/network.js)
- Added textarea support in settings form with proper styling and box-sizing (src/routes/dashboard/public/settings.css)
- Removed inline textarea styles in favor of CSS classes (src/routes/dashboard/public/settings.js)
- Moved Delete All Chats button to a separate Danger Zone section with warning styling (src/routes/dashboard/public/settings.js)
- Added confirmation modal for delete-all-chats with progress display (src/routes/dashboard/public/settings.js)
- Added error handling for delete-all-chats HTTP failures in the modal flow (src/routes/dashboard/public/settings.js)
- Added escape for single quotes and backticks in escHtml (XSS hardening) (src/routes/dashboard/public/shared.js)
- Changed modal visibility to use hidden CSS class instead of inline style.display (src/routes/dashboard/public/settings.js, src/routes/dashboard/settings.ts)
- Added toast limit cap on settings page (src/routes/dashboard/public/settings.js)
API & Streaming
- Added per-message size validation (100KB limit) to prevent OOM during token estimation (src/routes/chat.ts) (@studi929)
- Moved logIncomingRequest call removal -- no longer logs every request body (src/routes/chat.ts)
- Fixed pickAccount to be async in session setup, with proper decrementInFlight on acquire failure (src/routes/chat.ts) (@studi929)
- Added error type and code to error responses (src/routes/chat.ts) (@studi929)
- Fixed createQwenStreamWithRetry to forward toolChoice parameter (src/routes/chat.ts, src/routes/chatHelpers.ts) (@studi929)
- Fixed buildQwenMessages to serialize complex parameter values with JSON.stringify instead of String() (src/routes/chatHelpers.ts) (@studi929)
- Limited think/thought tag patterns in buildQwenMessages -- removed tool_call, tool_use, function_call, tool from think tag stripping (src/routes/chatHelpers.ts) (@studi929)
- Removed createLogEntry function -- consolidated into caller (src/routes/chatHelpers.ts)
- Fixed detectCumulativeChunk with multi-size fingerprint matching for robust delta detection (src/routes/chatHelpersCore.ts) (@studi929)
- Fixed getSnapshotDelta to handle cases where cleaned content becomes shorter than previous snapshot (src/routes/chatHelpersCore.ts) (@studi929)
- Restricted think tag patterns in cleanThinkTags -- only think, thinking, thought (removed tool_call, tool_use, function_call, tool) (src/routes/chatHelpersCore.ts) (@studi929)
- Added history trim to ToolSpamGuard to prevent unbounded growth (src/routes/chatHelpersCore.ts) (@studi929)
- Added periodic cleanup of pendingCorrections map (trim to 500 entries every 5 minutes) (src/routes/chatHelpersCore.ts) (@studi929)
- Made processToolCallsThroughGuard accept configurable maxToolCalls parameter (src/routes/chatHelpersCore.ts) (@studi929)
- Fixed non-streaming delta processing to only parse new content since last parsed position (src/routes/chatNonStreaming.ts) (@studi929)
- Added lastParsedPosition tracking in non-streaming processor (src/routes/chatNonStreaming.ts) (@studi929)
- Added handling for local_tool ph...
v0.3.1
v0.3.1 — XML Tool Calling & Install Fix
- Added XML tool call parser for Qwen's native
<function=name>format - New accounts get native tools/memory disabled on add
- Install script simplified: no pipes, no silent flags, always runs npm install
- Fixed raw.githubusercontent.com CDN cache issues via release tag
v0.3.0
v0.3.0 — Cleanup & Hardening
Removed
- Echo detection system — StreamingEchoFilter, ToolResultEchoFilter, and all related config keys
- XML stripping —
xmlStripper.tsdeleted; content passes through as-is - 12 stale test/data files (study captures, log replays, dead tests)
Changed
- Qwen request/response logging now respects
SAVE_REQUEST_LOGSflag (default: off) - Default MCP client name:
gateway→qwengate - System prompt no longer promises automatic stripping of artifacts
- Dashboard settings/logs UI cleaned of echo references
- Red ASCII art startup banner with green bullet points
Fixed
- All
tsc --noEmiterrors resolved createQwenStreamWithRetrytype mismatch (string → QwenMessage[]) — fixesmessages.map is not a functioncrashaislopscore: 95/100, zero source-tree findings
Tech
- Version bumped from 0.2.0 → 0.3.0
v0.2.0
[0.2.0] - 2026-06-04
Added
- Dashboard Web Interface: Complete vanilla HTML/JS dashboard with 5 pages (overview, logs, accounts, network, settings)
- Claymorphism Design: Warm cream/beige color palette with sage green accents (#F5F1EA bg, #5E9D5C accent)
- Unified Sidebar Navigation: Consistent navigation across all dashboard pages
- 12-Hour Time Format: All timestamps now display in 12-hour AM/PM format
- 100% Width Layout: Dashboard pages use full available width
- CLI Tool
qg: Command-line interface for account management (login, list, remove) - One-Command Install Script:
curl -sSL https://raw.githubusercontent.com/youssefvdel/qwen-gate/main/install.sh | bash - Network Debug Page: View outbound API calls with expandable detail panels
- System Logs Panel: Real-time system logs in overview dashboard
- Session Pool Dashboard: Live session utilization bar and model health table
Changed
- Dashboard Architecture: Replaced Astro+SolidJS with vanilla HTML/JS (no build step)
- Browser Automation: Migrated from Playwright to CloakBrowser for enhanced stealth
- Dashboard Styling: Applied Claymorphism design with soft shadows, 16px border radius, and Poppins typography
- Log Entry Layout: Two-column grid (70/30 split) with Raw/Processed Output side-by-side
- Chunk Stream: Fills 100% height with internal scroll, unfolds by default
- Network Page: Fixed JavaScript syntax errors (template literal escaping,
\n→\\n)
Fixed
- Thinking Emission Leak: Deferred thinking emission until after echo detection completes
- Token Waste: Abort upstream requests immediately on echo detection
- Streaming Delta Ordering: Fixed pattern ordering (B→C→A→D→E) with negative lookbehind
- Marker Leakage: Prevented
[READ TOOL RESULT]marker from appearing in user output - Tool Result Echo Filter: Integrated filter in streaming delta loop
- API Key Injection: Fixed template literal escape sequences in network page (
\'→"'") - Browser Profile Tracking: Added
.gitignorerules to exclude runtime browser profiles