Keep catalog membership on schedulable accounts and intersect advertised
capabilities across all active group members that map an alias. Preserve
upstream plugin, service-tier, and models-list body-limit changes.
Co-authored-by: Cursor <cursoragent@cursor.com>
Account model mappings decide availability, but generated Codex catalogs previously inferred capabilities from local model-name tables. Compatible upstreams can expose unknown models such as OpenCode x-preview-f-free, so reasoning levels, image input, and context limits were missing or wrong.
Sync capability metadata from the account model endpoint, enrich incomplete lists from the Models.dev provider matching the account base URL, and persist only complete snapshots. Mixed groups consume the safe intersection across schedulable accounts. When IDs sync without complete metadata, return an explicit warning and preserve the previous snapshot.
Third-party Responses providers often omit /models. If that endpoint returns 404 or 405 and the account already has concrete model mappings, use those configured upstream IDs for capability enrichment. Authentication, rate-limit, server, and network failures remain hard errors, and metadata is never guessed across providers by model name alone.
Advertise a single none choice for non-reasoning models so current Codex can select them, then omit that catalog placeholder when forwarding to compatible Responses upstreams while preserving official OpenAI request semantics.
- ChannelsView platformOrder now includes the three CN provider
platforms so channel pricing can be configured for them; composite
group expansion/attachment stays limited to the five main platforms
(matches backend isConcreteRequestPlatform and composite-routes
target_platform validation)
- SyncPricingModels maps kimi->moonshot, zhipu->zhipu,
deepseek->deepseek; also fixes gemini mapping to "google" which
matched zero catalog entries (provider key is "gemini")
- Add CN platform colors to channel pricing model tag classes
PR #5423 relaxed the email suffix whitelist: once a whitelist is
configured, non-whitelisted registrable domains are each allowed to
register one account. That behavior activated unconditionally.
Add registration_email_domain_quota_enabled (default false) to gate it:
- Off (default): restore pre-#5423 strict whitelist semantics — with a
non-empty whitelist, non-whitelisted domains are rejected with
EMAIL_SUFFIX_NOT_ALLOWED; the register/verify views restore the
client-side whitelist pre-check and allowed-domain hint.
- On: keep #5423 behavior — one account per non-whitelisted registrable
domain (EMAIL_DOMAIN_REGISTRATION_LIMIT).
- Empty whitelist keeps allowing all domains in both states.
Gating lives in validateRegistrationEmailQuota and (as a race-safety
backstop) createUserWithRegistrationEmailGuard; the repository-level
domain lock + in-tx recheck is unchanged. The admin update field is
*bool (omitted = keep current) so stale full-payload saves cannot
silently flip the switch. Email binding and OAuth auto-signup keep
their strict policy, and pending-OAuth bind-login for existing
accounts is unaffected because the handler resolves existing emails
before the quota check.
Frontend adds the toggle to admin settings (zh/en copy; whitelist hint
restored to strict wording, quota wording moved to the new toggle) and
exposes the flag via public settings + SSR injection payload.
Tests: #5423 quota tests now enable the switch explicitly; new
default-off regression tests cover register/send-code/async/pending
OAuth/OIDC create-account plus both register views; API contract JSON
and the injection drift guard are updated.
Resolves three conflicts, all of the "both branches appended to the same
block" shape. Every one is resolved as a union of both sides; nothing from
either parent is dropped.
- handler/admin/setting_handler_update.go: keep ChannelMonitorHideThroughput
(V2) alongside GrokDefaultTextModel / GrokCrossClientModelMapEnabled /
GrokDefaultBaseURLMode (#5408). UpdateSettings writes every key on each
save, so dropping either side would reset those settings to zero values.
- service/domain_constants.go: keep SettingKeyChannelMonitorHideThroughput
and the three SettingKeyGrok* constants.
- repository/migrations_runner.go: keep the 195 checksum rule (V2) and the
218/219/220 rules (#5408).
Remove optional upload_url / fake connectivity-only success from admin video
tests. Stamp Grok CLI headers only on the CLI proxy so OAuth media against
api.x.ai can complete and preview video like the gateway path.
Require oauth state/redirect consistency, fail closed on missing proxy,
and remove password login from create/reauth UI (admin-only password path stays off by default).
Add mode-first connectivity probes for text/image/video/search/tts/stt/realtime,
standalone voice and web-search paths, media upload options, and in-browser
image/audio/video preview (including ZDR-safe b64 images and edit validation).