Spaces:
Paused
Paused
Commit History
-
feat: add Test Connection diagnostic button (#63)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* feat: add Test Connection diagnostic button (#61) Add a "Test Connection" button to the Dashboard that runs 4 sequential checks (Server, Accounts, Transport, Upstream) and displays pass/fail/skip results with latency — helps Electron users diagnose connectivity issues without access to console logs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use socket address for localhost check, static import for buildHeaders - Replace spoofable x-forwarded-for/x-real-ip with getConnInfo() socket address for /debug/fingerprint and /debug/diagnostics endpoints - Add ::ffff:127.0.0.1 match for IPv4-mapped IPv6 addresses - Change dynamic import() of buildHeaders to static import Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>85a4cbd
-
feat: add Structured Outputs support (response_format → text.format)
icebear0828 +1: Claude Opus 4.6OpenAI response_format (json_object/json_schema) and Gemini responseMimeType/responseSchema now translate to Codex text.format. /v1/responses endpoint passes through text field as-is. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>53d3b3b -
fix: strict plan filtering in model-aware account routing
icebear0828 +1: Claude Opus 4.6When mixing free and team/plus accounts, requesting a plan-restricted model (e.g. gpt-5.4) could fall back to incompatible free accounts, causing HTTP 400 "model not supported". Now acquire() returns null instead of degrading to incompatible accounts when the model's plan requirements are known but no matching account is available. Also reduces model-fetcher initial delay from 5s to 1s to populate the plan map faster at startup. Fixes #54 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>be3d093 -
fix: let curl auto-negotiate Accept-Encoding for OAuth requests
icebear0828 +1: Claude Opus 4.6Remove the explicit Accept-Encoding header from curl-fetch.ts (used by OAuth and appcast requests only) and let --compressed auto-negotiate based on curl's actual decompression capabilities. This prevents error 61 on builds where curl lacks brotli/zstd support. Previously, the override only applied when !isImpersonate(), missing cases where curl-impersonate was available but lacked br/zstd libs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>b0a4fb7 -
fix: pass through cached_tokens from Codex API (#58)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* fix: pass through cached_tokens and reasoning_tokens from Codex API (#55) The proxy was only extracting input_tokens/output_tokens from Codex response usage, dropping input_tokens_details.cached_tokens and output_tokens_details.reasoning_tokens. This caused cached token counts to always show as 0 for downstream clients. Fixed across all three output formats (OpenAI, Anthropic, Gemini) in both streaming and non-streaming modes. Closes #55 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: pass reasoning_tokens through onUsage in Anthropic/Gemini translators The Anthropic and Gemini streaming translators were not forwarding reasoning_tokens via onUsage, unlike the OpenAI translator. Also fixes Gemini non-streaming path leaking cached_tokens: undefined by using conditional spread consistent with other translators. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com> Co-authored-by: Claud…fadda70 -
feat: model-aware multi-plan account routing (#57)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* feat: model-aware multi-plan account routing Different ChatGPT plans have different model access (e.g. Team has gpt-5.4, Free has gpt-oss-*). This adds plan→model mapping discovery and intelligent request routing to prevent model-not-supported errors. - model-store: track which plans can access each model via planMap - model-fetcher: query backend per distinct plan type in parallel - account-pool: model-aware acquire() prefers matching planType accounts - proxy-handler: auto-retry with different account on model-not-supported 4xx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: patch model-aware routing bugs from PR review - Fix double release when model retry has no available account - Tighten isModelNotSupportedError: add 4xx status guard, drop broad "invalid" keyword - Reuse selectByStrategy() in getDistinctPlanAccounts() instead of duplicated sort - Remove redundant triedEntryIds push Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-autho…90c89b6 -
fix: update model catalog — gpt-5.4/5.3-codex removed, gpt-5.2-codex is new flagship
icebear0828 +1: Claude Opus 4.6Backend dropped gpt-5.4, gpt-5.3-codex, gpt-5.3-codex-spark. New model list: gpt-5.2-codex (default), gpt-5.2, gpt-5.1-codex-max, gpt-5.1-codex, gpt-5.1, gpt-5-codex, gpt-5, gpt-oss-120b, gpt-oss-20b, gpt-5.1-codex-mini, gpt-5-codex-mini. - config/default.yaml: default model → gpt-5.2-codex - config/models.yaml: full rewrite matching backend /codex/models response - model-store.ts: isCodexCompatibleId() now matches gpt-oss-*, normalizeBackendModel() handles supported_reasoning_levels + effort key - codex-api.ts: getModels() adds ?client_version= (now required by backend) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>597668f -
feat: add force_http11 option for proxies without HTTP/2 support (#56)
Unverified signatureWhen using proxies like Clash/mihomo that don't support HTTP/2, users encounter errors like: "curl: (16) Remote peer returned unexpected data while we expected SETTINGS frame." This commit adds a `force_http11` config option to force HTTP/1.1 protocol in both curl CLI and libcurl FFI transports. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>34fceda
-
fix: version display picks higher of git tag vs package.json
icebear0828 +1: Claude Opus 4.6On master branch, `git describe --tags` may find an old tag (v0.8.0) since release tags live on the electron branch. Now both sources are compared and the higher version wins, so package.json's synced version (e.g. 1.0.16) is used correctly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>1b1294e -
feat: editable proxy_api_key from Dashboard settings panel
icebear0828 +1: Claude Opus 4.6Add GET/POST /admin/settings endpoints to read/write proxy_api_key in config/default.yaml with hot-reload. Dashboard gets a collapsible Settings panel with masked input, save, and clear key functionality. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>69a8388 -
fix: version display uses git tag + remove inline-grid layout hack
icebear0828 +1: Claude Opus 4.6- getProxyInfo() now tries `git describe --tags` first, falls back to package.json (skipping placeholder "1.0.0"), so git-mode users see the actual release version or just the commit hash - Replace all inline-grid overlay technique with simple whitespace-nowrap to fix two-line button text caused by invisible reference spans Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>66b06ea -
fix: Electron OAuth login + i18n layout shift + update modal (#53)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* fix: Electron OAuth login + i18n toggle layout shift + update modal 1. OAuth login fix for Electron: - Add focus/visibilitychange listeners to detect new accounts immediately when user switches back from system browser (bypasses Chromium throttling) - Track completed sessions server-side so code-relay returns success instead of "Invalid or expired session" after callback server handled it 2. i18n layout stability: - Push Star/Updates buttons from md to lg breakpoint to reduce crowding - Add inline-grid overlay to Star, Check for Updates, Proxy Settings buttons 3. Update modal: extract from Header into standalone UpdateModal component with auto-restart support (git mode spawns new process, frontend auto-refreshes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add polling guard + fix Star button inline-grid reference width - Add re-entrancy guard to checkForNewAccount (both shared/ and web/) to prevent concurrent fetches from rapid focu…1b6fb15 -
Merge pull request #52 from icebear0828/fix/oauth-direct-fallback
icebearUnverified signaturefix(auth): add direct-connection fallback for OAuth behind proxy8ab512c -
fix: use getRootDir() for package.json in self-update detection
icebear0828 +1: Claude Opus 4.6In Electron, process.cwd() points to the system directory instead of the app root, causing getProxyInfo() to return version "unknown". This made update detection always fail since "1.0.x" < "unknown" lexically. Add rootDir to PathConfig and getRootDir() helper so Electron can pass app.getAppPath() for correct package.json resolution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>504b471 -
fix(auth): add direct-connection fallback for OAuth behind proxy
icebear0828 +1: Claude Opus 4.6When a global proxy is configured, OAuth requests to auth.openai.com can fail due to Cloudflare challenges (403) or TLS/schannel errors. Since auth endpoints are not fingerprint-sensitive, we safely retry with a direct connection on these failures. - Add generic withDirectFallback() wrapper (src/tls/direct-fallback.ts) - Add proxyUrl pass-through to curlFetchGet/curlFetchPost - Fix Accept-Encoding for system curl (strip br/zstd like codex-api.ts) - Wrap all 4 OAuth functions with direct-connection fallback Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>abe58f1 -
fix: semver comparison + timer cleanup in self-update
icebear0828 +1: Claude Opus 4.6- Use localeCompare with numeric option instead of string equality for version comparison (prevents false "update available" on rollbacks) - Add .unref() to setTimeout/setInterval to not block process exit - Add void to fire-and-forget runCheck() calls Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>2fac785 -
feat: auto-release pipeline + multi-mode update system + commit hash display
icebear0828 +1: Claude Opus 4.6- sync-electron.yml: auto bump patch version + create tag after merge, concurrency group - release.yml: replace CHANGELOG extraction with GitHub auto-generated release notes - self-update.ts: support git/docker/electron deploy modes, GitHub Releases API, periodic checker - Header: show commit hash in status badge, expandable update panel with changelog - use-update-status: add applyUpdate, mode/commits/release fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>0c2aed2 -
fix: preserve model name suffixes (-fast, -high, etc.) in API responses
icebear0828 +1: Claude Opus 4.6Response model name was losing suffixes because it used the stripped base model ID from parseModelName() instead of reconstructing with suffixes. Also adds `none` to EFFORT_SUFFIXES (gpt-5.4 supports none reasoning). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>bc98e69
-
fix: strip service_tier from request body + add OpenAI-Beta header + update gpt-5.4 efforts
icebear0828 +1: Claude Opus 4.6- Codex backend rejects service_tier in request body ("Unsupported service_tier: fast"). Desktop app handles Fast mode at app-server level, not via the API. Proxy now strips service_tier before sending to backend. - Add OpenAI-Beta: responses_websockets=2026-02-06 header (matching Desktop binary). - Update gpt-5.4 reasoning efforts: minimal→none, add xhigh (matching backend). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>44b20f4 -
docs: add comment explaining stream:true hardcoding in responses route
icebear0828 +1: Claude Opus 4.6Codex API only supports streaming, so the proxy always sends stream:true upstream and uses collect mode to assemble JSON for non-streaming clients. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>d7a5e25 -
feat: /v1/responses passthrough endpoint + missing SSE event types + Docker docs fix (#37, #38)
icebear0828 +1: Claude Opus 4.6- Add /v1/responses endpoint for raw Codex Responses API passthrough with multi-account load balancing, no format translation - Recognize response.output_item.done, response.incomplete, response.queued SSE events to eliminate "Unknown event" debug log noise - Add cp .env.example .env step to Docker quick start in README Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>8068f1c
-
feat: model name suffix system + service_tier + Docker persistence fix (#35)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* feat: model name suffix system + service_tier (fast mode) support Add a unified model name suffix convention so CLI tools (Claude Code, opencode, etc.) can control reasoning effort and speed mode purely through the model name — no extra API fields needed. Suffix parsing (`parseModelName`): - `-fast` / `-flex` → `service_tier` - `-minimal` / `-low` / `-medium` / `-high` / `-xhigh` → `reasoning_effort` - Known model IDs and aliases are never suffix-parsed - Priority: explicit API field > suffix > model default > config default Backend: - `parseModelName()` in model-store.ts (core suffix resolver) - `service_tier` field in Zod schema + CodexResponsesRequest interface - `default_service_tier` in config schema + default.yaml - All 3 translation layers (OpenAI/Anthropic/Gemini) use parseModelName() Dashboard: - Standard / Fast speed toggle in ApiConfig - AnthropicSetup shows compound model name with suffixes - CodeExamples builds compound model name, suppresses redundant params Exampl…5416ffb -
feat: proxy assignment management page with bulk operations (#34)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* feat: proxy assignment management page with bulk operations Add dedicated page (#/proxy-settings) for managing proxy assignments across hundreds of accounts with matrix-style dual-column layout: - Left sidebar: proxy group list with counts, search, click-to-filter - Right panel: paginated account table (50/page) with search, status filter, Shift+click range select, per-row proxy dropdown - Bulk actions: batch assign to proxy, round-robin even distribute, rule-based assignment modal - Import/export: download JSON assignments, upload with diff preview - Hash routing (zero-dependency), Header navigation links - Backend: 6 new bulk API endpoints + ProxyPool.bulkAssign() - i18n: 35 new translation keys (en + zh) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR review issues in proxy assignment feature - Make accountPool required param (was optional but always passed) - Extract isValidProxyId() helper to eliminate duplicated validation - Add resp.ok checks…f878eff -
fix: update checker shows correct status + version display + dark mode fixes
icebear0828- Fix 'Up to date' shown incorrectly when Codex version changed (add version_changed field) - Change update status text from <span> to clickable <button> - Add proxy version number next to 'Server Online' badge - Fix dark mode for ProxyPool form inputs and AccountCard proxy selector - Add fingerprintUpdating translation key (zh/en)3cf831b -
feat: proxy pool add form with separate protocol/host/port/auth fields
icebear0828 +1: Claude Opus 4.6Replace single URL input with structured fields (protocol dropdown, host, port, username, password) for easier configuration of authenticated proxies. Backend still accepts raw url for API compat. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>af3e19d -
fix: remove wall-clock timeout from streaming SSE to prevent thinking chain cutoff
icebear0828 +1: Claude Opus 4.6The 60s --max-time timeout was killing curl mid-stream during long reasoning/thinking outputs (30-120+ seconds). Streaming requests now rely on header timeout + AbortSignal for protection instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>ffcac87 -
fix: proxy pool review fixes — security, validation, robustness
icebear0828 +1: Claude Opus 4.6- Skip disabled proxies in healthCheckAll (avoid unnecessary network calls) - Validate proxy URL scheme (only http/https/socks5/socks5h allowed) - Deduplicate proxy URLs on add (return existing ID if URL already exists) - Mask proxy credentials server-side via getAllMasked() (remove client-side maskUrl) - Add try-catch to all use-proxies hook operations (prevent unhandled rejections) - Fix misleading route ordering comment in proxies.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>deae086 -
feat: add proxy pool for per-account proxy routing
icebear0828 +1: Claude Opus 4.6Add proxy pool system allowing different accounts to route through different upstream proxies for IP diversity and risk isolation. Backend: - ProxyPool manager with CRUD, assignment, round-robin, health checks - TlsTransport interface accepts per-request proxyUrl parameter - Both curl-cli and libcurl-ffi transports support per-request proxy - CodexApi forwards proxy through the request chain - REST API at /api/proxies for proxy + assignment management - Periodic health checks (default 5min) via api.ipify.org Frontend: - ProxyPool management section in dashboard - Per-account proxy selector dropdown in AccountCard - Four assignment modes: Global/Direct/Auto(Round-Robin)/Specific Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>4ebb914 -
feat: GitHub Star badge + check-for-updates in dashboard header
icebear0828 +1: Claude Opus 4.6- Header: ⭐ Star badge linking to GitHub repo (amber pill style) - Header: 🔄 Check for Updates button with status display - Checks both proxy self-update (git fetch/pull/build) and Codex fingerprint (appcast) - CLI: auto git pull + npm install + build, prompt restart - Docker: fingerprint auto-update, proxy shows manual rebuild hint - Electron: version display only, managed by desktop app - New endpoints: GET /admin/update-status, POST /admin/check-update - Footer: version info (proxy commit + Codex Desktop version) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>06a5304
-
fix: move /v1/models/catalog route before :modelId param route
icebear0828 +1: Claude Opus 4.6Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>2b84f47 -
feat: add gpt-5.4 + codex-spark support, matrix model selector, extended reasoning efforts
icebear0828 +1: Claude Opus 4.6- Add gpt-5.4 (4 efforts: minimal/low/medium/high) and gpt-5.3-codex-spark (minimal/low) to models.yaml - Update codex alias to gpt-5.4 - Generalize isCodexModelId → isCodexCompatibleId to match bare gpt-X.Y models - Add /v1/models/catalog endpoint returning full CodexModelInfo[] with reasoning efforts - Replace flat model dropdown with family × reasoning effort matrix selector in dashboard - Add reasoning_effort to code examples when non-default effort is selected - Bump client to v26.305.950 (build 863) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>7824fcd -
fix: auto-admit new Codex models from backend API
icebear0828 +1: Claude Opus 4.6Previously applyBackendModels() filtered out any model not in the static YAML catalog. New Codex releases (e.g. gpt-5.4-codex) were silently dropped. Now models matching gpt-*-codex* pass through. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>5b8472d -
fix: remove unsupported previous_response_id parameter (#30)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* fix: remove unsupported previous_response_id parameter (#29) The Codex backend no longer accepts `previous_response_id`. Sending it causes HTTP 400: "Unsupported parameter: previous_response_id". Remove the injection logic in proxy-handler and clean up related dead code across translation functions and session manager. Closes #29 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: remove dead SessionManager (was only used for previous_response_id) SessionManager, session hashing, and onResponseId session storage were only used to track previous_response_id across turns. Since the backend no longer supports this parameter, the entire session system is dead code. Remove it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: icebear0828 <icebear0828@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>3c0eaf7
-
refactor: extract startServer() + path abstraction for Electron reuse
icebear0828 +1: Claude Opus 4.6- Export startServer(options?) from src/index.ts so Electron can import it - Add src/paths.ts: centralized path getters (getConfigDir, getDataDir, etc.) with setPaths() hook for Electron to redirect to userData - Replace all process.cwd() calls with path getters across src/ - Extract shared/ from web/ (i18n, theme, hooks, utils) for desktop reuse - Add /desktop route in web.ts (serves desktop UI if built, no-op otherwise) CLI behavior is unchanged — all path getters default to process.cwd(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>4a940a5 -
feat: add reasoning/thinking output support for OpenAI and Anthropic routes
icebear0828 +1: Claude Opus 4.6- Always send `summary: "auto"` to Codex API so reasoning summaries are available - Parse `response.reasoning_summary_text.delta/done` SSE events - OpenAI route: emit `reasoning_content` in chunks when client sends `reasoning_effort` - Anthropic route: emit thinking blocks when client sends `thinking.type: enabled/adaptive` - Extract block lifecycle helpers in Anthropic translator to eliminate duplication - Log unknown SSE events via console.debug for discovering new event types Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>7366e72 -
fix: Anthropic route thinking blocks validation + context token display
icebear0828 +1: Claude Opus 4.6- Add thinking/redacted_thinking to Anthropic content block schema (fixes /compact 400 error with extended thinking history) - Include input_tokens in message_delta usage (fixes Claude Code always showing 0% context) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>be3a571 -
fix: support thinking/redacted_thinking content blocks in Anthropic schema
icebear0828 +1: Claude Opus 4.6Claude Code /compact sends conversation history containing thinking and redacted_thinking content blocks which were rejected by the Zod schema. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>ca7b1cb -
feat: add image input support for all API routes
icebear0828 +1: Claude Opus 4.6Previously all image content was silently discarded by the translation layer. Now image_url (OpenAI), image/base64 (Anthropic), and inlineData (Gemini) content parts are translated to Codex input_image format and passed through to the backend. Closes #25 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>142c9c4
-
fix: normalize tool schemas missing `properties` field
icebear0828 +1: Claude Opus 4.6MCP tools with no parameters send `{"type":"object"}` without a `properties` key. The Codex/OpenAI backend strictly requires it, returning 400. Add a shared `normalizeSchema()` helper that injects `properties: {}` when missing, applied consistently across all four format converters (OpenAI tools, OpenAI functions, Anthropic, Gemini). Thanks to @lookvincent for identifying this issue (PR #22). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>2df0167 -
fix: window counter review issues — opacity modifier, catch-up spam, rounding
icebear0828 +1: Claude Opus 4.6- text-dim color uses <alpha-value> interpolation so dark:text-text-dim/70 works - Multi-window catch-up jumps to correct window in one step (no log spam) - formatWindowDuration uses Math.floor instead of Math.round Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>247b874 -
feat: add per-window usage counters with time-driven reset
icebear0828 +1: Claude Opus 4.6Dashboard previously showed cumulative token counts that never reset when the rate limit window rolled over. Now tracks per-window request/token counters that auto-reset via two layers: - Layer 1 (time-driven): refreshStatus() checks window_reset_at on every acquire/getAccounts call, zero API overhead - Layer 2 (backend sync): syncRateLimitWindow() corrects with actual backend values on Dashboard refresh Also syncs limit_window_seconds from backend and displays window duration badge (e.g. "3h") next to plan name in AccountCard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>4f2220c
-
fix: stop resetting local usage counters on rate limit window rollover
icebear0828 +1: Claude Opus 4.6syncRateLimitWindow() was zeroing request_count, tokens, and empty_response_count whenever the backend rate limit window changed. This caused the dashboard to show 0 requests/tokens while the backend quota still reported usage (e.g. 50% used), because the two data sources are independent. Local counters now accumulate since account creation; users can still manually reset via the API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>9d65acf
-
feat: add per-account empty response tracking with email in logs
icebear0828 +1: Claude Opus 4.6Track empty_response_count per account in AccountUsage, exposed via GET /auth/accounts. Logs now include account email for easier debugging. Counter resets on usage reset and rate limit window rollover. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>b3dfc6c -
fix: detect empty Codex responses and auto-retry with account rotation (#18)
icebear +2: icebear0828, Claude Opus 4.6Unverified signature* fix: detect empty Codex responses and auto-retry with account rotation Codex API intermittently returns HTTP 200 with valid SSE events but zero text deltas. Add EmptyResponseError detection in all three translation layers (OpenAI, Anthropic, Gemini) and a retry loop in proxy-handler that switches accounts on empty responses (up to 3 attempts). - Non-streaming: catch EmptyResponseError → release account → acquire new account → retry with fresh CodexApi (max 2 retries) - Streaming: inject "[Error] Codex returned an empty response" text chunk when response.completed fires with no content - All retries exhausted → 502 with clear error message Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: prevent double-release of account in empty-response retry loop The outer catch block used the original entryId, which was already released when EmptyResponseError switched to a new account. Introduce activeEntryId to track the currently-active account across retries. Also set Em…9d6278d -
chore: deduplicate model selector, auto-extract chromium version, harden update pipeline
icebear0828 +1: Claude Opus 4.6- Remove independent model dropdown from Anthropic SDK Setup; use shared Default Model from API Configuration - Auto-extract Chromium version from Electron via electron-to-chromium in extract-fingerprint - Add 5-min timeout kill timer for full-update child process to prevent permanent lock - Add try/finally in model-fetcher initial timer to prevent refresh loop interruption - Bump Codex Desktop to v26.228.1430 (build 760) - Update poll interval from 30min to 3 days Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>8728276 -
fix: harden prompt injection suppression and non-streaming error handling
icebear0828 +1: Claude Opus 4.6Strengthen SUPPRESS_PROMPT to prevent mini models from leaking Codex Desktop identity. Wrap collectTranslator in try/catch to return 502 JSON instead of 500 HTML on non-streaming errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>2def35e -
fix: filter non-Codex models from backend to prevent resolveModelId fallback breakage
icebear0828 +1: Claude Opus 4.6Backend model fetch returns ChatGPT-only slugs (gpt-5-2, gpt-5-1, etc.) that the Codex Responses API doesn't accept. Now only models already in the static YAML catalog are merged from the backend. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>eea9e24 -
fix: handle error SSE events from Codex API instead of silently dropping them
icebear0828 +1: Claude Opus 4.6When the Codex API returns `event: error` or `event: response.failed`, the proxy now surfaces the error message to clients instead of returning empty responses. Also detects non-SSE JSON error bodies from upstream. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>cf0807a
-
fix: support thinking.type "adaptive" for latest Claude Code
icebear0828 +1: Claude Opus 4.6Claude Code now sends thinking.type: "adaptive" (with optional budget_tokens) instead of always "enabled"/"disabled". Added the new variant to the Zod schema and translation logic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>be3ca8e
-
fix: Docker container auto-detect host proxy via host.docker.internal
icebear0828 +1: Claude Opus 4.6Docker containers can't reach host proxies on 127.0.0.1 (container loopback). Now probes both 127.0.0.1 and host.docker.internal so Docker users get automatic proxy detection without any configuration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>d7d7389