intersectUpstreamModelMetadata falls back to null for every Codex tool
capability field whose value differs across peer accounts. Since
e6d191a83 added service_tiers to codexToolCapabilityFields, a model served
by accounts with different (or partially declared) tier lists ends up with
"service_tiers": null in the generated Codex manifest. Codex decodes
service_tiers as a required array and rejects the whole manifest, so the
client loses model metadata for every model.
Fall back to [] for conflicting service_tiers (do not advertise any tier
that is not shared by all peers), and normalize an explicit null to []
when applying capabilities.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The warning said "Other errors will return 500", but custom error codes
only gate normal account-error handling (stop scheduling, rate-limit
marking). Request retry and account failover decide independently: on the
OpenAI-compatible gateway, unselected 403/5xx still fail over to another
account and only exhaust to 502; only some non-failover paths (for example
an ordinary 400) are rewritten to a generic 500. Reword zh/en to describe
what the setting actually does, including that an empty list applies no
filtering.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Map five_hour/seven_day/seven_day_overage_included to 5h/7d/7d overage
(raw key fallback) in the confirm message, credit tooltip and success message.
- Align zh/en confirm copy with the Codex dialog; {count} is the count
remaining after this use.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- R1-1: an explicit upstream "unavailable" answer now fences the organization
for 15 minutes (CLAUDE_RESET_UPSTREAM_UNAVAILABLE) instead of 24h; ambiguous
outcomes keep the 24h fence. Frontend tells the operator to retry later.
- R1-2: rotate the idempotency key after definite pre-claim refusals (busy,
not available, unresolved, upstream unavailable); map IDEMPOTENCY_IN_PROGRESS
and IDEMPOTENCY_RETRY_BACKOFF to clear zh/en messages.
- R1-3: redeem reason and cleared windows pass only through explicit
allowlists, so upstream values can never echo a grant ID to clients.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Orange 「重置」 button mirrors the Codex cell: enabled only after a query
shows a redeemable credit, danger confirm, one idempotency key per
confirmation reused on retry, outcome-specific messages, then refreshes
credits and the usage row. Ported from upstream PR #7591.
Co-authored-by: korkin25 <eugeny.kuzakov@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
POST /admin/accounts/:id/claude/reset-credits/redeem (Idempotency-Key
required, same middleware chain as the Codex reset-quota route). The server
re-queries eligibility and claims only the upstream next_grant_id when it is
redeemable; grant/org IDs never reach the client. Claims are serialized by
account and organization Redis leases, and a durable per-organization fence
in the idempotency table blocks further redemption after an unconfirmed
outcome (settles after 24h). Ported from upstream PR #7591.
Co-authored-by: korkin25 <eugeny.kuzakov@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>