Codex Router Changelog — Version History
This page tracks every release of Codex Router, synced weekly from the repository’s CHANGELOG.md. The current stable release line is 0.4.0-beta.2.
How updates work
Codex Router updates through the managed checkout: run ./bin/model-router codex update (or ./codex-router.ps1 codex update on Windows). Updates require a clean main checkout on the recognized GitHub origin, keep the previous revision as a local rollback ref, and reinstall the router from the new revision. After any update, run ./bin/model-router codex doctor --fix so the generated config and service match the source revision, then fully quit and reopen Codex so it reloads the merged model catalog.
The changelog below is the complete release history. If you are looking for what changed in a specific version, use your browser’s find-in-page (Control+F / Command+F) to jump to that version heading.
Unreleased
-
Codex updates now refresh the tray for every supported install location. Guided setup installs the companion at
~/Applications/Model Router.app, but updates only refreshed the tray when the checkout’s owndist/Model Router.appexisted. The update path now also detects the home-Applications bundle and the registered login-item bundle, then rebuilds and relaunches the tray from the updated checkout. -
doctor --fixno longer breaks a running install from a second checkout. When the recorded state owner still exists, repair now runs from that checkout and keeps ownership there. Deliberate ownership transfer still requires an explicit override or a fresh install. -
The macOS tray stays linked to the apps that launch it. If the tray bundle moves (for example from a checkout on a removable volume to the stable install), the next launch re-registers the login item against the current bundle; the launcher replaces an already-running tray with the rebuilt bundle; and
codex updaterebuilds and relaunches an installed tray so a router update never leaves a stale companion behind. Update & Verify now updates the checkout recorded as the installation owner instead of whichever checkout the tray binary was built from.
0.4.0-beta.2
-
Updates stop reinstalling dependencies that never changed. Every update re-ran the whole installer, so a commit that touched one
.mjsfile still wipednode_modulesfor a freshnpm ciand re-resolved the entirelitellm[proxy]tree against PyPI — which pulled unpinned transitive upgrades and, on a cold uv cache or a slow link, dominated the run. Both installers now fingerprint each dependency step (the lockfile for Node, the pinned requirement set plus the installed distribution versions for Python) and skip it when the artifacts already match, recording the stamp next tonode_modules/and.venv/so deleting either one reinstalls. Repair still rebuilds everything:doctor --fixpasses--force-deps(-ForceDepson Windows), which fingerprints cannot know about a corrupted tree. The LiteLLM and FastAPI pins now live insrc/install-plan.mjs, and a test fails if either installer’s copy drifts. -
update checkno longer performs the update. Thebin/updatewrapper hardcoded theupdatesubcommand, so the read-only availability check was unreachable from the CLI and asking “is there a new version?” reinstalled the router instead. Bothbin/updateandcodex-router.ps1 updatenow forward the subcommand, and a bare invocation still updates. -
Reasoning efforts now match what the installed Codex build can display. Codex’s picker parses effort levels into a fixed enum and silently drops values it does not recognize;
maxandultraonly joined that enum in Codex 0.143.0, so on older builds themaxtiers curated for several models simply vanished from the effort menu (GLM-5.2 lost its second tier, DeepSeek V4 Flash showed two levels instead of three). The catalog now derives the supported vocabulary from the installed Codex version and republishes out-of-range efforts at the nearest supported tier (max→xhigh), keeping defaults and announcement copy in range. Routing is unchanged — the forwarder already foldsxhighback to each vendor’s documented maximum. -
Legacy opencode Go models now offer Codex’s native migration prompt. GLM-5.1, Kimi K2.6, and MiniMax M2.7 carry an
upgradeToentry pointing at their generational successor on the same subscription (GLM-5.2, Kimi K3, MiniMax M3), so operators still running the older model get the full-screen “upgrade” modal and can switch their default with one accept — the older models stay in the picker. Upgrade targets are now validated at registry load: a checked-in prompt pointing at a missing or unlisted slug fails the build, and a user-curated one is skipped with a warning instead of shipping a modal that can never render. -
New models announce themselves in Codex. Checked-in models that newly become routable — shipped by a router update, or unlocked the moment their provider is credentialed and enabled — now carry Codex’s native “Introducing {model}” announcement for seven days, with copy assembled from their verified picker metadata (context window, effort ladder, image input). The first catalog capture seeds the tracking state silently so an install never announces the whole catalog, locally curated models never self-announce, and Codex’s own per-model show cap still applies. Curators can override the generated copy with an
availabilityNuxstring on the registry entry, and a newupgradeTofield ({ model, markdown }) drives Codex’s full-screen migration prompt for a genuine successor model — accepting it switches the operator’s default model, so it is reserved for deliberate hand-offs. -
Adapted the managed
[agents]concurrency default to the installed Codex build. Some Codex builds (observed on 0.141-0.145) parse[agents]as a pure role map and refuse to load any config containing the scalar, which brokecodex login statusandcodex doctoroutright. The config manager now probes the installed binary with a minimal config before writing the scalar and skips it when the build rejects it, so builds that accept the scalar keep the concurrency cap and strict builds keep a loadable config. -
Re-captured the native model catalog when the Codex build changes. The cached capture now records the Codex version that produced it and is refreshed from
codex debug modelson mismatch, so a catalog captured by an older build no longer feeds missing or stale capability fields (such assupports_reasoning_summaries) into the merged catalog after an upgrade. If the re-capture fails, the router keeps serving the previous capture and says so instead of failing the rebuild. -
Reasoning effort ladders now match each vendor’s documentation. Every listed model’s picker levels were verified against the provider’s official API docs: Kimi K3 (API) gains its documented low/high/max ladder instead of a forced max; DeepSeek V4 Flash gains its real low tier; Claude Opus 4.8 gains the full low/medium/high/xhigh/max
output_config.effortladder and the forwarder now passes the picked effort through instead of hardcoding high; GLM-5.2 sends its two documented tiers explicitly (upstream defaults to max when the parameter is omitted) and defaults to max as Z.ai recommends; GLM-5-Turbo no longer advertises effort control it does not support; and the cross-vendor DeepSeek/GLM models resold through the Alibaba plan gain the high/max ladder DashScope documents for them. The opencode Go models take their ladders from opencode’s own model registry (Grok low/medium/high; GLM-5.2 and DeepSeek V4 Pro high/max; DeepSeek V4 Flash low/high/max; HY3 low/high; Kimi K3 max-only; GPT 5.6 Luna low through max), passed through verbatim since the gateway validates these values itself. Providers whose thinking control is binary or undocumented (Qwen via DashScope, Ollama Cloud, MiniMax, MiMo, Kimi K2.x) intentionally keep a single level. -
Curated models now carry user-provided metadata, including reasoning efforts.
bin/curate-modelsasks for each new model’s context window, image support, and reasoning efforts (so curated models get the effort switcher in the Codex picker), with--effortsavailable for the non-interactive--modelsform. Every value defaults conservatively and stays editable inuser-models.json. No online metadata catalog is consulted — the provider’s own/v1/modelsendpoint decides which models exist, and the metadata is yours. -
New Meta Model API provider. The
metaprovider (shown as “Meta API”) routes the Responses protocol tohttps://api.meta.ai/v1with a storedMETA_API_KEY. Three Muse Spark models ship in the registry: 1.2, its cheaper 1.2 Contributor tier (whose inputs and outputs Meta may use for training), and the previous-generation 1.1 — the 1.2 tiers with reasoning summaries enabled. More Meta models can be curated per machine withbin/curate-models meta. -
opencode Go is one provider family everywhere. The
opencode-go-messagesandopencode-go-responsesprotocol variants now declarevariantOf: "opencode-go"in the registry, and provider selection treats the three as a single unit: enabling or disabling any of them toggles the whole family, the selection file stores onlyopencode-go, and every read expands it back to all variants. This retroactively fixes installs whose selection predates the variants — MiniMax, Qwen, and GPT 5.6 Luna models no longer vanish from the Codex picker while the other opencode Go models show. Setup, the tray, andproviders listnow show one opencode Go entry instead of three. -
Removed the Cursor and opencode app targets. The router now focuses on Codex only:
--target codexis the sole installer target, the Cursor Chat Completions gateway and the opencode config manager/subagent generator are gone, and their port blocks (4104-4107, 4116, 4120-4126) are released. The opencode Go model subscription is unaffected — it remains a regular provider inside Codex. Anyone with a previously installed Cursor or opencode integration can remove the old service with that checkout’smodel-router <target> uninstallbefore updating. -
A Show tray mode in the macOS tray’s Settings tab can tie the menu bar icon, Dynamic Island, and desktop panel to the Codex/ChatGPT desktop apps: the surfaces appear when either app launches and hide when the last one quits, while the tray process stays resident as the watcher. The default remains always-visible.
-
The macOS tray registers itself as a login item on its first launch, so it reopens automatically after a reboot instead of requiring a manual
./bin/model-router-tray. A Start at login toggle in the Settings tab (backed bySMAppService, also visible in System Settings › Login Items) controls it, and the automatic registration happens only once — disabling the item is never overridden. -
The opencode target now generates one subagent per selected model in opencode’s config, and refreshes those entries when providers are enabled, disabled, or given new keys.
setup,doctor,status,enable,disable, anduninstallall supportMODEL_ROUTER_TARGET=opencodethroughbin/model-router opencode ..., and the opencode installer works from bothinstall.sh --target opencodeandinstall.ps1 -Target opencode. -
Fixed native OpenAI models disappearing from the Codex picker on Windows when the Codex CLI is installed through npm (#46).
where.exe codexlists the extensionless POSIX shim beforecodex.cmd, and Node cannot spawn the former without a shell, so every probe threw ENOENT. The router now picks a shim Node can execute and runs.cmd/.batthrough a shell with the path quoted. -
A Codex binary that cannot be spawned is no longer reported as a signed-out session. That conflation is what let one spawn error silently strip every native model from the catalog; the catalog build now refuses to run rather than guess, and the doctor reports the probe failure on its own line.
-
DASHSCOPE_API_KEYis documented as aqwen-plancredential alongsideQWEN_PLAN_API_KEY, and the README now records that Qwen is key-only: Alibaba discontinued the Qwen Code OAuth free tier on 2026-04-15, so there is no OAuth path to add. PointQWEN_PLAN_BASE_URLat the DashScope compatible-mode endpoint to bill a pay-as-you-go key through the same provider. -
The Alibaba Model Studio plan provider (
qwen-plan) now lists every chat model the Individual Plan serves, not just Qwen3.7: Qwen3.8 Max, Qwen3.8 Max Preview and Qwen3.6 Flash (all with vision input), plus the cross-vendor models the plan resells — DeepSeek V4 Pro, DeepSeek V4 Flash (0731) and GLM-5.2. The cross-vendor entries use the DashScope compatible-mode request profile rather than each vendor’s native thinking profile, because DashScope rejects the vendor-specific parameters. The plan’s speech, image and video models are deliberately not listed — they are not chat-completions models and would fail on every request from a model picker. -
API keys can now be replaced or removed from the desktop app and the macOS tray, not just the terminal. Each connected API provider gains a Replace key action and a confirmed Remove action; removing deletes the managed key files and hides the provider from the Codex model picker. If a key is also present in the macOS Keychain or the environment, the removal result says where it still resolves from instead of claiming a clean disconnect.
control credential <provider> --removeexposes the same operation. -
The Dynamic Island setting is now a three-way mode: Off, Notch (the existing top-of-screen overlay), or Desktop — a draggable widget-style panel pinned just above the desktop icons that always shows live router activity, every connected provider’s vendor quota bars with reset countdowns, and the 7-day token trend, with its position remembered.
-
Added a Z.ai vendor quota adapter: when a
zai-codingprovider is configured, account usage now reports real plan windows (5-hour, weekly, token quota) with reset times from Z.ai’s key-authenticated quota API, plus a dashboard link. Alibaba plan and Ollama Cloud accounts stay local-only by design — their vendor dashboards are session-gated and the router never imports browser cookies — but now carry adashboardUrlso companion UIs can deep-link to the official usage pages. -
Service startup failures now include the underlying bounded, non-sensitive error message (for example which health check timed out or which service exited early) instead of a generic failure line.
-
Canceling a generation (or any client disconnect mid-request) no longer flips router health into the eight-second error state, so tray and island status indicators stop flashing red on ordinary cancels. Errors the router or an upstream actually produced still surface.
-
The hidden API-key prompt now confirms how many characters were captured after each entry, challenges input that looks like the same key pasted twice before saving, and re-prompts instead of failing on empty input, so a paste with terminal echo disabled is no longer a silent leap of faith.
-
Guided setup now offers to build and launch the desktop companion app as a final step on macOS (menu bar, installed into
~/Applications) and Linux (tray), with--with-tray/--no-trayoverrides oninstall.shandbin/setup. A missing toolchain or failed build warns and continues; it never fails the router install. -
Added an Ollama Cloud provider (
ollama-cloud) with GLM-5.2, Kimi K2.7 Code, MiniMax M3, and DeepSeek V4 Pro picker models, using ollama.com’s OpenAI-compatible API with an account API key and context windows read from Ollama’s published model metadata. -
Added a Qwen provider (
qwen-plan) for Alibaba Model Studio Token and Coding Plan subscriptions with Qwen3.7 Max and Qwen3.7 Plus picker models, defaulting to the Singapore Token Plan endpoint with an environment override for other regions or plans. -
Added a Z.ai GLM Coding Plan provider (
zai-coding) with GLM-5.2 and GLM-5-Turbo picker models. Requests use the plan’s dedicated coding endpoint, enable thinking, map Codex’s maximum reasoning tier to Z.ai’smaxeffort, and drop sampling overrides that conflict with thinking mode. -
Added interactive model curation:
bin/curate-models PROVIDERdiscovers the provider’s live model list, lets the user toggle models the registry does not ship, and stores them as protected local user models with conservative default metadata. User models overlay the registry at load time; invalid or colliding entries are skipped with warnings instead of failing the router, and the command can rebuild routes and restart the service on request. -
Rebuilt the guided setup as a stepped wizard: numbered progress headers, a toggleable provider list with live ready/needs-key/needs-sign-in status,
a/nselect-all/none shortcuts, invalid-input recovery instead of aborting, color when the terminal supports it (respectingNO_COLOR), and a review summary with explicit confirmation before anything is installed. -
Guided Codex setup can now onboard Grok OAuth (and offers to
npm installa missing official provider CLI), matching what the Cursor setup and tray already supported. -
Added a reversible tray toggle that lets signed-out Codex CLI/App sessions use connected external providers through a managed custom model provider, while preserving ChatGPT credentials and restoring the prior provider mode.
-
The macOS login-free toggle now gracefully restarts the registered Codex app after applying or restoring its model-provider mode.
-
Grok OAuth injects bare hosted
web_searchandx_searchtools so xAI can run server-side realtime search agentically, matching Grok Build. Router-side search env filters and request search-parameter mapping were removed. -
Use Thinking Orbs
Shapingwhile idle,Thinkingwhile generating, andSolvingfor the Island’s error indicator. -
Replace compact provider names with the providers’ published marks and Codex session titles, add a plain
+Nconcurrent-session indicator, and show dark hover rows with live status, elapsed time, daily usage, and ping-pong overflow for long titles. -
Added a native Windows and Linux tray companion with a seven-day token graph, connected-provider quota cards, secure onboarding, an animated top-center activity pill on Windows/X11, and an explicit tray-only Wayland fallback.
-
Balanced the Dynamic Island with an animated status dot and slow idle heartbeat, a clearer localized pulse and edge comet during generation, and a one-shot line-chart draw while preserving Reduce Motion behavior.
-
Restored the Dynamic Island’s daily line graph with today’s token total and provider quota percentage, while leaving longer-range controls in the tray.
-
Hide tray usage cards until the corresponding OAuth session or API key is configured; enabled providers and historical local traffic no longer create disconnected-account cards.
-
Cleaned up tray quota cards so each window has one standardized limit label and one reset line, with five-hour windows shown separately from weekly limits in both current and all-provider usage.
-
Fixed All usage cards so local traffic with request counts no longer shows “No use”, and local-only providers show “Local router traffic” instead of “No reset reported”.
-
Surface concurrent Codex model requests on the Dynamic Island: active count, multi-provider compact labels, and live request rows with elapsed time.
-
Added a credential-isolated Anthropic API provider with Claude Opus 4.8 in the Codex picker, native Anthropic Messages forwarding, secure key setup, tray controls, and a real LiteLLM-to-mock-Anthropic Codex integration test.
-
Added the macOS menu-bar control panel, all-provider usage grid, and optional Dynamic-Island-style activity overlay with secure provider onboarding.
-
Made tray usage selection account-aware, added quota reset times to provider cards, and kept Kimi and Grok OAuth sessions fresh during usage polling and routed requests.
-
Made macOS service reinstalls wait for launchd to finish unloading and use an in-place restart, preventing transient bootstrap status-5 failures.
-
Serialized background-service changes and added bounded readiness checks so repairs cannot overlap or report failure while a healthy router is starting.
-
Added a 30-second
Startinggrace state to the macOS tray so routine router recovery does not appear as an immediate failure. -
Added the isolated Cursor target and corrected its PowerShell installer path.
-
Removed the experimental Claude Desktop router target while retaining the direct, credential-isolated Anthropic API provider for Codex and Cursor.
-
Fixed partial startup failures so already-running forwarders are terminated, and isolated all six ports in the real LiteLLM integration test.
-
Grok OAuth account usage now reads weekly/monthly credit limits from the official Grok CLI billing endpoint.
-
Rewrote routed-model catalog identity text so external models no longer claim to be based on GPT-5 in Codex
base_instructions. -
Hardened local caller authentication with a separate per-install capability, exact internal-key checks, authenticated credential-detail health endpoints, browser-request rejection, and fail-closed routing before request bodies or provider quota are touched.
-
Protected Codex config and all config snapshots for the current user, and redacted the caller capability from status, migration, and support output.
-
Replaced raw exception text in HTTP responses and service logs with bounded, non-sensitive errors.
-
Fixed Windows private-file ACL grants for numeric user SIDs and corrected router-status detection for escaped Windows catalog paths.
0.3.0
- Added guided, provider-aware setup for Kimi OAuth, Kimi API, and DeepSeek API.
- Added safe detection, snapshots, automatic migration, and exact rollback for the two recognized earlier Kimi router layouts.
- Added macOS launchd, Linux systemd-user, and Windows Task Scheduler services, plus a native PowerShell installer and command wrapper.
- Added provider visibility and runtime enforcement so hidden external models cannot be mistaken for native models.
- Added
doctor --fix, privacy-safe support bundles, update rollback, guarded provider model discovery, and billed compatibility tests. - Added cross-platform CI, dependency audits, tagged source archives, SHA-256 checksums, and GitHub build-provenance attestations.
- Expanded zero-knowledge onboarding, installation, security, troubleshooting, and future-provider documentation.
0.2.0
- Generalized the original Kimi-only prototype into a validated provider/model registry.
- Added separate Kimi OAuth, Kimi API, and DeepSeek API routes while preserving native Codex models and ChatGPT authentication.