Skip to content

Update ghcr.io/james-6-23/codex2api Docker tag to v3.1.1 - #7965

Open
renovate[bot] wants to merge 1 commit into
localAppsfrom
renovate/ghcr.io-james-6-23-codex2api-3.x
Open

renovate[bot] wants to merge 1 commit into
localAppsfrom
renovate/ghcr.io-james-6-23-codex2api-3.x

Conversation

@renovate

@renovate renovate Bot commented Oct 22, 2026

Copy link
Copy Markdown

This PR contains the following updates:

Package Update Change
ghcr.io/james-6-23/codex2api minor 3.0.8 → 3.1.1

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Release Notes

james-6-23/codex2api (ghcr.io/james-6-23/codex2api)

v3.1.1

Compare Source

Features
  • Accounts can be checked for degraded answers on a schedule (#​790, @​OneAHPro). The new Intelligence Check page (/admin/intelligence-check) sends questions from an admin-maintained bank to a specific GPT/Codex, Responses relay or Claude account, manually or on an interval. Grok and Antigravity are not supported yet. Each question has an expected answer, matched exactly, by substring or by regex, and an optional latency limit. Checks reuse the account's request executor, identity, fingerprint and timezone, and go through the account's bound proxy only: they connect directly when none is bound and never fall back to direct when the bound proxy fails. A failed request is recorded as an error, separately from a wrong answer, and does not count toward the pass rate. After a configurable number of consecutive failures the account can be paused for dispatch or moved to another group, and it is restored once checks pass again. Only pauses and group changes made by the check are undone, and a manual change to the account cancels them. The account table, cards and details show the last 20 results next to the health bar, and a paged history (200 runs per account by default) keeps the question, judging config, final output and actions. Runs use a durable SQLite/PostgreSQL queue with leases, per-account deduplication and a shared concurrency limit. Automatic checks are off by default and existing accounts are opted out; new accounts are opted in but still need the global switch. Checks consume upstream quota and are logged with the internal source intelligence_check.

  • Responses keeps native request semantics, and Responses WebSocket connections run independent streams in parallel (#​788, @​dundunge). The Responses relay now keeps reasoning.effort, text.format, JSON Schema constraints and large integers as sent, and native fields take precedence over compatibility aliases such as reasoning_effort and response_format. An opt-in strict mode, enabled per request with X-Codex2API-Strict-Compatibility: true or globally with CODEX_STRICT_RESPONSES_COMPAT=true, rejects fields and tool or output schemas that the native Codex path would drop or rewrite with 400 unsupported_feature, listing them in error.details.fields. It checks against the native Codex account actually selected, so relay accounts are not blocked, and uses response.failed once SSE is committed and an error frame on WebSocket. On GET /v1/responses, response.create frames keep FIFO order within the default stream and within each stream_id, while different streams run in parallel: up to 16 active turns and 32 named streams per connection, with bounded queues. A request failure on one named stream no longer closes the other healthy streams. A connection can also continue from a store:false response committed on another of its own streams, with the same API key, group, account and credential isolation as before. Probed experimental_supported_tools are stored and the Codex model manifest advertises the intersection across the accounts a key can reach. response.append and response.steer return unsupported_feature. See docs/RESPONSES_COMPATIBILITY.md.

  • Antigravity publishes Gemini 4 Argon in three thinking tiers. Once an account's catalog contains the gemini-4-argon-high backing, the gateway publishes gemini-4-argon-low, -medium and -high, mapped to named thinkingLevel values; the bare gemini-4-argon alias defaults to high. /v1/messages now folds bare Antigravity logical model names into their fixed tier before key limits and account selection, while relay accounts keep the logical name. The Codex model manifest shows Argon as a single choice with per-key reasoning levels and a 1,048,576-token context window. Disabled catalog placeholders such as gemini-4-argon-disabled stay visible in the admin catalog with a disabled overlay, but they are never advertised, scheduled or picked for connection tests, and a batch test that only finds disabled models no longer marks the account as errored. Catalog models without quota metadata show an unknown quota instead of an invented remaining percentage. Argon generation has not been verified against a live Ultra account.

  • Antigravity Workspace and enterprise accounts can use their own Google Cloud project. Google only provisions a managed Cloud Code project for consumer tiers, so Workspace accounts on Gemini Code Assist Standard or Enterprise finished onboarding without a project and could not be dispatched. The Antigravity edit dialog gains a GCP project ID field (user_project_id, stored as antigravity_user_project_id). The project is sent to loadCodeAssist and, for non-free tiers, onboardUser, and saving it resyncs the account immediately. Projects returned by Google still take precedence, and the free tier never receives the user project because naming one there fails with FAILED_PRECONDITION. When onboarding ends without a project, the error now says whether the tier requires a caller-owned project and how to set it.

  • The unsupported-model cooldown is configurable, and an exhausted pool reports the real error. The new setting oauth_unsupported_model_cooldown_seconds (default 1800, range 0–1800, 0 disables) controls how long an account stops serving a model after upstream answers "model is not supported when using Codex with a ChatGPT account". Other models and the account's health are unaffected: the 400 no longer counts as an account failure. Lowering or disabling the cooldown clears existing ones longer than the new value. Responses, Chat Completions and Messages clients no longer get a 503 "no available accounts" for this case: when the last attempt failed with the 400, the upstream error is passed through, and when every eligible account is cooling down for it, the 400 (code model_not_supported) names the model and the earliest recovery time.

Fixes
  • gpt-6.1-sol no longer fails on every plan with "not supported when using Codex with a ChatGPT account" (#​793, reported by @​syunnrai123). Upstream returns the same 400 when the plan lacks a model and when the outbound client version is below the model's real minimum. gpt-6.1-sol declares minimal_client_version 0.153.0 but only appears in the models manifest from 0.159.0, so the bundled 0.153.3 was rejected everywhere and the gateway cooled each account down as if its plan were the problem. The bundled Codex CLI version and the codex_min_cli_version default for new installations move to 0.160.0, and official 0.160.0 Desktop and VSCode pairs are added so those User-Agent kinds clear the gate without a sync. When a Pro-tier account (Spark excluded) reports the error, it is treated as a version gate: no cooldown is written, and lower-tier failures with the same model and outbound version are not cooled down either for 30 minutes. A client-version sync that stores a newer version clears existing model_not_supported cooldowns, including through the legacy CLI-only sync endpoint. The outbound version is logged on these failures, and gpt-6.1-sol is marked as unavailable for API-key auth like the rest of GPT-6.

  • Credit override now actually serves traffic while quota auto-pause is configured (#​791, reported by @​xiaobulv). The account dialog showed credit override as active while the account received no requests. Auto-pause thresholds cap at 100%, so any account, group or global 5h or 7d auto-pause stopped dispatch before the window could run out and switch to credits, and the list still showed the "using credits" badge. While credits are covering, auto-pause and the 5h guard band (concurrency clamp and dispatch penalty) now step aside; they apply again once credits run out or a workspace hard stop lands. Turning credits on also releases a premium 5h penalty (rate_limited_5h) recorded from response headers or WHAM, not only the 7d one. Real /responses 429s are recorded under a separate reason and still apply.

  • Antigravity Gemini tool loops no longer fail with "Function call is missing a thought_signature" (#​792, reported by @​Likhixang). Replayed function calls only got the skip-validator signature stub when the upstream model name contained flash, pro or thinking, or was exactly gemini-4-argon-high. A pass-through Gemini model such as bare gemini-4-argon sent unsigned functionCall parts, so every multi-turn tool loop failed. Every gemini- backing now gets the stub, on the Responses, Chat Completions and Messages conversion and in native /v1beta sanitization. Claude and GPT-OSS backings are unchanged.

  • Claude Code's built-in WebSearch works through /v1/messages (#​784, @​Dominic485649). The Anthropic-to-Responses conversion treated Anthropic server tools (web_search_20250305, web_search_20260209, web_search_20260318, preview variants and name-only web_search) as ordinary functions, which failed upstream with 400 11129 or returned an empty web_search tool call that no client would run. They now become a hosted web_search tool, keeping user_location and domain filters, while a custom web_search function with an input_schema stays a function. Upstream web_search_call items come back as server_tool_use and web_search_tool_result blocks in streaming and non-streaming responses, including the query delta, and stop_reason stays end_turn after a hosted search. Failed or incomplete searches return a paired web_search_tool_result_error instead of a dangling server_tool_use. A forced web_search choice uses allowed_tools with mode: required, so the model cannot pick another function instead, and function tools without input_schema get empty parameters.

  • The first-run setup requires a one-time token from the service log. The bootstrap endpoint authorized any request that appeared to come from a private address. Behind Docker Desktop, rootless port forwarding or a private-network reverse proxy, public requests already arrive from a private peer, and X-Forwarded-For is client-controlled, so with ADMIN_SECRET unset anyone who could reach the port could set the admin secret first. The service now generates a token in memory, prints it in the startup banner and log, requires it on POST /api/admin/bootstrap, and revokes it after a successful setup; bootstrap-status issues a new one if the secret is cleared at runtime. BOOTSTRAP_ALLOWED_CIDR is now matched against the direct TCP peer, so forwarding headers cannot spoof their way into it. Only wrong-token attempts count against the rate limit, the audit log records the real peer and any claimed forwarded IP, and the setup page has a token field with the log lookup command.

  • Large Codex histories allocate far less memory before dispatch (#​787, reported by @​HanYC666). A 10 MiB Responses body allocated about 232 MB per request before reaching upstream, which on a Pi Zero W meant 20–90 s of full CPU and RSS peaks near 300 MB. Field cleanup on the HTTP, compact and WebSocket paths now deletes only fields that are present and skips writes that would not change the bytes, the image-generation check reads top-level fields in one pass, several input scans read the array without copying it, and the request size limiter reads a declared Content-Length into one buffer. Output bytes are unchanged. Per 10 MiB request, allocation drops from 232 MB to 87 MB; per 1 MiB request, from 23.7 MB to 11.3 MB.

  • One busy API key no longer stalls the durable image job queue. Workers took the oldest queued job and then waited for its API key's concurrency slot, so a key saturated by its own requests, such as long streams, held workers while other keys' jobs waited. Workers now look at the oldest queued job of each key and claim only jobs whose key has a free slot. Two new limits apply when the queue is enabled with IMAGE_JOB_WORKERS: IMAGE_JOB_MAX_QUEUED_PER_KEY (default 1000, 0 is unlimited) makes job creation return 429 with Retry-After once a key has that many queued jobs, and IMAGE_JOB_MAX_QUEUE_WAIT (default 24h, 0 disables, minimum 1m) fails jobs that have not started within that time and removes their stored reference images. Those jobs never reached upstream and can be retried. A (status, api_key_id, id) index is added.

  • Native Codex HTTP continuations no longer silently drop history (#​788, @​dundunge). A previous_response_id that the gateway cannot resolve from the requesting owner's cache now returns 409 (503 when the cache backend fails), instead of answering a turn without its history. New tool-call outputs are appended to the parent snapshot, and duplicates are skipped only when the full parent prefix and overlapping call_ids match; partial or conflicting replays return 409 response_context_unavailable. Duplicate top-level input or previous_response_id keys, including escaped duplicates, return 400 so different JSON parsers cannot pick different values. HTTP, compact and upstream WebSocket requests drop top-level gateway envelope fields such as type and stream_id while keeping nested fields of the same name. The built-in tool_search tool no longer gets an injected description, and background: false is no longer mistaken for the image background extension. First-run setup now fills the idle chat and blank WebSocket retention settings with their default of 8, and an explicit 0 is kept.

  • The public key-usage page rejects disabled API keys. It predated the per-key enable switch, so a disabled key could still read its usage summary, limits and recent request logs, and was shown as active. Disabled keys now get 401 and the attempt is audited, matching the proxy and the Image Studio portal. Expired and quota-exhausted keys stay readable so their holders can see why calls fail.

  • The pricing poller no longer times out at startup on slow SQLite storage (#​778, reported by @​HanYC666). The first read of the official pricing sync config ran table setup, including an insert that needs the SQLite write lock. After an upgrade the usage rollup backfill holds that lock almost continuously on slow storage, so the 5-second startup read failed with "context deadline exceeded". The config is now read first, and setup runs only when the read fails.

v3.1.0

Compare Source

Fixes
  • Antigravity Claude models can call tools again (#​783, reported by @​ATM-M). Every Claude request that carried tools failed with 400 tools.0.custom.input_schema.type: Input should be 'object'. This happened on /v1/chat/completions, /v1/messages, /v1/responses and native /v1beta; text-only requests and Gemini worked. Tool schemas travel as parametersJsonSchema, which Cloud Code hands to Claude verbatim as Anthropic input_schema, and since v2.9.4 the schema cleaner had uppercased every type (OBJECT, STRING). Types are now lowercase at every level, and Gemini accepts both casings. Claude also refuses a forced tool choice (Anthropic tool/any, Chat required or a named function). The Claude 5.5 family always refuses it, and Claude 4.x refuses it while thinking is enabled. In those cases the gateway sends AUTO instead and drops the allowed function names. Claude 4.x without thinking keeps the forced choice, and Gemini is unchanged.

  • /v1/messages keeps Claude model IDs that Antigravity serves instead of mapping them to Codex. The built-in Anthropic-to-Codex default map (for example claude-sonnet-4-6 → gpt-5.5) ran before the gateway checked whether an account could serve the requested ID under its own name. An Antigravity-only key got 503 "No available accounts", and a key that could also reach Codex silently got a GPT answer. The default map is now skipped when an account visible to the key publishes the ID directly, such as an Antigravity public model or a model declared by a relay account. Only structural conditions count: the key's visibility (the same as for /v1/models), its upstream channel and its affinity groups. Cooldowns and rate limits don't, so a busy pool never swaps in another vendor's model. Explicit model mappings still take precedence, and keys without such accounts keep the Codex fallback.

  • Structured output on Antigravity Claude returns the JSON instead of a 500. When a Claude model gets a json_schema response format, Cloud Code forces an internal json_mode tool. The non-streaming answer comes back as a json_mode function call with finish reason OTHER, which the gateway reported as antigravity response terminated with OTHER. That call is now turned into the JSON text answer, with key order preserved, preamble text dropped and thoughts kept. This applies to the Responses, Chat Completions and native /v1beta paths, streaming and non-streaming. OTHER becomes a normal stop once the answer has made a tool call, and requests that declare their own json_mode tool are left alone. Claude 5.5 rejects the forced tool upstream, so those requests now fail with a 400 antigravity_feature_unsupported error naming json_schema structured output, instead of an opaque tool_choice error.

v3.0.9

Compare Source

Features
  • The Antigravity account page gains batch delete and a full set of batch operations (#​782, reported by @​10373064). Selected accounts can be synced, tested, regrouped, enabled or disabled, locked or unlocked, reset, exported or deleted into the recycle bin, and API-key accounts can have their model list replaced in bulk. Sync and test can also target the current filter, and a one-click clean moves abnormal (banned or errored) accounts to the recycle bin using the same definition as the list. The quota column shows each quota group's 5h and weekly buckets with reset countdowns and marks snapshots older than six hours. Stat cards, status and credential-type filters, sorting by quota usage, today's requests or total requests, today and request columns, and health bars match the other channels. Clicking a row opens the shared account sheet with previous/next navigation and model cooldown management; clicking the quota opens a wide quota and access window with quota groups, Code Assist access and tiers, state and capabilities, AI credits and per-model quota. The single-row "refresh quota" and "refresh credential" buttons, which ran the same sync, become one sync action. Adding one account and importing files are separate entries: the add dialog detects whether the pasted credential is JSON, a refresh token or malformed JSON, the import dialog accepts dragged JSON files or many pasted refresh tokens, and proxy and group settings sit in a collapsible section.

  • Account refresh endpoints sync Antigravity accounts, and the account list filters and sorts them (#​782). POST /api/admin/accounts/:id/refresh and POST /api/admin/accounts/batch-refresh, including SSE progress, filter selectors and bounded concurrency, now run the full Antigravity control-plane sync (credential, project, access and quota). Disabled accounts are recognized from the database because they are not in the runtime pool. The paged account list accepts auth_kind=oauth|api_key for Antigravity, its summary counts OAuth and API-key accounts, and sort=usage orders accounts by the used share of their tightest quota bucket, the same key the scheduler uses. The dashboard's Antigravity quota distribution reads the same value.

  • Antigravity exports are one JSON file (#​782). GET /api/admin/accounts/antigravity/export now defaults to format=json: one account downloads as a single credential document and several as one JSON array, like the Codex and Claude exports. The importer reads both shapes, and the import dialog automatically splits files with more than 500 accounts into batches and merges the results. format=zip keeps the previous one-file-per-account archive.

Fixes
  • Long-range usage statistics no longer time out on slow SQLite storage (#​778, reported by @​HanYC666). The new usage_log_hourly table aggregates usage logs per UTC hour by API key, channel, model, endpoints, status, stream and internal flag. It is updated in the same transaction as each log batch, cleared with the logs and backfilled in the background; queries keep reading detail rows until the backfill completes. Queries read whole hours from the rollup and edge hours and window boundaries from detail rows, so results are unchanged. Rows written outside the normal path are detected and repaired, and the last three closed hours are re-counted every 20 minutes. This covers the public key-usage report, admin range totals and breakdowns, the error summary and request log counts; filters on account, search text, error kind or request shape other than stream still scan detail rows. On a 400k-row SQLite benchmark with a 30-day range the key-usage report drops from 950 ms to 12 ms and admin stats from 2.1 s to 21 ms. API-key rankings now break label ties by key ID.

  • Usage stat cards no longer show the previous range's numbers when a refresh fails (#​778, reported by @​HanYC666). A failed silent refresh after changing the range or filters kept the old figures under the new range's label, so a custom range spanning all history could show roughly today's totals. Cards are dimmed while new filters load, and a failed refresh covers them with the error and a retry button.

  • Edit buttons in the account group manager show a label. The common.edit translation was missing, so its tooltip showed the raw key.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Never, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants